Skip to content

Route A: Wood-Anderson (response-removed) amplitude pipeline for magnitudes#13

Open
mdenolle wants to merge 1 commit into
mainfrom
feat/magnitude-route-a
Open

Route A: Wood-Anderson (response-removed) amplitude pipeline for magnitudes#13
mdenolle wants to merge 1 commit into
mainfrom
feat/magnitude-route-a

Conversation

@mdenolle

Copy link
Copy Markdown
Collaborator

Adds the Route A pipeline — re-measure amplitudes as Wood-Anderson displacement (instrument response removed) — to run on a pnwstore-connected host, and to address the seismological caveats of the merged counts-based Method B (#12).

Why (Method B re-audit → what Route A fixes)

Method-B caveat Route-A fix
counts + a scalar station term can't represent a frequency-dependent response over ML −1.5…4.6 remove response → WA displacement; station term ≈ pure site
one station term per reused OBS code across yearly redeployments per-epoch station terms (NET.STA@epoch)
fixed 2.5 s window misses the delayed S/Lg peak (distance-dependent bias) distance-scaled window per phase
no SNR gate (noisy OBS; e.g. the window-edge peak of ARID 999382) pre-signal SNR measured + gated
Wood-Anderson product missing NC (133k) + BK (22k) from the old IRIS-only run NC/BK via NCEDC

Scripts (4_relocation/magnitude/)

  • route_a_build_station_inventory.py — coords + response + operational epochs (StationXML + CSV).
  • route_a_wa_amplitudes.py — per P and S pick: remove_response → IASPEI Wood-Anderson simulation → peak WA displacement in a distance-scaled window (all components, vertical fallback) + SNR + epoch tag. Appends on the fly; --start-index/--limit for resume/shard.
  • route_a_build_dataset.py — SNR gate + epoch-keyed station ids → dataset that feeds the existing phase3 → phase2 → phase4/5/6 unchanged (--suffix _routeA).
  • ROUTE_A_RUNBOOK.md — environment (pixi --environment internal), step-by-step, validation vs Method B, and parameter notes.

Design (confirmed)

Wood-Anderson amplitude; measured for P and S; distance-scaled window; all components with vertical fallback. IASPEI WA constants (T0=0.8 s, h=0.7, gain 2080); the absolute gain is absorbed by the ComCat-ML calibration.

Status / caveats

  • Not yet run — these are the scripts to git pull and execute on the pnwstore host; validate on a small --limit first and sanity-check wa_amp_mm.
  • Route A is a cross-check / upgrade of Method B, not a replacement of the merged catalog; compare cascadia_catalog_ML_routeA.csv vs _kpos on event_id.
  • Epochs are folded into the station id so the inversion produces per-deployment terms with no change to phase3.

🤖 Generated with Claude Code

Scripts to re-measure amplitudes as Wood-Anderson displacement on a pnwstore host,
addressing the Method-B seismological caveats (counts scalar response, OBS
redeployment station-term stability, fixed short window, no SNR gate, missing NC/BK):

- route_a_build_station_inventory.py: coords + response + operational epochs for all
  networks (NC/BK via NCEDC); StationXML + epoch CSV.
- route_a_wa_amplitudes.py: per P and S pick -> remove response, simulate IASPEI
  Wood-Anderson, peak WA displacement in a distance-scaled window (all components,
  vertical fallback), pre-signal SNR, response-epoch tag. Resumable/shardable.
- route_a_build_dataset.py: SNR gate + epoch-keyed station ids -> dataset feeding the
  existing phase3->phase2->phase4/5 pipeline unchanged (--suffix _routeA).
- ROUTE_A_RUNBOOK.md: environment, steps, validation vs Method B, parameter notes.

Design (per PI): Wood-Anderson; P and S; distance-scaled window; all components + Z
fallback. Untested against pnwstore -- validate on a small --limit first.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 12, 2026 16:55

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds Route A (response-removed Wood–Anderson amplitude measurements) as an alternative magnitude pre-processing path that can feed the existing Route B inversion/anchoring/QC stages unchanged. This is intended to address known limitations of counts-based amplitudes by removing instrument response, using distance-scaled windows, adding SNR measurements for gating, and tagging redeployment epochs.

Changes:

  • Add a waveform-driven per-pick Wood–Anderson amplitude measurement script (response removal + WA simulation + distance-scaled window + SNR + epoch tagging).
  • Add a station-inventory builder to assemble StationXML (with response + epochs) for networks found in the picks catalog, routing NC/BK to NCEDC.
  • Add a dataset builder to apply SNR gating and (optionally) epoch-key station IDs, producing the same schema consumed by phase3_route_b_relative_magnitude.py.
  • Add a Route A runbook documenting execution environment, steps, and validation guidance.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
4_relocation/magnitude/route_a_wa_amplitudes.py Implements per-pick waveform fetching, response removal, WA simulation, windowed amplitude measurement, SNR calculation, and epoch tagging.
4_relocation/magnitude/route_a_build_station_inventory.py Builds StationXML + CSV epoch inventory for response removal and redeployment epoch identification.
4_relocation/magnitude/route_a_build_dataset.py Filters raw WA measurements, applies SNR gate, optionally epoch-keys station IDs, and emits the downstream dataset schema.
4_relocation/magnitude/ROUTE_A_RUNBOOK.md Documents the Route A workflow, environment requirements, parameters, and validation comparisons vs Method B.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +117 to +122
for _, row in picks.iloc[sl].iterrows():
net, sta = str(row["station"]).split(".")[0].strip(), str(row["station"]).split(".")[1].strip()
phase = _phase(row["phase"])
rec = {k: "" for k in OUT_COLS}
rec.update(arid=row.get("arid"), event_id=row.get(ev_col), network=net,
station=f"{net}.{sta}", phase=phase, n_comp=0)
Comment on lines +134 to +136
try:
st = get_waveforms(net, sta, "*H*", tp - (args.noise_win + 5), tp + post + 5,
source=args.source)
Comment on lines +37 to +40
amp = pd.to_numeric(df["wa_amp_mm"], errors="coerce")
snr = pd.to_numeric(df.get("snr"), errors="coerce")
keep = amp.notna() & (amp > 0) & ((snr >= args.min_snr) | snr.isna())
n_lowsnr = int(((snr < args.min_snr)).sum())
Comment on lines +53 to +55
out = os.path.expanduser(args.out)
os.makedirs(os.path.dirname(out), exist_ok=True)
df[cols].to_csv(out, index=False)
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.

2 participants