Skip to content

Conversation

@ayushman1210
Copy link
Contributor

@ayushman1210 ayushman1210 commented Dec 14, 2025

Description

This PR standardizes dimensional unit conversions by replacing manual arithmetic with the centralized helper function PEcAn.utils::ud_convert() where appropriate. This reduces maintenance burden, improves readability, and minimizes the risk of unit conversion errors.
The changes focus strictly on dimensional unit conversions (mass, time, energy, area) and intentionally exclude model-specific scaling, biological constants, and timestep-dependent logic, per project guidance.

Summary of Changes

  • models/sipnet/R/model2netcdf.SIPNET.R
  • Replaced manual mass unit conversions (gC → kgC) with ud_convert()
  • Retained division by timestep.s for flux variables, since SIPNET outputs per-timestep accumulations (model-specific and required)
  • Left biological constants and model-specific scalings unchanged (e.g., SLA, carbon fractions, cm→mm water conversions)
  • models/dalec/R/model2netcdf.DALEC.R
  • Replaced manual conversions (* 0.001, / 86400) with ud_convert()
  • Removed redundant time division where ud_convert() already converts from daily to per-second units
  • Ensured fluxes are consistently written as kgC m⁻² s⁻¹ and pools as kgC m⁻²
  • models/gday/R/model2netcdf.GDAY.R
  • Replaced manual Mg/ha ↔ SI conversions with ud_convert()
  • Removed extra per-second scaling where ud_convert() already performs year → second conversion
  • Kept pool variables as state quantities without time division
  • models/sipnet/R/write_restart.SIPNET.R
  • Replaced manual mass conversions with ud_convert()
  • Removed redundant conversion factors while preserving model-specific logic
  • models/stics/R/met2model.STICS.R
  • Replaced precipitation conversion (kg m⁻² s⁻¹ → mm d⁻¹) with ud_convert()
  • Left radiation and other physical constants unchanged where conversion is not purely dimensional

NOT CHANGED

  • Biological / stoichiometric constants
  • Model-specific timestep logic
  • Physical constants mixed with unit conversions
  • Plot- or model-convention scaling

Fixes - #3712

Copy link
Member

@infotroph infotroph left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this! Can you describe how you tested these changes? I ask because I see a few issues here that should have produced obvious error messages in a test run. The issues themselves are minor and will be easy to fix, but since unit conversions can be surprisingly tricky it's important to know at review time that someone has actually run the code and looked at its output.

@ayushman1210
Copy link
Contributor Author

hi @infotroph Thanks for the review and for pointing this out.
You’re right — I should have been clearer about testing. In this case, I did not run a full test or execute all code paths after making the changes. My checks were based on static reasoning and spot inspection, and a proper run would indeed have surfaced the issues you noticed.
I understand why this is especially important for unit conversions, and I agree that changes like this should always be validated by running the code and inspecting the output. I’ll fix the issues shortly and will make sure to:

  • run the code locally,
  • verify the relevant outputs,
  • and explicitly describe the testing performed in the follow-up.

Thanks for the reminder !!

@ayushman1210
Copy link
Contributor Author

Hi @infotroph
Just a gentle follow-up regarding the PR [#3719 ]
Whenever you get a chance, I’d really appreciate a review.
Thanks for your time!

@ayushman1210
Copy link
Contributor Author

hey @infotroph sorry for the late response i have exams and college related work.
i have made changes as per your suggestion please review this pr
thanks !!

Comment on lines 44 to 50
# GDAY outputs in Mg/ha/year, convert directly to kgC/m2/s (ud_convert returns per-second)
output[[1]] <- PEcAn.utils::ud_convert(sub.GDAY.output[, "auto_resp"], "Mg/ha/yr", "kg/m2/s")
output[[2]] <- PEcAn.utils::ud_convert(sub.GDAY.output[, "hetero_resp"], "Mg/ha/yr", "kg/m2/s")
output[[3]] <- PEcAn.utils::ud_convert(sub.GDAY.output[, "auto_resp"] + sub.GDAY.output[, "hetero_resp"], "Mg/ha/yr", "kg/m2/s")
output[[4]] <- PEcAn.utils::ud_convert(sub.GDAY.output[, "gpp"], "Mg/ha/yr", "kg/m2/s")
output[[5]] <- PEcAn.utils::ud_convert(sub.GDAY.output[, "nep"] * -1, "Mg/ha/yr", "kg/m2/s")
output[[6]] <- PEcAn.utils::ud_convert(sub.GDAY.output[, "npp"], "Mg/ha/yr", "kg/m2/s")
Copy link
Member

@infotroph infotroph Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The existing code here is using a timestep.s of 86400 (and not the 86400/out_day used in model2netcdf.SIPNET below), so I'm pretty sure these should all be converting from Mg/ha/day rather than Mg/ha/yr. Sorry I didn't catch this on my last review!

I recommend constructing a test to make sure the outputs are identical before and after these unit changes -- consider checking it with a subset of the example output in https://github.com/mdekauwe/GDAY/blob/master/example/outputs/D1GDAYDUKEAMB.csv

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants