-
Add explicit upstream attribution in
README.md,DESCRIPTIONand newinst/ATTRIBUTION.md, citinggeco-bern/rsofun, Stocker et al. 2020 GMD and Paredes et al. 2025 GMD. Addsettings_calib,logpathand thename/logpath/walltimereturn fields tocalib_sofun()for API compatibility withrsofun::calib_sofun(). Addparallelandncoresarguments torunread_biomee()(kept for compatibility; BiomeE remains sequential). Setrunread_pmodel()defaultncoresto 1. Document the full consistency-test protocol ininst/parity-notes/consistency-tests.md. -
BiomeE parameter calibration is now supported through
calib_sofun(). The dispatcher acceptsmetric = cost_rmse_biomee(orcost_likelihood_biomee) and asettings$parlist forphiRL,LAI_light,tf_baseandpar_mort. Documentation and a testthat case using a short spin-up andmax.calllimit were added. -
Add the
vignettes/pmodel_use.Rmdvignette, replicating thersofunP-model usage example with thersofuncppC++17 backend. The vignette runsrunread_pmodel(), plots GPP with base R graphics, and calibrateskphiousingcalib_sofun()+GenSA.knitrandrmarkdownwere added toSuggestsandVignetteBuilder: knitrtoDESCRIPTION. -
Add multi-core site-level parallelism to
runread_pmodel()andrunread_pmodel_cpp()via theparallelandncoresarguments. On Unixparallel::mclapply()is used; on Windows aparallel::parLapply()cluster is created. Over 337 FluxDataKit sites the 8-core run is ~6x faster than sequential (~7.6 s vs ~1.3 s) and produces identical output. -
Close the residual per-site
kphiocalibration divergence on FluxDataKit v3.4.2. The Fortrancalc_optimal_chilocalmjhas an implicitSAVEattribute, so it retains its previous value whenvbkg <= 0(e.g. after the negativepatmoutlier inGL-Dsk).src/pmodel_bysite.cppcalc_optimal_chi_r()now uses astatic double mj_prevto match this behaviour. Across 337 FluxDataKit sites the calibratedkphiodiffers by at most 2.3e-05 (mean 1.2e-06) and the final RMSE by at most 8.5e-06. Climate-memory variables are also stored/dampened infloatto match Fortran's single-precision arithmetic, and thegpp_bysiteguard matches the Fortranfpc_grid > 0,dayl > 0,temp_memory > -5conditions. Benchmark scripts and results are ininst/benchmarks/. -
Add tests and example script (
inst/examples/rsofun_doc_pmodel_gpp.R) that exercisersofuncppwith the daily GPP subset of thersofun_docdata (https://github.com/geco-bern/rsofun_doc, Zenodo 17495564). The tests are skipped unlessRSOFUN_DOC_DIRpoints to a local clone ofrsofun_doc. They verify thatrunread_pmodel(),cost_rmse_pmodel()andcalib_sofun()work with the realrsofuncalibration drivers, and thatGenSAcan improvekphioon a five-site subset. -
Add technical note
inst/notes/stan-external-cpp-feasibility.mdsummarising the investigation into calling the C++17 BiomeE/P-model core fromcmdstan/cmdstanr. The conclusion is that a plain external C++ wrapper works only forgenerated quantities; for HMC sampling the model must either be rewritten in Stan, templated withstan::mathtypes, or supplied with manual reverse-mode gradients. -
Add consolidated project status report (
inst/notes/project-status.md) and update theREADME.mdstatus table. The report summarises the P-model and BiomeE migration status, merged PRs, quality gates, known pending issues, and the next steps (BiomeE cost functions, Stan calibration, CRAN preflight). -
Implement and validate
gs_leuningphotosynthesis and LULUC transitions in the C++17 BiomeE core.src/biomee_gpp_soil.cppdispatches between P-model (pt == 1) andgs_leuning(pt != 1) daily photosynthesis, using the Farquhar/Leuning constants and canopy extinction from the Fortran original.src/biomee_aggregated.cppaddsupdate_lu_fractions()(pool transfers and cohort density adjustment across land-use units) and aligns the aggregatedoutput_annual_celllayout with Fortran (empty LU tiles are NaN exceptlu_fraction, aggregatedtotCis intentionally left NaN, and the landscape-levelMaxVolume/MaxDBHaggregates use the sameMAX(max_age, ...)formula as the reference).src/biomee_bysite.cppnow passes the bundledluc_forcingarray throughpopulate_inputs(). The new tests are enabled intests/testthat/test-biomee_cpp_vs_r.Rwith spin-up and per-column tolerances matching the documented rsofun snapshot levels. -
Extend
tests/testthat/test-biomee_cpp_vs_r.Rwith placeholder tests forbiomee_gs_leuning_driversandbiomee_p_model_luluc_drivers. -
Improve the BiomeE
output_annual_tile$Densityparity by aligning denominator guards insrc/biomee_annual.cppandsrc/biomee_gpp_soil.cppwith the Fortran> 0.0/!= 0.0tests. The transient deviation inDensityforbiomee_p_model_driversis reduced from ~6% to ~0.3% (year 54). The remaining residual is dominated by a single cohort that is removed byvegn_annual_starvationone year earlier in C++ than in the Fortran reference; it arises from real32 vs double arithmetic in thebl_max/plablthreshold, not from a P-model 1e-5 numerical mismatch. The residual is a numerical artifact of the Fortranreal32implementation, not an error in the C++17 migration: the C++ backend usesdoubleprecision and is therefore mathematically more accurate. Reaching the 1e-5 target would require intentionally emulating the older Fortranreal32arithmetic so the two binaries take the same threshold branches. A detailed parity report with concrete examples is added ininst/parity-notes/biomee-density-parity.md; the test tolerances inhelper-biomee-compare.Rintentionally allow this residual while work to reach 1e-5 continues on a separate branch. -
Achieve BiomeE C++17 vs Fortran parity and enable the public C++ backend. Add unique cohort identifiers (
uid) toCohort, generate them increate_cohort/split_cohort, and match them tocIDoutput rows. Fix post-mortality cohort output (deathrate,n_deadtrees,c_deadtrees) viauidlookup. Align cohort list insertion order with Fortran (prepend increate_cohortandsplit_cohort). Update parity-test tolerances to rsofun snapshot levels (0.05/0.08/0.09) and skip the internalcIDcolumn.biomee_cpp_ready()now returnsTRUEandrun_biomee_bysite()/runread_biomee()dispatch to the C++17 engine. -
Port BiomeE daily/annual vegetation processes to C++17 (
src/biomee_annual.cpp):vegn_CNW_budgetorchestration,gppandSoilWaterDynamicsLayer/water_supply_layerstubs,plant_respiration,SOMdecomposition,vegn_N_uptake, phenology, allocation/growth (vegn_growth_EW), tissue turnover, natural mortality/reproduction, starvation and old-grass cleanup. AddsVegetationTile::lu_props()andOrgPoolthree-argument constructor needed by the process code. (The GPP/soil-water fast-step routines were completed in later PRs #11 and #15.) -
Align
runread_pmodel()andrunread_pmodel_cpp()output withrsofun::runread_pmodel_f(): a data frame withsitename,site_infoand a list columndata(instead of a named list). Updatecost_rmse_pmodel()andcost_likelihood_pmodel()to consume the nested data frame. -
BiomeE Stage 1 pure-R reference
run_biomee_r_bysite()andrunread_biomee_r(), plus the public APIrun_biomee_bysite()andrunread_biomee()matchingrsofun::run_biomee_f_bysite()/runread_biomee_f()signatures and nested output structure (output_daily_tile,output_annual_tile,output_annual_cohorts, and the aggregatedoutput_annual_cellfor LULUC). The R-level call chain (tc_home,build_*/prepare_*input preparation and the structured output builders) is reimplemented in base R with no tidyverse dependency; the numerical core is delegated to the compiledbiomee_f_CFortran routine of the installedrsofunpackage viagetNativeSymbolInfo(). -
Add
tests/testthat/helper-biomee-compare.Randtests/testthat/test-biomee_r_vs_fortran.Rvalidating the reference against the bundledbiomee_p_model_*,biomee_gs_leuning_*andbiomee_p_model_luluc_*reference outputs (tolerances follow rsofun's own snapshot tests, which allow up to 0.04/0.085 relative for nitrogen fluxes). -
BiomeE Stage 2 C++17/Rcpp backend scaffold. Adds the C++17 data model in
src/biomee.h(mirroringmd_interface_in_biomee,md_params_core,md_orgpool,md_cohort,md_interface_out_biomee) and the deterministic, self-contained pieces of the core: input population, species derived-parameter initialisation (init_pft_data/init_derived_species_data), simulation steering (get_steering/get_cycleyear), sub-daily to daily aggregation, and the output-array plumbing / year-driver loop. -
Port the
VegetationTile,LuTileandAggregatedTiledata structures (src/biomee_tile.cppandsrc/biomee_aggregated.cpp), including cohort create/merge/relayer/reduce/thin bookkeeping, pool aggregation, daily and annual diagnostics, and thebiosphere_annual()driver skeleton. The per-step physiological processes (vegn_CNW_budget,vegn_phenology,vegn_growth_EW, mortality, reproduction, soil biogeochemistry, LULUC transitions) are still stubs;biomee_cpp_ready()staysFALSEand the public API still dispatches to the validated Stage 1 Fortran-backed reference. -
Add
tests/testthat/test-biomee_cpp_vs_r.R: unit tests for the ported deterministic pieces against base-R reimplementations of the same equations (species derived params match to ~1e-9; steering exact) plus output-shape checks; the full-model cross-language comparison is skipped until the C++ core lands and uses the project per-column tolerances (never the P-model 1e-10). -
Add
calib_sofun()dispatcher withmethod = "GenSA"and optionalmethod = "BayesianTools", using pure-R cost functionscost_rmse_pmodel()andcost_likelihood_pmodel(). -
Input validation with
checkmateinrun_pmodel_bysite(),runread_pmodel(),cost_rmse_pmodel(),cost_likelihood_pmodel()andcalib_sofun(). -
Bundle BiomeE example drivers and validation data (
biomee_p_model_drivers,biomee_validation, etc.). -
GitHub Actions workflows for
R-CMD-check(Ubuntu, macOS, Windows),test-coverage, andpkgdown. -
Add
cran-comments.mdand refineDESCRIPTIONfor CRAN preflight. -
Stan calibration design in
inst/stan/README.mdand skeletoninst/stan/pmodel_calibration.stan. -
C++17 time-series P-model backend
run_pmodel_cpp_bysite()andrunread_pmodel_cpp()(Rcpp exportrun_pmodel_cpp_bysite_impl()), porting the pure-R reference.run_pmodel_r_bysite()(solar, water balance, gpp, isotope tracking, soil temperature, daily diagnostics and the spinup/recycle year-doy driver loop) to C++ with machine-precision parity againstrun_pmodel_r_bysite()on the bundledp_model_drivers. -
Rename
src/pmodel.hpptosrc/pmodel.h(CRAN-recognised header extension); it now also backs the time-series kernel. -
Public P-model API
run_pmodel_bysite()andrunread_pmodel()matchingrsofun::run_pmodel_f_bysite()/runread_pmodel_f()signatures and output columns. -
Pure-R Stage 1 reference
run_pmodel_r_bysite()andrunread_pmodel_r()that reproduce Fortran outputs to ~1e-5 relative for the bundledp_model_driversexample (spinup + 6-year transient). -
Bundle
p_model_driversexample data and a Fortran reference output ininst/extdata/pmodel_f_ref.rdsfor regression tests. -
Fix package-level constant collision that caused
calc_patm_r()to use the wrong reference temperature whenR/pmodel_r.RandR/pmodel_bysite_r.Rwere loaded together. -
Add
tests/testthat/helper-compare.Rwith a direct.Callto thersofunFortran.soand atest-pmodel_transparency.Rtest that comparesrsofuncpp::run_pmodel_bysite()against the liversofunFortran output (thersofunR wrappers depend on an olderdplyrstack, so the helpers bypass them).
- Initial package skeleton with C++17 / Rcpp / RcppParallel build setup.