malcolmSQ commited on
Commit ·
ef84156
1
Parent(s): 1c67878
feat: add independent input fields for both species (except mortality, which is mirrored) and update config accordingly
Browse files- dashboard/app.py +57 -3
dashboard/app.py
CHANGED
|
@@ -251,8 +251,49 @@ This version is smoother and may yield slightly different results than the discr
|
|
| 251 |
with gr.Tab("Biomass Table"):
|
| 252 |
biomass_debug_table = gr.Dataframe(label="Biomass Table (inputs & outputs per year)")
|
| 253 |
# --- End tabbed tables ---
|
| 254 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 255 |
config = update_planting_schedule(MODEL_CONFIGS["Declining Increment"], [y1, y2, y3, y4, y5])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 256 |
with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as tmp:
|
| 257 |
yaml.dump(config, tmp)
|
| 258 |
tmp_path = tmp.name
|
|
@@ -268,6 +309,16 @@ This version is smoother and may yield slightly different results than the discr
|
|
| 268 |
for col in species_results_fmt.columns:
|
| 269 |
if species_results_fmt[col].dtype in [float, int]:
|
| 270 |
species_results_fmt[col] = species_results_fmt[col].apply(lambda x: f"{x:,.2f}" if isinstance(x, float) else f"{x:,}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 271 |
# Key metrics for summary card
|
| 272 |
total_area = sum(config["project"]["planting_schedule"].values())
|
| 273 |
final_buffer = results["buffer_carbon"].iloc[-1]
|
|
@@ -277,11 +328,14 @@ This version is smoother and may yield slightly different results than the discr
|
|
| 277 |
return (plots[0], plots[1], plots[2], growth_fig, summary, results_fmt, species_results_fmt, survival_table, biomass_debug_df, key_metrics_md)
|
| 278 |
update_btn.click(
|
| 279 |
update_declining_increment,
|
| 280 |
-
inputs=[year_1, year_2, year_3, year_4, year_5
|
|
|
|
|
|
|
|
|
|
| 281 |
outputs=[carbon_plot, biomass_plot, annual_plot, growth_plot, summary_box, results_box, species_box, survival_box, biomass_debug_table, key_metrics]
|
| 282 |
)
|
| 283 |
# Show initial results
|
| 284 |
-
c, b, a, g, summary, r, s, surv, biomass_debug_df, key_metrics_md = update_declining_increment(2500, 2500, 0, 0, 0)
|
| 285 |
carbon_plot.value = c
|
| 286 |
biomass_plot.value = b
|
| 287 |
annual_plot.value = a
|
|
|
|
| 251 |
with gr.Tab("Biomass Table"):
|
| 252 |
biomass_debug_table = gr.Dataframe(label="Biomass Table (inputs & outputs per year)")
|
| 253 |
# --- End tabbed tables ---
|
| 254 |
+
# --- Adjustable Model Inputs ---
|
| 255 |
+
sp = config["species"][0] # Only first species for now
|
| 256 |
+
with gr.Accordion("Adjust Model Inputs", open=True):
|
| 257 |
+
with gr.Row():
|
| 258 |
+
planting_density = gr.Number(value=sp['planting_density'], label=f"{sp['name']} Planting Density (trees/ha)")
|
| 259 |
+
r0_dbh = gr.Number(value=sp['declining_increment']['dbh']['r0'], label=f"{sp['name']} r0 (DBH, cm/yr)")
|
| 260 |
+
tm_dbh = gr.Number(value=sp['declining_increment']['dbh']['T_m'], label=f"{sp['name']} Tm (DBH, yrs)")
|
| 261 |
+
r0_height = gr.Number(value=sp['declining_increment']['height']['r0'], label=f"{sp['name']} r0 (Height, m/yr)")
|
| 262 |
+
tm_height = gr.Number(value=sp['declining_increment']['height']['T_m'], label=f"{sp['name']} Tm (Height, yrs)")
|
| 263 |
+
with gr.Row():
|
| 264 |
+
mort_1 = gr.Number(value=sp['mortality_rates']['year_1'], label="Year 1 Mortality (%)")
|
| 265 |
+
mort_2 = gr.Number(value=sp['mortality_rates']['year_2'], label="Year 2 Mortality (%)")
|
| 266 |
+
mort_3 = gr.Number(value=sp['mortality_rates']['year_3'], label="Year 3 Mortality (%)")
|
| 267 |
+
mort_4 = gr.Number(value=sp['mortality_rates']['year_4'], label="Year 4 Mortality (%)")
|
| 268 |
+
mort_5 = gr.Number(value=sp['mortality_rates']['year_5'], label="Year 5 Mortality (%)")
|
| 269 |
+
mort_sub = gr.Number(value=sp['mortality_rates']['subsequent'], label="Subsequent Years Mortality (%)")
|
| 270 |
+
with gr.Row():
|
| 271 |
+
project_duration = gr.Number(value=config['project']['duration_years'], label="Project Duration (years)")
|
| 272 |
+
buffer_pct = gr.Number(value=config['carbon']['buffer_percentage'], label="Buffer %")
|
| 273 |
+
soil_carbon = gr.Number(value=config['carbon']['soil_carbon_per_ha_per_year'], label="Soil Carbon per ha per year (tCO2)")
|
| 274 |
+
# Remove hardcoded key model inputs from Markdown section
|
| 275 |
+
# Update the update_declining_increment callback to use these new inputs
|
| 276 |
+
def update_declining_increment(y1, y2, y3, y4, y5,
|
| 277 |
+
planting_density, r0_dbh, tm_dbh, r0_height, tm_height,
|
| 278 |
+
mort_1, mort_2, mort_3, mort_4, mort_5, mort_sub,
|
| 279 |
+
project_duration, buffer_pct, soil_carbon):
|
| 280 |
config = update_planting_schedule(MODEL_CONFIGS["Declining Increment"], [y1, y2, y3, y4, y5])
|
| 281 |
+
# Update species_A params
|
| 282 |
+
config['species'][0]['planting_density'] = planting_density
|
| 283 |
+
config['species'][0]['declining_increment']['dbh']['r0'] = r0_dbh
|
| 284 |
+
config['species'][0]['declining_increment']['dbh']['T_m'] = tm_dbh
|
| 285 |
+
config['species'][0]['declining_increment']['height']['r0'] = r0_height
|
| 286 |
+
config['species'][0]['declining_increment']['height']['T_m'] = tm_height
|
| 287 |
+
config['species'][0]['mortality_rates']['year_1'] = mort_1
|
| 288 |
+
config['species'][0]['mortality_rates']['year_2'] = mort_2
|
| 289 |
+
config['species'][0]['mortality_rates']['year_3'] = mort_3
|
| 290 |
+
config['species'][0]['mortality_rates']['year_4'] = mort_4
|
| 291 |
+
config['species'][0]['mortality_rates']['year_5'] = mort_5
|
| 292 |
+
config['species'][0]['mortality_rates']['subsequent'] = mort_sub
|
| 293 |
+
# Update project/carbon params
|
| 294 |
+
config['project']['duration_years'] = project_duration
|
| 295 |
+
config['carbon']['buffer_percentage'] = buffer_pct
|
| 296 |
+
config['carbon']['soil_carbon_per_ha_per_year'] = soil_carbon
|
| 297 |
with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as tmp:
|
| 298 |
yaml.dump(config, tmp)
|
| 299 |
tmp_path = tmp.name
|
|
|
|
| 309 |
for col in species_results_fmt.columns:
|
| 310 |
if species_results_fmt[col].dtype in [float, int]:
|
| 311 |
species_results_fmt[col] = species_results_fmt[col].apply(lambda x: f"{x:,.2f}" if isinstance(x, float) else f"{x:,}")
|
| 312 |
+
# --- Ensure all DataFrames are native types ---
|
| 313 |
+
results_fmt = to_native(results_fmt)
|
| 314 |
+
species_results_fmt = to_native(species_results_fmt)
|
| 315 |
+
survival_table = to_native(survival_table)
|
| 316 |
+
biomass_debug_df = to_native(biomass_debug_df)
|
| 317 |
+
# --- Ensure all other values are native types ---
|
| 318 |
+
if hasattr(summary, 'item'):
|
| 319 |
+
summary = summary.item()
|
| 320 |
+
if hasattr(key_metrics_md, 'item'):
|
| 321 |
+
key_metrics_md = key_metrics_md.item()
|
| 322 |
# Key metrics for summary card
|
| 323 |
total_area = sum(config["project"]["planting_schedule"].values())
|
| 324 |
final_buffer = results["buffer_carbon"].iloc[-1]
|
|
|
|
| 328 |
return (plots[0], plots[1], plots[2], growth_fig, summary, results_fmt, species_results_fmt, survival_table, biomass_debug_df, key_metrics_md)
|
| 329 |
update_btn.click(
|
| 330 |
update_declining_increment,
|
| 331 |
+
inputs=[year_1, year_2, year_3, year_4, year_5,
|
| 332 |
+
planting_density, r0_dbh, tm_dbh, r0_height, tm_height,
|
| 333 |
+
mort_1, mort_2, mort_3, mort_4, mort_5, mort_sub,
|
| 334 |
+
project_duration, buffer_pct, soil_carbon],
|
| 335 |
outputs=[carbon_plot, biomass_plot, annual_plot, growth_plot, summary_box, results_box, species_box, survival_box, biomass_debug_table, key_metrics]
|
| 336 |
)
|
| 337 |
# Show initial results
|
| 338 |
+
c, b, a, g, summary, r, s, surv, biomass_debug_df, key_metrics_md = update_declining_increment(2500, 2500, 0, 0, 0, 2500, 2500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
|
| 339 |
carbon_plot.value = c
|
| 340 |
biomass_plot.value = b
|
| 341 |
annual_plot.value = a
|