Plot Oct. 2022 SUNBEAR output¶

Adapt scripts_v3/CM7_DPSplots.ipynb to look at the scripts_v4 data, which ran while I was presenting scripts_v3 at DPS. Create plots with objective of making a final go/no-go call for the Remote Sensing special issue.

In [18]:
from astropy.io import fits as pyfits

CM7 = pyfits.open('output/CM7_v4_cube.fits')
CM7.info()

# overall output structure:
# primary - I/F hypercube + description of axes
# ext 1 - lat 2D array
# ext 2 - dlon 2D array
# ext 3 - mu (cos(emi)) 2D array
# ext 4 - mu0 (cos(inc)) 2D array
# ext 5 - g_eff 2D array
# ext 6 - table of parameter values for non-spatial dimensions 3-7

print('')
print('')
print('EXT 6: the BinTable --')
print('')
pvals = CM7[6].data
print(CM7[6].columns)

print('cube_dim: ', pvals['cube_dim'])
print('dim_name: ', pvals['dim_name'])
print('{:s}: '.format(CM7[6].columns[2].name))
for i in range(5):
    print(i, pvals.field(2)[i])
print('{:s}: '.format(CM7[6].columns[3].name), pvals.field(3))
print('{:s}: '.format(CM7[6].columns[4].name), pvals.field(4))
Filename: output/CM7_v4_cube.fits
No.    Name      Ver    Type      Cards   Dimensions   Format
  0  PRIMARY       1 PrimaryHDU      48   (16, 16, 3, 3, 6, 4, 6)   float64   
  1  LAT           1 ImageHDU         9   (16, 16)   float64   
  2  DLON          1 ImageHDU         9   (16, 16)   float64   
  3  MU            1 ImageHDU         8   (16, 16)   float64   
  4  MU0           1 ImageHDU         8   (16, 16)   float64   
  5  G_EFF         1 ImageHDU         9   (16, 16)   float64   
  6                1 BinTableHDU     19   5R x 5C   [I, 10A, 40A, I, 6D]   


EXT 6: the BinTable --

ColDefs(
    name = 'cube_dim'; format = 'I'
    name = 'dim_name'; format = '10A'
    name = 'dim_comment'; format = '40A'
    name = 'dim_len'; format = 'I'
    name = 'values_float'; format = '6D'; dim = '(6)'
)
cube_dim:  [3 4 5 6 7]
dim_name:  ['CENWAVE' 'P_N' 'tau_N' 'P_W' 'tau_W']
dim_comment: 
0 Filter central wavelength (micron)
1 Upper cloud base pressure (bar)
2 Upper cloud optical depth
3 Lower cloud base pressure (bar)
4 Lower cloud optical depth
dim_len:  [3 3 6 4 6]
values_float:  [[ 0.631  0.727  0.75   0.     0.     0.   ]
 [ 0.7    1.5    2.2    0.     0.     0.   ]
 [ 0.     1.     2.     5.    15.    50.   ]
 [ 3.     4.     5.     6.     0.     0.   ]
 [ 0.     1.     2.     5.    15.    50.   ]]

Plot the geometry parameter arrays¶

Follows example from https://matplotlib.org/stable/plot_types/arrays/imshow.html#sphx-glr-plot-types-arrays-imshow-py

In [19]:
import matplotlib.pyplot as plt
import numpy as np
import numpy.ma as ma
import matplotlib.cm as cm

#print(plt.style.available)
plt.style.use('default')
plt.rcParams['font.family'] = 'sans-serif'
plt.rcParams['font.sans-serif'] = ['Helvetica', 'Roboto', 'Verdana', 'Arial']
plt.rcParams['pdf.fonttype'] = 42
plt.rcParams["axes.grid"] = False
plt.rcParams['axes.facecolor'] = 'white'
plt.rcParams['font.size'] = 14

# prepare data with masked corners
planet = np.where(CM7[5].data < 1000., np.ones(CM7[5].data.shape), np.zeros(CM7[5].data.shape))


# plot
fig,ax = plt.subplots(figsize=(15, 2), ncols=5, gridspec_kw={'wspace': 0.35})

for i in range(5):
    ax[i].axes.xaxis.set_ticklabels([])
    ax[i].axes.yaxis.set_ticklabels([])
    panel_data = ma.masked_array(CM7[i+1].data, mask=planet)
    panel = ax[i].imshow(panel_data, origin='lower', cmap='turbo')
    fig.colorbar(panel, ax=ax[i], ticks=np.linspace(panel_data.min(), panel_data.max(), 5))
# notes: panel = ... saves the color "mappable" object returned by ax[i].imshow.
#        add the colorbar using the figure's method, telling which mappable we're 
#        talking about and which axes object it should be near.
#        https://matplotlib.org/3.5.0/gallery/color/colorbar_basics.html

fig.patch.set_facecolor('white')
ax[0].set_axis_off()
ax[1].set_axis_off()
ax[2].set_axis_off()
ax[3].set_axis_off()
ax[4].set_axis_off()

ax[0].set_title('Latitude')
ax[1].set_title('CML offset')
ax[2].set_title('$\mu$')
ax[3].set_title('$\mu_0$')
ax[4].set_title('$g_{\mathrm{eff}}$')

plt.savefig('CM7_geometry_grid_ipy.pdf')
1 extra bytes in post.stringData array
'created' timestamp seems very low; regarding as unix timestamp
Zapf NOT subset; don't know how to subset; dropped
feat NOT subset; don't know how to subset; dropped
meta NOT subset; don't know how to subset; dropped
morx NOT subset; don't know how to subset; dropped

Explore CM7 values¶

Make a plot array for all 1-cloud models.

In [20]:
# pick most frequently changed values:
#     continuum (0 = 631, 2 = 750)
#     tau of the thick cloud
i_cont = 0
i_taucloud = 5   #  [ 0.     1.     2.     5.    15.    50.   ]
cmap_str_C = 'turbo' # 'viridis' # 'jet'
cmap_str_727 = 'turbo' # 'cool' # 'jet' 'plasma'
cmap_str_CM7 = 'turbo' # 'jet'
In [21]:
import copy

fig,ax = plt.subplots(figsize=(15, 15), ncols=5, nrows=7, gridspec_kw={'wspace': 0.2, 'hspace': 0.35})
fig.patch.set_facecolor('white')


# for later use, save the chosen I/F data and CM7 ratios
# as a set of one-cloud models "_1C"
#
p_1C = np.concatenate((pvals['values_float'][1][0:3], pvals['values_float'][3][0:4]))
n_pcloud = 7 # just hard-code the dimensions
n_x = 16
n_y = 16

#if631_1C = ma.zeros((n_pcloud, n_x, n_y)) # I/F at continuum wavelength 631 nm / this doesn't make the mask right
if631_1C = ma.array(np.zeros((n_pcloud, n_x, n_y)), mask=np.zeros((n_pcloud, n_x, n_y))) # I/F at continuum wavelength 631 nm
if750_1C = copy.deepcopy(if631_1C) # I/F at continuum wavelength 750 nm
if727_1C = copy.deepcopy(if631_1C) # I/F at CH4-band wavelength 727 nm
cm7_6_1C = copy.deepcopy(if631_1C) # CM7 ratio (631 nm continuum)
cm7_7_1C = copy.deepcopy(if631_1C) # CM7 ratio (750 nm continuum)

# version with explicit limits (different for each p_cloud) - these are for tau = 50
vmin_631 = [0, 0, 0, 0, 0, 0, 0]
vmin_727 = [0, 0, 0, 0, 0, 0, 0]
vmin_750 = [0, 0, 0, 0, 0, 0, 0]
    
vmax_631 = [1, 1, 1, 1, 1, 1, 1]
vmax_727 = [0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5]
#vmax_727 = [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25]
#vmax_727 = [0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]
vmax_750 = [1, 1, 1, 1, 1, 1, 1]

#vmin_cm7_6 = [1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2]
#vmin_cm7_7 = [1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2]
    
#vmax_cm7_6 = [2.2, 2.2, 2.2, 2.2, 2.2, 2.2, 2.2]
#vmax_cm7_7 = [2.2, 2.2, 2.2, 2.2, 2.2, 2.2, 2.2]
    
vmin_cm7_6 = [1., 1, 1, 1, 1, 1, 1]
vmin_cm7_7 = [1., 1, 1, 1, 1, 1, 1]
    
vmax_cm7_6 = [3., 3, 3, 3, 3, 3, 3]
vmax_cm7_7 = [3., 3, 3, 3, 3, 3, 3]
    
# FIRST SET: upper cloud
#
for i_ptop in range(3): #  [ 0.7    1.5    2.2 ]
    i_pbot = 0 #  [ 3.     4.     5.     6.  ]
    i_tautop = i_taucloud
    i_taubot = 0 

    # select data and make ratios, mask out space in the corners,
    # save the results for later use
    #
    if631_1C[i_ptop][:][:] = ma.masked_array(np.squeeze(CM7[0].data[i_taubot,i_pbot,i_tautop,i_ptop,0,:,:]), 
                                             mask=planet)
    if750_1C[i_ptop][:][:] = ma.masked_array(np.squeeze(CM7[0].data[i_taubot,i_pbot,i_tautop,i_ptop,2,:,:]), 
                                             mask=planet)
    if727_1C[i_ptop][:][:] = ma.masked_array(np.squeeze(CM7[0].data[i_taubot,i_pbot,i_tautop,i_ptop,1,:,:]), 
                                             mask=planet)
    cm7_6_1C[i_ptop][:][:] = if631_1C[i_ptop][:][:] / if727_1C[i_ptop][:][:]
    cm7_7_1C[i_ptop][:][:] = if750_1C[i_ptop][:][:] / if727_1C[i_ptop][:][:]

    
    # this row: col 0, continuum 631
    panel = ax[i_ptop,0].imshow(if631_1C[i_ptop][:][:], origin='lower', cmap=cmap_str_C, \
                                vmin=vmin_631[i_ptop], vmax=vmax_631[i_ptop])
    fig.colorbar(panel, ax=ax[i_ptop,0], 
                 ticks=np.linspace(vmin_631[i_ptop], vmax_631[i_ptop], 5))

    # this row: col 1, CH4-band 727
    panel = ax[i_ptop,1].imshow(if727_1C[i_ptop][:][:], origin='lower', cmap=cmap_str_727, \
                                vmin=vmin_727[i_ptop], vmax=vmax_727[i_ptop])
    fig.colorbar(panel, ax=ax[i_ptop,1], 
                 ticks=np.linspace(vmin_727[i_ptop], vmax_727[i_ptop], 5))

    # this row: col 2, continuum 750
    panel = ax[i_ptop,2].imshow(if750_1C[i_ptop][:][:], origin='lower', cmap=cmap_str_C, \
                                vmin=vmin_750[i_ptop], vmax=vmax_750[i_ptop])
    fig.colorbar(panel, ax=ax[i_ptop,2], 
                 ticks=np.linspace(vmin_750[i_ptop], vmax_750[i_ptop], 5))

    # this row: col 3, CM7 ratio (631 continuum)
    panel = ax[i_ptop,3].imshow(cm7_6_1C[i_ptop][:][:], origin='lower', cmap=cmap_str_CM7, \
                                vmin=vmin_cm7_6[i_ptop], vmax=vmax_cm7_6[i_ptop])
    fig.colorbar(panel, ax=ax[i_ptop,3], 
                 ticks=np.linspace(vmin_cm7_6[i_ptop], vmax_cm7_6[i_ptop], 5))

    # this row: col 4, CM7 ratio (750 continuum)
    panel = ax[i_ptop,4].imshow(cm7_7_1C[i_ptop][:][:], origin='lower', cmap=cmap_str_CM7, \
                                vmin=vmin_cm7_7[i_ptop], vmax=vmax_cm7_7[i_ptop])
    fig.colorbar(panel, ax=ax[i_ptop,4], 
                 ticks=np.linspace(vmin_cm7_7[i_ptop], vmax_cm7_7[i_ptop], 5))

    # this row: y-axis on col 1 says the 1-cloud pressure level
    ax[i_ptop,0].set_ylabel('$P_{{\mathrm{{cloud}}}}$ = {:3.1f} bar'.format(pvals['values_float'][1,i_ptop]))

    
# SECOND SET: lower cloud 
#
for i_pbot in range(4): #  [ 3.     4.     5.     6.  ]
    i_ptop = 0 #  [ 0.7    1.5    2.2 ]
    i_tautop = 0 
    i_taubot = i_taucloud

#    xC6 = ma.masked_array(np.squeeze(CM7[0].data[i_taubot,i_pbot,i_tautop,i_ptop,0,:,:]), mask=planet)
#    xC7 = ma.masked_array(np.squeeze(CM7[0].data[i_taubot,i_pbot,i_tautop,i_ptop,2,:,:]), mask=planet)
#    x727 = ma.masked_array(np.squeeze(CM7[0].data[i_taubot,i_pbot,i_tautop,i_ptop,1,:,:]), mask=planet)
#    cm7_6 = xC6 / x727
#    cm7_7 = xC7 / x727

    if631_1C[i_pbot +3][:][:] = ma.masked_array(np.squeeze(CM7[0].data[i_taubot,i_pbot,i_tautop,i_ptop,0,:,:]), 
                                             mask=planet)
    if750_1C[i_pbot +3][:][:] = ma.masked_array(np.squeeze(CM7[0].data[i_taubot,i_pbot,i_tautop,i_ptop,2,:,:]), 
                                             mask=planet)
    if727_1C[i_pbot +3][:][:] = ma.masked_array(np.squeeze(CM7[0].data[i_taubot,i_pbot,i_tautop,i_ptop,1,:,:]), 
                                             mask=planet)
    cm7_6_1C[i_pbot +3][:][:] = if631_1C[i_pbot +3][:][:] / if727_1C[i_pbot +3][:][:]
    cm7_7_1C[i_pbot +3][:][:] = if750_1C[i_pbot +3][:][:] / if727_1C[i_pbot +3][:][:]

    panel = ax[i_pbot +3,0].imshow(if631_1C[i_pbot +3][:][:], origin='lower', cmap=cmap_str_C, \
                                vmin=vmin_631[i_pbot +3], vmax=vmax_631[i_pbot +3])
    fig.colorbar(panel, ax=ax[i_pbot +3,0], 
                 ticks=np.linspace(vmin_631[i_pbot +3], vmax_631[i_pbot +3], 5))

    panel = ax[i_pbot +3,1].imshow(if727_1C[i_pbot +3][:][:], origin='lower', cmap=cmap_str_727, \
                                vmin=vmin_727[i_pbot +3], vmax=vmax_727[i_pbot +3])
    fig.colorbar(panel, ax=ax[i_pbot +3,1], 
                 ticks=np.linspace(vmin_727[i_pbot +3], vmax_727[i_pbot +3], 5))

    panel = ax[i_pbot +3,2].imshow(if750_1C[i_pbot +3][:][:], origin='lower', cmap=cmap_str_C, \
                                vmin=vmin_750[i_pbot +3], vmax=vmax_750[i_pbot +3])
    fig.colorbar(panel, ax=ax[i_pbot +3,2], 
                 ticks=np.linspace(vmin_750[i_pbot +3], vmax_750[i_pbot +3], 5))

    panel = ax[i_pbot +3,3].imshow(cm7_6_1C[i_pbot +3][:][:], origin='lower', cmap=cmap_str_CM7, \
                                vmin=vmin_cm7_6[i_pbot +3], vmax=vmax_cm7_6[i_pbot +3])
    fig.colorbar(panel, ax=ax[i_pbot +3,3], 
                 ticks=np.linspace(vmin_cm7_6[i_pbot +3], vmax_cm7_6[i_pbot +3], 5))

    panel = ax[i_pbot +3,4].imshow(cm7_7_1C[i_pbot +3][:][:], origin='lower', cmap=cmap_str_CM7, \
                                vmin=vmin_cm7_7[i_pbot +3], vmax=vmax_cm7_7[i_pbot +3])
    fig.colorbar(panel, ax=ax[i_pbot +3,4], 
                 ticks=np.linspace(vmin_cm7_7[i_pbot +3], vmax_cm7_7[i_pbot +3], 5))
    
    ax[i_pbot +3,0].set_ylabel('$P_{{\mathrm{{cloud}}}}$ = {:3.1f} bar'.format(pvals['values_float'][3,i_pbot]))
    
    
for i in range(5):
    for j in range(7):
        ax[j,i].set_xticks([]) #axes.xaxis.set_ticklabels([])
        ax[j,i].set_yticks([])
        ax[j,i].set_frame_on(False)

ax[0,0].set_title('$\\tau$ = {:0.0f}\n{:3.0f} nm'.format(pvals['values_float'][2,i_taucloud], pvals['values_float'][0,0] *1000))
ax[0,1].set_title('{:3.0f} nm'.format(pvals['values_float'][0,1] *1000))
ax[0,2].set_title('{:3.0f} nm'.format(pvals['values_float'][0,2] *1000))
ax[0,3].set_title('631/727 ratio')
ax[0,4].set_title('750/727 ratio')

plt.savefig('CM7_ratio_maps_ipy.pdf')
1 extra bytes in post.stringData array
'created' timestamp seems very low; regarding as unix timestamp
Zapf NOT subset; don't know how to subset; dropped
feat NOT subset; don't know how to subset; dropped
meta NOT subset; don't know how to subset; dropped
morx NOT subset; don't know how to subset; dropped

Reflectivity vs P vs $\tau$¶

Based on code from CM7_CTL_tau.ipynb, CM7_newplots_incomplete.ipynb.

In [22]:
# read in actual data points for comparison
#

hst_631 = np.loadtxt("PJ42_631_minmax_mu0curve.txt", skiprows=6, usecols=(0,1,2,3))
hst_727 = np.loadtxt("PJ42_727_minmax_mu0curve.txt", skiprows=6, usecols=(0,1,2,3))
hst_750 = np.loadtxt("PJ42_750_minmax_mu0curve.txt", skiprows=6, usecols=(0,1,2,3))


plt.rcParams["font.size"] = 12

fig,ax = plt.subplots(figsize=(12,20), ncols=3, nrows=6, gridspec_kw={'wspace': 0.2})
fig.patch.set_facecolor('white')

cstep = 33
fullcolor = cm.get_cmap('turbo')

for i_taucloud in range(6): #  [ 0.     1.     2.     5.    15.    50.   ]


# setup the new I/F and ratio arrays for the selected tau_cloud:

    if631_tautest = ma.array(np.zeros((n_pcloud, n_x, n_y)), mask=np.zeros((n_pcloud, n_x, n_y))) # I/F at continuum wavelength 631 nm
    if750_tautest = if631_tautest.copy() # I/F at continuum wavelength 750 nm
    if727_tautest = if631_tautest.copy() # I/F at CH4-band wavelength 727 nm

# FIRST SET: upper cloud
#
    for i_ptop in range(3): #  [ 0.7    1.5    2.2 ]
        i_pbot = 0 #  [ 3.     4.     5.     6.  ]
        i_tautop = i_taucloud
        i_taubot = 0 

        if631_tautest[i_ptop][:][:] = ma.masked_array(np.squeeze(CM7[0].data[i_taubot,i_pbot,i_tautop,i_ptop,0,:,:]), 
                                             mask=planet)
        if750_tautest[i_ptop][:][:] = ma.masked_array(np.squeeze(CM7[0].data[i_taubot,i_pbot,i_tautop,i_ptop,2,:,:]), 
                                             mask=planet)
        if727_tautest[i_ptop][:][:] = ma.masked_array(np.squeeze(CM7[0].data[i_taubot,i_pbot,i_tautop,i_ptop,1,:,:]), 
                                             mask=planet)

# SECOND SET: lower cloud 
#
    for i_pbot in range(4): #  [ 3.     4.     5.     6.  ]
        i_ptop = 0 #  [ 0.7    1.5    2.2 ]
        i_tautop = 0 
        i_taubot = i_taucloud


        if631_tautest[i_pbot +3][:][:] = ma.masked_array(np.squeeze(CM7[0].data[i_taubot,i_pbot,i_tautop,i_ptop,0,:,:]), 
                                             mask=planet)
        if750_tautest[i_pbot +3][:][:] = ma.masked_array(np.squeeze(CM7[0].data[i_taubot,i_pbot,i_tautop,i_ptop,2,:,:]), 
                                             mask=planet)
        if727_tautest[i_pbot +3][:][:] = ma.masked_array(np.squeeze(CM7[0].data[i_taubot,i_pbot,i_tautop,i_ptop,1,:,:]), 
                                             mask=planet)

# estimate CM7 from known P and mu values
#
    for i_cloud in range(7):
        p_mu = ma.array(np.zeros((2, n_x, n_y)), mask=np.zeros((2, n_x, n_y)))
        p_mu[0][:][:] = p_1C[i_cloud]
        p_mu[1][:][:] = CM7[4].data
        p_flat = p_mu[0][:][:].flatten()
        mu_flat = p_mu[1][:][:].flatten()
        p_mu_flat = np.stack((p_flat, mu_flat), axis=0)

# plot this tau in a row

    for i_ptop in range(3): #  [ 0.7    1.5    2.2 ]
        i_cont = 2 # 750
        i_pbot = 0 #  [ 3.     4.     5.     6.  ]
        i_tautop = i_taucloud
        i_taubot = 0 
        i_color = i_ptop *cstep + 10
    
    # show fits
        ax[i_taucloud,0].plot(CM7[4].data.flatten(), if631_tautest[i_ptop][:][:].flatten(), 'o', 
                 markerfacecolor='none', color=fullcolor(i_color), 
                 label='{:3.1f} bar'.format(pvals['values_float'][1,i_ptop]))

        ax[i_taucloud,1].plot(CM7[4].data.flatten(), if727_tautest[i_ptop][:][:].flatten(), 'o', 
                 markerfacecolor='none', color=fullcolor(i_color), 
                 label='{:3.1f} bar'.format(pvals['values_float'][1,i_ptop]))

        ax[i_taucloud,2].plot(CM7[4].data.flatten(), if750_tautest[i_ptop][:][:].flatten(), 'o', 
                 markerfacecolor='none', color=fullcolor(i_color), 
                 label='{:3.1f} bar'.format(pvals['values_float'][1,i_ptop]))

    for i_pbot in range(4): #  [ 3.     4.     5.     6.  ]
        i_cont = 2
        i_ptop = 0 #  [ 0.7    1.5    2.2 ]
        i_tautop = 0 
        i_taubot = i_taucloud
        i_color = i_pbot *cstep + 10 + 3 *cstep

        ax[i_taucloud,0].plot(CM7[4].data.flatten(), if631_tautest[i_pbot +3][:][:].flatten(), 'o', 
                 markerfacecolor='none', color=fullcolor(i_color), 
                 label='{:3.1f} bar'.format(pvals['values_float'][3,i_pbot]))

        ax[i_taucloud,1].plot(CM7[4].data.flatten(), if727_tautest[i_pbot +3][:][:].flatten(), 'o', 
                 markerfacecolor='none', color=fullcolor(i_color), 
                 label='{:3.1f} bar'.format(pvals['values_float'][3,i_pbot]))

        ax[i_taucloud,2].plot(CM7[4].data.flatten(), if750_tautest[i_pbot +3][:][:].flatten(), 'o', 
                 markerfacecolor='none', color=fullcolor(i_color), 
                 label='{:3.1f} bar'.format(pvals['values_float'][3,i_pbot]))

    ax[i_taucloud,0].set_ylabel('I/F reflectivity', size=15)
    ax[i_taucloud,0].set_title('$\\tau$ = {:0.0f}   (631 nm)'.format(pvals['values_float'][2,i_taucloud]))
    ax[i_taucloud,1].set_title('$\\tau$ = {:0.0f}   (727 nm)'.format(pvals['values_float'][2,i_taucloud]))
    ax[i_taucloud,2].set_title('$\\tau$ = {:0.0f}   (750 nm)'.format(pvals['values_float'][2,i_taucloud]))
    ax[i_taucloud,0].set_ylim([0,0.9])
    ax[i_taucloud,1].set_ylim([0,0.9])
    ax[i_taucloud,2].set_ylim([0,0.9])

    # also show the HST data
    ax[i_taucloud,0].plot(hst_631[:,0], hst_631[:,1], '-', linewidth=3, color=fullcolor(0))
    ax[i_taucloud,0].plot(hst_631[:,0], hst_631[:,2], '--', linewidth=1, color=fullcolor(0))
    ax[i_taucloud,0].plot(hst_631[:,0], hst_631[:,3], '--', linewidth=1, color=fullcolor(0))
    
    ax[i_taucloud,1].plot(hst_727[:,0], hst_727[:,1], '-', linewidth=3, color=fullcolor(0))
    ax[i_taucloud,1].plot(hst_727[:,0], hst_727[:,2], '--', linewidth=1, color=fullcolor(0))
    ax[i_taucloud,1].plot(hst_727[:,0], hst_727[:,3], '--', linewidth=1, color=fullcolor(0))
    
    ax[i_taucloud,2].plot(hst_750[:,0], hst_750[:,1], '-', linewidth=3, color=fullcolor(0))
    ax[i_taucloud,2].plot(hst_750[:,0], hst_750[:,2], '--', linewidth=1, color=fullcolor(0))
    ax[i_taucloud,2].plot(hst_750[:,0], hst_750[:,3], '--', linewidth=1, color=fullcolor(0))
    

# x-label, legend only on bottom row
ax[5,0].set_xlabel('Incident angle cosine, $\mu_0$', size=15)
ax[5,1].set_xlabel('Incident angle cosine, $\mu_0$', size=15)
ax[5,2].set_xlabel('Incident angle cosine, $\mu_0$', size=15)
ax[5,1].legend(fontsize=12)

for axi in ax.flat:
    axi.minorticks_on()
    axi.tick_params(which='major', length=8, direction='in', right=True, top=True)
    axi.tick_params(which='minor', length=4, direction='in', right=True, top=True)
    axi.set_xlim([0.2,1])
    
plt.savefig('IF_CTL_tau_v4_ipy.pdf')
plt.savefig('IF_CTL_tau_v4_ipy.png')
1 extra bytes in post.stringData array
'created' timestamp seems very low; regarding as unix timestamp
Zapf NOT subset; don't know how to subset; dropped
feat NOT subset; don't know how to subset; dropped
meta NOT subset; don't know how to subset; dropped
morx NOT subset; don't know how to subset; dropped

Evaluation of v4 results¶

See below, after making next set of plots of CM7 ratio.

Some curve-fitting to $\mu_0$ or $\mu$.¶

Copied from scripts_v3/CM7_CTL_tau.ipynb.

In [23]:
from numpy.polynomial import polynomial as Poly

mu_cut = 0.3 # 0.2
# array to store the slopes / offsets from fit
#
slope6 = np.zeros(7)
slope7 = np.zeros(7)
offset6_orig = np.zeros(7)
offset7_orig = np.zeros(7)

i_taucloud = 5 #  [ 0.     1.     2.     5.    15.    50.   ]
cmap_str = 'turbo' # 'jet'
for i_ptop in range(3): #  [ 0.7    1.5    2.2 ]
    i_cont = 2 # 750
    i_pbot = 0 #  [ 3.     4.     5.     6.  ]
    i_tautop = i_taucloud
    i_taubot = 0 
    i_color = i_ptop *cstep + 10
    
    # create x,y, do linear fit (continuum 750)
    limx = CM7[4].data[CM7[4].data > mu_cut]
    limcm = (cm7_7_1C[i_ptop][:][:])[CM7[4].data > mu_cut]
    abx = Poly.polyfit(limx, limcm, deg=1)
    
    # store fit results for later
    fity = Poly.polyval([mu_cut,1], abx)
    slope7[i_ptop] = abx[1]
    offset7_orig[i_ptop] = abx[0]
    
    # show fits
    # repeat for continuum 631
    limcm = (cm7_6_1C[i_ptop][:][:])[CM7[4].data > mu_cut]
    abx = Poly.polyfit(limx, limcm, deg=1)
    fity = Poly.polyval([mu_cut,1], abx)
    slope6[i_ptop] = abx[1]
    offset6_orig[i_ptop] = abx[0]
    
for i_pbot in range(4): #  [ 3.     4.     5.     6.  ]
    i_cont = 2
    i_ptop = 0 #  [ 0.7    1.5    2.2 ]
    i_tautop = 0 
    i_taubot = i_taucloud
    i_color = i_pbot *cstep + 10 + 3 *cstep

    limcm = (cm7_7_1C[i_pbot +3][:][:])[CM7[4].data > mu_cut]
    abx = Poly.polyfit(limx, limcm, deg=1)
    fity = Poly.polyval([mu_cut,1], abx)
    slope7[i_pbot+3] = abx[1]
    offset7_orig[i_pbot+3] = abx[0]

    limcm = (cm7_6_1C[i_pbot +3][:][:])[CM7[4].data > mu_cut]
    abx = Poly.polyfit(limx, limcm, deg=1)
    fity = Poly.polyval([mu_cut,1], abx)
    slope6[i_pbot+3] = abx[1]
    offset6_orig[i_pbot+3] = abx[0]

pcloud = p_1C # np.concatenate((pvals['values_float'][1][0:3], pvals['values_float'][3][0:4]))
psqrt = pcloud**0.5

# sqrt()
curve6 = Poly.polyfit(psqrt, slope6, deg=2)
fit6 = Poly.polyval(psqrt, curve6)
curve7 = Poly.polyfit(psqrt, slope7, deg=2)
fit7 = Poly.polyval(psqrt, curve7)

# calculating R_0 values

# v2 of notebook used R0 = constant (indep. p_cloud).
# but now it looks like R0 also is a function of p_cloud**0.5

# use scipy approach of Volodimir Kopey here:
# https://stackoverflow.com/questions/11479064/multiple-linear-regression-in-python


import scipy
from scipy.optimize import curve_fit

# set up the simple function form i want
#
def CM7_fn(p_mu, r_00, r_01, r_02, m_0, m_1, m_2):
    p, mu = p_mu
    xr = r_00 + r_01 * p**0.5 + r_02 * p
    xm = m_0 * mu + m_1 * p**0.5 * mu +  m_2 * p * mu
    return xr + xm

# prepare the data (points in CM7_ratio_vs_mu0, where mu_0 > mu_cut)
# (use crude way of setting up the dependent variable matrix because i have limited python skillz)
#
mu_mask = np.where((CM7[4].data < mu_cut) | (CM7[5].data < 1000.), 
                   np.ones(CM7[4].data.shape), np.zeros(CM7[4].data.shape))

# clumsily try to apply the same mu_mask to the CM7 ratio data
#
p_mu = ma.array(np.zeros((2, n_pcloud, n_x, n_y)), mask=np.zeros((2, n_pcloud, n_x, n_y)))
rat_6 = ma.array(np.zeros((n_pcloud, n_x, n_y)), mask=np.zeros((n_pcloud, n_x, n_y)))
rat_7 = ma.array(np.zeros((n_pcloud, n_x, n_y)), mask=np.zeros((n_pcloud, n_x, n_y)))
for i in range(n_pcloud):
    p_mu[0][i][:][:] = ma.array(np.full((n_x, n_y), p_1C[i]), mask=mu_mask)
    p_mu[1][i][:][:] = ma.array(CM7[4].data, mask=mu_mask)
    rat_6[i][:][:] = ma.array(cm7_6_1C[i][:][:], mask=mu_mask)
    rat_7[i][:][:] = ma.array(cm7_7_1C[i][:][:], mask=mu_mask)

p_flat = ma.compressed(p_mu[0])
mu_flat = ma.compressed(p_mu[1])

p_mu_flat = np.stack((p_flat, mu_flat), axis=0)
fitparam_guess = [1.5, 1, -0.3, 0.01, 0.6, -0.01]

fitparam_CM7_6, fitcovar_CM7_6 = curve_fit(CM7_fn, p_mu_flat, ma.compressed(rat_6), fitparam_guess)
fitparam_CM7_7, fitcovar_CM7_7 = curve_fit(CM7_fn, p_mu_flat, ma.compressed(rat_7), fitparam_guess)

cm7_6_1C.flatten()


# calculate data needed for image matrix: row = p_cloud, col = CM7_6, CM7_7, fit_CM7_6, fit_CM7_7, P_6, P_7

#    CM7_6, CM7_7: output from SUNBEAR
#    fit_CM7_6, fit_CM7_7: CM7 values calculated from multivariate fit above, using the known P & mu_0 data
#    P_6, P_7: retrieved cloud pressures using multivariate fit and the CM7 values from SUNBEAR


# setup relevant arrays
#
fit_CM7_6 = ma.array(np.zeros((n_pcloud, n_x, n_y)),
                     mask=np.zeros((n_pcloud, n_x, n_y))) 
fit_CM7_7 = copy.deepcopy(fit_CM7_6)
invP_6 = copy.deepcopy(fit_CM7_6)
invP_7 = copy.deepcopy(fit_CM7_6)
quadsign_6 = [1, 1, 1, 1, 1, 1, 1]
quadsign_7 = [1, 1, 1, 1, 1, 1, 1]
#quadsign_6 = [-1, -1, -1, -1, -1, -1, -1]
#quadsign_7 = [-1, -1, -1, -1, -1, -1, -1]

# estimate CM7 from known P and mu values
#
for i_cloud in range(7):
    p_mu = ma.array(np.zeros((2, n_x, n_y)), mask=np.zeros((2, n_x, n_y)))
    p_mu[0][:][:] = p_1C[i_cloud]
    p_mu[1][:][:] = CM7[4].data

    p_flat = p_mu[0][:][:].flatten()
    mu_flat = p_mu[1][:][:].flatten()
    p_mu_flat = np.stack((p_flat, mu_flat), axis=0)

    raw = np.reshape(CM7_fn(p_mu_flat, *fitparam_CM7_6), (n_x, n_y))
    fit_CM7_6[i_cloud][:][:] = ma.array(raw, mask=planet)

    raw = np.reshape(CM7_fn(p_mu_flat, *fitparam_CM7_7), (n_x, n_y))
    fit_CM7_7[i_cloud][:][:] = ma.array(raw, mask=planet)

def invP_(fitparam, cm7, mu_0, mu_cut, quadsign):
    # solve for p using new multivariate function
    
    denom = fitparam[2] + fitparam[5]*mu_0
    quad_c = (fitparam[0] + fitparam[3]*mu_0 - cm7) / denom
    quad_b = (fitparam[1] + fitparam[4]*mu_0) / denom
    discriminant = np.clip(quad_b**2 - 4*quad_c, 0, 999.)
    return 0.5*quad_b**2 - quad_c + quadsign * 0.5*quad_b * discriminant**0.5
#    return (quad_b**2 - 4*quad_c) # check sign of "discriminant"

#[ 9.01026106e-01 -3.76380886e-02  1.12039573e-04 -6.39421562e-01 2.27854117e+00 -4.83750179e-01]


# calculate transformations
#
#
for i_cloud in range(7):

    invP_6[i_cloud][:][:] = invP_(fitparam_CM7_6, cm7_6_1C[i_cloud][:][:], 
                                  CM7[4].data, mu_cut, quadsign_6[i_cloud])
    invP_7[i_cloud][:][:] = invP_(fitparam_CM7_7, cm7_7_1C[i_cloud][:][:], 
                                  CM7[4].data, mu_cut, quadsign_7[i_cloud])

    
    
# read in actual data points for comparison
#

hst_CM7_6 = np.loadtxt("PJ42_CM7-631_minmax_mu0curve.txt", skiprows=6, usecols=(0,1,2,3))
hst_CM7_7 = np.loadtxt("PJ42_CM7-750_minmax_mu0curve.txt", skiprows=6, usecols=(0,1,2,3))



    

Some of the above may be delete-able.

But now, do a single-tau plot of the CM7 vs $\mu_0$:

In [24]:
plt.rcParams["font.size"] = 12
plt.rcParams['font.family'] = 'sans-serif'
plt.rcParams['font.sans-serif'] = ['Helvetica', 'Roboto', 'Verdana', 'Arial']
plt.rcParams['pdf.fonttype'] = 42

fig,ax = plt.subplots(figsize=(12,20), ncols=2, nrows=6, gridspec_kw={'wspace': 0.2})
fig.patch.set_facecolor('white')


for i_taucloud in range(6): #  [ 0.     1.     2.     5.    15.    50.   ]


# setup the new I/F and ratio arrays for the selected tau_cloud:

    if631_tautest = ma.array(np.zeros((n_pcloud, n_x, n_y)), mask=np.zeros((n_pcloud, n_x, n_y))) # I/F at continuum wavelength 631 nm
    if750_tautest = copy.deepcopy(if631_tautest) # I/F at continuum wavelength 750 nm
    if727_tautest = copy.deepcopy(if631_tautest) # I/F at CH4-band wavelength 727 nm
    cm7_6_tautest = copy.deepcopy(if631_tautest) # CM7 ratio (631 nm continuum)
    cm7_7_tautest = copy.deepcopy(if631_tautest) # CM7 ratio (750 nm continuum)

# FIRST SET: upper cloud
#
    for i_ptop in range(3): #  [ 0.7    1.5    2.2 ]
        i_pbot = 0 #  [ 3.     4.     5.     6.  ]
        i_tautop = i_taucloud
        i_taubot = 0 

        if631_tautest[i_ptop][:][:] = ma.masked_array(np.squeeze(CM7[0].data[i_taubot,i_pbot,i_tautop,i_ptop,0,:,:]), 
                                             mask=planet)
        if750_tautest[i_ptop][:][:] = ma.masked_array(np.squeeze(CM7[0].data[i_taubot,i_pbot,i_tautop,i_ptop,2,:,:]), 
                                             mask=planet)
        if727_tautest[i_ptop][:][:] = ma.masked_array(np.squeeze(CM7[0].data[i_taubot,i_pbot,i_tautop,i_ptop,1,:,:]), 
                                             mask=planet)
        cm7_6_tautest[i_ptop][:][:] = if631_tautest[i_ptop][:][:] / if727_tautest[i_ptop][:][:]
        cm7_7_tautest[i_ptop][:][:] = if750_tautest[i_ptop][:][:] / if727_tautest[i_ptop][:][:]

# SECOND SET: lower cloud 
#
    for i_pbot in range(4): #  [ 3.     4.     5.     6.  ]
        i_ptop = 0 #  [ 0.7    1.5    2.2 ]
        i_tautop = 0 
        i_taubot = i_taucloud

        if631_tautest[i_pbot +3][:][:] = ma.masked_array(np.squeeze(CM7[0].data[i_taubot,i_pbot,i_tautop,i_ptop,0,:,:]), 
                                             mask=planet)
        if750_tautest[i_pbot +3][:][:] = ma.masked_array(np.squeeze(CM7[0].data[i_taubot,i_pbot,i_tautop,i_ptop,2,:,:]), 
                                             mask=planet)
        if727_tautest[i_pbot +3][:][:] = ma.masked_array(np.squeeze(CM7[0].data[i_taubot,i_pbot,i_tautop,i_ptop,1,:,:]), 
                                             mask=planet)
        cm7_6_tautest[i_pbot +3][:][:] = if631_tautest[i_pbot +3][:][:] / if727_tautest[i_pbot +3][:][:]
        cm7_7_tautest[i_pbot +3][:][:] = if750_tautest[i_pbot +3][:][:] / if727_tautest[i_pbot +3][:][:]

# determine fit coefficients
#
    p_mu = ma.array(np.zeros((2, n_pcloud, n_x, n_y)), mask=np.zeros((2, n_pcloud, n_x, n_y)))
    rat_6_tautest = ma.array(np.zeros((n_pcloud, n_x, n_y)), mask=np.zeros((n_pcloud, n_x, n_y)))
    rat_7_tautest = ma.array(np.zeros((n_pcloud, n_x, n_y)), mask=np.zeros((n_pcloud, n_x, n_y)))
    for i in range(n_pcloud):
        p_mu[0][i][:][:] = ma.array(np.full((n_x, n_y), p_1C[i]), mask=mu_mask)
        p_mu[1][i][:][:] = ma.array(CM7[4].data, mask=mu_mask)
        rat_6_tautest[i][:][:] = ma.array(cm7_6_tautest[i][:][:], mask=mu_mask)
        rat_7_tautest[i][:][:] = ma.array(cm7_7_tautest[i][:][:], mask=mu_mask)

    p_flat = ma.compressed(p_mu[0])
    mu_flat = ma.compressed(p_mu[1])
    p_mu_flat = np.stack((p_flat, mu_flat), axis=0)

    fitparam_guess = [1.5, 1, -0.3, 0.01, 0.6, -0.01]
    fitparam_CM7_6_tautest, fitcovar_CM7_6_tautest = curve_fit(CM7_fn, p_mu_flat, ma.compressed(rat_6_tautest), fitparam_guess)
    fitparam_CM7_7_tautest, fitcovar_CM7_7_tautest = curve_fit(CM7_fn, p_mu_flat, ma.compressed(rat_7_tautest), fitparam_guess)

# get fitted values
#
    fit_CM7_6_tautest = ma.array(np.zeros((n_pcloud, n_x, n_y)),
                     mask=np.zeros((n_pcloud, n_x, n_y))) 
    fit_CM7_7_tautest = copy.deepcopy(fit_CM7_6)
    invP_6_tautest = copy.deepcopy(fit_CM7_6_tautest)
    invP_7_tautest = copy.deepcopy(fit_CM7_6_tautest)
    quadsign_6 = [1, 1, 1, 1, 1, 1, 1]
    quadsign_7 = [1, 1, 1, 1, 1, 1, 1]

# estimate CM7 from known P and mu values
#
    for i_cloud in range(7):
        p_mu = ma.array(np.zeros((2, n_x, n_y)), mask=np.zeros((2, n_x, n_y)))
        p_mu[0][:][:] = p_1C[i_cloud]
        p_mu[1][:][:] = CM7[4].data
        p_flat = p_mu[0][:][:].flatten()
        mu_flat = p_mu[1][:][:].flatten()
        p_mu_flat = np.stack((p_flat, mu_flat), axis=0)

        raw = np.reshape(CM7_fn(p_mu_flat, *fitparam_CM7_6_tautest), (n_x, n_y))
        fit_CM7_6_tautest[i_cloud][:][:] = ma.array(raw, mask=planet)
        raw = np.reshape(CM7_fn(p_mu_flat, *fitparam_CM7_7_tautest), (n_x, n_y))
        fit_CM7_7_tautest[i_cloud][:][:] = ma.array(raw, mask=planet)

# , plot this tau in a row

    for i_ptop in range(3): #  [ 0.7    1.5    2.2 ]
        i_cont = 2 # 750
        i_pbot = 0 #  [ 3.     4.     5.     6.  ]
        i_tautop = i_taucloud
        i_taubot = 0 
        i_color = i_ptop *cstep + 10
    
    # show fits
        ax[i_taucloud,0].plot(CM7[4].data.flatten(), cm7_7_tautest[i_ptop][:][:].flatten(), 'o', 
                 markerfacecolor='none', color=fullcolor(i_color), 
                 label='{:3.1f} bar'.format(pvals['values_float'][1,i_ptop]))
        ax[i_taucloud,0].plot(CM7[4].data.flatten(), fit_CM7_7_tautest[i_ptop][:][:].flatten(), '-', color=fullcolor(i_color))

        ax[i_taucloud,1].plot(CM7[4].data.flatten(), cm7_6_tautest[i_ptop][:][:].flatten(), 'o', 
                 markerfacecolor='none', color=fullcolor(i_color), 
                 label='{:3.1f} bar'.format(pvals['values_float'][1,i_ptop]))
        ax[i_taucloud,1].plot(CM7[4].data.flatten(), fit_CM7_6_tautest[i_ptop][:][:].flatten(), '-', color=fullcolor(i_color))

    for i_pbot in range(4): #  [ 3.     4.     5.     6.  ]
        i_cont = 2
        i_ptop = 0 #  [ 0.7    1.5    2.2 ]
        i_tautop = 0 
        i_taubot = i_taucloud
        i_color = i_pbot *cstep + 10 + 3 *cstep

        ax[i_taucloud,0].plot(CM7[4].data.flatten(), cm7_7_tautest[i_pbot +3][:][:].flatten(), 'o', 
                 markerfacecolor='none', color=fullcolor(i_color), 
                 label='{:3.1f} bar'.format(pvals['values_float'][3,i_pbot]))
        ax[i_taucloud,0].plot(CM7[4].data.flatten(), fit_CM7_7_tautest[i_pbot +3][:][:].flatten(), '-', color=fullcolor(i_color), linewidth=3)

        ax[i_taucloud,1].plot(CM7[4].data.flatten(), cm7_6_tautest[i_pbot +3][:][:].flatten(), 'o', 
                 markerfacecolor='none', color=fullcolor(i_color), 
                 label='{:3.1f} bar'.format(pvals['values_float'][3,i_pbot]))
        ax[i_taucloud,1].plot(CM7[4].data.flatten(), fit_CM7_6_tautest[i_pbot +3][:][:].flatten(), '-', color=fullcolor(i_color), linewidth=3)

    ax[i_taucloud,0].set_ylabel('CM7 reflectivity ratios', size=15)
    ax[i_taucloud,0].set_title('$\\tau$ = {:0.0f}   (750 / 727 ratio)'.format(pvals['values_float'][2,i_taucloud]))
    ax[i_taucloud,1].set_title('$\\tau$ = {:0.0f}   (631 / 727 ratio)'.format(pvals['values_float'][2,i_taucloud]))
    ax[i_taucloud,0].set_ylim([1.,3.5])  #[0.,10]) #[1.25,2.75])
    ax[i_taucloud,1].set_ylim([1.,3.5])  #[0.,10]) #[1.25,3.25])


    # also show the HST data
    ax[i_taucloud,0].plot(hst_CM7_7[:,0], hst_CM7_7[:,1], '-', linewidth=3, color=fullcolor(0))
    ax[i_taucloud,0].plot(hst_CM7_7[:,0], hst_CM7_7[:,2], '--', linewidth=1, color=fullcolor(0))
    ax[i_taucloud,0].plot(hst_CM7_7[:,0], hst_CM7_7[:,3], '--', linewidth=1, color=fullcolor(0))
    
    ax[i_taucloud,1].plot(hst_CM7_6[:,0], hst_CM7_6[:,1], '-', linewidth=3, color=fullcolor(0))
    ax[i_taucloud,1].plot(hst_CM7_6[:,0], hst_CM7_6[:,2], '--', linewidth=1, color=fullcolor(0))
    ax[i_taucloud,1].plot(hst_CM7_6[:,0], hst_CM7_6[:,3], '--', linewidth=1, color=fullcolor(0))

    
# x-label, legend only on bottom row
ax[5,0].set_xlabel('Incident angle cosine, $\mu_0$', size=15)
ax[5,1].set_xlabel('Incident angle cosine, $\mu_0$', size=15)
ax[5,1].legend(fontsize=12)

for axi in ax.flat:
    axi.minorticks_on()
    axi.tick_params(which='major', length=8, direction='in', right=True, top=True)
    axi.tick_params(which='minor', length=4, direction='in', right=True, top=True)
    axi.set_xlim([0.2,1])
    
#ax[0,0].set_ylim([0.,10]) #15])
#ax[0,1].set_ylim([0.,10]) #15])

plt.savefig('CM7_CTL_tau_v4_ipy.pdf')
1 extra bytes in post.stringData array
'created' timestamp seems very low; regarding as unix timestamp
Zapf NOT subset; don't know how to subset; dropped
feat NOT subset; don't know how to subset; dropped
meta NOT subset; don't know how to subset; dropped
morx NOT subset; don't know how to subset; dropped

Evaluation of v4 results¶

Initial thoughts (CM7):

  • Slope is opposite (over $\mu_0$ on [0.35, 1]): positive for model and negative for data. This could be helped by creme brulee, if disk-center observations see more of the creme (brighter in 727 so CM7 is lower).

Initial thoughts (I/F, from plot higher up):

  • 631 nm column looks brilliant!
  • 727 nm model is curved but data are linear in $\mu_0$, not sure how to fix. Reduce upper haze? Move ubiquitous layer deeper? Make it more compact? This might be OK with 631 because it doesn't care that much how deep the ubiquitous layer is.
  • 727 nm disk-center reflectivity is pretty good. Makes it seem like thick 0.7-bar clouds are not a real thing.
  • 750 nm disk-center reflectivity way too low for $\tau$ < 15. This may relate to color of ubiquitous layer. See scripts_v3/CM7_DPSplots.ipynb, n_i vs SSA plots at bottom. We used ssa_haze = 0.9999, rad_haze = 0.2, tau=0.1 for the upper haze and ssa_chromo = 0.995, tau=2 for the chromophore layer in the v4 run. Having the SSA curve go the other way (absorbing more at 631 than 750) could be justified to some extent by the Carlson++2016 data, but would take a bit of work to implement. See Figs. 13 and 14 of Dahl++2021: the $\Delta n_i$ between 631 and 750 nm is about 0.0013 (and our 0.995 is a sort of average between white and chromo particles). This may be necessary since any additional reflectivity would make the 631 channel too bright at high tau. It is beginning to look like a creme brulee is inescapable, however, spatial variability in the ubiquitous creme brulee layers would not be reproducible in this study of the depth of deep clouds. Particle larger than light wavelength might allow more scattering in 750 nm compared to 631 nm (r = 1 µm).
  • A series of plots showing $\tau$=2,50 for the successive scripts_vx models might be interesting to show convergence.
  • Most of the problems are at low $\tau$, where the reflectivity samples the ubiquitous layers.
  • 750 nm disk-center reflectivity slightly low compared to 631 nm for large $\tau$. Increase deep cloud particle size to 3 µm?

Recommended changes for v5:

  • Make new mu0curve data traces with min/max instead of stdev.
  • Creme brulee: split ubiquitous layer into absorbing (with $n_i$ greater at 631 than 750) + conservative. Need to work on partitioning of SSA and $\tau$, and depths of layer (move deeper to make 727 more linear, mainly by lowering I/F at moderate to high incidence angle). But overall opacity then needs to be slightly higher to make sure $\mu_0$ values are not too low:
    • "H" layer has chromophore component at 0.3 bar and white component at 0.4, 0.6, 0.8 bar.
    • Chromophore component has Carlson++2016 $n_i$ and Mie scattering, keep size at 0.2 µm for higher 631/750 extinction ratio (see scripts_v4/scratch_debug.ipynb).
    • White component has $n_i$ = 10-8 (see n_i vs SSA section in v3/CM7_DPSplots.ipynb).
    • Increase sizes for white layer to 1 µm? Recent literature has many examples of chromophore being submicron and upper cloud/haze being closer to 1 µm (but much higher $\tau$ than we want). But something is needed to increase the 750/631 ratio. Maybe 0.5 µm would work (see scripts_v4/scratch_debug.ipynb). The 750/631 would still be < 1, but not by much, and we still have the chromophore layer to offset.
    • 750/631 ratio is also a bit low at high $\tau$. Increase deep cloud particle size back to 3 µm.
    • Test white-layer $\tau$ values of 1, 3, 9. (Set to span v4 values)
  • Current model allows full range of $\tau$ for upper and lower cloud simultaneously. Consider formulating a new model: creme brulee/haze "H" layer varies between ~3 opacity states (and ideally a single vertical structure state but consider trying 3 structure states to see what fits best), and deep cloud "D" layer ranges from 2-6 bar. This could form the basis for a full MCMC retrieval on spectroscopic data. The three structure states test what can best fit the $\tau$=0 plots above, while the 3 opacity states model spatial variation on the disk.
  • After looking at some scattering plots (test_scattering.py_20221012b.pdf and a), I worry that r=3 µm cloud particles might be too forward scattering. Just make the cloud particles 2 µm.

Checklist for 10-12 Oct 2022:

  • _X_ Make new min/max mu0curve files and plot against v4 model
  • _X_ Finalize parameter values for v5 (edit comments above and table below)
  • _X_ Make scatterers plots to verify expectations for the variety of v5 particle types
  • _X_ Update template_v5 for new structure and values. Aersosol layers are strat_haze, chromo, trop_haze, cloud
  • _X_ Update generate_v5 for new structure and output filenames
  • _X_ Update v5 scratch.pro to call the new generate with the right codes
  • _X_ Move KWSS to office
  • ___ Initiate v5 run

Write down parameters for v5 in consistent way:

Parameter v2 v3 v4 v5 v6 v7

HAZE (stratosphere) | | | | | tau | 5 | 0.05 (1?) | 0.1 | 0.1 | 0.1 | 0.1 | | rad (µm) | 0.5 | 0.2 | 0.2 | 0.2 | 0.2 | 0.2 | | SSA | 0.99 | 0.9999 | n$_i$=1e-8 | n$_i$=1e-8 | n$_i$=1e-8 | n$_i$=1e-8 | | P | 0.3-0.05 | 0.1-0.001 | 0.1-0.001 | 0.1-0.001 | 0.1-0.001 | 0.1-0.001 | | H | 1 | 1 | 1 | 1 | 1 |

HAZE (chromophore) | | | | | tau | - | 0.25 (0.3?) | 2 | 0.1 | 0.15 | 0.15 | | rad (µm) | - | 0.2 | 0.2 | 0.2 | 0.2 | 0.2 | | SSA | - | 0.85 | 0.995 | n$_i$=0.01, from Carlson++2016 | n$_i$=0.01 | n$_i$=0.01 | | P | - | 0.3-0.05 | 0.3-0.05 | 0.3-0.1 | 0.3-0.1 | 0.3-0.1 | | H | - | 0.3 | 0.3 | 0.3 | 0.3 | 0.3 |

HAZE (white tropospheric) | | | | | tau | - | - | - | 1, 3, 9 | 1, 5, 15 | 3, 10, 15 | | rad (µm) | - | - | - | 1.0 | 0.5 | [0.2, 0.5, 2.0] | | SSA | - | - | - | n$_i$=1e-8| n$_i$=1e-8 | n$_i$=1e-8 | | P | - | - | - | [0.4,0.6,0.8]-0.3 | 0.5 | 0.5 | | H | - | - | - | 1 | 1 | 1 |

CLOUD | | | | | rad (µm) | 3 | 1 | 2 | 2 | 2 | 2 | | SSA | 0.999 | 0.9999 | n$_i$=1e-8 | n$_i$=1e-8 | n$_i$=1e-8 | n$_i$=1e-8 | | tau | [0,1,2,5,15,50] | [0,1,2,5,15,50] | [0,1,2,5,15,50] | [0,2,5,15,50] | [0,5,25,100] | [0,5,25,100] | | P | [0.7,1.5,2.2,3,4,5,6] | [0.7,1.5,2.2,3,4,5,6] | [0.7,1.5,2.2,3,4,5,6] | [2,3,4,5,6] | [2,3,4,5,6] |[2,3,4,5,6] |

ATMOSPHERE | | | | | Layers | 120 | 130 | 130 | 130 | 130 |130 | | Spacing | Log | Adaptive | Adaptive | Adaptive | Adaptive |Adaptive | | Pmax (bar) | 14 | 26 | 26 | 26 | 26 |26 | | NH$_3$ | NH3_profile_IDL.py | NH3_profile_wong22.py | NH3_profile_wong22.py | NH3_profile_wong22.py | NH3_profile_wong22.py | NH3_profile_wong22.py |

SCATTERERS | | | | | Gamma n | 400 | 200 | 200 | 200 | 200 | 200 |
| Gamma rmax (µm) | 100 | 5 | 5 | 50 | 50 | 50 |
| Spacing | linear | linear | linear | geometric | geometric | geometric |

GRID | | | | | ugly_angles | 16x16 | 16x16 | 16x16 (10x10 was aborted) | 16x16 | 16x16 | 16x16 |

Make scatterers plots¶

Verify expectations for the variety of v5 particle types below. Pickles come from test_scattering.py.

In [26]:
import pickle

cstep = 33
fullcolor = cm.get_cmap('turbo')

#print(plt.style.available)
plt.style.use('default')
plt.rcParams['font.family'] = 'sans-serif'
plt.rcParams['font.sans-serif'] = ['Helvetica', 'Roboto', 'Verdana', 'Arial']
plt.rcParams['pdf.fonttype'] = 42
plt.rcParams["axes.grid"] = False
plt.rcParams['axes.facecolor'] = 'white'
plt.rcParams['font.size'] = 14

haze_chromo = pickle.load(open(str('test_chromophore.pickle'),'rb'))
cloud       = pickle.load(open(str('test_cloud.pickle'),'rb'))
haze_strato = pickle.load(open(str('test_stratosphere.pickle'),'rb'))
haze_tropo  = pickle.load(open(str('test_white-tropospheric-haze.pickle'),'rb'))
haze_tropo_v6  = pickle.load(open(str('test_white-tropospheric-haze_v6.pickle'),'rb'))

cloud.keys()
# dict_keys(['asym', 'sigma', 'ssa', 'lam', 'R', 'nR'])
Out[26]:
dict_keys(['asym', 'sigma', 'ssa', 'lam', 'R', 'nR'])
In [49]:
fig,ax = plt.subplots(figsize=(20,4), ncols=5, nrows=1, gridspec_kw={'wspace': 0.4})

color1 = fullcolor(10)
color2 = fullcolor(215)
color3 = fullcolor(165)
color4 = fullcolor(60)
color5 = fullcolor(140)

ax[0].plot(haze_strato['lam'], haze_strato['ssa'], '-', color=color1, label='r= 0.2 $\mu$m, n$_i$= 1e-8')
ax[0].plot(haze_chromo['lam'], haze_chromo['ssa'], ':', lw=3, color=color2, label='r= 0.2 $\mu$m, n$_i$= 1e-2')
ax[0].plot(haze_tropo['lam'], haze_tropo['ssa'], '-', lw=6, color=color3, label='r= 1 $\mu$m, n$_i$= 1e-8')
ax[0].plot(haze_tropo['lam'], haze_tropo_v6['ssa'], '--', lw=3, color=color5, label='r= 0.5 $\mu$m, n$_i$= 1e-8')
ax[0].plot(cloud['lam'], cloud['ssa'], '-', color=color4, label='r= 2 $\mu$m, n$_i$= 1e-8')

ax[0].set_ylabel('SSA', size=15)
ax[0].set_xlabel('Wavelength (µm)', size=15)
ax[0].set_xlim([0.6,0.8])

ax[0].legend(fontsize=12)
    
ax[1].plot(haze_strato['lam'], haze_strato['asym'], '-', color=color1)
ax[1].plot(haze_chromo['lam'], haze_chromo['asym'], ':', lw=3, color=color2)
ax[1].plot(haze_tropo['lam'], haze_tropo['asym'], '-', lw=6, color=color3)
ax[1].plot(haze_tropo['lam'], haze_tropo_v6['asym'], '--', lw=3, color=color5)
ax[1].plot(cloud['lam'], cloud['asym'], '-', color=color4)

ax[1].set_ylabel('Asymmetry parameter', size=15)
ax[1].set_xlabel('Wavelength (µm)', size=15)
ax[1].set_xlim([0.6,0.8])

ax[2].plot(haze_strato['lam'], haze_strato['sigma'], '-', color=color1)
ax[2].plot(haze_chromo['lam'], haze_chromo['sigma'], ':', lw=3, color=color2)
ax[2].plot(haze_tropo['lam'], haze_tropo['sigma'], '-', lw=6, color=color3)
ax[2].plot(haze_tropo['lam'], haze_tropo_v6['sigma'], '--', lw=3, color=color5)
ax[2].plot(cloud['lam'], cloud['sigma'], '-', color=color4)

ax[2].set_ylabel('Extinction cross-section (µm$^2$)', size=15)
ax[2].set_xlabel('Wavelength (µm)', size=15)
ax[2].set_xlim([0.6,0.8])
ax[2].set_yscale("log")

ax[3].plot(haze_strato['R'], haze_strato['nR'], '-', color=color1)
ax[3].plot(haze_chromo['R'], haze_chromo['nR'], ':', lw=3, color=color2)
ax[3].plot(haze_tropo['R'], haze_tropo['nR'], '-', lw=6, color=color3)
ax[3].plot(haze_tropo['R'], haze_tropo_v6['nR'], '--', lw=3, color=color5)
ax[3].plot(cloud['R'], cloud['nR'], '-', color=color4)

ax[3].set_ylabel('Size distribution', size=15)
ax[3].set_xlabel('Radius (µm)', size=15)
ax[3].set_xlim([1e-2,50])
ax[3].set_xscale("log")

ax[4].plot(haze_strato['R'], haze_strato['nR'], '-', color=color1)
ax[4].plot(haze_chromo['R'], haze_chromo['nR'], ':', lw=3, color=color2)
ax[4].plot(haze_tropo['R'], haze_tropo['nR'], '-', lw=6, color=color3)
ax[4].plot(haze_tropo['R'], haze_tropo_v6['nR'], '--', lw=3, color=color5)
ax[4].plot(cloud['R'], cloud['nR'], '-', color=color4)

ax[4].set_ylabel('Size distribution', size=15)
ax[4].set_xlabel('Radius (µm)', size=15)
ax[4].set_xlim([1e-4,50])
ax[4].set_ylim([1e-20,1])
ax[4].set_xscale("log")
ax[4].set_yscale("log")


plt.subplots_adjust(bottom=0.2,left=0.05,right=0.95)

plt.savefig('test_scattering.py_20221016a.pdf')
plt.savefig('test_scattering.py_20221016a.png')
# sigma is the extinction cross section in square microns
1 extra bytes in post.stringData array
'created' timestamp seems very low; regarding as unix timestamp
Zapf NOT subset; don't know how to subset; dropped
feat NOT subset; don't know how to subset; dropped
meta NOT subset; don't know how to subset; dropped
morx NOT subset; don't know how to subset; dropped
In [16]:
# size parameter for 631 nm:
#    2 π r / (lambda / n_r)

lams = np.array([0.631, 0.7, 0.727, 0.75])

print(2. * 1.4 * 0.5 * np.pi / lams)


# size parameter is 28-23 for 2 µm
#                   14-12 for 1 µm
#                   7-6 for 0.5 µm
#                   2.8-2.3 for 0.2 µm
[6.97025311 6.28318531 6.04983455 5.86430629]
In [22]:
print(2.00000000e+01 / 1.99331107e+01)
1.0033556879810033
In [ ]: