📚 The CoCalc Library - books, templates and other resources
License: OTHER
1# coding: utf-823# # Analysis of leaf chamber experiments4# This worksheet produces figures for:5#6# **Leaf-scale experiments reveal important omission in the Penman-Monteith equation**7#8# Schymanski, S.J. and D. Or9#10# http://www.hydrol-earth-syst-sci-discuss.net/hess-2016-363/11#12# Author: Stan Schymanski ([email protected])1314# ## Worksheet setup and importing equations and functions from other worksheets1516# In[1]:1718get_ipython().run_cell_magic(u'capture', u'storage', u"# The above redirects all output of the below commands to the variable 'storage' instead of displaying it.\n# It can be viewed by typing: 'storage()'\n\n# Setup of worksheet, incl. importing of packages and defining general custom functions\nload('temp/Worksheet_setup.sage')\nfrom shutil import copyfile # for copying files between directories\nfrom matplotlib.ticker import MaxNLocator\nimport csv\nimport datetime\nimport time\nimport matplotlib.pyplot as plt\nimport matplotlib.dates as mdates")192021# In[2]:2223# From leaf_chamber_eqs, Leaf_enbalance2s_eqs and E_PM_eqs24load_session('temp/leaf_enbalance_eqs.sobj')25dict_vars1 = dict_vars.copy()2627load_session('temp/E_PM_eqs.sobj')28dict_vars1.update(dict_vars)2930load_session('temp/leaf_chamber_eqs.sobj')31dict_vars1.update(dict_vars)3233dict_vars = dict_vars1.copy()34fun_loadvars(vardict=dict_vars) # re-loading variable definitions353637# In[3]:3839path_figs = 'figures/'40path_data = 'data/'41path_data_orig = '/home/sschyman/Documents/STEP/Lab_data/leaf_chamber/'424344# ## Functions to compute steady-state leaf energy balance components4546# In[4]:4748def fun_SS(vdict1):49'''50Steady-state T_l, R_ll, H_l and E_l under forced conditions.51Parameters are given in a dictionary (vdict) with the following entries:52a_s, a_sh, L_l, P_a, P_wa, R_s, Re_c, T_a, g_sw, v_w53'''54vdict = vdict1.copy()55if not T_w in vdict1.keys():56vdict[T_w] = vdict[T_a]575859# Nusselt number60vdict[nu_a] = eq_nua.rhs().subs(vdict)61vdict[Re] = eq_Re.rhs().subs(vdict)62vdict[Nu] = eq_Nu_forced_all.rhs().subs(vdict)6364# h_c65vdict[k_a] = eq_ka.rhs().subs(vdict)66vdict[h_c] = eq_hc.rhs().subs(vdict)6768# gbw69vdict[D_va] = eq_Dva.rhs().subs(vdict)70vdict[alpha_a] = eq_alphaa.rhs().subs(vdict)71vdict[rho_a] = eq_rhoa.rhs().subs(vdict)72vdict[Le] = eq_Le.rhs().subs(vdict)73vdict[g_bw] = eq_gbw_hc.rhs().subs(vdict)7475# Hl, Rll76vdict[R_ll] = eq_Rll.rhs().subs(vdict)77vdict[H_l] = eq_Hl.rhs().subs(vdict)7879# El80vdict[g_tw] = eq_gtw.rhs().subs(vdict)81vdict[C_wa] = eq_Cwl.rhs()(P_wl = P_wa, T_l = T_a).subs(vdict)82vdict[P_wl] = eq_Pwl.rhs().subs(vdict)83vdict[C_wl] = eq_Cwl.rhs().subs(vdict)84vdict[E_lmol] = eq_Elmol.rhs().subs(vdict)85vdict[E_l] = eq_El.rhs().subs(eq_Elmol).subs(vdict)8687# Tl88try: vdict[T_l] = find_root((eq_Rs_enbal - R_s).rhs().subs(vdict), 273, 373)89except: print 'something missing: ' + str((eq_Rs_enbal - R_s).rhs().subs(vdict))9091# Re-inserting T_l92Tlss = vdict[T_l]93for name1 in [C_wl, P_wl, R_ll, H_l, E_l, E_lmol]:94vdict[name1] = vdict[name1].subs(T_l = Tlss)9596# Test for steady state97if n((E_l + H_l + R_ll - R_s).subs(vdict))>1.:98return 'error in energy balance: El + Hl + Rll - R_s = ' + str(n((E_l + H_l + R_ll - R_s).subs(vdict)))99return vdict100101102# In[5]:103104# Test using data from Fig. 8 in Ball et al. 1988105vdict = cdict.copy()106vdict[a_s] = 1107vdict[L_l] = 0.07108vdict[P_a] = 101325109vdict[P_wa] = 20/1000*101325110vdict[R_s] = 400111vdict[Re_c] = 3000112vdict[T_a] = 273+30113vdict[T_w] = vdict[T_a]114vdict[g_sw] = 0.15/40115vdict[v_w] = 1.116resdict = fun_SS(vdict)117118dict_print(resdict, list_names = [H_l, E_l, T_l])119120121# ### Model by Ball et al., 1988122123# In[6]:124125# for model by Ball et al. 1988126var2('g_svmol', 'Stomatal condutance to vapour in molar units', mole/meter^2/second)127var2('c_pmol', 'Molar heat capacity of air', value = 29.2, units = joule/mole/kelvin) # Units in the appendix are wrongly given as J mol/K128var2('L_E', 'Latent heat of vaporisation of water', value = 44000, units = joule/mole)129var2('r_bstar', 'Boundary layer resistance to heat transfer from unit area of leaf', meter^2*second/mole)130var2('r_b', 'Boundary layer resistnace to vapour transfer', meter^2*second/mole)131var2('r_s', 'Stomatal resistance to vapour transfer', meter^2*second/mole)132133eq_Hl_Ball = H_l == c_pmol*(T_l - T_a)/r_bstar134eq_El_Ball = E_l == L_E*(P_wl - P_wa)/P_a/(r_s + r_b)135eq_rbstar = r_bstar == (3.8*L_A^(1/4)*v_w^(-1/2))136eq_rb = r_b == (1.78/a_s*r_bstar)137print units_check(eq_Hl_Ball).simplify_full()138print units_check(eq_El_Ball).simplify_full()139140141# In[7]:142143def fun_SS_Ball(vdict1):144'''145Steady-state T_l, h_c, g_bv, g_tv, R_ll, H_l and E_l under forced conditions.146h_c and g_bv are calculated using Appendix in Ball et al. (1988).147see Ball_1988_Maintenance_of_Leaf2.pdf148Parameters are given in a dictionary (vdict) with the following entries:149a_s, L_l, P_a, P_wa, R_s, Re_c, T_a, g_svmol, v_w150'''151vdict = vdict1.copy()152if not L_A in vdict.keys():153vdict[L_A] = (pi()*L_l^2).subs(vdict)154if not T_w in vdict.keys():155vdict[T_w] = vdict[T_a]156157vdict[r_s] = (1/(40*g_sw)).subs(vdict)158try:159vdict[r_bstar] = eq_rbstar.rhs().subs(vdict).n() #two-sided resistance for sensible heat flux160except:161vdict[r_bstar] = eq_rbstar.rhs().subs(vdict)162print 'r_bstar = ' + str(vdict[r_bstar])163vdict[r_b] = eq_rb.rhs().subs(vdict) # one-sided resistance to latent heat flux164165166167Rll = eq_Rll.rhs().subs(vdict)168Hl = eq_Hl_Ball.rhs().subs(vdict)169El = eq_El_Ball.rhs().subs(eq_Pwl).subs(vdict)170171enbal = El + Hl + Rll - R_s == 0172#print enbal(R_ll = Rll, H_l = Hl, E_l = El).subs(vdict)173Tss = find_root(enbal(R_ll = Rll, H_l = Hl, E_l = El).subs(vdict), 273, 373)174175Rll1 = Rll(T_l = Tss)176Hl1= Hl(T_l = Tss)177El1 = El(T_l = Tss)178179# Test for steady state180if (El1 + Hl1 + Rll1 - vdict[R_s])>1.:181print (El, Hl, Rll, vdict[R_s])182print Tss183return 'error in energy balance'184Pwl = eq_Pwl.rhs()(T_l = Tss).subs(vdict)185186#dict_print(vdict)187return {'Tl_ball':n(Tss), 'Rll_ball':n(Rll1), 'Hl_ball':n(Hl1), 'El_ball':n(El1), 'rs_ball': vdict[r_s], 'rbstar_ball': vdict[r_bstar], 'rb_ball': vdict[r_b]}188189190# In[8]:191192# Fig. 8 in Ball et al. 1988193vdict = cdict.copy()194vdict[a_s] = 1195vdict[L_l] = 0.07196vdict[P_a] = 101325197vdict[P_wa] = 20/1000*101325198vdict[R_s] = 400199vdict[Re_c] = 3000200vdict[T_a] = 273+30201vdict[T_w] = vdict[T_a]202vdict[g_sw] = 0.15/40203204vdict[v_w] = 1.205ssdict = fun_SS(vdict)206#print ssdict207balldict = fun_SS_Ball(vdict)208#print balldict209print 'h_c(Ball): ' + str((c_pmol/balldict['rbstar_ball']).subs(vdict))210print 'g_vmol(Ball): ' + str((1/(r_b + r_s))(r_b = balldict['rb_ball'], r_s = balldict['rs_ball']))211print 'g_vmol(SS): ' + str(eq_gtwmol_gtw(T_l = T_a).subs(eq_gtw).subs(ssdict).subs(vdict))212print 'T_l(Ball): ' + str(balldict['Tl_ball'])213print 'T_l(SS): ' + str(ssdict[T_l])214print 'T_a: ' + str(vdict[T_a])215216217# <p><span style="color: #ff0000;">According to Fig. 8 in Ball et al., 1988, steady-state leaf temperature should be higher by 10 K than air temperature! Here it is only 6. <br /></span></p>218219# ### Analytical models220221# In[9]:222223def fun_SS_PM(vdict1):224'''225Analytical equations from Worksheet E_PM_eqs, including detailed steady-state.226'''227vdict = vdict1.copy()228if not L_A in vdict1.keys():229vdict[L_A] = (pi()*L_l^2).subs(vdict1)230if not T_w in vdict1.keys():231vdict[T_w] = vdict[T_a]232if not P_wa in vdict1.keys():233print 'P_wa is missing'234ss = fun_SS(vdict)235236vdict[P_was] = eq_Pwl.rhs()(T_l = T_a).subs(vdict)237vdict[Delta_eTa] = eq_Deltaeta_T.rhs().subs(vdict)238vdict[k_a] = eq_ka.rhs().subs(vdict)239vdict[nu_a] = eq_nua.rhs().subs(vdict)240vdict[Re] = eq_Re.rhs().subs(vdict)241vdict[Nu] = eq_Nu_forced_all.rhs().subs(vdict)242vdict[h_c] = eq_hc.rhs().subs(vdict)243244vdict[P_N2] = eq_PN2.rhs().subs(vdict)245vdict[P_O2] = eq_PO2.rhs().subs(vdict)246vdict[alpha_a] = eq_alphaa.rhs().subs(vdict)247vdict[k_a] = eq_ka.rhs().subs(vdict)248vdict[D_va] = eq_Dva.rhs().subs(vdict)249vdict[Le] = eq_Le.rhs().subs(vdict)250vdict[rho_a] = eq_rhoa_Pwa_Ta.rhs().subs(vdict)251vdict[g_bw] = eq_gbw_hc.rhs().subs(vdict)252vdict[g_tw] = eq_gtw.rhs().subs(vdict)253vdict[g_twmol] = eq_gtwmol_gtw_iso.rhs().subs(vdict)254255# Generalized Penman, getting Rll first256vdict_GPRll = vdict.copy()257vdict_GPRll[R_ll] = 0.258vdict_GPRll[T_l] = eq_Tl_Delta.rhs().subs(eq_ce_conv, eq_ch_hc).subs(vdict_GPRll)259vdict_GPRll[R_ll] = eq_Rll.rhs().subs(vdict_GPRll)260vdict_GPRll[E_l] = eq_El_Delta.rhs().subs(eq_ce_conv, eq_ch_hc).subs(vdict_GPRll)261vdict_GPRll[H_l] = eq_Hl_Delta.rhs().subs(eq_ce_conv, eq_ch_hc).subs(vdict_GPRll)262263264# Using linearised R_ll solution265vdict_lin = vdict.copy()266namesdict = [E_l, H_l, T_l, R_ll]267vdict_lin[E_l] = eq_El_Delta_Rlllin.rhs().subs(eq_ce_conv, eq_ch_hc).subs(vdict_lin)268vdict_lin[H_l] = eq_Hl_Delta_Rlllin.rhs().subs(eq_ce_conv, eq_ch_hc).subs(vdict_lin)269vdict_lin[T_l] = eq_Tl_Delta_Rlllin.rhs().subs(eq_ce_conv, eq_ch_hc).subs(vdict_lin)270vdict_lin[R_ll] = eq_Rll_tang.rhs().subs(vdict_lin)271272273# 'R_N = R_s:' MU-book, P. 79, under cloudy skies, implying that R_ll = 0274vdict2 = vdict.copy()275vdict2[R_ll] = 0276277# Generalized Penman278vdict_GP = vdict2.copy()279vdict_GP[E_l] = eq_El_Delta.rhs().subs(eq_ce_conv, eq_ch_hc).subs(vdict_GP)280vdict_GP[H_l] = eq_Hl_Delta.rhs().subs(eq_ce_conv, eq_ch_hc).subs(vdict_GP)281vdict_GP[T_l] = eq_Tl_Delta.rhs().subs(eq_ce_conv, eq_ch_hc).subs(vdict_GP)282283284# Penman-stomata285vdict_PS = vdict2.copy()286vdict_PS[S] = eq_S_gbw_gsw.rhs().subs(vdict_PS)287vdict_PS[f_u] = eq_fu_gbw.rhs().subs(vdict_PS)288vdict_PS[gamma_v] = eq_gammav_as.rhs().subs(vdict_PS)289vdict_PS[E_l] = eq_El_P52.rhs().subs(vdict_PS)290vdict_PS[H_l] = eq_Hl_P52.rhs().subs(vdict_PS)291vdict_PS[T_l] = eq_Tl_P52.rhs().subs(vdict_PS)292293# PM equation294vdict_PM = vdict2.copy()295vdict_PM[r_s] = 1/vdict_PM[g_sw]296vdict_PM[r_a] = eq_ra_hc.rhs().subs(vdict_PM)297vdict_PM[gamma_v] = eq_gammav_MU.rhs().subs(vdict_PM)298vdict_PM[epsilon] = eq_epsilon.rhs().subs(vdict_PM)299vdict_PM[E_l] = eq_El_PM2.rhs().subs(vdict_PM)300vdict_PM[H_l] = (R_s - R_ll - E_l).subs(vdict_PM)301302# MU equation303vdict_MU = vdict2.copy()304vdict_MU[n_MU] = (a_sh/a_s).subs(vdict_MU)305vdict_MU[r_s] = 1/vdict_MU[g_sw]306vdict_MU[r_a] = eq_ra_hc.rhs().subs(vdict_MU)307vdict_MU[gamma_v] = eq_gammav_MU.rhs().subs(vdict_MU)308vdict_MU[E_l] = eq_El_MU2.rhs().subs(vdict_MU)309vdict_MU[H_l] = (R_s - R_ll - E_l).subs(vdict_MU)310311# 'Corrected MU-equation: '312vdict_MUc = vdict2.copy()313vdict_MUc[r_s] = 1/vdict_MUc[g_sw]314vdict_MUc[r_a] = eq_ra_hc.rhs().subs(vdict_MUc)315vdict_MUc[gamma_v] = eq_gammav_MU.rhs().subs(vdict_MUc)316vdict_MUc[E_l] = eq_El_MU_corr.rhs().subs(vdict_MUc)317vdict_MUc[H_l] = (R_s - R_ll - E_l).subs(vdict_MUc)318319resdict = ss.copy()320str1 = 'GPRll'321namesdict = [E_l, H_l, T_l, R_ll]322for name1 in namesdict:323resdict[str1+'_'+str(name1)] = eval('vdict_'+str1)[name1]324325str1 = 'lin'326namesdict = [E_l, H_l, T_l, R_ll]327for name1 in namesdict:328resdict[str1+'_'+str(name1)] = eval('vdict_'+str1)[name1]329330str1 = 'GP'331namesdict = [E_l, H_l, T_l]332for name1 in namesdict:333resdict[str1+'_'+str(name1)] = eval('vdict_'+str1)[name1]334335str1 = 'PS'336namesdict = [E_l, H_l, T_l]337for name1 in namesdict:338resdict[str1+'_'+str(name1)] = eval('vdict_'+str1)[name1]339340str1 = 'PM'341namesdict = [E_l, H_l]342for name1 in namesdict:343resdict[str1+'_'+str(name1)] = eval('vdict_'+str1)[name1]344345str1 = 'MU'346namesdict = [E_l, H_l]347for name1 in namesdict:348resdict[str1+'_'+str(name1)] = eval('vdict_'+str1)[name1]349350str1 = 'MUc'351namesdict = [E_l, H_l]352for name1 in namesdict:353resdict[str1+'_'+str(name1)] = eval('vdict_'+str1)[name1]354355return resdict356357358# # Data reading, computing and display functions359360# ## Functions to read data361362# In[10]:363364def fun_read_csv(fname1, lc_datetime_format = "%Y-%m-%d %H:%M:%S", lc_timepos = [], split1 = ';'):365'''366Reads file written by leaf_chamber_read_data and saves them as lc_data367If csv file fname1 does not exist in path_data, copies the file from path_data_orig to path_data368before opening and reading into numpy array. Contents of data file are printed as table before returning numpy array.369'''370lc_timepos = lc_timepos[:]371fname = path_data + fname1372try:373reader = csv.reader(open(fname, 'r'), delimiter=split1, quotechar='"')374except:375copyfile(path_data_orig + fname1, fname)376reader = csv.reader(open(fname, 'r'), delimiter=split1, quotechar='"')377htmldata = []378lc_nameslist = reader.next()379htmldata.append(lc_nameslist)380htmldata[-1][-1] = htmldata[-1][-1]+ '...................................................' # To avoid very thick rows381#print htmldata382lc_formatslist = ['S200' for i in srange(len(lc_nameslist))]383lc_unitslist = reader.next()384htmldata.append(lc_unitslist)385#print lc_unitslist386#print reader.next()387ncols = len(lc_nameslist)388lc_datetime_format = "%Y-%m-%d %H:%M:%S"389csvdata = []390with open(fname, 'r') as file_out:391rows = file_out.readlines()392393# Determining dtypes394for row in rows[2:]:395row1 = row.strip('\r\n').split(split1)396for i in srange(len(row1)-1):397try:398blah = float(row1[i])399lc_formatslist[i] = 'float'400except:401try:402blah = datetime.datetime.fromtimestamp(time.mktime(time.strptime(row1[i].strip(), lc_datetime_format)))403lc_timepos.append(i)404lc_formatslist[i] = 'datetime64[us]'405except:406lc_formatslist[i] = 'S200'407408lc_timepos = list(set(lc_timepos)) # to get unique values, i.e. drop repeated positions409410for row in rows[2:]:411row1 = row.strip('\r\n').split(split1)412htmldata.append(row1[:])413for i in lc_timepos:414try:415row1[i] = datetime.datetime.fromtimestamp(time.mktime(time.strptime(row1[i].strip(), lc_datetime_format)))416except Exception, e:417print "failed because: %s" % e418print lc_timepos419print row1420return421row2 = tuple(row1)422csvdata.append(row2)423424425try:426lc_data = np.array(csvdata,dtype = zip(lc_nameslist,lc_formatslist))427except:428print 'Error in dtype'429return csvdata430pretty_print(table(htmldata, header_row=True, align='center'))431return lc_data432433434# In[11]:435436def fun_read_campbell(fname1, nr_datetime_format = "%Y-%m-%d %H:%M:%S.%f", datelen = 21, datelast = '.0'):437'''438Reads Campbell data logger file and returns numpy array.439If file fname1 does not exist in path_data, copies the file from path_data_orig to path_data440before opening.441'''442import sys, traceback443fname = path_data + fname1444try:445reader = csv.reader(open(fname, 'rb'), delimiter=',', quotechar='"')446except:447copyfile(path_data_orig + fname1, fname)448reader = csv.reader(open(fname, 'rb'), delimiter=',', quotechar='"')449450print reader.next()451nr_nameslist = reader.next()452print nr_nameslist453nr_unitslist = reader.next()454#print nr_unitslist455reader.next()456ncols = len(nr_nameslist)457458csvdata = []459contd = True460while contd:461try:462row1 = reader.next()463date1 = row1[0]464# Need to add milliseconds if missing465if len(date1) < datelen: date1 = date1+datelast466row1[0] = datetime.datetime.fromtimestamp(time.mktime(time.strptime(date1.strip(), nr_datetime_format)))467row2 = tuple(row1)468csvdata.append(row2)469except StopIteration:470contd = False471except:472traceback.print_exc(file=sys.stdout)473print row1474#contd = False475476#print csvdata477nr_formatslist = ['datetime64[us]', 'int']478for i in srange(len(nr_nameslist) - 2):479nr_formatslist.append('float')480nr_data = np.array(csvdata,dtype = zip(nr_nameslist,nr_formatslist))481return nr_data482483484# In[12]:485486def fun_read_li(li_fname, prefix1 = ['1900-01-01_']):487'''488Reads Licor data file and returns as numpy array. If data contains several days, add a prefix for each day.489If file li_fname does not exist in path_data, copies the file from path_data_orig to path_data490before opening.491'''492time_format = "%H:%M:%S"493datetime_format = "%Y-%m-%d %H:%M:%S"494fname = path_data + li_fname495try:496reader = csv.reader(open(fname, 'rb'), delimiter='\t')497except:498copyfile(path_data_orig + li_fname, fname)499reader = csv.reader(open(fname, 'rb'), delimiter='\t')500501502row = ['']503csvdata = []504outdata = []505nameflag = 'n'506dataflag = 'n'507prefpos = 0508timeold = 0509for row in reader:510#print row511if dataflag == 'n':512if row[0][0]!='<':513print row514if row == ['$STARTOFDATA$']:515print ' '516print 'NEW data set'517print 'length previous = '+str(len(csvdata))518if len(csvdata)>1: # Converting csvdata to np.array and adding to outdata519li_formatslist = ['int','datetime64[us]']520for i in srange(len(li_nameslist) - 3):521li_formatslist.append('float')522li_formatslist.append('str')523li_data = np.array(csvdata,dtype = zip(li_nameslist,li_formatslist))524outdata.append(li_data)525526# Starting new data series527csvdata = []528nameflag = 'y'529530531if len(row)>1:532if nameflag == 'y':533li_nameslist = row534nameflag = 'n'535dataflag = 'y'536elif dataflag == 'y':537row1 = row[:]538prefix = prefix1[prefpos]539TS = prefix[0:10] + " " + row[1].strip()540try:541row1[1] = datetime.datetime.fromtimestamp(time.mktime(time.strptime(TS, datetime_format)))542if timeold!=0:543if row1[1]<timeold: # increment to next date if new time smaller old time544prefpos = prefpos + 1545TS = prefix[0:10] + " " + row[1].strip()546row1[1] = datetime.datetime.fromtimestamp(time.mktime(time.strptime(TS, datetime_format)))547timeold = row1[1]548row3 = tuple(row1)549csvdata.append(row3)550except:551print 'failed'552elif dataflag == 'y':553print row554555556li_formatslist = ['int','datetime64[us]']557for i in srange(len(li_nameslist) - 3):558li_formatslist.append('float')559li_formatslist.append('str')560li_data = np.array(csvdata,dtype = zip(li_nameslist,li_formatslist))561outdata.append(li_data)562print 'number of data sets: '+str(len(outdata))563return outdata564565566# ## Equations to infer conductances from flux measurements567568# In[13]:569570eq_gsw_gtw = solve(eq_gtw, g_sw)[0]571units_check(eq_gsw_gtw).simplify_full()572573574# In[14]:575576eq_gtw_Elmol = solve(eq_Elmol.subs(eq_Cwa, eq_Cwl), g_tw)[0]577units_check(eq_gtw_Elmol)578579580# In[15]:581582eq_hc_Hl = solve(eq_Hl, h_c)[0]583units_check(eq_hc_Hl)584585586# ## Functions to automate computation of derived results and plotting587588# In[16]:589590def fun_results(lc_data, vdict1 = {}, poslist = [], nameRs = '', ndict1 = {}, Pwinoffset = 0, Tdewfac = 1.06, Tdewoffset = -2.45):591'''592Simulates steady-state conditions for every data set contained in lc_data593and returns a numpy array with input data and results. Mapping of fields in lc_data594is given in ndict, e.g.595ndict = {R_s: '', T_d: 'T_dew', T_l: 'T_leaf_in', Q_in: 'fan_power_avg', S_a: 'Rn_above_leaf', S_b: 'Rn_below_leaf', S_s: 'Rn_beside_leaf', T_in: 'T_in1', F_in_v: 'Air_inflow', v_w: 'Wind', T_a: 'T_chamber', E_lmol: 'water_flow_avg'}596If vdict1 is not given or values are missing, predefined values are assumed. Pwinoffset allows accounting for bias in Cellkraft P_w_in by negative 50 to negative 200 Pa, see LI6400_data_repaired2.sws.597Usage:598sage: fun_results(lc_data, vdict1 = {}, poslist = [1,2,4])599'''600601poslist = poslist[:]602def fun_subs(expr, vdict):603'''604Substitutes vdict in equation and returns result.605In case of a ValueError, e.g. because an entry is NaN,606returns NaN, rather than interrupting because of exception.607'''608try:609return float(expr.subs(vdict))610except:611#print expr.subs(vdict)612return float('NaN')613614615ndict = {R_s: '', T_d: 'T_dew', T_l: 'T_leaf_in', Q_in: 'fan_power_avg', S_a: 'Rn_above_leaf', S_b: 'Rn_below_leaf', S_s: 'Rn_beside_leaf', T_in: 'T_in1', F_in_v: 'Air_inflow', v_w: 'Wind', T_a: 'T_chamber', E_lmol: 'water_flow_avg'}616if len(ndict1)>0:617ndict = fun_dict(ndict,ndict1)618# Standard values619vdict = cdict.copy()620vdict[L_l] = 0.03 # 3x3 cm area621vdict[a_s] = 1 # one sided stomata622vdict[alpha_l] = 0 # assuming 0 albedo623vdict[g_sw] = 999 # unlimiting, filter paper only624vdict[P_a] = 101325625vdict[Re_c] = 3000626vdict[R_s] = 0627vdict[T_r] = vdict[T0]628vdict[P_a] = 101325629if len(vdict1)>0:630vdict = fun_dict(vdict,vdict1)631if L_A not in vdict.keys():632vdict[L_A] = vdict[L_l]^2633if R_d in vdict.keys():634vdict[R_s] = eq_Rs_Rd.rhs().subs(vdict)635#print vdict636results = []637allinput = []638639if len(poslist) == 0:640poslist = srange(len(lc_data))641642for i in poslist:643rdict1 = {} # For storing results that are not in vdict, e.g. if keys are strings rather than variables.644645# Tdew reported by Cellkraft is biased (see worksheet Cellkraft_tests). Corrections range between y=1.09*x - 2.42 and y=1.06*x - 2.45646Tdew = Tdewfac*lc_data[ndict[T_d]][i]+Tdewoffset+vdict[T0]647if P_w_in in ndict1:648vdict[P_w_in] = lc_data[ndict[P_w_in]][i]649else:650vdict[P_w_in] = eq_Pwl.rhs().subs(T_l = Tdew).subs(vdict) + Pwinoffset651Qin = lc_data[ndict[Q_in]][i]652Tlmeas = lc_data[ndict[T_l]][i]+vdict[T0]653try:654Rn_above = lc_data[ndict[S_a]][i]655Rn_below = lc_data[ndict[S_b]][i]656#Rn_beside = abs(lc_data[ndict[S_s]][i])657Rn_leaf = eq_Rbalance.rhs()(S_a = Rn_above, S_b = Rn_below)658rdict1['Rn_leaf'] = Rn_leaf659except:660pass661if len(ndict[R_s])>0:662vdict[R_d] = abs(lc_data[ndict[R_s]][i])663vdict[R_s] = eq_Rs_Rd.rhs().subs(vdict)664#print 'R_s from ' + nameRs665666vdict[T_in] = lc_data[ndict[T_in]][i]+vdict[T0]667vdict[F_in_va_n] = lc_data[ndict[F_in_v]][i]/1000/60668vdict[F_in_v] = eq_Finv_Finva_ref.rhs().subs(vdict)669vdict[F_in_mola] = eq_Finmola_Finva_ref.rhs().subs(vdict)670vdict[F_in_molw] = eq_Finmolw_Finmola_Pwa.rhs().subs(vdict)671672#print 'F_in_v = ' + str(vdict[F_in_v])673#print vdict[P_v_in]674675vdict[v_w] = lc_data[ndict[v_w]][i]676vdict[T_a] = lc_data[ndict[T_a]][i]+ 273.15677if T_w not in vdict1.keys():678vdict[T_w] = vdict[T_a]679680Elmolmeas = lc_data[ndict[E_lmol]][i]*1e-6/60/vdict[L_A]/vdict[M_w]681Elmeas = eq_El_Elmol.rhs()(E_lmol = Elmolmeas).subs(vdict)682vdict[P_wa] = eq_Pwout_Elmol.rhs().subs(E_lmol = Elmolmeas).subs(vdict)683vdict[F_out_molw] = eq_Foutmolw_Finmolw_Elmol.rhs().subs(E_lmol = Elmolmeas).subs(vdict)684#print 'P_w_out = ' + str(vdict[P_wa])685#Hlmeas = eq_Hl_Tin_Tout.rhs().subs(E_lmol = Elmolmeas, P_a = 101325, T_out = T_a, Q_in = Qin).subs(vdict)686Hlmeas = eq_Hl_Tin_Tout_Fmol.rhs().subs(E_lmol = Elmolmeas, P_a = 101325, T_out = T_a, Q_in = Qin).subs(vdict)687688689690Balldict = fun_SS_Ball(vdict)691PMdict = fun_SS_PM(vdict)692693# Inferring g_tw and g_sw from Elmolmeas, Tlmeas, P_wa and g_bw694vdict1 = vdict.copy()695vdict1[E_lmol] = Elmolmeas696vdict1[T_l] = Tlmeas697vdict1[P_wl] = eq_Pwl.rhs().subs(vdict1)698vdict1[g_bw] = PMdict[g_bw]699vdict1[g_tw] = fun_subs(eq_gtw_Elmol.rhs(), vdict1)700vdict1[g_sw] = fun_subs(eq_gsw_gtw.rhs(),vdict1)701702703# Inferring h_c from Hlmeas, Tlmeas and Tameas704vdict1[H_l] = Hlmeas705vdict1[h_c] = fun_subs(eq_hc_Hl.rhs(),vdict1)706707708#resdict = dict(vdict.items() + SSdict.items() + rdict1.items() + Balldict.items() + PMdict.items())709resdict = dict(vdict.items() + rdict1.items() + Balldict.items() + PMdict.items())710resdict['Tlmeas'] = Tlmeas711resdict['Elmeas'] = Elmeas712resdict['Elmolmeas'] = Elmolmeas713resdict['Hlmeas'] = Hlmeas714resdict['g_twmeas'] = vdict1[g_tw]715resdict['g_swmeas'] = vdict1[g_sw]716resdict['h_cmeas'] = vdict1[h_c]717results.append(tuple(list(lc_data[i]) + resdict.values()))718allinput.append(vdict)719#print resdict720names = [blah[0] for blah in lc_data.dtype.descr] + resdict.keys()721nameslist = [str(names[i]) for i in srange(len(names))]722formatslist = [blah[1] for blah in lc_data.dtype.descr] + ['f8' for i in srange(len(nameslist))]723#print results724#print zip(nameslist,formatslist)725try:726results = np.array(results,dtype = zip(nameslist,formatslist))727except:728print results729results1 = np.nan_to_num(results) # Converts any NaN to something that can be expressed as a float730print nameslist731print formatslist732print vdict733print results734return results735736return results737738739# In[17]:740741def fun_plot_diag(results1, varname1 = 'v_w', axeslabel1 = 'Wind speed (m s$^{-1}$)', Emods = [('E_l', '(mod.)', '-')], Hmods = [('H_l', '(mod.)', '-')], Rmods = [('R_ll', '(mod.)', '-')], energy=True, esums = False, esumsmod = False, rll = False, Hobs = True, fsize = 20, lfsize = 20, axfsize = 1.2, psize = 100, figsize1=[8,6], dpi1 = 50, leglength = 2, lwidth = 2, fname = False):742'''743Sorts results1 for variable varname1 and plots diagnostic plots744for energy, esums, leaftemp, alltemps (set either of them to False745if not desired).746Example:747sage: fun_plot_diag(results1, varname1 = 'v_w', axeslabel1 = 'Wind speed (m s$^{-1}$)', Emods = [('E_l', '(mod.)', '-')], Hmods = [('H_l', '(mod.)', '-')], Tmods = [('T_l', '(mod.)', '-')], energy=True, esums = True, leaftemp = True, alltemps = alltemps = [('T_leaf1', 'TC1', 'v'), ('T_leaf2', 'TC2', '^'), ('T_leaf_IR', 'TCIR', '.')], fsize = 10, lfsize = 'large', axfsize = 1.2, psize = 100, figsize1=[7,5], fname = False, fext = '.png')748'''749750# Sorting array along v_w751results2 = results1.copy()752results2 = np.sort(results2, order = varname1)753pos_vw = srange(len(results2))754xdata = results2[varname1][pos_vw]755Talist = results2['T_a'][pos_vw]756757if energy:758P = list_plot(zip(xdata,results2['Elmeas'][pos_vw]), frame = True, axes = False, plotjoined=False, marker='o', size=psize, legend_label = '$E_l$ (obs.)')759for i in srange(len(Emods)):760tup1 = Emods[i]761if len(tup1)<4:762tup1 = tuple(list(tup1) + ['blue'])763P += list_plot(zip(xdata,results2[tup1[0]][pos_vw]), color = tup1[3], plotjoined=True, thickness = lwidth, linestyle=tup1[2], marker=None, legend_label = '$E_l$ ' + tup1[1])764if Hobs:765P += list_plot(zip(xdata,results2['Hlmeas'][pos_vw]), marker='o', faceted = True, color = 'white', markeredgecolor = 'black', size=psize, plotjoined=False, legend_label = '$H_l$ (obs.)')766for i in srange(len(Hmods)):767tup1 = Hmods[i]768if len(tup1)<4:769tup1 = tuple(list(tup1) + ['black'])770P += list_plot(zip(xdata,results2[tup1[0]][pos_vw]), color = tup1[3], plotjoined=True, thickness = lwidth, linestyle=tup1[2], marker=None, legend_label = '$H_l$ ' + tup1[1])771P.axes_labels([axeslabel1, 'Energy flux from leaf (W m$^{-2}$)'])772773if esums:774P += list_plot(zip(xdata,results2['Elmeas'][pos_vw]+results2['Hlmeas'][pos_vw]), frame = True, axes = False, plotjoined=False, marker='s', faceted = True, color = 'red', markeredgecolor = 'black', size=psize, legend_label = '$E_l + H_l$ (obs.)')775if esumsmod:776for i in srange(len(Hmods)):777P += list_plot(zip(xdata,results2[Emods[i][0]][pos_vw]+results2[Hmods[i][0]][pos_vw]), frame = True, axes = False, plotjoined=True, thickness = 2*lwidth, linestyle=Emods[i][2], color = 'red', marker=None, legend_label = '$E_l + H_l$ ' + Emods[i][1])778if rll:779780if 'Rn_leaf' in results2.dtype.names:781P += list_plot(zip(xdata,results2['Rn_leaf'][pos_vw]), plotjoined=False, marker='o', faceted = True, color = 'red', markeredgecolor = 'black', size=psize, legend_label = '$R_{nleaf}$ (obs.)')782for i in srange(len(Rmods)):783P += list_plot(zip(xdata,results2['R_s'][pos_vw] - results2[Rmods[i][0]][pos_vw]), frame = True, axes = False, plotjoined=True, color = 'red', thickness = 2*lwidth, linestyle=Rmods[i][2], marker=None, legend_label = '$R_s - R_{ll}$ ' + Rmods[i][1])784785P.axes_labels([axeslabel1, 'Energy flux from leaf (W m$^{-2}$)'])786P.show(dpi = dpi1, fontsize = fsize, axes_labels_size = axfsize, fig_tight = True, figsize=figsize1, aspect_ratio = 'automatic', legend_font_size = lfsize, legend_loc=(1.01,0), legend_handlelength=leglength)787if fname:788P.save(fname, fontsize = fsize, axes_labels_size = axfsize, fig_tight = True, figsize=figsize1, aspect_ratio = 'automatic', legend_font_size = lfsize, legend_loc=(1.01,0), legend_handlelength=leglength)789790791# # Experiments in the dark792793# ## Black foil, 35.4 holes/mm2, Figures 6b and 7b in http://www.hydrol-earth-syst-sci-discuss.net/hess-2016-363/794795# In[18]:796797fname = 'exp_35_4_Tdew.csv'798lc_data_orig = fun_read_csv(fname, lc_timepos = [0, 16, 25, 26, 30, 31])799lc_data = lc_data_orig.copy()800lc_data['water_flow_avg'] = -lc_data_orig['water_flow_avg'] # Making flow positive801lc_data_orig = lc_data.copy()802lc_data_35_Pwa = lc_data.copy()803804805# In[19]:806807# Fig. 6b808vdict = cdict.copy()809vdict[a_s] = 1810vdict[L_l] = 0.03811vdict[P_a] = 101325.812vdict[R_s] = 0813vdict[Re_c] = 3000.814vdict[g_sw] = 0.035 # According to perforated_foils_LO: range 0.023-0.051815results_orig = fun_results(lc_data, vdict1 = vdict)816results1 = results_orig.copy()817results_35 = results_orig.copy()818list_vars = ['R_s', 'P_wa', 'T_a', 'v_w', 'g_sw']819for var1 in list_vars:820print var1 + ' = (' + str(min(results1[var1])) + ', ' + str(max(results1[var1])) + ') ' + str(udict[eval(var1)]/eval(var1))821fname = path_figs + '35_Pwa.eps'822823fun_plot_diag(results1, varname1 = 'P_wa', axeslabel1 = 'Vapour pressure (Pa)', Emods = [('E_l', '(mod.)', '-')], Hmods = [('H_l', '(mod.)', '-')], Rmods = [('R_ll', '(mod.)', '-')], esums = True, rll = True, dpi1=50, fname=fname)824825826# In[20]:827828# fig. 7b829fname = path_figs + '35_Pwa_anal.eps'830fun_plot_diag(results1, varname1 = 'P_wa', axeslabel1 = 'Vapour pressure (Pa)', Emods = [('lin_E_l', '(Rlin)', '-'), ('PS_E_l', '(MUc)', '-.'), ('PM_E_l', '(PM)', '--'), ('MU_E_l', '(MU)', ':')], Hmods = [('lin_H_l', '(Rlin)', '-'), ('PS_H_l', '(MUc)', '-.'), ('PM_H_l', '(PM)', '--'), ('MU_H_l', '(MU)', ':')], fname=fname)831832833# ## 35.4 holes/mm2, varying wind speed, Figures 6a and 7a in http://www.hydrol-earth-syst-sci-discuss.net/hess-2016-363/834#835836# In[21]:837838fname = 'exp_35_4_vw.csv'839lc_data_orig = fun_read_csv(fname, lc_timepos = [])840lc_data = lc_data_orig.copy()841lc_data['water_flow_avg'] = -lc_data_orig['water_flow_avg'] # Making flow positive842lc_data_orig = lc_data.copy()843844845# In[22]:846847# Fig. 6a848vdict = cdict.copy()849vdict[a_s] = 1850vdict[L_l] = 0.03851vdict[P_a] = 101325.852vdict[R_s] = 0853vdict[Re_c] = 3000.854#vdict[g_sw] = (0.028+0.051)/2 # According to perforated_foils_LO: range 0.027--0.042855vdict[g_sw] = 0.042856print vdict[g_sw]857results_orig = fun_results(lc_data, vdict)858results1 = results_orig.copy()859list_vars = ['R_s', 'P_wa', 'T_a', 'v_w', 'g_sw']860for var1 in list_vars:861print var1 + ' = (' + str(min(results1[var1])) + ', ' + str(max(results1[var1])) + ') ' + str(udict[eval(var1)]/eval(var1))862863fname = path_figs + '35_vw.eps'864fun_plot_diag(results1, Emods = [('E_l', '(mod.)', '-')], Hmods = [('H_l', '(mod.)', '-')], Rmods = [('R_ll', '(mod.)', '-')], esums = True, rll = True, dpi1=50, fname=fname)865866867# In[23]:868869# Fig. 7a870fname = path_figs + '35_vw_anal.eps'871fun_plot_diag(results1, Emods = [('lin_E_l', '(Rlin)', '-'), ('PS_E_l', '(MUc)', '-.'), ('PM_E_l', '(PM)', '--'), ('MU_E_l', '(MU)', ':')], Hmods = [('lin_H_l', '(Rlin)', '-'), ('PS_H_l', '(MUc)', '-.'), ('PM_H_l', '(PM)', '--'), ('MU_H_l', '(MU)', ':')], fname=fname)872873874# ## Leaf 7_1, Figures 6c and 7c875# (in http://www.hydrol-earth-syst-sci-discuss.net/hess-2016-363/)876877# In[24]:878879fname1 = 'new_tunnel_chamber_2Tin_leaf.csv'880fname = path_data + fname1881try:882reader = csv.reader(open(fname, 'rb'), delimiter=',', quotechar='"')883except:884copyfile(path_data_orig + fname1, fname)885reader = csv.reader(open(fname, 'rb'), delimiter=',', quotechar='"')886887nameslist = reader.next()888unitslist = reader.next()889ncols = len(nameslist)890print ncols891print nameslist892print unitslist893csvdata = []894for row in reader :895row1 = np.array(row)896# replacing empty fields by NaN897row1[row1==''] = 'NaN'898row = tuple(row1)899csvdata.append(row)900901formatslist = []902for i in srange(len(unitslist)):903if unitslist[i] == '':904formatslist.append('S100')905else:906formatslist.append('float')907data = np.array(csvdata,dtype = zip(nameslist,formatslist))908data_orig = data.copy()909910tabledata = []911tabledata.append(list(nameslist))912tabledata.append(list(unitslist))913for i in srange(len(data)):914line1 = data[i]915tabledata.append(list(line1) )916#print tabledata917table(tabledata)918919920# In[25]:921922data.dtype923924925# In[26]:926927# Identifying the data sets with low and high wind speed928pos_vlow = [3,4,5,6,7,9]929pos_vhigh = [10,11]930931932# In[27]:933934# Fig. 6c935vdict = cdict.copy()936vdict[a_s] = 1937vdict[L_l] = 0.03938vdict[P_a] = 101325.939vdict[R_s] = 0940vdict[Re_c] = 3000.941vdict[g_sw] = 0.0065 # Range: 0.005 to 0.01942ndict = {R_s: '', T_d: 'Tdew humidifier', T_l: 'Tlin', Q_in: 'Fan power', S_a: 'Rn_above_leaf', S_b: 'Rn_below_leaf', S_s: 'Rn_beside_leaf', T_in: 'Incoming2 Temp_C(5)', F_in_v: 'Inflow rate', v_w: 'Wind speed', T_a: 'chamber air Temp_C(1) ', E_lmol: 'Sensirion'}943944results_orig = fun_results(data, vdict1=vdict, ndict1=ndict)945results1 = results_orig[pos_vlow]946list_vars = ['R_s', 'P_wa', 'T_a', 'v_w', 'g_sw']947for var1 in list_vars:948print var1 + ' = (' + str(min(results1[var1])) + ', ' + str(max(results1[var1])) + ') ' + str(udict[eval(var1)]/eval(var1))949fname = path_figs + '7_Pwa.eps'950fun_plot_diag(results1, varname1 = 'P_wa', axeslabel1 = 'Vapour pressure (Pa)', Emods = [('E_l', '(mod.)', '-')], Hmods = [('H_l', '(mod.)', '-')], Rmods = [('R_ll', '(mod.)', '-')], esums = True, rll = True, dpi1=50, fname=fname)951952953# In[28]:954955fname = path_figs + '7_Pwa_anal.eps'956fun_plot_diag(results1, varname1 = 'P_wa', axeslabel1 = 'Vapour pressure (Pa)', Emods = [('lin_E_l', '(Rlin)', '-'), ('PS_E_l', '(MUc)', '-.'), ('PM_E_l', '(PM)', '--'), ('MU_E_l', '(MU)', ':')], Hmods = [('lin_H_l', '(Rlin)', '-'), ('PS_H_l', '(MUc)', '-.'), ('PM_H_l', '(PM)', '--'), ('MU_H_l', '(MU)', ':')], fname=fname)957958959# ### Comparison of 35 and 7 pores/mm2960961# In[29]:962963leglength=2964lfsize = 12965axfsize = 18966figsize1 = [6,5]967psize = 24968varname1 = 'P_wa'969axeslabel1 = 'Vapour pressure (Pa)'970Emods = [('E_l', '(mod., 35)', ':')]971Hmods = [('H_l', '(mod., 35)', ':')]972lwidth = 3973974# 35 holes data975results2 = results_35.copy()976977results2 = np.sort(results2, order = varname1)978pos_vw = srange(len(results2))979xdata = results2[varname1][pos_vw]980Talist = results2['T_a'][pos_vw]981982P = list_plot(zip(xdata,results2['Elmeas'][pos_vw]), frame = True, axes = False, plotjoined=False, marker='s', size=psize, legend_label = '$E_l$ (obs., 35)')983for i in srange(len(Emods)):984tup1 = Emods[i]985if len(tup1)<4:986tup1 = tuple(list(tup1) + ['blue'])987P += list_plot(zip(xdata,results2[tup1[0]][pos_vw]), color = tup1[3], plotjoined=True, thickness = lwidth, linestyle=tup1[2], marker=None, legend_label = '$E_l$ ' + tup1[1])988989P += list_plot(zip(xdata,results2['Hlmeas'][pos_vw]), marker='s', faceted = True, color = 'white', markeredgecolor = 'black', size=psize, plotjoined=False, legend_label = '$H_l$ (obs., 35)')990for i in srange(len(Hmods)):991tup1 = Hmods[i]992if len(tup1)<4:993tup1 = tuple(list(tup1) + ['black'])994P += list_plot(zip(xdata,results2[tup1[0]][pos_vw]), color = tup1[3], plotjoined=True, thickness = lwidth, linestyle=tup1[2], marker=None, legend_label = '$H_l$ ' + tup1[1])995996997# Now adding 7 pores / mm2998#Emods = [('E_l', '(S-mod.)', '-'), ('El_ball', '(B-mod.)', '--')]999#Hmods = [('H_l', '(S-mod.)', '-'), ('Hl_ball', '(B-mod.)', '--')]1000Emods = [('E_l', '(mod., 7)', '--')]1001Hmods = [('H_l', '(mod., 7)', '--')]1002lwidth = 210031004# Sorting array along v_w1005results2 = results1.copy()10061007results2 = np.sort(results2, order = varname1)1008pos_vw = srange(len(results2))1009xdata = results2[varname1][pos_vw]1010Talist = results2['T_a'][pos_vw]10111012P += list_plot(zip(xdata,results2['Elmeas'][pos_vw]), frame = True, axes = False, plotjoined=False, marker='o', size=psize, legend_label = '$E_l$ (obs., 7)')1013for i in srange(len(Emods)):1014tup1 = Emods[i]1015if len(tup1)<4:1016tup1 = tuple(list(tup1) + ['blue'])1017P += list_plot(zip(xdata,results2[tup1[0]][pos_vw]), color = tup1[3], plotjoined=True, thickness = lwidth, linestyle=tup1[2], marker=None, legend_label = '$E_l$ ' + tup1[1])10181019P += list_plot(zip(xdata,results2['Hlmeas'][pos_vw]), marker='o', faceted = True, color = 'white', markeredgecolor = 'black', size=psize, plotjoined=False, legend_label = '$H_l$ (obs., 7)')1020for i in srange(len(Hmods)):1021tup1 = Hmods[i]1022if len(tup1)<4:1023tup1 = tuple(list(tup1) + ['black'])1024P += list_plot(zip(xdata,results2[tup1[0]][pos_vw]), color = tup1[3], plotjoined=True, thickness = lwidth, linestyle=tup1[2], marker=None, legend_label = '$H_l$ ' + tup1[1])1025102610271028P.axes_labels([axeslabel1, 'Energy flux from leaf (W m$^{-2}$)'])1029P.show(fontsize = lfsize, fig_tight = True, figsize=figsize1, aspect_ratio = 'automatic', legend_font_size = lfsize, legend_handlelength=leglength, legend_loc=(1.01,0.))103010311032# # Simulations for varying radiation and air temperature (Fig. 8)1033# (in http://www.hydrol-earth-syst-sci-discuss.net/hess-2016-363/)10341035# In[30]:10361037# Fig. 8a1038# Conditions similar to experiment with 35.4 holes/mm21039vdict = cdict.copy()1040vdict[a_s] = 1.0 # one sided stomata1041vdict[g_sw] = 0.0451042vdict[T_a] = 2951043vdict[T_w] = vdict[T_a] # Wall temperature equal to air temperature1044vdict[P_a] = 1013251045rha = 0.51046vdict[P_wa] = rha*eq_Pwl.rhs()(T_l = T_a).subs(vdict)1047vdict[L_l] = 0.031048#vdict[L_A] = vdict[L_l]^21049vdict[Re_c] = 30001050vdict[R_s] = 0.1051#vdict[Q_in] = 01052vdict[v_w] = 1.01053resdict = fun_SS_PM(vdict)10541055dict_results = {}10561057for key1 in resdict.keys():1058dict_results[key1] = [resdict[key1]]1059106010611062list_Rs = srange(0, 800, 100)10631064for Rs in list_Rs:1065vdict[R_s] = Rs1066resdict = fun_SS_PM(vdict)10671068for key1 in resdict.keys():1069dict_results[key1].append(resdict[key1])10701071dict_results1 = {}1072for key1 in dict_results.keys():1073dict_results1[key1] = np.array(dict_results[key1])10741075results1 = dict_results1.copy()1076list_vars = [R_s, P_wa, T_a, v_w, g_sw]1077for var1 in list_vars:1078print str(var1) + ' = (' + str(min(results1[var1])) + ', ' + str(max(results1[var1])) + ') ' + str(udict[var1]/var1)10791080xdata = dict_results1[R_s]1081vary = [(dict_results1[E_l], 'x', 'blue', '$E_{l}$ (S-mod.)'), (dict_results1[H_l], 'x', 'black', '$H_{l}$ (S-mod.)'), (dict_results1['lin_E_l'], '-', 'blue', '$E_{l}$ (Rlin)'), (dict_results1['lin_H_l'], '-', 'black', '$H_{l}$ (Rlin)'), (dict_results1['PM_E_l'], '--', 'blue', '$E_{l}$ (PM)'), (dict_results1['PM_H_l'], '--', 'black', '$H_{l}$ (PM)')]10821083fsize = 201084lfsize = 201085axfsize = 1.21086psize = 1001087figsize1=[8,6]1088xlabel = 'Absorbed shortwave radiation (W m$^{-2}$)'1089ylabel = 'Energy flux from leaf (W m$^{-2}$)'1090i = 01091P = list_plot(zip(xdata, vary[i][0]), plotjoined=False, marker=vary[i][1], size=psize, faceted = True, color = vary[i][2], legend_label=vary[i][3])1092for i in srange(1,2):1093P += list_plot(zip(xdata, vary[i][0]), plotjoined=False, marker=vary[i][1], size=psize, color = vary[i][2], legend_label=vary[i][3])1094for i in srange(2,len(vary)):1095P += list_plot(zip(xdata, vary[i][0]), plotjoined=True, linestyle = vary[i][1], color=vary[i][2], legend_label=vary[i][3])1096P.axes_labels([xlabel, ylabel])1097P.show(fontsize = fsize, axes_labels_size = axfsize, fig_tight = True, figsize=figsize1, aspect_ratio = 'automatic', legend_font_size = lfsize, legend_loc=(1.01,0))1098P.save(path_figs + 'numexp_Rs.png', fontsize = fsize, axes_labels_size = axfsize, fig_tight = True, figsize=figsize1, aspect_ratio = 'automatic', legend_font_size = 14, legend_loc=(1.01,0))109911001101# In[31]:11021103# Fig. 8b1104# Conditions similar to experiment with 35.4 holes/mm2, 350 W/m2 irradiance1105Tlow = 282.1106Thigh = 300.1107vdict = cdict.copy()1108vdict[a_s] = 1.0 # one sided stomata1109vdict[g_sw] = 0.0451110vdict[T_a] = Tlow1111vdict[T_w] = vdict[T_a] # Wall temperature equal to air temperature1112vdict[P_a] = 1013251113rha = 0.51114vdict[P_wa] = rha*eq_Pwl.rhs()(T_l = T_a).subs(vdict)1115vdict[L_l] = 0.031116#vdict[L_A] = vdict[L_l]^21117vdict[Re_c] = 30001118vdict[R_s] = 350.1119#vdict[Q_in] = 01120vdict[v_w] = 1.01121resdict = fun_SS_PM(vdict)11221123dict_results = {}11241125for key1 in resdict.keys():1126dict_results[key1] = [resdict[key1]]1127112811291130list_Ta = srange(Tlow, Thigh, 2)11311132for Ta in list_Ta:1133vdict[T_a] = Ta1134vdict[T_w] = vdict[T_a] # Wall temperature equal to air temperature1135resdict = fun_SS_PM(vdict)11361137for key1 in resdict.keys():1138dict_results[key1].append(resdict[key1])11391140dict_results1 = {}1141for key1 in dict_results.keys():1142dict_results1[key1] = np.array(dict_results[key1])11431144results1 = dict_results1.copy()1145list_vars = [R_s, P_wa, T_a, v_w, g_sw]1146for var1 in list_vars:1147print str(var1) + ' = (' + str(min(results1[var1])) + ', ' + str(max(results1[var1])) + ') ' + str(udict[var1]/var1)11481149xdata = dict_results1[T_a]1150vary = [(dict_results1[E_l], 'x', 'blue', '$E_{l}$ (S-mod.)'), (dict_results1[H_l], 'x', 'black', '$H_{l}$ (S-mod.)'), (dict_results1['lin_E_l'], '-', 'blue', '$E_{l}$ (Rlin)'), (dict_results1['lin_H_l'], '-', 'black', '$H_{l}$ (Rlin)'), (dict_results1['PM_E_l'], '--', 'blue', '$E_{l}$ (PM)'), (dict_results1['PM_H_l'], '--', 'black', '$H_{l}$ (PM)')]11511152fsize = 201153lfsize = 201154axfsize = 1.21155psize = 1001156figsize1=[8,6]1157xlabel = 'Air temperature (K)'1158ylabel = 'Energy flux from leaf (W m$^{-2}$)'1159i = 01160P = list_plot(zip(xdata, vary[i][0]), plotjoined=False, marker=vary[i][1], size=psize, color = vary[i][2], legend_label=vary[i][3])1161for i in srange(1,2):1162P += list_plot(zip(xdata, vary[i][0]), plotjoined=False, marker=vary[i][1], size=psize, color = vary[i][2], legend_label=vary[i][3])1163for i in srange(2,len(vary)):1164P += list_plot(zip(xdata, vary[i][0]), plotjoined=True, linestyle = vary[i][1], color=vary[i][2], legend_label=vary[i][3])1165P.axes_labels([xlabel, ylabel])1166P.show(fontsize = fsize, axes_labels_size = axfsize, fig_tight = True, figsize=figsize1, aspect_ratio = 'automatic', legend_font_size = lfsize, legend_loc=(1.01,0))1167P.save(path_figs + 'numexp_T.png', fontsize = fsize, axes_labels_size = axfsize, fig_tight = True, figsize=figsize1, aspect_ratio = 'automatic', legend_font_size = 14, legend_loc=(1.01,0))116811691170# In[ ]:117111721173117411751176