diff --git a/.github/workflows/Example.yml b/.github/workflows/Example.yml index 24dcabe1..76696bc7 100644 --- a/.github/workflows/Example.yml +++ b/.github/workflows/Example.yml @@ -16,11 +16,8 @@ jobs: with: version: "1" - name: Use Github Registry - run: | - cd examples - julia -e 'using Pkg; Pkg.Registry.rm("General"); Pkg.Registry.add(RegistrySpec(url="https://github.com/JuliaRegistries/General"))' - julia --project -e 'using Pkg; Pkg.instantiate();' + run: julia -e 'using Pkg; Pkg.Registry.rm("General"); Pkg.Registry.add(RegistrySpec(url="https://github.com/JuliaRegistries/General"))' + - name: Install Dependencies + run: julia --project=examples/ -e 'using Pkg; Pkg.develop(path="."); Pkg.instantiate();' - name: Run Tests - run: | - cd examples - julia --project example.jl + run: julia --project=examples/ examples/example.jl diff --git a/Project.toml b/Project.toml index e51cdcba..3d20b022 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "Land" -uuid = "a4d78162-daa3-41d7-a3fe-155b9207f750" -authors = ["Yujie Wang "] +uuid = "27e3c115-2cb8-4114-b7a5-cd9f011f9dcc" +authors = ["CliMA Land Team"] version = "0.1.1" [deps] diff --git a/docs/Project.toml b/docs/Project.toml index b44bfb75..af573568 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,4 +1,3 @@ [deps] Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" Land = "27e3c115-2cb8-4114-b7a5-cd9f011f9dcc" -TextIO = "52be8cd1-7bc6-40f3-9b52-aa7544d4b77d" diff --git a/docs/src/examples/CanopyLayers/bigleaf.jl b/docs/src/examples/CanopyLayers/bigleaf.jl deleted file mode 100644 index e0c5b4c9..00000000 --- a/docs/src/examples/CanopyLayers/bigleaf.jl +++ /dev/null @@ -1,111 +0,0 @@ -# # Big Leaf Model - -## load packages -using Land.CanopyLayers -using PlotPlants -FT = Float32; -#------------------------------------------------------------------------------ - - - - -# ## Sunlit and shaded layers -# ### vs. leaf area index -lais = collect(FT, 0.1:0.1:5.0); -lai_sl = similar(lais); -par_sl = similar(lais); par_sh = similar(lais); -rad_sl = similar(lais); rad_sh = similar(lais); -for i in eachindex(lais) - lai_sl[i], par_sl[i], par_sh[i], rad_sl[i], rad_sh[i] = - big_leaf_partition(lais[i], FT(30), FT(800)); -end - -_fig,_axes = create_canvas("vs LAI"; ncol=3); -_ax1,_ax2,_ax3 = _axes; -_ax1.plot(lais, lai_sl, "k-"); -_ax2.plot(lais, par_sl, "k-", label="Sunlit"); -_ax2.plot(lais, par_sh, "k:", label="Shaded"); -_ax3.plot(lais, rad_sl, "k-", label="Sunlit"); -_ax3.plot(lais, rad_sh, "k:", label="Shaded"); -_ax2.legend(loc="upper right"); -_ax3.legend(loc="upper right"); -set_xlabels!(_axes, ["Leaf area index" for i in 1:3]); -set_ylabels!(_axes, ["Sunlit fraction", "PAR (μmol m⁻² s⁻¹)", "Rabs (W m⁻²)"]); -_fig.set_tight_layout(true); -_fig -#------------------------------------------------------------------------------ - -# ### vs. zenith angle -angles = collect(FT, 5:5:75); -lai_sl = similar(angles); -par_sl = similar(angles); par_sh = similar(angles); -rad_sl = similar(angles); rad_sh = similar(angles); -for i in eachindex(angles) - lai_sl[i], par_sl[i], par_sh[i], rad_sl[i], rad_sh[i] = - big_leaf_partition(FT(3), angles[i], FT(800)); -end - -_fig,_axes = create_canvas("vs Zenith angle"; ncol=3); -_ax1,_ax2,_ax3 = _axes; -_ax1.plot(angles, lai_sl, "k-"); -_ax2.plot(angles, par_sl, "k-", label="Sunlit"); -_ax2.plot(angles, par_sh, "k:", label="Shaded"); -_ax3.plot(angles, rad_sl, "k-", label="Sunlit"); -_ax3.plot(angles, rad_sh, "k:", label="Shaded"); -_ax2.legend(loc="upper left"); -_ax3.legend(loc="upper left"); -set_xlabels!(_axes, ["Zenith angle (°)" for i in 1:3]); -set_ylabels!(_axes, ["Sunlit fraction", "PAR (μmol m⁻² s⁻¹)", "Rabs (W m⁻²)"]); -_fig.set_tight_layout(true); -_fig -#------------------------------------------------------------------------------ - -# ### vs. total radiation -rads = collect(FT, 50:50:1000); -lai_sl = similar(rads); -par_sl = similar(rads); par_sh = similar(rads); -rad_sl = similar(rads); rad_sh = similar(rads); -for i in eachindex(rads) - lai_sl[i], par_sl[i], par_sh[i], rad_sl[i], rad_sh[i] = - big_leaf_partition(FT(3), FT(30), rads[i]); -end - -_fig,_axes = create_canvas("vs Total radiation"; ncol=3); -_ax1,_ax2,_ax3 = _axes; -_ax1.plot(rads, lai_sl, "k-"); -_ax2.plot(rads, par_sl, "k-", label="Sunlit"); -_ax2.plot(rads, par_sh, "k:", label="Shaded"); -_ax3.plot(rads, rad_sl, "k-", label="Sunlit"); -_ax3.plot(rads, rad_sh, "k:", label="Shaded"); -_ax2.legend(loc="upper left"); -_ax3.legend(loc="upper left"); -set_xlabels!(_axes, ["Total radiation (W m⁻²)" for i in 1:3]); -set_ylabels!(_axes, ["Sunlit fraction", "PAR (μmol m⁻² s⁻¹)", "Rabs (W m⁻²)"]); -_fig.set_tight_layout(true); -_fig -#------------------------------------------------------------------------------ - -# ### vs. direct light fraction -dirs = collect(FT, 0.2:0.05:0.8); -lai_sl = similar(dirs); -par_sl = similar(dirs); par_sh = similar(dirs); -rad_sl = similar(dirs); rad_sh = similar(dirs); -for i in eachindex(dirs) - lai_sl[i], par_sl[i], par_sh[i], rad_sl[i], rad_sh[i] = - big_leaf_partition(FT(3), FT(30), FT(800), dirs[i]); -end - -_fig,_axes = create_canvas("vs Direct light fraction"; ncol=3); -_ax1,_ax2,_ax3 = _axes; -_ax1.plot(dirs, lai_sl, "k-"); -_ax2.plot(dirs, par_sl, "k-", label="Sunlit"); -_ax2.plot(dirs, par_sh, "k:", label="Shaded"); -_ax3.plot(dirs, rad_sl, "k-", label="Sunlit"); -_ax3.plot(dirs, rad_sh, "k:", label="Shaded"); -_ax2.legend(loc="upper left"); -_ax3.legend(loc="upper left"); -set_xlabels!(_axes, ["Direct light fraction" for i in 1:3]); -set_ylabels!(_axes, ["Sunlit fraction", "PAR (μmol m⁻² s⁻¹)", "Rabs (W m⁻²)"]); -_fig.set_tight_layout(true); -_fig -#------------------------------------------------------------------------------ diff --git a/docs/src/examples/CanopyLayers/fluspect.jl b/docs/src/examples/CanopyLayers/fluspect.jl deleted file mode 100644 index e948b000..00000000 --- a/docs/src/examples/CanopyLayers/fluspect.jl +++ /dev/null @@ -1,69 +0,0 @@ -# # Fluspect - -## load packages -using Land.CanopyLayers -using PlotPlants -FT = Float32; -#------------------------------------------------------------------------------ - - - - -# ## Excitation wavelength -wls = WaveLengths{FT}(); -can = Canopy4RT{FT}(); -rt_dim = RTDimensions(can, wls); -leaf = LeafBios{FT}(rt_dim); -fluspect!(leaf, wls); - -_fig,_axes = create_canvas("Fluspect example"; ncol=3); -_ax1,_ax2,_ax3 = _axes; -_ax1.plot(wls.WL, leaf.ρ_SW, "k-", label="Reflectance"); -_ax1.plot(wls.WL, leaf.τ_SW, "k:", label="Transmittance"); -_ax2.contourf(wls.WLE, wls.WLF, leaf.Mb); -_ax3.contourf(wls.WLE, wls.WLF, leaf.Mf); -_ax1.legend(loc="upper right"); -_ax1.set_ylim(0,0.65); -set_xlabels!(_axes, ["Wavelength (nm)", "Excitation wavelength (nm)", - "Excitation wavelength (nm)"], fontsize=12); -set_ylabels!(_axes, ["Reflectance or Transmittance", "SIF wavelength (nm)", - "SIF wavelength (nm)"], fontsize=12); -set_titles!(_axes; labels=["Spectrum", "Backward matrix", "Forward matrix"], - usetex=false); -_fig.set_tight_layout(true); -_fig -#------------------------------------------------------------------------------ - - - - -# ## Change leaf properties -## here we change all the properties at the same time as an example -leaf.N = 2.0; -leaf.Cab = 50.0; -leaf.Car = 15.0; -leaf.Ant = 0.1; -leaf.Cs = 0.1; -leaf.Cw = 0.02; -leaf.Cm = 0.02; -leaf.Cx = 0.1; -leaf.fqe = 0.8; -fluspect!(leaf, wls); - -_fig,_axes = create_canvas("Change leaf properties"; ncol=3); -_ax1,_ax2,_ax3 = _axes; -_ax1.plot(wls.WL, leaf.ρ_SW, "k-", label="Reflectance"); -_ax1.plot(wls.WL, leaf.τ_SW, "k:", label="Transmittance"); -_ax2.contourf(wls.WLE, wls.WLF, leaf.Mb); -_ax3.contourf(wls.WLE, wls.WLF, leaf.Mf); -_ax1.legend(loc="upper right"); -_ax1.set_ylim(0,0.65); -set_xlabels!(_axes, ["Wavelength (nm)", "Excitation wavelength (nm)", - "Excitation wavelength (nm)"], fontsize=12); -set_ylabels!(_axes, ["Reflectance or Transmittance", "SIF wavelength (nm)", - "SIF wavelength (nm)"], fontsize=12); -set_titles!(_axes; labels=["Spectrum", "Backward matrix", "Forward matrix"], - usetex=false); -_fig.set_tight_layout(true); -_fig -#------------------------------------------------------------------------------ diff --git a/docs/src/examples/CanopyLayers/scope.jl b/docs/src/examples/CanopyLayers/scope.jl deleted file mode 100644 index ef25d01a..00000000 --- a/docs/src/examples/CanopyLayers/scope.jl +++ /dev/null @@ -1,71 +0,0 @@ -# # SCOPE Model - -## load packages -using Land.CanopyLayers -using PlotPlants -FT = Float32; -#------------------------------------------------------------------------------ - - - - -# ## Initialization -# Besides the individual functions to initialize parameters for `CanopyLayers`, -# a general function is provided to initialize all the parameters directly. -angles, can, can_opt, can_rad, in_rad, leaves, rt_con, rt_dim, soil, wls = - initialize_rt_module(FT; nLayer=20, LAI=3); -#------------------------------------------------------------------------------ - - - - -# ## Steps -## 1. Update canopy optical properties (required) -canopy_geometry!(can, angles, can_opt, rt_con); -## 2. Update scattering coefficients (required) -canopy_matrices!(leaves, can_opt); -## 3. Simulate short wave simulation (required) -short_wave!(can, can_opt, can_rad, in_rad, soil, rt_con); -## 4. Update integrated radiation fluxes (required for photosynthesis) -canopy_fluxes!(can, can_opt, can_rad, in_rad, soil, leaves, wls, rt_con); -## 5. Update SIF related spectrum (required for SIF) -SIF_fluxes!(leaves, can_opt, can_rad, can, soil, wls, rt_con, rt_dim); -## 6. Update thermo fluxes (required for leaf energy budget) -thermal_fluxes!(leaves, can_opt, can_rad, can, soil, [FT(400.0)], wls); - -_fig,_axes = create_canvas("SIF example"; ncol=2); -_ax1,_ax2 = _axes; -_ax1.plot(wls.WL , can_rad.alb_obs, "k-"); -_ax2.plot(wls.WLF, can_rad.SIF_obs, "k-"); -set_xlabels!(_axes, ["Wave length (nm)" for i in 1:2], fontsize=12); -set_ylabels!(_axes, ["Albedo", "obs SIF (mW m⁻² nm⁻¹ sr⁻¹)"], fontsize=12); -_fig.set_tight_layout(true); -_fig -#------------------------------------------------------------------------------ - - - - -# ## Change FQE -for leaf in leaves - leaf.Cx = 0.5; - leaf.fqe = 0.004; - fluspect!(leaf, wls); -end -can.Ω = 0.48 -canopy_geometry!(can, angles, can_opt, rt_con); -canopy_matrices!(leaves, can_opt); -short_wave!(can, can_opt, can_rad, in_rad, soil, rt_con); -canopy_fluxes!(can, can_opt, can_rad, in_rad, soil, leaves, wls, rt_con); -SIF_fluxes!(leaves, can_opt, can_rad, can, soil, wls, rt_con, rt_dim); -thermal_fluxes!(leaves, can_opt, can_rad, can, soil, [FT(400.0)], wls); - -_fig,_axes = create_canvas("SIF example FQE"; ncol=2); -_ax1,_ax2 = _axes; -_ax1.plot(wls.WL , can_rad.alb_obs, "k-"); -_ax2.plot(wls.WLF, can_rad.SIF_obs, "k-"); -set_xlabels!(_axes, ["Wave length (nm)" for i in 1:2], fontsize=12); -set_ylabels!(_axes, ["Albedo", "obs SIF (mW m⁻² nm⁻¹ sr⁻¹)"], fontsize=12); -_fig.set_tight_layout(true); -_fig -#------------------------------------------------------------------------------ diff --git a/docs/src/examples/Photosynthesis/parasets.jl b/docs/src/examples/Photosynthesis/parasets.jl deleted file mode 100644 index 97047289..00000000 --- a/docs/src/examples/Photosynthesis/parasets.jl +++ /dev/null @@ -1,193 +0,0 @@ -# # Predefined parameter sets - -## load packages -using Land.Photosynthesis -using PlotPlants -FT = Float32; -#------------------------------------------------------------------------------ - - - - -# ## Jmax -_td_1 = JmaxTDBernacchi(FT); -_td_2 = JmaxTDCLM(FT); -_td_3 = JmaxTDLeuning(FT); -_ts = collect(FT, 273:1:323); -_jm_1 = photo_TD_from_val.([_td_1], FT(100), _ts); -_jm_2 = photo_TD_from_val.([_td_2], FT(100), _ts); -_jm_3 = photo_TD_from_val.([_td_3], FT(100), _ts); - -_fig,_axes = create_canvas("Jmax"); -_ax1 = _axes[1]; -_ax1.plot(_ts .- 273.15, _jm_1, "k-", label="Bernacchi"); -_ax1.plot(_ts .- 273.15, _jm_2, "k:", label="CLM"); -_ax1.plot(_ts .- 273.15, _jm_3, "k--", label="Leuning"); -_ax1.set_xlabel("Leaf temperature (°C)"); -_ax1.set_ylabel("Jcmax (μmol m⁻² s⁻¹)"); -_ax1.legend(loc="upper left"); -_fig -#------------------------------------------------------------------------------ - - - - -# ## Kc -_td_1 = KcTDBernacchi(FT); -_td_2 = KcTDCLM(FT); -_ts = collect(FT, 273:1:323); -_kc_1 = photo_TD_from_set.([_td_1], _ts); -_kc_2 = photo_TD_from_set.([_td_2], _ts); - -_fig,_axes = create_canvas("Kc"); -_ax1 = _axes[1]; -_ax1.plot(_ts .- 273.15, _kc_1, "k-", label="Bernacchi"); -_ax1.plot(_ts .- 273.15, _kc_2, "k:", label="CLM"); -_ax1.set_xlabel("Leaf temperature (°C)"); -_ax1.set_ylabel("Kc (Pa)"); -_ax1.legend(loc="upper left"); -_fig -#------------------------------------------------------------------------------ - - - - -# ## Ko -_td_1 = KoTDBernacchi(FT); -_td_2 = KoTDCLM(FT); -_ts = collect(FT, 273:1:323); -_ko_1 = photo_TD_from_set.([_td_1], _ts); -_ko_2 = photo_TD_from_set.([_td_2], _ts); - -_fig,_axes = create_canvas("Ko"); -_ax1 = _axes[1]; -_ax1.plot(_ts .- 273.15, _ko_1, "k-", label="Bernacchi"); -_ax1.plot(_ts .- 273.15, _ko_2, "k:", label="CLM"); -_ax1.set_xlabel("Leaf temperature (°C)"); -_ax1.set_ylabel("Ko (Pa)"); -_ax1.legend(loc="upper left"); -_fig -#------------------------------------------------------------------------------ - - - - -# ## Kpep -_td_1 = KpepTDBoyd(FT); -_td_2 = KpepTDCLM(FT); -_ts = collect(FT, 273:1:323); -_kp_1 = photo_TD_from_set.([_td_1], _ts); -_kp_2 = photo_TD_from_set.([_td_2], _ts); - -_fig,_axes = create_canvas("Kpep"); -_ax1 = _axes[1]; -_ax1.plot(_ts .- 273.15, _kp_1, "k-", label="Boyd"); -_ax1.plot(_ts .- 273.15, _kp_2, "k:", label="CLM"); -_ax1.set_xlabel("Leaf temperature (°C)"); -_ax1.set_ylabel("Kpep (Pa)"); -_ax1.legend(loc="upper left"); -_fig -#------------------------------------------------------------------------------ - - - - -# ## Respiration -_td_1 = RespirationTDBernacchi(FT); -_td_2 = RespirationTDCLM(FT); -_td_3 = Q10TDAngiosperm(FT); -_td_4 = Q10TDGymnosperm(FT); -_ts = collect(FT, 273:1:323); -_rd_1 = photo_TD_from_val.([_td_1], FT(1), _ts); -_rd_2 = photo_TD_from_val.([_td_2], FT(1), _ts); -_rd_3 = photo_TD_from_val.([_td_3], FT(1), _ts); -_rd_4 = photo_TD_from_val.([_td_4], FT(1), _ts); - -_fig,_axes = create_canvas("Respiration"); -_ax1 = _axes[1]; -_ax1.plot(_ts .- 273.15, _rd_1, "k-", label="Bernacchi"); -_ax1.plot(_ts .- 273.15, _rd_2, "k:", label="CLM"); -_ax1.plot(_ts .- 273.15, _rd_3, "r-", label="Q10 Angiosperm"); -_ax1.plot(_ts .- 273.15, _rd_4, "r:", label="Q10 Gymnosperm"); -_ax1.set_xlabel("Leaf temperature (°C)"); -_ax1.set_ylabel("Respiration (μmol m⁻² s⁻¹)"); -_ax1.legend(loc="upper left"); -_fig -#------------------------------------------------------------------------------ - - - - -# ## Vcmax -_td_1 = VcmaxTDBernacchi(FT); -_td_2 = VcmaxTDCLM(FT); -_td_3 = VcmaxTDLeuning(FT); -_ts = collect(FT, 273:1:323); -_vc_1 = photo_TD_from_val.([_td_1], FT(100), _ts); -_vc_2 = photo_TD_from_val.([_td_2], FT(100), _ts); -_vc_3 = photo_TD_from_val.([_td_3], FT(100), _ts); - -_fig,_axes = create_canvas("Vcmax"); -_ax1 = _axes[1]; -_ax1.plot(_ts .- 273.15, _vc_1, "k-", label="Bernacchi"); -_ax1.plot(_ts .- 273.15, _vc_2, "k:", label="CLM"); -_ax1.plot(_ts .- 273.15, _vc_3, "k--", label="Leuning"); -_ax1.set_xlabel("Leaf temperature (°C)"); -_ax1.set_ylabel("Vcmax (μmol m⁻² s⁻¹)"); -_ax1.legend(loc="upper left"); -_fig -#------------------------------------------------------------------------------ - - - - -# ## Vomax -_td_1 = VomaxTDBernacchi(FT); -_ts = collect(FT, 273:1:323); -_vo_1 = photo_TD_from_val.([_td_1], FT(100), _ts); - -_fig,_axes = create_canvas("Vomax"); -_ax1 = _axes[1]; -_ax1.plot(_ts .- 273.15, _vo_1, "k-", label="Bernacchi"); -_ax1.set_xlabel("Leaf temperature (°C)"); -_ax1.set_ylabel("Vomax (μmol m⁻² s⁻¹)"); -_ax1.legend(loc="upper left"); -_fig -#------------------------------------------------------------------------------ - - - - -# ## Vpmax -_td_1 = VpmaxTDBoyd(FT); -_ts = collect(FT, 273:1:323); -_vp_1 = photo_TD_from_val.([_td_1], FT(100), _ts); - -_fig,_axes = create_canvas("Vpmax"); -_ax1 = _axes[1]; -_ax1.plot(_ts .- 273.15, _vp_1, "k-", label="Boyd"); -_ax1.set_xlabel("Leaf temperature (°C)"); -_ax1.set_ylabel("Vpmax (μmol m⁻² s⁻¹)"); -_ax1.legend(loc="upper left"); -_fig -#------------------------------------------------------------------------------ - - - - -# ## Γ* -_td_1 = ΓStarTDBernacchi(FT); -_td_2 = ΓStarTDCLM(FT); -_ts = collect(FT, 273:1:323); -_Γs_1 = photo_TD_from_set.([_td_1], _ts); -_Γs_2 = photo_TD_from_set.([_td_2], _ts); - -_fig,_axes = create_canvas("Γ*"); -_ax1 = _axes[1]; -_ax1.plot(_ts .- 273.15, _Γs_1, "k-", label="Bernacchi"); -_ax1.plot(_ts .- 273.15, _Γs_2, "k:", label="CLM"); -_ax1.set_xlabel("Leaf temperature (°C)"); -_ax1.set_ylabel("Γ* (Pa)"); -_ax1.legend(loc="upper left"); -_fig -#------------------------------------------------------------------------------ diff --git a/docs/src/examples/Photosynthesis/photosynthesis.jl b/docs/src/examples/Photosynthesis/photosynthesis.jl deleted file mode 100644 index d790142c..00000000 --- a/docs/src/examples/Photosynthesis/photosynthesis.jl +++ /dev/null @@ -1,75 +0,0 @@ -# # Temperature dependencies - -## load packages -using Land.Photosynthesis -using PlotPlants -FT = Float32; -#------------------------------------------------------------------------------ - - - - -# ## Simple example -## define photosynthesis system and leaf (C3 and C4), and envir -c3_set = C3CLM(FT); -c4_set = C4CLM(FT); -leaf_3 = Leaf{FT}(APAR=1000); -leaf_4 = Leaf{FT}(APAR=1000); -envir = AirLayer{FT}(); - -## define leaf temperature, total leaf conductance to CO₂, and internal CO₂ -T = FT(300); -glc = FT(0.1); -p_i = rand(FT) + 20; - -## remember to update the temperature dependencies when temperature changes -println("initialize temperature dependencies"); -leaf_temperature_dependence!(c3_set, leaf_3, envir, T); -leaf_temperature_dependence!(c4_set, leaf_4, envir, T); - -println("calculate photosynthesis from known internal CO₂ partial pressure"); -leaf_photosynthesis!(c3_set, leaf_3, envir, PCO₂Mode(), p_i); -leaf_photosynthesis!(c4_set, leaf_4, envir, PCO₂Mode(), p_i); -@show leaf_3.An; -@show leaf_4.An; - -println("calculate photosynthesis from known leaf conductance to CO₂"); -leaf_photosynthesis!(c3_set, leaf_3, envir, GCO₂Mode(), glc); -leaf_photosynthesis!(c4_set, leaf_4, envir, GCO₂Mode(), glc); -@show leaf_3.An; -@show leaf_4.An; -#------------------------------------------------------------------------------ - - - - -# ## A-Ci curve -# Here we show an example of the A-Ci curves for C3 and C4 photosynthesis. As -# stomatal conductance may differ when other environmental conditions -# change, we leave the examples of photosynthesis responses to the -# environment for `StomataModels` package. -## temperature not changing, no temperature dependencies update required -_p3 = collect(FT, 5:1:200); -_p4 = collect(FT, 0:0.1:15.01); -_a3 = similar(_p3); -_a4 = similar(_p4); -for i in eachindex(_p3) - leaf_photosynthesis!(c3_set, leaf_3, envir, PCO₂Mode(), _p3[i]); - _a3[i] = leaf_3.An; -end -for i in eachindex(_p4) - leaf_photosynthesis!(c4_set, leaf_4, envir, PCO₂Mode(), _p4[i]); - _a4[i] = leaf_4.An; -end - -_fig,_axes = create_canvas("A-Ci curve"; ncol=2); -_ax1,_ax2 = _axes; -_ax1.plot(_p3, _a3, "k-", label="C3"); -_ax2.plot(_p4, _a4, "k-", label="C4"); -_ax1.set_xlabel("Leaf internal CO₂ (Pa)"); -_ax1.set_ylabel("Anet (μmol m⁻² s⁻¹)"); -_ax2.set_xlabel("Leaf internal CO₂ (Pa)"); -_ax1.legend(loc="lower right"); -_ax2.legend(loc="lower right"); -_fig -#------------------------------------------------------------------------------ diff --git a/docs/src/examples/Photosynthesis/temperature.jl b/docs/src/examples/Photosynthesis/temperature.jl deleted file mode 100644 index 0f6d3d52..00000000 --- a/docs/src/examples/Photosynthesis/temperature.jl +++ /dev/null @@ -1,55 +0,0 @@ -# # Temperature dependencies - -## load packages -using Land.Photosynthesis -using PlotPlants -FT = Float32; -#------------------------------------------------------------------------------ - - - - -# ## Arrhenius correction -# ### Without deactivation term -## KcTDCLM is a ArrheniusTD type struct, use it as an example here -_td = KcTDCLM(FT); -_ts = collect(FT, 273:1:323); -_ks = temperature_correction.([_td], _ts); - -_fig,_axes = create_canvas("Arrhenius correction without deactivation"); -_ax1 = _axes[1]; -_ax1.plot(_ts .- 273.15, _ks, "k-"); -_ax1.set_xlabel("Leaf temperature (°C)"); -_ax1.set_ylabel("Relative to 25 °C"); -_fig -#------------------------------------------------------------------------------ - -# ### With deactivation term -## VcmaxTDCLM is a ArrheniusPeakTD type struct, use it as an example here -_td = VcmaxTDCLM(FT); -_ts = collect(FT, 273:1:323); -_ks = temperature_correction.([_td], _ts); - -_fig,_axes = create_canvas("Arrhenius correction with deactivation"); -_ax1 = _axes[1]; -_ax1.plot(_ts .- 273.15, _ks, "k-"); -_ax1.set_xlabel("Leaf temperature (°C)"); -_ax1.set_ylabel("Relative to 25 °C"); -_fig -#------------------------------------------------------------------------------ - - - - -# ## Q10 correction -_td = Q10TD{FT}(1.0, 273.15, 1.7); -_ts = collect(FT, 273:1:323); -_ks = temperature_correction.([_td], _ts); - -_fig,_axes = create_canvas("Q10 correction"); -_ax1 = _axes[1]; -_ax1.plot(_ts .- 273.15, _ks, "k-"); -_ax1.set_xlabel("Leaf temperature (°C)"); -_ax1.set_ylabel("Relative to 25 °C"); -_fig -#------------------------------------------------------------------------------ diff --git a/docs/src/index.md b/docs/src/index.md index 12ba9943..3e6a5fd4 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -1,9 +1,9 @@ -# CliMA Land Model +# CliMA Land Model v0.1 -## Install CliMA Land Model +## Install CliMA Land Model v0.1 ``` julia> using Pkg -julia> Pkg.add(PackageSpec(url="https://github.com/CliMA/Land.git")) +julia> Pkg.add(PackageSpec(url="https://github.com/silicormosia/clima-land-v0.1.git")) julia> using Land ``` diff --git a/docs/src/submodules/CanopyLayers.md b/docs/src/submodules/CanopyLayers.md index ed3860a9..25d8b0d2 100644 --- a/docs/src/submodules/CanopyLayers.md +++ b/docs/src/submodules/CanopyLayers.md @@ -41,14 +41,6 @@ initialize_rt_module -## Big Leaf Model -```@docs -big_leaf_partition -``` - - - - ## SCOPE Model ```@docs canopy_fluxes! diff --git a/docs/src/submodules/Photosynthesis.md b/docs/src/submodules/Photosynthesis.md index b39c66e7..dc642a82 100644 --- a/docs/src/submodules/Photosynthesis.md +++ b/docs/src/submodules/Photosynthesis.md @@ -312,3 +312,11 @@ The function that is used to compute fluorescene is ```@docs leaf_fluorescence! ``` + + + + +## Misc +```@docs +C3Cytochrome +``` diff --git a/docs/src/submodules/SoilPlantAirContinuum.md b/docs/src/submodules/SoilPlantAirContinuum.md index f3ff0a6f..39a28357 100644 --- a/docs/src/submodules/SoilPlantAirContinuum.md +++ b/docs/src/submodules/SoilPlantAirContinuum.md @@ -5,18 +5,7 @@ CurrentModule = Land.SoilPlantAirContinuum ## Types ```@docs -SPACContainer1L -SPACContainer2L SPACMono -SPACSimple -``` - -## Soil -```@docs -soil_moisture_swc! -soil_moisture_p! -soil_moisture_p25! -soil_moisture! ``` ## Planet @@ -26,29 +15,3 @@ atmospheric_pressure ppm_to_Pa zenith_angle ``` - -## Big-leaf model -```@docs -gain_risk_map -leaf_gas_exchange_nonopt! -leaf_gas_exchange! -optimize_flows! -big_leaf_partition! -radiative_conductance -black_body_emittance -boundary_layer_conductance -leaf_temperature -leaf_temperature_sunlit -leaf_temperature_shaded -annual_profit -annual_simulation! -create_dataframe -initialize_spac_canopy! -``` - -## Optimal investment -```@docs -leaf_allocation! -optimize_leaf! -optimize_hs! -``` diff --git a/docs/src/tips.md b/docs/src/tips.md index 814f8a82..c23ace8b 100644 --- a/docs/src/tips.md +++ b/docs/src/tips.md @@ -1,4 +1,4 @@ -# Git and Julia Tips for CliMA.Land +# Git and Julia Tips for CliMA Land v0.1 ## Instantiate the project 1. The Land project diff --git a/docs/src/tutorial_scripts/GSV_soil_model.jl b/docs/src/tutorial_scripts/GSV_soil_model.jl deleted file mode 100644 index d2b2118e..00000000 --- a/docs/src/tutorial_scripts/GSV_soil_model.jl +++ /dev/null @@ -1,93 +0,0 @@ -# # # GSV: a general model for hyperspectral soil reflectance simulation -# -# Soil reflectance is crucial for canopy radiative transfer modeling. Spectral vector models are more flexible than typical soil albedo models, because they can ingest observed data and significantly improves hyperspectral soil reflectance modeling in terms of accuracy and robustness. -# -# We demonstrate the usage of the general spectral vectors (GSV) model[^1] developed to employ three dry spectral vectors and one humid spectral vector derived from global dry and humid soil reflectance databases including 23,871 soil spectra (400–2500 nm). The GSV model accurately simulates global soil reflectance with an R2 of 0.99 and RMSE of 0.01. The GSV model is highly suitable to be coupled with the CliMA model for vegetation remote sensing studies. -# -# [^1]: Jiang, C., & Fang, H. (2019). GSV: a general model for hyperspectral soil reflectance simulation. International Journal of Applied Earth Observation and Geoinformation, 83(July), 101932. https://doi.org/10.1016/j.jag.2019.101932 -# - -# # Load used packages - -#### Use Julia Plots package and switch to plotly js option: -using Plots -using StatsPlots -pyplot() - -##---------------------------------------------------------------------------- - -## First, we include Revise (good for debugging) and Parameters (tools for structures) - -##using Revise -using Parameters -using Statistics -using CSV -using DataStructures - -##---------------------------------------------------------------------------- -using LinearAlgebra -#---------------------------------------------------------------------------- - -# # Define used variables - -## The hyperspectral wavelengths -WVL = 400:10:2501 -## The general spectral vectors derived in the manuscript -GSV = [CSV.read("DryVec.csv"; header=false);CSV.read("SMVec.csv"; header=false)] -## The test hyperspectral data -hyper = CSV.read("TestSpectrum_v1.csv";header=false) -## The wavelengths of multispectral data -wvl = [450,550,650,850,1650,2150] -## The test multispectral data sliced from hyperspectral data -indices = [] - -for i in wvl - push!(indices, findall(x -> x==i, WVL)[1]) -end - -multi = hyper[:,indices] - - -## Step 1: slice GSV according to the wavelengths of multispectral data -gsv = GSV[:,indices] -#---------------------------------------------------------------------------- - -# # Define plot - -## Step 2: fit multispectral soil reflectance and reconstruct multispectral soil reflectance -X=convert(Matrix,multi) -V=convert(Matrix,gsv) -C = X * LinearAlgebra.pinv(V) -R = C * V -R[R.<0] .= 0 -R[R.>1] .= 1 -#---------------------------------------------------------------------------- - -scatter(X,R,label="") -plot!([0,0.4],[0,0.4],label="") -ylabel!("Simulations") -xlabel!("Measurements") -#---------------------------------------------------------------------------- - -## Step 3: reconstruct hyperspectral soil reflectance using coefficients fitted from multispectral data -X = convert(Matrix,hyper) -V = convert(Matrix,GSV) -R = C * V -R[R.<0] .= 0 -R[R.>1] .= 1 -#---------------------------------------------------------------------------- - -scatter(X,R,label="") -plot!([0,0.4],[0,0.4],label="") -ylabel!("Simulations") -xlabel!("Measurements") -#---------------------------------------------------------------------------- - -## Compare measured multispectral data and hyperspectral data with reconstructed ones -plot(WVL,transpose(convert(Matrix,hyper)),label="Actual hyperspectral reflectance") -scatter!(wvl,transpose(Matrix(multi)),label="Observed multispectral reflectance") -plot!(WVL,transpose(R),label="Simulated hyperspectral reflectance\nfitted from multispectral reflectance") -ylabel!("Soil albedo") -xlabel!("wl (nm)") - -#---------------------------------------------------------------------------- diff --git a/docs/src/tutorial_scripts/Leaf-Photosynthesis-Rates.jl b/docs/src/tutorial_scripts/Leaf-Photosynthesis-Rates.jl deleted file mode 100644 index 43d991a5..00000000 --- a/docs/src/tutorial_scripts/Leaf-Photosynthesis-Rates.jl +++ /dev/null @@ -1,113 +0,0 @@ - -# # Rate Constants, T-dependence -# Here, we will just briefly summarize how temperature affects enzymatic rate constants and how much uncertainty there actually is in literature (in terms of how to best define them and how plastic some of the variables are) - -## Add usual tools we use: -#using Revise -using BenchmarkTools - -# Use PyPlot to plot figures -using PyPlot - -#---------------------------------------------------------------------------- - -## load Photosynthesis module: -using Land.Photosynthesis -#---------------------------------------------------------------------------- - -## Specify Field Type -const FT = Float32 -#---------------------------------------------------------------------------- - -# ## T-dependence of V$_{c,max}$ -# In literature, there are different implementations of the temperature dependence of enzymatic reaction rates. Common among all of them is a typical Arrhenius formulation with Activation energy $E_a$, which leads to a temperature dependence of a quantity $V$ given the standard value defined at 25°C as $T_{ref}$. -# -# $$V(T)= V(T_{ref})\, \underbrace{\exp\left(\frac{E_a}{RT_{ref}}-\frac{E_a}{RT}\right)}_{\text{Activation}}$$ -# -# Other formulations add de-activation of proteins due to denaturalization at higher temperatures: -# $$V(T)= V(T_{ref})\, \exp\left(\frac{E_a}{RT_{ref}}-\frac{E_a}{RT}\right) \underbrace{\frac{1+\exp\left((\Delta ST_{ref}-H_d)/RT_{ref}\right)}{1+\exp\left((\Delta ST-H_d)/RT\right)}}_{\text{de-activation}} $$ -# which includes an entropy term $\Delta S$ and the energy for deactivation $H_d$. -# -# To illustrate the differences, we show two different implementations, one only using the activation part based on Bernacchi et al 2001[^1] and one with the typical CLM5 implementation. -# -# [^1]: Bernacchi, C.J., Singsaas, E.L., Pimentel, C., Portis Jr, A.R. and Long, S.P., 2001. Improved temperature response functions for models of Rubisco‐limited photosynthesis. Plant, Cell & Environment, 24(2), pp.253-259. -# - -## This looks a bit more tedious here than it needs to but in reality - -vcmax_Bernacchi = Float32[] -vcmax_CLM = Float32[] - -## Define T-range -Tleaf = collect(FT,260.0:1.0:315.0) - -## Run through temperatures and save Vcmax values: -td_vc_bernacchi = Photosynthesis.VcmaxTDBernacchi(FT) -td_vc_clm = Photosynthesis.VcmaxTDCLM(FT) -for T in Tleaf - _Vcmax = Photosynthesis.photo_TD_from_val(td_vc_bernacchi, FT(100.0), T) - push!(vcmax_Bernacchi, _Vcmax) - _Vcmax = Photosynthesis.photo_TD_from_val(td_vc_clm, FT(100.0), T) - push!(vcmax_CLM, _Vcmax) -end -#---------------------------------------------------------------------------- - -figure() -plot(Tleaf .- 273.15, vcmax_Bernacchi, label="Bernacchi", lw=2) -plot(Tleaf .- 273.15, vcmax_CLM, label="CLM5", lw=2) -ylabel("Vcmax (µmol/m²/s)") -xlabel("Leaf Temperature (°C)") -legend() -gcf() -#---------------------------------------------------------------------------- - -# ### CO$_2$ compensation point $\Gamma_\star$ - -## Here, we only have one implementation: -Γ_CLM = Float32[] -Tleaf = collect(FT,260.0:1.0:315.0) -td_gamma_clm = Photosynthesis.ΓStarTDCLM(FT) - -for T in Tleaf - _ΓStar = Photosynthesis.photo_TD_from_set(td_gamma_clm, T) - push!(Γ_CLM, _ΓStar) -end -#---------------------------------------------------------------------------- -figure() -plot(Tleaf .- 273.15, Γ_CLM, label="Γ_CLM") -ylabel("Γ⋆ (Pa)") -xlabel("Leaf Temperature (°C)") -legend() -gcf() -#---------------------------------------------------------------------------- - -# ## T-dependence of J$_{max}$ - -Jmax_Bernacchi = Float32[] -Jmax_CLM = Float32[] -Tleaf = collect(FT,260.0:1.0:315.0) - -td_j_bernacchi = Photosynthesis.JmaxTDBernacchi(FT) -td_j_clm = Photosynthesis.JmaxTDCLM(FT) - -for T in Tleaf - _Jmax = Photosynthesis.photo_TD_from_val(td_j_bernacchi, FT(100.0), T) - push!(Jmax_Bernacchi, _Jmax) - _Jmax = Photosynthesis.photo_TD_from_val(td_j_clm, FT(100.0), T) - push!(Jmax_CLM, _Jmax) -end -#---------------------------------------------------------------------------- -figure() -plot(Tleaf .- 273.15, Jmax_Bernacchi, label="Bernacchi") -plot(Tleaf .- 273.15, Jmax_CLM, label="CLM5") -ylabel("Jmax (µmol/m2/s)") -xlabel("Leaf Temperature (°C)") -legend() -gcf() -#---------------------------------------------------------------------------- - -# --- -# ## Summary -# The way land surface models implement temperature variations in V$_{c,max}$ is still rather variable and there is no clear consensus in what model is best. In addition, gas exchange datasets performed at different temperatures might actually alias different confounding factors into the V$_{c,max}$ determination, so that the actually fitted V$_{c,max}$ strongly depends on the model formulation. E.g. mesophyll conductance is usually ignore in deriving V$_{c,max}$ but might be temperature dependent, which can cause T-dependent errors in V$_{c,max}$. -# -# That said, having the option to use different model forumations and actually using the ones that are implemented in land surface models directly when fitting leaf level measurements seems to be a prudent way to improve models in the future. More leaf level data might help in the future, especially looking at temperature dependencies, mesophyll conductance, and fluorescence yields. So many chemical and phsyical aspects change with temperature that it is hard to isolate impacting factors. Now, at least, we can run the models directly in the REPL, which is great for prototyping anc validating the model on the individual module level without any effort in terms of additional coding. diff --git a/docs/src/tutorial_scripts/Leaf-Photosynthesis-Synthesis.jl b/docs/src/tutorial_scripts/Leaf-Photosynthesis-Synthesis.jl deleted file mode 100644 index b7e8aa47..00000000 --- a/docs/src/tutorial_scripts/Leaf-Photosynthesis-Synthesis.jl +++ /dev/null @@ -1,336 +0,0 @@ - -# # Leaf Level Photosynthesis -# -# Here, we will go one step further and look at the entire leaf-level response, including the impact of stomatal conductance as well. - -# ## Stomatal Conductance -# Before, we focussed mainly on the demand-driven constraints through Rubisco and RuBP regeneration. Stomatal conductance is highly important as it drives the suppy-side of photosynthesis and interacts with the energy balance and leaf temperature as latent heat fluxes are a major factor in surface cooling. -# -# Before, we have derived net rates of photosynthesis $A_n$, which have to be matched with the supply side through CO$_2$ diffusion: -# -# $$A_n^{diff} = g_{leaf,C}(C_a-C_c)$$ -# -# which can be separated into diffusion from the air to the leaf surface with a boundary layer conductance $g_{b,C}$, diffusion from the surface to the interstitial air-space with stomatal conductance $g_{s,C}$ and diffusion from the interstitial air-space to the chloroplast with mesophyll conductance $g_{m,C}$ (the letter C stands for CO2 here, as the diffusion constants vary with species, e.g. H$_2$O stomatal conductance is a factor 1.6 higher than those for CO$_2$): -# -# $$A_n^{diff} = g_{b,C}(C_a-C_s) = g_{s,C}(C_s-C_i) = g_{m,C}(C_i-C_c) = g_{leaf,C}(C_a-C_c)$$ -# -# $$g_{leaf,C} = \left(\frac{1}{g_{b,C}+g_{s,C}+g_{m,C}}\right)^{-1}$$ -# -# The importance of stomatal conductance and its interplay with photosynthesis here is that the supply and demand rates determine $C_c$. A reduction in $C_c$ reduces the demand-limited rates while it increase the diffusion rates (at a given $g$). Most models run internal so-called A-$C_c$ iterations to ensure both rates are balanced and in steady-state ($\partial C_c/\partial t=0$). We implement this option but also opt to run stomatal conductance prognostically, as stomata don't open and close instantanously but have a response time of around 15 minutes. -# -# ### Empirical Stomatal Conductance models -# -# Currently, we can choose between the widely used Ball-Berry model[^1] or the Medlyn approach[^2]. -# -# Ball and Berry derived the following empirical formulation based on leaf level data (RH is relative humidity): -# -# $$g_{s,w} = g_0 + g_1 \frac{A_n \cdot RH}{C_s}$$ -# -# Medlyn derived the following equations based on stomatal optimization theory but in a similar form as the BB model: -# -# $$g_{s,w} = g_0 + \left(1 + \frac{g_1}{\sqrt{VPD}}\right) \frac{A_n}{C_s}$$ -# -# Both models are proportional to $A_n$ and inversely proportional to $C_s$, with the main difference in the dependence on either relative humidity in the Ball-Berry model vs. vapor pressure deficit (VPD) in Medlyn et al. In both cases, $g_0$ is the residual conductivity even if stomata are fully closed and $g_1$ is related to the marginal water cost of plant carbon gain. Importantly, $g_1$ can't be inter-changed between the formulations, underlining again that parameters have to be optimized with respect to the model that is eventually being used. -# -# ### Stomatal Optimization Theories -# -# The empirical formulations only hold in well-watered soil and our main goal is to implement stomatal optimization models to take the entire soil-plant-atmosphere continuum into account[^3]. Here, we will just use the empirical models and steady-state photosynthesis to show the underlying principles. -# -# [^1]: Ball, J.T., Woodrow, I.E. and Berry, J.A., 1987. A model predicting stomatal conductance and its contribution to the control of photosynthesis under different environmental conditions. In Progress in photosynthesis research (pp. 221-224). Springer, Dordrecht. -# -# [^2]: Medlyn, B.E., Duursma, R.A., Eamus, D., Ellsworth, D.S., Prentice, I.C., Barton, C.V., Crous, K.Y., De Angelis, P., Freeman, M. and Wingate, L., 2011. Reconciling the optimal and empirical approaches to modelling stomatal conductance. Global Change Biology, 17(6), pp.2134-2144. -# -# [^3]: Wang, Y., Sperry, J.S., Anderegg, W.R., Venturas, M.D. and Trugman, A.T., 2020. A theoretical and empirical assessment of stomatal optimization modeling. New Phytologist. -# - - - - - - - - -## Add usual tools we use: -##using Revise -using BenchmarkTools -using PyPlot -#---------------------------------------------------------------------------- - -## load Photosynthesis module: -using Land.Photosynthesis -#---------------------------------------------------------------------------- - -## Specify Field Type -const FT = Float64 -#---------------------------------------------------------------------------- - -## Create a standard leaf with defualt parameters -leaf3 = Leaf{FT}(APAR=1200, Vcmax25=90, Jmax25=90*1.9, Vpmax25=100, Rd25=1); -leaf4 = Leaf{FT}(APAR=1200, Vcmax25=90, Jmax25=90*1.9, Vpmax25=100, Rd25=1); -## Create a standard meteo structure: -envir = AirLayer{FT}(); -#---------------------------------------------------------------------------- - -## Setting some standard values (dynamic-state=false forces A-Cc iterations) -##leaf.dynamic_state = false -#---------------------------------------------------------------------------- - -# --- -# ## Modular stucture: -# The most important step is to define which submodules to use. There might be different implementations for Fluorescence, Photosynthesis (C3,C4,etc), respiration, stomatal conductance (e.g. Ball-Berry, Medlyn), the T-dependence of J$_{max}$, V$_{c,max}$ and Michaelis Menten constants as well as leaf boundary layer resistance (setting it to 0 here to mimic well vented laboratory leaf level measurements) and colimitation. -# -# Below, we create two different model setups with a C3 and C4 photosynthesis pathway. Note that we chose the Ball Berry stomatal conductance model with different $g_1$ for C3 and C4 (C4 typically much lower). - -## use this as the boundary layer resistance (1/gb) -## deprecated as there are g_bw and g_bc terms in Leaf struct -## ra = FT(0.5) - -## C3 Photosynthesis -# Use pre-defined parameter sets -modC3 = C3CLM(FT) -#modC3.Sto = Photosynthesis.OSMWang() -modC3.Sto = Photosynthesis.ESMBallBerry{FT}(g1 = 16) - -## C4 Photosynthesis -modC4 = C4CLM(FT) -#modC4.Sto = Photosynthesis.OSMWang() -modC4.Sto = Photosynthesis.ESMBallBerry{FT}(g1 = 8) -#---------------------------------------------------------------------------- - -# ## Light response curves -# Now we can compute light response curves for C3 and C4 photosynthesis - -##Again, this looks tedious and repetitive but is the easiest way to do this right now: - -## Variable I want to save: -Ag_C3 = Float32[]; Ag_C4 = Float32[] -An_C3 = Float32[]; An_C4 = Float32[] -Aj_C3 = Float32[]; Aj_C4 = Float32[] -Ap_C3 = Float32[]; Ap_C4 = Float32[] -Ac_C3 = Float32[]; Ac_C4 = Float32[] -Cc_C3 = Float32[]; Cc_C4 = Float32[] -gs_C3 = Float32[]; gs_C4 = Float32[] - -APAR = collect(FT, 0:10:1700) -for _APAR in APAR - leaf3.APAR = _APAR; - leaf4.APAR = _APAR; - ## Run C3 photosynthesis (general photosynthesis model): - leaf_photo_from_envir!(modC3, leaf3, envir, modC3.Sto); - ## Save leaf variables: - push!(An_C3, leaf3.An); push!(Ag_C3, leaf3.Ag); - push!(Aj_C3, leaf3.Aj); push!(Ap_C3, leaf3.Ap); - push!(Ac_C3, leaf3.Ac); push!(Cc_C3, leaf3.p_i); - push!(gs_C3, leaf3.g_sw); - - ## Run C4 photosynthesis: - leaf_photo_from_envir!(modC4, leaf4, envir, modC4.Sto); - ## Save leaf variables: - push!(An_C4, leaf4.An); push!(Ag_C4, leaf4.Ag); - push!(Aj_C4, leaf4.Aj); push!(Ap_C4, leaf4.Ap); - push!(Ac_C4, leaf4.Ac); push!(Cc_C4, leaf4.p_i); - push!(gs_C4, leaf4.g_sw); -end -#---------------------------------------------------------------------------- - -## Testing some times, how long does this take (as we need to run it globally, it has to be efficient)? -## Slow for now, because of unnecessary allocations -## Will improve when the structs are cleaned up -#@btime leaf_photo_from_envir!(modC3, leaf3, envir, modC3.Sto); -#@btime leaf_photo_from_envir!(modC4, leaf4, envir, modC4.Sto); -#---------------------------------------------------------------------------- - -# ## C3 Light Response Curve - -##plot(APAR, An, label="An") -figure() -plot(APAR, Ag_C3,color=:black,lw=2, alpha=0.7, label="Ag C3") -plot(APAR, Ac_C3, ls="--", lw=2, label="Ac C3") -plot(APAR, Aj_C3, ls="--", lw=2, label="Aj C3") -plot(APAR, Ap_C3, ls="--", lw=2, label="Ap C3" ) -xlabel("APAR [μmol/m2/s]") -ylabel("Aᵢ [μmol/m2/s]") -title("C3 photosynthesis light response") -legend() -gcf() -#---------------------------------------------------------------------------- - -# ## C4 Light Response Curve - -##plot(APAR, An, label="An") -figure() -plot(APAR, Ag_C4,color=:black, lw=2, alpha=0.7, label="Ag C4") -plot(APAR, Ac_C4, ls="--", lw=2, label="Ac C4") -plot(APAR, Aj_C4, ls="--", lw=2, label="Aj C4") -plot(APAR, Ap_C4, ls="--", lw=2, label="Ap C4" ) -xlabel("APAR [μmol/m2/s]") -ylabel("Aᵢ [μmol/m2/s]") -title("C4 photosynthesis light response") -legend() -gcf() -#---------------------------------------------------------------------------- - -# ### Dependence of $C_c$ on light -# Increasing light should result in overall lower $C_c$ concentrations. C4 plants can work with much lower $C_c$ as for C4, the concentration in the bundle sheath cells count, not the mesophyll. - -figure() -plot(APAR, Cc_C4/envir.p_a,color=:black ,lw=2, alpha=0.7, label="Cc/Ca C4") -plot(APAR, Cc_C3/envir.p_a,color=:orange,lw=2, alpha=0.7, label="Cc/Ca C3") -xlabel("APAR [μmol/m²/s]") -ylabel("Cc/Ca [-]") -legend() -gcf() -#---------------------------------------------------------------------------- - -# ### Dependence of stomatal coductance g$_s$ - -#This part has been broken by Yuije, please fix it -figure() -plot(APAR, gs_C4,color=:black ,lw=2, alpha=0.7, label="gs C4") -plot(APAR, gs_C3,color=:orange,lw=2, alpha=0.7, label="gs C3") -xlabel("APAR [μmol/m²/s]") -ylabel("gs") -legend() -gcf() -#---------------------------------------------------------------------------- - - -# ## More complex examples: - -##Again, this looks tedious and repetitive but is the easiest way to do this right now: - -## Now I want to vary T, APAR and CO2: -## Start CO2 from 100 ppm to make sure it is higher than Γ* -APAR = [100.0, 250.0, 500.0, 1000.0, 1500.0] -CO2 = collect(100:20:800) -T = collect(274:2:310) - -n1 = length(APAR); -n2 = length(CO2); -n3 = length(T); - -Ag_C3 = zeros(n1,n2,n3); Ag_C4 = zeros(n1,n2,n3) -An_C3 = zeros(n1,n2,n3); An_C4 = zeros(n1,n2,n3) -Aj_C3 = zeros(n1,n2,n3); Aj_C4 = zeros(n1,n2,n3) -Ap_C3 = zeros(n1,n2,n3); Ap_C4 = zeros(n1,n2,n3) -Ac_C3 = zeros(n1,n2,n3); Ac_C4 = zeros(n1,n2,n3) -Cc_C3 = zeros(n1,n2,n3); Cc_C4 = zeros(n1,n2,n3) -gs_C3 = zeros(n1,n2,n3); gs_C4 = zeros(n1,n2,n3) - -#---------------------------------------------------------------------------- - -## Run this over all potential 3D dimensions: - -## I really like the compact form of nested loops in Julia! -for iA in eachindex(APAR), iC in eachindex(CO2), iT in eachindex(T) - #println(iA, "/", iC, "/", iT) - envir.p_a = CO2[iC]/10; - leaf3.T = T[iT]; - leaf3.APAR = APAR[iA]; - leaf4.T = T[iT]; - leaf4.APAR = APAR[iA]; - - ## Run C3 photosynthesis: - leaf_photo_from_envir!(modC3, leaf3, envir, modC3.Sto); - - ## Save leaf variables: - An_C3[iA,iC,iT]=leaf3.An; - Ag_C3[iA,iC,iT]=leaf3.Ag; - Aj_C3[iA,iC,iT]=leaf3.Aj; - Ap_C3[iA,iC,iT]=leaf3.Ap; - Ac_C3[iA,iC,iT]=leaf3.Ac; - Cc_C3[iA,iC,iT]=leaf3.p_i; - gs_C3[iA,iC,iT]=leaf3.g_sw; - - ## Run C4 photosynthesis: - leaf_photo_from_envir!(modC4, leaf4, envir, modC4.Sto); - - ## Save leaf variables: - An_C4[iA,iC,iT]=leaf4.An; - Ag_C4[iA,iC,iT]=leaf4.Ag; - Aj_C4[iA,iC,iT]=leaf4.Aj; - Ap_C4[iA,iC,iT]=leaf4.Ap; - Ac_C4[iA,iC,iT]=leaf4.Ac; - Cc_C4[iA,iC,iT]=leaf4.p_i; - gs_C4[iA,iC,iT]=leaf4.g_sw; -end -#---------------------------------------------------------------------------- - -# #### Plotting 2D contours of A$_n$ vs. CO$_2$ and Temperature - -##Let's take one slice in APAR space: -i = 4 - -## and plot: -figure() -contourf(T.-273.15, CO2, An_C3[i,:,:]) -xlabel("T [°C]") -ylabel("Ambient CO₂ [ppm]") -title("C3 , An [μmol/m²/s] at APAR=$(APAR[i])") -colorbar() -gcf() -#---------------------------------------------------------------------------- - -## Same for C4 plants, why is it so different?? - -figure() -contourf(T.-273.15, CO2, Cc_C4[i,:,:]) -xlabel("T [°C]") -ylabel("Ambient CO₂ [ppm]") -title("C4 , Cc [Pa] at APAR=$(APAR[i])") -colorbar() -gcf() -#---------------------------------------------------------------------------- - - -## Same for C4 plants, why is it so different?? - -figure() -contourf(T.-273.15, CO2, An_C4[i,:,:]) -xlabel("T [°C]") -ylabel("Ambient CO₂ [ppm]") -title("C4 , An [μmol/m²/s] at APAR=$(APAR[i])") -colorbar() -gcf() -#---------------------------------------------------------------------------- - -# ## Ambient CO$_2$ response curves and limiting rates for C3 and C4 - -iA = 4; iT=12 -figure() -plot( CO2, Ag_C3[iA,:,iT],color=:black,lw=2, alpha=0.7, label="Ag C3") -plot(CO2, Ac_C3[iA,:,iT], ls="--", lw=2, label="Ac C3") -plot(CO2, Aj_C3[iA,:,iT], ls="--", lw=2, label="Aj C3") -plot(CO2, Ap_C3[iA,:,iT], ls="--", lw=2, label="Ap C3" ) -xlabel("CO₂ [ppm]") -ylabel("Aᵢ [μmol/m2/s]") -title("Ambient C3 CO₂ response, T=$(T[iT]-273), APAR=$(APAR[iA])") -legend() -gcf() - -#---------------------------------------------------------------------------- - -iA = 4; iT=12 -figure() -plot(CO2, Ag_C4[iA,:,iT],color=:black,lw=2, alpha=0.7, label="Ag C4") -plot(CO2, Ac_C4[iA,:,iT], ls="--", lw=2, label="Ac C4") -plot(CO2, Aj_C4[iA,:,iT], ls="--", lw=2, label="Aj C4") -plot(CO2, Ap_C4[iA,:,iT], ls="--", lw=2, label="Ap C4") -xlabel("CO₂ [ppm]") -ylabel("Aᵢ [μmol/m2/s]") -title("Ambient C4 CO₂ response, T=$(T[iT]-273), APAR=$(APAR[iA])") -legend() -gcf() - -#---------------------------------------------------------------------------- - -# --- -# ## Summary: -# Play around a bit with different parameters. You can also try to change humidity at the leaf level or the boundary layer resistance. There are ## many things that can be tested, and we often like to go to the extremes (T, CO$_2$, ra) to check for bugs, which most often have to do with the ## A-C$_c$ iterations. -# -# Note of caution: we really plotted CO$_2$ response curves against ambient CO$_2$. At low C$_c$, leaves can be a source of CO$_2$ due to the CO$_2$ compensation point (i.e. A$_g$ can be negative!). Also, at CO$_2$=0, stomatal conductance using the empirical formulation goes to $\infty$, which can cause unwanted behavior. -# -# Test things out, learn by changing parameters and try to break it! - - -#---------------------------------------------------------------------------- diff --git a/docs/src/tutorial_scripts/Leaf-Photosynthesis.jl b/docs/src/tutorial_scripts/Leaf-Photosynthesis.jl deleted file mode 100644 index 1692cc34..00000000 --- a/docs/src/tutorial_scripts/Leaf-Photosynthesis.jl +++ /dev/null @@ -1,184 +0,0 @@ - -# # Leaf Photosynthesis Basics -# This tutorial will walk you through the most basic aspects of how we implement Photosynthesis at the leaf level. Most of the concepts are described in the literature, with the first quantitative approach to modeling photosynthesis given in Farquhar, von Caemmerer and Berry[^1] in their seminal 1980 paper for C3 photosynthesis. C4 photosynthesis is largely based on Collatz et al[^2] but we approach the photosynthesis modeling with a rather generic approach that facilitates the application of different photosynthesis modeling approaches without changing the core code base. A good overview on the entire process of photosynthesis and different parameterizations can be found in Bonan[^3]. -# -# At the core of both C3 and C4 photosynthesis is an enzyme catalyzed reaction of ribulose-1,5-bisphosphate (RuBP) with -# CO$_2$, yielding two 3-carbon compounds (phosphoglycerate (PGA)) as the initial products of photosynthesis. The enzyme RuBP carboxylase/oxygenase (Rubisco) catalyzes this reaction. With the regeneration of the substrate RuBP through the light reactions (using produced ATP and NADPH), the core cycle of photosynthesis is formed. This cycle was discovered in 1950 by Melvin Calvin, James Bassham, and Andrew Benson at the University of California, Berkeley[^4][^5] by using the radioactive isotope carbon-14. -# -# An oxygenation step of RuBP releases half a CO$_2$. This so called photorespiration process results in inefficiencies in C3 photosynthesis, as both CO$_2$ and O$_2$ compete at the Rubisco site. The overall photosynthetic rate of the enzyme-catalyzed turnover rates at the Rubisco site thus determine the overall photosynthesis -# -# $$A_n = V_c - 0.5V_o - R_d\,,$$ -# -# with $V_c$ being the carboxylation rate, $V_o$ the oxygenation rate and $R_d$ the mitochondrial respiration. Both rates follow Michaelis-Menten kinetics, accounting for the competing substrate effects: -# -# $$V_c = \frac{V_{c,max}C_c}{C_c+K_c(1+O_c/K_o)}$$ -# -# $$V_o = \frac{V_{o,max}O_c}{O_c+K_o(1+C_c/K_c)}\,$$ -# -# with $K_c$ and $K_o$ being the Michaelis Menten constants for CO$_2$ and O$_2$, $C_c$ and $O_c$ the partial pressures of CO$_2$ and O$_2$ at the Rubisco site. -# -# The ratio of oxygenation to carboxylation rates is -# -# $$\phi = \frac{V_o}{V_c} = \frac{V_{o,max}K_c}{V_{c,max}K_o}\frac{O_c}{C_c}\,$$ -# -# which yields the CO$_2$ compensation point $\Gamma_\star$: -# -# $$\Gamma_\star = 0.5\frac{V_{o,max}K_c}{V_{c,max}K_o}O_c\,$$ -# -# with is the internal CO$_2$ partial pressure at which oxygenation and carboxylation cancel each other out in terms of CO$_2$ consumption and production (neglecting $R_d$). -# -# -# -# -# [^1]: Farquhar, G.D., von Caemmerer, S.V. and Berry, J.A., 1980. A biochemical model of photosynthetic CO$_2$ assimilation in leaves of C3 species. Planta, 149(1), pp.78-90. -# -# [^2]: Collatz, G.J., Ribas-Carbo, M. and Berry, J.A., 1992. Coupled photosynthesis-stomatal conductance model for leaves of C4 plants. Functional Plant Biology, 19(5), pp.519-538. -# -# [^3]: Bonan, G., 2019. Climate change and terrestrial ecosystem modeling. Cambridge University Press. -# -# [^4]: Calvin, Melvin, and Andrew Alm Benson. "The path of carbon in photosynthesis IV: the identity and sequence of the intermediates in sucrose synthesis." Science 109, no. 2824 (1949): 140-142. -# -# [^5]: Benson, A.A., Bassham, J.A., Calvin, M., Goodale, T.C., Haas, V.A. and Stepka, W., 1950. The path of carbon in photosynthesis. v. paper chromatography and radioautography of the products1. Journal of the American Chemical Society, 72(4), pp.1710-1718. -# - -# ## Rate Limiting Steps for photosynthesis -# -# ### Rubisco-limited rates: -# The net photosynthetic rate limited by Rubisco when RuBP re-generation is not constraining can thus be described as -# -# $$A_n = \left(1-\frac{\Gamma_\star}{C_c}\right)V_c-R_d\,$$ -# -# which equals (now denoting $A_c$ as the Rubisco limited rate): -# -# $$A_c = \frac{(C_c-\Gamma_\star) V_{c,max}}{C_c+K_c(1+O_c/K_o)}\,$$ -# -# which is implemented in our routines "rubisco_limited_rate!". -# -# ### RuBP-regeration limited rates (light-limited): -# -# RuBP is regenerated via the ligh reaction, which generates ATP and NADP to power this part of the Calvin-Benson-Bassham cycle. Without going into details of the NADPH or ATP requirements for regeneration, the rate of RuBP limited photosynthesis through light-powered electron transport $J$ (µmol/m$^2$/s) is given as -# -# $$A_j = \underbrace{\frac{C_c-\Gamma_\star}{Cc}}_{\text{loss in photorespiration}}\underbrace{\frac{J\,C_c}{4C_c+8\Gamma_\star}}_{\text{RuBP regeneration}} = \frac{J(C_c-\Gamma_\star)}{4C_c+8\Gamma_\star}\,$$ -# -# One can already see what the key difference between C3 and C4 photosynthesis is based on these set of equation for rubisco turnover and RuBP-regeneration limited rates. In C4 photosynthesis, $C_c$ is typically only about 70% of the ambient CO$_2$ concentration as CO$_2$ has to diffuse through stomata and the mesophyll. For C4, a carbon accumulation mechanism uses a four-carbon organic acid (hence C4) to transport CO$_2$ from the mesophyll cells to the bundle sheath cells, where the reaction with Rubisco takes place. This leads to much higher $C_c$ for C4 plants ($>>$ than ambient air CO$_2$), which is often simplified for $A_c$ as the limit of C3 equation with $\lim_{C_c \to \infty}$ Ac(C3): -# -# $$A_c^{C4} = V_{c,max}$$ -# -# Similarly, the RuBP-regeneration limited rate simplifies to: -# -# $$A_j^{C4} = \alpha J$$ -# -# with a slightly lower efficiency $\alpha$ for C4 photosynthesis compared to C3 (as the carbon accumulation mechanism also consumes ATP). In reality, the situation is somewhat more complex and there are different approximations for Rubisco and RuBP limited rate constants. A comprehensive overview is described in von Caemmerer [^6]. Again, our goal is to provide a flexible framework for photosynthesis modeling, so different implementations of rate limiting steps $A_c,A_j$ can be used in a modular framework (achieved through code abstraction and multiple dispatch in Julia). -# -# ### Electron Transport Rate $J$ -# -# The rate of electron transport is driven by absorbed photosynthetically absorbed radiation (APAR, $\mu mol/m^2/s$) by Photosystem II (PSII). With our leaf level optical model, we already compute the efficiency of absorbtion by leaves depending on pigment contents. We define $\varphi_{PSII}$ as the quantum yield of photosystem II (maxima about 0.83) and $f_{PSII}$ the fraction of light used for PSII (PSII/(PSI+PSII)), typically assume to be 0.5. -# -# $$J_{PSII} = f_{PSII} \varphi_{PSII} APAR$$ -# -# In most models, a maximum electron transport $J_{max}$ rate is assumed and the actual electron trapsort rate $J_a$ is defined as the lower root of the quadratic expression -# -# $$\Theta_j J_a^2 -(J_{PSII}+J_{max})+ J_{PSII}J_{max} = 0$$ -# -# where $\Theta_j$ is a curvature parameter to assure a smooth transition. -# -# ### Product limited rates: -# -# Typically, a thrid limitation of photosynthesis is being used as well, which we denote as product limited rate here, even though the processes for C3 and C4 plants differ. Typically, the export of the products of photosynthesis (triose phosphates) in the synthesis of sugars can be rate limiting, which is often parameterized by $V_{c,max}$: -# -# $$A_p = a V_{c,max}\,,$$ -# -# where our standard definition for C3 used a=0.5, which rarely limits photosynthesis compared to $A_c$ and $A_j$. -# -# For C4 plants, we use the PEP-carboxylase CO$_2$ concentration mechanism into the bundle sheath cell as product limited rate step, using Michaelis-Menten kinetics: -# -# $$A_p^{C4} = \frac{V_{p,max}C_c}{C_c + K_p}$$ -# -# with corresponding Michaelis Menten constant $K_p$ and maximal rates $V_{p,max}$. -# -# -# ### Total rate: -# -# The gross photosynthetic rate $A_g$ can then be define as the mininum of all possible limitations: -# -# $$A_g = min(Ac,Aj,Ap)$$ -# -# or, alternatively, using quadratic equations as for $J$, which provides smoother transitions and co-limitation to some degree (both are options in our setup with a user defined curvature parameter $\Theta$. -# -# Net leaf photosynthesis includes mitochondrial respiration as well: -# -# $$A_n = A_g - R_d$$ -# -# [^6]: Von Caemmerer, S., 2000. Biochemical models of leaf photosynthesis. Csiro publishing. - -# ## Simple example: -# We just want to lay out a first simple example as to how our model setup work: - -## Loading the Photosynthesis model: -using Land.Photosynthesis -## Defining our Field Type (we can easily switch between Double and Float precision this way) -const FT = Float32; -#---------------------------------------------------------------------------- - -## Create a standard leaf with defualt parameters -leaf = Leaf{FT}(); - -## Create a standard meteo structure: -envir = AirLayer{FT}(); -#---------------------------------------------------------------------------- - -# ---- -# How to use the documentation, what do we know about leaf_params, which stores most physiologically relevant parameters. (Not printed here, try in the command line! Type in, do not copy and paste!). - -##?LeafParams -#---------------------------------------------------------------------------- - -##?MeteoParams -#---------------------------------------------------------------------------- - -# ### Defining the model setup -# The most important step is to define which submodules to use. There might be different implementations for Fluorescence, Photosynthesis (C3,C4,etc), respiration, stomatal conductance (e.g. Ball-Berry, Medlyn), the T-dependence of J$_{max}$, V$_{c,max}$ and Michaelis Menten constants as well as leaf boundary layer resistance (setting it to 0 here to mimic well vented laboratory leaf level measurements) and colimitation. - -##Here, we just have to worry abou the photosynthesis module, which we set here: -#mod_photo = C3FvCBPhoto() - -## All modules here: -const photo_set = C3CLM(FT); -#---------------------------------------------------------------------------- - -## Set APAR to 250 $\mu mol/m^2/s$ -leaf.APAR = 250; -## Set temperature to 290K -leaf.T = 290; -## Applying the T-correction for all the rate constants -photo_temperature_dependence!(photo_set, leaf, envir); -@show leaf.Vcmax, leaf.Vcmax25; -#---------------------------------------------------------------------------- - -@show leaf.Jmax, leaf.Jmax25; -#---------------------------------------------------------------------------- - -## Specify Cc directly here in Pa -leaf.p_i = 35; -## update radiation dependent values first, like ETR -photo_radiation_dependence!(photo_set, leaf); -## update p_i dependent photosynthetic rates -photo_CO₂_dependence!(photo_set, leaf); -@show leaf.Ac; -#---------------------------------------------------------------------------- - -@show leaf.Aj; -#---------------------------------------------------------------------------- - -@show leaf.Ap; -#---------------------------------------------------------------------------- - -@show leaf.An; -#---------------------------------------------------------------------------- - -# ---- -# ### Summary -# This was the simplest example to compute A$_c$, A$_j$ and A$_p$ with a specified C$_c$ and APAR. In reality, C$_c$ is defined by the interplay of photosynthetic demand and the supply through diffusion through stomata and the mesophyll. However, you can easily exchange the photosynthesis model above with C4FvCBPhoto(). You can also play around with leaf temperature T and APAR as well as $C_c$. But remember to use the right function. - -#?Leaf -#---------------------------------------------------------------------------- diff --git a/docs/src/tutorial_scripts/Photosynthesis/1_basics.jl b/docs/src/tutorial_scripts/Photosynthesis/1_basics.jl deleted file mode 100644 index 2283482d..00000000 --- a/docs/src/tutorial_scripts/Photosynthesis/1_basics.jl +++ /dev/null @@ -1,111 +0,0 @@ -# # Leaf Photosynthesis Basics -# This tutorial will walk you through the most basic aspects of how we implement Photosynthesis at the leaf level. Most of the concepts are described in the literature, with the first quantitative approach to modeling photosynthesis given in Farquhar, von Caemmerer and Berry[^1] in their seminal 1980 paper for C3 photosynthesis. C4 photosynthesis is largely based on Collatz et al[^2] but we approach the photosynthesis modeling with a rather generic approach that facilitates the application of different photosynthesis modeling approaches without changing the core code base. A good overview on the entire process of photosynthesis and different parameterizations can be found in Bonan[^3]. -# -# At the core of both C3 and C4 photosynthesis is an enzyme catalyzed reaction of ribulose-1,5-bisphosphate (RuBP) with -# CO₂, yielding two 3-carbon compounds (phosphoglycerate (PGA)) as the initial products of photosynthesis. The enzyme RuBP carboxylase/oxygenase (Rubisco) catalyzes this reaction. With the regeneration of the substrate RuBP through the light reactions (using produced ATP and NADPH), the core cycle of photosynthesis is formed. This cycle was discovered in 1950 by Melvin Calvin, James Bassham, and Andrew Benson at the University of California, Berkeley[^4][^5] by using the radioactive isotope carbon-14. -# -# An oxygenation step of RuBP releases half a CO₂. This so called photorespiration process results in inefficiencies in C3 photosynthesis, as both CO₂ and O₂ compete at the Rubisco site. The overall photosynthetic rate of the enzyme-catalyzed turnover rates at the Rubisco site thus determine the overall photosynthesis -# -# $$A_n = V_c - 0.5V_o - R_d\,,$$ -# -# with $V_c$ being the carboxylation rate, $V_o$ the oxygenation rate and $R_d$ the mitochondrial respiration. Both rates follow Michaelis-Menten kinetics, accounting for the competing substrate effects: -# -# $$V_c = \frac{V_{c,max}C_c}{C_c+K_c(1+O_c/K_o)}$$ -# -# $$V_o = \frac{V_{o,max}O_c}{O_c+K_o(1+C_c/K_c)}\,$$ -# -# with $K_c$ and $K_o$ being the Michaelis Menten constants for CO₂ and O₂, $C_c$ and $O_c$ the partial pressures of CO₂ and O₂ at the Rubisco site. -# -# The ratio of oxygenation to carboxylation rates is -# -# $$\phi = \frac{V_o}{V_c} = \frac{V_{o,max}K_c}{V_{c,max}K_o}\frac{O_c}{C_c}\,$$ -# -# which yields the CO₂ compensation point $\Gamma^\star$: -# -# $$\Gamma^\star = 0.5\frac{V_{o,max}K_c}{V_{c,max}K_o}O_c\,$$ -# -# with is the internal CO₂ partial pressure at which oxygenation and carboxylation cancel each other out in terms of CO₂ consumption and production (neglecting $R_d$). -# -# -# -# -# [^1]: Farquhar, G.D., von Caemmerer, S.V. and Berry, J.A., 1980. A biochemical model of photosynthetic CO₂ assimilation in leaves of C3 species. Planta, 149(1), pp.78-90. -# -# [^2]: Collatz, G.J., Ribas-Carbo, M. and Berry, J.A., 1992. Coupled photosynthesis-stomatal conductance model for leaves of C4 plants. Functional Plant Biology, 19(5), pp.519-538. -# -# [^3]: Bonan, G., 2019. Climate change and terrestrial ecosystem modeling. Cambridge University Press. -# -# [^4]: Calvin, Melvin, and Andrew Alm Benson. "The path of carbon in photosynthesis IV: the identity and sequence of the intermediates in sucrose synthesis." Science 109, no. 2824 (1949): 140-142. -# -# [^5]: Benson, A.A., Bassham, J.A., Calvin, M., Goodale, T.C., Haas, V.A. and Stepka, W., 1950. The path of carbon in photosynthesis. v. paper chromatography and radioautography of the products1. Journal of the American Chemical Society, 72(4), pp.1710-1718. -# -# ## Rate Limiting Steps for photosynthesis -# -# ### Rubisco-limited rates: -# The net photosynthetic rate limited by Rubisco when RuBP re-generation is not constraining can thus be described as -# -# $$A_n = \left(1-\frac{\Gamma_\star}{C_c}\right)V_c-R_d\,$$ -# -# which equals (now denoting $A_c$ as the Rubisco limited rate): -# -# $$A_c = \frac{(C_c-\Gamma_\star) V_{c,max}}{C_c+K_c(1+O_c/K_o)}\,$$ -# -# which is implemented in our routines "rubisco_limited_rate!". -# -# ### RuBP-regeration limited rates (light-limited): -# -# RuBP is regenerated via the ligh reaction, which generates ATP and NADP to power this part of the Calvin-Benson-Bassham cycle. Without going into details of the NADPH or ATP requirements for regeneration, the rate of RuBP limited photosynthesis through light-powered electron transport $J$ (µmol/m$^2$/s) is given as -# -# $$A_j = \underbrace{\frac{C_c-\Gamma_\star}{Cc}}_{\text{loss in photorespiration}}\underbrace{\frac{J\,C_c}{4C_c+8\Gamma_\star}}_{\text{RuBP regeneration}} = \frac{J(C_c-\Gamma_\star)}{4C_c+8\Gamma_\star}\,$$ -# -# One can already see what the key difference between C3 and C4 photosynthesis is based on these set of equation for rubisco turnover and RuBP-regeneration limited rates. In C4 photosynthesis, $C_c$ is typically only about 70% of the ambient CO₂ concentration as CO₂ has to diffuse through stomata and the mesophyll. For C4, a carbon accumulation mechanism uses a four-carbon organic acid (hence C4) to transport CO₂ from the mesophyll cells to the bundle sheath cells, where the reaction with Rubisco takes place. This leads to much higher $C_c$ for C4 plants ($>>$ than ambient air CO₂), which is often simplified for $A_c$ as the limit of C3 equation with $\lim_{C_c \to \infty}$ Ac(C3): -# -# $$A_c^{C4} = V_{c,max}$$ -# -# Similarly, the RuBP-regeneration limited rate simplifies to: -# -# $$A_j^{C4} = \alpha J$$ -# -# with a slightly lower efficiency $\alpha$ for C4 photosynthesis compared to C3 (as the carbon accumulation mechanism also consumes ATP). In reality, the situation is somewhat more complex and there are different approximations for Rubisco and RuBP limited rate constants. A comprehensive overview is described in von Caemmerer [^6]. Again, our goal is to provide a flexible framework for photosynthesis modeling, so different implementations of rate limiting steps $A_c,A_j$ can be used in a modular framework (achieved through code abstraction and multiple dispatch in Julia). -# -# ### Electron Transport Rate $J$ -# -# The rate of electron transport is driven by absorbed photosynthetically absorbed radiation (APAR, $\mu mol/m^2/s$) by Photosystem II (PSII). With our leaf level optical model, we already compute the efficiency of absorbtion by leaves depending on pigment contents. We define $\varphi_{PSII}$ as the quantum yield of photosystem II (maxima about 0.83) and $f_{PSII}$ the fraction of light used for PSII (PSII/(PSI+PSII)), typically assume to be 0.5. -# -# $$J_{PSII} = f_{PSII} \varphi_{PSII} APAR$$ -# -# In most models, a maximum electron transport $J_{max}$ rate is assumed and the actual electron trapsort rate $J_a$ is defined as the lower root of the quadratic expression -# -# $$\Theta_j J_a^2 -(J_{PSII}+J_{max})+ J_{PSII}J_{max} = 0$$ -# -# where $\Theta_j$ is a curvature parameter to assure a smooth transition. -# -# ### Product limited rates: -# -# Typically, a thrid limitation of photosynthesis is being used as well, which we denote as product limited rate here, even though the processes for C3 and C4 plants differ. Typically, the export of the products of photosynthesis (triose phosphates) in the synthesis of sugars can be rate limiting, which is often parameterized by $V_{c,max}$: -# -# $$A_p = a V_{c,max}\,,$$ -# -# where our standard definition for C3 used a=0.5, which rarely limits photosynthesis compared to $A_c$ and $A_j$. -# -# For C4 plants, we use the PEP-carboxylase CO₂ concentration mechanism into the bundle sheath cell as product limited rate step, using Michaelis-Menten kinetics: -# -# $$A_p^{C4} = \frac{V_{p,max}C_c}{C_c + K_p}$$ -# -# with corresponding Michaelis Menten constant $K_p$ and maximal rates $V_{p,max}$. -# -# -# ### Total rate: -# -# The gross photosynthetic rate $A_g$ can then be define as the mininum of all possible limitations: -# -# $$A_g = min(Ac,Aj,Ap)$$ -# -# or, alternatively, using quadratic equations as for $J$, which provides smoother transitions and co-limitation to some degree (both are options in our setup with a user defined curvature parameter $\Theta$. -# -# Net leaf photosynthesis includes mitochondrial respiration as well: -# -# $$A_n = A_g - R_d$$ -# -# [^6]: Von Caemmerer, S., 2000. Biochemical models of leaf photosynthesis. Csiro publishing. -# diff --git a/docs/src/tutorial_scripts/Photosynthesis/2_temperature.jl b/docs/src/tutorial_scripts/Photosynthesis/2_temperature.jl deleted file mode 100644 index fc70b96c..00000000 --- a/docs/src/tutorial_scripts/Photosynthesis/2_temperature.jl +++ /dev/null @@ -1,228 +0,0 @@ -# # Rate Constants and T-Dependency -# -# Here, we will just briefly summarize how temperature affects enzymatic rate constants and how much uncertainty there actually is in literature (in terms of how to best define them and how plastic some of the variables are) - -## Add usual tools we use: -using BenchmarkTools -using PyPlot - -#---------------------------------------------------------------------------- - -## load Photosynthesis module: -using Land.Photosynthesis -#---------------------------------------------------------------------------- - -## Specify Field Type -const FT = Float32; -#---------------------------------------------------------------------------- - -# ## T-dependence -# In literature, there are different implementations of the temperature dependence of enzymatic reaction rates. Common among all of them is a typical Arrhenius formulation with Activation energy $E_a$, which leads to a temperature dependence of a quantity $V$ given the standard value defined at 25 °C as $T_{ref}$. -# -# $$V(T)= V(T_{ref})\, \underbrace{\exp\left(\frac{E_a}{RT_{ref}}-\frac{E_a}{RT}\right)}_{\text{Activation}}$$ -# -# Other formulations add de-activation of proteins due to denaturalization at higher temperatures: -# -# $$V(T)= V(T_{ref})\, \exp\left(\frac{E_a}{RT_{ref}}-\frac{E_a}{RT}\right) \underbrace{\frac{1+\exp\left[(\Delta ST_{ref}-H_d)/RT_{ref}\right]}{1+\exp\left[(\Delta ST-H_d)/RT\right]}}_{\text{de-activation}}$$ -# -# which includes an entropy term $\Delta S$ and the energy for deactivation $H_d$. -# -# To illustrate the differences, we show two different implementations, one only using the activation part based on Bernacchi et al 2001[^1] and one with the typical CLM5 implementation. -# -# The T-Dependency applies to $V_{max}$, $J_{max}$, $K_{c}$, $K_{o}$, $K_{pep}$, Respiration, and $\Gamma^{*}$, and there are multiple parameter sets for each of the parameters. Below, we show the differences of the sets for each of $V_{max}$, $J_{max}$, $K_{c}$, $K_{o}$, $K_{pep}$, Respiration, and $\Gamma^{*}$. -# -# [^1]: Bernacchi, C.J., Singsaas, E.L., Pimentel, C., Portis Jr, A.R. and Long, S.P., 2001. Improved temperature response functions for models of Rubisco‐limited photosynthesis. Plant, Cell & Environment, 24(2), pp.253-259. -# -# ### $V_{cmax}$ -# - -## Bernacchi set -vc_td_bernacchi = Photosynthesis.VcmaxTDBernacchi(FT) -## CLM set -vc_td_clm = Photosynthesis.VcmaxTDCLM(FT) -## Leuning set -vc_td_leuning = Photosynthesis.VcmaxTDLeuning(FT) - -## an array of temperature from 10 to 50 degree C -t_array = collect(FT, 10:50) .+ FT(273.15) -vcm_bernacchi = photo_TD_from_val(vc_td_bernacchi, FT(60), t_array) -vcm_clm = photo_TD_from_val(vc_td_clm , FT(60), t_array) -vcm_leuning = photo_TD_from_val(vc_td_leuning , FT(60), t_array) - -## plot the TD curves -figure(figsize=(8,6), dpi=100) -tight_layout(true) -plot(t_array, vcm_bernacchi, "r-", label="Bernacchi") -plot(t_array, vcm_clm , "g-", label="CLM5" ) -plot(t_array, vcm_leuning , "b-", label="Leuning" ) -xlabel("Temperature (K)" , fontsize=16) -ylabel("\$V_{cmax}\$ (μmol m⁻² s⁻¹)", fontsize=16) -legend(loc="upper left") -gcf() -#---------------------------------------------------------------------------- - -# ### $V_{pmax}$ -# - -## Boyd set -vp_td_boyd = Photosynthesis.VpmaxTDBoyd(FT) - -## an array of temperature from 10 to 50 degree C -vpm_boyd = photo_TD_from_val(vp_td_boyd, FT(60), t_array) - -## plot the TD curves -figure(figsize=(8,6), dpi=100) -tight_layout(true) -plot(t_array, vpm_boyd, "r-", label="Boyd") -xlabel("Temperature (K)" , fontsize=16) -ylabel("\$V_{pmax}\$ (μmol m⁻² s⁻¹)", fontsize=16) -legend(loc="upper left") -gcf() -#---------------------------------------------------------------------------- - -# ### $J_{max}$ -# - -## Bernacchi set -j_td_bernacchi = Photosynthesis.JmaxTDBernacchi(FT) -## CLM set -j_td_clm = Photosynthesis.JmaxTDCLM(FT) -## Leuning set -j_td_leuning = Photosynthesis.JmaxTDLeuning(FT) - -## an array of temperature from 10 to 50 degree C -jm_bernacchi = photo_TD_from_val(j_td_bernacchi, FT(120), t_array) -jm_clm = photo_TD_from_val(j_td_clm , FT(120), t_array) -jm_leuning = photo_TD_from_val(j_td_leuning , FT(120), t_array) - -## plot the TD curves -figure(figsize=(8,6), dpi=100) -tight_layout(true) -plot(t_array, jm_bernacchi, "r-", label="Bernacchi") -plot(t_array, jm_clm , "g-", label="CLM5" ) -plot(t_array, jm_leuning , "b-", label="Leuning" ) -xlabel("Temperature (K)" , fontsize=16) -ylabel("\$J_{max}\$ (μmol m⁻² s⁻¹)", fontsize=16) -legend(loc="upper left") -gcf() -#---------------------------------------------------------------------------- - -# ### $K_{c}$ -# - -## Bernacchi set -kc_td_bernacchi = Photosynthesis.KcTDBernacchi(FT) -## CLM set -kc_td_clm = Photosynthesis.KcTDCLM(FT) - -## an array of temperature from 10 to 50 degree C -kc_bernacchi = photo_TD_from_set(kc_td_bernacchi, t_array) -kc_clm = photo_TD_from_set(kc_td_clm , t_array) - -## plot the TD curves -figure(figsize=(8,6), dpi=100) -tight_layout(true) -plot(t_array, kc_bernacchi, "r-", label="Bernacchi") -plot(t_array, kc_clm , "g-", label="CLM5" ) -xlabel("Temperature (K)", fontsize=16) -ylabel("\$K_{c}\$ (Pa)" , fontsize=16) -legend(loc="upper left") -gcf() -#---------------------------------------------------------------------------- - -# ### $K_{o}$ -# - -## Bernacchi set -ko_td_bernacchi = Photosynthesis.KoTDBernacchi(FT) -## CLM set -ko_td_clm = Photosynthesis.KoTDCLM(FT) - -## an array of temperature from 10 to 50 degree C -ko_bernacchi = photo_TD_from_set(ko_td_bernacchi, t_array) -ko_clm = photo_TD_from_set(ko_td_clm , t_array) - -## plot the TD curves -figure(figsize=(8,6), dpi=100) -tight_layout(true) -plot(t_array, ko_bernacchi, "r-", label="Bernacchi") -plot(t_array, ko_clm , "g-", label="CLM5" ) -xlabel("Temperature (K)", fontsize=16) -ylabel("\$K_{o}\$ (Pa)" , fontsize=16) -legend(loc="upper left") -gcf() -#---------------------------------------------------------------------------- - -# ### $K_{pep}$ -# - -## Boyd set -kpep_td_boyd = Photosynthesis.KpepTDBoyd(FT) -## CLM set -kpep_td_clm = Photosynthesis.KpepTDCLM(FT) - -## an array of temperature from 10 to 50 degree C -kpep_boyd = photo_TD_from_set(kpep_td_boyd, t_array) -kpep_clm = photo_TD_from_set(kpep_td_clm , t_array) - -## plot the TD curves -figure(figsize=(8,6), dpi=100) -tight_layout(true) -plot(t_array, kpep_boyd, "r-", label="Boyd") -plot(t_array, kpep_clm , "g-", label="CLM5") -xlabel("Temperature (K)" , fontsize=16) -ylabel("\$K_{pep}\$ (Pa)", fontsize=16) -legend(loc="upper left") -gcf() -#---------------------------------------------------------------------------- - -# ### Respiration -# - -## Bernacchi set -re_td_bernacchi = Photosynthesis.RespirationTDBernacchi(FT) -## CLM set -re_td_clm = Photosynthesis.RespirationTDCLM(FT) - -## an array of temperature from 10 to 50 degree C -re_bernacchi = photo_TD_from_val(re_td_bernacchi, FT(1.0), t_array) -re_clm = photo_TD_from_val(re_td_clm , FT(1.0), t_array) - -## plot the TD curves -figure(figsize=(8,6), dpi=100) -tight_layout(true) -plot(t_array, re_bernacchi, "r-", label="Bernacchi") -plot(t_array, re_clm , "g-", label="CLM5" ) -xlabel("Temperature (K)" , fontsize=16) -ylabel("Respiration Rate (μmol m⁻² s⁻¹)", fontsize=16) -legend(loc="upper left") -gcf() -#---------------------------------------------------------------------------- - -# ### $\Gamma^{*}$ -# - -## Bernacchi set -Γs_td_bernacchi = Photosynthesis.ΓStarTDBernacchi(FT) -## CLM set -Γs_td_clm = Photosynthesis.ΓStarTDCLM(FT) - -## an array of temperature from 10 to 50 degree C -Γs_bernacchi = photo_TD_from_set(Γs_td_bernacchi, t_array) -Γs_clm = photo_TD_from_set(Γs_td_clm , t_array) - -## plot the TD curves -figure(figsize=(8,6), dpi=100) -tight_layout(true) -plot(t_array, Γs_bernacchi, "r-", label="Bernacchi") -plot(t_array, Γs_clm , "g-", label="CLM5" ) -xlabel("Temperature (K)" , fontsize=16) -ylabel("\$\\Gamma^{*}\$ (Pa)", fontsize=16) -legend(loc="upper left") -gcf() -#---------------------------------------------------------------------------- - -# ## Summary -# The way land surface models implement temperature variations in $V_{c,max}$ is still rather variable and there is no clear consensus in what model is best. In addition, gas exchange datasets performed at different temperatures might actually alias different confounding factors into the $V_{c,max}$ determination, so that the actually fitted $V_{c,max}$ strongly depends on the model formulation. E.g. mesophyll conductance is usually ignored in deriving $V_{c,max}$ but might be temperature dependent, which can cause T-dependent errors in $V_{c,max}$. Also, the T-dependencies may change with time, known as acclimation of optimal temperature. -# -# That said, having the option to use different model forumations (as well as parameter settings) and actually using the ones that are implemented in land surface models directly when fitting leaf level measurements seems to be a prudent way to improve models in the future. More leaf level data might help in the future, especially looking at temperature dependencies, mesophyll conductance, and fluorescence yields. So many chemical and phsyical aspects change with temperature that it is hard to isolate impacting factors. Now, at least, we can run the models directly in the REPL, which is great for prototyping anc validating the model on the individual module level without any effort in terms of additional coding. diff --git a/docs/src/tutorial_scripts/Photosynthesis/3_photosynthesis.jl b/docs/src/tutorial_scripts/Photosynthesis/3_photosynthesis.jl deleted file mode 100644 index 5ffa40fa..00000000 --- a/docs/src/tutorial_scripts/Photosynthesis/3_photosynthesis.jl +++ /dev/null @@ -1,187 +0,0 @@ -# # Leaf Level Photosynthesis -# -# Here, we will go one step further and look at the entire leaf-level response to different environmental conditions, including the impact of leaf diffusive conductance here. See next tutorial for how stomatal conductance responds to the environment. - -# ## Leaf Diffusive Conductance and Stomatal Conductance -# Before, we focussed mainly on the demand-driven constraints through Rubisco and RuBP regeneration. Leaf diffusive conductance is highly important as it drives the suppy-side of photosynthesis and interacts with the energy balance and leaf temperature as latent heat fluxes are a major factor in surface cooling. -# -# Before, we have derived net rates of photosynthesis $A_n$, which have to be matched with the supply side through CO₂ diffusion: -# -# $$A_n^{diff} = g_{leaf,C}(C_a-C_c) = g_{leaf,C}\frac{P_a-P_c}{P_{atm}}$$ -# -# which can be separated into diffusion from the air to the leaf surface with a boundary layer conductance $g_{b,C}$, diffusion from the surface to the interstitial air-space with stomatal conductance $g_{s,C}$ and diffusion from the interstitial air-space to the chloroplast with mesophyll conductance $g_{m,C}$ (the letter C stands for CO₂ here, as the diffusion constants vary with species, e.g. H$_2$O stomatal conductance is a factor 1.6 higher than those for CO₂): -# -# $$A_n^{diff} = g_{b,C}(C_a-C_s) = g_{s,C}(C_s-C_i) = g_{m,C}(C_i-C_c) = g_{leaf,C}(C_a-C_c)$$ -# -# $$g_{leaf,C} = \left(\frac{1}{g_{b,C}}+\frac{1}{g_{s,C}}+\frac{1}{g_{m,C}}\right)^{-1}$$ -# -# The importance of diffusive conductance and its interplay with photosynthesis here is that the supply and demand rates determine $C_c$. A reduction in $C_c$ reduces the demand-limited rates while it increase the diffusion rates (at a given $g$). Most models run internal so-called A-$C_c$ iterations to ensure both rates are balanced and in steady-state ($\partial C_c/\partial t=0$). We implement this option but also opt to run stomatal conductance prognostically, as stomata don't open and close instantanously but have a response time of around 15 minutes. -# -# Below, we show simple examples of how the environmental conditions and the leaf diffusive conductance impact leaf photosynthesis. -# - -## load packages -using PyPlot -using Land.Photosynthesis - -## set the default floating type -FT = Float32; - -## define default photosynthesis parameter sets -c3_set = C3CLM(FT); -c4_set = C4CLM(FT); - -## define leaf photosynthetic parameters and environmental conditions -leaf_3 = LeafPhotoContainer{FT}(APAR=1200, Vcmax25=60, Jmax25=120, Vpmax25=80, Rd25=1); -leaf_4 = LeafPhotoContainer{FT}(APAR=1200, Vcmax25=60, Jmax25=120, Vpmax25=80, Rd25=1); -envir = EnvironmentConditions{FT}(); -#---------------------------------------------------------------------------- - -# ## $A$ ~ $P_c$ - -## set the internal CO₂ to 30 Pa and temperature to 298.15 K and PAR to 1500 -leaf_3.p_i=30; leaf_3.T=298.15; leaf_3.APAR=1500; -leaf_4.p_i=30; leaf_4.T=298.15; leaf_4.APAR=1500; - -## set an array of internal CO₂ -p_array = collect(FT, 5:200); -ac_3 = similar(p_array); aj_3 = similar(p_array); ap_3 = similar(p_array); ag_3 = similar(p_array); an_3 = similar(p_array); -ac_4 = similar(p_array); aj_4 = similar(p_array); ap_4 = similar(p_array); ag_4 = similar(p_array); an_4 = similar(p_array); - -## update the temperature and PAR dependent photosynthesis -Photosynthesis.photosynthesis_TD!(c3_set, leaf_3, envir); -Photosynthesis.photosynthesis_TD!(c4_set, leaf_4, envir); - - -## update the CO₂ dependent photosynthesis -for i in eachindex(p_array); - p_i = p_array[i]; - photosynthesis_PD!(c3_set, leaf_3, p_i); - photosynthesis_PD!(c4_set, leaf_4, p_i); - - ac_3[i], aj_3[i], ap_3[i], ag_3[i], an_3[i] = leaf_3.Ac, leaf_3.Aj, leaf_3.Ap, leaf_3.Ag, leaf_3.An; - ac_4[i], aj_4[i], ap_4[i], ag_4[i], an_4[i] = leaf_4.Ac, leaf_4.Aj, leaf_4.Ap, leaf_4.Ag, leaf_4.An; -end - -## plot the CO₂ responses for C3 and C4 photosynthesis -figure(figsize=(10,6), dpi=100); -tight_layout(true); -subplot(1,2,1); -plot(p_array, ac_3, "r:", lw=2, label="Ac"); -plot(p_array, aj_3, "b:", lw=2, label="Aj"); -plot(p_array, ap_3, "g:", lw=2, label="Ap"); -plot(p_array, ag_3, "k-", lw=1, label="Ag"); -plot(p_array, an_3, "k:", lw=1, label="An"); -xlabel("Leaf Internal CO₂ (Pa)" , fontsize=16); -ylabel("Photosynthetic Rate (μmol m⁻² s⁻¹)", fontsize=16); -legend(loc="lower right") -subplot(1,2,2); -plot(p_array, ac_4, "r:", lw=2, label="Ac"); -plot(p_array, aj_4, "b:", lw=2, label="Aj"); -plot(p_array, ap_4, "g:", lw=2, label="Ap"); -plot(p_array, ag_4, "k-", lw=1, label="Ag"); -plot(p_array, an_4, "k:", lw=1, label="An"); -xlabel("Leaf Internal CO₂ (Pa)" , fontsize=16); -legend(loc="lower right") -gcf() -#---------------------------------------------------------------------------- - -# ## $A$ ~ $PAR$ - -## set the internal CO₂ to 30 Pa and temperature to 298.15 K and PAR to 1500 -leaf_3.p_i=30; leaf_3.T=298.15; leaf_3.APAR=1500; -leaf_4.p_i=30; leaf_4.T=298.15; leaf_4.APAR=1500; - -## set an array of APAR -par_array = collect(FT, 10:10:2000); -ac_3 = similar(par_array); aj_3 = similar(par_array); ap_3 = similar(par_array); ag_3 = similar(par_array); an_3 = similar(par_array); -ac_4 = similar(par_array); aj_4 = similar(par_array); ap_4 = similar(par_array); ag_4 = similar(par_array); an_4 = similar(par_array); - -for i in eachindex(par_array); - leaf_3.APAR = par_array[i]; - leaf_4.APAR = par_array[i]; - - ## update the temperature dependent photosynthesis - Photosynthesis.photosynthesis_TD!(c3_set, leaf_3, envir); - Photosynthesis.photosynthesis_TD!(c4_set, leaf_4, envir); - - ## update the CO₂ dependent photosynthesis - photosynthesis_PD!(c3_set, leaf_3, leaf_3.p_i); - photosynthesis_PD!(c4_set, leaf_4, leaf_4.p_i); - - ac_3[i], aj_3[i], ap_3[i], ag_3[i], an_3[i] = leaf_3.Ac, leaf_3.Aj, leaf_3.Ap, leaf_3.Ag, leaf_3.An; - ac_4[i], aj_4[i], ap_4[i], ag_4[i], an_4[i] = leaf_4.Ac, leaf_4.Aj, leaf_4.Ap, leaf_4.Ag, leaf_4.An; -end - -## plot the CO₂ responses for C3 and C4 photosynthesis -figure(figsize=(10,6), dpi=100); -tight_layout(true); -subplot(1,2,1); -plot(par_array, ac_3, "r:", lw=2, label="Ac"); -plot(par_array, aj_3, "b:", lw=2, label="Aj"); -plot(par_array, ap_3, "g:", lw=2, label="Ap"); -plot(par_array, ag_3, "k-", lw=1, label="Ag"); -plot(par_array, an_3, "k:", lw=1, label="An"); -xlabel("Absorbed PAR (μmol m⁻² s⁻¹)" , fontsize=16); -ylabel("Photosynthetic Rate (μmol m⁻² s⁻¹)", fontsize=16); -legend(loc="lower right") -subplot(1,2,2); -plot(par_array, ac_4, "r:", lw=2, label="Ac"); -plot(par_array, aj_4, "b:", lw=2, label="Aj"); -plot(par_array, ap_4, "g:", lw=2, label="Ap"); -plot(par_array, ag_4, "k-", lw=1, label="Ag"); -plot(par_array, an_4, "k:", lw=1, label="An"); -xlabel("Absorbed PAR (μmol m⁻² s⁻¹)" , fontsize=16); -legend(loc="lower right") -gcf() -#---------------------------------------------------------------------------- - -# ## $A$ ~ $T$ - -## set the internal CO₂ to 30 Pa and temperature to 298.15 K and PAR to 1500 -leaf_3.p_i=30; leaf_3.T=298.15; leaf_3.APAR=1500; -leaf_4.p_i=30; leaf_4.T=298.15; leaf_4.APAR=1500; - -## set an array of APAR -t_array = collect(FT, 10:50) .+ FT(273.15); -ac_3 = similar(t_array); aj_3 = similar(t_array); ap_3 = similar(t_array); ag_3 = similar(t_array); an_3 = similar(t_array); -ac_4 = similar(t_array); aj_4 = similar(t_array); ap_4 = similar(t_array); ag_4 = similar(t_array); an_4 = similar(t_array); - -for i in eachindex(t_array); - leaf_3.T = t_array[i]; - leaf_4.T = t_array[i]; - - ## update the temperature dependent photosynthesis - Photosynthesis.photosynthesis_TD!(c3_set, leaf_3, envir); - Photosynthesis.photosynthesis_TD!(c4_set, leaf_4, envir); - - ## update the CO₂ dependent photosynthesis - photosynthesis_PD!(c3_set, leaf_3, leaf_3.p_i); - photosynthesis_PD!(c4_set, leaf_4, leaf_4.p_i); - - ac_3[i], aj_3[i], ap_3[i], ag_3[i], an_3[i] = leaf_3.Ac, leaf_3.Aj, leaf_3.Ap, leaf_3.Ag, leaf_3.An; - ac_4[i], aj_4[i], ap_4[i], ag_4[i], an_4[i] = leaf_4.Ac, leaf_4.Aj, leaf_4.Ap, leaf_4.Ag, leaf_4.An; -end - -## plot the CO₂ responses for C3 and C4 photosynthesis -figure(figsize=(10,6), dpi=100); -tight_layout(true); -subplot(1,2,1); -plot(t_array, ac_3, "r:", lw=2, label="Ac"); -plot(t_array, aj_3, "b:", lw=2, label="Aj"); -plot(t_array, ap_3, "g:", lw=2, label="Ap"); -plot(t_array, ag_3, "k-", lw=1, label="Ag"); -plot(t_array, an_3, "k:", lw=1, label="An"); -xlabel("Temperature (K)" , fontsize=16); -ylabel("Photosynthetic Rate (μmol m⁻² s⁻¹)", fontsize=16); -legend(loc="upper left") -subplot(1,2,2); -plot(t_array, ac_4, "r:", lw=2, label="Ac"); -plot(t_array, aj_4, "b:", lw=2, label="Aj"); -plot(t_array, ap_4, "g:", lw=2, label="Ap"); -plot(t_array, ag_4, "k-", lw=1, label="Ag"); -plot(t_array, an_4, "k:", lw=1, label="An"); -xlabel("Temperature (K)" , fontsize=16); -legend(loc="upper left") -gcf() -#---------------------------------------------------------------------------- diff --git a/docs/src/tutorial_scripts/Photosynthesis/4_stomata.jl b/docs/src/tutorial_scripts/Photosynthesis/4_stomata.jl deleted file mode 100644 index 0efe5e26..00000000 --- a/docs/src/tutorial_scripts/Photosynthesis/4_stomata.jl +++ /dev/null @@ -1,197 +0,0 @@ -# # Stomatal conductance -# -# Here, we will go one step further and look at the entire leaf-level response to different environmental conditions, including the impact of stomatal responses to the environment here. -# -# ## Empirical Stomatal Conductance models -# -# Currently, we can choose between the widely used Ball-Berry model[^1] or the Medlyn approach[^2]. -# -# Ball and Berry derived the following empirical formulation based on leaf level data (RH is relative humidity): -# -# $$g_{s,w} = g_0 + g_1 \frac{A_n \cdot RH}{C_s}$$ -# -# Medlyn derived the following equations based on stomatal optimization theory but in a similar form as the BB model: -# -# $$g_{s,w} = g_0 + \left(1 + \frac{g_1}{\sqrt{VPD}}\right) \frac{A_n}{C_s}$$ -# -# Both models are proportional to $A_n$ and inversely proportional to $C_s$, with the main difference in the dependence on either relative humidity in the Ball-Berry model vs. vapor pressure deficit (VPD) in Medlyn et al. In both cases, $g_0$ is the residual conductivity even if stomata are fully closed and $g_1$ is related to the marginal water cost of plant carbon gain. Importantly, $g_1$ can't be inter-changed between the formulations, underlining again that parameters have to be optimized with respect to the model that is eventually being used. -# -# ## Stomatal Optimization Theories -# -# The empirical formulations only hold in well-watered soil and our main goal is to implement stomatal optimization models to take the entire soil-plant-atmosphere continuum into account[^3]. Here, we will just use the empirical models and steady-state photosynthesis to show the underlying principles. -# -# [^1]: Ball, J.T., Woodrow, I.E. and Berry, J.A., 1987. A model predicting stomatal conductance and its contribution to the control of photosynthesis under different environmental conditions. In Progress in photosynthesis research (pp. 221-224). Springer, Dordrecht. -# -# [^2]: Medlyn, B.E., Duursma, R.A., Eamus, D., Ellsworth, D.S., Prentice, I.C., Barton, C.V., Crous, K.Y., De Angelis, P., Freeman, M. and Wingate, L., 2011. Reconciling the optimal and empirical approaches to modelling stomatal conductance. Global Change Biology, 17(6), pp.2134-2144. -# -# [^3]: Wang, Y., Sperry, J.S., Anderegg, W.R., Venturas, M.D. and Trugman, A.T., 2020. A theoretical and empirical assessment of stomatal optimization modeling. New Phytologist. -# - -## add usual tools -using BenchmarkTools -using PyPlot - -## load photosynthesis modules -using Land.WaterPhysics -using Land.Photosynthesis -using Land.Plant - -## specify floating type -FT = Float32; -#---------------------------------------------------------------------------- - -## define default photosynthesis parameter sets -c3_set = C3CLM(FT); -c4_set = C4CLM(FT); - -## define leaf photosynthetic parameters and environmental conditions -leaf_3 = LeafPhotoContainer{FT}(APAR=1200, Vcmax25=60, Jmax25=120, Vpmax25=80, Rd25=1); -leaf_4 = LeafPhotoContainer{FT}(APAR=1200, Vcmax25=60, Jmax25=120, Vpmax25=80, Rd25=1); -envir = EnvironmentConditions{FT}(); - -## create empirical stomatal scheme -sto_c3 = ESMBallBerry{FT}(g1 = 20) -sto_c4 = ESMBallBerry{FT}(g1 = 4) -#---------------------------------------------------------------------------- - -# ## Stomatal response to CO₂ - -## set the internal CO₂ to 30 Pa and temperature to 298.15 K and PAR to 1500 -leaf_3.p_i=30; leaf_3.T=298.15; leaf_3.APAR=1500; -leaf_4.p_i=30; leaf_4.T=298.15; leaf_4.APAR=1500; - -## set an array of internal CO₂ -p_array = collect(FT, 5:200); -an_3 = similar(p_array); gs_3 = similar(p_array); pi_3 = similar(p_array); -an_4 = similar(p_array); gs_4 = similar(p_array); pi_4 = similar(p_array); - -for i in eachindex(p_array) - envir.p_a = p_array[i]; - get_empirical_gsw_pi(c3_set, leaf_3, envir, sto_c3); - get_empirical_gsw_pi(c4_set, leaf_4, envir, sto_c4); - an_3[i], gs_3[i], pi_3[i] = leaf_3.An, leaf_3.g_sw, leaf_3.p_i - an_4[i], gs_4[i], pi_4[i] = leaf_4.An, leaf_4.g_sw, leaf_4.p_i -end - -## plot the results -figure(figsize=(12,3.5), dpi=100) -tight_layout(true) -subplot(1,3,1) -plot(p_array, an_3, label="C3") -plot(p_array, an_4, label="C4") -xlabel("Leaf internal CO₂ (Pa)", fontsize=12) -ylabel("Anet (μmol m⁻² s⁻¹)" , fontsize=12) -legend() -subplot(1,3,2) -plot(p_array, gs_3, label="C3") -plot(p_array, gs_4, label="C4") -xlabel("Leaf internal CO₂ (Pa)" , fontsize=12) -ylabel("Stomatal conductance (mol m⁻² s⁻¹)", fontsize=12) -legend() -subplot(1,3,3) -plot(p_array, pi_3 ./ p_array, label="C3") -plot(p_array, pi_4 ./ p_array, label="C4") -xlabel("Leaf internal CO₂ (Pa)", fontsize=12) -ylabel("Cc/Ca" , fontsize=12) -legend() -gcf() -#---------------------------------------------------------------------------- - -# ## Stomatal response to PAR - -## set the internal CO₂ to 30 Pa and temperature to 298.15 K and PAR to 1500 -leaf_3.p_i=30; leaf_3.T=298.15; leaf_3.APAR=1500; -leaf_4.p_i=30; leaf_4.T=298.15; leaf_4.APAR=1500; -envir = EnvironmentConditions{FT}(); - -## set an array of internal CO₂ -par_array = collect(FT, 0:10:2000); -an_3 = similar(par_array); gs_3 = similar(par_array); pi_3 = similar(par_array); -an_4 = similar(par_array); gs_4 = similar(par_array); pi_4 = similar(par_array); - -for i in eachindex(par_array) - leaf_3.APAR = par_array[i]; - leaf_4.APAR = par_array[i]; - get_empirical_gsw_pi(c3_set, leaf_3, envir, sto_c3); - get_empirical_gsw_pi(c4_set, leaf_4, envir, sto_c4); - an_3[i], gs_3[i], pi_3[i] = leaf_3.An, leaf_3.g_sw, leaf_3.p_i - an_4[i], gs_4[i], pi_4[i] = leaf_4.An, leaf_4.g_sw, leaf_4.p_i -end - -## plot the results -figure(figsize=(12,3.5), dpi=100) -tight_layout(true) -subplot(1,3,1) -plot(par_array, an_3, label="C3") -plot(par_array, an_4, label="C4") -xlabel("PAR (μmol m⁻² s⁻¹)" , fontsize=12) -ylabel("Anet (μmol m⁻² s⁻¹)", fontsize=12) -legend() -subplot(1,3,2) -plot(par_array, gs_3, label="C3") -plot(par_array, gs_4, label="C4") -xlabel("PAR (μmol m⁻² s⁻¹)" , fontsize=12) -ylabel("Stomatal conductance (mol m⁻² s⁻¹)", fontsize=12) -legend() -subplot(1,3,3) -plot(par_array, pi_3 ./ envir.p_a, label="C3") -plot(par_array, pi_4 ./ envir.p_a, label="C4") -xlabel("PAR (μmol m⁻² s⁻¹)", fontsize=12) -ylabel("Cc/Ca" , fontsize=12) -legend() -gcf() -#---------------------------------------------------------------------------- - -# ## Stomatal response to Temperature - -## set the internal CO₂ to 30 Pa and temperature to 298.15 K and PAR to 1500 -leaf_3.p_i=30; leaf_3.T=298.15; leaf_3.APAR=1500; -leaf_4.p_i=30; leaf_4.T=298.15; leaf_4.APAR=1500; -envir = EnvironmentConditions{FT}(); - -## set an array of internal CO₂ -t_array = collect(FT, 280:320); -an_3 = similar(t_array); gs_3 = similar(t_array); pi_3 = similar(t_array); -an_4 = similar(t_array); gs_4 = similar(t_array); pi_4 = similar(t_array); - -for i in eachindex(t_array) - leaf_3.T = t_array[i]; - leaf_4.T = t_array[i]; - envir.p_H₂O = saturation_vapor_pressure(t_array[i]) * 0.5; - get_empirical_gsw_pi(c3_set, leaf_3, envir, sto_c3); - get_empirical_gsw_pi(c4_set, leaf_4, envir, sto_c4); - an_3[i], gs_3[i], pi_3[i] = leaf_3.An, leaf_3.g_sw, leaf_3.p_i - an_4[i], gs_4[i], pi_4[i] = leaf_4.An, leaf_4.g_sw, leaf_4.p_i -end - -## plot the results -t_array .-= FT(273.15) - -figure(figsize=(12,3.5), dpi=100) -tight_layout(true) -subplot(1,3,1) -plot(t_array, an_3, label="C3") -plot(t_array, an_4, label="C4") -xlabel("Temperature (K)" , fontsize=12) -ylabel("Anet (μmol m⁻² s⁻¹)", fontsize=12) -legend() -subplot(1,3,2) -plot(t_array, gs_3, label="C3") -plot(t_array, gs_4, label="C4") -xlabel("Temperature (K)" , fontsize=12) -ylabel("Stomatal conductance (mol m⁻² s⁻¹)", fontsize=12) -legend() -subplot(1,3,3) -plot(t_array, pi_3 ./ envir.p_a, label="C3") -plot(t_array, pi_4 ./ envir.p_a, label="C4") -xlabel("Temperature (K)", fontsize=12) -ylabel("Cc/Ca" , fontsize=12) -legend() -gcf() -#---------------------------------------------------------------------------- - - - - -##@btime get_empirical_gsw_pi(c3_set, leaf_3, envir, sto_c3); -##@btime get_empirical_gsw_pi(c4_set, leaf_4, envir, sto_c4); diff --git a/docs/src/tutorial_scripts/RAMI_benchmarking_example.jl b/docs/src/tutorial_scripts/RAMI_benchmarking_example.jl deleted file mode 100644 index c7891940..00000000 --- a/docs/src/tutorial_scripts/RAMI_benchmarking_example.jl +++ /dev/null @@ -1,810 +0,0 @@ -# # # RAMI Benchmarking -# The goal of the RAMI4PILPS experiment[^1] is to evaluate different approaches by which Land Surface Models in larger Earth System Models quantify the radiation transfer within vegetation canopies. The RAMI4PILPS can be interpreted as a quality control mechanism used to: -# -# 1) quantify the errors in the radiative transfer scheme; -# -# 2) identify the impact that structural and spectral sub-grid variability may have on radiative transfer; and -# -# 3) verify the conservation of energy at the level of the surface, as well as inconsistencies arising from different levels of assumptions/simplifications. -# -# This approach involves direct comparison with reference solutions obtained from highly accurate 3D models identified during the third phase of the RAMI benchmarking exercise[^2]. -# -# A set of 3D experiments compares the partitioning of incident solar energy into an absorbed (A) flux, a transmitted (T) flux component and the surface reflectance (R). The overall canopy structure for these test cases is reminiscent of open forest canopies with randomly oriented foliage, confined to spherical volumes located at varying heights above the ground. -# In here, we use a total of 36 test cases including various canopy density, soil brightness, and illumination conditions for the visible (VIS) (400-700nm) and near infra-red (NIR) (700-3000nm) spectral ranges. -# -# [^1]: J.L. Widlowski, B. Pinty, M. Clerici, Y. Dai, M. De Kauwe, K. de Ridder, A. Kallel, H. Kobayashi, T. Lavergne, W. Ni-Meister, A. Olchev, T. Quaife, S. Wang, W. Yang, Y. Yang, and H. Yuan (2011), RAMI4PILPS: An intercomparison of formulations for the partitioning of solar radiation in land surface models, Journal of Geophysical Research, 116, G02019, 25, DOI: 10.1029/2010JG001511. -# -# [^2]: Widlowski, J-L., M. Taberner, B. Pinty, V. Bruniquel-Pinel, M. Disney, R. Fernandes, J.-P. Gastellu-Etchegorry, N. Gobron, A. Kuusk, T. Lavergne, S. Leblanc, P. Lewis, E. Martin, M. Mottus, P. J. R. North, W. Qin, M.Robustelli, N. Rochdi, R.Ruiloba, C.Soler, R.Thompson, W. Verhoef, M. M.Verstraete, and D. Xie (2007), 'The third RAdiation transfer Model Intercomparison (RAMI) exercise: Documenting progress in canopy reflectance modelling', Journal of Geophysical Research, 112, D09111, 28, DOI: 10.1029/2006JD007821. -# - - -#### Use Julia Plots package and switch to plotly js option: -using PyPlot - -##---------------------------------------------------------------------------- - -## First, we include Revise (good for debugging) and Parameters (tools for structures) - -##using Revise -using Parameters -##---------------------------------------------------------------------------- - -## Now include the Land modules - -using Land -using Land.CanopyRT -##---------------------------------------------------------------------------- - -##Defining all reference values for the Sparse case - -#---------------------------------------------------------------------------- - -const FT = Float32 - -wl_set = create_wl_para_set(FT) -leaf = create_leaf_bio(FT, wl_set.nwl, wl_set.nWlE, wl_set.nWlF); -canopy_rt = Canopy4RT{FT, 20, 3.0}() -canRad_rt = CanopyRadiation{FT, wl_set.nwl, wl_set.nWlF, length(canopy_rt.litab), length(canopy_rt.lazitab), canopy_rt.nlayers}() -canOpt_rt = create_canopy_optical(FT, wl_set.nwl, canopy_rt.nlayers, length(canopy_rt.lazitab), length(canopy_rt.litab); using_marray=false) -sunRad_rt = IncomingRadiation{FT}(wl_set.swl); - -soil = SoilOpti{FT}(wl_set.wl, FT(0.2)*ones(FT, length(wl_set.wl)), FT[0.1], FT(290.0)) -angles = SolarAngles{FT}() - -arrayOfLeaves = [create_leaf_bio(FT, wl_set.nwl, wl_set.nWlE, wl_set.nWlF) for i in 1:canopy_rt.nlayers] -for i in 1:canopy_rt.nlayers - fluspect!(arrayOfLeaves[i], wl_set) -end - -#---------------------------------------------------------------------------- - -RAMI_SZA = [27.,60.,83.] - -RAMI_fabsRed_050_BLK = [0.09380509999999999, 0.16259713, 0.53931207] -RAMI_frefRed_050_BLK = [0.00330673, 0.00517598, 0.01626682] -RAMI_ftranRed_050_BLK = [0.90288817, 0.83222689, 0.44442110999999995] - -RAMI_fabsRed_050_MED = [0.10897124, 0.17760124000000002, 0.54764719] -RAMI_frefRed_050_MED = [0.09759354, 0.09107608, 0.06177913] -RAMI_ftranRed_050_MED = [0.90337609, 0.83265704, 0.44469279] - -RAMI_fabsRed_050_SNW = [0.21471034, 0.28200132, 0.60564705] -RAMI_frefRed_050_SNW = [0.7526521700000001, 0.6879087300000001, 0.37825442000000004] -RAMI_ftranRed_050_SNW = [0.90659694, 0.83583194, 0.44718138] -#---------------------------------------------------------------------------- - -function RAMI_case(LAI, soil_albedo, clumping_index) - - soil.albedo_SW[:] .=soil_albedo; - ##Clumping index - canopy_rt.Ω = 1.0 - ##Viewing Zenith Angle in degrees - angles.tto=0.0 - ##Leaf Area index - canopy_rt.LAI=LAI - - reflRed_SZA = [] - absRed_SZA = [] - transRed_SZA = [] - - for SZA=0.0:1:85 - angles.tts=SZA - - fluspect!(leaf, wl_set); - compute_canopy_geometry!(canopy_rt, angles, canOpt_rt) - compute_canopy_matrices!(arrayOfLeaves, canOpt_rt); - - ## leaf reflectance RED - leaf.ρ_SW[28] = 0.0735 - ## leaf transmittance - leaf.τ_SW[28]= 0.0566 - - ##Setting all diffuse to zero - sunRad_rt.E_diffuse[28] = 0.0 - - simulate_short_wave!(canopy_rt, canOpt_rt, canRad_rt, sunRad_rt, soil); - push!(reflRed_SZA, canRad_rt.alb_direct[28]) - push!(absRed_SZA, (sum(canRad_rt.netSW_shade,dims=2)[28,1].+sum(canRad_rt.netSW_sunlit,dims=2)[28,1])./(sunRad_rt.E_diffuse[28].+sunRad_rt.E_direct[28])) - push!(transRed_SZA, (canOpt_rt.Es_[28,end] .+ canRad_rt.E_down[28,end])./(sunRad_rt.E_diffuse[28].+sunRad_rt.E_direct[28])) - end - - ######## Clumped Case - - reflRed_clump_SZA = [] - absRed_clump_SZA = [] - transRed_clump_SZA = [] - - - ##Clumping index - canopy_rt.Ω = clumping_index - - for SZA=0.0:1:85 - angles.tts=SZA - - fluspect!(leaf, wl_set); - compute_canopy_geometry!(canopy_rt, angles, canOpt_rt) - compute_canopy_matrices!(arrayOfLeaves, canOpt_rt); - - simulate_short_wave!(canopy_rt, canOpt_rt, canRad_rt, sunRad_rt, soil); - push!(reflRed_clump_SZA, canRad_rt.alb_direct[28]) - push!(absRed_clump_SZA, (sum(canRad_rt.netSW_shade,dims=2)[28,1].+sum(canRad_rt.netSW_sunlit,dims=2)[28,1])./(sunRad_rt.E_diffuse[28].+sunRad_rt.E_direct[28])) - push!(transRed_clump_SZA, (canOpt_rt.Es_[28,end] .+ canRad_rt.E_down[28,end])./(sunRad_rt.E_diffuse[28].+sunRad_rt.E_direct[28])) - - end - - return reflRed_SZA,absRed_SZA,transRed_SZA,reflRed_clump_SZA,absRed_clump_SZA,transRed_clump_SZA - -end; - -#---------------------------------------------------------------------------- - - -#TODO nest those into a loop! - -##Sparse case with black soil -reflRed_SZA,absRed_SZA,transRed_SZA,reflRed_clump_SZA,absRed_clump_SZA,transRed_clump_SZA=RAMI_case(0.50265, 0.0, 0.365864235); - -#---------------------------------------------------------------------------- - -SZA=0:1:85 - -figure(figsize=(10,5)) - -subplot(1,2,1) -plot(SZA, reflRed_SZA,label=["reflectance"]) -plot(SZA, absRed_SZA ,label=["absorptance"]) -plot(SZA, transRed_SZA,label=["transmittance"]) -scatter(RAMI_SZA, RAMI_frefRed_050_BLK) -scatter(RAMI_SZA, RAMI_fabsRed_050_BLK) -scatter(RAMI_SZA, RAMI_ftranRed_050_BLK) -title("050_BLK - Default") -ylabel("Radiation Partitioning") -xlabel("Sun Zenith Angle") -xlim(0.0, 90.) -ylim(-0.05, 1.0) -xticks(0:20:91.) -yticks(0:0.2:1.0) - -subplot(1,2,2) -plot(SZA, reflRed_clump_SZA,label=["reflectance"]) -plot(SZA, absRed_clump_SZA ,label=["absorptance"]) -plot(SZA,transRed_clump_SZA,label=["transmittance"]) -scatter(RAMI_SZA, RAMI_frefRed_050_BLK,label="RAMI reflectance") -scatter(RAMI_SZA, RAMI_fabsRed_050_BLK,label="RAMI absorptance") -scatter(RAMI_SZA, RAMI_ftranRed_050_BLK,label="RAMI transmittance") -title("Clumping") -ylabel("Radiation Partitioning") -xlabel("Sun Zenith Angle") -xlim(0.0, 90.) -ylim(-0.05, 1.0) -xticks(0:20:91.) -yticks(0:0.2:1.0) - -legend() -gcf() - -#---------------------------------------------------------------------------- - -##Sparse case with medium soil -reflRed_SZA,absRed_SZA,transRed_SZA,reflRed_clump_SZA,absRed_clump_SZA,transRed_clump_SZA=RAMI_case(0.50265, 0.1217, 0.365864235); - -#---------------------------------------------------------------------------- - -SZA=0:1:85 - -figure(figsize=(10,5)) - -subplot(1,2,1) -plot(SZA, reflRed_SZA,label=["reflectance"]) -plot(SZA, absRed_SZA ,label=["absorptance"]) -plot(SZA, transRed_SZA,label=["transmittance"]) -scatter(RAMI_SZA, RAMI_frefRed_050_MED) -scatter(RAMI_SZA, RAMI_fabsRed_050_MED) -scatter(RAMI_SZA, RAMI_ftranRed_050_MED) -title("050_MED - Default") -ylabel("Radiation Partitioning") -xlabel("Sun Zenith Angle") -xlim(0.0, 90.) -ylim(-0.05, 1.0) -xticks(0:20:91.) -yticks(0:0.2:1.0) - -subplot(1,2,2) -plot(SZA, reflRed_clump_SZA,label=["reflectance"]) -plot(SZA, absRed_clump_SZA ,label=["absorptance"]) -plot(SZA,transRed_clump_SZA,label=["transmittance"]) -scatter(RAMI_SZA, RAMI_frefRed_050_MED,label="RAMI reflectance") -scatter(RAMI_SZA, RAMI_fabsRed_050_MED,label="RAMI absorptance") -scatter(RAMI_SZA, RAMI_ftranRed_050_MED,label="RAMI transmittance") -title("Clumping") -ylabel("Radiation Partitioning") -xlabel("Sun Zenith Angle") -xlim(0.0, 90.) -ylim(-0.05, 1.0) -xticks(0:20:91.) -yticks(0:0.2:1.0) - -legend() -gcf() - -#---------------------------------------------------------------------------- - -##Sparse case with snowy soil -reflRed_SZA,absRed_SZA,transRed_SZA,reflRed_clump_SZA,absRed_clump_SZA,transRed_clump_SZA=RAMI_case(0.50265, 0.9640, 0.365864235); - -#---------------------------------------------------------------------------- - -SZA=0:1:85 - -figure(figsize=(10,5)) - -subplot(1,2,1) -plot(SZA, reflRed_SZA,label=["reflectance"]) -plot(SZA, absRed_SZA ,label=["absorptance"]) -plot(SZA, transRed_SZA,label=["transmittance"]) -scatter(RAMI_SZA, RAMI_frefRed_050_SNW) -scatter(RAMI_SZA, RAMI_fabsRed_050_SNW) -scatter(RAMI_SZA, RAMI_ftranRed_050_SNW) -title("050_SNW - Default") -ylabel("Radiation Partitioning") -xlabel("Sun Zenith Angle") -xlim(0.0, 90.) -ylim(-0.05, 1.0) -xticks(0:20:91.) -yticks(0:0.2:1.0) - -subplot(1,2,2) -plot(SZA, reflRed_clump_SZA,label=["reflectance"]) -plot(SZA, absRed_clump_SZA ,label=["absorptance"]) -plot(SZA,transRed_clump_SZA,label=["transmittance"]) -scatter(RAMI_SZA, RAMI_frefRed_050_SNW,label="RAMI reflectance") -scatter(RAMI_SZA, RAMI_fabsRed_050_SNW,label="RAMI absorptance") -scatter(RAMI_SZA, RAMI_ftranRed_050_SNW,label="RAMI transmittance") -title("Clumping") -ylabel("Radiation Partitioning") -xlabel("Sun Zenith Angle") -xlim(0.0, 90.) -ylim(-0.05, 1.0) -xticks(0:20:91.) -yticks(0:0.2:1.0) - -legend() -gcf() - -#---------------------------------------------------------------------------- - -##Defining all reference values for the Medium case - -RAMI_SZA = [27.,60.,83.] - - -RAMI_fabsRed_150_BLK = [0.28137804, 0.46514268999999997, 0.89063486] -RAMI_frefRed_150_BLK = [0.00923676, 0.01379672, 0.02970703] -RAMI_ftranRed_150_BLK = [0.7093851999999999, 0.52106059, 0.07965811] - -RAMI_fabsRed_150_MED = [0.31403827, 0.49003033, 0.89432051] -RAMI_frefRed_150_MED = [0.06195053, 0.05151941, 0.03561715] -RAMI_ftranRed_150_MED = [0.7104761399999999, 0.52197456, 0.07977039000000001] - -RAMI_fabsRed_150_SNW = [0.5431621799999999, 0.66519762, 0.9201217300000001] -RAMI_frefRed_150_SNW = [0.43100610000000006, 0.31581022999999997, 0.07698033] -RAMI_ftranRed_150_SNW = [0.71754777, 0.52755972, 0.08049832999999999] -#---------------------------------------------------------------------------- - -##Medium case with black soil -reflRed_SZA,absRed_SZA,transRed_SZA,reflRed_clump_SZA,absRed_clump_SZA,transRed_clump_SZA=RAMI_case(1.5017, 0.0, 0.405417644); - -#---------------------------------------------------------------------------- - -SZA=0:1:85 - -figure(figsize=(10,5)) - -subplot(1,2,1) -plot(SZA, reflRed_SZA,label=["reflectance"]) -plot(SZA, absRed_SZA ,label=["absorptance"]) -plot(SZA, transRed_SZA,label=["transmittance"]) -scatter(RAMI_SZA, RAMI_frefRed_150_BLK) -scatter(RAMI_SZA, RAMI_fabsRed_150_BLK) -scatter(RAMI_SZA, RAMI_ftranRed_150_BLK) -title("150_BLK - Default") -ylabel("Radiation Partitioning") -xlabel("Sun Zenith Angle") -xlim(0.0, 90.) -ylim(-0.05, 1.0) -xticks(0:20:91.) -yticks(0:0.2:1.0) - -subplot(1,2,2) -plot(SZA, reflRed_clump_SZA,label=["reflectance"]) -plot(SZA, absRed_clump_SZA ,label=["absorptance"]) -plot(SZA,transRed_clump_SZA,label=["transmittance"]) -scatter(RAMI_SZA, RAMI_frefRed_150_BLK,label="RAMI reflectance") -scatter(RAMI_SZA, RAMI_fabsRed_150_BLK,label="RAMI absorptance") -scatter(RAMI_SZA, RAMI_ftranRed_150_BLK,label="RAMI transmittance") -title("Clumping") -ylabel("Radiation Partitioning") -xlabel("Sun Zenith Angle") -xlim(0.0, 90.) -ylim(-0.05, 1.0) -xticks(0:20:91.) -yticks(0:0.2:1.0) - -legend() -gcf() - -#---------------------------------------------------------------------------- - -##Medium case with medium soil -reflRed_SZA,absRed_SZA,transRed_SZA,reflRed_clump_SZA,absRed_clump_SZA,transRed_clump_SZA=RAMI_case(1.5017, 0.1217, 0.405417644); - -#---------------------------------------------------------------------------- - -SZA=0:1:85 - -figure(figsize=(10,5)) - -subplot(1,2,1) -plot(SZA, reflRed_SZA,label=["reflectance"]) -plot(SZA, absRed_SZA ,label=["absorptance"]) -plot(SZA, transRed_SZA,label=["transmittance"]) -scatter(RAMI_SZA, RAMI_frefRed_150_MED) -scatter(RAMI_SZA, RAMI_fabsRed_150_MED) -scatter(RAMI_SZA, RAMI_ftranRed_150_MED) -title("150_MED - Default") -ylabel("Radiation Partitioning") -xlabel("Sun Zenith Angle") -xlim(0.0, 90.) -ylim(-0.05, 1.0) -xticks(0:20:91.) -yticks(0:0.2:1.0) - -subplot(1,2,2) -plot(SZA, reflRed_clump_SZA,label=["reflectance"]) -plot(SZA, absRed_clump_SZA ,label=["absorptance"]) -plot(SZA,transRed_clump_SZA,label=["transmittance"]) -scatter(RAMI_SZA, RAMI_frefRed_150_MED,label="RAMI reflectance") -scatter(RAMI_SZA, RAMI_fabsRed_150_MED,label="RAMI absorptance") -scatter(RAMI_SZA, RAMI_ftranRed_150_MED,label="RAMI transmittance") -title("Clumping") -ylabel("Radiation Partitioning") -xlabel("Sun Zenith Angle") -xlim(0.0, 90.) -ylim(-0.05, 1.0) -xticks(0:20:91.) -yticks(0:0.2:1.0) - -legend() -gcf() - -#---------------------------------------------------------------------------- - -##Medium case with black soil -reflRed_SZA,absRed_SZA,transRed_SZA,reflRed_clump_SZA,absRed_clump_SZA,transRed_clump_SZA=RAMI_case(1.5017, 0.9640, 0.405417644); - -#---------------------------------------------------------------------------- - -SZA=0:1:85 - -figure(figsize=(10,5)) - -subplot(1,2,1) -plot(SZA, reflRed_SZA,label=["reflectance"]) -plot(SZA, absRed_SZA ,label=["absorptance"]) -plot(SZA, transRed_SZA,label=["transmittance"]) -scatter(RAMI_SZA, RAMI_frefRed_150_SNW) -scatter(RAMI_SZA, RAMI_fabsRed_150_SNW) -scatter(RAMI_SZA, RAMI_ftranRed_150_SNW) -title("150_SNW - Default") -ylabel("Radiation Partitioning") -xlabel("Sun Zenith Angle") -xlim(0.0, 90.) -ylim(-0.05, 1.0) -xticks(0:20:91.) -yticks(0:0.2:1.0) - -subplot(1,2,2) -plot(SZA, reflRed_clump_SZA,label=["reflectance"]) -plot(SZA, absRed_clump_SZA ,label=["absorptance"]) -plot(SZA,transRed_clump_SZA,label=["transmittance"]) -scatter(RAMI_SZA, RAMI_frefRed_150_SNW,label="RAMI reflectance") -scatter(RAMI_SZA, RAMI_fabsRed_150_SNW,label="RAMI absorptance") -scatter(RAMI_SZA, RAMI_ftranRed_150_SNW,label="RAMI transmittance") -title("Clumping") -ylabel("Radiation Partitioning") -xlabel("Sun Zenith Angle") -xlim(0.0, 90.) -ylim(-0.05, 1.0) -xticks(0:20:91.) -yticks(0:0.2:1.0) - -legend() -gcf() - -#---------------------------------------------------------------------------- - -##Defining all reference values for the Dense case - -RAMI_SZA = [27.,60.,83.] - - -RAMI_fabsRed_250_BLK = [0.46852539, 0.70426097, 0.9461774300000001] -RAMI_frefRed_250_BLK = [0.01445858, 0.02016963, 0.03477486] -RAMI_ftranRed_250_BLK = [0.51701603, 0.2755694, 0.01904771] - -RAMI_fabsRed_250_MED = [0.50540545, 0.72429659, 0.94742381] -RAMI_frefRed_250_MED = [0.03953053, 0.03315039, 0.03580858] -RAMI_ftranRed_250_MED = [0.51811911, 0.27616192, 0.01909098] - -RAMI_fabsRed_250_SNW = [0.76512258, 0.86538802, 0.9562473199999999] -RAMI_frefRed_250_SNW = [0.21595537, 0.124503, 0.043056080000000004] -RAMI_ftranRed_250_SNW = [0.5256125, 0.280805, 0.01935] -#---------------------------------------------------------------------------- - -##Dense case with black soil -reflRed_SZA,absRed_SZA,transRed_SZA,reflRed_clump_SZA,absRed_clump_SZA,transRed_clump_SZA=RAMI_case(2.5007, 0.0, 0.45946608); - -#---------------------------------------------------------------------------- - -SZA=0:1:85 - -figure(figsize=(10,5)) - -subplot(1,2,1) -plot(SZA, reflRed_SZA,label=["reflectance"]) -plot(SZA, absRed_SZA ,label=["absorptance"]) -plot(SZA, transRed_SZA,label=["transmittance"]) -scatter(RAMI_SZA, RAMI_frefRed_250_BLK) -scatter(RAMI_SZA, RAMI_fabsRed_250_BLK) -scatter(RAMI_SZA, RAMI_ftranRed_250_BLK) -title("250_BLK - Default") -ylabel("Radiation Partitioning") -xlabel("Sun Zenith Angle") -xlim(0.0, 90.) -ylim(-0.05, 1.0) -xticks(0:20:91.) -yticks(0:0.2:1.0) - -subplot(1,2,2) -plot(SZA, reflRed_clump_SZA,label=["reflectance"]) -plot(SZA, absRed_clump_SZA ,label=["absorptance"]) -plot(SZA,transRed_clump_SZA,label=["transmittance"]) -scatter(RAMI_SZA, RAMI_frefRed_250_BLK,label="RAMI reflectance") -scatter(RAMI_SZA, RAMI_fabsRed_250_BLK,label="RAMI absorptance") -scatter(RAMI_SZA, RAMI_ftranRed_250_BLK,label="RAMI transmittance") -title("Clumping") -ylabel("Radiation Partitioning") -xlabel("Sun Zenith Angle") -xlim(0.0, 90.) -ylim(-0.05, 1.0) -xticks(0:20:91.) -yticks(0:0.2:1.0) - -legend() -gcf() - -#---------------------------------------------------------------------------- - -##Medium case with medium soil -reflRed_SZA,absRed_SZA,transRed_SZA,reflRed_clump_SZA,absRed_clump_SZA,transRed_clump_SZA=RAMI_case(2.5007, 0.1217, 0.45946608); - -#---------------------------------------------------------------------------- - -SZA=0:1:85 - -figure(figsize=(10,5)) - -subplot(1,2,1) -plot(SZA, reflRed_SZA,label=["reflectance"]) -plot(SZA, absRed_SZA ,label=["absorptance"]) -plot(SZA, transRed_SZA,label=["transmittance"]) -scatter(RAMI_SZA, RAMI_frefRed_250_MED) -scatter(RAMI_SZA, RAMI_fabsRed_250_MED) -scatter(RAMI_SZA, RAMI_ftranRed_250_MED) -title("250_MED - Default") -ylabel("Radiation Partitioning") -xlabel("Sun Zenith Angle") -xlim(0.0, 90.) -ylim(-0.05, 1.0) -xticks(0:20:91.) -yticks(0:0.2:1.0) - -subplot(1,2,2) -plot(SZA, reflRed_clump_SZA,label=["reflectance"]) -plot(SZA, absRed_clump_SZA ,label=["absorptance"]) -plot(SZA,transRed_clump_SZA,label=["transmittance"]) -scatter(RAMI_SZA, RAMI_frefRed_250_MED,label="RAMI reflectance") -scatter(RAMI_SZA, RAMI_fabsRed_250_MED,label="RAMI absorptance") -scatter(RAMI_SZA, RAMI_ftranRed_250_MED,label="RAMI transmittance") -title("Clumping") -ylabel("Radiation Partitioning") -xlabel("Sun Zenith Angle") -xlim(0.0, 90.) -ylim(-0.05, 1.0) -xticks(0:20:91.) -yticks(0:0.2:1.0) - -legend() -gcf() - -#---------------------------------------------------------------------------- - -##Dense case with snowy soil -reflRed_SZA,absRed_SZA,transRed_SZA,reflRed_clump_SZA,absRed_clump_SZA,transRed_clump_SZA=RAMI_case(2.5007, 0.9640, 0.45946608); - -#---------------------------------------------------------------------------- - -SZA=0:1:85 - -figure(figsize=(10,5)) - -subplot(1,2,1) -plot(SZA, reflRed_SZA,label=["reflectance"]) -plot(SZA, absRed_SZA ,label=["absorptance"]) -plot(SZA, transRed_SZA,label=["transmittance"]) -scatter(RAMI_SZA, RAMI_frefRed_250_SNW) -scatter(RAMI_SZA, RAMI_fabsRed_250_SNW) -scatter(RAMI_SZA, RAMI_ftranRed_250_SNW) -title("250_SNW - Default") -ylabel("Radiation Partitioning") -xlabel("Sun Zenith Angle") -xlim(0.0, 90.) -ylim(-0.05, 1.0) -xticks(0:20:91.) -yticks(0:0.2:1.0) - -subplot(1,2,2) -plot(SZA, reflRed_clump_SZA,label=["reflectance"]) -plot(SZA, absRed_clump_SZA ,label=["absorptance"]) -plot(SZA,transRed_clump_SZA,label=["transmittance"]) -scatter(RAMI_SZA, RAMI_frefRed_250_SNW,label="RAMI reflectance") -scatter(RAMI_SZA, RAMI_fabsRed_250_SNW,label="RAMI absorptance") -scatter(RAMI_SZA, RAMI_ftranRed_250_SNW,label="RAMI transmittance") -title("Clumping") -ylabel("Radiation Partitioning") -xlabel("Sun Zenith Angle") -xlim(0.0, 90.) -ylim(-0.05, 1.0) -xticks(0:20:91.) -yticks(0:0.2:1.0) - -legend() -gcf() - -#---------------------------------------------------------------------------- - -# # ### Test a VZA dependence in the principal plane with clumping - -## Define a few wavelengths: -wl_blue = 450.0; -wl_red = 600.0; -wl_FarRed = 740.0; -wl_Red = 685.0; -ind_wle_blue = argmin(abs.(wl_set.wle .-wl_blue)); -ind_wle_red = argmin(abs.(wl_set.wle .-wl_red)); -ind_wlf_FR = argmin(abs.(wl_set.wlf .-wl_FarRed)); -ind_wlf_R = argmin(abs.(wl_set.wlf .-wl_Red)); -ind_red = argmin(abs.(wl_set.wl .-wl_Red)); -ind_NIR = argmin(abs.(wl_set.wl .-800)); - -#---------------------------------------------------------------------------- - -SIF_FR = Float32[] -SIF_R = Float32[] -reflVIS = Float32[] -reflNIR = Float32[] - -#### Just running the code over all geometries: -##MED -soil.albedo_SW[:] .=0.1217; -#### Set sun SZA to 27 degrees -angles.tts=27. -#### Set 0 azimuth (principal plane) -angles.psi=0 - -##Adding clumping -canopy_rt.Ω = 1.0 -#### LAI of 3: -canopy_rt.LAI = 2.5007 -#### Define VZA -VZA=collect(-89.5:0.5:89.5) - -for VZA_ in VZA - angles.tto=VZA_ - compute_canopy_geometry!(canopy_rt, angles, canOpt_rt) - compute_canopy_matrices!(arrayOfLeaves, canOpt_rt); - simulate_short_wave!(canopy_rt, canOpt_rt, canRad_rt, sunRad_rt, soil); - computeSIF_Fluxes!(arrayOfLeaves, canOpt_rt, canRad_rt, canopy_rt, soil, wl_set); - #### Handpicked indices in - push!(reflVIS, canRad_rt.alb_obs[ind_red]) - push!(reflNIR, canRad_rt.alb_obs[ind_NIR]) - push!(SIF_R , canRad_rt.SIF_obs[ind_wlf_R]) - push!(SIF_FR, canRad_rt.SIF_obs[ind_wlf_FR ]) -end - - -##Adding clumping -canopy_rt.Ω = 0.45946608 - -SIF_FR_clump = Float32[] -SIF_R_clump = Float32[] -reflVIS_clump = Float32[] -reflNIR_clump = Float32[] - - -for VZA_ in VZA - angles.tto=VZA_ - compute_canopy_geometry!(canopy_rt, angles, canOpt_rt) - compute_canopy_matrices!(arrayOfLeaves, canOpt_rt); - simulate_short_wave!(canopy_rt, canOpt_rt, canRad_rt, sunRad_rt, soil); - computeSIF_Fluxes!(arrayOfLeaves, canOpt_rt, canRad_rt, canopy_rt, soil, wl_set); - #### Handpicked indices in - push!(reflVIS_clump, canRad_rt.alb_obs[ind_red]) - push!(reflNIR_clump, canRad_rt.alb_obs[ind_NIR]) - push!(SIF_R_clump , canRad_rt.SIF_obs[ind_wlf_R]) - push!(SIF_FR_clump, canRad_rt.SIF_obs[ind_wlf_FR ]) -end -#---------------------------------------------------------------------------- - -#### Plots Visible -figure() -plot(VZA, reflVIS, color=:black,label="Red Reflectance", lw=2) -plot(VZA, SIF_R/30, color=:orange,label="Red SIF (/30)", lw=2) -plot(VZA, reflVIS_clump, color=:black, ls="--", lw=2,label="Red Reflectance w/ Clumping") -plot(VZA, SIF_R_clump/30, color=:orange, ls="--", lw=2,label="Red SIF (/30) w/ Clumping") -xlabel("Viewing Zenith Angle") -legend() -gcf() -#---------------------------------------------------------------------------- - -#### Plots Visible -figure() -plot(VZA, reflNIR, color=:black,label="NIR Reflectance", lw=2) -plot(VZA, SIF_FR/6, color=:orange,label="Far Red SIF (/6)", lw=2) -plot(VZA, reflNIR_clump, color=:black, ls="--", lw=2,label="NIR Reflectance w/ Clumping") -plot(VZA, SIF_FR_clump/6, color=:orange, ls="--", lw=2,label="Far Red SIF (/6) w/ Clumping") -xlabel("Viewing Zenith Angle") -legend() -gcf() -#---------------------------------------------------------------------------- - -# # ## BRDF sampling -# -# By going through viewing and azimuth angles, we can construct a full BRDF for reflectance and SIF emissions at different wavelengths: -# - -reflVIS = Float32[] -reflNIR = Float32[] -SIF_FR = Float32[] -SIF_R = Float32[] - -##MED -soil.albedo_SW[:] .=0.1217; -angles.tts=27. -angles.psi=0 -canopy_rt.LAI=2.5007 -canopy_rt.Ω = 1.0 -for psi=0:360 - angles.psi=psi - for VZA=0:1:85 - angles.tto=VZA - - compute_canopy_geometry!(canopy_rt, angles, canOpt_rt) - compute_canopy_matrices!(arrayOfLeaves, canOpt_rt); - simulate_short_wave!(canopy_rt, canOpt_rt, canRad_rt, sunRad_rt, soil); - computeSIF_Fluxes!(arrayOfLeaves, canOpt_rt, canRad_rt, canopy_rt, soil, wl_set); - push!(reflVIS, canRad_rt.alb_obs[28]) - push!(reflNIR, canRad_rt.alb_obs[52]) - push!(SIF_R , canRad_rt.SIF_obs[8]) - push!(SIF_FR, canRad_rt.SIF_obs[20]) - end -end - -##Adding clumping -canopy_rt.Ω = 0.45946608 - -SIF_FR_clump = Float32[] -SIF_R_clump = Float32[] -reflVIS_clump = Float32[] -reflNIR_clump = Float32[] - -for psi=0:360 - angles.psi=psi - for VZA=0:1:85 - angles.tto=VZA - - compute_canopy_geometry!(canopy_rt, angles, canOpt_rt) - compute_canopy_matrices!(arrayOfLeaves, canOpt_rt); - simulate_short_wave!(canopy_rt, canOpt_rt, canRad_rt, sunRad_rt, soil); - computeSIF_Fluxes!(arrayOfLeaves, canOpt_rt, canRad_rt, canopy_rt, soil, wl_set); - push!(reflVIS_clump, canRad_rt.alb_obs[28]) - push!(reflNIR_clump, canRad_rt.alb_obs[52]) - push!(SIF_R_clump , canRad_rt.SIF_obs[8]) - push!(SIF_FR_clump, canRad_rt.SIF_obs[20]) - end -end - - -#---------------------------------------------------------------------------- - -A = reshape(reflNIR, ( 86,361)); -B = reshape(reflVIS, ( 86,361)); -SIFFER = reshape(SIF_R, ( 86,361)); -SIFFER_FR = reshape(SIF_FR, ( 86,361)); - -A_clump = reshape(reflNIR_clump, ( 86,361)); -B_clump = reshape(reflVIS_clump, ( 86,361)); -SIFFER_clump = reshape(SIF_R_clump, ( 86,361)); -SIFFER_FR_clump = reshape(SIF_FR_clump, ( 86,361)); -#---------------------------------------------------------------------------- - -figure(figsize=(10,5)) -subplot(1,2,1, polar=true) -grid(false) -hm = contourf(deg2rad.(collect((0:360))),collect(0:1:85), A, cmap=:viridis, levels=collect(0.25:0.012:0.5)) -title("NIR reflectance BRDF") -yticks([]) -colorbar() -subplot(1,2,2, polar=true) -grid(false) -hm = contourf(deg2rad.(collect((0:360))),collect(0:1:85), A_clump, cmap=:viridis, levels=collect(0.25:0.012:0.5)) -title("Clumping") -yticks([]) -colorbar() -gcf() - -#---------------------------------------------------------------------------- - -figure(figsize=(10,5)) -subplot(1,2,1, polar=true) -grid(false) -hm = contourf(deg2rad.(collect((0:360))),collect(0:1:85), B, cmap=:viridis, levels=collect(0.0:0.005:0.045)) -title("Red reflectance BRDF") -yticks([]) -colorbar() -subplot(1,2,2, polar=true) -grid(false) -hm = contourf(deg2rad.(collect((0:360))),collect(0:1:85), B_clump, cmap=:viridis, levels=collect(0.0:0.005:0.045)) -title("Clumping") -yticks([]) -colorbar() -gcf() - -#---------------------------------------------------------------------------- - -figure(figsize=(10,5)) -subplot(1,2,1, polar=true) -grid(false) -hm = contourf(deg2rad.(collect((0:360))),collect(0:1:85), SIFFER, cmap=:viridis, levels=collect(0.3:0.05:0.8)) -title("Red SIF emission BRDF") -yticks([]) -colorbar() -subplot(1,2,2, polar=true) -grid(false) -hm = contourf(deg2rad.(collect((0:360))),collect(0:1:85), SIFFER_clump, cmap=:viridis, levels=collect(0.3:0.05:0.8)) -title("Clumping") -yticks([]) -colorbar() -gcf() - - -#---------------------------------------------------------------------------- - -figure(figsize=(10,5)) -subplot(1,2,1, polar=true) -grid(false) -hm = contourf(deg2rad.(collect((0:360))),collect(0:1:85), SIFFER_FR, cmap=:viridis, levels=collect(1.:0.1:3.5)) -title("Far-Red SIF emission BRDF") -yticks([]) -colorbar() -subplot(1,2,2, polar=true) -grid(false) -hm = contourf(deg2rad.(collect((0:360))),collect(0:1:85), SIFFER_FR_clump, cmap=:viridis, levels=collect(1.:0.1:3.5)) -title("Clumping") -yticks([]) -colorbar() -gcf() - - - -#---------------------------------------------------------------------------- diff --git a/docs/src/tutorial_scripts/Radiation_Test_BRDF.jl b/docs/src/tutorial_scripts/Radiation_Test_BRDF.jl deleted file mode 100644 index 172d22f1..00000000 --- a/docs/src/tutorial_scripts/Radiation_Test_BRDF.jl +++ /dev/null @@ -1,314 +0,0 @@ - -# # Canopy Radiative Transfer Example #1 -# This example will go through the calculations of hemispheric and bidirectional reflectance as well as emission of Solar Induced Chlorophyll Fluorescence (SIF). The sun sensor geometry is defined by the solar zenith angle SZA, the viewing zenith angle VZA (observer, 0degrees=Nadir looking) and the relative azimuth angle between the sun and observer (0 or 180degrees denoting the principal plane). -# - -## Use Julia Plots package and switch to plotly js option: -using PyPlot - -#---------------------------------------------------------------------------- - -# First, we include Revise (good for debugging) and Parameters (tools for structures) - -#using Revise -using Parameters -#---------------------------------------------------------------------------- - -# Now include the Land modules - -using Land -using Land.CanopyRT -#---------------------------------------------------------------------------- - -# and unpack some of the mostly used variables or structure (same as writing CanopyRT.leafbio) - -#(; FT, leafbio, canopy, angles, canOpt, canRad,sunRad,soil, wl, wle, wlf) = CanopyRT -#---------------------------------------------------------------------------- - -# This extracted a number of structures, which are loaded with default values at startup: -# * *leafbio* includes all leaf pigment concentrations, such as Chlorophyll, leaf water, Carotenoids and dry matter content. (mutable struct leafbio) -# * *canopy* includes Canopy properties such as LAI, leaf inclination distribution, clumping factor (mutable struct struct_canopy) -# * *angles* includes SZA, VZA and azimuth (mutable struct struct_angles) -# * *canOpt* saves a variety of canopy optical properties to be computed (mutable struct struct_canopyOptProps) -# * *canRad* includes radiation computed within the Canopy RT module (mutable struct struct_canopyRadiation) -# * *sunRad* provides incoming direct and diffuse incoming solar radiation (mutable struct incomingRadiation) -# * *soil* provides soil albedo and skin temperature -# -# as well as some arrays: -# * *wl* is the wavelength grid (nm) for the solar radiation computation -# * *wle* is the wavelength grid in the photosynthetically active range (a subset of wl, used to define fluorescence excitation and driving photosynthesis) -# * *wlf* is the wavelength grid for SIF (subset of wl). The fluorescence excitation matrices are defined on the basis of wle and wlf. - -# Let us just define our own leaf here, we can construct it using standard values but need to provide all dimensions (will be fixed as variables are saved in MArrays): - -const FT = Float32 - -wl_set = create_wl_para_set(FT) -leaf = create_leaf_bio(FT, wl_set.nwl, wl_set.nWlE, wl_set.nWlF); -canopy_rt = Canopy4RT{FT, 20, 3.0}() -canRad_rt = CanopyRadiation{FT, wl_set.nwl, wl_set.nWlF, length(canopy_rt.litab), length(canopy_rt.lazitab), canopy_rt.nlayers}() -canOpt_rt = create_canopy_optical(FT, wl_set.nwl, canopy_rt.nlayers, length(canopy_rt.lazitab), length(canopy_rt.litab); using_marray=false) -sunRad_rt = IncomingRadiation{FT}(wl_set.swl); - -## show leaf Chlorophyll content: -@show leaf.Cab -#---------------------------------------------------------------------------- - -# --- -# ## Leaf Optical Properties -# -# Now we can first run fluspect, which is an extension of the Prospect leaf optical properties program and includes computations of the fluorescence emission responses as well. CanopyRT.optis includes all pigment absorption cross sections as well as refractive index of water to compute leaf optical properties. -# For details, see: -# -# Féret, J.B., Gitelson, A.A., Noble, S.D. and Jacquemoud, S., 2017. PROSPECT-D: Towards modeling leaf optical properties through a complete lifecycle. Remote Sensing of Environment, 193, pp.204-215. -# -# Van der Tol, C., Verhoef, W., Timmermans, J., Verhoef, A. and Su, Z., 2009. An integrated model of soil-canopy spectral radiances, photosynthesis, fluorescence, temperature and energy balance. Biogeosciences, 6(12). -# -# Vilfan, N., Van der Tol, C., Muller, O., Rascher, U. and Verhoef, W., 2016. Fluspect-B: A model for leaf fluorescence, reflectance and transmittance spectra. Remote sensing of environment, 186, pp.596-615. - -## Run Fluspect: -fluspect!(leaf, wl_set); -#---------------------------------------------------------------------------- - -# #### Fluorescence excitation matrices -# Now we can visualize the fluorescence excitatiom matrices, which determine how absorbed photons at a specific wavelength *wle* incident on the leaf are emitted backwards (in relation to the incident light but hemispherically diffuse here) or forward. Here, we ignore contributions from Photosystem I and just use a fixed shape as input at the chloroplast level for Photosystem II, hence all spectral shapes are determined by the light distribution within the leaf. Several effects can be observed in the plots below: The first SIF peak at 680nm is much weaker in the forward direction than in the backward direction as more the re-absorption within the leaf is much higher for the forward direction. Similarly, blue incident light penetrates the leaf less than at higher wavelengths, so the chlorophyll re-absorption (backwards) is less re-absorbed by chlorophyll as it emanates from less deep layers. -# - -## Plot Mb matrix -figure() -contourf(wl_set.wle, wl_set.wlf, leaf.Mb) -xlabel("Excitation wavelength (nm)") -ylabel("Emission wavelength (nm)") -title("Fluorescence backward (refl) emission (Mb)") -gcf() -#---------------------------------------------------------------------------- - -## Plot Mf matrix -figure() -contourf(wl_set.wle, wl_set.wlf, leaf.Mf) -xlabel("Excitation wavelength (nm)") -ylabel("Emission wavelength (nm)") -title("Fluorescence forward (transmission) emission (Mf)") -gcf() -#---------------------------------------------------------------------------- - -## Define a few wavelengths: -wl_blue = 450.0; -wl_red = 600.0; -wl_FarRed = 740.0; -wl_Red = 685.0; -ind_wle_blue = argmin(abs.(wl_set.wle .-wl_blue)); -ind_wle_red = argmin(abs.(wl_set.wle .-wl_red)); -ind_wlf_FR = argmin(abs.(wl_set.wlf .-wl_FarRed)); -ind_wlf_R = argmin(abs.(wl_set.wlf .-wl_Red)); -ind_red = argmin(abs.(wl_set.wl .-wl_Red)); -ind_NIR = argmin(abs.(wl_set.wl .-800)); - -#---------------------------------------------------------------------------- - -## Plot some cross section in wle and wlf space: -figure() -plot(wl_set.wlf,leaf.Mf[:,ind_wle_blue], color=:black, lw = 2 , label="Forward SIF, excited at $wl_blue nm") -plot(wl_set.wlf,leaf.Mb[:,ind_wle_blue],color=:orange, lw = 2 , label="Backward SIF, excited at $wl_blue nm" ) -plot(wl_set.wlf,leaf.Mf[:,ind_wle_red], color=:black,ls="--",lw=2, label="Forward SIF, excited at $wl_red nm" ) -plot(wl_set.wlf,leaf.Mb[:,ind_wle_red], color=:orange,ls="--",lw=2, label="Backward SIF, excited at $wl_red nm" ) -xlabel("Wavelength (nm)") -ylabel("Fluorescence") -legend() -gcf() -#---------------------------------------------------------------------------- - -## Plot some cross section in wle and wlf space: -figure() -plot(wl_set.wle,leaf.Mf[ind_wlf_FR,:], color=:black, lw = 2 , label="Forward SIF, emitted at $wl_FarRed nm") -plot(wl_set.wle,leaf.Mb[ind_wlf_FR,:],color=:orange, lw = 2 , label="Backward SIF, emitted at $wl_FarRed nm" ) -plot(wl_set.wle,leaf.Mf[ind_wlf_R,:], color=:black,ls="--",lw=2, label="Forward SIF, emitted at $wl_Red nm" ) -plot(wl_set.wle,leaf.Mb[ind_wlf_R,:], color=:orange,ls="--",lw=2, label="Backward SIF, emitted at $wl_Red nm" ) -xlabel("Absorbed Wavelength (nm)") -ylabel("Fluorescence") -legend() -gcf() -#---------------------------------------------------------------------------- - -# --- -# ### Leaf reflectance and transmission -# Within Fluspect, leaf reflectance and transmission is calculated (this part is actually identical to what PROSPECT is doing and much less involved than the Fluorescence part). The model basically uses a doubling adding routine to solve for the radiative transfer within the leaf using constituent absorption cross sections and constituent abundances in the leaf (assuming vertically homogenous distribution). -# -# Here, we just create another leaf with different concentrations to show the impact on leaf reflectance and transmission due to changes in chlorophyll content and liquid water content (mostly in the two liquid water absorption bands at 1400 and 1900nm). - -## Let's create a leaf with a different Cab and Cw (water) content (Try changing other pigment contents, plot leaf reflectance and transmissions and explain where (spectrally) and why reflectance and transmission changes): -leaf_2 = create_leaf_bio(FT, wl_set.nwl, wl_set.nWlE, wl_set.nWlF); -leaf_2.Cab = 80 -leaf_2.Cw = 0.012 -## show leaf Chlorophyll content: -## and Run Fluspect: -fluspect!(leaf_2, wl_set); -#---------------------------------------------------------------------------- - -figure() -plot(wl_set.wl,1 .-leaf.τ_SW, color=:black, lw = 2 , label="Leaf Transmission") -plot(wl_set.wl,leaf.ρ_SW,color=:orange, lw = 2 , label="Leaf Reflectance" ) -plot(wl_set.wl,1 .-leaf_2.τ_SW, color=:black, ls="--",lw=2, label="Leaf ##2 Transmission") -plot(wl_set.wl,leaf_2.ρ_SW,color=:orange, ls="--",lw=2, label="Leaf ##2 Reflectance" ) -xlabel("Wavelength (nm)") -legend() -gcf() -#---------------------------------------------------------------------------- - -# --- -# ## Moving from the leaf to the entire canopy -# -# Our model here is based on mSCOPE[^1] and we can prescribe different leaf optical properties within a complex canopy. At the moment, the leaf angular distribution is the same vertically (but could be changed in the future). -# -# [^1]: Yang, P., Verhoef, W. and van der Tol, C., 2017. The mSCOPE model: A simple adaptation to the SCOPE model to describe reflectance, fluorescence and photosynthesis of vertically heterogeneous canopies. Remote sensing of environment, 201, pp.1-11. -# - -## This is to be changed later but at the moment, we need to generate an Array of leaves, basically for each layer of the canopy - -arrayOfLeaves = [create_leaf_bio(FT, wl_set.nwl, wl_set.nWlE, wl_set.nWlF) for i in 1:canopy_rt.nlayers] -for i in 1:canopy_rt.nlayers - fluspect!(arrayOfLeaves[i], wl_set) -end -#---------------------------------------------------------------------------- - -# ### Basic Steps for Canopy RT: -# Below are the basic steps for the canopy radiative transfer (SIF fluxes are dependent on stress levels at each leaf but here we use a standard SIF yield for now): - -## Set Soil albedo to 0.2 -soil = SoilOpti{FT}(wl_set.wl, FT(0.2)*ones(FT, length(wl_set.wl)), FT[0.1], FT(290.0)) -angles = SolarAngles{FT}() - -## Compute Canopyoptical properties dependend on sun-sensor and leaf angle distributions: -compute_canopy_geometry!(canopy_rt, angles, canOpt_rt) -## Compute RT matrices with leaf reflectance and transmissions folded in: -compute_canopy_matrices!(arrayOfLeaves, canOpt_rt); -## Perform SW radiation transfer: -simulate_short_wave!(canopy_rt, canOpt_rt, canRad_rt, sunRad_rt, soil); -## Compute outgoing SIF flux (using constant fluorescence efficiency at the chloroplast level) -derive_canopy_fluxes!(canopy_rt, canOpt_rt, canRad_rt, sunRad_rt, soil, arrayOfLeaves, wl_set); -#---------------------------------------------------------------------------- - -# ### Test a VZA dependence in the principal plane - - -SIF_FR = Float32[] -SIF_R = Float32[] -reflVIS = Float32[] -reflNIR = Float32[] - -## Just running the code over all geometries: - -## Set sun SZA to 30 degrees -angles.tts=30 -## Set 0 azimuth (principal plane) -angles.psi=0 -## LAI of 3: -canopy_rt.LAI = 3 -## Define VZA -VZA=collect(-89.5:0.5:89.5) - -for VZA_ in VZA - angles.tto=VZA_ - compute_canopy_geometry!(canopy_rt, angles, canOpt_rt) - compute_canopy_matrices!(arrayOfLeaves, canOpt_rt); - simulate_short_wave!(canopy_rt, canOpt_rt, canRad_rt, sunRad_rt, soil); - computeSIF_Fluxes!(arrayOfLeaves, canOpt_rt, canRad_rt, canopy_rt, soil, wl_set); - ## Handpicked indices in - push!(reflVIS, canRad_rt.alb_obs[ind_red]) - push!(reflNIR, canRad_rt.alb_obs[ind_NIR]) - push!(SIF_R , canRad_rt.SIF_obs[ind_wlf_R]) - push!(SIF_FR, canRad_rt.SIF_obs[ind_wlf_FR ]) -end -#---------------------------------------------------------------------------- - -## Plots Visible -figure() -plot(VZA, reflVIS, label="Red Reflectance", lw=2) -plot(VZA, SIF_R/30, label="Red SIF (/30)", lw=2) -xlabel("Viewing Zenith Angle") -legend() -gcf() -#---------------------------------------------------------------------------- - -## Plot Near Infrared: -figure() -plot(VZA, reflNIR, label="NIR Reflectance", lw=2) -plot(VZA, SIF_FR/6, label="Far Red SIF (/6)", lw=2) -xlabel("Viewing Zenith Angle") -gcf() -#---------------------------------------------------------------------------- - -# --- -# ## BRDF sampling -# By going through viewing and azimuth angles, we can construct a full BRDF for reflectance and SIF emissions at different wavelengths: - -reflVIS = Float32[] -reflNIR = Float32[] -SIF_FR = Float32[] -SIF_R = Float32[] -angles.tts=48 -angles.psi=0 -canopy_rt.LAI=3.22 -for psi=0:360 - angles.psi=psi - for VZA=0:1:85 - angles.tto=VZA - - compute_canopy_geometry!(canopy_rt, angles, canOpt_rt) - compute_canopy_matrices!(arrayOfLeaves, canOpt_rt); - simulate_short_wave!(canopy_rt, canOpt_rt, canRad_rt, sunRad_rt, soil); - computeSIF_Fluxes!(arrayOfLeaves, canOpt_rt, canRad_rt, canopy_rt, soil, wl_set); - push!(reflVIS, canRad_rt.alb_obs[28]) - push!(reflNIR, canRad_rt.alb_obs[52]) - push!(SIF_R , canRad_rt.SIF_obs[8]) - push!(SIF_FR, canRad_rt.SIF_obs[20]) - end -end -#---------------------------------------------------------------------------- - -A = reshape(reflNIR, ( 86,361)); -B = reshape(reflVIS, ( 86,361)); -SIFFER = reshape(SIF_R, ( 86,361)); -SIFFER_FR = reshape(SIF_FR, ( 86,361)); -#---------------------------------------------------------------------------- - -##heatmap(A, cmap=) -figure() -subplot(1,1,1, polar=true) -grid(false) -hm = contourf(deg2rad.(collect((0:360))),collect(0:1:85), A, cmap=:viridis) -title("NIR reflectance BRDF") -colorbar() -gcf() -#---------------------------------------------------------------------------- - -##heatmap(A, cmap=) -figure() -subplot(1,1,1, polar=true) -grid(false) -hm = contourf(deg2rad.(collect((0:360))),collect(0:1:85), B, cmap=:viridis) -title("VIS reflectance BRDF") -colorbar() -gcf() -#---------------------------------------------------------------------------- - -figure() -subplot(1,1,1, polar=true) -grid(false) -hm = contourf(deg2rad.(collect((0:360))),collect(0:1:85), SIFFER, cmap=:viridis) -title("Red SIF emission BRDF") -colorbar() -gcf() -#---------------------------------------------------------------------------- - -figure() -subplot(1,1,1, polar=true) -grid(false) -hm = contourf(deg2rad.(collect((0:360))),collect(0:1:85), SIFFER_FR, cmap=:viridis) -title("Far Red SIF emission BRDF") -colorbar() -gcf() -#---------------------------------------------------------------------------- - - -#---------------------------------------------------------------------------- diff --git a/examples/Manifest.toml b/examples/Manifest.toml deleted file mode 100644 index be133990..00000000 --- a/examples/Manifest.toml +++ /dev/null @@ -1,639 +0,0 @@ -# This file is machine-generated - editing it directly is not advised - -julia_version = "1.10.0" -manifest_format = "2.0" -project_hash = "89e0fb5120cc4484e1a10a943435504282a4097d" - -[[deps.ArgTools]] -uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" -version = "1.1.1" - -[[deps.Artifacts]] -uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" - -[[deps.Base64]] -uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" - -[[deps.BufferedStreams]] -git-tree-sha1 = "4ae47f9a4b1dc19897d3743ff13685925c5202ec" -uuid = "e1450e63-4bb3-523b-b2a4-4ffa8c0fd77d" -version = "1.2.1" - -[[deps.Bzip2_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "9e2a6b69137e6969bab0152632dcb3bc108c8bdd" -uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" -version = "1.0.8+1" - -[[deps.CFTime]] -deps = ["Dates", "Printf"] -git-tree-sha1 = "ed2e76c1c3c43fd9d0cb9248674620b29d71f2d1" -uuid = "179af706-886a-5703-950a-314cd64e0468" -version = "0.1.2" - -[[deps.Calculus]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "f641eb0a4f00c343bbc32346e1217b86f3ce9dad" -uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" -version = "0.5.1" - -[[deps.CodeTracking]] -deps = ["InteractiveUtils", "UUIDs"] -git-tree-sha1 = "c0216e792f518b39b22212127d4a84dc31e4e386" -uuid = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2" -version = "1.3.5" - -[[deps.CodecZlib]] -deps = ["TranscodingStreams", "Zlib_jll"] -git-tree-sha1 = "cd67fc487743b2f0fd4380d4cbd3a24660d0eec8" -uuid = "944b1d66-785c-5afd-91f1-9de20f533193" -version = "0.7.3" - -[[deps.CommonDataModel]] -deps = ["CFTime", "DataStructures", "Dates", "Preferences", "Printf"] -git-tree-sha1 = "7f5717cbb2c1ce650cfd454451f282df33103596" -uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" -version = "0.2.5" - -[[deps.Compat]] -deps = ["TOML", "UUIDs"] -git-tree-sha1 = "75bd5b6fc5089df449b5d35fa501c846c9b6549b" -uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.12.0" -weakdeps = ["Dates", "LinearAlgebra"] - - [deps.Compat.extensions] - CompatLinearAlgebraExt = "LinearAlgebra" - -[[deps.CompilerSupportLibraries_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" -version = "1.0.5+1" - -[[deps.ConstrainedRootSolvers]] -deps = ["DocStringExtensions", "PkgUtility", "Test", "UnPack"] -git-tree-sha1 = "26fb23009728099595c4d47c2028f0f9ef161122" -uuid = "7e2492bd-0955-4089-8696-9df2af57a479" -version = "0.1.5" - -[[deps.Crayons]] -git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15" -uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" -version = "4.1.1" - -[[deps.DataAPI]] -git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" -uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" -version = "1.16.0" - -[[deps.DataFrames]] -deps = ["Compat", "DataAPI", "DataStructures", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrecompileTools", "PrettyTables", "Printf", "REPL", "Random", "Reexport", "SentinelArrays", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"] -git-tree-sha1 = "04c738083f29f86e62c8afc341f0967d8717bdb8" -uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -version = "1.6.1" - -[[deps.DataStructures]] -deps = ["Compat", "InteractiveUtils", "OrderedCollections"] -git-tree-sha1 = "ac67408d9ddf207de5cfa9a97e114352430f01ed" -uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.16" - -[[deps.DataValueInterfaces]] -git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" -uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" -version = "1.0.0" - -[[deps.Dates]] -deps = ["Printf"] -uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" - -[[deps.Distributed]] -deps = ["Random", "Serialization", "Sockets"] -uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" - -[[deps.DocStringExtensions]] -deps = ["LibGit2"] -git-tree-sha1 = "2fb1e02f2b635d0845df5d7c167fec4dd739b00d" -uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" -version = "0.9.3" - -[[deps.Downloads]] -deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] -uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" -version = "1.6.0" - -[[deps.DualNumbers]] -deps = ["Calculus", "NaNMath", "SpecialFunctions"] -git-tree-sha1 = "5837a837389fccf076445fce071c8ddaea35a566" -uuid = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74" -version = "0.6.8" - -[[deps.EmeraldConstants]] -deps = ["DocStringExtensions", "Test"] -git-tree-sha1 = "fff28dae7585fbe4c2a7645edb08baca0f800556" -uuid = "f1e47f7f-56cf-4a63-9b2b-695e95ad7a29" -version = "0.1.0" - -[[deps.FileIO]] -deps = ["Pkg", "Requires", "UUIDs"] -git-tree-sha1 = "c5c28c245101bd59154f649e19b038d15901b5dc" -uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" -version = "1.16.2" - -[[deps.FileWatching]] -uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" - -[[deps.Future]] -deps = ["Random"] -uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" - -[[deps.HDF5]] -deps = ["Compat", "HDF5_jll", "Libdl", "MPIPreferences", "Mmap", "Preferences", "Printf", "Random", "Requires", "UUIDs"] -git-tree-sha1 = "26407bd1c60129062cec9da63dc7d08251544d53" -uuid = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" -version = "0.17.1" - - [deps.HDF5.extensions] - MPIExt = "MPI" - - [deps.HDF5.weakdeps] - MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195" - -[[deps.HDF5_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "LibCURL_jll", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "OpenSSL_jll", "TOML", "Zlib_jll", "libaec_jll"] -git-tree-sha1 = "8156325170d6763b5494c072ac4754214db3e669" -uuid = "0234f1f7-429e-5d53-9886-15a909be8d59" -version = "1.14.3+0" - -[[deps.HypergeometricFunctions]] -deps = ["DualNumbers", "LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] -git-tree-sha1 = "f218fe3736ddf977e0e772bc9a586b2383da2685" -uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" -version = "0.3.23" - -[[deps.InlineStrings]] -deps = ["Parsers"] -git-tree-sha1 = "9cc2baf75c6d09f9da536ddf58eb2f29dedaf461" -uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" -version = "1.4.0" - -[[deps.InteractiveUtils]] -deps = ["Markdown"] -uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" - -[[deps.InvertedIndices]] -git-tree-sha1 = "0dc7b50b8d436461be01300fd8cd45aa0274b038" -uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f" -version = "1.3.0" - -[[deps.IrrationalConstants]] -git-tree-sha1 = "630b497eafcc20001bba38a4651b327dcfc491d2" -uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" -version = "0.2.2" - -[[deps.IteratorInterfaceExtensions]] -git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" -uuid = "82899510-4779-5014-852e-03e436cf321d" -version = "1.0.0" - -[[deps.JLD2]] -deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "Pkg", "PrecompileTools", "Printf", "Reexport", "Requires", "TranscodingStreams", "UUIDs"] -git-tree-sha1 = "7c0008f0b7622c6c0ee5c65cbc667b69f8a65672" -uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.4.45" - -[[deps.JLLWrappers]] -deps = ["Artifacts", "Preferences"] -git-tree-sha1 = "7e5d6779a1e09a36db2a7b6cff50942a0a7d0fca" -uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" -version = "1.5.0" - -[[deps.JuliaInterpreter]] -deps = ["CodeTracking", "InteractiveUtils", "Random", "UUIDs"] -git-tree-sha1 = "04663b9e1eb0d0eabf76a6d0752e0dac83d53b36" -uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a" -version = "0.9.28" - -[[deps.LaTeXStrings]] -git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" -uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" -version = "1.3.1" - -[[deps.Land]] -deps = ["ConstrainedRootSolvers", "DataFrames", "DocStringExtensions", "EmeraldConstants", "HypergeometricFunctions", "LazyArtifacts", "LinearAlgebra", "MAT", "NetcdfIO", "Pkg", "PkgUtility", "QuadGK", "Revise", "SpecialFunctions", "Statistics", "Test", "WaterPhysics"] -path = ".." -uuid = "a4d78162-daa3-41d7-a3fe-155b9207f750" -version = "0.1.1" - -[[deps.LazyArtifacts]] -deps = ["Artifacts", "Pkg"] -uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" - -[[deps.LibCURL]] -deps = ["LibCURL_jll", "MozillaCACerts_jll"] -uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" -version = "0.6.4" - -[[deps.LibCURL_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] -uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" -version = "8.4.0+0" - -[[deps.LibGit2]] -deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] -uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" - -[[deps.LibGit2_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] -uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" -version = "1.6.4+0" - -[[deps.LibSSH2_jll]] -deps = ["Artifacts", "Libdl", "MbedTLS_jll"] -uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" -version = "1.11.0+1" - -[[deps.Libdl]] -uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" - -[[deps.Libiconv_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "f9557a255370125b405568f9767d6d195822a175" -uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" -version = "1.17.0+0" - -[[deps.LinearAlgebra]] -deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] -uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" - -[[deps.LogExpFunctions]] -deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] -git-tree-sha1 = "7d6dd4e9212aebaeed356de34ccf262a3cd415aa" -uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" -version = "0.3.26" - - [deps.LogExpFunctions.extensions] - LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" - LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables" - LogExpFunctionsInverseFunctionsExt = "InverseFunctions" - - [deps.LogExpFunctions.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" - InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" - -[[deps.Logging]] -uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" - -[[deps.LoweredCodeUtils]] -deps = ["JuliaInterpreter"] -git-tree-sha1 = "20ce1091ba18bcdae71ad9b71ee2367796ba6c48" -uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b" -version = "2.4.4" - -[[deps.MAT]] -deps = ["BufferedStreams", "CodecZlib", "HDF5", "SparseArrays"] -git-tree-sha1 = "ed1cf0a322d78cee07718bed5fd945e2218c35a1" -uuid = "23992714-dd62-5051-b70f-ba57cb901cac" -version = "0.10.6" - -[[deps.MPICH_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "2ee75365ca243c1a39d467e35ffd3d4d32eef11e" -uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" -version = "4.1.2+1" - -[[deps.MPIPreferences]] -deps = ["Libdl", "Preferences"] -git-tree-sha1 = "8f6af051b9e8ec597fa09d8885ed79fd582f33c9" -uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" -version = "0.1.10" - -[[deps.MPItrampoline_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "8eeb3c73bbc0ca203d0dc8dad4008350bbe5797b" -uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" -version = "5.3.1+1" - -[[deps.MacroTools]] -deps = ["Markdown", "Random"] -git-tree-sha1 = "2fa9ee3e63fd3a4f7a9a4f4744a52f4856de82df" -uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -version = "0.5.13" - -[[deps.Markdown]] -deps = ["Base64"] -uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" - -[[deps.MbedTLS_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" -version = "2.28.2+1" - -[[deps.MicrosoftMPI_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "b01beb91d20b0d1312a9471a36017b5b339d26de" -uuid = "9237b28f-5490-5468-be7b-bb81f5f5e6cf" -version = "10.1.4+1" - -[[deps.Missings]] -deps = ["DataAPI"] -git-tree-sha1 = "f66bdc5de519e8f8ae43bdc598782d35a25b1272" -uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" -version = "1.1.0" - -[[deps.Mmap]] -uuid = "a63ad114-7e13-5084-954f-fe012c677804" - -[[deps.MozillaCACerts_jll]] -uuid = "14a3606d-f60d-562e-9121-12d972cd8159" -version = "2023.1.10" - -[[deps.NaNMath]] -deps = ["OpenLibm_jll"] -git-tree-sha1 = "0877504529a3e5c3343c6f8b4c0381e57e4387e4" -uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" -version = "1.0.2" - -[[deps.NetCDF_jll]] -deps = ["Artifacts", "Bzip2_jll", "HDF5_jll", "JLLWrappers", "LibCURL_jll", "Libdl", "XML2_jll", "Zlib_jll", "Zstd_jll"] -git-tree-sha1 = "10c612c81eaffdd6b7c28a45a554cdd9d2f40ff1" -uuid = "7243133f-43d8-5620-bbf4-c2c921802cf3" -version = "400.902.208+0" - -[[deps.NetcdfIO]] -deps = ["CFTime", "CommonDataModel", "DataFrames", "DataStructures", "Dates", "DocStringExtensions", "NetCDF_jll", "NetworkOptions", "Printf", "Test"] -git-tree-sha1 = "38f0c217683c68a8b2efc25811bc6f390c560ca2" -uuid = "6a36f34d-89cf-423a-87c4-84549e82f670" -version = "0.2.7" - -[[deps.NetworkOptions]] -uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" -version = "1.2.0" - -[[deps.OpenBLAS_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] -uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" -version = "0.3.23+2" - -[[deps.OpenLibm_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "05823500-19ac-5b8b-9628-191a04bc5112" -version = "0.8.1+2" - -[[deps.OpenMPI_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "e25c1778a98e34219a00455d6e4384e017ea9762" -uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" -version = "4.1.6+0" - -[[deps.OpenSSL_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "cc6e1927ac521b659af340e0ca45828a3ffc748f" -uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.0.12+0" - -[[deps.OpenSpecFun_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1" -uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" -version = "0.5.5+0" - -[[deps.OrderedCollections]] -git-tree-sha1 = "dfdf5519f235516220579f949664f1bf44e741c5" -uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" -version = "1.6.3" - -[[deps.Parsers]] -deps = ["Dates", "PrecompileTools", "UUIDs"] -git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821" -uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" -version = "2.8.1" - -[[deps.Pkg]] -deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] -uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" -version = "1.10.0" - -[[deps.PkgUtility]] -deps = ["Dates", "LazyArtifacts", "Pkg", "Statistics", "StatsBase", "Test"] -git-tree-sha1 = "968844493dfb3c8f6cf6f420f07d926508836b5d" -uuid = "0d262f2c-28e9-492c-8e19-d7a5c4f11611" -version = "0.2.1" - -[[deps.PooledArrays]] -deps = ["DataAPI", "Future"] -git-tree-sha1 = "36d8b4b899628fb92c2749eb488d884a926614d3" -uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720" -version = "1.4.3" - -[[deps.PrecompileTools]] -deps = ["Preferences"] -git-tree-sha1 = "03b4c25b43cb84cee5c90aa9b5ea0a78fd848d2f" -uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" -version = "1.2.0" - -[[deps.Preferences]] -deps = ["TOML"] -git-tree-sha1 = "00805cd429dcb4870060ff49ef443486c262e38e" -uuid = "21216c6a-2e73-6563-6e65-726566657250" -version = "1.4.1" - -[[deps.PrettyTables]] -deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] -git-tree-sha1 = "88b895d13d53b5577fd53379d913b9ab9ac82660" -uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" -version = "2.3.1" - -[[deps.Printf]] -deps = ["Unicode"] -uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" - -[[deps.QuadGK]] -deps = ["DataStructures", "LinearAlgebra"] -git-tree-sha1 = "9b23c31e76e333e6fb4c1595ae6afa74966a729e" -uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -version = "2.9.4" - -[[deps.REPL]] -deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] -uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" - -[[deps.Random]] -deps = ["SHA"] -uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" - -[[deps.Reexport]] -git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" -uuid = "189a3867-3050-52da-a836-e630ba90ab69" -version = "1.2.2" - -[[deps.Requires]] -deps = ["UUIDs"] -git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" -uuid = "ae029012-a4dd-5104-9daa-d747884805df" -version = "1.3.0" - -[[deps.Revise]] -deps = ["CodeTracking", "Distributed", "FileWatching", "JuliaInterpreter", "LibGit2", "LoweredCodeUtils", "OrderedCollections", "Pkg", "REPL", "Requires", "UUIDs", "Unicode"] -git-tree-sha1 = "3fe4e5b9cdbb9bbc851c57b149e516acc07f8f72" -uuid = "295af30f-e4ad-537b-8983-00126c2a3abe" -version = "3.5.13" - -[[deps.SHA]] -uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" -version = "0.7.0" - -[[deps.SentinelArrays]] -deps = ["Dates", "Random"] -git-tree-sha1 = "0e7508ff27ba32f26cd459474ca2ede1bc10991f" -uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" -version = "1.4.1" - -[[deps.Serialization]] -uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" - -[[deps.Sockets]] -uuid = "6462fe0b-24de-5631-8697-dd941f90decc" - -[[deps.SortingAlgorithms]] -deps = ["DataStructures"] -git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085" -uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" -version = "1.2.1" - -[[deps.SparseArrays]] -deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] -uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" -version = "1.10.0" - -[[deps.SpecialFunctions]] -deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] -git-tree-sha1 = "e2cfc4012a19088254b3950b85c3c1d8882d864d" -uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "2.3.1" - - [deps.SpecialFunctions.extensions] - SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" - - [deps.SpecialFunctions.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - -[[deps.Statistics]] -deps = ["LinearAlgebra", "SparseArrays"] -uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" -version = "1.10.0" - -[[deps.StatsAPI]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "1ff449ad350c9c4cbc756624d6f8a8c3ef56d3ed" -uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" -version = "1.7.0" - -[[deps.StatsBase]] -deps = ["DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] -git-tree-sha1 = "d1bf48bfcc554a3761a133fe3a9bb01488e06916" -uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" -version = "0.33.21" - -[[deps.StringManipulation]] -deps = ["PrecompileTools"] -git-tree-sha1 = "a04cabe79c5f01f4d723cc6704070ada0b9d46d5" -uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e" -version = "0.3.4" - -[[deps.SuiteSparse_jll]] -deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] -uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" -version = "7.2.1+1" - -[[deps.TOML]] -deps = ["Dates"] -uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" -version = "1.0.3" - -[[deps.TableTraits]] -deps = ["IteratorInterfaceExtensions"] -git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" -uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" -version = "1.0.1" - -[[deps.Tables]] -deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits"] -git-tree-sha1 = "cb76cf677714c095e535e3501ac7954732aeea2d" -uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" -version = "1.11.1" - -[[deps.Tar]] -deps = ["ArgTools", "SHA"] -uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" -version = "1.10.0" - -[[deps.Test]] -deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] -uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[[deps.TranscodingStreams]] -git-tree-sha1 = "1fbeaaca45801b4ba17c251dd8603ef24801dd84" -uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.10.2" -weakdeps = ["Random", "Test"] - - [deps.TranscodingStreams.extensions] - TestExt = ["Test", "Random"] - -[[deps.UUIDs]] -deps = ["Random", "SHA"] -uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" - -[[deps.UnPack]] -git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" -uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" -version = "1.0.2" - -[[deps.Unicode]] -uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" - -[[deps.WaterPhysics]] -deps = ["DocStringExtensions", "EmeraldConstants", "PkgUtility", "Test", "UnPack"] -git-tree-sha1 = "2ca56b50c07bb8d6e6c214c8dabafb97cad479bf" -uuid = "20dd5ee6-61da-454b-ac5d-c09c2977e03a" -version = "0.1.5" - -[[deps.XML2_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] -git-tree-sha1 = "801cbe47eae69adc50f36c3caec4758d2650741b" -uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.12.2+0" - -[[deps.Zlib_jll]] -deps = ["Libdl"] -uuid = "83775a58-1f1d-513f-b197-d71354ab007a" -version = "1.2.13+1" - -[[deps.Zstd_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "49ce682769cd5de6c72dcf1b94ed7790cd08974c" -uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" -version = "1.5.5+0" - -[[deps.libaec_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "eddd19a8dea6b139ea97bdc8a0e2667d4b661720" -uuid = "477f73a3-ac25-53e9-8cc3-50b2fa2566f0" -version = "1.0.6+1" - -[[deps.libblastrampoline_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" -version = "5.8.0+1" - -[[deps.nghttp2_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" -version = "1.52.0+1" - -[[deps.p7zip_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" -version = "17.4.0+2" diff --git a/examples/Project.toml b/examples/Project.toml index 4f2f4b3c..e6037cff 100644 --- a/examples/Project.toml +++ b/examples/Project.toml @@ -2,7 +2,7 @@ DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -Land = "a4d78162-daa3-41d7-a3fe-155b9207f750" +Land = "27e3c115-2cb8-4114-b7a5-cd9f011f9dcc" NetcdfIO = "6a36f34d-89cf-423a-87c4-84549e82f670" PkgUtility = "0d262f2c-28e9-492c-8e19-d7a5c4f11611" diff --git a/examples/example.jl b/examples/example.jl index 80f250c3..dd91e2d7 100644 --- a/examples/example.jl +++ b/examples/example.jl @@ -363,7 +363,7 @@ function run_model!(spac::SPACMono{FT}, df::DataFrame, nc_out::String) where {FT end -@time dict = load("debug.jld2"); -@time wddf = prepare_wd(dict, "debug.nc"); +@time dict = load("$(@__DIR__)/debug.jld2"); +@time wddf = prepare_wd(dict, "$(@__DIR__)/debug.nc"); @time spac = prepare_spac(dict); -@time run_model!(spac, wddf, "debug.output.nc"); +@time run_model!(spac, wddf, "$(@__DIR__)/debug.output.nc");