Skip to content

Add hardness, water-type, data-density, and water-level-change products#100

Merged
jirhiker merged 1 commit into
mainfrom
claude/dreamy-lamport-bc0ed4
Jun 29, 2026
Merged

Add hardness, water-type, data-density, and water-level-change products#100
jirhiker merged 1 commit into
mainfrom
claude/dreamy-lamport-bc0ed4

Conversation

@jirhiker

Copy link
Copy Markdown
Member

Summary

Four new OGC GeoJSON products, all reusing existing cohort source fetches (zero new API pulls):

Product output_type Cohort Per-feature signal
NM Water Hardness ogc_hardness analytes_state_NM total hardness as CaCO₃ + soft/moderate/hard/very-hard class
NM Water Type ogc_water_type analytes_state_NM Piper class from meq% of major ions + charge-balance QC
NM WL Data Density ogc_data_density waterlevels_state_NM obs/day counts, span, mean interval, obs/year
NM WL Change ogc_waterlevel_change waterlevels_state_NM ΔDTW over trailing window (default 5y), direction

Hardness + water-type pivot per-well summaries (analytes cohort). Data-density + WL-change consume sites/timeseries (waterlevels cohort). Source assets: 68 before, 68 after — the four ride fetches the existing products already perform.

Design decisions

  • Hardness = 2.497·Ca + 4.118·Mg (mg/L as CaCO₃). Latest-each pairing; Ca/Mg dates may differ, both emitted. Missing ion → insufficient.
  • Water-type: mg/L → meq/L by equivalent weight; dominant cation/anion at >50% else mixed; charge_balance_pct flags suspect analyses. No cations or no anions → insufficient.
  • Data-density: record_count = distinct days, observation_count = raw valid readings.
  • WL-change: end = latest daily value; start = daily value nearest window_years before, accepted only within ½ window of target else status=insufficient. Positive change_ft = depth-to-water increased = water table declined. window_years configurable in YAML.

Files

  • backend/persisters/ogc_features.py — 4 dumpers + shared _num/_pivot_by_well/_well_feature/_site_feature.
  • orchestration/assets/products.py — combine dispatch + multi-analyte param handling.
  • orchestration/definitions.py — 4 added to _SUPPORTED_OUTPUT_TYPES.
  • orchestration/config/products.yaml — 4 product entries.
  • tests/test_persisters/test_ogc_features.py — 14 new dumper tests.

Verification

  • Dumper tests: 34 pass. Full suite: 297 pass.
  • dg.Definitions builds clean (assets + jobs + schedules); new products land in the correct cohorts; graph adds 0 new source assets.

Note: this branch is slightly behind main on products.py (missing the later asset-description commits). Edits are in non-overlapping regions, so a 3-way merge should keep main's descriptions — rebase if any conflict surfaces.

🤖 Generated with Claude Code

Four new OGC GeoJSON products, all reusing existing cohort source fetches
(zero new API pulls):

- nm_hardness (ogc_hardness): total hardness as CaCO3 from latest calcium +
  magnesium, with soft/moderate/hard/very-hard class.
- nm_water_type (ogc_water_type): hydrochemical (Piper) water type from the
  major-ion suite — meq% of cations (Ca/Mg/Na+K) and anions (HCO3+CO3/Cl/SO4),
  dominant ion >50% else mixed, plus charge-balance QC.
- nm_waterlevel_data_density (ogc_data_density): per-well measurement coverage
  (raw/daily counts, span, mean interval, observations per year).
- nm_waterlevel_change (ogc_waterlevel_change): depth-to-water change over a
  trailing window (default 5y); positive = water table declined; start must be
  within half the window of the target else status=insufficient.

Hardness and water-type pivot per-well summaries (analytes cohort); data-density
and water-level-change consume sites/timeseries (waterlevels cohort). All four
add no new shared source assets — they ride fetches the existing products
already perform.

Adds the dumpers + shared pivot/feature helpers in ogc_features.py, the combine
dispatch and multi-analyte param handling in products.py, the output types in
definitions.py, the product entries in products.yaml, and dumper tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@jirhiker jirhiker merged commit 08679f3 into main Jun 29, 2026
2 checks passed
@github-actions

github-actions Bot commented Jun 29, 2026

Copy link
Copy Markdown

Your pull request is automatically being deployed to Dagster Cloud.

Location Status Link Updated
die-orchestration View in Cloud Jun 29, 2026 at 08:14 AM (UTC)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant