Skip to content

Commit 090dbec

Browse files
authored
Merge branch 'develop' into fix/3882-sa-median-manifest-lookup
2 parents af5afba + 3a8c485 commit 090dbec

181 files changed

Lines changed: 58337 additions & 1260 deletions

File tree

Some content is hidden

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

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ tests/BC*
8181
compile_on_geo.sh
8282
documentation/tutorials/*/*.html
8383
pecan.Rproj
84+
.rcookies
8485
shiny/BenchmarkReport/*
8586
# Installation files from make
8687
.install/

CHANGELOG.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ For more information about this file see also [Keep a Changelog](http://keepacha
99
## Unreleased
1010

1111
### Added
12+
- New function `PEcAn.utils::netcdf2df()` flattens all dims and vars of a netCDF into a dataframe,
13+
with units attached as an attribute.
14+
- New package `PEcAn.RothC` runs the RothC soil carbon model.
15+
- Added `inst/ilamb/` pipeline in PEcAn.benchmark to convert downscaled SDA reanalysis GeoTIFFs into ILAMB-compatible CF netCDF for carbon-cycle benchmarking (#4019).
1216
- Added PEcAn.PEPRMT model, including a demo run with example data
1317
- Add `format_try_for_ma()` and `try_trait_mapping()` to `PEcAn.data.remote` to convert trait data from the external TRY database into the tabular format required by the PEcAn meta-analysis module (#3717).
1418
- Add function `qsub_sda()` for submitting SDA batch jobs by splitting a large number of sites into multiple small groups of sites (#3634).
@@ -23,13 +27,17 @@ For more information about this file see also [Keep a Changelog](http://keepacha
2327
- Added lookup functions to `PEcAn.data.land`: `look_up_ca_n_rate()` and `look_up_ca_compost_amendment()` for querying crop-specific fertilization and compost data.
2428
- PEcAn.SIPNET gains support for SIPNET v2, whose features includes management events, nitrogen cycle tracking, explicit N2O and methane fluxes, runtime setting of feature flags, and changes to the parameter set (now 73 parameters). SIPNET v1 is still fully supported, but workarounds for bugs in the legacy `sipnet.unk` version have been removed.
2529
- Added `PEcAn.data.land::to_co2e()` for converting SOC change, CH4, and N2O to CO2-equivalent emissions using IPCC Global Warming Potential values.
30+
- Added `PEcAn.data.land::event_parquet_to_json` for generating PEcAn `event.json` files from well-formatted event parquet files, with support for ensembles of events.
2631

2732
### Fixed
33+
- Removed unused `grid2netcdf()` from `PEcAn.data.remote` and fixed R CMD check reference notes for `download.LandTrendr.AGB()` (#2758).
2834
- Fixed broken pecanproject.github.io, pecan.gitbooks.io, and other outdated documentation links across book_source, tutorials, models, modules, web, and shiny files (#3710).
2935
- Added note to DEV-INTRO.md documenting Traefik workaround for Apple Silicon (ARM64) Macs: use `traefik:v2.11` with `platform: linux/arm64` to fix 404 errors (#3910)
3036
- Fixed `web/08-finished.php`: show database info instead of "Still running" when workflow folder doesn't exist locally (#3501).
37+
- `PEcAn.utils::transformstats()`: corrected the LSD-to-SE conversion. The previous implementation included an extra `sqrt(n)` factor, causing SE estimates derived from LSD to appear `sqrt(n)` times smaller than they should be, non-conservatively over-weighting those observations in meta-analysis. (#3998)
3138

3239
### Changed
40+
- `PEcAn.uncertainty::get.parameter.samples()`: replaced the `save_to_disk` flag (from #3860) with an `outdir` argument (default `settings$outdir`) controlling whether `samples.Rdata` is written; `outdir = NULL` skips the save. Existing callers are unaffected (@omkarrr2533, #4016)
3341
- Updated Docker architecture documentation to match current docker-compose.yml: removed portainer/minio/thredds, added rstudio/api sections, updated service lists and volumes (#3268).
3442
- Improved PEcAn.SIPNET documentation including README, model description, and current installation instructions (@Eshaan-byte; #3703, #3705).
3543
- `assign.treatments` has been renamed to `assign_treatments` and moved from `PEcAn.utils` to `PEcAn.MA` since that's the only place where it's used.
@@ -45,7 +53,6 @@ For more information about this file see also [Keep a Changelog](http://keepacha
4553
- Management events specified via `events.json` are now required to specify a crop code for each planting event, so that models can know when to restart with a different PFT (#3828, #3836).
4654

4755

48-
4956
## [1.10.0] - 2026-01-06
5057

5158
### Added

CITATION.cff

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ authors:
129129
affiliation: National Institute of Technology, Tiruchirappalli
130130
- given-names: Om Kapale
131131
affiliation: Chatrapati Shahu Maharaj CSCOE, Maharashtra
132+
- given-names: Tejas Dahiya
132133

133134

134135
preferred-citation:

Makefile

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,12 @@ recurse_dir = $(foreach d, $(wildcard $1*), $(call recurse_dir, $d/) $d)
6969
# For output from recurse_dir this removes all dirs, but in other cases beware.
7070
drop_parents = $(filter-out $(patsubst %/,%,$(dir $1)), $1)
7171

72-
# Generates a list of regular files at any depth inside its argument
73-
files_in_dir = $(call drop_parents, $(call recurse_dir, $1))
72+
# Generates a list of regular files at any depth inside its argument,
73+
# excluding those in any `docs` folder
74+
files_in_dir = $(filter-out \
75+
${1}/docs/%, \
76+
$(call drop_parents, $(call recurse_dir,$1)))
77+
7478

7579
# Git hash + clean status for this directory
7680
git_rev = $(shell \
@@ -118,9 +122,8 @@ check_modules: $(BASE_I) $(MODULES_C)
118122

119123
document: $(ALL_PKGS_D) .doc/base/all
120124

121-
pkgdocs:
125+
pkgdocs: $(ALL_PKGS_D) .doc/base/all
122126
Rscript scripts/build_pkgdown.R $(ALL_PKGS) base/all || exit 1
123-
124127

125128
install: $(ALL_PKGS_I) .install/base/all
126129
check: $(ALL_PKGS_C) .check/base/all

base/db/DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,5 +80,5 @@ Copyright: Authors
8080
LazyLoad: yes
8181
LazyData: FALSE
8282
Encoding: UTF-8
83-
RoxygenNote: 7.3.3
8483
X-schema.org-keywords: PEcAn, database
84+
RoxygenNote: 7.3.3

base/db/NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export(get.trait.data)
3333
export(get.trait.data.pft)
3434
export(get_postgres_envvars)
3535
export(get_run_ids)
36+
export(get_trait_data_pft)
3637
export(get_users)
3738
export(get_var_names)
3839
export(get_workflow_ids)

base/db/NEWS.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# PEcAn.DB 1.8.2
22

3+
## Fixed
4+
5+
* `arrhenius.scaling.traits()`: previously returned `NULL` when no temperature covariates were found, crashing `query.trait.data()` with `argument is of length zero`. The function now drops rows that lack a measurement temperature covariate and emits a `logger.warn()` with the row count. If no observations have any temperature covariate, an empty data frame (zero rows, same columns) is returned. The `missing.temp` argument is retained for backward compatibility but is no longer applied.
6+
* `filter_sunleaf_traits()`: returned `NULL` instead of `data` unchanged when no `canopy_layer` covariate was found. Now returns the input data frame unmodified in that case, consistent with the more standardised measurement protocol for sun-leaf traits.
7+
* `query.trait.data()`: the `warning()` call for missing trait data was placed after `return(NA)` and therefore never fired. Moved before the return and changed to `logger.warn()` for consistency with the rest of the codebase.
8+
39
* Refactored `convert.input()` internals into smaller, and hopefully more testable, chunks. No user-visible changes expected.
410
* Roxygen cleanup.
511

base/db/R/covariate.functions.R

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -53,37 +53,57 @@ query.covariates <- function(trait.ids, con = NULL, ...){
5353
##--------------------------------------------------------------------------------------------------#
5454
##' Apply Arrhenius scaling to 25 degC for temperature-dependent traits
5555
##'
56+
##' Rows whose measurement temperature covariate is missing are dropped with a
57+
##' warning rather than silently assigned a default temperature. If no
58+
##' temperature covariate is recorded for any observation the function returns
59+
##' an empty data frame (zero rows, same columns as \code{data}).
60+
##'
5661
##' @param data data frame of data to scale, as returned by query.data()
5762
##' @param covariates data frame of covariates, as returned by query.covariates().
58-
##' Note that data with no matching covariates will be unchanged.
5963
##' @param temp.covariates names of covariates used to adjust for temperature;
6064
##' if length > 1, order matters (first will be used preferentially)
61-
##' @param new.temp the reference temperature for the scaled traits. Curerntly 25 degC
62-
##' @param missing.temp the temperature assumed for traits with no covariate found. Curerntly 25 degC
65+
##' @param new.temp the reference temperature for the scaled traits. Currently 25 degC
66+
##' @param missing.temp no longer used; kept for backward compatibility only
6367
##' @author Carl Davidson, David LeBauer, Ryan Kelly
6468
arrhenius.scaling.traits <- function(data, covariates, temp.covariates, new.temp = 25, missing.temp = 25){
6569
# Select covariates that match temp.covariates
66-
covariates <- covariates[covariates$name %in% temp.covariates,]
67-
68-
if(nrow(covariates)>0) {
70+
covariates <- covariates[covariates$name %in% temp.covariates, ]
71+
72+
if (nrow(covariates) > 0) {
6973
# Sort covariates in order of priority
7074
covariates <- do.call(rbind,
71-
lapply(temp.covariates, function(temp.covariate) covariates[covariates$name == temp.covariate, ])
75+
lapply(temp.covariates, function(tc) covariates[covariates$name == tc, ])
7276
)
73-
77+
7478
data <- append.covariate(data, 'temp', covariates)
75-
76-
# Assign default value for traits with no covariates
77-
data$temp[is.na(data$temp)] <- missing.temp
78-
79+
80+
# Drop rows that have no temperature covariate recorded
81+
n_missing <- sum(is.na(data$temp))
82+
if (n_missing > 0) {
83+
PEcAn.logger::logger.warn(
84+
n_missing, "row(s) of trait data dropped due to missing temperature covariate."
85+
)
86+
data <- data[!is.na(data$temp), ]
87+
}
88+
89+
# Remove temporary covariate column before returning if nothing survived
90+
if (nrow(data) == 0) {
91+
return(data[, colnames(data) != 'temp', drop = FALSE])
92+
}
93+
7994
# Scale traits
80-
data$mean <- PEcAn.utils::arrhenius.scaling(observed.value = data$mean, old.temp = data$temp, new.temp=new.temp)
81-
data$stat <- PEcAn.utils::arrhenius.scaling(observed.value = data$stat, old.temp = data$temp, new.temp=new.temp)
82-
83-
#remove temporary covariate column.
84-
data<-data[,colnames(data)!='temp']
95+
data$mean <- PEcAn.utils::arrhenius.scaling(observed.value = data$mean, old.temp = data$temp, new.temp = new.temp)
96+
data$stat <- PEcAn.utils::arrhenius.scaling(observed.value = data$stat, old.temp = data$temp, new.temp = new.temp)
97+
98+
# Remove temporary covariate column
99+
data <- data[, colnames(data) != 'temp', drop = FALSE]
85100
} else {
86-
data <- NULL
101+
# No temperature covariates found for any observation; drop all rows.
102+
n_rows <- nrow(data)
103+
PEcAn.logger::logger.warn(
104+
n_rows, "row(s) of trait data dropped: no temperature covariate found for any observation."
105+
)
106+
data <- data[0, , drop = FALSE]
87107
}
88108
return(data)
89109
}
@@ -108,7 +128,7 @@ filter_sunleaf_traits <- function(data, covariates){
108128
# remove temporary covariate column
109129
data <- data[,colnames(data)!='canopy_layer']
110130
} else {
111-
data <- NULL
131+
# No canopy_layer covariate found; return data unchanged rather than NULL.
112132
}
113133
return(data)
114134
}

0 commit comments

Comments
 (0)