跳转至

14 - 光合作用与 SIF 模拟

本章介绍动态叶温、Farquhar 光合作用和日光诱导叶绿素荧光(SIF)的统一流程。 同一场景可以包含 Mesh、TurbidBoundary,或两者的混合。

需要哪些属性

参与动态光合和动态 SIF 的叶片 component 需要:

属性域 常用属性 用途
optical Fluspect 叶片反射、透射、吸收和荧光光谱
thermal ThermalProperty 初始温度与长波发射率
biophysical BiophysicalProperty 叶宽、气孔面、热量与水汽交换
physiological Farquhar Angs 和动态 Phi_f
plant.set_property(
    "leaves",
    less.Fluspect(
        N=1.5, cab=45, car=10, cw=0.012, cm=0.006,
        fqe=0.012,
    ),
)
plant.set_property(
    "leaves",
    less.ThermalProperty(
        temperature="air",
        emissivity=0.98,
    ),
)
plant.set_property(
    "leaves",
    less.BiophysicalProperty(
        leaf_width=0.05,
        stomata_side="bottom",
    ),
)
plant.set_property(
    "leaves",
    less.Farquhar(Vcmax25=60.0),
)

Fluspect.fqe 用于静态 SIF。动态 SIF 的 Phi_f 由光合状态计算。

选择 FvCB 公式

less.Farquhar() 现在默认使用 formulation="scope"absorption_component="chlorophyll",因此这两个参数都可以省略。默认值采用 SCOPE 的 C3 方程。

如需使用 LESS3 的旧版方程,请显式选择:

plant.set_property(
    "leaves",
    less.Farquhar(Vcmax25=60.0, formulation="jmax"),
)

只有在 formulation="jmax" 时,省略的 Jmax25 才会解析为 2 * Vcmax25。Scope 公式不使用 Jmax,因此会拒绝 Jmax25:使用 Scope 时 请删除 Jmax25;确实需要指定 Jmax 容量时,请改用 formulation="jmax"。 选择 Jmax 不会暗中改用总吸收;两种公式仍都默认使用叶绿素吸收。

选择吸收光组分

Farquhar.absorption_component 指定驱动光合作用的吸收组分,默认值为 "chlorophyll"ProspectFluspect 会自动提供随波长变化的生化吸收分区, 因此常用叶片模型不需要额外输入分区数据。如果希望 Farquhar 使用叶片总吸收, 请显式设置 absorption_component="total"

plant.set_property(
    "leaves",
    less.Farquhar(Vcmax25=60.0, absorption_component="total"),
)

MeasuredSpectrum 不能仅凭叶绿素含量推断色素吸收。需要提供与实测光谱同一波长网格 上的显式分区,或者指定一个分区模型:

measured = less.MeasuredSpectrum(
    wavelengths=[400.0, 550.0, 700.0],
    reflectance=[0.08, 0.12, 0.18],
    transmittance=[0.04, 0.08, 0.12],
    absorption_partition=less.ProspectPartition(cab=45.0),
)

比较色素敏感的 APAR 时,建议在 PAR 范围内使用约 1 nm 的光谱采样。较粗的波段 可能使随波长变化的叶绿素吸收比例产生偏差。该建议只针对光谱吸收,不会消除由不同 生理公式造成的差异。

环境单位与结果元数据

Microclimate.pressure 的单位是 Pa,Microclimate.oxygen 的单位是 mmol mol-1,Microclimate.ca 表示以 umol mol-1 计的 CO2。LESS 根据空气温度 和湿度推导以 Pa 计的实际水汽压(actual vapor pressure)。Scope 求解叶温时, 实际水汽压保持不变,并按求得的叶温重新计算叶片相对湿度。

光合产品逐行保存 formulationabsorption_component、压力、氧气、实际水汽压、 CO2 和科学环境指纹。APAR 始终表示所选吸收组分的值,APAR_total 始终表示 叶片总吸收 PAR。

读取缺少这两个选择器的旧版 Farquhar 序列化记录时,LESS 会将其迁移为 formulation="jmax"absorption_component="total",从而保留旧版含义; 新序列化记录会显式保存这两个字段。

推荐流程

microclimate = less.Microclimate(
    air_temperature=25.0,  # 摄氏度
    humidity=60.0,         # 百分数
    wind_speed=2.0,
    ca=400.0,
)

state = scene.solve(
    microclimate=microclimate,
    modules=["energy_balance", "photosynthesis", "sif"],
)

photo = state.photosynthesis
print("An:", photo.An)
print("gs:", photo.gs)
print("Phi_f:", photo.Phi_f)
print("leaf temperature:", photo.T_leaf)

thermal = scene.simulate(
    less.ThermalImager(
        less.Orthographic(image_size=512),
        bands=[10600.0],
        quality=128,
    )
)

sif = scene.simulate(
    less.SIFImager(
        less.Orthographic(image_size=512),
        bands=[687.0, 740.0, 760.0],
        quality=256,
    )
)

thermal.save("dynamic_temperature.tif")
sif.save("dynamic_sif.tif")

这一次 solve 中,能量平衡、AngsPhi_f 使用同一个耦合状态。 ThermalImagerSIFImager 默认读取这个当前状态,不需要手工传递中间结果。

阳叶和阴叶

直射光在冠层中不是均匀的。LESS 记录:

  • sunlit_fraction:直接见到太阳的叶面积比例;
  • APAR:所选 absorption_component 的 APAR;
  • APAR_total:组分分区前的叶片总吸收 PAR;
  • APAR_sunlitAPAR_shaded:条件阳叶/阴叶的所选组分 APAR;
  • APAR_total_sunlitAPAR_total_shaded:条件阳叶/阴叶的总 APAR;
  • absorption_component:与每个输出元素对应的实际吸收组分;
  • T_sunlitT_shaded:条件阳叶和阴叶温度;
  • An_sunlitAn_shaded:对应的净光合速率。

天空光和多次散射同时进入阳叶和阴叶。只有条件阳叶包含无遮挡直射项。 最终 component 或面片结果按阳叶比例加权:

所选组分和总吸收两组 APAR 各自独立闭合。例如:

\[ APAR_\mathrm{total} = p_\mathrm{sunlit} APAR_{\mathrm{total,sunlit}} + (1-p_\mathrm{sunlit}) APAR_{\mathrm{total,shaded}}. \]
\[ \overline{An} = p_\mathrm{sunlit} An_\mathrm{sunlit} + (1-p_\mathrm{sunlit}) An_\mathrm{shaded} \]

光合是非线性过程,因此先分别求解阳叶和阴叶,再平均;不能先平均 APAR, 再只运行一次 Farquhar。

结果空间层次

print(photo.spatial_mode)
  • 纯 Mesh 场景返回 "primitive",每个三角面片一个结果;
  • TurbidBoundary 的静态光合计算,其顶层数组按 Turbid component 返回, spatial_mode"component"。对于静态 Mesh+Turbid 场景, photo.scene_elements 还会保留彼此对齐的 Mesh 与 Turbid 行身份;
  • 联合动态热力—生理产品的公开数组跨越多种场景元素时, spatial_mode"mixed"
  • 统计介质中的临时叶面积样本只用于数值积分,不会成为永久体素或场景几何;
  • 如果需要更细的统计介质输出,可把树冠划分为多个 component。

静态 SIF:不需要光合和温度

如果只希望使用给定的 Fluspect.fqe 模拟荧光,可以直接计算静态 SIF:

source = scene.simulate(
    less.SIFProcess(
        mode="static",
        quality="high",
    )
)

image = scene.simulate(
    less.SIFImager(
        less.Orthographic(image_size=512),
        bands=[687.0, 740.0, 760.0],
        quality=256,
        sif_result=source,
    )
)

静态 SIF 不运行 Farquhar,不需要 PhotosynthesisProcess,也不需要温度属性。 它仍然需要 Fluspect,因为反射、透射、吸收、荧光激发和发射光谱来自该属性。

采样质量

动态生理过程可使用质量预设:

state = scene.solve(
    microclimate=microclimate,
    modules=["energy_balance", "photosynthesis", "sif"],
    photosynthesis_kwargs={"quality": "high"},
    sif_kwargs={"quality": "high"},
    seed=42,
)

可选值为 "preview""standard""high"。正式研究还应改变采样数, 检查 APAR、叶温、AngsPhi_f 是否稳定。固定 seed 可复现实验。

三后端一致性

以下后端使用同一套公开 API:

scene = less.Scene(backend="optix")
scene = less.Scene(backend="vulkan")
scene = less.Scene(backend="embree")

OptiX 适合 NVIDIA GPU;Vulkan 可使用支持 Ray Query 的 GPU;Embree 使用 CPU。 切换后端不需要改变 solveThermalImagerSIFImager 的调用方式。

查看闭合与收敛

eb = state.energy_balance.result
print("energy converged:", eb.converged)
print("photo converged:", state.photosynthesis.converged)
print("iterations:", state.photosynthesis.iterations)
print("max residual:", abs(eb.residual[eb.active_mask]).max())

如果光照、微气候、属性或几何发生变化,请重新运行 scene.solve(...)。LESS 会 拒绝把旧状态用于新的 Thermal 或 SIF 图像。

下一步

Mesh 与 Turbid 混合场景

scene.solve(...) 可以同时处理 Mesh 叶片、TurbidBoundary 冠层和地形。 结果中的 scene_elements 会标识每一行对应的场景元素,并提供叶面积、阳叶比例、 阳叶/阴叶温度、APAR、净光合速率和气孔导度等字段。修改场景属性、光照或微气候后, 请重新运行 scene.solve(...),再将新的 energy_balancesif 产品传给成像传感器。

相关 API

  • less.PhotosynthesisProcessless.SIFProcess
  • less.Farquharless.Fluspectless.BiophysicalProperty
  • less.Microclimateless.EnergyBalanceProcess
  • less.SIFImagerless.ThermalImager
  • less.PhotosynthesisProcessProductless.SIFProcessProduct