Skip to content

Commit 37e9b11

Browse files
committed
Update to MultiScaleTreeGraph v0.15.0
1 parent f484edc commit 37e9b11

58 files changed

Lines changed: 1643 additions & 1523 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/src/index.md

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -209,52 +209,52 @@ The package is designed to be easily scalable, and can be used to simulate model
209209

210210
```@example readme
211211
mapping = ModelMapping(
212-
"Scene" => ToyDegreeDaysCumulModel(),
213-
"Plant" => (
212+
:Scene => ToyDegreeDaysCumulModel(),
213+
:Plant => (
214214
MultiScaleModel(
215215
model=ToyLAIModel(),
216216
mapped_variables=[
217-
:TT_cu => "Scene",
217+
:TT_cu => :Scene,
218218
],
219219
),
220220
Beer(0.6),
221221
MultiScaleModel(
222222
model=ToyAssimModel(),
223-
mapped_variables=[:soil_water_content => "Soil"],
223+
mapped_variables=[:soil_water_content => :Soil],
224224
),
225225
MultiScaleModel(
226226
model=ToyCAllocationModel(),
227227
mapped_variables=[
228-
:carbon_demand => ["Leaf", "Internode"],
229-
:carbon_allocation => ["Leaf", "Internode"]
228+
:carbon_demand => [:Leaf, :Internode],
229+
:carbon_allocation => [:Leaf, :Internode]
230230
],
231231
),
232232
MultiScaleModel(
233233
model=ToyPlantRmModel(),
234-
mapped_variables=[:Rm_organs => ["Leaf" => :Rm, "Internode" => :Rm],],
234+
mapped_variables=[:Rm_organs => [:Leaf => :Rm, :Internode => :Rm],],
235235
),
236236
),
237-
"Internode" => (
237+
:Internode => (
238238
MultiScaleModel(
239239
model=ToyCDemandModel(optimal_biomass=10.0, development_duration=200.0),
240-
mapped_variables=[:TT => "Scene",],
240+
mapped_variables=[:TT => :Scene,],
241241
),
242242
MultiScaleModel(
243243
model=ToyInternodeEmergence(TT_emergence=20.0),
244-
mapped_variables=[:TT_cu => "Scene"],
244+
mapped_variables=[:TT_cu => :Scene],
245245
),
246246
ToyMaintenanceRespirationModel(1.5, 0.06, 25.0, 0.6, 0.004),
247247
Status(carbon_biomass=1.0)
248248
),
249-
"Leaf" => (
249+
:Leaf => (
250250
MultiScaleModel(
251251
model=ToyCDemandModel(optimal_biomass=10.0, development_duration=200.0),
252-
mapped_variables=[:TT => "Scene",],
252+
mapped_variables=[:TT => :Scene,],
253253
),
254254
ToyMaintenanceRespirationModel(2.1, 0.06, 25.0, 1.0, 0.025),
255255
Status(carbon_biomass=1.0)
256256
),
257-
"Soil" => (
257+
:Soil => (
258258
ToySoilWaterModel(),
259259
),
260260
);
@@ -283,11 +283,11 @@ And run the simulation:
283283

284284
```@example readme
285285
out_vars = Dict(
286-
"Scene" => (:TT_cu,),
287-
"Plant" => (:carbon_allocation, :carbon_assimilation, :soil_water_content, :aPPFD, :TT_cu, :LAI),
288-
"Leaf" => (:carbon_demand, :carbon_allocation),
289-
"Internode" => (:carbon_demand, :carbon_allocation),
290-
"Soil" => (:soil_water_content,),
286+
:Scene => (:TT_cu,),
287+
:Plant => (:carbon_allocation, :carbon_assimilation, :soil_water_content, :aPPFD, :TT_cu, :LAI),
288+
:Leaf => (:carbon_demand, :carbon_allocation),
289+
:Internode => (:carbon_demand, :carbon_allocation),
290+
:Soil => (:soil_water_content,),
291291
)
292292
293293
out = run!(mtg, mapping, meteo, tracked_outputs=out_vars, executor=SequentialEx());
@@ -299,7 +299,7 @@ We can then extract the outputs and convert them to a `DataFrame` for each scale
299299
```@example readme
300300
using DataFrames
301301
df_outputs = convert_outputs(out, DataFrame)
302-
leaf_df = df_outputs isa AbstractDict ? df_outputs["Leaf"] : df_outputs
302+
leaf_df = df_outputs isa AbstractDict ? df_outputs[:Leaf] : df_outputs
303303
sort!(leaf_df, [:timestep, :node])
304304
```
305305

docs/src/multirate/multirate_tutorial.md

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ using MultiScaleTreeGraph
1818
using DataFrames
1919
using Dates
2020
21-
mtg = Node(NodeMTG("/", "Scene", 1, 0))
22-
plant = Node(mtg, NodeMTG("+", "Plant", 1, 1))
23-
internode = Node(plant, NodeMTG("/", "Internode", 1, 2))
24-
Node(internode, NodeMTG("+", "Leaf", 1, 2))
21+
mtg = Node(NodeMTG("/", :Scene, 1, 0))
22+
plant = Node(mtg, NodeMTG("+", :Plant, 1, 1))
23+
internode = Node(plant, NodeMTG("/", :Internode, 1, 2))
24+
Node(internode, NodeMTG("+", :Leaf, 1, 2))
2525
2626
PlantSimEngine.@process "tutorialmeteodriven" verbose=false
2727
struct TutorialMeteoDrivenModel <: AbstractTutorialmeteodrivenModel
@@ -35,7 +35,7 @@ function PlantSimEngine.run!(m::TutorialMeteoDrivenModel, models, status, meteo,
3535
end
3636
PlantSimEngine.timestep_hint(::Type{<:TutorialMeteoDrivenModel}) = (; required=(Minute(30), Hour(2)), preferred=Hour(1))
3737
38-
mapping = ModelMapping("Leaf" => (ModelSpec(TutorialMeteoDrivenModel(Ref(0))),))
38+
mapping = ModelMapping(:Leaf => (ModelSpec(TutorialMeteoDrivenModel(Ref(0))),))
3939
meteo_30min = Weather([
4040
Atmosphere(date=DateTime(2025, 6, 12, 12, 0, 0), duration=Minute(30), T=20.0, Wind=1.0, Rh=0.6),
4141
Atmosphere(date=DateTime(2025, 6, 12, 12, 30, 0), duration=Minute(30), T=21.0, Wind=1.0, Rh=0.6),
@@ -47,10 +47,10 @@ out_meteo_driven = run!(
4747
mapping,
4848
meteo_30min;
4949
executor=SequentialEx(),
50-
tracked_outputs=Dict("Leaf" => (:count,)),
50+
tracked_outputs=Dict(:Leaf => (:count,)),
5151
)
5252
out_meteo_driven_df = PlantSimEngine.convert_outputs(out_meteo_driven, DataFrame)
53-
out_meteo_driven_df["Leaf"][end, :count]
53+
out_meteo_driven_df[:Leaf][end, :count]
5454
```
5555

5656
The last value is `3.0`, showing the model ran on all three 30-minute meteo rows, even though `preferred=Hour(1)`.
@@ -79,7 +79,7 @@ function PlantSimEngine.run!(::TutorialHourlyIntegratorModel, models, status, me
7979
end
8080
8181
mapping_coarse = ModelMapping(
82-
"Leaf" => (
82+
:Leaf => (
8383
ModelSpec(TutorialHalfHourSourceModel(Ref(0))),
8484
ModelSpec(TutorialHourlyIntegratorModel()) |>
8585
TimeStepModel(Hour(1)) |>
@@ -100,10 +100,10 @@ out_coarse = run!(
100100
mapping_coarse,
101101
meteo_30min_4;
102102
executor=SequentialEx(),
103-
tracked_outputs=Dict("Leaf" => (:A_hourly, :T_hourly)),
103+
tracked_outputs=Dict(:Leaf => (:A_hourly, :T_hourly)),
104104
)
105105
out_coarse_df = PlantSimEngine.convert_outputs(out_coarse, DataFrame)
106-
(out_coarse_df["Leaf"][end, :A_hourly], out_coarse_df["Leaf"][end, :T_hourly])
106+
(out_coarse_df[:Leaf][end, :A_hourly], out_coarse_df[:Leaf][end, :T_hourly])
107107
```
108108

109109
The final tuple is `(3600.0, 23.0)`: hourly integrated assimilation (`1.0 * 1800 s * 2`) and hourly mean temperature over the coarse window.
@@ -124,10 +124,10 @@ using Dates
124124
using Statistics
125125
126126
# Minimal plant: Scene -> Plant -> Internode -> Leaf
127-
mtg = Node(NodeMTG("/", "Scene", 1, 0))
128-
plant = Node(mtg, NodeMTG("+", "Plant", 1, 1))
129-
internode = Node(plant, NodeMTG("/", "Internode", 1, 2))
130-
Node(internode, NodeMTG("+", "Leaf", 1, 2))
127+
mtg = Node(NodeMTG("/", :Scene, 1, 0))
128+
plant = Node(mtg, NodeMTG("+", :Plant, 1, 1))
129+
internode = Node(plant, NodeMTG("/", :Internode, 1, 2))
130+
Node(internode, NodeMTG("+", :Leaf, 1, 2))
131131
132132
meteo_path = joinpath(pkgdir(PlantSimEngine), "examples", "meteo_day.csv")
133133
leaf_mesh_path = joinpath(pkgdir(PlantSimEngine), "examples", "leaf_with_petiole.ply")
@@ -208,23 +208,23 @@ plant_daily_proc = process(TutorialPlantDailyModel())
208208
plant_weekly_proc = process(TutorialPlantWeeklyModel())
209209
210210
mapping = ModelMapping(
211-
"Leaf" => (
211+
:Leaf => (
212212
ModelSpec(TutorialLeafHourlyModel()) |>
213213
TimeStepModel(hourly) |>
214214
ScopeModel(:plant),
215215
),
216-
"Plant" => (
216+
:Plant => (
217217
ModelSpec(TutorialPlantDailyModel()) |>
218218
ScopeModel(:plant) |>
219-
MultiScaleModel([:leaf_assim_h => "Leaf"]) |>
219+
MultiScaleModel([:leaf_assim_h => :Leaf]) |>
220220
TimeStepModel(daily) |>
221221
MeteoBindings(
222222
;
223223
T=MeanWeighted(),
224224
Rh=MeanWeighted(),
225225
Ri_SW_q=(source=:Ri_SW_f, reducer=RadiationEnergy()),
226226
) |>
227-
InputBindings(; leaf_assim_h=(process=leaf_proc, var=:leaf_assim_h, scale="Leaf", policy=Integrate())),
227+
InputBindings(; leaf_assim_h=(process=leaf_proc, var=:leaf_assim_h, scale=:Leaf, policy=Integrate())),
228228
ModelSpec(TutorialPlantWeeklyModel()) |>
229229
ScopeModel(:plant) |>
230230
TimeStepModel(weekly) |>
@@ -238,27 +238,27 @@ mapping = ModelMapping(
238238
Run directly from `mtg + mapping` and request exported series.
239239

240240
```@example multirate_tutorial
241-
req_leaf_hourly = OutputRequest("Leaf", :leaf_assim_h;
241+
req_leaf_hourly = OutputRequest(:Leaf, :leaf_assim_h;
242242
name=:leaf_assim_hourly,
243243
process=leaf_proc,
244244
policy=HoldLast(),
245245
)
246246
247-
req_plant_daily = OutputRequest("Plant", :plant_assim_d;
247+
req_plant_daily = OutputRequest(:Plant, :plant_assim_d;
248248
name=:plant_assim_daily,
249249
process=plant_daily_proc,
250250
policy=HoldLast(),
251251
clock=daily,
252252
)
253253
254-
req_plant_daily_T = OutputRequest("Plant", :T;
254+
req_plant_daily_T = OutputRequest(:Plant, :T;
255255
name=:T_daily,
256256
process=plant_daily_proc,
257257
policy=HoldLast(),
258258
clock=daily,
259259
)
260260
261-
req_plant_weekly = OutputRequest("Plant", :plant_assim_w;
261+
req_plant_weekly = OutputRequest(:Plant, :plant_assim_w;
262262
name=:plant_assim_weekly,
263263
process=plant_weekly_proc,
264264
policy=HoldLast(),
@@ -301,7 +301,7 @@ Of course the outputs of the models are still available in the `status_outputs`
301301

302302
```@example multirate_tutorial
303303
outs = convert_outputs(out_status, DataFrame)
304-
outs["Plant"][1:3,:]
304+
outs[:Plant][1:3,:]
305305
```
306306

307307
## 5. Deeper notes

0 commit comments

Comments
 (0)