Skip to content

Manifest-based OAT sensitivity drops median row for shared SA-median run #3882

@dlebauer

Description

@dlebauer

Bug Description

This is based on the modules/uncertainty/vignettes/uncertainty.qmd and I am unsure how general the issue is.

This was observed in the manifest-based OAT sensitivity. The older sa.run.ids-based path on main should not have this specific lookup problem.

The OAT sensitivity workflow appears to drop the median (50) row from sensitivity outputs.

In the full workflow, the median run exists (out/SA-median--1/2004.nc), but read.sa.output() warns:

Run ID invalid or missing for <trait> 50

and the saved sensitivity.output.*.Rdata contains NA for the 50 row.

The issue seems to be a mismatch between manifest writing and lookup:

  • write.sa.configs() writes one shared median SA run with:
    • run_id = SA-median--1
    • pft_name = "NA"
    • trait = "NA"
    • quantile = 50
  • read.sa.output() looks up runs by matching:
    • type
    • pft_name
    • trait
    • quantile

So the shared median run can never match a trait- and PFT-specific lookup.

In the saved downstream analysis objects, the median sample value is still present in sa.samples, but the corresponding median output is NA, so the downstream sensitivity fit proceeds without a valid median response.

To Reproduce

Minimal reprex showing the current read.sa.output() behavior:

withr::with_tempdir({
  manifest <- data.frame(
    type = "Sensitivity",
    pft_name = "temperate.coniferous",
    trait = "growth_resp_factor",
    quantile = "50",
    run_id = NA_character_
  )
  write.csv(manifest, "runs_manifest.csv", row.names = FALSE)

  out <- PEcAn.uncertainty::read.sa.output(
    traits = "growth_resp_factor",
    quantiles = "50",
    pecandir = getwd(),
    outdir = getwd(),
    pft.name = "temperate.coniferous",
    start.year = 2004,
    end.year = 2004,
    variable = PEcAn.utils::convert.expr("NPP")
  )

  sensitivity.output <- list("temperate.coniferous" = out)
  save(sensitivity.output, file = "sensitivity.output.test.NPP.2004.2004.Rdata")
  rm(sensitivity.output)
  load("sensitivity.output.test.NPP.2004.2004.Rdata")

  sensitivity.output[["temperate.coniferous"]]
})
#>    growth_resp_factor
#> 50                 NA

Created on 2026-03-18 with reprex v2.1.1

Standard output and standard error

2026-03-18 18:29:52.480915 WARN   [PEcAn.uncertainty::read.sa.output] : 
   Run ID invalid or missing for growth_resp_factor 50 
2026-03-18 18:29:52.506574 INFO   [PEcAn.uncertainty::read.sa.output] : 
   reading sensitivity analysis output for model run at 50 quantiles of 
   trait growth_resp_factor 

Expected behavior

The median row should be populated, since it is part of the intended OAT sensitivity workflow.

Screenshots

If applicable, add screenshots to help explain your problem.

Machine (please complete the following information):

OS: macOS
Version: PEcAn worktree based on develop as of 2026-03-18

Additional context

This appears to be a mismatch between manifest writing and lookup:

write.sa.configs() writes one shared median SA run with run_id = SA-median--1, pft_name = "NA", trait = "NA", quantile = 50 read.sa.output()` looks up runs by matching type, pft_name, trait, and quantile
So the shared median run cannot match a trait- and PFT-specific lookup.

This appears to be specific to the newer manifest-based SA lookup path. In the older sa.run.ids-based path, the median run is stored in the per-trait/PFT run-id table, so this specific warning should not occur under normal use.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions