Add v0.4.0 sign convention to the manuscript; real-archive validation section - #37
Open
mdenolle wants to merge 14 commits into
Open
Add v0.4.0 sign convention to the manuscript; real-archive validation section#37mdenolle wants to merge 14 commits into
mdenolle wants to merge 14 commits into
Conversation
… section Prompted by two things landing this week: the physical dv/v sign convention correction (v0.4.0, PR #36) and a real-archive validation against Clements & Denolle (2022) at three CI stations. - Boxed sign-convention definition where dv/v is first introduced (Introduction): dv/v = -eps/(1+eps), with the first-order shortcut's 0.17% bias at landslide-scale (4%) changes. - Sec. methods-fig: states all seven estimators return physical dv/v under this convention as of v0.4.0, the synthetic generator imposes in the same convention, and tests/test_sign_convention.py holds every estimator to it in both signs. - New Discussion item, "Validate against something you did not generate": the cautionary finding that internal consistency isn't correctness -- generator and estimators agreed with each other before the fix, so every synthetic test passed, while real-archive dv/v anticorrelated with CD2022 and seasonal hydrology at three stations (r=-0.69,-0.45,-0.40) until ground-truthing through the exact call path caught it. - New Sec. deployment content: the real-archive validation. Comparison methodology (CD2022's trailing-90-day product lags a centered daily series by ~45 days; match by applying the same trailing mean, compare demeaned, exclude a 150-day burn-in), headline numbers (CI.LJR r=0.990, CI.ARV 0.66-0.92, CI.RXH 0.68), and three figures: the station-by-station validation against CD2022 (whose own annotated r is a different, unmatched-smoothing comparison -- the caption is explicit about why the two numbers differ), the daily CCF interferograms explaining why validation quality differs by station, and an optional supplement on the ensemble's warm-up honesty. - Consistency sweep found and fixed two real inconsistencies beyond the new content: the appendix's estimator-definitions section equated "epsilon" directly with "the recovered dv/v" (the pre-fix convention) instead of treating epsilon as the stretch factor that converts via the boxed relation -- fixed there and in the aggregation-approach formulas. The Synthetic Framework section's own impose-dv/v equation still used the pre-fix formula (t/(1+dv/v), division) instead of the current code's t*(1+dv/v) (multiplication) -- fixed. Figures copied from paper/figures/gate1/ (committed validation artifacts, see paper/data/gate1/README.md) into literature/figs/ as realdata_1_validation.png, realdata_2_interferograms.png, realdata_3_warmup.png. Verified: 245/245 tests pass (1 unrelated skip), PDF builds cleanly (only the 2 pre-existing, already-tracked dangling citations from issue #30), all three new figures checked against their actual pixel content before writing captions, box/section/figure renders visually confirmed on rendered PDF pages. NOT addressed here, flagged for a separate pass: every one of the paper's 15 synthetic demo figures (demo_1 through demo_15) was generated before the sign-convention fix (all last content-committed 2026-07-20 through 2026-08-03; the fix landed 2026-08-09). The code change is not a pure sign negation -- impose_dvv changed from t/(1+dvv) to t*(1+dvv), a different nonlinear map -- so regenerating is needed to know which specific figures/numbers actually flip and by how much, especially at the paper's own larger-magnitude tests (the +/-5% sweep, the 4% landslide scenario) where the boxed convention's own math says the nonlinear correction is not negligible.
There was a problem hiding this comment.
Pull request overview
Updates the marine manuscript to reflect codameter v0.4.0’s physical dv/v sign convention and adds a real-archive validation narrative and figures (CI stations vs Clements & Denolle product), plus consistency fixes to formulas and appendix definitions.
Changes:
- Adds a boxed dv/v sign-convention definition and updates methods/discussion text to reflect v0.4.0 behavior and test coverage.
- Updates the synthetic framework’s imposed dv/v equation to match the current implementation (
t*(1+dv/v)). - Adds a real-archive validation section with three figures and updates appendix aggregation/estimator definitions to distinguish stretch factor ε from physical dv/v.
Reviewed changes
Copilot reviewed 2 out of 5 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| paper/manuscript_marine.tex | Adds sign-convention box, real-archive validation + figures, and updates equations/appendix text for the v0.4.0 convention. |
| paper/manuscript_marine.qmd | Mirrors the manuscript updates in the Quarto source (equation fix, validation section + figures, appendix wording). |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| claim is drawn from it. | ||
|
|
||
| After the correction, single-station \dvv~(NoisePy correlations, a | ||
| codameter 5-member ensemble, 2--4,Hz, 2018--2019) validates against the |
|
|
||
| As an optional supplement, | ||
| Fig.\textasciitilde{}\ref{fig:realdata-warmup} shows the ensemble's | ||
| warm-up behaviour on a separate 90-day smoke run at CI.LJR: \dvv\\ |
| whether coseismic softening is a shallow site response or slip on the | ||
| fault at depth \citep{Rubinstein2005} --- so a depth reported without | ||
| its uncertainty cannot support that claim. | ||
| \citep[\citet{Mao2025}]{Takano2017, Feng2020, Mao2022}. The step from a |
Comment on lines
+306
to
+308
| The first-order shortcut $\dvv \approx -\varepsilon$ is accurate to order | ||
| $\varepsilon^2$ --- negligible below $1\,\%$ but a $0.17\,\%$ absolute bias at | ||
| the $4\,\%$ changes seen on landslides. |
Copilot's own 4 comments, plus what investigating them turned up:
- The flagged 2--4,Hz (missing thin space) turned out to be one
instance of a paper-wide, pre-existing bug: pandoc's markdown reader
treats a bare `\,` outside math/raw-latex blocks as an escaped
literal comma (CommonMark punctuation-escape rules), silently
eating the backslash. Audited every `\,` in the document against
its actual rendered .tex output rather than guessing; found and
fixed 9 corrupted unit-spacing instances (Hz/s) across 6 lines,
using the same $\,$ math-wrapped form already proven safe elsewhere
in this document. Raw-latex-fenced tables were correctly unaffected
and left alone.
- Same root cause, different symptom: three "\dvv\, " instances
(macro + backslash-comma used as prose spacing) were rendering as
"\dvv," -- a spurious visible comma after the delta-v/v symbol in
three places, including the Introduction's very first sentence
introducing dv/v. Fixed the same way. (Two other \dvv, matches were
genuine, intentional commas -- verified each one's qmd source before
touching anything.)
- The flagged forced line-break (`\dvv\\`) was caused by a related
CommonMark rule: a bare backslash at the end of a source line is a
hard-line-break request. Fixed by reflowing so the line doesn't end
there.
- The malformed \citep[\citet{...}]{...} nesting was a real citation
bug: a comma instead of a semicolon between two citation keys made
pandoc parse the second key as a locator/suffix on the first
instead of a separate citation. Fixed the separator.
- The 0.17% first-order-bias number was correct but ambiguous about
which quantity is "4%" (epsilon or dv/v) -- Copilot's own sanity
check computed a different, also-valid 0.15% by assuming epsilon.
Reworded to say "a true dv/v of 4%" explicitly, keeping the
0.17% figure since that's the physically meaningful reading (a
real dv/v magnitude "seen on landslides", not an internal
stretch-factor value).
Verified: 245/245 tests pass (1 unrelated skip, no Python touched),
PDF builds cleanly, re-audited the whole document for both bug
patterns (digit-comma-unit and macro-comma) after the fix -- zero
remaining instances of either.
…verify every quantitative claim Every one of the 15 synthetic demo figures predated the v0.4.0 sign fix (flagged in PR #37, not fixed there). impose_dvv changed from t/(1+dvv) to t*(1+dvv) -- a different nonlinear map, not a pure sign negation -- so regenerating could plausibly change specific numbers, not just axis labels. Regenerated all 14 figures actually referenced in the manuscript (literature/synthetic_dvv_demo.py, codameter.deviations.build_figs, codameter.uq_bayes.build_figs; demo_9_multiverse.png also regenerated but stays unreferenced/orphaned as before) and re-derived every quantitative claim tied to them directly from the current code rather than eyeballing the new plots. Real changes found and fixed, not just cosmetic: - Fig. methods (demo_1): the +/-5% sweep now shows genuine sign asymmetry for WCC and WTDTW -- WCC tracks the 1:1 line tightly on the negative branch but breaks sharply near +5%; WTDTW crosses 1% error at +1% true dv/v but only at -3% on the other branch. This is real physics from the corrected nonlinear convention, not noise. Rewrote the caption and body paragraph with per-branch thresholds instead of the old (now false) claim that TS/WTS/WCC "track the 1:1 line throughout" and that DTW/WTDTW break symmetrically past +/-3-4%. - Fig. deviations (demo_10) + multiverse text: the deviation ranking reordered substantially -- WCS is now catastrophic (~50x baseline, not previously flagged this way), baseline RMS moved from ~0.02% to ~0.03%. Sobol sensitivity ranking changed too: estimator is now 2nd for RMS (was stated "third"), still 3rd for the drop. - Sec. params: Brenguier-style joint inversion RMS moved to ~0.03% (was ~0.04%, so no longer distinct from the fixed-stack baseline). The "early 15% stack is ~1.5x worse" claim did not reproduce -- re-verified it's actually comparable to (or slightly better than) the whole-record reference, and rewrote that paragraph to state the real (and more interesting) reason why: a shorter, earlier reference avoids averaging across the developing pre-eruptive trend. - Sec. window: coda-window-detection numbers (the actual detected window boundaries) matched exactly, as expected since envelope detection doesn't depend on measurement sign; RMS numbers shifted by rounding-level amounts, tightened to match. - Results-synthesis table: fixed the same two errors (TS/WTS best-case claim -> TS only, since WTS now peaks at 0.093% not <0.01%; reference-scheme range -> ~0.03% only). Confirmed unchanged (RMS-type metrics on small-amplitude signals are close to sign-invariant, consistent with the boxed convention's own "negligible below 1%" claim): aggregation (demo_2), network uncertainty (demo_3/14, every number re-verified via network_dvv() directly), frequency-band depth selection (demo_4), stacking length (demo_6), Bayesian N_eff, artifacts and branch-asymmetry figures (demo_8/13, qualitative claims only, still hold). Verified: 245/245 tests pass (1 unrelated skip), PDF builds cleanly (only the 2 pre-existing dangling citations from issue #30), no unit- spacing or citation corruption reintroduced.
Figure 10a (multiverse RMS panel): pin to a fixed, symmetric (-0.8, 0.8) range instead of a dynamic percentile-based span, since the cycle-skipping pipelines were making the colourbar/axis scale distractingly asymmetric. Figure 11 (Bayesian measurement model): restructure from a cramped 1x3 row to a 2x2 grid with panel (c) full-width on its own row -- it carries four legend entries and was too horizontally squeezed sharing a row with (a) and (b). Verified: 245/245 tests pass, PDF builds cleanly, both fixes confirmed on the rendered PDF pages (Fig 10 p.22, Fig 11 p.26). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Ran a plain-voice pass over manuscript_marine.qmd. Prior editing passes had already scrubbed the heavy tells (delve, leverage, robust filler, landscape/tapestry-style metaphors); this pass caught the remainder plus grammar breaks found while reading closely: Register/filler cuts: "demonstrating robustness of the methods" (redundant clause), "comprehensive" (package), "utilize" -> "use" (x2), "various" (parameter impacts), "typically" (redundant with "by habit"), "comprehensively" (redundant with "cumulative... full choice set"), "downstream scientific insights" -> "downstream science". Grammar/typo fixes: missing "of"/"in" (price of, reporting of, studies in), a stray leading period breaking two sentences into one, "atomsphere"->atmosphere, "chanes"->changes, "scatterd"->scattered, "strething"->stretching, "te moving-window"->the, "a implementation"->an, "cross-componet"->cross-component, "a inter-station"->an, "characteristixcs"->characteristics, "can alters"->materially changes, "an researchers'"->a researcher's, "both side exhibit"->both sides exhibit, "parametic"->parametric, "researchers typically would measure"->typically measure. Checked and left unchanged: em-dash usage (every instance is a single parenthetical pair per sentence, never chained), statistical/technical uses of "robust," "significant," "framework," "workflow" (legitimate domain vocabulary, not ornament), hedge preambles and metaphor clichés (none found), tricolon lists (all are genuine parallel enumerations, not decorative filler). Verified: PDF builds cleanly (only 2 pre-existing undefined citations, lobkis01/poupinet84, unrelated to this change). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The trial-epsilon search in stretching_cc, measure_stretching_trailing, and
measure_wts previously resampled the reference waveform at t/(1+eps) while
holding current fixed. This commit flips the convention to resample current
at (1+eps)*t, matching the field's usual practice of keeping the high-SNR
reference stack invariant throughout the epsilon search.
The exact conversion dv/v = -eps/(1+eps) remains unchanged — both conventions
give the identical exact formula (see derivation in PR). The swap is a targeted
implementation change with a small finite-sample effect (~single-digit percent
drift in synthetic metrics on per-day current traces vs. averaged references)
but ensures the estimator behaves as documented: it holds reference fixed and
trials act on the current correlation.
IMPLEMENTATION:
- stretching_cc: now normalizes reference once, resamples current per trial
- measure_stretching_trailing: resamples cur_mat (per-day, noisier) against
fixed trailing reference (computed once per day); vectorized gather via
precomputed searchsorted indices/weights
- measure_wts: resamples per-scale Wcur (current wavelet transform) at
(1+eps)*t; Wref (reference) fixed per scale
- New dvv_to_epsilon(dvv) helper: exact inverse of eps_to_dvv, with domain
guard on dvv <= -1
- New _stretch_window(t, window, eps_max, branch='both'): computes the
tightest common window such that all trial positions (1+eps)*t stay within
t's support for every eps in [-eps_max, eps_max]; warns if shrinkage needed,
raises if no window fits. Eliminates silent extrapolation via np.interp's
default clamp behavior
TESTS (new file tests/test_stretching_interpolation.py, 55 cases):
- Truth-known recovery at dvv in {0, ±0.001, ±0.01, ±0.04, ±0.05}, sub-1e-4
error at high SNR
- Independent analytic oracle: hand-built closed-form coda (not impose_dvv),
current created by explicit travel-time-ratio resampling; detector should
not share code path with generator (catches pre-v0.4.0 failure mode)
- Reciprocity test: both conventions applied to same ideal synthetic, both
converted through same eps_to_dvv, discrepancy < 1e-5 (empirical duality)
- One-axis-at-a-time bias sweeps: eps magnitude, sampling rate, window
position/length, bandwidth, SNR
- eps_to_dvv/dvv_to_epsilon round-trip and domain-guard tests
- measure_stretching_trailing vectorized vs. day-by-day loop equivalence to 1e-16
GOLDEN MANIFEST:
- Regenerated against new numerics (golden.MANIFEST_VERSION: 2→3)
- Diffs: easy +9.30%, medium +6.71%, hard -0.79%, rms_wrong_layer +0.00%
- All within existing tolerances; no sign flips
MANUSCRIPT (paper/manuscript_marine.qmd):
- Appendix A Trace Stretching definition rewritten to specify current-
interpolated convention: c_ε(t) = I[c]((1+ε)t), reference fixed
- New "Interpolation direction and convention" subsection (320 words):
explains why current is interpolated (invariant reference), mathematical
equivalence in continuous limit, symmetry-breaking in finite windows, and
empirical validation (sub-10⁻⁴ bias at high SNR, ~few% at landslide scale)
- All other sections (Introduction, Methods, WCC/MWCS/DTW/WCS/WTS/WTDTW,
Aggregation) already consistent; no additional changes needed
DOCSTRINGS:
- synthetic_demo module docstring: updated to describe current-interpolated
stretching
- run_pipeline (deviations.py): updated to describe correct resampling direction
- eps_to_dvv: clarified it is exact; first-order is approximation only
- impose_dvv: docstring clarity pass (formula unchanged, already correct)
BACKWARD COMPATIBILITY:
- No raw epsilon/eps values persisted anywhere in the codebase, so no data
migration needed
- No public API signature changes; measure_stretching etc. still return physical
dv/v with same call shape
- MANIFEST_VERSION bump ensures per-user golden cache regenerates on next run
- Hidden/private golden corpus built externally should be regenerated separately
All 300 tests pass. No regressions.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
…ections Explain how denoising, filtering, and spatial redundancy can improve SNR of short-time correlations, enabling dv/v measurements at finer temporal resolution than conventional long-duration stacking allows. - Introduction: one sentence on the temporal-resolution tradeoff (line 95) - Substacking section: new paragraph framing substack duration as a precision–temporal-resolution tradeoff, citing approaches like adaptive filtering, SVD denoising, learned denoising, and array redundancy (Hadziioannou2011, Moreau2017, Mao2019, Viens2020) - Add four new references to references.bib - Rebuild PDF Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Add formal definition of measurement uncertainty notation in Introduction
(line 127) so readers encounter $\sigma$ defined before Table 2.
Define all variants upfront:
- $\sigma$: generic measurement uncertainty on dv/v
- $\sigma_k$: per-component uncertainty
- $\sigma_{\varepsilon}$: measurement error on raw stretch factor
- $\sigma_{\mathrm{SE}}$, $\sigma_{\mathrm{SD}}$: standard error and standard deviation conventions
- $\sigma_d$: data covariance matrix diagonal
Standardize subscript formatting across paper:
- Line 964, 967: $\sigma_{\rm tot}$ → $\sigma_{\mathrm{tot}}$
- Line 986: $N_{\rm eff}$ → $N_{\mathrm{eff}}$
All subscripts now consistently use \mathrm for mathematical roman formatting.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Keep Introduction definition general (σ denotes measurement uncertainty).
Move specific subscript definitions to where each variant first appears:
- $\sigma_k$ (per-component): added to Bayesian section (line 967)
'where $\sigma_k(t)$ is the per-component measurement uncertainty'
- $\sigma_d$ (data covariance diagonal): added to figure caption (line 984)
'The diagonal ($\sigma_d(t)$, the measurement uncertainty from $C_d$)'
- $\sigma_{\varepsilon}$ (on stretch factor): added to Appendix A TS definition (line 1298)
'The single-measurement error on the raw stretch factor $\varepsilon$ (denoted $\sigma_{\varepsilon}$)'
- $\sigma_{\mathrm{SE}}$, $\sigma_{\mathrm{SD}}$ already locally defined in Appendix B
This approach keeps Introduction clean, teaches notation as readers encounter it.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Fixed issues from file overwrite: - Simplified σ definition in Introduction (line 158): now includes σ, B, W - Updated Table 1 caption (lines 241-243): Added key notation definitions - Fixed Table 1 row labels to use proper notation: $B$ and $W$ - Fixed broken σ reference in Estimator row - Verified Appendix A has formal definitions This creates consistent notation framework: - Introduction introduces all key symbols - Table 1 reinforces them in caption - Appendix A provides formal definitions - Subscripts defined locally where first introduced Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Moving reference erases trends within segments, but stitching approaches (like Ermert 2023) can recover trend information across segments. Joint inversion preserves trends throughout. Updated Table 1 Reference row to clarify the nuance: 'Moving reference erases trends within segments (unless stitched across segments); joint inversion preserves them' This reflects the practical choice between moving reference and joint inversion depending on segment-level trend preservation needs. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
… reports The survey does not support the claims the reference section was making. Searching all fields of all 103 surveyed studies for a trailing/moving/ segment-wise reference returns nothing. The nine stack_scheme entries that mention moving or rolling windows are all moving *current* stacks read against a fixed long-term reference (Brenguier 2008: 5-day windows vs a 1550-day reference; Wang 2017: moving-window current stack vs a ~1-yr reference), which belongs to the substacking axis, not the reference axis. Ermert 2023 in particular was mischaracterised. Its surveyed scheme is 'Clustered (GMM) autocorrelation stacks' -- waveform clustering to stabilise urban autocorrelations -- not a multiple or segment-wise reference. The prose attributed a method to that paper the survey does not support, and the Table 1 row I added last commit built a stitching caveat on top of it. - Table 1: drop the stitching caveat; state what Fig. params(c) shows. - Reference section: replace the Ermert-as-multiple-reference sentence with the survey null result, which justifies the joint inversion more directly than the analogy did, and describe Ermert's GMM clustering accurately as reference *selection* -- a distinct axis codameter does not implement. Hedged as 'none of the 103 studies reports' rather than 'nobody does': the stack_scheme field was not among the four measurement fields re-verified against full text for the 82 readable studies. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ounts My previous commit (01cebfd) asserted that no surveyed study uses a trailing reference and that Ermert 2023 does not use a multiple reference. Both claims are false, and the underlying physical claim was too strong. Verified against the sources: - Ermert et al. 2023 states verbatim 'We use a multiple-reference approach due to the lack of long-term waveform coherence in our observations'. The GMM clustering is real but selects which windows to stack; it is orthogonal to reference construction, not a substitute for it. The survey row I based the claim on is coded 'abstract only (paywalled)' -- yet Solid Earth is fully open access, so that row is a survey data-quality bug in its own right. - James et al. 2017 (GRL, 10.1002/2016GL072468) re-baseline against the adjacent prior day-stack and cumulate the daily dt/t, and RECOVER a seasonal permafrost trend that a stationary reference could not detect (it cycle-skipped). The survey missed this paper entirely; it contains James et al. 2019, a different study with a different DOI. - Zotz-Wilson, Boerrigter & Barnhoorn 2019 (JASA) use a rolling reference wavefield for lab coda monitoring of rock deforming to yielding. The physics correction: 'moving reference erases the trend' is a property of the uncumulated INCREMENT, which is what measure_stretching_moving computes, not of trailing references in general. Cumulating recovers the trend at the cost of integrating the error into a random-walk drift -- James 2017 report exactly that drift and correct it linearly against a stationary anchor. - Table 1: trailing reference gives increments; trend absent unless cumulated. - Reference section: replace the null result with the increment-vs-cumulated distinction, cite James2017 and ZotzWilson2019, describe Ermert accurately, and state plainly that codameter implements neither construction. - references.bib: add James2017, ZotzWilson2019 (metadata verified, not guessed). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Fetched Rivet 2014 and James 2017 via the documented Wiley TDM path and read
them, rather than inferring from abstracts as I did with Ermert.
Rivet et al. (2014) is segment-wise stitching, verbatim: a separate reference
stack per period ("For the three time periods ... we define reference cross
correlation as the average of correlations during the entire time period"),
merged by "comput[ing] the relative velocity changes between the reference
cross-correlations of station pairs that stayed at the same sites for two
successive periods". Its bibliography yielded Sens-Schonfelder, Pomponi &
Peltier (2014), the multiple-reference study at the same volcano.
Rivet et al. (2011) was in the survey the whole time, coded from full text as
"previous-epoch referencing" -- in the uncertainty_treatment column, not
stack_scheme, which is why my earlier all-field search missed it. That search
also dropped the previous-epoch pattern I had used in the first pass. The
"none of the 103 studies" claim came from a search I ran carelessly.
The published alternatives to a fixed reference form two families, and the
uncumulated day-by-day trailing reference codameter sweeps is in neither:
cumulated increments James 2017, Rivet 2011 (and Zotz-Wilson 2019 in the
lab) -- recovers the trend, integrates error into a
random-walk drift, needs an independent anchor
piecewise + stitching Rivet 2014, Sens-Schonfelder 2014, Ermert 2023 --
reference fixed within a segment, segments joined by
the measured offset between adjacent references
Stitching two segments by the relative dv/v between their references is the
adjacent-pair case of the system measure_inversion already solves over all
block pairs, so the reference axis is one continuum -- global reference,
segment references joined pairwise, fully coupled inversion -- not a menu.
The section now says that.
Also retires the three remaining assertions of the old claim: the fig_reference
plot title, the measure_stretching_moving docstring (now states plainly that it
returns the uncumulated increment and that James 2017 sums these), and the
fig:params(c) caption. demo_7_reference.png regenerated.
references.bib: add Rivet2014, SensSchonfelder2014 (metadata read off the
fetched PDF and its bibliography, not guessed).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two things landed this week that needed to go into the manuscript: the
physical dv/v sign-convention correction (v0.4.0, #36) and a real-archive
validation against Clements & Denolle (2022) at three CI stations.
1-2. Sign convention (methods + boxed definition, discussion)
Boxed definition where dv/v is first introduced (dv/v = -eps/(1+eps), with
the 0.17% first-order bias at landslide-scale changes). Methods states all
seven estimators return physical dv/v as of v0.4.0 and points at
tests/test_sign_convention.py. New Discussion item, "Validate againstsomething you did not generate": the honest cautionary story -- generator
and estimators agreed with each other before the fix, so every synthetic
test passed, while real-archive dv/v anticorrelated with CD2022 and seasonal
hydrology (r=-0.69,-0.45,-0.40) until ground-truthing through the exact call
path caught it.
3-4. Real-archive validation (results) + figures
Comparison methodology (CD2022's trailing-90-day product lags a centered
daily series by ~45 days; matched by applying the same trailing mean,
comparing demeaned, excluding a 150-day burn-in) and headline numbers
(CI.LJR r=0.990, CI.ARV 0.66-0.92, CI.RXH 0.68). Three figures from
paper/figures/gate1/: station-by-station validation (caption is explicitthat its own annotated r is a different, unmatched-smoothing comparison from
the headline number -- I checked this against the actual image before
writing the caption, not just the prompt), the CCF interferograms explaining
why validation quality differs by station, and an optional supplement on
ensemble warm-up honesty.
5. Consistency sweep -- found two real bugs, not just wording
epsilonwith "the recovered dv/v" -- the pre-fix convention. Fixed there and in
the Approach A/B aggregation formulas.
the pre-fix formula (
t/(1+dv/v), division) instead of what the codeactually does now (
t*(1+dv/v), multiplication). Fixed.Flagging, not silently changing
Every one of the paper's 15 synthetic demo figures (
demo_1throughdemo_15) predates the sign fix -- last content-committed 2026-07-20 through2026-08-03, the fix landed 2026-08-09 (verified via
git logper figure).The code change is not a pure sign negation (
impose_dvvwent fromt/(1+dvv)tot*(1+dvv), a different nonlinear map), so I can't justmentally flip a sign and call it correct -- regenerating is the only way to
know which figures/numbers actually change and by how much, especially at
the paper's own larger-magnitude tests (the ±5% sweep, the 4% landslide
scenario) where the boxed convention's own math says the nonlinear term is
not negligible. Not attempted in this PR; flagging for a dedicated pass.
Test plan
citations from issue Dangling citation keys @lobkis01 and @poupinet84 have no matching bib entry #30)
content before writing captions