Skip to main content

Photosynthesis Models

PhyTorch implements the Farquhar-von Caemmerer-Berry (FvCB) model for C3 photosynthesis, one of the most widely used biochemical models of leaf photosynthesis.

FvCB Model

The FvCB model calculates net CO2 assimilation rate (AA) as the minimum of three potentially limiting rates:

A=min(Wc,Wj,Wp)RdA = \min(W_c, W_j, W_p) - R_d

where:

  • Rubisco-limited rate (WcW_c): Limited by the maximum carboxylation rate (VcmaxV_{{cmax}})
  • RuBP regeneration-limited rate (WjW_j): Limited by electron transport capacity (JmaxJ_{{max}})
  • Triose phosphate utilization-limited rate (WpW_p): Limited by the capacity to use photosynthetic products
  • RdR_d: Day respiration

Rubisco-Limited Rate

Wc=Vcmax(CiΓ)Ci+Kc(1+O/Ko)W_c = \frac{{V_{{cmax}} \cdot (C_i - \Gamma^*)}}{{C_i + K_c(1 + O/K_o)}}

RuBP Regeneration-Limited Rate

Wj=J(CiΓ)4(Ci+2Γ)W_j = \frac{{J \cdot (C_i - \Gamma^*)}}{{4(C_i + 2\Gamma^*)}}

where JJ is the electron transport rate, calculated from light response

Basic Usage

PhyTorch's unified API makes fitting photosynthesis models simple and consistent:

from phytorch import fit
from phytorch.models.photosynthesis import FvCB
import pandas as pd

# Load LI-COR A-Ci curve data
df = pd.read_csv('your_aci_data.csv')

# Prepare data dictionary
data = {
'Ci': df['Ci'].values, # Intercellular CO2 (μmol/mol)
'Q': df['PARi'].values, # Light intensity (μmol/m²/s)
'Tleaf': df['Tleaf'].values, # Leaf temperature (°C)
'A': df['Photo'].values # Net photosynthesis (μmol/m²/s)
}

# Fit the FvCB model (that's it!)
result = fit(FvCB(), data)

# View fitted parameters
print(f"Vcmax25: {result.parameters['Vcmax25']:.2f} μmol/m²/s")
print(f"Jmax25: {result.parameters['Jmax25']:.2f} μmol/m²/s")
print(f"Rd25: {result.parameters['Rd25']:.2f} μmol/m²/s")
print(f"R² = {result.r_squared:.4f}")

# Generate comprehensive plots
# Includes: 1:1, A vs Ci, A vs Q, A vs T, and 3D surfaces
result.plot()

# Save the plot
result.plot(save='fvcb_fit.png')

Key Parameters

PhyTorch fits the following parameters at 25°C:

ParameterDescriptionTypical RangeUnits
Vcmax25Maximum carboxylation rate at 25°C50-150μmol/m²/s
Jmax25Maximum electron transport rate at 25°C100-250μmol/m²/s
Rd25Day respiration at 25°C0.5-2.0μmol/m²/s
Tp25Triose phosphate utilization at 25°C5-15μmol/m²/s

Biochemical Constants

ParameterDescriptionValue at 25°CUnits
KcMichaelis constant for CO2260μmol/mol
KoMichaelis constant for O2179mmol/mol
Γ*CO2 compensation point~40μmol/mol

Temperature Response

PhyTorch supports two temperature response types:

Type 1: Arrhenius Function

# Simple Arrhenius temperature response
fvcbm = fvcb.model(lcd, LightResp_type=2, TempResp_type=1)

The Arrhenius function:

k=k25exp[ΔHaR(12981Tleaf)]k = k_{{25}} \exp\left[\frac{{\Delta H_a}}{{R}}\left(\frac{{1}}{{298}}-\frac{{1}}{{T_{{leaf}}}}\right)\right]
ParameterDescriptionValue/RangeUnits
kkParameter value (Vcmax, Jmax, or TPU)Variableμmol/m²/s
k25k_{{25}}Parameter value at 25°CVariableμmol/m²/s
ΔHa\Delta H_aActivation energy50,000-100,000J/mol
RRUniversal gas constant8.314J/mol/K
TleafT_{{leaf}}Leaf temperature273-323 (0-50°C)K

Type 2: Peaked Arrhenius Function

# Peaked Arrhenius (includes high-temperature deactivation)
fvcbm = fvcb.model(lcd, LightResp_type=2, TempResp_type=2)

The peaked Arrhenius function:

k=k25exp[ΔHaR(12981Tleaf)]f(298)f(Tleaf)k = k_{{25}} \exp\left[\frac{{\Delta H_a}}{{R}} \left(\frac{{1}}{{298}}-\frac{{1}}{{T_{{leaf}}}}\right)\right] \frac{{f(298)}}{{f(T_{{leaf}})}}

where:

f(T)=1+exp[ΔHdR(1Topt1T)ln(ΔHdΔHa1)]f(T) = 1+\exp \left[\frac{{\Delta H_d}}{{R}}\left(\frac{{1}}{{T_{{opt}}}}-\frac{{1}}{{T}} \right)-\ln \left(\frac{{\Delta H_d}}{{\Delta H_a}}-1 \right) \right]
ParameterDescriptionValue/RangeUnits
kkParameter value (Vcmax, Jmax, or TPU)Variableμmol/m²/s
k25k_{{25}}Parameter value at 25°CVariableμmol/m²/s
ΔHa\Delta H_aActivation energy50,000-100,000J/mol
ΔHd\Delta H_dDeactivation energy150,000-250,000J/mol
ToptT_{{opt}}Optimal temperature298-313 (25-40°C)K
RRUniversal gas constant8.314J/mol/K
TleafT_{{leaf}}Leaf temperature273-323 (0-50°C)K

Light Response

PhyTorch supports three light response types for electron transport rate (JJ):

Type 0: No Light Dependence

fvcbm = fvcb.model(lcd, LightResp_type=0, TempResp_type=2)
J=JmaxJ = J_{{max}}

No additional parameters are fitted. Electron transport is simply equal to JmaxJ_{{max}}.

Type 1: Rectangular Hyperbola

fvcbm = fvcb.model(lcd, LightResp_type=1, TempResp_type=2)
J=αQJmaxαQ+JmaxJ = \frac{{\alpha Q J_{{max}}}}{{\alpha Q + J_{{max}}}}
ParameterDescriptionTypical RangeUnits
JmaxJ_{{max}}Maximum electron transport rate100-250μmol/m²/s
α\alphaLight use efficiency0.2-0.4mol e⁻/mol photons
QQPhotosynthetic photon flux density (PPFD)0-2500μmol/m²/s

Type 2: Non-Rectangular Hyperbola

fvcbm = fvcb.model(lcd, LightResp_type=2, TempResp_type=2)
J=αQ+Jmax(αQ+Jmax)24θαQJmax2θJ = \frac{{\alpha Q + J_{{max}} - \sqrt{{(\alpha Q + J_{{max}})^2 - 4 \theta \alpha Q J_{{max}}}}}}{{2 \theta}}
ParameterDescriptionTypical RangeUnits
JmaxJ_{{max}}Maximum electron transport rate100-250μmol/m²/s
α\alphaLight use efficiency0.2-0.4mol e⁻/mol photons
θ\thetaCurvature parameter0.7-0.9dimensionless
QQPhotosynthetic photon flux density (PPFD)0-2500μmol/m²/s

A-Ci Curves

Fitting A-Ci (assimilation vs. intercellular CO2) curves:

from phytorch import fit
from phytorch.models.photosynthesis import FvCB
import numpy as np

# Your A-Ci curve data
data = {
'Ci': np.array([50, 100, 200, 400, 600, 800, 1000]),
'Q': np.full(7, 1500), # Constant light at 1500 μmol/m²/s
'Tleaf': np.full(7, 25), # Constant temperature at 25°C
'A': np.array([5.2, 10.5, 18.3, 24.1, 26.8, 28.2, 29.1])
}

# Fit the model
result = fit(FvCB(), data)

# View results
print(f"Vcmax25: {result.parameters['Vcmax25']:.2f} μmol/m²/s")
print(f"Jmax25: {result.parameters['Jmax25']:.2f} μmol/m²/s")
print(f"Rd25: {result.parameters['Rd25']:.2f} μmol/m²/s")

# Plot comprehensive results
result.plot()

Advanced Features

Custom Parameter Constraints

from phytorch import fit, FitOptions
from phytorch.models.photosynthesis import FvCB

# Define custom parameter bounds
options = FitOptions(
bounds={
'Vcmax25': (20, 200),
'Jmax25': (40, 400),
'Rd25': (0, 5)
}
)

result = fit(FvCB(), data, options)

Custom Initial Guesses

from phytorch import fit, FitOptions

# Provide initial parameter estimates
options = FitOptions(
initial_guess={
'Vcmax25': 100,
'Jmax25': 180,
'Rd25': 1.5
}
)

result = fit(FvCB(), data, options)

Making Predictions

# Fit the model
result = fit(FvCB(), training_data)

# Make predictions on new data
new_data = {
'Ci': np.linspace(50, 1000, 100),
'Q': np.full(100, 1500),
'Tleaf': np.full(100, 25)
}

predictions = result.predict(new_data)

References

  • Farquhar, G. D., von Caemmerer, S., & Berry, J. A. (1980). A biochemical model of photosynthetic CO2 assimilation in leaves of C3 species. Planta, 149(1), 78-90.
  • Sharkey, T. D., et al. (2007). Fitting photosynthetic carbon dioxide response curves for C3 leaves. Plant, Cell & Environment, 30(9), 1035-1040.