Upper cloud base dependence on temperature¶

Use previous model runs, make 2D scatter plots: NH3 and NH4SH cloud bases for each run, as a function of temperature. Two diagonal swarms of dots. Maybe add a H2O swarm for 2.7x solar case.

Parse the cldden.X files to get cloud bases¶

Read in all data.

Read cloud base location by searching "cldrate" (not "mixrat") files for the first nonzero value of NH4SH-ice, NH3-ice, get the corresponding pressure level. (Keep the mixrat approach for water because it covers both ice and solution.)

In [24]:
import os
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np

# copy some plot commands from freshclouds_simon22.ipynb
plt.rcParams['font.family'] = 'sans-serif'
plt.rcParams['font.sans-serif'] = ['Helvetica', 'Roboto', 'Verdana', 'Arial']
plt.rcParams['pdf.fonttype'] = 42


# setup the big arrays for storing results
#
ENRH2O_seq = (np.arange(0.158, 4.69, 0.22))**2 # no, this is matrix/... see inputp_generator.py
ENRH2O_seq = (np.arange(0.1, 4.75, 0.22))**2 # yes... see inputp_generator_v2.py

T500_seq = np.arange(128.,143.)
Gamma_seq = np.arange(0.9,1.001,0.1)
    
n_ENRH2O = len(ENRH2O_seq)
n_T500 = len(T500_seq)
n_Gamma = len(Gamma_seq)

P_H2O = np.zeros((n_T500, n_ENRH2O, n_Gamma))
P_NH3 = np.zeros((n_T500, n_ENRH2O, n_Gamma))
P_NH4SH = np.zeros((n_T500, n_ENRH2O, n_Gamma))
T_5 = np.zeros((n_T500, n_ENRH2O, n_Gamma))
T_500 = np.zeros((n_T500, n_ENRH2O, n_Gamma)) # a silly but convenient array to have


# big matrix to get P-values for every 10 km from 1 bar level, span +30 to -60 first, in attempt to 
#     cover 0.5 bar to 4 bar
#
zgrid = list(range(15,-50,-5)) # last one is not included
n_zsave = len(zgrid)
P_zgrid = np.zeros((n_T500, n_ENRH2O, n_Gamma, n_zsave))



# loop stuff just like in inputp_generator.py
#
for T500 in T500_seq:
    for ENRH2O in ENRH2O_seq:
        for Gamma_factor in Gamma_seq:

            # generate run-ID code / filename suffix from parameter values
            #
            T_code = 'T{:03d}'.format(int(T500))
            E_code = 'E{:02d}p{:02d}'.format(int(ENRH2O), int(round(100 * (ENRH2O - np.fix(ENRH2O)))))
            G_code = 'G{:03d}'.format(int(100 * Gamma_factor))

            suffix = "{:s}_{:s}_{:s}".format(T_code,E_code,G_code)
            filename = "matrix_v2/mixrat.{:s}".format(suffix)
            cratname = "matrix_v2/cldrate.{:s}".format(suffix)
            
            # load pressure, temperature, delta-H2O
            #
            if os.path.exists(filename):
                tph2o = np.loadtxt(filename, skiprows=7, usecols=(1,2,4))
                tpupper = np.loadtxt(cratname, skiprows=7, usecols=(0,1,2,3,4,5,6))
            
            # get the condensation levels
            #
                LCL = tph2o[((np.nonzero(tph2o[:,2]))[0])[0], 1]
                LCL_nh3 = tph2o[((np.nonzero(tpupper[:,6]))[0])[0], 1]
                LCL_nh4sh = tph2o[((np.nonzero(tpupper[:,5]))[0])[0], 1]

            # interpolate to find the temperature at 5 bars
            #
                T5 = np.interp(5., np.flip(tph2o[:,1]), np.flip(tph2o[:,0]))

            # rescale to z=0 at 1 bar, get P at each zgrid point
            #
                delta_z = np.interp(1., np.flip(tpupper[:,2]), np.flip(tpupper[:,0]))
                z_1bar = tpupper[:,0] - delta_z
                
                pticks = np.interp(zgrid, z_1bar, tpupper[:,2])
            
            # store in the big arrays.
            # get indices in a way safe for floating point errors
            #
                i_T500 = np.argmin(abs(T500_seq - T500))
                i_ENRH2O = np.argmin(abs(ENRH2O_seq - ENRH2O))
                i_Gamma = np.argmin(abs(Gamma_seq - Gamma_factor))
            
                P_H2O[i_T500,i_ENRH2O, i_Gamma] = LCL
                P_NH3[i_T500,i_ENRH2O, i_Gamma] = LCL_nh3
                P_NH4SH[i_T500,i_ENRH2O, i_Gamma] = LCL_nh4sh
                T_5[i_T500,i_ENRH2O, i_Gamma] = T5
                T_500[i_T500,i_ENRH2O, i_Gamma] = T500
                
                P_zgrid[i_T500,i_ENRH2O, i_Gamma, :] = pticks

           
print(np.sum(P_H2O)) 
6218.282799999999
In [27]:
# examine stats of the new P_zgrid data

patz_mean = np.zeros(n_zsave)
patz_std = np.zeros(n_zsave)
patz_min = np.zeros(n_zsave)
patz_max = np.zeros(n_zsave)


for i in range(n_zsave):
    pslice = P_zgrid[:,:,:,i].flatten()
    patz_mean[i] = np.mean(pslice)
    patz_std[i] = np.std(pslice)
    patz_min[i] = np.min(pslice)
    patz_max[i] = np.max(pslice)

    print('{:2}   {:2}   {:1.2} ±{:1.2}   {:1.2}  {:1.2}'.format(i, 
          zgrid[i], patz_mean[i],patz_std[i],patz_min[i],patz_max[i]))
 0   15   0.53 ±0.012   0.51  0.56
 1   10   0.67 ±0.0094   0.65  0.68
 2    5   0.82 ±0.0055   0.81  0.83
 3    0   1.0 ±3.2e-16   1.0  1.0
 4   -5   1.2 ±0.0074   1.2  1.2
 5   -10   1.4 ±0.017   1.4  1.5
 6   -15   1.7 ±0.029   1.6  1.8
 7   -20   2.0 ±0.044   1.9  2.1
 8   -25   2.3 ±0.061   2.2  2.4
 9   -30   2.7 ±0.083   2.5  2.8
10   -35   3.1 ±0.11   2.9  3.3
11   -40   3.5 ±0.14   3.3  3.8
12   -45   4.0 ±0.17   3.7  4.3
  • (For z-step = 10 km:) Only z in [+10, -40] fit on the plot... re-do range 15 to -45 with stepsize 5
  • Below, just plot some lines that we will assemble by hand into boxplots in Illustrator
In [29]:
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from matplotlib import ticker
from matplotlib import colors
import os




# setup plot
#
fig,axs=plt.subplots(1,1,figsize=(10, 4.5))
fullcolor = cm.get_cmap('jet')


# plot data
#
axs.plot(P_NH3[:,:,0], T_500[:,:,0], '-', color=fullcolor(185))
axs.plot(P_NH3[:,:,1], T_500[:,:,1], '-', color=fullcolor(185))

axs.plot(P_NH4SH[:,:,0], T_500[:,:,0], '-', color=fullcolor(20))
axs.plot(P_NH4SH[:,:,1], T_500[:,:,1], '-', color=fullcolor(20))



# plot stuff to make custom z-ticks in illustrator later
#
for i in range(n_zsave):
    axs.plot((patz_mean[i], patz_mean[i]), (140,141), '-', color=fullcolor(210))
    axs.plot((patz_mean[i]-patz_std[i], patz_mean[i]+patz_std[i]), (139,139), '-', color=fullcolor(210))
    axs.plot((patz_min[i], patz_max[i]), (138,138), '-', color=fullcolor(210))




# plot formatting
#
axs.set_xlim(0.5, 4.0)
axs.set_xscale('log')
axs.set_ylim(128,142)
axs.set_ylabel('T at 500 mbar (K)')
axs.set_xlabel('Cloud base level (bar)')

axs.tick_params(axis='both', which='major', size=6, top=True, bottom=True, left=True, right=True)
axs.tick_params(axis='both', which='minor', size=3, top=True, bottom=True, left=True, right=True)


plt.savefig('upperclouds_z_orig.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
In [9]:
zgrid = list(range(-60,40,10))
print(len(zgrid))
10
In [ ]: