Skip to content
Open
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
5b609f9
rewrite create_n_rate_data data raw script
divine7022 May 18, 2026
af7171a
refresh n_application_rates csv
divine7022 May 18, 2026
9079a65
rebuild ca_n_application_rate rda
divine7022 May 18, 2026
4ba0b09
add oz_per_tree_to_lb_per_acre helper
divine7022 May 18, 2026
4da526e
add doc for oz_per_tree_to_lb_per_acre
divine7022 May 18, 2026
00a4ce8
add tpa_lookup helper
divine7022 May 18, 2026
b738e65
add doc for tpa_lookup
divine7022 May 18, 2026
70f56c8
rewrite create_compost_data with material class
divine7022 May 18, 2026
ef7d28c
refresh compost_amendments csv
divine7022 May 18, 2026
1b96343
rebuild ca_compost_amendment rda
divine7022 May 18, 2026
36ed147
update doc for ca_compost_amendment
divine7022 May 18, 2026
3598750
add create_ca_compost_distributions data raw script
divine7022 May 18, 2026
adc5190
add ca_compost_pct_c_distribution rda
divine7022 May 18, 2026
9a15db8
add ca_compost_cn_distribution rda
divine7022 May 18, 2026
e850cee
add ca_compost_app_rate_envelope rda
divine7022 May 18, 2026
c5cb2ad
add ca_compost_calendar_window rda
divine7022 May 18, 2026
5e2fff3
add ca_compost_material_whitelist rda
divine7022 May 18, 2026
e41539f
add doc for ca_compost_pct_c_distribution
divine7022 May 18, 2026
de0bb71
add doc for ca_compost_cn_distribution
divine7022 May 18, 2026
9b22635
add doc for ca_compost_app_rate_envelope
divine7022 May 18, 2026
4dfed63
add doc for ca_compost_calendar_window
divine7022 May 18, 2026
56a95f6
add doc for ca_compost_material_whitelist
divine7022 May 18, 2026
ee1ef5e
add sample_ca_compost functions
divine7022 May 18, 2026
d858456
add doc for sample_ca_compost_pct_c
divine7022 May 18, 2026
c5d72f0
add doc for sample_ca_compost_cn
divine7022 May 18, 2026
c353ef5
add doc for sample_ca_compost_app_rate
divine7022 May 18, 2026
1d24977
add doc for sample_ca_compost_date_offset
divine7022 May 18, 2026
a71ef65
add doc for sample_ca_compost_material
divine7022 May 18, 2026
5f5172c
add tests for sample_ca_compost
divine7022 May 18, 2026
f52c1c3
update bundled dataset docs
divine7022 May 18, 2026
955e7f1
export new helpers and samplers
divine7022 May 18, 2026
30e620d
add ncc event type to events schema
divine7022 May 18, 2026
d0c79ef
update doc for ca_n_application_rate
divine7022 May 18, 2026
0974b36
update dataset docs
divine7022 May 18, 2026
d0844c9
update create_compost_data
divine7022 May 18, 2026
0bd71d9
Merge branch 'develop' into ncc-compost
dlebauer May 20, 2026
246fb5b
revert events schema additions; drop ncc as a seperate event
divine7022 May 23, 2026
f503d37
drop sample_ca_compost functions
divine7022 May 23, 2026
3fbfcec
drop sample_ca_compost tests
divine7022 May 23, 2026
81864e8
drop compost distributions build script
divine7022 May 23, 2026
0b71a7e
drop ca_compost_pct_c_distribution rda
divine7022 May 23, 2026
daf20d8
drop ca_compost_cn_distribution rda
divine7022 May 23, 2026
bb138b0
drop ca_compost_app_rate_envelope rda
divine7022 May 23, 2026
93c7456
drop ca_compost_calendar_window rda
divine7022 May 23, 2026
eb461d3
drop ca_compost_material_whitelist rda
divine7022 May 23, 2026
5d4070a
drop doc for ca_compost_pct_c_distribution
divine7022 May 23, 2026
aec34bf
drop doc for ca_compost_cn_distribution
divine7022 May 23, 2026
d4567f0
drop doc for ca_compost_app_rate_envelope
divine7022 May 23, 2026
34a4068
drop doc for ca_compost_calendar_window
divine7022 May 23, 2026
9a9dcf0
drop doc for ca_compost_material_whitelist
divine7022 May 23, 2026
7ee162b
drop doc for sample_ca_compost_pct_c
divine7022 May 23, 2026
6d943fb
drop doc for sample_ca_compost_cn
divine7022 May 23, 2026
3da67e0
drop doc for sample_ca_compost_app_rate
divine7022 May 23, 2026
6e025b4
drop doc for sample_ca_compost_date_offset
divine7022 May 23, 2026
9433f59
drop doc for sample_ca_compost_material
divine7022 May 23, 2026
0a715a6
drop oz_per_tree_to_lb_per_acre helper
divine7022 May 23, 2026
2467216
drop doc for oz_per_tree_to_lb_per_acre
divine7022 May 23, 2026
1e5dbe5
drop tpa_lookup helper
divine7022 May 23, 2026
aa60cf2
drop doc for tpa_lookup
divine7022 May 23, 2026
6d3850c
drop docs for removed compost distribution datasets
divine7022 May 23, 2026
b5c658b
drop namespace exports for removed functions
divine7022 May 23, 2026
1bc7c15
update look_up_ca_compost_amendment for new column set
divine7022 May 23, 2026
740cc8c
regen doc for look_up_ca_compost_amendment
divine7022 May 23, 2026
4150ede
update lookup tests for recovered crops and new compost columns
divine7022 May 23, 2026
7a59c49
add raw compost tsv to data-raw
divine7022 May 23, 2026
229b2ac
add raw n fertilization tsv to data-raw
divine7022 May 23, 2026
ca51a68
read raw compost tsv from data-raw and use ud_convert
divine7022 May 23, 2026
39ce033
read raw n tsv from data-raw and use ud_convert
divine7022 May 23, 2026
50c2ffa
rebuild ca_compost_amendment rda
divine7022 May 23, 2026
0cc6cdf
rebuild ca_n_application_rate rda
divine7022 May 23, 2026
7b3dd3b
Merge remote-tracking branch 'origin/develop' into ncc-compost
divine7022 May 23, 2026
76455c1
update news entry to match new compost and n rate columns
divine7022 May 23, 2026
335031c
update ca_compost_amendment doc to mention material_class
divine7022 May 23, 2026
fc67a4e
regen doc for ca_compost_amendment
divine7022 May 23, 2026
b7d07e3
Merge branch 'ncc-compost' of github.com:divine7022/pecan into ncc-co…
divine7022 May 23, 2026
e721e3f
add harmonized ca_n_application_rate csv
divine7022 Jun 9, 2026
aadf430
add harmonized ca_organic_amendment_properties csv
divine7022 Jun 9, 2026
3f7592e
add harmonized ca_organic_amendment_app_rate csv
divine7022 Jun 9, 2026
37a7245
add create script for ca_n_application_rate
divine7022 Jun 9, 2026
3fcaab0
add create script for organic amendment tables
divine7022 Jun 9, 2026
702cf07
build ca_organic_amendment_properties rda
divine7022 Jun 9, 2026
6ac9e51
build ca_organic_amendment_app_rate rda
divine7022 Jun 9, 2026
b5aa883
rebuild ca_n_application_rate rda from harmonized csv
divine7022 Jun 9, 2026
c56a21c
rename look_up_ca_compost_amendment to look_up_ca_organic_amendment
divine7022 Jun 9, 2026
e8752f6
rewrite dataset docs for split amendment tables
divine7022 Jun 9, 2026
db4b6b1
update exports for renamed lookup function
divine7022 Jun 9, 2026
d7b4391
add doc for ca_organic_amendment_properties
divine7022 Jun 9, 2026
2044ea3
add doc for ca_organic_amendment_app_rate
divine7022 Jun 9, 2026
1a4a05a
add doc for look_up_ca_organic_amendment
divine7022 Jun 9, 2026
95165aa
regen doc for ca_n_application_rate
divine7022 Jun 9, 2026
2ad6403
update lookup tests for split tables
divine7022 Jun 9, 2026
d58ca09
document fertilization datasets in data-raw readme
divine7022 Jun 9, 2026
6b95f43
add news entries for ca fertilization datasets
divine7022 Jun 9, 2026
7d7ae2f
drop raw compost tsv superseded by harmonized csv
divine7022 Jun 9, 2026
5d60c92
drop raw n fertilization tsv superseded by harmonized csv
divine7022 Jun 9, 2026
24f9212
drop old compost build script
divine7022 Jun 9, 2026
b7ee992
drop old n rate build script
divine7022 Jun 9, 2026
84cda6f
drop ca_compost_amendment rda replaced by split tables
divine7022 Jun 9, 2026
40d6d5b
drop doc for ca_compost_amendment
divine7022 Jun 9, 2026
a9e4e10
drop doc for look_up_ca_compost_amendment
divine7022 Jun 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions modules/data.land/NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export(mslsp_to_canopycover)
export(ndti_to_sipnet_tillage)
export(netcdf.writer.BADM)
export(om2soc)
export(oz_per_tree_to_lb_per_acre)
export(parse.MatrixNames)
export(partition_roots)
export(plot2AGB)
Expand All @@ -65,6 +66,11 @@ export(pool_ic_netcdf2list)
export(prepare_pools)
export(preprocess_soilgrids_data)
export(put_veg_module)
export(sample_ca_compost_app_rate)
export(sample_ca_compost_cn)
export(sample_ca_compost_date_offset)
export(sample_ca_compost_material)
export(sample_ca_compost_pct_c)
export(sample_ic)
export(sclass)
export(shp2kml)
Expand All @@ -84,6 +90,7 @@ export(subset_layer)
export(to.Tag)
export(to.TreeCode)
export(to_co2e)
export(tpa_lookup)
export(validate_events_json)
export(write_ic)
export(write_veg)
Expand Down
84 changes: 79 additions & 5 deletions modules/data.land/R/data.R
Original file line number Diff line number Diff line change
Expand Up @@ -255,21 +255,19 @@
#' @format A tibble with 32 rows and the following columns:
#' \describe{
#' \item{material}{\code{character}. Amendment material name.}
#' \item{material_class}{\code{character}. CalRecycle taxonomy
#' (14 CCR section 17852): one of green, food, wood, yard, ag,
#' biosolids.}
#' \item{cn_min, cn_max, cn_avg}{\code{numeric}. Carbon-to-nitrogen ratio
#' range and average.}
#' \item{c_pct}{\code{numeric}. Assumed carbon content (percent).}
#' \item{n_pct}{\code{numeric}. Total nitrogen content (percent).}
#' \item{pan_pct}{\code{numeric}. Plant-available nitrogen after 4 weeks
#' (percent). Negative values indicate N immobilization.}
#' \item{n_class}{\code{character}. "LOWER" or "HIGHER" N content class.}
#' \item{app_rate_min, app_rate_max}{\code{numeric}. Application rate range
#' (lbs/acre).}
#' \item{total_c_min_lbs_acre, total_c_max_lbs_acre}{\code{numeric}.
#' Total carbon applied (lbs C/acre).}
#' \item{total_n_min_lbs_acre, total_n_max_lbs_acre}{\code{numeric}.
#' Total nitrogen applied (lbs N/acre).}
#' \item{total_c_min_g_m2, total_c_max_g_m2}{\code{numeric}.
#' Total carbon in SI units (g C/m\eqn{^2}).}
#' \item{total_n_min_g_m2, total_n_max_g_m2}{\code{numeric}.
#' Total nitrogen in SI units (g N/m\eqn{^2}).}
#' \item{source}{\code{character}. Short citation for the data source.}
Expand All @@ -288,6 +286,82 @@
#' composition (N/C fractions) from the SWAT/DayCent database.
"ca_compost_amendment"

#' California compost carbon content distribution
#'
#' Truncated normal distribution parameters for compost %C (dry weight
#' basis) used by sample_ca_compost_pct_c.
#'
#' @format A tibble with one row:
#' \describe{
#' \item{a, b}{Lower and upper truncation bounds.}
#' \item{mean, sd}{Untruncated mean and standard deviation.}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
#' \item{mean, sd}{Untruncated mean and standard deviation.}
#' \item{mean, sd}{Mean and standard deviation of the underlying normal
#' distribution.}

#' \item{source}{Short citation for the parameters.}
#' }
#' @source Bernard et al. 2023 Frontiers in Environmental Science;
#' Sullivan, Bary, Miller & Brewer 2018 OSU EM9217;
#' CalRecycle finished compost characterization.
"ca_compost_pct_c_distribution"

#' California compost C:N ratio distribution
#'
#' Truncated normal distribution parameters for compost C:N used by
#' sample_ca_compost_cn.
#'
#' @format A tibble with one row:
#' \describe{
#' \item{a, b}{Lower and upper truncation bounds.}
#' \item{mean, sd}{Untruncated mean and standard deviation.}
#' \item{source}{Short citation.}
#' }
#' @source CDFA Healthy Soils Program white paper (Geisseler et al.);
#' HSP 2026 Practice Guidelines.
"ca_compost_cn_distribution"

#' California compost application rate envelope by PFT family
#'
#' Per family uniform rate envelope (dry weight tons per acre) used by
#' sample_ca_compost_app_rate.
#'
#' @format A tibble with one row per PFT family:
#' \describe{
#' \item{pft_family}{"annual" or "perennial".}
#' \item{min_t_ac, max_t_ac}{Application rate bounds.}
#' \item{source}{Short citation.}
#' }
#' @source CDFA HSP white paper Table 2; HSP 2026 Practice Guidelines;
#' NRCS Conservation Practice Standard 336 Soil Carbon Amendment (2022).
"ca_compost_app_rate_envelope"

#' California compost application calendar window by PFT family
#'
#' Per family integer day offsets (subtracted from the cycle anchor) used
#' by sample_ca_compost_date_offset.
#'
#' @format A tibble with one row per PFT family:
#' \describe{
#' \item{pft_family}{"annual" or "perennial".}
#' \item{offset_days_min, offset_days_max}{Bounds on days before the anchor.}
#' \item{source}{Short citation.}
#' }
#' @source CDFA HSP white paper Box 1; UC ANR cost studies;
#' Bernard et al. 2023 vineyard timing.
"ca_compost_calendar_window"

#' California compost material whitelist by PFT family
#'
#' Allowed CalRecycle material classes for each PFT family, used by
#' sample_ca_compost_material.
#'
#' @format A tibble in long format, one row per allowed pair:
#' \describe{
#' \item{pft_family}{"annual" or "perennial".}
#' \item{material_class}{CalRecycle class: one of green, food, wood,
#' yard, ag, biosolids.}
#' \item{source}{Short citation.}
Comment thread
infotroph marked this conversation as resolved.
Outdated
#' }
#' @source 14 CCR section 17852; CalRecycle SB 1383 dominant feedstocks.
"ca_compost_material_whitelist"

#' Crop-specific rooting depths and water-depletion thresholds
#'
#' Maximum effective rooting depth and minimum soil water content thresholds
Expand Down
20 changes: 20 additions & 0 deletions modules/data.land/R/oz_per_tree_to_lb_per_acre.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#' Convert N application rate from oz N per tree to lb N per acre
#'
#' California extension guidelines for young orchards (CDFA FREP, UC ANR,
#' Almond Board) publish N rates per tree. This helper multiplies by
#' orchard density to give lb N per acre for pipelines that need per acre
#' inputs.
#'
#' @param oz_per_tree numeric vector. N rate in ounces N per tree.
#' @param tpa numeric scalar or vector. Orchard density in trees per acre.
#' Recycled to length of oz_per_tree if scalar.
#'
#' @return numeric vector. N rate in lb N per acre. NA inputs propagate.
#'
#' @examples
#' oz_per_tree_to_lb_per_acre(c(1, 3), tpa = 145)
#'
#' @export
oz_per_tree_to_lb_per_acre <- function(oz_per_tree, tpa) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

🤯 plz use PEcAn.utils::ud_convert for such transformations! Hard coded conversions are error prone.

Also, I would suggest quarantining imperial units and not supporting them in PEcAn; i.e. the conversion can be done within the data ingest functions.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

good catch,
okey oz_per_tree_to_lb_per_acre helper is just gone, cuz raw tsv doesn't have any oz/tree rows anymore (for those i replaced upstream with AB Board 2020 NBMP Table 2 lb/ac for almonds)
background story around this -- i originally left this helper in cuz i had used it before our slack discussion and figured it might still be useful down the line. but at this point it was basically dead code anyway. so dropped

oz_per_tree * tpa / 16
}
187 changes: 187 additions & 0 deletions modules/data.land/R/sample_ca_compost.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
#' Sample California compost amendment %C
#'
#' Draws n values of compost carbon content (%C, dry weight basis) from
#' the bundled truncated normal distribution at
#' ca_compost_pct_c_distribution.
#'
#' The default range (15 to 30%, mean 20%, sd 5) reflects CA finished
#' compost characterizations: Bernard et al. 2023 (central coast
#' vineyard, 14 to 15% C); Sullivan, Bary, Miller and Brewer 2018 (OSU
#' EM9217 proficiency program, median 15% TOC); CalRecycle generic
#' compost roughly 20 to 23% C.
#'
#' @param n integer. Number of draws.
#' @param params optional list overriding the bundled distribution. Must
#' contain numeric a, b, mean, sd.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Might be easier on the reader to name the bounds upper_bound and lower_bound instead of a and b

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

  • Above I propose we don't use truncnorm because of the discontinuities at a,b that don't correspond to prior knowledge
  • More generally, it makes sense to have the parameter list map directly to the names used by the underlying R functions. Among other things, it helps remove ambiguity when a single distribution has more than one way of being parameterized.

#'
#' @return numeric vector of length n, each value in [a, b].
#'
#' @examples
#' sample_ca_compost_pct_c(5)
#'
#' @export
sample_ca_compost_pct_c <- function(n, params = NULL) {
p <- params %||% as.list(PEcAn.data.land::ca_compost_pct_c_distribution)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why not set this as the default directly?

Suggested change
sample_ca_compost_pct_c <- function(n, params = NULL) {
p <- params %||% as.list(PEcAn.data.land::ca_compost_pct_c_distribution)
sample_ca_compost_pct_c <- function(n, params = PEcAn.data.land::ca_compost_pct_c_distribution) {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

make sense,
but now i drops everything opinionated (distribution tibbles, samplers, build script for that, all gone). lnly thing remaining is the two ref tables (ca_n_application_rate , ca_compost_amendment with the new material_class column for CalRecycle). and actual sampling handled downstream workflow PR #4003

truncnorm::rtruncnorm(n, a = p$a, b = p$b, mean = p$mean, sd = p$sd)
}

#' Sample California compost C:N ratio
#'
#' Draws n values of compost C:N from the bundled truncated normal
#' distribution at ca_compost_cn_distribution.
#'
#' Default range (8 to 25, mean 12, sd 4) reflects the bimodal CA compost
#' distribution documented in the CDFA Healthy Soils Program white paper
#' (Geisseler et al.): manure dominant compost clusters at C:N at or
#' below 11 while plant dominant compost sits above 11. HSP 2026 Practice
#' Guidelines require applied C:N at or below 25.
#'
#' @param n integer. Number of draws.
#' @param params optional list overriding the bundled distribution.
#'
#' @return numeric vector of length n.
#'
#' @examples
#' sample_ca_compost_cn(5)
#'
#' @export
sample_ca_compost_cn <- function(n, params = NULL) {
p <- params %||% as.list(PEcAn.data.land::ca_compost_cn_distribution)
truncnorm::rtruncnorm(n, a = p$a, b = p$b, mean = p$mean, sd = p$sd)
}

#' Sample California compost application rate by PFT family
#'
#' Draws n application rates (dry weight tons per acre) uniformly from
#' the per family envelope at ca_compost_app_rate_envelope.
#'
#' Envelopes follow CDFA Healthy Soils Program white paper Table 2 plus
#' HSP 2026 Practice Guidelines plus USDA NRCS Conservation Practice
#' Standard 336 Soil Carbon Amendment (2022). Defaults: annual crops 3
#' to 8 t/ac dry, perennial crops 2 to 6 t/ac dry.
#'
#' @param pft_family character vector. PFT family for each draw. Must be
#' one of "annual", "perennial". Length 1 broadcasts to length n.
#' @param n integer. Number of draws. If pft_family has length > 1 then
#' n must equal length(pft_family).
#'
#' @return numeric vector of length n in tons per acre dry weight.
#'
#' @examples
#' sample_ca_compost_app_rate("annual", 5)
#' sample_ca_compost_app_rate(c("annual", "perennial", "annual"), 3)
#'
#' @export
sample_ca_compost_app_rate <- function(pft_family, n = length(pft_family)) {
if (length(pft_family) == 1 && n > 1) {
pft_family <- rep(pft_family, n)
}
if (length(pft_family) != n) {
PEcAn.logger::logger.severe(
"length(pft_family) must equal n; got ", length(pft_family), " vs ", n)
}
env <- PEcAn.data.land::ca_compost_app_rate_envelope

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Confusing name -- in R "env" almost always means an environment. Consider rate_envelope or maybe just rates?

out <- numeric(n)
for (fam in unique(pft_family)) {
if (!fam %in% env$pft_family) {
PEcAn.logger::logger.severe(
"Unknown pft_family '", fam, "'. Supported: ",
paste(env$pft_family, collapse = ", "))
}
row <- env[env$pft_family == fam, , drop = FALSE]
idx <- which(pft_family == fam)
out[idx] <- stats::runif(length(idx), min = row$min_t_ac, max = row$max_t_ac)
}
out
}

#' Sample California compost application date offset by PFT family
#'
#' Returns n integer day offsets (subtract from the cycle anchor,
#' typically MSLSP mslsp_OGI) drawn uniformly from the per family
#' calendar window at ca_compost_calendar_window.
#'
#' Defaults: annual crops 7 to 28 days before the anchor (CDFA HSP Box 1,
#' applied and incorporated before planting); perennial crops 60 to 180
#' days before the anchor (dormant season application, UC ANR cost
#' studies plus Bernard et al. 2023 vineyard timing of Nov 9 and Jan 10).
#'
#' @param pft_family character vector. PFT family for each draw.
#' @param n integer. Number of draws.
#'
#' @return integer vector of day offsets.
#'
#' @examples
#' sample_ca_compost_date_offset("annual", 5)
#'
#' @export
sample_ca_compost_date_offset <- function(pft_family, n = length(pft_family)) {
if (length(pft_family) == 1 && n > 1) {
pft_family <- rep(pft_family, n)
}
if (length(pft_family) != n) {
PEcAn.logger::logger.severe(
"length(pft_family) must equal n; got ", length(pft_family), " vs ", n)
}
win <- PEcAn.data.land::ca_compost_calendar_window
out <- integer(n)
for (fam in unique(pft_family)) {
if (!fam %in% win$pft_family) {
PEcAn.logger::logger.severe(
"Unknown pft_family '", fam, "'. Supported: ",
paste(win$pft_family, collapse = ", "))
}
row <- win[win$pft_family == fam, , drop = FALSE]
idx <- which(pft_family == fam)
out[idx] <- sample(row$offset_days_min:row$offset_days_max,
length(idx), replace = TRUE)
}
out
}

#' Sample California compost material class by PFT family
#'
#' Returns n material classes drawn from the per family whitelist at
#' ca_compost_material_whitelist. Uniform within the whitelist.
#'
#' Whitelist follows the CalRecycle taxonomy (14 CCR section 17852 plus
#' SB 1383 dominant feedstocks: green, food, wood, yard, ag, biosolids).
#' Defaults: annual crops can receive green / food / ag; perennial crops
#' can receive green / food / yard. Biosolids are excluded from food
#' crop parcels for regulatory compliance; wood waste is deferred since
#' it immobilizes N.
#'
#' @param pft_family character vector. PFT family for each draw.
#' @param n integer. Number of draws.
#'
#' @return character vector of material classes.
#'
#' @examples
#' sample_ca_compost_material("annual", 5)
#'
#' @export
sample_ca_compost_material <- function(pft_family, n = length(pft_family)) {
if (length(pft_family) == 1 && n > 1) {
pft_family <- rep(pft_family, n)
}
if (length(pft_family) != n) {
PEcAn.logger::logger.severe(
"length(pft_family) must equal n; got ", length(pft_family), " vs ", n)
}
wl <- PEcAn.data.land::ca_compost_material_whitelist
out <- character(n)
for (fam in unique(pft_family)) {
allowed <- wl$material_class[wl$pft_family == fam]
if (length(allowed) == 0) {
PEcAn.logger::logger.severe(
"No material whitelist for pft_family '", fam, "'. Supported: ",
paste(unique(wl$pft_family), collapse = ", "))
}
idx <- which(pft_family == fam)
out[idx] <- sample(allowed, length(idx), replace = TRUE)
}
out
}

# small null fallback helper.
`%||%` <- function(x, y) if (is.null(x)) y else x
45 changes: 45 additions & 0 deletions modules/data.land/R/tpa_lookup.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#' Look up California orchard density (trees per acre) by crop
#'
#' Returns the median trees per acre value for a California orchard crop,
#' derived from the DEMETER cropland biomass dataset. DEMETER photo dates
#' span 2010 to 2016, so modern high density plantings may be under
#' represented.
#'
#' Supported crops: Almonds, Walnuts, Oranges, Pistachios. Other crops
#' return NA with a warning.
#'
#' @param crop character. Crop name (case insensitive). One of "Almonds",
#' "Walnuts", "Oranges", "Pistachios".
#'
#' @return integer scalar. Trees per acre for the requested crop. Returns
#' NA_integer_ with a warning if the crop is not supported.
#'
#' @source Kroodsma, D. A., & Field, C. B. (2006). Carbon sequestration
#' in California agriculture, 1980-2000. Ecological Applications,
#' 16(5), 1975-1985.
#'
#' @examples
#' tpa_lookup("Almonds")
#' tpa_lookup("walnuts")
#'
#' @export
tpa_lookup <- function(crop) {
# median trees per acre by crop from DEMETER.
# TODO: promote to a bundled age keyed dataset when per parcel
# orchard age becomes available.
medians <- c(
almonds = 80L,
walnuts = 41L,
oranges = 110L,
pistachios = 119L
)
key <- tolower(crop)
if (!key %in% names(medians)) {
PEcAn.logger::logger.warn(
"No DEMETER TPA available for crop '", crop, "'. ",
"Supported: ", paste(names(medians), collapse = ", "), "."
)
return(NA_integer_)
}
medians[[key]]
}
Loading
Loading