Skip to content

Add CYGNSS preprocessed scalar observation operator - #184

Draft
amfox37 wants to merge 21 commits into
developfrom
feature/amfox/cygnss-preprocessed-operator
Draft

Add CYGNSS preprocessed scalar observation operator#184
amfox37 wants to merge 21 commits into
developfrom
feature/amfox/cygnss-preprocessed-operator

Conversation

@amfox37

@amfox37 amfox37 commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

This PR adds support for assimilating preprocessed CYGNSS L1 scalar observations.

Summary:

  • Adds the CYGNSS L1 scalar observation species and wires it into the supported update paths.
  • Adds cygnss_preprocessed_obs.F90 for reading/caching preprocessed daily CYGNSS files, including schema checks through version 0.5.
  • Updates observation reading, support/owner tile lookup, state-vector handling, and MWRTM/update plumbing needed by update types 12 and 13.
  • Adds default namelist entries for the CYGNSS preprocessed observation configuration.
  • Cleans up CYGNSS preprocessed observation cache storage during finalize.

Related PRs:
Care must be taken when develop is merged into the present branch after #186 is merged into develop.
There will be conflicts in GEOSldas_App/LDASsa_DEFAULT_inputs_ensupd.nml and GEOSlandassim_GridComp/clsm_ensupd_glob_param.F90

Testing:

  • Passed GEOSldas regression tests on Discover.
  • Built locally on macOS with cmake --build build-develop-20260520 --target install -j 4.

amfox37 and others added 18 commits May 20, 2026 16:05
…y ig/jg

Replace experiment-specific tile_index0 support-tile identity with globally
stable tile_ig/tile_jg (M36 EASE-grid column/row).  Both the coefficient
operator cache (cygnss_preprocessed_obs.F90) and the observation reader
(clsm_ensupd_read_obs.F90) now require schema_version = 0.4 and abort with
a clear message on older files.

Lookup is by tile_coord_lH%i_indg/j_indg instead of %f_num, so the
coefficient product is portable across GEOSldas experiments with different
tile counts or ordering.  The missing-halo abort now reports ig/jg for
easier diagnosis.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…a no-op

The day-spanning loop in read_obs_cygnss_l1_scalar opens the previous
UTC day's file for 00z-centered windows, but with the CYGNSS_operator
preprocessor's daily-merge convention that file never contributes rows:
each target day's file already has its own window 0 built from the
prior day's 22:30-24:00 tail. Note this so the generic cross-day loop
isn't mistaken for a bug or for missing data.
The schema-0.4 port already moved support-tile lookup to globally-stable
ig/jg, but two other spots still trusted the preprocessor's own
experiment-specific tile index:

- read_obs_cygnss_l1_scalar (clsm_ensupd_read_obs.F90) assigned each
  observation to its owner tile via sp_nearest_tile_index0+1 directly as
  a local tile number. That index is tied to whatever domain the
  preprocessor itself was run against, so for a cropped/limited-domain
  experiment with a much smaller local tile count, nearly every value
  landed outside the valid range and got rejected as a "bad owner tile"
  -- 100% rejection in the worst case. Now resolved via
  sp_nearest_tile_ig/jg matched against this experiment's own
  tile_coord%i_indg/j_indg.

- cygnss_preproc_load's per-observation cache (cygnss_preprocessed_obs.F90)
  had the same bug, plus the call site in clsm_ensupd_upd_routines.F90
  was passing a full-domain tile number where a local-plus-halo index was
  expected. Fixed the cache the same way (now takes N_catlH/tile_coord_lH)
  and converted the call site via f2l(), the same full-to-local map
  already used for the generic FOV-based obs path one branch up.

- cygnss_preproc_get_obs_pred aborted the whole run if any one
  observation's support tile fell outside the EnKF halo -- expected for
  observations near a cropped domain's edge. Now resolves all of an
  observation's support tiles up front and treats it as no-data rather
  than aborting if any are unresolvable (also drops the now-redundant
  per-ensemble-member repeated ig/jg lookup).

Verified on both a limited-domain (CONUS box, Jul 2020) and the original
full-global-domain (Nov 2019) experiment.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
cygnss_preproc_clear() existed but was only called internally to
invalidate the cache before loading a new day; it was never wired
into GridComp Finalize(), so the module-level cache arrays were
missed by the recent memory-leak cleanup pass.
@amfox37 amfox37 added enhancement New feature or request 0-diff labels Jul 21, 2026
amfox37 and others added 3 commits July 20, 2026 18:11
read_obs_cygnss_l1_scalar() guessed the coefficient product's EASE grid
by substring-matching 'M36'/'M09' against the full file path. Since
files are stored under Y<year>/M<month>/, any September file's path
contains "M09" (the month directory), which clobbered a correct M36
match from the filename and aborted the run with a bogus grid mismatch.

Schema-0.5 files already declare their grid explicitly via a 'grid'
global attribute - read and trust that instead, keeping the old
path/attribute substring guess only as a fallback for files without it,
and dropping the full-path (tmpfname) search from that fallback since
it's the source of the collision.
@github-actions

Copy link
Copy Markdown

This PR is being prevented from merging because you have added one of our blocking labels: Contingent - DNA, Needs Lead Approval, Contingent -- Do Not Approve. You'll need to remove it before this PR can be merged.

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