Constraint scan

Generate constraintscandf

import numpy as np
import pandas as pd
import pyDOE
from mmon_gcm.constraintscan import generate_constraints_df

Define parameter bounds

parameter_bounds = {}

Photons

We can go 10% above and below the value for photon reflectance and transmission from Zhu et al (2010)

parameter_bounds["P_abs"] = [0.9*0.9, 0.9*1.1, r"Dimensionless",
                             "90% of Zhu, Long, and Ort (2010)", "110% of Zhu, Long, and Ort (2010)"]  # proportion of photons absorbed by the leaf

The lower bound is the default we’ve used from Wuyts et al (2021), for a higher value we’ll use one from Ramonell 2001.

parameter_bounds["T_l"] = [0.017 * 10 ** -2, 0.024 * 10 ** -2, r"m", "Wuyts et al. (2010)", "Ramonell et al. (2001)"]

The are of the leaf being simulated is fixed at 1m\(^2\)

parameter_bounds["A_l"] = [1, 1, r"m$^2$", "Fixed", "Fixed"]

For the lower bound we can use the average volume of an Arabidopsis guard cell as the midpoint of the values given in table 1 of Jezek and Blatt (2017). For the upper bound we can use the volume given in Hills et al (2012).

j_b_upper = 0.65
j_b_lower = 0.3
V_gc_ind = (j_b_lower+j_b_upper)/2  # pL
V_gc_ind = V_gc_ind * 10**-12  # dm3
parameter_bounds["V_gc_ind"] = [V_gc_ind, 4.1E-12, r"dm$^3$", "Jezek and Blatt (2017)", "Hills et al. (2012)"]

The photosynthetic efficient of guard cells compared to the mesophyll was taken from Lawson (2003).

In leaves of all species the values of photosynthetic efficiency for guard cells were either indistinguishable from or only slightly lower (minimum of 79%) than those of the underlying, spongy mesophyll cells.

We’ll use these as the bounds.

parameter_bounds["FqFm"] = [0.79, 0.9, r"Dimensionless", "Lawson (2003)", "Lawson (2003)"]

Fujiwara et al (2019) provide a range of values for number of chloroplasts in mesophyll and guard cells, we can take the upper gc and lower me and vice versa to get the upper and lower bound for the ratios, respectively.

upper_gc = 5.5
lower_gc = 3.5

upper_me = 100
lower_me = 30

rch_lower_bound = lower_gc/upper_me
rch_upper_bound = upper_gc/lower_me

parameter_bounds["R_ch"] = [rch_lower_bound, rch_upper_bound, r"Dimensionless",
                            "Fujiwara, Sanjaya, and Itoh (2019)", "Fujiwara, Sanjaya, and Itoh (2019)"]

Added in Nov 2023: The proportion of chloroplast volumes between guard cells and mesophyll cells for Arabidopsis Col-0 based on Chl a data from Knoblauch et al. (2023) Table S1. We can the standard error values to calculate the range with min/max being 2 SE away.

chl_vol_me = 88.24
chl_vol_se_me = 1.58
min_chl_vol_me = chl_vol_me - 2 * chl_vol_se_me
max_chl_vol_me = chl_vol_me + 2 * chl_vol_se_me

chl_vol_gc = 17.69
chl_vol_se_gc = 0.21
min_chl_vol_gc = chl_vol_gc - 2 * chl_vol_se_gc
max_chl_vol_gc = chl_vol_gc + 2 * chl_vol_se_gc

min_R_ch_vol = min_chl_vol_gc / max_chl_vol_me
max_R_ch_vol = max_chl_vol_gc / min_chl_vol_me

#modelparameters["R_ch_vol"] = [R_ch_vol, r"Dimensionless", "Knoblauch et al. (2023)"]

parameter_bounds["R_ch_vol"] = [min_R_ch_vol, max_R_ch_vol, r"Dimensionless",
                            "Knoblauch et al. (2023)", "Knoblauch et al. (2023)"]

For the lower bound Ramonell et al. (2001) provide a percentage of the leaf that is space at atmospheric pressure in Table 1.For the upper bound we take the proportion of the leaf that is air from Earles et al 2018 for Guzmania zahnii from Table 2.

parameter_bounds["L_air"] = [0.185, 0.37, r"Dimensionless", "Ramonell et al. (2001)", "Earles et al. (2018)"]

Willmer and Fricker (1996) provide a lower bound of 0.1 and Ramonell et al. (2001) an upper bound of 0.24 for the proportion of the leaf that is epidermis.

parameter_bounds["L_epidermis"] = [0.1, 0.24, r"Dimensionless", "Willmer and Fricker (1996)", "Ramonell et al. (2001)"]

Osmolarity

Wang et al. (2017) use a value of 0.751 to be the proportion of the Guard Cell that is vacuole, Andrés et al. (2014) quote a value of 90% from an old MacRobbie paper.

parameter_bounds["Vac_frac"] = [0.751, 0.9, r"Dimensionless", "Wang et al. (2017)", "Andrés et al. (2014) "]

A reasonable range for temperature seems to be 10C to 25C, this covers a wide range:

parameter_bounds["T"] = [273.15+10, 273.15+25, "K", "10C", "25C"]

Ideal gas constant, from NIST, (reference Tiesinga2019). This is constant, so won’t change in the model

R = 8.205*10**(-5)  # m3atmK-1mol-1
R = R*10**3  # dm3atmK-1mol-1
parameter_bounds["R"] = [
    R, R, r"dm$^3$$\cdot$atm$\cdot$K$^{-1}$$\cdot$mol$^{-1}$", "Tiesinga et al. (2019)", "Tiesinga et al. (2019)"]

The density of guard cells per m\(^2\) of leaf was taken by multiplying the density of stomata from Papanatsiou et al (2016) by two. This only takes into account the abaxial surface of the leaf, so for the upper bound, we’ll double this again. For the lower bound, we’ll use a value for Commelina from Willmer and Fricker (1996).

parameter_bounds["N_gcs"] = [172 * 10 ** 6, 290 * 10 ** 6 * 2.0 * 2,
                             r"GCs$\cdot$m$^{-2}$", "Willmer and Fricker (1996)", "Papanatsiou, Amtmann, and Blatt (2016)"]

The following parameters required for osmolarity are based taking values from an older OnGuard paper (Wang et al. (2012)) and the newer, updated model (Wang et al 2017).

parameter_bounds["n"] = [1.5, 2.5, "atm", "Wang et al. (2012)", "Wang et al. (2017)"]
parameter_bounds["m"] = [0.8, 1, r"atm$\cdot$µm$^{-1}$", "Wang et al. (2017)", "Wang et al. (2012)"]
parameter_bounds["r"] = [0.05 * 10 ** (-12), 0.08 * 10 ** (-12),
                         r"dm$^3$ µm$^{-1}$", "Wang et al. (2017)", "Wang et al. (2012)"]
parameter_bounds["s"] = [0.1 * 10 ** (-12), 0.3 * 10 ** (-12), r"dm$^3$", "Wang et al. (2012)", "Wang et al. (2017)"]

For the apoplastic concentration, we use the value from the OnGuard model as the lower bound, and use a combination of values which have been collated by Roelfsema and Hedrich (2002) from Lohaus et al. (2001) for the upper bound:

apoplastic_concs_wang_2017 = {
    "K": 10,
    "Ca": 1,
    "Cl": 12,
    "Suc": 0.01,
    "MH2": 3.2*10**(-6),
    "MH": 7.9*10**(-5),
    "M": 0.00999,
}
apoplastic_conc_wang_2017 = sum(apoplastic_concs_wang_2017.values())
apoplastic_concs_roelfsema_2002 = {
    "K": 13,
    "Ca": 0.7,
    "Cl": 11,
    "Suc": 1.6,
    "Mal": 0.7,
    "Amino Acids": 9.6,
    "Hexoses": 0.7,
}
apoplastic_conc_roelfsema_2002 = sum(apoplastic_concs_roelfsema_2002.values())
parameter_bounds["C_apo"] = [apoplastic_conc_wang_2017*10 **
                             (-3), apoplastic_conc_roelfsema_2002*10**(-3), r"mol$\cdot$dm$^{-3}$", "Wang et al. (2017)", "Roelfsema and Hedrich (2002)"]

Apertures

For the closed aperture, we’ll use 1 µm value from Jezek and Blatt (2017) as a lower bound and 4 µm from Wang et al. (2017) as an upper bound.

parameter_bounds["A_closed"] = [1, 4, r"µm", "Jezek and Blatt (2017)", "Wang et al. (2017)"]

For the open aperture, we’ll use the 2.75 µm from Horrer et al. (2016) as the lower bound and 12 µm from Wang et al. (2017) as the upper bound.

parameter_bounds["A_open"] = [2.75, 12, r"µm", "Horrer et al. (2016)", "Wang et al. (2017)"]

For the proportion of photons that are absorbed by the leaf we can just go for 10% above and below the value that is reported by

ATPase

We’ll go between constraining the ATPase to 0 and the level of ATPase that Flütsch et al. (2020) measured (17 fmoles\(\cdot\)GC\(^{-1}\cdot\)h\(^{-1}\)).

parameter_bounds["ATPase"] = [
    0, 17, r"fmoles$\cdot$GC$^{-1}\cdot$h$^{-1}$", "Supplementary", "Flütsch et al. (2020)"]

Export parameters to csv

params_df = pd.DataFrame.from_dict(parameter_bounds, orient="index", columns=[
                                   "Lower", "Upper", "Units", "Source Lower", "Source Upper"])
params_df.to_csv("../outputs/constraint_scan/parameter_bounds.csv")
params_df.to_csv("../plant_cell_paper/supplemental_table_2.csv")
params_df
Lower Upper Units Source Lower Source Upper
P_abs 8.100000e-01 9.900000e-01 Dimensionless 90% of Zhu, Long, and Ort (2010) 110% of Zhu, Long, and Ort (2010)
T_l 1.700000e-04 2.400000e-04 m Wuyts et al. (2010) Ramonell et al. (2001)
A_l 1.000000e+00 1.000000e+00 m$^2$ Fixed Fixed
V_gc_ind 4.750000e-13 4.100000e-12 dm$^3$ Jezek and Blatt (2017) Hills et al. (2012)
FqFm 7.900000e-01 9.000000e-01 Dimensionless Lawson (2003) Lawson (2003)
R_ch 3.500000e-02 1.833333e-01 Dimensionless Fujiwara, Sanjaya, and Itoh (2019) Fujiwara, Sanjaya, and Itoh (2019)
R_ch_vol 1.889497e-01 2.128585e-01 Dimensionless Knoblauch et al. (2023) Knoblauch et al. (2023)
L_air 1.850000e-01 3.700000e-01 Dimensionless Ramonell et al. (2001) Earles et al. (2018)
L_epidermis 1.000000e-01 2.400000e-01 Dimensionless Willmer and Fricker (1996) Ramonell et al. (2001)
Vac_frac 7.510000e-01 9.000000e-01 Dimensionless Wang et al. (2017) Andrés et al. (2014)
T 2.831500e+02 2.981500e+02 K 10C 25C
R 8.205000e-02 8.205000e-02 dm$^3$$\cdot$atm$\cdot$K$^{-1}$$\cdot$mol$^{-1}$ Tiesinga et al. (2019) Tiesinga et al. (2019)
N_gcs 1.720000e+08 1.160000e+09 GCs$\cdot$m$^{-2}$ Willmer and Fricker (1996) Papanatsiou, Amtmann, and Blatt (2016)
n 1.500000e+00 2.500000e+00 atm Wang et al. (2012) Wang et al. (2017)
m 8.000000e-01 1.000000e+00 atm$\cdot$µm$^{-1}$ Wang et al. (2017) Wang et al. (2012)
r 5.000000e-14 8.000000e-14 dm$^3$ µm$^{-1}$ Wang et al. (2017) Wang et al. (2012)
s 1.000000e-13 3.000000e-13 dm$^3$ Wang et al. (2012) Wang et al. (2017)
C_apo 2.302007e-02 3.730000e-02 mol$\cdot$dm$^{-3}$ Wang et al. (2017) Roelfsema and Hedrich (2002)
A_closed 1.000000e+00 4.000000e+00 µm Jezek and Blatt (2017) Wang et al. (2017)
A_open 2.750000e+00 1.200000e+01 µm Horrer et al. (2016) Wang et al. (2017)
ATPase 0.000000e+00 1.700000e+01 fmoles$\cdot$GC$^{-1}\cdot$h$^{-1}$ Supplementary Flütsch et al. (2020)

Generate constraints array

np.random.seed(12345)
lhs_df = pd.DataFrame(pyDOE.lhs(len(params_df), samples=1000), columns=params_df.index)
lhs_df
P_abs T_l A_l V_gc_ind FqFm R_ch R_ch_vol L_air L_epidermis Vac_frac ... R N_gcs n m r s C_apo A_closed A_open ATPase
0 0.028292 0.338674 0.246570 0.493142 0.175427 0.977324 0.107802 0.302049 0.820428 0.722450 ... 0.153025 0.279797 0.433548 0.963205 0.962184 0.339327 0.746393 0.440446 0.926376 0.636275
1 0.628777 0.286029 0.662705 0.214036 0.901474 0.394613 0.289387 0.822685 0.690041 0.582330 ... 0.284006 0.902879 0.525073 0.731138 0.133381 0.332031 0.035277 0.500199 0.757259 0.032343
2 0.113928 0.708559 0.423511 0.007883 0.282366 0.895879 0.663943 0.792196 0.754813 0.440387 ... 0.351717 0.408732 0.641889 0.864175 0.526540 0.728559 0.773222 0.600727 0.063580 0.460229
3 0.394433 0.307405 0.547051 0.107012 0.696204 0.109513 0.649222 0.673176 0.499691 0.420982 ... 0.817482 0.215708 0.577401 0.704240 0.249197 0.257664 0.472720 0.799821 0.776907 0.741573
4 0.586647 0.711518 0.268645 0.072868 0.512344 0.168328 0.188196 0.903058 0.990504 0.399266 ... 0.319339 0.884972 0.896012 0.088992 0.884727 0.326487 0.378155 0.768411 0.529806 0.645322
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
995 0.221154 0.062372 0.705868 0.597328 0.823500 0.669811 0.193784 0.567541 0.812587 0.292890 ... 0.032674 0.242698 0.211337 0.908292 0.632804 0.031215 0.710780 0.281261 0.948274 0.943505
996 0.819293 0.213236 0.684359 0.629102 0.074376 0.423523 0.539439 0.044292 0.273993 0.488128 ... 0.312923 0.496296 0.389247 0.845017 0.595832 0.283269 0.640695 0.107333 0.326160 0.161772
997 0.033990 0.053332 0.580020 0.684893 0.322015 0.769551 0.472401 0.750660 0.782582 0.532717 ... 0.827666 0.740442 0.471395 0.855506 0.972350 0.980135 0.600408 0.097973 0.486267 0.087818
998 0.691945 0.917259 0.613010 0.178557 0.087392 0.087096 0.574029 0.898432 0.661794 0.428601 ... 0.881107 0.961280 0.813188 0.286382 0.440802 0.225379 0.006156 0.448663 0.366312 0.162148
999 0.798469 0.994228 0.731902 0.388958 0.946242 0.678050 0.002710 0.303771 0.266437 0.629726 ... 0.695088 0.383094 0.061648 0.888340 0.577126 0.542766 0.916561 0.442069 0.710851 0.284280

1000 rows × 21 columns

constraints_df = generate_constraints_df(lhs_df, params_df)
constraints_df.head()
Removing 32 combinations where open aperture is smaller than closed
P_abs T_l A_l V_gc_ind FqFm R_ch R_ch_vol L_air L_epidermis Vac_frac ... R N_gcs n m r s C_apo A_closed A_open ATPase
0 0.815093 0.000194 1.0 2.262641e-12 0.809297 0.179970 0.191527 0.240879 0.214860 0.858645 ... 0.08205 4.484392e+08 1.933548 0.992641 7.886553e-14 1.678654e-13 0.033679 2.321339 11.318979 10.816668
1 0.923180 0.000190 1.0 1.250880e-12 0.889162 0.093534 0.195869 0.337197 0.196606 0.837767 ... 0.08205 1.064044e+09 2.025073 0.946228 5.400144e-14 1.664063e-13 0.023524 2.500598 9.754649 0.549826
2 0.830507 0.000220 1.0 5.035745e-13 0.821060 0.167889 0.204824 0.331556 0.205674 0.816618 ... 0.08205 5.758277e+08 2.141889 0.972835 6.579620e-14 2.457118e-13 0.034062 2.802180 3.338120 7.823891
3 0.880998 0.000192 1.0 8.629192e-13 0.866582 0.051244 0.204472 0.309538 0.169957 0.813726 ... 0.08205 3.851195e+08 2.077401 0.940848 5.747590e-14 1.515328e-13 0.029770 3.399462 9.936390 12.606738
4 0.915597 0.000220 1.0 7.391447e-13 0.846358 0.059969 0.193449 0.352066 0.238671 0.810491 ... 0.08205 1.046353e+09 2.396012 0.817798 7.654181e-14 1.652973e-13 0.028420 3.305233 7.650706 10.970481

5 rows × 21 columns

constraints_df.to_csv("../outputs/constraint_scan/constraints_df.csv")