diff --git a/.claude/skills/codameter-advisor/SKILL.md b/.claude/skills/codameter-advisor/SKILL.md index 153494e..98c5ef5 100644 --- a/.claude/skills/codameter-advisor/SKILL.md +++ b/.claude/skills/codameter-advisor/SKILL.md @@ -10,12 +10,12 @@ description: > glacier / geothermal site," or wants their parameter choices adapted to a specific monitoring use case. The skill is an orchestrator: it elicits the user's use case, maps it to a recommended processing-choice set from the - literature survey (codameter.use_cases), then proves the recommendation by - running the real synthetic engine live, quantifying the bias and error-bar cost + literature survey (codameter.use_cases), then assesses the recommendation conditionally by + running the real synthetic engine live, quantifying the recovery error and availability of the recommended versus the user's current choices on a matched synthetic with known ground truth (codameter.golden + codameter.deviations). It never invents parameters from memory; every recommendation is grounded in - literature/best_practices.md and validated numerically. Also use it to add or + literature/best_practices.md and checked on the stated synthetic scenario. Also use it to add or regenerate golden synthetic datasets. Do not use it to review a manuscript (that is pre-submission-reviewer). --- @@ -52,7 +52,7 @@ So you split the work into four steps and wire them together: 1. **Elicit** the use case and the user's current choices. 2. **Map** to a recommended config from `codameter.use_cases`. 3. **Validate** live: run the recommended and the user's config on a matched - synthetic, report the bias and error-bar difference. + synthetic, report the recovery error and availability. 4. **Report** the config, the rationale with citations, and a reproducible snippet. You run the Python through `pixi run python` (the default pixi env has codameter @@ -97,20 +97,24 @@ matter most for this use case. ## STEP 3: VALIDATE LIVE -Follow `references/validation_loop.md`. Synthesize a matched scenario (reuse a -golden case when the application maps to one, else `codameter.golden.generate`), -then run `codameter.deviations.run_pipeline` for the recommended config and for +Follow `references/validation_loop.md`. Build a public development scenario with `codameter.golden.advisory_case`. +This supports all six applications independently of the evaluation corpus. +Run `codameter.golden.recover` for the recommended config and for the user's current or a deliberately naive config. Report: - the RMS error against the known truth for each config, - the difference in the recovered signal (for a transient, the recovered drop), - for the volcano-style factorial, the first-order variance attribution from `codameter.deviations.multiverse` (which choice controls the answer), -- optionally the marginal measurement covariance `C_d` from +- optionally the constructed single-member covariance `C_d` from `codameter.uq_bayes.bayes_dvv_from_ccfs`. -State the numbers you actually got. If the user's choice is within noise of the -recommendation, say so; do not manufacture a difference. +State the numbers you actually got, including availability on fixed support. +A single seeded RMS comparison cannot establish statistical equivalence. +Report which elicited properties the scenario represents and which it omits. +Only the six config axes are executable overrides; site geometry, forcing, +noise and gaps require explicit scenario construction. Do not imply they were +modeled merely because the user supplied them. ## STEP 4: REPORT @@ -126,9 +130,8 @@ caveat that matters most for this use case (the `key_rule`). See `references/golden_datasets.md`. The corpus lives in `tests/data/golden/manifest.json` (recipes plus expected metrics); arrays are regenerated from seeds on demand and cached under `tests/data/golden/cache/` -(gitignored). To add a case, append a recipe to `codameter.golden.CASES`, then -run `pixi run golden` to refresh the manifest, and `pixi run -e test pytest -tests/test_golden.py` to lock it in. Never commit the `.npz` cache. +(gitignored). For deliberate corpus changes, follow `references/golden_datasets.md`. +Do not refresh thresholds merely to make a failing check pass. Never commit the `.npz` cache. --- diff --git a/.claude/skills/codameter-advisor/references/golden_datasets.md b/.claude/skills/codameter-advisor/references/golden_datasets.md index 202d882..d770f77 100644 --- a/.claude/skills/codameter-advisor/references/golden_datasets.md +++ b/.claude/skills/codameter-advisor/references/golden_datasets.md @@ -1,8 +1,10 @@ # Golden datasets Seeded synthetic CCF suites with known ground-truth dv/v(t), organised as a -**graded benchmark**: 30 cases, 10 per difficulty grade, spanning the monitoring -applications. Two consumers: the pytest regression oracle +**graded template family**: 30 templates, 10 per difficulty grade. +The checkout exposes three public cases, one per grade. A separately +provisioned corpus supplies private cases. Public examples are development +checks; no completed external-model evaluation is claimed. Two consumers: the pytest regression oracle (`tests/test_golden.py`) and this advisor's live validation. ## Layout @@ -27,11 +29,12 @@ earthquake/fault, landslide, groundwater, cryosphere, geothermal). - **medium** (split `validation`): a transient coseismic-style drop with logarithmic partial healing, plus more measurement noise (SNR 3-5). - **hard** (split `test`): a **multi-channel** (4-channel) *and* - **depth/frequency-dependent** problem. A shallow (high-frequency) layer carries + **frequency-component selection** problem. A shallow (high-frequency) layer carries a coseismic drop-and-heal plus a full hydrological seasonal cycle; a deep (low-frequency) layer carries a long-term trend. Each case targets one depth - (`target: shallow|deep`), so the measurement **band selects the depth** and must - match the target. Low SNR (2-4) with waveform decorrelation; channels are + (`target: shallow|deep`), so the measurement band selects the imposed component and must + match the target. This separated-band surrogate does not validate physical + depth resolution or kernels. Low SNR (2-4) with waveform decorrelation; channels are measured independently and aggregated (`golden.recover`). The benchmark therefore grades estimator, reference, stacking, aggregation *and* @@ -51,9 +54,9 @@ for c in m['cases']: ## Add or change a case -1. Append a recipe dict to `codameter.golden.CASES` (see the docstring there for - the fields). Reuse the synthesis geometry from `codameter.use_cases` via the - `use_case` key; only add a new ground-truth generator in `golden.TRUTH` if no +1. Append a recipe dict to the explicit public recipe source or private corpus builder, as appropriate. + `CASES` is populated when the module loads; it is not a persistent registry. Reuse the synthesis geometry from `codameter.use_cases` via the + `use_case` key; only add a new ground-truth generator in `golden.MOTIF` if no existing one fits. 2. Regenerate the oracle: `pixi run golden`. Review the printed RMS values; they should be small for a recovery case and a stable non-zero value for an @@ -75,3 +78,17 @@ The same cases are exposed as a FrugalMind benchmark through regression vs truth). Export with `pixi run frugalmind-export`; the drop-in suite is in `integrations/frugalmind/`. Adding or changing a golden case updates the FrugalMind rows automatically, since both read `golden.CASES`. + +## Evaluation limits + +Public templates and application defaults share construction assumptions. +Hidden amplitudes do not establish a holdout of waveform physics. Difficulty +and split are confounded in the current template family. Frozen RMS tolerances +are regression tolerances, not scientific accuracy requirements. + +`observed()` removes truth keys from a dictionary; it is not a sandbox. +An evaluated agent must not access recipe files, truth caches, scorer metadata, +or generator routes that reconstruct the answer. Process and filesystem +isolation remain work for the evaluation harness. Scorer support is fixed per +case; missing predictions are scored as null change and availability is reported. +No model transcripts or validated agent-performance claims accompany this corpus. diff --git a/.claude/skills/codameter-advisor/references/report_format.md b/.claude/skills/codameter-advisor/references/report_format.md index 0d90725..1272eec 100644 --- a/.claude/skills/codameter-advisor/references/report_format.md +++ b/.claude/skills/codameter-advisor/references/report_format.md @@ -24,25 +24,24 @@ difference or invent one that is not there. 3. **Why**: one line per axis, each with its driver and a citation from `USE_CASES[key]`. Name the one or two axes that matter most for this use case. -4. **Validation**: the table from Step 3: +4. **Validation**: report measured RMS, fixed-support availability, and the + scenario recipe from Step 3. The following values illustrate formatting only: | Config | RMS vs truth | Recovered signal | | --- | --- | --- | | recommended | 0.024 % | drop -0.40 % (true -0.40 %) | | user / naive | 0.31 % | drop -0.18 % | - State the ratio and what it means in one sentence. If a factorial was run, add + State the difference and availability. Do not infer equivalence from one seed. If a factorial was run, add the top variance-driving axis. 5. **Reproduce**: a short snippet the user can paste: ```python from codameter import use_cases as uc, golden - from codameter.deviations import run_pipeline key = "volcano" - d = golden.generate(golden.MAINSTREAM_BY_USE_CASE[key]) - dvv, valid = run_pipeline(d["ccfs"], d["t"], d["fs"], - uc.recommend(key), eps_max=uc.eps_max(key)) + d = golden.advisory_case(key, seed=101) + dvv, valid = golden.recover(d, uc.recommend(key), uc.eps_max(key)) ``` 6. **One caveat**: the `key_rule` for this use case, verbatim in substance (for diff --git a/.claude/skills/codameter-advisor/references/validation_loop.md b/.claude/skills/codameter-advisor/references/validation_loop.md index 17698f9..ec12835 100644 --- a/.claude/skills/codameter-advisor/references/validation_loop.md +++ b/.claude/skills/codameter-advisor/references/validation_loop.md @@ -1,101 +1,77 @@ -# Live validation +# Live synthetic assessment -This is the step that makes the advice more than an opinion. Run the recommended -config and a comparison config on a matched synthetic with known ground truth, -and report the difference in bias and error bar. The truth is known exactly, so -every difference is an artifact of the processing choice, not of nature. +Use public development scenarios for advice. Synthetic recovery measures +performance conditional on the imposed truth, waveform, noise, and choices. +It does not prove a recommendation for field observations. -## The primitives +## Recommended versus comparison -- `codameter.golden.generate(case_id)` returns `{ccfs, t, days, truth, fs, ...}` - for a seeded case. `codameter.golden.MAINSTREAM_BY_USE_CASE[use_case]` gives a matched - (easy-grade) case id for an application. -- `codameter.deviations.run_pipeline(ccfs, t, fs, cfg, eps_max=...)` returns - `(dvv, valid)` for one config. -- `codameter.golden._rms(dvv, truth, days, valid)` is the baseline-aligned RMS - error (removes the unobservable DC offset of a relative measurement). -- `codameter.deviations.multiverse(...)` returns the first-order variance - attribution (volcano synthetic; use it for the "which choice controls the - answer" statement). -- `codameter.uq_bayes.bayes_dvv_from_ccfs(ccfs, t, fs, truth=truth, days=days)` - returns `(BayesResult, EnsembleRun)`; `BayesResult.Cd` is the marginal - measurement covariance for a downstream inversion. +`golden.advisory_case` builds a seasonal example for every application. +It does not depend on `MAINSTREAM_BY_USE_CASE` or private cases. +The returned recipe records the seed, duration, application, and noise. +Application defaults share assumptions with the generator. This is a +consistency check, not an independent generalization benchmark. -## Recommended vs comparison, on a matched synthetic - -Fill `USER_CFG` with the user's current choices (or a deliberately naive config -if they have none). Run: - -```bash -pixi run python - <<'PY' +```python +import numpy as np from codameter import use_cases as uc, golden -from codameter.deviations import run_pipeline - -USE_CASE = "volcano" # from Step 1 -USER_CFG = {"reference": "moving"} # the user's current choice(s), as overrides - -key = uc.resolve(USE_CASE) -d = golden.generate(golden.MAINSTREAM_BY_USE_CASE[key]) -eps = uc.eps_max(key) +key = uc.resolve("volcano") +user_overrides = {"reference": "moving"} +d = golden.advisory_case(key, seed=101) rec = uc.recommend(key) -usr = uc.recommend(key, **USER_CFG) - -for label, cfg in [("recommended", rec), ("user/naive", usr)]: - dvv, valid = run_pipeline(d["ccfs"], d["t"], d["fs"], cfg, eps_max=eps) - rms = golden._rms(dvv, d["truth"], d["days"], valid) - print(f"{label:<12} {cfg}") - print(f"{'':<12} RMS vs truth = {rms*100:.4f} % (valid epochs {int(valid.sum())})") -PY -``` - -Report the two RMS values and the ratio. If the user's config is within ~20 % of -the recommended RMS, tell them their choice is fine; do not invent a penalty. - -## Which choice controls the answer (volcano factorial) - -For the ranking of axes by impact, run the one-at-a-time sweep or the multiverse: - -```bash -pixi run python - <<'PY' -from codameter.deviations import multiverse -mv = multiverse(years=1.5, cadence=4) -print("pipelines:", mv["n_pipelines"]) -for axis, frac in sorted(mv["sobol_rms"].items(), key=lambda kv: -(kv[1] or 0)): - print(f" {axis:<11} first-order variance share of RMS = {frac:.2f}") -PY -``` - -`multiverse` is wired to the volcano truth and geometry. For other applications, -report the OAT contrast from the recommended-vs-comparison run above rather than -claiming a full factorial you did not run. - -## Optional: the marginal covariance C_d - -For a user heading into a depth or stress inversion, show that the honest error -bar comes from marginalising the processing choice: - -```bash -pixi run python - <<'PY' -from codameter import golden -from codameter.uq_bayes import bayes_dvv_from_ccfs -d = golden.generate("easy-volcano-01") -res, ens = bayes_dvv_from_ccfs(d["ccfs"], d["t"], d["fs"], - truth=d["truth"], days=d["days"], cadence=4) -import numpy as np -print("posterior median dv/v std:", float(np.nanmedian(np.sqrt(np.diag(res.Cd))))*100, "%") -PY +usr = uc.recommend(key, **user_overrides) +eps = uc.eps_max(key) +support = golden.scoring_support(d, rec, eps) +print("scenario:", d["recipe"]) +for label, cfg in [("recommended", rec), ("comparison", usr)]: + dvv, valid = golden.recover(d, cfg, eps) + prediction = np.where(valid, dvv, np.nan) + rms, availability = golden.rms_on_support(prediction, d["truth"], **support) + print(label, cfg, "RMS [%]", rms * 100, "availability", availability) ``` -This is slower (it runs an ensemble of pipelines plus a Gibbs sampler); only run -it when the user cares about the propagated uncertainty, and say it is running. - -## Reading the numbers honestly - -- A lower RMS is better recovery; state the percentage, not an adjective. -- A `moving` reference erases the slow trend, so on a trend case it shows a large - RMS by design. That is the point, not a bug. -- Harder cases (medium = transient + noise; hard = multi-channel composite) - are in the golden manifest; pull one with `golden.generate("--")` - when the user's situation is noisier or more complex than a clean seasonal one. - Ids are in `golden.CASES_BY_ID`. +`recover` measures each channel before averaging multi-channel cases. +Both configurations use the reference configuration's fixed epochs and datum. +Missing predictions on that support count as zero baseline-relative change. +Report availability separately. Selective abstention can still improve a poor +prediction; the score is not evidence of complete temporal recovery. +A non-finite RMS means the comparison lacks a usable datum. + +For a named public evaluation case, inspect `golden.CASES_BY_ID` first. +Apply the recipe's `config` overrides before creating the reference config. +A hard groundwater case targets a particular frequency component; its band +is not the generic groundwater default. Never open private evaluation data +for routine advice or display scorer truth to an evaluated agent. + +## Interpret the comparison + +Report RMS in percent, the difference, and both availabilities. +Do not call choices equivalent because their RMS values differ by 20 percent. +Repeated independent waveform/noise realizations are needed to quantify the +uncertainty of that difference. Record all seeds and settings when repeating. +The default example is seasonal; transient recovery requires a stated +transient scenario, not a claim inferred from the seasonal run. +A trailing reference without accumulation measures a different temporal +quantity. Label that comparison as an ablation. + +The six pipeline axes are executable overrides. Other elicited properties +are context until explicitly encoded in the generator. State unmodeled +geometry, target depth, forcings, SNR, artifacts, and gaps. + +## Optional factorial and covariance + +`codameter.deviations.multiverse` uses the volcano scenario. Its sensitivity +ranking is conditional on that waveform and sampled configuration menu. +Do not report it as an application-independent ranking or an attribution +across independent field observations. + +`bayes_dvv_from_ccfs` accepts a complete daily CCF grid. It returns a model +posterior and a separately constructed single-member covariance `Cd`. +`mu_cov` describes the combined estimate under the conditional-independence +model. Neither object automatically captures shared artifacts. The locked +calibration reports poor credible-band coverage on the combined estimate. +A single-member `Cd` is not a calibrated covariance of that estimate or a +cross-band covariance for depth inversion. Explain these distinctions before +using either object downstream. Report standard deviations in fractional +dv/v or percent explicitly; covariance units are fractional dv/v squared. diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 258df3f..25d843b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -26,5 +26,5 @@ repos: rev: v1.7.0 hooks: - id: mypy - additional_dependencies: [numpy, types-PyYAML] + additional_dependencies: ["numpy<2.5", types-PyYAML] exclude: ^(tests/|examples/|docs/|scripts/) diff --git a/CHANGELOG.md b/CHANGELOG.md index 15aae79..6b238b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,8 +6,144 @@ and this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.ht ## Unreleased +### Added + +- `golden.advisory_case`: public seasonal development examples for all six + applications, independent of private evaluation records. Advisor snippets + use per-channel recovery, fixed scoring support, and report availability. + Conditional synthetic checks no longer claim proof of field performance + or statistical equivalence from one seeded RMS comparison. (AG-01/02/03) + +### Fixed + +- Enlarge the calibration table, preserve nonzero Monte Carlo standard errors, + correct abstract percent formatting, and keep the running title within the + page margin. (FIG-03, FMT-01) + +- Reject non-daily CCF input in the processing ensemble. Already measured + irregular series remain supported by `gibbs_dvv`. Moving-reference and + non-stretching ensemble members now honor the coherence gate. (UQ-05) +- Calibration excludes unavailable member epochs, including invalid floors, + from conditional coverage and reports their availability separately. + The archived 600 locked runs have zero missing fraction; their reported + results are unchanged by this correction. (SCI-05) +- Include use-case synthesis geometry source in golden cache identity. (DET-02) +- Distinguish joint hierarchical fitting from pipeline mixture marginalization + in the manuscript and API. Near-nominal 95% pointwise member coverage does + not establish covariance calibration: 68% intervals overcover, and the + combined estimate's credible band undercovers. Downstream covariance and + shared errors remain unvalidated. (UQ-03/04, INV-01) +- Correct field-data availability and review-adjudication statements to + reflect the missing run provenance and pending author inputs. (REP-02, COMP-01) + +### Added + +- `codameter.calibration`: repeated-realisation coverage calibration of the + Bayesian measurement covariance (`python -m codameter.calibration --n 200 + --scenario clean|shared_source|clock_drift --out ...`): pointwise 68/95 percent coverage + of member errors, credible-band coverage of the combined estimate, width, + bias, RMSE and failures per realisation, with standard errors across + realisations and a predefined acceptance margin. (SCI-05) + +- `codameter.figures`: one driver for every generated paper figure + (`python -m codameter.figures --out literature/figs`). Each figure is + written with a `.npz` sidecar holding every plotted array (and the + generator's result arrays under `data/`) and a `.json` sidecar with the + generator, codameter version, git commit, timestamp, library versions and + an inventory. `paper/build.py --figures` uses it; previously the build ran + only the `synthetic_demo` subset and six of the manuscript's figures had + no generator in the build (2026-09-10 audit, REP-01). The three real-data + figures are documented as external in `literature/figs/SOURCES.md`. + ### Changed (BREAKING) +- **The Bayesian ensemble runs every configuration through the canonical + pipeline** (`deviations.run_pipeline`): `reference` (`fixed`/`moving`) and + `gate` now take effect (they were ignored), stacking happens on the daily + grid and only the output is decimated by `cadence` (a 10-day stack used to + span 27 days at cadence 3), epochs a configuration cannot produce are NaN + and treated as missing, and coherence below `MIN_COHERENCE` gives a + missing floor instead of being clipped to 0.5. `reference="inversion"` is + rejected. Member labels now include stack, reference and gate. (UQ-05) + +- **`gibbs_dvv` builds its smoothness prior on the physical time grid** + (`second_difference_operator`: exactly `[1, -2, 1]` on a regular grid, and + a curvature penalty that scales with the interval across gaps), accepts + missing members (zero precision), and reports `beta_mean` and `n_obs`. + The per-epoch decomposition no longer counts the within-method floor + twice: `method_std**2` is the between-configuration variance of the + offset-corrected members minus the calibrated floor, floored at zero, and + `total_std**2` is their sum. `Cd` is documented as a constructed + measurement covariance that cannot represent an error shared by every + configuration (tested as a documented limitation). (UQ-03, UQ-04, UQ-05) + +- **`weaver_stretching_error` now requires the band width** (`bandwidth_hz`; + or call `weaver_stretching_error_band(cc, (f1, f2), t1, t2)`). It implements + Weaver et al. (2011) eq. 20 with the `sqrt(1-X^2)/(2X)` prefactor and the + spectral timescale `T = sqrt(ln 10) / (pi B)` (band edges at the -10 dB + points of Weaver's Gaussian spectrum; `bandwidth_timescale`). The native + form is exposed as `weaver_rms_dilation(cc, omega_c, t1, t2, T)` and is + tested against Weaver's own numerical example (their eq. 21). The previous + implementation omitted `T`, so its result was not dimensionless and did not + depend on band width, and used `(1-CC^2)/(2CC^2)` for the variance, twice + Weaver's. Found by the 2026-09-10 pre-submission audit (UQ-01). + `ProcessingChoice` gains a `bandwidth_hz` field and `ProcessingPrior` a + `relative_bandwidth` (default 2/3, a one-octave band). In the Bayesian + ensemble the fitted rescale `s` absorbs the constant; only the relative + weights of members in different bands change. + +- **`per_band_marginal_error` no longer adds the spread of the floors as a + "processing-choice" variance.** That term has no probabilistic meaning: a + mixture of zero-mean components with different precisions has marginal + variance `E_c[sigma_c^2]` and no spread term. The processing-choice spread + is now computed only from `conditional_means=` (the estimate each choice + returns on the same data) and is zero otherwise. A `band_bias` is reported + as `bias` and enters `rmse`, not the centred `sd` (`total` is kept as an + alias of `sd`). Found by the 2026-09-10 pre-submission audit (UQ-02). + +- **The golden scorers evaluate on a fixed support.** `frugalmind._gold` now + records per case the epochs where the reference pipeline is valid + (`support`) and the earliest 20% of them (`baseline`); both scorers call + `golden.rms_on_support`, which demeans truth and prediction over that fixed + datum and scores a missing (non-finite) prediction inside the support as + the null prediction. Previously the support and the datum came from the + submission's own finite values, so ten zeros followed by nulls scored 1.0 + on every public case. Export version is `v0.2`; `scorer_spec.config` + carries the rule (`version: 2`). Expected metrics in the manifest are + unchanged (the reference pipeline has no gaps on its own support). Found by + the 2026-09-10 pre-submission audit (EV-01). + +- **`linear_fit` no longer reports zero uncertainty for a parameter on an + active bound.** The covariance keeps the unconstrained curvature and the + new `LinearFitResult.at_bound` flags the parameter (also in `to_dict`). + A one-sided interval needs a truncated-normal treatment. (INV-02) + +- **`global_reference_inversion` checks the pair graph.** Each connected + component gets its own sum-zero datum, a warning is issued when there is + more than one, and an epoch with no pairs is returned as NaN in `dvv` and + `sigma` instead of a spurious zero. `GlobalReferenceSolution` gains + `component` and `n_components`. (INV-02) + +- **The golden cache is exact and versioned.** `golden.generate` keys the + cache on the recipe hash *and* a hash of the package version plus the + synthesis source, stores float64 (the warm route used to return float32, + differing from the cold route at the 1e-7 level), writes atomically, + removes stale files for the case, and returns `recipe_hash` and + `generator_hash` on every route. (DET-02) + +- **`codameter-bench aggregate` refuses incomplete or duplicated input.** + It requires every shard `k` of the declared `N`, each + `(case_id, config_index)` cell exactly once, and one codameter version + across rows (rows now carry `codameter_version`); `--allow-partial` + accepts missing shards only. An `aggregate_manifest.json` records the + inventory. `_read_jsonl_dir` now yields `(shard_name, row)`. (SCALE-02) + +- **`gibbs_dvv` solves the smoothness-prior update in banded form** (the + second-difference normal matrix is pentadiagonal), removing the dense + `T x T` Cholesky per iteration; `solver="dense"` keeps the explicit path + for equivalence tests. The module docstring no longer calls `Cd` the + posterior covariance of `mu`. (SCALE-01, UQ-04 wording) + - **dv/v sign convention is now physical everywhere**: a velocity *increase* is positive; every estimator and `run_pipeline` return `dv/v = -eps / (1 + eps)` where `eps` is the stretch factor (exact at all @@ -22,6 +158,30 @@ and this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.ht that negated codameter output to get physical dv/v must remove that negation. +- **The stretching-family trial-epsilon search now resamples `current`, not + `reference`.** `stretching_cc`, `measure_stretching_trailing`, and + `measure_wts` previously interpolated the *reference* waveform at trial + positions `t/(1+eps)` and held `current` fixed; they now interpolate + *current* at `(1+eps)*t` and hold `reference` fixed, matching the field's + usual convention (the reference is the stable, often multi-day-averaged + anchor; the current trace is the one being tested against it). **The exact + conversion `dv/v = -eps/(1+eps)` is unchanged** — both conventions give + the identical exact map (see the derivation in the PR), so this is not a + second sign-convention flip; it is an internal numerics change with a + small (single-digit-percent) shift in finite-sample results, since a + different (per-day, typically noisier) trace is now the one being + resampled. Added `synthetic_demo.dvv_to_epsilon` (the exact inverse of + `eps_to_dvv`) and `synthetic_demo._stretch_window`, a common + valid-support window shared across the whole epsilon grid so no trial + epsilon is silently extrapolated and every candidate is scored on an + identical sample count (warns and shrinks the window if the requested + one would need extrapolation at the edges of `eps_max`; none of the + packaged `use_cases.py` configs hit this). + `tests/data/golden/manifest.json` regenerated against the new numerics + (`golden.MANIFEST_VERSION` bumped 2 → 3 so stale per-user caches + regenerate); a hidden/private golden corpus built with `private_golden.py` + before this change should be regenerated too. + ### Added - `synthetic_demo.eps_to_dvv`: the exact stretch-to-velocity map. @@ -43,13 +203,14 @@ and this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.ht the estimators whose band usage is that one linear filter (stretching, WCC, DTW, MWCS — the wavelet estimators raise). - **`measure_stretching_trailing`** — vectorized stretching against a trailing - (moving) reference. The stretched sample positions `t/(1+eps)` are + (moving) reference. The stretched sample positions `(1+eps)*t` are data-independent, so the interpolation gather indices/weights are computed once per epsilon and applied to all days at once; trailing references come from a cumulative sum and the band-pass runs once over the whole matrix. `deviations._moving_reference` dispatches to it for the stretching estimator (~3x on the 3-year volcano synthetic, observed 3-4.5x across repeated runs), keeping the generic per-day loop for the other estimators. + (Updated below: the resampled trace is `current`, not `reference`.) ### Changed diff --git a/literature/README.md b/literature/README.md index d946eca..6188f3e 100644 --- a/literature/README.md +++ b/literature/README.md @@ -63,11 +63,15 @@ practice** and the **undocumented choices** that break intercomparability: | `demo_11_multiverse.png` | Full factorial (108 pipelines) | Spread + first-order variance attribution: which choice controls dv/v | | `demo_12_bayes.png` | Bayesian processing-ensemble inversion | Posterior dv/v + time-dependent data covariance C_d (`codameter.uq_bayes`) | -Figures `demo_1`–`demo_9` come from `synthetic_dvv_demo.py`; `demo_10`–`demo_11` -from `python -m codameter.deviations` (the deviation ranking + ultimate -multiverse); `demo_12` from `python -m codameter.uq_bayes` (the Bayesian -measurement model — the *new* best practice that marginalises the processing -choice into a single time-dependent covariance for downstream inversion). +All generated figures come from one driver, `python -m codameter.figures --out +literature/figs`, which also writes a `.npz` (every plotted array) and a `.json` +(generator, version, git commit, inventory) next to each PNG; see +`figs/SOURCES.md`. The builders themselves live in `codameter.synthetic_demo` +(`demo_1`-`demo_9`, `demo_13`-`demo_18`), `codameter.deviations` (`demo_10`, +`demo_11`) and `codameter.uq_bayes` (`demo_12`, the Bayesian measurement model +that marginalises the processing choice into a single time-dependent covariance). +`synthetic_dvv_demo.py` still renders the `synthetic_demo` subset without +sidecars. The three `realdata_*` figures are produced outside this repository. ## How to extend it diff --git a/literature/figs/SOURCES.md b/literature/figs/SOURCES.md new file mode 100644 index 0000000..501f360 --- /dev/null +++ b/literature/figs/SOURCES.md @@ -0,0 +1,31 @@ +# Figure sources + +Every generated figure in this directory is written by one driver, + + python -m codameter.figures --out literature/figs + +which also writes `.npz` (every plotted array plus the generator's +result arrays under `data/`) and `.json` (generator, codameter version, +git commit, timestamp, library versions, axes and array inventory). Numbers +quoted in the manuscript about a figure should be computed from that figure's +sidecar, not re-derived elsewhere. `python -m codameter.figures --list` +prints the registry. `paper/build.py --figures` runs the driver. + +| Figure | Generator | +|---|---| +| `demo_1` to `demo_9`, `demo_13` to `demo_18` | `codameter.synthetic_demo.FIGURES` (one builder each) | +| `demo_10_deviations` | `codameter.deviations.oat_effects` + `fig_deviation_ranking` (slow) | +| `demo_11_multiverse` | `codameter.deviations.multiverse` + `fig_multiverse_full` (slow) | +| `demo_12_bayes` | `codameter.uq_bayes._build_bayes` + `_fig_bayes` (slow) | + +## Produced outside this repository + +`realdata_1_validation.png`, `realdata_2_interferograms.png` and +`realdata_3_warmup.png` come from the noisepy-dvv-cloud Gate 1 run +(CI.LJR / CI.RXH / CI.ARV, 2018-2019; see `paper/data/gate1/README.md`). +Their inputs are the daily ensemble products under `paper/data/gate1/dvv2y/` +(not tracked by git) and the published Clements and Denolle (2022) product +under `paper/data/gate1/legacy_cd2022/`. The comparison script +(`scripts/compare_cd2022.py`) and the figure scripts live in that repository; +the commit they were run at is to be pinned here (audit finding REP-02). +Until then these three figures cannot be regenerated from this checkout. diff --git a/literature/figs/demo_10_deviations.json b/literature/figs/demo_10_deviations.json new file mode 100644 index 0000000..c0510c3 --- /dev/null +++ b/literature/figs/demo_10_deviations.json @@ -0,0 +1,201 @@ +{ + "figure": "demo_10_deviations", + "generator": "codameter.deviations.oat_effects + fig_deviation_ranking", + "codameter_version": "0.4.0", + "git_commit": "7bfdcef47453919afb5ee5e32a0d7979330402e0", + "generated_utc": "2026-09-10T19:07:17+00:00", + "python": "3.12.13", + "numpy": "2.4.3", + "matplotlib": "3.10.9", + "axes": [ + { + "axes": "ax0", + "title": "(a) RMS error of each deviation", + "xlabel": "RMS error vs truth (dv/v, %, log)", + "ylabel": "", + "lines": [ + "best practice (0.032%)" + ], + "images": 0, + "collections": [], + "patches": 12 + }, + { + "axes": "ax1", + "title": "(b) Distortion of the drop", + "xlabel": "drop error (%, symlog)", + "ylabel": "", + "lines": [ + "_child12" + ], + "images": 0, + "collections": [], + "patches": 12 + } + ], + "arrays": [ + "ax0/line0/x", + "ax0/line0/y", + "ax0/patch0/xywh", + "ax0/patch1/xywh", + "ax0/patch10/xywh", + "ax0/patch11/xywh", + "ax0/patch2/xywh", + "ax0/patch3/xywh", + "ax0/patch4/xywh", + "ax0/patch5/xywh", + "ax0/patch6/xywh", + "ax0/patch7/xywh", + "ax0/patch8/xywh", + "ax0/patch9/xywh", + "ax1/line0/x", + "ax1/line0/y", + "ax1/patch0/xywh", + "ax1/patch1/xywh", + "ax1/patch10/xywh", + "ax1/patch11/xywh", + "ax1/patch2/xywh", + "ax1/patch3/xywh", + "ax1/patch4/xywh", + "ax1/patch5/xywh", + "ax1/patch6/xywh", + "ax1/patch7/xywh", + "ax1/patch8/xywh", + "ax1/patch9/xywh" + ], + "oat_rows": [ + { + "axis": "baseline", + "option": "best practice", + "is_best": true, + "rms": 0.0003168436926370666, + "drop_err": 0.00017951251247123878 + }, + { + "axis": "Estimator", + "option": "stretching (TS)", + "is_best": true, + "rms": 0.0003168436926370666, + "drop_err": 0.00017951251247123878 + }, + { + "axis": "Estimator", + "option": "MWCS", + "is_best": false, + "rms": 0.0038544999247035884, + "drop_err": -0.0031678133738542264 + }, + { + "axis": "Estimator", + "option": "WCS", + "is_best": false, + "rms": 0.015437845575104556, + "drop_err": -0.015622735939078099 + }, + { + "axis": "Estimator", + "option": "DTW", + "is_best": false, + "rms": 0.0019010637080520015, + "drop_err": -0.0020390256143288923 + }, + { + "axis": "Frequency band", + "option": "0.4\u20131", + "is_best": true, + "rms": 0.0003168436926370666, + "drop_err": 0.00017951251247123878 + }, + { + "axis": "Frequency band", + "option": "0.8\u20132", + "is_best": false, + "rms": 0.00022192379795304393, + "drop_err": 0.00011883437646301436 + }, + { + "axis": "Frequency band", + "option": "0.2\u20130.5", + "is_best": false, + "rms": 0.0005723467342313203, + "drop_err": -0.00026992542065171904 + }, + { + "axis": "Coda window", + "option": "10\u201330", + "is_best": true, + "rms": 0.0003168436926370666, + "drop_err": 0.00017951251247123878 + }, + { + "axis": "Coda window", + "option": "4\u201314", + "is_best": false, + "rms": 0.0002673549431669386, + "drop_err": 0.0004439333638909552 + }, + { + "axis": "Coda window", + "option": "25\u201345", + "is_best": false, + "rms": 0.0006250252824107874, + "drop_err": -0.00047533302360930514 + }, + { + "axis": "Stack length", + "option": "10", + "is_best": true, + "rms": 0.0003168436926370666, + "drop_err": 0.00017951251247123878 + }, + { + "axis": "Stack length", + "option": "1", + "is_best": false, + "rms": 0.0007901562880647926, + "drop_err": -0.00154359683642415 + }, + { + "axis": "Stack length", + "option": "45", + "is_best": false, + "rms": 0.0005136764602364905, + "drop_err": 0.0006787803991007047 + }, + { + "axis": "Reference scheme", + "option": "fixed", + "is_best": true, + "rms": 0.0003168436926370666, + "drop_err": 0.00017951251247123878 + }, + { + "axis": "Reference scheme", + "option": "moving", + "is_best": false, + "rms": 0.0016412776082229397, + "drop_err": 0.0011609599559004881 + }, + { + "axis": "Reference scheme", + "option": "inversion", + "is_best": true, + "rms": 0.0006509366074710296, + "drop_err": 0.0007229148088323343 + }, + { + "axis": "CC gating", + "option": "True", + "is_best": true, + "rms": 0.0003168436926370666, + "drop_err": 0.00017951251247123878 + }, + { + "axis": "CC gating", + "option": "False", + "is_best": false, + "rms": 0.0003168436926370666, + "drop_err": 0.00017951251247123878 + } + ] +} diff --git a/literature/figs/demo_10_deviations.npz b/literature/figs/demo_10_deviations.npz new file mode 100644 index 0000000..e99bfd8 Binary files /dev/null and b/literature/figs/demo_10_deviations.npz differ diff --git a/literature/figs/demo_10_deviations.png b/literature/figs/demo_10_deviations.png index ee29663..c4dac74 100644 Binary files a/literature/figs/demo_10_deviations.png and b/literature/figs/demo_10_deviations.png differ diff --git a/literature/figs/demo_11_multiverse.json b/literature/figs/demo_11_multiverse.json new file mode 100644 index 0000000..1c6e4f4 --- /dev/null +++ b/literature/figs/demo_11_multiverse.json @@ -0,0 +1,1041 @@ +{ + "figure": "demo_11_multiverse", + "generator": "codameter.deviations.multiverse + fig_multiverse_full", + "codameter_version": "0.4.0", + "git_commit": "7bfdcef47453919afb5ee5e32a0d7979330402e0", + "generated_utc": "2026-09-10T19:19:09+00:00", + "python": "3.12.13", + "numpy": "2.4.3", + "matplotlib": "3.10.9", + "axes": [ + { + "axes": "ax0", + "title": "(a) 108 pipelines (colour = RMS error)", + "xlabel": "time (years)", + "ylabel": "dv/v (%)", + "lines": [ + "_child0", + "_child1", + "_child2", + "_child3", + "_child4", + "_child5", + "_child6", + "_child7", + "_child8", + "_child9", + "_child10", + "_child11", + "_child12", + "_child13", + "_child14", + "_child15", + "_child16", + "_child17", + "_child18", + "_child19", + "_child20", + "_child21", + "_child22", + "_child23", + "_child24", + "_child25", + "_child26", + "_child27", + "_child28", + "_child29", + "_child30", + "_child31", + "_child32", + "_child33", + "_child34", + "_child35", + "_child36", + "_child37", + "_child38", + "_child39", + "_child40", + "_child41", + "_child42", + "_child43", + "_child44", + "_child45", + "_child46", + "_child47", + "_child48", + "_child49", + "_child50", + "_child51", + "_child52", + "_child53", + "_child54", + "_child55", + "_child56", + "_child57", + "_child58", + "_child59", + "_child60", + "_child61", + "_child62", + "_child63", + "_child64", + "_child65", + "_child66", + "_child67", + "_child68", + "_child69", + "_child70", + "_child71", + "_child72", + "_child73", + "_child74", + "_child75", + "_child76", + "_child77", + "_child78", + "_child79", + "_child80", + "_child81", + "_child82", + "_child83", + "_child84", + "_child85", + "_child86", + "_child87", + "_child88", + "_child89", + "_child90", + "_child91", + "_child92", + "_child93", + "_child94", + "_child95", + "_child96", + "_child97", + "_child98", + "_child99", + "_child100", + "_child101", + "_child102", + "_child103", + "_child104", + "_child105", + "_child106", + "_child107", + "median", + "ground truth", + "_child111" + ], + "images": 0, + "collections": [ + "10\u201390% across pipelines" + ], + "patches": 0 + }, + { + "axes": "ax1", + "title": "(b) Which choice controls the answer", + "xlabel": "", + "ylabel": "first-order variance fraction", + "lines": [], + "images": 0, + "collections": [], + "patches": 10 + }, + { + "axes": "ax2", + "title": "", + "xlabel": "", + "ylabel": "RMS vs truth (dv/v, fraction)", + "lines": [], + "images": 0, + "collections": [ + "_child0", + "_child1" + ], + "patches": 0 + } + ], + "arrays": [ + "ax0/collection0/offsets", + "ax0/collection0/path_lengths", + "ax0/collection0/vertices", + "ax0/line0/x", + "ax0/line0/y", + "ax0/line1/x", + "ax0/line1/y", + "ax0/line10/x", + "ax0/line10/y", + "ax0/line100/x", + "ax0/line100/y", + "ax0/line101/x", + "ax0/line101/y", + "ax0/line102/x", + "ax0/line102/y", + "ax0/line103/x", + "ax0/line103/y", + "ax0/line104/x", + "ax0/line104/y", + "ax0/line105/x", + "ax0/line105/y", + "ax0/line106/x", + "ax0/line106/y", + "ax0/line107/x", + "ax0/line107/y", + "ax0/line108/x", + "ax0/line108/y", + "ax0/line109/x", + "ax0/line109/y", + "ax0/line11/x", + "ax0/line11/y", + "ax0/line110/x", + "ax0/line110/y", + "ax0/line12/x", + "ax0/line12/y", + "ax0/line13/x", + "ax0/line13/y", + "ax0/line14/x", + "ax0/line14/y", + "ax0/line15/x", + "ax0/line15/y", + "ax0/line16/x", + "ax0/line16/y", + "ax0/line17/x", + "ax0/line17/y", + "ax0/line18/x", + "ax0/line18/y", + "ax0/line19/x", + "ax0/line19/y", + "ax0/line2/x", + "ax0/line2/y", + "ax0/line20/x", + "ax0/line20/y", + "ax0/line21/x", + "ax0/line21/y", + "ax0/line22/x", + "ax0/line22/y", + "ax0/line23/x", + "ax0/line23/y", + "ax0/line24/x", + "ax0/line24/y", + "ax0/line25/x", + "ax0/line25/y", + "ax0/line26/x", + "ax0/line26/y", + "ax0/line27/x", + "ax0/line27/y", + "ax0/line28/x", + "ax0/line28/y", + "ax0/line29/x", + "ax0/line29/y", + "ax0/line3/x", + "ax0/line3/y", + "ax0/line30/x", + "ax0/line30/y", + "ax0/line31/x", + "ax0/line31/y", + "ax0/line32/x", + "ax0/line32/y", + "ax0/line33/x", + "ax0/line33/y", + "ax0/line34/x", + "ax0/line34/y", + "ax0/line35/x", + "ax0/line35/y", + "ax0/line36/x", + "ax0/line36/y", + "ax0/line37/x", + "ax0/line37/y", + "ax0/line38/x", + "ax0/line38/y", + "ax0/line39/x", + "ax0/line39/y", + "ax0/line4/x", + "ax0/line4/y", + "ax0/line40/x", + "ax0/line40/y", + "ax0/line41/x", + "ax0/line41/y", + "ax0/line42/x", + "ax0/line42/y", + "ax0/line43/x", + "ax0/line43/y", + "ax0/line44/x", + "ax0/line44/y", + "ax0/line45/x", + "ax0/line45/y", + "ax0/line46/x", + "ax0/line46/y", + "ax0/line47/x", + "ax0/line47/y", + "ax0/line48/x", + "ax0/line48/y", + "ax0/line49/x", + "ax0/line49/y", + "ax0/line5/x", + "ax0/line5/y", + "ax0/line50/x", + "ax0/line50/y", + "ax0/line51/x", + "ax0/line51/y", + "ax0/line52/x", + "ax0/line52/y", + "ax0/line53/x", + "ax0/line53/y", + "ax0/line54/x", + "ax0/line54/y", + "ax0/line55/x", + "ax0/line55/y", + "ax0/line56/x", + "ax0/line56/y", + "ax0/line57/x", + "ax0/line57/y", + "ax0/line58/x", + "ax0/line58/y", + "ax0/line59/x", + "ax0/line59/y", + "ax0/line6/x", + "ax0/line6/y", + "ax0/line60/x", + "ax0/line60/y", + "ax0/line61/x", + "ax0/line61/y", + "ax0/line62/x", + "ax0/line62/y", + "ax0/line63/x", + "ax0/line63/y", + "ax0/line64/x", + "ax0/line64/y", + "ax0/line65/x", + "ax0/line65/y", + "ax0/line66/x", + "ax0/line66/y", + "ax0/line67/x", + "ax0/line67/y", + "ax0/line68/x", + "ax0/line68/y", + "ax0/line69/x", + "ax0/line69/y", + "ax0/line7/x", + "ax0/line7/y", + "ax0/line70/x", + "ax0/line70/y", + "ax0/line71/x", + "ax0/line71/y", + "ax0/line72/x", + "ax0/line72/y", + "ax0/line73/x", + "ax0/line73/y", + "ax0/line74/x", + "ax0/line74/y", + "ax0/line75/x", + "ax0/line75/y", + "ax0/line76/x", + "ax0/line76/y", + "ax0/line77/x", + "ax0/line77/y", + "ax0/line78/x", + "ax0/line78/y", + "ax0/line79/x", + "ax0/line79/y", + "ax0/line8/x", + "ax0/line8/y", + "ax0/line80/x", + "ax0/line80/y", + "ax0/line81/x", + "ax0/line81/y", + "ax0/line82/x", + "ax0/line82/y", + "ax0/line83/x", + "ax0/line83/y", + "ax0/line84/x", + "ax0/line84/y", + "ax0/line85/x", + "ax0/line85/y", + "ax0/line86/x", + "ax0/line86/y", + "ax0/line87/x", + "ax0/line87/y", + "ax0/line88/x", + "ax0/line88/y", + "ax0/line89/x", + "ax0/line89/y", + "ax0/line9/x", + "ax0/line9/y", + "ax0/line90/x", + "ax0/line90/y", + "ax0/line91/x", + "ax0/line91/y", + "ax0/line92/x", + "ax0/line92/y", + "ax0/line93/x", + "ax0/line93/y", + "ax0/line94/x", + "ax0/line94/y", + "ax0/line95/x", + "ax0/line95/y", + "ax0/line96/x", + "ax0/line96/y", + "ax0/line97/x", + "ax0/line97/y", + "ax0/line98/x", + "ax0/line98/y", + "ax0/line99/x", + "ax0/line99/y", + "ax1/patch0/xywh", + "ax1/patch1/xywh", + "ax1/patch2/xywh", + "ax1/patch3/xywh", + "ax1/patch4/xywh", + "ax1/patch5/xywh", + "ax1/patch6/xywh", + "ax1/patch7/xywh", + "ax1/patch8/xywh", + "ax1/patch9/xywh", + "ax2/collection0/offsets", + "ax2/collection1/offsets", + "ax2/collection1/path_lengths", + "ax2/collection1/vertices", + "data/curves", + "data/drop", + "data/rms" + ], + "multiverse": { + "days": [ + 0, + 3, + 6, + 9, + 12, + 15, + 18, + 21, + 24, + 27, + 30, + 33, + 36, + 39, + 42, + 45, + 48, + 51, + 54, + 57, + 60, + 63, + 66, + 69, + 72, + 75, + 78, + 81, + 84, + 87, + 90, + 93, + 96, + 99, + 102, + 105, + 108, + 111, + 114, + 117, + 120, + 123, + 126, + 129, + 132, + 135, + 138, + 141, + 144, + 147, + 150, + 153, + 156, + 159, + 162, + 165, + 168, + 171, + 174, + 177, + 180, + 183, + 186, + 189, + 192, + 195, + 198, + 201, + 204, + 207, + 210, + 213, + 216, + 219, + 222, + 225, + 228, + 231, + 234, + 237, + 240, + 243, + 246, + 249, + 252, + 255, + 258, + 261, + 264, + 267, + 270, + 273, + 276, + 279, + 282, + 285, + 288, + 291, + 294, + 297, + 300, + 303, + 306, + 309, + 312, + 315, + 318, + 321, + 324, + 327, + 330, + 333, + 336, + 339, + 342, + 345, + 348, + 351, + 354, + 357, + 360, + 363, + 366, + 369, + 372, + 375, + 378, + 381, + 384, + 387, + 390, + 393, + 396, + 399, + 402, + 405, + 408, + 411, + 414, + 417, + 420, + 423, + 426, + 429, + 432, + 435, + 438, + 441, + 444, + 447, + 450, + 453, + 456, + 459, + 462, + 465, + 468, + 471, + 474, + 477, + 480, + 483, + 486, + 489, + 492, + 495, + 498, + 501, + 504, + 507, + 510, + 513, + 516, + 519, + 522, + 525, + 528, + 531, + 534, + 537, + 540, + 543, + 546, + 549, + 552, + 555, + 558, + 561, + 564, + 567, + 570, + 573, + 576, + 579, + 582, + 585, + 588, + 591, + 594, + 597, + 600, + 603, + 606, + 609, + 612, + 615, + 618, + 621, + 624, + 627, + 630, + 633, + 636, + 639, + 642, + 645, + 648, + 651, + 654, + 657, + 660, + 663, + 666, + 669, + 672, + 675, + 678, + 681, + 684, + 687, + 690, + 693, + 696, + 699, + 702, + 705, + 708, + 711, + 714, + 717, + 720, + 723, + 726, + 729, + 732, + 735, + 738, + 741, + 744, + 747, + 750, + 753, + 756, + 759, + 762, + 765, + 768, + 771, + 774, + 777, + 780, + 783, + 786, + 789, + 792, + 795, + 798, + 801, + 804, + 807, + 810, + 813, + 816, + 819, + 822, + 825, + 828, + 831, + 834, + 837, + 840, + 843, + 846, + 849, + 852, + 855, + 858, + 861, + 864, + 867, + 870, + 873, + 876, + 879, + 882, + 885, + 888, + 891, + 894, + 897, + 900, + 903, + 906, + 909, + 912 + ], + "truth": [ + -0.0004292007616459458, + -0.00041539850840606235, + -0.00040049016548914526, + -0.00038451542962945906, + -0.0003675168370664706, + -0.00034953965028277815, + -0.00033063173748281935, + -0.00031084344513327393, + -0.000290227463904549, + -0.0002688386883703071, + -0.0002467340708386187, + -0.00022397246970394557, + -0.00020061449272375045, + -0.00017672233563704385, + -0.0001523596165545817, + -0.0001275912065616864, + -0.00010248305698474766, + -7.71020237813447e-05, + -5.151568952158939e-05, + -2.5792183434704183e-05, + 0.0, + 2.5792183434704183e-05, + 5.151568952158939e-05, + 7.71020237813447e-05, + 0.00010248305698474766, + 0.0001275912065616864, + 0.0001523596165545817, + 0.00017672233563704385, + 0.00020061449272375045, + 0.00022397246970394557, + 0.0002467340708386187, + 0.0002688386883703071, + 0.000290227463904549, + 0.00031084344513327393, + 0.00033063173748281935, + 0.00034953965028277815, + 0.0003675168370664706, + 0.00038451542962945906, + 0.00040049016548914526, + 0.00041539850840606235, + 0.0004292007616459458, + 0.00044186017368099886, + 0.00045334303604889926, + 0.00046361877310897685, + 0.000472660023456566, + 0.00048044271277874887, + 0.00048694611795749624, + 0.0004921529222495165, + 0.0004960492613958846, + 0.0004986247605386725, + 0.0004998725618462867, + 0.0004997893427739478, + 0.0004983753249106964, + 0.0004956342733893628, + 0.0004915734868610749, + 0.00048620377806099844, + 0.00047953944501705653, + 0.0004715982329782933, + 0.00046240128716425443, + 0.00045197309646120056, + 0.00044034142821507377, + 0.00042753725429484665, + 0.00041359466862312484, + 0.00039855079639359713, + 0.0003824456952170613, + 0.0003653222484592458, + 0.00034722605105443814, + 0.00032820528809896903, + 0.00030831060654781914, + 0.00028759498035598873, + 0.0002661135694237198, + 0.00024392357272115596, + 0.00022108407598353603, + 0.00019765589438245753, + 0.0001737014105921387, + 0.0001492844086818601, + 0.0001244699042768833, + 9.932397144008557e-05, + 7.391356673526524e-05, + 4.830635094060155e-05, + 2.2570508886985965e-05, + -3.225432099052575e-06, + -2.9012784664390174e-05, + -5.472288432445778e-05, + -8.028727229749689e-05, + -0.00010563787779108964, + -0.0001307071992555781, + -0.00015542848412175182, + -0.0001797359065442116, + -0.0002035647426771258, + -0.00022685154301567211, + -0.000249534301344266, + -0.00027155261984171587, + -0.0002928478699036754, + -0.0003133633482541651, + -0.0003330444279304885, + -0.0003518387037395064, + -0.00036969613179796206, + -0.00038656916278530137, + -0.0004024128685541726, + -0.0004171850617614769, + -0.0004308464082014261, + -0.00044336053154149654, + -0.00045469411018239625, + -0.00046481696598413475, + -0.0004737021446219423, + -0.0004813259873580744, + -0.0004876681940383919, + -0.0004927118771459762, + -0.0004964436067678482, + -0.0004988534463550584, + -0.0004999349791809296, + -0.0004996853254269984, + -0.0004981051498511649, + -0.0004951986600176279, + -0.000490973595093323, + -0.0004854412052406918, + -0.000478616221661656, + -0.00047051681737255986, + -0.0004611645588145272, + -0.00045058434842807846, + -0.0004388043583449196, + -0.00042585595537345943, + -0.0004117736174778003, + -0.0003965948419725922, + -0.0003803600456782052, + -0.00036311245730207714, + -0.00034489800233279433, + -0.00032576518075340107, + -0.00030576493789955265, + -0.00028495052880638124, + -0.0002633773764052771, + -0.0002411029239481763, + -0.0002181864820522962, + -0.00019468907077260076, + -0.00017067325712251808, + -0.00014620298847553868, + -0.00012134342229129771, + -9.616075261954741e-05, + -7.0722033843971e-05, + -4.509500213517257e-05, + -1.9347895088263447e-05, + 6.450729974709827e-06, + 3.22321785536809e-05, + 5.792780188473924e-05, + 8.346917973252943e-05, + 0.00010878830257414086, + 0.00013381775268938323, + 0.00015849088367526394, + 0.0001827419979066559, + 0.00020650652147064037, + 0.00022972117610872301, + 0.0002523241477090763, + 0.0002742552509001803, + 0.00029545608930757824, + 0.0003158702110470373, + 0.0003354432590400791, + 0.0003541231157516244, + 0.0003718600419643704, + 0.0003886068092203682, + 0.00040431882557715636, + 0.00041895425434359065, + 0.0004324741254792171, + 0.0004448424393605522, + 0.000456026262637982, + 0.00046599581592803176, + 0.0004747245531075068, + 0.00048218923199837255, + 0.0004883699762551523, + 0.0004932503282900589, + 0.000496817293094933, + 0.0004990613728433038, + 0.0004999765921804365, + 0.0004995605141340248, + 0.0004978142466031647, + 0.0004947424394083303, + 0.0004903532719102058, + 0.0004771584312303439, + 0.00044767308113163943, + 0.0004169158216414836, + 0.00038490863952510984, + 0.00035167684974100693, + 0.0003172490280342874, + 0.0002816569348474955, + 0.00024493543075146076, + 0.00020712238362137817, + 0.00016825856780528146, + 0.0001283875555533951, + 8.755560099745673e-05, + 4.5811516988942256e-05, + 3.2065451241382217e-06, + -4.020578069785253e-05, + -8.436977682086083e-05, + -0.0001292277581016112, + -0.0001747201915090631, + -0.00022078585464417965, + -0.00026736199875799154, + -0.00031438451583390957, + -0.00036178810928939355, + -0.0004095064678424196, + -0.0004574724420798271, + -0.0005056182232573659, + -0.0005538755238553479, + -0.0006021757594091622, + -0.0006504502311304558, + -0.000698630308832733, + -0.0007466476136742861, + -0.0007944342002318655, + -0.0008419227374202773, + -0.000889046687776173, + -0.0009357404846286442, + -0.0009819397066848715, + -0.0010275812495659517, + -0.0010726034938361548, + -0.0011169464690781897, + -0.0011605520135776017, + -0.001203363929191099, + -0.0012453281309864367, + -0.0012863927912554237, + -0.0013265084775165611, + -0.0013656282841398744, + -0.0014037079572434452, + -0.0014407060125290788, + -0.0014765838457433582, + -0.0015113058354699325, + -0.0015448394379793551, + -0.00157715527388391, + -0.001608227206366669, + -0.0016380324107765102, + -0.0016665514354037552, + -0.0016937682532746153, + -0.0017196703048265257, + -0.001744248531350739, + -0.0017674973991131206, + -0.0017894149140889341, + -0.0018100026272723677, + -0.0018292656305466718, + -0.0018472125431259032, + -0.001863855488604377, + -0.0018792100626749341, + -0.001893295291601991, + -0.0019061335815599306, + -0.001917750658971752, + -0.0019281755020068205, + -0.005834531753358536, + -0.00569191806056562, + -0.005552422418342122, + -0.0054159481119256765, + -0.005282405729449504, + -0.005151712896858257, + -0.005023794010579789, + -0.004898579968123878, + -0.004776007896802175, + -0.004656020880785823, + -0.00453856768673816, + -0.00442360248827981, + -0.004311084589562048, + -0.0042009781482417255, + -0.004093251898167153, + -0.00398787887209914, + -0.0038848361248048874, + -0.003784104456874538, + -0.0036856681396210227, + -0.003589514641433204, + -0.0034956343559603247, + -0.0034040203325124384, + -0.0033146680090666543, + -0.003227574948272886, + -0.003142740576855199, + -0.0030601659288058453, + -0.0029798533927687535, + -0.0029018064640074443, + -0.0028260295013492766, + -0.0027525274894934625, + -0.002681305807064531, + -0.0026123700007858507, + -0.0025457255661395133, + -0.002481377734869274, + -0.0024193312696725137, + -0.0023595902664152388, + -0.002302157964191068, + -0.002247036563531036, + -0.0021942270530558214, + -0.002143729044845881, + -0.0020955406187878325, + -0.002049658176137434, + -0.0020060763025206755, + -0.0019647876405749012, + -0.0019257827724115145, + -0.0018890501120608885, + -0.001854575808038458, + -0.001822343656148904, + -0.0017923350226227192, + -0.0017645287776564638, + -0.0017389012394046907, + -0.0017154261284479217, + -0.001694074532737239, + -0.001674814882992127, + -0.001657612938504193, + -0.0016424317832753727, + -0.0016292318323953142, + -0.001617970848538798, + -0.0016086039684404926, + -0.001601083739180976, + -0.0015953601640949972 + ], + "sobol_rms": { + "estimator": 0.19172730464675428, + "band": 0.020594323416902805, + "window": 0.27548277786930814, + "stack": 0.1720939509947523, + "reference": 0.0002193875128073912 + }, + "sobol_drop": { + "estimator": 0.18311655669696053, + "band": 0.049651795492108027, + "window": 0.19170881230491268, + "stack": 0.2062488515155831, + "reference": 0.001916032998687386 + }, + "n_pipelines": 108, + "axes": [ + "estimator", + "band", + "window", + "stack", + "reference" + ] + } +} diff --git a/literature/figs/demo_11_multiverse.npz b/literature/figs/demo_11_multiverse.npz new file mode 100644 index 0000000..6c4b522 Binary files /dev/null and b/literature/figs/demo_11_multiverse.npz differ diff --git a/literature/figs/demo_11_multiverse.png b/literature/figs/demo_11_multiverse.png index efb8324..bd11951 100644 Binary files a/literature/figs/demo_11_multiverse.png and b/literature/figs/demo_11_multiverse.png differ diff --git a/literature/figs/demo_12_bayes.json b/literature/figs/demo_12_bayes.json new file mode 100644 index 0000000..ee3723b --- /dev/null +++ b/literature/figs/demo_12_bayes.json @@ -0,0 +1,164 @@ +{ + "figure": "demo_12_bayes", + "generator": "codameter.uq_bayes._build_bayes + _fig_bayes", + "codameter_version": "0.4.0", + "git_commit": "7bfdcef47453919afb5ee5e32a0d7979330402e0", + "generated_utc": "2026-09-10T19:18:25+00:00", + "python": "3.12.13", + "numpy": "2.4.3", + "matplotlib": "3.10.9", + "axes": [ + { + "axes": "ax0", + "title": "(a) Ensemble to posterior", + "xlabel": "time (years)", + "ylabel": "dv/v (%)", + "lines": [ + "_child0", + "_child1", + "_child2", + "_child3", + "_child4", + "_child5", + "_child6", + "_child7", + "_child8", + "_child9", + "_child10", + "_child11", + "truth", + "posterior mean" + ], + "images": 0, + "collections": [ + "$\\pm2\\sigma$ of $C_d$ (single-measurement error)", + "95% credible (estimator)" + ], + "patches": 0 + }, + { + "axes": "ax1", + "title": "(b) data covariance $C_d$", + "xlabel": "time (yr)", + "ylabel": "time (yr)", + "lines": [], + "images": 1, + "collections": [], + "patches": 0 + }, + { + "axes": "ax2", + "title": "", + "xlabel": "", + "ylabel": "$C_d$ (dv/v fraction)$^2$", + "lines": [], + "images": 0, + "collections": [ + "_child0", + "_child1" + ], + "patches": 0 + }, + { + "axes": "ax3", + "title": "(c) time-dependent error; $N_{eff}$=23/229", + "xlabel": "time (years)", + "ylabel": "$\\sigma$ (dv/v, %)", + "lines": [ + "$\\sigma_d(t)$ (total)", + "between-configuration", + "within-method", + "posterior of mean", + "_child4" + ], + "images": 0, + "collections": [], + "patches": 0 + } + ], + "arrays": [ + "ax0/collection0/offsets", + "ax0/collection0/path_lengths", + "ax0/collection0/vertices", + "ax0/collection1/offsets", + "ax0/collection1/path_lengths", + "ax0/collection1/vertices", + "ax0/line0/x", + "ax0/line0/y", + "ax0/line1/x", + "ax0/line1/y", + "ax0/line10/x", + "ax0/line10/y", + "ax0/line11/x", + "ax0/line11/y", + "ax0/line12/x", + "ax0/line12/y", + "ax0/line13/x", + "ax0/line13/y", + "ax0/line2/x", + "ax0/line2/y", + "ax0/line3/x", + "ax0/line3/y", + "ax0/line4/x", + "ax0/line4/y", + "ax0/line5/x", + "ax0/line5/y", + "ax0/line6/x", + "ax0/line6/y", + "ax0/line7/x", + "ax0/line7/y", + "ax0/line8/x", + "ax0/line8/y", + "ax0/line9/x", + "ax0/line9/y", + "ax1/image0", + "ax1/image0/extent", + "ax2/collection0/offsets", + "ax2/collection1/offsets", + "ax2/collection1/path_lengths", + "ax2/collection1/vertices", + "ax3/line0/x", + "ax3/line0/y", + "ax3/line1/x", + "ax3/line1/y", + "ax3/line2/x", + "ax3/line2/y", + "ax3/line3/x", + "ax3/line3/y", + "ax3/line4/x", + "ax3/line4/y", + "data/Cd", + "data/members", + "data/method_std", + "data/mu_cov", + "data/mu_hi", + "data/mu_lo", + "data/mu_mean", + "data/times_days", + "data/total_std", + "data/truth", + "data/within_sigma", + "data/within_std" + ], + "bayes": { + "tau": 0.0003612992348785833, + "s": 12.098861625892763, + "corr_length_days": 39.20671143105746, + "n_eff": 22.760567115510465, + "n_epochs": 229, + "labels": [ + "stretching (TS) 0.4-1Hz 8-28s stack10d fixed", + "stretching (TS) 0.4-1Hz 12-34s stack10d fixed", + "stretching (TS) 0.6-1.4Hz 8-28s stack10d fixed", + "stretching (TS) 0.6-1.4Hz 12-34s stack10d fixed", + "MWCS 0.4-1Hz 8-28s stack10d fixed", + "MWCS 0.4-1Hz 12-34s stack10d fixed", + "MWCS 0.6-1.4Hz 8-28s stack10d fixed", + "MWCS 0.6-1.4Hz 12-34s stack10d fixed", + "DTW 0.4-1Hz 8-28s stack10d fixed", + "DTW 0.4-1Hz 12-34s stack10d fixed", + "DTW 0.6-1.4Hz 8-28s stack10d fixed", + "DTW 0.6-1.4Hz 12-34s stack10d fixed" + ] + } +} diff --git a/literature/figs/demo_12_bayes.npz b/literature/figs/demo_12_bayes.npz new file mode 100644 index 0000000..ab46c21 Binary files /dev/null and b/literature/figs/demo_12_bayes.npz differ diff --git a/literature/figs/demo_12_bayes.png b/literature/figs/demo_12_bayes.png index 786eb55..2151a0e 100644 Binary files a/literature/figs/demo_12_bayes.png and b/literature/figs/demo_12_bayes.png differ diff --git a/literature/figs/demo_13_branch_asymmetry.json b/literature/figs/demo_13_branch_asymmetry.json new file mode 100644 index 0000000..9ca81d8 --- /dev/null +++ b/literature/figs/demo_13_branch_asymmetry.json @@ -0,0 +1,57 @@ +{ + "figure": "demo_13_branch_asymmetry", + "generator": "codameter.synthetic_demo.fig_branch_asymmetry", + "codameter_version": "0.4.0", + "git_commit": "7bfdcef47453919afb5ee5e32a0d7979330402e0", + "generated_utc": "2026-09-10T19:03:57+00:00", + "python": "3.12.13", + "numpy": "2.4.3", + "matplotlib": "3.10.9", + "axes": [ + { + "axes": "ax0", + "title": "(a) one-sided change", + "xlabel": "time (years)", + "ylabel": "dv/v (%)", + "lines": [ + "quiet branch (acausal)", + "greatest-change branch (causal)", + "mean of branches (dilutes)", + "truth (structural)" + ], + "images": 0, + "collections": [], + "patches": 0 + }, + { + "axes": "ax1", + "title": "(b) same change, both branches", + "xlabel": "SNR", + "ylabel": "median recovered dv/v (%)", + "lines": [ + "true drop (both branches)", + "mean of branches", + "greatest change (biased)" + ], + "images": 0, + "collections": [], + "patches": 0 + } + ], + "arrays": [ + "ax0/line0/x", + "ax0/line0/y", + "ax0/line1/x", + "ax0/line1/y", + "ax0/line2/x", + "ax0/line2/y", + "ax0/line3/x", + "ax0/line3/y", + "ax1/line0/x", + "ax1/line0/y", + "ax1/line1/x", + "ax1/line1/y", + "ax1/line2/x", + "ax1/line2/y" + ] +} diff --git a/literature/figs/demo_13_branch_asymmetry.npz b/literature/figs/demo_13_branch_asymmetry.npz new file mode 100644 index 0000000..f0f2520 Binary files /dev/null and b/literature/figs/demo_13_branch_asymmetry.npz differ diff --git a/literature/figs/demo_13_branch_asymmetry.png b/literature/figs/demo_13_branch_asymmetry.png index bb7779d..cff97e6 100644 Binary files a/literature/figs/demo_13_branch_asymmetry.png and b/literature/figs/demo_13_branch_asymmetry.png differ diff --git a/literature/figs/demo_14_network_pairs.json b/literature/figs/demo_14_network_pairs.json new file mode 100644 index 0000000..fad6fe9 --- /dev/null +++ b/literature/figs/demo_14_network_pairs.json @@ -0,0 +1,77 @@ +{ + "figure": "demo_14_network_pairs", + "generator": "codameter.synthetic_demo.fig_network_pairs", + "codameter_version": "0.4.0", + "git_commit": "141e7bc25bb439420c5ee73223bf78eb4ca7a839", + "generated_utc": "2026-09-10T18:30:57+00:00", + "python": "3.12.13", + "numpy": "2.4.3", + "matplotlib": "3.10.9", + "axes": [ + { + "axes": "ax0", + "title": "Individual station-pair dv/v -- wider than the network error bar", + "xlabel": "time (years)", + "ylabel": "dv/v (%)", + "lines": [ + "_child0", + "_child1", + "_child2", + "_child3", + "_child4", + "_child5", + "_child6", + "_child7", + "_child8", + "network truth" + ], + "images": 0, + "collections": [ + "individual-pair range" + ], + "patches": 0 + }, + { + "axes": "ax1", + "title": "", + "xlabel": "", + "ylabel": "pair SNR", + "lines": [], + "images": 0, + "collections": [ + "_child0", + "_child1" + ], + "patches": 0 + } + ], + "arrays": [ + "ax0/collection0/offsets", + "ax0/collection0/path_lengths", + "ax0/collection0/vertices", + "ax0/line0/x", + "ax0/line0/y", + "ax0/line1/x", + "ax0/line1/y", + "ax0/line2/x", + "ax0/line2/y", + "ax0/line3/x", + "ax0/line3/y", + "ax0/line4/x", + "ax0/line4/y", + "ax0/line5/x", + "ax0/line5/y", + "ax0/line6/x", + "ax0/line6/y", + "ax0/line7/x", + "ax0/line7/y", + "ax0/line8/x", + "ax0/line8/y", + "ax0/line9/x", + "ax0/line9/y", + "ax1/collection0/offsets", + "ax1/collection1/offsets", + "ax1/collection1/path_lengths", + "ax1/collection1/vertices" + ] +} diff --git a/literature/figs/demo_14_network_pairs.npz b/literature/figs/demo_14_network_pairs.npz new file mode 100644 index 0000000..4671991 Binary files /dev/null and b/literature/figs/demo_14_network_pairs.npz differ diff --git a/literature/figs/demo_14_network_pairs.png b/literature/figs/demo_14_network_pairs.png index 89c0256..7bb5eb0 100644 Binary files a/literature/figs/demo_14_network_pairs.png and b/literature/figs/demo_14_network_pairs.png differ diff --git a/literature/figs/demo_15_window_envelope.json b/literature/figs/demo_15_window_envelope.json new file mode 100644 index 0000000..6f1162c --- /dev/null +++ b/literature/figs/demo_15_window_envelope.json @@ -0,0 +1,53 @@ +{ + "figure": "demo_15_window_envelope", + "generator": "codameter.synthetic_demo.fig_window_envelope", + "codameter_version": "0.4.0", + "git_commit": "141e7bc25bb439420c5ee73223bf78eb4ca7a839", + "generated_utc": "2026-09-10T18:31:11+00:00", + "python": "3.12.13", + "numpy": "2.4.3", + "matplotlib": "3.10.9", + "axes": [ + { + "axes": "ax0", + "title": "(a) window shrinks with frequency", + "xlabel": "lapse time (s)", + "ylabel": "coda envelope (norm.)", + "lines": [ + "low 0.3\u20130.8 Hz", + "mid 1.0\u20132.5 Hz", + "high 3.0\u20136.0 Hz" + ], + "images": 0, + "collections": [], + "patches": 3 + }, + { + "axes": "ax1", + "title": "(b) fixed window fails at high band", + "xlabel": "", + "ylabel": "RMS error vs truth (dv/v, %, log)", + "lines": [], + "images": 0, + "collections": [], + "patches": 6 + } + ], + "arrays": [ + "ax0/line0/x", + "ax0/line0/y", + "ax0/line1/x", + "ax0/line1/y", + "ax0/line2/x", + "ax0/line2/y", + "ax0/patch0/xywh", + "ax0/patch1/xywh", + "ax0/patch2/xywh", + "ax1/patch0/xywh", + "ax1/patch1/xywh", + "ax1/patch2/xywh", + "ax1/patch3/xywh", + "ax1/patch4/xywh", + "ax1/patch5/xywh" + ] +} diff --git a/literature/figs/demo_15_window_envelope.npz b/literature/figs/demo_15_window_envelope.npz new file mode 100644 index 0000000..e47780c Binary files /dev/null and b/literature/figs/demo_15_window_envelope.npz differ diff --git a/literature/figs/demo_15_window_envelope.png b/literature/figs/demo_15_window_envelope.png index b84a961..06bc9cf 100644 Binary files a/literature/figs/demo_15_window_envelope.png and b/literature/figs/demo_15_window_envelope.png differ diff --git a/literature/figs/demo_16_band_sensitivity.json b/literature/figs/demo_16_band_sensitivity.json new file mode 100644 index 0000000..9395d30 --- /dev/null +++ b/literature/figs/demo_16_band_sensitivity.json @@ -0,0 +1,31 @@ +{ + "figure": "demo_16_band_sensitivity", + "generator": "codameter.synthetic_demo.fig_band_sensitivity", + "codameter_version": "0.4.0", + "git_commit": "141e7bc25bb439420c5ee73223bf78eb4ca7a839", + "generated_utc": "2026-09-10T18:35:20+00:00", + "python": "3.12.13", + "numpy": "2.4.3", + "matplotlib": "3.10.9", + "axes": [ + { + "axes": "ax0", + "title": "RMS is flat within the layer's band, then rises sharply past its edge", + "xlabel": "band-center offset from the true band, $\\Delta f$ (Hz)", + "ylabel": "RMS error vs truth (dv/v, %)", + "lines": [ + "_child0", + "true band center" + ], + "images": 0, + "collections": [], + "patches": 0 + } + ], + "arrays": [ + "ax0/line0/x", + "ax0/line0/y", + "ax0/line1/x", + "ax0/line1/y" + ] +} diff --git a/literature/figs/demo_16_band_sensitivity.npz b/literature/figs/demo_16_band_sensitivity.npz new file mode 100644 index 0000000..29e37dc Binary files /dev/null and b/literature/figs/demo_16_band_sensitivity.npz differ diff --git a/literature/figs/demo_16_band_sensitivity.png b/literature/figs/demo_16_band_sensitivity.png new file mode 100644 index 0000000..cc85e8d Binary files /dev/null and b/literature/figs/demo_16_band_sensitivity.png differ diff --git a/literature/figs/demo_17_reference_schemes.json b/literature/figs/demo_17_reference_schemes.json new file mode 100644 index 0000000..ab759ed --- /dev/null +++ b/literature/figs/demo_17_reference_schemes.json @@ -0,0 +1,51 @@ +{ + "figure": "demo_17_reference_schemes", + "generator": "codameter.synthetic_demo.fig_reference_schemes", + "codameter_version": "0.4.0", + "git_commit": "141e7bc25bb439420c5ee73223bf78eb4ca7a839", + "generated_utc": "2026-09-10T18:39:35+00:00", + "python": "3.12.13", + "numpy": "2.4.3", + "matplotlib": "3.10.9", + "axes": [ + { + "axes": "ax0", + "title": "(a) five reference schemes", + "xlabel": "", + "ylabel": "RMS error vs truth (dv/v, %, log)", + "lines": [], + "images": 0, + "collections": [], + "patches": 10 + }, + { + "axes": "ax1", + "title": "(b) a longer trailing window helps,\nbut never converges", + "xlabel": "moving-reference length (days)", + "ylabel": "RMS error vs truth (dv/v, %)", + "lines": [ + "_child0", + "whole-record reference" + ], + "images": 0, + "collections": [], + "patches": 0 + } + ], + "arrays": [ + "ax0/patch0/xywh", + "ax0/patch1/xywh", + "ax0/patch2/xywh", + "ax0/patch3/xywh", + "ax0/patch4/xywh", + "ax0/patch5/xywh", + "ax0/patch6/xywh", + "ax0/patch7/xywh", + "ax0/patch8/xywh", + "ax0/patch9/xywh", + "ax1/line0/x", + "ax1/line0/y", + "ax1/line1/x", + "ax1/line1/y" + ] +} diff --git a/literature/figs/demo_17_reference_schemes.npz b/literature/figs/demo_17_reference_schemes.npz new file mode 100644 index 0000000..3f26c20 Binary files /dev/null and b/literature/figs/demo_17_reference_schemes.npz differ diff --git a/literature/figs/demo_17_reference_schemes.png b/literature/figs/demo_17_reference_schemes.png new file mode 100644 index 0000000..5a2aa3f Binary files /dev/null and b/literature/figs/demo_17_reference_schemes.png differ diff --git a/literature/figs/demo_18_stack_coherence.json b/literature/figs/demo_18_stack_coherence.json new file mode 100644 index 0000000..507ec4a --- /dev/null +++ b/literature/figs/demo_18_stack_coherence.json @@ -0,0 +1,57 @@ +{ + "figure": "demo_18_stack_coherence", + "generator": "codameter.synthetic_demo.fig_stack_coherence", + "codameter_version": "0.4.0", + "git_commit": "141e7bc25bb439420c5ee73223bf78eb4ca7a839", + "generated_utc": "2026-09-10T18:41:24+00:00", + "python": "3.12.13", + "numpy": "2.4.3", + "matplotlib": "3.10.9", + "axes": [ + { + "axes": "ax0", + "title": "(a) coherence rises with stack length", + "xlabel": "stack length (days)", + "ylabel": "median stretching CC", + "lines": [ + "SNR 0.5 (poor)", + "SNR 4 (workable)", + "CC gate (0.6)" + ], + "images": 0, + "collections": [], + "patches": 0 + }, + { + "axes": "ax1", + "title": "(b) noise floor vs step-smearing tradeoff", + "xlabel": "stack length (days)", + "ylabel": "dv/v error (%, log)", + "lines": [ + "SNR 0.5 (poor): RMS", + "SNR 0.5 (poor): |bias|", + "SNR 4 (workable): RMS", + "SNR 4 (workable): |bias|" + ], + "images": 0, + "collections": [], + "patches": 0 + } + ], + "arrays": [ + "ax0/line0/x", + "ax0/line0/y", + "ax0/line1/x", + "ax0/line1/y", + "ax0/line2/x", + "ax0/line2/y", + "ax1/line0/x", + "ax1/line0/y", + "ax1/line1/x", + "ax1/line1/y", + "ax1/line2/x", + "ax1/line2/y", + "ax1/line3/x", + "ax1/line3/y" + ] +} diff --git a/literature/figs/demo_18_stack_coherence.npz b/literature/figs/demo_18_stack_coherence.npz new file mode 100644 index 0000000..18de5dd Binary files /dev/null and b/literature/figs/demo_18_stack_coherence.npz differ diff --git a/literature/figs/demo_18_stack_coherence.png b/literature/figs/demo_18_stack_coherence.png new file mode 100644 index 0000000..8c22864 Binary files /dev/null and b/literature/figs/demo_18_stack_coherence.png differ diff --git a/literature/figs/demo_1_methods.json b/literature/figs/demo_1_methods.json new file mode 100644 index 0000000..3f6a0ed --- /dev/null +++ b/literature/figs/demo_1_methods.json @@ -0,0 +1,119 @@ +{ + "figure": "demo_1_methods", + "generator": "codameter.synthetic_demo.fig_methods", + "codameter_version": "0.4.0", + "git_commit": "1374e81e863346a84aeb8ce28a0f58d876454009", + "generated_utc": "2026-09-10T18:21:42+00:00", + "python": "3.12.13", + "numpy": "2.4.3", + "matplotlib": "3.10.9", + "axes": [ + { + "axes": "ax0", + "title": "(a) clean, small dv/v", + "xlabel": "true dv/v (%)", + "ylabel": "recovered dv/v (%)", + "lines": [ + "1:1 (truth)", + "stretching (TS)", + "WCC", + "DTW", + "MWCS", + "WCS", + "WTS", + "WTDTW" + ], + "images": 0, + "collections": [], + "patches": 0 + }, + { + "axes": "ax1", + "title": "(b) clean, $\\pm 5\\,\\%$ sweep", + "xlabel": "true dv/v (%)", + "ylabel": "recovered dv/v (%)", + "lines": [ + "1:1 (truth)", + "stretching (TS)", + "WCC", + "DTW", + "MWCS", + "WCS", + "WTS", + "WTDTW" + ], + "images": 0, + "collections": [], + "patches": 0 + }, + { + "axes": "ax2", + "title": "(c) large dv/v \u2014 MWCS cycle-skips", + "xlabel": "time (years)", + "ylabel": "dv/v (%)", + "lines": [ + "truth (landslide)", + "stretching (TS)", + "WCC", + "DTW", + "MWCS", + "WCS", + "WTS", + "WTDTW" + ], + "images": 0, + "collections": [], + "patches": 0 + } + ], + "arrays": [ + "ax0/line0/x", + "ax0/line0/y", + "ax0/line1/x", + "ax0/line1/y", + "ax0/line2/x", + "ax0/line2/y", + "ax0/line3/x", + "ax0/line3/y", + "ax0/line4/x", + "ax0/line4/y", + "ax0/line5/x", + "ax0/line5/y", + "ax0/line6/x", + "ax0/line6/y", + "ax0/line7/x", + "ax0/line7/y", + "ax1/line0/x", + "ax1/line0/y", + "ax1/line1/x", + "ax1/line1/y", + "ax1/line2/x", + "ax1/line2/y", + "ax1/line3/x", + "ax1/line3/y", + "ax1/line4/x", + "ax1/line4/y", + "ax1/line5/x", + "ax1/line5/y", + "ax1/line6/x", + "ax1/line6/y", + "ax1/line7/x", + "ax1/line7/y", + "ax2/line0/x", + "ax2/line0/y", + "ax2/line1/x", + "ax2/line1/y", + "ax2/line2/x", + "ax2/line2/y", + "ax2/line3/x", + "ax2/line3/y", + "ax2/line4/x", + "ax2/line4/y", + "ax2/line5/x", + "ax2/line5/y", + "ax2/line6/x", + "ax2/line6/y", + "ax2/line7/x", + "ax2/line7/y" + ] +} diff --git a/literature/figs/demo_1_methods.npz b/literature/figs/demo_1_methods.npz new file mode 100644 index 0000000..a564865 Binary files /dev/null and b/literature/figs/demo_1_methods.npz differ diff --git a/literature/figs/demo_1_methods.png b/literature/figs/demo_1_methods.png index 90ee1a3..56dab2f 100644 Binary files a/literature/figs/demo_1_methods.png and b/literature/figs/demo_1_methods.png differ diff --git a/literature/figs/demo_2_aggregation.json b/literature/figs/demo_2_aggregation.json new file mode 100644 index 0000000..5b8c72c --- /dev/null +++ b/literature/figs/demo_2_aggregation.json @@ -0,0 +1,96 @@ +{ + "figure": "demo_2_aggregation", + "generator": "codameter.synthetic_demo.fig_aggregation", + "codameter_version": "0.4.0", + "git_commit": "7bfdcef47453919afb5ee5e32a0d7979330402e0", + "generated_utc": "2026-09-10T19:01:48+00:00", + "python": "3.12.13", + "numpy": "2.4.3", + "matplotlib": "3.10.9", + "axes": [ + { + "axes": "ax0", + "title": "(a) Component aggregation: three recipes", + "xlabel": "time (years)", + "ylabel": "dv/v (%)", + "lines": [ + "_child0", + "_child1", + "_child2", + "_child3", + "_child4", + "_child5", + "A: avg dv/v (unweighted)", + "A: avg dv/v (CC-weighted)", + "B: avg CC images, then peak", + "truth" + ], + "images": 0, + "collections": [ + "B uncertainty = CC-peak width" + ], + "patches": 0 + }, + { + "axes": "ax1", + "title": "(b) averaged CC(dv/v, t) image (B)", + "xlabel": "time (years)", + "ylabel": "dv/v candidate (%)", + "lines": [ + "peak of mean CC (B)", + "truth" + ], + "images": 1, + "collections": [], + "patches": 0 + }, + { + "axes": "ax2", + "title": "", + "xlabel": "", + "ylabel": "coherence CC (dark = high)", + "lines": [], + "images": 0, + "collections": [ + "_child0", + "_child1" + ], + "patches": 0 + } + ], + "arrays": [ + "ax0/collection0/offsets", + "ax0/collection0/path_lengths", + "ax0/collection0/vertices", + "ax0/line0/x", + "ax0/line0/y", + "ax0/line1/x", + "ax0/line1/y", + "ax0/line2/x", + "ax0/line2/y", + "ax0/line3/x", + "ax0/line3/y", + "ax0/line4/x", + "ax0/line4/y", + "ax0/line5/x", + "ax0/line5/y", + "ax0/line6/x", + "ax0/line6/y", + "ax0/line7/x", + "ax0/line7/y", + "ax0/line8/x", + "ax0/line8/y", + "ax0/line9/x", + "ax0/line9/y", + "ax1/image0", + "ax1/image0/extent", + "ax1/line0/x", + "ax1/line0/y", + "ax1/line1/x", + "ax1/line1/y", + "ax2/collection0/offsets", + "ax2/collection1/offsets", + "ax2/collection1/path_lengths", + "ax2/collection1/vertices" + ] +} diff --git a/literature/figs/demo_2_aggregation.npz b/literature/figs/demo_2_aggregation.npz new file mode 100644 index 0000000..8dc56dd Binary files /dev/null and b/literature/figs/demo_2_aggregation.npz differ diff --git a/literature/figs/demo_2_aggregation.png b/literature/figs/demo_2_aggregation.png index 35bb134..7ea2e95 100644 Binary files a/literature/figs/demo_2_aggregation.png and b/literature/figs/demo_2_aggregation.png differ diff --git a/literature/figs/demo_3_uncertainty.json b/literature/figs/demo_3_uncertainty.json new file mode 100644 index 0000000..6e3c730 --- /dev/null +++ b/literature/figs/demo_3_uncertainty.json @@ -0,0 +1,70 @@ +{ + "figure": "demo_3_uncertainty", + "generator": "codameter.synthetic_demo.fig_uncertainty", + "codameter_version": "0.4.0", + "git_commit": "1374e81e863346a84aeb8ce28a0f58d876454009", + "generated_utc": "2026-09-10T18:27:17+00:00", + "python": "3.12.13", + "numpy": "2.4.3", + "matplotlib": "3.10.9", + "axes": [ + { + "axes": "ax0", + "title": "(a) same mean, different error bands", + "xlabel": "time (years)", + "ylabel": "dv/v (%)", + "lines": [ + "network truth", + "CC-weighted, std. error", + "unweighted, std. error", + "unweighted, std. deviation" + ], + "images": 0, + "collections": [ + "_child1", + "_child3", + "_child5" + ], + "patches": 0 + }, + { + "axes": "ax1", + "title": "(b) the error bar is a choice (\u22483.2\u00d7 range)", + "xlabel": "time (years)", + "ylabel": "reported 1$\\sigma$ on dv/v (%)", + "lines": [ + "CC-weighted, std. error", + "unweighted, std. error", + "unweighted, std. deviation" + ], + "images": 0, + "collections": [], + "patches": 0 + } + ], + "arrays": [ + "ax0/collection0/offsets", + "ax0/collection0/path_lengths", + "ax0/collection0/vertices", + "ax0/collection1/offsets", + "ax0/collection1/path_lengths", + "ax0/collection1/vertices", + "ax0/collection2/offsets", + "ax0/collection2/path_lengths", + "ax0/collection2/vertices", + "ax0/line0/x", + "ax0/line0/y", + "ax0/line1/x", + "ax0/line1/y", + "ax0/line2/x", + "ax0/line2/y", + "ax0/line3/x", + "ax0/line3/y", + "ax1/line0/x", + "ax1/line0/y", + "ax1/line1/x", + "ax1/line1/y", + "ax1/line2/x", + "ax1/line2/y" + ] +} diff --git a/literature/figs/demo_3_uncertainty.npz b/literature/figs/demo_3_uncertainty.npz new file mode 100644 index 0000000..f23581e Binary files /dev/null and b/literature/figs/demo_3_uncertainty.npz differ diff --git a/literature/figs/demo_3_uncertainty.png b/literature/figs/demo_3_uncertainty.png index 8ea193c..817a992 100644 Binary files a/literature/figs/demo_3_uncertainty.png and b/literature/figs/demo_3_uncertainty.png differ diff --git a/literature/figs/demo_4_frequency_depth.json b/literature/figs/demo_4_frequency_depth.json new file mode 100644 index 0000000..3a6a283 --- /dev/null +++ b/literature/figs/demo_4_frequency_depth.json @@ -0,0 +1,37 @@ +{ + "figure": "demo_4_frequency_depth", + "generator": "codameter.synthetic_demo.fig_frequency_depth", + "codameter_version": "0.4.0", + "git_commit": "7bfdcef47453919afb5ee5e32a0d7979330402e0", + "generated_utc": "2026-09-10T19:02:00+00:00", + "python": "3.12.13", + "numpy": "2.4.3", + "matplotlib": "3.10.9", + "axes": [ + { + "axes": "ax0", + "title": "Frequency band selects depth,\nand a different signal", + "xlabel": "time (years)", + "ylabel": "dv/v (%)", + "lines": [ + "truth: shallow", + "truth: deep", + "high band -> shallow", + "low band -> deep" + ], + "images": 0, + "collections": [], + "patches": 0 + } + ], + "arrays": [ + "ax0/line0/x", + "ax0/line0/y", + "ax0/line1/x", + "ax0/line1/y", + "ax0/line2/x", + "ax0/line2/y", + "ax0/line3/x", + "ax0/line3/y" + ] +} diff --git a/literature/figs/demo_4_frequency_depth.npz b/literature/figs/demo_4_frequency_depth.npz new file mode 100644 index 0000000..5bcdb15 Binary files /dev/null and b/literature/figs/demo_4_frequency_depth.npz differ diff --git a/literature/figs/demo_4_frequency_depth.png b/literature/figs/demo_4_frequency_depth.png index ce8f421..b8b2d30 100644 Binary files a/literature/figs/demo_4_frequency_depth.png and b/literature/figs/demo_4_frequency_depth.png differ diff --git a/literature/figs/demo_5_window_band.json b/literature/figs/demo_5_window_band.json new file mode 100644 index 0000000..eec05d4 --- /dev/null +++ b/literature/figs/demo_5_window_band.json @@ -0,0 +1,36 @@ +{ + "figure": "demo_5_window_band", + "generator": "codameter.synthetic_demo.fig_window_band", + "codameter_version": "0.4.0", + "git_commit": "7bfdcef47453919afb5ee5e32a0d7979330402e0", + "generated_utc": "2026-09-10T19:02:00+00:00", + "python": "3.12.13", + "numpy": "2.4.3", + "matplotlib": "3.10.9", + "axes": [ + { + "axes": "ax0", + "title": "High-frequency coda\ndecays first", + "xlabel": "lapse time (s)", + "ylabel": "coda envelope (norm.)", + "lines": [ + "low band", + "high band", + "noise floor" + ], + "images": 0, + "collections": [], + "patches": 2 + } + ], + "arrays": [ + "ax0/line0/x", + "ax0/line0/y", + "ax0/line1/x", + "ax0/line1/y", + "ax0/line2/x", + "ax0/line2/y", + "ax0/patch0/xywh", + "ax0/patch1/xywh" + ] +} diff --git a/literature/figs/demo_5_window_band.npz b/literature/figs/demo_5_window_band.npz new file mode 100644 index 0000000..99a41a7 Binary files /dev/null and b/literature/figs/demo_5_window_band.npz differ diff --git a/literature/figs/demo_5_window_band.png b/literature/figs/demo_5_window_band.png index d90fb58..876c6c2 100644 Binary files a/literature/figs/demo_5_window_band.png and b/literature/figs/demo_5_window_band.png differ diff --git a/literature/figs/demo_6_stacking.json b/literature/figs/demo_6_stacking.json new file mode 100644 index 0000000..593da78 --- /dev/null +++ b/literature/figs/demo_6_stacking.json @@ -0,0 +1,40 @@ +{ + "figure": "demo_6_stacking", + "generator": "codameter.synthetic_demo.fig_stacking", + "codameter_version": "0.4.0", + "git_commit": "7bfdcef47453919afb5ee5e32a0d7979330402e0", + "generated_utc": "2026-09-10T19:02:22+00:00", + "python": "3.12.13", + "numpy": "2.4.3", + "matplotlib": "3.10.9", + "axes": [ + { + "axes": "ax0", + "title": "Stack length trades noise vs coseismic-step sharpness", + "xlabel": "time (years)", + "ylabel": "dv/v (%)", + "lines": [ + "ground truth", + "1-day (noisy)", + "10-day stack", + "45-day stack", + "_child4" + ], + "images": 0, + "collections": [], + "patches": 0 + } + ], + "arrays": [ + "ax0/line0/x", + "ax0/line0/y", + "ax0/line1/x", + "ax0/line1/y", + "ax0/line2/x", + "ax0/line2/y", + "ax0/line3/x", + "ax0/line3/y", + "ax0/line4/x", + "ax0/line4/y" + ] +} diff --git a/literature/figs/demo_6_stacking.npz b/literature/figs/demo_6_stacking.npz new file mode 100644 index 0000000..5ab3a38 Binary files /dev/null and b/literature/figs/demo_6_stacking.npz differ diff --git a/literature/figs/demo_6_stacking.png b/literature/figs/demo_6_stacking.png index 9672151..b5595ae 100644 Binary files a/literature/figs/demo_6_stacking.png and b/literature/figs/demo_6_stacking.png differ diff --git a/literature/figs/demo_7_reference.json b/literature/figs/demo_7_reference.json new file mode 100644 index 0000000..9ce02d5 --- /dev/null +++ b/literature/figs/demo_7_reference.json @@ -0,0 +1,40 @@ +{ + "figure": "demo_7_reference", + "generator": "codameter.synthetic_demo.fig_reference", + "codameter_version": "0.4.0", + "git_commit": "7bfdcef47453919afb5ee5e32a0d7979330402e0", + "generated_utc": "2026-09-10T19:03:30+00:00", + "python": "3.12.13", + "numpy": "2.4.3", + "matplotlib": "3.10.9", + "axes": [ + { + "axes": "ax0", + "title": "Uncumulated moving reference removes the trend", + "xlabel": "time (years)", + "ylabel": "dv/v (%)", + "lines": [ + "ground truth", + "fixed reference", + "60-day moving ref.", + "joint inversion", + "_child4" + ], + "images": 0, + "collections": [], + "patches": 0 + } + ], + "arrays": [ + "ax0/line0/x", + "ax0/line0/y", + "ax0/line1/x", + "ax0/line1/y", + "ax0/line2/x", + "ax0/line2/y", + "ax0/line3/x", + "ax0/line3/y", + "ax0/line4/x", + "ax0/line4/y" + ] +} diff --git a/literature/figs/demo_7_reference.npz b/literature/figs/demo_7_reference.npz new file mode 100644 index 0000000..fcb9633 Binary files /dev/null and b/literature/figs/demo_7_reference.npz differ diff --git a/literature/figs/demo_7_reference.png b/literature/figs/demo_7_reference.png index 5884bfb..6a6df24 100644 Binary files a/literature/figs/demo_7_reference.png and b/literature/figs/demo_7_reference.png differ diff --git a/literature/figs/demo_8_artifacts.json b/literature/figs/demo_8_artifacts.json new file mode 100644 index 0000000..d94fe71 --- /dev/null +++ b/literature/figs/demo_8_artifacts.json @@ -0,0 +1,54 @@ +{ + "figure": "demo_8_artifacts", + "generator": "codameter.synthetic_demo.fig_artifacts", + "codameter_version": "0.4.0", + "git_commit": "141e7bc25bb439420c5ee73223bf78eb4ca7a839", + "generated_utc": "2026-09-10T18:32:30+00:00", + "python": "3.12.13", + "numpy": "2.4.3", + "matplotlib": "3.10.9", + "axes": [ + { + "axes": "ax0", + "title": "(a) clock drift splits the branches", + "xlabel": "time (years)", + "ylabel": "apparent dv/v (%)", + "lines": [ + "truth (no change)", + "causal branch", + "acausal branch" + ], + "images": 0, + "collections": [], + "patches": 0 + }, + { + "axes": "ax1", + "title": "(b) late-coda noise -> spurious cycle", + "xlabel": "time (years)", + "ylabel": "dv/v (%)", + "lines": [ + "truth", + "early 8\u201318 s window (clean)", + "late 28\u201345 s window (contaminated)" + ], + "images": 0, + "collections": [], + "patches": 0 + } + ], + "arrays": [ + "ax0/line0/x", + "ax0/line0/y", + "ax0/line1/x", + "ax0/line1/y", + "ax0/line2/x", + "ax0/line2/y", + "ax1/line0/x", + "ax1/line0/y", + "ax1/line1/x", + "ax1/line1/y", + "ax1/line2/x", + "ax1/line2/y" + ] +} diff --git a/literature/figs/demo_8_artifacts.npz b/literature/figs/demo_8_artifacts.npz new file mode 100644 index 0000000..882544a Binary files /dev/null and b/literature/figs/demo_8_artifacts.npz differ diff --git a/literature/figs/demo_8_artifacts.png b/literature/figs/demo_8_artifacts.png index a47f949..51d8664 100644 Binary files a/literature/figs/demo_8_artifacts.png and b/literature/figs/demo_8_artifacts.png differ diff --git a/literature/figs/demo_9_multiverse.json b/literature/figs/demo_9_multiverse.json new file mode 100644 index 0000000..492cbfb --- /dev/null +++ b/literature/figs/demo_9_multiverse.json @@ -0,0 +1,120 @@ +{ + "figure": "demo_9_multiverse", + "generator": "codameter.synthetic_demo.fig_multiverse", + "codameter_version": "0.4.0", + "git_commit": "141e7bc25bb439420c5ee73223bf78eb4ca7a839", + "generated_utc": "2026-09-10T18:34:02+00:00", + "python": "3.12.13", + "numpy": "2.4.3", + "matplotlib": "3.10.9", + "axes": [ + { + "axes": "ax0", + "title": "One dataset, 27 defensible pipelines", + "xlabel": "time (years)", + "ylabel": "dv/v (%)", + "lines": [ + "_child0", + "_child1", + "_child2", + "_child3", + "_child4", + "_child5", + "_child6", + "_child7", + "_child8", + "_child9", + "_child10", + "_child11", + "_child12", + "_child13", + "_child14", + "_child15", + "_child16", + "_child17", + "_child18", + "_child19", + "_child20", + "_child21", + "_child22", + "_child23", + "_child24", + "_child25", + "_child26", + "median of 27 pipelines", + "ground truth", + "_child30" + ], + "images": 0, + "collections": [ + "10\u201390% across pipelines" + ], + "patches": 0 + } + ], + "arrays": [ + "ax0/collection0/offsets", + "ax0/collection0/path_lengths", + "ax0/collection0/vertices", + "ax0/line0/x", + "ax0/line0/y", + "ax0/line1/x", + "ax0/line1/y", + "ax0/line10/x", + "ax0/line10/y", + "ax0/line11/x", + "ax0/line11/y", + "ax0/line12/x", + "ax0/line12/y", + "ax0/line13/x", + "ax0/line13/y", + "ax0/line14/x", + "ax0/line14/y", + "ax0/line15/x", + "ax0/line15/y", + "ax0/line16/x", + "ax0/line16/y", + "ax0/line17/x", + "ax0/line17/y", + "ax0/line18/x", + "ax0/line18/y", + "ax0/line19/x", + "ax0/line19/y", + "ax0/line2/x", + "ax0/line2/y", + "ax0/line20/x", + "ax0/line20/y", + "ax0/line21/x", + "ax0/line21/y", + "ax0/line22/x", + "ax0/line22/y", + "ax0/line23/x", + "ax0/line23/y", + "ax0/line24/x", + "ax0/line24/y", + "ax0/line25/x", + "ax0/line25/y", + "ax0/line26/x", + "ax0/line26/y", + "ax0/line27/x", + "ax0/line27/y", + "ax0/line28/x", + "ax0/line28/y", + "ax0/line29/x", + "ax0/line29/y", + "ax0/line3/x", + "ax0/line3/y", + "ax0/line4/x", + "ax0/line4/y", + "ax0/line5/x", + "ax0/line5/y", + "ax0/line6/x", + "ax0/line6/y", + "ax0/line7/x", + "ax0/line7/y", + "ax0/line8/x", + "ax0/line8/y", + "ax0/line9/x", + "ax0/line9/y" + ] +} diff --git a/literature/figs/demo_9_multiverse.npz b/literature/figs/demo_9_multiverse.npz new file mode 100644 index 0000000..0e3d952 Binary files /dev/null and b/literature/figs/demo_9_multiverse.npz differ diff --git a/literature/figs/demo_9_multiverse.png b/literature/figs/demo_9_multiverse.png index a8d0d01..0a3e3f7 100644 Binary files a/literature/figs/demo_9_multiverse.png and b/literature/figs/demo_9_multiverse.png differ diff --git a/literature/figs/realdata_1_validation.png b/literature/figs/realdata_1_validation.png new file mode 100644 index 0000000..cd2c753 Binary files /dev/null and b/literature/figs/realdata_1_validation.png differ diff --git a/literature/figs/realdata_2_interferograms.png b/literature/figs/realdata_2_interferograms.png new file mode 100644 index 0000000..53c13ad Binary files /dev/null and b/literature/figs/realdata_2_interferograms.png differ diff --git a/literature/figs/realdata_3_warmup.png b/literature/figs/realdata_3_warmup.png new file mode 100644 index 0000000..500b7f6 Binary files /dev/null and b/literature/figs/realdata_3_warmup.png differ diff --git a/paper/_preamble.tex b/paper/_preamble.tex index 6b44a46..612fa05 100644 --- a/paper/_preamble.tex +++ b/paper/_preamble.tex @@ -79,3 +79,8 @@ \AtBeginEnvironment{tabular}{\singlespacing} \AtBeginEnvironment{tabularx}{\singlespacing} \AtBeginEnvironment{longtable}{\singlespacing} + +% The full manuscript title overflows GJI's odd-page running header. +\makeatletter +\AtBeginDocument{\gdef\@shorttitle{Processing choices in seismic velocity monitoring}} +\makeatother diff --git a/paper/build.py b/paper/build.py index df402bf..8a49e3d 100644 --- a/paper/build.py +++ b/paper/build.py @@ -5,7 +5,8 @@ (currently ``manuscript_marine.qmd`` --- see :data:`SOURCE_CANDIDATES` if it is ever renamed). This script - 1. (optionally) regenerates the synthetic-demo figures into ``literature/figs/``; + 1. (optionally) regenerates every generated figure into ``literature/figs/`` + with numerical sidecars (``python -m codameter.figures``); 2. regenerates the 103-study ``survey.bib`` and ``appendix_table.tex`` from the literature CSV (``paper/build_survey.py``); 3. runs ``quarto render .qmd --to pdf`` which, with ``keep-tex: true``, @@ -20,6 +21,7 @@ python paper/build.py --no-survey # skip the survey/appendix regeneration python paper/build.py --qmd manuscript_marine.qmd # pin the source explicitly """ + from __future__ import annotations import argparse @@ -122,10 +124,18 @@ def main() -> int: print(f"manuscript source: {source.relative_to(ROOT)}") if args.figures: - run([sys.executable, "literature/synthetic_dvv_demo.py"], ROOT) + # One driver for every generated figure, each with .npz/.json sidecars + # (codameter.figures). The three real-data figures are external; see + # literature/figs/SOURCES.md. + run( + [sys.executable, "-m", "codameter.figures", "--out", "literature/figs"], + ROOT, + ) if not args.no_survey: run([sys.executable, "paper/build_survey.py"], ROOT) + # Calibration table from the archived runs (paper/data/calibration/). + run([sys.executable, "paper/build_calibration_table.py"], ROOT) # Quarto reads/writes relative to the .qmd directory. run(["quarto", "render", source.name, "--to", "pdf"], HERE) diff --git a/paper/build_calibration_table.py b/paper/build_calibration_table.py new file mode 100644 index 0000000..4673eae --- /dev/null +++ b/paper/build_calibration_table.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python3 +"""Write paper/calibration_table.tex from the calibration JSON files. + +Reads locked runs (or pilots if no locked files exist) written by +``python -m codameter.calibration`` and emits one LaTeX table column per scenario: +scenario, number of realisations, member-level 68 and 95 percent coverage +(mean and standard error across realisations), credible-band coverage, the +mu +- sigma_Cd coverage, median sigma_Cd, shared bias, RMSE of mu, and the +prior shares. The manuscript inputs the file as ``\\input{calibration_table.tex}`` +so the quoted numbers and the archived runs cannot drift apart. +""" + +from __future__ import annotations + +import json +from pathlib import Path + +HERE = Path(__file__).resolve().parent +SRC = HERE / "data" / "calibration" +OUT = HERE / "calibration_table.tex" + + +def _pm(m: dict, scale: float = 1.0, digits: int = 3) -> str: + if m is None or m.get("mean") is None: + return "--" + mean = m["mean"] * scale + if m.get("se") is None: + return f"{mean:.{digits}f}" + se = m["se"] * scale + # Preserve the distinction between small Monte Carlo error and zero. + se_text = f"{se:.{digits}f}" + while se > 0 and float(se_text) == 0: + digits += 1 + se_text = f"{se:.{digits}f}" + return f"{mean:.{digits}f} $\\pm$ {se_text}" + + +def main() -> int: + files = sorted(SRC.glob("locked_*.json")) or sorted(SRC.glob("*.json")) + files = sorted(files, key=lambda f: ("clean" not in f.name, "clock" in f.name)) + runs = [json.loads(f.read_text()) for f in files] + if not runs: + raise ValueError("no calibration runs archived") + headings = [ + r["settings"]["scenario"].replace("_", " ") + + f" ($n={r['summary']['n_realizations']}$)" + for r in runs + ] + metrics = [ + ("Member 68\\%", "member_coverage68", 1, 3), + ("Member 95\\%", "member_coverage95", 1, 3), + ("Posterior 95\\%", "coverage95_posterior", 1, 3), + (r"Median $\sigma_{C_d}$ (\%)", "median_sd", 100, 3), + ("Bias (\\%)", "shared_bias", 100, 3), + (r"RMSE($\mu$) (\%)", "rmse", 100, 3), + (r"Prior scale share $\tau^2$", "prior_weight_tau2", 1, 2), + ] + rows = [] + for label, key, scale, digits in metrics: + cells = [_pm(r["summary"][key], scale, digits) for r in runs] + rows.append(label + " & " + " & ".join(cells) + r" \\") + body = "\n".join(rows) + header = "Quantity & " + " & ".join(headings) + r" \\" + OUT.write_text( + "\\begin{table}\n\\footnotesize\n" + "\\caption{Coverage calibration of the Bayesian measurement model over " + "independent synthetic realisations of the volcano scenario (2.5 years, " + "SNR 7, 4-day cadence, 12-member ensemble). Member coverage: fraction of " + "member epochs with $|m_k(t)-\\mathrm{truth}(t)|\\le z\\,\\sigma_{C_d}(t)$, the " + "target of the proposed single-member error scale. These pointwise tests " + "do not validate the temporal covariance. Nominal 68\\% intervals overcover. " + "Posterior: fraction of epochs whose 95\\% credible band on $\\mu$ contains " + "the truth. " + "Means with standard errors across realisations; no realisation failed; " + "$\\sigma_{C_d}$, bias and RMSE in percent; prior $\\tau^2$ is the fraction of " + "conditional posterior rate supplied by the prior scale term (the $\\lambda$ ratio is " + "below 0.01 throughout). " + "Clock drift: $4\\times10^{-5}$\\,s/day from 40\\% of the record; the " + "two-branch measurement cancels it. Shared source: a seasonal source " + "effect warping the coda beyond 6\\,s lapse with a spurious 0.2\\% " + "seasonal \\dvv, seen by every configuration. Generated from " + "\\texttt{paper/data/calibration/} by \\texttt{paper/build\\_calibration\\_table.py}.}\n" + "\\label{tab:calibration}\n" + "\\begin{tabularx}{\\textwidth}{@{}L" + + "r" * len(runs) + + "@{}}\n\\toprule\n" + + header + + "\n\\midrule\n" + + body + + "\n\\bottomrule\n\\end{tabularx}\n\\end{table}\n" + ) + print(f"wrote {OUT} ({len(rows)} rows from {len(files)} files)") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/paper/calibration_table.tex b/paper/calibration_table.tex new file mode 100644 index 0000000..00f3b66 --- /dev/null +++ b/paper/calibration_table.tex @@ -0,0 +1,18 @@ +\begin{table} +\footnotesize +\caption{Coverage calibration of the Bayesian measurement model over independent synthetic realisations of the volcano scenario (2.5 years, SNR 7, 4-day cadence, 12-member ensemble). Member coverage: fraction of member epochs with $|m_k(t)-\mathrm{truth}(t)|\le z\,\sigma_{C_d}(t)$, the target of the proposed single-member error scale. These pointwise tests do not validate the temporal covariance. Nominal 68\% intervals overcover. Posterior: fraction of epochs whose 95\% credible band on $\mu$ contains the truth. Means with standard errors across realisations; no realisation failed; $\sigma_{C_d}$, bias and RMSE in percent; prior $\tau^2$ is the fraction of conditional posterior rate supplied by the prior scale term (the $\lambda$ ratio is below 0.01 throughout). Clock drift: $4\times10^{-5}$\,s/day from 40\% of the record; the two-branch measurement cancels it. Shared source: a seasonal source effect warping the coda beyond 6\,s lapse with a spurious 0.2\% seasonal \dvv, seen by every configuration. Generated from \texttt{paper/data/calibration/} by \texttt{paper/build\_calibration\_table.py}.} +\label{tab:calibration} +\begin{tabularx}{\textwidth}{@{}Lrrr@{}} +\toprule +Quantity & clean ($n=200$) & shared source ($n=200$) & clock drift ($n=200$) \\ +\midrule +Member 68\% & 0.808 $\pm$ 0.001 & 0.795 $\pm$ 0.001 & 0.804 $\pm$ 0.001 \\ +Member 95\% & 0.9561 $\pm$ 0.0003 & 0.9496 $\pm$ 0.0004 & 0.9543 $\pm$ 0.0003 \\ +Posterior 95\% & 0.590 $\pm$ 0.004 & 0.340 $\pm$ 0.004 & 0.604 $\pm$ 0.004 \\ +Median $\sigma_{C_d}$ (\%) & 0.225 $\pm$ 0.001 & 0.330 $\pm$ 0.001 & 0.222 $\pm$ 0.001 \\ +Bias (\%) & -0.017 $\pm$ 0.001 & -0.045 $\pm$ 0.001 & -0.019 $\pm$ 0.001 \\ +RMSE($\mu$) (\%) & 0.0669 $\pm$ 0.0005 & 0.161 $\pm$ 0.001 & 0.0656 $\pm$ 0.0005 \\ +Prior scale share $\tau^2$ & 0.09 $\pm$ 0.01 & 0.025 $\pm$ 0.005 & 0.08 $\pm$ 0.01 \\ +\bottomrule +\end{tabularx} +\end{table} diff --git a/paper/data/calibration/locked_clean_n200.json b/paper/data/calibration/locked_clean_n200.json new file mode 100644 index 0000000..5389a7d --- /dev/null +++ b/paper/data/calibration/locked_clean_n200.json @@ -0,0 +1,5528 @@ +{ + "codameter_version": "0.4.0", + "git_commit": "b426c4e660e50d5bbc705d8541269fd97b97c2ee", + "started_utc": "2026-09-10T19:54:30+00:00", + "finished_utc": "2026-09-10T20:52:14+00:00", + "wall_seconds": 3463.596305, + "settings": { + "scenario": "clean", + "years": 2.5, + "snr": 7.0, + "cadence": 4, + "n_iter": 1200, + "burn": 400, + "thin": 2 + }, + "seeds": [ + 2000, + 2001, + 2002, + 2003, + 2004, + 2005, + 2006, + 2007, + 2008, + 2009, + 2010, + 2011, + 2012, + 2013, + 2014, + 2015, + 2016, + 2017, + 2018, + 2019, + 2020, + 2021, + 2022, + 2023, + 2024, + 2025, + 2026, + 2027, + 2028, + 2029, + 2030, + 2031, + 2032, + 2033, + 2034, + 2035, + 2036, + 2037, + 2038, + 2039, + 2040, + 2041, + 2042, + 2043, + 2044, + 2045, + 2046, + 2047, + 2048, + 2049, + 2050, + 2051, + 2052, + 2053, + 2054, + 2055, + 2056, + 2057, + 2058, + 2059, + 2060, + 2061, + 2062, + 2063, + 2064, + 2065, + 2066, + 2067, + 2068, + 2069, + 2070, + 2071, + 2072, + 2073, + 2074, + 2075, + 2076, + 2077, + 2078, + 2079, + 2080, + 2081, + 2082, + 2083, + 2084, + 2085, + 2086, + 2087, + 2088, + 2089, + 2090, + 2091, + 2092, + 2093, + 2094, + 2095, + 2096, + 2097, + 2098, + 2099, + 2100, + 2101, + 2102, + 2103, + 2104, + 2105, + 2106, + 2107, + 2108, + 2109, + 2110, + 2111, + 2112, + 2113, + 2114, + 2115, + 2116, + 2117, + 2118, + 2119, + 2120, + 2121, + 2122, + 2123, + 2124, + 2125, + 2126, + 2127, + 2128, + 2129, + 2130, + 2131, + 2132, + 2133, + 2134, + 2135, + 2136, + 2137, + 2138, + 2139, + 2140, + 2141, + 2142, + 2143, + 2144, + 2145, + 2146, + 2147, + 2148, + 2149, + 2150, + 2151, + 2152, + 2153, + 2154, + 2155, + 2156, + 2157, + 2158, + 2159, + 2160, + 2161, + 2162, + 2163, + 2164, + 2165, + 2166, + 2167, + 2168, + 2169, + 2170, + 2171, + 2172, + 2173, + 2174, + 2175, + 2176, + 2177, + 2178, + 2179, + 2180, + 2181, + 2182, + 2183, + 2184, + 2185, + 2186, + 2187, + 2188, + 2189, + 2190, + 2191, + 2192, + 2193, + 2194, + 2195, + 2196, + 2197, + 2198, + 2199 + ], + "summary": { + "n_realizations": 200, + "n_failed": 0, + "failures": [], + "margin": 0.03, + "member_coverage68": { + "mean": 0.807920305676856, + "se": 0.0007261762794585474, + "n": 200 + }, + "member_coverage95": { + "mean": 0.9561244541484716, + "se": 0.0003102369938492323, + "n": 200 + }, + "member_rmse": { + "mean": 0.0022935367636978676, + "se": 8.59449577553801e-06, + "n": 200 + }, + "shared_bias": { + "mean": -0.00017097815708316076, + "se": 5.349323923496784e-06, + "n": 200 + }, + "coverage68": { + "mean": 0.9975545851528385, + "se": 0.0001821910006491242, + "n": 200 + }, + "coverage95": { + "mean": 0.9999781659388646, + "se": 2.1834061135371218e-05, + "n": 200 + }, + "coverage95_posterior": { + "mean": 0.5899781659388647, + "se": 0.003691423287111879, + "n": 200 + }, + "median_sd": { + "mean": 0.0022542694726094526, + "se": 6.261568589018551e-06, + "n": 200 + }, + "median_halfwidth95": { + "mean": 0.004418287012613513, + "se": 1.2272449018007158e-05, + "n": 200 + }, + "bias": { + "mean": -0.00017097815708316076, + "se": 5.349323923496784e-06, + "n": 200 + }, + "rmse": { + "mean": 0.000668837656225284, + "se": 4.598936463593073e-06, + "n": 200 + }, + "max_abs_err": { + "mean": 0.002597001055585071, + "se": 4.015044100047297e-05, + "n": 200 + }, + "tau": { + "mean": 0.00024280825391082957, + "se": 7.320078421765792e-06, + "n": 200 + }, + "s": { + "mean": 11.665754049283839, + "se": 0.03135772018801208, + "n": 200 + }, + "corr_length_days": { + "mean": 30.14387295108152, + "se": 0.8627435290075752, + "n": 200 + }, + "n_eff": { + "mean": 32.31681393789955, + "se": 0.6417892519935303, + "n": 200 + }, + "missing_fraction": { + "mean": 0.0, + "se": 0.0, + "n": 200 + }, + "prior_weight_tau2": { + "mean": 0.08898616629409556, + "se": 0.008468411290270143, + "n": 200 + }, + "prior_weight_s2": { + "mean": 5.553086076197376e-14, + "se": 3.0136573501188545e-16, + "n": 200 + }, + "prior_weight_lambda": { + "mean": 2.0436428089713247e-05, + "se": 1.0968623191806546e-06, + "n": 200 + }, + "member_coverage95_within_margin": true, + "member_coverage68_within_margin": false + }, + "results": [ + { + "seed": 2000, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7958515283842795, + "member_coverage95": 0.9552401746724891, + "member_rmse": 0.0020429772046196082, + "shared_bias": -0.00010803126872195994, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5327510917030568, + "median_sd": 0.002119531915425591, + "median_halfwidth95": 0.004154206251085203, + "bias": -0.00010803126872195994, + "rmse": 0.0006206296461172921, + "max_abs_err": 0.00242435083668182, + "tau": 8.994563135910393e-05, + "s": 11.074832091572507, + "corr_length_days": 25.102638023627126, + "n_eff": 38.03460166498179, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.37998106491927547, + "prior_weight_s2": 6.114919917821163e-14, + "prior_weight_lambda": 3.482610737636895e-05 + }, + { + "seed": 2001, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8093158660844251, + "member_coverage95": 0.9566957787481805, + "member_rmse": 0.0021932378793292216, + "shared_bias": -0.00028445185091077036, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.7248908296943232, + "median_sd": 0.0022136424005568655, + "median_halfwidth95": 0.004338659413965037, + "bias": -0.00028445185091077036, + "rmse": 0.0006670097979098636, + "max_abs_err": 0.002431160741592585, + "tau": 0.00038543415760045724, + "s": 11.415633787345671, + "corr_length_days": 61.04967386879167, + "n_eff": 22.893616826815506, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01219930932969702, + "prior_weight_s2": 5.787432999202523e-14, + "prior_weight_lambda": 1.272086002300974e-05 + }, + { + "seed": 2002, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7998544395924309, + "member_coverage95": 0.9541484716157205, + "member_rmse": 0.002296177164237327, + "shared_bias": -0.00024233797422969027, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5414847161572053, + "median_sd": 0.002280216175279114, + "median_halfwidth95": 0.004469141615764754, + "bias": -0.00024233797422969027, + "rmse": 0.000750651508474282, + "max_abs_err": 0.003781621514167738, + "tau": 0.0002858779210332495, + "s": 11.588697235888741, + "corr_length_days": 26.555177785480737, + "n_eff": 25.55955706126277, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.02303059437145119, + "prior_weight_s2": 5.604548705043736e-14, + "prior_weight_lambda": 1.1411537364658345e-05 + }, + { + "seed": 2003, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8180494905385735, + "member_coverage95": 0.9588791848617176, + "member_rmse": 0.0023043164825205975, + "shared_bias": -0.00025399592830345876, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.4978165938864629, + "median_sd": 0.00232096360718788, + "median_halfwidth95": 0.004549005115398386, + "bias": -0.00025399592830345876, + "rmse": 0.0006665582603005457, + "max_abs_err": 0.0017674590520714625, + "tau": 0.00014735612483408913, + "s": 12.025588180242503, + "corr_length_days": 30.11439112028414, + "n_eff": 38.201128932213464, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.11687578428664913, + "prior_weight_s2": 5.1914405014592215e-14, + "prior_weight_lambda": 2.6441183720338543e-05 + }, + { + "seed": 2004, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8027656477438136, + "member_coverage95": 0.9512372634643377, + "member_rmse": 0.0022505759706761214, + "shared_bias": -0.00020080741784614126, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5414847161572053, + "median_sd": 0.0022258348434554044, + "median_halfwidth95": 0.004362556163118228, + "bias": -0.00020080741784614126, + "rmse": 0.0006758900773130642, + "max_abs_err": 0.0029147914206257572, + "tau": 0.00033675027107214474, + "s": 11.453955963115959, + "corr_length_days": 37.155718033362035, + "n_eff": 23.280508966968718, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.014812366631525147, + "prior_weight_s2": 5.719591247798182e-14, + "prior_weight_lambda": 2.678344534048347e-05 + }, + { + "seed": 2005, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8293304221251819, + "member_coverage95": 0.9581513828238719, + "member_rmse": 0.0025042831259372133, + "shared_bias": -0.00018381504320114206, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6375545851528385, + "median_sd": 0.002436615999828301, + "median_halfwidth95": 0.004775679641487476, + "bias": -0.00018381504320114206, + "rmse": 0.0006658210885483213, + "max_abs_err": 0.0023753408513045317, + "tau": 0.000472081099110869, + "s": 12.321436470313797, + "corr_length_days": 37.13141807517663, + "n_eff": 19.305986590123215, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.00792394749000607, + "prior_weight_s2": 4.9541669697431786e-14, + "prior_weight_lambda": 1.8047051430297987e-05 + }, + { + "seed": 2006, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8111353711790393, + "member_coverage95": 0.9599708879184862, + "member_rmse": 0.0024656008947137177, + "shared_bias": -0.0002753851281809271, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5938864628820961, + "median_sd": 0.002286901702197768, + "median_halfwidth95": 0.004482245007846346, + "bias": -0.0002753851281809271, + "rmse": 0.0007163433974986284, + "max_abs_err": 0.0024539809637212327, + "tau": 0.0004645638984748826, + "s": 11.621587277182456, + "corr_length_days": 33.89799030948579, + "n_eff": 16.888796925366286, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.007678234675567885, + "prior_weight_s2": 5.5788890099326624e-14, + "prior_weight_lambda": 1.6447989451074896e-05 + }, + { + "seed": 2007, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8104075691411936, + "member_coverage95": 0.9570596797671034, + "member_rmse": 0.0023886558608840263, + "shared_bias": -0.00018138450883741517, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5720524017467249, + "median_sd": 0.0023586633592212265, + "median_halfwidth95": 0.004622895272192672, + "bias": -0.00018138450883741517, + "rmse": 0.0007522916014784285, + "max_abs_err": 0.0030388753835325993, + "tau": 0.00022365672734799057, + "s": 12.215173523975006, + "corr_length_days": 33.20400448281352, + "n_eff": 36.48570863619896, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.04311834139626083, + "prior_weight_s2": 5.040111129256685e-14, + "prior_weight_lambda": 1.3970486458058348e-05 + }, + { + "seed": 2008, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8220524017467249, + "member_coverage95": 0.9621542940320232, + "member_rmse": 0.0023020158950433846, + "shared_bias": -0.0003053783416847817, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6200873362445415, + "median_sd": 0.0022757044231455988, + "median_halfwidth95": 0.00446029874400614, + "bias": -0.0003053783416847817, + "rmse": 0.0006322963018323987, + "max_abs_err": 0.0020847633751079997, + "tau": 0.0004188329190099956, + "s": 11.777534184996062, + "corr_length_days": 28.9369437775835, + "n_eff": 19.04749543927452, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.009739407550246406, + "prior_weight_s2": 5.411495309641055e-14, + "prior_weight_lambda": 3.174236602515858e-05 + }, + { + "seed": 2009, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8129548762736536, + "member_coverage95": 0.9581513828238719, + "member_rmse": 0.0024422355430002525, + "shared_bias": -0.000258828274194729, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5676855895196506, + "median_sd": 0.002410642381266583, + "median_halfwidth95": 0.0047247722841567774, + "bias": -0.000258828274194729, + "rmse": 0.0007619162237276303, + "max_abs_err": 0.0020586536722025425, + "tau": 0.00022404823066571103, + "s": 12.52615500222273, + "corr_length_days": 45.52064265004798, + "n_eff": 37.01168542430314, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.041572628170547715, + "prior_weight_s2": 4.8023011380112596e-14, + "prior_weight_lambda": 1.1097425930956089e-05 + }, + { + "seed": 2010, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7983988355167394, + "member_coverage95": 0.9526928675400291, + "member_rmse": 0.0022700289074574164, + "shared_bias": -0.00024350220402745426, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.62882096069869, + "median_sd": 0.0022457251426271315, + "median_halfwidth95": 0.0044015404334440435, + "bias": -0.00024350220402745426, + "rmse": 0.0007047800164682541, + "max_abs_err": 0.001980288903318735, + "tau": 0.0003055801457936125, + "s": 11.618952261002953, + "corr_length_days": 26.525397025988624, + "n_eff": 23.97167262607392, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.019913364205404467, + "prior_weight_s2": 5.5965425423982057e-14, + "prior_weight_lambda": 7.80197810892009e-06 + }, + { + "seed": 2011, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8067685589519651, + "member_coverage95": 0.9552401746724891, + "member_rmse": 0.0023467865496066796, + "shared_bias": -0.0003053526912453135, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5895196506550219, + "median_sd": 0.0022146852428989367, + "median_halfwidth95": 0.004340703347413172, + "bias": -0.0003053526912453135, + "rmse": 0.0006340150661864661, + "max_abs_err": 0.0021426654165416672, + "tau": 0.0003286902898709906, + "s": 11.409619429872842, + "corr_length_days": 27.39637826343665, + "n_eff": 22.64677740761157, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.015220853301660226, + "prior_weight_s2": 5.789369795389777e-14, + "prior_weight_lambda": 2.2127329494617747e-05 + }, + { + "seed": 2012, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7867540029112081, + "member_coverage95": 0.9512372634643377, + "member_rmse": 0.0022010009686573317, + "shared_bias": -0.00010668288888389525, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5327510917030568, + "median_sd": 0.0021948957053648578, + "median_halfwidth95": 0.004301916566269728, + "bias": -0.00010668288888389525, + "rmse": 0.0006340507677997826, + "max_abs_err": 0.003084349938176744, + "tau": 8.537708862716358e-05, + "s": 11.467232679493208, + "corr_length_days": 20.92116202103975, + "n_eff": 36.81019676026347, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.4791629523935716, + "prior_weight_s2": 5.66065031507889e-14, + "prior_weight_lambda": 6.051701374425066e-05 + }, + { + "seed": 2013, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8111353711790393, + "member_coverage95": 0.9541484716157205, + "member_rmse": 0.0023715509494582456, + "shared_bias": -0.00013022126712787632, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6157205240174672, + "median_sd": 0.002323464816461934, + "median_halfwidth95": 0.004553907395531998, + "bias": -0.00013022126712787632, + "rmse": 0.0006831393103281145, + "max_abs_err": 0.003061258322832804, + "tau": 0.00021337133941661974, + "s": 11.8929846476407, + "corr_length_days": 22.786251659223815, + "n_eff": 28.771138738686876, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.047084414197490716, + "prior_weight_s2": 5.3356651755481925e-14, + "prior_weight_lambda": 1.0241602258555537e-05 + }, + { + "seed": 2014, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7987627365356623, + "member_coverage95": 0.9516011644832606, + "member_rmse": 0.0021734684880817235, + "shared_bias": -0.00015913162929418986, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5152838427947598, + "median_sd": 0.002204543825502123, + "median_halfwidth95": 0.004320826534406443, + "bias": -0.00015913162929418986, + "rmse": 0.0007002972192367226, + "max_abs_err": 0.0025148180369244624, + "tau": 0.00012830676787137156, + "s": 11.588172807711215, + "corr_length_days": 25.243326955783946, + "n_eff": 38.323329843077836, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.1707874145541106, + "prior_weight_s2": 5.608466030084655e-14, + "prior_weight_lambda": 1.184023297546139e-05 + }, + { + "seed": 2015, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8176855895196506, + "member_coverage95": 0.9552401746724891, + "member_rmse": 0.0023837672510387538, + "shared_bias": -0.00019812002988021216, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6331877729257642, + "median_sd": 0.0022475447008395385, + "median_halfwidth95": 0.004405106702036266, + "bias": -0.00019812002988021216, + "rmse": 0.000636776904662773, + "max_abs_err": 0.0025227640877763646, + "tau": 0.00035582174249247043, + "s": 11.601858195380766, + "corr_length_days": 27.856731834449505, + "n_eff": 21.383334123981655, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.013502426130515872, + "prior_weight_s2": 5.582825480909608e-14, + "prior_weight_lambda": 1.7229741509193166e-05 + }, + { + "seed": 2016, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7987627365356623, + "member_coverage95": 0.9497816593886463, + "member_rmse": 0.002168349069925523, + "shared_bias": -8.205624501292363e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.611353711790393, + "median_sd": 0.002147510310152164, + "median_halfwidth95": 0.004209042897527076, + "bias": -8.205624501292363e-05, + "rmse": 0.0006183108217687086, + "max_abs_err": 0.0032109021013455533, + "tau": 0.00025372132108493007, + "s": 11.045725384906726, + "corr_length_days": 39.96425055490145, + "n_eff": 30.483833785218952, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03032042448304874, + "prior_weight_s2": 6.198761632644629e-14, + "prior_weight_lambda": 1.00642478018059e-05 + }, + { + "seed": 2017, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8107714701601164, + "member_coverage95": 0.9563318777292577, + "member_rmse": 0.002226756450389041, + "shared_bias": -0.00015944366883733645, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6244541484716157, + "median_sd": 0.0023389564725255535, + "median_halfwidth95": 0.004584270483717074, + "bias": -0.00015944366883733645, + "rmse": 0.0006364711890726774, + "max_abs_err": 0.0022958468164819513, + "tau": 0.00028532455052668695, + "s": 11.977221293532521, + "corr_length_days": 28.287253671200435, + "n_eff": 24.426077892932806, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.023755354396909643, + "prior_weight_s2": 5.234113373449635e-14, + "prior_weight_lambda": 2.6066300349327034e-05 + }, + { + "seed": 2018, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8067685589519651, + "member_coverage95": 0.9592430858806404, + "member_rmse": 0.002275460952291553, + "shared_bias": -3.1037622478676834e-05, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6506550218340611, + "median_sd": 0.0022660856804220184, + "median_halfwidth95": 0.004441446354542661, + "bias": -3.1037622478676834e-05, + "rmse": 0.0006171700075433755, + "max_abs_err": 0.00227993287073681, + "tau": 0.00010580889011042925, + "s": 11.719664717380965, + "corr_length_days": 37.47476533002771, + "n_eff": 56.740579850638866, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.29289473981746683, + "prior_weight_s2": 5.5007944146295455e-14, + "prior_weight_lambda": 8.436528238545946e-06 + }, + { + "seed": 2019, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8074963609898108, + "member_coverage95": 0.9592430858806404, + "member_rmse": 0.0022957288420007308, + "shared_bias": -0.00016405844497568997, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6244541484716157, + "median_sd": 0.0022902354649676467, + "median_halfwidth95": 0.0044887790628598484, + "bias": -0.00016405844497568997, + "rmse": 0.0006516997262511495, + "max_abs_err": 0.0030606560329220567, + "tau": 0.00020530384775310664, + "s": 11.973901276159891, + "corr_length_days": 27.227314451968404, + "n_eff": 32.01979325169039, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.05543894252772735, + "prior_weight_s2": 5.26703913890133e-14, + "prior_weight_lambda": 7.77956273052763e-06 + }, + { + "seed": 2020, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8111353711790393, + "member_coverage95": 0.9516011644832606, + "member_rmse": 0.002225082817175845, + "shared_bias": -0.00020400531667055132, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6157205240174672, + "median_sd": 0.002271084237253989, + "median_halfwidth95": 0.0044512433459852774, + "bias": -0.00020400531667055132, + "rmse": 0.0007017492367401642, + "max_abs_err": 0.003020413759233449, + "tau": 0.0001248351397346266, + "s": 11.832630094937496, + "corr_length_days": 30.563998229666772, + "n_eff": 42.0488540552206, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.1814443998610499, + "prior_weight_s2": 5.375530137494363e-14, + "prior_weight_lambda": 1.0971113170999987e-05 + }, + { + "seed": 2021, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8089519650655022, + "member_coverage95": 0.9621542940320232, + "member_rmse": 0.0021129723108517795, + "shared_bias": -0.00011338613780613589, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6768558951965066, + "median_sd": 0.002204990849749954, + "median_halfwidth95": 0.004321702685839319, + "bias": -0.00011338613780613589, + "rmse": 0.0005672127268643163, + "max_abs_err": 0.0017377392478001253, + "tau": 0.0002884769591574421, + "s": 11.411347928205265, + "corr_length_days": 17.23097771511624, + "n_eff": 25.73783043408432, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.019857087099981748, + "prior_weight_s2": 5.795225451501214e-14, + "prior_weight_lambda": 1.1655503274911963e-05 + }, + { + "seed": 2022, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8020378457059679, + "member_coverage95": 0.9541484716157205, + "member_rmse": 0.002247350852087615, + "shared_bias": -4.476296464552174e-05, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.5720524017467249, + "median_sd": 0.00230837511260336, + "median_halfwidth95": 0.004524332119198532, + "bias": -4.476296464552174e-05, + "rmse": 0.0006879131379657901, + "max_abs_err": 0.0037177650256936027, + "tau": 7.923439221194114e-05, + "s": 12.051313048442223, + "corr_length_days": 22.722724887710196, + "n_eff": 37.1924943807293, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.6061470501335887, + "prior_weight_s2": 5.1637746374989667e-14, + "prior_weight_lambda": 2.029066156253998e-05 + }, + { + "seed": 2023, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.787117903930131, + "member_coverage95": 0.9534206695778749, + "member_rmse": 0.00224179872057592, + "shared_bias": -0.0002198226114774014, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5283842794759825, + "median_sd": 0.0022436691860664468, + "median_halfwidth95": 0.004397510832599537, + "bias": -0.0002198226114774014, + "rmse": 0.0007450639675167718, + "max_abs_err": 0.0020627677228765465, + "tau": 0.00013703423770500546, + "s": 11.467382975639447, + "corr_length_days": 40.20266649825255, + "n_eff": 37.27751197733375, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.14407635808051847, + "prior_weight_s2": 5.74961362746908e-14, + "prior_weight_lambda": 9.481055261017482e-06 + }, + { + "seed": 2024, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7962154294032023, + "member_coverage95": 0.9494177583697234, + "member_rmse": 0.002316930945062076, + "shared_bias": -0.00033837336277790336, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5502183406113537, + "median_sd": 0.002276396371287327, + "median_halfwidth95": 0.004461654937453794, + "bias": -0.00033837336277790336, + "rmse": 0.0007400451460933321, + "max_abs_err": 0.002346578721453075, + "tau": 0.00039309828349927823, + "s": 11.606067780780316, + "corr_length_days": 17.736565714373324, + "n_eff": 19.528973576549554, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01099096590160373, + "prior_weight_s2": 5.5621745001326557e-14, + "prior_weight_lambda": 3.8185922237039836e-05 + }, + { + "seed": 2025, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8176855895196506, + "member_coverage95": 0.9581513828238719, + "member_rmse": 0.0023569819231984094, + "shared_bias": -9.78000614774709e-05, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5764192139737991, + "median_sd": 0.0022890424028147553, + "median_halfwidth95": 0.004486440703990419, + "bias": -9.78000614774709e-05, + "rmse": 0.0006883233005176334, + "max_abs_err": 0.0021104219201966475, + "tau": 0.0002531340534775942, + "s": 11.849440061471197, + "corr_length_days": 39.14283860210033, + "n_eff": 31.529452590555447, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03076864160890814, + "prior_weight_s2": 5.370207568105973e-14, + "prior_weight_lambda": 1.1244696842686257e-05 + }, + { + "seed": 2026, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8038573508005823, + "member_coverage95": 0.950509461426492, + "member_rmse": 0.0022441405853187734, + "shared_bias": -0.00010851857407816284, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6593886462882096, + "median_sd": 0.0021981487612993994, + "median_halfwidth95": 0.004308292438791416, + "bias": -0.00010851857407816284, + "rmse": 0.0006363846245130662, + "max_abs_err": 0.003201447591389633, + "tau": 0.0003952244420664126, + "s": 11.11687053409064, + "corr_length_days": 29.202521359444383, + "n_eff": 19.2057639561349, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01046160552993551, + "prior_weight_s2": 6.135120598080074e-14, + "prior_weight_lambda": 8.962125046334249e-06 + }, + { + "seed": 2027, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8162299854439592, + "member_coverage95": 0.9526928675400291, + "member_rmse": 0.002648685694966, + "shared_bias": -0.00020812541986035693, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5589519650655022, + "median_sd": 0.0023548992010879754, + "median_halfwidth95": 0.004615517657761193, + "bias": -0.00020812541986035693, + "rmse": 0.0008850219086333574, + "max_abs_err": 0.004869539552602721, + "tau": 0.0002870951911788386, + "s": 12.160914561608399, + "corr_length_days": 14.250831962036155, + "n_eff": 27.57786245051565, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.02320520275924059, + "prior_weight_s2": 5.099637600425985e-14, + "prior_weight_lambda": 1.1840703912874488e-05 + }, + { + "seed": 2028, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8078602620087336, + "member_coverage95": 0.9592430858806404, + "member_rmse": 0.0022357397253855373, + "shared_bias": -8.455729193314249e-05, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6157205240174672, + "median_sd": 0.002260632667732584, + "median_halfwidth95": 0.004430758645979826, + "bias": -8.455729193314249e-05, + "rmse": 0.0005937317185108893, + "max_abs_err": 0.0019117584867691757, + "tau": 0.00037892614953383233, + "s": 11.607766333220852, + "corr_length_days": 27.601819293398325, + "n_eff": 20.40681279236824, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.011797409653778245, + "prior_weight_s2": 5.5704862025590844e-14, + "prior_weight_lambda": 2.968760631602707e-05 + }, + { + "seed": 2029, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8020378457059679, + "member_coverage95": 0.9625181950509462, + "member_rmse": 0.002050113001102935, + "shared_bias": -8.476118028642492e-05, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5720524017467249, + "median_sd": 0.0021267674469020847, + "median_halfwidth95": 0.004168387632299998, + "bias": -8.476118028642492e-05, + "rmse": 0.0005915591277354847, + "max_abs_err": 0.0018271579411058376, + "tau": 0.00026658332267815593, + "s": 10.94038861470866, + "corr_length_days": 17.484168146614323, + "n_eff": 27.743784707285275, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.02793439362149671, + "prior_weight_s2": 6.281588599456304e-14, + "prior_weight_lambda": 2.223832127730317e-05 + }, + { + "seed": 2030, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8100436681222707, + "member_coverage95": 0.9581513828238719, + "member_rmse": 0.002400631141305832, + "shared_bias": -0.00017136709209142695, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6593886462882096, + "median_sd": 0.0023020657080159304, + "median_halfwidth95": 0.004511965913345736, + "bias": -0.00017136709209142695, + "rmse": 0.0006265069317579375, + "max_abs_err": 0.002772077681725412, + "tau": 0.00036174705483515637, + "s": 11.82936360839896, + "corr_length_days": 43.66557339094592, + "n_eff": 26.939159320068093, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.013089508702394899, + "prior_weight_s2": 5.368516933876757e-14, + "prior_weight_lambda": 1.7185416431250572e-05 + }, + { + "seed": 2031, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8271470160116449, + "member_coverage95": 0.9596069868995634, + "member_rmse": 0.0025395838561594036, + "shared_bias": -0.00011074742062418696, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6681222707423581, + "median_sd": 0.0024180561412015704, + "median_halfwidth95": 0.004739302986733995, + "bias": -0.00011074742062418696, + "rmse": 0.0005827574086871947, + "max_abs_err": 0.0023102234585141053, + "tau": 0.00034123023538510435, + "s": 12.316702668579785, + "corr_length_days": 25.03646766109021, + "n_eff": 23.495683235329903, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.015298792961450336, + "prior_weight_s2": 4.9297899362356285e-14, + "prior_weight_lambda": 3.709662167083284e-05 + }, + { + "seed": 2032, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7951237263464338, + "member_coverage95": 0.9526928675400291, + "member_rmse": 0.0022571379119177113, + "shared_bias": -0.00025228661305334545, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5982532751091703, + "median_sd": 0.0022923961861942804, + "median_halfwidth95": 0.004493013998678087, + "bias": -0.00025228661305334545, + "rmse": 0.0006639214731508023, + "max_abs_err": 0.0021655921060093194, + "tau": 0.0002894892183887233, + "s": 11.812238820980996, + "corr_length_days": 9.702110280246702, + "n_eff": 30.31941339758849, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.022118472316267016, + "prior_weight_s2": 5.3932989080930466e-14, + "prior_weight_lambda": 1.9276905896800102e-05 + }, + { + "seed": 2033, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8417030567685589, + "member_coverage95": 0.9599708879184862, + "member_rmse": 0.0024670907294108185, + "shared_bias": -0.00021141440938089918, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5676855895196506, + "median_sd": 0.00246287093825697, + "median_halfwidth95": 0.004827138375629885, + "bias": -0.00021141440938089918, + "rmse": 0.0006276687554323375, + "max_abs_err": 0.002492352397304987, + "tau": 0.00012735601902671387, + "s": 12.61220555439457, + "corr_length_days": 10.858841659273963, + "n_eff": 46.00124890050552, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.17972491979131297, + "prior_weight_s2": 4.67474766852772e-14, + "prior_weight_lambda": 5.742437363624633e-05 + }, + { + "seed": 2034, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8184133915574964, + "member_coverage95": 0.9617903930131004, + "member_rmse": 0.002307109057481371, + "shared_bias": -0.00024852199390485363, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5545851528384279, + "median_sd": 0.0022450530476472606, + "median_halfwidth95": 0.004400223151478915, + "bias": -0.00024852199390485363, + "rmse": 0.0006856337733036411, + "max_abs_err": 0.0026542830024445805, + "tau": 0.00032121039204267344, + "s": 11.55541892218801, + "corr_length_days": 23.43900573540665, + "n_eff": 24.28258590949234, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01756377264912014, + "prior_weight_s2": 5.617694863447849e-14, + "prior_weight_lambda": 3.659510628024082e-05 + }, + { + "seed": 2035, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7918486171761281, + "member_coverage95": 0.9526928675400291, + "member_rmse": 0.002176531429788858, + "shared_bias": -3.9838909457154e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6637554585152838, + "median_sd": 0.0021222061644282416, + "median_halfwidth95": 0.004159447682857434, + "bias": -3.9838909457154e-05, + "rmse": 0.0006678870362424084, + "max_abs_err": 0.0032231704991668936, + "tau": 0.00010713644480728072, + "s": 10.930395436540994, + "corr_length_days": 27.534353564571116, + "n_eff": 38.52540784971867, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.2553037872472589, + "prior_weight_s2": 6.342565795148562e-14, + "prior_weight_lambda": 6.946158315776766e-06 + }, + { + "seed": 2036, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7962154294032023, + "member_coverage95": 0.9490538573508006, + "member_rmse": 0.00229655673096714, + "shared_bias": -0.00031406819623351075, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5851528384279476, + "median_sd": 0.002274345819895408, + "median_halfwidth95": 0.004457635930545484, + "bias": -0.00031406819623351075, + "rmse": 0.0007658952003758081, + "max_abs_err": 0.0023623461388036044, + "tau": 0.000503700532224136, + "s": 11.422936953494212, + "corr_length_days": 46.410025461068265, + "n_eff": 15.378172895993687, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.00673844545189193, + "prior_weight_s2": 5.774483225017696e-14, + "prior_weight_lambda": 1.388866470995914e-05 + }, + { + "seed": 2037, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8074963609898108, + "member_coverage95": 0.9577874818049491, + "member_rmse": 0.0022873686138016147, + "shared_bias": -0.00013631289034773158, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.62882096069869, + "median_sd": 0.0022336453002499185, + "median_halfwidth95": 0.004377864377259032, + "bias": -0.00013631289034773158, + "rmse": 0.0005558589105878874, + "max_abs_err": 0.0022977619832504665, + "tau": 0.00014907792605676332, + "s": 11.70076889062281, + "corr_length_days": 37.59431635062535, + "n_eff": 45.43792053214534, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.12111232604510147, + "prior_weight_s2": 5.4659685299364153e-14, + "prior_weight_lambda": 3.733097228798306e-05 + }, + { + "seed": 2038, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8114992721979621, + "member_coverage95": 0.9588791848617176, + "member_rmse": 0.002474750614560264, + "shared_bias": -8.298979526800382e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6200873362445415, + "median_sd": 0.0024239185971710753, + "median_halfwidth95": 0.00475079318938581, + "bias": -8.298979526800382e-05, + "rmse": 0.000650872811913257, + "max_abs_err": 0.003130599429873741, + "tau": 0.0003476295029080537, + "s": 12.511761367914009, + "corr_length_days": 25.676876184007806, + "n_eff": 24.102684731725095, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.015701589175638186, + "prior_weight_s2": 4.781152700128906e-14, + "prior_weight_lambda": 3.479362515678865e-05 + }, + { + "seed": 2039, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8038573508005823, + "member_coverage95": 0.9534206695778749, + "member_rmse": 0.0022450848119198877, + "shared_bias": -0.00028934453722539294, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6069868995633187, + "median_sd": 0.0021882632052999712, + "median_halfwidth95": 0.004288917104912553, + "bias": -0.00028934453722539294, + "rmse": 0.0006660915948180779, + "max_abs_err": 0.00212167242919476, + "tau": 0.0002738090046085734, + "s": 11.103999352253108, + "corr_length_days": 49.99877166855152, + "n_eff": 33.43759206284607, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.025134290924962104, + "prior_weight_s2": 6.098640487375836e-14, + "prior_weight_lambda": 1.4308311492440378e-05 + }, + { + "seed": 2040, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8093158660844251, + "member_coverage95": 0.9516011644832606, + "member_rmse": 0.0023294295787015433, + "shared_bias": -0.00012904403689009724, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5065502183406113, + "median_sd": 0.0023206537893706875, + "median_halfwidth95": 0.00454839788363013, + "bias": -0.00012904403689009724, + "rmse": 0.0006650472698677797, + "max_abs_err": 0.0029463539286726866, + "tau": 0.00041391895649608464, + "s": 11.811242293008867, + "corr_length_days": 34.29249798720407, + "n_eff": 19.42354743457967, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.009289379872826317, + "prior_weight_s2": 5.361011353464038e-14, + "prior_weight_lambda": 5.653058575426799e-05 + }, + { + "seed": 2041, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8042212518195051, + "member_coverage95": 0.950509461426492, + "member_rmse": 0.0022350837551446787, + "shared_bias": -6.584446100677998e-05, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6200873362445415, + "median_sd": 0.0022853743620533254, + "median_halfwidth95": 0.004479251476147484, + "bias": -6.584446100677998e-05, + "rmse": 0.0007892455620095224, + "max_abs_err": 0.0026360803877445256, + "tau": 9.00790699158647e-05, + "s": 11.963709493733266, + "corr_length_days": 19.406512011921457, + "n_eff": 34.34920238398187, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.43325445093056264, + "prior_weight_s2": 5.2583181044188665e-14, + "prior_weight_lambda": 1.2838497383993477e-05 + }, + { + "seed": 2042, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8151382823871907, + "member_coverage95": 0.9606986899563319, + "member_rmse": 0.002373420595491269, + "shared_bias": -0.0002090171892993464, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.537117903930131, + "median_sd": 0.0023081482462837003, + "median_halfwidth95": 0.0045238874693791864, + "bias": -0.0002090171892993464, + "rmse": 0.0006701158655076653, + "max_abs_err": 0.0020619068371463853, + "tau": 0.00014323331849521752, + "s": 12.060642046197108, + "corr_length_days": 53.96650083155862, + "n_eff": 53.009445169307725, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.13174183022317473, + "prior_weight_s2": 5.168436295652225e-14, + "prior_weight_lambda": 1.8676445922000736e-05 + }, + { + "seed": 2043, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8045851528384279, + "member_coverage95": 0.9566957787481805, + "member_rmse": 0.0023319849034948935, + "shared_bias": -0.00012300905262675423, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6462882096069869, + "median_sd": 0.0022883484910437434, + "median_halfwidth95": 0.00448508066190006, + "bias": -0.00012300905262675423, + "rmse": 0.000536047348243663, + "max_abs_err": 0.002293335328753868, + "tau": 0.000170822259209645, + "s": 12.020160303788096, + "corr_length_days": 17.09109399602918, + "n_eff": 38.95520978932533, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.08629278390080927, + "prior_weight_s2": 5.1903098034637433e-14, + "prior_weight_lambda": 3.15909047068074e-05 + }, + { + "seed": 2044, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8151382823871907, + "member_coverage95": 0.9625181950509462, + "member_rmse": 0.0023136404570008808, + "shared_bias": -0.000297442904287844, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.49344978165938863, + "median_sd": 0.002373583545417681, + "median_halfwidth95": 0.00465213830001102, + "bias": -0.000297442904287844, + "rmse": 0.0007427261157199888, + "max_abs_err": 0.0017575172981940303, + "tau": 0.00021645628523483173, + "s": 12.35323653002242, + "corr_length_days": 58.27069558577449, + "n_eff": 43.38389870684118, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.04394858996878739, + "prior_weight_s2": 4.941405196323632e-14, + "prior_weight_lambda": 1.4147542081001974e-05 + }, + { + "seed": 2045, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7998544395924309, + "member_coverage95": 0.9537845705967977, + "member_rmse": 0.002171492885853288, + "shared_bias": -4.5907380086526305e-05, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6026200873362445, + "median_sd": 0.0022208574435597793, + "median_halfwidth95": 0.004352800638509199, + "bias": -4.5907380086526305e-05, + "rmse": 0.0006645012755703407, + "max_abs_err": 0.001718287205140433, + "tau": 0.0001636728247593479, + "s": 11.624980481060472, + "corr_length_days": 11.738062252182294, + "n_eff": 39.70562822660038, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.08565260006560108, + "prior_weight_s2": 5.593365652807462e-14, + "prior_weight_lambda": 7.380439384521459e-06 + }, + { + "seed": 2046, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8049490538573508, + "member_coverage95": 0.950509461426492, + "member_rmse": 0.0021863114255283728, + "shared_bias": -0.00020645232022124138, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6375545851528385, + "median_sd": 0.002174228580870565, + "median_halfwidth95": 0.0042614097462773965, + "bias": -0.00020645232022124138, + "rmse": 0.0006148288378807315, + "max_abs_err": 0.0025379628206324526, + "tau": 0.0002492294760252786, + "s": 11.18705295869939, + "corr_length_days": 44.12508738862077, + "n_eff": 30.80821253670048, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.031366041312620926, + "prior_weight_s2": 5.996912630259807e-14, + "prior_weight_lambda": 2.397761756448798e-05 + }, + { + "seed": 2047, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8067685589519651, + "member_coverage95": 0.9574235807860262, + "member_rmse": 0.0021727653034889455, + "shared_bias": -0.0002687911835650058, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5895196506550219, + "median_sd": 0.002171781017362893, + "median_halfwidth95": 0.004256612609914646, + "bias": -0.0002687911835650058, + "rmse": 0.0006400975011963771, + "max_abs_err": 0.002809360354787785, + "tau": 0.00025728573421407935, + "s": 11.348014389375663, + "corr_length_days": 44.802500943965015, + "n_eff": 32.67157807258211, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.02821845938801759, + "prior_weight_s2": 5.863564396432395e-14, + "prior_weight_lambda": 1.6329078398564376e-05 + }, + { + "seed": 2048, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7983988355167394, + "member_coverage95": 0.9599708879184862, + "member_rmse": 0.0023317561890324858, + "shared_bias": -1.1703030266335463e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5720524017467249, + "median_sd": 0.0023197333486309306, + "median_halfwidth95": 0.0045465938529160735, + "bias": -1.1703030266335463e-05, + "rmse": 0.0006372494899109789, + "max_abs_err": 0.002063196858611693, + "tau": 0.00010193643285904224, + "s": 12.067928567708568, + "corr_length_days": 56.72335204212487, + "n_eff": 61.97077406400678, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.3156440152911725, + "prior_weight_s2": 5.158280061604125e-14, + "prior_weight_lambda": 1.5960729336684328e-05 + }, + { + "seed": 2049, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8096797671033479, + "member_coverage95": 0.9574235807860262, + "member_rmse": 0.002372672486454042, + "shared_bias": -9.579301397226132e-05, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5633187772925764, + "median_sd": 0.002354635585695667, + "median_halfwidth95": 0.004615000981082423, + "bias": -9.579301397226132e-05, + "rmse": 0.0006970229586759961, + "max_abs_err": 0.002199790562057216, + "tau": 0.00010504175173803522, + "s": 12.254892366486073, + "corr_length_days": 17.043111418287097, + "n_eff": 37.468870597744896, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.3204659389365094, + "prior_weight_s2": 5.012659278355367e-14, + "prior_weight_lambda": 1.3617611440627225e-05 + }, + { + "seed": 2050, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8064046579330422, + "member_coverage95": 0.9574235807860262, + "member_rmse": 0.002448263423861686, + "shared_bias": -0.0001671045708644526, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5589519650655022, + "median_sd": 0.0022839731283458265, + "median_halfwidth95": 0.0044765051085252, + "bias": -0.0001671045708644526, + "rmse": 0.0007099715234239555, + "max_abs_err": 0.002377462689067746, + "tau": 0.00018862798145067696, + "s": 11.971936567893094, + "corr_length_days": 16.238229111365545, + "n_eff": 35.669781890412224, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.06534964722945595, + "prior_weight_s2": 5.229418757747035e-14, + "prior_weight_lambda": 1.8085431923152698e-05 + }, + { + "seed": 2051, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8013100436681223, + "member_coverage95": 0.9559679767103348, + "member_rmse": 0.002266674054726853, + "shared_bias": -0.00029018297911574025, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5633187772925764, + "median_sd": 0.0022277936018884298, + "median_halfwidth95": 0.004366395259131655, + "bias": -0.00029018297911574025, + "rmse": 0.0006540151699428496, + "max_abs_err": 0.0023014511666269804, + "tau": 0.00026297829624934084, + "s": 11.594823443087176, + "corr_length_days": 20.429769443580295, + "n_eff": 25.885415232924213, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.025745431887864653, + "prior_weight_s2": 5.6059892887756425e-14, + "prior_weight_lambda": 1.2734928897013812e-05 + }, + { + "seed": 2052, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8082241630276564, + "member_coverage95": 0.9661572052401747, + "member_rmse": 0.002241678464513236, + "shared_bias": -0.00018154986739600702, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.5982532751091703, + "median_sd": 0.0023233617627314946, + "median_halfwidth95": 0.004553705413930271, + "bias": -0.00018154986739600702, + "rmse": 0.0007614184805420051, + "max_abs_err": 0.002771700692117905, + "tau": 0.00014827624654204137, + "s": 12.063708661154964, + "corr_length_days": 44.856780157843204, + "n_eff": 43.324806308475594, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.11483705677547469, + "prior_weight_s2": 5.1779548088250223e-14, + "prior_weight_lambda": 1.1416836016921312e-05 + }, + { + "seed": 2053, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8071324599708879, + "member_coverage95": 0.9556040756914119, + "member_rmse": 0.002126638847917608, + "shared_bias": -0.00015173302838694804, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6026200873362445, + "median_sd": 0.0021608134169883927, + "median_halfwidth95": 0.004235116508014238, + "bias": -0.00015173302838694804, + "rmse": 0.0006897514000578053, + "max_abs_err": 0.003253245116018648, + "tau": 8.004434606541594e-05, + "s": 11.300663875260202, + "corr_length_days": 23.210908616306604, + "n_eff": 36.02464223193498, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.5195889427001692, + "prior_weight_s2": 5.89269140833467e-14, + "prior_weight_lambda": 1.4103858625076272e-05 + }, + { + "seed": 2054, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8336972343522562, + "member_coverage95": 0.9643377001455604, + "member_rmse": 0.002292268963114418, + "shared_bias": -0.0002554127825496534, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6550218340611353, + "median_sd": 0.0023018114886645393, + "median_halfwidth95": 0.004511467652568905, + "bias": -0.0002554127825496534, + "rmse": 0.0005234338932439409, + "max_abs_err": 0.002049534588324995, + "tau": 0.0003130031311420004, + "s": 11.88007625514324, + "corr_length_days": 7.110353224181385, + "n_eff": 31.420636867628545, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.018189756486788805, + "prior_weight_s2": 5.295949396272077e-14, + "prior_weight_lambda": 4.119739086048535e-05 + }, + { + "seed": 2055, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7943959243085881, + "member_coverage95": 0.9454148471615721, + "member_rmse": 0.0021951410956591796, + "shared_bias": -0.00026829383873042253, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.5938864628820961, + "median_sd": 0.0021439669667073645, + "median_halfwidth95": 0.004202098071935633, + "bias": -0.00026829383873042253, + "rmse": 0.0007242261872038196, + "max_abs_err": 0.003393591150245501, + "tau": 0.00021294289448126798, + "s": 11.245791929509759, + "corr_length_days": 38.45327533819959, + "n_eff": 30.426693673246696, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.043548420420831256, + "prior_weight_s2": 5.960932906044396e-14, + "prior_weight_lambda": 1.2880724920409268e-05 + }, + { + "seed": 2056, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8034934497816594, + "member_coverage95": 0.9585152838427947, + "member_rmse": 0.0022507471576028062, + "shared_bias": -0.00024165558808879613, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5414847161572053, + "median_sd": 0.0022033614685920597, + "median_halfwidth95": 0.004318509157427567, + "bias": -0.00024165558808879613, + "rmse": 0.0006981352480150333, + "max_abs_err": 0.0019926623311726345, + "tau": 0.00023173846937309854, + "s": 11.71618227161035, + "corr_length_days": 14.304270595899034, + "n_eff": 33.144178538284365, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03892516073736479, + "prior_weight_s2": 5.4754434250081406e-14, + "prior_weight_lambda": 2.1054276124659862e-05 + }, + { + "seed": 2057, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7976710334788938, + "member_coverage95": 0.9526928675400291, + "member_rmse": 0.0023289960984393767, + "shared_bias": -3.2681844400647156e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6244541484716157, + "median_sd": 0.0022502829674673915, + "median_halfwidth95": 0.004410473606049258, + "bias": -3.2681844400647156e-05, + "rmse": 0.0006636970169698322, + "max_abs_err": 0.003906428759515818, + "tau": 0.00020152522274413654, + "s": 11.794863754401328, + "corr_length_days": 48.02970045782309, + "n_eff": 35.69419363790881, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.05451423456450986, + "prior_weight_s2": 5.428754767425413e-14, + "prior_weight_lambda": 9.050350283770952e-06 + }, + { + "seed": 2058, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8122270742358079, + "member_coverage95": 0.9625181950509462, + "member_rmse": 0.0024667698626748696, + "shared_bias": -0.00014583016426700858, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5764192139737991, + "median_sd": 0.002364852307577042, + "median_halfwidth95": 0.00463502538816793, + "bias": -0.00014583016426700858, + "rmse": 0.0006010282471806416, + "max_abs_err": 0.0017309914203276072, + "tau": 0.0004179301392573051, + "s": 12.204679278137323, + "corr_length_days": 19.221276180754383, + "n_eff": 19.373165351168225, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.009898618753607301, + "prior_weight_s2": 5.0097233315276896e-14, + "prior_weight_lambda": 7.061906811218208e-05 + }, + { + "seed": 2059, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8264192139737991, + "member_coverage95": 0.9581513828238719, + "member_rmse": 0.002270334651327973, + "shared_bias": -6.525625068470112e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5633187772925764, + "median_sd": 0.0022283385080137793, + "median_halfwidth95": 0.004367463255520719, + "bias": -6.525625068470112e-05, + "rmse": 0.0006275943169845094, + "max_abs_err": 0.0023955220852554873, + "tau": 0.0002220450965260626, + "s": 11.723520883453391, + "corr_length_days": 43.849161511533545, + "n_eff": 40.74122314644985, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.042080967116043845, + "prior_weight_s2": 5.45693791625935e-14, + "prior_weight_lambda": 1.6524315807264528e-05 + }, + { + "seed": 2060, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7965793304221251, + "member_coverage95": 0.9570596797671034, + "member_rmse": 0.002163038537557748, + "shared_bias": -0.000261503898420811, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5633187772925764, + "median_sd": 0.0021766875344219065, + "median_halfwidth95": 0.004266229206715697, + "bias": -0.000261503898420811, + "rmse": 0.0006218074789883896, + "max_abs_err": 0.002303458335952793, + "tau": 0.0002847830347465486, + "s": 11.210855096283076, + "corr_length_days": 32.13213919900429, + "n_eff": 24.487149106647404, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.021952123473720865, + "prior_weight_s2": 5.972195389462608e-14, + "prior_weight_lambda": 1.8672937300593016e-05 + }, + { + "seed": 2061, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8067685589519651, + "member_coverage95": 0.9516011644832606, + "member_rmse": 0.0022044369257856306, + "shared_bias": -0.0002151878134072178, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6419213973799127, + "median_sd": 0.002188212676526389, + "median_halfwidth95": 0.0042888180703353675, + "bias": -0.0002151878134072178, + "rmse": 0.0006164139006313129, + "max_abs_err": 0.001967689560774751, + "tau": 0.000310573621258046, + "s": 11.22050368188576, + "corr_length_days": 15.046826727632476, + "n_eff": 24.492148225554413, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01783662068142963, + "prior_weight_s2": 5.967890657188473e-14, + "prior_weight_lambda": 1.839983032135896e-05 + }, + { + "seed": 2062, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8162299854439592, + "member_coverage95": 0.9577874818049491, + "member_rmse": 0.0023057287084226902, + "shared_bias": -0.00022896688170394967, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6375545851528385, + "median_sd": 0.0023077919053679547, + "median_halfwidth95": 0.004523189054012598, + "bias": -0.00022896688170394967, + "rmse": 0.0006770832330704033, + "max_abs_err": 0.002645905113323662, + "tau": 0.0003189534921611973, + "s": 11.866782533297226, + "corr_length_days": 21.872896076635374, + "n_eff": 24.64836769777443, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.017595846970064333, + "prior_weight_s2": 5.368443212940373e-14, + "prior_weight_lambda": 9.868099299858225e-06 + }, + { + "seed": 2063, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8013100436681223, + "member_coverage95": 0.9490538573508006, + "member_rmse": 0.0021593130250078876, + "shared_bias": -9.844959922219509e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.62882096069869, + "median_sd": 0.002261601387580905, + "median_halfwidth95": 0.004432657302008621, + "bias": -9.844959922219509e-05, + "rmse": 0.0007001381747218958, + "max_abs_err": 0.0027522103867316725, + "tau": 0.0002445763434007974, + "s": 11.603387607078417, + "corr_length_days": 27.62272892870297, + "n_eff": 26.85365474159763, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.032875344967214566, + "prior_weight_s2": 5.6339471161064707e-14, + "prior_weight_lambda": 5.027480730803662e-06 + }, + { + "seed": 2064, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7969432314410481, + "member_coverage95": 0.9468704512372634, + "member_rmse": 0.002162257396200343, + "shared_bias": -0.00018628618324102088, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.611353711790393, + "median_sd": 0.0021857743935882468, + "median_halfwidth95": 0.004284039123554795, + "bias": -0.00018628618324102088, + "rmse": 0.0006875077808909844, + "max_abs_err": 0.0032025494728298545, + "tau": 0.0003045005668866146, + "s": 11.260349514284862, + "corr_length_days": 38.857370426390496, + "n_eff": 27.56213432120546, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.020200018640674854, + "prior_weight_s2": 5.957984027439916e-14, + "prior_weight_lambda": 8.973417707147788e-06 + }, + { + "seed": 2065, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8249636098981077, + "member_coverage95": 0.960334788937409, + "member_rmse": 0.0024539579555588826, + "shared_bias": -0.00013450807991105236, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.62882096069869, + "median_sd": 0.0023726131091932573, + "median_halfwidth95": 0.004650236279946853, + "bias": -0.00013450807991105236, + "rmse": 0.0007656786955865791, + "max_abs_err": 0.0032416409609258567, + "tau": 0.0003325898031302022, + "s": 12.28432090112424, + "corr_length_days": 49.88517842415365, + "n_eff": 27.721351695886174, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01616025289967949, + "prior_weight_s2": 5.00600082248013e-14, + "prior_weight_lambda": 8.682120777613585e-06 + }, + { + "seed": 2066, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8002183406113537, + "member_coverage95": 0.9483260553129549, + "member_rmse": 0.0022780529766013038, + "shared_bias": -0.00024942217255725436, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.4978165938864629, + "median_sd": 0.002333188811753572, + "median_halfwidth95": 0.004572966076239778, + "bias": -0.00024942217255725436, + "rmse": 0.0006746165971037996, + "max_abs_err": 0.0017303807235602084, + "tau": 0.00020606272463372148, + "s": 12.001269745065638, + "corr_length_days": 26.250351562238095, + "n_eff": 30.903843078545897, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.048486682259336895, + "prior_weight_s2": 5.2203846692062083e-14, + "prior_weight_lambda": 2.4646697288831585e-05 + }, + { + "seed": 2067, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8136826783114993, + "member_coverage95": 0.9556040756914119, + "member_rmse": 0.0021118489926343054, + "shared_bias": -0.00020000814418432485, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6026200873362445, + "median_sd": 0.0021056108790920617, + "median_halfwidth95": 0.0041269215210287934, + "bias": -0.00020000814418432485, + "rmse": 0.0005735451613287844, + "max_abs_err": 0.0030408809356434825, + "tau": 0.0002512515906710975, + "s": 10.908724810481043, + "corr_length_days": 12.457763145464398, + "n_eff": 29.293755602145282, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.029647853784514337, + "prior_weight_s2": 6.280834497130278e-14, + "prior_weight_lambda": 6.69567682923464e-05 + }, + { + "seed": 2068, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8147743813682679, + "member_coverage95": 0.9577874818049491, + "member_rmse": 0.0023969540185757553, + "shared_bias": -0.0002741712724159158, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6506550218340611, + "median_sd": 0.0022909536260302325, + "median_halfwidth95": 0.004490186632688718, + "bias": -0.0002741712724159158, + "rmse": 0.000645385525453871, + "max_abs_err": 0.0022343037516162445, + "tau": 0.00024925110269807474, + "s": 11.8092781842112, + "corr_length_days": 26.764118160562354, + "n_eff": 32.94710310774732, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.030994992619084453, + "prior_weight_s2": 5.4100512834271273e-14, + "prior_weight_lambda": 8.675384118486046e-06 + }, + { + "seed": 2069, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8180494905385735, + "member_coverage95": 0.9570596797671034, + "member_rmse": 0.0023545836676916697, + "shared_bias": -0.00024016538151904826, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6768558951965066, + "median_sd": 0.002307400484535447, + "median_halfwidth95": 0.004522421883272033, + "bias": -0.00024016538151904826, + "rmse": 0.0006220442181544124, + "max_abs_err": 0.0030459627783424818, + "tau": 0.0004546112481718465, + "s": 11.717493497738099, + "corr_length_days": 53.91935647009168, + "n_eff": 19.320057298030754, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.008378922793333736, + "prior_weight_s2": 5.4737556378047977e-14, + "prior_weight_lambda": 2.6041420941285125e-05 + }, + { + "seed": 2070, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8293304221251819, + "member_coverage95": 0.9617903930131004, + "member_rmse": 0.0025269735002806377, + "shared_bias": -0.00041586632811227106, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5589519650655022, + "median_sd": 0.002334040438794336, + "median_halfwidth95": 0.004574635234581102, + "bias": -0.00041586632811227106, + "rmse": 0.0007084418577530662, + "max_abs_err": 0.002411657417154219, + "tau": 0.0005489948290644585, + "s": 11.853629828663973, + "corr_length_days": 43.06800255593759, + "n_eff": 15.176201458680401, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.005301172290811804, + "prior_weight_s2": 5.335863732455123e-14, + "prior_weight_lambda": 4.0989092866505085e-05 + }, + { + "seed": 2071, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8355167394468704, + "member_coverage95": 0.9650655021834061, + "member_rmse": 0.0026238995403404255, + "shared_bias": -8.70136524824458e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6550218340611353, + "median_sd": 0.00252562352346526, + "median_halfwidth95": 0.004950131183545065, + "bias": -8.70136524824458e-05, + "rmse": 0.0006823917348807978, + "max_abs_err": 0.002614030292991929, + "tau": 0.0004553770771863852, + "s": 12.966148278275648, + "corr_length_days": 20.23174500507677, + "n_eff": 18.923299861123176, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.008266510256943574, + "prior_weight_s2": 4.4684143612439166e-14, + "prior_weight_lambda": 1.708173373598379e-05 + }, + { + "seed": 2072, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8169577874818049, + "member_coverage95": 0.9541484716157205, + "member_rmse": 0.0023856805516947023, + "shared_bias": -0.0001810137472987482, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5851528384279476, + "median_sd": 0.0023644841685422605, + "median_halfwidth95": 0.004634303848912763, + "bias": -0.0001810137472987482, + "rmse": 0.0006710731862164624, + "max_abs_err": 0.001686387201081621, + "tau": 0.00014816257816825152, + "s": 12.364091986763345, + "corr_length_days": 48.01746066840723, + "n_eff": 52.107881687537706, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.12125440380097773, + "prior_weight_s2": 4.9243357845048655e-14, + "prior_weight_lambda": 1.0783673558609734e-05 + }, + { + "seed": 2073, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8031295487627366, + "member_coverage95": 0.9461426491994177, + "member_rmse": 0.0022114748475507494, + "shared_bias": -0.00012094205409236902, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6157205240174672, + "median_sd": 0.002158180747019226, + "median_halfwidth95": 0.00422995656965079, + "bias": -0.00012094205409236902, + "rmse": 0.000542767139986371, + "max_abs_err": 0.002192720145483889, + "tau": 0.00022259289949726232, + "s": 11.143549756832039, + "corr_length_days": 44.347455410852774, + "n_eff": 33.8466977879236, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03964284743778323, + "prior_weight_s2": 6.034530663317454e-14, + "prior_weight_lambda": 3.3826189943422615e-05 + }, + { + "seed": 2074, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7998544395924309, + "member_coverage95": 0.9548762736535662, + "member_rmse": 0.0022823499722714443, + "shared_bias": -0.0002314710362260642, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5720524017467249, + "median_sd": 0.0022714206946724104, + "median_halfwidth95": 0.004451902790412916, + "bias": -0.0002314710362260642, + "rmse": 0.0007268483595200465, + "max_abs_err": 0.00186357503677392, + "tau": 0.00015046715001904888, + "s": 11.785495638394387, + "corr_length_days": 40.45195557890159, + "n_eff": 47.13329149131068, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.10976462496272489, + "prior_weight_s2": 5.4122336562883264e-14, + "prior_weight_lambda": 1.9023784944884977e-05 + }, + { + "seed": 2075, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8089519650655022, + "member_coverage95": 0.9585152838427947, + "member_rmse": 0.0022760260005578, + "shared_bias": -0.0001508157663689995, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6375545851528385, + "median_sd": 0.0022563240917289253, + "median_halfwidth95": 0.004422313992121392, + "bias": -0.0001508157663689995, + "rmse": 0.0006048312818069537, + "max_abs_err": 0.002449619786560237, + "tau": 0.0001297424625054563, + "s": 11.720257249751413, + "corr_length_days": 51.6520332405606, + "n_eff": 53.71637539258361, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.16147977441876027, + "prior_weight_s2": 5.468005245199089e-14, + "prior_weight_lambda": 2.0100735659375296e-05 + }, + { + "seed": 2076, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8176855895196506, + "member_coverage95": 0.9537845705967977, + "member_rmse": 0.002318472548225302, + "shared_bias": -0.00021298576213661037, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6419213973799127, + "median_sd": 0.0022689931877918966, + "median_halfwidth95": 0.004447144964317357, + "bias": -0.00021298576213661037, + "rmse": 0.0006457513140489901, + "max_abs_err": 0.0018392033026179027, + "tau": 0.0003282618836914732, + "s": 11.69923156956161, + "corr_length_days": 35.59479440573789, + "n_eff": 25.377006210394196, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.016437599004686092, + "prior_weight_s2": 5.488170631740102e-14, + "prior_weight_lambda": 1.8754589472511883e-05 + }, + { + "seed": 2077, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8140465793304221, + "member_coverage95": 0.9556040756914119, + "member_rmse": 0.002412295113286235, + "shared_bias": -0.0001377169145549738, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5807860262008734, + "median_sd": 0.0021676626199303877, + "median_halfwidth95": 0.004248540699209243, + "bias": -0.0001377169145549738, + "rmse": 0.0006820181348205585, + "max_abs_err": 0.0037127263010461793, + "tau": 0.00033818971331658996, + "s": 11.112035054460396, + "corr_length_days": 47.63947804926077, + "n_eff": 24.849514386856544, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.015174091882657843, + "prior_weight_s2": 6.083211813771457e-14, + "prior_weight_lambda": 2.0354497387683556e-05 + }, + { + "seed": 2078, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7976710334788938, + "member_coverage95": 0.9519650655021834, + "member_rmse": 0.002231384277197691, + "shared_bias": -0.0001687603643959596, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.4672489082969432, + "median_sd": 0.0021879005772728398, + "median_halfwidth95": 0.004288206367033984, + "bias": -0.0001687603643959596, + "rmse": 0.000766965499974148, + "max_abs_err": 0.0024845797907789937, + "tau": 0.00024343239216845027, + "s": 11.317480534760664, + "corr_length_days": 24.207405950213673, + "n_eff": 27.489246760233716, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03300102564455397, + "prior_weight_s2": 5.865333345314505e-14, + "prior_weight_lambda": 2.843038256299101e-05 + }, + { + "seed": 2079, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8031295487627366, + "member_coverage95": 0.9545123726346434, + "member_rmse": 0.002270617900859367, + "shared_bias": -0.00013803104554192607, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5895196506550219, + "median_sd": 0.0022207408837797552, + "median_halfwidth95": 0.004352572185536504, + "bias": -0.00013803104554192607, + "rmse": 0.0006293909765379417, + "max_abs_err": 0.0017141538420500982, + "tau": 0.00010436395527195521, + "s": 11.492599336018163, + "corr_length_days": 24.725448199813545, + "n_eff": 40.924532147137064, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.2755690714260425, + "prior_weight_s2": 5.6705162077698336e-14, + "prior_weight_lambda": 2.5547229673769428e-05 + }, + { + "seed": 2080, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8165938864628821, + "member_coverage95": 0.960334788937409, + "member_rmse": 0.002513327090708347, + "shared_bias": -0.0002564179342044775, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6026200873362445, + "median_sd": 0.002293308933235401, + "median_halfwidth95": 0.004494802950019789, + "bias": -0.0002564179342044775, + "rmse": 0.0006532882694034177, + "max_abs_err": 0.002030819539567088, + "tau": 0.00024203183987237702, + "s": 11.874839539644242, + "corr_length_days": 40.4134020333138, + "n_eff": 36.15179353299432, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03490936583941049, + "prior_weight_s2": 5.352082131162466e-14, + "prior_weight_lambda": 1.4907995734132414e-05 + }, + { + "seed": 2081, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8296943231441049, + "member_coverage95": 0.9614264919941776, + "member_rmse": 0.0022862475961788024, + "shared_bias": -0.00012325001337793858, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5938864628820961, + "median_sd": 0.002314692825066451, + "median_halfwidth95": 0.004536714608188542, + "bias": -0.00012325001337793858, + "rmse": 0.0007005826963485597, + "max_abs_err": 0.0033095162024647158, + "tau": 0.00018697773710476441, + "s": 12.03298357275798, + "corr_length_days": 7.811000315277097, + "n_eff": 46.38447158177491, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.07296493051671304, + "prior_weight_s2": 5.181005868041021e-14, + "prior_weight_lambda": 2.611679553874032e-05 + }, + { + "seed": 2082, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8224163027656477, + "member_coverage95": 0.9617903930131004, + "member_rmse": 0.002313798707820402, + "shared_bias": -0.00011599275823734152, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.7467248908296943, + "median_sd": 0.0023101565858350066, + "median_halfwidth95": 0.004527823742599523, + "bias": -0.00011599275823734152, + "rmse": 0.0004778103305644116, + "max_abs_err": 0.002321662022846324, + "tau": 0.00038402125494717553, + "s": 11.869382951648662, + "corr_length_days": 11.043975322482003, + "n_eff": 22.81875629897657, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.012140837476839573, + "prior_weight_s2": 5.2924467465013e-14, + "prior_weight_lambda": 0.00013319323133104295 + }, + { + "seed": 2083, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8165938864628821, + "member_coverage95": 0.9614264919941776, + "member_rmse": 0.002348563100914844, + "shared_bias": -0.00013728215081919285, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.519650655021834, + "median_sd": 0.0023182167877320928, + "median_halfwidth95": 0.004543621448150544, + "bias": -0.00013728215081919285, + "rmse": 0.000707016709340849, + "max_abs_err": 0.0022990975439340696, + "tau": 0.0002721055475370101, + "s": 12.23875961919628, + "corr_length_days": 32.27420063343758, + "n_eff": 29.580805933623534, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.025409929403636133, + "prior_weight_s2": 4.9847293003756775e-14, + "prior_weight_lambda": 4.291619107050706e-05 + }, + { + "seed": 2084, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8031295487627366, + "member_coverage95": 0.9563318777292577, + "member_rmse": 0.00221374736695883, + "shared_bias": -0.00011534730104085607, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6244541484716157, + "median_sd": 0.0021841323751265913, + "median_halfwidth95": 0.004280820826482614, + "bias": -0.00011534730104085607, + "rmse": 0.0006386370548572486, + "max_abs_err": 0.0033857318196769057, + "tau": 0.00018256322929395915, + "s": 11.257139700896701, + "corr_length_days": 24.2786071257978, + "n_eff": 32.405302324245, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.07047222631259473, + "prior_weight_s2": 5.94801582539348e-14, + "prior_weight_lambda": 1.7421111624846754e-05 + }, + { + "seed": 2085, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8144104803493449, + "member_coverage95": 0.9537845705967977, + "member_rmse": 0.002333526738233311, + "shared_bias": -4.124750847252258e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6550218340611353, + "median_sd": 0.002265470159806369, + "median_halfwidth95": 0.00444023995629473, + "bias": -4.124750847252258e-05, + "rmse": 0.0005717262225419493, + "max_abs_err": 0.0024528739008363417, + "tau": 8.405372325696692e-05, + "s": 11.688071971320849, + "corr_length_days": 16.398439993767433, + "n_eff": 40.74431260931822, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.487229780587919, + "prior_weight_s2": 5.476060879380497e-14, + "prior_weight_lambda": 2.615380167772544e-05 + }, + { + "seed": 2086, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8078602620087336, + "member_coverage95": 0.960334788937409, + "member_rmse": 0.0023031852454980933, + "shared_bias": -0.00016700318873654979, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6157205240174672, + "median_sd": 0.002210923267866191, + "median_halfwidth95": 0.0043333300117800915, + "bias": -0.00016700318873654979, + "rmse": 0.0006731593120218422, + "max_abs_err": 0.0030129028692157957, + "tau": 0.00013270950904475086, + "s": 11.434315010544017, + "corr_length_days": 22.10675350624733, + "n_eff": 38.784087781751886, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.15279847649144196, + "prior_weight_s2": 5.762519856907729e-14, + "prior_weight_lambda": 1.4292976440075657e-05 + }, + { + "seed": 2087, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7958515283842795, + "member_coverage95": 0.9577874818049491, + "member_rmse": 0.0021673584321462557, + "shared_bias": -0.00011486504932074312, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5807860262008734, + "median_sd": 0.002277559145948926, + "median_halfwidth95": 0.004463933933930641, + "bias": -0.00011486504932074312, + "rmse": 0.0006690612903707124, + "max_abs_err": 0.0023328482110622625, + "tau": 0.00016042767652578793, + "s": 11.722777971182085, + "corr_length_days": 34.89749117675121, + "n_eff": 35.20535497174148, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.09381210076856682, + "prior_weight_s2": 5.50752544579647e-14, + "prior_weight_lambda": 7.809141539439216e-06 + }, + { + "seed": 2088, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8085880640465793, + "member_coverage95": 0.9523289665211062, + "member_rmse": 0.0021799335184385536, + "shared_bias": -0.00015008068783201536, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6244541484716157, + "median_sd": 0.0022491737115706086, + "median_halfwidth95": 0.004408299504424776, + "bias": -0.00015008068783201536, + "rmse": 0.0006227586414792464, + "max_abs_err": 0.0027252469381305977, + "tau": 0.0001502935543765112, + "s": 11.735434022736818, + "corr_length_days": 9.132642419886126, + "n_eff": 46.703581302336914, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.11854257217189759, + "prior_weight_s2": 5.445860894302598e-14, + "prior_weight_lambda": 2.3252470747689744e-05 + }, + { + "seed": 2089, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8118631732168851, + "member_coverage95": 0.9621542940320232, + "member_rmse": 0.002264283075244728, + "shared_bias": -0.00016511910548788427, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.7248908296943232, + "median_sd": 0.0022596781130342514, + "median_halfwidth95": 0.004428887753135063, + "bias": -0.00016511910548788427, + "rmse": 0.000506426851600276, + "max_abs_err": 0.0021429664648478317, + "tau": 0.00040626461716495324, + "s": 11.527142462878905, + "corr_length_days": 18.289544016162132, + "n_eff": 19.091253522012675, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.010740873519283906, + "prior_weight_s2": 5.635833594277827e-14, + "prior_weight_lambda": 4.68285015029569e-05 + }, + { + "seed": 2090, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8238719068413392, + "member_coverage95": 0.9606986899563319, + "member_rmse": 0.002288762188131945, + "shared_bias": -0.0001057129448404354, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5938864628820961, + "median_sd": 0.0023137808768035825, + "median_halfwidth95": 0.004534927222423457, + "bias": -0.0001057129448404354, + "rmse": 0.0006352391758278887, + "max_abs_err": 0.002410612312036289, + "tau": 0.0002419440678609943, + "s": 12.069208036064985, + "corr_length_days": 40.716232114652406, + "n_eff": 38.10721998782469, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03292485034657242, + "prior_weight_s2": 5.165427450655641e-14, + "prior_weight_lambda": 1.950811267681012e-05 + }, + { + "seed": 2091, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8173216885007278, + "member_coverage95": 0.9552401746724891, + "member_rmse": 0.002333759741839282, + "shared_bias": -0.00013354690784525696, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6375545851528385, + "median_sd": 0.0023052862080466495, + "median_halfwidth95": 0.004518277977467944, + "bias": -0.00013354690784525696, + "rmse": 0.0006425162899389053, + "max_abs_err": 0.0027582598063210645, + "tau": 0.00011999194644975384, + "s": 12.075219210073497, + "corr_length_days": 25.666129962001534, + "n_eff": 44.14757729953623, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.21620367549745875, + "prior_weight_s2": 5.1708065546384206e-14, + "prior_weight_lambda": 1.1917952214911661e-05 + }, + { + "seed": 2092, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8013100436681223, + "member_coverage95": 0.9556040756914119, + "member_rmse": 0.00215547970376428, + "shared_bias": -0.00016334179738929485, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6375545851528385, + "median_sd": 0.0020690431665199775, + "median_halfwidth95": 0.004055250120825161, + "bias": -0.00016334179738929485, + "rmse": 0.0005954343445014859, + "max_abs_err": 0.0027174292612732022, + "tau": 0.00016951122783680122, + "s": 10.69310998599394, + "corr_length_days": 20.83442383130478, + "n_eff": 33.29440612105809, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.07997314478407908, + "prior_weight_s2": 6.565523859600041e-14, + "prior_weight_lambda": 3.108728145204416e-05 + }, + { + "seed": 2093, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7885735080058224, + "member_coverage95": 0.9454148471615721, + "member_rmse": 0.0022074076581086108, + "shared_bias": -0.00012628981447316287, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5152838427947598, + "median_sd": 0.002184628244956837, + "median_halfwidth95": 0.004281792713498582, + "bias": -0.00012628981447316287, + "rmse": 0.0006503194348908433, + "max_abs_err": 0.002306403502196313, + "tau": 0.00024627617047827296, + "s": 11.201921810295072, + "corr_length_days": 29.432266061546553, + "n_eff": 26.665365092955508, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03265462491740386, + "prior_weight_s2": 5.975401712240838e-14, + "prior_weight_lambda": 2.4495769533134743e-05 + }, + { + "seed": 2094, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8286026200873362, + "member_coverage95": 0.9610625909752547, + "member_rmse": 0.002390367007930348, + "shared_bias": -0.00020049312459729534, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6462882096069869, + "median_sd": 0.002362880022632359, + "median_halfwidth95": 0.004631159780678609, + "bias": -0.00020049312459729534, + "rmse": 0.0006177273823036558, + "max_abs_err": 0.002269719983500586, + "tau": 0.000291309926837725, + "s": 12.154690422026624, + "corr_length_days": 35.168075216873866, + "n_eff": 31.202258181058458, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.022451673759192537, + "prior_weight_s2": 5.060598062705007e-14, + "prior_weight_lambda": 5.938073600064307e-05 + }, + { + "seed": 2095, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8005822416302766, + "member_coverage95": 0.9523289665211062, + "member_rmse": 0.0023868870711981735, + "shared_bias": -0.00022770708868142392, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5982532751091703, + "median_sd": 0.0022911703587212232, + "median_halfwidth95": 0.004490611420960683, + "bias": -0.00022770708868142392, + "rmse": 0.000739222521873538, + "max_abs_err": 0.0035006394293516925, + "tau": 0.0002577355416106212, + "s": 11.97950858121091, + "corr_length_days": 22.768716062456978, + "n_eff": 28.14120753580015, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.02950639790170151, + "prior_weight_s2": 5.245660918717303e-14, + "prior_weight_lambda": 1.1915504239429686e-05 + }, + { + "seed": 2096, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8060407569141194, + "member_coverage95": 0.9530567685589519, + "member_rmse": 0.0024567276653680546, + "shared_bias": -0.00026674396622182656, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.62882096069869, + "median_sd": 0.0023316646928829648, + "median_halfwidth95": 0.004569978858121667, + "bias": -0.00026674396622182656, + "rmse": 0.0007262404850809674, + "max_abs_err": 0.0029611910247675506, + "tau": 0.00020674061341136537, + "s": 12.171726857927592, + "corr_length_days": 13.086235969859978, + "n_eff": 35.77824161148897, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.05267752081688794, + "prior_weight_s2": 5.0646990010791746e-14, + "prior_weight_lambda": 2.021652066909959e-05 + }, + { + "seed": 2097, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8129548762736536, + "member_coverage95": 0.9596069868995634, + "member_rmse": 0.0022303449625498575, + "shared_bias": -0.00012677548028221982, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.4847161572052402, + "median_sd": 0.0022617623800702405, + "median_halfwidth95": 0.004432972841491989, + "bias": -0.00012677548028221982, + "rmse": 0.0006999126080146665, + "max_abs_err": 0.0029889854956086283, + "tau": 0.00025015021987001963, + "s": 11.699411185482925, + "corr_length_days": 11.260217967340296, + "n_eff": 32.2354754961427, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0303699688917674, + "prior_weight_s2": 5.481303878719959e-14, + "prior_weight_lambda": 2.216914082657205e-05 + }, + { + "seed": 2098, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8060407569141194, + "member_coverage95": 0.9519650655021834, + "member_rmse": 0.0021781698793512053, + "shared_bias": -0.00015711327873929265, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5982532751091703, + "median_sd": 0.0021708138809156444, + "median_halfwidth95": 0.00425471705729495, + "bias": -0.00015711327873929265, + "rmse": 0.0007000426587630132, + "max_abs_err": 0.0022750583945317683, + "tau": 0.0001801443001305046, + "s": 11.340891751503191, + "corr_length_days": 19.04253718260811, + "n_eff": 33.083684945479725, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.06908646277049797, + "prior_weight_s2": 5.874115587988932e-14, + "prior_weight_lambda": 7.753514608166984e-06 + }, + { + "seed": 2099, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7987627365356623, + "member_coverage95": 0.9508733624454149, + "member_rmse": 0.0024150946801891945, + "shared_bias": 9.926106471045211e-06, + "coverage68": 0.9956331877729258, + "coverage95": 0.9956331877729258, + "coverage95_posterior": 0.5589519650655022, + "median_sd": 0.0022597490524953203, + "median_halfwidth95": 0.004429026791924938, + "bias": 9.926106471045211e-06, + "rmse": 0.0007504741040426803, + "max_abs_err": 0.004055735275875104, + "tau": 0.0003581710744133196, + "s": 11.581527563641089, + "corr_length_days": 34.7149553441999, + "n_eff": 22.64409701698472, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0140027847885084, + "prior_weight_s2": 5.621394877407029e-14, + "prior_weight_lambda": 1.1395758078178699e-05 + }, + { + "seed": 2100, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8147743813682679, + "member_coverage95": 0.9596069868995634, + "member_rmse": 0.0021539523759390353, + "shared_bias": -0.00019919719495090744, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6200873362445415, + "median_sd": 0.002213536740778244, + "median_halfwidth95": 0.004338452324602691, + "bias": -0.00019919719495090744, + "rmse": 0.0006876051729490532, + "max_abs_err": 0.0030752587458454795, + "tau": 0.0001239169069661734, + "s": 11.648186521275788, + "corr_length_days": 24.514739693638756, + "n_eff": 36.435709876768684, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.20242022449626196, + "prior_weight_s2": 5.5833588933925936e-14, + "prior_weight_lambda": 7.251018369574222e-06 + }, + { + "seed": 2101, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8064046579330422, + "member_coverage95": 0.9501455604075691, + "member_rmse": 0.002229023596575403, + "shared_bias": -0.00025560419817116854, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6069868995633187, + "median_sd": 0.002215370026512345, + "median_halfwidth95": 0.004342045498643242, + "bias": -0.00025560419817116854, + "rmse": 0.0006877106557117743, + "max_abs_err": 0.0037465730995129448, + "tau": 0.00023447198329520897, + "s": 11.596587902739168, + "corr_length_days": 30.756684671177865, + "n_eff": 28.385215937187354, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03709541033031656, + "prior_weight_s2": 5.602684676528579e-14, + "prior_weight_lambda": 1.49294857844731e-05 + }, + { + "seed": 2102, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8100436681222707, + "member_coverage95": 0.9596069868995634, + "member_rmse": 0.0025166326472085155, + "shared_bias": -0.00014916452207356087, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5938864628820961, + "median_sd": 0.0023806829875426287, + "median_halfwidth95": 0.004666052950996001, + "bias": -0.00014916452207356087, + "rmse": 0.0006198165269862432, + "max_abs_err": 0.0024069454960241273, + "tau": 0.0001745994735680617, + "s": 12.333459345683304, + "corr_length_days": 6.418354565695633, + "n_eff": 54.4592098323934, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.08563063445839059, + "prior_weight_s2": 4.948757938684297e-14, + "prior_weight_lambda": 2.6731420901390166e-05 + }, + { + "seed": 2103, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8024017467248908, + "member_coverage95": 0.9552401746724891, + "member_rmse": 0.0022740404949788623, + "shared_bias": -0.00023891190984331212, + "coverage68": 0.9868995633187773, + "coverage95": 1.0, + "coverage95_posterior": 0.5414847161572053, + "median_sd": 0.002255639556276889, + "median_halfwidth95": 0.004420972327278677, + "bias": -0.00023891190984331212, + "rmse": 0.0008024419220018326, + "max_abs_err": 0.0029687745730397953, + "tau": 0.0002130713155992258, + "s": 11.62082390124398, + "corr_length_days": 30.619704587366993, + "n_eff": 36.67147630918826, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.044987333353357556, + "prior_weight_s2": 5.573798194144392e-14, + "prior_weight_lambda": 1.4487081959244369e-05 + }, + { + "seed": 2104, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8009461426491994, + "member_coverage95": 0.9523289665211062, + "member_rmse": 0.0022557903167122425, + "shared_bias": -0.0001788742714631679, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.537117903930131, + "median_sd": 0.002140410766238632, + "median_halfwidth95": 0.004195128047040134, + "bias": -0.0001788742714631679, + "rmse": 0.000708906540298277, + "max_abs_err": 0.002753517568248026, + "tau": 0.0004320192089511251, + "s": 11.054768366728206, + "corr_length_days": 16.54940482166173, + "n_eff": 15.898689614426718, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.008781888096743717, + "prior_weight_s2": 6.19754129667259e-14, + "prior_weight_lambda": 1.0042237627486044e-05 + }, + { + "seed": 2105, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7983988355167394, + "member_coverage95": 0.950509461426492, + "member_rmse": 0.002153897752218578, + "shared_bias": -0.0001494014731323354, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5676855895196506, + "median_sd": 0.002142696791085616, + "median_halfwidth95": 0.004199608573443329, + "bias": -0.0001494014731323354, + "rmse": 0.0006444330307748703, + "max_abs_err": 0.0029331492311985004, + "tau": 0.00012929235576394826, + "s": 11.232272154787845, + "corr_length_days": 42.308259907024045, + "n_eff": 38.846320009057784, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.1844941959868097, + "prior_weight_s2": 5.96751129903298e-14, + "prior_weight_lambda": 1.7506546521983327e-05 + }, + { + "seed": 2106, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7976710334788938, + "member_coverage95": 0.9545123726346434, + "member_rmse": 0.0022700088281192785, + "shared_bias": -0.0001113795912221452, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.519650655021834, + "median_sd": 0.002139339442254888, + "median_halfwidth95": 0.0041930282905996595, + "bias": -0.0001113795912221452, + "rmse": 0.0007278225222777022, + "max_abs_err": 0.00210843882390845, + "tau": 0.00015544117506789058, + "s": 11.219359591884839, + "corr_length_days": 32.09691487035739, + "n_eff": 39.19867881793965, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.10452740423516692, + "prior_weight_s2": 6.035867783273932e-14, + "prior_weight_lambda": 5.517639137904145e-06 + }, + { + "seed": 2107, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8136826783114993, + "member_coverage95": 0.9632459970887919, + "member_rmse": 0.0023932745389398224, + "shared_bias": -2.0273139311475137e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5764192139737991, + "median_sd": 0.00224442074690688, + "median_halfwidth95": 0.004398983864790596, + "bias": -2.0273139311475137e-05, + "rmse": 0.000677130695725431, + "max_abs_err": 0.0026799905523044423, + "tau": 0.0002726575466812978, + "s": 11.670470456675172, + "corr_length_days": 24.44237633019548, + "n_eff": 28.892542737967723, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.024825045501008683, + "prior_weight_s2": 5.5078150428010074e-14, + "prior_weight_lambda": 2.166532767727771e-05 + }, + { + "seed": 2108, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7922125181950509, + "member_coverage95": 0.9512372634643377, + "member_rmse": 0.002072481230118281, + "shared_bias": -0.00013290611578665817, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5807860262008734, + "median_sd": 0.00206605396071879, + "median_halfwidth95": 0.004049391385066243, + "bias": -0.00013290611578665817, + "rmse": 0.0006469379609956209, + "max_abs_err": 0.003269913045188588, + "tau": 9.586984348822734e-05, + "s": 10.866300569988995, + "corr_length_days": 34.27356422902372, + "n_eff": 41.66580012086359, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.3275418560792777, + "prior_weight_s2": 6.384060198792488e-14, + "prior_weight_lambda": 1.2984101056937053e-05 + }, + { + "seed": 2109, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8002183406113537, + "member_coverage95": 0.9519650655021834, + "member_rmse": 0.0022531503479600776, + "shared_bias": -5.772633706901611e-05, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.611353711790393, + "median_sd": 0.002165703093807311, + "median_halfwidth95": 0.004244700098550953, + "bias": -5.772633706901611e-05, + "rmse": 0.0005898421197559102, + "max_abs_err": 0.001594088308549531, + "tau": 0.00022415315156675746, + "s": 11.358348263237279, + "corr_length_days": 12.67629898142688, + "n_eff": 34.3414535037909, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03909773551103468, + "prior_weight_s2": 5.87123345812686e-14, + "prior_weight_lambda": 9.785238335927934e-06 + }, + { + "seed": 2110, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8067685589519651, + "member_coverage95": 0.9501455604075691, + "member_rmse": 0.0021235200209948246, + "shared_bias": -9.046944115190963e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5851528384279476, + "median_sd": 0.0020648033180974247, + "median_halfwidth95": 0.0040469401705515015, + "bias": -9.046944115190963e-05, + "rmse": 0.0005733056062892242, + "max_abs_err": 0.0027909862949615184, + "tau": 0.0002037692301977054, + "s": 10.772645221545304, + "corr_length_days": 27.217347495443846, + "n_eff": 31.752471679568668, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.050982106821188755, + "prior_weight_s2": 6.470970596956471e-14, + "prior_weight_lambda": 2.43252810832903e-05 + }, + { + "seed": 2111, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8162299854439592, + "member_coverage95": 0.9581513828238719, + "member_rmse": 0.002324109525455303, + "shared_bias": -0.00026115291122652014, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6026200873362445, + "median_sd": 0.002271013122761725, + "median_halfwidth95": 0.004451103964140561, + "bias": -0.00026115291122652014, + "rmse": 0.0006699114841806159, + "max_abs_err": 0.002513238226502299, + "tau": 0.0002966330950354408, + "s": 11.696535080532572, + "corr_length_days": 26.64203247030765, + "n_eff": 26.99908343354117, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.022143400187255694, + "prior_weight_s2": 5.50055865513647e-14, + "prior_weight_lambda": 1.5825324612568005e-05 + }, + { + "seed": 2112, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8195050946142649, + "member_coverage95": 0.9566957787481805, + "member_rmse": 0.0023415584856503226, + "shared_bias": -0.0001854340309289793, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.5589519650655022, + "median_sd": 0.0023079070955884314, + "median_halfwidth95": 0.0045234148226978846, + "bias": -0.0001854340309289793, + "rmse": 0.0007361347606749439, + "max_abs_err": 0.0025326707368945184, + "tau": 0.0006177886923943105, + "s": 11.490758287931623, + "corr_length_days": 45.052788263089624, + "n_eff": 11.884205094853087, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.004215097115204153, + "prior_weight_s2": 5.730554847604939e-14, + "prior_weight_lambda": 1.0396933658232777e-05 + }, + { + "seed": 2113, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8118631732168851, + "member_coverage95": 0.9592430858806404, + "member_rmse": 0.0023957409516971524, + "shared_bias": -0.0002763912413572821, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5676855895196506, + "median_sd": 0.0022480180954790436, + "median_halfwidth95": 0.004406034538487489, + "bias": -0.0002763912413572821, + "rmse": 0.0006790993325551175, + "max_abs_err": 0.002358226823592431, + "tau": 0.00034621882062081487, + "s": 11.654046411110187, + "corr_length_days": 30.7975891351055, + "n_eff": 23.272751826880583, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.015077644796637094, + "prior_weight_s2": 5.5384043861383265e-14, + "prior_weight_lambda": 2.3164648659699664e-05 + }, + { + "seed": 2114, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8067685589519651, + "member_coverage95": 0.9596069868995634, + "member_rmse": 0.002109588360220933, + "shared_bias": -0.00018800629023532688, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5720524017467249, + "median_sd": 0.002175437648786208, + "median_halfwidth95": 0.004263779475865611, + "bias": -0.00018800629023532688, + "rmse": 0.0005302506082003949, + "max_abs_err": 0.0024762418274194642, + "tau": 0.00026821183558071966, + "s": 11.199001732687275, + "corr_length_days": 25.40311633685463, + "n_eff": 27.078288122253863, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.026584740967865773, + "prior_weight_s2": 5.944532479428202e-14, + "prior_weight_lambda": 9.108062323619504e-05 + }, + { + "seed": 2115, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8093158660844251, + "member_coverage95": 0.9512372634643377, + "member_rmse": 0.0020903204797783174, + "shared_bias": -0.0001419668587172309, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5633187772925764, + "median_sd": 0.002087656886249644, + "median_halfwidth95": 0.004091732341401397, + "bias": -0.0001419668587172309, + "rmse": 0.000638873276519272, + "max_abs_err": 0.0023627109645845096, + "tau": 0.00017917408862994853, + "s": 10.84780930052844, + "corr_length_days": 28.9167576952686, + "n_eff": 33.86612547448095, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.07055754051233457, + "prior_weight_s2": 6.404982144602025e-14, + "prior_weight_lambda": 1.7582505786072762e-05 + }, + { + "seed": 2116, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8096797671033479, + "member_coverage95": 0.9581513828238719, + "member_rmse": 0.0025040427356857434, + "shared_bias": -0.0002768991376744962, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.611353711790393, + "median_sd": 0.002200191262156467, + "median_halfwidth95": 0.004312295666941237, + "bias": -0.0002768991376744962, + "rmse": 0.0006007408276662099, + "max_abs_err": 0.002160175223684198, + "tau": 0.00032772040925409945, + "s": 11.56587185191983, + "corr_length_days": 32.38765194503766, + "n_eff": 24.65374391638061, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.017431460612074217, + "prior_weight_s2": 5.625236971738923e-14, + "prior_weight_lambda": 2.11656370642787e-05 + }, + { + "seed": 2117, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8024017467248908, + "member_coverage95": 0.9574235807860262, + "member_rmse": 0.0022304111835123736, + "shared_bias": -0.00024981879138320486, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5633187772925764, + "median_sd": 0.002232342516647032, + "median_halfwidth95": 0.004375310968297584, + "bias": -0.00024981879138320486, + "rmse": 0.0006875827570203399, + "max_abs_err": 0.0017463529994325797, + "tau": 0.00027012875460645714, + "s": 11.563657570528045, + "corr_length_days": 41.058634713121805, + "n_eff": 31.982773304339844, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.027128941708599693, + "prior_weight_s2": 5.636048363243304e-14, + "prior_weight_lambda": 1.3671082871156511e-05 + }, + { + "seed": 2118, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8147743813682679, + "member_coverage95": 0.9574235807860262, + "member_rmse": 0.0025403322106476367, + "shared_bias": -0.00024253214700757652, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5807860262008734, + "median_sd": 0.0023727814397986424, + "median_halfwidth95": 0.004650566201873507, + "bias": -0.00024253214700757652, + "rmse": 0.0007673794115015229, + "max_abs_err": 0.0038624837333756826, + "tau": 0.0003544932863507204, + "s": 12.013829967176218, + "corr_length_days": 33.588543369143466, + "n_eff": 23.85031629065724, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.014539623763496963, + "prior_weight_s2": 5.2194073269576864e-14, + "prior_weight_lambda": 1.1842104175704216e-05 + }, + { + "seed": 2119, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7823871906841339, + "member_coverage95": 0.9490538573508006, + "member_rmse": 0.0022278925133150146, + "shared_bias": -0.00016356294112198426, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5021834061135371, + "median_sd": 0.0021333489794161655, + "median_halfwidth95": 0.004181287199092425, + "bias": -0.00016356294112198426, + "rmse": 0.0007495277684769144, + "max_abs_err": 0.002363066303627625, + "tau": 0.00010869354139425993, + "s": 11.194199593633439, + "corr_length_days": 29.95641616843922, + "n_eff": 44.292962256708, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.23451327315786005, + "prior_weight_s2": 6.01893290452655e-14, + "prior_weight_lambda": 1.078241706689748e-05 + }, + { + "seed": 2120, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8024017467248908, + "member_coverage95": 0.9563318777292577, + "member_rmse": 0.002243283415106268, + "shared_bias": -0.00010447582475260916, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.537117903930131, + "median_sd": 0.002153036755965487, + "median_halfwidth95": 0.004219874532369139, + "bias": -0.00010447582475260916, + "rmse": 0.0006494709543949674, + "max_abs_err": 0.002358105984729712, + "tau": 0.00010037589426726185, + "s": 11.328427673421546, + "corr_length_days": 46.37221426619289, + "n_eff": 59.334096855632616, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.33362891153470436, + "prior_weight_s2": 5.867533212501523e-14, + "prior_weight_lambda": 1.329102143318606e-05 + }, + { + "seed": 2121, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8020378457059679, + "member_coverage95": 0.9523289665211062, + "member_rmse": 0.0023185114701672767, + "shared_bias": -0.00016649957572706988, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5502183406113537, + "median_sd": 0.0022394290958112468, + "median_halfwidth95": 0.004389200408342594, + "bias": -0.00016649957572706988, + "rmse": 0.0007403966642889811, + "max_abs_err": 0.002823842040978897, + "tau": 0.0003520457421501181, + "s": 11.539632261231148, + "corr_length_days": 43.999716991316134, + "n_eff": 23.34371632828324, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.014237811694160956, + "prior_weight_s2": 5.681101890098886e-14, + "prior_weight_lambda": 7.979542961185753e-06 + }, + { + "seed": 2122, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7969432314410481, + "member_coverage95": 0.9574235807860262, + "member_rmse": 0.0020940106373047536, + "shared_bias": -0.00017400887763002165, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5895196506550219, + "median_sd": 0.0021182601706735645, + "median_halfwidth95": 0.0041517136771540425, + "bias": -0.00017400887763002165, + "rmse": 0.0006856077875134332, + "max_abs_err": 0.0026408924421767494, + "tau": 0.0002355173748415413, + "s": 10.913574952073153, + "corr_length_days": 24.99666076046441, + "n_eff": 30.19552771468321, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03979370737806732, + "prior_weight_s2": 6.371475176633952e-14, + "prior_weight_lambda": 7.163455162889267e-06 + }, + { + "seed": 2123, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8151382823871907, + "member_coverage95": 0.9574235807860262, + "member_rmse": 0.0022415130030363386, + "shared_bias": -0.00022461494631722186, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5676855895196506, + "median_sd": 0.0022422526148153598, + "median_halfwidth95": 0.004394734403943972, + "bias": -0.00022461494631722186, + "rmse": 0.0007526391759968356, + "max_abs_err": 0.002409450041164454, + "tau": 0.00034002615395211657, + "s": 11.67356702243004, + "corr_length_days": 26.697517930183373, + "n_eff": 24.115263603215723, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.014960163314898385, + "prior_weight_s2": 5.533395610305381e-14, + "prior_weight_lambda": 1.460945259116402e-05 + }, + { + "seed": 2124, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8180494905385735, + "member_coverage95": 0.9596069868995634, + "member_rmse": 0.0022920251964780257, + "shared_bias": -9.163160984881395e-05, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6681222707423581, + "median_sd": 0.00223000652264963, + "median_halfwidth95": 0.004370732504158459, + "bias": -9.163160984881395e-05, + "rmse": 0.0006086119279177549, + "max_abs_err": 0.002906819880325327, + "tau": 0.00010330027538045117, + "s": 11.619848366161376, + "corr_length_days": 52.839317475391915, + "n_eff": 55.62046167856072, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.2876053448019565, + "prior_weight_s2": 5.564727623277729e-14, + "prior_weight_lambda": 1.3208288496520069e-05 + }, + { + "seed": 2125, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8085880640465793, + "member_coverage95": 0.960334788937409, + "member_rmse": 0.0023378170187884546, + "shared_bias": -0.00016702327396767852, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6200873362445415, + "median_sd": 0.002294706064616419, + "median_halfwidth95": 0.004497541277229855, + "bias": -0.00016702327396767852, + "rmse": 0.0006726517148455353, + "max_abs_err": 0.0020531439139720403, + "tau": 0.00023265429775031063, + "s": 11.857995831656856, + "corr_length_days": 53.76023073600311, + "n_eff": 41.18687294583857, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03813162500760367, + "prior_weight_s2": 5.357503676732854e-14, + "prior_weight_lambda": 9.381184718956555e-06 + }, + { + "seed": 2126, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8093158660844251, + "member_coverage95": 0.9588791848617176, + "member_rmse": 0.0022871498451420462, + "shared_bias": -0.00014926124033624592, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6637554585152838, + "median_sd": 0.0023190776597148315, + "median_halfwidth95": 0.0045453087262453205, + "bias": -0.00014926124033624592, + "rmse": 0.0006447533005930625, + "max_abs_err": 0.002299546425586393, + "tau": 0.0001033322736575639, + "s": 12.045738405880941, + "corr_length_days": 16.43603731712083, + "n_eff": 42.76827873090878, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.29693779073546533, + "prior_weight_s2": 5.1898529791277576e-14, + "prior_weight_lambda": 1.28459463546258e-05 + }, + { + "seed": 2127, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8089519650655022, + "member_coverage95": 0.9563318777292577, + "member_rmse": 0.0022091852335926077, + "shared_bias": -9.794799455543958e-05, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5764192139737991, + "median_sd": 0.0022139861467545536, + "median_halfwidth95": 0.004339333144137642, + "bias": -9.794799455543958e-05, + "rmse": 0.0006301433477713778, + "max_abs_err": 0.002123041409500085, + "tau": 0.00013119515761339295, + "s": 11.435219729662398, + "corr_length_days": 26.00058814435483, + "n_eff": 38.25838845586339, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.15514311892488747, + "prior_weight_s2": 5.74063240202181e-14, + "prior_weight_lambda": 2.0430868575524685e-05 + }, + { + "seed": 2128, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8060407569141194, + "member_coverage95": 0.9585152838427947, + "member_rmse": 0.002283657354180532, + "shared_bias": -5.2618925467692366e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.611353711790393, + "median_sd": 0.002256442107552689, + "median_halfwidth95": 0.004422545298887398, + "bias": -5.2618925467692366e-05, + "rmse": 0.0006511456588055715, + "max_abs_err": 0.002873321305803142, + "tau": 0.00018672487646161014, + "s": 11.827434275038186, + "corr_length_days": 15.517804141634507, + "n_eff": 37.00340278087913, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.06621595269958201, + "prior_weight_s2": 5.356579699535945e-14, + "prior_weight_lambda": 2.150935192367647e-05 + }, + { + "seed": 2129, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8104075691411936, + "member_coverage95": 0.9537845705967977, + "member_rmse": 0.002195982119173705, + "shared_bias": -0.00020028741388480935, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5895196506550219, + "median_sd": 0.0021444505792345635, + "median_halfwidth95": 0.004203045935078892, + "bias": -0.00020028741388480935, + "rmse": 0.0006210812081617851, + "max_abs_err": 0.0027138794291935156, + "tau": 0.00022630588394187146, + "s": 10.973363871015184, + "corr_length_days": 47.32361199261085, + "n_eff": 35.36161755483678, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.040544553985044716, + "prior_weight_s2": 6.262747816350895e-14, + "prior_weight_lambda": 1.2507050194368258e-05 + }, + { + "seed": 2130, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7962154294032023, + "member_coverage95": 0.9559679767103348, + "member_rmse": 0.0024554287778801535, + "shared_bias": -0.00020912528997164164, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5240174672489083, + "median_sd": 0.002304833437424333, + "median_halfwidth95": 0.004517390563347945, + "bias": -0.00020912528997164164, + "rmse": 0.0006801738682012052, + "max_abs_err": 0.0029043129049146402, + "tau": 0.00025536823649027356, + "s": 11.990700115961676, + "corr_length_days": 37.26032074717983, + "n_eff": 31.96083345406073, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.030205361632626996, + "prior_weight_s2": 5.200364485735418e-14, + "prior_weight_lambda": 4.168457094533204e-05 + }, + { + "seed": 2131, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8129548762736536, + "member_coverage95": 0.9617903930131004, + "member_rmse": 0.0021391119971496102, + "shared_bias": -0.000164822627239214, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.62882096069869, + "median_sd": 0.002191376641444594, + "median_halfwidth95": 0.004295019327672313, + "bias": -0.000164822627239214, + "rmse": 0.0005573637407129899, + "max_abs_err": 0.002626128868099452, + "tau": 0.00017466143408631578, + "s": 11.45596463231359, + "corr_length_days": 34.0274520436026, + "n_eff": 38.876836081760935, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.07615239923954346, + "prior_weight_s2": 5.713480651278205e-14, + "prior_weight_lambda": 4.745611799770628e-05 + }, + { + "seed": 2132, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8064046579330422, + "member_coverage95": 0.950509461426492, + "member_rmse": 0.0022440078669219727, + "shared_bias": -7.989496986174828e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5720524017467249, + "median_sd": 0.0022042745142658816, + "median_halfwidth95": 0.004320298694078614, + "bias": -7.989496986174828e-05, + "rmse": 0.0006791743362137328, + "max_abs_err": 0.002802548714358146, + "tau": 0.00019478679763774604, + "s": 11.254160773752664, + "corr_length_days": 45.59338671788246, + "n_eff": 39.757108245240886, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.06026349856895849, + "prior_weight_s2": 5.92558466572628e-14, + "prior_weight_lambda": 1.9678917383328716e-05 + }, + { + "seed": 2133, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7991266375545851, + "member_coverage95": 0.9556040756914119, + "member_rmse": 0.002282877550091192, + "shared_bias": -0.0001004053264686144, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5720524017467249, + "median_sd": 0.0022032196944358267, + "median_halfwidth95": 0.0043182312851852206, + "bias": -0.0001004053264686144, + "rmse": 0.0007888106424125613, + "max_abs_err": 0.004088099265994872, + "tau": 0.0002890687269359766, + "s": 11.33198840973917, + "corr_length_days": 42.50920702001215, + "n_eff": 27.638465490943418, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.021695889445217886, + "prior_weight_s2": 5.900415971992055e-14, + "prior_weight_lambda": 7.0350661795318994e-06 + }, + { + "seed": 2134, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8104075691411936, + "member_coverage95": 0.9548762736535662, + "member_rmse": 0.002378067030568243, + "shared_bias": -0.00019660682730671602, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5764192139737991, + "median_sd": 0.002271447666631807, + "median_halfwidth95": 0.004451955654482343, + "bias": -0.00019660682730671602, + "rmse": 0.000647783777234749, + "max_abs_err": 0.0027754785846318087, + "tau": 0.0001910633649126275, + "s": 11.739219159449455, + "corr_length_days": 28.26427150121909, + "n_eff": 35.09815759170534, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.06684114127459809, + "prior_weight_s2": 5.430088819966341e-14, + "prior_weight_lambda": 4.3621409421941684e-05 + }, + { + "seed": 2135, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8114992721979621, + "member_coverage95": 0.9559679767103348, + "member_rmse": 0.0024480353997554114, + "shared_bias": -0.0001964721729431029, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6244541484716157, + "median_sd": 0.0022710227183646335, + "median_halfwidth95": 0.00445112277117682, + "bias": -0.0001964721729431029, + "rmse": 0.000632819076365763, + "max_abs_err": 0.00280794803016974, + "tau": 0.0003552890993160862, + "s": 12.0500183294004, + "corr_length_days": 48.75732798295315, + "n_eff": 26.59372415506031, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.013438771252162874, + "prior_weight_s2": 5.1952424546590186e-14, + "prior_weight_lambda": 1.611101266158478e-05 + }, + { + "seed": 2136, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8129548762736536, + "member_coverage95": 0.9585152838427947, + "member_rmse": 0.0023093350421161604, + "shared_bias": -5.141841904938335e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6419213973799127, + "median_sd": 0.0022727156964484933, + "median_halfwidth95": 0.004454440947273975, + "bias": -5.141841904938335e-05, + "rmse": 0.0006809719684510538, + "max_abs_err": 0.0029514430428254604, + "tau": 0.00024208210753700284, + "s": 11.793241183631814, + "corr_length_days": 34.53661616663054, + "n_eff": 33.18906441761136, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.036569596524699016, + "prior_weight_s2": 5.4629934607571767e-14, + "prior_weight_lambda": 5.745492152027495e-06 + }, + { + "seed": 2137, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8191411935953421, + "member_coverage95": 0.9632459970887919, + "member_rmse": 0.002423385584206704, + "shared_bias": -0.000222599892741801, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5764192139737991, + "median_sd": 0.0023383803106024072, + "median_halfwidth95": 0.004583141227089536, + "bias": -0.000222599892741801, + "rmse": 0.0007497643298465551, + "max_abs_err": 0.0030008628576556153, + "tau": 0.00034118715028315664, + "s": 12.08592817353013, + "corr_length_days": 26.742906672522892, + "n_eff": 23.69858040977007, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.015174925612464795, + "prior_weight_s2": 5.171503591826499e-14, + "prior_weight_lambda": 9.288030362707015e-06 + }, + { + "seed": 2138, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7951237263464338, + "member_coverage95": 0.9552401746724891, + "member_rmse": 0.0022856430684494258, + "shared_bias": -0.00022938738734801776, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.4759825327510917, + "median_sd": 0.002198863230229726, + "median_halfwidth95": 0.0043096927721739745, + "bias": -0.00022938738734801776, + "rmse": 0.0006914734629299367, + "max_abs_err": 0.0018063827110377908, + "tau": 0.0003139474428065143, + "s": 11.2366883764869, + "corr_length_days": 47.61633189196319, + "n_eff": 27.22138330985771, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.017045664803284163, + "prior_weight_s2": 5.93765463712305e-14, + "prior_weight_lambda": 2.6046104682882074e-05 + }, + { + "seed": 2139, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8173216885007278, + "member_coverage95": 0.9588791848617176, + "member_rmse": 0.002440155074463237, + "shared_bias": -0.00018345174406330254, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6419213973799127, + "median_sd": 0.002380527574996021, + "median_halfwidth95": 0.0046657483479995016, + "bias": -0.00018345174406330254, + "rmse": 0.000610528175164731, + "max_abs_err": 0.0025226652726228816, + "tau": 0.0003984899842030077, + "s": 12.122286629001485, + "corr_length_days": 31.728507664793785, + "n_eff": 21.72855033858365, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01104403606473843, + "prior_weight_s2": 5.119350144155325e-14, + "prior_weight_lambda": 1.9157622668964255e-05 + }, + { + "seed": 2140, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8034934497816594, + "member_coverage95": 0.9534206695778749, + "member_rmse": 0.0020783238256597935, + "shared_bias": -3.797888734468869e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.62882096069869, + "median_sd": 0.0020926381873609115, + "median_halfwidth95": 0.0041014955122526415, + "bias": -3.797888734468869e-05, + "rmse": 0.0006520389818707234, + "max_abs_err": 0.0027187733471307277, + "tau": 0.00011555803318931187, + "s": 10.799949412282468, + "corr_length_days": 31.603195351914966, + "n_eff": 41.222333203833074, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.20993573447119393, + "prior_weight_s2": 6.491212253336179e-14, + "prior_weight_lambda": 8.424337096149916e-06 + }, + { + "seed": 2141, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8165938864628821, + "member_coverage95": 0.9548762736535662, + "member_rmse": 0.002485853471710951, + "shared_bias": -0.00016373940711838754, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6157205240174672, + "median_sd": 0.002453627494648, + "median_halfwidth95": 0.004809021558920273, + "bias": -0.00016373940711838754, + "rmse": 0.0007040233128247122, + "max_abs_err": 0.0035091706528958032, + "tau": 0.00024099064313586673, + "s": 12.621557817450542, + "corr_length_days": 38.21090283754628, + "n_eff": 34.368196860413754, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03820423601286239, + "prior_weight_s2": 4.730370716131876e-14, + "prior_weight_lambda": 1.3577629955420846e-05 + }, + { + "seed": 2142, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8067685589519651, + "member_coverage95": 0.9566957787481805, + "member_rmse": 0.0021747436035524817, + "shared_bias": -8.655770401319128e-05, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.4978165938864629, + "median_sd": 0.0022089644285982536, + "median_halfwidth95": 0.004329490757333148, + "bias": -8.655770401319128e-05, + "rmse": 0.0007130314422315831, + "max_abs_err": 0.0017285477949762987, + "tau": 0.00019854881950765824, + "s": 11.498288197324827, + "corr_length_days": 49.25818079129843, + "n_eff": 42.3600007480556, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0574495365384671, + "prior_weight_s2": 5.70911049218532e-14, + "prior_weight_lambda": 1.1165761826120484e-05 + }, + { + "seed": 2143, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.799490538573508, + "member_coverage95": 0.9523289665211062, + "member_rmse": 0.002291498258431153, + "shared_bias": -0.00014800310202653017, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5109170305676856, + "median_sd": 0.0022841095287675236, + "median_halfwidth95": 0.0044767724484413105, + "bias": -0.00014800310202653017, + "rmse": 0.0008012274985714219, + "max_abs_err": 0.002828927270424444, + "tau": 0.00022410095766637375, + "s": 11.766922638986367, + "corr_length_days": 21.75144281786051, + "n_eff": 28.17957612327973, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.04492752102860227, + "prior_weight_s2": 5.449184845876968e-14, + "prior_weight_lambda": 9.112123171114802e-06 + }, + { + "seed": 2144, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8169577874818049, + "member_coverage95": 0.9563318777292577, + "member_rmse": 0.002371145968947535, + "shared_bias": -0.00020327223236289095, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5764192139737991, + "median_sd": 0.0023231054499777185, + "median_halfwidth95": 0.004553203050160129, + "bias": -0.00020327223236289095, + "rmse": 0.000635475171043747, + "max_abs_err": 0.0024469299321231825, + "tau": 0.0002856688322849155, + "s": 12.25436871762589, + "corr_length_days": 33.49918158892743, + "n_eff": 26.915636038775197, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.022965754783241577, + "prior_weight_s2": 4.9912341504500575e-14, + "prior_weight_lambda": 3.7187089648118425e-05 + }, + { + "seed": 2145, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8024017467248908, + "member_coverage95": 0.9570596797671034, + "member_rmse": 0.0021164943009420404, + "shared_bias": -0.0002455571605772392, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5938864628820961, + "median_sd": 0.002157852624784592, + "median_halfwidth95": 0.004229313461883309, + "bias": -0.0002455571605772392, + "rmse": 0.0006195490984646017, + "max_abs_err": 0.0015770586651939634, + "tau": 0.00032361761569402485, + "s": 11.193923962703613, + "corr_length_days": 28.69266277669269, + "n_eff": 22.753922771115647, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01808895572247165, + "prior_weight_s2": 6.03161026161095e-14, + "prior_weight_lambda": 1.1201441118440186e-05 + }, + { + "seed": 2146, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8216885007278021, + "member_coverage95": 0.9657933042212519, + "member_rmse": 0.0024393181270084344, + "shared_bias": -0.00041331464347305985, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5327510917030568, + "median_sd": 0.0024447441970982435, + "median_halfwidth95": 0.004791610615521462, + "bias": -0.00041331464347305985, + "rmse": 0.0008540695299195649, + "max_abs_err": 0.003867050077431124, + "tau": 0.0004318655019434286, + "s": 12.508584283793436, + "corr_length_days": 31.17005622079679, + "n_eff": 17.682532890307648, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.009268093830600992, + "prior_weight_s2": 4.797427075310506e-14, + "prior_weight_lambda": 1.7085286113611373e-05 + }, + { + "seed": 2147, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8162299854439592, + "member_coverage95": 0.9563318777292577, + "member_rmse": 0.002268117890079676, + "shared_bias": -2.5396751420803637e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5895196506550219, + "median_sd": 0.0022953676736739924, + "median_halfwidth95": 0.004498838007164773, + "bias": -2.5396751420803637e-05, + "rmse": 0.0006493862613243003, + "max_abs_err": 0.003049126145188061, + "tau": 9.646316676093575e-05, + "s": 11.904136092353186, + "corr_length_days": 17.140649201701045, + "n_eff": 43.253493946177706, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.3337084666672563, + "prior_weight_s2": 5.3107917249491634e-14, + "prior_weight_lambda": 9.768695187294936e-06 + }, + { + "seed": 2148, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8045851528384279, + "member_coverage95": 0.9574235807860262, + "member_rmse": 0.002417822745764777, + "shared_bias": -8.626861406562545e-05, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5764192139737991, + "median_sd": 0.0023055238576768482, + "median_halfwidth95": 0.0045187437621877465, + "bias": -8.626861406562545e-05, + "rmse": 0.0006597453190047523, + "max_abs_err": 0.0020421953842717157, + "tau": 0.0001541213461126654, + "s": 11.905397455131618, + "corr_length_days": 18.977397926821947, + "n_eff": 37.982633371096306, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.11644406704489242, + "prior_weight_s2": 5.298807448897055e-14, + "prior_weight_lambda": 1.860217808940669e-05 + }, + { + "seed": 2149, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8144104803493449, + "member_coverage95": 0.9526928675400291, + "member_rmse": 0.0024095933198973215, + "shared_bias": -0.0002428196161793422, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6200873362445415, + "median_sd": 0.0023435434649126167, + "median_halfwidth95": 0.004593260823663992, + "bias": -0.0002428196161793422, + "rmse": 0.0006566918667395448, + "max_abs_err": 0.0020729428821687225, + "tau": 0.0004003558762152577, + "s": 11.820439159324573, + "corr_length_days": 27.218261920640355, + "n_eff": 20.364741929088765, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.010918567368115311, + "prior_weight_s2": 5.4200088080602124e-14, + "prior_weight_lambda": 8.716662991731267e-06 + }, + { + "seed": 2150, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8042212518195051, + "member_coverage95": 0.9519650655021834, + "member_rmse": 0.0023574460397538756, + "shared_bias": -0.00022893469566651284, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5895196506550219, + "median_sd": 0.0021666136625575544, + "median_halfwidth95": 0.004246484780520954, + "bias": -0.00022893469566651284, + "rmse": 0.000756809216794818, + "max_abs_err": 0.0032020746273317244, + "tau": 0.0001629393726858505, + "s": 11.335871121999684, + "corr_length_days": 18.995422324915648, + "n_eff": 30.79797818778044, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.09126082991209686, + "prior_weight_s2": 5.858704212234878e-14, + "prior_weight_lambda": 1.274400920596113e-05 + }, + { + "seed": 2151, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8136826783114993, + "member_coverage95": 0.962882096069869, + "member_rmse": 0.00212727027124746, + "shared_bias": -0.00010269482535815949, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6768558951965066, + "median_sd": 0.002069120430548441, + "median_halfwidth95": 0.0040554015555394445, + "bias": -0.00010269482535815949, + "rmse": 0.0005215561543603508, + "max_abs_err": 0.002774004604717677, + "tau": 0.00022732153626289282, + "s": 10.87901753192121, + "corr_length_days": 11.872440154891509, + "n_eff": 32.37240430699714, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03838895160526161, + "prior_weight_s2": 6.328475945701878e-14, + "prior_weight_lambda": 3.481172965858169e-05 + }, + { + "seed": 2152, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8060407569141194, + "member_coverage95": 0.9617903930131004, + "member_rmse": 0.002147451839046823, + "shared_bias": -5.259524807473744e-05, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5720524017467249, + "median_sd": 0.0021982652923597853, + "median_halfwidth95": 0.0043085208354746544, + "bias": -5.259524807473744e-05, + "rmse": 0.0006425482281892106, + "max_abs_err": 0.0016106933037892276, + "tau": 0.00017916573877727523, + "s": 11.49538333218169, + "corr_length_days": 32.26462505984494, + "n_eff": 30.846444362703636, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.07360670380929069, + "prior_weight_s2": 5.697203325007961e-14, + "prior_weight_lambda": 1.7040239228401885e-05 + }, + { + "seed": 2153, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7991266375545851, + "member_coverage95": 0.950509461426492, + "member_rmse": 0.002303997676164781, + "shared_bias": -0.00020892486721148064, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.519650655021834, + "median_sd": 0.00222718134565183, + "median_halfwidth95": 0.004365195258949143, + "bias": -0.00020892486721148064, + "rmse": 0.0006865131664762454, + "max_abs_err": 0.0028705936841600566, + "tau": 0.0001286237100445726, + "s": 11.633193769242498, + "corr_length_days": 28.224575060909302, + "n_eff": 38.418675931608504, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.15703192592784787, + "prior_weight_s2": 5.5622540033167124e-14, + "prior_weight_lambda": 1.4265641026078657e-05 + }, + { + "seed": 2154, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7893013100436681, + "member_coverage95": 0.9545123726346434, + "member_rmse": 0.002201509029718265, + "shared_bias": -0.00015302084131147605, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.47161572052401746, + "median_sd": 0.002215975192086582, + "median_halfwidth95": 0.004343231601382786, + "bias": -0.00015302084131147605, + "rmse": 0.0007155482301901789, + "max_abs_err": 0.0020294882159039972, + "tau": 0.00014498530618247587, + "s": 11.530190417031262, + "corr_length_days": 22.68363939247448, + "n_eff": 34.07314806929011, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.13188030298467512, + "prior_weight_s2": 5.666037865324362e-14, + "prior_weight_lambda": 1.5967508295052924e-05 + }, + { + "seed": 2155, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7991266375545851, + "member_coverage95": 0.9574235807860262, + "member_rmse": 0.0021440630338187662, + "shared_bias": -7.513063721291951e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5545851528384279, + "median_sd": 0.0021632020331196367, + "median_halfwidth95": 0.0042397981096412955, + "bias": -7.513063721291951e-05, + "rmse": 0.0006859319156715389, + "max_abs_err": 0.003017231182027017, + "tau": 8.36455850385236e-05, + "s": 11.202354367986237, + "corr_length_days": 27.17625780405492, + "n_eff": 36.35899262786439, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.4776292547562866, + "prior_weight_s2": 5.983565189052924e-14, + "prior_weight_lambda": 1.550520188576216e-05 + }, + { + "seed": 2156, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8060407569141194, + "member_coverage95": 0.9625181950509462, + "member_rmse": 0.0021594335548511217, + "shared_bias": -8.161987156868711e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5764192139737991, + "median_sd": 0.0022548387534889005, + "median_halfwidth95": 0.00441940278264312, + "bias": -8.161987156868711e-05, + "rmse": 0.0006811471305190933, + "max_abs_err": 0.002674894787178644, + "tau": 0.00010489755213047397, + "s": 11.751292173720445, + "corr_length_days": 27.921917269170617, + "n_eff": 34.78666929506479, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.29045595092484, + "prior_weight_s2": 5.463447581713207e-14, + "prior_weight_lambda": 9.220356503137739e-06 + }, + { + "seed": 2157, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7805676855895196, + "member_coverage95": 0.9454148471615721, + "member_rmse": 0.002053351231254572, + "shared_bias": -0.00017442363474599843, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.5545851528384279, + "median_sd": 0.002046084523249168, + "median_halfwidth95": 0.0040102520065255325, + "bias": -0.00017442363474599843, + "rmse": 0.0007397741361081767, + "max_abs_err": 0.003916397506142441, + "tau": 0.000276737962852302, + "s": 10.503813303171786, + "corr_length_days": 14.093333013631675, + "n_eff": 24.483898447962442, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.022830324641025187, + "prior_weight_s2": 6.8485828265719e-14, + "prior_weight_lambda": 9.409168165698539e-06 + }, + { + "seed": 2158, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8093158660844251, + "member_coverage95": 0.9497816593886463, + "member_rmse": 0.0022440474592528214, + "shared_bias": -0.0002616172870833502, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5982532751091703, + "median_sd": 0.00222987980285121, + "median_halfwidth95": 0.004370484137915469, + "bias": -0.0002616172870833502, + "rmse": 0.0006891766037210754, + "max_abs_err": 0.002716203835157282, + "tau": 0.00030828123329784327, + "s": 11.621481879202237, + "corr_length_days": 16.920752576599217, + "n_eff": 25.001278638324468, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.019482206457131772, + "prior_weight_s2": 5.5749539026062857e-14, + "prior_weight_lambda": 1.494820501780516e-05 + }, + { + "seed": 2159, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8071324599708879, + "member_coverage95": 0.9537845705967977, + "member_rmse": 0.0022025731807504903, + "shared_bias": -9.923730320080624e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6462882096069869, + "median_sd": 0.0021702098711505143, + "median_halfwidth95": 0.0042535332198996465, + "bias": -9.923730320080624e-05, + "rmse": 0.0006638115015144977, + "max_abs_err": 0.003327596120555315, + "tau": 0.00033051833091989215, + "s": 11.204813979539592, + "corr_length_days": 44.54263615169099, + "n_eff": 24.26234845375546, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.017013467486616054, + "prior_weight_s2": 6.025567962975325e-14, + "prior_weight_lambda": 9.173385064672683e-06 + }, + { + "seed": 2160, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8140465793304221, + "member_coverage95": 0.9570596797671034, + "member_rmse": 0.0022030375620534664, + "shared_bias": -0.00022561061445837356, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5152838427947598, + "median_sd": 0.0021914904462266246, + "median_halfwidth95": 0.00429524238094812, + "bias": -0.00022561061445837356, + "rmse": 0.0006525276812826413, + "max_abs_err": 0.0020766173445352274, + "tau": 0.00024109461840006138, + "s": 11.603475806686731, + "corr_length_days": 17.45626682156512, + "n_eff": 30.061704122211907, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.032196424686593866, + "prior_weight_s2": 5.5781897141886475e-14, + "prior_weight_lambda": 2.0233912246110243e-05 + }, + { + "seed": 2161, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8074963609898108, + "member_coverage95": 0.9508733624454149, + "member_rmse": 0.0023769776918904175, + "shared_bias": -0.00012195071236672265, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5764192139737991, + "median_sd": 0.0023023243978102454, + "median_halfwidth95": 0.00451247293602976, + "bias": -0.00012195071236672265, + "rmse": 0.0006933327925990715, + "max_abs_err": 0.0028631956377508667, + "tau": 0.00025786129793272343, + "s": 11.936909449340694, + "corr_length_days": 40.87315805159782, + "n_eff": 29.19168641024653, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.031773374251341545, + "prior_weight_s2": 5.2800299563390274e-14, + "prior_weight_lambda": 1.1605445298633689e-05 + }, + { + "seed": 2162, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8056768558951966, + "member_coverage95": 0.9556040756914119, + "member_rmse": 0.0022724796789121756, + "shared_bias": -0.00022177950114915185, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6069868995633187, + "median_sd": 0.002204746839672701, + "median_halfwidth95": 0.004321224434872266, + "bias": -0.00022177950114915185, + "rmse": 0.000627796742341026, + "max_abs_err": 0.0026821180405878797, + "tau": 0.0001706903818136502, + "s": 11.524198052483476, + "corr_length_days": 24.71365483167572, + "n_eff": 38.22546400174971, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.08044095076956306, + "prior_weight_s2": 5.671211297831697e-14, + "prior_weight_lambda": 1.2469595082313947e-05 + }, + { + "seed": 2163, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8224163027656477, + "member_coverage95": 0.9610625909752547, + "member_rmse": 0.00241195831599081, + "shared_bias": -0.00023132335465321047, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6157205240174672, + "median_sd": 0.0024107059558743232, + "median_halfwidth95": 0.004724896888099262, + "bias": -0.00023132335465321047, + "rmse": 0.0006368620982208697, + "max_abs_err": 0.0026385728082658428, + "tau": 0.0003604127374714898, + "s": 12.487436415496692, + "corr_length_days": 32.65303426592691, + "n_eff": 24.034676147118216, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.012933444374172839, + "prior_weight_s2": 4.804873992689193e-14, + "prior_weight_lambda": 3.8199328211760075e-05 + }, + { + "seed": 2164, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7922125181950509, + "member_coverage95": 0.960334788937409, + "member_rmse": 0.002097957785874133, + "shared_bias": -0.00019561131060458434, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6244541484716157, + "median_sd": 0.002137402216803781, + "median_halfwidth95": 0.004189231398455606, + "bias": -0.00019561131060458434, + "rmse": 0.0006754377538938851, + "max_abs_err": 0.002750009326550417, + "tau": 0.00024079560143308, + "s": 11.109584645207391, + "corr_length_days": 21.283547986181166, + "n_eff": 25.232316762481652, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0333265050977455, + "prior_weight_s2": 6.123232143428186e-14, + "prior_weight_lambda": 1.0591417473592689e-05 + }, + { + "seed": 2165, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8275109170305677, + "member_coverage95": 0.962882096069869, + "member_rmse": 0.0023866405847856975, + "shared_bias": -0.00012031093152961396, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.6637554585152838, + "median_sd": 0.0022914986590004045, + "median_halfwidth95": 0.004491254877689069, + "bias": -0.00012031093152961396, + "rmse": 0.0006233095859189277, + "max_abs_err": 0.003654162933579049, + "tau": 0.00017216162187624006, + "s": 11.979141539314773, + "corr_length_days": 40.041668908980824, + "n_eff": 48.023328566762714, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.08967941275915929, + "prior_weight_s2": 5.2215358839324445e-14, + "prior_weight_lambda": 3.1970184644935505e-05 + }, + { + "seed": 2166, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7983988355167394, + "member_coverage95": 0.9566957787481805, + "member_rmse": 0.002291368192250401, + "shared_bias": -0.0002068225073685127, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.49344978165938863, + "median_sd": 0.0022554234549219333, + "median_halfwidth95": 0.004420548776402612, + "bias": -0.0002068225073685127, + "rmse": 0.000774678729612725, + "max_abs_err": 0.002509546062044299, + "tau": 0.00012689190753482603, + "s": 11.596866272545615, + "corr_length_days": 18.03734903204372, + "n_eff": 37.810654267018236, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.1890618528245598, + "prior_weight_s2": 5.595011216046514e-14, + "prior_weight_lambda": 1.2541001565362885e-05 + }, + { + "seed": 2167, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8235080058224163, + "member_coverage95": 0.9534206695778749, + "member_rmse": 0.002299305110593817, + "shared_bias": -8.009050490944066e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5720524017467249, + "median_sd": 0.0022405300090800394, + "median_halfwidth95": 0.00439135815871655, + "bias": -8.009050490944066e-05, + "rmse": 0.0007054400613371915, + "max_abs_err": 0.00222818661421811, + "tau": 0.00012179455215485257, + "s": 11.704795937738226, + "corr_length_days": 24.45487062330488, + "n_eff": 34.583169609109355, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.20461825000257855, + "prior_weight_s2": 5.508001406482351e-14, + "prior_weight_lambda": 1.091149884309597e-05 + }, + { + "seed": 2168, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8082241630276564, + "member_coverage95": 0.9592430858806404, + "member_rmse": 0.0022842131355146193, + "shared_bias": -0.00017011352880683407, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6899563318777293, + "median_sd": 0.0023178747317234693, + "median_halfwidth95": 0.004542951030687658, + "bias": -0.00017011352880683407, + "rmse": 0.0006343221639238502, + "max_abs_err": 0.0026677671862840252, + "tau": 0.0002972996738150599, + "s": 12.129698544981865, + "corr_length_days": 33.464000307742694, + "n_eff": 26.920024317189146, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.02212393420057646, + "prior_weight_s2": 5.143071510095165e-14, + "prior_weight_lambda": 7.587011784373884e-06 + }, + { + "seed": 2169, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8042212518195051, + "member_coverage95": 0.9596069868995634, + "member_rmse": 0.0021645007080132836, + "shared_bias": -0.00013596783242172302, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6419213973799127, + "median_sd": 0.002171094429798805, + "median_halfwidth95": 0.004255266923006185, + "bias": -0.00013596783242172302, + "rmse": 0.0006443144623297467, + "max_abs_err": 0.0020744735396463383, + "tau": 8.714016075117966e-05, + "s": 11.234019424782609, + "corr_length_days": 31.64040069475298, + "n_eff": 41.23143675630252, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.4396175920285915, + "prior_weight_s2": 5.994636994544763e-14, + "prior_weight_lambda": 8.84957628739942e-06 + }, + { + "seed": 2170, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8140465793304221, + "member_coverage95": 0.9610625909752547, + "member_rmse": 0.002263929008325836, + "shared_bias": -0.00022054388053845933, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6331877729257642, + "median_sd": 0.002235030495378387, + "median_halfwidth95": 0.004380579309843805, + "bias": -0.00022054388053845933, + "rmse": 0.0005875936353926082, + "max_abs_err": 0.0019862742516846723, + "tau": 0.0003471163117357701, + "s": 11.43143931817306, + "corr_length_days": 6.550296161788742, + "n_eff": 27.62753902647533, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.014573478461078324, + "prior_weight_s2": 5.737817624326967e-14, + "prior_weight_lambda": 3.310431026606045e-05 + }, + { + "seed": 2171, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7933042212518195, + "member_coverage95": 0.9512372634643377, + "member_rmse": 0.002375346227875668, + "shared_bias": -0.00013044960087394284, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5676855895196506, + "median_sd": 0.0023522766281278942, + "median_halfwidth95": 0.00461037750917206, + "bias": -0.00013044960087394284, + "rmse": 0.0007501248316021743, + "max_abs_err": 0.0023614447532744986, + "tau": 0.00023067865619816447, + "s": 12.144956298603393, + "corr_length_days": 47.61561714269802, + "n_eff": 35.634010411408546, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03804779879334207, + "prior_weight_s2": 5.1207344526528085e-14, + "prior_weight_lambda": 8.178829638479644e-06 + }, + { + "seed": 2172, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7936681222707423, + "member_coverage95": 0.9599708879184862, + "member_rmse": 0.002140055338857092, + "shared_bias": -0.00016480545096657996, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.62882096069869, + "median_sd": 0.0021382556807836876, + "median_halfwidth95": 0.004190904157131519, + "bias": -0.00016480545096657996, + "rmse": 0.0006155434870859923, + "max_abs_err": 0.0025028299064302813, + "tau": 0.00029188294244352685, + "s": 11.19038692667756, + "corr_length_days": 13.370307998521971, + "n_eff": 25.69147933810847, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.022031595964485246, + "prior_weight_s2": 5.982907376550288e-14, + "prior_weight_lambda": 2.847331614291046e-05 + }, + { + "seed": 2173, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7951237263464338, + "member_coverage95": 0.9577874818049491, + "member_rmse": 0.002405200954421083, + "shared_bias": -0.00012742198805673144, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6681222707423581, + "median_sd": 0.0023155176715463337, + "median_halfwidth95": 0.004538331277594639, + "bias": -0.00012742198805673144, + "rmse": 0.0006961020368144622, + "max_abs_err": 0.0025413534325014198, + "tau": 0.0002176965430943986, + "s": 11.901558372787743, + "corr_length_days": 35.51313241922902, + "n_eff": 31.073350067481087, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.049427891517331686, + "prior_weight_s2": 5.329515411762947e-14, + "prior_weight_lambda": 8.369840995047784e-06 + }, + { + "seed": 2174, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7867540029112081, + "member_coverage95": 0.9465065502183406, + "member_rmse": 0.002277830741990489, + "shared_bias": -0.0002726787075011147, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5021834061135371, + "median_sd": 0.002249820921908755, + "median_halfwidth95": 0.004409568013387971, + "bias": -0.0002726787075011147, + "rmse": 0.0007550090888556244, + "max_abs_err": 0.0034684435958832085, + "tau": 0.00037912604952587974, + "s": 11.598084425450104, + "corr_length_days": 32.57684357442302, + "n_eff": 20.040496566057673, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.012213058098723988, + "prior_weight_s2": 5.606671797158303e-14, + "prior_weight_lambda": 1.2588889665063469e-05 + }, + { + "seed": 2175, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8224163027656477, + "member_coverage95": 0.9559679767103348, + "member_rmse": 0.002525581729923353, + "shared_bias": -0.00017910898865862083, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6681222707423581, + "median_sd": 0.0024472399833162504, + "median_halfwidth95": 0.004796502266660452, + "bias": -0.00017910898865862083, + "rmse": 0.0006071353254711627, + "max_abs_err": 0.002870242270137139, + "tau": 0.00020997707416912375, + "s": 12.654769516980288, + "corr_length_days": 12.631771489126317, + "n_eff": 36.425943713288305, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.056229960501017855, + "prior_weight_s2": 4.6571965148563426e-14, + "prior_weight_lambda": 4.537887835780283e-05 + }, + { + "seed": 2176, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8195050946142649, + "member_coverage95": 0.9588791848617176, + "member_rmse": 0.002386490804202139, + "shared_bias": -0.00021501006601641598, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5982532751091703, + "median_sd": 0.002388210678337874, + "median_halfwidth95": 0.004680806953957813, + "bias": -0.00021501006601641598, + "rmse": 0.0006834991643349228, + "max_abs_err": 0.00235924392959049, + "tau": 0.00030351483393774943, + "s": 12.28854704220539, + "corr_length_days": 23.321631092503683, + "n_eff": 27.07651395757445, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.020995421405014144, + "prior_weight_s2": 4.99824221577965e-14, + "prior_weight_lambda": 1.3979240954404408e-05 + }, + { + "seed": 2177, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8114992721979621, + "member_coverage95": 0.9588791848617176, + "member_rmse": 0.002106976095738537, + "shared_bias": -0.00018380084145238755, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5807860262008734, + "median_sd": 0.0021602349534412747, + "median_halfwidth95": 0.004233982740286575, + "bias": -0.00018380084145238755, + "rmse": 0.0006644287052807208, + "max_abs_err": 0.0032467290823870723, + "tau": 0.00028158285379849106, + "s": 11.194685297357383, + "corr_length_days": 46.207523818632595, + "n_eff": 28.65290196138586, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.023846827501565093, + "prior_weight_s2": 5.987162430643736e-14, + "prior_weight_lambda": 2.5331970404154082e-05 + }, + { + "seed": 2178, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8060407569141194, + "member_coverage95": 0.9643377001455604, + "member_rmse": 0.002288622633930231, + "shared_bias": -0.00027995940258600076, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5021834061135371, + "median_sd": 0.0022997535188136885, + "median_halfwidth95": 0.004507434105748152, + "bias": -0.00027995940258600076, + "rmse": 0.0008832105549179917, + "max_abs_err": 0.0021727619519439226, + "tau": 0.00020280849079731155, + "s": 12.145960316321176, + "corr_length_days": 29.5735930998265, + "n_eff": 35.676026504840074, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.06021472228392166, + "prior_weight_s2": 5.11614161564637e-14, + "prior_weight_lambda": 8.625731731133184e-06 + }, + { + "seed": 2179, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8136826783114993, + "member_coverage95": 0.9581513828238719, + "member_rmse": 0.002491250822773483, + "shared_bias": -3.393714797809395e-05, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6244541484716157, + "median_sd": 0.002467355711256314, + "median_halfwidth95": 0.00483592836925677, + "bias": -3.393714797809395e-05, + "rmse": 0.0007051153543226192, + "max_abs_err": 0.0033879235978019995, + "tau": 0.00032245848659368453, + "s": 12.579021516370743, + "corr_length_days": 33.03324908276776, + "n_eff": 27.024357285040598, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.018068983996602617, + "prior_weight_s2": 4.7663342137783645e-14, + "prior_weight_lambda": 1.1416840766147493e-05 + }, + { + "seed": 2180, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8136826783114993, + "member_coverage95": 0.9581513828238719, + "member_rmse": 0.002394850112284871, + "shared_bias": -0.00019832107096570947, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5283842794759825, + "median_sd": 0.002326999261709879, + "median_halfwidth95": 0.004560834780977942, + "bias": -0.00019832107096570947, + "rmse": 0.0006791071059480389, + "max_abs_err": 0.0019975381865409473, + "tau": 0.0002978271882050956, + "s": 12.143285793987962, + "corr_length_days": 16.915411025732535, + "n_eff": 26.629719022840057, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.02288630049178342, + "prior_weight_s2": 5.081826411910284e-14, + "prior_weight_lambda": 2.6273458671584313e-05 + }, + { + "seed": 2181, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8049490538573508, + "member_coverage95": 0.960334788937409, + "member_rmse": 0.0024088691433010023, + "shared_bias": -0.00015779218363211163, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5109170305676856, + "median_sd": 0.0023081860595632287, + "median_halfwidth95": 0.004523961582045784, + "bias": -0.00015779218363211163, + "rmse": 0.000644676380883488, + "max_abs_err": 0.0024803039606388533, + "tau": 0.00022753512497716453, + "s": 11.947496513775949, + "corr_length_days": 38.23175194498611, + "n_eff": 32.02773743265432, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.04058286359246696, + "prior_weight_s2": 5.254398878535763e-14, + "prior_weight_lambda": 3.160065876344948e-05 + }, + { + "seed": 2182, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8064046579330422, + "member_coverage95": 0.9519650655021834, + "member_rmse": 0.002319207547512823, + "shared_bias": -0.0002739349502371827, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.47161572052401746, + "median_sd": 0.0022719971301777024, + "median_halfwidth95": 0.00445303258325161, + "bias": -0.0002739349502371827, + "rmse": 0.0008029557181201327, + "max_abs_err": 0.0023137219650081215, + "tau": 0.0001961849575950544, + "s": 11.690310059721378, + "corr_length_days": 52.16705837303143, + "n_eff": 42.40381295682191, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.05835424519434456, + "prior_weight_s2": 5.497891796890259e-14, + "prior_weight_lambda": 1.5255177550700918e-05 + }, + { + "seed": 2183, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8104075691411936, + "member_coverage95": 0.9523289665211062, + "member_rmse": 0.002312751375674226, + "shared_bias": -0.00022215744847247452, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5589519650655022, + "median_sd": 0.002274311592753574, + "median_halfwidth95": 0.004457568846579666, + "bias": -0.00022215744847247452, + "rmse": 0.0007052385590547625, + "max_abs_err": 0.0020705454309670386, + "tau": 0.0003101223217441616, + "s": 11.661656539428721, + "corr_length_days": 36.3148912108629, + "n_eff": 26.9154198602698, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01859545404678274, + "prior_weight_s2": 5.553986364995303e-14, + "prior_weight_lambda": 8.731888815347067e-06 + }, + { + "seed": 2184, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8002183406113537, + "member_coverage95": 0.9541484716157205, + "member_rmse": 0.0020332263555067408, + "shared_bias": -0.0001845545343113871, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5502183406113537, + "median_sd": 0.0021054281135632455, + "median_halfwidth95": 0.004126563307171873, + "bias": -0.0001845545343113871, + "rmse": 0.000609274050145015, + "max_abs_err": 0.002043458199862862, + "tau": 8.928150641367864e-05, + "s": 10.875004933375388, + "corr_length_days": 31.3302264267637, + "n_eff": 37.847670987717905, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.382942666725472, + "prior_weight_s2": 6.327300866943309e-14, + "prior_weight_lambda": 3.791301268260318e-05 + }, + { + "seed": 2185, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7951237263464338, + "member_coverage95": 0.9545123726346434, + "member_rmse": 0.002230317744525495, + "shared_bias": -0.00018916650986083202, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6026200873362445, + "median_sd": 0.002165758401427156, + "median_halfwidth95": 0.004244808499494775, + "bias": -0.00018916650986083202, + "rmse": 0.0006294899909704693, + "max_abs_err": 0.0027612524636529243, + "tau": 0.00011766909700718136, + "s": 11.109327289000271, + "corr_length_days": 8.117997744077538, + "n_eff": 53.95853878102496, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.2064222098511114, + "prior_weight_s2": 6.069685997803662e-14, + "prior_weight_lambda": 2.7400206692127283e-05 + }, + { + "seed": 2186, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8107714701601164, + "member_coverage95": 0.9545123726346434, + "member_rmse": 0.002362959999856873, + "shared_bias": -0.0001914437909437438, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6200873362445415, + "median_sd": 0.0022266099456611714, + "median_halfwidth95": 0.004364075335537852, + "bias": -0.0001914437909437438, + "rmse": 0.0007063603205044791, + "max_abs_err": 0.0024010409864780842, + "tau": 0.0002701293941730934, + "s": 11.482388953552125, + "corr_length_days": 17.698552472652317, + "n_eff": 27.11336539135252, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.02635055263611719, + "prior_weight_s2": 5.728525991317194e-14, + "prior_weight_lambda": 9.639800399814407e-06 + }, + { + "seed": 2187, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8176855895196506, + "member_coverage95": 0.960334788937409, + "member_rmse": 0.0024808591637082195, + "shared_bias": -0.00019070314380829944, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5545851528384279, + "median_sd": 0.0022678490776524207, + "median_halfwidth95": 0.004444902549631949, + "bias": -0.00019070314380829944, + "rmse": 0.0006539985566396377, + "max_abs_err": 0.002463717641761532, + "tau": 0.00035588098849065027, + "s": 11.615235724010102, + "corr_length_days": 34.71116541017187, + "n_eff": 21.59163095054462, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.013333222646736037, + "prior_weight_s2": 5.564019397388432e-14, + "prior_weight_lambda": 3.24907655896529e-05 + }, + { + "seed": 2188, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8118631732168851, + "member_coverage95": 0.9512372634643377, + "member_rmse": 0.002284453345775007, + "shared_bias": -0.00022667361970409974, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6200873362445415, + "median_sd": 0.0021973536892955533, + "median_halfwidth95": 0.00430673412628647, + "bias": -0.00022667361970409974, + "rmse": 0.0006064589305061648, + "max_abs_err": 0.0019460325591415563, + "tau": 0.0002258707569640477, + "s": 11.324396459855386, + "corr_length_days": 42.92893010839152, + "n_eff": 35.1131324405293, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.04750953226740725, + "prior_weight_s2": 5.866547377324476e-14, + "prior_weight_lambda": 1.7142153183178378e-05 + }, + { + "seed": 2189, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8256914119359534, + "member_coverage95": 0.9621542940320232, + "member_rmse": 0.0025102112143916707, + "shared_bias": -0.0001911535055005014, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6724890829694323, + "median_sd": 0.002335787320622365, + "median_halfwidth95": 0.004578059060076293, + "bias": -0.0001911535055005014, + "rmse": 0.0006355062863988062, + "max_abs_err": 0.003175524319030269, + "tau": 0.00038598543173943504, + "s": 11.78727340285874, + "corr_length_days": 28.686058960942912, + "n_eff": 21.776379943580256, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.011243079345411125, + "prior_weight_s2": 5.428119451662669e-14, + "prior_weight_lambda": 1.099318916293979e-05 + }, + { + "seed": 2190, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7947598253275109, + "member_coverage95": 0.950509461426492, + "member_rmse": 0.0024261896987142926, + "shared_bias": -0.000105861437790884, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.462882096069869, + "median_sd": 0.0021833312341690736, + "median_halfwidth95": 0.004279250619046954, + "bias": -0.000105861437790884, + "rmse": 0.0007232489184546405, + "max_abs_err": 0.0028597697404197015, + "tau": 0.0001904646421039648, + "s": 11.304160207664202, + "corr_length_days": 66.11895223639128, + "n_eff": 49.20662707700887, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.06709227822879657, + "prior_weight_s2": 5.902514354264752e-14, + "prior_weight_lambda": 1.3546389339741808e-05 + }, + { + "seed": 2191, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8205967976710334, + "member_coverage95": 0.9668850072780204, + "member_rmse": 0.002385234215334502, + "shared_bias": -0.00010493149662105121, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6157205240174672, + "median_sd": 0.002316321237877579, + "median_halfwidth95": 0.004539906238675491, + "bias": -0.00010493149662105121, + "rmse": 0.0005748358971574955, + "max_abs_err": 0.0025613247178606032, + "tau": 0.00027570316710086095, + "s": 11.970044485367714, + "corr_length_days": 38.55811306714105, + "n_eff": 30.86643959493077, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.024285331530299634, + "prior_weight_s2": 5.2366301940485763e-14, + "prior_weight_lambda": 3.15726629246788e-05 + }, + { + "seed": 2192, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7893013100436681, + "member_coverage95": 0.9490538573508006, + "member_rmse": 0.00205693455387977, + "shared_bias": -0.00013249911867993272, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6550218340611353, + "median_sd": 0.002120585445744423, + "median_halfwidth95": 0.004156271132583022, + "bias": -0.00013249911867993272, + "rmse": 0.0005245361721973566, + "max_abs_err": 0.0018265190397990967, + "tau": 8.063946942231536e-05, + "s": 11.135272465606722, + "corr_length_days": 25.666611678963857, + "n_eff": 40.025044157055916, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.5029456902875131, + "prior_weight_s2": 6.05252656989847e-14, + "prior_weight_lambda": 1.9889091661211125e-05 + }, + { + "seed": 2193, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8220524017467249, + "member_coverage95": 0.9556040756914119, + "member_rmse": 0.002502832130061847, + "shared_bias": -0.00024183715985626503, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5545851528384279, + "median_sd": 0.002467281454062827, + "median_halfwidth95": 0.004835782827830795, + "bias": -0.00024183715985626503, + "rmse": 0.00065681331506194, + "max_abs_err": 0.00235777183215839, + "tau": 0.00029580850106784027, + "s": 12.662359802841502, + "corr_length_days": 39.816978132487286, + "n_eff": 31.79301442956315, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.021053121289150514, + "prior_weight_s2": 4.664447860636156e-14, + "prior_weight_lambda": 4.690255447415159e-05 + }, + { + "seed": 2194, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8049490538573508, + "member_coverage95": 0.9559679767103348, + "member_rmse": 0.0022053680795705963, + "shared_bias": -0.00019058856735803964, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5895196506550219, + "median_sd": 0.0021627123119382684, + "median_halfwidth95": 0.004238838273755777, + "bias": -0.00019058856735803964, + "rmse": 0.0007152386056447177, + "max_abs_err": 0.0032213402211690705, + "tau": 0.00020327418201929572, + "s": 11.166438565390902, + "corr_length_days": 46.1451304543826, + "n_eff": 37.787112520029225, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.056297867935847866, + "prior_weight_s2": 6.064142078235514e-14, + "prior_weight_lambda": 8.177867146022249e-06 + }, + { + "seed": 2195, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8074963609898108, + "member_coverage95": 0.9494177583697234, + "member_rmse": 0.0023979499123952743, + "shared_bias": -0.00021854687789615856, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6812227074235808, + "median_sd": 0.002237177830954802, + "median_halfwidth95": 0.004384788010269498, + "bias": -0.00021854687789615856, + "rmse": 0.0006208779343770943, + "max_abs_err": 0.002360415242222296, + "tau": 0.00030535402304413434, + "s": 11.483047357538283, + "corr_length_days": 20.16944290552964, + "n_eff": 24.20939623529572, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.019711358963892627, + "prior_weight_s2": 5.702027839061327e-14, + "prior_weight_lambda": 1.5204973163599798e-05 + }, + { + "seed": 2196, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7965793304221251, + "member_coverage95": 0.9516011644832606, + "member_rmse": 0.0022509554217259504, + "shared_bias": -0.00026592936715854893, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5240174672489083, + "median_sd": 0.0022317900546303224, + "median_halfwidth95": 0.004374228162633466, + "bias": -0.00026592936715854893, + "rmse": 0.0006590523037814943, + "max_abs_err": 0.001779476644676265, + "tau": 0.0001680438435396924, + "s": 11.576942257978153, + "corr_length_days": 26.704707471851087, + "n_eff": 33.49015482993465, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.08599917214940732, + "prior_weight_s2": 5.61902084589776e-14, + "prior_weight_lambda": 1.591194617775783e-05 + }, + { + "seed": 2197, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8118631732168851, + "member_coverage95": 0.9548762736535662, + "member_rmse": 0.0024994562881974045, + "shared_bias": -0.0001457587786151623, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5414847161572053, + "median_sd": 0.002398657135832457, + "median_halfwidth95": 0.004701281634574726, + "bias": -0.0001457587786151623, + "rmse": 0.0007828026302687801, + "max_abs_err": 0.003585041450278081, + "tau": 0.00020676447849593484, + "s": 12.587588382892532, + "corr_length_days": 15.340354182050596, + "n_eff": 34.49777908745716, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.05873909674770112, + "prior_weight_s2": 4.7614579608578964e-14, + "prior_weight_lambda": 1.0354606564000744e-05 + }, + { + "seed": 2198, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.787117903930131, + "member_coverage95": 0.9592430858806404, + "member_rmse": 0.00207948399469858, + "shared_bias": -5.075468517596711e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5414847161572053, + "median_sd": 0.0021180744754176564, + "median_halfwidth95": 0.004151349721137491, + "bias": -5.075468517596711e-05, + "rmse": 0.0006638671967985018, + "max_abs_err": 0.002823428617808921, + "tau": 9.108224004113982e-05, + "s": 11.028775147907842, + "corr_length_days": 16.169631981657464, + "n_eff": 37.38518861927206, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.4084368529023646, + "prior_weight_s2": 6.189132700098591e-14, + "prior_weight_lambda": 1.3086276414104377e-05 + }, + { + "seed": 2199, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8027656477438136, + "member_coverage95": 0.9581513828238719, + "member_rmse": 0.002315509200580317, + "shared_bias": -0.00016696929871942178, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5807860262008734, + "median_sd": 0.0022799957986126217, + "median_halfwidth95": 0.0044687096854319885, + "bias": -0.00016696929871942178, + "rmse": 0.0007398671854135989, + "max_abs_err": 0.0027516097618673512, + "tau": 0.00010805891757196792, + "s": 11.829867217762681, + "corr_length_days": 27.445590573217054, + "n_eff": 41.77548939413776, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.2624083196260219, + "prior_weight_s2": 5.386940736928902e-14, + "prior_weight_lambda": 1.0096243758478024e-05 + } + ] +} diff --git a/paper/data/calibration/locked_clock_drift_n200.json b/paper/data/calibration/locked_clock_drift_n200.json new file mode 100644 index 0000000..d639fd9 --- /dev/null +++ b/paper/data/calibration/locked_clock_drift_n200.json @@ -0,0 +1,5528 @@ +{ + "codameter_version": "0.4.0", + "git_commit": "58be201703a7fe06f64f3575ff696b00cb3b2fc9", + "started_utc": "2026-09-10T21:50:42+00:00", + "finished_utc": "2026-09-10T22:47:10+00:00", + "wall_seconds": 3388.383524, + "settings": { + "scenario": "clock_drift", + "years": 2.5, + "snr": 7.0, + "cadence": 4, + "n_iter": 1200, + "burn": 400, + "thin": 2 + }, + "seeds": [ + 2000, + 2001, + 2002, + 2003, + 2004, + 2005, + 2006, + 2007, + 2008, + 2009, + 2010, + 2011, + 2012, + 2013, + 2014, + 2015, + 2016, + 2017, + 2018, + 2019, + 2020, + 2021, + 2022, + 2023, + 2024, + 2025, + 2026, + 2027, + 2028, + 2029, + 2030, + 2031, + 2032, + 2033, + 2034, + 2035, + 2036, + 2037, + 2038, + 2039, + 2040, + 2041, + 2042, + 2043, + 2044, + 2045, + 2046, + 2047, + 2048, + 2049, + 2050, + 2051, + 2052, + 2053, + 2054, + 2055, + 2056, + 2057, + 2058, + 2059, + 2060, + 2061, + 2062, + 2063, + 2064, + 2065, + 2066, + 2067, + 2068, + 2069, + 2070, + 2071, + 2072, + 2073, + 2074, + 2075, + 2076, + 2077, + 2078, + 2079, + 2080, + 2081, + 2082, + 2083, + 2084, + 2085, + 2086, + 2087, + 2088, + 2089, + 2090, + 2091, + 2092, + 2093, + 2094, + 2095, + 2096, + 2097, + 2098, + 2099, + 2100, + 2101, + 2102, + 2103, + 2104, + 2105, + 2106, + 2107, + 2108, + 2109, + 2110, + 2111, + 2112, + 2113, + 2114, + 2115, + 2116, + 2117, + 2118, + 2119, + 2120, + 2121, + 2122, + 2123, + 2124, + 2125, + 2126, + 2127, + 2128, + 2129, + 2130, + 2131, + 2132, + 2133, + 2134, + 2135, + 2136, + 2137, + 2138, + 2139, + 2140, + 2141, + 2142, + 2143, + 2144, + 2145, + 2146, + 2147, + 2148, + 2149, + 2150, + 2151, + 2152, + 2153, + 2154, + 2155, + 2156, + 2157, + 2158, + 2159, + 2160, + 2161, + 2162, + 2163, + 2164, + 2165, + 2166, + 2167, + 2168, + 2169, + 2170, + 2171, + 2172, + 2173, + 2174, + 2175, + 2176, + 2177, + 2178, + 2179, + 2180, + 2181, + 2182, + 2183, + 2184, + 2185, + 2186, + 2187, + 2188, + 2189, + 2190, + 2191, + 2192, + 2193, + 2194, + 2195, + 2196, + 2197, + 2198, + 2199 + ], + "summary": { + "n_realizations": 200, + "n_failed": 0, + "failures": [], + "margin": 0.03, + "member_coverage68": { + "mean": 0.8038555312954877, + "se": 0.0007899533075598508, + "n": 200 + }, + "member_coverage95": { + "mean": 0.9543413391557496, + "se": 0.0003318196204736724, + "n": 200 + }, + "member_rmse": { + "mean": 0.0022905301120412108, + "se": 8.520021103333328e-06, + "n": 200 + }, + "shared_bias": { + "mean": -0.0001860509174779412, + "se": 5.312595417824318e-06, + "n": 200 + }, + "coverage68": { + "mean": 0.998122270742358, + "se": 0.00016528619731370097, + "n": 200 + }, + "coverage95": { + "mean": 1.0, + "se": 0.0, + "n": 200 + }, + "coverage95_posterior": { + "mean": 0.6043449781659389, + "se": 0.003806634018768227, + "n": 200 + }, + "median_sd": { + "mean": 0.0022243873495228802, + "se": 6.529750797552057e-06, + "n": 200 + }, + "median_halfwidth95": { + "mean": 0.004359719127120263, + "se": 1.2798076492173322e-05, + "n": 200 + }, + "bias": { + "mean": -0.0001860509174779412, + "se": 5.312595417824318e-06, + "n": 200 + }, + "rmse": { + "mean": 0.0006562279066809316, + "se": 4.700894391034319e-06, + "n": 200 + }, + "max_abs_err": { + "mean": 0.0024996090443816068, + "se": 3.85952692960486e-05, + "n": 200 + }, + "tau": { + "mean": 0.00024557373653242133, + "se": 7.305013459945172e-06, + "n": 200 + }, + "s": { + "mean": 10.882459108645099, + "se": 0.03153730492639741, + "n": 200 + }, + "corr_length_days": { + "mean": 29.385197564047974, + "se": 0.8717482608128544, + "n": 200 + }, + "n_eff": { + "mean": 32.438931923608706, + "se": 0.6620043163346215, + "n": 200 + }, + "missing_fraction": { + "mean": 0.0, + "se": 0.0, + "n": 200 + }, + "prior_weight_tau2": { + "mean": 0.0849718380229744, + "se": 0.008154641100002807, + "n": 200 + }, + "prior_weight_s2": { + "mean": 6.372640064716824e-14, + "se": 3.7249316455067295e-16, + "n": 200 + }, + "prior_weight_lambda": { + "mean": 3.884222388790273e-05, + "se": 1.1626877725726795e-05, + "n": 200 + }, + "member_coverage95_within_margin": true, + "member_coverage68_within_margin": false + }, + "results": [ + { + "seed": 2000, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7962154294032023, + "member_coverage95": 0.9570596797671034, + "member_rmse": 0.002038718442699086, + "shared_bias": -0.00011988949422870605, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5895196506550219, + "median_sd": 0.0020808843985969886, + "median_halfwidth95": 0.004078458509411748, + "bias": -0.00011988949422870605, + "rmse": 0.0006041998532341015, + "max_abs_err": 0.0022943949347862176, + "tau": 0.00010598599350614421, + "s": 10.321087257444152, + "corr_length_days": 25.844180500197915, + "n_eff": 38.58337528497961, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.2507991221287591, + "prior_weight_s2": 7.032731262621368e-14, + "prior_weight_lambda": 4.1076243145699224e-05 + }, + { + "seed": 2001, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8016739446870451, + "member_coverage95": 0.9552401746724891, + "member_rmse": 0.0021936547362796884, + "shared_bias": -0.0003072503673617776, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.7030567685589519, + "median_sd": 0.0021804892047592992, + "median_halfwidth95": 0.0042736803437168555, + "bias": -0.0003072503673617776, + "rmse": 0.0006462617921506305, + "max_abs_err": 0.0023159291676898433, + "tau": 0.0003661321165730547, + "s": 10.582856671528459, + "corr_length_days": 63.49610323720028, + "n_eff": 24.54326039880192, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.013641377781969607, + "prior_weight_s2": 6.713246925935933e-14, + "prior_weight_lambda": 1.870401413182162e-05 + }, + { + "seed": 2002, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7954876273653566, + "member_coverage95": 0.9490538573508006, + "member_rmse": 0.002293239923310836, + "shared_bias": -0.00023946934220935378, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5764192139737991, + "median_sd": 0.002248491995960929, + "median_halfwidth95": 0.004406963366371567, + "bias": -0.00023946934220935378, + "rmse": 0.000739491210678255, + "max_abs_err": 0.0036696245532438524, + "tau": 0.0002489650493008014, + "s": 10.861978091300161, + "corr_length_days": 23.112717496875412, + "n_eff": 28.410566199387695, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03187678957074796, + "prior_weight_s2": 6.360600465722954e-14, + "prior_weight_lambda": 1.5547982948117766e-05 + }, + { + "seed": 2003, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8129548762736536, + "member_coverage95": 0.9588791848617176, + "member_rmse": 0.002310294296334633, + "shared_bias": -0.00025919367106996377, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.4890829694323144, + "median_sd": 0.002291112850809101, + "median_halfwidth95": 0.004490498707523208, + "bias": -0.00025919367106996377, + "rmse": 0.00066395914546569, + "max_abs_err": 0.0018043567764957056, + "tau": 0.0001162837455763385, + "s": 11.243846548783958, + "corr_length_days": 28.30418778149981, + "n_eff": 42.10228350457391, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.21928607809073344, + "prior_weight_s2": 5.928027259691075e-14, + "prior_weight_lambda": 3.0014226470892347e-05 + }, + { + "seed": 2004, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8009461426491994, + "member_coverage95": 0.9508733624454149, + "member_rmse": 0.002246481199122198, + "shared_bias": -0.00021988461798161786, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5458515283842795, + "median_sd": 0.0022045287379861634, + "median_halfwidth95": 0.004320796963418313, + "bias": -0.00021988461798161786, + "rmse": 0.0006671500033599826, + "max_abs_err": 0.002798831219007448, + "tau": 0.0003220619472135432, + "s": 10.823111423017536, + "corr_length_days": 36.380253178355005, + "n_eff": 24.987417298457068, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.016358901865420286, + "prior_weight_s2": 6.391051252003937e-14, + "prior_weight_lambda": 3.591381092723566e-05 + }, + { + "seed": 2005, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8286026200873362, + "member_coverage95": 0.9566957787481805, + "member_rmse": 0.0024969235890490702, + "shared_bias": -0.00018993275075909259, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6637554585152838, + "median_sd": 0.002420614065977682, + "median_halfwidth95": 0.004744316427209881, + "bias": -0.00018993275075909259, + "rmse": 0.0006466139204330092, + "max_abs_err": 0.0019708191503032676, + "tau": 0.0004734604456876752, + "s": 11.55148408060569, + "corr_length_days": 36.64489521828873, + "n_eff": 19.02726198278969, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.007771579801425699, + "prior_weight_s2": 5.624707682311548e-14, + "prior_weight_lambda": 2.3124906611506728e-05 + }, + { + "seed": 2006, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8056768558951966, + "member_coverage95": 0.9552401746724891, + "member_rmse": 0.0024693155193865972, + "shared_bias": -0.0002990497065911815, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5895196506550219, + "median_sd": 0.0022573883724008796, + "median_halfwidth95": 0.004424399943924318, + "bias": -0.0002990497065911815, + "rmse": 0.0007310680095799628, + "max_abs_err": 0.0024316232694835387, + "tau": 0.00045898668741357185, + "s": 10.941889429611969, + "corr_length_days": 33.64900654070067, + "n_eff": 17.3711728029583, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.007907723309240477, + "prior_weight_s2": 6.28269079430649e-14, + "prior_weight_lambda": 1.9260911431065242e-05 + }, + { + "seed": 2007, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8085880640465793, + "member_coverage95": 0.9548762736535662, + "member_rmse": 0.002396601515694004, + "shared_bias": -0.00018208648750949884, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6026200873362445, + "median_sd": 0.0023019788331011073, + "median_halfwidth95": 0.004511795641640178, + "bias": -0.00018208648750949884, + "rmse": 0.0007311276135497308, + "max_abs_err": 0.0030471922898320744, + "tau": 0.00022133833529473568, + "s": 11.394617094767622, + "corr_length_days": 30.814229904064565, + "n_eff": 36.88016636412177, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.04422695932001321, + "prior_weight_s2": 5.783260048361493e-14, + "prior_weight_lambda": 1.619993082035672e-05 + }, + { + "seed": 2008, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8216885007278021, + "member_coverage95": 0.960334788937409, + "member_rmse": 0.002295160350703897, + "shared_bias": -0.0003177824096307427, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6419213973799127, + "median_sd": 0.0022678228544540783, + "median_halfwidth95": 0.004444851153107233, + "bias": -0.0003177824096307427, + "rmse": 0.0006166146345673367, + "max_abs_err": 0.0017719055609168753, + "tau": 0.0004128017743445063, + "s": 10.992843026117104, + "corr_length_days": 27.540018551007787, + "n_eff": 18.92384035003212, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.010013884306710281, + "prior_weight_s2": 6.198040433821553e-14, + "prior_weight_lambda": 4.279655402526433e-05 + }, + { + "seed": 2009, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8071324599708879, + "member_coverage95": 0.9563318777292577, + "member_rmse": 0.0024269699165869575, + "shared_bias": -0.0002589412805307033, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5807860262008734, + "median_sd": 0.0023472213174430094, + "median_halfwidth95": 0.00460046928222087, + "bias": -0.0002589412805307033, + "rmse": 0.0007353175315456826, + "max_abs_err": 0.0018847684881719909, + "tau": 0.00015998959398943888, + "s": 11.637627242647314, + "corr_length_days": 45.517886450275576, + "n_eff": 42.76466541159304, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.09440037485339602, + "prior_weight_s2": 5.550765184105241e-14, + "prior_weight_lambda": 1.3246102207162459e-05 + }, + { + "seed": 2010, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7878457059679768, + "member_coverage95": 0.9494177583697234, + "member_rmse": 0.002272019682725855, + "shared_bias": -0.00025549289690864714, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6419213973799127, + "median_sd": 0.002173544370484938, + "median_halfwidth95": 0.004260068718553141, + "bias": -0.00025549289690864714, + "rmse": 0.0006941722730467692, + "max_abs_err": 0.0019933373390017264, + "tau": 0.00032938882942060084, + "s": 10.652207180066071, + "corr_length_days": 29.218250334392515, + "n_eff": 23.430387324871965, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01636312356604365, + "prior_weight_s2": 6.647110391127835e-14, + "prior_weight_lambda": 9.163504687551802e-06 + }, + { + "seed": 2011, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8016739446870451, + "member_coverage95": 0.9512372634643377, + "member_rmse": 0.0022845118735044384, + "shared_bias": -0.0003122645471513611, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5938864628820961, + "median_sd": 0.0021233083322935286, + "median_halfwidth95": 0.0041616078921953535, + "bias": -0.0003122645471513611, + "rmse": 0.0006434169043201722, + "max_abs_err": 0.0022194507065107505, + "tau": 0.00031244938599771205, + "s": 10.42003388697329, + "corr_length_days": 23.952685909376946, + "n_eff": 23.06991667044032, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01690073995026121, + "prior_weight_s2": 6.936423180617137e-14, + "prior_weight_lambda": 2.3297865663322987e-05 + }, + { + "seed": 2012, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7860262008733624, + "member_coverage95": 0.9494177583697234, + "member_rmse": 0.0021955250030609445, + "shared_bias": -9.952244703647579e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5327510917030568, + "median_sd": 0.0021462236913650065, + "median_halfwidth95": 0.004206521171022524, + "bias": -9.952244703647579e-05, + "rmse": 0.0006402832816119298, + "max_abs_err": 0.0030259153117900336, + "tau": 8.963170312503738e-05, + "s": 10.600518893694796, + "corr_length_days": 22.655493317625584, + "n_eff": 37.90414290895875, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.4219320783375496, + "prior_weight_s2": 6.61776843507184e-14, + "prior_weight_lambda": 6.810010840004078e-05 + }, + { + "seed": 2013, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8078602620087336, + "member_coverage95": 0.9541484716157205, + "member_rmse": 0.00237727568295934, + "shared_bias": -0.00014325995128137482, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6462882096069869, + "median_sd": 0.002341763216785607, + "median_halfwidth95": 0.004589771601423986, + "bias": -0.00014325995128137482, + "rmse": 0.000658436317798892, + "max_abs_err": 0.0029308270235794843, + "tau": 0.0002420233925665223, + "s": 11.138590421956637, + "corr_length_days": 22.845571169695564, + "n_eff": 27.689865230232193, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03384996650224, + "prior_weight_s2": 6.071162921533343e-14, + "prior_weight_lambda": 1.2672648909169076e-05 + }, + { + "seed": 2014, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7903930131004366, + "member_coverage95": 0.9486899563318777, + "member_rmse": 0.0021800039999647033, + "shared_bias": -0.00018053371469962378, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5458515283842795, + "median_sd": 0.0021532597516091623, + "median_halfwidth95": 0.0042203115958029, + "bias": -0.00018053371469962378, + "rmse": 0.0007085907482107224, + "max_abs_err": 0.002375873533230536, + "tau": 0.00013972622016575464, + "s": 10.764988567046245, + "corr_length_days": 24.281621428095452, + "n_eff": 38.28834967244297, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.1374116190948984, + "prior_weight_s2": 6.496657392721554e-14, + "prior_weight_lambda": 1.1714403704280015e-05 + }, + { + "seed": 2015, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8074963609898108, + "member_coverage95": 0.9526928675400291, + "member_rmse": 0.002381189243131361, + "shared_bias": -0.00023080016698512202, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6200873362445415, + "median_sd": 0.002162907822713242, + "median_halfwidth95": 0.004239221467836337, + "bias": -0.00023080016698512202, + "rmse": 0.0006053728679844952, + "max_abs_err": 0.0022121222573485955, + "tau": 0.00034276984331995086, + "s": 10.706450839189184, + "corr_length_days": 24.144646487393814, + "n_eff": 21.544704907337124, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.014577483938844326, + "prior_weight_s2": 6.541942647278907e-14, + "prior_weight_lambda": 2.2853150631856112e-05 + }, + { + "seed": 2016, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7947598253275109, + "member_coverage95": 0.9497816593886463, + "member_rmse": 0.0022008996854032303, + "shared_bias": -0.00010864402760675842, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6462882096069869, + "median_sd": 0.00213799276472903, + "median_halfwidth95": 0.004190388851129369, + "bias": -0.00010864402760675842, + "rmse": 0.0005933346874892891, + "max_abs_err": 0.0030906998042510084, + "tau": 0.0002768804911075801, + "s": 10.30191180175746, + "corr_length_days": 40.34413548941513, + "n_eff": 29.163642956043937, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.024546422477604295, + "prior_weight_s2": 7.107641910505693e-14, + "prior_weight_lambda": 1.3205977264915098e-05 + }, + { + "seed": 2017, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8038573508005823, + "member_coverage95": 0.9566957787481805, + "member_rmse": 0.0022276381410456453, + "shared_bias": -0.00017444725541135346, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6200873362445415, + "median_sd": 0.0023265938207939567, + "median_halfwidth95": 0.004560040131378606, + "bias": -0.00017444725541135346, + "rmse": 0.0006285756934812188, + "max_abs_err": 0.002209919243008128, + "tau": 0.0002996286059184221, + "s": 11.176564678940128, + "corr_length_days": 25.370913501078046, + "n_eff": 23.74471579553847, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.02090271918876552, + "prior_weight_s2": 6.004832356439716e-14, + "prior_weight_lambda": 2.825039169092623e-05 + }, + { + "seed": 2018, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8016739446870451, + "member_coverage95": 0.9577874818049491, + "member_rmse": 0.002272302925506848, + "shared_bias": -5.991750748770566e-05, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6681222707423581, + "median_sd": 0.0022182870798786018, + "median_halfwidth95": 0.004347762818227184, + "bias": -5.991750748770566e-05, + "rmse": 0.0006173271259085556, + "max_abs_err": 0.002156369405960557, + "tau": 0.00010442198667551769, + "s": 11.07247006136319, + "corr_length_days": 37.013778550836335, + "n_eff": 58.007466590610775, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.305315379684021, + "prior_weight_s2": 6.156408532507845e-14, + "prior_weight_lambda": 8.530400403068562e-06 + }, + { + "seed": 2019, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8056768558951966, + "member_coverage95": 0.9592430858806404, + "member_rmse": 0.0022918111157151175, + "shared_bias": -0.0001780716843654148, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6375545851528385, + "median_sd": 0.002270740935061987, + "median_halfwidth95": 0.004450570486047832, + "bias": -0.0001780716843654148, + "rmse": 0.0006458789771136563, + "max_abs_err": 0.0029356055386958613, + "tau": 0.000222571490014638, + "s": 11.173666970743717, + "corr_length_days": 26.504269292815213, + "n_eff": 31.47795495701442, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.04439992174030352, + "prior_weight_s2": 6.036364228084098e-14, + "prior_weight_lambda": 9.423902028922357e-06 + }, + { + "seed": 2020, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8038573508005823, + "member_coverage95": 0.9508733624454149, + "member_rmse": 0.0022135199074355275, + "shared_bias": -0.00020681160974130936, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6069868995633187, + "median_sd": 0.002252734454395904, + "median_halfwidth95": 0.004415278432175614, + "bias": -0.00020681160974130936, + "rmse": 0.0006685880634898114, + "max_abs_err": 0.002742854660286942, + "tau": 0.00010583781222328892, + "s": 10.98501145403563, + "corr_length_days": 29.930950994126373, + "n_eff": 43.764289672262265, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.28495996669288437, + "prior_weight_s2": 6.218677379359177e-14, + "prior_weight_lambda": 1.4818436137857965e-05 + }, + { + "seed": 2021, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8074963609898108, + "member_coverage95": 0.9592430858806404, + "member_rmse": 0.002112060210740099, + "shared_bias": -0.00013542214333471587, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.7117903930131004, + "median_sd": 0.0021457546552873935, + "median_halfwidth95": 0.004205601877195701, + "bias": -0.00013542214333471587, + "rmse": 0.0005544105868379234, + "max_abs_err": 0.0019448823597372645, + "tau": 0.00027767127905838047, + "s": 10.569655490459391, + "corr_length_days": 16.427919113388057, + "n_eff": 26.682286909198183, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.021472929774489054, + "prior_weight_s2": 6.751550916820749e-14, + "prior_weight_lambda": 1.1605409137326587e-05 + }, + { + "seed": 2022, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8060407569141194, + "member_coverage95": 0.9541484716157205, + "member_rmse": 0.0022470002641533865, + "shared_bias": -5.01834334281971e-05, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.5807860262008734, + "median_sd": 0.0022787960909369472, + "median_halfwidth95": 0.004466358301577143, + "bias": -5.01834334281971e-05, + "rmse": 0.0006751059390800043, + "max_abs_err": 0.003504865024946194, + "tau": 9.6143954509755e-05, + "s": 11.332745769464205, + "corr_length_days": 17.33364597973377, + "n_eff": 38.31751938706867, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.38247959259927594, + "prior_weight_s2": 5.828267324970638e-14, + "prior_weight_lambda": 2.6455285802158693e-05 + }, + { + "seed": 2023, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7860262008733624, + "member_coverage95": 0.9490538573508006, + "member_rmse": 0.002248168102706691, + "shared_bias": -0.00022937222814794545, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5327510917030568, + "median_sd": 0.002259214318334745, + "median_halfwidth95": 0.004427978732220641, + "bias": -0.00022937222814794545, + "rmse": 0.0007562276891640902, + "max_abs_err": 0.0020591391707097985, + "tau": 0.00013815313157882297, + "s": 10.807291488201315, + "corr_length_days": 36.75806854873147, + "n_eff": 36.9063812338244, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.14692096175353292, + "prior_weight_s2": 6.467861669474829e-14, + "prior_weight_lambda": 9.540468868159865e-06 + }, + { + "seed": 2024, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7954876273653566, + "member_coverage95": 0.9421397379912664, + "member_rmse": 0.0023199072675266614, + "shared_bias": -0.0003514166607717902, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5283842794759825, + "median_sd": 0.0022279777623093674, + "median_halfwidth95": 0.004366756206926917, + "bias": -0.0003514166607717902, + "rmse": 0.0007643094931227722, + "max_abs_err": 0.0022604679596116275, + "tau": 0.0003805166852842416, + "s": 10.749893663946644, + "corr_length_days": 19.315214389705332, + "n_eff": 19.7268907787653, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.011773858530069573, + "prior_weight_s2": 6.48805174242825e-14, + "prior_weight_lambda": 3.147110794478337e-05 + }, + { + "seed": 2025, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8165938864628821, + "member_coverage95": 0.9574235807860262, + "member_rmse": 0.0023497578775294624, + "shared_bias": -0.00011545910216355833, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5851528384279476, + "median_sd": 0.0022700951085103866, + "median_halfwidth95": 0.004449304689256452, + "bias": -0.00011545910216355833, + "rmse": 0.0006615706346072996, + "max_abs_err": 0.0020309018565390553, + "tau": 0.00024023821546734624, + "s": 11.0986149266551, + "corr_length_days": 38.06983366632724, + "n_eff": 32.87108777824827, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03452389367100696, + "prior_weight_s2": 6.105178499968409e-14, + "prior_weight_lambda": 1.4860665492455612e-05 + }, + { + "seed": 2026, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8013100436681223, + "member_coverage95": 0.9475982532751092, + "member_rmse": 0.002241164056077387, + "shared_bias": -0.00011998447985348245, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6724890829694323, + "median_sd": 0.002166906811477035, + "median_halfwidth95": 0.004247059341849775, + "bias": -0.00011998447985348245, + "rmse": 0.0006143750129682681, + "max_abs_err": 0.0028062983090996613, + "tau": 0.0004051613989761658, + "s": 10.26891209643204, + "corr_length_days": 23.538468294756882, + "n_eff": 18.378713059116883, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.009903897353557433, + "prior_weight_s2": 7.173485436005588e-14, + "prior_weight_lambda": 1.1394162637915535e-05 + }, + { + "seed": 2027, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8209606986899564, + "member_coverage95": 0.9541484716157205, + "member_rmse": 0.002642421322919413, + "shared_bias": -0.00023215061493224315, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5938864628820961, + "median_sd": 0.002345876436371421, + "median_halfwidth95": 0.004597833363736275, + "bias": -0.00023215061493224315, + "rmse": 0.0008806737865528016, + "max_abs_err": 0.004905702141451612, + "tau": 0.0003258592129146732, + "s": 11.442296134761284, + "corr_length_days": 13.127386435611433, + "n_eff": 25.162396040580678, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.016588738424722006, + "prior_weight_s2": 5.75070673743003e-14, + "prior_weight_lambda": 1.3541385861868712e-05 + }, + { + "seed": 2028, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8096797671033479, + "member_coverage95": 0.9574235807860262, + "member_rmse": 0.002234325587459159, + "shared_bias": -0.00010051590216986915, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6244541484716157, + "median_sd": 0.0022313231574747116, + "median_halfwidth95": 0.004373313061016766, + "bias": -0.00010051590216986915, + "rmse": 0.0005797400075256739, + "max_abs_err": 0.0018377306512907636, + "tau": 0.00035255960100666166, + "s": 10.871672174080583, + "corr_length_days": 22.644605999136452, + "n_eff": 21.590891679120165, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.013780155050665238, + "prior_weight_s2": 6.353666454398811e-14, + "prior_weight_lambda": 2.4816867036693273e-05 + }, + { + "seed": 2029, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8074963609898108, + "member_coverage95": 0.960334788937409, + "member_rmse": 0.0020473588277642248, + "shared_bias": -0.00010210537171389447, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6026200873362445, + "median_sd": 0.0021395099216645094, + "median_halfwidth95": 0.004193362424105259, + "bias": -0.00010210537171389447, + "rmse": 0.0005907861638275797, + "max_abs_err": 0.0018725991426192566, + "tau": 0.00027221151241218306, + "s": 10.300003773076774, + "corr_length_days": 20.86493451015454, + "n_eff": 28.025446312851862, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.02630727306806372, + "prior_weight_s2": 7.076220199306436e-14, + "prior_weight_lambda": 2.5446232771675375e-05 + }, + { + "seed": 2030, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8093158660844251, + "member_coverage95": 0.9563318777292577, + "member_rmse": 0.0023959515117671737, + "shared_bias": -0.00018746643428877832, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6462882096069869, + "median_sd": 0.002295733511092644, + "median_halfwidth95": 0.004499555035335182, + "bias": -0.00018746643428877832, + "rmse": 0.0006033651278740265, + "max_abs_err": 0.002504403590803894, + "tau": 0.00036406114991340807, + "s": 11.171455949392067, + "corr_length_days": 41.746164860028514, + "n_eff": 26.755223602443944, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.012865833501772148, + "prior_weight_s2": 6.001878871953197e-14, + "prior_weight_lambda": 2.4995638893341372e-05 + }, + { + "seed": 2031, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8176855895196506, + "member_coverage95": 0.9588791848617176, + "member_rmse": 0.0025381872416717533, + "shared_bias": -0.0001285323231707805, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6550218340611353, + "median_sd": 0.0023939563462395666, + "median_halfwidth95": 0.004692068256201086, + "bias": -0.0001285323231707805, + "rmse": 0.0005850491847546562, + "max_abs_err": 0.002311806861065892, + "tau": 0.0003404217948835901, + "s": 11.638226395968676, + "corr_length_days": 24.835505681006495, + "n_eff": 23.83450672304501, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.015253397339716966, + "prior_weight_s2": 5.512719391798728e-14, + "prior_weight_lambda": 4.6263983348237826e-05 + }, + { + "seed": 2032, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7922125181950509, + "member_coverage95": 0.9501455604075691, + "member_rmse": 0.0022521856070758404, + "shared_bias": -0.0002752691977371578, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6200873362445415, + "median_sd": 0.002259629325621283, + "median_halfwidth95": 0.004428792131561992, + "bias": -0.0002752691977371578, + "rmse": 0.0006235982048288117, + "max_abs_err": 0.00205708992296986, + "tau": 0.00032589471795722543, + "s": 10.969562280428503, + "corr_length_days": 9.34882424146594, + "n_eff": 27.00103685030228, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01661586109258922, + "prior_weight_s2": 6.228619999121822e-14, + "prior_weight_lambda": 3.704076923982265e-05 + }, + { + "seed": 2033, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8424308588064047, + "member_coverage95": 0.960334788937409, + "member_rmse": 0.0024348719891138966, + "shared_bias": -0.00020794446023167344, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5895196506550219, + "median_sd": 0.002433474149409429, + "median_halfwidth95": 0.004769521727773102, + "bias": -0.00020794446023167344, + "rmse": 0.0005947176732938107, + "max_abs_err": 0.002411764140916497, + "tau": 0.00012187674403788302, + "s": 11.901463260245482, + "corr_length_days": 10.71740975036268, + "n_eff": 47.10733098882554, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.20786318034423382, + "prior_weight_s2": 5.2347258477287076e-14, + "prior_weight_lambda": 9.321703970697436e-05 + }, + { + "seed": 2034, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8162299854439592, + "member_coverage95": 0.960334788937409, + "member_rmse": 0.00231410954189766, + "shared_bias": -0.0002681137870827308, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5807860262008734, + "median_sd": 0.002234605891766777, + "median_halfwidth95": 0.004379747102050779, + "bias": -0.0002681137870827308, + "rmse": 0.0006831032359164964, + "max_abs_err": 0.0025159298998441767, + "tau": 0.00035267877879104157, + "s": 10.81209082178931, + "corr_length_days": 19.871927855865845, + "n_eff": 21.833473269615496, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.013940988395931244, + "prior_weight_s2": 6.408493304874433e-14, + "prior_weight_lambda": 4.370494112983732e-05 + }, + { + "seed": 2035, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7882096069868996, + "member_coverage95": 0.9479621542940321, + "member_rmse": 0.0021698731696376135, + "shared_bias": -3.882356918681098e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6855895196506551, + "median_sd": 0.0021015613155250397, + "median_halfwidth95": 0.004118984522221719, + "bias": -3.882356918681098e-05, + "rmse": 0.000639736764939539, + "max_abs_err": 0.00312989778005246, + "tau": 9.474296910804516e-05, + "s": 10.134894043020376, + "corr_length_days": 26.44577871971707, + "n_eff": 40.99025776883557, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.34998529660508293, + "prior_weight_s2": 7.348754543141152e-14, + "prior_weight_lambda": 1.0186271904681818e-05 + }, + { + "seed": 2036, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7849344978165939, + "member_coverage95": 0.9486899563318777, + "member_rmse": 0.002246949220627199, + "shared_bias": -0.00032726027261884103, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5458515283842795, + "median_sd": 0.0022325415942241315, + "median_halfwidth95": 0.004375701153181906, + "bias": -0.00032726027261884103, + "rmse": 0.0007564525045972506, + "max_abs_err": 0.0023464907843143267, + "tau": 0.0004467984763338987, + "s": 10.659822582990428, + "corr_length_days": 47.048453924151055, + "n_eff": 17.168357647604754, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.008581662439490085, + "prior_weight_s2": 6.616871192926823e-14, + "prior_weight_lambda": 1.73886009606499e-05 + }, + { + "seed": 2037, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8067685589519651, + "member_coverage95": 0.9570596797671034, + "member_rmse": 0.002284682742341532, + "shared_bias": -0.00016156637564052447, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6593886462882096, + "median_sd": 0.0022456584479201777, + "median_halfwidth95": 0.004401409714219423, + "bias": -0.00016156637564052447, + "rmse": 0.0005727394081788816, + "max_abs_err": 0.0021001162314768598, + "tau": 0.00016647457888676308, + "s": 10.952192087641649, + "corr_length_days": 38.08226430205456, + "n_eff": 45.38153421442023, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.08958733401758118, + "prior_weight_s2": 6.235710887046123e-14, + "prior_weight_lambda": 3.94792720497849e-05 + }, + { + "seed": 2038, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8067685589519651, + "member_coverage95": 0.9588791848617176, + "member_rmse": 0.00249522041868231, + "shared_bias": -0.00010012934909797262, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6550218340611353, + "median_sd": 0.0024090557823271664, + "median_halfwidth95": 0.0047216626073530825, + "bias": -0.00010012934909797262, + "rmse": 0.000645023846080873, + "max_abs_err": 0.0030088094526837766, + "tau": 0.0003851841245030623, + "s": 11.711488451499442, + "corr_length_days": 26.64263187534013, + "n_eff": 22.181174026276107, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.012064433806979871, + "prior_weight_s2": 5.453478117971582e-14, + "prior_weight_lambda": 3.480093445100642e-05 + }, + { + "seed": 2039, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8056768558951966, + "member_coverage95": 0.9508733624454149, + "member_rmse": 0.0022207734714569643, + "shared_bias": -0.0002951757762096248, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5982532751091703, + "median_sd": 0.0021766698037368882, + "median_halfwidth95": 0.004266194455211367, + "bias": -0.0002951757762096248, + "rmse": 0.0006569042240164759, + "max_abs_err": 0.002148122219850627, + "tau": 0.00026719450433957515, + "s": 10.271104466042743, + "corr_length_days": 49.730723779275095, + "n_eff": 33.38749010054204, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.02640050819447522, + "prior_weight_s2": 7.118289661721394e-14, + "prior_weight_lambda": 1.6034262093110797e-05 + }, + { + "seed": 2040, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8060407569141194, + "member_coverage95": 0.9537845705967977, + "member_rmse": 0.0023238729269326004, + "shared_bias": -0.00015099822536441884, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5502183406113537, + "median_sd": 0.0023148574984752923, + "median_halfwidth95": 0.004537037362141628, + "bias": -0.00015099822536441884, + "rmse": 0.0006425767175811262, + "max_abs_err": 0.0027777278380337364, + "tau": 0.00041491845279507337, + "s": 11.158626373578015, + "corr_length_days": 34.99589889923144, + "n_eff": 19.548818104588292, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.009198835707432497, + "prior_weight_s2": 5.986500186898769e-14, + "prior_weight_lambda": 0.00010316406146731166 + }, + { + "seed": 2041, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7922125181950509, + "member_coverage95": 0.9472343522561864, + "member_rmse": 0.002235940930527486, + "shared_bias": -0.00010495657550609023, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.6157205240174672, + "median_sd": 0.0022247189326451105, + "median_halfwidth95": 0.0043603690181028415, + "bias": -0.00010495657550609023, + "rmse": 0.0007855460695291553, + "max_abs_err": 0.0026372836478772807, + "tau": 8.365690223504578e-05, + "s": 11.050525746534039, + "corr_length_days": 20.243960177825265, + "n_eff": 33.03430495812052, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.5278381135804061, + "prior_weight_s2": 6.147887749659834e-14, + "prior_weight_lambda": 1.698059707738028e-05 + }, + { + "seed": 2042, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8202328966521106, + "member_coverage95": 0.9588791848617176, + "member_rmse": 0.0023773232770248204, + "shared_bias": -0.00023265510587512997, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5414847161572053, + "median_sd": 0.002309543565120849, + "median_halfwidth95": 0.00452662224406852, + "bias": -0.00023265510587512997, + "rmse": 0.0006895441264550915, + "max_abs_err": 0.001994201504660026, + "tau": 0.00017116331243248727, + "s": 11.425359339907246, + "corr_length_days": 54.19678154064306, + "n_eff": 49.48506503874312, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0817192323241462, + "prior_weight_s2": 5.753656983544431e-14, + "prior_weight_lambda": 2.0863564287002548e-05 + }, + { + "seed": 2043, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8053129548762736, + "member_coverage95": 0.9581513828238719, + "member_rmse": 0.0023085315515379637, + "shared_bias": -0.0001188559627895034, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5764192139737991, + "median_sd": 0.002346894008547319, + "median_halfwidth95": 0.004599827768568438, + "bias": -0.0001188559627895034, + "rmse": 0.00046255944697483304, + "max_abs_err": 0.0022640604538440336, + "tau": 0.00015538397167457542, + "s": 11.51903831587933, + "corr_length_days": 12.534133573219824, + "n_eff": 42.65847199742439, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.11265645845857333, + "prior_weight_s2": 5.5583438181531644e-14, + "prior_weight_lambda": 0.0023164710053183678 + }, + { + "seed": 2044, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8104075691411936, + "member_coverage95": 0.9566957787481805, + "member_rmse": 0.0022959022024631663, + "shared_bias": -0.0002917354418329165, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.4759825327510917, + "median_sd": 0.0023351335663282036, + "median_halfwidth95": 0.004576777725194892, + "bias": -0.0002917354418329165, + "rmse": 0.0007315953606804376, + "max_abs_err": 0.0017306581982062834, + "tau": 0.00017240626550638877, + "s": 11.405737934896495, + "corr_length_days": 52.7007054583835, + "n_eff": 46.72817210884477, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.07883885614823845, + "prior_weight_s2": 5.780437455668705e-14, + "prior_weight_lambda": 1.90504341556172e-05 + }, + { + "seed": 2045, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7903930131004366, + "member_coverage95": 0.9483260553129549, + "member_rmse": 0.002176298744039863, + "shared_bias": -6.664145599085987e-05, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.62882096069869, + "median_sd": 0.0021677058236680554, + "median_halfwidth95": 0.004248625376979736, + "bias": -6.664145599085987e-05, + "rmse": 0.0006517013050860713, + "max_abs_err": 0.0016886669972535585, + "tau": 0.00015589022265215835, + "s": 10.851405680918706, + "corr_length_days": 9.414847471979126, + "n_eff": 44.75088812379154, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.09641917042980334, + "prior_weight_s2": 6.404720004453465e-14, + "prior_weight_lambda": 8.843829799693507e-06 + }, + { + "seed": 2046, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7940320232896652, + "member_coverage95": 0.9468704512372634, + "member_rmse": 0.002185319345374306, + "shared_bias": -0.00024197826491030228, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6200873362445415, + "median_sd": 0.0021166388263097182, + "median_halfwidth95": 0.004148535900569301, + "bias": -0.00024197826491030228, + "rmse": 0.0005942806159979684, + "max_abs_err": 0.0024258783611314457, + "tau": 0.00024065552864323028, + "s": 10.30898241729678, + "corr_length_days": 41.98309892386523, + "n_eff": 30.63347267874998, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.033881816712502344, + "prior_weight_s2": 7.045042369708561e-14, + "prior_weight_lambda": 3.4017094579908036e-05 + }, + { + "seed": 2047, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8020378457059679, + "member_coverage95": 0.9570596797671034, + "member_rmse": 0.002175418514848339, + "shared_bias": -0.0002696433795995783, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6200873362445415, + "median_sd": 0.0021644325486555416, + "median_halfwidth95": 0.00424220987579311, + "bias": -0.0002696433795995783, + "rmse": 0.0006269368796626734, + "max_abs_err": 0.0027455215796135346, + "tau": 0.00022944369346877437, + "s": 10.777656474406598, + "corr_length_days": 42.65630170089506, + "n_eff": 35.28734238679095, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03721889484251461, + "prior_weight_s2": 6.480867803849835e-14, + "prior_weight_lambda": 2.3295121569552727e-05 + }, + { + "seed": 2048, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7940320232896652, + "member_coverage95": 0.9585152838427947, + "member_rmse": 0.0023250184547870616, + "shared_bias": -1.5040830936635205e-05, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5807860262008734, + "median_sd": 0.002275095699590337, + "median_halfwidth95": 0.004459105667751875, + "bias": -1.5040830936635205e-05, + "rmse": 0.0006346778813212387, + "max_abs_err": 0.0019448238150566633, + "tau": 0.00010941620048979257, + "s": 11.308569216085708, + "corr_length_days": 56.97358370459256, + "n_eff": 63.077771513341375, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.2644391521641997, + "prior_weight_s2": 5.872058924777762e-14, + "prior_weight_lambda": 1.5673150053729815e-05 + }, + { + "seed": 2049, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8053129548762736, + "member_coverage95": 0.9552401746724891, + "member_rmse": 0.0023619036947107497, + "shared_bias": -0.00010043195218656221, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5851528384279476, + "median_sd": 0.002318336753083752, + "median_halfwidth95": 0.004543856575921042, + "bias": -0.00010043195218656221, + "rmse": 0.000708397515734398, + "max_abs_err": 0.0022742074520141274, + "tau": 0.00011091129847663776, + "s": 11.378609066319811, + "corr_length_days": 20.18321343344266, + "n_eff": 37.84278018219884, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.27787219931761364, + "prior_weight_s2": 5.807911308176582e-14, + "prior_weight_lambda": 1.536913051552351e-05 + }, + { + "seed": 2050, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8045851528384279, + "member_coverage95": 0.9530567685589519, + "member_rmse": 0.0024484304082545015, + "shared_bias": -0.00020245228841869804, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5633187772925764, + "median_sd": 0.002307591161833037, + "median_halfwidth95": 0.004522795603910926, + "bias": -0.00020245228841869804, + "rmse": 0.000713585409110578, + "max_abs_err": 0.002191556090506402, + "tau": 0.0002112730251277078, + "s": 11.302909115231948, + "corr_length_days": 15.217898583790321, + "n_eff": 34.30765779521461, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.04801671879624015, + "prior_weight_s2": 5.860880361105536e-14, + "prior_weight_lambda": 1.9509612386927137e-05 + }, + { + "seed": 2051, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7918486171761281, + "member_coverage95": 0.9530567685589519, + "member_rmse": 0.002263382207593248, + "shared_bias": -0.00031177233769319273, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5807860262008734, + "median_sd": 0.002180805591034273, + "median_halfwidth95": 0.0042743004494258975, + "bias": -0.00031177233769319273, + "rmse": 0.0006422072579597525, + "max_abs_err": 0.00226126071390244, + "tau": 0.00026002265564445046, + "s": 10.748554820978072, + "corr_length_days": 20.363011042469715, + "n_eff": 26.683671950376667, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.026163043232397546, + "prior_weight_s2": 6.510215968821013e-14, + "prior_weight_lambda": 1.610195858219058e-05 + }, + { + "seed": 2052, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7991266375545851, + "member_coverage95": 0.9614264919941776, + "member_rmse": 0.0022406535184619062, + "shared_bias": -0.0002029676283744197, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6069868995633187, + "median_sd": 0.002208365486087497, + "median_halfwidth95": 0.004328316851573995, + "bias": -0.0002029676283744197, + "rmse": 0.0006946275350432712, + "max_abs_err": 0.0023682235523246682, + "tau": 0.0001409855950742515, + "s": 10.957471234415408, + "corr_length_days": 43.913535896686874, + "n_eff": 45.13055287455567, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.1281461569475814, + "prior_weight_s2": 6.263295920029203e-14, + "prior_weight_lambda": 1.4739447283979183e-05 + }, + { + "seed": 2053, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8034934497816594, + "member_coverage95": 0.9556040756914119, + "member_rmse": 0.0021275575510062987, + "shared_bias": -0.00018439172454551322, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6069868995633187, + "median_sd": 0.0021296018786507707, + "median_halfwidth95": 0.004173943016487879, + "bias": -0.00018439172454551322, + "rmse": 0.0006727421595748124, + "max_abs_err": 0.0032269477741445995, + "tau": 8.647689032203287e-05, + "s": 10.578088738374493, + "corr_length_days": 23.27460897851914, + "n_eff": 39.024661067229694, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.4266913547806229, + "prior_weight_s2": 6.710929628049803e-14, + "prior_weight_lambda": 1.819872089640044e-05 + }, + { + "seed": 2054, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8282387190684134, + "member_coverage95": 0.9632459970887919, + "member_rmse": 0.0022731327189585366, + "shared_bias": -0.000277643245452481, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6637554585152838, + "median_sd": 0.002240918788625556, + "median_halfwidth95": 0.0043921201526297, + "bias": -0.000277643245452481, + "rmse": 0.0005232014918154508, + "max_abs_err": 0.0020054160250825167, + "tau": 0.0003106486677064139, + "s": 11.048029161404811, + "corr_length_days": 7.102916206542862, + "n_eff": 30.726644296360742, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.018335279169255418, + "prior_weight_s2": 6.108438482125992e-14, + "prior_weight_lambda": 6.559735797105041e-05 + }, + { + "seed": 2055, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7882096069868996, + "member_coverage95": 0.9417758369723436, + "member_rmse": 0.0021892457099626553, + "shared_bias": -0.0002724677977625717, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5851528384279476, + "median_sd": 0.002104720263079866, + "median_halfwidth95": 0.0041251759457070665, + "bias": -0.0002724677977625717, + "rmse": 0.0006969398201192657, + "max_abs_err": 0.003270715756658083, + "tau": 0.00019495960345452629, + "s": 10.360723121785089, + "corr_length_days": 36.431107593545406, + "n_eff": 32.14237844914772, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.053748309961308326, + "prior_weight_s2": 7.001004316424056e-14, + "prior_weight_lambda": 1.8691599837152867e-05 + }, + { + "seed": 2056, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7987627365356623, + "member_coverage95": 0.9574235807860262, + "member_rmse": 0.0022495268219462346, + "shared_bias": -0.0002553510413973058, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5414847161572053, + "median_sd": 0.002168037192098822, + "median_halfwidth95": 0.004249274847174776, + "bias": -0.0002553510413973058, + "rmse": 0.0006923016653119085, + "max_abs_err": 0.0020268543607958505, + "tau": 0.0002434695931929046, + "s": 10.933222147338133, + "corr_length_days": 16.689067156509434, + "n_eff": 31.409303496109942, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03402499424094584, + "prior_weight_s2": 6.289424350201047e-14, + "prior_weight_lambda": 1.8586505769865338e-05 + }, + { + "seed": 2057, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7983988355167394, + "member_coverage95": 0.9519650655021834, + "member_rmse": 0.0023322852338037857, + "shared_bias": -5.2190599246953254e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6593886462882096, + "median_sd": 0.0021934927234840964, + "median_halfwidth95": 0.0042991667722907835, + "bias": -5.2190599246953254e-05, + "rmse": 0.0006328983257177797, + "max_abs_err": 0.0035653617421085295, + "tau": 0.00016481947363576388, + "s": 11.04336438034179, + "corr_length_days": 46.99691990323771, + "n_eff": 40.741431903785745, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.09368713159870214, + "prior_weight_s2": 6.166079172703858e-14, + "prior_weight_lambda": 1.4202913589514594e-05 + }, + { + "seed": 2058, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8056768558951966, + "member_coverage95": 0.9585152838427947, + "member_rmse": 0.0024660760926740826, + "shared_bias": -0.0001596052254338869, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5764192139737991, + "median_sd": 0.002313190527812099, + "median_halfwidth95": 0.004533770159652712, + "bias": -0.0001596052254338869, + "rmse": 0.000607923078952057, + "max_abs_err": 0.001941282955633531, + "tau": 0.00041695374888570043, + "s": 11.3746241060051, + "corr_length_days": 13.738889094769386, + "n_eff": 19.54565718456158, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.009896003700364307, + "prior_weight_s2": 5.762899103336521e-14, + "prior_weight_lambda": 7.747265697139258e-05 + }, + { + "seed": 2059, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8278748180494906, + "member_coverage95": 0.9592430858806404, + "member_rmse": 0.0022659277345721896, + "shared_bias": -8.551359457738287e-05, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5851528384279476, + "median_sd": 0.0022684405382959708, + "median_halfwidth95": 0.004446061791200724, + "bias": -8.551359457738287e-05, + "rmse": 0.0006053573260278495, + "max_abs_err": 0.0023657582722880436, + "tau": 0.00022015179956074308, + "s": 11.059252743876247, + "corr_length_days": 41.0672978476285, + "n_eff": 40.42289010846272, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.043088260329344825, + "prior_weight_s2": 6.121264430207131e-14, + "prior_weight_lambda": 1.9548517162027937e-05 + }, + { + "seed": 2060, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7962154294032023, + "member_coverage95": 0.9566957787481805, + "member_rmse": 0.0021618575337845614, + "shared_bias": -0.0002864301057866739, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5720524017467249, + "median_sd": 0.002202329985888885, + "median_halfwidth95": 0.004316487488462723, + "bias": -0.0002864301057866739, + "rmse": 0.0006238572338126897, + "max_abs_err": 0.002142176556775644, + "tau": 0.0002763891690552026, + "s": 10.496603872759705, + "corr_length_days": 32.94321955698216, + "n_eff": 25.54113284912994, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.02346177908615786, + "prior_weight_s2": 6.804345691263186e-14, + "prior_weight_lambda": 2.0049034278220437e-05 + }, + { + "seed": 2061, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8056768558951966, + "member_coverage95": 0.9512372634643377, + "member_rmse": 0.002201973302002493, + "shared_bias": -0.00021994489955052927, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6375545851528385, + "median_sd": 0.002155388211724177, + "median_halfwidth95": 0.004224483301003765, + "bias": -0.00021994489955052927, + "rmse": 0.0006095092676242668, + "max_abs_err": 0.0018889908992574794, + "tau": 0.00030643965603545424, + "s": 10.442909289820182, + "corr_length_days": 18.58428084997431, + "n_eff": 24.301972626423385, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.018130038919794353, + "prior_weight_s2": 6.879037701255633e-14, + "prior_weight_lambda": 2.1667222527850192e-05 + }, + { + "seed": 2062, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8096797671033479, + "member_coverage95": 0.9563318777292577, + "member_rmse": 0.0023064138494542814, + "shared_bias": -0.0002460934085929151, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6681222707423581, + "median_sd": 0.002292432391418756, + "median_halfwidth95": 0.00449308495961467, + "bias": -0.0002460934085929151, + "rmse": 0.0006857748167303287, + "max_abs_err": 0.0030328244023314446, + "tau": 0.00033389731053677126, + "s": 11.05848210080776, + "corr_length_days": 21.188998715095135, + "n_eff": 24.040772146957053, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01566681582589008, + "prior_weight_s2": 6.174948945126342e-14, + "prior_weight_lambda": 1.0352747586363921e-05 + }, + { + "seed": 2063, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7976710334788938, + "member_coverage95": 0.9486899563318777, + "member_rmse": 0.0021575690469587054, + "shared_bias": -0.00011990410323204795, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6768558951965066, + "median_sd": 0.002210886546498712, + "median_halfwidth95": 0.0043332580392218024, + "bias": -0.00011990410323204795, + "rmse": 0.0006593974301036794, + "max_abs_err": 0.002590283925522777, + "tau": 0.00022973572769199272, + "s": 10.79893084357232, + "corr_length_days": 28.901183737184287, + "n_eff": 29.37171744328918, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.037926024617034294, + "prior_weight_s2": 6.483129371034938e-14, + "prior_weight_lambda": 6.836792589415123e-06 + }, + { + "seed": 2064, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7958515283842795, + "member_coverage95": 0.9465065502183406, + "member_rmse": 0.002159174852046236, + "shared_bias": -0.00020156147347537593, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6157205240174672, + "median_sd": 0.0021645061405900323, + "median_halfwidth95": 0.004242354113335402, + "bias": -0.00020156147347537593, + "rmse": 0.0006637193870593252, + "max_abs_err": 0.0028506183281560276, + "tau": 0.00028399365515981536, + "s": 10.562496405379074, + "corr_length_days": 34.994502061676556, + "n_eff": 27.774852828464578, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.023669736058890178, + "prior_weight_s2": 6.749203827085245e-14, + "prior_weight_lambda": 1.228548539539174e-05 + }, + { + "seed": 2065, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8231441048034934, + "member_coverage95": 0.9592430858806404, + "member_rmse": 0.0024519947292874203, + "shared_bias": -0.00015107967028900917, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6331877729257642, + "median_sd": 0.0023450199862705373, + "median_halfwidth95": 0.004596154752370747, + "bias": -0.00015107967028900917, + "rmse": 0.0007583120561348312, + "max_abs_err": 0.0030179803850377282, + "tau": 0.00032449527864990415, + "s": 11.543904372534216, + "corr_length_days": 45.49617988660128, + "n_eff": 27.760068242930494, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.016936760554840367, + "prior_weight_s2": 5.6609970957641297e-14, + "prior_weight_lambda": 9.33353543691754e-06 + }, + { + "seed": 2066, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7973071324599709, + "member_coverage95": 0.9446870451237264, + "member_rmse": 0.0022825300111965026, + "shared_bias": -0.0002565681489374083, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5283842794759825, + "median_sd": 0.00231276051049699, + "median_halfwidth95": 0.004532927341195722, + "bias": -0.0002565681489374083, + "rmse": 0.0006852958998762297, + "max_abs_err": 0.0017120046417756446, + "tau": 0.00016198351389264159, + "s": 11.331715993779937, + "corr_length_days": 27.49807892114495, + "n_eff": 34.78638213479563, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.09127825678053744, + "prior_weight_s2": 5.847980484083993e-14, + "prior_weight_lambda": 2.5097158011632374e-05 + }, + { + "seed": 2067, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8071324599708879, + "member_coverage95": 0.9530567685589519, + "member_rmse": 0.002113137893087683, + "shared_bias": -0.00020665053801373188, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6244541484716157, + "median_sd": 0.0021165123124810233, + "median_halfwidth95": 0.004148287938019557, + "bias": -0.00020665053801373188, + "rmse": 0.0005712832049446546, + "max_abs_err": 0.0029497265771122588, + "tau": 0.00024008294152601904, + "s": 10.190145571488713, + "corr_length_days": 11.335572621684184, + "n_eff": 31.543441584878384, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0329816973738098, + "prior_weight_s2": 7.183670285454947e-14, + "prior_weight_lambda": 9.129386315729428e-05 + }, + { + "seed": 2068, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8118631732168851, + "member_coverage95": 0.9559679767103348, + "member_rmse": 0.0023941576491115432, + "shared_bias": -0.0002930075375358303, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6593886462882096, + "median_sd": 0.0023026363030781874, + "median_halfwidth95": 0.004513084259126336, + "bias": -0.0002930075375358303, + "rmse": 0.000633506906671029, + "max_abs_err": 0.001916695175446864, + "tau": 0.0002573837869317018, + "s": 11.123160530145526, + "corr_length_days": 28.91463429559758, + "n_eff": 33.78730533877245, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.028565808623166638, + "prior_weight_s2": 6.08373082477893e-14, + "prior_weight_lambda": 1.0864004312437543e-05 + }, + { + "seed": 2069, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8169577874818049, + "member_coverage95": 0.9548762736535662, + "member_rmse": 0.002355625091524106, + "shared_bias": -0.00026797649288083793, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6550218340611353, + "median_sd": 0.0022923916336926664, + "median_halfwidth95": 0.004493005075938813, + "bias": -0.00026797649288083793, + "rmse": 0.0006265252177183669, + "max_abs_err": 0.0027582331472651034, + "tau": 0.0004576991395056624, + "s": 10.983283538800908, + "corr_length_days": 52.04201938021933, + "n_eff": 18.984114003078183, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.008288955133363307, + "prior_weight_s2": 6.223381708229195e-14, + "prior_weight_lambda": 2.823740882724983e-05 + }, + { + "seed": 2070, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8264192139737991, + "member_coverage95": 0.962882096069869, + "member_rmse": 0.0025225868514684217, + "shared_bias": -0.0004293441734238469, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5458515283842795, + "median_sd": 0.0022999400672383437, + "median_halfwidth95": 0.004507799733944733, + "bias": -0.0004293441734238469, + "rmse": 0.0007039715583930079, + "max_abs_err": 0.002241844963046121, + "tau": 0.0005581785647392428, + "s": 11.082812476478079, + "corr_length_days": 46.0637800147825, + "n_eff": 14.77358653100018, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0051129750656995375, + "prior_weight_s2": 6.082486415534676e-14, + "prior_weight_lambda": 7.589486717049297e-05 + }, + { + "seed": 2071, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8326055312954876, + "member_coverage95": 0.9647016011644832, + "member_rmse": 0.0026229477773818013, + "shared_bias": -9.543098989458479e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6681222707423581, + "median_sd": 0.0025246809111113587, + "median_halfwidth95": 0.004948283697265464, + "bias": -9.543098989458479e-05, + "rmse": 0.0006762233570832907, + "max_abs_err": 0.0024301569136643748, + "tau": 0.00045311012137920546, + "s": 12.261671875825146, + "corr_length_days": 17.96249622628467, + "n_eff": 19.181605366905057, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.008332705916765026, + "prior_weight_s2": 4.989088805567971e-14, + "prior_weight_lambda": 1.9305733236550482e-05 + }, + { + "seed": 2072, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8104075691411936, + "member_coverage95": 0.9512372634643377, + "member_rmse": 0.0023839368055662744, + "shared_bias": -0.00021238261394920872, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6157205240174672, + "median_sd": 0.0023288344991709334, + "median_halfwidth95": 0.004564431780333059, + "bias": -0.00021238261394920872, + "rmse": 0.0006558505226411174, + "max_abs_err": 0.0016287427406242061, + "tau": 0.00013624505818407906, + "s": 11.586420424713387, + "corr_length_days": 52.223490445494534, + "n_eff": 57.869424882371725, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.15172735586207017, + "prior_weight_s2": 5.5931515922959074e-14, + "prior_weight_lambda": 1.3885981222538701e-05 + }, + { + "seed": 2073, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8034934497816594, + "member_coverage95": 0.9450509461426492, + "member_rmse": 0.002205212829881496, + "shared_bias": -0.00014243669546625096, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5982532751091703, + "median_sd": 0.002114071386901562, + "median_halfwidth95": 0.004143503811757133, + "bias": -0.00014243669546625096, + "rmse": 0.0005482651238236699, + "max_abs_err": 0.0020636970422983217, + "tau": 0.00021910861766176926, + "s": 10.439542163704541, + "corr_length_days": 43.365066207183425, + "n_eff": 34.20337738263456, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.040440121201155386, + "prior_weight_s2": 6.862721083278101e-14, + "prior_weight_lambda": 4.329143676793204e-05 + }, + { + "seed": 2074, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7969432314410481, + "member_coverage95": 0.9574235807860262, + "member_rmse": 0.002289529289876087, + "shared_bias": -0.00022610430925830736, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5676855895196506, + "median_sd": 0.0022426146745426214, + "median_halfwidth95": 0.004395444027975254, + "bias": -0.00022610430925830736, + "rmse": 0.000698433826548112, + "max_abs_err": 0.0019548396824244254, + "tau": 0.00015077805683045978, + "s": 11.02712484456305, + "corr_length_days": 40.41367443669795, + "n_eff": 49.538407686904435, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.11247982205483618, + "prior_weight_s2": 6.163355370597992e-14, + "prior_weight_lambda": 2.836813563535415e-05 + }, + { + "seed": 2075, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8107714701601164, + "member_coverage95": 0.9577874818049491, + "member_rmse": 0.0022796236828374027, + "shared_bias": -0.0001685364612111569, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6506550218340611, + "median_sd": 0.002247525802657104, + "median_halfwidth95": 0.004405069662279029, + "bias": -0.0001685364612111569, + "rmse": 0.0006081231897713153, + "max_abs_err": 0.0023684595492694306, + "tau": 0.00012185342293664533, + "s": 11.129380148119298, + "corr_length_days": 48.14350421451107, + "n_eff": 54.460930682968296, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.19190158473754054, + "prior_weight_s2": 6.051715403325194e-14, + "prior_weight_lambda": 2.4343090537530856e-05 + }, + { + "seed": 2076, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8140465793304221, + "member_coverage95": 0.9537845705967977, + "member_rmse": 0.0023184224568889465, + "shared_bias": -0.0002291696018141784, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6637554585152838, + "median_sd": 0.0022759546563521026, + "median_halfwidth95": 0.004460789192082493, + "bias": -0.0002291696018141784, + "rmse": 0.0006271975937308061, + "max_abs_err": 0.0018141626212203926, + "tau": 0.00034671088136089694, + "s": 11.032911406698464, + "corr_length_days": 34.40723933740355, + "n_eff": 23.723187317652545, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.014348631656539044, + "prior_weight_s2": 6.154940889229726e-14, + "prior_weight_lambda": 2.5889099171793908e-05 + }, + { + "seed": 2077, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8053129548762736, + "member_coverage95": 0.9530567685589519, + "member_rmse": 0.0024097198197339216, + "shared_bias": -0.00015532148911386945, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6069868995633187, + "median_sd": 0.002114446767100323, + "median_halfwidth95": 0.004144239543433017, + "bias": -0.00015532148911386945, + "rmse": 0.0006408846042639253, + "max_abs_err": 0.0036313568721312584, + "tau": 0.0003250777214040734, + "s": 10.316695444404887, + "corr_length_days": 46.553373351347965, + "n_eff": 26.103281509762056, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01651526120617142, + "prior_weight_s2": 7.037472359658936e-14, + "prior_weight_lambda": 3.0003831973447912e-05 + }, + { + "seed": 2078, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7914847161572053, + "member_coverage95": 0.9497816593886463, + "member_rmse": 0.002224386426463773, + "shared_bias": -0.00017671927211220596, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.4847161572052402, + "median_sd": 0.0021137486976389656, + "median_halfwidth95": 0.004142871352419258, + "bias": -0.00017671927211220596, + "rmse": 0.0007312313492625432, + "max_abs_err": 0.0021818043030910205, + "tau": 0.00021034051530261486, + "s": 10.49423998278437, + "corr_length_days": 24.49509348043187, + "n_eff": 29.248125532710855, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.04662858499849183, + "prior_weight_s2": 6.800666879330124e-14, + "prior_weight_lambda": 4.376324524455248e-05 + }, + { + "seed": 2079, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8031295487627366, + "member_coverage95": 0.9530567685589519, + "member_rmse": 0.002263287018714702, + "shared_bias": -0.0001539655695183296, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6331877729257642, + "median_sd": 0.0021932514431492593, + "median_halfwidth95": 0.0042986938715205945, + "bias": -0.0001539655695183296, + "rmse": 0.0006156601374561651, + "max_abs_err": 0.0017309192395332596, + "tau": 0.00014761878758125935, + "s": 10.795107504029751, + "corr_length_days": 22.979018829573448, + "n_eff": 37.888245358587284, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.11301651690636828, + "prior_weight_s2": 6.424697640165032e-14, + "prior_weight_lambda": 2.803036697828035e-05 + }, + { + "seed": 2080, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8147743813682679, + "member_coverage95": 0.9599708879184862, + "member_rmse": 0.0025071270886268242, + "shared_bias": -0.00026260980315943037, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5895196506550219, + "median_sd": 0.0022877488597849234, + "median_halfwidth95": 0.004483905406219498, + "bias": -0.00026260980315943037, + "rmse": 0.0006045700075257547, + "max_abs_err": 0.0018132800784159834, + "tau": 0.00022900611753243894, + "s": 11.134981191640982, + "corr_length_days": 35.577035868818804, + "n_eff": 36.89837443516826, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03961865882771894, + "prior_weight_s2": 6.051046529766227e-14, + "prior_weight_lambda": 3.5425170448145805e-05 + }, + { + "seed": 2081, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8289665211062591, + "member_coverage95": 0.9596069868995634, + "member_rmse": 0.0022863114654681055, + "shared_bias": -0.00015486269598265066, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6200873362445415, + "median_sd": 0.002313743752773065, + "median_halfwidth95": 0.004534854460660108, + "bias": -0.00015486269598265066, + "rmse": 0.0006571455607445992, + "max_abs_err": 0.0032954637692594563, + "tau": 0.00024527899334484256, + "s": 11.304227758360884, + "corr_length_days": 6.839435070773917, + "n_eff": 40.34007027062998, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03407166815464127, + "prior_weight_s2": 5.847372310783347e-14, + "prior_weight_lambda": 5.471476395946874e-05 + }, + { + "seed": 2082, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8195050946142649, + "member_coverage95": 0.9625181950509462, + "member_rmse": 0.002309052456012044, + "shared_bias": -0.00013391382363166479, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.7729257641921398, + "median_sd": 0.0023127384956685084, + "median_halfwidth95": 0.0045328841929244326, + "bias": -0.00013391382363166479, + "rmse": 0.00045147035606166923, + "max_abs_err": 0.0021572369629005036, + "tau": 0.0004011295378649482, + "s": 11.131141046669367, + "corr_length_days": 10.12300697532813, + "n_eff": 21.76632361382154, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.011038465654005085, + "prior_weight_s2": 5.994225050299391e-14, + "prior_weight_lambda": 0.0003315676057576521 + }, + { + "seed": 2083, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8093158660844251, + "member_coverage95": 0.9592430858806404, + "member_rmse": 0.002349750914970857, + "shared_bias": -0.00016987307706862746, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5152838427947598, + "median_sd": 0.002310777974120148, + "median_halfwidth95": 0.004529041641268421, + "bias": -0.00016987307706862746, + "rmse": 0.0006811120311570043, + "max_abs_err": 0.0022214578413115044, + "tau": 0.00029018948926211037, + "s": 11.441283851885338, + "corr_length_days": 29.356448452854014, + "n_eff": 27.87545298278641, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.021501799415973376, + "prior_weight_s2": 5.68873117196192e-14, + "prior_weight_lambda": 6.847579236019446e-05 + }, + { + "seed": 2084, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8005822416302766, + "member_coverage95": 0.9545123726346434, + "member_rmse": 0.0022073430473114482, + "shared_bias": -0.00013471464587594414, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6419213973799127, + "median_sd": 0.0021127472086198756, + "median_halfwidth95": 0.004140908469995446, + "bias": -0.00013471464587594414, + "rmse": 0.0006332972095600916, + "max_abs_err": 0.00349609074050155, + "tau": 0.00021277489401815193, + "s": 10.41579460166452, + "corr_length_days": 15.995282727475548, + "n_eff": 30.498344700689945, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.046919696838186795, + "prior_weight_s2": 6.946714053252025e-14, + "prior_weight_lambda": 1.7525966580694196e-05 + }, + { + "seed": 2085, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8111353711790393, + "member_coverage95": 0.9508733624454149, + "member_rmse": 0.0023295877032914, + "shared_bias": -5.9449235421622585e-05, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6637554585152838, + "median_sd": 0.0022279203237664234, + "median_halfwidth95": 0.004366643629450534, + "bias": -5.9449235421622585e-05, + "rmse": 0.0005330104175163622, + "max_abs_err": 0.00202242050775091, + "tau": 7.83891759164721e-05, + "s": 10.898072449405374, + "corr_length_days": 21.985377464718233, + "n_eff": 40.93477568675171, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.5817628869745172, + "prior_weight_s2": 6.261602098058099e-14, + "prior_weight_lambda": 6.90269297950533e-05 + }, + { + "seed": 2086, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7969432314410481, + "member_coverage95": 0.9566957787481805, + "member_rmse": 0.002296879471391086, + "shared_bias": -0.00016373008587545915, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.62882096069869, + "median_sd": 0.0021760941693483, + "median_halfwidth95": 0.004265066232532572, + "bias": -0.00016373008587545915, + "rmse": 0.0006513545196357921, + "max_abs_err": 0.0027673957618411338, + "tau": 8.999431819881724e-05, + "s": 10.575306686686082, + "corr_length_days": 23.50958224953978, + "n_eff": 44.248224665355785, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.4355550784193427, + "prior_weight_s2": 6.725622095699225e-14, + "prior_weight_lambda": 1.4850758754301453e-05 + }, + { + "seed": 2087, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7940320232896652, + "member_coverage95": 0.9552401746724891, + "member_rmse": 0.002168782008134417, + "shared_bias": -0.00011883640156739407, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5895196506550219, + "median_sd": 0.0022635542973345234, + "median_halfwidth95": 0.004436484934820962, + "bias": -0.00011883640156739407, + "rmse": 0.0006512700865730326, + "max_abs_err": 0.002246194816894257, + "tau": 0.0001098046472943322, + "s": 10.960900329663966, + "corr_length_days": 33.52163239488869, + "n_eff": 40.98161773809861, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.2651986695631843, + "prior_weight_s2": 6.280222133952666e-14, + "prior_weight_lambda": 9.535295992364705e-06 + }, + { + "seed": 2088, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8049490538573508, + "member_coverage95": 0.9508733624454149, + "member_rmse": 0.002178587606111226, + "shared_bias": -0.0001607107220790899, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.62882096069869, + "median_sd": 0.002226595479997948, + "median_halfwidth95": 0.004364046983358698, + "bias": -0.0001607107220790899, + "rmse": 0.0005964234490885249, + "max_abs_err": 0.002497483576883117, + "tau": 0.00014673443184197834, + "s": 11.018807510245534, + "corr_length_days": 8.706128085473503, + "n_eff": 48.1004864272007, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.12729465625009215, + "prior_weight_s2": 6.156479216956513e-14, + "prior_weight_lambda": 3.748784425105455e-05 + }, + { + "seed": 2089, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8024017467248908, + "member_coverage95": 0.9596069868995634, + "member_rmse": 0.002202640573784024, + "shared_bias": -0.00017899490243657986, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.7161572052401747, + "median_sd": 0.0021680150626851597, + "median_halfwidth95": 0.0042492314743206566, + "bias": -0.00017899490243657986, + "rmse": 0.0005101854861509355, + "max_abs_err": 0.002062595384544124, + "tau": 0.00038472494136931163, + "s": 10.61028944872353, + "corr_length_days": 20.459105458933884, + "n_eff": 19.23113585200622, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.011960071548568232, + "prior_weight_s2": 6.646329758752798e-14, + "prior_weight_lambda": 5.221473272604752e-05 + }, + { + "seed": 2090, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8140465793304221, + "member_coverage95": 0.9566957787481805, + "member_rmse": 0.0022781554287638157, + "shared_bias": -0.0001334329095799521, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6200873362445415, + "median_sd": 0.0022568489508381652, + "median_halfwidth95": 0.004423342697080574, + "bias": -0.0001334329095799521, + "rmse": 0.0006158873991761816, + "max_abs_err": 0.0022441384585675014, + "tau": 0.00024230763674903914, + "s": 11.391549687072162, + "corr_length_days": 41.05721632072906, + "n_eff": 37.54765464746197, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03237268647904946, + "prior_weight_s2": 5.784327866331474e-14, + "prior_weight_lambda": 2.6253793523718926e-05 + }, + { + "seed": 2091, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8147743813682679, + "member_coverage95": 0.9566957787481805, + "member_rmse": 0.0023329425092620815, + "shared_bias": -0.00015197553122830572, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6899563318777293, + "median_sd": 0.002306268304741577, + "median_halfwidth95": 0.00452020285163452, + "bias": -0.00015197553122830572, + "rmse": 0.0006051915299358114, + "max_abs_err": 0.002600327353724087, + "tau": 0.0001467227150062596, + "s": 11.327023292120868, + "corr_length_days": 21.145629650672944, + "n_eff": 43.72756710148944, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.12807909088109493, + "prior_weight_s2": 5.859673504167605e-14, + "prior_weight_lambda": 1.7841751235975334e-05 + }, + { + "seed": 2092, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7911208151382824, + "member_coverage95": 0.9516011644832606, + "member_rmse": 0.0021601356048428205, + "shared_bias": -0.00017758134151203082, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6419213973799127, + "median_sd": 0.002008314436533763, + "median_halfwidth95": 0.00393622399628646, + "bias": -0.00017758134151203082, + "rmse": 0.000588097523133325, + "max_abs_err": 0.002668641539148721, + "tau": 0.00017090856342855156, + "s": 9.873031554872666, + "corr_length_days": 20.47631602177192, + "n_eff": 33.666038885652625, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.07690571990453876, + "prior_weight_s2": 7.688661683147622e-14, + "prior_weight_lambda": 3.943822445332096e-05 + }, + { + "seed": 2093, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.784570596797671, + "member_coverage95": 0.9435953420669578, + "member_rmse": 0.0022063079978380143, + "shared_bias": -0.00014445536866562744, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.519650655021834, + "median_sd": 0.0021174491375548924, + "median_halfwidth95": 0.004150124081438637, + "bias": -0.00014445536866562744, + "rmse": 0.0006387915891397193, + "max_abs_err": 0.0022103209913065264, + "tau": 0.00022799052721487515, + "s": 10.395475406089638, + "corr_length_days": 31.306343119898546, + "n_eff": 29.27129607600212, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.039065178082911545, + "prior_weight_s2": 6.925980103546738e-14, + "prior_weight_lambda": 2.981504555367765e-05 + }, + { + "seed": 2094, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8245997088791849, + "member_coverage95": 0.9596069868995634, + "member_rmse": 0.0023724229663801117, + "shared_bias": -0.00020505003308056872, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6812227074235808, + "median_sd": 0.002369013525915115, + "median_halfwidth95": 0.004643181226306693, + "bias": -0.00020505003308056872, + "rmse": 0.000597250439540186, + "max_abs_err": 0.0022122358588366115, + "tau": 0.00028911981653003023, + "s": 11.421496544081899, + "corr_length_days": 33.211704107882404, + "n_eff": 31.473116747828406, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.02256108742006075, + "prior_weight_s2": 5.72601323920687e-14, + "prior_weight_lambda": 6.624947150758308e-05 + }, + { + "seed": 2095, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8038573508005823, + "member_coverage95": 0.9530567685589519, + "member_rmse": 0.002384522801674267, + "shared_bias": -0.0002451668135626849, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.611353711790393, + "median_sd": 0.0022716326466414413, + "median_halfwidth95": 0.004452318208641946, + "bias": -0.0002451668135626849, + "rmse": 0.0007409245508454828, + "max_abs_err": 0.003367286718554014, + "tau": 0.0002855895268690297, + "s": 11.277008917426562, + "corr_length_days": 22.746542935885415, + "n_eff": 25.975739087178024, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.022550313764468498, + "prior_weight_s2": 5.90026845630154e-14, + "prior_weight_lambda": 1.7869986757761656e-05 + }, + { + "seed": 2096, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8020378457059679, + "member_coverage95": 0.9497816593886463, + "member_rmse": 0.0024592337560411484, + "shared_bias": -0.00027728700166666646, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.62882096069869, + "median_sd": 0.0022917416460352135, + "median_halfwidth95": 0.004491731123529762, + "bias": -0.00027728700166666646, + "rmse": 0.0007190546510705652, + "max_abs_err": 0.0030073578651053463, + "tau": 0.00022968519666479695, + "s": 11.358423619932465, + "corr_length_days": 14.806064902408151, + "n_eff": 32.85976223933357, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03994109418694278, + "prior_weight_s2": 5.807021931283437e-14, + "prior_weight_lambda": 2.487113603316273e-05 + }, + { + "seed": 2097, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8078602620087336, + "member_coverage95": 0.9556040756914119, + "member_rmse": 0.0022343363183212586, + "shared_bias": -0.0001437126872103476, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5152838427947598, + "median_sd": 0.002215408934336874, + "median_halfwidth95": 0.0043421217565786365, + "bias": -0.0001437126872103476, + "rmse": 0.0006644055586542665, + "max_abs_err": 0.0028057348761021655, + "tau": 0.0002457948670984708, + "s": 10.818581428879932, + "corr_length_days": 10.849553437041896, + "n_eff": 32.670419067268874, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.031028696447432697, + "prior_weight_s2": 6.400323475034539e-14, + "prior_weight_lambda": 2.619256680161989e-05 + }, + { + "seed": 2098, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.799490538573508, + "member_coverage95": 0.9486899563318777, + "member_rmse": 0.0021748360606657384, + "shared_bias": -0.00016723974940499527, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6550218340611353, + "median_sd": 0.002104158058083235, + "median_halfwidth95": 0.004124074044153049, + "bias": -0.00016723974940499527, + "rmse": 0.0006779695208317605, + "max_abs_err": 0.002189019190198196, + "tau": 0.00016103968544395057, + "s": 10.414918819523532, + "corr_length_days": 18.274594689263704, + "n_eff": 34.791659592070694, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.09260641788174058, + "prior_weight_s2": 6.95529513154853e-14, + "prior_weight_lambda": 8.565191912743582e-06 + }, + { + "seed": 2099, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7962154294032023, + "member_coverage95": 0.9497816593886463, + "member_rmse": 0.0024047339956995164, + "shared_bias": -9.568847984009092e-06, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5676855895196506, + "median_sd": 0.00219277190616756, + "median_halfwidth95": 0.004297753996299796, + "bias": -9.568847984009092e-06, + "rmse": 0.00071406056033208, + "max_abs_err": 0.003623314903617458, + "tau": 0.00036387148398602534, + "s": 10.621132731932095, + "corr_length_days": 40.113504726706566, + "n_eff": 22.704448811057397, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.013398986736515727, + "prior_weight_s2": 6.667798229272981e-14, + "prior_weight_lambda": 1.5347837075772478e-05 + }, + { + "seed": 2100, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8074963609898108, + "member_coverage95": 0.9596069868995634, + "member_rmse": 0.002149789124034933, + "shared_bias": -0.00021114147164597337, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6244541484716157, + "median_sd": 0.0021869661224247165, + "median_halfwidth95": 0.004286374869172037, + "bias": -0.00021114147164597337, + "rmse": 0.0006812144063793178, + "max_abs_err": 0.002898644575848057, + "tau": 0.0001420650671504598, + "s": 10.878857388460716, + "corr_length_days": 24.861993315293102, + "n_eff": 34.77701882631969, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.1402051225847133, + "prior_weight_s2": 6.387713354491394e-14, + "prior_weight_lambda": 8.866216970488716e-06 + }, + { + "seed": 2101, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7987627365356623, + "member_coverage95": 0.9454148471615721, + "member_rmse": 0.0022284847490215013, + "shared_bias": -0.0002747806493491508, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6244541484716157, + "median_sd": 0.0021732748427926263, + "median_halfwidth95": 0.004259540453979207, + "bias": -0.0002747806493491508, + "rmse": 0.0007066796218016721, + "max_abs_err": 0.003867204292421996, + "tau": 0.00023225771076610684, + "s": 10.785153380607412, + "corr_length_days": 34.078408313424845, + "n_eff": 29.65818448948249, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03732162800912835, + "prior_weight_s2": 6.475910141747174e-14, + "prior_weight_lambda": 1.405740097713494e-05 + }, + { + "seed": 2102, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8038573508005823, + "member_coverage95": 0.9588791848617176, + "member_rmse": 0.0024542670786737355, + "shared_bias": -0.000155114576700819, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5982532751091703, + "median_sd": 0.00228143928903897, + "median_halfwidth95": 0.0044715388747019755, + "bias": -0.000155114576700819, + "rmse": 0.0006053785966928469, + "max_abs_err": 0.0022572321720383797, + "tau": 0.00015988358108928383, + "s": 11.317533338814428, + "corr_length_days": 6.997190884931393, + "n_eff": 53.172700112113944, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.10597295806524018, + "prior_weight_s2": 5.865637599939832e-14, + "prior_weight_lambda": 3.630130477791432e-05 + }, + { + "seed": 2103, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7918486171761281, + "member_coverage95": 0.9523289665211062, + "member_rmse": 0.002248512641808029, + "shared_bias": -0.00023052412219961842, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5458515283842795, + "median_sd": 0.002172670565934034, + "median_halfwidth95": 0.004258356093090333, + "bias": -0.00023052412219961842, + "rmse": 0.0007794854739462145, + "max_abs_err": 0.002907111043845339, + "tau": 0.00017822100710774292, + "s": 10.553048803247293, + "corr_length_days": 33.066944314564985, + "n_eff": 42.29287234267798, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.07015283927215007, + "prior_weight_s2": 6.739912981282256e-14, + "prior_weight_lambda": 2.0526320092763272e-05 + }, + { + "seed": 2104, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.799490538573508, + "member_coverage95": 0.9501455604075691, + "member_rmse": 0.002248507356089756, + "shared_bias": -0.00019296525783619762, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5458515283842795, + "median_sd": 0.0021182769449303203, + "median_halfwidth95": 0.0041517465540934105, + "bias": -0.00019296525783619762, + "rmse": 0.0006868228677039687, + "max_abs_err": 0.0026065811025084303, + "tau": 0.0004264675873441181, + "s": 10.328796954023101, + "corr_length_days": 14.938086123909397, + "n_eff": 16.22216574499357, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.008970392014138219, + "prior_weight_s2": 7.077962297771197e-14, + "prior_weight_lambda": 1.37089092857937e-05 + }, + { + "seed": 2105, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7929403202328966, + "member_coverage95": 0.9501455604075691, + "member_rmse": 0.002160004157943329, + "shared_bias": -0.00017997338616491387, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5982532751091703, + "median_sd": 0.0021341417918946427, + "median_halfwidth95": 0.004182841083008992, + "bias": -0.00017997338616491387, + "rmse": 0.0006436681881394869, + "max_abs_err": 0.0028306196917104276, + "tau": 0.00015872037249552723, + "s": 10.478290627108514, + "corr_length_days": 42.92306504831769, + "n_eff": 37.00088962829783, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.10346715082299608, + "prior_weight_s2": 6.85436651199616e-14, + "prior_weight_lambda": 1.8285193436815077e-05 + }, + { + "seed": 2106, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7907569141193596, + "member_coverage95": 0.9559679767103348, + "member_rmse": 0.002247751031816461, + "shared_bias": -0.00011481202303629383, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5545851528384279, + "median_sd": 0.0021447095298806652, + "median_halfwidth95": 0.004203553469023028, + "bias": -0.00011481202303629383, + "rmse": 0.0007408247971693258, + "max_abs_err": 0.002231997796684091, + "tau": 0.0001581414929320318, + "s": 10.49422561620801, + "corr_length_days": 33.54958561271387, + "n_eff": 39.94022760815993, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.09787994223734793, + "prior_weight_s2": 6.89618029781363e-14, + "prior_weight_lambda": 5.216646689166184e-06 + }, + { + "seed": 2107, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8140465793304221, + "member_coverage95": 0.9621542940320232, + "member_rmse": 0.0023878427233416126, + "shared_bias": -3.662578914869243e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5851528384279476, + "median_sd": 0.002223731726902921, + "median_halfwidth95": 0.004358434130387557, + "bias": -3.662578914869243e-05, + "rmse": 0.0006808550257470507, + "max_abs_err": 0.0026089324641157758, + "tau": 0.00025591739594421994, + "s": 10.926465410667912, + "corr_length_days": 14.194010730054535, + "n_eff": 30.49944112577774, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.02923272458692948, + "prior_weight_s2": 6.277878652852404e-14, + "prior_weight_lambda": 2.279274270053222e-05 + }, + { + "seed": 2108, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7907569141193596, + "member_coverage95": 0.9454148471615721, + "member_rmse": 0.002060818736431597, + "shared_bias": -0.00014227644631827944, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6244541484716157, + "median_sd": 0.002033383766445146, + "median_halfwidth95": 0.003985358980416894, + "bias": -0.00014227644631827944, + "rmse": 0.0006193847727246287, + "max_abs_err": 0.0032321311170235957, + "tau": 0.00011601495964387172, + "s": 10.067699148820923, + "corr_length_days": 35.82094689056585, + "n_eff": 39.37670627435941, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.2032754475350731, + "prior_weight_s2": 7.408599397516165e-14, + "prior_weight_lambda": 2.227472203409192e-05 + }, + { + "seed": 2109, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7936681222707423, + "member_coverage95": 0.9512372634643377, + "member_rmse": 0.002248925656982236, + "shared_bias": -6.67540149180501e-05, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6026200873362445, + "median_sd": 0.0021146379845173747, + "median_halfwidth95": 0.004144614322686612, + "bias": -6.67540149180501e-05, + "rmse": 0.0005569583064736875, + "max_abs_err": 0.001728299434380189, + "tau": 0.00019001893312345738, + "s": 10.478647714603143, + "corr_length_days": 13.263358101457413, + "n_eff": 36.92314782236843, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.05817631639247624, + "prior_weight_s2": 6.869298846770161e-14, + "prior_weight_lambda": 1.6041460173819685e-05 + }, + { + "seed": 2110, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8034934497816594, + "member_coverage95": 0.9497816593886463, + "member_rmse": 0.0021272925119722804, + "shared_bias": -0.00010873599191180482, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6462882096069869, + "median_sd": 0.0020261348509307544, + "median_halfwidth95": 0.003971151366969646, + "bias": -0.00010873599191180482, + "rmse": 0.0005416838839446781, + "max_abs_err": 0.002669746077734271, + "tau": 0.00020735961257607602, + "s": 10.005319452926367, + "corr_length_days": 25.75629113537025, + "n_eff": 32.05654728581903, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.04815550598786779, + "prior_weight_s2": 7.480579605933765e-14, + "prior_weight_lambda": 3.639347958288787e-05 + }, + { + "seed": 2111, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8118631732168851, + "member_coverage95": 0.9563318777292577, + "member_rmse": 0.0023044495460164496, + "shared_bias": -0.0002727979966634894, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6200873362445415, + "median_sd": 0.002220934741499785, + "median_halfwidth95": 0.004352952139688885, + "bias": -0.0002727979966634894, + "rmse": 0.0006750464736585512, + "max_abs_err": 0.002600144269584629, + "tau": 0.0002973211140327235, + "s": 10.876133143538171, + "corr_length_days": 23.34012300474541, + "n_eff": 25.603610728424037, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.021771410259474842, + "prior_weight_s2": 6.353736891412541e-14, + "prior_weight_lambda": 1.7558412649232855e-05 + }, + { + "seed": 2112, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8122270742358079, + "member_coverage95": 0.9563318777292577, + "member_rmse": 0.0023363242558092803, + "shared_bias": -0.00021017160899734904, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5895196506550219, + "median_sd": 0.002308233482510936, + "median_halfwidth95": 0.0045240545293160645, + "bias": -0.00021017160899734904, + "rmse": 0.0007393161918451449, + "max_abs_err": 0.0025283273977156273, + "tau": 0.0006066561959642428, + "s": 10.757309620712288, + "corr_length_days": 44.33024480171583, + "n_eff": 12.088408357556407, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0043773157464238365, + "prior_weight_s2": 6.526915111154685e-14, + "prior_weight_lambda": 1.2164182143989554e-05 + }, + { + "seed": 2113, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8133187772925764, + "member_coverage95": 0.9592430858806404, + "member_rmse": 0.002388673666160032, + "shared_bias": -0.00028958659007741026, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5895196506550219, + "median_sd": 0.002226768147547285, + "median_halfwidth95": 0.004364385405539367, + "bias": -0.00028958659007741026, + "rmse": 0.000681913109971221, + "max_abs_err": 0.002171642233717344, + "tau": 0.0003424480752705251, + "s": 10.847134287814198, + "corr_length_days": 29.927787309907917, + "n_eff": 23.681592811747663, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.015266525293391545, + "prior_weight_s2": 6.389598884839236e-14, + "prior_weight_lambda": 2.315287228649652e-05 + }, + { + "seed": 2114, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8045851528384279, + "member_coverage95": 0.9552401746724891, + "member_rmse": 0.0021128808217325034, + "shared_bias": -0.00021624798541635228, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5327510917030568, + "median_sd": 0.002160413470466864, + "median_halfwidth95": 0.004234332627230117, + "bias": -0.00021624798541635228, + "rmse": 0.0005211789971431128, + "max_abs_err": 0.002344475721378882, + "tau": 0.00026507516533454806, + "s": 10.553203919888986, + "corr_length_days": 27.02426943464417, + "n_eff": 27.176620848860566, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.02731850056010575, + "prior_weight_s2": 6.685134371417413e-14, + "prior_weight_lambda": 0.00011299834501462302 + }, + { + "seed": 2115, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8031295487627366, + "member_coverage95": 0.950509461426492, + "member_rmse": 0.0020888201382522407, + "shared_bias": -0.0001457027254626318, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5589519650655022, + "median_sd": 0.002035218435278787, + "median_halfwidth95": 0.003988954865282753, + "bias": -0.0001457027254626318, + "rmse": 0.0006318845011394679, + "max_abs_err": 0.002108165978082637, + "tau": 0.00018791932263217975, + "s": 10.042108161475085, + "corr_length_days": 20.257692212120688, + "n_eff": 32.352385945662746, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.06258410407178731, + "prior_weight_s2": 7.461118556417553e-14, + "prior_weight_lambda": 2.192080041329793e-05 + }, + { + "seed": 2116, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8053129548762736, + "member_coverage95": 0.9585152838427947, + "member_rmse": 0.002497375755640205, + "shared_bias": -0.00028726420180985433, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6200873362445415, + "median_sd": 0.002223578062662536, + "median_halfwidth95": 0.004358132954008315, + "bias": -0.00028726420180985433, + "rmse": 0.0006018428603117863, + "max_abs_err": 0.0020802439709203357, + "tau": 0.0003306208514975823, + "s": 10.872236156853686, + "corr_length_days": 34.105097049623005, + "n_eff": 25.158830463838715, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.016985028089886705, + "prior_weight_s2": 6.361804124447237e-14, + "prior_weight_lambda": 2.130733966740947e-05 + }, + { + "seed": 2117, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7983988355167394, + "member_coverage95": 0.9552401746724891, + "member_rmse": 0.002235065877564547, + "shared_bias": -0.0002598050890129971, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5633187772925764, + "median_sd": 0.0022246998404337245, + "median_halfwidth95": 0.004360331598055845, + "bias": -0.0002598050890129971, + "rmse": 0.0006909906547928949, + "max_abs_err": 0.0016468572181440508, + "tau": 0.0003141881082062147, + "s": 10.820133490169198, + "corr_length_days": 45.28684330951171, + "n_eff": 29.351060579415325, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01828698006146639, + "prior_weight_s2": 6.427217730449442e-14, + "prior_weight_lambda": 1.5740764960535638e-05 + }, + { + "seed": 2118, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8151382823871907, + "member_coverage95": 0.9570596797671034, + "member_rmse": 0.0025292294274819973, + "shared_bias": -0.0002564687728391512, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6331877729257642, + "median_sd": 0.0023362219873455186, + "median_halfwidth95": 0.0045789109912056725, + "bias": -0.0002564687728391512, + "rmse": 0.0007489868460385867, + "max_abs_err": 0.00383380148649966, + "tau": 0.0003507950702596457, + "s": 11.334459934158414, + "corr_length_days": 33.30151550817411, + "n_eff": 23.501042823344015, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.014771176554138935, + "prior_weight_s2": 5.85128234623359e-14, + "prior_weight_lambda": 1.4457025553681733e-05 + }, + { + "seed": 2119, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.774745269286754, + "member_coverage95": 0.9457787481804949, + "member_rmse": 0.00221730179872944, + "shared_bias": -0.00018995298255840387, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5021834061135371, + "median_sd": 0.0020744965971620497, + "median_halfwidth95": 0.0040659386485601195, + "bias": -0.00018995298255840387, + "rmse": 0.0007495972023347, + "max_abs_err": 0.002216261107868659, + "tau": 0.0001047826945504342, + "s": 10.279222499745106, + "corr_length_days": 28.265694389892914, + "n_eff": 44.793488845765765, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.2531834078068203, + "prior_weight_s2": 7.129006846494287e-14, + "prior_weight_lambda": 1.1952343726108316e-05 + }, + { + "seed": 2120, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7987627365356623, + "member_coverage95": 0.9548762736535662, + "member_rmse": 0.0022119493249644013, + "shared_bias": -0.00011671079584783766, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5502183406113537, + "median_sd": 0.0021616089256645283, + "median_halfwidth95": 0.004236675676381151, + "bias": -0.00011671079584783766, + "rmse": 0.0006456841330859035, + "max_abs_err": 0.0023944964183202095, + "tau": 0.00010323780250928453, + "s": 10.581934841842033, + "corr_length_days": 44.81335679515083, + "n_eff": 58.073319010904534, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.3059963574519461, + "prior_weight_s2": 6.71123560436157e-14, + "prior_weight_lambda": 1.6208461020283453e-05 + }, + { + "seed": 2121, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7951237263464338, + "member_coverage95": 0.9516011644832606, + "member_rmse": 0.0023173367402051616, + "shared_bias": -0.00018342405563263498, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5720524017467249, + "median_sd": 0.0022057102297612886, + "median_halfwidth95": 0.004323112644763855, + "bias": -0.00018342405563263498, + "rmse": 0.0007326495015964042, + "max_abs_err": 0.0027285370732217508, + "tau": 0.0003742011580799054, + "s": 10.695851800178042, + "corr_length_days": 43.458170294850035, + "n_eff": 21.871625677989172, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.012272103281784023, + "prior_weight_s2": 6.604141445765086e-14, + "prior_weight_lambda": 8.698692445420902e-06 + }, + { + "seed": 2122, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7903930131004366, + "member_coverage95": 0.9545123726346434, + "member_rmse": 0.002079516816848965, + "shared_bias": -0.0001787702919781408, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6419213973799127, + "median_sd": 0.00209742776411606, + "median_halfwidth95": 0.00411088291026797, + "bias": -0.0001787702919781408, + "rmse": 0.0006706780159967219, + "max_abs_err": 0.0025342692609645412, + "tau": 0.00023890324675269282, + "s": 10.196995659449348, + "corr_length_days": 32.32820101147885, + "n_eff": 32.79975731507966, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03790119171776876, + "prior_weight_s2": 7.283050528740064e-14, + "prior_weight_lambda": 8.625592881239762e-06 + }, + { + "seed": 2123, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8085880640465793, + "member_coverage95": 0.9545123726346434, + "member_rmse": 0.0022436189868044356, + "shared_bias": -0.00023844015772464788, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6244541484716157, + "median_sd": 0.002186656444573268, + "median_halfwidth95": 0.0042857679117316, + "bias": -0.00023844015772464788, + "rmse": 0.0007279129766063816, + "max_abs_err": 0.0023753546590184666, + "tau": 0.0003617074327691037, + "s": 10.760032175989082, + "corr_length_days": 22.4122371512868, + "n_eff": 22.067083497894295, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.012822152793107033, + "prior_weight_s2": 6.499042314938852e-14, + "prior_weight_lambda": 1.8946963469417056e-05 + }, + { + "seed": 2124, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8147743813682679, + "member_coverage95": 0.9588791848617176, + "member_rmse": 0.00228816345523587, + "shared_bias": -0.00010891342590276167, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6681222707423581, + "median_sd": 0.0022021223896860984, + "median_halfwidth95": 0.0043160806073787245, + "bias": -0.00010891342590276167, + "rmse": 0.0006005588679109243, + "max_abs_err": 0.0029823622413020614, + "tau": 0.00010011969531280616, + "s": 10.818672054565022, + "corr_length_days": 46.89805866345521, + "n_eff": 52.137243760962335, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.3114647453815175, + "prior_weight_s2": 6.410066981726462e-14, + "prior_weight_lambda": 1.4961942955564844e-05 + }, + { + "seed": 2125, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8024017467248908, + "member_coverage95": 0.9577874818049491, + "member_rmse": 0.0023302161778835317, + "shared_bias": -0.00017526849484130868, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6462882096069869, + "median_sd": 0.002234661957217759, + "median_halfwidth95": 0.004379856988316348, + "bias": -0.00017526849484130868, + "rmse": 0.0006392450278319634, + "max_abs_err": 0.002014088998601036, + "tau": 0.0002604908503079137, + "s": 10.969933826747667, + "corr_length_days": 52.70217935494727, + "n_eff": 36.893567119923745, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.02836135805047895, + "prior_weight_s2": 6.250385817153851e-14, + "prior_weight_lambda": 1.1025003312728246e-05 + }, + { + "seed": 2126, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8042212518195051, + "member_coverage95": 0.9577874818049491, + "member_rmse": 0.002288531341829452, + "shared_bias": -0.0001575293951299068, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6637554585152838, + "median_sd": 0.0022946640560653213, + "median_halfwidth95": 0.004497458941982012, + "bias": -0.0001575293951299068, + "rmse": 0.0006473472307357179, + "max_abs_err": 0.002450446966100419, + "tau": 0.00013881146553240968, + "s": 11.264462239217815, + "corr_length_days": 16.440578615555836, + "n_eff": 40.593470272660696, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.13844455231096264, + "prior_weight_s2": 5.930530792920984e-14, + "prior_weight_lambda": 1.4245364024090046e-05 + }, + { + "seed": 2127, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8038573508005823, + "member_coverage95": 0.9548762736535662, + "member_rmse": 0.0022067175922005455, + "shared_bias": -0.00011144962320709622, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5895196506550219, + "median_sd": 0.002213423483242651, + "median_halfwidth95": 0.0043382303439102, + "bias": -0.00011144962320709622, + "rmse": 0.0006124859413675013, + "max_abs_err": 0.0019983156596377247, + "tau": 0.00017041289343353326, + "s": 10.738176433307522, + "corr_length_days": 21.481541668505486, + "n_eff": 35.89520940892431, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.07614683172396051, + "prior_weight_s2": 6.498733543138044e-14, + "prior_weight_lambda": 2.6466981936366386e-05 + }, + { + "seed": 2128, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8027656477438136, + "member_coverage95": 0.9563318777292577, + "member_rmse": 0.0022851045968056865, + "shared_bias": -6.0556008188769745e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6244541484716157, + "median_sd": 0.0022565843701412153, + "median_halfwidth95": 0.004422824128439457, + "bias": -6.0556008188769745e-05, + "rmse": 0.0006385994122594692, + "max_abs_err": 0.002679438930853089, + "tau": 0.00021257285074925694, + "s": 11.09715911728076, + "corr_length_days": 17.48086303040699, + "n_eff": 35.05809739192837, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.04699031579630518, + "prior_weight_s2": 6.065363663398492e-14, + "prior_weight_lambda": 3.42967622186026e-05 + }, + { + "seed": 2129, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8078602620087336, + "member_coverage95": 0.9530567685589519, + "member_rmse": 0.002193725171669578, + "shared_bias": -0.0002205432030045714, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6200873362445415, + "median_sd": 0.0021320144490023047, + "median_halfwidth95": 0.004178671567524353, + "bias": -0.0002205432030045714, + "rmse": 0.0006294437460002387, + "max_abs_err": 0.0028827350705285665, + "tau": 0.00026693821459439297, + "s": 10.238445755123786, + "corr_length_days": 51.048672936958084, + "n_eff": 31.927509506742236, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.02665762808708895, + "prior_weight_s2": 7.189597117095311e-14, + "prior_weight_lambda": 1.2783861825248144e-05 + }, + { + "seed": 2130, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7907569141193596, + "member_coverage95": 0.9552401746724891, + "member_rmse": 0.0024318669697861177, + "shared_bias": -0.00022043142380241706, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5458515283842795, + "median_sd": 0.002265898506790445, + "median_halfwidth95": 0.004441079500963028, + "bias": -0.00022043142380241706, + "rmse": 0.0006500689107088531, + "max_abs_err": 0.0027644870102440174, + "tau": 0.00027093109670684275, + "s": 11.193394992189443, + "corr_length_days": 34.958097167028924, + "n_eff": 30.446717990964956, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.025816565561819917, + "prior_weight_s2": 5.944667006008927e-14, + "prior_weight_lambda": 8.686791206689951e-05 + }, + { + "seed": 2131, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8038573508005823, + "member_coverage95": 0.9566957787481805, + "member_rmse": 0.0021427416898011733, + "shared_bias": -0.00017915115321316593, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6244541484716157, + "median_sd": 0.002127776225968315, + "median_halfwidth95": 0.004170364802953763, + "bias": -0.00017915115321316593, + "rmse": 0.0005635840775871003, + "max_abs_err": 0.0026643648564922792, + "tau": 0.0001676543999587538, + "s": 10.633315081849235, + "corr_length_days": 35.22221641716669, + "n_eff": 40.05899348977383, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0857170740082617, + "prior_weight_s2": 6.621791558759373e-14, + "prior_weight_lambda": 5.946891833801638e-05 + }, + { + "seed": 2132, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8013100436681223, + "member_coverage95": 0.950509461426492, + "member_rmse": 0.0022513481881045903, + "shared_bias": -0.00010245201484985651, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5720524017467249, + "median_sd": 0.0021632640723380204, + "median_halfwidth95": 0.004239919704275916, + "bias": -0.00010245201484985651, + "rmse": 0.0006675649859129552, + "max_abs_err": 0.002679108631384113, + "tau": 0.00018395593071453747, + "s": 10.511030627768214, + "corr_length_days": 40.95643279909057, + "n_eff": 39.751339729304725, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.069194146577565, + "prior_weight_s2": 6.782278946532174e-14, + "prior_weight_lambda": 2.281019216218875e-05 + }, + { + "seed": 2133, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7922125181950509, + "member_coverage95": 0.9519650655021834, + "member_rmse": 0.0022626278847439115, + "shared_bias": -0.00011030520395864603, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6069868995633187, + "median_sd": 0.002174397230454265, + "median_halfwidth95": 0.004261740293390063, + "bias": -0.00011030520395864603, + "rmse": 0.0007865103669074361, + "max_abs_err": 0.004079284799264509, + "tau": 0.00025262632964078043, + "s": 10.575658924226351, + "corr_length_days": 38.236104453478724, + "n_eff": 29.694986396517365, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.029611824539904522, + "prior_weight_s2": 6.75653695772628e-14, + "prior_weight_lambda": 8.778574483299466e-06 + }, + { + "seed": 2134, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8067685589519651, + "member_coverage95": 0.9556040756914119, + "member_rmse": 0.0023806069647892155, + "shared_bias": -0.00019944517268788656, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5764192139737991, + "median_sd": 0.00224138203052659, + "median_halfwidth95": 0.004393028090079017, + "bias": -0.00019944517268788656, + "rmse": 0.0006252208660309185, + "max_abs_err": 0.002527467416886096, + "tau": 0.00018172149849137966, + "s": 10.959883574215473, + "corr_length_days": 24.23288770102277, + "n_eff": 35.612413544376935, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.07634068651302311, + "prior_weight_s2": 6.214894713356923e-14, + "prior_weight_lambda": 6.191889328291513e-05 + }, + { + "seed": 2135, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8104075691411936, + "member_coverage95": 0.9534206695778749, + "member_rmse": 0.0024398217144434554, + "shared_bias": -0.0002033149655515604, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6550218340611353, + "median_sd": 0.002251855784537838, + "median_halfwidth95": 0.0044135562708859195, + "bias": -0.0002033149655515604, + "rmse": 0.000589089411191065, + "max_abs_err": 0.002466673596577752, + "tau": 0.0003581072725934981, + "s": 11.317870409851146, + "corr_length_days": 45.076322933981665, + "n_eff": 25.851962882012675, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.013121674013384968, + "prior_weight_s2": 5.852413628784008e-14, + "prior_weight_lambda": 4.424340337261063e-05 + }, + { + "seed": 2136, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8096797671033479, + "member_coverage95": 0.9552401746724891, + "member_rmse": 0.0023074976488583394, + "shared_bias": -7.179261904309854e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6375545851528385, + "median_sd": 0.0022493213331994315, + "median_halfwidth95": 0.0044085888375028906, + "bias": -7.179261904309854e-05, + "rmse": 0.0006627666796358497, + "max_abs_err": 0.0028533265841219724, + "tau": 0.0002389538515176832, + "s": 11.045498980664334, + "corr_length_days": 31.812110657667947, + "n_eff": 33.37318676045277, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0372748433650801, + "prior_weight_s2": 6.209017824168649e-14, + "prior_weight_lambda": 7.521627273154788e-06 + }, + { + "seed": 2137, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8173216885007278, + "member_coverage95": 0.9621542940320232, + "member_rmse": 0.0024207023658433424, + "shared_bias": -0.00023593557377242418, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.611353711790393, + "median_sd": 0.002319694104541469, + "median_halfwidth95": 0.0045465169359135155, + "bias": -0.00023593557377242418, + "rmse": 0.0007244546164816758, + "max_abs_err": 0.002845473055191413, + "tau": 0.00036000705019181736, + "s": 11.338760550514086, + "corr_length_days": 22.525709577136542, + "n_eff": 22.214703368553053, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.013312726341879924, + "prior_weight_s2": 5.866828966682785e-14, + "prior_weight_lambda": 1.0460800180664069e-05 + }, + { + "seed": 2138, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7878457059679768, + "member_coverage95": 0.950509461426492, + "member_rmse": 0.002291953846455476, + "shared_bias": -0.0002441561735147701, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5109170305676856, + "median_sd": 0.0021782858443554843, + "median_halfwidth95": 0.004269361836646352, + "bias": -0.0002441561735147701, + "rmse": 0.000683490471945537, + "max_abs_err": 0.0017261335934843029, + "tau": 0.00030557562031326916, + "s": 10.508895845441975, + "corr_length_days": 46.35842263383429, + "n_eff": 27.808280569947385, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.017970007027702895, + "prior_weight_s2": 6.778821310187527e-14, + "prior_weight_lambda": 3.0269206003789098e-05 + }, + { + "seed": 2139, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8125909752547307, + "member_coverage95": 0.9566957787481805, + "member_rmse": 0.002446144055194161, + "shared_bias": -0.00019216273831583429, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6768558951965066, + "median_sd": 0.0023156809923999323, + "median_halfwidth95": 0.004538651380588141, + "bias": -0.00019216273831583429, + "rmse": 0.0006165876851946144, + "max_abs_err": 0.0023815088295867483, + "tau": 0.00041430459192607353, + "s": 11.329129027132538, + "corr_length_days": 31.237183980763454, + "n_eff": 20.498662950979995, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.010008173300438204, + "prior_weight_s2": 5.851729431133151e-14, + "prior_weight_lambda": 2.2953628547764697e-05 + }, + { + "seed": 2140, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7980349344978166, + "member_coverage95": 0.9519650655021834, + "member_rmse": 0.0020807876101114255, + "shared_bias": -4.9227147990512614e-05, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.6331877729257642, + "median_sd": 0.002089175004277267, + "median_halfwidth95": 0.004094707798083289, + "bias": -4.9227147990512614e-05, + "rmse": 0.0006518035974864962, + "max_abs_err": 0.00252518861745057, + "tau": 0.00011875735451563362, + "s": 10.135269039898844, + "corr_length_days": 30.221364760608907, + "n_eff": 43.28785404388009, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.19642539862197486, + "prior_weight_s2": 7.36154858883584e-14, + "prior_weight_lambda": 8.990098988424952e-06 + }, + { + "seed": 2141, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8114992721979621, + "member_coverage95": 0.9545123726346434, + "member_rmse": 0.0024730870961846827, + "shared_bias": -0.00017745344486845893, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6637554585152838, + "median_sd": 0.0024611360995759816, + "median_halfwidth95": 0.00482373815426934, + "bias": -0.00017745344486845893, + "rmse": 0.0006951527886210604, + "max_abs_err": 0.0033587598254773677, + "tau": 0.00021040925676848172, + "s": 11.856764385448418, + "corr_length_days": 39.83846472422526, + "n_eff": 37.529411527633584, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.05417064340352738, + "prior_weight_s2": 5.3505004805813344e-14, + "prior_weight_lambda": 1.5602446744435564e-05 + }, + { + "seed": 2142, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7962154294032023, + "member_coverage95": 0.9526928675400291, + "member_rmse": 0.0021651298765087376, + "shared_bias": -0.00010253816708381361, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5240174672489083, + "median_sd": 0.00214772168065626, + "median_halfwidth95": 0.004209457176105766, + "bias": -0.00010253816708381361, + "rmse": 0.000692674541339629, + "max_abs_err": 0.00174049753570264, + "tau": 0.0002167955030218167, + "s": 10.581765227924203, + "corr_length_days": 47.23132417168419, + "n_eff": 39.09441947357111, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.04452044808151621, + "prior_weight_s2": 6.732702739875442e-14, + "prior_weight_lambda": 1.2526183872030283e-05 + }, + { + "seed": 2143, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7943959243085881, + "member_coverage95": 0.9501455604075691, + "member_rmse": 0.002295775891489039, + "shared_bias": -0.00015417192207181236, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.537117903930131, + "median_sd": 0.002226289976398575, + "median_halfwidth95": 0.004363448207302057, + "bias": -0.00015417192207181236, + "rmse": 0.0007807967841967984, + "max_abs_err": 0.0025734330044664363, + "tau": 0.000265906857923972, + "s": 11.044963825469136, + "corr_length_days": 19.191327182263475, + "n_eff": 25.82552691021034, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.028430315967766868, + "prior_weight_s2": 6.176818341415266e-14, + "prior_weight_lambda": 1.0150150665889562e-05 + }, + { + "seed": 2144, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8147743813682679, + "member_coverage95": 0.9556040756914119, + "member_rmse": 0.0023654180093039805, + "shared_bias": -0.00022149150191939882, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6069868995633187, + "median_sd": 0.0023561874733110232, + "median_halfwidth95": 0.0046180426249405665, + "bias": -0.00022149150191939882, + "rmse": 0.0006291213530360959, + "max_abs_err": 0.0024679619915702394, + "tau": 0.00030303767710214993, + "s": 11.422681639577274, + "corr_length_days": 33.03997797597306, + "n_eff": 25.82265745435576, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01971989570556847, + "prior_weight_s2": 5.735643065873352e-14, + "prior_weight_lambda": 4.480485041112973e-05 + }, + { + "seed": 2145, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7965793304221251, + "member_coverage95": 0.9556040756914119, + "member_rmse": 0.002114896615525245, + "shared_bias": -0.0002596473431358828, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6331877729257642, + "median_sd": 0.0021340540682147973, + "median_halfwidth95": 0.004182669147754547, + "bias": -0.0002596473431358828, + "rmse": 0.0006168620723894777, + "max_abs_err": 0.0015735676592567335, + "tau": 0.0003254270465875187, + "s": 10.390508839587365, + "corr_length_days": 29.843343106842216, + "n_eff": 22.787211447808698, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.017570793338016207, + "prior_weight_s2": 6.992300542630042e-14, + "prior_weight_lambda": 1.2123012582174235e-05 + }, + { + "seed": 2146, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8195050946142649, + "member_coverage95": 0.9625181950509462, + "member_rmse": 0.00244047886272834, + "shared_bias": -0.000419094504180923, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5458515283842795, + "median_sd": 0.002395040160754698, + "median_halfwidth95": 0.004694192493633421, + "bias": -0.000419094504180923, + "rmse": 0.0008357654760595626, + "max_abs_err": 0.003893279877270795, + "tau": 0.00043086727220029245, + "s": 11.710506273860512, + "corr_length_days": 36.93214344710349, + "n_eff": 18.28909677594489, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.009303897930584386, + "prior_weight_s2": 5.465060634825546e-14, + "prior_weight_lambda": 1.984860954701859e-05 + }, + { + "seed": 2147, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8111353711790393, + "member_coverage95": 0.9526928675400291, + "member_rmse": 0.002267796646775513, + "shared_bias": -3.291592172761926e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6026200873362445, + "median_sd": 0.0022294256318740363, + "median_halfwidth95": 0.004369593979150364, + "bias": -3.291592172761926e-05, + "rmse": 0.0006267029517941895, + "max_abs_err": 0.0028188075318457805, + "tau": 0.00010120938848892893, + "s": 10.976539124295442, + "corr_length_days": 19.54444419545271, + "n_eff": 42.691849137715806, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.296938838137117, + "prior_weight_s2": 6.227907462837078e-14, + "prior_weight_lambda": 1.4005768636717509e-05 + }, + { + "seed": 2148, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8045851528384279, + "member_coverage95": 0.9566957787481805, + "member_rmse": 0.0024174009210870873, + "shared_bias": -0.00011295396799043541, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6157205240174672, + "median_sd": 0.002297094170001803, + "median_halfwidth95": 0.004502221877813414, + "bias": -0.00011295396799043541, + "rmse": 0.000640585733506158, + "max_abs_err": 0.001946773907056106, + "tau": 0.00018641370100780746, + "s": 11.236371989706557, + "corr_length_days": 12.77444326810252, + "n_eff": 38.2109852379856, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.06873098109645574, + "prior_weight_s2": 5.935964340171255e-14, + "prior_weight_lambda": 2.5738162821398115e-05 + }, + { + "seed": 2149, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8096797671033479, + "member_coverage95": 0.9497816593886463, + "member_rmse": 0.0024161877667975037, + "shared_bias": -0.0002752255084848738, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6550218340611353, + "median_sd": 0.002348660646892478, + "median_halfwidth95": 0.0046032903161259695, + "bias": -0.0002752255084848738, + "rmse": 0.0006245510097455176, + "max_abs_err": 0.001963559963946503, + "tau": 0.0004135379579274643, + "s": 11.136352358543878, + "corr_length_days": 29.542572515597296, + "n_eff": 19.67140906836516, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.010080815081919327, + "prior_weight_s2": 6.082672902251454e-14, + "prior_weight_lambda": 1.3276878505015849e-05 + }, + { + "seed": 2150, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7987627365356623, + "member_coverage95": 0.9490538573508006, + "member_rmse": 0.0024277438404183512, + "shared_bias": -0.00024937955399231755, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5938864628820961, + "median_sd": 0.0021285136788935744, + "median_halfwidth95": 0.004171810184138966, + "bias": -0.00024937955399231755, + "rmse": 0.000741895337118396, + "max_abs_err": 0.003012503368617281, + "tau": 0.00016941539763492842, + "s": 10.559888120706074, + "corr_length_days": 20.95886837072722, + "n_eff": 31.09191791692988, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.08160775562128797, + "prior_weight_s2": 6.735553106037642e-14, + "prior_weight_lambda": 1.6572668522141748e-05 + }, + { + "seed": 2151, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8173216885007278, + "member_coverage95": 0.9639737991266376, + "member_rmse": 0.0021322574717847075, + "shared_bias": -0.0001181954974149975, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6462882096069869, + "median_sd": 0.002090753918639116, + "median_halfwidth95": 0.004097802413391596, + "bias": -0.0001181954974149975, + "rmse": 0.0005072885301697609, + "max_abs_err": 0.002633172148009346, + "tau": 0.0002244677051050824, + "s": 10.325633899565306, + "corr_length_days": 6.779940964519536, + "n_eff": 40.66549212169593, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03964704123399472, + "prior_weight_s2": 6.994237790110613e-14, + "prior_weight_lambda": 7.578888703065296e-05 + }, + { + "seed": 2152, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.799490538573508, + "member_coverage95": 0.9581513828238719, + "member_rmse": 0.0021463272604983945, + "shared_bias": -6.768625216221652e-05, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5414847161572053, + "median_sd": 0.0021464811501053587, + "median_halfwidth95": 0.004207025780885099, + "bias": -6.768625216221652e-05, + "rmse": 0.0006157015181503091, + "max_abs_err": 0.0014800823283550799, + "tau": 0.0002138955796443903, + "s": 10.49952075361293, + "corr_length_days": 31.171758798144484, + "n_eff": 29.149366265495768, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.04424280151989766, + "prior_weight_s2": 6.801890176600432e-14, + "prior_weight_lambda": 3.210842127834396e-05 + }, + { + "seed": 2153, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7929403202328966, + "member_coverage95": 0.9461426491994177, + "member_rmse": 0.0023031130042804764, + "shared_bias": -0.0002239740380931093, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5414847161572053, + "median_sd": 0.002212099575244157, + "median_halfwidth95": 0.004335635531893839, + "bias": -0.0002239740380931093, + "rmse": 0.0006822522599713476, + "max_abs_err": 0.0025682098196041186, + "tau": 0.00012004320187734732, + "s": 10.768404603933554, + "corr_length_days": 30.764940177082643, + "n_eff": 43.37797992595232, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.19093540930251057, + "prior_weight_s2": 6.480177385970877e-14, + "prior_weight_lambda": 1.6537944389184002e-05 + }, + { + "seed": 2154, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7885735080058224, + "member_coverage95": 0.9526928675400291, + "member_rmse": 0.0021979314115402656, + "shared_bias": -0.0001518391281467412, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.4890829694323144, + "median_sd": 0.002198126245490675, + "median_halfwidth95": 0.004308248308616885, + "bias": -0.0001518391281467412, + "rmse": 0.0007027528860208951, + "max_abs_err": 0.0019361158534043645, + "tau": 0.0001381930671500975, + "s": 10.755899268218851, + "corr_length_days": 23.89147156975769, + "n_eff": 35.88627262304715, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.15047288779560464, + "prior_weight_s2": 6.501562649669106e-14, + "prior_weight_lambda": 1.8132326117821646e-05 + }, + { + "seed": 2155, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7907569141193596, + "member_coverage95": 0.9545123726346434, + "member_rmse": 0.002142585064327904, + "shared_bias": -8.7424499123617e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5720524017467249, + "median_sd": 0.00212318786495048, + "median_halfwidth95": 0.004161371780539803, + "bias": -8.7424499123617e-05, + "rmse": 0.0006848835629710207, + "max_abs_err": 0.0029241608983284523, + "tau": 0.00010022305679724515, + "s": 10.445432907884573, + "corr_length_days": 24.7951723116522, + "n_eff": 36.35681110941139, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.3068290559486229, + "prior_weight_s2": 6.870585488814177e-14, + "prior_weight_lambda": 1.9346803846972866e-05 + }, + { + "seed": 2156, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8027656477438136, + "member_coverage95": 0.9566957787481805, + "member_rmse": 0.0021640390563501238, + "shared_bias": -0.00010058619476559339, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5895196506550219, + "median_sd": 0.0022176683749201074, + "median_halfwidth95": 0.004346550178781913, + "bias": -0.00010058619476559339, + "rmse": 0.0006810429465419203, + "max_abs_err": 0.0025840688884293463, + "tau": 0.00012009670944160851, + "s": 10.845716135391365, + "corr_length_days": 22.145517885109427, + "n_eff": 35.83604770680447, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.20375659013111225, + "prior_weight_s2": 6.411725269019127e-14, + "prior_weight_lambda": 9.329092203322988e-06 + }, + { + "seed": 2157, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7692867540029112, + "member_coverage95": 0.9432314410480349, + "member_rmse": 0.002048772351287183, + "shared_bias": -0.00019424406962879304, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.5502183406113537, + "median_sd": 0.0019845109481978593, + "median_halfwidth95": 0.003889570016073669, + "bias": -0.00019424406962879304, + "rmse": 0.0007368727151770183, + "max_abs_err": 0.003908701592864697, + "tau": 0.00027359329113823633, + "s": 9.748466108234018, + "corr_length_days": 17.47595963858961, + "n_eff": 23.26284304572971, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.023304736804718933, + "prior_weight_s2": 7.938859941413549e-14, + "prior_weight_lambda": 1.0714219635836414e-05 + }, + { + "seed": 2158, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7973071324599709, + "member_coverage95": 0.9486899563318777, + "member_rmse": 0.0022405156757783038, + "shared_bias": -0.0002855019812972671, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5895196506550219, + "median_sd": 0.002164929059151408, + "median_halfwidth95": 0.00424318301849063, + "bias": -0.0002855019812972671, + "rmse": 0.0006604954032220218, + "max_abs_err": 0.0023483764143720693, + "tau": 0.00032981834944764184, + "s": 10.668858287493544, + "corr_length_days": 16.69583692277038, + "n_eff": 22.794752523553424, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01645187764852184, + "prior_weight_s2": 6.603369054912228e-14, + "prior_weight_lambda": 1.8295824652008227e-05 + }, + { + "seed": 2159, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8067685589519651, + "member_coverage95": 0.9537845705967977, + "member_rmse": 0.0022025544538199597, + "shared_bias": -0.00011316844122975049, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6419213973799127, + "median_sd": 0.0021356772704459025, + "median_halfwidth95": 0.004185850565692233, + "bias": -0.00011316844122975049, + "rmse": 0.0006171873627372188, + "max_abs_err": 0.002955427983824252, + "tau": 0.0003644837786409799, + "s": 10.421149399126982, + "corr_length_days": 47.13461231461804, + "n_eff": 22.306003141928233, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.013478259250940601, + "prior_weight_s2": 6.943385411740142e-14, + "prior_weight_lambda": 1.3189450670181588e-05 + }, + { + "seed": 2160, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8085880640465793, + "member_coverage95": 0.9541484716157205, + "member_rmse": 0.002187985198339102, + "shared_bias": -0.00023876057079119916, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5327510917030568, + "median_sd": 0.0021385126389039688, + "median_halfwidth95": 0.004191407785796779, + "bias": -0.00023876057079119916, + "rmse": 0.000613077882099594, + "max_abs_err": 0.0018517458251788481, + "tau": 0.00019653682263606244, + "s": 10.727342041300064, + "corr_length_days": 17.878282595494674, + "n_eff": 34.87282877579627, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.052380194891690615, + "prior_weight_s2": 6.498777372319861e-14, + "prior_weight_lambda": 3.638192085671132e-05 + }, + { + "seed": 2161, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.799490538573508, + "member_coverage95": 0.9439592430858806, + "member_rmse": 0.0023537483946285396, + "shared_bias": -0.00013470083504649313, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5807860262008734, + "median_sd": 0.002229495443703639, + "median_halfwidth95": 0.0043697308078231595, + "bias": -0.00013470083504649313, + "rmse": 0.0007052368094421318, + "max_abs_err": 0.002837769480321255, + "tau": 0.00026201614570382195, + "s": 10.902724883583701, + "corr_length_days": 36.89132602971249, + "n_eff": 27.14943036925757, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.02941468069012833, + "prior_weight_s2": 6.322908123039867e-14, + "prior_weight_lambda": 1.2651555168799504e-05 + }, + { + "seed": 2162, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8071324599708879, + "member_coverage95": 0.9563318777292577, + "member_rmse": 0.002270500738739263, + "shared_bias": -0.00025182137909652804, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6244541484716157, + "median_sd": 0.002196475259800984, + "median_halfwidth95": 0.004305012436100575, + "bias": -0.00025182137909652804, + "rmse": 0.0006049807397472385, + "max_abs_err": 0.0026079612867766027, + "tau": 0.0001850395592056054, + "s": 10.822643036581301, + "corr_length_days": 27.022072866137393, + "n_eff": 38.60004146895527, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.06489473007997724, + "prior_weight_s2": 6.401094849579109e-14, + "prior_weight_lambda": 2.3149416598280068e-05 + }, + { + "seed": 2163, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8155021834061136, + "member_coverage95": 0.9610625909752547, + "member_rmse": 0.0024117799900500374, + "shared_bias": -0.00024450658413745614, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6375545851528385, + "median_sd": 0.002347792989579181, + "median_halfwidth95": 0.004601589739027571, + "bias": -0.00024450658413745614, + "rmse": 0.0006184509431083619, + "max_abs_err": 0.002650367887661625, + "tau": 0.000366870061869, + "s": 11.564841872169866, + "corr_length_days": 31.289573470123976, + "n_eff": 23.028584588226614, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01230545512846841, + "prior_weight_s2": 5.5931686262232953e-14, + "prior_weight_lambda": 4.867623342978598e-05 + }, + { + "seed": 2164, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7918486171761281, + "member_coverage95": 0.9566957787481805, + "member_rmse": 0.0020984874376669327, + "shared_bias": -0.00021339270141248887, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6506550218340611, + "median_sd": 0.002127558349795205, + "median_halfwidth95": 0.004169937773498009, + "bias": -0.00021339270141248887, + "rmse": 0.0006620804049552923, + "max_abs_err": 0.002541316393294529, + "tau": 0.0002649524795809179, + "s": 10.314318686986761, + "corr_length_days": 23.968867935606138, + "n_eff": 23.908497207285887, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.026302754285720962, + "prior_weight_s2": 7.089587072032293e-14, + "prior_weight_lambda": 1.292174926614393e-05 + }, + { + "seed": 2165, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8253275109170306, + "member_coverage95": 0.9581513828238719, + "member_rmse": 0.002361209644454564, + "shared_bias": -0.0001356774498134117, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6986899563318777, + "median_sd": 0.0022535810444622817, + "median_halfwidth95": 0.004416937718228472, + "bias": -0.0001356774498134117, + "rmse": 0.0006021709784644932, + "max_abs_err": 0.0034940744506156327, + "tau": 0.00021987319573141758, + "s": 11.081029166941999, + "corr_length_days": 48.30816408925843, + "n_eff": 44.62601161315082, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0453283278422055, + "prior_weight_s2": 6.096218813322404e-14, + "prior_weight_lambda": 3.948719880743006e-05 + }, + { + "seed": 2166, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8002183406113537, + "member_coverage95": 0.9545123726346434, + "member_rmse": 0.0022907629457193305, + "shared_bias": -0.00021613584008033044, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5327510917030568, + "median_sd": 0.0022668754858836894, + "median_halfwidth95": 0.004442994344814539, + "bias": -0.00021613584008033044, + "rmse": 0.0007642270154017406, + "max_abs_err": 0.0025127238359669707, + "tau": 0.0001526603229035172, + "s": 10.888899647401866, + "corr_length_days": 19.620091751218272, + "n_eff": 36.46546521365267, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.11527409929210825, + "prior_weight_s2": 6.341672747945165e-14, + "prior_weight_lambda": 1.3395110338096413e-05 + }, + { + "seed": 2167, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8224163027656477, + "member_coverage95": 0.9556040756914119, + "member_rmse": 0.002299593548302895, + "shared_bias": -9.182295070224379e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5895196506550219, + "median_sd": 0.002244877662676554, + "median_halfwidth95": 0.00439987940325019, + "bias": -9.182295070224379e-05, + "rmse": 0.0006642159609645124, + "max_abs_err": 0.002099380334405614, + "tau": 0.00012935017953260314, + "s": 10.997898126923872, + "corr_length_days": 23.71139909949528, + "n_eff": 35.370622615394524, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.1787597097782204, + "prior_weight_s2": 6.212002779926323e-14, + "prior_weight_lambda": 1.8851552187080873e-05 + }, + { + "seed": 2168, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8074963609898108, + "member_coverage95": 0.9574235807860262, + "member_rmse": 0.002286828110926762, + "shared_bias": -0.00018180830523695514, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.7248908296943232, + "median_sd": 0.0022928323107654944, + "median_halfwidth95": 0.004493868787137182, + "bias": -0.00018180830523695514, + "rmse": 0.0006301225396358924, + "max_abs_err": 0.0025934200984159194, + "tau": 0.0003077036627848762, + "s": 11.430997653239908, + "corr_length_days": 27.74831933854185, + "n_eff": 25.30973419268156, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.019855801823231885, + "prior_weight_s2": 5.782792923508131e-14, + "prior_weight_lambda": 8.19568342877622e-06 + }, + { + "seed": 2169, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7965793304221251, + "member_coverage95": 0.9541484716157205, + "member_rmse": 0.002163455671890165, + "shared_bias": -0.00014960751858157786, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6462882096069869, + "median_sd": 0.0021197288070570527, + "median_halfwidth95": 0.004154592151594769, + "bias": -0.00014960751858157786, + "rmse": 0.0006290143932334486, + "max_abs_err": 0.002151545299624302, + "tau": 8.974289831400753e-05, + "s": 10.38257917177862, + "corr_length_days": 33.59076956696836, + "n_eff": 44.09341422518585, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.40809224353629425, + "prior_weight_s2": 7.007005871208721e-14, + "prior_weight_lambda": 1.0211235209351971e-05 + }, + { + "seed": 2170, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8096797671033479, + "member_coverage95": 0.9585152838427947, + "member_rmse": 0.0022550200539108475, + "shared_bias": -0.00023220336624602868, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6593886462882096, + "median_sd": 0.0021713524358543605, + "median_halfwidth95": 0.0042557726055868555, + "bias": -0.00023220336624602868, + "rmse": 0.0006208840328267316, + "max_abs_err": 0.0021126003430716983, + "tau": 0.00032863345250414396, + "s": 10.59467112332766, + "corr_length_days": 10.091021993537716, + "n_eff": 25.638788999077995, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01632070938570741, + "prior_weight_s2": 6.704760495337287e-14, + "prior_weight_lambda": 1.6783382496870682e-05 + }, + { + "seed": 2171, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7914847161572053, + "member_coverage95": 0.9512372634643377, + "member_rmse": 0.0024201951774397317, + "shared_bias": -0.00015088398252905783, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5982532751091703, + "median_sd": 0.0022948404360763727, + "median_halfwidth95": 0.004497804640453992, + "bias": -0.00015088398252905783, + "rmse": 0.0007331935571107481, + "max_abs_err": 0.0023541172037250804, + "tau": 0.0002582620417791869, + "s": 11.37640838569739, + "corr_length_days": 49.229357571843984, + "n_eff": 36.4295318663106, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.028679575712752658, + "prior_weight_s2": 5.816163083319351e-14, + "prior_weight_lambda": 1.2121108249928023e-05 + }, + { + "seed": 2172, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.787117903930131, + "member_coverage95": 0.9588791848617176, + "member_rmse": 0.002142091629593149, + "shared_bias": -0.00018730454741199093, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6550218340611353, + "median_sd": 0.002116564027468273, + "median_halfwidth95": 0.004148389297532826, + "bias": -0.00018730454741199093, + "rmse": 0.0005895128115972158, + "max_abs_err": 0.0023536948160411755, + "tau": 0.00029261405596432965, + "s": 10.37878842101868, + "corr_length_days": 11.79441654324832, + "n_eff": 26.066361594536854, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.02158904608465315, + "prior_weight_s2": 6.932190408332567e-14, + "prior_weight_lambda": 4.831725689145588e-05 + }, + { + "seed": 2173, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7893013100436681, + "member_coverage95": 0.9545123726346434, + "member_rmse": 0.002407580629871677, + "shared_bias": -0.0001486470656532291, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6637554585152838, + "median_sd": 0.002248463675424233, + "median_halfwidth95": 0.0044069078591391815, + "bias": -0.0001486470656532291, + "rmse": 0.0006940919842654781, + "max_abs_err": 0.002524820439548698, + "tau": 0.00021685194407868055, + "s": 11.046076370178767, + "corr_length_days": 26.261434876825014, + "n_eff": 30.15595702401887, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.04862899920548125, + "prior_weight_s2": 6.182504922776698e-14, + "prior_weight_lambda": 8.491226191246987e-06 + }, + { + "seed": 2174, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7816593886462883, + "member_coverage95": 0.9450509461426492, + "member_rmse": 0.002283012731824453, + "shared_bias": -0.00029781716190780284, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5240174672489083, + "median_sd": 0.0022325728886104833, + "median_halfwidth95": 0.004375762489052557, + "bias": -0.00029781716190780284, + "rmse": 0.0007399816831147797, + "max_abs_err": 0.003118324163710828, + "tau": 0.0003913557892620695, + "s": 10.738250473967808, + "corr_length_days": 30.606050810305167, + "n_eff": 19.07357082941122, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01129387241864472, + "prior_weight_s2": 6.529078862499179e-14, + "prior_weight_lambda": 1.491498065248468e-05 + }, + { + "seed": 2175, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8216885007278021, + "member_coverage95": 0.9541484716157205, + "member_rmse": 0.00252308606898852, + "shared_bias": -0.0002087988602333369, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6768558951965066, + "median_sd": 0.0024110860186931193, + "median_halfwidth95": 0.004725641797541841, + "bias": -0.0002087988602333369, + "rmse": 0.0005981651129434778, + "max_abs_err": 0.0027998091045233742, + "tau": 0.0002562433723532738, + "s": 11.894316428134779, + "corr_length_days": 13.616825148603066, + "n_eff": 31.966591320454484, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03207969345917685, + "prior_weight_s2": 5.265004736039124e-14, + "prior_weight_lambda": 5.939539718222155e-05 + }, + { + "seed": 2176, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8136826783114993, + "member_coverage95": 0.9581513828238719, + "member_rmse": 0.0023749462197230333, + "shared_bias": -0.00022328843029975664, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5982532751091703, + "median_sd": 0.002368490446615205, + "median_halfwidth95": 0.004642156009709723, + "bias": -0.00022328843029975664, + "rmse": 0.0006579301712066876, + "max_abs_err": 0.0020884428581114745, + "tau": 0.0003161584883342351, + "s": 11.492764182396712, + "corr_length_days": 15.92183190125548, + "n_eff": 25.78041228374013, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01874353524747488, + "prior_weight_s2": 5.699060415800949e-14, + "prior_weight_lambda": 1.9433420498756866e-05 + }, + { + "seed": 2177, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8067685589519651, + "member_coverage95": 0.9534206695778749, + "member_rmse": 0.002157531655631435, + "shared_bias": -0.00018597784369534307, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6026200873362445, + "median_sd": 0.002116459894124733, + "median_halfwidth95": 0.004148185199928288, + "bias": -0.00018597784369534307, + "rmse": 0.0006584348039314701, + "max_abs_err": 0.003166427935978022, + "tau": 0.0002555502039100631, + "s": 10.401697037072891, + "corr_length_days": 46.63957788725435, + "n_eff": 32.66133921142, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.029754963339068602, + "prior_weight_s2": 6.919121649109539e-14, + "prior_weight_lambda": 3.404097646512175e-05 + }, + { + "seed": 2178, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8060407569141194, + "member_coverage95": 0.9617903930131004, + "member_rmse": 0.002330089674401394, + "shared_bias": -0.00031062963835029866, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5240174672489083, + "median_sd": 0.0022582680711051946, + "median_halfwidth95": 0.004426124121715622, + "bias": -0.00031062963835029866, + "rmse": 0.0008677807989066573, + "max_abs_err": 0.0021750743029978693, + "tau": 0.00026294897059795237, + "s": 11.309624830078208, + "corr_length_days": 30.93410433885123, + "n_eff": 31.802404345291603, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03060430954585915, + "prior_weight_s2": 5.889818568307785e-14, + "prior_weight_lambda": 1.0745971260179257e-05 + }, + { + "seed": 2179, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8085880640465793, + "member_coverage95": 0.9585152838427947, + "member_rmse": 0.0024911992941915534, + "shared_bias": -6.161675406659115e-05, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6812227074235808, + "median_sd": 0.002400376308827136, + "median_halfwidth95": 0.004704651151754068, + "bias": -6.161675406659115e-05, + "rmse": 0.0006779236920640588, + "max_abs_err": 0.003151596264521117, + "tau": 0.0003025590001461886, + "s": 11.76892926031451, + "corr_length_days": 33.0533427120557, + "n_eff": 28.403910837958364, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.020973953922449894, + "prior_weight_s2": 5.4268844014644564e-14, + "prior_weight_lambda": 1.7064134945713053e-05 + }, + { + "seed": 2180, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8074963609898108, + "member_coverage95": 0.9559679767103348, + "member_rmse": 0.002376451568220656, + "shared_bias": -0.00020192509623456637, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.519650655021834, + "median_sd": 0.0023044601307946676, + "median_halfwidth95": 0.00451665889579284, + "bias": -0.00020192509623456637, + "rmse": 0.0006819834285602711, + "max_abs_err": 0.001995240160895777, + "tau": 0.00028116662500498566, + "s": 11.234218441156564, + "corr_length_days": 14.234368429949232, + "n_eff": 27.930264066878088, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.026077760461397866, + "prior_weight_s2": 5.932603272140162e-14, + "prior_weight_lambda": 2.7704293536086213e-05 + }, + { + "seed": 2181, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8013100436681223, + "member_coverage95": 0.9599708879184862, + "member_rmse": 0.002406586916895345, + "shared_bias": -0.0001779393604315279, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5283842794759825, + "median_sd": 0.0022997395099733356, + "median_halfwidth95": 0.004507406648925379, + "bias": -0.0001779393604315279, + "rmse": 0.0006439128417551784, + "max_abs_err": 0.0023736117905497262, + "tau": 0.00023326944090000718, + "s": 11.157137251848857, + "corr_length_days": 33.710590142439266, + "n_eff": 30.831595074381752, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.037788672872237396, + "prior_weight_s2": 6.012173692004764e-14, + "prior_weight_lambda": 4.336881513861646e-05 + }, + { + "seed": 2182, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7976710334788938, + "member_coverage95": 0.9501455604075691, + "member_rmse": 0.0023161990233911854, + "shared_bias": -0.0002854954196070061, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.48034934497816595, + "median_sd": 0.002177850637604798, + "median_halfwidth95": 0.00426850884708245, + "bias": -0.0002854954196070061, + "rmse": 0.0007945193702827485, + "max_abs_err": 0.002359581034271644, + "tau": 0.00018943578121370191, + "s": 10.774343930757425, + "corr_length_days": 48.97123853557156, + "n_eff": 41.24772940410554, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.06310711007743561, + "prior_weight_s2": 6.46466823068722e-14, + "prior_weight_lambda": 1.6992138045883483e-05 + }, + { + "seed": 2183, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8089519650655022, + "member_coverage95": 0.9541484716157205, + "member_rmse": 0.0023127415354470536, + "shared_bias": -0.0002374394428488962, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5720524017467249, + "median_sd": 0.0022654272912226007, + "median_halfwidth95": 0.0044401559354138136, + "bias": -0.0002374394428488962, + "rmse": 0.0007060984070934104, + "max_abs_err": 0.0022102920486647367, + "tau": 0.00032074330853580575, + "s": 11.00833874914001, + "corr_length_days": 36.258359578220016, + "n_eff": 26.551267045004288, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.017062455400245022, + "prior_weight_s2": 6.222544481489976e-14, + "prior_weight_lambda": 9.814300978788623e-06 + }, + { + "seed": 2184, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7911208151382824, + "member_coverage95": 0.9501455604075691, + "member_rmse": 0.0020351825774032077, + "shared_bias": -0.00018561399501269892, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5240174672489083, + "median_sd": 0.00206057299412077, + "median_halfwidth95": 0.004038648887848922, + "bias": -0.00018561399501269892, + "rmse": 0.0005870198593652246, + "max_abs_err": 0.002015698484154002, + "tau": 7.698508570754281e-05, + "s": 9.983447292712771, + "corr_length_days": 36.22995044504166, + "n_eff": 41.008955822145104, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.566256967099201, + "prior_weight_s2": 7.491251438933323e-14, + "prior_weight_lambda": 5.159288717004142e-05 + }, + { + "seed": 2185, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7958515283842795, + "member_coverage95": 0.9530567685589519, + "member_rmse": 0.002225857583122004, + "shared_bias": -0.0002183811295778611, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.62882096069869, + "median_sd": 0.002110276065961001, + "median_halfwidth95": 0.004136065119345187, + "bias": -0.0002183811295778611, + "rmse": 0.0006346041309135857, + "max_abs_err": 0.002571560932984382, + "tau": 0.000120695391820842, + "s": 10.262480321557133, + "corr_length_days": 9.1107493897219, + "n_eff": 49.90557585117956, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.1911820602976645, + "prior_weight_s2": 7.10482650475993e-14, + "prior_weight_lambda": 3.116126748920865e-05 + }, + { + "seed": 2186, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8067685589519651, + "member_coverage95": 0.9508733624454149, + "member_rmse": 0.002357858053575143, + "shared_bias": -0.0002090609959812549, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6506550218340611, + "median_sd": 0.002183385219348334, + "median_halfwidth95": 0.004279356428054839, + "bias": -0.0002090609959812549, + "rmse": 0.0006848099552547498, + "max_abs_err": 0.002485818200507635, + "tau": 0.0002934561411974957, + "s": 10.60899821173081, + "corr_length_days": 16.846378580208174, + "n_eff": 25.209739847621364, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.02087188046595429, + "prior_weight_s2": 6.695563658590635e-14, + "prior_weight_lambda": 1.2023344541291308e-05 + }, + { + "seed": 2187, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8198689956331878, + "member_coverage95": 0.9585152838427947, + "member_rmse": 0.002483038545939919, + "shared_bias": -0.00021467064289023855, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5676855895196506, + "median_sd": 0.0022711783046273407, + "median_halfwidth95": 0.004451427714650622, + "bias": -0.00021467064289023855, + "rmse": 0.0006517479160386192, + "max_abs_err": 0.002522514551294684, + "tau": 0.0003765330941732509, + "s": 10.873428916044654, + "corr_length_days": 38.128629107575016, + "n_eff": 21.204214321289754, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.011733760279556837, + "prior_weight_s2": 6.337184235892113e-14, + "prior_weight_lambda": 4.118801101624697e-05 + }, + { + "seed": 2188, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8096797671033479, + "member_coverage95": 0.9545123726346434, + "member_rmse": 0.002282946645779187, + "shared_bias": -0.0002362239368233744, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6506550218340611, + "median_sd": 0.002193671906890503, + "median_halfwidth95": 0.004299517965316738, + "bias": -0.0002362239368233744, + "rmse": 0.0005813882741674409, + "max_abs_err": 0.001889259548180526, + "tau": 0.0002289447805608686, + "s": 10.672484812950458, + "corr_length_days": 32.8206348960637, + "n_eff": 32.199654784115864, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0447727875832182, + "prior_weight_s2": 6.577394916376558e-14, + "prior_weight_lambda": 3.096669680474787e-05 + }, + { + "seed": 2189, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8198689956331878, + "member_coverage95": 0.9610625909752547, + "member_rmse": 0.0025057412455583255, + "shared_bias": -0.00020570163078301965, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.7074235807860262, + "median_sd": 0.0022909227026934845, + "median_halfwidth95": 0.004490126024061933, + "bias": -0.00020570163078301965, + "rmse": 0.0006283468644145148, + "max_abs_err": 0.003205504239588179, + "tau": 0.00037695775663417765, + "s": 11.042655603644718, + "corr_length_days": 29.632504576563466, + "n_eff": 22.321157218989878, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.011798971888041167, + "prior_weight_s2": 6.173563145509545e-14, + "prior_weight_lambda": 1.2957607661443631e-05 + }, + { + "seed": 2190, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7969432314410481, + "member_coverage95": 0.9497816593886463, + "member_rmse": 0.002425659262921563, + "shared_bias": -0.00012016187098937919, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.4978165938864629, + "median_sd": 0.002176543078630414, + "median_halfwidth95": 0.004265946078564781, + "bias": -0.00012016187098937919, + "rmse": 0.0007283612248614517, + "max_abs_err": 0.002812337557231695, + "tau": 0.00020419586853894075, + "s": 10.66796430774378, + "corr_length_days": 68.2500822268142, + "n_eff": 48.640085593821816, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.05564206783746276, + "prior_weight_s2": 6.622243545999758e-14, + "prior_weight_lambda": 1.3982842041330848e-05 + }, + { + "seed": 2191, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8144104803493449, + "member_coverage95": 0.965429403202329, + "member_rmse": 0.002395263295064808, + "shared_bias": -0.00012596886152480908, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6244541484716157, + "median_sd": 0.0022794333042769053, + "median_halfwidth95": 0.00446760721678378, + "bias": -0.00012596886152480908, + "rmse": 0.0005726335336724101, + "max_abs_err": 0.0024667270510695233, + "tau": 0.0002910231001858919, + "s": 11.20917584162018, + "corr_length_days": 33.776309789979564, + "n_eff": 29.468621470677515, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.02134351412911593, + "prior_weight_s2": 5.96355704409485e-14, + "prior_weight_lambda": 3.6243053062834087e-05 + }, + { + "seed": 2192, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.779839883551674, + "member_coverage95": 0.9479621542940321, + "member_rmse": 0.002059672847196487, + "shared_bias": -0.00014228091511377715, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6855895196506551, + "median_sd": 0.0020910800733623482, + "median_halfwidth95": 0.004098441664907562, + "bias": -0.00014228091511377715, + "rmse": 0.0005125240833582215, + "max_abs_err": 0.0017765487038993025, + "tau": 7.895703228260008e-05, + "s": 10.357856336673082, + "corr_length_days": 13.982189390610767, + "n_eff": 44.231984067695564, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.5287970220698089, + "prior_weight_s2": 6.97690022885032e-14, + "prior_weight_lambda": 2.74941280306874e-05 + }, + { + "seed": 2193, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8165938864628821, + "member_coverage95": 0.9534206695778749, + "member_rmse": 0.002502612585978833, + "shared_bias": -0.0002645045916710145, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5545851528384279, + "median_sd": 0.002431778753775976, + "median_halfwidth95": 0.004766198813365777, + "bias": -0.0002645045916710145, + "rmse": 0.000655142718192634, + "max_abs_err": 0.0021699407484122935, + "tau": 0.0003303895209392267, + "s": 11.889649331742637, + "corr_length_days": 42.10829056436975, + "n_eff": 29.34263014213295, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01605321101563031, + "prior_weight_s2": 5.2784500710603046e-14, + "prior_weight_lambda": 6.895555619027872e-05 + }, + { + "seed": 2194, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7980349344978166, + "member_coverage95": 0.9556040756914119, + "member_rmse": 0.0021991415843191924, + "shared_bias": -0.00020717124646616012, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5895196506550219, + "median_sd": 0.0021521774819243376, + "median_halfwidth95": 0.004218190386182353, + "bias": -0.00020717124646616012, + "rmse": 0.00071605549232278, + "max_abs_err": 0.0031363734335341795, + "tau": 0.0002249424085104601, + "s": 10.455009071127337, + "corr_length_days": 47.67213956790323, + "n_eff": 36.58875696000052, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.042230055721912296, + "prior_weight_s2": 6.906221512495134e-14, + "prior_weight_lambda": 9.34648661906588e-06 + }, + { + "seed": 2195, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7998544395924309, + "member_coverage95": 0.9472343522561864, + "member_rmse": 0.002395680988282556, + "shared_bias": -0.0002406335592466559, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.7030567685589519, + "median_sd": 0.0022194183482757315, + "median_halfwidth95": 0.004349980063559896, + "bias": -0.0002406335592466559, + "rmse": 0.0005969160771606998, + "max_abs_err": 0.002258169058168688, + "tau": 0.0003014270657858853, + "s": 10.70018169636518, + "corr_length_days": 19.72387795767805, + "n_eff": 24.446090763373306, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.020221953247512713, + "prior_weight_s2": 6.549286786516401e-14, + "prior_weight_lambda": 2.1549526082448807e-05 + }, + { + "seed": 2196, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7940320232896652, + "member_coverage95": 0.9472343522561864, + "member_rmse": 0.0022554425609353037, + "shared_bias": -0.0002784921601489029, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5240174672489083, + "median_sd": 0.0021792593665574916, + "median_halfwidth95": 0.004271269905115487, + "bias": -0.0002784921601489029, + "rmse": 0.0006791714288234759, + "max_abs_err": 0.001742355632816515, + "tau": 0.00014264700312887764, + "s": 10.73268126099442, + "corr_length_days": 24.444108323453577, + "n_eff": 34.89364131863393, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.13258389871926565, + "prior_weight_s2": 6.537442202742586e-14, + "prior_weight_lambda": 1.4162875516319483e-05 + }, + { + "seed": 2197, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8056768558951966, + "member_coverage95": 0.9548762736535662, + "member_rmse": 0.0024984050705170453, + "shared_bias": -0.0001683879526328112, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5851528384279476, + "median_sd": 0.002372925335085301, + "median_halfwidth95": 0.004650848231455128, + "bias": -0.0001683879526328112, + "rmse": 0.00074336885230991, + "max_abs_err": 0.003027963861021142, + "tau": 0.0002594083205909572, + "s": 11.693612919574287, + "corr_length_days": 14.400799250138409, + "n_eff": 30.541010167140577, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.030933104234916384, + "prior_weight_s2": 5.505695199580547e-14, + "prior_weight_lambda": 1.3796538207195646e-05 + }, + { + "seed": 2198, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7794759825327511, + "member_coverage95": 0.9548762736535662, + "member_rmse": 0.0020834160760811026, + "shared_bias": -8.057054435421087e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5676855895196506, + "median_sd": 0.0021158308337250868, + "median_halfwidth95": 0.004146952264191156, + "bias": -8.057054435421087e-05, + "rmse": 0.0006349494766735151, + "max_abs_err": 0.0025355157318414463, + "tau": 9.961749464569354e-05, + "s": 10.300640854257606, + "corr_length_days": 16.18057073579864, + "n_eff": 38.6405475559946, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.32799830844134636, + "prior_weight_s2": 7.078167863622309e-14, + "prior_weight_lambda": 1.7037672194386568e-05 + }, + { + "seed": 2199, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7943959243085881, + "member_coverage95": 0.9585152838427947, + "member_rmse": 0.002315162638648328, + "shared_bias": -0.00019576177314232533, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5764192139737991, + "median_sd": 0.0022580122229157685, + "median_halfwidth95": 0.004425622668474881, + "bias": -0.00019576177314232533, + "rmse": 0.000770741290579663, + "max_abs_err": 0.0028132817827286245, + "tau": 0.00012436604412049008, + "s": 11.066065341859598, + "corr_length_days": 28.079685480785493, + "n_eff": 40.378562945253464, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.18016516404907526, + "prior_weight_s2": 6.154079879287706e-14, + "prior_weight_lambda": 9.92720468379536e-06 + } + ] +} diff --git a/paper/data/calibration/locked_shared_source_n200.json b/paper/data/calibration/locked_shared_source_n200.json new file mode 100644 index 0000000..88e6a17 --- /dev/null +++ b/paper/data/calibration/locked_shared_source_n200.json @@ -0,0 +1,5528 @@ +{ + "codameter_version": "0.4.0", + "git_commit": "b426c4e660e50d5bbc705d8541269fd97b97c2ee", + "started_utc": "2026-09-10T20:52:16+00:00", + "finished_utc": "2026-09-10T21:50:39+00:00", + "wall_seconds": 3502.912184, + "settings": { + "scenario": "shared_source", + "years": 2.5, + "snr": 7.0, + "cadence": 4, + "n_iter": 1200, + "burn": 400, + "thin": 2 + }, + "seeds": [ + 2000, + 2001, + 2002, + 2003, + 2004, + 2005, + 2006, + 2007, + 2008, + 2009, + 2010, + 2011, + 2012, + 2013, + 2014, + 2015, + 2016, + 2017, + 2018, + 2019, + 2020, + 2021, + 2022, + 2023, + 2024, + 2025, + 2026, + 2027, + 2028, + 2029, + 2030, + 2031, + 2032, + 2033, + 2034, + 2035, + 2036, + 2037, + 2038, + 2039, + 2040, + 2041, + 2042, + 2043, + 2044, + 2045, + 2046, + 2047, + 2048, + 2049, + 2050, + 2051, + 2052, + 2053, + 2054, + 2055, + 2056, + 2057, + 2058, + 2059, + 2060, + 2061, + 2062, + 2063, + 2064, + 2065, + 2066, + 2067, + 2068, + 2069, + 2070, + 2071, + 2072, + 2073, + 2074, + 2075, + 2076, + 2077, + 2078, + 2079, + 2080, + 2081, + 2082, + 2083, + 2084, + 2085, + 2086, + 2087, + 2088, + 2089, + 2090, + 2091, + 2092, + 2093, + 2094, + 2095, + 2096, + 2097, + 2098, + 2099, + 2100, + 2101, + 2102, + 2103, + 2104, + 2105, + 2106, + 2107, + 2108, + 2109, + 2110, + 2111, + 2112, + 2113, + 2114, + 2115, + 2116, + 2117, + 2118, + 2119, + 2120, + 2121, + 2122, + 2123, + 2124, + 2125, + 2126, + 2127, + 2128, + 2129, + 2130, + 2131, + 2132, + 2133, + 2134, + 2135, + 2136, + 2137, + 2138, + 2139, + 2140, + 2141, + 2142, + 2143, + 2144, + 2145, + 2146, + 2147, + 2148, + 2149, + 2150, + 2151, + 2152, + 2153, + 2154, + 2155, + 2156, + 2157, + 2158, + 2159, + 2160, + 2161, + 2162, + 2163, + 2164, + 2165, + 2166, + 2167, + 2168, + 2169, + 2170, + 2171, + 2172, + 2173, + 2174, + 2175, + 2176, + 2177, + 2178, + 2179, + 2180, + 2181, + 2182, + 2183, + 2184, + 2185, + 2186, + 2187, + 2188, + 2189, + 2190, + 2191, + 2192, + 2193, + 2194, + 2195, + 2196, + 2197, + 2198, + 2199 + ], + "summary": { + "n_realizations": 200, + "n_failed": 0, + "failures": [], + "margin": 0.03, + "member_coverage68": { + "mean": 0.7945123726346435, + "se": 0.000944941871924279, + "n": 200 + }, + "member_coverage95": { + "mean": 0.949561499272198, + "se": 0.0003750220524867418, + "n": 200 + }, + "member_rmse": { + "mean": 0.0035139165299497644, + "se": 1.0773159246632899e-05, + "n": 200 + }, + "shared_bias": { + "mean": -0.00045443441962889373, + "se": 7.963688526075521e-06, + "n": 200 + }, + "coverage68": { + "mean": 0.9763973799126637, + "se": 0.0013253505480707282, + "n": 200 + }, + "coverage95": { + "mean": 1.0, + "se": 0.0, + "n": 200 + }, + "coverage95_posterior": { + "mean": 0.3403275109170306, + "se": 0.0038972087996702477, + "n": 200 + }, + "median_sd": { + "mean": 0.003300896641952251, + "se": 9.702527232567708e-06, + "n": 200 + }, + "median_halfwidth95": { + "mean": 0.006469638585947302, + "se": 1.9016604084852336e-05, + "n": 200 + }, + "bias": { + "mean": -0.00045443441962889373, + "se": 7.963688526075521e-06, + "n": 200 + }, + "rmse": { + "mean": 0.0016128235682199667, + "se": 8.318774631720938e-06, + "n": 200 + }, + "max_abs_err": { + "mean": 0.004064167813162548, + "se": 4.31489155954433e-05, + "n": 200 + }, + "tau": { + "mean": 0.0004579240479937903, + "se": 1.0633896408167719e-05, + "n": 200 + }, + "s": { + "mean": 12.69841941154758, + "se": 0.0378348941360989, + "n": 200 + }, + "corr_length_days": { + "mean": 29.93779008492537, + "se": 0.9166651010427155, + "n": 200 + }, + "n_eff": { + "mean": 26.440478925411142, + "se": 0.574465100391262, + "n": 200 + }, + "missing_fraction": { + "mean": 0.0, + "se": 0.0, + "n": 200 + }, + "prior_weight_tau2": { + "mean": 0.024580127148341933, + "se": 0.0046761323546567046, + "n": 200 + }, + "prior_weight_s2": { + "mean": 4.6786274250638935e-14, + "se": 2.755564068273868e-16, + "n": 200 + }, + "prior_weight_lambda": { + "mean": 2.6233956764316734e-05, + "se": 6.825029156419385e-06, + "n": 200 + }, + "member_coverage95_within_margin": true, + "member_coverage68_within_margin": false + }, + "results": [ + { + "seed": 2000, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8038573508005823, + "member_coverage95": 0.9516011644832606, + "member_rmse": 0.003587768910493033, + "shared_bias": -0.0004363357933741332, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.2183406113537118, + "median_sd": 0.003306362211507539, + "median_halfwidth95": 0.006480350905515162, + "bias": -0.0004363357933741332, + "rmse": 0.0015702825213768114, + "max_abs_err": 0.0035928352592646787, + "tau": 0.000329861321603337, + "s": 13.116446431621082, + "corr_length_days": 20.490251030598643, + "n_eff": 31.985585602015217, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.018472214812326946, + "prior_weight_s2": 4.315237748155711e-14, + "prior_weight_lambda": 0.00026999517951122726 + }, + { + "seed": 2001, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7954876273653566, + "member_coverage95": 0.9443231441048034, + "member_rmse": 0.003624533033451236, + "shared_bias": -0.0007228622784940762, + "coverage68": 0.9301310043668122, + "coverage95": 1.0, + "coverage95_posterior": 0.4279475982532751, + "median_sd": 0.0033243086709263785, + "median_halfwidth95": 0.006515525319903548, + "bias": -0.0007228622784940762, + "rmse": 0.0019056168093854766, + "max_abs_err": 0.005928954232938644, + "tau": 0.0005886414046041963, + "s": 12.860834294508612, + "corr_length_days": 54.03368096604181, + "n_eff": 21.17936003804387, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.005164901090728756, + "prior_weight_s2": 4.548231332980492e-14, + "prior_weight_lambda": 8.723023221230739e-06 + }, + { + "seed": 2002, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7827510917030568, + "member_coverage95": 0.9472343522561864, + "member_rmse": 0.0033861570781444266, + "shared_bias": -0.00047570289580465354, + "coverage68": 0.9694323144104804, + "coverage95": 1.0, + "coverage95_posterior": 0.3799126637554585, + "median_sd": 0.003177322864156986, + "median_halfwidth95": 0.006227438430124584, + "bias": -0.00047570289580465354, + "rmse": 0.0015969609146239297, + "max_abs_err": 0.004273576357260906, + "tau": 0.0004282354763890663, + "s": 12.216782449505597, + "corr_length_days": 27.357168466100084, + "n_eff": 23.53199557265331, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.009932831808251436, + "prior_weight_s2": 5.0302401521791674e-14, + "prior_weight_lambda": 9.006915890814311e-06 + }, + { + "seed": 2003, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7856622998544396, + "member_coverage95": 0.9450509461426492, + "member_rmse": 0.0035368372851589686, + "shared_bias": -0.0006080539662062954, + "coverage68": 0.9475982532751092, + "coverage95": 1.0, + "coverage95_posterior": 0.32751091703056767, + "median_sd": 0.003324190853571557, + "median_halfwidth95": 0.006515294402129524, + "bias": -0.0006080539662062954, + "rmse": 0.0016919371404134683, + "max_abs_err": 0.004564087872348613, + "tau": 0.00037688920955659944, + "s": 12.614397443865306, + "corr_length_days": 33.110925005833906, + "n_eff": 25.190210117894118, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01335092890843117, + "prior_weight_s2": 4.716111713558244e-14, + "prior_weight_lambda": 1.8337848742589564e-05 + }, + { + "seed": 2004, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7903930131004366, + "member_coverage95": 0.9472343522561864, + "member_rmse": 0.0035981038730767832, + "shared_bias": -0.00041649084023913954, + "coverage68": 0.9694323144104804, + "coverage95": 1.0, + "coverage95_posterior": 0.314410480349345, + "median_sd": 0.003310513154910268, + "median_halfwidth95": 0.0064884866051505485, + "bias": -0.00041649084023913954, + "rmse": 0.0016548940563189494, + "max_abs_err": 0.003956337350497101, + "tau": 0.0004789860423386672, + "s": 12.778088561860057, + "corr_length_days": 39.114349727888545, + "n_eff": 25.76539402167847, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.007340856705064456, + "prior_weight_s2": 4.577463190294941e-14, + "prior_weight_lambda": 2.63109397257426e-05 + }, + { + "seed": 2005, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8213245997088792, + "member_coverage95": 0.9494177583697234, + "member_rmse": 0.003834037642685608, + "shared_bias": -0.0005127285156333879, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.44541484716157204, + "median_sd": 0.0035551574430788308, + "median_halfwidth95": 0.0069679806027665575, + "bias": -0.0005127285156333879, + "rmse": 0.0015991113075173942, + "max_abs_err": 0.004087731947714243, + "tau": 0.0008387996296402301, + "s": 13.330860478313799, + "corr_length_days": 32.03519239643343, + "n_eff": 13.211458159650336, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0024529879276939852, + "prior_weight_s2": 4.2196666908584085e-14, + "prior_weight_lambda": 1.5373416199478727e-05 + }, + { + "seed": 2006, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8351528384279476, + "member_coverage95": 0.9585152838427947, + "member_rmse": 0.0037385027068722065, + "shared_bias": -0.0005892030886291679, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.40611353711790393, + "median_sd": 0.0035125329373058662, + "median_halfwidth95": 0.006884438105933755, + "bias": -0.0005892030886291679, + "rmse": 0.0014057452557525018, + "max_abs_err": 0.0033089666007042767, + "tau": 0.0007258520124487462, + "s": 13.514006452396469, + "corr_length_days": 37.16003237623295, + "n_eff": 15.670470303862338, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0031074243845825556, + "prior_weight_s2": 4.0954141154922277e-14, + "prior_weight_lambda": 2.5517531899720777e-05 + }, + { + "seed": 2007, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8067685589519651, + "member_coverage95": 0.9541484716157205, + "member_rmse": 0.0037149881827984108, + "shared_bias": -0.00047961711656891847, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.388646288209607, + "median_sd": 0.0035668272198502763, + "median_halfwidth95": 0.006990852945126627, + "bias": -0.00047961711656891847, + "rmse": 0.0015681270392129492, + "max_abs_err": 0.0034773734080353045, + "tau": 0.000546469134985489, + "s": 13.604738799424315, + "corr_length_days": 34.00771554837656, + "n_eff": 23.457742680059486, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.005935527968243024, + "prior_weight_s2": 4.0580084947816624e-14, + "prior_weight_lambda": 8.80043614195211e-06 + }, + { + "seed": 2008, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8027656477438136, + "member_coverage95": 0.9501455604075691, + "member_rmse": 0.0033303029024699, + "shared_bias": -0.0006463682647878833, + "coverage68": 0.9737991266375546, + "coverage95": 1.0, + "coverage95_posterior": 0.3930131004366812, + "median_sd": 0.0032289174839037777, + "median_halfwidth95": 0.006328562027421984, + "bias": -0.0006463682647878833, + "rmse": 0.0015741628983637354, + "max_abs_err": 0.004155695383968335, + "tau": 0.0006028096549562439, + "s": 12.319373043812744, + "corr_length_days": 28.894433708711198, + "n_eff": 17.886474851338946, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.004611096865907676, + "prior_weight_s2": 4.941198732340188e-14, + "prior_weight_lambda": 2.103087198612672e-05 + }, + { + "seed": 2009, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8238719068413392, + "member_coverage95": 0.9534206695778749, + "member_rmse": 0.003959590843605985, + "shared_bias": -0.0006013680591812226, + "coverage68": 0.9868995633187773, + "coverage95": 1.0, + "coverage95_posterior": 0.4104803493449782, + "median_sd": 0.0036576553118042353, + "median_halfwidth95": 0.007168872735545076, + "bias": -0.0006013680591812226, + "rmse": 0.0016270125921371821, + "max_abs_err": 0.004653645177509549, + "tau": 0.0006333909143154323, + "s": 14.101608941227385, + "corr_length_days": 44.07278861457666, + "n_eff": 21.228153679557565, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.004493144425541203, + "prior_weight_s2": 3.7768599408875795e-14, + "prior_weight_lambda": 9.394412471697284e-06 + }, + { + "seed": 2010, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7936681222707423, + "member_coverage95": 0.9501455604075691, + "member_rmse": 0.0035514173856604947, + "shared_bias": -0.0005253222324919703, + "coverage68": 0.9868995633187773, + "coverage95": 1.0, + "coverage95_posterior": 0.388646288209607, + "median_sd": 0.0033863822307242096, + "median_halfwidth95": 0.006637187262459145, + "bias": -0.0005253222324919703, + "rmse": 0.0015849225812847396, + "max_abs_err": 0.0039785545146063615, + "tau": 0.0005076353782782932, + "s": 13.19130670357105, + "corr_length_days": 36.11816029716928, + "n_eff": 22.54389298631061, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.006820051518254466, + "prior_weight_s2": 4.3246170732998484e-14, + "prior_weight_lambda": 6.188811828519135e-06 + }, + { + "seed": 2011, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7998544395924309, + "member_coverage95": 0.9519650655021834, + "member_rmse": 0.003553200175187869, + "shared_bias": -0.0006285157527123722, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.3799126637554585, + "median_sd": 0.003271731310270556, + "median_halfwidth95": 0.00641247558580312, + "bias": -0.0006285157527123722, + "rmse": 0.0015053600113819929, + "max_abs_err": 0.003203478732369874, + "tau": 0.0006046609116571858, + "s": 12.437445595348894, + "corr_length_days": 24.94096003743297, + "n_eff": 17.02533777967526, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.004242062606071319, + "prior_weight_s2": 4.859533363136301e-14, + "prior_weight_lambda": 1.7472269088034324e-05 + }, + { + "seed": 2012, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7678311499272198, + "member_coverage95": 0.9352256186317321, + "member_rmse": 0.0033965598250486105, + "shared_bias": -0.000367023823228688, + "coverage68": 0.9432314410480349, + "coverage95": 1.0, + "coverage95_posterior": 0.26200873362445415, + "median_sd": 0.0031687335450708773, + "median_halfwidth95": 0.006210603673931297, + "bias": -0.000367023823228688, + "rmse": 0.0016372483893105985, + "max_abs_err": 0.00414430206243225, + "tau": 0.00016240535740587154, + "s": 12.389703864506396, + "corr_length_days": 11.296114484245543, + "n_eff": 46.16699170173588, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.12813500701595698, + "prior_weight_s2": 4.8397164415392746e-14, + "prior_weight_lambda": 5.25954352770212e-05 + }, + { + "seed": 2013, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8013100436681223, + "member_coverage95": 0.9443231441048034, + "member_rmse": 0.0035712885568860557, + "shared_bias": -0.00038037990476349516, + "coverage68": 0.9868995633187773, + "coverage95": 1.0, + "coverage95_posterior": 0.3318777292576419, + "median_sd": 0.003407324251356391, + "median_halfwidth95": 0.006678232868985478, + "bias": -0.00038037990476349516, + "rmse": 0.001665938125480503, + "max_abs_err": 0.003638561001551742, + "tau": 0.0004433621186964227, + "s": 12.99874876019473, + "corr_length_days": 32.78201415375722, + "n_eff": 25.533392163894998, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.009012054199649998, + "prior_weight_s2": 4.4585431755624035e-14, + "prior_weight_lambda": 6.950787528581618e-06 + }, + { + "seed": 2014, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8064046579330422, + "member_coverage95": 0.9552401746724891, + "member_rmse": 0.003486054646050438, + "shared_bias": -0.0005007454472853993, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.39737991266375544, + "median_sd": 0.003379619572324509, + "median_halfwidth95": 0.006623932695451434, + "bias": -0.0005007454472853993, + "rmse": 0.0015334201087925084, + "max_abs_err": 0.003532510748848686, + "tau": 0.0004726132970279996, + "s": 13.092353215349657, + "corr_length_days": 22.506180729220574, + "n_eff": 23.76720189934624, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0077539434184013675, + "prior_weight_s2": 4.3843185292930225e-14, + "prior_weight_lambda": 9.52321937899375e-06 + }, + { + "seed": 2015, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7802037845705968, + "member_coverage95": 0.950509461426492, + "member_rmse": 0.0034008551308888912, + "shared_bias": -0.00046440486622048956, + "coverage68": 0.9781659388646288, + "coverage95": 1.0, + "coverage95_posterior": 0.34497816593886466, + "median_sd": 0.003134565279707918, + "median_halfwidth95": 0.00614363510387745, + "bias": -0.00046440486622048956, + "rmse": 0.0016651069498176201, + "max_abs_err": 0.0043588297981621785, + "tau": 0.0006106096843607437, + "s": 11.938594306887435, + "corr_length_days": 27.268864317830644, + "n_eff": 16.22986776995512, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.00433542882815164, + "prior_weight_s2": 5.265352584916639e-14, + "prior_weight_lambda": 1.2136993373009981e-05 + }, + { + "seed": 2016, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7816593886462883, + "member_coverage95": 0.9486899563318777, + "member_rmse": 0.0033549887906130452, + "shared_bias": -0.0003555749362465133, + "coverage68": 0.982532751091703, + "coverage95": 1.0, + "coverage95_posterior": 0.2794759825327511, + "median_sd": 0.0032180122010794484, + "median_halfwidth95": 0.00630718806567648, + "bias": -0.0003555749362465133, + "rmse": 0.0016383581068676809, + "max_abs_err": 0.0036002729050820556, + "tau": 0.0005425968503410844, + "s": 12.044264956440468, + "corr_length_days": 43.903656160279894, + "n_eff": 22.366989766453337, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.005894312691617894, + "prior_weight_s2": 5.1925339880261194e-14, + "prior_weight_lambda": 9.233404140064172e-06 + }, + { + "seed": 2017, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7918486171761281, + "member_coverage95": 0.9516011644832606, + "member_rmse": 0.0034219567914067447, + "shared_bias": -0.0003650892038680328, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.3056768558951965, + "median_sd": 0.003370613220705378, + "median_halfwidth95": 0.006606280570506596, + "bias": -0.0003650892038680328, + "rmse": 0.0015319307845390855, + "max_abs_err": 0.0037205874289293695, + "tau": 0.0004566494873560599, + "s": 12.951864186727299, + "corr_length_days": 30.087754437537747, + "n_eff": 22.866568797864055, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.008677708695797398, + "prior_weight_s2": 4.455761781630205e-14, + "prior_weight_lambda": 3.159826860041719e-05 + }, + { + "seed": 2018, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8013100436681223, + "member_coverage95": 0.9559679767103348, + "member_rmse": 0.003437630407687138, + "shared_bias": -0.0002247098390457793, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.3624454148471616, + "median_sd": 0.0032949871065681893, + "median_halfwidth95": 0.006458056109337814, + "bias": -0.0002247098390457793, + "rmse": 0.0015282042829382646, + "max_abs_err": 0.003558061870448927, + "tau": 0.00022805784699934242, + "s": 12.669698331715052, + "corr_length_days": 36.98694812195562, + "n_eff": 50.32415456511893, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.05202838027987495, + "prior_weight_s2": 4.707652767284347e-14, + "prior_weight_lambda": 4.814096431733738e-06 + }, + { + "seed": 2019, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8362445414847162, + "member_coverage95": 0.9639737991266376, + "member_rmse": 0.0037664442865469354, + "shared_bias": -0.0004883031792679286, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.4847161572052402, + "median_sd": 0.0036784463637665847, + "median_halfwidth95": 0.0072096224489134105, + "bias": -0.0004883031792679286, + "rmse": 0.0015503506335512744, + "max_abs_err": 0.004083617685783877, + "tau": 0.00042149424343284226, + "s": 14.611022003847681, + "corr_length_days": 9.082248824148833, + "n_eff": 33.15429027553985, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.011393681677403473, + "prior_weight_s2": 3.5109797570833427e-14, + "prior_weight_lambda": 1.0048557387744976e-05 + }, + { + "seed": 2020, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7969432314410481, + "member_coverage95": 0.9537845705967977, + "member_rmse": 0.0034185717707668505, + "shared_bias": -0.0005495055661166777, + "coverage68": 0.982532751091703, + "coverage95": 1.0, + "coverage95_posterior": 0.34934497816593885, + "median_sd": 0.003296886731101637, + "median_halfwidth95": 0.006461779305036889, + "bias": -0.0005495055661166777, + "rmse": 0.0015548971228769625, + "max_abs_err": 0.003935994851927678, + "tau": 0.00044183902673794706, + "s": 12.680652316536507, + "corr_length_days": 34.373629599329185, + "n_eff": 29.081518881825698, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.009331199879015087, + "prior_weight_s2": 4.68059874134799e-14, + "prior_weight_lambda": 7.148322673070153e-06 + }, + { + "seed": 2021, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7878457059679768, + "member_coverage95": 0.9494177583697234, + "member_rmse": 0.003396311790706653, + "shared_bias": -0.00034201449875810493, + "coverage68": 0.9781659388646288, + "coverage95": 1.0, + "coverage95_posterior": 0.24017467248908297, + "median_sd": 0.0032212318045241944, + "median_halfwidth95": 0.006313498372522458, + "bias": -0.00034201449875810493, + "rmse": 0.0017166036635671204, + "max_abs_err": 0.00450948934646501, + "tau": 0.00043348407910336404, + "s": 12.497371008841549, + "corr_length_days": 18.494538644811012, + "n_eff": 25.252328237488708, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.008614310213576958, + "prior_weight_s2": 4.8109520295932454e-14, + "prior_weight_lambda": 1.0985713852465936e-05 + }, + { + "seed": 2022, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7973071324599709, + "member_coverage95": 0.9516011644832606, + "member_rmse": 0.003445529095350377, + "shared_bias": -0.00039186586935917344, + "coverage68": 0.9694323144104804, + "coverage95": 1.0, + "coverage95_posterior": 0.36681222707423583, + "median_sd": 0.003370051517759255, + "median_halfwidth95": 0.0066051796529535, + "bias": -0.00039186586935917344, + "rmse": 0.001595006641060751, + "max_abs_err": 0.004528180077802268, + "tau": 0.000332473507522308, + "s": 13.109269303687269, + "corr_length_days": 12.75729168486941, + "n_eff": 31.972203965281672, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.018788331619609022, + "prior_weight_s2": 4.3537901592568724e-14, + "prior_weight_lambda": 2.228954839187874e-05 + }, + { + "seed": 2023, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7882096069868996, + "member_coverage95": 0.9534206695778749, + "member_rmse": 0.0033479717472075956, + "shared_bias": -0.0005076834552429634, + "coverage68": 0.9606986899563319, + "coverage95": 1.0, + "coverage95_posterior": 0.33624454148471616, + "median_sd": 0.0032811386820043257, + "median_halfwidth95": 0.006430913695735926, + "bias": -0.0005076834552429634, + "rmse": 0.001634818236376938, + "max_abs_err": 0.0055852782910902656, + "tau": 0.0002908475505609334, + "s": 12.594842158576746, + "corr_length_days": 42.86673126917408, + "n_eff": 33.969091797303676, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.024782840560355766, + "prior_weight_s2": 4.7675639023499025e-14, + "prior_weight_lambda": 5.092755567941835e-06 + }, + { + "seed": 2024, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7925764192139738, + "member_coverage95": 0.9501455604075691, + "member_rmse": 0.0035794242934762657, + "shared_bias": -0.0008170260358127899, + "coverage68": 0.9737991266375546, + "coverage95": 1.0, + "coverage95_posterior": 0.3537117903930131, + "median_sd": 0.0033439552594203724, + "median_halfwidth95": 0.006554031926074591, + "bias": -0.0008170260358127899, + "rmse": 0.0016704422111595441, + "max_abs_err": 0.003887669712405859, + "tau": 0.00086835487108524, + "s": 12.514576326255819, + "corr_length_days": 21.71735687990031, + "n_eff": 11.1244159472105, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.002107173659367058, + "prior_weight_s2": 4.770117449731821e-14, + "prior_weight_lambda": 3.5303770776649534e-05 + }, + { + "seed": 2025, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7947598253275109, + "member_coverage95": 0.9472343522561864, + "member_rmse": 0.003467379423352354, + "shared_bias": -0.0003528838085591377, + "coverage68": 0.9694323144104804, + "coverage95": 1.0, + "coverage95_posterior": 0.34934497816593885, + "median_sd": 0.0032099464194518656, + "median_halfwidth95": 0.006291379424054557, + "bias": -0.0003528838085591377, + "rmse": 0.0016521553570042588, + "max_abs_err": 0.004279277418832529, + "tau": 0.000416687552021388, + "s": 12.552996778864333, + "corr_length_days": 40.08900759990961, + "n_eff": 27.448505069647254, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01077057932177338, + "prior_weight_s2": 4.7775032142151856e-14, + "prior_weight_lambda": 7.714405970418814e-06 + }, + { + "seed": 2026, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7652838427947598, + "member_coverage95": 0.9359534206695779, + "member_rmse": 0.003412812964744793, + "shared_bias": -0.0003266369413908817, + "coverage68": 0.9650655021834061, + "coverage95": 1.0, + "coverage95_posterior": 0.3056768558951965, + "median_sd": 0.003115882491557485, + "median_halfwidth95": 0.006107017511682975, + "bias": -0.0003266369413908817, + "rmse": 0.0016738965051895122, + "max_abs_err": 0.004192539296845968, + "tau": 0.00043560792626129804, + "s": 11.80290628871291, + "corr_length_days": 22.511689751542768, + "n_eff": 24.347921954682317, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.008957020581861205, + "prior_weight_s2": 5.429960979051713e-14, + "prior_weight_lambda": 6.414197184473297e-06 + }, + { + "seed": 2027, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7907569141193596, + "member_coverage95": 0.9494177583697234, + "member_rmse": 0.003824518022282778, + "shared_bias": -0.0005057053375417368, + "coverage68": 0.9606986899563319, + "coverage95": 1.0, + "coverage95_posterior": 0.33624454148471616, + "median_sd": 0.003441889352847669, + "median_halfwidth95": 0.006745979223564729, + "bias": -0.0005057053375417368, + "rmse": 0.0019054177333005435, + "max_abs_err": 0.006649956078173809, + "tau": 0.0005128354352708105, + "s": 13.11032605909315, + "corr_length_days": 13.067686709123112, + "n_eff": 22.48900597807053, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.00656222777074793, + "prior_weight_s2": 4.388575012182015e-14, + "prior_weight_lambda": 5.956650514035362e-06 + }, + { + "seed": 2028, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7936681222707423, + "member_coverage95": 0.9537845705967977, + "member_rmse": 0.003408379375292362, + "shared_bias": -0.0003120017052991917, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.37554585152838427, + "median_sd": 0.0032927359731278767, + "median_halfwidth95": 0.006453643968835606, + "bias": -0.0003120017052991917, + "rmse": 0.0013864848394335716, + "max_abs_err": 0.0039772984506549315, + "tau": 0.0006291645107343753, + "s": 12.508800180266105, + "corr_length_days": 21.781858652312767, + "n_eff": 16.749752680645493, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.004148992129991595, + "prior_weight_s2": 4.7870163217424616e-14, + "prior_weight_lambda": 2.2640525057488166e-05 + }, + { + "seed": 2029, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7827510917030568, + "member_coverage95": 0.9497816593886463, + "member_rmse": 0.0031582756865410878, + "shared_bias": -0.00033415302062853996, + "coverage68": 0.9650655021834061, + "coverage95": 1.0, + "coverage95_posterior": 0.27074235807860264, + "median_sd": 0.0030820004119236598, + "median_halfwidth95": 0.006040609855355544, + "bias": -0.00033415302062853996, + "rmse": 0.0016354073041144669, + "max_abs_err": 0.004331079378291691, + "tau": 0.00032684669785598507, + "s": 11.838434652641125, + "corr_length_days": 15.774516207124602, + "n_eff": 29.99063780240167, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.019560908398880524, + "prior_weight_s2": 5.351695246707482e-14, + "prior_weight_lambda": 1.6558860408651478e-05 + }, + { + "seed": 2030, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.799490538573508, + "member_coverage95": 0.9516011644832606, + "member_rmse": 0.003528915672138741, + "shared_bias": -0.0004829513183012654, + "coverage68": 0.9868995633187773, + "coverage95": 1.0, + "coverage95_posterior": 0.4017467248908297, + "median_sd": 0.003387333082674542, + "median_halfwidth95": 0.006639050898051126, + "bias": -0.0004829513183012654, + "rmse": 0.0014879038440738608, + "max_abs_err": 0.005025239608323855, + "tau": 0.0006110559027782086, + "s": 12.690472550612649, + "corr_length_days": 44.66612074895079, + "n_eff": 20.67464629303503, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.00437922469012294, + "prior_weight_s2": 4.6696364274144314e-14, + "prior_weight_lambda": 7.747115740739362e-06 + }, + { + "seed": 2031, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8016739446870451, + "member_coverage95": 0.9508733624454149, + "member_rmse": 0.0036889966747249677, + "shared_bias": -0.0003227964385775772, + "coverage68": 0.9868995633187773, + "coverage95": 1.0, + "coverage95_posterior": 0.3056768558951965, + "median_sd": 0.003356587909416754, + "median_halfwidth95": 0.006578791465292099, + "bias": -0.0003227964385775772, + "rmse": 0.0015265089427283559, + "max_abs_err": 0.003962869811192157, + "tau": 0.000563560138563541, + "s": 12.864489248942451, + "corr_length_days": 26.734196680059704, + "n_eff": 19.398515964002595, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.005344596853494756, + "prior_weight_s2": 4.520094164680037e-14, + "prior_weight_lambda": 1.9861271166961273e-05 + }, + { + "seed": 2032, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7831149927219796, + "member_coverage95": 0.9428675400291121, + "member_rmse": 0.0036061050324448594, + "shared_bias": -0.0005348100494321961, + "coverage68": 0.9475982532751092, + "coverage95": 1.0, + "coverage95_posterior": 0.3406113537117904, + "median_sd": 0.0033656671405621146, + "median_halfwidth95": 0.0065965864314846846, + "bias": -0.0005348100494321961, + "rmse": 0.0018445418702996198, + "max_abs_err": 0.005511545564153267, + "tau": 0.00048121161579416154, + "s": 12.913097640794886, + "corr_length_days": 8.992978884696502, + "n_eff": 26.793299217978156, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.007559962259275196, + "prior_weight_s2": 4.4970876905598735e-14, + "prior_weight_lambda": 1.8773518067248275e-05 + }, + { + "seed": 2033, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8118631732168851, + "member_coverage95": 0.9541484716157205, + "member_rmse": 0.003567822603430278, + "shared_bias": -0.0004510312155347323, + "coverage68": 0.9388646288209607, + "coverage95": 1.0, + "coverage95_posterior": 0.19213973799126638, + "median_sd": 0.003527248020287121, + "median_halfwidth95": 0.006913279138834027, + "bias": -0.0004510312155347323, + "rmse": 0.0017449753162054656, + "max_abs_err": 0.004417945589232241, + "tau": 0.00023385485583243744, + "s": 13.393532757512515, + "corr_length_days": 8.41162531170441, + "n_eff": 49.19545569158238, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0451482484492126, + "prior_weight_s2": 4.1355106110324865e-14, + "prior_weight_lambda": 5.989242795052009e-05 + }, + { + "seed": 2034, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8031295487627366, + "member_coverage95": 0.9548762736535662, + "member_rmse": 0.00350098548160151, + "shared_bias": -0.0005907341097887957, + "coverage68": 0.9650655021834061, + "coverage95": 1.0, + "coverage95_posterior": 0.36681222707423583, + "median_sd": 0.0031784933535280104, + "median_halfwidth95": 0.0062297325471541735, + "bias": -0.0005907341097887957, + "rmse": 0.0015216027704631943, + "max_abs_err": 0.00418587823294053, + "tau": 0.0006342016058798765, + "s": 12.162229104794752, + "corr_length_days": 21.623995680905118, + "n_eff": 17.381097907907673, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.004123290041976152, + "prior_weight_s2": 5.064068067812487e-14, + "prior_weight_lambda": 2.6676942552139423e-05 + }, + { + "seed": 2035, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7907569141193596, + "member_coverage95": 0.9559679767103348, + "member_rmse": 0.003346522765368929, + "shared_bias": -0.0002304991128511139, + "coverage68": 0.9781659388646288, + "coverage95": 1.0, + "coverage95_posterior": 0.3537117903930131, + "median_sd": 0.0031171995568464723, + "median_halfwidth95": 0.006109598912235039, + "bias": -0.0002304991128511139, + "rmse": 0.0014898672065077933, + "max_abs_err": 0.004026143314131514, + "tau": 9.44028637988171e-05, + "s": 12.278708304050207, + "corr_length_days": 24.251645784190302, + "n_eff": 44.241940825628866, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.4656066157869581, + "prior_weight_s2": 5.0002391498099334e-14, + "prior_weight_lambda": 5.711440300457172e-06 + }, + { + "seed": 2036, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7554585152838428, + "member_coverage95": 0.9344978165938864, + "member_rmse": 0.003444269355746087, + "shared_bias": -0.0006180840309388737, + "coverage68": 0.9301310043668122, + "coverage95": 1.0, + "coverage95_posterior": 0.2925764192139738, + "median_sd": 0.0031753119906663173, + "median_halfwidth95": 0.006223497190474318, + "bias": -0.0006180840309388737, + "rmse": 0.0017615485481958983, + "max_abs_err": 0.0038351935249840074, + "tau": 0.0006709095640339235, + "s": 11.919534031016486, + "corr_length_days": 47.30351273057381, + "n_eff": 15.154512939203615, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0037883018535001573, + "prior_weight_s2": 5.293410646801685e-14, + "prior_weight_lambda": 1.0110581910612947e-05 + }, + { + "seed": 2037, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8071324599708879, + "member_coverage95": 0.9530567685589519, + "member_rmse": 0.0035096622800384523, + "shared_bias": -0.0004771455618084437, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.48034934497816595, + "median_sd": 0.003317021470536203, + "median_halfwidth95": 0.006501242669478019, + "bias": -0.0004771455618084437, + "rmse": 0.0013810020859702833, + "max_abs_err": 0.0029615324579851067, + "tau": 0.0005827716747172273, + "s": 12.735941506581595, + "corr_length_days": 29.780894493457016, + "n_eff": 20.15337721899663, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.004904736463088617, + "prior_weight_s2": 4.60663257242582e-14, + "prior_weight_lambda": 3.232973128337059e-05 + }, + { + "seed": 2038, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7820232896652111, + "member_coverage95": 0.9439592430858806, + "member_rmse": 0.003519721566693248, + "shared_bias": -0.0002781228123182647, + "coverage68": 0.9519650655021834, + "coverage95": 1.0, + "coverage95_posterior": 0.31877729257641924, + "median_sd": 0.003297825785959427, + "median_halfwidth95": 0.006463619818752183, + "bias": -0.0002781228123182647, + "rmse": 0.00170558272226257, + "max_abs_err": 0.0043745429647896635, + "tau": 0.0006131746882546409, + "s": 12.743335813442444, + "corr_length_days": 25.94184512443995, + "n_eff": 17.20434527225529, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.004608067391230538, + "prior_weight_s2": 4.611287337700311e-14, + "prior_weight_lambda": 1.8479907353962595e-05 + }, + { + "seed": 2039, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7809315866084425, + "member_coverage95": 0.9457787481804949, + "member_rmse": 0.0034892008293320705, + "shared_bias": -0.0006382322539513957, + "coverage68": 0.9563318777292577, + "coverage95": 1.0, + "coverage95_posterior": 0.3799126637554585, + "median_sd": 0.0031516195360583523, + "median_halfwidth95": 0.006177060832371072, + "bias": -0.0006382322539513957, + "rmse": 0.0016925843191479225, + "max_abs_err": 0.0043766297508959105, + "tau": 0.00046968772541225977, + "s": 11.794144901753114, + "corr_length_days": 57.46542513340735, + "n_eff": 26.852053823239107, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.007939843500332966, + "prior_weight_s2": 5.3854027420738736e-14, + "prior_weight_lambda": 1.3733889485431181e-05 + }, + { + "seed": 2040, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7856622998544396, + "member_coverage95": 0.9465065502183406, + "member_rmse": 0.0033756362400450403, + "shared_bias": -0.0003747463673816702, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.3406113537117904, + "median_sd": 0.003236702159473473, + "median_halfwidth95": 0.006343819711290267, + "bias": -0.0003747463673816702, + "rmse": 0.0015037031670458373, + "max_abs_err": 0.0032138322485722043, + "tau": 0.0005994395312783411, + "s": 12.19936138892051, + "corr_length_days": 33.049260832333374, + "n_eff": 18.21822680667751, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.004360882532987878, + "prior_weight_s2": 5.021803695487863e-14, + "prior_weight_lambda": 3.695453136231024e-05 + }, + { + "seed": 2041, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7874818049490538, + "member_coverage95": 0.9523289665211062, + "member_rmse": 0.003494230597333853, + "shared_bias": -0.00031941527652970574, + "coverage68": 0.982532751091703, + "coverage95": 1.0, + "coverage95_posterior": 0.37554585152838427, + "median_sd": 0.0033108716207387334, + "median_halfwidth95": 0.006489189185269571, + "bias": -0.00031941527652970574, + "rmse": 0.0015355386451308811, + "max_abs_err": 0.003945158468520071, + "tau": 0.00023917444297345426, + "s": 13.046257252968488, + "corr_length_days": 14.649441314787083, + "n_eff": 35.94886755367829, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.04693637445275741, + "prior_weight_s2": 4.422139904623757e-14, + "prior_weight_lambda": 7.864369894142137e-06 + }, + { + "seed": 2042, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7925764192139738, + "member_coverage95": 0.9541484716157205, + "member_rmse": 0.0034212289021256954, + "shared_bias": -0.0005546399327666906, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.34497816593886466, + "median_sd": 0.00326251999446256, + "median_halfwidth95": 0.006394421738426817, + "bias": -0.0005546399327666906, + "rmse": 0.0015812143767779793, + "max_abs_err": 0.0035851694275647, + "tau": 0.0005202501715659866, + "s": 12.548503456407877, + "corr_length_days": 52.390622308082776, + "n_eff": 25.55341092563344, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.006101152072341209, + "prior_weight_s2": 4.774824331728766e-14, + "prior_weight_lambda": 1.282865453943318e-05 + }, + { + "seed": 2043, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8056768558951966, + "member_coverage95": 0.9483260553129549, + "member_rmse": 0.0035020859040308995, + "shared_bias": -0.0003396866516481081, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.22707423580786026, + "median_sd": 0.0033686456366915046, + "median_halfwidth95": 0.006602424176672428, + "bias": -0.0003396866516481081, + "rmse": 0.0014561714524181128, + "max_abs_err": 0.0029056871721179676, + "tau": 0.0002745553781680899, + "s": 13.015151990688997, + "corr_length_days": 11.703344876710766, + "n_eff": 38.362553755738354, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.032735697758712615, + "prior_weight_s2": 4.357189117262139e-14, + "prior_weight_lambda": 0.0013379072593023443 + }, + { + "seed": 2044, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8024017467248908, + "member_coverage95": 0.9530567685589519, + "member_rmse": 0.0037173768802340502, + "shared_bias": -0.000626264202896733, + "coverage68": 0.9781659388646288, + "coverage95": 1.0, + "coverage95_posterior": 0.3624454148471616, + "median_sd": 0.003501754618597988, + "median_halfwidth95": 0.006863312989285787, + "bias": -0.000626264202896733, + "rmse": 0.0017149734737840195, + "max_abs_err": 0.004416178717628548, + "tau": 0.0003550091733437474, + "s": 13.59937656083446, + "corr_length_days": 76.32187877187712, + "n_eff": 41.872519688711826, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.015542676380369606, + "prior_weight_s2": 4.0577548458446744e-14, + "prior_weight_lambda": 1.6297028477203404e-05 + }, + { + "seed": 2045, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7991266375545851, + "member_coverage95": 0.9454148471615721, + "member_rmse": 0.0032868202531281033, + "shared_bias": -0.0002864303316870319, + "coverage68": 0.9781659388646288, + "coverage95": 1.0, + "coverage95_posterior": 0.39737991266375544, + "median_sd": 0.0031556152811508774, + "median_halfwidth95": 0.006184892348905598, + "bias": -0.0002864303316870319, + "rmse": 0.001459136117054009, + "max_abs_err": 0.0048802265500255725, + "tau": 0.000275349381270578, + "s": 12.307466133406654, + "corr_length_days": 19.009964136353165, + "n_eff": 32.922938316162856, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.027531619067926127, + "prior_weight_s2": 4.9873889202817754e-14, + "prior_weight_lambda": 4.437158885390363e-06 + }, + { + "seed": 2046, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7852983988355168, + "member_coverage95": 0.9461426491994177, + "member_rmse": 0.003387174087198148, + "shared_bias": -0.0004414406261098983, + "coverage68": 0.9781659388646288, + "coverage95": 1.0, + "coverage95_posterior": 0.3056768558951965, + "median_sd": 0.003150538719554501, + "median_halfwidth95": 0.006174942470932919, + "bias": -0.0004414406261098983, + "rmse": 0.0016055234705466134, + "max_abs_err": 0.004129020614938324, + "tau": 0.0003121641623270411, + "s": 12.005106082452771, + "corr_length_days": 53.19641068343788, + "n_eff": 39.978417322187, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.021088032819103483, + "prior_weight_s2": 5.1999130208182474e-14, + "prior_weight_lambda": 1.5725607650998725e-05 + }, + { + "seed": 2047, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7878457059679768, + "member_coverage95": 0.9439592430858806, + "member_rmse": 0.003338952509042327, + "shared_bias": -0.0005962513196427733, + "coverage68": 0.9694323144104804, + "coverage95": 1.0, + "coverage95_posterior": 0.3624454148471616, + "median_sd": 0.0031166419435916526, + "median_halfwidth95": 0.00610850601032967, + "bias": -0.0005962513196427733, + "rmse": 0.0015787708109795196, + "max_abs_err": 0.004026755777476895, + "tau": 0.0004754246415863049, + "s": 11.986700253477782, + "corr_length_days": 44.71507823860013, + "n_eff": 24.09038708159028, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.007519935372098153, + "prior_weight_s2": 5.251566392338631e-14, + "prior_weight_lambda": 1.0261951224722375e-05 + }, + { + "seed": 2048, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7834788937409025, + "member_coverage95": 0.9490538573508006, + "member_rmse": 0.003490613365790859, + "shared_bias": -0.000252970778136273, + "coverage68": 0.982532751091703, + "coverage95": 1.0, + "coverage95_posterior": 0.28820960698689957, + "median_sd": 0.0033625081556920753, + "median_halfwidth95": 0.006590394934862863, + "bias": -0.000252970778136273, + "rmse": 0.001684397454877129, + "max_abs_err": 0.0038278799207773365, + "tau": 0.000175383515897599, + "s": 13.176645618254662, + "corr_length_days": 28.448181241315833, + "n_eff": 38.97561988395585, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.10851171421799695, + "prior_weight_s2": 4.3121122312271e-14, + "prior_weight_lambda": 1.4893251111204519e-05 + }, + { + "seed": 2049, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8114992721979621, + "member_coverage95": 0.9526928675400291, + "member_rmse": 0.003740957621308449, + "shared_bias": -0.00027568722804788634, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.36681222707423583, + "median_sd": 0.0035208786933373973, + "median_halfwidth95": 0.006900795487308339, + "bias": -0.00027568722804788634, + "rmse": 0.0015924684381256402, + "max_abs_err": 0.003917521120255336, + "tau": 0.00037942114184406537, + "s": 13.591170134183388, + "corr_length_days": 24.97302694566039, + "n_eff": 30.119116658728238, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.014993214267962343, + "prior_weight_s2": 4.069636837470782e-14, + "prior_weight_lambda": 1.1518527219191683e-05 + }, + { + "seed": 2050, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7976710334788938, + "member_coverage95": 0.9454148471615721, + "member_rmse": 0.0037773834412260965, + "shared_bias": -0.000520788603021855, + "coverage68": 0.9781659388646288, + "coverage95": 1.0, + "coverage95_posterior": 0.37554585152838427, + "median_sd": 0.003354868663845482, + "median_halfwidth95": 0.006575421805865247, + "bias": -0.000520788603021855, + "rmse": 0.0016440528082526159, + "max_abs_err": 0.0045600772553219164, + "tau": 0.00046370285423964335, + "s": 13.0204162178502, + "corr_length_days": 20.120182617383904, + "n_eff": 24.85713769764493, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.00808889038314626, + "prior_weight_s2": 4.410816808400357e-14, + "prior_weight_lambda": 1.5211572164313187e-05 + }, + { + "seed": 2051, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7852983988355168, + "member_coverage95": 0.9475982532751092, + "member_rmse": 0.0035899858052225037, + "shared_bias": -0.0006968704757309748, + "coverage68": 0.9519650655021834, + "coverage95": 1.0, + "coverage95_posterior": 0.37117903930131, + "median_sd": 0.0032878087654389233, + "median_halfwidth95": 0.006443986819144734, + "bias": -0.0006968704757309748, + "rmse": 0.001723388130847832, + "max_abs_err": 0.004300716790957138, + "tau": 0.0005166239543812237, + "s": 12.744167783793678, + "corr_length_days": 24.753123547103193, + "n_eff": 20.47640766088566, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.006135794315765646, + "prior_weight_s2": 4.633575143422094e-14, + "prior_weight_lambda": 8.258206830593339e-06 + }, + { + "seed": 2052, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8180494905385735, + "member_coverage95": 0.9592430858806404, + "member_rmse": 0.003783021006240786, + "shared_bias": -0.0005477305839690755, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.37117903930131, + "median_sd": 0.003750463532323966, + "median_halfwidth95": 0.00735077350666781, + "bias": -0.0005477305839690755, + "rmse": 0.0017667347472700037, + "max_abs_err": 0.00400061778131884, + "tau": 0.0004922586567998274, + "s": 14.466961783321215, + "corr_length_days": 40.379214909485476, + "n_eff": 27.17920583642431, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.007115106790347561, + "prior_weight_s2": 3.588627700889592e-14, + "prior_weight_lambda": 9.510029054093758e-06 + }, + { + "seed": 2053, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7907569141193596, + "member_coverage95": 0.9512372634643377, + "member_rmse": 0.003194849233604442, + "shared_bias": -0.00042112736933578253, + "coverage68": 0.9781659388646288, + "coverage95": 1.0, + "coverage95_posterior": 0.22707423580786026, + "median_sd": 0.003141791516052823, + "median_halfwidth95": 0.0061577982669689555, + "bias": -0.00042112736933578253, + "rmse": 0.0016597485300180984, + "max_abs_err": 0.004079000506156647, + "tau": 0.00023614901183051414, + "s": 12.16559819633374, + "corr_length_days": 18.963542220378443, + "n_eff": 33.367012545713784, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03974349362429182, + "prior_weight_s2": 5.075142805172551e-14, + "prior_weight_lambda": 1.240935260377425e-05 + }, + { + "seed": 2054, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8180494905385735, + "member_coverage95": 0.9541484716157205, + "member_rmse": 0.003263620598212532, + "shared_bias": -0.0005215459639321453, + "coverage68": 0.982532751091703, + "coverage95": 1.0, + "coverage95_posterior": 0.33624454148471616, + "median_sd": 0.0032296772904331283, + "median_halfwidth95": 0.006330051220866476, + "bias": -0.0005215459639321453, + "rmse": 0.0015022277601686623, + "max_abs_err": 0.00345463906274938, + "tau": 0.00048787824194240407, + "s": 12.383433388264597, + "corr_length_days": 6.93577720958979, + "n_eff": 26.380573259222434, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.007119469046302798, + "prior_weight_s2": 4.863879174325793e-14, + "prior_weight_lambda": 3.5534462415842314e-05 + }, + { + "seed": 2055, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8009461426491994, + "member_coverage95": 0.9497816593886463, + "member_rmse": 0.003570694187502728, + "shared_bias": -0.0006015222110392017, + "coverage68": 0.9650655021834061, + "coverage95": 1.0, + "coverage95_posterior": 0.3406113537117904, + "median_sd": 0.003191102554738613, + "median_halfwidth95": 0.006254446127595711, + "bias": -0.0006015222110392017, + "rmse": 0.0017184321699729318, + "max_abs_err": 0.005728695446956321, + "tau": 0.000501019816731267, + "s": 12.77017740816939, + "corr_length_days": 35.1143054623147, + "n_eff": 21.362898916375272, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.006762109235735633, + "prior_weight_s2": 4.611899403889877e-14, + "prior_weight_lambda": 9.084405688224992e-06 + }, + { + "seed": 2056, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7860262008733624, + "member_coverage95": 0.9454148471615721, + "member_rmse": 0.003446735901511639, + "shared_bias": -0.0005623044768177683, + "coverage68": 0.9126637554585153, + "coverage95": 1.0, + "coverage95_posterior": 0.40611353711790393, + "median_sd": 0.0031731176043348027, + "median_halfwidth95": 0.006219196272262457, + "bias": -0.0005623044768177683, + "rmse": 0.0017318300414482077, + "max_abs_err": 0.00532974965976602, + "tau": 0.00046051263841104516, + "s": 12.263273856430787, + "corr_length_days": 10.273780522694834, + "n_eff": 25.482098481947226, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.008561295630976573, + "prior_weight_s2": 4.996866625883768e-14, + "prior_weight_lambda": 1.2594690506489291e-05 + }, + { + "seed": 2057, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7849344978165939, + "member_coverage95": 0.9454148471615721, + "member_rmse": 0.003383706284548316, + "shared_bias": -0.0002225845708931925, + "coverage68": 0.9781659388646288, + "coverage95": 1.0, + "coverage95_posterior": 0.38427947598253276, + "median_sd": 0.0031377546428413964, + "median_halfwidth95": 0.0061498861408019944, + "bias": -0.0002225845708931925, + "rmse": 0.0015587463085603567, + "max_abs_err": 0.004234546859751122, + "tau": 0.0002607549620430578, + "s": 12.306207773786493, + "corr_length_days": 51.14902283865199, + "n_eff": 36.954597728087506, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03381281819419532, + "prior_weight_s2": 4.988340353173631e-14, + "prior_weight_lambda": 4.795290248187061e-06 + }, + { + "seed": 2058, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7969432314410481, + "member_coverage95": 0.9592430858806404, + "member_rmse": 0.0037698287881579515, + "shared_bias": -0.00038974350974134436, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.26200873362445415, + "median_sd": 0.0035417269905984173, + "median_halfwidth95": 0.006941657399401236, + "bias": -0.00038974350974134436, + "rmse": 0.0016477746329290463, + "max_abs_err": 0.0035078833230097143, + "tau": 0.0006583421693325191, + "s": 13.588919196102204, + "corr_length_days": 16.075783481613577, + "n_eff": 17.703932974841965, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.003930711951918406, + "prior_weight_s2": 4.022923942926477e-14, + "prior_weight_lambda": 0.00010312464247924431 + }, + { + "seed": 2059, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8049490538573508, + "member_coverage95": 0.9537845705967977, + "member_rmse": 0.0034329874110491047, + "shared_bias": -0.0002472143805642866, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.32751091703056767, + "median_sd": 0.0033009860044319497, + "median_halfwidth95": 0.006469813733190462, + "bias": -0.0002472143805642866, + "rmse": 0.0015582523255127597, + "max_abs_err": 0.0034024738869675736, + "tau": 0.0003548847405267604, + "s": 12.905102755837852, + "corr_length_days": 45.95447403966145, + "n_eff": 35.00572768330863, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01538910324831861, + "prior_weight_s2": 4.482649798619501e-14, + "prior_weight_lambda": 1.7771587423579573e-05 + }, + { + "seed": 2060, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7852983988355168, + "member_coverage95": 0.9526928675400291, + "member_rmse": 0.0034609208946917926, + "shared_bias": -0.000647198459659434, + "coverage68": 0.9737991266375546, + "coverage95": 1.0, + "coverage95_posterior": 0.35807860262008734, + "median_sd": 0.003297474141599876, + "median_halfwidth95": 0.006462930608466659, + "bias": -0.000647198459659434, + "rmse": 0.0017192556930559959, + "max_abs_err": 0.005650517612730585, + "tau": 0.0005800648000906409, + "s": 12.606376668476557, + "corr_length_days": 38.80264113110669, + "n_eff": 18.171965696178916, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0048855920454131865, + "prior_weight_s2": 4.718197275567371e-14, + "prior_weight_lambda": 1.0792810232824275e-05 + }, + { + "seed": 2061, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7671033478893741, + "member_coverage95": 0.9352256186317321, + "member_rmse": 0.0032798662901801128, + "shared_bias": -0.0005026719842650807, + "coverage68": 0.9475982532751092, + "coverage95": 1.0, + "coverage95_posterior": 0.2794759825327511, + "median_sd": 0.0031048057987782527, + "median_halfwidth95": 0.006085307592596619, + "bias": -0.0005026719842650807, + "rmse": 0.00175827629855394, + "max_abs_err": 0.004951519091780979, + "tau": 0.00043091368073113574, + "s": 11.802089236322564, + "corr_length_days": 27.44366525052453, + "n_eff": 23.287105684466653, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.009136096833878369, + "prior_weight_s2": 5.3841373744842334e-14, + "prior_weight_lambda": 1.3363585541314358e-05 + }, + { + "seed": 2062, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.772197962154294, + "member_coverage95": 0.9421397379912664, + "member_rmse": 0.0033841068018184966, + "shared_bias": -0.0005020175674452788, + "coverage68": 0.9563318777292577, + "coverage95": 1.0, + "coverage95_posterior": 0.32751091703056767, + "median_sd": 0.0031200836125989864, + "median_halfwidth95": 0.00611525155768396, + "bias": -0.0005020175674452788, + "rmse": 0.001744192047874437, + "max_abs_err": 0.004168198388482371, + "tau": 0.00046494334441018917, + "s": 11.982275068007953, + "corr_length_days": 34.16858708795686, + "n_eff": 22.678408030534534, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.007903395383735988, + "prior_weight_s2": 5.277998384960181e-14, + "prior_weight_lambda": 4.169378204867687e-06 + }, + { + "seed": 2063, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7867540029112081, + "member_coverage95": 0.9494177583697234, + "member_rmse": 0.0034106657886089214, + "shared_bias": -0.00033417939721026445, + "coverage68": 0.9694323144104804, + "coverage95": 1.0, + "coverage95_posterior": 0.36681222707423583, + "median_sd": 0.0031933901045932715, + "median_halfwidth95": 0.006258929642959047, + "bias": -0.00033417939721026445, + "rmse": 0.0015963358763465497, + "max_abs_err": 0.004427522860171281, + "tau": 0.0004808585479769342, + "s": 12.496139723942338, + "corr_length_days": 26.082530070188152, + "n_eff": 21.501514843682166, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.007638766212392281, + "prior_weight_s2": 4.847488559941791e-14, + "prior_weight_lambda": 3.450825172505368e-06 + }, + { + "seed": 2064, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7929403202328966, + "member_coverage95": 0.9486899563318777, + "member_rmse": 0.003465465527237859, + "shared_bias": -0.00048355877813706735, + "coverage68": 0.9475982532751092, + "coverage95": 1.0, + "coverage95_posterior": 0.48034934497816595, + "median_sd": 0.0032491741164553593, + "median_halfwidth95": 0.006368264297984312, + "bias": -0.00048355877813706735, + "rmse": 0.0015981954348611338, + "max_abs_err": 0.0038178091451584522, + "tau": 0.0005049636578729387, + "s": 12.515195850270137, + "corr_length_days": 36.90021839175438, + "n_eff": 23.405883203149084, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0069685723996455355, + "prior_weight_s2": 4.798373968446886e-14, + "prior_weight_lambda": 8.773714206581075e-06 + }, + { + "seed": 2065, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8100436681222707, + "member_coverage95": 0.9501455604075691, + "member_rmse": 0.003510723134484407, + "shared_bias": -0.00033578087458169427, + "coverage68": 0.9868995633187773, + "coverage95": 1.0, + "coverage95_posterior": 0.4192139737991266, + "median_sd": 0.0033468092752644346, + "median_halfwidth95": 0.006559625694384383, + "bias": -0.00033578087458169427, + "rmse": 0.001465486506328183, + "max_abs_err": 0.0036239111118832467, + "tau": 0.0005214355223523422, + "s": 12.93926953319757, + "corr_length_days": 53.62296083574817, + "n_eff": 24.69571205558756, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.006316503860362193, + "prior_weight_s2": 4.514490011955215e-14, + "prior_weight_lambda": 4.3975958395856435e-06 + }, + { + "seed": 2066, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.784570596797671, + "member_coverage95": 0.9403202328966521, + "member_rmse": 0.003579435680399226, + "shared_bias": -0.0005395721463679623, + "coverage68": 0.982532751091703, + "coverage95": 1.0, + "coverage95_posterior": 0.2925764192139738, + "median_sd": 0.003390712815779901, + "median_halfwidth95": 0.006645675053267238, + "bias": -0.0005395721463679623, + "rmse": 0.0016942890957254303, + "max_abs_err": 0.003824506974512408, + "tau": 0.0003612313629732467, + "s": 13.022383228657505, + "corr_length_days": 29.63351779520283, + "n_eff": 30.55073922637092, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.014328490274873616, + "prior_weight_s2": 4.4250067885057294e-14, + "prior_weight_lambda": 1.9176363139675757e-05 + }, + { + "seed": 2067, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7882096069868996, + "member_coverage95": 0.9435953420669578, + "member_rmse": 0.0034406608411096345, + "shared_bias": -0.0005172713997886477, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.25327510917030566, + "median_sd": 0.003182933592661414, + "median_halfwidth95": 0.0062384352560070355, + "bias": -0.0005172713997886477, + "rmse": 0.0016201903252141422, + "max_abs_err": 0.003588793109080991, + "tau": 0.00037004054315845607, + "s": 12.206528872776541, + "corr_length_days": 11.329967437456022, + "n_eff": 29.913144400607933, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.013494898512891675, + "prior_weight_s2": 4.998723632100741e-14, + "prior_weight_lambda": 6.918547102408494e-05 + }, + { + "seed": 2068, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7885735080058224, + "member_coverage95": 0.9483260553129549, + "member_rmse": 0.003565657451387393, + "shared_bias": -0.0006096540923456832, + "coverage68": 0.9519650655021834, + "coverage95": 1.0, + "coverage95_posterior": 0.3799126637554585, + "median_sd": 0.0032726240218993144, + "median_halfwidth95": 0.006414225268457868, + "bias": -0.0006096540923456832, + "rmse": 0.00168522291767406, + "max_abs_err": 0.004329634471205152, + "tau": 0.0004256281467482572, + "s": 12.390784788349627, + "corr_length_days": 13.246023423802692, + "n_eff": 27.59157009935204, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.009810713156186417, + "prior_weight_s2": 4.9111060916802384e-14, + "prior_weight_lambda": 5.302920344601459e-06 + }, + { + "seed": 2069, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7827510917030568, + "member_coverage95": 0.9490538573508006, + "member_rmse": 0.003422172189710564, + "shared_bias": -0.0004751939464881927, + "coverage68": 0.982532751091703, + "coverage95": 1.0, + "coverage95_posterior": 0.28820960698689957, + "median_sd": 0.003222061910581253, + "median_halfwidth95": 0.006315125350510474, + "bias": -0.0004751939464881927, + "rmse": 0.001582569473564538, + "max_abs_err": 0.003502804748774403, + "tau": 0.0005490470331955627, + "s": 12.343999043895428, + "corr_length_days": 48.001478404534524, + "n_eff": 21.636474701169227, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.005864484175255999, + "prior_weight_s2": 4.90967082628733e-14, + "prior_weight_lambda": 3.126025779387339e-05 + }, + { + "seed": 2070, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8140465793304221, + "member_coverage95": 0.9556040756914119, + "member_rmse": 0.0038980182526486364, + "shared_bias": -0.0007407842184590443, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.3799126637554585, + "median_sd": 0.0035830911931738246, + "median_halfwidth95": 0.007022729747337742, + "bias": -0.0007407842184590443, + "rmse": 0.0016827797876013979, + "max_abs_err": 0.004151070294058369, + "tau": 0.0008319730886296575, + "s": 13.572998107105327, + "corr_length_days": 40.99206986389119, + "n_eff": 14.014621195061919, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.002307272370809221, + "prior_weight_s2": 4.0494448853667836e-14, + "prior_weight_lambda": 5.3835978408191185e-05 + }, + { + "seed": 2071, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8184133915574964, + "member_coverage95": 0.9574235807860262, + "member_rmse": 0.0038447007512469487, + "shared_bias": -0.00029420065937816844, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.44541484716157204, + "median_sd": 0.0035746817027241815, + "median_halfwidth95": 0.007006247448798098, + "bias": -0.00029420065937816844, + "rmse": 0.0015621288716904042, + "max_abs_err": 0.003781774606924235, + "tau": 0.0007629864785095859, + "s": 13.51174987369225, + "corr_length_days": 15.52128144056552, + "n_eff": 14.735188806139815, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.00283151055969084, + "prior_weight_s2": 4.114216977110415e-14, + "prior_weight_lambda": 9.748183080539863e-06 + }, + { + "seed": 2072, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8013100436681223, + "member_coverage95": 0.9486899563318777, + "member_rmse": 0.0036572230560192017, + "shared_bias": -0.0005255137577279699, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.27074235807860264, + "median_sd": 0.00349352135489545, + "median_halfwidth95": 0.0068471760888263065, + "bias": -0.0005255137577279699, + "rmse": 0.0016259463851338654, + "max_abs_err": 0.0036406916170729944, + "tau": 0.00046371544410168106, + "s": 13.44970986483054, + "corr_length_days": 43.80105055249407, + "n_eff": 30.237666903799916, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.00827759626594592, + "prior_weight_s2": 4.145991481258236e-14, + "prior_weight_lambda": 1.1619885352239467e-05 + }, + { + "seed": 2073, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8089519650655022, + "member_coverage95": 0.9512372634643377, + "member_rmse": 0.0035157638404835065, + "shared_bias": -0.0004107923333525304, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.4410480349344978, + "median_sd": 0.003264763934652696, + "median_halfwidth95": 0.006398819780417637, + "bias": -0.0004107923333525304, + "rmse": 0.0013582404239083903, + "max_abs_err": 0.0031827027337634245, + "tau": 0.0005463515675966677, + "s": 12.396065085478813, + "corr_length_days": 38.81420136298979, + "n_eff": 21.760776734475634, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.005555745313697002, + "prior_weight_s2": 4.854417789434081e-14, + "prior_weight_lambda": 4.43818413150816e-05 + }, + { + "seed": 2074, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7936681222707423, + "member_coverage95": 0.9494177583697234, + "member_rmse": 0.003496097422048389, + "shared_bias": -0.0004306838870455863, + "coverage68": 0.9737991266375546, + "coverage95": 1.0, + "coverage95_posterior": 0.37554585152838427, + "median_sd": 0.003313933962207212, + "median_halfwidth95": 0.006495191264303497, + "bias": -0.0004306838870455863, + "rmse": 0.0015064872128182662, + "max_abs_err": 0.004101054107382582, + "tau": 0.00021916876357100672, + "s": 12.930141549577845, + "corr_length_days": 46.399239194376584, + "n_eff": 50.96476287692482, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.05019261024778343, + "prior_weight_s2": 4.481509312696938e-14, + "prior_weight_lambda": 1.6713755301584088e-05 + }, + { + "seed": 2075, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7980349344978166, + "member_coverage95": 0.9530567685589519, + "member_rmse": 0.003185089523777699, + "shared_bias": -0.00030612826157195547, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.31004366812227074, + "median_sd": 0.003146258522944661, + "median_halfwidth95": 0.00616655343966471, + "bias": -0.00030612826157195547, + "rmse": 0.001394843647527455, + "max_abs_err": 0.0033218852162120527, + "tau": 0.0001601797568026302, + "s": 12.018911396375547, + "corr_length_days": 50.44909447932833, + "n_eff": 56.90719588059048, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.11615671701311193, + "prior_weight_s2": 5.193543205327025e-14, + "prior_weight_lambda": 1.3530693131744799e-05 + }, + { + "seed": 2076, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8074963609898108, + "member_coverage95": 0.9439592430858806, + "member_rmse": 0.003645992340537426, + "shared_bias": -0.0004898596547985802, + "coverage68": 0.982532751091703, + "coverage95": 1.0, + "coverage95_posterior": 0.3318777292576419, + "median_sd": 0.003407571178883925, + "median_halfwidth95": 0.006678716838050053, + "bias": -0.0004898596547985802, + "rmse": 0.0015272091896221817, + "max_abs_err": 0.0046608239687978125, + "tau": 0.0004107269670472974, + "s": 13.097672738206318, + "corr_length_days": 35.411676766447336, + "n_eff": 27.41196898058217, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0110580062334274, + "prior_weight_s2": 4.357997095966339e-14, + "prior_weight_lambda": 1.975064098000667e-05 + }, + { + "seed": 2077, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8027656477438136, + "member_coverage95": 0.9552401746724891, + "member_rmse": 0.0034646562276313825, + "shared_bias": -0.00044042332352896665, + "coverage68": 0.9737991266375546, + "coverage95": 1.0, + "coverage95_posterior": 0.3799126637554585, + "median_sd": 0.003194993957223955, + "median_halfwidth95": 0.0062620731363764925, + "bias": -0.00044042332352896665, + "rmse": 0.001438333520226097, + "max_abs_err": 0.0035210713431571396, + "tau": 0.000608739206297366, + "s": 12.138203214163426, + "corr_length_days": 51.569933101934645, + "n_eff": 18.42308193121722, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0044532444222329095, + "prior_weight_s2": 5.0853421147632095e-14, + "prior_weight_lambda": 1.565963000206475e-05 + }, + { + "seed": 2078, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7820232896652111, + "member_coverage95": 0.9494177583697234, + "member_rmse": 0.003282849490889808, + "shared_bias": -0.00046903363265260987, + "coverage68": 0.9694323144104804, + "coverage95": 1.0, + "coverage95_posterior": 0.31004366812227074, + "median_sd": 0.0031899746528965866, + "median_halfwidth95": 0.006252235480589806, + "bias": -0.00046903363265260987, + "rmse": 0.001538467603430137, + "max_abs_err": 0.003563083188162293, + "tau": 0.000500026008573704, + "s": 12.057121346046676, + "corr_length_days": 29.969525525960275, + "n_eff": 22.81939540158314, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.006833833896167746, + "prior_weight_s2": 5.152194031391197e-14, + "prior_weight_lambda": 2.709541967928051e-05 + }, + { + "seed": 2079, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7882096069868996, + "member_coverage95": 0.9516011644832606, + "member_rmse": 0.00345402405460191, + "shared_bias": -0.0003821001954126275, + "coverage68": 0.9737991266375546, + "coverage95": 1.0, + "coverage95_posterior": 0.2794759825327511, + "median_sd": 0.0033266750723082742, + "median_halfwidth95": 0.006520163381421615, + "bias": -0.0003821001954126275, + "rmse": 0.001663133485957587, + "max_abs_err": 0.003830866601573204, + "tau": 0.00024854898604903384, + "s": 12.762508380943927, + "corr_length_days": 26.67976783549714, + "n_eff": 38.14778155666862, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03649559786934928, + "prior_weight_s2": 4.584770682633903e-14, + "prior_weight_lambda": 2.5457034994318726e-05 + }, + { + "seed": 2080, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8089519650655022, + "member_coverage95": 0.9548762736535662, + "member_rmse": 0.003667714101912755, + "shared_bias": -0.0006473918704828463, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.37554585152838427, + "median_sd": 0.003345125793159401, + "median_halfwidth95": 0.006556326130063872, + "bias": -0.0006473918704828463, + "rmse": 0.001545919174784826, + "max_abs_err": 0.0037908018476195972, + "tau": 0.00048742791671933696, + "s": 13.020312686451465, + "corr_length_days": 36.26136033806734, + "n_eff": 24.505624547172687, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.007541760431110814, + "prior_weight_s2": 4.428983752932506e-14, + "prior_weight_lambda": 1.8319924913605816e-05 + }, + { + "seed": 2081, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7998544395924309, + "member_coverage95": 0.9479621542940321, + "member_rmse": 0.0034515840321436534, + "shared_bias": -0.0004985874407233394, + "coverage68": 0.9781659388646288, + "coverage95": 1.0, + "coverage95_posterior": 0.3056768558951965, + "median_sd": 0.0033146646091106765, + "median_halfwidth95": 0.006496623305930998, + "bias": -0.0004985874407233394, + "rmse": 0.001737286775099917, + "max_abs_err": 0.005081734748287211, + "tau": 0.0005930590409122472, + "s": 12.61108548318066, + "corr_length_days": 6.966562535554325, + "n_eff": 21.216083659777134, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.004791821679105894, + "prior_weight_s2": 4.711884490358262e-14, + "prior_weight_lambda": 1.9889469717509387e-05 + }, + { + "seed": 2082, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8013100436681223, + "member_coverage95": 0.9479621542940321, + "member_rmse": 0.0035696053460209263, + "shared_bias": -0.00033461771299157523, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.2576419213973799, + "median_sd": 0.0033819045356915348, + "median_halfwidth95": 0.0066284111413921236, + "bias": -0.00033461771299157523, + "rmse": 0.0015680887681170355, + "max_abs_err": 0.003251034463471582, + "tau": 0.0005888397564262733, + "s": 12.78226310734887, + "corr_length_days": 9.336860609522203, + "n_eff": 20.81855682211303, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.005059158872486174, + "prior_weight_s2": 4.564831845062532e-14, + "prior_weight_lambda": 6.371593200102836e-05 + }, + { + "seed": 2083, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7987627365356623, + "member_coverage95": 0.9588791848617176, + "member_rmse": 0.0035914532954099813, + "shared_bias": -0.0004454797316759471, + "coverage68": 0.9475982532751092, + "coverage95": 1.0, + "coverage95_posterior": 0.34497816593886466, + "median_sd": 0.0033938795243797846, + "median_halfwidth95": 0.0066518816881215, + "bias": -0.0004454797316759471, + "rmse": 0.0016608861940330952, + "max_abs_err": 0.004641823880072685, + "tau": 0.0005508058864150943, + "s": 13.223946583799062, + "corr_length_days": 24.86214173802019, + "n_eff": 19.986685543903505, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.005416049721055996, + "prior_weight_s2": 4.265491688094801e-14, + "prior_weight_lambda": 2.8010273857053613e-05 + }, + { + "seed": 2084, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8013100436681223, + "member_coverage95": 0.9516011644832606, + "member_rmse": 0.003365005042484551, + "shared_bias": -0.0003659369030347022, + "coverage68": 0.9737991266375546, + "coverage95": 1.0, + "coverage95_posterior": 0.3799126637554585, + "median_sd": 0.003172061899754822, + "median_halfwidth95": 0.006217127129291061, + "bias": -0.0003659369030347022, + "rmse": 0.001594946041989768, + "max_abs_err": 0.0037712190245617755, + "tau": 0.0003387315520533558, + "s": 12.346553941480584, + "corr_length_days": 18.566911717031658, + "n_eff": 29.548737702525546, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.017826312627142665, + "prior_weight_s2": 4.935660974196523e-14, + "prior_weight_lambda": 1.2697857573794562e-05 + }, + { + "seed": 2085, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8125909752547307, + "member_coverage95": 0.9548762736535662, + "member_rmse": 0.0035360471293799617, + "shared_bias": -0.00025083179194807713, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.28820960698689957, + "median_sd": 0.0034166408572984005, + "median_halfwidth95": 0.006696493081234003, + "bias": -0.00025083179194807713, + "rmse": 0.001383253681203154, + "max_abs_err": 0.0024563978802242246, + "tau": 9.755036699952722e-05, + "s": 13.517807694815616, + "corr_length_days": 29.31018165602308, + "n_eff": 41.026954495061794, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.4259887478701057, + "prior_weight_s2": 4.0517675598468887e-14, + "prior_weight_lambda": 0.00010065434062802222 + }, + { + "seed": 2086, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8060407569141194, + "member_coverage95": 0.9537845705967977, + "member_rmse": 0.0036132300622931804, + "shared_bias": -0.00039664398278339467, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.3056768558951965, + "median_sd": 0.003392099930180243, + "median_halfwidth95": 0.0066483937475557905, + "bias": -0.00039664398278339467, + "rmse": 0.0015806684136872176, + "max_abs_err": 0.003848572433026192, + "tau": 0.0002878327326906974, + "s": 12.817600778092997, + "corr_length_days": 18.228387445562326, + "n_eff": 36.172218301621214, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.026289123759653938, + "prior_weight_s2": 4.564566075183115e-14, + "prior_weight_lambda": 1.6688477119688756e-05 + }, + { + "seed": 2087, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7878457059679768, + "member_coverage95": 0.9577874818049491, + "member_rmse": 0.0032190661894596962, + "shared_bias": -0.00038378781005190567, + "coverage68": 0.9781659388646288, + "coverage95": 1.0, + "coverage95_posterior": 0.4410480349344978, + "median_sd": 0.003211442486022836, + "median_halfwidth95": 0.006294311660675261, + "bias": -0.00038378781005190567, + "rmse": 0.0015337717000072433, + "max_abs_err": 0.003910873735635193, + "tau": 0.0002611315848164774, + "s": 12.592217972943592, + "corr_length_days": 36.18313689498561, + "n_eff": 31.974224289032467, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03298626298891151, + "prior_weight_s2": 4.7607624229440835e-14, + "prior_weight_lambda": 5.903803066066409e-06 + }, + { + "seed": 2088, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7758369723435226, + "member_coverage95": 0.9432314410480349, + "member_rmse": 0.003357545315003169, + "shared_bias": -0.0003936476215019118, + "coverage68": 0.9737991266375546, + "coverage95": 1.0, + "coverage95_posterior": 0.3537117903930131, + "median_sd": 0.0032510844371584574, + "median_halfwidth95": 0.006372008457790839, + "bias": -0.0003936476215019118, + "rmse": 0.0016313901036289745, + "max_abs_err": 0.004234725173198481, + "tau": 0.0003325223491804961, + "s": 12.462002450555131, + "corr_length_days": 10.161932884366621, + "n_eff": 35.15145509968887, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.018251894724068473, + "prior_weight_s2": 4.823154579088375e-14, + "prior_weight_lambda": 1.7876221163637215e-05 + }, + { + "seed": 2089, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7983988355167394, + "member_coverage95": 0.9574235807860262, + "member_rmse": 0.003457300741482856, + "shared_bias": -0.0004018629277334419, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.314410480349345, + "median_sd": 0.003353955456652493, + "median_halfwidth95": 0.0065736319526424475, + "bias": -0.0004018629277334419, + "rmse": 0.001583684417531949, + "max_abs_err": 0.0035055870035990253, + "tau": 0.0006084436909881889, + "s": 12.576493447409158, + "corr_length_days": 11.460021832722518, + "n_eff": 19.0287094879359, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.004726131116533482, + "prior_weight_s2": 4.71698042152395e-14, + "prior_weight_lambda": 5.4167175319150065e-05 + }, + { + "seed": 2090, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7991266375545851, + "member_coverage95": 0.9545123726346434, + "member_rmse": 0.0035718657764392705, + "shared_bias": -0.0003321430110263053, + "coverage68": 0.9737991266375546, + "coverage95": 1.0, + "coverage95_posterior": 0.3624454148471616, + "median_sd": 0.00337725746239358, + "median_halfwidth95": 0.00661930304502277, + "bias": -0.0003321430110263053, + "rmse": 0.0015923880443027714, + "max_abs_err": 0.003824955033489792, + "tau": 0.000518630918674898, + "s": 13.087631543971886, + "corr_length_days": 32.83114456056884, + "n_eff": 23.144308659082046, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.006149759261107505, + "prior_weight_s2": 4.384872068064164e-14, + "prior_weight_lambda": 1.4018985737601196e-05 + }, + { + "seed": 2091, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8078602620087336, + "member_coverage95": 0.9501455604075691, + "member_rmse": 0.0035642239590426895, + "shared_bias": -0.0004787332083268818, + "coverage68": 0.9737991266375546, + "coverage95": 1.0, + "coverage95_posterior": 0.388646288209607, + "median_sd": 0.003398271261182813, + "median_halfwidth95": 0.0066604893341529105, + "bias": -0.0004787332083268818, + "rmse": 0.0015501000911303509, + "max_abs_err": 0.005075143894132867, + "tau": 0.00044153708909891893, + "s": 13.0469120345752, + "corr_length_days": 26.06530428087378, + "n_eff": 26.7502341838649, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.009394248628964512, + "prior_weight_s2": 4.4280919644286046e-14, + "prior_weight_lambda": 8.06112866661135e-06 + }, + { + "seed": 2092, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7922125181950509, + "member_coverage95": 0.9545123726346434, + "member_rmse": 0.003405955865314902, + "shared_bias": -0.00043402711774857106, + "coverage68": 0.9781659388646288, + "coverage95": 1.0, + "coverage95_posterior": 0.3930131004366812, + "median_sd": 0.0031079238705668364, + "median_halfwidth95": 0.006091418901051659, + "bias": -0.00043402711774857106, + "rmse": 0.001450252562327562, + "max_abs_err": 0.0035455211400268615, + "tau": 0.000437065120924058, + "s": 12.024920022831237, + "corr_length_days": 18.44592136183334, + "n_eff": 23.211656172264217, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.009300376634492631, + "prior_weight_s2": 5.1718951122694104e-14, + "prior_weight_lambda": 3.389876171776109e-05 + }, + { + "seed": 2093, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.784570596797671, + "member_coverage95": 0.9472343522561864, + "member_rmse": 0.003355247622158706, + "shared_bias": -0.00035000015667338146, + "coverage68": 0.982532751091703, + "coverage95": 1.0, + "coverage95_posterior": 0.34497816593886466, + "median_sd": 0.003236151953401351, + "median_halfwidth95": 0.006342741327196325, + "bias": -0.00035000015667338146, + "rmse": 0.0015655495281855028, + "max_abs_err": 0.003683377495615484, + "tau": 0.0002604873651459681, + "s": 12.524999428962674, + "corr_length_days": 32.498463750597956, + "n_eff": 32.13294618043006, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03524123649206082, + "prior_weight_s2": 4.758791066978642e-14, + "prior_weight_lambda": 2.4308354253598595e-05 + }, + { + "seed": 2094, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7983988355167394, + "member_coverage95": 0.950509461426492, + "member_rmse": 0.0035606061715315763, + "shared_bias": -0.0004224494618045815, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.3056768558951965, + "median_sd": 0.003361283199742523, + "median_halfwidth95": 0.006587994065300154, + "bias": -0.0004224494618045815, + "rmse": 0.0015675913205868753, + "max_abs_err": 0.0032349149937110975, + "tau": 0.0005182996644480388, + "s": 12.784756047673643, + "corr_length_days": 38.135304710650985, + "n_eff": 23.224028271113685, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.006400364202760089, + "prior_weight_s2": 4.56385487690507e-14, + "prior_weight_lambda": 5.5160541122792e-05 + }, + { + "seed": 2095, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.779839883551674, + "member_coverage95": 0.9392285298398836, + "member_rmse": 0.003710023253280975, + "shared_bias": -0.0005448288083949104, + "coverage68": 0.9781659388646288, + "coverage95": 1.0, + "coverage95_posterior": 0.3406113537117904, + "median_sd": 0.0033097720138523514, + "median_halfwidth95": 0.00648703399535811, + "bias": -0.0005448288083949104, + "rmse": 0.0017607492897063536, + "max_abs_err": 0.004455468870680365, + "tau": 0.0003524691718220624, + "s": 12.923090052242001, + "corr_length_days": 25.124648533931424, + "n_eff": 28.519445664888874, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01562782772122819, + "prior_weight_s2": 4.50244423775759e-14, + "prior_weight_lambda": 7.181612928043452e-06 + }, + { + "seed": 2096, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7794759825327511, + "member_coverage95": 0.9435953420669578, + "member_rmse": 0.0037147550709408935, + "shared_bias": -0.0005147559062836387, + "coverage68": 0.9650655021834061, + "coverage95": 1.0, + "coverage95_posterior": 0.28820960698689957, + "median_sd": 0.003269108796769456, + "median_halfwidth95": 0.00640733555375145, + "bias": -0.0005147559062836387, + "rmse": 0.001763253322472601, + "max_abs_err": 0.004827633779579315, + "tau": 0.0002521491756362156, + "s": 12.943108593028928, + "corr_length_days": 13.625567839624457, + "n_eff": 38.3967079513318, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0394896724426243, + "prior_weight_s2": 4.469736020688003e-14, + "prior_weight_lambda": 1.484386618654652e-05 + }, + { + "seed": 2097, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8224163027656477, + "member_coverage95": 0.9632459970887919, + "member_rmse": 0.003565537864922996, + "shared_bias": -0.00046551368781998464, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.4890829694323144, + "median_sd": 0.0034800743764906014, + "median_halfwidth95": 0.0068208204952440255, + "bias": -0.00046551368781998464, + "rmse": 0.0014123414625729627, + "max_abs_err": 0.0033686289295658993, + "tau": 0.0006523279249602598, + "s": 13.32649164497945, + "corr_length_days": 8.684629793858257, + "n_eff": 19.338537174216928, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.003928795540090402, + "prior_weight_s2": 4.213130416345377e-14, + "prior_weight_lambda": 1.7395791933224515e-05 + }, + { + "seed": 2098, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7860262008733624, + "member_coverage95": 0.9421397379912664, + "member_rmse": 0.0033091905485385293, + "shared_bias": -0.00035850930168771617, + "coverage68": 0.982532751091703, + "coverage95": 1.0, + "coverage95_posterior": 0.30131004366812225, + "median_sd": 0.003136746009109452, + "median_halfwidth95": 0.006147909254998198, + "bias": -0.00035850930168771617, + "rmse": 0.0015769410910554124, + "max_abs_err": 0.003794641645850995, + "tau": 0.0002447878758706129, + "s": 12.085083537011055, + "corr_length_days": 16.694601472483516, + "n_eff": 35.340170129747186, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0383678377084615, + "prior_weight_s2": 5.16207011539648e-14, + "prior_weight_lambda": 5.399312845470907e-06 + }, + { + "seed": 2099, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7983988355167394, + "member_coverage95": 0.9512372634643377, + "member_rmse": 0.003541087360207766, + "shared_bias": -0.00020476434723038726, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.38427947598253276, + "median_sd": 0.0033568550060317005, + "median_halfwidth95": 0.006579314965041916, + "bias": -0.00020476434723038726, + "rmse": 0.0015874409319693368, + "max_abs_err": 0.0037275743887739926, + "tau": 0.0005468308918658135, + "s": 12.778101225567019, + "corr_length_days": 31.66329544489803, + "n_eff": 21.421437988741282, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.005894242236737799, + "prior_weight_s2": 4.6022640235758775e-14, + "prior_weight_lambda": 9.257221543718962e-06 + }, + { + "seed": 2100, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7852983988355168, + "member_coverage95": 0.9465065502183406, + "member_rmse": 0.003283874220382322, + "shared_bias": -0.0005539147728660807, + "coverage68": 0.9475982532751092, + "coverage95": 1.0, + "coverage95_posterior": 0.37554585152838427, + "median_sd": 0.003126630836604274, + "median_halfwidth95": 0.00612808388103426, + "bias": -0.0005539147728660807, + "rmse": 0.0016523071477302954, + "max_abs_err": 0.0050239065176036855, + "tau": 0.00034657249076780705, + "s": 12.08248031822271, + "corr_length_days": 28.506155852685524, + "n_eff": 28.474740633908464, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.016740034652915077, + "prior_weight_s2": 5.1956616069911135e-14, + "prior_weight_lambda": 4.1324162218336895e-06 + }, + { + "seed": 2101, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7838427947598253, + "member_coverage95": 0.9399563318777293, + "member_rmse": 0.003518378442856905, + "shared_bias": -0.0005647208960173489, + "coverage68": 0.9737991266375546, + "coverage95": 1.0, + "coverage95_posterior": 0.28820960698689957, + "median_sd": 0.003132045902359775, + "median_halfwidth95": 0.0061386972149726745, + "bias": -0.0005647208960173489, + "rmse": 0.001714943668956597, + "max_abs_err": 0.004756144694364108, + "tau": 0.00046983120928391125, + "s": 12.452000584020462, + "corr_length_days": 36.347892212438296, + "n_eff": 24.3336966935492, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.007975633984876329, + "prior_weight_s2": 4.8431917753938623e-14, + "prior_weight_lambda": 1.3416280057496082e-05 + }, + { + "seed": 2102, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7943959243085881, + "member_coverage95": 0.9599708879184862, + "member_rmse": 0.0036448608245588827, + "shared_bias": -0.00041137619742332544, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.31004366812227074, + "median_sd": 0.0034530916411554453, + "median_halfwidth95": 0.006767935305365591, + "bias": -0.00041137619742332544, + "rmse": 0.0014187564908613012, + "max_abs_err": 0.0029493835762984515, + "tau": 0.0003778271576427375, + "s": 13.375761269198595, + "corr_length_days": 8.116010266301958, + "n_eff": 36.36774025756049, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01439120179372265, + "prior_weight_s2": 4.1784176873706454e-14, + "prior_weight_lambda": 7.026431993475778e-05 + }, + { + "seed": 2103, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7685589519650655, + "member_coverage95": 0.9475982532751092, + "member_rmse": 0.003647151913296659, + "shared_bias": -0.0005459491344852263, + "coverage68": 0.9694323144104804, + "coverage95": 1.0, + "coverage95_posterior": 0.2445414847161572, + "median_sd": 0.0033574427931810833, + "median_halfwidth95": 0.006580467006694369, + "bias": -0.0005459491344852263, + "rmse": 0.0017937341202941737, + "max_abs_err": 0.004070942058565879, + "tau": 0.00047320674773248085, + "s": 12.70848747763471, + "corr_length_days": 32.00334101547741, + "n_eff": 25.793481115969005, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.007603195608979719, + "prior_weight_s2": 4.6441102356260136e-14, + "prior_weight_lambda": 1.3671033193603646e-05 + }, + { + "seed": 2104, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7943959243085881, + "member_coverage95": 0.9446870451237264, + "member_rmse": 0.0036607821356263977, + "shared_bias": -0.0004519208585251162, + "coverage68": 0.9694323144104804, + "coverage95": 1.0, + "coverage95_posterior": 0.2925764192139738, + "median_sd": 0.003307192777473596, + "median_halfwidth95": 0.006481978784908259, + "bias": -0.0004519208585251162, + "rmse": 0.0018850003362719365, + "max_abs_err": 0.004026524537969344, + "tau": 0.0006559811883250932, + "s": 12.738722236750776, + "corr_length_days": 12.871402169141266, + "n_eff": 16.54949036405375, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0037890515810734904, + "prior_weight_s2": 4.646344348641805e-14, + "prior_weight_lambda": 8.485507288137948e-06 + }, + { + "seed": 2105, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7951237263464338, + "member_coverage95": 0.9512372634643377, + "member_rmse": 0.0034832354324633307, + "shared_bias": -0.0004759857562771461, + "coverage68": 0.9781659388646288, + "coverage95": 1.0, + "coverage95_posterior": 0.37554585152838427, + "median_sd": 0.0032659982100121123, + "median_halfwidth95": 0.00640123891568818, + "bias": -0.0004759857562771461, + "rmse": 0.0015907002959501678, + "max_abs_err": 0.0037768700415591484, + "tau": 0.00046621840754349414, + "s": 12.70042874618476, + "corr_length_days": 28.805325049529408, + "n_eff": 21.93353625633607, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.008109899108386234, + "prior_weight_s2": 4.645222563886464e-14, + "prior_weight_lambda": 2.330482177204269e-05 + }, + { + "seed": 2106, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7991266375545851, + "member_coverage95": 0.9494177583697234, + "member_rmse": 0.0035377252805754073, + "shared_bias": -0.00048015054606664317, + "coverage68": 0.9388646288209607, + "coverage95": 1.0, + "coverage95_posterior": 0.36681222707423583, + "median_sd": 0.0033079371700421474, + "median_halfwidth95": 0.006483437767544488, + "bias": -0.00048015054606664317, + "rmse": 0.0017491830361154393, + "max_abs_err": 0.005573349424288581, + "tau": 0.00047637595748609477, + "s": 12.762882295623601, + "corr_length_days": 37.11646673143383, + "n_eff": 24.89111871136159, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.007401963755523947, + "prior_weight_s2": 4.6662569055105915e-14, + "prior_weight_lambda": 2.765608664684752e-06 + }, + { + "seed": 2107, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8111353711790393, + "member_coverage95": 0.9548762736535662, + "member_rmse": 0.003649476263211587, + "shared_bias": -0.0004018566249224691, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.3406113537117904, + "median_sd": 0.0033753332552726224, + "median_halfwidth95": 0.00661553166833715, + "bias": -0.0004018566249224691, + "rmse": 0.0015458772258500526, + "max_abs_err": 0.003901519498083368, + "tau": 0.0007318650760500452, + "s": 13.010597047582799, + "corr_length_days": 31.53039753090211, + "n_eff": 16.07860499908015, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0029186222918170476, + "prior_weight_s2": 4.415953575716532e-14, + "prior_weight_lambda": 2.0065518326590533e-05 + }, + { + "seed": 2108, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7933042212518195, + "member_coverage95": 0.9494177583697234, + "member_rmse": 0.0036632540279720334, + "shared_bias": -0.0004969952151856968, + "coverage68": 0.9606986899563319, + "coverage95": 1.0, + "coverage95_posterior": 0.24890829694323144, + "median_sd": 0.003374046946957987, + "median_halfwidth95": 0.006613010550347564, + "bias": -0.0004969952151856968, + "rmse": 0.0016815160850557013, + "max_abs_err": 0.00441130701159554, + "tau": 0.00041554049655804105, + "s": 13.159012552427194, + "corr_length_days": 35.13854736184916, + "n_eff": 29.60198194082795, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.010335754053120915, + "prior_weight_s2": 4.310291262097373e-14, + "prior_weight_lambda": 4.062508494438024e-05 + }, + { + "seed": 2109, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7867540029112081, + "member_coverage95": 0.9490538573508006, + "member_rmse": 0.003440735867304344, + "shared_bias": -0.0002793481843456873, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.35807860262008734, + "median_sd": 0.00318649097120488, + "median_halfwidth95": 0.006245407589886602, + "bias": -0.0002793481843456873, + "rmse": 0.0014686107380343892, + "max_abs_err": 0.003435285230229787, + "tau": 0.0004292069035606102, + "s": 12.343633266369528, + "corr_length_days": 13.286433761773749, + "n_eff": 26.71507620734115, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.009615834641336337, + "prior_weight_s2": 4.958336409242525e-14, + "prior_weight_lambda": 7.4641065268248885e-06 + }, + { + "seed": 2110, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8096797671033479, + "member_coverage95": 0.9519650655021834, + "member_rmse": 0.0034555107728668813, + "shared_bias": -0.0003272989081388337, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.3231441048034934, + "median_sd": 0.003229421058408414, + "median_halfwidth95": 0.006329549015322389, + "bias": -0.0003272989081388337, + "rmse": 0.001592472615942889, + "max_abs_err": 0.004431587624620199, + "tau": 0.00046151309184946855, + "s": 12.332111411219877, + "corr_length_days": 29.505702900319918, + "n_eff": 24.33387896333612, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.008447326543337616, + "prior_weight_s2": 4.933552744500988e-14, + "prior_weight_lambda": 1.3767174434866263e-05 + }, + { + "seed": 2111, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7951237263464338, + "member_coverage95": 0.9479621542940321, + "member_rmse": 0.0035772207794063852, + "shared_bias": -0.0006050484882901949, + "coverage68": 0.9781659388646288, + "coverage95": 1.0, + "coverage95_posterior": 0.39737991266375544, + "median_sd": 0.003307624322918976, + "median_halfwidth95": 0.006482824598445568, + "bias": -0.0006050484882901949, + "rmse": 0.0015273077917474101, + "max_abs_err": 0.0038971765830364312, + "tau": 0.0005361007873938886, + "s": 12.643077065504626, + "corr_length_days": 32.051881706144535, + "n_eff": 21.381990170568503, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0063295456340295925, + "prior_weight_s2": 4.7053473986082106e-14, + "prior_weight_lambda": 9.065157100780295e-06 + }, + { + "seed": 2112, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8053129548762736, + "member_coverage95": 0.9552401746724891, + "member_rmse": 0.003674239250092681, + "shared_bias": -0.0004141709467652886, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.37554585152838427, + "median_sd": 0.0033795882262601033, + "median_halfwidth95": 0.006623871258293657, + "bias": -0.0004141709467652886, + "rmse": 0.0015982841439785493, + "max_abs_err": 0.004106780880135939, + "tau": 0.0008241592608367744, + "s": 12.752855335726391, + "corr_length_days": 50.14930014340228, + "n_eff": 13.44210968501326, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.002383176767742772, + "prior_weight_s2": 4.624676384022095e-14, + "prior_weight_lambda": 1.238552464065427e-05 + }, + { + "seed": 2113, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7834788937409025, + "member_coverage95": 0.9486899563318777, + "member_rmse": 0.0035164264913167616, + "shared_bias": -0.0006219096885607787, + "coverage68": 0.9475982532751092, + "coverage95": 1.0, + "coverage95_posterior": 0.34497816593886466, + "median_sd": 0.0031526895418394966, + "median_halfwidth95": 0.0061791580051819076, + "bias": -0.0006219096885607787, + "rmse": 0.0016893193321348803, + "max_abs_err": 0.004343731761969322, + "tau": 0.0006180644905425718, + "s": 12.134116029855075, + "corr_length_days": 38.22619817866955, + "n_eff": 17.426105323784363, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.004496757661353549, + "prior_weight_s2": 5.10500161888547e-14, + "prior_weight_lambda": 1.4686802524217803e-05 + }, + { + "seed": 2114, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7874818049490538, + "member_coverage95": 0.9508733624454149, + "member_rmse": 0.003399389575085393, + "shared_bias": -0.00046866599566557104, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.38427947598253276, + "median_sd": 0.003222731446533837, + "median_halfwidth95": 0.0063164376168742455, + "bias": -0.00046866599566557104, + "rmse": 0.0015906540650296402, + "max_abs_err": 0.003484888372014639, + "tau": 0.0005214031720778701, + "s": 12.234978966564839, + "corr_length_days": 28.58364754265754, + "n_eff": 20.455424909995255, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.006469711638374194, + "prior_weight_s2": 4.975832944413783e-14, + "prior_weight_lambda": 6.149328935355602e-05 + }, + { + "seed": 2115, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8147743813682679, + "member_coverage95": 0.9519650655021834, + "member_rmse": 0.0034472138733985455, + "shared_bias": -0.0004061036369120481, + "coverage68": 0.982532751091703, + "coverage95": 1.0, + "coverage95_posterior": 0.28820960698689957, + "median_sd": 0.003271022518161535, + "median_halfwidth95": 0.006411086378785955, + "bias": -0.0004061036369120481, + "rmse": 0.0014572004578156334, + "max_abs_err": 0.0037411982324188826, + "tau": 0.00045514972754154433, + "s": 12.520823012480548, + "corr_length_days": 29.986922773914372, + "n_eff": 24.912878532831765, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.008462896514367803, + "prior_weight_s2": 4.7844086952229257e-14, + "prior_weight_lambda": 1.9672586787870237e-05 + }, + { + "seed": 2116, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7740174672489083, + "member_coverage95": 0.9432314410480349, + "member_rmse": 0.0036585841057904392, + "shared_bias": -0.000495868221896564, + "coverage68": 0.9694323144104804, + "coverage95": 1.0, + "coverage95_posterior": 0.31004366812227074, + "median_sd": 0.0031812101592106996, + "median_halfwidth95": 0.006235057388487239, + "bias": -0.000495868221896564, + "rmse": 0.0017006083112152456, + "max_abs_err": 0.003926954999403722, + "tau": 0.0005459911161319076, + "s": 12.333307843185032, + "corr_length_days": 26.873011293104554, + "n_eff": 20.11520677498633, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.005962277391555632, + "prior_weight_s2": 4.93484527312879e-14, + "prior_weight_lambda": 1.699297560665834e-05 + }, + { + "seed": 2117, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.784570596797671, + "member_coverage95": 0.9443231441048034, + "member_rmse": 0.003535550554062823, + "shared_bias": -0.0005238113994721868, + "coverage68": 0.9432314410480349, + "coverage95": 1.0, + "coverage95_posterior": 0.35807860262008734, + "median_sd": 0.003351236880476149, + "median_halfwidth95": 0.006568303641205555, + "bias": -0.0005238113994721868, + "rmse": 0.0017778514738062518, + "max_abs_err": 0.004933009759600128, + "tau": 0.0003382264601118085, + "s": 12.991376635009594, + "corr_length_days": 44.62157474037501, + "n_eff": 33.3767446025696, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01839702008773979, + "prior_weight_s2": 4.4610608183947535e-14, + "prior_weight_lambda": 7.205056131923071e-06 + }, + { + "seed": 2118, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8045851528384279, + "member_coverage95": 0.9526928675400291, + "member_rmse": 0.0037341840506955794, + "shared_bias": -0.000513750140346808, + "coverage68": 0.9781659388646288, + "coverage95": 1.0, + "coverage95_posterior": 0.27074235807860264, + "median_sd": 0.0035154048309694887, + "median_halfwidth95": 0.006890066914126283, + "bias": -0.000513750140346808, + "rmse": 0.001799861828529737, + "max_abs_err": 0.0045103300955810525, + "tau": 0.000516883874544266, + "s": 13.642598622342161, + "corr_length_days": 26.664000198775486, + "n_eff": 23.396681112657465, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.006940891878843109, + "prior_weight_s2": 4.0276370843907086e-14, + "prior_weight_lambda": 1.2130613351571319e-05 + }, + { + "seed": 2119, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7751091703056768, + "member_coverage95": 0.9519650655021834, + "member_rmse": 0.0033699329168901137, + "shared_bias": -0.0004998135217465994, + "coverage68": 0.9694323144104804, + "coverage95": 1.0, + "coverage95_posterior": 0.3624454148471616, + "median_sd": 0.0031461245718063255, + "median_halfwidth95": 0.006166290900255813, + "bias": -0.0004998135217465994, + "rmse": 0.0016182159343444903, + "max_abs_err": 0.004288284002651981, + "tau": 0.00033250390689271305, + "s": 12.373495213056593, + "corr_length_days": 24.75487106021078, + "n_eff": 29.833963140622465, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.017727275773456855, + "prior_weight_s2": 4.924204365854683e-14, + "prior_weight_lambda": 6.831975747099611e-06 + }, + { + "seed": 2120, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7820232896652111, + "member_coverage95": 0.9465065502183406, + "member_rmse": 0.0035102415558284773, + "shared_bias": -0.0004610175028689115, + "coverage68": 0.9781659388646288, + "coverage95": 1.0, + "coverage95_posterior": 0.24890829694323144, + "median_sd": 0.0031950970862782146, + "median_halfwidth95": 0.006262275265610195, + "bias": -0.0004610175028689115, + "rmse": 0.0016006701742049916, + "max_abs_err": 0.003558270790878801, + "tau": 0.0004916719210860285, + "s": 12.29343516114023, + "corr_length_days": 42.73876713937233, + "n_eff": 23.974141631587653, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.007175102553814237, + "prior_weight_s2": 4.965900224291361e-14, + "prior_weight_lambda": 1.524926809493093e-05 + }, + { + "seed": 2121, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7976710334788938, + "member_coverage95": 0.9577874818049491, + "member_rmse": 0.0035700202790092082, + "shared_bias": -0.0004947377883963626, + "coverage68": 0.9650655021834061, + "coverage95": 1.0, + "coverage95_posterior": 0.4410480349344978, + "median_sd": 0.0033763505095362454, + "median_halfwidth95": 0.006617525450072698, + "bias": -0.0004947377883963626, + "rmse": 0.0017036861927481404, + "max_abs_err": 0.005066294958947939, + "tau": 0.0006776534740028808, + "s": 12.716438131956572, + "corr_length_days": 39.25320765095151, + "n_eff": 16.30838808309265, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.003582589547639279, + "prior_weight_s2": 4.6659802015873735e-14, + "prior_weight_lambda": 5.600620745512089e-06 + }, + { + "seed": 2122, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.787117903930131, + "member_coverage95": 0.9516011644832606, + "member_rmse": 0.0033629495928755716, + "shared_bias": -0.00043256035468878, + "coverage68": 0.9781659388646288, + "coverage95": 1.0, + "coverage95_posterior": 0.2925764192139738, + "median_sd": 0.003185762247054778, + "median_halfwidth95": 0.006243979316786471, + "bias": -0.00043256035468878, + "rmse": 0.0016422117783761396, + "max_abs_err": 0.0034393895658100925, + "tau": 0.00039783577305530404, + "s": 12.102231557153795, + "corr_length_days": 22.42295958999223, + "n_eff": 26.396270537664517, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0129277722817034, + "prior_weight_s2": 5.164587027873409e-14, + "prior_weight_lambda": 5.484709794633044e-06 + }, + { + "seed": 2123, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.789665211062591, + "member_coverage95": 0.9461426491994177, + "member_rmse": 0.0035353084722367827, + "shared_bias": -0.0005075234390553956, + "coverage68": 0.9432314410480349, + "coverage95": 1.0, + "coverage95_posterior": 0.2314410480349345, + "median_sd": 0.0033176740851767906, + "median_halfwidth95": 0.006502521770679444, + "bias": -0.0005075234390553956, + "rmse": 0.0019171503388245139, + "max_abs_err": 0.004283581609834258, + "tau": 0.00041928635746867987, + "s": 12.880372129539928, + "corr_length_days": 21.25237169902756, + "n_eff": 26.282661056352666, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01032309422196152, + "prior_weight_s2": 4.535838979155299e-14, + "prior_weight_lambda": 9.621900141128505e-06 + }, + { + "seed": 2124, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8155021834061136, + "member_coverage95": 0.9508733624454149, + "member_rmse": 0.003564286962389435, + "shared_bias": -0.00041401093434121364, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.32751091703056767, + "median_sd": 0.0035082347544804706, + "median_halfwidth95": 0.0068760138223305615, + "bias": -0.00041401093434121364, + "rmse": 0.0016135247166297723, + "max_abs_err": 0.0040599823072401, + "tau": 0.0002723769285047503, + "s": 13.431700890656401, + "corr_length_days": 48.6803455394174, + "n_eff": 44.47204948797767, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03163035114310059, + "prior_weight_s2": 4.1474873648538074e-14, + "prior_weight_lambda": 1.40276485210782e-05 + }, + { + "seed": 2125, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7983988355167394, + "member_coverage95": 0.9497816593886463, + "member_rmse": 0.0035702604393793042, + "shared_bias": -0.0003911127453177477, + "coverage68": 0.9868995633187773, + "coverage95": 1.0, + "coverage95_posterior": 0.37117903930131, + "median_sd": 0.0034120411619478477, + "median_halfwidth95": 0.006687477843935951, + "bias": -0.0003911127453177477, + "rmse": 0.0015456913941684276, + "max_abs_err": 0.004343198960336762, + "tau": 0.000336475192865735, + "s": 13.006529393474477, + "corr_length_days": 39.770413146587586, + "n_eff": 34.15897960382296, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.017593939663842394, + "prior_weight_s2": 4.4433567000895535e-14, + "prior_weight_lambda": 6.337101078025843e-06 + }, + { + "seed": 2126, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7987627365356623, + "member_coverage95": 0.9501455604075691, + "member_rmse": 0.0037234923458057657, + "shared_bias": -0.000464050359626414, + "coverage68": 0.9432314410480349, + "coverage95": 1.0, + "coverage95_posterior": 0.3537117903930131, + "median_sd": 0.003543786999171059, + "median_halfwidth95": 0.006945694942043306, + "bias": -0.000464050359626414, + "rmse": 0.0018682003553488191, + "max_abs_err": 0.005166143914430958, + "tau": 0.0004518568641479759, + "s": 13.466408810028659, + "corr_length_days": 13.509463175306387, + "n_eff": 27.046588898328444, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.008699505509667473, + "prior_weight_s2": 4.139995878976098e-14, + "prior_weight_lambda": 1.3032172877279835e-05 + }, + { + "seed": 2127, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.789665211062591, + "member_coverage95": 0.9501455604075691, + "member_rmse": 0.00330429839696111, + "shared_bias": -0.0003848245166739774, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.4279475982532751, + "median_sd": 0.003196403859150844, + "median_halfwidth95": 0.006264836493396725, + "bias": -0.0003848245166739774, + "rmse": 0.001439709736346832, + "max_abs_err": 0.003412162017891989, + "tau": 0.000389683594207237, + "s": 12.090270661817113, + "corr_length_days": 18.54086285547986, + "n_eff": 25.29886741238395, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.011452732471110448, + "prior_weight_s2": 5.136852156594223e-14, + "prior_weight_lambda": 1.2745798144513086e-05 + }, + { + "seed": 2128, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7838427947598253, + "member_coverage95": 0.9450509461426492, + "member_rmse": 0.003582883193654537, + "shared_bias": -0.0003172888078126479, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.2445414847161572, + "median_sd": 0.0032352863415093824, + "median_halfwidth95": 0.006341044759050095, + "bias": -0.0003172888078126479, + "rmse": 0.0016759963039406928, + "max_abs_err": 0.003218528268089555, + "tau": 0.000397948982196893, + "s": 12.66156556115636, + "corr_length_days": 22.60845164924666, + "n_eff": 26.91663127509654, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01169970722421191, + "prior_weight_s2": 4.671350497768347e-14, + "prior_weight_lambda": 1.3686099960031498e-05 + }, + { + "seed": 2129, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8114992721979621, + "member_coverage95": 0.9421397379912664, + "member_rmse": 0.003372388091771944, + "shared_bias": -0.0005143792670248947, + "coverage68": 0.9694323144104804, + "coverage95": 1.0, + "coverage95_posterior": 0.314410480349345, + "median_sd": 0.0031685042753617104, + "median_halfwidth95": 0.006210154313555039, + "bias": -0.0005143792670248947, + "rmse": 0.0016070216041269014, + "max_abs_err": 0.0037265637203299944, + "tau": 0.0005825276974158978, + "s": 11.935484251454177, + "corr_length_days": 46.8102197268412, + "n_eff": 20.2033588504203, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.004995609687545857, + "prior_weight_s2": 5.2827328260386496e-14, + "prior_weight_lambda": 9.05392885399002e-06 + }, + { + "seed": 2130, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7645560407569141, + "member_coverage95": 0.9428675400291121, + "member_rmse": 0.00356796047563709, + "shared_bias": -0.0004486400190929692, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.2925764192139738, + "median_sd": 0.003325301925729628, + "median_halfwidth95": 0.006517472063560745, + "bias": -0.0004486400190929692, + "rmse": 0.001610403185717532, + "max_abs_err": 0.003153087781089704, + "tau": 0.00037659684320911867, + "s": 12.703539726123006, + "corr_length_days": 32.99448131031765, + "n_eff": 28.671028999575206, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.013266727913595478, + "prior_weight_s2": 4.6263584326552835e-14, + "prior_weight_lambda": 3.0736982151910505e-05 + }, + { + "seed": 2131, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7922125181950509, + "member_coverage95": 0.9494177583697234, + "member_rmse": 0.003253346325268337, + "shared_bias": -0.00039392765632329234, + "coverage68": 0.9606986899563319, + "coverage95": 1.0, + "coverage95_posterior": 0.38427947598253276, + "median_sd": 0.0031107067388690436, + "median_halfwidth95": 0.006096873222740726, + "bias": -0.00039392765632329234, + "rmse": 0.0015516044713311014, + "max_abs_err": 0.0037513540580611116, + "tau": 0.00028714408933490186, + "s": 12.112111194549918, + "corr_length_days": 47.421100549075426, + "n_eff": 40.400840952620676, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.026189141598655524, + "prior_weight_s2": 5.109452806968665e-14, + "prior_weight_lambda": 2.9581513643489538e-05 + }, + { + "seed": 2132, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7867540029112081, + "member_coverage95": 0.9461426491994177, + "member_rmse": 0.003465303999550834, + "shared_bias": -0.00034544140779502647, + "coverage68": 0.9650655021834061, + "coverage95": 1.0, + "coverage95_posterior": 0.26200873362445415, + "median_sd": 0.00313193603358127, + "median_halfwidth95": 0.00613848187612208, + "bias": -0.00034544140779502647, + "rmse": 0.0015550187470503391, + "max_abs_err": 0.0038619687076832895, + "tau": 0.0004199530547675344, + "s": 11.984538974654614, + "corr_length_days": 36.26779625235916, + "n_eff": 27.23325144686079, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.010772467522438467, + "prior_weight_s2": 5.212632840158263e-14, + "prior_weight_lambda": 1.6851860884324516e-05 + }, + { + "seed": 2133, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.787117903930131, + "member_coverage95": 0.9512372634643377, + "member_rmse": 0.003465624667795861, + "shared_bias": -0.00043574115951860277, + "coverage68": 0.9519650655021834, + "coverage95": 1.0, + "coverage95_posterior": 0.37117903930131, + "median_sd": 0.0031365397742543375, + "median_halfwidth95": 0.006147505042106628, + "bias": -0.00043574115951860277, + "rmse": 0.0016600424861368732, + "max_abs_err": 0.004851934198730431, + "tau": 0.0005761235408405785, + "s": 12.187470244643228, + "corr_length_days": 39.77503541577593, + "n_eff": 19.52320904701168, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.00505245518711179, + "prior_weight_s2": 5.0883870568501697e-14, + "prior_weight_lambda": 5.126440768618565e-06 + }, + { + "seed": 2134, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7863901018922853, + "member_coverage95": 0.9428675400291121, + "member_rmse": 0.003671756458688206, + "shared_bias": -0.00048159378282540237, + "coverage68": 0.925764192139738, + "coverage95": 1.0, + "coverage95_posterior": 0.2096069868995633, + "median_sd": 0.003273446442654401, + "median_halfwidth95": 0.00641583718353069, + "bias": -0.00048159378282540237, + "rmse": 0.0018367315538998675, + "max_abs_err": 0.004112496602723141, + "tau": 0.0003809714355021964, + "s": 12.665635295397353, + "corr_length_days": 21.137531784755375, + "n_eff": 29.091223986503152, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01426080172986888, + "prior_weight_s2": 4.651980561834297e-14, + "prior_weight_lambda": 4.2098061943911605e-05 + }, + { + "seed": 2135, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8056768558951966, + "member_coverage95": 0.9523289665211062, + "member_rmse": 0.0037196569996468974, + "shared_bias": -0.0005804791899171357, + "coverage68": 0.9737991266375546, + "coverage95": 1.0, + "coverage95_posterior": 0.30131004366812225, + "median_sd": 0.003383039869028483, + "median_halfwidth95": 0.006630636353860541, + "bias": -0.0005804791899171357, + "rmse": 0.0017034430855459115, + "max_abs_err": 0.0038566200289391886, + "tau": 0.0007581007083917086, + "s": 12.848455268759137, + "corr_length_days": 52.308519780562285, + "n_eff": 14.547784537801016, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0027572204421525024, + "prior_weight_s2": 4.5569911453838474e-14, + "prior_weight_lambda": 1.3618120821689527e-05 + }, + { + "seed": 2136, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8184133915574964, + "member_coverage95": 0.9585152838427947, + "member_rmse": 0.0035809775010598134, + "shared_bias": -0.0002688547275595723, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.3930131004366812, + "median_sd": 0.003506085117074621, + "median_halfwidth95": 0.006871800610402043, + "bias": -0.0002688547275595723, + "rmse": 0.0014913354331141874, + "max_abs_err": 0.0038354606238841893, + "tau": 0.0004329365500753543, + "s": 13.506523760852277, + "corr_length_days": 38.14058844490796, + "n_eff": 32.49486253160632, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.010418636170396005, + "prior_weight_s2": 4.129492307865291e-14, + "prior_weight_lambda": 8.703303180756062e-06 + }, + { + "seed": 2137, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.789665211062591, + "member_coverage95": 0.9497816593886463, + "member_rmse": 0.0038359715204801825, + "shared_bias": -0.0005903585144011111, + "coverage68": 0.9694323144104804, + "coverage95": 1.0, + "coverage95_posterior": 0.37554585152838427, + "median_sd": 0.0035345850934143906, + "median_halfwidth95": 0.006927659538028843, + "bias": -0.0005903585144011111, + "rmse": 0.0017814586881507999, + "max_abs_err": 0.004266424903266344, + "tau": 0.0006775179524116132, + "s": 13.433041175569398, + "corr_length_days": 35.55302313795366, + "n_eff": 18.25848562771872, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0035520657882930694, + "prior_weight_s2": 4.180754687049294e-14, + "prior_weight_lambda": 5.561759189258497e-06 + }, + { + "seed": 2138, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7780203784570596, + "member_coverage95": 0.9435953420669578, + "member_rmse": 0.003571561815301415, + "shared_bias": -0.000456555592469892, + "coverage68": 0.9563318777292577, + "coverage95": 1.0, + "coverage95_posterior": 0.24017467248908297, + "median_sd": 0.003224767861789952, + "median_halfwidth95": 0.006320428917465281, + "bias": -0.000456555592469892, + "rmse": 0.0018032656518917464, + "max_abs_err": 0.004398051676694823, + "tau": 0.0003888651873881401, + "s": 12.29358555215546, + "corr_length_days": 53.40246039660398, + "n_eff": 34.338011340391965, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.011503538623137573, + "prior_weight_s2": 4.947425581389326e-14, + "prior_weight_lambda": 2.030517188972485e-05 + }, + { + "seed": 2139, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8107714701601164, + "member_coverage95": 0.9545123726346434, + "member_rmse": 0.0036580572982354152, + "shared_bias": -0.0004975238671734298, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.39737991266375544, + "median_sd": 0.003373090491860265, + "median_halfwidth95": 0.006611135932788412, + "bias": -0.0004975238671734298, + "rmse": 0.0014596957448157406, + "max_abs_err": 0.004094271104854578, + "tau": 0.0006211782703430111, + "s": 12.974317961427229, + "corr_length_days": 30.151191221115326, + "n_eff": 18.77773470563969, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.004400905976488737, + "prior_weight_s2": 4.4649979839787646e-14, + "prior_weight_lambda": 1.1725761818234934e-05 + }, + { + "seed": 2140, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7962154294032023, + "member_coverage95": 0.9454148471615721, + "member_rmse": 0.003496099395038135, + "shared_bias": -0.0003051248103173224, + "coverage68": 0.982532751091703, + "coverage95": 1.0, + "coverage95_posterior": 0.314410480349345, + "median_sd": 0.0031610324169045003, + "median_halfwidth95": 0.006195509739965812, + "bias": -0.0003051248103173224, + "rmse": 0.0015968674983065322, + "max_abs_err": 0.004319678874953577, + "tau": 0.000423286320908596, + "s": 12.201236846829545, + "corr_length_days": 30.866971848549127, + "n_eff": 25.33494818422204, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.009673849725392147, + "prior_weight_s2": 5.065822162348993e-14, + "prior_weight_lambda": 8.369900962703991e-06 + }, + { + "seed": 2141, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7983988355167394, + "member_coverage95": 0.9545123726346434, + "member_rmse": 0.0036085613662326338, + "shared_bias": -0.00044616672085060475, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.388646288209607, + "median_sd": 0.0035051466285034253, + "median_halfwidth95": 0.006869961206588088, + "bias": -0.00044616672085060475, + "rmse": 0.0014963950989615128, + "max_abs_err": 0.004319985118970988, + "tau": 0.0005854157290825766, + "s": 13.357432701994142, + "corr_length_days": 33.91401494306739, + "n_eff": 19.743841163343117, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.005177712531014416, + "prior_weight_s2": 4.2218045803609045e-14, + "prior_weight_lambda": 8.249827742837924e-06 + }, + { + "seed": 2142, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7998544395924309, + "member_coverage95": 0.9508733624454149, + "member_rmse": 0.0035348197301379833, + "shared_bias": -0.0003857136553635665, + "coverage68": 0.9737991266375546, + "coverage95": 1.0, + "coverage95_posterior": 0.3537117903930131, + "median_sd": 0.0034175863734631426, + "median_halfwidth95": 0.006698346258878315, + "bias": -0.0003857136553635665, + "rmse": 0.00168729932391505, + "max_abs_err": 0.003946305877969202, + "tau": 0.0005575320663207959, + "s": 12.992944046231765, + "corr_length_days": 45.53721438052683, + "n_eff": 23.70048076554218, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0054524078483049335, + "prior_weight_s2": 4.4454728781380336e-14, + "prior_weight_lambda": 1.3620521711773289e-05 + }, + { + "seed": 2143, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7776564774381368, + "member_coverage95": 0.9486899563318777, + "member_rmse": 0.003531418465035673, + "shared_bias": -0.0004096099739578583, + "coverage68": 0.9563318777292577, + "coverage95": 1.0, + "coverage95_posterior": 0.3406113537117904, + "median_sd": 0.003227315245411288, + "median_halfwidth95": 0.00632542169765729, + "bias": -0.0004096099739578583, + "rmse": 0.0017476920356764298, + "max_abs_err": 0.004842441334166713, + "tau": 0.0005090805377781902, + "s": 12.698904711275388, + "corr_length_days": 17.150359515989138, + "n_eff": 21.187336213809093, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.00699811200246564, + "prior_weight_s2": 4.6701117442825195e-14, + "prior_weight_lambda": 6.325523563943338e-06 + }, + { + "seed": 2144, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7973071324599709, + "member_coverage95": 0.9450509461426492, + "member_rmse": 0.003567034939668745, + "shared_bias": -0.0004831629536945081, + "coverage68": 0.9737991266375546, + "coverage95": 1.0, + "coverage95_posterior": 0.31877729257641924, + "median_sd": 0.0033061472026872257, + "median_halfwidth95": 0.006479929495967666, + "bias": -0.0004831629536945081, + "rmse": 0.001614435813031117, + "max_abs_err": 0.003846870035044079, + "tau": 0.0005305540832664542, + "s": 12.96436466880661, + "corr_length_days": 40.516572430525414, + "n_eff": 21.168044100719577, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.006116931078380018, + "prior_weight_s2": 4.4533862407435285e-14, + "prior_weight_lambda": 2.6500888215459008e-05 + }, + { + "seed": 2145, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7951237263464338, + "member_coverage95": 0.9559679767103348, + "member_rmse": 0.003394333778981205, + "shared_bias": -0.0005850688067785124, + "coverage68": 0.9737991266375546, + "coverage95": 1.0, + "coverage95_posterior": 0.34934497816593885, + "median_sd": 0.003264169071484216, + "median_halfwidth95": 0.00639765387002249, + "bias": -0.0005850688067785124, + "rmse": 0.0016880226308298007, + "max_abs_err": 0.004940657054064115, + "tau": 0.0006509366986801129, + "s": 12.56853184862089, + "corr_length_days": 29.46966832113936, + "n_eff": 15.866301627236234, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.004095303602827191, + "prior_weight_s2": 4.7534703535642007e-14, + "prior_weight_lambda": 1.489578768647982e-05 + }, + { + "seed": 2146, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8151382823871907, + "member_coverage95": 0.9526928675400291, + "member_rmse": 0.003678485319430337, + "shared_bias": -0.0007427635529812405, + "coverage68": 0.925764192139738, + "coverage95": 1.0, + "coverage95_posterior": 0.43231441048034935, + "median_sd": 0.0035212986365151058, + "median_halfwidth95": 0.006901618560818693, + "bias": -0.0007427635529812405, + "rmse": 0.0018604995224231961, + "max_abs_err": 0.004532881196367515, + "tau": 0.0006300545135702379, + "s": 13.343485048923021, + "corr_length_days": 33.53331311909419, + "n_eff": 18.42094559363012, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.004278168745901366, + "prior_weight_s2": 4.202950342556547e-14, + "prior_weight_lambda": 1.5187125704839984e-05 + }, + { + "seed": 2147, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8053129548762736, + "member_coverage95": 0.9475982532751092, + "member_rmse": 0.0032905136394470917, + "shared_bias": -0.00024896370809561404, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.4017467248908297, + "median_sd": 0.0032371712919229516, + "median_halfwidth95": 0.006344739194002476, + "bias": -0.00024896370809561404, + "rmse": 0.001265073380526413, + "max_abs_err": 0.003121005892298816, + "tau": 0.00016415423985683534, + "s": 12.53784831617086, + "corr_length_days": 16.999694120707584, + "n_eff": 42.80254323094677, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.11859689392613897, + "prior_weight_s2": 4.778588879659962e-14, + "prior_weight_lambda": 7.461477981146545e-06 + }, + { + "seed": 2148, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8042212518195051, + "member_coverage95": 0.9512372634643377, + "member_rmse": 0.0036625971398003988, + "shared_bias": -0.00040915318875493507, + "coverage68": 0.982532751091703, + "coverage95": 1.0, + "coverage95_posterior": 0.3537117903930131, + "median_sd": 0.003368291871546805, + "median_halfwidth95": 0.006601730809724362, + "bias": -0.00040915318875493507, + "rmse": 0.0016526840941945627, + "max_abs_err": 0.003796182622176243, + "tau": 0.0005126520844273913, + "s": 12.8886170659682, + "corr_length_days": 15.857014680334725, + "n_eff": 23.508722563564124, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.006983609403611775, + "prior_weight_s2": 4.513452066859629e-14, + "prior_weight_lambda": 1.5393331164245735e-05 + }, + { + "seed": 2149, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7903930131004366, + "member_coverage95": 0.9461426491994177, + "member_rmse": 0.0036796392487191396, + "shared_bias": -0.00048758911885463715, + "coverage68": 0.9694323144104804, + "coverage95": 1.0, + "coverage95_posterior": 0.4410480349344978, + "median_sd": 0.0033863190952381633, + "median_halfwidth95": 0.006637063519179372, + "bias": -0.00048758911885463715, + "rmse": 0.0016569955240438535, + "max_abs_err": 0.00440913192096716, + "tau": 0.0006289219932186868, + "s": 12.858515940690436, + "corr_length_days": 21.04122446251316, + "n_eff": 17.374783028060424, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.004293746842260475, + "prior_weight_s2": 4.5662915270116415e-14, + "prior_weight_lambda": 6.642742941321429e-06 + }, + { + "seed": 2150, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7889374090247453, + "member_coverage95": 0.950509461426492, + "member_rmse": 0.003370726798132889, + "shared_bias": -0.000480236881191241, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.34497816593886466, + "median_sd": 0.003148911384655193, + "median_halfwidth95": 0.0061717529531143305, + "bias": -0.000480236881191241, + "rmse": 0.0014088577276151221, + "max_abs_err": 0.003160107242793711, + "tau": 0.0003123495862065111, + "s": 12.408884514761054, + "corr_length_days": 23.548354295276017, + "n_eff": 29.41643860817714, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.02183389967601773, + "prior_weight_s2": 4.880266573463185e-14, + "prior_weight_lambda": 9.438866382107944e-06 + }, + { + "seed": 2151, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8296943231441049, + "member_coverage95": 0.9566957787481805, + "member_rmse": 0.0036372329612804, + "shared_bias": -0.0004426505503898806, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.37554585152838427, + "median_sd": 0.003381279517463989, + "median_halfwidth95": 0.00662718612816679, + "bias": -0.0004426505503898806, + "rmse": 0.0014612611839419616, + "max_abs_err": 0.0035244974611202424, + "tau": 0.0005849595061877625, + "s": 12.8861721338094, + "corr_length_days": 14.463562558380904, + "n_eff": 20.541482672837123, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.005085477502955465, + "prior_weight_s2": 4.4859693377969553e-14, + "prior_weight_lambda": 5.276427654266913e-05 + }, + { + "seed": 2152, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8013100436681223, + "member_coverage95": 0.9519650655021834, + "member_rmse": 0.0033733742146144345, + "shared_bias": -0.00030775460446012836, + "coverage68": 0.982532751091703, + "coverage95": 1.0, + "coverage95_posterior": 0.314410480349345, + "median_sd": 0.0032263259814146236, + "median_halfwidth95": 0.006323482775837331, + "bias": -0.00030775460446012836, + "rmse": 0.0015576077706623026, + "max_abs_err": 0.00412741463300677, + "tau": 0.0004967757043185914, + "s": 12.444970962950208, + "corr_length_days": 32.53021013743973, + "n_eff": 23.140983315404963, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.006844557792638835, + "prior_weight_s2": 4.848583573164981e-14, + "prior_weight_lambda": 1.4594076472705182e-05 + }, + { + "seed": 2153, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7791120815138283, + "member_coverage95": 0.9439592430858806, + "member_rmse": 0.003536995918627214, + "shared_bias": -0.0004892352900595756, + "coverage68": 0.9519650655021834, + "coverage95": 1.0, + "coverage95_posterior": 0.314410480349345, + "median_sd": 0.0032745703682265227, + "median_halfwidth95": 0.006418040037190729, + "bias": -0.0004892352900595756, + "rmse": 0.0017470270335841307, + "max_abs_err": 0.004334657472519766, + "tau": 0.00016245625561142786, + "s": 12.751864090049796, + "corr_length_days": 31.86672301473879, + "n_eff": 42.36223764327386, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.10654559175636193, + "prior_weight_s2": 4.616512092805205e-14, + "prior_weight_lambda": 1.052864711367688e-05 + }, + { + "seed": 2154, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7634643377001455, + "member_coverage95": 0.9392285298398836, + "member_rmse": 0.003452634706048988, + "shared_bias": -0.0003527291188336631, + "coverage68": 0.925764192139738, + "coverage95": 1.0, + "coverage95_posterior": 0.33624454148471616, + "median_sd": 0.0031948557731988807, + "median_halfwidth95": 0.006261802300661971, + "bias": -0.0003527291188336631, + "rmse": 0.0017754088265308882, + "max_abs_err": 0.004337294952729645, + "tau": 0.0002526148221842532, + "s": 12.36626936678295, + "corr_length_days": 24.3105511684335, + "n_eff": 35.193321511346795, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.039391021626745515, + "prior_weight_s2": 4.920166527053028e-14, + "prior_weight_lambda": 1.060765875782277e-05 + }, + { + "seed": 2155, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7885735080058224, + "member_coverage95": 0.9519650655021834, + "member_rmse": 0.0033562057642717216, + "shared_bias": -0.00028924756175767436, + "coverage68": 0.982532751091703, + "coverage95": 1.0, + "coverage95_posterior": 0.34934497816593885, + "median_sd": 0.0031647096287271428, + "median_halfwidth95": 0.006202716942758566, + "bias": -0.00028924756175767436, + "rmse": 0.0014897955432219233, + "max_abs_err": 0.0037670365812366505, + "tau": 0.0002436259180277878, + "s": 12.264700059843777, + "corr_length_days": 25.121556086651207, + "n_eff": 35.08500521484814, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.04304164050432689, + "prior_weight_s2": 4.989411846335237e-14, + "prior_weight_lambda": 1.0860634778962786e-05 + }, + { + "seed": 2156, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7925764192139738, + "member_coverage95": 0.950509461426492, + "member_rmse": 0.003404064929819241, + "shared_bias": -0.0003290034339761997, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.3799126637554585, + "median_sd": 0.003257522572257631, + "median_halfwidth95": 0.006384626970812356, + "bias": -0.0003290034339761997, + "rmse": 0.0015908194314442768, + "max_abs_err": 0.004444509800382604, + "tau": 0.00020860856373266078, + "s": 12.719443324776217, + "corr_length_days": 32.50173067474081, + "n_eff": 30.620356713746943, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0629173997570849, + "prior_weight_s2": 4.658862230469178e-14, + "prior_weight_lambda": 6.2393877747725e-06 + }, + { + "seed": 2157, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7681950509461426, + "member_coverage95": 0.9385007278020379, + "member_rmse": 0.0031459674103302914, + "shared_bias": -0.0004130513846632407, + "coverage68": 0.9475982532751092, + "coverage95": 1.0, + "coverage95_posterior": 0.34497816593886466, + "median_sd": 0.002965683826942706, + "median_halfwidth95": 0.005812633536189934, + "bias": -0.0004130513846632407, + "rmse": 0.001539836069439621, + "max_abs_err": 0.003828471889906061, + "tau": 0.0004507784366766905, + "s": 11.425539686082958, + "corr_length_days": 17.11558446450639, + "n_eff": 20.9563774843454, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.008260911979461152, + "prior_weight_s2": 5.764890956529032e-14, + "prior_weight_lambda": 8.325494567964436e-06 + }, + { + "seed": 2158, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7838427947598253, + "member_coverage95": 0.9410480349344978, + "member_rmse": 0.0033885936739203185, + "shared_bias": -0.0005438914634710501, + "coverage68": 0.9694323144104804, + "coverage95": 1.0, + "coverage95_posterior": 0.29694323144104806, + "median_sd": 0.0032421506945588085, + "median_halfwidth95": 0.006354498643910261, + "bias": -0.0005438914634710501, + "rmse": 0.0016793828341012472, + "max_abs_err": 0.004760015398433349, + "tau": 0.0004744381747368433, + "s": 12.54525064999898, + "corr_length_days": 13.462490870627486, + "n_eff": 23.785056774336475, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.007899513579136788, + "prior_weight_s2": 4.773313414535764e-14, + "prior_weight_lambda": 1.0855439093353337e-05 + }, + { + "seed": 2159, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7805676855895196, + "member_coverage95": 0.9417758369723436, + "member_rmse": 0.003447816460234098, + "shared_bias": -0.00034005473943915466, + "coverage68": 0.9606986899563319, + "coverage95": 1.0, + "coverage95_posterior": 0.32751091703056767, + "median_sd": 0.0031575701580346194, + "median_halfwidth95": 0.006188723837222165, + "bias": -0.00034005473943915466, + "rmse": 0.0015915365104271397, + "max_abs_err": 0.004228055562525728, + "tau": 0.0004637867750228944, + "s": 12.186054718225469, + "corr_length_days": 46.468981845205484, + "n_eff": 26.2438934362401, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.008539938136120691, + "prior_weight_s2": 5.0794840431469836e-14, + "prior_weight_lambda": 6.7465694570244864e-06 + }, + { + "seed": 2160, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7743813682678311, + "member_coverage95": 0.9461426491994177, + "member_rmse": 0.003536827832825292, + "shared_bias": -0.0005206592730032601, + "coverage68": 0.9606986899563319, + "coverage95": 1.0, + "coverage95_posterior": 0.24017467248908297, + "median_sd": 0.0032130932786506292, + "median_halfwidth95": 0.006297547154797202, + "bias": -0.0005206592730032601, + "rmse": 0.0018620670936161092, + "max_abs_err": 0.003918152070524346, + "tau": 0.0004115053372200128, + "s": 12.650643053337063, + "corr_length_days": 20.016730283786668, + "n_eff": 24.89531766692963, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.010368234481324635, + "prior_weight_s2": 4.672396306041075e-14, + "prior_weight_lambda": 2.263563479973137e-05 + }, + { + "seed": 2161, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8078602620087336, + "member_coverage95": 0.9537845705967977, + "member_rmse": 0.0033963783672047703, + "shared_bias": -0.00040364710371069214, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.42358078602620086, + "median_sd": 0.0033266533247116445, + "median_halfwidth95": 0.006520120756915134, + "bias": -0.00040364710371069214, + "rmse": 0.0013114752577794966, + "max_abs_err": 0.003109932429321351, + "tau": 0.0004810394514882671, + "s": 12.689822560356065, + "corr_length_days": 27.892715248442247, + "n_eff": 22.648560077780164, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.007734915233141346, + "prior_weight_s2": 4.665498717701658e-14, + "prior_weight_lambda": 7.693829511263717e-06 + }, + { + "seed": 2162, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8085880640465793, + "member_coverage95": 0.9534206695778749, + "member_rmse": 0.003648848942046546, + "shared_bias": -0.0005659240758256055, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.33624454148471616, + "median_sd": 0.003441304612340808, + "median_halfwidth95": 0.006744833153221939, + "bias": -0.0005659240758256055, + "rmse": 0.0015612876834688316, + "max_abs_err": 0.003515105761430753, + "tau": 0.0005021576897142711, + "s": 13.224570820961954, + "corr_length_days": 30.134910195711072, + "n_eff": 24.39245790223207, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0068115427022567045, + "prior_weight_s2": 4.2746449589816174e-14, + "prior_weight_lambda": 2.260842952423294e-05 + }, + { + "seed": 2163, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8169577874818049, + "member_coverage95": 0.9585152838427947, + "member_rmse": 0.0038130877430693224, + "shared_bias": -0.0004715219479514003, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.2663755458515284, + "median_sd": 0.00365014574750598, + "median_halfwidth95": 0.0071541542598648105, + "bias": -0.0004715219479514003, + "rmse": 0.0017055215193126907, + "max_abs_err": 0.004010440808905967, + "tau": 0.0005457636088053268, + "s": 14.137055568563532, + "corr_length_days": 36.11566201083373, + "n_eff": 23.391350580110966, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.005568223782322914, + "prior_weight_s2": 3.72942589036619e-14, + "prior_weight_lambda": 5.471864453360481e-05 + }, + { + "seed": 2164, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7943959243085881, + "member_coverage95": 0.9566957787481805, + "member_rmse": 0.003225542675971085, + "shared_bias": -0.00047578259786276966, + "coverage68": 0.9519650655021834, + "coverage95": 1.0, + "coverage95_posterior": 0.3231441048034934, + "median_sd": 0.003158238068303635, + "median_halfwidth95": 0.006190032917304666, + "bias": -0.00047578259786276966, + "rmse": 0.0016922064955207984, + "max_abs_err": 0.005173586858791489, + "tau": 0.00045527850102285313, + "s": 12.17130107953583, + "corr_length_days": 16.378348064929735, + "n_eff": 22.302415428427107, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.008529819648099464, + "prior_weight_s2": 5.082575598329722e-14, + "prior_weight_lambda": 9.3895582434168e-06 + }, + { + "seed": 2165, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7954876273653566, + "member_coverage95": 0.9537845705967977, + "member_rmse": 0.0034891458688320314, + "shared_bias": -0.00040104056977774346, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.2925764192139738, + "median_sd": 0.0031840326171539203, + "median_halfwidth95": 0.006240589304447466, + "bias": -0.00040104056977774346, + "rmse": 0.001587852916497046, + "max_abs_err": 0.0034431095671730366, + "tau": 0.00035821711256155874, + "s": 12.365414480992143, + "corr_length_days": 43.619653904189086, + "n_eff": 34.41364272196253, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.015359771822267347, + "prior_weight_s2": 4.9026373572148543e-14, + "prior_weight_lambda": 1.8929518278747906e-05 + }, + { + "seed": 2166, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7867540029112081, + "member_coverage95": 0.9490538573508006, + "member_rmse": 0.0035057135484735194, + "shared_bias": -0.0005291784928442858, + "coverage68": 0.9519650655021834, + "coverage95": 1.0, + "coverage95_posterior": 0.2794759825327511, + "median_sd": 0.0033232913623269917, + "median_halfwidth95": 0.00651353143167186, + "bias": -0.0005291784928442858, + "rmse": 0.0017071649885717726, + "max_abs_err": 0.003924810792234924, + "tau": 0.0002617035087294293, + "s": 12.700853367857881, + "corr_length_days": 16.18321788908405, + "n_eff": 35.8162707577717, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03562401083259099, + "prior_weight_s2": 4.6549314909758047e-14, + "prior_weight_lambda": 9.831310591170438e-06 + }, + { + "seed": 2167, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8071324599708879, + "member_coverage95": 0.9472343522561864, + "member_rmse": 0.003448593225294177, + "shared_bias": -0.00030417804489107507, + "coverage68": 0.982532751091703, + "coverage95": 1.0, + "coverage95_posterior": 0.2794759825327511, + "median_sd": 0.003214964483967353, + "median_halfwidth95": 0.006301214649854589, + "bias": -0.00030417804489107507, + "rmse": 0.0016676723725071035, + "max_abs_err": 0.00409625712146282, + "tau": 0.00036642013271659087, + "s": 12.373168209826915, + "corr_length_days": 23.002653954136218, + "n_eff": 27.264962942426244, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.013941533907472315, + "prior_weight_s2": 4.9331142628429707e-14, + "prior_weight_lambda": 6.362985017559954e-06 + }, + { + "seed": 2168, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8049490538573508, + "member_coverage95": 0.9552401746724891, + "member_rmse": 0.0035264328592861855, + "shared_bias": -0.00040949043154651417, + "coverage68": 0.9868995633187773, + "coverage95": 1.0, + "coverage95_posterior": 0.3406113537117904, + "median_sd": 0.003311009014932326, + "median_halfwidth95": 0.006489458472942821, + "bias": -0.00040949043154651417, + "rmse": 0.001599112785708917, + "max_abs_err": 0.0038687206812958947, + "tau": 0.0005306566596614443, + "s": 13.106223590864763, + "corr_length_days": 24.382266937938635, + "n_eff": 20.553638157869823, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.00632504765777494, + "prior_weight_s2": 4.401152454533371e-14, + "prior_weight_lambda": 4.4536926132244845e-06 + }, + { + "seed": 2169, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7860262008733624, + "member_coverage95": 0.9516011644832606, + "member_rmse": 0.0033828166760032563, + "shared_bias": -0.0003686752243888205, + "coverage68": 0.9475982532751092, + "coverage95": 1.0, + "coverage95_posterior": 0.314410480349345, + "median_sd": 0.0031359191541533212, + "median_halfwidth95": 0.00614628864905096, + "bias": -0.0003686752243888205, + "rmse": 0.0015999926691849138, + "max_abs_err": 0.0044654033721482495, + "tau": 0.00011222589993100415, + "s": 12.207237865977719, + "corr_length_days": 28.074341620580338, + "n_eff": 45.39437077019864, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.3014291461867798, + "prior_weight_s2": 5.058025222741912e-14, + "prior_weight_lambda": 7.2741077983549585e-06 + }, + { + "seed": 2170, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8005822416302766, + "member_coverage95": 0.9530567685589519, + "member_rmse": 0.003395089309980055, + "shared_bias": -0.0005229247912002982, + "coverage68": 0.9781659388646288, + "coverage95": 1.0, + "coverage95_posterior": 0.3930131004366812, + "median_sd": 0.0032073416961835286, + "median_halfwidth95": 0.006286274260218654, + "bias": -0.0005229247912002982, + "rmse": 0.0014804782071138828, + "max_abs_err": 0.005028523223576033, + "tau": 0.0005233574280196767, + "s": 12.010560725303552, + "corr_length_days": 8.36771676371553, + "n_eff": 22.744019483535574, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0062604748249103295, + "prior_weight_s2": 5.2147200534882015e-14, + "prior_weight_lambda": 1.0666580271611597e-05 + }, + { + "seed": 2171, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7936681222707423, + "member_coverage95": 0.9545123726346434, + "member_rmse": 0.0035414415513580237, + "shared_bias": -0.0003869793681176582, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.3406113537117904, + "median_sd": 0.0033451721906338767, + "median_halfwidth95": 0.006556417067443535, + "bias": -0.0003869793681176582, + "rmse": 0.0016186861901484242, + "max_abs_err": 0.0036213578264155276, + "tau": 0.00048003455751747967, + "s": 13.016723044911629, + "corr_length_days": 48.390218531235774, + "n_eff": 28.147098215398337, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.007508445459796755, + "prior_weight_s2": 4.4502948990787164e-14, + "prior_weight_lambda": 5.637637015902062e-06 + }, + { + "seed": 2172, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7900291120815138, + "member_coverage95": 0.9526928675400291, + "member_rmse": 0.0032961053766322134, + "shared_bias": -0.00047854351239442697, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.34497816593886466, + "median_sd": 0.0032349622430789386, + "median_halfwidth95": 0.006340409537793969, + "bias": -0.00047854351239442697, + "rmse": 0.0014931686703184616, + "max_abs_err": 0.003514646230718152, + "tau": 0.0005399627643915334, + "s": 12.250256696479088, + "corr_length_days": 16.221806294105505, + "n_eff": 19.371990886663227, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.006013551621615541, + "prior_weight_s2": 4.983750467344499e-14, + "prior_weight_lambda": 1.9694701536357128e-05 + }, + { + "seed": 2173, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.789665211062591, + "member_coverage95": 0.950509461426492, + "member_rmse": 0.0037451122265794077, + "shared_bias": -0.000434673885358881, + "coverage68": 0.982532751091703, + "coverage95": 1.0, + "coverage95_posterior": 0.4017467248908297, + "median_sd": 0.0034655654232581394, + "median_halfwidth95": 0.006792383469230716, + "bias": -0.000434673885358881, + "rmse": 0.0017172139260123638, + "max_abs_err": 0.00491180645040028, + "tau": 0.0005110563973779957, + "s": 13.298433322089453, + "corr_length_days": 48.15336341081259, + "n_eff": 25.761129400772713, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.006748537141693229, + "prior_weight_s2": 4.26147539408252e-14, + "prior_weight_lambda": 5.325172756509002e-06 + }, + { + "seed": 2174, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7711062590975255, + "member_coverage95": 0.9421397379912664, + "member_rmse": 0.003436101349184567, + "shared_bias": -0.0005667448741397493, + "coverage68": 0.9737991266375546, + "coverage95": 1.0, + "coverage95_posterior": 0.3406113537117904, + "median_sd": 0.003229197843344756, + "median_halfwidth95": 0.006329111521833361, + "bias": -0.0005667448741397493, + "rmse": 0.0016839416112917345, + "max_abs_err": 0.003750374831718728, + "tau": 0.0005964016425330926, + "s": 12.534567788682166, + "corr_length_days": 33.465232755877665, + "n_eff": 18.372921183053734, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.004796307731148753, + "prior_weight_s2": 4.793066516480196e-14, + "prior_weight_lambda": 7.961485892410852e-06 + }, + { + "seed": 2175, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8096797671033479, + "member_coverage95": 0.9490538573508006, + "member_rmse": 0.0035583220608077703, + "shared_bias": -0.0005382501469628209, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.3318777292576419, + "median_sd": 0.0034314471638723512, + "median_halfwidth95": 0.006725512909091909, + "bias": -0.0005382501469628209, + "rmse": 0.0013661319316314777, + "max_abs_err": 0.003088888927995494, + "tau": 0.0005249783862949129, + "s": 13.279160971177406, + "corr_length_days": 11.464908231595855, + "n_eff": 22.914127672932107, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.006275963719668627, + "prior_weight_s2": 4.202270327126662e-14, + "prior_weight_lambda": 0.00012618373442378574 + }, + { + "seed": 2176, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7969432314410481, + "member_coverage95": 0.9475982532751092, + "member_rmse": 0.003709762548295068, + "shared_bias": -0.0005005884882604964, + "coverage68": 0.982532751091703, + "coverage95": 1.0, + "coverage95_posterior": 0.314410480349345, + "median_sd": 0.0034151079163464502, + "median_halfwidth95": 0.006693488572154054, + "bias": -0.0005005884882604964, + "rmse": 0.0016859121562675218, + "max_abs_err": 0.003971102198553276, + "tau": 0.0006025559509845959, + "s": 13.089224506949979, + "corr_length_days": 18.664852074873828, + "n_eff": 19.03448276011721, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.004731214661258364, + "prior_weight_s2": 4.40233561232193e-14, + "prior_weight_lambda": 8.537654752414988e-06 + }, + { + "seed": 2177, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7889374090247453, + "member_coverage95": 0.9508733624454149, + "member_rmse": 0.0032441823693598304, + "shared_bias": -0.00039034609030045626, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.26200873362445415, + "median_sd": 0.0030916389166500756, + "median_halfwidth95": 0.006059500977633149, + "bias": -0.00039034609030045626, + "rmse": 0.0015046016949038675, + "max_abs_err": 0.0036252225353230255, + "tau": 0.00030304301210938844, + "s": 12.050924379015038, + "corr_length_days": 53.743058436410934, + "n_eff": 39.04846232186246, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.022863660831690925, + "prior_weight_s2": 5.143006803994281e-14, + "prior_weight_lambda": 2.769959763982182e-05 + }, + { + "seed": 2178, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7936681222707423, + "member_coverage95": 0.9570596797671034, + "member_rmse": 0.003640292645523483, + "shared_bias": -0.0006604224334150319, + "coverage68": 0.9563318777292577, + "coverage95": 1.0, + "coverage95_posterior": 0.35807860262008734, + "median_sd": 0.0033856023473278775, + "median_halfwidth95": 0.0066356587190781365, + "bias": -0.0006604224334150319, + "rmse": 0.0018795813468773085, + "max_abs_err": 0.004876401665541546, + "tau": 0.0005957871804913997, + "s": 12.96426293058539, + "corr_length_days": 34.83553653436885, + "n_eff": 19.67641873237729, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.005146382650993174, + "prior_weight_s2": 4.484685299739042e-14, + "prior_weight_lambda": 6.060902484403256e-06 + }, + { + "seed": 2179, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7900291120815138, + "member_coverage95": 0.9523289665211062, + "member_rmse": 0.003715534547812324, + "shared_bias": -0.00024166269486506918, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.30131004366812225, + "median_sd": 0.0034794714462896823, + "median_halfwidth95": 0.006819638773755711, + "bias": -0.00024166269486506918, + "rmse": 0.001698332938089245, + "max_abs_err": 0.004235703347249275, + "tau": 0.0005390640218658081, + "s": 13.208295012200434, + "corr_length_days": 34.18196410767256, + "n_eff": 21.951204809520725, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.006100722529806589, + "prior_weight_s2": 4.3187893056752e-14, + "prior_weight_lambda": 7.315953378001928e-06 + }, + { + "seed": 2180, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7991266375545851, + "member_coverage95": 0.9501455604075691, + "member_rmse": 0.003580827994088366, + "shared_bias": -0.0005298365666872256, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.3537117903930131, + "median_sd": 0.0034031469167622, + "median_halfwidth95": 0.006670045443564909, + "bias": -0.0005298365666872256, + "rmse": 0.0016789472901922035, + "max_abs_err": 0.0036760839488944536, + "tau": 0.00043942169561875846, + "s": 13.338572258501943, + "corr_length_days": 22.27836174664648, + "n_eff": 25.566179897105993, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01012160994514736, + "prior_weight_s2": 4.2031055932056954e-14, + "prior_weight_lambda": 1.83090804238787e-05 + }, + { + "seed": 2181, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8049490538573508, + "member_coverage95": 0.9556040756914119, + "member_rmse": 0.0036068532617303827, + "shared_bias": -0.00047147255659529195, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.3056768558951965, + "median_sd": 0.003433622715363973, + "median_halfwidth95": 0.006729776911695634, + "bias": -0.00047147255659529195, + "rmse": 0.00157736423832101, + "max_abs_err": 0.003480308776468419, + "tau": 0.0005354085496629045, + "s": 13.029698908247502, + "corr_length_days": 46.04908204869641, + "n_eff": 23.180662151026613, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.005929787385182352, + "prior_weight_s2": 4.398769311083866e-14, + "prior_weight_lambda": 4.1007324179007344e-05 + }, + { + "seed": 2182, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7976710334788938, + "member_coverage95": 0.9461426491994177, + "member_rmse": 0.003453985769966638, + "shared_bias": -0.0005973600457268919, + "coverage68": 0.9781659388646288, + "coverage95": 1.0, + "coverage95_posterior": 0.34934497816593885, + "median_sd": 0.003285376613829646, + "median_halfwidth95": 0.0064392198895480085, + "bias": -0.0005973600457268919, + "rmse": 0.0015252595449290827, + "max_abs_err": 0.0038696593489140657, + "tau": 0.0004236714138774142, + "s": 12.569333184830795, + "corr_length_days": 49.78693925392744, + "n_eff": 28.734652725952614, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.010161192377436264, + "prior_weight_s2": 4.7400365114483056e-14, + "prior_weight_lambda": 1.4698757450658482e-05 + }, + { + "seed": 2183, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7951237263464338, + "member_coverage95": 0.9548762736535662, + "member_rmse": 0.0037240361152387413, + "shared_bias": -0.0006087018981498331, + "coverage68": 0.9606986899563319, + "coverage95": 1.0, + "coverage95_posterior": 0.36681222707423583, + "median_sd": 0.003509565976918374, + "median_halfwidth95": 0.006878622970384844, + "bias": -0.0006087018981498331, + "rmse": 0.0017266771980270692, + "max_abs_err": 0.004267420840558765, + "tau": 0.0006037951359869749, + "s": 13.500502446958654, + "corr_length_days": 31.068589387656825, + "n_eff": 20.343257770639948, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.004533879939888457, + "prior_weight_s2": 4.12477956900602e-14, + "prior_weight_lambda": 7.640474007449324e-06 + }, + { + "seed": 2184, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.779839883551674, + "member_coverage95": 0.9410480349344978, + "member_rmse": 0.0032930149351042873, + "shared_bias": -0.0004527164617122816, + "coverage68": 0.9650655021834061, + "coverage95": 1.0, + "coverage95_posterior": 0.34934497816593885, + "median_sd": 0.003102690597020194, + "median_halfwidth95": 0.006081161873298088, + "bias": -0.0004527164617122816, + "rmse": 0.0014797904132584385, + "max_abs_err": 0.003713863718766566, + "tau": 0.00019267683370060808, + "s": 11.807435847480667, + "corr_length_days": 32.90136764710147, + "n_eff": 39.80630113162402, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.07767187506593845, + "prior_weight_s2": 5.360649152970996e-14, + "prior_weight_lambda": 2.878698876605328e-05 + }, + { + "seed": 2185, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7751091703056768, + "member_coverage95": 0.9428675400291121, + "member_rmse": 0.0034856813847975476, + "shared_bias": -0.000544779188338748, + "coverage68": 0.9388646288209607, + "coverage95": 1.0, + "coverage95_posterior": 0.30131004366812225, + "median_sd": 0.003084601474624508, + "median_halfwidth95": 0.006045707844610949, + "bias": -0.000544779188338748, + "rmse": 0.00171048346422532, + "max_abs_err": 0.0041942556359140515, + "tau": 0.0004219193284912073, + "s": 11.78958243139707, + "corr_length_days": 8.285860653977752, + "n_eff": 29.145993324135976, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.010233969371037259, + "prior_weight_s2": 5.385198950621972e-14, + "prior_weight_lambda": 2.216173840606468e-05 + }, + { + "seed": 2186, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7820232896652111, + "member_coverage95": 0.9381368267831149, + "member_rmse": 0.0034272094294799144, + "shared_bias": -0.0005167591091222951, + "coverage68": 0.9694323144104804, + "coverage95": 1.0, + "coverage95_posterior": 0.34497816593886466, + "median_sd": 0.0031428416634180297, + "median_halfwidth95": 0.006159856517999455, + "bias": -0.0005167591091222951, + "rmse": 0.0015834345096757097, + "max_abs_err": 0.003733903947930012, + "tau": 0.0005073547538626849, + "s": 12.012920807348165, + "corr_length_days": 12.90716001923817, + "n_eff": 21.268234931661446, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.006493737501170076, + "prior_weight_s2": 5.228206765747049e-14, + "prior_weight_lambda": 6.121267001895386e-06 + }, + { + "seed": 2187, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8020378457059679, + "member_coverage95": 0.9545123726346434, + "member_rmse": 0.0036383290363468193, + "shared_bias": -0.0003949935598587882, + "coverage68": 0.982532751091703, + "coverage95": 1.0, + "coverage95_posterior": 0.29694323144104806, + "median_sd": 0.0033280435395410014, + "median_halfwidth95": 0.00652284552793294, + "bias": -0.0003949935598587882, + "rmse": 0.001623119271460992, + "max_abs_err": 0.0038124879637693606, + "tau": 0.00043242385083124, + "s": 12.726183959602691, + "corr_length_days": 38.268704159017204, + "n_eff": 26.75722085678329, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.009477369704492797, + "prior_weight_s2": 4.61512002771593e-14, + "prior_weight_lambda": 3.6283853619706155e-05 + }, + { + "seed": 2188, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7969432314410481, + "member_coverage95": 0.9443231441048034, + "member_rmse": 0.003350537571847371, + "shared_bias": -0.0005049766789387793, + "coverage68": 0.9694323144104804, + "coverage95": 1.0, + "coverage95_posterior": 0.32751091703056767, + "median_sd": 0.0031521294603825407, + "median_halfwidth95": 0.006178060265689206, + "bias": -0.0005049766789387793, + "rmse": 0.001524322078104027, + "max_abs_err": 0.003474511942338204, + "tau": 0.00034047388915961794, + "s": 11.989816657735506, + "corr_length_days": 46.22646787457106, + "n_eff": 34.50734189464268, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01995574008541509, + "prior_weight_s2": 5.213964786328145e-14, + "prior_weight_lambda": 1.714932048990731e-05 + }, + { + "seed": 2189, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8009461426491994, + "member_coverage95": 0.9479621542940321, + "member_rmse": 0.003537329334495266, + "shared_bias": -0.00040544208005943575, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.3231441048034934, + "median_sd": 0.0032374795961565184, + "median_halfwidth95": 0.006345343459201315, + "bias": -0.00040544208005943575, + "rmse": 0.0015242154741847592, + "max_abs_err": 0.003611985666035901, + "tau": 0.000584813576395879, + "s": 12.173852169049814, + "corr_length_days": 25.696867650500817, + "n_eff": 18.418839417758317, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0047821574275735594, + "prior_weight_s2": 5.0727561972142815e-14, + "prior_weight_lambda": 9.908002244399957e-06 + }, + { + "seed": 2190, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7849344978165939, + "member_coverage95": 0.9425036390101892, + "member_rmse": 0.0035398599606504214, + "shared_bias": -0.00044808628690860987, + "coverage68": 0.9563318777292577, + "coverage95": 1.0, + "coverage95_posterior": 0.314410480349345, + "median_sd": 0.0032573418408765454, + "median_halfwidth95": 0.006384272743811758, + "bias": -0.00044808628690860987, + "rmse": 0.0016535397789058008, + "max_abs_err": 0.0038918107768904893, + "tau": 0.0004863778620703513, + "s": 12.33003165620424, + "corr_length_days": 58.82441614798537, + "n_eff": 25.59059296059517, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.007838693487689634, + "prior_weight_s2": 4.944654606031831e-14, + "prior_weight_lambda": 1.2632702302770882e-05 + }, + { + "seed": 2191, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8060407569141194, + "member_coverage95": 0.9508733624454149, + "member_rmse": 0.0034684219997940307, + "shared_bias": -0.0003473702257583085, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.31877729257641924, + "median_sd": 0.0033392767636198956, + "median_halfwidth95": 0.006544862242731505, + "bias": -0.0003473702257583085, + "rmse": 0.001568157995379941, + "max_abs_err": 0.003936932972624518, + "tau": 0.0004881728039866128, + "s": 12.712842394134341, + "corr_length_days": 33.521015541209, + "n_eff": 24.03161112175033, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.007141581736401889, + "prior_weight_s2": 4.645381033160614e-14, + "prior_weight_lambda": 1.583967917795236e-05 + }, + { + "seed": 2192, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7809315866084425, + "member_coverage95": 0.9457787481804949, + "member_rmse": 0.00329338865661273, + "shared_bias": -0.000289765434984427, + "coverage68": 0.9868995633187773, + "coverage95": 1.0, + "coverage95_posterior": 0.3318777292576419, + "median_sd": 0.0030741637158628278, + "median_halfwidth95": 0.0060252502131973714, + "bias": -0.000289765434984427, + "rmse": 0.0015758077157731797, + "max_abs_err": 0.003990788611940785, + "tau": 9.026279036554443e-05, + "s": 12.043602830261923, + "corr_length_days": 22.853632698166212, + "n_eff": 42.58985745368824, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.4853620432446314, + "prior_weight_s2": 5.1673405391623744e-14, + "prior_weight_lambda": 1.2068462405581135e-05 + }, + { + "seed": 2193, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7954876273653566, + "member_coverage95": 0.9428675400291121, + "member_rmse": 0.003599767091050599, + "shared_bias": -0.00048617774015873857, + "coverage68": 0.9737991266375546, + "coverage95": 1.0, + "coverage95_posterior": 0.2794759825327511, + "median_sd": 0.0034768905555446505, + "median_halfwidth95": 0.006814580320807516, + "bias": -0.00048617774015873857, + "rmse": 0.0015803365571972806, + "max_abs_err": 0.0045315300013791535, + "tau": 0.0004088970668016661, + "s": 13.201801249199825, + "corr_length_days": 45.78421748393041, + "n_eff": 31.87581932761174, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01075129108839861, + "prior_weight_s2": 4.277315546514541e-14, + "prior_weight_lambda": 5.1086718223276424e-05 + }, + { + "seed": 2194, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7893013100436681, + "member_coverage95": 0.9446870451237264, + "member_rmse": 0.003458548277095958, + "shared_bias": -0.0004815160766492839, + "coverage68": 0.9694323144104804, + "coverage95": 1.0, + "coverage95_posterior": 0.32751091703056767, + "median_sd": 0.0031408482875993765, + "median_halfwidth95": 0.006155949573156424, + "bias": -0.0004815160766492839, + "rmse": 0.0016580069052613612, + "max_abs_err": 0.004362395848250119, + "tau": 0.0005970098294918046, + "s": 11.853122496053707, + "corr_length_days": 51.83172301303124, + "n_eff": 19.81333615171604, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.004831174757441565, + "prior_weight_s2": 5.3713425903626505e-14, + "prior_weight_lambda": 6.109302839345793e-06 + }, + { + "seed": 2195, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7852983988355168, + "member_coverage95": 0.9395924308588064, + "member_rmse": 0.0037290893436127764, + "shared_bias": -0.0005891957971947643, + "coverage68": 0.9563318777292577, + "coverage95": 1.0, + "coverage95_posterior": 0.38427947598253276, + "median_sd": 0.003384000294469962, + "median_halfwidth95": 0.006632518753150525, + "bias": -0.0005891957971947643, + "rmse": 0.0017080128894561807, + "max_abs_err": 0.004260806206674626, + "tau": 0.0005697738046003546, + "s": 12.936179218223366, + "corr_length_days": 12.229484639476128, + "n_eff": 20.37762663674047, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.00523930572140804, + "prior_weight_s2": 4.464362343463017e-14, + "prior_weight_lambda": 2.3573350389974955e-05 + }, + { + "seed": 2196, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.799490538573508, + "member_coverage95": 0.9497816593886463, + "member_rmse": 0.003401290069776096, + "shared_bias": -0.0005724061714391303, + "coverage68": 0.9694323144104804, + "coverage95": 1.0, + "coverage95_posterior": 0.45414847161572053, + "median_sd": 0.0033492226874427206, + "median_halfwidth95": 0.006564355895370985, + "bias": -0.0005724061714391303, + "rmse": 0.0014939592700746922, + "max_abs_err": 0.00435856128847287, + "tau": 0.00029428927479440255, + "s": 12.92350627675678, + "corr_length_days": 34.59028227605456, + "n_eff": 35.126271455084364, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.024998602523237764, + "prior_weight_s2": 4.491538191628799e-14, + "prior_weight_lambda": 1.503618707977818e-05 + }, + { + "seed": 2197, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8162299854439592, + "member_coverage95": 0.950509461426492, + "member_rmse": 0.0037979887468451465, + "shared_bias": -0.0005258035191221571, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.34497816593886466, + "median_sd": 0.0035795692362374687, + "median_halfwidth95": 0.007015826838532934, + "bias": -0.0005258035191221571, + "rmse": 0.001627553202393967, + "max_abs_err": 0.0043320111169856314, + "tau": 0.0006242517674443822, + "s": 13.99457055376076, + "corr_length_days": 17.93711757676317, + "n_eff": 19.075768552949576, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.004383238405285592, + "prior_weight_s2": 3.837047197008905e-14, + "prior_weight_lambda": 1.0205116762598975e-05 + }, + { + "seed": 2198, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7783842794759825, + "member_coverage95": 0.9497816593886463, + "member_rmse": 0.003247733471680635, + "shared_bias": -0.00025746969785313495, + "coverage68": 0.982532751091703, + "coverage95": 1.0, + "coverage95_posterior": 0.29694323144104806, + "median_sd": 0.0030555547574894577, + "median_halfwidth95": 0.0059887773247080675, + "bias": -0.00025746969785313495, + "rmse": 0.0015296923278916637, + "max_abs_err": 0.00346037976300617, + "tau": 0.00010436818145620916, + "s": 12.022211303683275, + "corr_length_days": 18.245340823814608, + "n_eff": 38.89879562086831, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.38188342763170163, + "prior_weight_s2": 5.1868581821460274e-14, + "prior_weight_lambda": 1.207471828331953e-05 + }, + { + "seed": 2199, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7987627365356623, + "member_coverage95": 0.9537845705967977, + "member_rmse": 0.0035812745750307532, + "shared_bias": -0.0004675891227259235, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.3624454148471616, + "median_sd": 0.0033667978660825363, + "median_halfwidth95": 0.006598802612798592, + "bias": -0.0004675891227259235, + "rmse": 0.0015197571473148986, + "max_abs_err": 0.0036031897301615433, + "tau": 0.000532166659375895, + "s": 13.108684517332374, + "corr_length_days": 24.85035067397985, + "n_eff": 21.495167462304526, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.005975739884732249, + "prior_weight_s2": 4.383051353715831e-14, + "prior_weight_lambda": 7.363311864410508e-06 + } + ] +} diff --git a/paper/data/calibration/pilot_clean_n20.json b/paper/data/calibration/pilot_clean_n20.json new file mode 100644 index 0000000..c923610 --- /dev/null +++ b/paper/data/calibration/pilot_clean_n20.json @@ -0,0 +1,668 @@ +{ + "codameter_version": "0.4.0", + "git_commit": "7bfdcef47453919afb5ee5e32a0d7979330402e0", + "started_utc": "2026-09-10T18:54:20+00:00", + "finished_utc": "2026-09-10T19:04:52+00:00", + "wall_seconds": 631.575817, + "settings": { + "scenario": "clean", + "years": 2.5, + "snr": 7.0, + "cadence": 4, + "n_iter": 1200, + "burn": 400, + "thin": 2 + }, + "seeds": [ + 1000, + 1001, + 1002, + 1003, + 1004, + 1005, + 1006, + 1007, + 1008, + 1009, + 1010, + 1011, + 1012, + 1013, + 1014, + 1015, + 1016, + 1017, + 1018, + 1019 + ], + "summary": { + "n_realizations": 20, + "n_failed": 0, + "failures": [], + "margin": 0.03, + "member_coverage68": { + "mean": 0.8037663755458515, + "se": 0.002660511524997402, + "n": 20 + }, + "member_coverage95": { + "mean": 0.9550764192139738, + "se": 0.001320397077958184, + "n": 20 + }, + "member_rmse": { + "mean": 0.0022988425628368532, + "se": 2.6524377021795635e-05, + "n": 20 + }, + "shared_bias": { + "mean": -0.00017004215351686035, + "se": 1.4853385428323389e-05, + "n": 20 + }, + "coverage68": { + "mean": 0.9967248908296943, + "se": 0.0006236250770496513, + "n": 20 + }, + "coverage95": { + "mean": 1.0, + "se": 0.0, + "n": 20 + }, + "coverage95_posterior": { + "mean": 0.5930131004366812, + "se": 0.01069458502199962, + "n": 20 + }, + "median_sd": { + "mean": 0.002271807476540366, + "se": 2.1101618340464582e-05, + "n": 20 + }, + "median_halfwidth95": { + "mean": 0.004452660868949963, + "se": 4.135841228905033e-05, + "n": 20 + }, + "bias": { + "mean": -0.00017004215351686035, + "se": 1.4853385428323389e-05, + "n": 20 + }, + "rmse": { + "mean": 0.000698789111221017, + "se": 1.5443238227296262e-05, + "n": 20 + }, + "max_abs_err": { + "mean": 0.0028339310378489415, + "se": 0.0001060080345514674, + "n": 20 + }, + "tau": { + "mean": 0.0002216449082950678, + "se": 1.8731328541687664e-05, + "n": 20 + }, + "s": { + "mean": 11.742435505978671, + "se": 0.09936972988966151, + "n": 20 + }, + "corr_length_days": { + "mean": 28.894676599643436, + "se": 2.0645378476228062, + "n": 20 + }, + "n_eff": { + "mean": 33.48820076254423, + "se": 1.8025616774509405, + "n": 20 + }, + "missing_fraction": { + "mean": 0.0, + "se": 0.0, + "n": 20 + }, + "prior_weight_tau2": { + "mean": 0.09471112301083581, + "se": 0.026435439081573045, + "n": 20 + }, + "prior_weight_s2": { + "mean": 5.483022811102666e-14, + "se": 9.339709848345006e-16, + "n": 20 + }, + "prior_weight_lambda": { + "mean": 1.7391291340398028e-05, + "se": 2.715036569194347e-06, + "n": 20 + }, + "member_coverage95_within_margin": true, + "member_coverage68_within_margin": false + }, + "results": [ + { + "seed": 1000, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7965793304221251, + "member_coverage95": 0.9599708879184862, + "member_rmse": 0.002279911340018597, + "shared_bias": -0.0002703599990215597, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6244541484716157, + "median_sd": 0.0022324225068906804, + "median_halfwidth95": 0.0043754677462954856, + "bias": -0.0002703599990215597, + "rmse": 0.0005953968611226891, + "max_abs_err": 0.002082309271791779, + "tau": 0.00031150261553347826, + "s": 11.561791823971834, + "corr_length_days": 30.950588652298407, + "n_eff": 24.10824198728834, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.018632316684066806, + "prior_weight_s2": 5.5975624936899525e-14, + "prior_weight_lambda": 4.271979531874158e-05 + }, + { + "seed": 1001, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7925764192139738, + "member_coverage95": 0.9443231441048034, + "member_rmse": 0.0024030499980777233, + "shared_bias": -0.00014111743226916386, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.5938864628820961, + "median_sd": 0.0022355026383458917, + "median_halfwidth95": 0.004381504693062967, + "bias": -0.00014111743226916386, + "rmse": 0.0008515932610556482, + "max_abs_err": 0.003203379426159806, + "tau": 0.00018838420360658492, + "s": 11.580209382519135, + "corr_length_days": 45.41770508325185, + "n_eff": 39.08673418627379, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.06876945296308763, + "prior_weight_s2": 5.670747455451825e-14, + "prior_weight_lambda": 3.8772806717611845e-06 + }, + { + "seed": 1002, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.826783114992722, + "member_coverage95": 0.960334788937409, + "member_rmse": 0.002362815371835266, + "shared_bias": -0.0002666643817064384, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6026200873362445, + "median_sd": 0.0023057977903035245, + "median_halfwidth95": 0.004519280660274457, + "bias": -0.0002666643817064384, + "rmse": 0.0006326099720954976, + "max_abs_err": 0.0031126364949907418, + "tau": 0.00029902152448791383, + "s": 11.987802155708492, + "corr_length_days": 29.561866857227987, + "n_eff": 27.280179916782348, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.020374775824116367, + "prior_weight_s2": 5.234368951949217e-14, + "prior_weight_lambda": 1.83026294956077e-05 + }, + { + "seed": 1003, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8009461426491994, + "member_coverage95": 0.9596069868995634, + "member_rmse": 0.002412401400203964, + "shared_bias": -7.183627302539797e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.611353711790393, + "median_sd": 0.0022544260154693115, + "median_halfwidth95": 0.004418593830983294, + "bias": -7.183627302539797e-05, + "rmse": 0.0008167595220332827, + "max_abs_err": 0.002740188572006502, + "tau": 0.0002683053880919122, + "s": 11.763914044838552, + "corr_length_days": 27.967536670904344, + "n_eff": 27.8003905448705, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.02795035467416881, + "prior_weight_s2": 5.5012080915924525e-14, + "prior_weight_lambda": 4.736755172727345e-06 + }, + { + "seed": 1004, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7885735080058224, + "member_coverage95": 0.9454148471615721, + "member_rmse": 0.0021652927634260083, + "shared_bias": -0.00010976105288720698, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.49344978165938863, + "median_sd": 0.002124237510243205, + "median_halfwidth95": 0.004163429047526313, + "bias": -0.00010976105288720698, + "rmse": 0.0007672192322179457, + "max_abs_err": 0.003585691571966972, + "tau": 0.00012979953019198447, + "s": 11.03667296069126, + "corr_length_days": 35.7129247582563, + "n_eff": 39.75361033089848, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.16579578470064812, + "prior_weight_s2": 6.188265234711871e-14, + "prior_weight_lambda": 1.1463265912044584e-05 + }, + { + "seed": 1005, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8034934497816594, + "member_coverage95": 0.9606986899563319, + "member_rmse": 0.002255847124328808, + "shared_bias": -0.0001967860167755355, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6331877729257642, + "median_sd": 0.002317752930128503, + "median_halfwidth95": 0.004542712303946381, + "bias": -0.0001967860167755355, + "rmse": 0.0006589967291717987, + "max_abs_err": 0.0027329906079298, + "tau": 0.0001891225908469357, + "s": 11.884113970822783, + "corr_length_days": 27.509429958935186, + "n_eff": 31.762571258649743, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.058124721018428804, + "prior_weight_s2": 5.3175969125677237e-14, + "prior_weight_lambda": 2.2985779408818025e-05 + }, + { + "seed": 1006, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7991266375545851, + "member_coverage95": 0.9548762736535662, + "member_rmse": 0.0022098277356763915, + "shared_bias": -0.00016826124892689717, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5764192139737991, + "median_sd": 0.0022057003693094716, + "median_halfwidth95": 0.004323093318633269, + "bias": -0.00016826124892689717, + "rmse": 0.0006982366153072414, + "max_abs_err": 0.0027499559109918055, + "tau": 0.00016122741493306307, + "s": 11.326129104008837, + "corr_length_days": 32.1357177805466, + "n_eff": 35.75241649836525, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.09765715655123722, + "prior_weight_s2": 5.887403398811999e-14, + "prior_weight_lambda": 9.303981966731787e-06 + }, + { + "seed": 1007, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7885735080058224, + "member_coverage95": 0.9556040756914119, + "member_rmse": 0.00216244736081247, + "shared_bias": -0.0001975575305483143, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.4978165938864629, + "median_sd": 0.002107069331413141, + "median_halfwidth95": 0.004129780035073825, + "bias": -0.0001975575305483143, + "rmse": 0.0006551824541732879, + "max_abs_err": 0.002357918578161723, + "tau": 0.00011187394137301715, + "s": 11.105721117234706, + "corr_length_days": 33.41835782102334, + "n_eff": 34.39704393668614, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.23763174397777106, + "prior_weight_s2": 6.06327221457958e-14, + "prior_weight_lambda": 3.0123924368532614e-05 + }, + { + "seed": 1008, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8085880640465793, + "member_coverage95": 0.950509461426492, + "member_rmse": 0.002172233210151531, + "shared_bias": -5.322453051105241e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6637554585152838, + "median_sd": 0.002233968510338788, + "median_halfwidth95": 0.004378497857397652, + "bias": -5.322453051105241e-05, + "rmse": 0.0006336594736701756, + "max_abs_err": 0.0027636403229747038, + "tau": 0.0002952395989189862, + "s": 11.415652556747467, + "corr_length_days": 35.71586358545551, + "n_eff": 27.40933377577577, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.021299098115436906, + "prior_weight_s2": 5.809770011083185e-14, + "prior_weight_lambda": 7.003443715967435e-06 + }, + { + "seed": 1009, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7936681222707423, + "member_coverage95": 0.9490538573508006, + "member_rmse": 0.00221266349570515, + "shared_bias": -8.871149775691355e-05, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5895196506550219, + "median_sd": 0.002287760923215561, + "median_halfwidth95": 0.004483929050109264, + "bias": -8.871149775691355e-05, + "rmse": 0.0006711785243214647, + "max_abs_err": 0.0026192727758449766, + "tau": 9.824135694867393e-05, + "s": 11.843783736687499, + "corr_length_days": 17.982967584435666, + "n_eff": 36.561820920602344, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.36275473155255655, + "prior_weight_s2": 5.3566908673632126e-14, + "prior_weight_lambda": 1.4534571676378104e-05 + }, + { + "seed": 1010, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8024017467248908, + "member_coverage95": 0.9501455604075691, + "member_rmse": 0.0022887977644547655, + "shared_bias": -0.0001962600244635213, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5458515283842795, + "median_sd": 0.0022261039693455753, + "median_halfwidth95": 0.004363083640174431, + "bias": -0.0001962600244635213, + "rmse": 0.000674259600966659, + "max_abs_err": 0.0026819448058072065, + "tau": 0.0002477936272106011, + "s": 11.529084005902215, + "corr_length_days": 35.2479510641504, + "n_eff": 32.435897779943126, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03155198646688704, + "prior_weight_s2": 5.611279108401023e-14, + "prior_weight_lambda": 3.939873413020461e-05 + }, + { + "seed": 1011, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.824235807860262, + "member_coverage95": 0.9625181950509462, + "member_rmse": 0.0022342911998866465, + "shared_bias": -0.00013509754018844862, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.62882096069869, + "median_sd": 0.0023883048030004703, + "median_halfwidth95": 0.004680991434908014, + "bias": -0.00013509754018844862, + "rmse": 0.0006523525551757202, + "max_abs_err": 0.0031531807615981467, + "tau": 0.00020733710465624394, + "s": 12.247655395303063, + "corr_length_days": 40.8088999539057, + "n_eff": 36.767316002125135, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.051167065046651666, + "prior_weight_s2": 5.005027788615494e-14, + "prior_weight_lambda": 1.5193449303522468e-05 + }, + { + "seed": 1012, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8169577874818049, + "member_coverage95": 0.9592430858806404, + "member_rmse": 0.0024572587644145325, + "shared_bias": -0.00023648961575419185, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6593886462882096, + "median_sd": 0.00238956256157656, + "median_halfwidth95": 0.004683456596437841, + "bias": -0.00023648961575419185, + "rmse": 0.0006432326095562055, + "max_abs_err": 0.002950334365081424, + "tau": 0.0003392478340727002, + "s": 12.418626338869517, + "corr_length_days": 23.795749550521627, + "n_eff": 25.28573351342531, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.015001988465844497, + "prior_weight_s2": 4.880452713151198e-14, + "prior_weight_lambda": 1.9829412588626403e-05 + }, + { + "seed": 1013, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7976710334788938, + "member_coverage95": 0.950509461426492, + "member_rmse": 0.002294209779778639, + "shared_bias": -9.67573193888552e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5764192139737991, + "median_sd": 0.002255046122162911, + "median_halfwidth95": 0.004419809217778908, + "bias": -9.67573193888552e-05, + "rmse": 0.00074176648316361, + "max_abs_err": 0.0034346763896861096, + "tau": 9.167945627899141e-05, + "s": 11.8244351857143, + "corr_length_days": 8.064609889836834, + "n_eff": 58.830667253461115, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.42995696326721394, + "prior_weight_s2": 5.3953614093983064e-14, + "prior_weight_lambda": 9.15028343792859e-06 + }, + { + "seed": 1014, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7911208151382824, + "member_coverage95": 0.9537845705967977, + "member_rmse": 0.002187294550456029, + "shared_bias": -0.00016742138515687952, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5982532751091703, + "median_sd": 0.002172339850755361, + "median_halfwidth95": 0.00425770790324588, + "bias": -0.00016742138515687952, + "rmse": 0.0006362037058792295, + "max_abs_err": 0.002269327940652381, + "tau": 0.00026576940398112347, + "s": 11.285865632433206, + "corr_length_days": 31.875132136544014, + "n_eff": 28.904002467902025, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.027194012715592165, + "prior_weight_s2": 5.915506618168597e-14, + "prior_weight_lambda": 1.3410133129738923e-05 + }, + { + "seed": 1015, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8009461426491994, + "member_coverage95": 0.9566957787481805, + "member_rmse": 0.0022933550248764073, + "shared_bias": -0.00014050191793481346, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.611353711790393, + "median_sd": 0.0022588336384590044, + "median_halfwidth95": 0.004427232613368665, + "bias": -0.00014050191793481346, + "rmse": 0.0007826901936104759, + "max_abs_err": 0.003667210347106552, + "tau": 0.0001598897024021327, + "s": 11.596472104461988, + "corr_length_days": 30.113387053537554, + "n_eff": 40.62282955536182, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.12081858128541957, + "prior_weight_s2": 5.625295657168723e-14, + "prior_weight_lambda": 8.641777870928512e-06 + }, + { + "seed": 1016, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8042212518195051, + "member_coverage95": 0.9559679767103348, + "member_rmse": 0.0023451033546727155, + "shared_bias": -0.00021828865809144803, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.62882096069869, + "median_sd": 0.002373631288365493, + "median_halfwidth95": 0.004652231874469986, + "bias": -0.00021828865809144803, + "rmse": 0.0006871196663044217, + "max_abs_err": 0.0021095976076303336, + "tau": 0.00021453817277084511, + "s": 12.31505480432505, + "corr_length_days": 12.041523697379857, + "n_eff": 36.19446857473697, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.04557366415001441, + "prior_weight_s2": 4.952165320091069e-14, + "prior_weight_lambda": 1.508500695180962e-05 + }, + { + "seed": 1017, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8176855895196506, + "member_coverage95": 0.960334788937409, + "member_rmse": 0.0024850419559230524, + "shared_bias": -0.00025876292004342973, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6069868995633187, + "median_sd": 0.0024400029263837108, + "median_halfwidth95": 0.004782317895606724, + "bias": -0.00025876292004342973, + "rmse": 0.0007346818916773366, + "max_abs_err": 0.002369904606521424, + "tau": 0.00040065652579792836, + "s": 12.321367898343656, + "corr_length_days": 26.40839567585267, + "n_eff": 21.322551153400095, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.010624855039151199, + "prior_weight_s2": 4.947573763157085e-14, + "prior_weight_lambda": 1.3036881409756237e-05 + }, + { + "seed": 1018, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8224163027656477, + "member_coverage95": 0.9643377001455604, + "member_rmse": 0.0025755305039327483, + "shared_bias": -0.000242035920224602, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5152838427947598, + "median_sd": 0.002427276974340479, + "median_halfwidth95": 0.004757375487736262, + "bias": -0.000242035920224602, + "rmse": 0.0006764226609529205, + "max_abs_err": 0.0026738165443279983, + "tau": 0.0002443668518737805, + "s": 12.498043713620014, + "corr_length_days": 18.135749333646267, + "n_eff": 32.452321207701466, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03578990694733931, + "prior_weight_s2": 4.789247309626705e-14, + "prior_weight_lambda": 4.2189238629425646e-05 + }, + { + "seed": 1019, + "scenario": "clean", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7987627365356623, + "member_coverage95": 0.9475982532751092, + "member_rmse": 0.002179478558105623, + "shared_bias": -0.00014494780566253794, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.6026200873362445, + "median_sd": 0.0022004088707596793, + "median_halfwidth95": 0.004312722171969624, + "bias": -0.00014494780566253794, + "rmse": 0.000766220211964728, + "max_abs_err": 0.0034206438557484484, + "tau": 0.00020890132192446026, + "s": 11.306314187369807, + "corr_length_days": 35.02917488515867, + "n_eff": 33.03588438663471, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.04755330077108403, + "prior_weight_s2": 5.911660902474103e-14, + "prior_weight_lambda": 6.839481648709111e-06 + } + ] +} diff --git a/paper/data/calibration/pilot_clock_drift_n20.json b/paper/data/calibration/pilot_clock_drift_n20.json new file mode 100644 index 0000000..58c78ad --- /dev/null +++ b/paper/data/calibration/pilot_clock_drift_n20.json @@ -0,0 +1,668 @@ +{ + "codameter_version": "0.4.0", + "git_commit": "5d1ae802e3ff233c3291e1c88d7989ce27f23445", + "started_utc": "2026-09-10T19:04:55+00:00", + "finished_utc": "2026-09-10T19:41:53+00:00", + "wall_seconds": 2217.895121, + "settings": { + "scenario": "clock_drift", + "years": 2.5, + "snr": 7.0, + "cadence": 4, + "n_iter": 1200, + "burn": 400, + "thin": 2 + }, + "seeds": [ + 1000, + 1001, + 1002, + 1003, + 1004, + 1005, + 1006, + 1007, + 1008, + 1009, + 1010, + 1011, + 1012, + 1013, + 1014, + 1015, + 1016, + 1017, + 1018, + 1019 + ], + "summary": { + "n_realizations": 20, + "n_failed": 0, + "failures": [], + "margin": 0.03, + "member_coverage68": { + "mean": 0.7994177583697234, + "se": 0.003008760662327549, + "n": 20 + }, + "member_coverage95": { + "mean": 0.9525836972343521, + "se": 0.0013054335919963284, + "n": 20 + }, + "member_rmse": { + "mean": 0.0022952541438208997, + "se": 2.6002095063346253e-05, + "n": 20 + }, + "shared_bias": { + "mean": -0.00018029255804363772, + "se": 1.4544327329774822e-05, + "n": 20 + }, + "coverage68": { + "mean": 0.9971615720524017, + "se": 0.0005733150854179016, + "n": 20 + }, + "coverage95": { + "mean": 1.0, + "se": 0.0, + "n": 20 + }, + "coverage95_posterior": { + "mean": 0.6120087336244542, + "se": 0.011093833776852418, + "n": 20 + }, + "median_sd": { + "mean": 0.0022431994191602043, + "se": 2.1742234278442762e-05, + "n": 20 + }, + "median_halfwidth95": { + "mean": 0.00439659010637491, + "se": 4.261399646531381e-05, + "n": 20 + }, + "bias": { + "mean": -0.00018029255804363772, + "se": 1.4544327329774822e-05, + "n": 20 + }, + "rmse": { + "mean": 0.0006864289818403638, + "se": 1.5808862465040705e-05, + "n": 20 + }, + "max_abs_err": { + "mean": 0.002774123992794585, + "se": 0.00010774912893477555, + "n": 20 + }, + "tau": { + "mean": 0.0002273234260823591, + "se": 1.843833735251731e-05, + "n": 20 + }, + "s": { + "mean": 10.950959399864546, + "se": 0.09584049160874432, + "n": 20 + }, + "corr_length_days": { + "mean": 27.359388387349252, + "se": 2.074734078201324, + "n": 20 + }, + "n_eff": { + "mean": 33.55640816141477, + "se": 1.834609681254573, + "n": 20 + }, + "missing_fraction": { + "mean": 0.0, + "se": 0.0, + "n": 20 + }, + "prior_weight_tau2": { + "mean": 0.08519855338776665, + "se": 0.02347113852588594, + "n": 20 + }, + "prior_weight_s2": { + "mean": 6.294993544570372e-14, + "se": 1.1156324951142926e-15, + "n": 20 + }, + "prior_weight_lambda": { + "mean": 2.222406736424732e-05, + "se": 3.880100372705388e-06, + "n": 20 + }, + "member_coverage95_within_margin": true, + "member_coverage68_within_margin": false + }, + "results": [ + { + "seed": 1000, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7973071324599709, + "member_coverage95": 0.9552401746724891, + "member_rmse": 0.002282480905525119, + "shared_bias": -0.000278914381157261, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6637554585152838, + "median_sd": 0.002258722342825476, + "median_halfwidth95": 0.004427014477933591, + "bias": -0.000278914381157261, + "rmse": 0.0005819657742571976, + "max_abs_err": 0.0021251600312500135, + "tau": 0.0002954105457197348, + "s": 10.915955484907965, + "corr_length_days": 33.19012848551535, + "n_eff": 26.62349996399447, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.02102810833160571, + "prior_weight_s2": 6.263459084873332e-14, + "prior_weight_lambda": 6.502942135784756e-05 + }, + { + "seed": 1001, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.787117903930131, + "member_coverage95": 0.9425036390101892, + "member_rmse": 0.0024046210546445953, + "shared_bias": -0.00015077776757696162, + "coverage68": 0.9912663755458515, + "coverage95": 1.0, + "coverage95_posterior": 0.5982532751091703, + "median_sd": 0.0021673766101352023, + "median_halfwidth95": 0.004247980130307032, + "bias": -0.00015077776757696162, + "rmse": 0.0008296516421031915, + "max_abs_err": 0.003135889698481958, + "tau": 0.00023703165437846026, + "s": 10.67701809601613, + "corr_length_days": 41.78670774760895, + "n_eff": 34.39589845038631, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03663168327859234, + "prior_weight_s2": 6.660919519899585e-14, + "prior_weight_lambda": 4.509877843937647e-06 + }, + { + "seed": 1002, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8293304221251819, + "member_coverage95": 0.9610625909752547, + "member_rmse": 0.002364561946077854, + "shared_bias": -0.00028393294596069067, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6550218340611353, + "median_sd": 0.0023346829150382347, + "median_halfwidth95": 0.0045758944648899985, + "bias": -0.00028393294596069067, + "rmse": 0.0006191507447365322, + "max_abs_err": 0.003098246563581019, + "tau": 0.0003484169659830969, + "s": 11.230181630463013, + "corr_length_days": 28.30882723573345, + "n_eff": 24.16960019682101, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.014170473690987782, + "prior_weight_s2": 5.95095058914989e-14, + "prior_weight_lambda": 2.437407587482324e-05 + }, + { + "seed": 1003, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7998544395924309, + "member_coverage95": 0.9548762736535662, + "member_rmse": 0.002410499303166505, + "shared_bias": -8.717987452929081e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.62882096069869, + "median_sd": 0.0022450100023860874, + "median_halfwidth95": 0.004400138784316645, + "bias": -8.717987452929081e-05, + "rmse": 0.0008030194968310628, + "max_abs_err": 0.0027580141569534407, + "tau": 0.000270139927250039, + "s": 10.957020241648154, + "corr_length_days": 24.895564449863837, + "n_eff": 27.83089861159601, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.02726820602225128, + "prior_weight_s2": 6.32582918486376e-14, + "prior_weight_lambda": 5.774997616519321e-06 + }, + { + "seed": 1004, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7812954876273653, + "member_coverage95": 0.9417758369723436, + "member_rmse": 0.002165163839644261, + "shared_bias": -0.00011054080064411575, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5545851528384279, + "median_sd": 0.0020822109321845944, + "median_halfwidth95": 0.004081058467488246, + "bias": -0.00011054080064411575, + "rmse": 0.0007721997933848498, + "max_abs_err": 0.0036888597843051734, + "tau": 0.000140853679762062, + "s": 10.34776689541538, + "corr_length_days": 33.60864404144874, + "n_eff": 40.41097698267077, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.13803845433591663, + "prior_weight_s2": 7.034690065937594e-14, + "prior_weight_lambda": 1.1856841767370412e-05 + }, + { + "seed": 1005, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7933042212518195, + "member_coverage95": 0.9556040756914119, + "member_rmse": 0.0022543235466960547, + "shared_bias": -0.00019359405041921283, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6244541484716157, + "median_sd": 0.002263139432453543, + "median_halfwidth95": 0.004435671814589376, + "bias": -0.00019359405041921283, + "rmse": 0.0006493493010683543, + "max_abs_err": 0.00252112456590525, + "tau": 0.0001416038651208217, + "s": 10.976220163100262, + "corr_length_days": 23.066653418517973, + "n_eff": 36.76212157994985, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.12088450025280349, + "prior_weight_s2": 6.226157812363687e-14, + "prior_weight_lambda": 2.4156094217014846e-05 + }, + { + "seed": 1006, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7849344978165939, + "member_coverage95": 0.950509461426492, + "member_rmse": 0.002206894716419459, + "shared_bias": -0.00018174961571762056, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5589519650655022, + "median_sd": 0.002156284077686622, + "median_halfwidth95": 0.004226239166038983, + "bias": -0.00018174961571762056, + "rmse": 0.0006890469849966209, + "max_abs_err": 0.0024853886535623135, + "tau": 0.00015942089416851206, + "s": 10.426766989327819, + "corr_length_days": 28.422701909538056, + "n_eff": 36.136906740688936, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.10136299504676614, + "prior_weight_s2": 6.934274765823003e-14, + "prior_weight_lambda": 1.1157842014822111e-05 + }, + { + "seed": 1007, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7805676855895196, + "member_coverage95": 0.9519650655021834, + "member_rmse": 0.0021660528927198866, + "shared_bias": -0.00021229763034465605, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.537117903930131, + "median_sd": 0.0020752268294776974, + "median_halfwidth95": 0.004067369877610426, + "bias": -0.00021229763034465605, + "rmse": 0.0006584634211904179, + "max_abs_err": 0.002238908460367836, + "tau": 0.00011496317342192552, + "s": 10.339454481601367, + "corr_length_days": 37.12828960342101, + "n_eff": 36.7172213510138, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.2234420252910042, + "prior_weight_s2": 6.984186104996771e-14, + "prior_weight_lambda": 3.7317673949672344e-05 + }, + { + "seed": 1008, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8089519650655022, + "member_coverage95": 0.9494177583697234, + "member_rmse": 0.0021772680503117964, + "shared_bias": -7.705170220356905e-05, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6943231441048034, + "median_sd": 0.00219925407179383, + "median_halfwidth95": 0.004310458807569322, + "bias": -7.705170220356905e-05, + "rmse": 0.0006251103429422171, + "max_abs_err": 0.002831045220979609, + "tau": 0.00026013765940062196, + "s": 10.767635017293886, + "corr_length_days": 36.750708301872216, + "n_eff": 30.428922281214156, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.028713482925011025, + "prior_weight_s2": 6.512848747103414e-14, + "prior_weight_lambda": 8.647895051892503e-06 + }, + { + "seed": 1009, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7878457059679768, + "member_coverage95": 0.9490538573508006, + "member_rmse": 0.002215429087802446, + "shared_bias": -9.516221415732181e-05, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6069868995633187, + "median_sd": 0.0022960395821817812, + "median_halfwidth95": 0.004500154923651333, + "bias": -9.516221415732181e-05, + "rmse": 0.0006499729850357877, + "max_abs_err": 0.0026411204256550406, + "tau": 0.00010923269232955415, + "s": 11.136560101632984, + "corr_length_days": 17.39422919133644, + "n_eff": 37.52908423437507, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.2779134571492754, + "prior_weight_s2": 6.045464075502714e-14, + "prior_weight_lambda": 1.9026688591303237e-05 + }, + { + "seed": 1010, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7976710334788938, + "member_coverage95": 0.9526928675400291, + "member_rmse": 0.0022676744663618314, + "shared_bias": -0.0002012407864330994, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.537117903930131, + "median_sd": 0.0021926381595798092, + "median_halfwidth95": 0.004297491857802681, + "bias": -0.0002012407864330994, + "rmse": 0.000665461232481989, + "max_abs_err": 0.002639487575679975, + "tau": 0.0002395736836242952, + "s": 10.741046577037581, + "corr_length_days": 28.774994324772834, + "n_eff": 31.39669894317982, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03404120482625028, + "prior_weight_s2": 6.44830772363446e-14, + "prior_weight_lambda": 5.9245175693226446e-05 + }, + { + "seed": 1011, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8147743813682679, + "member_coverage95": 0.9588791848617176, + "member_rmse": 0.0022081811304350166, + "shared_bias": -0.00013612425944413523, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6331877729257642, + "median_sd": 0.002341312421549292, + "median_halfwidth95": 0.004588888058989437, + "bias": -0.00013612425944413523, + "rmse": 0.0006176721944471783, + "max_abs_err": 0.0028021500860964817, + "tau": 0.00017647556763555715, + "s": 11.31884032310757, + "corr_length_days": 31.41326997384057, + "n_eff": 35.36973935215846, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.07688437187149692, + "prior_weight_s2": 5.845053680836984e-14, + "prior_weight_lambda": 2.0645034757358053e-05 + }, + { + "seed": 1012, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8096797671033479, + "member_coverage95": 0.9588791848617176, + "member_rmse": 0.002445323798898625, + "shared_bias": -0.00023888949192853425, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6768558951965066, + "median_sd": 0.0023340808728163193, + "median_halfwidth95": 0.004574714483808565, + "bias": -0.00023888949192853425, + "rmse": 0.0006204784451263063, + "max_abs_err": 0.002770355476346859, + "tau": 0.0003483001504716803, + "s": 11.611907049769517, + "corr_length_days": 26.365945093307673, + "n_eff": 24.59378624040778, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.014023855527502562, + "prior_weight_s2": 5.568021597185502e-14, + "prior_weight_lambda": 2.8030739674216385e-05 + }, + { + "seed": 1013, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7947598253275109, + "member_coverage95": 0.9497816593886463, + "member_rmse": 0.002297716281439365, + "shared_bias": -0.000100856234484782, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.5807860262008734, + "median_sd": 0.002237457773186184, + "median_halfwidth95": 0.004385336686965086, + "bias": -0.000100856234484782, + "rmse": 0.0007363187300673177, + "max_abs_err": 0.0033319873247646577, + "tau": 9.454946149284892e-05, + "s": 11.048887603239722, + "corr_length_days": 7.733895080060093, + "n_eff": 60.058677407388366, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.40795702271156803, + "prior_weight_s2": 6.175561213853912e-14, + "prior_weight_lambda": 9.174612919773585e-06 + }, + { + "seed": 1014, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7893013100436681, + "member_coverage95": 0.9483260553129549, + "member_rmse": 0.0021842393996638265, + "shared_bias": -0.00018032042554858255, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6200873362445415, + "median_sd": 0.0021430661428354317, + "median_halfwidth95": 0.004200332489576304, + "bias": -0.00018032042554858255, + "rmse": 0.0006194912570270847, + "max_abs_err": 0.0022532570553335913, + "tau": 0.00027024168105444695, + "s": 10.53346366099354, + "corr_length_days": 29.690943633650335, + "n_eff": 28.644857553951336, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.025393334000792266, + "prior_weight_s2": 6.774464404359878e-14, + "prior_weight_lambda": 1.7377966259520577e-05 + }, + { + "seed": 1015, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8005822416302766, + "member_coverage95": 0.9530567685589519, + "member_rmse": 0.0022888772128056064, + "shared_bias": -0.00015856224483455956, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6637554585152838, + "median_sd": 0.0022344104498186663, + "median_halfwidth95": 0.004379364042868392, + "bias": -0.00015856224483455956, + "rmse": 0.0007721694568233897, + "max_abs_err": 0.0037097696018792707, + "tau": 0.0002255875896309769, + "s": 10.846321872398862, + "corr_length_days": 33.96263577072983, + "n_eff": 34.75534620985516, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.04479980688454087, + "prior_weight_s2": 6.427106179806405e-14, + "prior_weight_lambda": 9.339972835760362e-06 + }, + { + "seed": 1016, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8027656477438136, + "member_coverage95": 0.9545123726346434, + "member_rmse": 0.0023438599357201795, + "shared_bias": -0.00024158314924560523, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6419213973799127, + "median_sd": 0.002389519676266715, + "median_halfwidth95": 0.004683372542774416, + "bias": -0.00024158314924560523, + "rmse": 0.0006695459857669313, + "max_abs_err": 0.0021406194084133304, + "tau": 0.00023004314715527563, + "s": 11.637345414367363, + "corr_length_days": 8.178715251576815, + "n_eff": 40.731541156329065, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03812265222203544, + "prior_weight_s2": 5.532895469324741e-14, + "prior_weight_lambda": 1.9831450734212483e-05 + }, + { + "seed": 1017, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8198689956331878, + "member_coverage95": 0.9577874818049491, + "member_rmse": 0.002480015044684322, + "shared_bias": -0.00026312895041537396, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.6331877729257642, + "median_sd": 0.0024230813986268348, + "median_halfwidth95": 0.004749152310378246, + "bias": -0.00026312895041537396, + "rmse": 0.0007174839498021474, + "max_abs_err": 0.0022398631908421575, + "tau": 0.0003773942579604618, + "s": 11.528176806277218, + "corr_length_days": 23.40965649347658, + "n_eff": 22.238366113478506, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.012085050418600259, + "prior_weight_s2": 5.642702371810706e-14, + "prior_weight_lambda": 1.4941997243308271e-05 + }, + { + "seed": 1018, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8162299854439592, + "member_coverage95": 0.9621542940320232, + "member_rmse": 0.0025608541409710773, + "shared_bias": -0.00023658128942920825, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.5240174672489083, + "median_sd": 0.0023292350248900616, + "median_halfwidth95": 0.004565216796323625, + "bias": -0.00023658128942920825, + "rmse": 0.0006714185773335946, + "max_abs_err": 0.0027505614818644033, + "tau": 0.00024545036033927397, + "s": 11.553486155929425, + "corr_length_days": 16.38815783502839, + "n_eff": 32.318458572856116, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03498008301087486, + "prior_weight_s2": 5.6001133100732425e-14, + "prior_weight_lambda": 4.667253456177407e-05 + }, + { + "seed": 1019, + "scenario": "clock_drift", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7922125181950509, + "member_coverage95": 0.9435953420669578, + "member_rmse": 0.0021810461224301683, + "shared_bias": -0.00017736334639817416, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.6069868995633187, + "median_sd": 0.0021612396674717026, + "median_halfwidth95": 0.004235951943616508, + "bias": -0.00017736334639817416, + "rmse": 0.0007606093213851048, + "max_abs_err": 0.0033206710936293338, + "tau": 0.00026164156474753727, + "s": 10.425133432763154, + "corr_length_days": 36.71709990568597, + "n_eff": 30.01556128598047, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.02623029995745777, + "prior_weight_s2": 6.946864990007857e-14, + "prior_weight_lambda": 7.3704543205929725e-06 + } + ] +} diff --git a/paper/data/calibration/pilot_shared_source_n20.json b/paper/data/calibration/pilot_shared_source_n20.json new file mode 100644 index 0000000..9cb8179 --- /dev/null +++ b/paper/data/calibration/pilot_shared_source_n20.json @@ -0,0 +1,668 @@ +{ + "codameter_version": "0.4.0", + "git_commit": "5d1ae802e3ff233c3291e1c88d7989ce27f23445", + "started_utc": "2026-09-10T19:44:29+00:00", + "finished_utc": "2026-09-10T19:52:50+00:00", + "wall_seconds": 500.821647, + "settings": { + "scenario": "shared_source", + "years": 2.5, + "snr": 7.0, + "cadence": 4, + "n_iter": 1200, + "burn": 400, + "thin": 2 + }, + "seeds": [ + 1000, + 1001, + 1002, + 1003, + 1004, + 1005, + 1006, + 1007, + 1008, + 1009, + 1010, + 1011, + 1012, + 1013, + 1014, + 1015, + 1016, + 1017, + 1018, + 1019 + ], + "summary": { + "n_realizations": 20, + "n_failed": 0, + "failures": [], + "margin": 0.03, + "member_coverage68": { + "mean": 0.7935407569141193, + "se": 0.0036671777203424604, + "n": 20 + }, + "member_coverage95": { + "mean": 0.9503093158660845, + "se": 0.001460497739940689, + "n": 20 + }, + "member_rmse": { + "mean": 0.0034985598803430294, + "se": 4.257347538385945e-05, + "n": 20 + }, + "shared_bias": { + "mean": -0.00045640872178638446, + "se": 2.1257796681390827e-05, + "n": 20 + }, + "coverage68": { + "mean": 0.9759825327510916, + "se": 0.003950507711291272, + "n": 20 + }, + "coverage95": { + "mean": 1.0, + "se": 0.0, + "n": 20 + }, + "coverage95_posterior": { + "mean": 0.3521834061135371, + "se": 0.01114798227750567, + "n": 20 + }, + "median_sd": { + "mean": 0.0033208634292375442, + "se": 4.205211637795768e-05, + "n": 20 + }, + "median_halfwidth95": { + "mean": 0.006508772770222135, + "se": 8.242063422460748e-05, + "n": 20 + }, + "bias": { + "mean": -0.00045640872178638446, + "se": 2.1257796681390827e-05, + "n": 20 + }, + "rmse": { + "mean": 0.0015872186453374157, + "se": 3.5326674953574294e-05, + "n": 20 + }, + "max_abs_err": { + "mean": 0.004107125533884937, + "se": 0.00013590681365518507, + "n": 20 + }, + "tau": { + "mean": 0.0004342621249427537, + "se": 3.305440792692002e-05, + "n": 20 + }, + "s": { + "mean": 12.787231288620706, + "se": 0.15136613842671454, + "n": 20 + }, + "corr_length_days": { + "mean": 24.911500321002553, + "se": 2.0440409209981754, + "n": 20 + }, + "n_eff": { + "mean": 27.292206875659616, + "se": 1.802304174751284, + "n": 20 + }, + "missing_fraction": { + "mean": 0.0, + "se": 0.0, + "n": 20 + }, + "prior_weight_tau2": { + "mean": 0.02467801822892112, + "se": 0.01050293001747359, + "n": 20 + }, + "prior_weight_s2": { + "mean": 4.6288983418273784e-14, + "se": 1.0393812939544117e-15, + "n": 20 + }, + "prior_weight_lambda": { + "mean": 1.40424868162668e-05, + "se": 2.4337189031780266e-06, + "n": 20 + }, + "member_coverage95_within_margin": true, + "member_coverage68_within_margin": false + }, + "results": [ + { + "seed": 1000, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7762008733624454, + "member_coverage95": 0.9417758369723436, + "member_rmse": 0.0034279500835835393, + "shared_bias": -0.0005834846299080461, + "coverage68": 0.9432314410480349, + "coverage95": 1.0, + "coverage95_posterior": 0.314410480349345, + "median_sd": 0.003220262250458121, + "median_halfwidth95": 0.006311598081456901, + "bias": -0.0005834846299080461, + "rmse": 0.0016736049189311404, + "max_abs_err": 0.004087343781102305, + "tau": 0.0005788719472633456, + "s": 12.290829850214564, + "corr_length_days": 29.75578285400998, + "n_eff": 18.58282105245536, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.005003521911034935, + "prior_weight_s2": 4.9411586604086046e-14, + "prior_weight_lambda": 4.058943760115181e-05 + }, + { + "seed": 1001, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7867540029112081, + "member_coverage95": 0.9475982532751092, + "member_rmse": 0.003505345966795759, + "shared_bias": -0.0003863472986307176, + "coverage68": 0.982532751091703, + "coverage95": 1.0, + "coverage95_posterior": 0.37554585152838427, + "median_sd": 0.003288598942043897, + "median_halfwidth95": 0.006445535536844125, + "bias": -0.0003863472986307176, + "rmse": 0.0015825804608764293, + "max_abs_err": 0.004364840495869574, + "tau": 0.00040312649061681726, + "s": 12.678979008023557, + "corr_length_days": 40.938347799927506, + "n_eff": 29.973815764700618, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.011789143691887188, + "prior_weight_s2": 4.715385272187806e-14, + "prior_weight_lambda": 2.9936777557140608e-06 + }, + { + "seed": 1002, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8085880640465793, + "member_coverage95": 0.950509461426492, + "member_rmse": 0.003446786881942028, + "shared_bias": -0.0005703317284106121, + "coverage68": 0.9868995633187773, + "coverage95": 1.0, + "coverage95_posterior": 0.40611353711790393, + "median_sd": 0.0032411591317788356, + "median_halfwidth95": 0.006352555216557774, + "bias": -0.0005703317284106121, + "rmse": 0.0015595555314159373, + "max_abs_err": 0.004725930837859852, + "tau": 0.00049655188275027, + "s": 12.591693594545188, + "corr_length_days": 36.4808504321116, + "n_eff": 24.29512211041879, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.00691571035275139, + "prior_weight_s2": 4.7440530401482866e-14, + "prior_weight_lambda": 1.0233260210304177e-05 + }, + { + "seed": 1003, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8184133915574964, + "member_coverage95": 0.9577874818049491, + "member_rmse": 0.003663861183549894, + "shared_bias": -0.0003897818888859551, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.48034934497816595, + "median_sd": 0.0033797048311123216, + "median_halfwidth95": 0.006624099799606231, + "bias": -0.0003897818888859551, + "rmse": 0.0014250206583304873, + "max_abs_err": 0.0034828347195966533, + "tau": 0.0005823082882319129, + "s": 13.198822243797176, + "corr_length_days": 17.144635299731277, + "n_eff": 19.921042104699602, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.005284537393682626, + "prior_weight_s2": 4.350713213264164e-14, + "prior_weight_lambda": 4.051591339392014e-06 + }, + { + "seed": 1004, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7933042212518195, + "member_coverage95": 0.9486899563318777, + "member_rmse": 0.003383588835748416, + "shared_bias": -0.0003799261060300248, + "coverage68": 0.9781659388646288, + "coverage95": 1.0, + "coverage95_posterior": 0.3799126637554585, + "median_sd": 0.0031576955250043333, + "median_halfwidth95": 0.006188969551969593, + "bias": -0.0003799261060300248, + "rmse": 0.0015277727716686707, + "max_abs_err": 0.0052074900724910795, + "tau": 0.00037356738720992216, + "s": 12.161899145650876, + "corr_length_days": 26.17922743591003, + "n_eff": 29.160440550345573, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.013822208438453372, + "prior_weight_s2": 5.0881921603512344e-14, + "prior_weight_lambda": 8.629533200802824e-06 + }, + { + "seed": 1005, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7776564774381368, + "member_coverage95": 0.9548762736535662, + "member_rmse": 0.003306070802202102, + "shared_bias": -0.0004590088646714993, + "coverage68": 0.9781659388646288, + "coverage95": 1.0, + "coverage95_posterior": 0.34934497816593885, + "median_sd": 0.00318787453814522, + "median_halfwidth95": 0.006248119331281258, + "bias": -0.0004590088646714993, + "rmse": 0.0016054263143549902, + "max_abs_err": 0.003844280343049282, + "tau": 0.00028352182541789377, + "s": 12.355152078474328, + "corr_length_days": 29.36861235473872, + "n_eff": 30.30023283557811, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.024785458201933737, + "prior_weight_s2": 4.9261039494846544e-14, + "prior_weight_lambda": 1.060561644842696e-05 + }, + { + "seed": 1006, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8002183406113537, + "member_coverage95": 0.9523289665211062, + "member_rmse": 0.0035281439879819338, + "shared_bias": -0.0004660747194138614, + "coverage68": 0.982532751091703, + "coverage95": 1.0, + "coverage95_posterior": 0.40611353711790393, + "median_sd": 0.0032833106216834, + "median_halfwidth95": 0.006435170619317083, + "bias": -0.0004660747194138614, + "rmse": 0.0014787159423164408, + "max_abs_err": 0.004193201688282074, + "tau": 0.0005192677765109794, + "s": 12.626517032953016, + "corr_length_days": 27.29982867637573, + "n_eff": 20.520138347174367, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.006672501110892678, + "prior_weight_s2": 4.709835556812815e-14, + "prior_weight_lambda": 1.2258097396121442e-05 + }, + { + "seed": 1007, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7918486171761281, + "member_coverage95": 0.9494177583697234, + "member_rmse": 0.0031479178780342175, + "shared_bias": -0.00043548900902487596, + "coverage68": 0.9781659388646288, + "coverage95": 1.0, + "coverage95_posterior": 0.3318777292576419, + "median_sd": 0.0029806239460949484, + "median_halfwidth95": 0.0058419156318840395, + "bias": -0.00043548900902487596, + "rmse": 0.0013083627689700725, + "max_abs_err": 0.0032503529845281814, + "tau": 0.0001292014093747939, + "s": 11.782759848423431, + "corr_length_days": 31.15927805688523, + "n_eff": 42.503511591816014, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.20883257595465005, + "prior_weight_s2": 5.374772684011974e-14, + "prior_weight_lambda": 2.2352415848249175e-05 + }, + { + "seed": 1008, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7943959243085881, + "member_coverage95": 0.9454148471615721, + "member_rmse": 0.0033604315073136565, + "shared_bias": -0.0002764341914429292, + "coverage68": 0.9694323144104804, + "coverage95": 1.0, + "coverage95_posterior": 0.3537117903930131, + "median_sd": 0.0031974894353593627, + "median_halfwidth95": 0.0062669641836846784, + "bias": -0.0002764341914429292, + "rmse": 0.0016051624782946943, + "max_abs_err": 0.00381390037263289, + "tau": 0.00048777268663269745, + "s": 12.166852608924792, + "corr_length_days": 28.58500233216794, + "n_eff": 22.60263824300058, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.00733718575226865, + "prior_weight_s2": 5.1007137566530197e-14, + "prior_weight_lambda": 5.310891383685297e-06 + }, + { + "seed": 1009, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7969432314410481, + "member_coverage95": 0.9475982532751092, + "member_rmse": 0.003349424685271689, + "shared_bias": -0.0003542511977201716, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.31004366812227074, + "median_sd": 0.003319968197896715, + "median_halfwidth95": 0.0065070181490224374, + "bias": -0.0003542511977201716, + "rmse": 0.001315320871195647, + "max_abs_err": 0.0030701633074819296, + "tau": 0.00019077228732208845, + "s": 12.825199949517602, + "corr_length_days": 17.976768462908453, + "n_eff": 35.936523034921066, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.08482133763840935, + "prior_weight_s2": 4.553423190860652e-14, + "prior_weight_lambda": 1.3871588648543715e-05 + }, + { + "seed": 1010, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7594614264919942, + "member_coverage95": 0.9392285298398836, + "member_rmse": 0.0035202110367398027, + "shared_bias": -0.0005290986333743811, + "coverage68": 0.9519650655021834, + "coverage95": 1.0, + "coverage95_posterior": 0.25327510917030566, + "median_sd": 0.0031878651026848804, + "median_halfwidth95": 0.006248100838118669, + "bias": -0.0005290986333743811, + "rmse": 0.0018826933752772086, + "max_abs_err": 0.003892913690142387, + "tau": 0.0004040594885763965, + "s": 12.214378897802415, + "corr_length_days": 24.185105999316388, + "n_eff": 25.001580061472886, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.01111227762314982, + "prior_weight_s2": 4.994097461671884e-14, + "prior_weight_lambda": 2.626728709117429e-05 + }, + { + "seed": 1011, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7998544395924309, + "member_coverage95": 0.9574235807860262, + "member_rmse": 0.0035536109293266777, + "shared_bias": -0.0005104088690513783, + "coverage68": 0.982532751091703, + "coverage95": 1.0, + "coverage95_posterior": 0.3799126637554585, + "median_sd": 0.0034936906698791533, + "median_halfwidth95": 0.006847507940099025, + "bias": -0.0005104088690513783, + "rmse": 0.0016299633143107913, + "max_abs_err": 0.004281410778125293, + "tau": 0.00045534720433512417, + "s": 13.493000455327802, + "corr_length_days": 35.641959781643415, + "n_eff": 25.856375841639732, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.00880391419345944, + "prior_weight_s2": 4.11039940499074e-14, + "prior_weight_lambda": 1.3898930809425349e-05 + }, + { + "seed": 1012, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.824235807860262, + "member_coverage95": 0.9599708879184862, + "member_rmse": 0.003752194241535859, + "shared_bias": -0.0005356467468239357, + "coverage68": 1.0, + "coverage95": 1.0, + "coverage95_posterior": 0.3799126637554585, + "median_sd": 0.0037656777944920722, + "median_halfwidth95": 0.00738059291280386, + "bias": -0.0005356467468239357, + "rmse": 0.0014647806377900631, + "max_abs_err": 0.0035562590455543363, + "tau": 0.0005557922687893453, + "s": 14.427379640206475, + "corr_length_days": 21.302560057748433, + "n_eff": 21.94413966629211, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.005428212473292194, + "prior_weight_s2": 3.5950056455950903e-14, + "prior_weight_lambda": 2.5198479908217968e-05 + }, + { + "seed": 1013, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8118631732168851, + "member_coverage95": 0.9610625909752547, + "member_rmse": 0.003552266547025321, + "shared_bias": -0.0003365663906412238, + "coverage68": 0.9781659388646288, + "coverage95": 1.0, + "coverage95_posterior": 0.3624454148471616, + "median_sd": 0.003467828215609524, + "median_halfwidth95": 0.006796818460778906, + "bias": -0.0003365663906412238, + "rmse": 0.0015267501503297845, + "max_abs_err": 0.004422725533493876, + "tau": 0.000295335750362615, + "s": 13.66045934645135, + "corr_length_days": 6.920156603892575, + "n_eff": 47.85130241338563, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.026560534787602594, + "prior_weight_s2": 4.031488316226297e-14, + "prior_weight_lambda": 7.558933930061979e-06 + }, + { + "seed": 1014, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7834788937409025, + "member_coverage95": 0.9457787481804949, + "member_rmse": 0.0033816032173398175, + "shared_bias": -0.00038463758402150597, + "coverage68": 0.9519650655021834, + "coverage95": 1.0, + "coverage95_posterior": 0.2925764192139738, + "median_sd": 0.0031650328542302112, + "median_halfwidth95": 0.006203350453108462, + "bias": -0.00038463758402150597, + "rmse": 0.0016303771807913835, + "max_abs_err": 0.004696118856425079, + "tau": 0.00028268161360725904, + "s": 12.273398089060661, + "corr_length_days": 23.508502261199116, + "n_eff": 33.8338590803328, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.03007518944062265, + "prior_weight_s2": 4.9980769805885526e-14, + "prior_weight_lambda": 7.222446924471839e-06 + }, + { + "seed": 1015, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7827510917030568, + "member_coverage95": 0.9530567685589519, + "member_rmse": 0.003415288894012611, + "shared_bias": -0.00042973464114655265, + "coverage68": 0.9650655021834061, + "coverage95": 1.0, + "coverage95_posterior": 0.3624454148471616, + "median_sd": 0.0032196942275022357, + "median_halfwidth95": 0.0063104847769121925, + "bias": -0.00042973464114655265, + "rmse": 0.001676671329520968, + "max_abs_err": 0.004284650657989456, + "tau": 0.0005007939781537393, + "s": 12.40961176115121, + "corr_length_days": 29.59891256082987, + "n_eff": 21.64964382821764, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.007361161267773965, + "prior_weight_s2": 4.912933298357102e-14, + "prior_weight_lambda": 5.173538979123298e-06 + }, + { + "seed": 1016, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7729257641921398, + "member_coverage95": 0.9494177583697234, + "member_rmse": 0.0035614569565808663, + "shared_bias": -0.0005176776073475145, + "coverage68": 0.982532751091703, + "coverage95": 1.0, + "coverage95_posterior": 0.32751091703056767, + "median_sd": 0.0034787735856920583, + "median_halfwidth95": 0.00681827099210735, + "bias": -0.0005176776073475145, + "rmse": 0.0016744665825845536, + "max_abs_err": 0.0038979181199428133, + "tau": 0.000442392943031358, + "s": 13.26376037993221, + "corr_length_days": 9.445328389619815, + "n_eff": 29.773754918555955, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.008998222330200284, + "prior_weight_s2": 4.258936360207847e-14, + "prior_weight_lambda": 1.2093681202116798e-05 + }, + { + "seed": 1017, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8071324599708879, + "member_coverage95": 0.9494177583697234, + "member_rmse": 0.004056200086968193, + "shared_bias": -0.0006411561114893532, + "coverage68": 0.9694323144104804, + "coverage95": 1.0, + "coverage95_posterior": 0.3537117903930131, + "median_sd": 0.0036880831517888246, + "median_halfwidth95": 0.007228510206512632, + "bias": -0.0006411561114893532, + "rmse": 0.0019080963603751193, + "max_abs_err": 0.005353904630025354, + "tau": 0.0007420397085062466, + "s": 13.881971863882738, + "corr_length_days": 13.01237751526313, + "n_eff": 16.753191389636083, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.002943862920671194, + "prior_weight_s2": 3.8849947105344993e-14, + "prior_weight_lambda": 1.0378831311354229e-05 + }, + { + "seed": 1018, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.8045851528384279, + "member_coverage95": 0.9570596797671034, + "member_rmse": 0.0036521955032847203, + "shared_bias": -0.0005452641369999877, + "coverage68": 0.9956331877729258, + "coverage95": 1.0, + "coverage95_posterior": 0.28820960698689957, + "median_sd": 0.0034231897070303038, + "median_halfwidth95": 0.006709328590949942, + "bias": -0.0005452641369999877, + "rmse": 0.0014942964589674055, + "max_abs_err": 0.0034016329815241644, + "tau": 0.0005722547683535508, + "s": 12.967979649244066, + "corr_length_days": 16.855214972005825, + "n_eff": 20.360487793722662, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.0053208200135180005, + "prior_weight_s2": 4.439678289981823e-14, + "prior_weight_lambda": 3.785192347109416e-05 + }, + { + "seed": 1019, + "scenario": "shared_source", + "ok": true, + "n_epochs": 229, + "member_coverage68": 0.7802037845705968, + "member_coverage95": 0.9377729257641921, + "member_rmse": 0.003406648381623475, + "shared_bias": -0.00039685408069316296, + "coverage68": 0.9432314410480349, + "coverage95": 1.0, + "coverage95_posterior": 0.33624454148471616, + "median_sd": 0.003270745856264472, + "median_halfwidth95": 0.00641054413142754, + "bias": -0.00039685408069316296, + "rmse": 0.001774754800446525, + "max_abs_err": 0.004314637781582124, + "tau": 0.00038958279380871947, + "s": 12.473980328830658, + "corr_length_days": 32.87155457376603, + "n_eff": 29.023516884826737, + "missing_fraction": 0.0, + "prior_weight_tau2": 0.011691989082168272, + "prior_weight_s2": 4.8480048842105264e-14, + "prior_weight_lambda": 4.3095728659045816e-06 + } + ] +} diff --git a/paper/data/gate1/README.md b/paper/data/gate1/README.md index edf3e02..0c2ac19 100644 --- a/paper/data/gate1/README.md +++ b/paper/data/gate1/README.md @@ -22,8 +22,37 @@ Clements & Denolle (2022), generated by the noisepy-dvv-cloud Gate 1 run gate1_heatmaps_zoom.png interferograms zoomed to +-8 s lag dvv_smoke_check_90d.png ensemble warm-up behavior (90-day smoke run) -Headline comparison (trailing-90d smoothing matched, demeaned, 150-day -reference burn-in): CI.LJR r=0.990; CI.ARV 0.66-0.92 (join-method -sensitive, 2018 gaps); CI.RXH 0.68 (near-flat station, site -non-stationarity Apr-May 2019). Comparison script: -noisepy-dvv-cloud scripts/compare_cd2022.py. +Comparison statistics quoted in the manuscript come from the in-repo +script `scripts/compare_gate1.py`, which reads the products above and +writes `comparison.json` with its rules stated (calendar-day join, +trailing 90-day mean with at least 45 finite days, 150-day burn-in; +plus a centred 45-day rule and the raw daily overlap for reference). +Matched rule (2026-09-10): CI.LJR r=0.985 on 579 days, slope 1.07; +CI.ARV r=0.905 on 357 days, slope 2.15; CI.RXH r=0.829 on 446 days, +slope 0.81. The earlier headline (0.990 / 0.66-0.92 / 0.68, "681 days") +came from noisepy-dvv-cloud `scripts/compare_cd2022.py` under rules +not recorded here; 681 is the raw daily overlap for LJR. + +Error-column correction (2026-09-10): the archived `dvv_err_within` +was computed with the codameter 0.4 Weaver floor (no spectral timescale, +variance prefactor twice Weaver eq. 20) and a geometric-mean centre +frequency. Every ensemble member shares the band, so the corrected floor +is the archived one times a constant per band (0.463, 0.328, 0.232 and +0.164 for the 1-2, 2-4, 4-8 and 8-16 Hz products). The columns under +`dvv2y/` have been rescaled in place by +`scripts/correct_gate1_within_error.py`, `dvv_err` recomputed, the +originals kept as `CI..v040.parquet`, and the factors and +before/after medians logged in `dvv2y/correction.json`. The comparison +statistics do not use these columns. The figures in `../figures/gate1/` +still show the uncorrected bars. + +Ensemble members (from `noisepy_dvv_cloud/dvv.py`): the codameter +recommendation for the `--use-case` passed to the run, at the product's +band, plus four perturbations (stack halved, stack doubled, coda window +shifted later by a quarter of its length, fixed reference swapped to +moving). `config_hash` covers the NoisePy correlation settings only. + +Provenance still to pin (audit REP-02): the noisepy-dvv-cloud commit of +the Gate 1 run (candidates: bbd1b02, 341b83b, be1538b, all dated +2026-08-09) and the `--use-case` it was given, neither of which the +products record. diff --git a/paper/data/gate1/comparison.json b/paper/data/gate1/comparison.json new file mode 100644 index 0000000..5cbd66f --- /dev/null +++ b/paper/data/gate1/comparison.json @@ -0,0 +1,135 @@ +{ + "rules": { + "band_hz": "2.0-4.0", + "burn_in_days": 150, + "trailing_days": 90, + "trailing_min_finite": 45, + "centered_days": 45, + "centered_min_finite": 23, + "join": "inner join on calendar date; published product restricted to 2018-2019", + "r": "Pearson, on the overlap, after removing each series' overlap mean", + "slope": "OLS slope of the published product on the codameter series" + }, + "stations": [ + { + "station": "CI.LJR", + "daily_rows": 681, + "daily_first": "2018-01-01", + "daily_last": "2019-12-30", + "legacy_rows_2018_2019": 729, + "burn_in_until": "2018-05-31", + "matched": { + "n": 579, + "first": "2018-05-31", + "last": "2019-12-30", + "r": 0.9850624256185397, + "rms_diff": 0.04616500786170553, + "slope": 1.0691502357580198 + }, + "matched_no_burn_in": { + "n": 639, + "first": "2018-04-01", + "last": "2019-12-30", + "r": 0.9842861169792171, + "rms_diff": 0.04475023506362687, + "slope": 1.06604616277162 + }, + "centered": { + "n": 682, + "first": "2018-02-16", + "last": "2019-12-30", + "r": 0.8653456948495024, + "rms_diff": 0.11961154037286262, + "slope": 0.8767149750561822 + }, + "raw": { + "n": 681, + "first": "2018-02-15", + "last": "2019-12-30", + "r": 0.8482459139276761, + "rms_diff": 0.12926786732877105, + "slope": 0.8270457775608157 + } + }, + { + "station": "CI.ARV", + "daily_rows": 394, + "daily_first": "2018-01-01", + "daily_last": "2019-12-30", + "legacy_rows_2018_2019": 729, + "burn_in_until": "2018-05-31", + "matched": { + "n": 357, + "first": "2018-05-31", + "last": "2019-08-17", + "r": 0.9045574746252278, + "rms_diff": 0.1499582242219106, + "slope": 2.1497390972385637 + }, + "matched_no_burn_in": { + "n": 390, + "first": "2018-04-28", + "last": "2019-08-17", + "r": 0.8991749046935936, + "rms_diff": 0.14417421369707928, + "slope": 2.01388560869008 + }, + "centered": { + "n": 424, + "first": "2018-03-20", + "last": "2019-10-31", + "r": 0.36862022477672945, + "rms_diff": 0.21417922543897486, + "slope": 0.7964142472626492 + }, + "raw": { + "n": 394, + "first": "2018-02-15", + "last": "2019-12-14", + "r": 0.3050023982841881, + "rms_diff": 0.23344247992602937, + "slope": 0.48000644317005864 + } + }, + { + "station": "CI.RXH", + "daily_rows": 563, + "daily_first": "2018-01-01", + "daily_last": "2019-12-30", + "legacy_rows_2018_2019": 640, + "burn_in_until": "2018-05-31", + "matched": { + "n": 446, + "first": "2018-05-31", + "last": "2019-12-30", + "r": 0.8288596923048149, + "rms_diff": 0.020031985799333026, + "slope": 0.8061950785354097 + }, + "matched_no_burn_in": { + "n": 507, + "first": "2018-03-31", + "last": "2019-12-30", + "r": 0.7639616357430739, + "rms_diff": 0.024834967608089075, + "slope": 0.6416129386867837 + }, + "centered": { + "n": 554, + "first": "2018-02-15", + "last": "2019-11-28", + "r": 0.620432199974238, + "rms_diff": 0.03468605759921402, + "slope": 0.5227569651774386 + }, + "raw": { + "n": 560, + "first": "2018-02-15", + "last": "2019-12-30", + "r": 0.4911444632042665, + "rms_diff": 0.045858139775157306, + "slope": 0.35447454696414116 + } + } + ] +} diff --git a/paper/data/gate1/dvv2y/correction.json b/paper/data/gate1/dvv2y/correction.json new file mode 100644 index 0000000..fa8edf4 --- /dev/null +++ b/paper/data/gate1/dvv2y/correction.json @@ -0,0 +1,281 @@ +{ + "files": { + "band=1.0-2.0/CI.ARV.parquet": { + "date": "2026-09-10T22:44:34+00:00", + "codameter_version": "0.4.0", + "band_hz": [ + 1.0, + 2.0 + ], + "T_s": 0.48301205684678217, + "prefactor_and_T": 0.4914326285701745, + "centre_frequency": 0.9428090415820635, + "factor": 0.4633271255444004, + "original": "CI.ARV.v040.parquet", + "median_before_percent": { + "dvv_err": 0.3989313054832341, + "dvv_err_within": 0.38496608755057693, + "dvv_err_method": 0.09072053739899266 + }, + "median_after_percent": { + "dvv_err": 0.2063324371110779, + "dvv_err_within": 0.1783652307768828, + "dvv_err_method": 0.09072053739899266 + } + }, + "band=1.0-2.0/CI.LJR.parquet": { + "date": "2026-09-10T22:44:34+00:00", + "codameter_version": "0.4.0", + "band_hz": [ + 1.0, + 2.0 + ], + "T_s": 0.48301205684678217, + "prefactor_and_T": 0.4914326285701745, + "centre_frequency": 0.9428090415820635, + "factor": 0.4633271255444004, + "original": "CI.LJR.v040.parquet", + "median_before_percent": { + "dvv_err": 0.14980899342552628, + "dvv_err_within": 0.1427022119473286, + "dvv_err_method": 0.037576960375098424 + }, + "median_after_percent": { + "dvv_err": 0.07878918271268028, + "dvv_err_within": 0.06611780567038356, + "dvv_err_method": 0.037576960375098424 + } + }, + "band=1.0-2.0/CI.RXH.parquet": { + "date": "2026-09-10T22:44:34+00:00", + "codameter_version": "0.4.0", + "band_hz": [ + 1.0, + 2.0 + ], + "T_s": 0.48301205684678217, + "prefactor_and_T": 0.4914326285701745, + "centre_frequency": 0.9428090415820635, + "factor": 0.4633271255444004, + "original": "CI.RXH.v040.parquet", + "median_before_percent": { + "dvv_err": 0.1482549188791674, + "dvv_err_within": 0.14297336722058265, + "dvv_err_method": 0.03553232820378844 + }, + "median_after_percent": { + "dvv_err": 0.0773387393354241, + "dvv_err_within": 0.06624343926371656, + "dvv_err_method": 0.03553232820378844 + } + }, + "band=2.0-4.0/CI.ARV.parquet": { + "date": "2026-09-10T22:44:34+00:00", + "codameter_version": "0.4.0", + "band_hz": [ + 2.0, + 4.0 + ], + "T_s": 0.24150602842339108, + "prefactor_and_T": 0.34749534415830025, + "centre_frequency": 0.9428090415820635, + "factor": 0.3276217523801163, + "original": "CI.ARV.v040.parquet", + "median_before_percent": { + "dvv_err": 0.4039569780775442, + "dvv_err_within": 0.38160709775532387, + "dvv_err_method": 0.12892133751168672 + }, + "median_after_percent": { + "dvv_err": 0.17944456849907658, + "dvv_err_within": 0.12502278608728956, + "dvv_err_method": 0.12892133751168672 + } + }, + "band=2.0-4.0/CI.LJR.parquet": { + "date": "2026-09-10T22:44:34+00:00", + "codameter_version": "0.4.0", + "band_hz": [ + 2.0, + 4.0 + ], + "T_s": 0.24150602842339108, + "prefactor_and_T": 0.34749534415830025, + "centre_frequency": 0.9428090415820635, + "factor": 0.3276217523801163, + "original": "CI.LJR.v040.parquet", + "median_before_percent": { + "dvv_err": 0.12336355702542022, + "dvv_err_within": 0.08173836352725314, + "dvv_err_method": 0.09308926644633768 + }, + "median_after_percent": { + "dvv_err": 0.09659110748682291, + "dvv_err_within": 0.026779265895481658, + "dvv_err_method": 0.09308926644633768 + } + }, + "band=2.0-4.0/CI.RXH.parquet": { + "date": "2026-09-10T22:44:34+00:00", + "codameter_version": "0.4.0", + "band_hz": [ + 2.0, + 4.0 + ], + "T_s": 0.24150602842339108, + "prefactor_and_T": 0.34749534415830025, + "centre_frequency": 0.9428090415820635, + "factor": 0.3276217523801163, + "original": "CI.RXH.v040.parquet", + "median_before_percent": { + "dvv_err": 0.21072846383525445, + "dvv_err_within": 0.20671927993664127, + "dvv_err_method": 0.03374568666381958 + }, + "median_after_percent": { + "dvv_err": 0.07763734252207219, + "dvv_err_within": 0.06772573274359824, + "dvv_err_method": 0.03374568666381958 + } + }, + "band=4.0-8.0/CI.ARV.parquet": { + "date": "2026-09-10T22:44:34+00:00", + "codameter_version": "0.4.0", + "band_hz": [ + 4.0, + 8.0 + ], + "T_s": 0.12075301421169554, + "prefactor_and_T": 0.24571631428508725, + "centre_frequency": 0.9428090415820635, + "factor": 0.2316635627722002, + "original": "CI.ARV.v040.parquet", + "median_before_percent": { + "dvv_err": 0.2630361448680867, + "dvv_err_within": 0.2542477184061325, + "dvv_err_method": 0.06387822119108076 + }, + "median_after_percent": { + "dvv_err": 0.08735855716623209, + "dvv_err_within": 0.05889993227266775, + "dvv_err_method": 0.06387822119108076 + } + }, + "band=4.0-8.0/CI.LJR.parquet": { + "date": "2026-09-10T22:44:34+00:00", + "codameter_version": "0.4.0", + "band_hz": [ + 4.0, + 8.0 + ], + "T_s": 0.12075301421169554, + "prefactor_and_T": 0.24571631428508725, + "centre_frequency": 0.9428090415820635, + "factor": 0.2316635627722002, + "original": "CI.LJR.v040.parquet", + "median_before_percent": { + "dvv_err": 0.17242362230984834, + "dvv_err_within": 0.09705472945336975, + "dvv_err_method": 0.14551989453957587 + }, + "median_after_percent": { + "dvv_err": 0.14692144974261456, + "dvv_err_within": 0.022484044409059635, + "dvv_err_method": 0.14551989453957587 + } + }, + "band=4.0-8.0/CI.RXH.parquet": { + "date": "2026-09-10T22:44:34+00:00", + "codameter_version": "0.4.0", + "band_hz": [ + 4.0, + 8.0 + ], + "T_s": 0.12075301421169554, + "prefactor_and_T": 0.24571631428508725, + "centre_frequency": 0.9428090415820635, + "factor": 0.2316635627722002, + "original": "CI.RXH.v040.parquet", + "median_before_percent": { + "dvv_err": 0.21484229485676792, + "dvv_err_within": 0.19525503354426074, + "dvv_err_method": 0.05860339340347467 + }, + "median_after_percent": { + "dvv_err": 0.0761872429037315, + "dvv_err_within": 0.0452334767200689, + "dvv_err_method": 0.05860339340347467 + } + }, + "band=8.0-16.0/CI.ARV.parquet": { + "date": "2026-09-10T22:44:34+00:00", + "codameter_version": "0.4.0", + "band_hz": [ + 8.0, + 16.0 + ], + "T_s": 0.06037650710584777, + "prefactor_and_T": 0.17374767207915012, + "centre_frequency": 0.9428090415820635, + "factor": 0.16381087619005816, + "original": "CI.ARV.v040.parquet", + "median_before_percent": { + "dvv_err": 0.1364112483898754, + "dvv_err_within": 0.13476775490085302, + "dvv_err_method": 0.024494540673929175 + }, + "median_after_percent": { + "dvv_err": 0.032691826831880724, + "dvv_err_within": 0.022076424012475736, + "dvv_err_method": 0.024494540673929175 + } + }, + "band=8.0-16.0/CI.LJR.parquet": { + "date": "2026-09-10T22:44:34+00:00", + "codameter_version": "0.4.0", + "band_hz": [ + 8.0, + 16.0 + ], + "T_s": 0.06037650710584777, + "prefactor_and_T": 0.17374767207915012, + "centre_frequency": 0.9428090415820635, + "factor": 0.16381087619005816, + "original": "CI.LJR.v040.parquet", + "median_before_percent": { + "dvv_err": 0.12024332647840354, + "dvv_err_within": 0.10509781435262401, + "dvv_err_method": 0.05390649245896394 + }, + "median_after_percent": { + "dvv_err": 0.056500560904500736, + "dvv_err_within": 0.017216165054763408, + "dvv_err_method": 0.05390649245896394 + } + }, + "band=8.0-16.0/CI.RXH.parquet": { + "date": "2026-09-10T22:44:34+00:00", + "codameter_version": "0.4.0", + "band_hz": [ + 8.0, + 16.0 + ], + "T_s": 0.06037650710584777, + "prefactor_and_T": 0.17374767207915012, + "centre_frequency": 0.9428090415820635, + "factor": 0.16381087619005816, + "original": "CI.RXH.v040.parquet", + "median_before_percent": { + "dvv_err": 0.11704864315284673, + "dvv_err_within": 0.10556651392490583, + "dvv_err_method": 0.051641487436389875 + }, + "median_after_percent": { + "dvv_err": 0.055154950356061445, + "dvv_err_within": 0.0172929431423688, + "dvv_err_method": 0.051641487436389875 + } + } + }, + "note": "dvv_err_within rescaled to the corrected Weaver floor (codameter >= 0.5): sqrt(T/2) for the missing spectral timescale and the eq. 20 prefactor, times f_geo/f_arith for the centre-frequency convention; dvv_err recomputed." +} diff --git a/paper/manuscript_marine.qmd b/paper/manuscript_marine.qmd index c223e58..44b38b6 100644 --- a/paper/manuscript_marine.qmd +++ b/paper/manuscript_marine.qmd @@ -7,29 +7,48 @@ author: - name: Department of Earth and Space Sciences, University of Washington, Seattle, WA, USA date: today abstract: | - Relative seismic velocity changes (\dvv) from the ambient seismic field are a + Relative seismic velocity changes (\dvv) from repeated coda waves are a standard observable for volcanoes, faults, landslides, aquifers and the - cryosphere. Yet turning cross-correlation functions into a \dvv\ time series - involves a long sequence of choices --- the estimator, the frequency band, the - coda window, the reference, the stacking, and how cross-components and station - pairs are aggregated and weighted --- made *ad hoc* and seldom reported in full. - Using a controlled synthetic in which the ground-truth \dvv\ is known exactly, we - quantify how much each choice moves the recovered value *and its stated - uncertainty*. Reproducing the seven NoisePy estimators, we show that at large - \dvv\ methods split by family with distinct failure modes; that the same station - pair yields different \dvv\ depending only on whether one averages the - per-component \dvv\ or the correlation-coefficient images; and, most - consequentially, that the reported $1\sigma$ on a network-averaged \dvv\ varies by - $\sim\!\sqrt{N}$ - from the standard-error-versus-standard-deviation and weighting conventions --- - so a change that is "$3\sigma$ significant" in one study is "not significant" in - another, from identical data. Running the full *multiverse* of choices, we rank - each by the bias and error-bar change it induces, and propose a Bayesian - measurement model that marginalises the ensemble into a single time-dependent - data covariance $C_d$ --- the object a downstream depth or stress - inversion needs. We argue that these undocumented choices, not the physics, are - the leading obstacle to intercomparing \dvv\ studies, and release an open - framework (codameter) that makes every choice explicit and reproducible. + cryosphere. Turning cross-correlation functions into a \dvv\ time series + involves a long sequence of choices, the estimator, the frequency band, the + coda window, the reference, the stacking, and how cross-components and + station pairs are aggregated and weighted, made ad hoc and reported + incompletely, so the same data can support different values and different + error bars. We quantify the individual and combined effects of these choices + on synthetic correlation functions in which the ground-truth \dvv\ is known + exactly. On these synthetics, at large \dvv\ the estimators split by family + with distinct failure modes; the same station pair yields different \dvv\ depending only on whether one averages per-component \dvv\ or the + correlation-coefficient images; and the number quoted as the $1\sigma$ + uncertainty of a network-averaged \dvv\ differs by $\sim\!\sqrt{N}$ between + the standard error of the network mean and the between-pair standard + deviation, two different quantities that studies rarely distinguish. A + one-at-a-time sweep and a 108-pipeline factorial on one scenario rank the + choices by the error they induce. We then propose a hierarchical Bayesian + measurement model that runs an ensemble of defensible pipelines on the same + correlations and combines their estimates into a single \dvv\ series. A separate construction proposes a time-dependent single-member error covariance $C_d$. + On 200 independent synthetic realisations of a volcano scenario, $C_d$ covers + 95.6% of individual member errors at the 95% level, whereas the + credible band on the ensemble mean covers the truth only 59% of the time + because the configurations share time-varying biases; a seasonal source + artefact seen by every configuration reduces that coverage to 34% and more than doubles + the error of the ensemble mean while leaving member coverage near 95%. + The nominal 68% member intervals cover 81% in the clean case; + these pointwise checks do not validate the full covariance. Shared errors + require diagnostics beyond agreement among processing choices. We set out how $C_d$ enters a depth inversion of + shear-velocity change; that stage is described, not evaluated, here. On three + California stations the same measurement code, run on NoisePy correlations in + a cloud batch pipeline, reproduces a published \dvv\ product (correlation + 0.83--0.99 on 360--580 matched days, with a reproducible comparison script), + a comparison that also exposed and corrected a sign-convention error. The + framework, estimators, figures with their numerical sidecars, and the + calibration experiments are released in the open Python package + ``codameter``, together with a processing-choice advisor and a seeded + golden dataset with fixed scoring support and a null-change penalty for + missing predictions; an + evaluation of agents against that dataset is left to future work. + + + bibliography: - references.bib - survey.bib @@ -47,98 +66,129 @@ format: ```{=latex} \begin{keywords} -Time-series analysis; Interferometry; Seismic noise; Coda waves; Inverse theory; Statistical methods. +Coda-wave Interferometry; Seismic noise; Coda waves; Inverse theory; Statistical methods. \end{keywords} ``` # Introduction {#sec:intro} -Changes in subsurface properties occur due geodynamics, which drive earthquake damage -and volcanic eruption, and hydrodynamics, which controls fluid exchange between the atomsphere -and the solid Earth. These processes influence the mechanical property of Earth materials, -which directly affect the speed at which seismic waves propagates. Changes in seismic +Changes in subsurface properties occur due to geodynamics, which drive earthquake damage +and volcanic eruption, and hydrodynamics, which controls fluid exchange between the atmosphere +and the solid Earth. These processes influence the mechanical properties of Earth materials, +which directly affect the speed at which seismic waves propagate. Changes in seismic velocity, often measured and referred to as \dvv\, can be tracked by measuring changes in arrival -times of seismic waves, especially scatterd waves such as coda waves, +times of seismic waves, especially scattered waves such as coda waves, provided that the source and receivers are at the same location. -```{=latex} -\begin{center} -\fbox{\begin{minipage}{0.95\linewidth} -\textbf{Sign convention.} \dvv\ is the fractional seismic velocity change, -positive for a velocity \emph{increase}. The stretching family of estimators -measures the stretch factor $\varepsilon$ that maps the reference coda onto -the current coda; the exact relation is -\[ -\dvv = -\frac{\varepsilon}{1+\varepsilon}. -\] -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. -\end{minipage}} -\end{center} -``` - Due to the sensitivity of coda waves to small perturbations in the material properties, -\dvv\ was discovered as an effective method to monitor chanes during volcanic unrest since its -discovery at Piton de la Fournaise [@Brenguier2008] and is now calculated in continuous -along side of more conventional seismic monitoring methods in the same volcano observatory - [@Duputel2009] and was a determining early warning parameter used by the Icelandic Meteorological - Office used \dvv\ in its response to the 2020 Reykjanes unrest (Cubuk-Sabuncu et al., 2021). - The Institute of Mine Seismology also uses \dvv\ to monitor the internal state of tens of tailings - dams and mines to flag instability before failure (Olivier et al., 2017; Ouellet et al., 2022). - A broader set of operations is emerging around the same signal: groundwater - storage for water management (Clements and Denolle, 2018; Mao et al., 2022), - landslide early warning (Le Breton et al., 2021), levee and embankment integrity - (Planès et al., 2016), and geothermal and CO$_2$ reservoir surveillance (Nakata et al., 2021). +\dvv\ has become an effective way to monitor volcanic unrest, from the first +passive monitoring at Merapi [@SensSchonfelder2006] to the pre-eruptive +velocity drops at Piton de la Fournaise [@Brenguier2008], where it is now +computed continuously alongside conventional observatory monitoring +[@Duputel2009]; the Icelandic Meteorological Office included \dvv\ among the +parameters it followed during the 2020 Reykjanes unrest [@CubukSabuncu2021]. +The same signal is used to monitor the internal state of tailings dams and +mines and to flag instability before failure [@Olivier2017; @Ouellet2022]. +A broader set of operations is emerging around the same signal: groundwater + storage for water management [@Clements2018; @Mao2022], + landslide early warning [@LeBreton2021], levee and embankment integrity + [@Planes2016], and geothermal and CO$_2$ reservoir surveillance [@Tsuji2021]. Each of these deployments rests on the same fragile assumption: that the \dvv\ curve an operator acts on is a property of the subsurface, not of the analyst's processing choices. -The elevated sensitivity comes at the price a long series of processing choices + \dvv\ is the fractional seismic velocity change, positive for a velocity \emph{increase}. + The stretching family of estimators measures the stretch factor $\varepsilon$ that maps + the current coda onto the reference coda. Throughout this work, the reference correlation + is held fixed and trial dilations are applied to the current correlation, +$$ +c_\epsilon(t)=c[(1+\epsilon)t], +$$ +where interpolation is performed only on (c). Thus $(\epsilon=t_{\rm cur}/t_{\rm ref}-1)$ is a fractional travel-time dilation: +$\epsilon>0$ denotes a delayed phase in the current coda (slower) and $\epsilon<0$ denotes an earlier arrival time (faster). +For unchanged propagation geometry, +$$ +1+\epsilon=\frac{t_{\rm cur}}{t_{\rm ref}} +=\frac{v_{\rm ref}}{v_{\rm cur}}, +$$ +and therefore the physical fractional velocity change reported throughout this work is +$$ +\boxed{ +\frac{\delta v}{v} +\equiv +\frac{v_{\rm cur}-v_{\rm ref}}{v_{\rm ref}} += +-\frac{\epsilon}{1+\epsilon}. +} +$$ +The commonly used relation ($\delta v/v\simeq-\epsilon\simeq-\delta t/t$) is its first-order approximation +and used in the majority of published work. We retain the exact finite-change transformation because its +computational cost is negligible and because the distinction becomes measurable for velocity perturbations +of several percent measured in large strain phenomena such as landslides. The current coda is stretched +rather than the reference correlation so that the high-SNR reference stack remains unchanged throughout +the search. While the reciprocal formulations are mathematically equivalent; in sampled, finite-window +data they can differ because interpolation and boundary truncation break that symmetry. + +The elevated sensitivity comes at the price of a long series of processing choices, and at almost every step the analyst makes a choice. Among these are choices of - estimators between windowed phase measurements or strething [@Mikesell2015, @Mao2020, @Yuan2021], + estimators between windowed phase measurements or stretching [@Mikesell2015, @Mao2020, @Yuan2021], frequency band and coda window (which together set the sampled depth; @Obermann2013 [@Obermann2016]), - reference window [@Brenguier2014, @Ermert2023, @Okubo2024], how much to substack to increase - coherence among windows (Hadzianou Celine), + reference window [@Brenguier2014, @Ermert2023, @Okubo2024], increasing the temporal + resolution of the measurement through substacking-filtering-denoising [@Hadziioannou2011,@Moreau2017,@Mao2019,@Viens2020], and how to aggregate and weight the many cross-component and station-pair measurements that make up a single reported \dvv\ time series (e.g., @Hobiger2012). - These choices are typically made by habit, justified briefly if at all , and rarely reported in + These choices are made by habit, justified briefly if at all, and rarely reported in enough detail to reproduce. The community has long flagged *individual* pitfalls (spurious changes from non-stationary noise, @Zhan2013; measurement-error -formulae, @Clarke2011 [@Weaver2011]), but the *cumulative* effect of the full -choice set on both the value and its stated uncertainty has not been quantified -comprehensively in the literature. +formulae, @Clarke2011 [@Weaver2011]) and has compared estimators against one +another on simulated data [@Yuan2021]. What has not been done, to our +knowledge, is to quantify on one truth-known dataset the *joint* effect of the +full choice set on both the value and its stated uncertainty, and to carry +that spread into a measurement covariance. One indication of the stakes is the +compilation of @Denolle25b, in which most studies find \dvv\ anticorrelated +with groundwater level, but with a scatter across studies that differences in +frequency band, single-station versus inter-station correlations and other +processing choices can explain in part, alongside genuine hydrogeological +differences between sites; that scatter limits how far the compiled relation +can be used quantitatively in hydrological work. This is a reproducibility problem of exactly the "garden of forking paths" type identified in the statistical sciences [@Gelman2013; @Steegen2016]: many individually reasonable analyses of the same data give different answers, and -without full reporting parameter choices we cannot fully interpret \dvv\ as robust values. -. Here we make the problem concrete for \dvv\ monitoring. We use purely synthetic correlation +without full reporting of parameter choices we cannot interpret a reported +\dvv\ as a robust value. Here we make the problem concrete for \dvv\ monitoring. +We use purely synthetic correlation time series to test the methods (estimators) and parameter choices that the community -makes to estimate \dvv\, which we report over 103 studies Appendix~\ref{app:survey}. +makes to estimate \dvv$\,$which we report over 103 studies in Appendix\ \ref{app:survey}. We do not aim to report the "best" pipeline, which is most often the one reported in -scientific papers, but instead document the various parameter impacts (Section~\ref{sec:results}). -We then propose a new measurement error that incoporates these effects into a data -covariance matrix $C_d$ (Section~\ref{sec:bayes}). +scientific papers, but instead document the parameter impacts (Section\ \ref{sec:results}). +We then propose a new measurement error that incorporates these effects into a data +covariance matrix $C_d$ (Section\ \ref{sec:bayes}). Throughout this paper, key notation includes: $\sigma$ (measurement uncertainty of a recovered \dvv\ estimate), $B$ (frequency bandwidth), and $W=[t_1,t_2]$ (coda window); subscripts distinguish specific contexts (e.g., $\sigma_k$ for per-component uncertainty), each defined where first introduced. -One example of propagating such error in downstream scientific insights is the +One example of propagating such error into downstream science is the migration of the surface \dvv\ measurement to depth profiles of perturbations in -shear wave velocity $\Delta V_S(z)/V_S(z)$, which often depends on the wavefield -constituting the coda waves, such as surface waves or body waves, and that depend -on the source-receiver pair geometry. We illustrate the propagation of errors to a -depth profile (Section~\ref{sec:depth}). We only utilize synthetic examples for -ground truthing on the signal processing parameters, since the concepts behind -the observations of phase lags in scattered waves is well established [@Obermann2013]. -We package this new methodology in a Python software, ``codameter``, which we also -recast as an agentic skill: an AI agent can be asked to recommend a processing -configuration or recover a \dvv(t) series, and its answer is scored against -seeded synthetic golden cases with known ground truth, including a -hidden-truth variant that withholds the answer from the public package so it -cannot be reconstructed rather than measured. +shear wave velocity $\Delta V_S(z)/V_S(z)$, which depends on the wavefield +constituting the coda waves, surface or body waves, and on the source-receiver +geometry. We set out how the measurement covariance enters such a depth +inversion (Section\ \ref{sec:depth}); the executable depth stage is described +there, not evaluated. We use synthetic examples for ground truthing of the +signal-processing parameters, since the physics of phase lags in scattered +waves is well established [@Obermann2013]. + +We then compare single-station \dvv\ from the same measurement code, run on +NoisePy correlations for three California stations, with a published product +(Section\ \ref{sec:deployment}). We package the methodology in a Python +software, ``codameter``, which also ships an advisor skill: an AI agent can be +asked to recommend a processing configuration or recover a \dvv(t) series, +and its answer can be scored against seeded synthetic golden cases with known +ground truth, including a hidden-truth variant that withholds the answer from +the public package. The scorer and dataset are part of the release; an +evaluation of agents against them is not part of this paper. # Synthetic framework {#sec:methods} We build each synthetic reference coda wave as a band-limited random-phase -wavefield modulated by a physically grounded coda envelope. We model the envelope from the exact single-scattering +wavefield modulated by a physically grounded coda envelope. We model the envelope +from the exact single-scattering solution of the two-dimensional radiative transfer equation for isotropic scattering [@Sato1993; @Paasschens1997], which underlies coda-envelope modelling of scattering and intrinsic attenuation [@Margerin1998]. The energy density at @@ -170,7 +220,7 @@ reproduces the observation that high frequencies are retained only at short lag times, so a fixed late window samples different depths at different bands. A homogeneous velocity change is imposed exactly by stretching the lapse-time -axis, $u_{\rm cur}(t) = u_{\rm ref}\!\left(t/(1+\dvv)\right)$, and a repeated time +axis, $u_{\rm cur}(t) = u_{\rm ref}\!\left(t\,(1+\dvv)\right)$, and a repeated time series is produced by generating this stretched coda with a prescribed ground-truth $\dvv(t)$ and additive band-limited noise at a controlled signal-to-noise ratio. The concept has been demonstrated using full waveform @@ -179,54 +229,53 @@ we do not repeat that full-waveform modeling here. Because the imposed $\dvv(t)$ a recovered series from it is an artefact of the processing, not of the data. -We utilize seven \dvv\ estimators that were implemented in ``noisepy`` in the -`monitoring_methods` module [@Jiang2020]: trace stretching (TS, @lobkis01), windowed +We use seven \dvv\ estimators that were implemented in ``noisepy`` +[@Jiang2020]: trace stretching (TS, @lobkis03), windowed cross-correlation (WCC, @poupinet84), dynamic time warping (DTW, @Mikesell2015), -te moving-window cross-spectrum (MWCS; @Clarke2011), and three wavelet-domain methods, the +the moving-window cross-spectrum (MWCS; @Clarke2011), and three wavelet-domain methods, the wavelet cross-spectrum (WCS, @Mao2020) and the two wavelet stretching (WTS) and wavelet DTW (WTDTW) -introduced and benchmarked numerically by @Yuan2021. The framework, the figures below, and a - implementation are released in the open ``codameter`` package -(Section~\ref{sec:discussion}). Formal definitions of all seven methods, of +introduced and benchmarked numerically by @Yuan2021. The framework, the figures below, and an +implementation are released in the open ``codameter`` package +(Section\ \ref{sec:discussion}). Formal definitions of all seven methods, of the two aggregation pathways, and of the uncertainty conventions are described in -Appendices~\ref{app:estimators} and~\ref{app:aggregation}. +Appendices\ \ref{app:estimators} and\ \ref{app:aggregation}. Each of these methods require specific parameter choices, which we categorize and -reference in Table~\ref{tab:hyperparams}. The work presented below measure the impacts +reference in Table\ \ref{tab:hyperparams}. The work presented below measure the impacts of each of these parameter choices on the resulting \dvv\. ```{=latex} \begin{table} \footnotesize \caption{Processing choices (``hyper-parameters'') and their effect on the -recovered value and the reported uncertainty ($B$: bandwidth, $N$: measurement -count, $N_{\mathrm{eff}}$: weighted effective count).} +recovered value and the reported uncertainty. Key notation: $B$ (frequency bandwidth), +$W=[t_1,t_2]$ (coda window), $N$ (measurement count), $N_{\mathrm{eff}}$ (weighted effective count), $\sigma$ (measurement uncertainty).} \label{tab:hyperparams} \begin{tabularx}{\textwidth}{@{}>{\raggedright\arraybackslash}p{2.35cm} L L L@{}} \toprule \textbf{Choice} & \textbf{Options / typical range} & \textbf{Effect on the value} & \textbf{Effect on the uncertainty} \\ \midrule -Estimator & TS, WCC, DTW, MWCS, WCS, WTS, WTDTW (7 in NoisePy) & +Estimator & TS, WCC, DTW, MWCS, WCS, WTS, WTDTW & Agree at small \dvv; at large \dvv\ phase methods cycle-skip, warps under-shoot -(Fig.~\ref{fig:methods}) & Each has its own error model; the inter-method spread -is itself an uncertainty \\ \hline +(Fig.~\ref{fig:methods}) & Each has its own error model; inter-method spread is an uncertainty \\ \hline Phase unwrapping & on / off (phase methods) & Decides whether MWCS/WCS cycle-skip (Fig.~\ref{fig:methods}b) & Sets the usable \dvv\ range \\ \hline -Frequency band $[f_1,f_2]$ & 0.1--2\,Hz (volcano), 2--4\,Hz (aquifer), +$B$ & 0.1--2\,Hz (volcano), 2--4\,Hz (aquifer), 4--12\,Hz (landslide) & Selects the sampled depth, hence \emph{which} signal -(Fig.~\ref{fig:params}a) & $\sigma$ falls as bandwidth $B$ grows \\ \hline -Coda window $[t_1,t_2]$ & a few to tens of mean free times & Later lapse $\to$ -deeper, larger sensitivity & $\sigma\propto(t_2^3-t_1^3)^{-1/2}$, but late coda -is low-SNR \\ \hline -Window--band coupling & fixed vs scaled with $f$ & A fixed late window at high -$f$ measures noise (Fig.~\ref{fig:params}b) & Inflates $\sigma$ / decorrelation -at high band \\ \hline -Reference & total stack / trailing / joint inversion & Moving reference erases -slow trends (Fig.~\ref{fig:params}c) & Reference noise propagates; inversion +(Fig.~\ref{fig:params}a) & $\sigma$ decreases with increasing $B$ \\ \hline +$W$ & a few to tens of mean free times & Later lapse $\to$ +deeper, larger sensitivity & $\sigma\propto(t_2^3-t_1^3)^{-1/2}$ (duration effect), +but late coda is low-SNR \\ \hline +$W$-$B$ coupling & fixed vs scaled with $f$ & A fixed late window at high +$f$ measures noise (Fig.~\ref{fig:params}b) & inceases $\sigma$ due to decorrelation +at high $f$ \\ \hline +Reference & total stack / trailing / joint inversion & Trailing reference gives +increments: the trend is absent unless they are cumulated, which then drifts; +joint inversion preserves it directly (Fig.~\ref{fig:params}c) & Reference noise propagates; inversion lowers it \\ \hline Stacking / substack & 1--30+ days & Smears and delays transients -(Fig.~\ref{fig:params}d) & $\sigma$ falls with stack length; resolution falls -too \\ \hline +(Fig.~\ref{fig:params}d) & $\sigma$ and resolution decreases with stacking length \\ \hline Component aggregation & A (average \dvv) vs B (average CC images); weighted vs not & Different time series (Fig.~\ref{fig:aggregation}) & Different uncertainty object (ensemble spread vs CC-peak width) \\ \hline @@ -246,31 +295,77 @@ Clock / timing & causal vs acausal branch handling & A clock error fabricates \end{table} ``` +Several quantities in this paper are reported with the same symbol $\sigma$ +but estimate different things. Table\ \ref{tab:estimands} fixes, for each, what +it is an estimate of, its units, and the datum and epochs it is evaluated on; +figure captions refer to it. + +```{=latex} +\begin{table} +\footnotesize +\caption{Reported quantities, what each estimates, and how it is evaluated. +All \dvv\ quantities are fractions of velocity; figures show percent.} +\label{tab:estimands} +\begin{tabularx}{\textwidth}{@{}>{\raggedright\arraybackslash}p{3.1cm} L L@{}} +\toprule +\textbf{Quantity} & \textbf{Estimate of} & \textbf{Datum and support} \\ +\midrule +Recovery RMS (Sections~\ref{sec:results}--\ref{sec:multiverse}) & Root mean +square of (recovered $-$ imposed) \dvv\ for one configuration on one waveform +realisation & Raw recovered series, no baseline alignment; epochs the pipeline +produced; fixed reference from the first 60\% of the record \\ \hline +Within-measurement $\sigma_k(t)$ & Standard error of one dilation estimate from +finite coda coherence, eq.~\ref{eq:weaver} & Per epoch and configuration; +depends on coherence, band, window; a lower bound (Section~\ref{sec:bayes}) \\ \hline +Between-pair SD, $\sigma_{\mathrm{SD}}$ & Dispersion of the $N$ pair estimates +at one epoch (physical heterogeneity plus pair noise) & Finite network; no datum +change \\ \hline +Network SE, $\sigma_{\mathrm{SE}}$, $\sigma_{\mathrm{SE},w}$ & Precision of the +network mean under independent pairs; shared stations or noise make it +optimistic & Same epochs; the target is the finite-network mean \\ \hline +Posterior credible band on $\mu(t)$ & Precision of the ensemble-combined +estimate under the model of Section~\ref{sec:bayes} & Decimated epochs; under-covers +when configurations share a bias \\ \hline +$C_d$ & Proposed error covariance of one ensemble member: fitted +floor, excess spread, temporal correlation, offset scale $\tau$ & Same +epochs; 95\% pointwise member coverage supported, 68\% overcoverage; +temporal covariance unvalidated (Table~\ref{tab:calibration}) \\ \hline +Field comparison $r$, slope & Agreement with a published product after matched +smoothing & Calendar-day join, 150-day burn-in, trailing 90-day mean +(Section~\ref{sec:deployment}) \\ +\bottomrule +\end{tabularx} +\end{table} +``` + # parameter-dependent \dvv\ and its errors {#sec:results} -The literature agrees on the components of a well-posed \dvv\ measurement: a -stretching-family estimator for robustness at low SNR and large change -[@Mikesell2015; @Yuan2021], a coherence-based error model -[@Clarke2011; @Weaver2011], a long stable reference [@Wang2017], and -cross-validation against a second estimator [@Obermann2019]. Yet +The literature agrees on the components of a well-posed \dvv\ measurement: an +estimator matched to the expected size of the change (the stretching family +remains accurate at large \dvv, Section\ \ref{sec:methods-fig}; its noise +robustness relative to the warping methods depends on the setting, and +@Yuan2021 rank it below DTW in that respect on their heterogeneous full-wave +simulations), a coherence-based error model [@Clarke2011; @Weaver2011], a +long stable reference [@Wang2017], and cross-validation against a second +estimator [@Obermann2019]. Yet studies do not always report the same set, and the uncertainty convention -is rarely, if ever, quantified (Appendix~\ref{app:survey}). The sections below address each +is rarely, if ever, quantified (Appendix\ \ref{app:survey}). The sections below address each component in turn and quantify, against a known truth, how far a parameter choice -impacts the recovered \dvv\ and its error. The deliverable of this -section is a measurement covariance, which every subsequent step in the inference -chain (Sections~\ref{sec:depth}--\ref{sec:stress}) consumes. +impacts the recovered \dvv\ and its error. -Each of the parametric components is implemented in a single comprehensive package ``codameter`` -that borrows from ``msnoise`` [@Lecocq2014] and ``noisepy`` [@Jiang2020] to extract the -measurement of \dvv\ from the ambient noise monitoring workflow and generalize it -to any coda wave from repeated source-receiver paths. -Table~\ref{tab:results-synthesis} previews the RMS error against the known +Table\ \ref{tab:results-synthesis} previews the RMS error against the known synthetic ground truth for the best- and worst-case option on each axis -covered in this section, each derived in its own dedicated synthetic (detailed +covered in this section, each derived in its own dedicated synthetic exercise (detailed in the corresponding subsection below); it is a synthesis of *this section's* -per-choice numbers, distinct from Table~\ref{tab:bp-measure}'s one-at-a-time -sweep on a single shared scenario in Section~\ref{sec:multiverse}. +per-choice numbers, distinct from Table\ \ref{tab:bp-measure}'s one-at-a-time +sweep on a single shared scenario in Section\ \ref{sec:multiverse}. Every RMS +in this section is computed on the raw recovered series against the imposed +truth over the epochs the pipeline produced, with no baseline alignment, so a +reference offset counts as error (Section\ \ref{sec:param_ref} shows that +explicitly); the network-level uncertainty conventions of +Section\ \ref{sec:uncertainty} are reported quantities, not recovery errors, +and are listed in Table\ \ref{tab:estimands} rather than here. ```{=latex} \begin{table} @@ -283,21 +378,21 @@ its own dedicated synthetic scenario (see the cross-referenced subsection).} \toprule \textbf{Axis} & \textbf{Best-case RMS} & \textbf{Worst-case RMS} & \textbf{Section} \\ \midrule -Estimator (family split) & $<\!0.01\,\%$ (TS/WTS, up to 5\,\% true \dvv) & -cycle-skip $>\!0.5\,\%$ past $\sim\!1.4\,\%$ true \dvv\ (MWCS) & +Estimator (family split) & $<\!0.01\,\%$ (TS, up to 5\,\% true \dvv) & +cycle-skip $>\!0.5\,\%$ past $\sim\!1.5\,\%$ true \dvv\ (MWCS) & Section~\ref{sec:methods-fig} \\ \hline Cross-component aggregation & $\sim\!0.03\,\%$ (Approach B, averaged images) & $\sim\!0.31\,\%$ (Approach A, unweighted) & Section~\ref{sec:aggregation} \\ \hline -Network aggregation (per-pair spread) & $\sim\!0.005\,\%$ (network SE) & -$\sim\!0.05\,\%$ (individual-pair range) & Section~\ref{sec:uncertainty} \\ \hline -Frequency band & $\sim\!0.003$--$0.03\,\%$ (matched to depth) & -$\sim\!0.10\,\%$ (mismatched) & Section~\ref{sec:params} \\ \hline +Frequency band & $\sim\!0.028$--$0.031\,\%$ (within $\pm0.3\,$Hz of the true +band) & $\sim\!0.10\,\%$ (center off by $>\!0.5\,$Hz) & +Section~\ref{sec:params_freq} \\ \hline Coda window & $\sim\!0.01\,\%$ (adapted to band) & -$\sim\!3.8\,\%$ (fixed, wrong band) & Section~\ref{sec:window} \\ \hline -Reference scheme & $\sim\!0.03$--$0.04\,\%$ (fixed stack / joint inversion) & -$\sim\!0.16\,\%$ (60-day moving) & Section~\ref{sec:params} \\ \hline -Stack length & $\sim\!0.018\,\%$ (10-day) & -$\sim\!0.044\,\%$ (1-day, noisy) & Section~\ref{sec:params} \\ +$\sim\!3.9\,\%$ (fixed, wrong band) & Section~\ref{sec:param_window} \\ \hline +Reference scheme & $\sim\!0.03\,\%$ (whole record, earliest period, or joint +inversion) & $\sim\!0.15$--$0.16\,\%$ (end-of-record fixed, or moving) & +Section~\ref{sec:param_ref} \\ \hline +Stack length & $\sim\!0.020\,\%$ (7--10-day, workable deployment) & +$\sim\!0.044\,\%$ (1-day, same deployment) & Section~\ref{sec:param_substack} \\ \bottomrule \end{tabularx} \end{table} @@ -305,25 +400,32 @@ $\sim\!0.044\,\%$ (1-day, noisy) & Section~\ref{sec:params} \\ ## Estimator family {#sec:methods-fig} +We implement all methods as in previous work [@Jiang2020]. + + + As of codameter v0.4.0, all seven estimators return physical \dvv\ under the sign convention above rather than the raw stretch factor $\varepsilon$; the synthetic generator imposes changes in the same convention, so a positive -imposed \dvv\ recovers as positive. `tests/test_sign_convention.py` holds -every estimator to this convention in both signs, and checks the full -`run_pipeline` call path end to end, so the convention cannot silently drift -back. - -On small, clean \dvv\, all seven estimators agree, demonstrating robustness of the methods -(Fig.~\ref{fig:methods}a). Sweeping the same clean recovery out to -$\pm 5\,\%$ (Fig.~\ref{fig:methods}b) shows exactly where and how each family +imposed \dvv\ recovers as positive. A dedicated regression test holds every +estimator to this convention in both signs, end to end through the full +measurement pipeline, so the convention cannot silently drift back. + +On small, clean \dvv$\,$all seven estimators agree to within 0.04\,\% RMS +(Fig.\ \ref{fig:methods}a). Sweeping the same clean recovery out to +$\pm 5\,\%$ (Fig.\ \ref{fig:methods}b) shows exactly where and how each family first departs from the 1:1 line, and the estimator choice becomes consequential -at large, noisy \dvv\ (Fig.~\ref{fig:methods}c), where the effect of the methods -is split according to their phase measurement approaches. The stretching family (TS, WTS) and WCC match the whole dilated -coda and remain accurate for high SNR coda waves; the phase methods (MWCS) read a wrapped phase and may -cycle-skips, while the *same* cross-wavelet phase (WCS), once unwrapped in 2-D, -recovers the change. The warping methods (DTW, WTDTW) track but under-shoot the largest -strains. No estimator is simply "right" and choices in the estimators -can alters the \dvv\ measurements for larger strain changes. +at large, noisy \dvv\ (Fig.\ \ref{fig:methods}c), where the effect of the methods +is split according to their phase measurement approaches. The stretching family +(TS, WTS) and WCC match the whole dilated coda and stay within 0.05\,\% RMS of +the truth on the noisy landslide signal (0.005, 0.010 and 0.046\,\%); the +warping methods (DTW, WTDTW) track but under-shoot the largest strains (0.16 and +0.08\,\% RMS); both phase methods fail on this noisy, large-strain signal, +MWCS by cycle-skipping (2.9\,\% RMS) and WCS, whose 2-D unwrapping recovers +the clean sweep of panel (b), by losing the phase track once noise is added +(3.8\,\% RMS; the numbers are computed from the figure's numerical sidecar). +No estimator is simply "right"; the choice of estimator materially changes the +\dvv\ measurement at larger strain. \begin{figure} @@ -331,38 +433,53 @@ can alters the \dvv\ measurements for larger strain changes. \includegraphics[width=\textwidth]{demo_1_methods.png} \caption{Estimator choice across the seven NoisePy methods. (a) Clean, small \dvv: all agree. (b) The same clean recovery swept over $\pm 5\,\%$ - true \dvv: MWCS cycle-skips almost immediately past $\pm 1$--$2\,\%$, DTW/WTDTW - break past $\pm 3$--$4\,\%$, WCS degrades smoothly, while TS/WTS/WCC track the - 1:1 line throughout. (c) Large, noisy \dvv\ (a pre-failure landslide signal): - MWCS cycle-skips, 2-D-unwrapped WCS and the stretching family track, the - warping methods under-shoot.} + true \dvv: MWCS cycle-skips past $\sim\!1.5\,\%$ on either branch; TS and WTS + track the 1:1 line throughout; WCC tracks just as tightly on the negative + branch but breaks sharply near the positive edge; DTW and WTDTW break + asymmetrically, WTDTW near $+1\,\%$ but only near $-3\,\%$ on the other + branch; WCS degrades smoothly, crossing $1\,\%$ error beyond $\pm 4\,\%$. + (c) Large, noisy \dvv\ (a pre-failure landslide signal): the stretching + family and WCC track, the warping methods under-shoot, and both phase + methods fail (MWCS cycle-skips; WCS loses the phase track in noise despite + the 2-D unwrapping that carries it through the clean sweep in b). RMS + errors are given in the text; the plotted arrays are in the figure's + sidecar (Table~\ref{tab:estimands}).} \label{fig:methods} \end{figure} -On a clean, noiseless sweep of true \dvv\ from 0 to 5\,\% (Fig.~\ref{fig:methods}b), -the phase-wrapped MWCS estimator is the first to break: its error stays below -$0.1\,\%$ up to a true \dvv\ of $\sim\!1.2\,\%$, then jumps discontinuously past -$0.5\,\%$ error by $\sim\!1.4\,\%$ true \dvv\ --- the cycle-skip. The stretching -family (TS, WTS) stays below $0.01\,\%$ error out to the full 5\,\% tested, and -WCC stays below $0.1\,\%$; the warping methods (DTW, WTDTW) are accurate at small -\dvv\ but develop intermittent, large ($>\!1\,\%$) errors from $\sim\!3\,\%$ -true \dvv\ onward as the warp path becomes ill-conditioned, while WCS degrades -smoothly rather than catastrophically, crossing $1\,\%$ error only beyond -$\sim\!4\,\%$ true \dvv. +On a clean, noiseless sweep of true \dvv\ from $-5$ to $5\,\%$ (Fig.\ \ref{fig:methods}b), +the phase-wrapped MWCS estimator is the first to break on either branch: its +error stays below $0.1\,\%$ out to $\sim\!1.3\,\%$ true \dvv, then exceeds +$1\,\%$ error by $\sim\!1.5\,\%$ --- the cycle-skip, essentially symmetric in +sign. The stretching family (TS, WTS) stays below $0.1\,\%$ error out to the +full $5\,\%$ tested, on both branches. WCC is just as accurate on the negative +branch (error stays below $0.1\,\%$ throughout) but breaks sharply on the +positive branch, crossing both $0.1\,\%$ and $1\,\%$ error abruptly at the +edge of the tested range ($\sim\!4.75\,\%$) --- a sign asymmetry from the +physical convention itself (Section\ \ref{sec:intro}), not a processing +artefact. The warping methods develop large ($>\!1\,\%$) errors asymmetrically +as the warp path becomes ill-conditioned: WTDTW crosses $1\,\%$ error already +at $\sim\!1\,\%$ true \dvv\ on the positive branch but only at $\sim\!3\,\%$ on +the negative branch, and DTW crosses at $\sim\!2.5\,\%$ versus $\sim\!3\,\%$. +WCS degrades smoothly rather than catastrophically, crossing $1\,\%$ error +beyond $\pm4\,\%$ true \dvv\ on either branch. + ## Aggregating cross-component results {#sec:aggregation} -Each three-component seismic station (e.g., Z, N, E) carries 6 cross-componet correlations -(ZZ, NN, EE, ZE, ZN, NE), whether they are calculated at the single station or -a inter-station pair. Each carry a signature of the changes in velocity, components -may be dominated by Love or Rayleigh waves [@Lin2008; @Stehly2006], but there scattering and non-straight -ray path induce cross-component leakage between modes [@Hennino2001; @Margerin2019], and thus it is often -assumed in practice that coda waves of cross-components with multi-scattering characteristixcs +Each three-component seismic station (e.g., Z, N, E) carries 6 cross-component correlations +(ZZ, NN, EE, ZE, ZN, NE), whether they are calculated at a single station or +an inter-station pair. Each carries a signature of the changes in velocity; components +may be dominated by Love or Rayleigh waves [@Lin2008; @Stehly2006], but scattering and non-straight +ray paths induce cross-component leakage between modes [@Hennino2001; @Margerin2019], and thus it is often +assumed in practice that coda waves of cross-components with multi-scattering characteristics (e.g., no clearly separated phases) are composed of "surface waves" with strong S-wave sensitivity. Combining them together requires parameter choices, such as averaging them directly [@Liu2014], -or weighted (e.g., using coherence-based weighting @Hobiger2012, @DePlaen2016). Combining is another workflow +or weighted (e.g., using coherence-based weighting @Hobiger2012, @DePlaen2016). + +Combining is another workflow choice that can change both the value and the uncertainty -(Fig.~\ref{fig:aggregation}). One may peak-pick each component's +(Fig.\ \ref{fig:aggregation}). One may peak-pick each component's correlation-coefficient curve $\mathrm{CC}(\varepsilon,t)$ and then average the per-component \dvv\ (Approach A) --- unweighted, a few poor components bias the mean; coherence-weighted, they are suppressed --- or one may average the @@ -396,13 +513,25 @@ Adding the next layer up --- combining many station pairs into a unified network --- exposes the most consequential and least-reported choice of all: how to summarize the uncertainty. Three conventions are common: a coherence-weighted standard error (e.g., @Clarke2011), an unweighted standard error ($\sigma=\mathrm{std}/\sqrt{N}$; e.g., @Brenguier2008), -and the between-pair standard deviation (e.g., @Clements2018). On the same synthetic network the recovered means nearly coincide, -but the reported $1\sigma$ spans a factor of $\sim\!\sqrt{N}$ -(Fig.~\ref{fig:uncertainty}). A velocity change that is "$3\sigma$ significant" -under the tightest convention is "$1\sigma$, not significant" under the most -conservative one --- from identical data. Error bars on published \dvv\ are -therefore not comparable across studies unless the aggregation, the weighting, -and the standard-error-versus-standard-deviation convention are all stated. +and the between-pair standard deviation (e.g., @Clements2018). These are +estimates of different quantities (Table\ \ref{tab:estimands}): the standard +error is the precision of the network mean under independent pairs, the +standard deviation is the dispersion of the pairs, which on this synthetic +mixes the 15\,\% pair-to-pair amplitude heterogeneity we impose with the pair +noise, and the two are related by $\sqrt{N}$ by construction. On the same +synthetic network the recovered means nearly coincide, but the number reported +as $1\sigma$ spans a factor of $\sim\!\sqrt{N}$ (Fig.\ \ref{fig:uncertainty}). +A velocity change that is three times the coherence-weighted standard error is +about one between-pair standard deviation, from identical data; neither +statement is wrong, but a study that reports only "$1\sigma$" leaves the reader +unable to tell which is meant. Error bars on published \dvv\ are therefore not +comparable across studies unless the aggregation, the weighting, and the +standard-error-versus-standard-deviation convention are all stated. Neither +convention is the precision of the mean when pairs share stations or noise; +that requires the pair covariance, $\mathbf{a}^\top\Sigma\mathbf{a}$ for +normalised weights $\mathbf{a}$, which the Bayesian ensemble of +Section\ \ref{sec:bayes} supplies for the configuration axis and which a +network extension would supply for the pair axis. \begin{figure} \centering @@ -414,8 +543,8 @@ and the standard-error-versus-standard-deviation convention are all stated. \label{fig:uncertainty} \end{figure} -Figure~\ref{fig:uncertainty} plots only the *network-aggregate* series, which -hides how much the individual pairs actually disagree. Fig.~\ref{fig:network-pairs} +Figure\ \ref{fig:uncertainty} plots only the *network-aggregate* series, which +hides how much the individual pairs actually disagree. Fig.\ \ref{fig:network-pairs} plots the same nine-pair network's *individual* \dvv(t) curves, styled after a basin-scale, urban ambient-noise deployment such as the San Gabriel Valley groundwater network [@Clements2018] --- an illustrative geometry rather than a @@ -440,31 +569,203 @@ against a published network value. \label{fig:network-pairs} \end{figure} -## Frequency band, reference and stacking {#sec:params} +## Frequency band {#sec:params_freq} The remaining choices are no less consequential. The **frequency band** sets the sampled depth: in a two-layer medium, high frequencies recover shallow, often seasonal signals and low frequencies recover a deeper, maybe more tectonic, signal -(Fig.~\ref{fig:params}a). On our synthetic two-layer groundwater scenario, a band -matched to each layer (1.5--6\,Hz for the shallow, seasonal signal; 0.2--0.8\,Hz -for the deep, drought-trend signal) recovers each with RMS error -$\sim\!0.003$--$0.03\,\%$; using the wrong band for a given depth inflates the -error to $\sim\!0.10\,\%$ for both --- a $\sim\!4$--30$\times$ degradation. +(Fig.\ \ref{fig:params}a). In practice a band often gets reused from a neighboring +deployment or an earlier study at the same site without re-checking that it still +matches the target depth --- exactly the error this section quantifies. + +On our synthetic two-layer groundwater scenario, holding the recovery band's width +fixed (0.6$\,$Hz) and sweeping its center away from the deep layer's true +0.2--0.8$\,$Hz band shows the cost is not gradual: RMS error against the known +truth stays flat, $\sim\!0.028$--$0.031\,\%$, for a center offset within +$\sim\!0.3\,$Hz of the true center, then rises by a factor of $\sim\!3$--$4$ once +the offset passes $\sim\!0.5\,$Hz --- the point at which the assumed band starts +sampling the shallow layer's signal instead of the deep one --- and plateaus +near $\sim\!0.10\,\%$ beyond that (Fig.\ \ref{fig:band-sensitivity}). The band +choice is forgiving up to the edge of the layer it targets, and expensive +immediately past it, not gradually worse the further off it drifts. + +\begin{figure} + \centering + \includegraphics[width=0.7\textwidth]{demo_16_band_sensitivity.png} + \caption{Frequency-band sensitivity: RMS error against the known + groundwater deep-layer truth as the recovery band's center is swept away + from the true 0.2--0.8$\,$Hz band, holding its 0.6$\,$Hz width fixed. Error + is flat within $\sim\!\pm0.3\,$Hz of the true center, then rises sharply + once the assumed band drifts into the shallow layer's territory.} + \label{fig:band-sensitivity} +\end{figure} + +**Scale of effect:** a band-center error under $\sim\!0.3\,$Hz costs essentially +nothing here; past $\sim\!0.5\,$Hz it costs a factor of $\sim\!3$--$4$ in RMS, +from $\sim\!0.03\,\%$ to $\sim\!0.10\,\%$. + +## Reference {#sec:param_ref} The **reference** defines what survives: a moving reference re-baselines continuously and erases slow trends that a fixed reference or a joint inversion -[@Brenguier2014] preserve (Fig.~\ref{fig:params}c). On the volcano synthetic, a -fixed total-stack reference gives RMS $\sim\!0.03\,\%$ and a Brenguier-style -joint inversion $\sim\!0.04\,\%$ (both preserve the pre-eruptive trend), while a -60-day moving reference gives RMS $\sim\!0.16\,\%$ --- roughly 4--5$\times$ worse ---- because it re-baselines away the very trend being measured. +[@Brenguier2014] preserve (Fig.\ \ref{fig:params}c). In practice the choice is +rarely just fixed-versus-moving: an analyst also decides *which* period of the +record a fixed reference is built from, and that choice alone can dominate the +error --- for instance when a deployment barely predates the process of +interest, or when the only quiet-looking period available sits close in time +to the process itself. + +We compare five named schemes on the volcano synthetic: a reference built from +the **beginning** of the pre-eruptive record (its earliest 15\%), from the +**end** of that record (its latest 15\%, immediately before the eruption), +from the **whole** pre-eruptive record, a 60-day **moving** (trailing) +reference, and **no single reference at all** --- the Brenguier et al. +(2014)-style joint inversion, which measures relative dv/v between many short +stacks instead of referencing every day to one (Fig.\ \ref{fig:reference-schemes}a). +The whole-record, beginning, and inversion schemes all recover the truth to RMS +$\sim\!0.03\,\%$. The end-of-record reference does far worse, RMS +$\sim\!0.15\,\%$ --- not because it tracks the dynamics any less faithfully +(its residual scatter around the truth, $\sim\!0.029\,\%$, matches every other +fixed scheme) but because the reference epoch itself already sits +$\sim\!0.15\,\%$ into the developing pre-eruptive ramp, and every dv/v value is +reported *relative to whatever the reference was doing*. Reference choice sets +the zero point, not just the noise floor: comparing dv/v across studies, or +across deployments that started at different times, requires knowing what the +reference period itself was doing, not just how well each pipeline scores +against a single truth. + +The 60-day moving reference gives RMS $\sim\!0.16\,\%$ --- comparable to the +worst fixed case, but for the opposite reason: it re-baselines away the trend +continuously rather than sitting at one biased epoch. Lengthening the trailing +window helps only slowly and never converges to the fixed-reference baseline: +RMS falls from $\sim\!0.168\,\%$ at a 10-day trailing window to $\sim\!0.151\,\%$ +at 240 days, still $\sim\!4$--$5\times$ the whole-record RMS +(Fig.\ \ref{fig:reference-schemes}b) --- the erasure is structural, not a noise +effect that more averaging fixes. + +Read carefully, though, that erasure is a property of the \emph{uncumulated +increment}, not of a non-fixed reference as such --- and the published +alternatives to a fixed reference do not take the form the sweep assumes. They +fall into two families, neither of which re-baselines every epoch and reports +the raw increment. + +The first cumulates. @James2017 re-baseline each day against the immediately +preceding day-stack and sum the daily $\delta t/t$ from a fixed start date, +recovering a seasonal freeze--thaw trend in Alaskan permafrost that a stationary +reference could not detect at all: the frozen-to-thawed velocity contrast made +the stationary comparison cycle-skip, while adjacent days stayed coherent. +@Rivet2011 likewise reference each epoch to the previous one. The cost is that +summation integrates the measurement error --- @James2017 report a positive +drift in the cumulated series that their quadrature error budget could not +account for, and correct it linearly against a stationary-reference anchor. The +same rolling construction appears in laboratory coda monitoring of rock +deforming to failure, where the scattering properties change too much for a +fixed reference to stay valid [@ZotzWilson2019]. + +The second holds the reference fixed within a segment and stitches the segments +together. @Rivet2014 define a separate reference stack for each of three +multi-year periods at Piton de la Fournaise, then merge the three series by +measuring the relative velocity change \emph{between} the adjacent segment +references, using station pairs that occupied the same sites across the network +change. @SensSchonfelder2014 develop the multiple-reference form of the same +idea at the same volcano, and @Ermert2023 adopt a multiple-reference approach +for urban single-station autocorrelations in Mexico City, where long-term +waveform coherence is simply unavailable, stabilising the stacks by clustering +correlation windows with a Gaussian mixture model so that day-time and +night-time noise regimes stack separately. + +That second family is worth naming precisely, because it is not a separate +method from the joint inversion --- it is a restriction of it. Stitching two +segments by measuring the relative dv/v between their references is exactly the +adjacent-pair case of the over-determined system the inversion solves over all +pairs of block stacks. The reference axis is therefore better read as a single +continuum, from one global reference, through segment references joined +pairwise, to the fully coupled inversion, than as a menu of unrelated choices. + +Against that, the uncumulated day-by-day trailing reference swept above is a +limit case rather than a practice: we found no surveyed study that re-baselines +continuously and reports the increments without summing them. It is retained +here because it isolates what re-baselining costs when the trend is not +reconstructed, which is the failure mode the two families above exist to avoid. +codameter implements the joint inversion but neither the cumulated trailing +reference nor cluster-based reference selection. + +\begin{figure} + \centering + \includegraphics[width=\textwidth]{demo_17_reference_schemes.png} + \caption{Reference construction on the volcano synthetic. (a) Five named + schemes, each scored by RMS against the known truth over the whole record + and over the pre-eruptive ramp alone. (b) RMS for the moving reference as a + function of its trailing length; the dashed line is the whole-record fixed + reference's RMS, which the moving reference never reaches.} + \label{fig:reference-schemes} +\end{figure} + +**Scale of effect:** which *period* a fixed reference is drawn from can cost as +much as switching to a moving reference altogether ($\sim\!0.15$--$0.16\,\%$ RMS +either way); a reference from the quietest available period, of any length, +recovers the trend to $\sim\!0.03\,\%$. + +## Substacking {#sec:param_substack} The **stacking length** trades noise against temporal resolution, rounding off -and delaying a coseismic step (Fig.~\ref{fig:params}d). On the earthquake -synthetic, a 1-day stack (noisy) gives RMS $\sim\!0.044\,\%$, a 10-day stack -$\sim\!0.018\,\%$ (the best of the three), and an over-long 45-day stack -$\sim\!0.031\,\%$ --- worse than the 10-day stack despite averaging down more -noise, because it smears the step itself. +and delaying a coseismic step (Fig.\ \ref{fig:params}d). In practice the +decision is rarely "how many days" in the abstract; it is "how long until the +coda is coherent enough to trust" --- stacking only as long as needed to clear +a working correlation-coefficient (CC) threshold, then stopping. codameter's +own quality-control gate uses CC~$>0.6$ (Section\ \ref{sec:results}), and how +quickly a station clears that bar depends entirely on its data quality. + +Substack duration therefore defines a fundamental precision--temporal-resolution tradeoff. +Longer stacks suppress incoherent noise fluctuations and accelerate the convergence of +noise correlation functions, whereas shorter substacks preserve transient changes that +would otherwise be averaged within the stacking window. The reduced signal-to-noise ratio +of shorter correlations can be partially compensated through adaptive filtering, SVD-based +or learned denoising, or through redundancy across dense seismic arrays, enabling \dvv\ measurements at daily, hourly, and even sub-hourly resolution [@Hadziioannou2011,@Moreau2017,@Mao2019,@Viens2020]. + + + In this paper, the choice of substack length is guided by data-dependent quality gates + (the CC threshold above) rather than a fixed duration, which allows stations with high + coherence to preserve shorter temporal windows and thereby track rapid changes, while + stations with lower SNR substack as needed to achieve stable estimates. + + +On the earthquake synthetic, a workable deployment (SNR 4, the same setting +used throughout this section) clears CC~$>0.6$ already at a 1-day stack +(median CC 0.86); a poor, coherence-limited deployment (SNR 0.5) needs 14 days +of substacking to clear the same bar (Fig.\ \ref{fig:stack-coherence}a). The +two regimes behave differently past that point, too. For the workable +deployment, RMS is U-shaped: it falls from $\sim\!0.044\,\%$ at 1 day to a +minimum $\sim\!0.020\,\%$ around 7--10 days, then rises again to +$\sim\!0.038\,\%$ by 60 days as the stack smears the step +(Fig.\ \ref{fig:stack-coherence}b) --- the classic noise-versus-smearing +tradeoff, and the reason "longer is always better" is wrong even once the +coherence gate is satisfied. For the poor deployment, RMS is still falling at +60 days ($\sim\!0.067\,\%$, down from $\sim\!0.71\,\%$ at 1 day): the noise +floor dominates over the whole tested range, and the smearing penalty never +gets the chance to show up. The signed error in the recovered step amplitude +is negative (an under-estimate) at every stack length for the poor deployment, +and for the workable deployment up to about 45 days, past which it crosses +zero and the step is over-estimated. A recovered step is therefore a lower +bound on the true drop only in the noise-limited regime; the sign of the error +depends on the deployment and the stack length, and both should be reported. + +\begin{figure} + \centering + \includegraphics[width=\textwidth]{demo_18_stack_coherence.png} + \caption{Substacking on the earthquake synthetic, at two deployment + qualities. (a) Median stretching correlation coefficient versus stack + length; the dashed line is codameter's own CC-gate threshold + (Section~\ref{sec:results}). (b) RMS error and the absolute bias in the + recovered coseismic-step amplitude, both against the known truth, log + scale.} + \label{fig:stack-coherence} +\end{figure} + +**Scale of effect:** for a workable deployment, the noise/smearing tradeoff +bottoms out around 7--10 days at RMS $\sim\!0.02\,\%$; for a poor deployment, +substack at least $\sim\!2$ weeks just to clear the coherence gate, and expect +RMS an order of magnitude worse even after clearing it. \begin{figure} \centering @@ -474,30 +775,19 @@ noise, because it smears the step itself. \includegraphics[width=0.49\textwidth]{demo_6_stacking.png} \caption{Parameter choices. (a) Frequency band selects depth and signal. (b) A coda window does not transfer across bands. (c) Reference strategy: a moving - reference erases the trend a fixed reference and the joint inversion keep. (d) + reference differences the trend away unless its increments are cumulated; + a fixed reference and the joint inversion retain it. (d) Stacking length smears the coseismic step.} \label{fig:params} \end{figure} The accepted range for each of these parameters across the published literature is catalogued directly, study by study, in the survey of -Appendix~\ref{app:survey} (Table~\ref{tab:survey}): the frequency band, coda +Appendix\ \ref{app:survey} (Table\ \ref{tab:survey}): the frequency band, coda window, estimator, and uncertainty treatment actually reported by 103 ambient-noise \dvv\ studies. -The **reference** choice also has a construction axis beyond fixed-versus-moving: -how much of the record a "fixed" reference actually stacks. On the volcano -synthetic, a reference built from the whole pre-eruptive record gives RMS -$\sim\!0.03\,\%$, one built from only the earliest 15\,\% of that record (an -"early stack," noisier for having fewer days) gives $\sim\!0.04\,\%$ -($\sim\!1.5\times$ worse), a 60-day moving stack gives $\sim\!0.16\,\%$ -(erasing the trend, as above), and the Brenguier-style joint inversion -[@Brenguier2014] gives $\sim\!0.04\,\%$ while additionally preserving the trend ---- so among the reference-construction choices, whole-period and joint -inversion are comparably good, early-stacking is a modest ($\sim\!1.5\times$) -noise penalty, and only the moving reference actively destroys signal. - -## Coda window and its covariation with frequency band {#sec:window} +## Coda window {#sec:param_window} The coda window is not independent of the frequency band --- it deserves its own treatment because the two covary strongly, and getting this wrong is one of the @@ -505,36 +795,36 @@ larger, more avoidable sources of error in \S\ref{sec:results}. Because intrinsi and scattering attenuation both grow with frequency, high-frequency coda energy falls into the noise floor much sooner than low-frequency coda: a coda window that is well past the direct arrival for a $\sim\!0.3$--$0.8\,$Hz band is, at -$\sim\!3$--$6\,$Hz, sampling almost pure noise (Fig.~\ref{fig:params}b). On our -synthetic, a fixed 20--40\,s window at the high band gives RMS error -$\sim\!3.8\,\%$ (the noise floor, not the signal), while a window hand-adapted -to the band (3--12\,s) recovers the truth at $\sim\!0.01\,\%$ --- nearly a +$\sim\!3$--$6\,$Hz, sampling almost pure noise (Fig.\ \ref{fig:params}b). On our +synthetic, a fixed 20--40$\,$s window at the high band gives RMS error +$\sim\!3.9\,\%$ (the noise floor, not the signal), while a window hand-adapted +to the band (3--12$\,$s) recovers the truth at $\sim\!0.01\,\%$ --- nearly a 400$\times$ difference from this one choice alone. This is itself an instance of a literature-documented tension: band-matched windowing is recommended, but -Table~\ref{tab:survey} shows many surveyed studies instead reuse one fixed +Table\ \ref{tab:survey} shows many surveyed studies instead reuse one fixed window across bands. Hand-adapting the window per band, as above, requires knowing the band in advance and re-tuning per deployment. A more principled alternative --- used in our group --- is to track the coda envelope directly and stop the window where it *flattens* onto the noise floor, rather than pre-specifying a window from a -rule of thumb. We implement this as `coda_window_from_envelope()`: band-pass a -long-term reference stack, smooth its envelope, estimate the noise floor from a -common late-lapse window, and take the window end as the first lapse time past +rule of thumb. We implement this by band-passing a +long-term reference stack, smoothing its envelope, estimating the noise floor from a +common late-lapse window, and taking the window end as the first lapse time past a short onset where the envelope stays within a factor of that floor for a sustained interval (not a single noisy dip). Applied blind (without being told which band it is) to three bands spanning low, mid, and high frequency -(Fig.~\ref{fig:window-envelope}a), the detector recovers windows of +(Fig.\ \ref{fig:window-envelope}a), the detector recovers windows of $\sim\!(3,29)\,$s, $\sim\!(3,37)\,$s, and $\sim\!(3,14)\,$s respectively --- correctly shrinking at the high band, though the low-versus-mid ordering is not perfectly monotonic on this synthetic (an artifact of how the fixed additive noise floor interacts with each band's filter, not a claim that the detector is exact). Recovering \dvv\ with each band's own detected window instead of one -universal fixed (10--30\,s) window (Fig.~\ref{fig:window-envelope}b) gives RMS -$\sim\!0.032\,\%$ vs.\ $\sim\!0.036\,\%$ at the low band (a modest, -$\sim\!1.1\times$ gain), $\sim\!0.017\,\%$ vs.\ $\sim\!0.035\,\%$ at the mid -band ($\sim\!2\times$), and $\sim\!0.019\,\%$ vs.\ $\sim\!1.8\,\%$ at the high -band ($\sim\!93\times$) --- the fixed window is adequate at low frequency and +universal fixed (10--30$\,$s) window (Fig.\ \ref{fig:window-envelope}b) gives RMS +$\sim\!0.030\,\%$ vs.\ $\sim\!0.036\,\%$ at the low band (a modest, +$\sim\!1.2\times$ gain), $\sim\!0.017\,\%$ vs.\ $\sim\!0.035\,\%$ at the mid +band ($\sim\!2\times$), and $\sim\!0.020\,\%$ vs.\ $\sim\!2.0\,\%$ at the high +band ($\sim\!100\times$) --- the fixed window is adequate at low frequency and catastrophic at high frequency, while the envelope-derived window is close to the best achievable at every band without ever being told what band it is measuring. @@ -551,29 +841,6 @@ measuring. \label{fig:window-envelope} \end{figure} -## Choices that create spurious \texorpdfstring{\dvv}{dv/v} {#sec:artifacts} - -Some choices may create spurious signal. A station -clock error delays the whole correlation by a lapse-independent shift, producing -an apparent \dvv\ that appears with opposite sign on the causal and acausal -branches; measuring the two branches separately is the diagnostic -(Fig.~\ref{fig:artifacts}a). Seasonally varying noise sources warp the low-SNR -late coda, so a late measurement window reports a coherent spurious *seasonal* -\dvv\ many times the real signal while an earlier window stays clean -[the waveform-level version of @Zhan2013] (Fig.~\ref{fig:artifacts}b). - -Biases from spurious arrivals could be quantified but mostly we should -decontaminate our workflow from these artefacts or not interpret the results. - -\begin{figure} - \centering - \includegraphics[width=\textwidth]{demo_8_artifacts.png} - \caption{Deviations that create spurious \dvv. (a) A clock drift splits the causal - and acausal branches with opposite sign. (b) Seasonal late-coda noise injects a - spurious seasonal \dvv\ into a late window but not an early one.} - \label{fig:artifacts} -\end{figure} - ## Causal and acausal branches {#sec:branches} In a symmetric cross-correlation, both sides of the coda (positive or negative lags) @@ -582,26 +849,28 @@ recorded at the two stations, the correlated wavefield in the coda may differ [@ While the interpretation of such coda in terms of Earth's structure effect is difficult [@Snieder2002], the stability of the wavefield excited in the coda is the main requirement for stable \dvv\ measurements [@Hadziioannou2009]. Given the challenge in interpreting both sides independently, -researchers typically would measure \dvv\ on each lag and then report its average [@Kidiwela2026]. +researchers typically measure \dvv\ on each lag and then report its average [@Kidiwela2026]. The causal (positive-lag) and acausal (negative-lag) branches sample opposite-direction paths with different source-side illumination, and in a 3D medium their sensitivity kernels sample partly different volumes, so the two can report genuinely different \dvv\ without either being wrong. Two regimes bound the -choice (Fig.~\ref{fig:branches}). When a change is *localized* to the volume one +choice (Fig.\ \ref{fig:branches}). When a change is *localized* to the volume one branch samples, symmetrizing or averaging the branches --- the common default --- dilutes it toward zero, while the branch that carries the change recovers it -(Fig.~\ref{fig:branches}a); here preferring the branch of greatest change is -an researchers' judgement. +(Fig.\ \ref{fig:branches}a); here preferring the branch of greatest change is +a researcher's judgement. When instead both branches share the *same* change, their difference is measurement noise, and selecting the branch of greatest change over-reports it --- a max-of-two-estimators selection bias that grows as -SNR falls (Fig.~\ref{fig:branches}b). When both side exhibit the same change -(sign, coherence) but with different magnitude, it is reasonable to use the -\dvv\ of greatest change given the already low sensitivity in coda waves [@Obermann2013]. -An acceptable workflow is to measure both branches, evaluate on that consistency, -select by the coherence of the change rather than its amplitude (a criterion independent of the answer, so -it carries no selection bias), and carry the between-branch difference as an -explicit term of the measurement covariance $C_d$ (Section~\ref{sec:bayes}) +SNR falls (Fig.\ \ref{fig:branches}b). Choosing the branch of greatest change +after seeing the data is therefore a selection rule that Fig.\ \ref{fig:branches}b +shows to be biased, and the coherence of each branch is estimated from the same +observations, so selecting on coherence reduces but does not remove that bias. +The rule we adopt is fixed before the data are seen: measure both branches and +report both; combine them by their mean unless independent physical +information (source-side illumination, a change known to be confined to one +side) designates a branch beforehand; and carry the between-branch difference as +an explicit term of the measurement covariance $C_d$ (Section\ \ref{sec:bayes}) rather than discarding it by averaging. \begin{figure} @@ -616,46 +885,75 @@ rather than discarding it by averaging. \label{fig:branches} \end{figure} + +## Choices that create spurious \texorpdfstring{\dvv}{dv/v} {#sec:artifacts} + +Some choices may create spurious signal. A station +clock error delays the whole correlation by a lapse-independent shift, producing +an apparent \dvv\ that appears with opposite sign on the causal and acausal +branches; measuring the two branches separately is the diagnostic +(Fig.\ \ref{fig:artifacts}a). Seasonally varying noise sources warp the low-SNR +late coda, so a late measurement window reports a coherent spurious *seasonal* +\dvv\ many times the real signal while an earlier window stays clean +[the waveform-level version of @Zhan2013] (Fig.\ \ref{fig:artifacts}b). + +Biases from spurious arrivals could be quantified but mostly we should +decontaminate our workflow from these artefacts or not interpret the results. + +\begin{figure} + \centering + \includegraphics[width=\textwidth]{demo_8_artifacts.png} + \caption{Deviations that create spurious \dvv. (a) A clock drift splits the causal + and acausal branches with opposite sign. (b) Seasonal late-coda noise injects a + spurious seasonal \dvv\ into a late window but not an early one.} + \label{fig:artifacts} +\end{figure} + + Taken together, the choices compound. We make this concrete in -Section~\ref{sec:multiverse} by running the full *multiverse* of best-practice +Section\ \ref{sec:multiverse} by running the full *multiverse* of best-practice and deviation choices on one synthetic dataset and ranking each by the bias and the error-bar change it induces. -# The multiverse of processing choices {#sec:multiverse} +# The combined impact of processing choices {#sec:multiverse} The scenario is a single representative station pair monitoring a shallow volcanic edifice, in the style of the permanent broadband deployments used at effusive/dome volcanoes such as Piton de la Fournaise [@Brenguier2008]: a coda band matched to -shallow depths (0.4--1.0\,Hz), a coda window past the direct arrival (10--30\,s), +shallow depths (0.4--1.0$\,$Hz), a coda window past the direct arrival (10--30$\,$s), and daily correlations sampled every 3 days over 2.5 years at a per-day correlation-coefficient SNR of 7, typical of a continuously operating station. The synthetic ground truth combines an annual seasonal \dvv\ cycle (as from near-surface thermoelastic/hydrologic effects), a slow pre-eruptive inflation ramp, and a sharp co-eruptive velocity drop with partial recovery. This single-pair scenario isolates the measurement-step choices from the network-aggregation choices -already covered in Sections~\ref{sec:aggregation}--\ref{sec:uncertainty}. +already covered in Sections\ \ref{sec:aggregation}--\ref{sec:uncertainty}. The previous sections only identified single choices, but the overall research workflow -involves them all. We now estimate the combined effects of these parametic choices. +involves them all. We now estimate the combined effects of these parametric choices. Starting from a single **best-practice baseline** (trace stretching, a band matched to the target depth, a coda window well past the direct arrival, a 10-day stack, a long stable reference, coherence gating; the cross-cutting rules of @Brenguier2014 [@Weaver2011; @Clarke2011] as distilled in our survey), we change one parameter at a time to a deviation from best practice documented in the literature - and measure the resulting error against the known truth (Fig.~\ref{fig:deviations}). The ranking is unambiguous: relative -to a best-practice RMS error of $\sim\!0.02\,\%$, an unwrapped phase estimator that -cycle-skips is catastrophic, a moving reference and a wrapped-phase MWCS each inflate the -error roughly an order of magnitude, an over-long stack and a late low-SNR window -distort the co-eruptive drop, while the frequency band (which mostly sets -precision here) and the gating are second-order. The joint inversion is -nearly as good as the fixed reference and preserves the trend. + and measure the resulting error against the known truth (Fig.\ \ref{fig:deviations}). The ranking is unambiguous: relative +to a best-practice RMS error of $\sim\!0.03\,\%$, the two-dimensionally-unwrapped +WCS estimator is catastrophic here ($\sim\!50\times$ worse), a wrapped-phase MWCS +inflates the error by roughly an order of magnitude ($\sim\!12\times$), and DTW by +$\sim\!6\times$; among the non-estimator choices the uncumulated trailing +reference is worst ($\sim\!5\times$, and most distorts the recovered drop; it +is an ablation of re-baselining without trend reconstruction, not a surveyed +workflow, Section\ \ref{sec:param_ref}), while stack length, coda +window, and frequency band deviations are each more modest +($1.5$--$2.5\times$). The joint-inversion reference stays closest to the +fixed-reference baseline among the reference-scheme deviations. \begin{figure} \centering \includegraphics[width=\textwidth]{demo_10_deviations.png} - \caption{One-at-a-time deviations from a best-practice baseline, ranked by the - bias they inject (a, log scale) and by how they distort the recovered - co-eruptive drop (b, symlog). Bars are coloured red when the error exceeds + \caption{One-at-a-time deviations from a best-practice baseline, ranked by + their RMS error against the truth (a, log scale; RMS mixes bias and + scatter) and by how they distort the recovered co-eruptive drop (b, symlog). Bars are coloured red when the error exceeds three times the baseline. The estimator and reference choices dominate; the band and gating are minor for this scenario.} \label{fig:deviations} @@ -665,17 +963,19 @@ We test the compounding effects of these choices through 108 reasonable workflow three estimators, two frequency bands, three coda windows, three stacking lengths and two reference schemes on a synthetic "volcano" dv/v time series that includes a seasonal oscillation, a slow pre-eruptive inflation ramp, and a -sharp co-eruptive drop with partial exponential recovery (Fig.~\ref{fig:multiverse}a). +sharp co-eruptive drop with partial exponential recovery (Fig.\ \ref{fig:multiverse}a). The per-day standard deviation across the 108 pipelines varies by a factor of $\sim\!4$--5 over the time series (from $\sim\!0.4\,\%$ to $\sim\!1.7\,\%$), and is widest exactly at the sharp co-eruptive drop; the RMS error against the known truth spans over two orders of magnitude across pipelines ($\sim\!0.02$--$2.8\,\%$). Attributing the variance of the outcome to each axis with a first-order (main-effect) sensitivity index -(Fig.~\ref{fig:multiverse}b) shows that, for this dataset, the **coda window and -the stack length** control the RMS error most, the **stack length** dominates the -recovered drop amplitude, and the estimator is third; the first-order indices sum -to well under one, so a large part of the spread is *interaction* between choices +(Fig.\ \ref{fig:multiverse}b) shows that, for this dataset, the **coda window** +controls the RMS error most, with the estimator second and the stack length +third; for the recovered drop amplitude the order changes to **stack length** +first, window second, and estimator third. The first-order indices sum to +well under one in both cases ($\sim\!0.66$ for RMS, $\sim\!0.63$ for the +drop), so a large part of the spread is *interaction* between choices compounding. The appropriate object is therefore not a single curve but a distribution of \dvv\ over the processing choices. @@ -684,20 +984,23 @@ but a distribution of \dvv\ over the processing choices. \centering \includegraphics[width=\textwidth]{demo_11_multiverse.png} \caption{The full multiverse. (a) 108 reasonable pipelines on one dataset, - each coloured by its RMS error against the truth on a colourblind-safe scale - (bright accurate, dark biased; the worst run off the clipped axis); the grey band - is the 10--90\% inter-pipeline spread, widest at the velocity drop. (b) First-order variance attribution: which - choice controls the RMS error and the recovered drop. Window and stack length - dominate; the sub-unity sum signals strong interactions.} + each coloured by its RMS error against the truth (a fraction of velocity) on + a colourblind-safe scale (bright accurate, dark biased); the axis is clipped + at $\pm0.8\,\%$ and the number of pipelines that leave it is printed on the + panel; the grey band is the 10--90\% inter-pipeline spread, widest at the + velocity drop. (b) First-order variance attribution: which + choice controls the RMS error and the recovered drop. Window, estimator, and + stack length dominate, in that order for RMS and reordered for the drop; + the sub-unity sum signals strong interactions.} \label{fig:multiverse} \end{figure} -Table~\ref{tab:bp-measure} summarizes this into the measurement-step best practice +Table\ \ref{tab:bp-measure} summarizes this into the measurement-step best practice and the documented deviation for each choice, with the consequence the synthetic makes concrete. The baseline and deviation sets are the ones our survey extracts from the literature (the cross-cutting rules of @Snieder2002 [@Clarke2011; -@Weaver2011; @Brenguier2014; @Wang2017; @Obermann2019]). are implemented in -`codameter.deviations`. +@Weaver2011; @Brenguier2014; @Wang2017; @Obermann2019]) and are implemented in +codameter. ```{=latex} \begin{table} @@ -711,8 +1014,7 @@ follow the literature survey (Appendix~\ref{app:survey}).} \textbf{Choice} & \textbf{Best practice} & \textbf{Common deviation} & \textbf{Consequence} \\ \midrule -Estimator & Stretching family (TS/WTS/WCC), robust at low SNR and large \dvv\ -\citep{Mikesell2015,Yuan2021} & Wrapped-phase MWCS \citep{Clarke2011} without 2-D +Estimator & Stretching family (TS/WTS/WCC), robust at low SNR and large \dvv\ \citep{Mikesell2015,Yuan2021} & Wrapped-phase MWCS \citep{Clarke2011} without 2-D unwrapping \citep{Mao2020} & Cycle-skips at large \dvv; error inflated $\sim\!10\times$ or catastrophic \\ \hline Frequency band & Matched to the target depth: $\sim\!0.1$--2\,Hz (volcano, crust), @@ -726,7 +1028,9 @@ Stack length & Short enough to resolve the transient ($\sim\!10$\,d), on a long, stable reference span \citep{Wang2017} & Over-long stack ($\sim\!45$\,d) & Smears and delays a step; distorts the recovered drop \\ \hline Reference & Long fixed stack or all-to-all joint inversion -\citep{Brenguier2014,Wang2017} & Moving / trailing reference & Erases slow trends \\ \hline +\citep{Brenguier2014,Wang2017} & Uncumulated trailing reference (an ablation: +published moving-reference workflows cumulate or stitch, +Section~\ref{sec:param_ref}) & Erases slow trends \\ \hline Coherence gating & Discard low-coherence epochs (CC / SNR threshold) \citep{Clarke2011} & No gating & Keeps corrupted epochs; changes the effective $N$ \\ \hline Uncertainty definition & State it explicitly: within-measurement @@ -755,8 +1059,8 @@ reported ratios are wall-clock, vary with system load, and should be read as If the processing choice controls the answer, the principled response is not to select a single pipeline but to treat the choice as a **nuisance parameter** with a -prior and marginalise it out. We propose this as the new best practice for the -\dvv\ *measurement*, and implement it as a Bayesian hierarchical inversion. For +prior and assess its influence. We explore a Bayesian hierarchical model +for the \dvv\ *measurement*, conditional on a specified pipeline menu. For configuration $k$ drawn from a prior over reasonable pipelines we obtain a measured series $m_k(t)$ with a coherence-limited within-method floor $\sigma_k(t)$ [@Weaver2011; @Clarke2011], and posit @@ -766,84 +1070,140 @@ m_k(t) = \mu(t) + \beta_k + \varepsilon_k(t), \qquad \varepsilon_k(t)\sim\mathcal N\!\big(0,\,s^2\sigma_k(t)^2\big), \label{eq:bayes} \end{equation} -with a second-difference random-walk smoothness prior on the latent true series -$\mu(t)$. Here $\beta_k$ is configuration $k$'s methodological bias (the -systematic offset between, say, MWCS and stretching), $\tau$ its scale across the -ensemble, and $s$ rescales the Weaver floor so the data report whether it is -calibrated. A conjugate Gibbs sampler returns the joint posterior; the -implementation is `codameter.uq_bayes` (pure NumPy, no external sampler). - -The model yields two distinct objects, and conflating them is the error the -field makes (Fig.~\ref{fig:bayes}). The posterior of $\mu$ is the precision of -the *combined* estimate: it is tight and shrinks with ensemble size --- yet it -\emph{under-covers the truth}, because the configurations share a common-mode -bias that averaging cannot remove. The object a downstream depth or stress -inversion must consume is the **marginal measurement covariance** +The likelihood treats residuals as conditionally independent across +configurations and epochs. Shared input waveforms do not ensure this +assumption. Fitting all member outputs jointly is not the same operation as +marginalising a discrete mixture of alternative pipelines. The posterior is +therefore conditional on this working likelihood. We use a +second-difference smoothness prior of precision $\lambda$ on the latent +true series $\mu(t)$, built on the physical time grid so that a gap in the +record is a gap in the prior. Here $\beta_k$ is configuration $k$'s constant +offset (the systematic offset between, say, MWCS and stretching), $\tau$ its +scale across the ensemble, and $s$ rescales the coherence floor of +eq.\ \ref{eq:weaver} so that the data report whether that floor is calibrated. +Every configuration is run through the same pipeline code as the rest of the +paper, so the estimator, band, window, stack length in days, reference scheme +and coherence gate all take effect; an epoch a configuration does not produce +(reference warm-up, a gated coherence) is simply missing and carries no +information. The hyper-priors on $\tau^2$, $s^2$ and $\lambda$ are conjugate +inverse-gamma and gamma distributions whose scales are small against the data +terms. Codameter reports the prior scale term divided by the conditional +posterior rate, evaluated at posterior means. The ratio is about 0.09 for +$\tau^2$ in the clean scenario and below 0.01 for $s^2$ and $\lambda$ +(Table\ \ref{tab:calibration}). This diagnostic does not measure the total +influence of the prior or establish sampler convergence. A conjugate Gibbs sampler, +implemented in codameter with no external sampler dependency and with a banded +solve for the smoothness update, returns the joint posterior. + +The model yields two distinct objects, and conflating them is a common +error (Fig.\ \ref{fig:bayes}; Table\ \ref{tab:estimands}). The posterior of +$\mu$ is the precision of the *combined* estimate: it is tight and shrinks +with ensemble size under the working likelihood. Separately, we construct +a candidate **single-member error covariance** \begin{equation} -C_d(t,t') = \underbrace{D R D}_{\text{within}\,\oplus\,\text{methodological},\ \text{temporally correlated}} +C_d(t,t') = \underbrace{D R D}_{\text{calibrated floor}\,\oplus\,\text{excess spread},\ \text{temporally correlated}} \;+\; \underbrace{\tau^2\,\mathbf{1}\mathbf{1}^\top}_{\text{common mode}}, -\qquad D=\operatorname{diag}\!\big(\sigma_{\rm tot}(t)\big), +\qquad D=\operatorname{diag}\!\big(\sigma_{\mathrm{tot}}(t)\big), \label{eq:cd} \end{equation} -with $\sigma_{\rm tot}^2 = s^2\sigma_k^2$-average $+$ methodological variance and -$R_{ij}=e^{-|t_i-t_j|/L}$ for a correlation length $L$ estimated from the -ensemble residuals. This $C_d$ is **time-dependent** --- wider at the sharp drop -and at low coherence --- and its temporal correlation plus common-mode term -collapse the effective number of independent epochs by an order of magnitude. On -our synthetic the marginal $C_d$ covers the truth at the nominal rate while the -naive posterior band does not, making concrete that the *measurement covariance*, -not the posterior of the averaged series, is what must be propagated. +with $\sigma_{\mathrm{tot}}^2(t) = s^2\,\overline{\sigma_k^2(t)} + +\max\!\big[\operatorname{Var}_k(m_k(t)-\beta_k) - s^2\,\overline{\sigma_k^2(t)},\,0\big]$, +the calibrated floor plus whatever spread across configurations exceeds it +(so that the floor is not counted twice), and $R_{ij}=e^{-|t_i-t_j|/L}$ for a +correlation length $L$ estimated from the ensemble residuals. $C_d$ is +constructed from the fitted model, not sampled. It targets the error of one +measurement drawn from the ensemble, not of $\mu$. The between-configuration +offset scale $\tau$ does not identify an error shared by all configurations. +Pointwise coverage tests only the diagonal scale; it does not validate $R$ +or the rank-one term. A downstream inversion needs the error covariance of +its actual input estimate. Neither using this $C_d$ for the ensemble mean +nor interpreting its time axes as frequency-band axes is justified here. + +Two properties of the fit deserve to be stated plainly. First, $s\approx 12$ +on this synthetic: the residual scatter of the members about the ensemble mean +is an order of magnitude above the coherence floor of eq.\ \ref{eq:weaver}, +which treats the reference as noise-free and knows nothing of the estimator. +The floor is a lower bound, and the rescale is what makes it usable. Second, +once $s$ is fitted on those residuals, the calibrated floor absorbs nearly all +of the between-configuration spread, and the excess term of eq.\ \ref{eq:cd} is +non-zero only at the epochs where the configurations disagree more than they +usually do (Fig.\ \ref{fig:bayes}c). The assumed temporal correlation ($L\approx 40$ +days at a 4-day cadence) and the common-mode term collapse the effective +number of independent epochs from 229 to a few tens. + +Whether these intervals mean what they say is a question one realisation +cannot answer, so we repeat the whole measurement on independent +realisations of the same scenario (Table\ \ref{tab:calibration}; the driver +is \texttt{codameter.calibration}). Three coverages answer three different +questions. The fraction of member epochs whose error against the truth lies +within $1.96\,\sigma_{C_d}$ is 0.956 on 200 realisations, within the margin of $\pm 0.03$ fixed +before the run. This supports the 95\,\% pointwise interval on this +scenario, not calibration of the entire covariance. At the 68\,\% level +it covers 0.81 and fails the same margin. One Gaussian scale therefore does +not calibrate both interval levels. The 95\,\% credible band on +$\mu$ contains the truth at only 0.59 of the epochs: the ensemble mean +inherits the biases its members share (the stacking that rounds the drop, the +estimator biases at low coherence), and no amount of averaging over +configurations removes them, which is what the posterior's precision cannot +know. Comparing $\mu$ with $\pm 2\sigma_{C_d}$ mixes the ensemble mean with +a single-member scale and yields nearly complete coverage here; it does +not validate the uncertainty of the combined estimate. The other two scenarios of Table\ \ref{tab:calibration} inject artefacts that +every configuration sees identically. A station clock drift leaves every +statistic unchanged, because a lapse-independent shift appears with opposite +signs on the causal and acausal branches (Section\ \ref{sec:artifacts}) and +every configuration in this ensemble measures both branches together, so the +drift cancels in the estimate; that is a property of the two-branch +measurement, not evidence that the ensemble could have detected it. +A seasonal source effect confined to the late coda, the waveform-level +artefact of @Zhan2013 (Section\ \ref{sec:artifacts}), is the genuine shared +error: it warps the coda every configuration measures, and on that scenario +the credible band covers the truth at only 0.34 of the epochs and the RMSE of +$\mu$ more than doubles, from 0.067 to 0.161\,\%, while the member-level coverage of +$C_d$ stays at 0.95. That last number is right for a reason that gives no +comfort: the artefact also inflates the scatter that $s$ absorbs, so $C_d$ +widens, but its coherent part biases every member and the ensemble mean +together and leaves no trace in their spread. That is the limit of the +method, not a defect of the fit: an ensemble over processing choices can only reveal the errors on which +its members disagree, and an error shared by every pipeline (a source change, +a contaminated reference, a clock drift measured on one branch) needs an +independent diagnostic, such as the branch asymmetry of +Section\ \ref{sec:artifacts}. \begin{figure} \centering \includegraphics[width=\textwidth]{demo_12_bayes.png} - \caption{The Bayesian measurement model. (a) The processing ensemble (grey) + \caption{The Bayesian measurement model on one realisation of the volcano + scenario (12 configurations: three estimators, two bands, two windows, 10-day + stacks, fixed reference, 4-day cadence). (a) The processing ensemble (grey) is marginalised into a posterior mean (purple) with a narrow credible band - (the estimator precision) and a much wider $\pm2\sigma$ band from the marginal - $C_d$ (the honest data error), which covers the truth where the credible band - does not. (b) The resulting time-dependent data covariance $C_d$. (c) Its - diagonal $\sigma_d(t)$ decomposed into within-method and methodological parts, - rising at the eruption; the posterior-of-the-mean (dotted) is far tighter, and - $N_{\rm eff}$ is a fraction of the epoch count.} + (the estimator precision) and a wider $\pm2\sigma$ band from $C_d$, the + single-measurement error, which encloses the individual members + (Table~\ref{tab:calibration} gives the coverages over repeated realisations). + (b) The time-dependent covariance $C_d$, in squared fractional \dvv. + (c) Its diagonal $\sigma_d(t)$, in percent, split into the calibrated + coherence floor ($s\,\overline{\sigma_k}$, which with $s\approx12$ carries + almost all of the spread) and the excess between-configuration spread, which + is non-zero only where the configurations disagree more than usual; the + posterior-of-the-mean (dotted) is far tighter, and $N_{\mathrm{eff}}$ is a + small fraction of the epoch count.} \label{fig:bayes} \end{figure} -# Toward deployment: a real-data retrospective pipeline {#sec:deployment} - -Every result so far is on a truth-known synthetic, by design (Section~\ref{sec:methods}): -it is the only way to separate a processing artefact from a real signal. The -next step is to test whether the same measurement machinery holds up against -real data at deployment scale, not just against a synthetic that was built to -resemble it. We are building a companion pipeline, `noisepy-dvv-cloud`, that -correlates real continuous waveforms for station CI.LJR (Lake Hughes, -California) --- the reference station of @Clements2023 --- pulled from the -public Southern California Earthquake Data Center S3 archive, using the -NoisePy package [@Jiang2020] for the correlation step. Correlation and dv/v -estimation each run as an AWS Batch job on Fargate Spot compute, following the -same deployment pattern as QuakeScope; dv/v estimation itself is handed to -`codameter.deviations.run_pipeline` and `codameter.uq_measurement`, with -baseline processing configurations drawn from `codameter.use_cases.recommend` ---- the same functions this paper's synthetic results are built on, not a -separate reimplementation. The retrospective run is validated against the -already-published @Clements2023 CI.LJR result before any new claim is drawn -from it. +\input{calibration_table.tex} - -# Depth: propagating the measurement covariance through sensitivity kernels {#sec:depth} +# Propagating \dvv\ errors at depth $\Delta\beta/\beta(z)$ {#sec:depth} The remaining sections present a framework rather than new synthetics: they set -out how the covariance of Section~\ref{sec:bayes} propagates down the inference +out how the covariance of Section\ \ref{sec:bayes} propagates down the inference chain, and ground each step in what the monitoring literature does and does not yet report. The executable stages are in development in the open codameter package -(Section~\ref{sec:discussion}). +(Section\ \ref{sec:discussion}). The field has converged on one physical rule for depth --- *depth is set by the frequency band and the coda lapse time, it is not assumed* [@Obermann2013; @Obermann2016] --- and, increasingly, on multi-band measurement as the means to -resolve it [@Takano2017; @Feng2020; @Mao2022, @Mao2025]. The step from a set of per-band +resolve it [@Takano2017; @Feng2020; @Mao2022; @Mao2025]. The step from a set of per-band \dvv\ series to a depth profile is where reporting is least consistent: many studies read a single band as a single depth, only a few invert several bands against surface-wave sensitivity kernels, and the propagation of the measurement @@ -860,14 +1220,16 @@ depth, \label{eq:kernel} \end{equation} where $K_b(z)$ is the (Rayleigh-wave) depth-sensitivity kernel for band $b$ and -$\varepsilon_b$ carries that band's measurement covariance from -Section~\ref{sec:bayes}. Stacking bands gives a linear system +$\varepsilon_b$ is that band's observation error. Stacking bands gives a linear system $\mathbf{d}=\mathbf{G}\,\mathbf{m}+\boldsymbol\varepsilon$ with -$\mathbf{G}_{bz}=K_b(z)$ and data covariance $C_d$; the Bayesian solution under a +$\mathbf{G}_{bz}=K_b(z)$ and cross-band data covariance $C_d^{\mathrm{band}}$. +This covariance must describe the band estimates actually supplied. The +temporal $C_d$ in Section\ \ref{sec:bayes} does not supply its cross-band +entries. Given such a covariance, the Bayesian solution under a smoothness prior returns a depth profile $\delta V_S/V_S(z)$ together with its -posterior covariance $C_m(z)$ (implemented in `codameter.uq_depth`). The bands +posterior covariance $C_m(z)$, implemented in codameter. The bands must sit where the kernels resolve: too low and the kernel leaks into the -half-space, too high and the coda is incoherent (Section~\ref{sec:params}). The +half-space, too high and the coda is incoherent (Section\ \ref{sec:params_freq}). The width of $C_m(z)$ --- not the profile alone --- is the deliverable, and it inherits the temporal correlation and common-mode structure of $C_d$. @@ -888,7 +1250,7 @@ Hydrological and cryospheric targets, where saturation varies strongly biases the inferred velocity change and, downstream, the stress. The framework carries $\delta\rho/\rho$ as a second inverted field with its own kernel and reports how much of the surface \dvv\ each explains; the executable version is a documented -extension (Section~\ref{sec:discussion}). +extension (Section\ \ref{sec:discussion}). \begin{table} \footnotesize @@ -915,38 +1277,155 @@ unstated model & Hidden systematic in the kernels and the moduli \\ \end{tabularx} \end{table} -# Stress: a downstream step, not attempted here {#sec:stress} - -The quantity of interest is rarely the velocity change itself but the stress, -strain, or pore-pressure change that produces it and --- increasingly --- the -forcing responsible for it. Here the literature remains fragmented. Volcano and -fault studies often interpret the velocity change qualitatively (a pre-eruptive -pressurization, coseismic damage); hydrological studies fit an explicit -poroelastic or thermoelastic model and separate the two by their seasonal phase -lag [@Tsai2011; @Wang2017; @Clements2018]. What is largely absent across this -literature is the *uncertainty* on that final quantity and a reasonable -apportionment of it among the competing forcings. - -Converting a depth-resolved velocity-change posterior to stress or strain is a -further step this paper does not attempt: it requires material priors --- an -acoustoelastic, poroelastic, or thermoelastic coefficient, its depth dependence, -and the fracture fabric or drainage regime that selects which stress or strain -component the velocity change actually tracks --- that are outside this paper's -scope. Because those coefficients are themselves poorly constrained, any such -conversion is dominated by *epistemic* prior uncertainty rather than by the -measurement, so a stress value reported without accounting for that is the least -constrained quantity in the chain, and the one most often reported as a result. -We stop deliberately at the depth-resolved posterior of Section~\ref{sec:depth} -and its covariance: that object, not a stress or strain estimate, is what this -paper delivers, and what any downstream stress or strain conversion must -consume. +# Real-data comparison and deployment {#sec:deployment} + +Every result so far is on a truth-known synthetic, by design (Section\ \ref{sec:methods}): +it is the only way to separate a processing artefact from a real signal. The +next step is to test whether the same measurement machinery holds up against +real data, not just against a synthetic that was built to resemble it. We are building a companion cloud pipeline that +correlates real continuous waveforms for station CI.LJR (Lake Hughes, +California) --- the reference station of @Clements2023 --- pulled from the +public Southern California Earthquake Data Center S3 archive, using the +NoisePy package [@Jiang2020] for the correlation step. Correlation and dv/v +estimation each run as a cloud batch job on spot compute; dv/v estimation +itself is handed to the same codameter measurement and uncertainty functions +this paper's synthetic results are built on, with baseline processing +configurations drawn from the same recommendation logic --- not a separate +reimplementation. The retrospective run is compared with the +already-published @Clements2023 CI.LJR result before any new claim is drawn +from it. + +After the correction, single-station \dvv\ (NoisePy correlations, a +codameter 5-member ensemble, 2--4$\,$Hz, 2018--2019) agrees in shape with the +published @Clements2023 product. The comparison is not trivial to get right: +the CD2023 90-day-comp product is a *trailing* 90-day stack, so it lags a +centered-smoothed daily series by about 45 days, and comparing without +matching that smoothing caps the correlation near 0.7 even on a real annual +cycle (Fig.\ \ref{fig:realdata-validation}). We match by applying the same +trailing 90-day mean to the daily series (at least 45 finite days in the +window), compare demeaned --- the two products reference different epochs, +and a constant offset is bookkeeping, not error --- and exclude the first 150 +days of each station's series as reference burn-in. The comparison is +computed by a script archived with the paper +(\texttt{scripts/compare\_gate1.py}) from the daily products and the +published series, with the join, smoothing and mask stated in its output +(\texttt{paper/data/gate1/comparison.json}); Table\ \ref{tab:gate1} lists the +result. Under the matched rule CI.LJR reaches $r=0.985$ on 579 days with an +amplitude slope of 1.07 (published on codameter); CI.ARV reaches $r=0.905$ on +357 days, the 2018 data gaps reducing the overlap, but with a slope of 2.15, +so the published product has twice the amplitude of ours there; CI.RXH +reaches $r=0.829$ on 446 days with a slope of 0.81 on a station whose +recovered \dvv\ is nearly flat. Correlation measures the shape of the annual +cycle after smoothing; it does not validate the amplitude (the ARV slope) or +the error bars, which the published product does not carry, and the earlier +draft's quoted 681 days was the raw daily overlap, not the count under the +stated mask. + +```{=latex} +\begin{table} +\footnotesize +\caption{Comparison of codameter single-station \dvv\ (2--4\,Hz, 2018--2019) +with the published \citet{Clements2023} product, from +\texttt{scripts/compare\_gate1.py}. Matched: trailing 90-day mean, 150-day +burn-in. Centred: centred 45-day mean, no burn-in (the rule behind the +annotation on Fig.~\ref{fig:realdata-validation}). Slope is the OLS slope of +the published product on codameter; RMS is the RMS difference after removing +each series' mean over the overlap.} +\label{tab:gate1} +\begin{tabular}{@{}llrrrr@{}} +\toprule +Station & Rule & Days & $r$ & RMS diff (\%) & Slope \\ +\midrule +CI.LJR & matched & 579 & 0.985 & 0.046 & 1.07 \\ +CI.LJR & centred & 682 & 0.865 & 0.120 & 0.88 \\ +CI.ARV & matched & 357 & 0.905 & 0.150 & 2.15 \\ +CI.ARV & centred & 424 & 0.369 & 0.214 & 0.80 \\ +CI.RXH & matched & 446 & 0.829 & 0.020 & 0.81 \\ +CI.RXH & centred & 554 & 0.620 & 0.035 & 0.52 \\ +\bottomrule +\end{tabular} +\end{table} +``` + +\begin{figure} + \centering + \includegraphics[width=\textwidth]{realdata_1_validation.png} + \caption{Single-station \dvv\ at three CI stations, 2018--2019, against the + published \citet{Clements2023} product (dashed, reference-shifted; the + panel labels name it by its 2022 data release). Daily \dvv\ (points) with the + between-configuration spread of the five-member ensemble (shaded) and the + within-measurement error bars (Table~\ref{tab:estimands}), and a centred + 45-day-smoothed curve. This figure was produced by the Gate 1 cloud run + itself and is not regenerated from this repository; its annotated $r$ values + correspond to the centred rule of Table~\ref{tab:gate1} (0.87, 0.37 and + 0.62 for LJR, ARV and RXH from the archived products), not to the matched + rule quoted in the text. The error bars drawn here predate the Weaver-floor + correction of the present revision and are too large by a factor of 3.1 at + 2--4\,Hz (the archived columns have since been rescaled by + \texttt{scripts/correct\_gate1\_within\_error.py}; the externally produced + figure has not been regenerated).} + \label{fig:realdata-validation} +\end{figure} + +Part of why agreement differs by station is visible in the correlation +function itself (Fig.\ \ref{fig:realdata-interferograms}), although an +interferogram alone cannot separate a site change from an instrument or +processing change, which station metadata and processing logs would be needed +to rule out. CI.LJR +shows a stable, narrow coda near zero lag through the year. CI.RXH shows +multipath, several coherent arrivals spread across the full $\pm 8\,$s of +lag shown, and a visible shift in that pattern in April--May 2019, +consistent with a site change rather than a processing artefact. CI.ARV's +coherent energy is compact and concentrated near zero lag but comparatively +sparse, consistent with its higher scatter and join-method sensitivity. + +\begin{figure} + \centering + \includegraphics[width=\textwidth]{realdata_2_interferograms.png} + \caption{Daily NZ (north-vertical) cross-component correlation functions, + 2--4$\,$Hz, $\pm 8\,$s lag, 2019, each day normalised to its maximum + absolute amplitude (colour scale unlabelled on this externally produced + figure). CI.LJR's coda is stable and narrow. CI.RXH shows multipath (several + coherent bands across the full lag range) and a shift in that pattern in + April--May 2019. CI.ARV's coherent energy is compact and near zero lag but + comparatively sparse. These differences are consistent with, but do not by + themselves explain, the station-to-station agreement in + Fig.~\ref{fig:realdata-validation}.} + \label{fig:realdata-interferograms} +\end{figure} + +As an optional supplement, Fig.\ \ref{fig:realdata-warmup} shows the +ensemble's warm-up behaviour on a separate 90-day smoke run at CI.LJR: \dvv$\,$is +undefined until enough history has accumulated for the moving-reference +member to compute a trailing reference, and each band's per-epoch stretching +correlation coefficient is reported alongside the recovered series. + +\begin{figure} + \centering + \includegraphics[width=\textwidth]{realdata_3_warmup.png} + \caption{CI.LJR single-station \dvv, a separate 90-day smoke run (January--April + 2023), four frequency bands. The ensemble spread (shaded) and measurement + error bars are reported once at least one member is defined; the member + count annotated on each panel is the number of members defined on the last + day shown, which is below five where the moving-reference member's warm-up + had not yet elapsed. Bottom panel: per-band stretching correlation + coefficient. Produced by the cloud run, not regenerated here.} + \label{fig:realdata-warmup} +\end{figure} + # Discussion {#sec:discussion} -The experiments above share one finding: for ambient-noise \dvv, the dominant -control on both the reported value and its uncertainty is frequently the -*processing choice*, not the data. This is a consequential but tractable problem. We -suggest three responses. +The experiments above share one finding: on these synthetics, with one +waveform realisation held fixed, the processing choice moves both the +recovered \dvv\ and its stated uncertainty by more than the measurement noise +does, by two orders of magnitude in RMS across the 108-pipeline multiverse and +by a factor $\sqrt{N}$ in the reported network error bar. Whether processing +also dominates the variability between real deployments is a question these +experiments cannot answer, because they hold the observed waveform fixed; the +repeated-realisation calibration of Section\ \ref{sec:bayes} is the first step +toward it. The problem is consequential but tractable. We suggest the +following responses. **Report the choices.** At minimum, a \dvv\ study should state the estimator and its parameters, the frequency band(s) and coda window(s) and how the window @@ -954,9 +1433,11 @@ was set relative to the band, the reference scheme, the stacking, the cross-component and station-pair aggregation *and weighting*, and --- critically --- the exact definition of the quoted uncertainty (within-measurement error, between-component/pair standard error, or standard deviation). Our results show -that the last item alone can change a stated $1\sigma$ by $\sqrt{N}$. -Table~\ref{tab:checklist} collects this into a minimal reporting checklist, and -Appendix~\ref{app:survey} shows how unevenly these items are reported across the +that the last item alone changes the number quoted as $1\sigma$ by $\sqrt{N}$, +because the two conventions estimate different quantities +(Table\ \ref{tab:estimands}). +Table\ \ref{tab:checklist} collects this into a minimal reporting checklist, and +Appendix\ \ref{app:survey} shows how unevenly these items are reported across the literature today. \begin{table} @@ -993,16 +1474,35 @@ Software & Package, version, and the parameter file or its DOI \\ **Quantify the choice-induced uncertainty.** Where a choice is not forced by the physics, it can be sampled. Pushing a distribution of reasonable processing -choices through the measurement-error floors of @Clarke2011 [@Weaver2011] yields, -by the law of total variance, a marginal \dvv\ uncertainty that includes the -processing-choice spread --- a more honest error bar than any single pipeline -provides, and the natural input to a depth/stress inversion. Section~\ref{sec:bayes} -makes this a Bayesian measurement model whose deliverable is a time-dependent -data covariance $C_d$. - -**Make it executable.** All synthetics, estimators and figures in this paper are -released in the open codameter package, which reproduces every result with a -single command and is unit-tested. An executable record turns an undocumented +choices through the same correlations measures conditional sensitivity. +A probabilistic mixture would combine conditional variances and the variance +of conditional means. The joint likelihood in +Section\ \ref{sec:bayes} instead defines a working Bayesian model whose +deliverable is a time-dependent single-measurement covariance $C_d$. Its +limitations are as important as its construction. The prior over pipelines is +a menu, not a representative sample of practice, and the covariance is +conditional on it. Every configuration transforms the same waveforms, so an +error they all share (a source change, a contaminated reference, a clock +drift measured on one branch) leaves no trace in their spread: on the +shared-source scenario of Table\ \ref{tab:calibration} the ensemble agrees with +itself, the error of its mean doubles, and $C_d$ cannot see it. Configurations in different bands sample +different depths and may not estimate the same physical quantity, so the +configuration axis should be marginalised only over pipelines that target +one estimand. And the coherence floor of @Weaver2011 is a lower bound: on our +synthetic the residual scatter about the ensemble mean is an order of +magnitude above it, which the fitted rescale $s$ reports rather than hides. +The pointwise tests in Table\ \ref{tab:calibration} support the 95\,\% +member intervals on the listed scenarios. They also expose 68\,\% +overcoverage and poor coverage of the combined estimate. They do not establish +temporal covariance calibration, convergence across independent chains, or +valid downstream intervals. + +**Make it executable.** All synthetics, estimators and generated figures in +this paper are released in the open codameter package; one driver regenerates +every generated figure together with a numerical sidecar holding every plotted +array and the run's provenance, and the package is unit-tested. The three +real-data figures were produced by the cloud run and are archived, not +regenerated (Section\ \ref{sec:deployment}). An executable record turns an undocumented choice into a versioned, inspectable one, and lets a reader re-run a study's pipeline on the truth-known synthetic to see its bias before trusting it on data. @@ -1011,9 +1511,10 @@ this paper passed before the discovery below, and that is exactly the danger: a synthetic built under the same sign convention as the estimator reading it will always agree, whether the convention is physically correct or not. Testing codameter's estimators against a real cross-network deployment -(Section~\ref{sec:deployment}), recovered \dvv\ anticorrelated with the -published Clements & Denolle (2022) product and with seasonal hydrology at -three stations ($r=-0.69,-0.45,-0.40$). Ground-truthing through the exact +(Section\ \ref{sec:deployment}), recovered \dvv\ anticorrelated with the +published @Clements2023 product and with seasonal hydrology at three +stations ($r=-0.69,-0.45,-0.40$ under the rule used at the time, recorded in +the codameter v0.4.0 release notes). Ground-truthing through the exact call path made the cause obvious: imposing a $+0.5\,\%$ velocity change returned $-0.50\,\%$. The synthetic generator and all seven estimators had consistently used the stretch factor $\varepsilon$ (positive for a coda @@ -1021,42 +1522,47 @@ dilation, i.e.\ a slowdown), not physical \dvv\ (positive for a speedup) --- internally coherent, so every synthetic-recovery test in the sections above passed, but opposite to the sign convention the field expects and to the published product it was compared against. The fix is the convention boxed -in Section~\ref{sec:intro}, shipped as codameter v0.4.0. Internal consistency +in Section\ \ref{sec:intro}, shipped as codameter v0.4.0. Internal consistency is not correctness: a pipeline that only checks itself will confirm whatever convention it started with, and only the comparison against an -independently-produced result caught this one. Full details and the -ground-truthing procedure are in codameter PR \#36 and its commit history on -branch `fix/dvv-sign-convention`. +independently-produced result caught this one. The fix and its +ground-truthing procedure are documented in the codameter release history. **Propagate the covariance, do not truncate it.** The measurement covariance is -not the end of the analysis but its first input. Section~\ref{sec:depth} sets out +not the end of the analysis but its first input. Section\ \ref{sec:depth} sets out the next step of the chain: invert the per-band $C_d$ through sensitivity kernels for a depth profile and its covariance, separating the shear-velocity and density contributions where the ground is partially saturated. Converting that -depth-resolved posterior to stress or strain (Section~\ref{sec:stress}) requires +depth-resolved posterior to stress or strain requires material priors this paper does not attempt to constrain, and is left to other -work; what we deliver is the depth posterior and its covariance, the object any -such conversion must consume. Building and testing the depth-propagation stage on -truth-known synthetics is the natural continuation of this work, and is under way -in the open codameter framework. +work. What codameter provides today is the interface that consumes $C_d$; the +depth posterior itself, its resolution, and the calibration of its covariance +are not demonstrated in this paper. Building and testing the depth-propagation +stage on truth-known synthetics with overlapping kernels is the natural +continuation of this work. # Conclusions {#sec:conclusions} Ambient-noise \dvv\ monitoring rests on a chain of processing choices that are made ad hoc and reported incompletely. Using a truth-known synthetic and the full estimator suite of an open toolbox, we have shown that these choices change the -recovered \dvv\ and, more consequentially, change the reported uncertainty by a -factor of $\sim\!\sqrt{N}$ --- enough to flip the significance of a result --- all -without touching the data. The remedy is not a single mandated pipeline but -transparency: report every choice, sample the ones the physics does not fix, -carry the resulting measurement covariance into the inference, and release the -pipeline as executable code. The same discipline extends down the inference -chain: the measurement covariance is the input a depth inversion consumes, and -only a pipeline that carries the covariance that far can attach an honest -uncertainty to a depth-resolved velocity-change profile. Converting that profile -to stress or strain is a further step this paper does not attempt -(Section~\ref{sec:stress}). We offer codameter as one such record, and as the -package in which the depth stage is being built. +recovered \dvv\ by up to two orders of magnitude in RMS across reasonable +pipelines and, more consequentially, change the number reported as its +uncertainty by a factor of $\sim\!\sqrt{N}$ depending on which of two +different quantities a study calls $1\sigma$, all without touching the data. +The remedy is not a single mandated pipeline but transparency: report every +choice and name the quantity each error bar estimates, sample the choices the +physics does not fix, carry the resulting measurement covariance into the +inference after validating its target, and release the pipeline as executable +code. Repeated synthetic realisations support the proposed 95\,\% +pointwise member intervals, while the nominal 68\,\% intervals overcover +and the combined estimate's credible band undercovers +(Table\ \ref{tab:calibration}). Temporal and cross-band covariance and +shared errors remain unvalidated. A depth inversion also needs kernel +uncertainty and the covariance of the actual observations it consumes. +Converting a depth profile to stress or strain is a further step this paper +does not attempt. We offer codameter as one such record; its depth stage is an +interface awaiting evaluation. \appendix @@ -1064,29 +1570,56 @@ package in which the depth stage is being built. Let $r(t)$ and $c(t)$ be the reference and current cross-correlations, band-passed to $[f_1,f_2]$ (central frequency $f_c$, bandwidth $B$) and read over -the coda window $W=[t_1,t_2]$ on one or both branches. We use the convention -$\delta t/t = -\,\dvv$, and write $\varepsilon$ for the recovered \dvv. +the coda window $W=[t_1,t_2]$ on one or both branches. Each method below +estimates a trial stretch factor $\varepsilon$, the fractional dilation of +the current coda relative to the reference; physical \dvv\ follows via the +convention boxed in Section\ \ref{sec:intro}, $\dvv=-\varepsilon/(1+\varepsilon)$. -**Trace stretching (TS).** For a trial stretch $s$, define -$r_s(t)=r\!\left(t/(1+s)\right)$ and the windowed correlation coefficient +**Trace stretching (TS).** For each trial stretch factor $\varepsilon$, the current correlation is interpolated as $c_\varepsilon(t)=\mathcal{I}[c]\big((1+\varepsilon)t\big)$ (interpolation on current only) while the reference $r(t)$ remains fixed. The windowed correlation coefficient is \begin{equation} -\mathrm{CC}(s) = \frac{\int_W c(t)\,r_s(t)\,\mathrm{d}t} -{\left(\int_W c^2\,\mathrm{d}t\int_W r_s^2\,\mathrm{d}t\right)^{1/2}}, -\qquad \varepsilon = \arg\max_s \mathrm{CC}(s). +\mathrm{CC}(\varepsilon) = \frac{\int_W r(t)\,c_\varepsilon(t)\,\mathrm{d}t} +{\left(\int_W r^2\,\mathrm{d}t\int_W c_\varepsilon^2\,\mathrm{d}t\right)^{1/2}}, +\qquad \varepsilon^\star = \arg\max_\varepsilon \mathrm{CC}(\varepsilon). \end{equation} +The best-fit stretch $\varepsilon^\star$ is then converted to physical $\dvv$ via $\dvv^\star = -\varepsilon^\star/(1+\varepsilon^\star)$ as boxed in the Introduction. The single-measurement error decreases with the coherence $\mathrm{CC}$, the -bandwidth $B$, and the window length, approximately as $\sigma_{\varepsilon} \propto -\sqrt{(1-\mathrm{CC}^2)/\mathrm{CC}^2}\, \big/\!\left[f_c\sqrt{B\,(t_2^3-t_1^3)}\right]$ -[@Weaver2011]. +bandwidth $B$, and the window length. We use eq.\ 20 of @Weaver2011, +\begin{equation} +\sigma_{\varepsilon} = \frac{\sqrt{1-\mathrm{CC}^2}}{2\,\mathrm{CC}} +\sqrt{\frac{6\sqrt{\pi/2}\;T}{\omega_c^2\,(t_2^3-t_1^3)}}, +\qquad T=\frac{\sqrt{\ln 10}}{\pi B}, +\label{eq:weaver} +\end{equation} +with $\omega_c=2\pi f_c$ and $T$ the spectral timescale of Weaver et al.'s +Gaussian spectrum, fixed here by placing the band edges at that spectrum's +$-10$\,dB points; any convention with $T\propto 1/B$ gives the same +$1/\sqrt{B}$ scaling and differs by a constant that the rescale $s$ of +Section\ \ref{sec:bayes} absorbs. The corresponding error on \dvv\ follows +from the exact map, $\sigma_{\dvv}=\sigma_{\varepsilon}/(1+\varepsilon)^2$, +which equals $\sigma_{\varepsilon}$ to first order. (The codameter +implementation before this revision omitted $T$ and used a variance prefactor +twice this one; the fitted $s$ absorbed the constant, and only the relative +weighting of configurations in different bands changed when it was +corrected.) + +*Interpolation direction and convention.* The interpolation is applied to the current waveform and not the reference so that the high-SNR reference stack remains invariant throughout the epsilon search, which is particularly important when the reference is built as a long-term or moving average. In the continuous-signal, infinite-support limit the two conventions (interpolating current versus interpolating reference) are mathematically equivalent after their fitted parameters are converted to the same physical $\dvv$ through the exact relation $\dvv = -\varepsilon/(1+\varepsilon)$. In sampled, finite-window signals, that symmetry is broken: interpolation error, edge truncation, and the finite support of the data cause the two conventions to give slightly different numerical results even when both use the exact conversion. Therefore the interpolation direction must be reported explicitly and treated as a fixed processing choice. For diffuse codas in ambient-noise and volcanic monitoring, we have verified that the choice has a measurable but small effect: truth-known synthetics recover $\dvv$ with sub-$10^{-4}$ bias when the signal-to-noise ratio is high and the changes are small, with the effect growing as a few percent at landslide-scale perturbations ($\dvv\sim4\,\%$). + +Throughout this appendix a delay $\delta t$ is the lag of the current trace +relative to the reference, positive when the current arrival is later, so for +the pure dilation $c(t)=r(t/(1+\varepsilon))$ a phase at reference lapse +$t_i$ appears at $(1+\varepsilon)t_i$ and $\delta t_i=+\varepsilon\,t_i$; with +that sign every estimator below returns the dilation $\varepsilon$ of the +Introduction, and a regression test in codameter holds each of them to it in +both signs. **Windowed cross-correlation (WCC).** In sub-windows centred at lapse $t_i$ the delay is $\delta t_i=\arg\max_{\tau}\int c(t)\,r(t-\tau)\,\mathrm{d}t$; a -least-squares fit of $\delta t_i=-\varepsilon\,t_i$ gives $\varepsilon$. +least-squares fit of $\delta t_i=\varepsilon\,t_i$ gives $\varepsilon$. **Moving-window cross-spectrum (MWCS).** In each sub-window the cross-spectrum is $X(f)=\hat c(f)\,\hat r^{*}(f)$ with phase $\varphi(f)=\arg X(f)\approx 2\pi f\,\delta t_i$; a coherence-weighted linear fit of $\varphi(f)$ over $[f_1,f_2]$ -yields $\delta t_i$, and $\varepsilon$ is minus the slope of $\delta t_i$ versus +yields $\delta t_i$, and $\varepsilon$ is the slope of $\delta t_i$ versus $t_i$ [@Clarke2011]. Because $\varphi$ is defined modulo $2\pi$, the estimate cycle-skips once $|\delta t_i|>1/(2f)$. @@ -1095,14 +1628,14 @@ cycle-skips once $|\delta t_i|>1/(2f)$. \sum_i \big(c_i - r_{i+l(i)}\big)^2 \;+\; \gamma\sum_i \big(l(i{+}1)-l(i)\big)^2, \end{equation} where $\gamma$ penalises strain (limits the lag's rate of change); $\varepsilon$ -is minus the slope of $l(i)/f_s$ versus lapse. +is the slope of the lag $l(i)/f_s$ (current relative to reference) versus lapse. **Wavelet cross-spectrum (WCS).** With continuous wavelet transforms $W_c,W_r$, the cross-wavelet spectrum is $W_{xy}(f,\tau)=W_c\,W_r^{*}$ and the delay $\delta t(f,\tau)=\varphi(f,\tau)/(2\pi f)$. Unwrapping $\varphi$ in two dimensions --- along lapse (anchored at $\tau\!\to\!0$, where $\delta t\!\to\!0$) then along frequency --- removes the cycle-skip; $\varepsilon$ follows from the -$|W_{xy}|$-weighted regression $\delta t=-\varepsilon\,\tau$ over the +$|W_{xy}|$-weighted regression $\delta t=\varepsilon\,\tau$ over the time--frequency window [@Mao2020]. **Wavelet stretching / warping (WTS, WTDTW).** TS (respectively DTW) is applied @@ -1112,16 +1645,19 @@ per-scale estimates are pooled with cross-wavelet-power weights. # Aggregation and uncertainty conventions {#app:aggregation} For component $k$ of a station pair, stretching yields the image -$\mathrm{CC}_k(\varepsilon,t)$. +$\mathrm{CC}_k(\varepsilon,t)$; each per-component stretch factor converts to +physical $\dvv_k$ via the boxed relation. -**Approach A (average the \dvv).** -$\varepsilon_k(t)=\arg\max_{\varepsilon} \mathrm{CC}_k(\varepsilon,t)$ and the pair -estimate is the (possibly weighted) mean $x_p(t)=\sum_k w_k\,\varepsilon_k/\sum_k -w_k$, with $w_k=\max_{\varepsilon} \mathrm{CC}_k$ (coherence-weighted) or $w_k=1$ -(unweighted). +**Approach A (average the per-component \dvv).** +$\dvv_k(t)$ follows from $\varepsilon_k(t)=\arg\max_{\varepsilon} +\mathrm{CC}_k(\varepsilon,t)$, and the pair estimate is the (possibly +weighted) mean $x_p(t)=\sum_k w_k\,\dvv_k/\sum_k w_k$, with $w_k=\max_{\varepsilon} +\mathrm{CC}_k$ (coherence-weighted) or $w_k=1$ (unweighted). -**Approach B (average the images).** -$x_p(t)=\arg\max_{\varepsilon}\big[\tfrac1{N_c}\sum_k \mathrm{CC}_k(\varepsilon,t)\big]$. +**Approach B (average the images).** The pair stretch factor +$\varepsilon_p(t)=\arg\max_{\varepsilon}\big[\tfrac1{N_c}\sum_k +\mathrm{CC}_k(\varepsilon,t)\big]$ converts to $x_p(t)=\dvv_p(t)$ via the same +relation. **Network over pairs.** With pair weights $W_p$ (e.g.\ mean coherence), \begin{equation} @@ -1129,7 +1665,7 @@ $x_p(t)=\arg\max_{\varepsilon}\big[\tfrac1{N_c}\sum_k \mathrm{CC}_k(\varepsilon, s^2=\frac{\sum_p W_p (x_p-\bar x)^2}{\sum_p W_p},\quad N_{\mathrm{eff}}=\frac{(\sum_p W_p)^2}{\sum_p W_p^2}. \end{equation} -The three uncertainty conventions used in Section~\ref{sec:uncertainty} are the +The three uncertainty conventions used in Section\ \ref{sec:uncertainty} are the weighted standard error $\sigma_{\mathrm{SE},w}=s/\sqrt{N_{\mathrm{eff}}}$, the unweighted standard error $\sigma_{\mathrm{SE}}=\mathrm{std}(x_p)/\sqrt{N}$, and the standard deviation $\sigma_{\mathrm{SD}}=\mathrm{std}(x_p)$. They share the @@ -1137,9 +1673,11 @@ mean $\bar x$ but obey $\sigma_{\mathrm{SD}}/\sigma_{\mathrm{SE}}=\sqrt{N}$. # Survey of processing choices across the literature {#app:survey} -Table~\ref{tab:survey} catalogues the processing choices of the 103 ambient-noise -\dvv\ monitoring studies we surveyed (full machine-readable version and -provenance in the codameter `literature/` directory). It is the empirical basis +Table\ \ref{tab:survey} catalogues the processing choices of the ambient-noise +\dvv\ monitoring studies we surveyed: 103 rows for 102 publications, one +publication [@Obermann2013] contributing two rows for two distinct +measurement set-ups (the full machine-readable version and provenance are +distributed with the codameter package). It is the empirical basis for the paper's claim that no convention is shared: the estimator, the frequency band, the coda window, the reference scheme and --- most unevenly of all --- the uncertainty treatment vary study to study, and the last is frequently @@ -1153,24 +1691,45 @@ value is genuinely not stated in the paper. The remaining rows were populated from abstracts and search metadata, where ``n/r'' means only that the value was not found in the abstract, not that the study failed to report it; those cells are flagged in the machine-readable table (\texttt{measurement\_source}) and -remain to be filled from the paywalled full texts. The apparent under-reporting -in the table is therefore a lower bound on what the literature actually states. +remain to be filled from the paywalled full texts. Because a cell populated from +an abstract can only move from ``n/r'' to reported once the full text is read, +the apparent under-reporting in the table is an upper bound on the true +under-reporting; the verified rate is the one among the 82 full-text rows. \input{appendix_table.tex} # Data availability {.unnumbered} -The codameter package, including the synthetic-demonstration module, the -figure-generating scripts, and the literature survey that motivates this work, is -openly available at . All figures are -reproduced by `python literature/synthetic_dvv_demo.py`, the multiverse and -deviation ranking by `python -m codameter.deviations`, and the Bayesian -measurement model by `python -m codameter.uq_bayes`. The manuscript itself is -rendered from `paper/manuscript_marine.qmd` by `python paper/build.py`. +All synthetics, estimators, and generated figures in this paper are implemented +in the open-source Python package codameter (MIT license), openly available at +; each generated figure's sidecar +records its generating commit and numerical arrays. The figures and manuscript +can originate from different revisions. \texttt{python -m codameter.figures} +regenerates every generated figure with a \texttt{.npz} sidecar of its plotted +arrays and a \texttt{.json} sidecar of its provenance; +\texttt{python -m codameter.calibration} reproduces +Table\ \ref{tab:calibration} (\texttt{paper/data/calibration/}); +\texttt{scripts/compare\_gate1.py} reproduces Table\ \ref{tab:gate1} from the +daily products under \texttt{paper/data/gate1/} and the published +\citet{Clements2023} series archived there. The daily products and the three +real-data figures were produced by the noisepy-dvv-cloud Gate 1 run from +public Southern California Earthquake Data Center waveforms; the products are +available locally during this analysis but are not tracked in the repository. +The exact Gate 1 run commit, run configuration and redistribution archive +remain to be supplied; their current provenance limits are recorded in +\texttt{paper/data/gate1/README.md}. A versioned archive is planned but +has not yet been deposited. # Acknowledgements {.unnumbered} -[To be completed.] +[Funding, contributions and thanks to be completed by the author.] AI +assistance: this manuscript was checked with the Denolle Group Pre-Submission +Reviewer (v2.4, model Codex/GPT-6), an advisory AI tool, through one review +iteration and a subsequent evidence reconciliation; final author adjudication +remains to be recorded. The tool does not endorse manuscript validity. Code +revisions and text edits in response to that review were drafted with Claude +(Anthropic) and Codex (OpenAI) under the author's direction and are recorded +in the repository history. # References {.unnumbered} diff --git a/paper/manuscript_marine.tex b/paper/manuscript_marine.tex index 0626455..151b6ba 100644 --- a/paper/manuscript_marine.tex +++ b/paper/manuscript_marine.tex @@ -188,6 +188,11 @@ \AtBeginEnvironment{tabular}{\singlespacing} \AtBeginEnvironment{tabularx}{\singlespacing} \AtBeginEnvironment{longtable}{\singlespacing} + +% The full manuscript title overflows GJI's odd-page running header. +\makeatletter +\AtBeginDocument{\gdef\@shorttitle{Processing choices in seismic velocity monitoring}} +\makeatother \makeatletter \@ifpackageloaded{caption}{}{\usepackage{caption}} \AtBeginDocument{% @@ -246,127 +251,197 @@ \title{The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring} \author{M. A. Denolle} -\date{2026-08-08} +\date{2026-09-10} \begin{document} \maketitle \begin{abstract} -Relative seismic velocity changes (\dvv) from the ambient seismic field -are a standard observable for volcanoes, faults, landslides, aquifers -and the cryosphere. Yet turning cross-correlation functions into a -\dvv~time series involves a long sequence of choices --- the estimator, -the frequency band, the coda window, the reference, the stacking, and -how cross-components and station pairs are aggregated and weighted --- -made \emph{ad hoc} and seldom reported in full. Using a controlled -synthetic in which the ground-truth \dvv~is known exactly, we quantify -how much each choice moves the recovered value \emph{and its stated -uncertainty}. Reproducing the seven NoisePy estimators, we show that at -large \dvv~methods split by family with distinct failure modes; that the +Relative seismic velocity changes (\dvv) from repeated coda waves are a +standard observable for volcanoes, faults, landslides, aquifers and the +cryosphere. Turning cross-correlation functions into a \dvv~time series +involves a long sequence of choices, the estimator, the frequency band, +the coda window, the reference, the stacking, and how cross-components +and station pairs are aggregated and weighted, made ad hoc and reported +incompletely, so the same data can support different values and +different error bars. We quantify the individual and combined effects of +these choices on synthetic correlation functions in which the +ground-truth \dvv~is known exactly. On these synthetics, at large +\dvv~the estimators split by family with distinct failure modes; the same station pair yields different \dvv~depending only on whether one -averages the per-component \dvv~or the correlation-coefficient images; -and, most consequentially, that the reported \(1\sigma\) on a -network-averaged \dvv~varies by \(\sim\!\sqrt{N}\) from the -standard-error-versus-standard-deviation and weighting conventions --- -so a change that is ``\(3\sigma\) significant'' in one study is ``not -significant'' in another, from identical data. Running the full -\emph{multiverse} of choices, we rank each by the bias and error-bar -change it induces, and propose a Bayesian measurement model that -marginalises the ensemble into a single time-dependent data covariance -\(C_d\) --- the object a downstream depth or stress inversion needs. We -argue that these undocumented choices, not the physics, are the leading -obstacle to intercomparing \dvv~studies, and release an open framework -(codameter) that makes every choice explicit and reproducible. +averages per-component \dvv~or the correlation-coefficient images; and +the number quoted as the \(1\sigma\) uncertainty of a network-averaged +\dvv~differs by \(\sim\!\sqrt{N}\) between the standard error of the +network mean and the between-pair standard deviation, two different +quantities that studies rarely distinguish. A one-at-a-time sweep and a +108-pipeline factorial on one scenario rank the choices by the error +they induce. We then propose a hierarchical Bayesian measurement model +that runs an ensemble of defensible pipelines on the same correlations +and combines their estimates into a single \dvv~series. A separate +construction proposes a time-dependent single-member error covariance +\(C_d\). On 200 independent synthetic realisations of a volcano +scenario, \(C_d\) covers 95.6\% of individual member errors at the 95\% +level, whereas the credible band on the ensemble mean covers the truth +only 59\% of the time because the configurations share time-varying +biases; a seasonal source artefact seen by every configuration reduces +that coverage to 34\% and more than doubles the error of the ensemble +mean while leaving member coverage near 95\%. The nominal 68\% member +intervals cover 81\% in the clean case; these pointwise checks do not +validate the full covariance. Shared errors require diagnostics beyond +agreement among processing choices. We set out how \(C_d\) enters a +depth inversion of shear-velocity change; that stage is described, not +evaluated, here. On three California stations the same measurement code, +run on NoisePy correlations in a cloud batch pipeline, reproduces a +published \dvv~product (correlation 0.83--0.99 on 360--580 matched days, +with a reproducible comparison script), a comparison that also exposed +and corrected a sign-convention error. The framework, estimators, +figures with their numerical sidecars, and the calibration experiments +are released in the open Python package \texttt{codameter}, together +with a processing-choice advisor and a seeded golden dataset with fixed +scoring support and a null-change penalty for missing predictions; an +evaluation of agents against that dataset is left to future work. \end{abstract} \begin{keywords} -Time-series analysis; Interferometry; Seismic noise; Coda waves; Inverse theory; Statistical methods. +Coda-wave Interferometry; Seismic noise; Coda waves; Inverse theory; Statistical methods. \end{keywords} \section{Introduction}\label{sec:intro} -Changes in subsurface properties occur due geodynamics, which drive +Changes in subsurface properties occur due to geodynamics, which drive earthquake damage and volcanic eruption, and hydrodynamics, which -controls fluid exchange between the atomsphere and the solid Earth. -These processes influence the mechanical property of Earth materials, -which directly affect the speed at which seismic waves propagates. +controls fluid exchange between the atmosphere and the solid Earth. +These processes influence the mechanical properties of Earth materials, +which directly affect the speed at which seismic waves propagate. Changes in seismic velocity, often measured and referred to as \dvv, can be tracked by measuring changes in arrival times of seismic waves, -especially scatterd waves such as coda waves, provided that the source +especially scattered waves such as coda waves, provided that the source and receivers are at the same location. Due to the sensitivity of coda waves to small perturbations in the -material properties, \dvv~was discovered as an effective method to -monitor chanes during volcanic unrest since its discovery at Piton de la -Fournaise \citep{Brenguier2008} and is now calculated in continuous -along side of more conventional seismic monitoring methods in the same -volcano observatory \citep{Duputel2009} and was a determining early -warning parameter used by the Icelandic Meteorological Office used -\dvv~in its response to the 2020 Reykjanes unrest (Cubuk-Sabuncu et al., -2021). The Institute of Mine Seismology also uses \dvv~to monitor the -internal state of tens of tailings dams and mines to flag instability -before failure (Olivier et al., 2017; Ouellet et al., 2022). A broader -set of operations is emerging around the same signal: groundwater -storage for water management (Clements and Denolle, 2018; Mao et al., -2022), landslide early warning (Le Breton et al., 2021), levee and -embankment integrity (Planès et al., 2016), and geothermal and CO\(_2\) -reservoir surveillance (Nakata et al., 2021). Each of these deployments -rests on the same fragile assumption: that the \dvv~curve an operator -acts on is a property of the subsurface, not of the analyst's processing -choices. - -The elevated sensitivity comes at the price a long series of processing -choices and at almost every step the analyst makes a choice. Among these -are choices of estimators between windowed phase measurements or -strething \citep[\citet{Mao2020}, \citet{Yuan2021}]{Mikesell2015}, -frequency band and coda window (which together set the sampled depth; -\citeauthor{Obermann2013} +material properties, \dvv~has become an effective way to monitor +volcanic unrest, from the first passive monitoring at Merapi +\citep{SensSchonfelder2006} to the pre-eruptive velocity drops at Piton +de la Fournaise \citep{Brenguier2008}, where it is now computed +continuously alongside conventional observatory monitoring +\citep{Duputel2009}; the Icelandic Meteorological Office included +\dvv~among the parameters it followed during the 2020 Reykjanes unrest +\citep{CubukSabuncu2021}. The same signal is used to monitor the +internal state of tailings dams and mines and to flag instability before +failure \citep{Olivier2017, Ouellet2022}. A broader set of operations is +emerging around the same signal: groundwater storage for water +management \citep{Clements2018, Mao2022}, landslide early warning +\citep{LeBreton2021}, levee and embankment integrity \citep{Planes2016}, +and geothermal and CO\(_2\) reservoir surveillance \citep{Tsuji2021}. +Each of these deployments rests on the same fragile assumption: that the +\dvv~curve an operator acts on is a property of the subsurface, not of +the analyst's processing choices. + +\dvv~is the fractional seismic velocity change, positive for a velocity +\emph{increase}. The stretching family of estimators measures the +stretch factor \(\varepsilon\) that maps the current coda onto the +reference coda. Throughout this work, the reference correlation is held +fixed and trial dilations are applied to the current correlation, \[ +c_\epsilon(t)=c[(1+\epsilon)t], +\] where interpolation is performed only on (c). Thus +\((\epsilon=t_{\rm cur}/t_{\rm ref}-1)\) is a fractional travel-time +dilation: \(\epsilon>0\) denotes a delayed phase in the current coda +(slower) and \(\epsilon<0\) denotes an earlier arrival time (faster). +For unchanged propagation geometry, \[ +1+\epsilon=\frac{t_{\rm cur}}{t_{\rm ref}} +=\frac{v_{\rm ref}}{v_{\rm cur}}, +\] and therefore the physical fractional velocity change reported +throughout this work is \[ +\boxed{ +\frac{\delta v}{v} +\equiv +\frac{v_{\rm cur}-v_{\rm ref}}{v_{\rm ref}} += +-\frac{\epsilon}{1+\epsilon}. +} +\] The commonly used relation +(\(\delta v/v\simeq-\epsilon\simeq-\delta t/t\)) is its first-order +approximation and used in the majority of published work. We retain the +exact finite-change transformation because its computational cost is +negligible and because the distinction becomes measurable for velocity +perturbations of several percent measured in large strain phenomena such +as landslides. The current coda is stretched rather than the reference +correlation so that the high-SNR reference stack remains unchanged +throughout the search. While the reciprocal formulations are +mathematically equivalent; in sampled, finite-window data they can +differ because interpolation and boundary truncation break that +symmetry. + +The elevated sensitivity comes at the price of a long series of +processing choices, and at almost every step the analyst makes a choice. +Among these are choices of estimators between windowed phase +measurements or stretching \citep[\citet{Mao2020}, +\citet{Yuan2021}]{Mikesell2015}, frequency band and coda window (which +together set the sampled depth; \citeauthor{Obermann2013} \citetext{\citeyear{Obermann2013}; \citealp{Obermann2016}}), reference -window \citep[\citet{Ermert2023}, \citet{Okubo2024}]{Brenguier2014}, how -much to substack to increase coherence among windows (Hadzianou Celine), +window \citep[\citet{Ermert2023}, \citet{Okubo2024}]{Brenguier2014}, +increasing the temporal resolution of the measurement through +substacking-filtering-denoising +\citep[\citet{Moreau2017},\citet{Mao2019},\citet{Viens2020}]{Hadziioannou2011}, and how to aggregate and weight the many cross-component and station-pair measurements that make up a single reported \dvv~time -series (e.g., \citet{Hobiger2012}). These choices are typically made by -habit, justified briefly if at all , and rarely reported in enough -detail to reproduce. The community has long flagged \emph{individual} -pitfalls (spurious changes from non-stationary noise, \citet{Zhan2013}; +series (e.g., \citet{Hobiger2012}). These choices are made by habit, +justified briefly if at all, and rarely reported in enough detail to +reproduce. The community has long flagged \emph{individual} pitfalls +(spurious changes from non-stationary noise, \citet{Zhan2013}; measurement-error formulae, \citeauthor{Clarke2011} -\citetext{\citeyear{Clarke2011}; \citealp{Weaver2011}}), but the -\emph{cumulative} effect of the full choice set on both the value and -its stated uncertainty has not been quantified comprehensively in the -literature. +\citetext{\citeyear{Clarke2011}; \citealp{Weaver2011}}) and has compared +estimators against one another on simulated data \citep{Yuan2021}. What +has not been done, to our knowledge, is to quantify on one truth-known +dataset the \emph{joint} effect of the full choice set on both the value +and its stated uncertainty, and to carry that spread into a measurement +covariance. One indication of the stakes is the compilation of +\citet{Denolle25b}, in which most studies find \dvv~anticorrelated with +groundwater level, but with a scatter across studies that differences in +frequency band, single-station versus inter-station correlations and +other processing choices can explain in part, alongside genuine +hydrogeological differences between sites; that scatter limits how far +the compiled relation can be used quantitatively in hydrological work. This is a reproducibility problem of exactly the ``garden of forking paths'' type identified in the statistical sciences \citep{Gelman2013, Steegen2016}: many individually reasonable analyses -of the same data give different answers, and without full reporting -parameter choices we cannot fully interpret \dvv~as robust values. . +of the same data give different answers, and without full reporting of +parameter choices we cannot interpret a reported \dvv~as a robust value. Here we make the problem concrete for \dvv~monitoring. We use purely synthetic correlation time series to test the methods (estimators) and -parameter choices that the community makes to estimate \dvv, which we -report over 103 studies Appendix\textasciitilde{}\ref{app:survey}. We do -not aim to report the ``best'' pipeline, which is most often the one -reported in scientific papers, but instead document the various -parameter impacts (Section\textasciitilde{}\ref{sec:results}). We then -propose a new measurement error that incoporates these effects into a -data covariance matrix \(C_d\) -(Section\textasciitilde{}\ref{sec:bayes}). - -One example of propagating such error in downstream scientific insights -is the migration of the surface \dvv~measurement to depth profiles of +parameter choices that the community makes to estimate \dvv\(\,\)which +we report over 103 studies in Appendix~\ref{app:survey}. We do not aim +to report the ``best'' pipeline, which is most often the one reported in +scientific papers, but instead document the parameter impacts +(Section~\ref{sec:results}). We then propose a new measurement error +that incorporates these effects into a data covariance matrix \(C_d\) +(Section~\ref{sec:bayes}). Throughout this paper, key notation includes: +\(\sigma\) (measurement uncertainty of a recovered \dvv~estimate), \(B\) +(frequency bandwidth), and \(W=[t_1,t_2]\) (coda window); subscripts +distinguish specific contexts (e.g., \(\sigma_k\) for per-component +uncertainty), each defined where first introduced. + +One example of propagating such error into downstream science is the +migration of the surface \dvv~measurement to depth profiles of perturbations in shear wave velocity \(\Delta V_S(z)/V_S(z)\), which -often depends on the wavefield constituting the coda waves, such as -surface waves or body waves, and that depend on the source-receiver pair -geometry. We illustrate the propagation of errors to a depth profile -(Section\textasciitilde{}\ref{sec:depth}). We only utilize synthetic -examples for ground truthing on the signal processing parameters, since -the concepts behind the observations of phase lags in scattered waves is -well established \citep{Obermann2013}. We package this new methodology -in a Python software, \texttt{codameter}, which we also recast as an -agentic skill: an AI agent can be asked to recommend a processing -configuration or recover a \dvv(t) series, and its answer is scored -against seeded synthetic golden cases with known ground truth, including -a hidden-truth variant that withholds the answer from the public package -so it cannot be reconstructed rather than measured. +depends on the wavefield constituting the coda waves, surface or body +waves, and on the source-receiver geometry. We set out how the +measurement covariance enters such a depth inversion +(Section~\ref{sec:depth}); the executable depth stage is described +there, not evaluated. We use synthetic examples for ground truthing of +the signal-processing parameters, since the physics of phase lags in +scattered waves is well established \citep{Obermann2013}. + +We then compare single-station \dvv~from the same measurement code, run +on NoisePy correlations for three California stations, with a published +product (Section~\ref{sec:deployment}). We package the methodology in a +Python software, \texttt{codameter}, which also ships an advisor skill: +an AI agent can be asked to recommend a processing configuration or +recover a \dvv(t) series, and its answer can be scored against seeded +synthetic golden cases with known ground truth, including a hidden-truth +variant that withholds the answer from the public package. The scorer +and dataset are part of the release; an evaluation of agents against +them is not part of this paper. \section{Synthetic framework}\label{sec:methods} @@ -409,7 +484,7 @@ \section{Synthetic framework}\label{sec:methods} A homogeneous velocity change is imposed exactly by stretching the lapse-time axis, -\(u_{\rm cur}(t) = u_{\rm ref}\!\left(t/(1+\dvv)\right)\), and a +\(u_{\rm cur}(t) = u_{\rm ref}\!\left(t\,(1+\dvv)\right)\), and a repeated time series is produced by generating this stretched coda with a prescribed ground-truth \(\dvv(t)\) and additive band-limited noise at a controlled signal-to-noise ratio. The concept has been demonstrated @@ -419,59 +494,55 @@ \section{Synthetic framework}\label{sec:methods} every departure of a recovered series from it is an artefact of the processing, not of the data. -We utilize seven \dvv~estimators that were implemented in -\texttt{noisepy} in the \texttt{monitoring\_methods} module -\citep{Jiang2020}: trace stretching (TS, \citet{lobkis01}), windowed +We use seven \dvv~estimators that were implemented in \texttt{noisepy} +\citep{Jiang2020}: trace stretching (TS, \citet{lobkis03}), windowed cross-correlation (WCC, \citet{poupinet84}), dynamic time warping (DTW, -\citet{Mikesell2015}), te moving-window cross-spectrum (MWCS; +\citet{Mikesell2015}), the moving-window cross-spectrum (MWCS; \citet{Clarke2011}), and three wavelet-domain methods, the wavelet cross-spectrum (WCS, \citet{Mao2020}) and the two wavelet stretching (WTS) and wavelet DTW (WTDTW) introduced and benchmarked numerically by -\citet{Yuan2021}. The framework, the figures below, and a implementation -are released in the open \texttt{codameter} package -(Section\textasciitilde{}\ref{sec:discussion}). Formal definitions of -all seven methods, of the two aggregation pathways, and of the -uncertainty conventions are described in -Appendices\textasciitilde{}\ref{app:estimators} -and\textasciitilde{}\ref{app:aggregation}. +\citet{Yuan2021}. The framework, the figures below, and an +implementation are released in the open \texttt{codameter} package +(Section~\ref{sec:discussion}). Formal definitions of all seven methods, +of the two aggregation pathways, and of the uncertainty conventions are +described in Appendices~\ref{app:estimators} and~\ref{app:aggregation}. Each of these methods require specific parameter choices, which we -categorize and reference in Table\textasciitilde{}\ref{tab:hyperparams}. -The work presented below measure the impacts of each of these parameter -choices on the resulting \dvv. +categorize and reference in Table~\ref{tab:hyperparams}. The work +presented below measure the impacts of each of these parameter choices +on the resulting \dvv. \begin{table} \footnotesize \caption{Processing choices (``hyper-parameters'') and their effect on the -recovered value and the reported uncertainty ($B$: bandwidth, $N$: measurement -count, $N_{\mathrm{eff}}$: weighted effective count).} +recovered value and the reported uncertainty. Key notation: $B$ (frequency bandwidth), +$W=[t_1,t_2]$ (coda window), $N$ (measurement count), $N_{\mathrm{eff}}$ (weighted effective count), $\sigma$ (measurement uncertainty).} \label{tab:hyperparams} \begin{tabularx}{\textwidth}{@{}>{\raggedright\arraybackslash}p{2.35cm} L L L@{}} \toprule \textbf{Choice} & \textbf{Options / typical range} & \textbf{Effect on the value} & \textbf{Effect on the uncertainty} \\ \midrule -Estimator & TS, WCC, DTW, MWCS, WCS, WTS, WTDTW (7 in NoisePy) & +Estimator & TS, WCC, DTW, MWCS, WCS, WTS, WTDTW & Agree at small \dvv; at large \dvv\ phase methods cycle-skip, warps under-shoot -(Fig.~\ref{fig:methods}) & Each has its own error model; the inter-method spread -is itself an uncertainty \\ \hline +(Fig.~\ref{fig:methods}) & Each has its own error model; inter-method spread is an uncertainty \\ \hline Phase unwrapping & on / off (phase methods) & Decides whether MWCS/WCS cycle-skip (Fig.~\ref{fig:methods}b) & Sets the usable \dvv\ range \\ \hline -Frequency band $[f_1,f_2]$ & 0.1--2\,Hz (volcano), 2--4\,Hz (aquifer), +$B$ & 0.1--2\,Hz (volcano), 2--4\,Hz (aquifer), 4--12\,Hz (landslide) & Selects the sampled depth, hence \emph{which} signal -(Fig.~\ref{fig:params}a) & $\sigma$ falls as bandwidth $B$ grows \\ \hline -Coda window $[t_1,t_2]$ & a few to tens of mean free times & Later lapse $\to$ -deeper, larger sensitivity & $\sigma\propto(t_2^3-t_1^3)^{-1/2}$, but late coda -is low-SNR \\ \hline -Window--band coupling & fixed vs scaled with $f$ & A fixed late window at high -$f$ measures noise (Fig.~\ref{fig:params}b) & Inflates $\sigma$ / decorrelation -at high band \\ \hline -Reference & total stack / trailing / joint inversion & Moving reference erases -slow trends (Fig.~\ref{fig:params}c) & Reference noise propagates; inversion +(Fig.~\ref{fig:params}a) & $\sigma$ decreases with increasing $B$ \\ \hline +$W$ & a few to tens of mean free times & Later lapse $\to$ +deeper, larger sensitivity & $\sigma\propto(t_2^3-t_1^3)^{-1/2}$ (duration effect), +but late coda is low-SNR \\ \hline +$W$-$B$ coupling & fixed vs scaled with $f$ & A fixed late window at high +$f$ measures noise (Fig.~\ref{fig:params}b) & inceases $\sigma$ due to decorrelation +at high $f$ \\ \hline +Reference & total stack / trailing / joint inversion & Trailing reference gives +increments: the trend is absent unless they are cumulated, which then drifts; +joint inversion preserves it directly (Fig.~\ref{fig:params}c) & Reference noise propagates; inversion lowers it \\ \hline Stacking / substack & 1--30+ days & Smears and delays transients -(Fig.~\ref{fig:params}d) & $\sigma$ falls with stack length; resolution falls -too \\ \hline +(Fig.~\ref{fig:params}d) & $\sigma$ and resolution decreases with stacking length \\ \hline Component aggregation & A (average \dvv) vs B (average CC images); weighted vs not & Different time series (Fig.~\ref{fig:aggregation}) & Different uncertainty object (ensemble spread vs CC-peak width) \\ \hline @@ -490,38 +561,77 @@ \section{Synthetic framework}\label{sec:methods} \end{tabularx} \end{table} +Several quantities in this paper are reported with the same symbol +\(\sigma\) but estimate different things. Table~\ref{tab:estimands} +fixes, for each, what it is an estimate of, its units, and the datum and +epochs it is evaluated on; figure captions refer to it. + +\begin{table} +\footnotesize +\caption{Reported quantities, what each estimates, and how it is evaluated. +All \dvv\ quantities are fractions of velocity; figures show percent.} +\label{tab:estimands} +\begin{tabularx}{\textwidth}{@{}>{\raggedright\arraybackslash}p{3.1cm} L L@{}} +\toprule +\textbf{Quantity} & \textbf{Estimate of} & \textbf{Datum and support} \\ +\midrule +Recovery RMS (Sections~\ref{sec:results}--\ref{sec:multiverse}) & Root mean +square of (recovered $-$ imposed) \dvv\ for one configuration on one waveform +realisation & Raw recovered series, no baseline alignment; epochs the pipeline +produced; fixed reference from the first 60\% of the record \\ \hline +Within-measurement $\sigma_k(t)$ & Standard error of one dilation estimate from +finite coda coherence, eq.~\ref{eq:weaver} & Per epoch and configuration; +depends on coherence, band, window; a lower bound (Section~\ref{sec:bayes}) \\ \hline +Between-pair SD, $\sigma_{\mathrm{SD}}$ & Dispersion of the $N$ pair estimates +at one epoch (physical heterogeneity plus pair noise) & Finite network; no datum +change \\ \hline +Network SE, $\sigma_{\mathrm{SE}}$, $\sigma_{\mathrm{SE},w}$ & Precision of the +network mean under independent pairs; shared stations or noise make it +optimistic & Same epochs; the target is the finite-network mean \\ \hline +Posterior credible band on $\mu(t)$ & Precision of the ensemble-combined +estimate under the model of Section~\ref{sec:bayes} & Decimated epochs; under-covers +when configurations share a bias \\ \hline +$C_d$ & Proposed error covariance of one ensemble member: fitted +floor, excess spread, temporal correlation, offset scale $\tau$ & Same +epochs; 95\% pointwise member coverage supported, 68\% overcoverage; +temporal covariance unvalidated (Table~\ref{tab:calibration}) \\ \hline +Field comparison $r$, slope & Agreement with a published product after matched +smoothing & Calendar-day join, 150-day burn-in, trailing 90-day mean +(Section~\ref{sec:deployment}) \\ +\bottomrule +\end{tabularx} +\end{table} + \section{\texorpdfstring{parameter-dependent \dvv~and its errors}{parameter-dependent ~and its errors}}\label{sec:results} The literature agrees on the components of a well-posed -\dvv~measurement: a stretching-family estimator for robustness at low -SNR and large change \citep{Mikesell2015, Yuan2021}, a coherence-based -error model \citep{Clarke2011, Weaver2011}, a long stable reference -\citep{Wang2017}, and cross-validation against a second estimator -\citep{Obermann2019}. Yet studies do not always report the same set, and -the uncertainty convention is rarely, if ever, quantified -(Appendix\textasciitilde{}\ref{app:survey}). The sections below address -each component in turn and quantify, against a known truth, how far a -parameter choice impacts the recovered \dvv~and its error. The -deliverable of this section is a measurement covariance, which every -subsequent step in the inference chain -(Sections\textasciitilde{}\ref{sec:depth}--\ref{sec:stress}) consumes. - -Each of the parametric components is implemented in a single -comprehensive package \texttt{codameter} that borrows from -\texttt{msnoise} \citep{Lecocq2014} and \texttt{noisepy} -\citep{Jiang2020} to extract the measurement of \dvv~from the ambient -noise monitoring workflow and generalize it to any coda wave from -repeated source-receiver paths. - -Table\textasciitilde{}\ref{tab:results-synthesis} previews the RMS error -against the known synthetic ground truth for the best- and worst-case -option on each axis covered in this section, each derived in its own -dedicated synthetic (detailed in the corresponding subsection below); it +\dvv~measurement: an estimator matched to the expected size of the +change (the stretching family remains accurate at large \dvv, +Section~\ref{sec:methods-fig}; its noise robustness relative to the +warping methods depends on the setting, and \citet{Yuan2021} rank it +below DTW in that respect on their heterogeneous full-wave simulations), +a coherence-based error model \citep{Clarke2011, Weaver2011}, a long +stable reference \citep{Wang2017}, and cross-validation against a second +estimator \citep{Obermann2019}. Yet studies do not always report the +same set, and the uncertainty convention is rarely, if ever, quantified +(Appendix~\ref{app:survey}). The sections below address each component +in turn and quantify, against a known truth, how far a parameter choice +impacts the recovered \dvv~and its error. + +Table~\ref{tab:results-synthesis} previews the RMS error against the +known synthetic ground truth for the best- and worst-case option on each +axis covered in this section, each derived in its own dedicated +synthetic exercise (detailed in the corresponding subsection below); it is a synthesis of \emph{this section's} per-choice numbers, distinct -from Table\textasciitilde{}\ref{tab:bp-measure}'s one-at-a-time sweep on -a single shared scenario in -Section\textasciitilde{}\ref{sec:multiverse}. +from Table~\ref{tab:bp-measure}'s one-at-a-time sweep on a single shared +scenario in Section~\ref{sec:multiverse}. Every RMS in this section is +computed on the raw recovered series against the imposed truth over the +epochs the pipeline produced, with no baseline alignment, so a reference +offset counts as error (Section~\ref{sec:param_ref} shows that +explicitly); the network-level uncertainty conventions of +Section~\ref{sec:uncertainty} are reported quantities, not recovery +errors, and are listed in Table~\ref{tab:estimands} rather than here. \begin{table} \footnotesize @@ -533,86 +643,111 @@ \section{\texorpdfstring{parameter-dependent \dvv~and its \toprule \textbf{Axis} & \textbf{Best-case RMS} & \textbf{Worst-case RMS} & \textbf{Section} \\ \midrule -Estimator (family split) & $<\!0.01\,\%$ (TS/WTS, up to 5\,\% true \dvv) & -cycle-skip $>\!0.5\,\%$ past $\sim\!1.4\,\%$ true \dvv\ (MWCS) & +Estimator (family split) & $<\!0.01\,\%$ (TS, up to 5\,\% true \dvv) & +cycle-skip $>\!0.5\,\%$ past $\sim\!1.5\,\%$ true \dvv\ (MWCS) & Section~\ref{sec:methods-fig} \\ \hline Cross-component aggregation & $\sim\!0.03\,\%$ (Approach B, averaged images) & $\sim\!0.31\,\%$ (Approach A, unweighted) & Section~\ref{sec:aggregation} \\ \hline -Network aggregation (per-pair spread) & $\sim\!0.005\,\%$ (network SE) & -$\sim\!0.05\,\%$ (individual-pair range) & Section~\ref{sec:uncertainty} \\ \hline -Frequency band & $\sim\!0.003$--$0.03\,\%$ (matched to depth) & -$\sim\!0.10\,\%$ (mismatched) & Section~\ref{sec:params} \\ \hline +Frequency band & $\sim\!0.028$--$0.031\,\%$ (within $\pm0.3\,$Hz of the true +band) & $\sim\!0.10\,\%$ (center off by $>\!0.5\,$Hz) & +Section~\ref{sec:params_freq} \\ \hline Coda window & $\sim\!0.01\,\%$ (adapted to band) & -$\sim\!3.8\,\%$ (fixed, wrong band) & Section~\ref{sec:window} \\ \hline -Reference scheme & $\sim\!0.03$--$0.04\,\%$ (fixed stack / joint inversion) & -$\sim\!0.16\,\%$ (60-day moving) & Section~\ref{sec:params} \\ \hline -Stack length & $\sim\!0.018\,\%$ (10-day) & -$\sim\!0.044\,\%$ (1-day, noisy) & Section~\ref{sec:params} \\ +$\sim\!3.9\,\%$ (fixed, wrong band) & Section~\ref{sec:param_window} \\ \hline +Reference scheme & $\sim\!0.03\,\%$ (whole record, earliest period, or joint +inversion) & $\sim\!0.15$--$0.16\,\%$ (end-of-record fixed, or moving) & +Section~\ref{sec:param_ref} \\ \hline +Stack length & $\sim\!0.020\,\%$ (7--10-day, workable deployment) & +$\sim\!0.044\,\%$ (1-day, same deployment) & Section~\ref{sec:param_substack} \\ \bottomrule \end{tabularx} \end{table} \subsection{Estimator family}\label{sec:methods-fig} -On small, clean \dvv, all seven estimators agree, demonstrating -robustness of the methods (Fig.\textasciitilde{}\ref{fig:methods}a). -Sweeping the same clean recovery out to \(\pm 5\,\%\) -(Fig.\textasciitilde{}\ref{fig:methods}b) shows exactly where and how -each family first departs from the 1:1 line, and the estimator choice -becomes consequential at large, noisy -\dvv~(Fig.\textasciitilde{}\ref{fig:methods}c), where the effect of the -methods is split according to their phase measurement approaches. The -stretching family (TS, WTS) and WCC match the whole dilated coda and -remain accurate for high SNR coda waves; the phase methods (MWCS) read a -wrapped phase and may cycle-skips, while the \emph{same} cross-wavelet -phase (WCS), once unwrapped in 2-D, recovers the change. The warping -methods (DTW, WTDTW) track but under-shoot the largest strains. No -estimator is simply ``right'' and choices in the estimators can alters -the \dvv~measurements for larger strain changes. +We implement all methods as in previous work \citep{Jiang2020}. + +As of codameter v0.4.0, all seven estimators return physical \dvv~under +the sign convention above rather than the raw stretch factor +\(\varepsilon\); the synthetic generator imposes changes in the same +convention, so a positive imposed \dvv~recovers as positive. A dedicated +regression test holds every estimator to this convention in both signs, +end to end through the full measurement pipeline, so the convention +cannot silently drift back. + +On small, clean \dvv\(\,\)all seven estimators agree to within 0.04,\% +RMS (Fig.~\ref{fig:methods}a). Sweeping the same clean recovery out to +\(\pm 5\,\%\) (Fig.~\ref{fig:methods}b) shows exactly where and how each +family first departs from the 1:1 line, and the estimator choice becomes +consequential at large, noisy \dvv~(Fig.~\ref{fig:methods}c), where the +effect of the methods is split according to their phase measurement +approaches. The stretching family (TS, WTS) and WCC match the whole +dilated coda and stay within 0.05,\% RMS of the truth on the noisy +landslide signal (0.005, 0.010 and 0.046,\%); the warping methods (DTW, +WTDTW) track but under-shoot the largest strains (0.16 and 0.08,\% RMS); +both phase methods fail on this noisy, large-strain signal, MWCS by +cycle-skipping (2.9,\% RMS) and WCS, whose 2-D unwrapping recovers the +clean sweep of panel (b), by losing the phase track once noise is added +(3.8,\% RMS; the numbers are computed from the figure's numerical +sidecar). No estimator is simply ``right''; the choice of estimator +materially changes the \dvv~measurement at larger strain. \begin{figure} \centering \includegraphics[width=\textwidth]{demo_1_methods.png} \caption{Estimator choice across the seven NoisePy methods. (a) Clean, small \dvv: all agree. (b) The same clean recovery swept over $\pm 5\,\%$ - true \dvv: MWCS cycle-skips almost immediately past $\pm 1$--$2\,\%$, DTW/WTDTW - break past $\pm 3$--$4\,\%$, WCS degrades smoothly, while TS/WTS/WCC track the - 1:1 line throughout. (c) Large, noisy \dvv\ (a pre-failure landslide signal): - MWCS cycle-skips, 2-D-unwrapped WCS and the stretching family track, the - warping methods under-shoot.} + true \dvv: MWCS cycle-skips past $\sim\!1.5\,\%$ on either branch; TS and WTS + track the 1:1 line throughout; WCC tracks just as tightly on the negative + branch but breaks sharply near the positive edge; DTW and WTDTW break + asymmetrically, WTDTW near $+1\,\%$ but only near $-3\,\%$ on the other + branch; WCS degrades smoothly, crossing $1\,\%$ error beyond $\pm 4\,\%$. + (c) Large, noisy \dvv\ (a pre-failure landslide signal): the stretching + family and WCC track, the warping methods under-shoot, and both phase + methods fail (MWCS cycle-skips; WCS loses the phase track in noise despite + the 2-D unwrapping that carries it through the clean sweep in b). RMS + errors are given in the text; the plotted arrays are in the figure's + sidecar (Table~\ref{tab:estimands}).} \label{fig:methods} \end{figure} -On a clean, noiseless sweep of true \dvv~from 0 to 5,\% -(Fig.\textasciitilde{}\ref{fig:methods}b), the phase-wrapped MWCS -estimator is the first to break: its error stays below \(0.1\,\%\) up to -a true \dvv~of \(\sim\!1.2\,\%\), then jumps discontinuously past -\(0.5\,\%\) error by \(\sim\!1.4\,\%\) true \dvv~--- the cycle-skip. The -stretching family (TS, WTS) stays below \(0.01\,\%\) error out to the -full 5,\% tested, and WCC stays below \(0.1\,\%\); the warping methods -(DTW, WTDTW) are accurate at small \dvv~but develop intermittent, large -(\(>\!1\,\%\)) errors from \(\sim\!3\,\%\) true \dvv~onward as the warp -path becomes ill-conditioned, while WCS degrades smoothly rather than -catastrophically, crossing \(1\,\%\) error only beyond \(\sim\!4\,\%\) -true \dvv. +On a clean, noiseless sweep of true \dvv~from \(-5\) to \(5\,\%\) +(Fig.~\ref{fig:methods}b), the phase-wrapped MWCS estimator is the first +to break on either branch: its error stays below \(0.1\,\%\) out to +\(\sim\!1.3\,\%\) true \dvv, then exceeds \(1\,\%\) error by +\(\sim\!1.5\,\%\) --- the cycle-skip, essentially symmetric in sign. The +stretching family (TS, WTS) stays below \(0.1\,\%\) error out to the +full \(5\,\%\) tested, on both branches. WCC is just as accurate on the +negative branch (error stays below \(0.1\,\%\) throughout) but breaks +sharply on the positive branch, crossing both \(0.1\,\%\) and \(1\,\%\) +error abruptly at the edge of the tested range (\(\sim\!4.75\,\%\)) --- +a sign asymmetry from the physical convention itself +(Section~\ref{sec:intro}), not a processing artefact. The warping +methods develop large (\(>\!1\,\%\)) errors asymmetrically as the warp +path becomes ill-conditioned: WTDTW crosses \(1\,\%\) error already at +\(\sim\!1\,\%\) true \dvv~on the positive branch but only at +\(\sim\!3\,\%\) on the negative branch, and DTW crosses at +\(\sim\!2.5\,\%\) versus \(\sim\!3\,\%\). WCS degrades smoothly rather +than catastrophically, crossing \(1\,\%\) error beyond \(\pm4\,\%\) true +\dvv~on either branch. \subsection{Aggregating cross-component results}\label{sec:aggregation} Each three-component seismic station (e.g., Z, N, E) carries 6 -cross-componet correlations (ZZ, NN, EE, ZE, ZN, NE), whether they are -calculated at the single station or a inter-station pair. Each carry a -signature of the changes in velocity, components may be dominated by -Love or Rayleigh waves \citep{Lin2008, Stehly2006}, but there scattering -and non-straight ray path induce cross-component leakage between modes +cross-component correlations (ZZ, NN, EE, ZE, ZN, NE), whether they are +calculated at a single station or an inter-station pair. Each carries a +signature of the changes in velocity; components may be dominated by +Love or Rayleigh waves \citep{Lin2008, Stehly2006}, but scattering and +non-straight ray paths induce cross-component leakage between modes \citep{Hennino2001, Margerin2019}, and thus it is often assumed in practice that coda waves of cross-components with multi-scattering -characteristixcs (e.g., no clearly separated phases) are composed of +characteristics (e.g., no clearly separated phases) are composed of ``surface waves'' with strong S-wave sensitivity. Combining them together requires parameter choices, such as averaging them directly \citep{Liu2014}, or weighted (e.g., using coherence-based weighting -\citet{Hobiger2012}, \citet{DePlaen2016}). Combining is another workflow -choice that can change both the value and the uncertainty -(Fig.\textasciitilde{}\ref{fig:aggregation}). One may peak-pick each +\citet{Hobiger2012}, \citet{DePlaen2016}). + +Combining is another workflow choice that can change both the value and +the uncertainty (Fig.~\ref{fig:aggregation}). One may peak-pick each component's correlation-coefficient curve \(\mathrm{CC}(\varepsilon,t)\) and then average the per-component \dvv~(Approach A) --- unweighted, a few poor components bias the mean; coherence-weighted, they are @@ -651,15 +786,27 @@ \subsection{Aggregating across station pairs}\label{sec:uncertainty} common: a coherence-weighted standard error (e.g., \citet{Clarke2011}), an unweighted standard error (\(\sigma=\mathrm{std}/\sqrt{N}\); e.g., \citet{Brenguier2008}), and the between-pair standard deviation (e.g., -\citet{Clements2018}). On the same synthetic network the recovered means -nearly coincide, but the reported \(1\sigma\) spans a factor of -\(\sim\!\sqrt{N}\) (Fig.\textasciitilde{}\ref{fig:uncertainty}). A -velocity change that is ``\(3\sigma\) significant'' under the tightest -convention is ``\(1\sigma\), not significant'' under the most -conservative one --- from identical data. Error bars on published -\dvv~are therefore not comparable across studies unless the aggregation, -the weighting, and the standard-error-versus-standard-deviation -convention are all stated. +\citet{Clements2018}). These are estimates of different quantities +(Table~\ref{tab:estimands}): the standard error is the precision of the +network mean under independent pairs, the standard deviation is the +dispersion of the pairs, which on this synthetic mixes the 15,\% +pair-to-pair amplitude heterogeneity we impose with the pair noise, and +the two are related by \(\sqrt{N}\) by construction. On the same +synthetic network the recovered means nearly coincide, but the number +reported as \(1\sigma\) spans a factor of \(\sim\!\sqrt{N}\) +(Fig.~\ref{fig:uncertainty}). A velocity change that is three times the +coherence-weighted standard error is about one between-pair standard +deviation, from identical data; neither statement is wrong, but a study +that reports only ``\(1\sigma\)'' leaves the reader unable to tell which +is meant. Error bars on published \dvv~are therefore not comparable +across studies unless the aggregation, the weighting, and the +standard-error-versus-standard-deviation convention are all stated. +Neither convention is the precision of the mean when pairs share +stations or noise; that requires the pair covariance, +\(\mathbf{a}^\top\Sigma\mathbf{a}\) for normalised weights +\(\mathbf{a}\), which the Bayesian ensemble of Section~\ref{sec:bayes} +supplies for the configuration axis and which a network extension would +supply for the pair axis. \begin{figure} \centering @@ -671,24 +818,23 @@ \subsection{Aggregating across station pairs}\label{sec:uncertainty} \label{fig:uncertainty} \end{figure} -Figure\textasciitilde{}\ref{fig:uncertainty} plots only the -\emph{network-aggregate} series, which hides how much the individual -pairs actually disagree. Fig.\textasciitilde{}\ref{fig:network-pairs} -plots the same nine-pair network's \emph{individual} \dvv(t) curves, -styled after a basin-scale, urban ambient-noise deployment such as the -San Gabriel Valley groundwater network \citep{Clements2018} --- an -illustrative geometry rather than a literal reproduction of that -network's exact station spacing. The individual pairs range in quality -from a coherence-weighted SNR of \(\sim\!2.5\) to \(\sim\!11\), and -their spread at any given day (median range \(\sim\!0.053\,\%\)) is -nearly \(10\times\) wider than the coherence-weighted network standard -error (median \(\sim\!0.005\,\%\)) and more than \(3\times\) wider than -the more conservative between-pair standard deviation (median -\(\sim\!0.017\,\%\)). A network-level error bar, however it is computed, -describes the precision of the \emph{mean}, not the \emph{dispersion} of -what individual pairs actually report --- the two are routinely -conflated when a single station-pair result is compared against a -published network value. +Figure~\ref{fig:uncertainty} plots only the \emph{network-aggregate} +series, which hides how much the individual pairs actually disagree. +Fig.~\ref{fig:network-pairs} plots the same nine-pair network's +\emph{individual} \dvv(t) curves, styled after a basin-scale, urban +ambient-noise deployment such as the San Gabriel Valley groundwater +network \citep{Clements2018} --- an illustrative geometry rather than a +literal reproduction of that network's exact station spacing. The +individual pairs range in quality from a coherence-weighted SNR of +\(\sim\!2.5\) to \(\sim\!11\), and their spread at any given day (median +range \(\sim\!0.053\,\%\)) is nearly \(10\times\) wider than the +coherence-weighted network standard error (median \(\sim\!0.005\,\%\)) +and more than \(3\times\) wider than the more conservative between-pair +standard deviation (median \(\sim\!0.017\,\%\)). A network-level error +bar, however it is computed, describes the precision of the \emph{mean}, +not the \emph{dispersion} of what individual pairs actually report --- +the two are routinely conflated when a single station-pair result is +compared against a published network value. \begin{figure} \centering @@ -700,36 +846,226 @@ \subsection{Aggregating across station pairs}\label{sec:uncertainty} \label{fig:network-pairs} \end{figure} -\subsection{Frequency band, reference and stacking}\label{sec:params} +\subsection{Frequency band}\label{sec:params_freq} The remaining choices are no less consequential. The \textbf{frequency band} sets the sampled depth: in a two-layer medium, high frequencies recover shallow, often seasonal signals and low frequencies recover a -deeper, maybe more tectonic, signal -(Fig.\textasciitilde{}\ref{fig:params}a). On our synthetic two-layer -groundwater scenario, a band matched to each layer (1.5--6,Hz for the -shallow, seasonal signal; 0.2--0.8,Hz for the deep, drought-trend -signal) recovers each with RMS error \(\sim\!0.003\)--\(0.03\,\%\); -using the wrong band for a given depth inflates the error to -\(\sim\!0.10\,\%\) for both --- a \(\sim\!4\)--30\(\times\) degradation. +deeper, maybe more tectonic, signal (Fig.~\ref{fig:params}a). In +practice a band often gets reused from a neighboring deployment or an +earlier study at the same site without re-checking that it still matches +the target depth --- exactly the error this section quantifies. + +On our synthetic two-layer groundwater scenario, holding the recovery +band's width fixed (0.6\(\,\)Hz) and sweeping its center away from the +deep layer's true 0.2--0.8\(\,\)Hz band shows the cost is not gradual: +RMS error against the known truth stays flat, +\(\sim\!0.028\)--\(0.031\,\%\), for a center offset within +\(\sim\!0.3\,\)Hz of the true center, then rises by a factor of +\(\sim\!3\)--\(4\) once the offset passes \(\sim\!0.5\,\)Hz --- the +point at which the assumed band starts sampling the shallow layer's +signal instead of the deep one --- and plateaus near \(\sim\!0.10\,\%\) +beyond that (Fig.~\ref{fig:band-sensitivity}). The band choice is +forgiving up to the edge of the layer it targets, and expensive +immediately past it, not gradually worse the further off it drifts. + +\begin{figure} + \centering + \includegraphics[width=0.7\textwidth]{demo_16_band_sensitivity.png} + \caption{Frequency-band sensitivity: RMS error against the known + groundwater deep-layer truth as the recovery band's center is swept away + from the true 0.2--0.8$\,$Hz band, holding its 0.6$\,$Hz width fixed. Error + is flat within $\sim\!\pm0.3\,$Hz of the true center, then rises sharply + once the assumed band drifts into the shallow layer's territory.} + \label{fig:band-sensitivity} +\end{figure} + +\textbf{Scale of effect:} a band-center error under \(\sim\!0.3\,\)Hz +costs essentially nothing here; past \(\sim\!0.5\,\)Hz it costs a factor +of \(\sim\!3\)--\(4\) in RMS, from \(\sim\!0.03\,\%\) to +\(\sim\!0.10\,\%\). + +\subsection{Reference}\label{sec:param_ref} The \textbf{reference} defines what survives: a moving reference re-baselines continuously and erases slow trends that a fixed reference or a joint inversion \citep{Brenguier2014} preserve -(Fig.\textasciitilde{}\ref{fig:params}c). On the volcano synthetic, a -fixed total-stack reference gives RMS \(\sim\!0.03\,\%\) and a -Brenguier-style joint inversion \(\sim\!0.04\,\%\) (both preserve the -pre-eruptive trend), while a 60-day moving reference gives RMS -\(\sim\!0.16\,\%\) --- roughly 4--5\(\times\) worse --- because it -re-baselines away the very trend being measured. +(Fig.~\ref{fig:params}c). In practice the choice is rarely just +fixed-versus-moving: an analyst also decides \emph{which} period of the +record a fixed reference is built from, and that choice alone can +dominate the error --- for instance when a deployment barely predates +the process of interest, or when the only quiet-looking period available +sits close in time to the process itself. + +We compare five named schemes on the volcano synthetic: a reference +built from the \textbf{beginning} of the pre-eruptive record (its +earliest 15\%), from the \textbf{end} of that record (its latest 15\%, +immediately before the eruption), from the \textbf{whole} pre-eruptive +record, a 60-day \textbf{moving} (trailing) reference, and \textbf{no +single reference at all} --- the Brenguier et al. (2014)-style joint +inversion, which measures relative dv/v between many short stacks +instead of referencing every day to one +(Fig.~\ref{fig:reference-schemes}a). The whole-record, beginning, and +inversion schemes all recover the truth to RMS \(\sim\!0.03\,\%\). The +end-of-record reference does far worse, RMS \(\sim\!0.15\,\%\) --- not +because it tracks the dynamics any less faithfully (its residual scatter +around the truth, \(\sim\!0.029\,\%\), matches every other fixed scheme) +but because the reference epoch itself already sits \(\sim\!0.15\,\%\) +into the developing pre-eruptive ramp, and every dv/v value is reported +\emph{relative to whatever the reference was doing}. Reference choice +sets the zero point, not just the noise floor: comparing dv/v across +studies, or across deployments that started at different times, requires +knowing what the reference period itself was doing, not just how well +each pipeline scores against a single truth. + +The 60-day moving reference gives RMS \(\sim\!0.16\,\%\) --- comparable +to the worst fixed case, but for the opposite reason: it re-baselines +away the trend continuously rather than sitting at one biased epoch. +Lengthening the trailing window helps only slowly and never converges to +the fixed-reference baseline: RMS falls from \(\sim\!0.168\,\%\) at a +10-day trailing window to \(\sim\!0.151\,\%\) at 240 days, still +\(\sim\!4\)--\(5\times\) the whole-record RMS +(Fig.~\ref{fig:reference-schemes}b) --- the erasure is structural, not a +noise effect that more averaging fixes. + +Read carefully, though, that erasure is a property of the +\emph{uncumulated +increment}, not of a non-fixed reference as such --- and the published +alternatives to a fixed reference do not take the form the sweep +assumes. They fall into two families, neither of which re-baselines +every epoch and reports the raw increment. + +The first cumulates. \citet{James2017} re-baseline each day against the +immediately preceding day-stack and sum the daily \(\delta t/t\) from a +fixed start date, recovering a seasonal freeze--thaw trend in Alaskan +permafrost that a stationary reference could not detect at all: the +frozen-to-thawed velocity contrast made the stationary comparison +cycle-skip, while adjacent days stayed coherent. \citet{Rivet2011} +likewise reference each epoch to the previous one. The cost is that +summation integrates the measurement error --- \citet{James2017} report +a positive drift in the cumulated series that their quadrature error +budget could not account for, and correct it linearly against a +stationary-reference anchor. The same rolling construction appears in +laboratory coda monitoring of rock deforming to failure, where the +scattering properties change too much for a fixed reference to stay +valid \citep{ZotzWilson2019}. + +The second holds the reference fixed within a segment and stitches the +segments together. \citet{Rivet2014} define a separate reference stack +for each of three multi-year periods at Piton de la Fournaise, then +merge the three series by measuring the relative velocity change +\emph{between} the adjacent segment references, using station pairs that +occupied the same sites across the network change. +\citet{SensSchonfelder2014} develop the multiple-reference form of the +same idea at the same volcano, and \citet{Ermert2023} adopt a +multiple-reference approach for urban single-station autocorrelations in +Mexico City, where long-term waveform coherence is simply unavailable, +stabilising the stacks by clustering correlation windows with a Gaussian +mixture model so that day-time and night-time noise regimes stack +separately. + +That second family is worth naming precisely, because it is not a +separate method from the joint inversion --- it is a restriction of it. +Stitching two segments by measuring the relative dv/v between their +references is exactly the adjacent-pair case of the over-determined +system the inversion solves over all pairs of block stacks. The +reference axis is therefore better read as a single continuum, from one +global reference, through segment references joined pairwise, to the +fully coupled inversion, than as a menu of unrelated choices. + +Against that, the uncumulated day-by-day trailing reference swept above +is a limit case rather than a practice: we found no surveyed study that +re-baselines continuously and reports the increments without summing +them. It is retained here because it isolates what re-baselining costs +when the trend is not reconstructed, which is the failure mode the two +families above exist to avoid. codameter implements the joint inversion +but neither the cumulated trailing reference nor cluster-based reference +selection. + +\begin{figure} + \centering + \includegraphics[width=\textwidth]{demo_17_reference_schemes.png} + \caption{Reference construction on the volcano synthetic. (a) Five named + schemes, each scored by RMS against the known truth over the whole record + and over the pre-eruptive ramp alone. (b) RMS for the moving reference as a + function of its trailing length; the dashed line is the whole-record fixed + reference's RMS, which the moving reference never reaches.} + \label{fig:reference-schemes} +\end{figure} + +\textbf{Scale of effect:} which \emph{period} a fixed reference is drawn +from can cost as much as switching to a moving reference altogether +(\(\sim\!0.15\)--\(0.16\,\%\) RMS either way); a reference from the +quietest available period, of any length, recovers the trend to +\(\sim\!0.03\,\%\). + +\subsection{Substacking}\label{sec:param_substack} The \textbf{stacking length} trades noise against temporal resolution, -rounding off and delaying a coseismic step -(Fig.\textasciitilde{}\ref{fig:params}d). On the earthquake synthetic, a -1-day stack (noisy) gives RMS \(\sim\!0.044\,\%\), a 10-day stack -\(\sim\!0.018\,\%\) (the best of the three), and an over-long 45-day -stack \(\sim\!0.031\,\%\) --- worse than the 10-day stack despite -averaging down more noise, because it smears the step itself. +rounding off and delaying a coseismic step (Fig.~\ref{fig:params}d). In +practice the decision is rarely ``how many days'' in the abstract; it is +``how long until the coda is coherent enough to trust'' --- stacking +only as long as needed to clear a working correlation-coefficient (CC) +threshold, then stopping. codameter's own quality-control gate uses +CC\textasciitilde{}\(>0.6\) (Section~\ref{sec:results}), and how quickly +a station clears that bar depends entirely on its data quality. + +Substack duration therefore defines a fundamental +precision--temporal-resolution tradeoff. Longer stacks suppress +incoherent noise fluctuations and accelerate the convergence of noise +correlation functions, whereas shorter substacks preserve transient +changes that would otherwise be averaged within the stacking window. The +reduced signal-to-noise ratio of shorter correlations can be partially +compensated through adaptive filtering, SVD-based or learned denoising, +or through redundancy across dense seismic arrays, enabling +\dvv~measurements at daily, hourly, and even sub-hourly resolution +\citep[\citet{Moreau2017},\citet{Mao2019},\citet{Viens2020}]{Hadziioannou2011}. + +In this paper, the choice of substack length is guided by data-dependent +quality gates (the CC threshold above) rather than a fixed duration, +which allows stations with high coherence to preserve shorter temporal +windows and thereby track rapid changes, while stations with lower SNR +substack as needed to achieve stable estimates. + +On the earthquake synthetic, a workable deployment (SNR 4, the same +setting used throughout this section) clears CC\textasciitilde{}\(>0.6\) +already at a 1-day stack (median CC 0.86); a poor, coherence-limited +deployment (SNR 0.5) needs 14 days of substacking to clear the same bar +(Fig.~\ref{fig:stack-coherence}a). The two regimes behave differently +past that point, too. For the workable deployment, RMS is U-shaped: it +falls from \(\sim\!0.044\,\%\) at 1 day to a minimum \(\sim\!0.020\,\%\) +around 7--10 days, then rises again to \(\sim\!0.038\,\%\) by 60 days as +the stack smears the step (Fig.~\ref{fig:stack-coherence}b) --- the +classic noise-versus-smearing tradeoff, and the reason ``longer is +always better'' is wrong even once the coherence gate is satisfied. For +the poor deployment, RMS is still falling at 60 days +(\(\sim\!0.067\,\%\), down from \(\sim\!0.71\,\%\) at 1 day): the noise +floor dominates over the whole tested range, and the smearing penalty +never gets the chance to show up. The signed error in the recovered step +amplitude is negative (an under-estimate) at every stack length for the +poor deployment, and for the workable deployment up to about 45 days, +past which it crosses zero and the step is over-estimated. A recovered +step is therefore a lower bound on the true drop only in the +noise-limited regime; the sign of the error depends on the deployment +and the stack length, and both should be reported. + +\begin{figure} + \centering + \includegraphics[width=\textwidth]{demo_18_stack_coherence.png} + \caption{Substacking on the earthquake synthetic, at two deployment + qualities. (a) Median stretching correlation coefficient versus stack + length; the dashed line is codameter's own CC-gate threshold + (Section~\ref{sec:results}). (b) RMS error and the absolute bias in the + recovered coseismic-step amplitude, both against the known truth, log + scale.} + \label{fig:stack-coherence} +\end{figure} + +\textbf{Scale of effect:} for a workable deployment, the noise/smearing +tradeoff bottoms out around 7--10 days at RMS \(\sim\!0.02\,\%\); for a +poor deployment, substack at least \(\sim\!2\) weeks just to clear the +coherence gate, and expect RMS an order of magnitude worse even after +clearing it. \begin{figure} \centering @@ -739,34 +1075,19 @@ \subsection{Frequency band, reference and stacking}\label{sec:params} \includegraphics[width=0.49\textwidth]{demo_6_stacking.png} \caption{Parameter choices. (a) Frequency band selects depth and signal. (b) A coda window does not transfer across bands. (c) Reference strategy: a moving - reference erases the trend a fixed reference and the joint inversion keep. (d) + reference differences the trend away unless its increments are cumulated; + a fixed reference and the joint inversion retain it. (d) Stacking length smears the coseismic step.} \label{fig:params} \end{figure} The accepted range for each of these parameters across the published literature is catalogued directly, study by study, in the survey of -Appendix\textasciitilde{}\ref{app:survey} -(Table\textasciitilde{}\ref{tab:survey}): the frequency band, coda -window, estimator, and uncertainty treatment actually reported by 103 -ambient-noise \dvv~studies. - -The \textbf{reference} choice also has a construction axis beyond -fixed-versus-moving: how much of the record a ``fixed'' reference -actually stacks. On the volcano synthetic, a reference built from the -whole pre-eruptive record gives RMS \(\sim\!0.03\,\%\), one built from -only the earliest 15,\% of that record (an ``early stack,'' noisier for -having fewer days) gives \(\sim\!0.04\,\%\) (\(\sim\!1.5\times\) worse), -a 60-day moving stack gives \(\sim\!0.16\,\%\) (erasing the trend, as -above), and the Brenguier-style joint inversion \citep{Brenguier2014} -gives \(\sim\!0.04\,\%\) while additionally preserving the trend --- so -among the reference-construction choices, whole-period and joint -inversion are comparably good, early-stacking is a modest -(\(\sim\!1.5\times\)) noise penalty, and only the moving reference -actively destroys signal. - -\subsection{Coda window and its covariation with frequency -band}\label{sec:window} +Appendix~\ref{app:survey} (Table~\ref{tab:survey}): the frequency band, +coda window, estimator, and uncertainty treatment actually reported by +103 ambient-noise \dvv~studies. + +\subsection{Coda window}\label{sec:param_window} The coda window is not independent of the frequency band --- it deserves its own treatment because the two covary strongly, and getting this @@ -776,39 +1097,38 @@ \subsection{Coda window and its covariation with frequency floor much sooner than low-frequency coda: a coda window that is well past the direct arrival for a \(\sim\!0.3\)--\(0.8\,\)Hz band is, at \(\sim\!3\)--\(6\,\)Hz, sampling almost pure noise -(Fig.\textasciitilde{}\ref{fig:params}b). On our synthetic, a fixed -20--40,s window at the high band gives RMS error \(\sim\!3.8\,\%\) (the -noise floor, not the signal), while a window hand-adapted to the band -(3--12,s) recovers the truth at \(\sim\!0.01\,\%\) --- nearly a -400\(\times\) difference from this one choice alone. This is itself an -instance of a literature-documented tension: band-matched windowing is -recommended, but Table\textasciitilde{}\ref{tab:survey} shows many -surveyed studies instead reuse one fixed window across bands. +(Fig.~\ref{fig:params}b). On our synthetic, a fixed 20--40\(\,\)s window +at the high band gives RMS error \(\sim\!3.9\,\%\) (the noise floor, not +the signal), while a window hand-adapted to the band (3--12\(\,\)s) +recovers the truth at \(\sim\!0.01\,\%\) --- nearly a 400\(\times\) +difference from this one choice alone. This is itself an instance of a +literature-documented tension: band-matched windowing is recommended, +but Table~\ref{tab:survey} shows many surveyed studies instead reuse one +fixed window across bands. Hand-adapting the window per band, as above, requires knowing the band in advance and re-tuning per deployment. A more principled alternative --- used in our group --- is to track the coda envelope directly and stop the window where it \emph{flattens} onto the noise floor, rather -than pre-specifying a window from a rule of thumb. We implement this as -\texttt{coda\_window\_from\_envelope()}: band-pass a long-term reference -stack, smooth its envelope, estimate the noise floor from a common -late-lapse window, and take the window end as the first lapse time past -a short onset where the envelope stays within a factor of that floor for -a sustained interval (not a single noisy dip). Applied blind (without -being told which band it is) to three bands spanning low, mid, and high -frequency (Fig.\textasciitilde{}\ref{fig:window-envelope}a), the -detector recovers windows of \(\sim\!(3,29)\,\)s, \(\sim\!(3,37)\,\)s, -and \(\sim\!(3,14)\,\)s respectively --- correctly shrinking at the high -band, though the low-versus-mid ordering is not perfectly monotonic on -this synthetic (an artifact of how the fixed additive noise floor -interacts with each band's filter, not a claim that the detector is -exact). Recovering \dvv~with each band's own detected window instead of -one universal fixed (10--30,s) window -(Fig.\textasciitilde{}\ref{fig:window-envelope}b) gives RMS -\(\sim\!0.032\,\%\) vs.~\(\sim\!0.036\,\%\) at the low band (a modest, -\(\sim\!1.1\times\) gain), \(\sim\!0.017\,\%\) vs.~\(\sim\!0.035\,\%\) -at the mid band (\(\sim\!2\times\)), and \(\sim\!0.019\,\%\) -vs.~\(\sim\!1.8\,\%\) at the high band (\(\sim\!93\times\)) --- the +than pre-specifying a window from a rule of thumb. We implement this by +band-passing a long-term reference stack, smoothing its envelope, +estimating the noise floor from a common late-lapse window, and taking +the window end as the first lapse time past a short onset where the +envelope stays within a factor of that floor for a sustained interval +(not a single noisy dip). Applied blind (without being told which band +it is) to three bands spanning low, mid, and high frequency +(Fig.~\ref{fig:window-envelope}a), the detector recovers windows of +\(\sim\!(3,29)\,\)s, \(\sim\!(3,37)\,\)s, and \(\sim\!(3,14)\,\)s +respectively --- correctly shrinking at the high band, though the +low-versus-mid ordering is not perfectly monotonic on this synthetic (an +artifact of how the fixed additive noise floor interacts with each +band's filter, not a claim that the detector is exact). Recovering +\dvv~with each band's own detected window instead of one universal fixed +(10--30\(\,\)s) window (Fig.~\ref{fig:window-envelope}b) gives RMS +\(\sim\!0.030\,\%\) vs.~\(\sim\!0.036\,\%\) at the low band (a modest, +\(\sim\!1.2\times\) gain), \(\sim\!0.017\,\%\) vs.~\(\sim\!0.035\,\%\) +at the mid band (\(\sim\!2\times\)), and \(\sim\!0.020\,\%\) +vs.~\(\sim\!2.0\,\%\) at the high band (\(\sim\!100\times\)) --- the fixed window is adequate at low frequency and catastrophic at high frequency, while the envelope-derived window is close to the best achievable at every band without ever being told what band it is @@ -826,32 +1146,6 @@ \subsection{Coda window and its covariation with frequency \label{fig:window-envelope} \end{figure} -\subsection{\texorpdfstring{Choices that create spurious -\texorpdfstring{\dvv}{dv/v}}{Choices that create spurious }}\label{sec:artifacts} - -Some choices may create spurious signal. A station clock error delays -the whole correlation by a lapse-independent shift, producing an -apparent \dvv~that appears with opposite sign on the causal and acausal -branches; measuring the two branches separately is the diagnostic -(Fig.\textasciitilde{}\ref{fig:artifacts}a). Seasonally varying noise -sources warp the low-SNR late coda, so a late measurement window reports -a coherent spurious \emph{seasonal} \dvv~many times the real signal -while an earlier window stays clean \citep[the waveform-level version -of][]{Zhan2013} (Fig.\textasciitilde{}\ref{fig:artifacts}b). - -Biases from spurious arrivals could be quantified but mostly we should -decontaminate our workflow from these artefacts or not interpret the -results. - -\begin{figure} - \centering - \includegraphics[width=\textwidth]{demo_8_artifacts.png} - \caption{Deviations that create spurious \dvv. (a) A clock drift splits the causal - and acausal branches with opposite sign. (b) Seasonal late-coda noise injects a - spurious seasonal \dvv\ into a late window but not an early one.} - \label{fig:artifacts} -\end{figure} - \subsection{Causal and acausal branches}\label{sec:branches} In a symmetric cross-correlation, both sides of the coda (positive or @@ -862,31 +1156,31 @@ \subsection{Causal and acausal branches}\label{sec:branches} \citep{Snieder2002}, the stability of the wavefield excited in the coda is the main requirement for stable \dvv~measurements \citep{Hadziioannou2009}. Given the challenge in interpreting both sides -independently, researchers typically would measure \dvv~on each lag and -then report its average \citep{Kidiwela2026}. The causal (positive-lag) -and acausal (negative-lag) branches sample opposite-direction paths with +independently, researchers typically measure \dvv~on each lag and then +report its average \citep{Kidiwela2026}. The causal (positive-lag) and +acausal (negative-lag) branches sample opposite-direction paths with different source-side illumination, and in a 3D medium their sensitivity kernels sample partly different volumes, so the two can report genuinely different \dvv~without either being wrong. Two regimes bound the choice -(Fig.\textasciitilde{}\ref{fig:branches}). When a change is -\emph{localized} to the volume one branch samples, symmetrizing or -averaging the branches --- the common default --- dilutes it toward -zero, while the branch that carries the change recovers it -(Fig.\textasciitilde{}\ref{fig:branches}a); here preferring the branch -of greatest change is an researchers' judgement. When instead both -branches share the \emph{same} change, their difference is measurement -noise, and selecting the branch of greatest change over-reports it --- a -max-of-two-estimators selection bias that grows as SNR falls -(Fig.\textasciitilde{}\ref{fig:branches}b). When both side exhibit the -same change (sign, coherence) but with different magnitude, it is -reasonable to use the \dvv~of greatest change given the already low -sensitivity in coda waves \citep{Obermann2013}. An acceptable workflow -is to measure both branches, evaluate on that consistency, select by the -coherence of the change rather than its amplitude (a criterion -independent of the answer, so it carries no selection bias), and carry -the between-branch difference as an explicit term of the measurement -covariance \(C_d\) (Section\textasciitilde{}\ref{sec:bayes}) rather than -discarding it by averaging. +(Fig.~\ref{fig:branches}). When a change is \emph{localized} to the +volume one branch samples, symmetrizing or averaging the branches --- +the common default --- dilutes it toward zero, while the branch that +carries the change recovers it (Fig.~\ref{fig:branches}a); here +preferring the branch of greatest change is a researcher's judgement. +When instead both branches share the \emph{same} change, their +difference is measurement noise, and selecting the branch of greatest +change over-reports it --- a max-of-two-estimators selection bias that +grows as SNR falls (Fig.~\ref{fig:branches}b). Choosing the branch of +greatest change after seeing the data is therefore a selection rule that +Fig.~\ref{fig:branches}b shows to be biased, and the coherence of each +branch is estimated from the same observations, so selecting on +coherence reduces but does not remove that bias. The rule we adopt is +fixed before the data are seen: measure both branches and report both; +combine them by their mean unless independent physical information +(source-side illumination, a change known to be confined to one side) +designates a branch beforehand; and carry the between-branch difference +as an explicit term of the measurement covariance \(C_d\) +(Section~\ref{sec:bayes}) rather than discarding it by averaging. \begin{figure} \centering @@ -900,32 +1194,58 @@ \subsection{Causal and acausal branches}\label{sec:branches} \label{fig:branches} \end{figure} +\subsection{\texorpdfstring{Choices that create spurious +\texorpdfstring{\dvv}{dv/v}}{Choices that create spurious }}\label{sec:artifacts} + +Some choices may create spurious signal. A station clock error delays +the whole correlation by a lapse-independent shift, producing an +apparent \dvv~that appears with opposite sign on the causal and acausal +branches; measuring the two branches separately is the diagnostic +(Fig.~\ref{fig:artifacts}a). Seasonally varying noise sources warp the +low-SNR late coda, so a late measurement window reports a coherent +spurious \emph{seasonal} \dvv~many times the real signal while an +earlier window stays clean \citep[the waveform-level version +of][]{Zhan2013} (Fig.~\ref{fig:artifacts}b). + +Biases from spurious arrivals could be quantified but mostly we should +decontaminate our workflow from these artefacts or not interpret the +results. + +\begin{figure} + \centering + \includegraphics[width=\textwidth]{demo_8_artifacts.png} + \caption{Deviations that create spurious \dvv. (a) A clock drift splits the causal + and acausal branches with opposite sign. (b) Seasonal late-coda noise injects a + spurious seasonal \dvv\ into a late window but not an early one.} + \label{fig:artifacts} +\end{figure} + Taken together, the choices compound. We make this concrete in -Section\textasciitilde{}\ref{sec:multiverse} by running the full -\emph{multiverse} of best-practice and deviation choices on one -synthetic dataset and ranking each by the bias and the error-bar change -it induces. +Section~\ref{sec:multiverse} by running the full \emph{multiverse} of +best-practice and deviation choices on one synthetic dataset and ranking +each by the bias and the error-bar change it induces. -\section{The multiverse of processing choices}\label{sec:multiverse} +\section{The combined impact of processing +choices}\label{sec:multiverse} The scenario is a single representative station pair monitoring a shallow volcanic edifice, in the style of the permanent broadband deployments used at effusive/dome volcanoes such as Piton de la Fournaise \citep{Brenguier2008}: a coda band matched to shallow depths -(0.4--1.0,Hz), a coda window past the direct arrival (10--30,s), and -daily correlations sampled every 3 days over 2.5 years at a per-day -correlation-coefficient SNR of 7, typical of a continuously operating -station. The synthetic ground truth combines an annual seasonal -\dvv~cycle (as from near-surface thermoelastic/hydrologic effects), a -slow pre-eruptive inflation ramp, and a sharp co-eruptive velocity drop -with partial recovery. This single-pair scenario isolates the -measurement-step choices from the network-aggregation choices already -covered in -Sections\textasciitilde{}\ref{sec:aggregation}--\ref{sec:uncertainty}. +(0.4--1.0\(\,\)Hz), a coda window past the direct arrival +(10--30\(\,\)s), and daily correlations sampled every 3 days over 2.5 +years at a per-day correlation-coefficient SNR of 7, typical of a +continuously operating station. The synthetic ground truth combines an +annual seasonal \dvv~cycle (as from near-surface +thermoelastic/hydrologic effects), a slow pre-eruptive inflation ramp, +and a sharp co-eruptive velocity drop with partial recovery. This +single-pair scenario isolates the measurement-step choices from the +network-aggregation choices already covered in +Sections~\ref{sec:aggregation}--\ref{sec:uncertainty}. The previous sections only identified single choices, but the overall research workflow involves them all. We now estimate the combined -effects of these parametic choices. Starting from a single +effects of these parametric choices. Starting from a single \textbf{best-practice baseline} (trace stretching, a band matched to the target depth, a coda window well past the direct arrival, a 10-day stack, a long stable reference, coherence gating; the cross-cutting @@ -933,22 +1253,26 @@ \section{The multiverse of processing choices}\label{sec:multiverse} \citetext{\citeyear{Brenguier2014}; \citealp{Weaver2011}; \citealp{Clarke2011}} as distilled in our survey), we change one parameter at a time to a deviation from best practice documented in the literature and measure -the resulting error against the known truth -(Fig.\textasciitilde{}\ref{fig:deviations}). The ranking is unambiguous: -relative to a best-practice RMS error of \(\sim\!0.02\,\%\), an -unwrapped phase estimator that cycle-skips is catastrophic, a moving -reference and a wrapped-phase MWCS each inflate the error roughly an -order of magnitude, an over-long stack and a late low-SNR window distort -the co-eruptive drop, while the frequency band (which mostly sets -precision here) and the gating are second-order. The joint inversion is -nearly as good as the fixed reference and preserves the trend. +the resulting error against the known truth (Fig.~\ref{fig:deviations}). +The ranking is unambiguous: relative to a best-practice RMS error of +\(\sim\!0.03\,\%\), the two-dimensionally-unwrapped WCS estimator is +catastrophic here (\(\sim\!50\times\) worse), a wrapped-phase MWCS +inflates the error by roughly an order of magnitude +(\(\sim\!12\times\)), and DTW by \(\sim\!6\times\); among the +non-estimator choices the uncumulated trailing reference is worst +(\(\sim\!5\times\), and most distorts the recovered drop; it is an +ablation of re-baselining without trend reconstruction, not a surveyed +workflow, Section~\ref{sec:param_ref}), while stack length, coda window, +and frequency band deviations are each more modest +(\(1.5\)--\(2.5\times\)). The joint-inversion reference stays closest to +the fixed-reference baseline among the reference-scheme deviations. \begin{figure} \centering \includegraphics[width=\textwidth]{demo_10_deviations.png} - \caption{One-at-a-time deviations from a best-practice baseline, ranked by the - bias they inject (a, log scale) and by how they distort the recovered - co-eruptive drop (b, symlog). Bars are coloured red when the error exceeds + \caption{One-at-a-time deviations from a best-practice baseline, ranked by + their RMS error against the truth (a, log scale; RMS mixes bias and + scatter) and by how they distort the recovered co-eruptive drop (b, symlog). Bars are coloured red when the error exceeds three times the baseline. The estimator and reference choices dominate; the band and gating are minor for this scenario.} \label{fig:deviations} @@ -959,43 +1283,46 @@ \section{The multiverse of processing choices}\label{sec:multiverse} windows, three stacking lengths and two reference schemes on a synthetic ``volcano'' dv/v time series that includes a seasonal oscillation, a slow pre-eruptive inflation ramp, and a sharp co-eruptive drop with -partial exponential recovery -(Fig.\textasciitilde{}\ref{fig:multiverse}a). The per-day standard -deviation across the 108 pipelines varies by a factor of \(\sim\!4\)--5 -over the time series (from \(\sim\!0.4\,\%\) to \(\sim\!1.7\,\%\)), and -is widest exactly at the sharp co-eruptive drop; the RMS error against -the known truth spans over two orders of magnitude across pipelines -(\(\sim\!0.02\)--\(2.8\,\%\)). +partial exponential recovery (Fig.~\ref{fig:multiverse}a). The per-day +standard deviation across the 108 pipelines varies by a factor of +\(\sim\!4\)--5 over the time series (from \(\sim\!0.4\,\%\) to +\(\sim\!1.7\,\%\)), and is widest exactly at the sharp co-eruptive drop; +the RMS error against the known truth spans over two orders of magnitude +across pipelines (\(\sim\!0.02\)--\(2.8\,\%\)). Attributing the variance of the outcome to each axis with a first-order -(main-effect) sensitivity index -(Fig.\textasciitilde{}\ref{fig:multiverse}b) shows that, for this -dataset, the \textbf{coda window and the stack length} control the RMS -error most, the \textbf{stack length} dominates the recovered drop -amplitude, and the estimator is third; the first-order indices sum to -well under one, so a large part of the spread is \emph{interaction} -between choices compounding. The appropriate object is therefore not a -single curve but a distribution of \dvv~over the processing choices. +(main-effect) sensitivity index (Fig.~\ref{fig:multiverse}b) shows that, +for this dataset, the \textbf{coda window} controls the RMS error most, +with the estimator second and the stack length third; for the recovered +drop amplitude the order changes to \textbf{stack length} first, window +second, and estimator third. The first-order indices sum to well under +one in both cases (\(\sim\!0.66\) for RMS, \(\sim\!0.63\) for the drop), +so a large part of the spread is \emph{interaction} between choices +compounding. The appropriate object is therefore not a single curve but +a distribution of \dvv~over the processing choices. \begin{figure} \centering \includegraphics[width=\textwidth]{demo_11_multiverse.png} \caption{The full multiverse. (a) 108 reasonable pipelines on one dataset, - each coloured by its RMS error against the truth on a colourblind-safe scale - (bright accurate, dark biased; the worst run off the clipped axis); the grey band - is the 10--90\% inter-pipeline spread, widest at the velocity drop. (b) First-order variance attribution: which - choice controls the RMS error and the recovered drop. Window and stack length - dominate; the sub-unity sum signals strong interactions.} + each coloured by its RMS error against the truth (a fraction of velocity) on + a colourblind-safe scale (bright accurate, dark biased); the axis is clipped + at $\pm0.8\,\%$ and the number of pipelines that leave it is printed on the + panel; the grey band is the 10--90\% inter-pipeline spread, widest at the + velocity drop. (b) First-order variance attribution: which + choice controls the RMS error and the recovered drop. Window, estimator, and + stack length dominate, in that order for RMS and reordered for the drop; + the sub-unity sum signals strong interactions.} \label{fig:multiverse} \end{figure} -Table\textasciitilde{}\ref{tab:bp-measure} summarizes this into the -measurement-step best practice and the documented deviation for each -choice, with the consequence the synthetic makes concrete. The baseline -and deviation sets are the ones our survey extracts from the literature -(the cross-cutting rules of \citeauthor{Snieder2002} -\citetext{\citeyear{Snieder2002}; \citealp{Clarke2011}; \citealp{Weaver2011}; \citealp{Brenguier2014}; \citealp{Wang2017}; \citealp{Obermann2019}}). -are implemented in \texttt{codameter.deviations}. +Table~\ref{tab:bp-measure} summarizes this into the measurement-step +best practice and the documented deviation for each choice, with the +consequence the synthetic makes concrete. The baseline and deviation +sets are the ones our survey extracts from the literature (the +cross-cutting rules of \citeauthor{Snieder2002} +\citetext{\citeyear{Snieder2002}; \citealp{Clarke2011}; \citealp{Weaver2011}; \citealp{Brenguier2014}; \citealp{Wang2017}; \citealp{Obermann2019}}) +and are implemented in codameter. \begin{table} \footnotesize @@ -1008,8 +1335,7 @@ \section{The multiverse of processing choices}\label{sec:multiverse} \textbf{Choice} & \textbf{Best practice} & \textbf{Common deviation} & \textbf{Consequence} \\ \midrule -Estimator & Stretching family (TS/WTS/WCC), robust at low SNR and large \dvv\ -\citep{Mikesell2015,Yuan2021} & Wrapped-phase MWCS \citep{Clarke2011} without 2-D +Estimator & Stretching family (TS/WTS/WCC), robust at low SNR and large \dvv\ \citep{Mikesell2015,Yuan2021} & Wrapped-phase MWCS \citep{Clarke2011} without 2-D unwrapping \citep{Mao2020} & Cycle-skips at large \dvv; error inflated $\sim\!10\times$ or catastrophic \\ \hline Frequency band & Matched to the target depth: $\sim\!0.1$--2\,Hz (volcano, crust), @@ -1023,7 +1349,9 @@ \section{The multiverse of processing choices}\label{sec:multiverse} stable reference span \citep{Wang2017} & Over-long stack ($\sim\!45$\,d) & Smears and delays a step; distorts the recovered drop \\ \hline Reference & Long fixed stack or all-to-all joint inversion -\citep{Brenguier2014,Wang2017} & Moving / trailing reference & Erases slow trends \\ \hline +\citep{Brenguier2014,Wang2017} & Uncumulated trailing reference (an ablation: +published moving-reference workflows cumulate or stitch, +Section~\ref{sec:param_ref}) & Erases slow trends \\ \hline Coherence gating & Discard low-coherence epochs (CC / SNR threshold) \citep{Clarke2011} & No gating & Keeps corrupted epochs; changes the effective $N$ \\ \hline Uncertainty definition & State it explicitly: within-measurement @@ -1053,106 +1381,169 @@ \section{A Bayesian measurement model and its data If the processing choice controls the answer, the principled response is not to select a single pipeline but to treat the choice as a -\textbf{nuisance parameter} with a prior and marginalise it out. We -propose this as the new best practice for the \dvv~\emph{measurement}, -and implement it as a Bayesian hierarchical inversion. For configuration -\(k\) drawn from a prior over reasonable pipelines we obtain a measured -series \(m_k(t)\) with a coherence-limited within-method floor -\(\sigma_k(t)\) \citep{Weaver2011, Clarke2011}, and posit -\begin{equation} +\textbf{nuisance parameter} with a prior and assess its influence. We +explore a Bayesian hierarchical model for the \dvv~\emph{measurement}, +conditional on a specified pipeline menu. For configuration \(k\) drawn +from a prior over reasonable pipelines we obtain a measured series +\(m_k(t)\) with a coherence-limited within-method floor \(\sigma_k(t)\) +\citep{Weaver2011, Clarke2011}, and posit \begin{equation} m_k(t) = \mu(t) + \beta_k + \varepsilon_k(t), \qquad \beta_k\sim\mathcal N(0,\tau^2),\quad \varepsilon_k(t)\sim\mathcal N\!\big(0,\,s^2\sigma_k(t)^2\big), \label{eq:bayes} -\end{equation} with a second-difference random-walk smoothness prior on -the latent true series \(\mu(t)\). Here \(\beta_k\) is configuration -\(k\)'s methodological bias (the systematic offset between, say, MWCS -and stretching), \(\tau\) its scale across the ensemble, and \(s\) -rescales the Weaver floor so the data report whether it is calibrated. A -conjugate Gibbs sampler returns the joint posterior; the implementation -is \texttt{codameter.uq\_bayes} (pure NumPy, no external sampler). - -The model yields two distinct objects, and conflating them is the error -the field makes (Fig.\textasciitilde{}\ref{fig:bayes}). The posterior of -\(\mu\) is the precision of the \emph{combined} estimate: it is tight -and shrinks with ensemble size --- yet it \emph{under-covers the truth}, -because the configurations share a common-mode bias that averaging -cannot remove. The object a downstream depth or stress inversion must -consume is the \textbf{marginal measurement covariance} \begin{equation} -C_d(t,t') = \underbrace{D R D}_{\text{within}\,\oplus\,\text{methodological},\ \text{temporally correlated}} +\end{equation} The likelihood treats residuals as conditionally +independent across configurations and epochs. Shared input waveforms do +not ensure this assumption. Fitting all member outputs jointly is not +the same operation as marginalising a discrete mixture of alternative +pipelines. The posterior is therefore conditional on this working +likelihood. We use a second-difference smoothness prior of precision +\(\lambda\) on the latent true series \(\mu(t)\), built on the physical +time grid so that a gap in the record is a gap in the prior. Here +\(\beta_k\) is configuration \(k\)'s constant offset (the systematic +offset between, say, MWCS and stretching), \(\tau\) its scale across the +ensemble, and \(s\) rescales the coherence floor of eq.~\ref{eq:weaver} +so that the data report whether that floor is calibrated. Every +configuration is run through the same pipeline code as the rest of the +paper, so the estimator, band, window, stack length in days, reference +scheme and coherence gate all take effect; an epoch a configuration does +not produce (reference warm-up, a gated coherence) is simply missing and +carries no information. The hyper-priors on \(\tau^2\), \(s^2\) and +\(\lambda\) are conjugate inverse-gamma and gamma distributions whose +scales are small against the data terms. Codameter reports the prior +scale term divided by the conditional posterior rate, evaluated at +posterior means. The ratio is about 0.09 for \(\tau^2\) in the clean +scenario and below 0.01 for \(s^2\) and \(\lambda\) +(Table~\ref{tab:calibration}). This diagnostic does not measure the +total influence of the prior or establish sampler convergence. A +conjugate Gibbs sampler, implemented in codameter with no external +sampler dependency and with a banded solve for the smoothness update, +returns the joint posterior. + +The model yields two distinct objects, and conflating them is a common +error (Fig.~\ref{fig:bayes}; Table~\ref{tab:estimands}). The posterior +of \(\mu\) is the precision of the \emph{combined} estimate: it is tight +and shrinks with ensemble size under the working likelihood. Separately, +we construct a candidate \textbf{single-member error covariance} +\begin{equation} +C_d(t,t') = \underbrace{D R D}_{\text{calibrated floor}\,\oplus\,\text{excess spread},\ \text{temporally correlated}} \;+\; \underbrace{\tau^2\,\mathbf{1}\mathbf{1}^\top}_{\text{common mode}}, -\qquad D=\operatorname{diag}\!\big(\sigma_{\rm tot}(t)\big), +\qquad D=\operatorname{diag}\!\big(\sigma_{\mathrm{tot}}(t)\big), \label{eq:cd} -\end{equation} with \(\sigma_{\rm tot}^2 = s^2\sigma_k^2\)-average \(+\) -methodological variance and \(R_{ij}=e^{-|t_i-t_j|/L}\) for a -correlation length \(L\) estimated from the ensemble residuals. This -\(C_d\) is \textbf{time-dependent} --- wider at the sharp drop and at -low coherence --- and its temporal correlation plus common-mode term -collapse the effective number of independent epochs by an order of -magnitude. On our synthetic the marginal \(C_d\) covers the truth at the -nominal rate while the naive posterior band does not, making concrete -that the \emph{measurement covariance}, not the posterior of the -averaged series, is what must be propagated. +\end{equation} with +\(\sigma_{\mathrm{tot}}^2(t) = s^2\,\overline{\sigma_k^2(t)} + +\max\!\big[\operatorname{Var}_k(m_k(t)-\beta_k) - s^2\,\overline{\sigma_k^2(t)},\,0\big]\), +the calibrated floor plus whatever spread across configurations exceeds +it (so that the floor is not counted twice), and +\(R_{ij}=e^{-|t_i-t_j|/L}\) for a correlation length \(L\) estimated +from the ensemble residuals. \(C_d\) is constructed from the fitted +model, not sampled. It targets the error of one measurement drawn from +the ensemble, not of \(\mu\). The between-configuration offset scale +\(\tau\) does not identify an error shared by all configurations. +Pointwise coverage tests only the diagonal scale; it does not validate +\(R\) or the rank-one term. A downstream inversion needs the error +covariance of its actual input estimate. Neither using this \(C_d\) for +the ensemble mean nor interpreting its time axes as frequency-band axes +is justified here. + +Two properties of the fit deserve to be stated plainly. First, +\(s\approx 12\) on this synthetic: the residual scatter of the members +about the ensemble mean is an order of magnitude above the coherence +floor of eq.~\ref{eq:weaver}, which treats the reference as noise-free +and knows nothing of the estimator. The floor is a lower bound, and the +rescale is what makes it usable. Second, once \(s\) is fitted on those +residuals, the calibrated floor absorbs nearly all of the +between-configuration spread, and the excess term of eq.~\ref{eq:cd} is +non-zero only at the epochs where the configurations disagree more than +they usually do (Fig.~\ref{fig:bayes}c). The assumed temporal +correlation (\(L\approx 40\) days at a 4-day cadence) and the +common-mode term collapse the effective number of independent epochs +from 229 to a few tens. + +Whether these intervals mean what they say is a question one realisation +cannot answer, so we repeat the whole measurement on independent +realisations of the same scenario (Table~\ref{tab:calibration}; the +driver is \texttt{codameter.calibration}). Three coverages answer three +different questions. The fraction of member epochs whose error against +the truth lies within \(1.96\,\sigma_{C_d}\) is 0.956 on 200 +realisations, within the margin of \(\pm 0.03\) fixed before the run. +This supports the 95,\% pointwise interval on this scenario, not +calibration of the entire covariance. At the 68,\% level it covers 0.81 +and fails the same margin. One Gaussian scale therefore does not +calibrate both interval levels. The 95,\% credible band on \(\mu\) +contains the truth at only 0.59 of the epochs: the ensemble mean +inherits the biases its members share (the stacking that rounds the +drop, the estimator biases at low coherence), and no amount of averaging +over configurations removes them, which is what the posterior's +precision cannot know. Comparing \(\mu\) with \(\pm 2\sigma_{C_d}\) +mixes the ensemble mean with a single-member scale and yields nearly +complete coverage here; it does not validate the uncertainty of the +combined estimate. The other two scenarios of +Table~\ref{tab:calibration} inject artefacts that every configuration +sees identically. A station clock drift leaves every statistic +unchanged, because a lapse-independent shift appears with opposite signs +on the causal and acausal branches (Section~\ref{sec:artifacts}) and +every configuration in this ensemble measures both branches together, so +the drift cancels in the estimate; that is a property of the two-branch +measurement, not evidence that the ensemble could have detected it. A +seasonal source effect confined to the late coda, the waveform-level +artefact of \citet{Zhan2013} (Section~\ref{sec:artifacts}), is the +genuine shared error: it warps the coda every configuration measures, +and on that scenario the credible band covers the truth at only 0.34 of +the epochs and the RMSE of \(\mu\) more than doubles, from 0.067 to +0.161,\%, while the member-level coverage of \(C_d\) stays at 0.95. That +last number is right for a reason that gives no comfort: the artefact +also inflates the scatter that \(s\) absorbs, so \(C_d\) widens, but its +coherent part biases every member and the ensemble mean together and +leaves no trace in their spread. That is the limit of the method, not a +defect of the fit: an ensemble over processing choices can only reveal +the errors on which its members disagree, and an error shared by every +pipeline (a source change, a contaminated reference, a clock drift +measured on one branch) needs an independent diagnostic, such as the +branch asymmetry of Section~\ref{sec:artifacts}. \begin{figure} \centering \includegraphics[width=\textwidth]{demo_12_bayes.png} - \caption{The Bayesian measurement model. (a) The processing ensemble (grey) + \caption{The Bayesian measurement model on one realisation of the volcano + scenario (12 configurations: three estimators, two bands, two windows, 10-day + stacks, fixed reference, 4-day cadence). (a) The processing ensemble (grey) is marginalised into a posterior mean (purple) with a narrow credible band - (the estimator precision) and a much wider $\pm2\sigma$ band from the marginal - $C_d$ (the honest data error), which covers the truth where the credible band - does not. (b) The resulting time-dependent data covariance $C_d$. (c) Its - diagonal $\sigma_d(t)$ decomposed into within-method and methodological parts, - rising at the eruption; the posterior-of-the-mean (dotted) is far tighter, and - $N_{\rm eff}$ is a fraction of the epoch count.} + (the estimator precision) and a wider $\pm2\sigma$ band from $C_d$, the + single-measurement error, which encloses the individual members + (Table~\ref{tab:calibration} gives the coverages over repeated realisations). + (b) The time-dependent covariance $C_d$, in squared fractional \dvv. + (c) Its diagonal $\sigma_d(t)$, in percent, split into the calibrated + coherence floor ($s\,\overline{\sigma_k}$, which with $s\approx12$ carries + almost all of the spread) and the excess between-configuration spread, which + is non-zero only where the configurations disagree more than usual; the + posterior-of-the-mean (dotted) is far tighter, and $N_{\mathrm{eff}}$ is a + small fraction of the epoch count.} \label{fig:bayes} \end{figure} -\section{Toward deployment: a real-data retrospective -pipeline}\label{sec:deployment} +\input{calibration_table.tex} -Every result so far is on a truth-known synthetic, by design -(Section\textasciitilde{}\ref{sec:methods}): it is the only way to -separate a processing artefact from a real signal. The next step is to -test whether the same measurement machinery holds up against real data -at deployment scale, not just against a synthetic that was built to -resemble it. We are building a companion pipeline, -\texttt{noisepy-dvv-cloud}, that correlates real continuous waveforms -for station CI.LJR (Lake Hughes, California) --- the reference station -of \citet{Clements2023} --- pulled from the public Southern California -Earthquake Data Center S3 archive, using the NoisePy package -\citep{Jiang2020} for the correlation step. Correlation and dv/v -estimation each run as an AWS Batch job on Fargate Spot compute, -following the same deployment pattern as QuakeScope; dv/v estimation -itself is handed to \texttt{codameter.deviations.run\_pipeline} and -\texttt{codameter.uq\_measurement}, with baseline processing -configurations drawn from \texttt{codameter.use\_cases.recommend} --- -the same functions this paper's synthetic results are built on, not a -separate reimplementation. The retrospective run is validated against -the already-published \citet{Clements2023} CI.LJR result before any new -claim is drawn from it. - -\section{Depth: propagating the measurement covariance through -sensitivity kernels}\label{sec:depth} +\section{\texorpdfstring{Propagating \dvv~errors at depth +\(\Delta\beta/\beta(z)\)}{Propagating ~errors at depth \textbackslash Delta\textbackslash beta/\textbackslash beta(z)}}\label{sec:depth} The remaining sections present a framework rather than new synthetics: -they set out how the covariance of -Section\textasciitilde{}\ref{sec:bayes} propagates down the inference -chain, and ground each step in what the monitoring literature does and -does not yet report. The executable stages are in development in the -open codameter package (Section\textasciitilde{}\ref{sec:discussion}). +they set out how the covariance of Section~\ref{sec:bayes} propagates +down the inference chain, and ground each step in what the monitoring +literature does and does not yet report. The executable stages are in +development in the open codameter package +(Section~\ref{sec:discussion}). The field has converged on one physical rule for depth --- \emph{depth is set by the frequency band and the coda lapse time, it is not assumed} \citep{Obermann2013, Obermann2016} --- and, increasingly, on multi-band measurement as the means to resolve it -\citep{Takano2017, Feng2020, Mao2022}. The step from a set of per-band -\dvv~series to a depth profile is where reporting is least consistent: -many studies read a single band as a single depth, only a few invert -several bands against surface-wave sensitivity kernels, and the -propagation of the measurement error into the depth estimate is seldom -shown. The depth assignment is frequently the scientific claim itself ---- whether the change lies in the aquifer or the overlying soil, +\citep{Takano2017, Feng2020, Mao2022, Mao2025}. The step from a set of +per-band \dvv~series to a depth profile is where reporting is least +consistent: many studies read a single band as a single depth, only a +few invert several bands against surface-wave sensitivity kernels, and +the propagation of the measurement error into the depth estimate is +seldom shown. The depth assignment is frequently the scientific claim +itself --- whether the change lies in the aquifer or the overlying soil, 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. @@ -1162,19 +1553,21 @@ \section{Depth: propagating the measurement covariance through \Big(\tfrac{\delta v}{v}\Big)_b = \int_0^\infty K_b(z)\,\frac{\delta V_S}{V_S}(z)\,\mathrm{d}z \;+\; \varepsilon_b, \label{eq:kernel} \end{equation} where \(K_b(z)\) is the (Rayleigh-wave) depth-sensitivity -kernel for band \(b\) and \(\varepsilon_b\) carries that band's -measurement covariance from Section\textasciitilde{}\ref{sec:bayes}. -Stacking bands gives a linear system +kernel for band \(b\) and \(\varepsilon_b\) is that band's observation +error. Stacking bands gives a linear system \(\mathbf{d}=\mathbf{G}\,\mathbf{m}+\boldsymbol\varepsilon\) with -\(\mathbf{G}_{bz}=K_b(z)\) and data covariance \(C_d\); the Bayesian -solution under a smoothness prior returns a depth profile -\(\delta V_S/V_S(z)\) together with its posterior covariance \(C_m(z)\) -(implemented in \texttt{codameter.uq\_depth}). The bands must sit where -the kernels resolve: too low and the kernel leaks into the half-space, -too high and the coda is incoherent -(Section\textasciitilde{}\ref{sec:params}). The width of \(C_m(z)\) --- -not the profile alone --- is the deliverable, and it inherits the -temporal correlation and common-mode structure of \(C_d\). +\(\mathbf{G}_{bz}=K_b(z)\) and cross-band data covariance +\(C_d^{\mathrm{band}}\). This covariance must describe the band +estimates actually supplied. The temporal \(C_d\) in +Section~\ref{sec:bayes} does not supply its cross-band entries. Given +such a covariance, the Bayesian solution under a smoothness prior +returns a depth profile \(\delta V_S/V_S(z)\) together with its +posterior covariance \(C_m(z)\), implemented in codameter. The bands +must sit where the kernels resolve: too low and the kernel leaks into +the half-space, too high and the coda is incoherent +(Section~\ref{sec:params_freq}). The width of \(C_m(z)\) --- not the +profile alone --- is the deliverable, and it inherits the temporal +correlation and common-mode structure of \(C_d\). One assumption is usually left implicit: that a \dvv~change is a shear-velocity change alone. In partially saturated ground it is not. @@ -1194,8 +1587,7 @@ \section{Depth: propagating the measurement covariance through change and, downstream, the stress. The framework carries \(\delta\rho/\rho\) as a second inverted field with its own kernel and reports how much of the surface \dvv~each explains; the executable -version is a documented extension -(Section\textasciitilde{}\ref{sec:discussion}). +version is a documented extension (Section~\ref{sec:discussion}). \begin{table} \footnotesize @@ -1222,42 +1614,156 @@ \section{Depth: propagating the measurement covariance through \end{tabularx} \end{table} -\section{Stress: a downstream step, not attempted -here}\label{sec:stress} - -The quantity of interest is rarely the velocity change itself but the -stress, strain, or pore-pressure change that produces it and --- -increasingly --- the forcing responsible for it. Here the literature -remains fragmented. Volcano and fault studies often interpret the -velocity change qualitatively (a pre-eruptive pressurization, coseismic -damage); hydrological studies fit an explicit poroelastic or -thermoelastic model and separate the two by their seasonal phase lag -\citep{Tsai2011, Wang2017, Clements2018}. What is largely absent across -this literature is the \emph{uncertainty} on that final quantity and a -reasonable apportionment of it among the competing forcings. - -Converting a depth-resolved velocity-change posterior to stress or -strain is a further step this paper does not attempt: it requires -material priors --- an acoustoelastic, poroelastic, or thermoelastic -coefficient, its depth dependence, and the fracture fabric or drainage -regime that selects which stress or strain component the velocity change -actually tracks --- that are outside this paper's scope. Because those -coefficients are themselves poorly constrained, any such conversion is -dominated by \emph{epistemic} prior uncertainty rather than by the -measurement, so a stress value reported without accounting for that is -the least constrained quantity in the chain, and the one most often -reported as a result. We stop deliberately at the depth-resolved -posterior of Section\textasciitilde{}\ref{sec:depth} and its covariance: -that object, not a stress or strain estimate, is what this paper -delivers, and what any downstream stress or strain conversion must -consume. +\section{Real-data comparison and deployment}\label{sec:deployment} + +Every result so far is on a truth-known synthetic, by design +(Section~\ref{sec:methods}): it is the only way to separate a processing +artefact from a real signal. The next step is to test whether the same +measurement machinery holds up against real data, not just against a +synthetic that was built to resemble it. We are building a companion +cloud pipeline that correlates real continuous waveforms for station +CI.LJR (Lake Hughes, California) --- the reference station of +\citet{Clements2023} --- pulled from the public Southern California +Earthquake Data Center S3 archive, using the NoisePy package +\citep{Jiang2020} for the correlation step. Correlation and dv/v +estimation each run as a cloud batch job on spot compute; dv/v +estimation itself is handed to the same codameter measurement and +uncertainty functions this paper's synthetic results are built on, with +baseline processing configurations drawn from the same recommendation +logic --- not a separate reimplementation. The retrospective run is +compared with the already-published \citet{Clements2023} CI.LJR result +before any new claim is drawn from it. + +After the correction, single-station \dvv~(NoisePy correlations, a +codameter 5-member ensemble, 2--4\(\,\)Hz, 2018--2019) agrees in shape +with the published \citet{Clements2023} product. The comparison is not +trivial to get right: the CD2023 90-day-comp product is a +\emph{trailing} 90-day stack, so it lags a centered-smoothed daily +series by about 45 days, and comparing without matching that smoothing +caps the correlation near 0.7 even on a real annual cycle +(Fig.~\ref{fig:realdata-validation}). We match by applying the same +trailing 90-day mean to the daily series (at least 45 finite days in the +window), compare demeaned --- the two products reference different +epochs, and a constant offset is bookkeeping, not error --- and exclude +the first 150 days of each station's series as reference burn-in. The +comparison is computed by a script archived with the paper +(\texttt{scripts/compare\_gate1.py}) from the daily products and the +published series, with the join, smoothing and mask stated in its output +(\texttt{paper/data/gate1/comparison.json}); Table~\ref{tab:gate1} lists +the result. Under the matched rule CI.LJR reaches \(r=0.985\) on 579 +days with an amplitude slope of 1.07 (published on codameter); CI.ARV +reaches \(r=0.905\) on 357 days, the 2018 data gaps reducing the +overlap, but with a slope of 2.15, so the published product has twice +the amplitude of ours there; CI.RXH reaches \(r=0.829\) on 446 days with +a slope of 0.81 on a station whose recovered \dvv~is nearly flat. +Correlation measures the shape of the annual cycle after smoothing; it +does not validate the amplitude (the ARV slope) or the error bars, which +the published product does not carry, and the earlier draft's quoted 681 +days was the raw daily overlap, not the count under the stated mask. + +\begin{table} +\footnotesize +\caption{Comparison of codameter single-station \dvv\ (2--4\,Hz, 2018--2019) +with the published \citet{Clements2023} product, from +\texttt{scripts/compare\_gate1.py}. Matched: trailing 90-day mean, 150-day +burn-in. Centred: centred 45-day mean, no burn-in (the rule behind the +annotation on Fig.~\ref{fig:realdata-validation}). Slope is the OLS slope of +the published product on codameter; RMS is the RMS difference after removing +each series' mean over the overlap.} +\label{tab:gate1} +\begin{tabular}{@{}llrrrr@{}} +\toprule +Station & Rule & Days & $r$ & RMS diff (\%) & Slope \\ +\midrule +CI.LJR & matched & 579 & 0.985 & 0.046 & 1.07 \\ +CI.LJR & centred & 682 & 0.865 & 0.120 & 0.88 \\ +CI.ARV & matched & 357 & 0.905 & 0.150 & 2.15 \\ +CI.ARV & centred & 424 & 0.369 & 0.214 & 0.80 \\ +CI.RXH & matched & 446 & 0.829 & 0.020 & 0.81 \\ +CI.RXH & centred & 554 & 0.620 & 0.035 & 0.52 \\ +\bottomrule +\end{tabular} +\end{table} + +\begin{figure} + \centering + \includegraphics[width=\textwidth]{realdata_1_validation.png} + \caption{Single-station \dvv\ at three CI stations, 2018--2019, against the + published \citet{Clements2023} product (dashed, reference-shifted; the + panel labels name it by its 2022 data release). Daily \dvv\ (points) with the + between-configuration spread of the five-member ensemble (shaded) and the + within-measurement error bars (Table~\ref{tab:estimands}), and a centred + 45-day-smoothed curve. This figure was produced by the Gate 1 cloud run + itself and is not regenerated from this repository; its annotated $r$ values + correspond to the centred rule of Table~\ref{tab:gate1} (0.87, 0.37 and + 0.62 for LJR, ARV and RXH from the archived products), not to the matched + rule quoted in the text. The error bars drawn here predate the Weaver-floor + correction of the present revision and are too large by a factor of 3.1 at + 2--4\,Hz (the archived columns have since been rescaled by + \texttt{scripts/correct\_gate1\_within\_error.py}; the externally produced + figure has not been regenerated).} + \label{fig:realdata-validation} +\end{figure} + +Part of why agreement differs by station is visible in the correlation +function itself (Fig.~\ref{fig:realdata-interferograms}), although an +interferogram alone cannot separate a site change from an instrument or +processing change, which station metadata and processing logs would be +needed to rule out. CI.LJR shows a stable, narrow coda near zero lag +through the year. CI.RXH shows multipath, several coherent arrivals +spread across the full \(\pm 8\,\)s of lag shown, and a visible shift in +that pattern in April--May 2019, consistent with a site change rather +than a processing artefact. CI.ARV's coherent energy is compact and +concentrated near zero lag but comparatively sparse, consistent with its +higher scatter and join-method sensitivity. + +\begin{figure} + \centering + \includegraphics[width=\textwidth]{realdata_2_interferograms.png} + \caption{Daily NZ (north-vertical) cross-component correlation functions, + 2--4$\,$Hz, $\pm 8\,$s lag, 2019, each day normalised to its maximum + absolute amplitude (colour scale unlabelled on this externally produced + figure). CI.LJR's coda is stable and narrow. CI.RXH shows multipath (several + coherent bands across the full lag range) and a shift in that pattern in + April--May 2019. CI.ARV's coherent energy is compact and near zero lag but + comparatively sparse. These differences are consistent with, but do not by + themselves explain, the station-to-station agreement in + Fig.~\ref{fig:realdata-validation}.} + \label{fig:realdata-interferograms} +\end{figure} + +As an optional supplement, Fig.~\ref{fig:realdata-warmup} shows the +ensemble's warm-up behaviour on a separate 90-day smoke run at CI.LJR: +\dvv\(\,\)is undefined until enough history has accumulated for the +moving-reference member to compute a trailing reference, and each band's +per-epoch stretching correlation coefficient is reported alongside the +recovered series. + +\begin{figure} + \centering + \includegraphics[width=\textwidth]{realdata_3_warmup.png} + \caption{CI.LJR single-station \dvv, a separate 90-day smoke run (January--April + 2023), four frequency bands. The ensemble spread (shaded) and measurement + error bars are reported once at least one member is defined; the member + count annotated on each panel is the number of members defined on the last + day shown, which is below five where the moving-reference member's warm-up + had not yet elapsed. Bottom panel: per-band stretching correlation + coefficient. Produced by the cloud run, not regenerated here.} + \label{fig:realdata-warmup} +\end{figure} \section{Discussion}\label{sec:discussion} -The experiments above share one finding: for ambient-noise \dvv, the -dominant control on both the reported value and its uncertainty is -frequently the \emph{processing choice}, not the data. This is a -consequential but tractable problem. We suggest three responses. +The experiments above share one finding: on these synthetics, with one +waveform realisation held fixed, the processing choice moves both the +recovered \dvv~and its stated uncertainty by more than the measurement +noise does, by two orders of magnitude in RMS across the 108-pipeline +multiverse and by a factor \(\sqrt{N}\) in the reported network error +bar. Whether processing also dominates the variability between real +deployments is a question these experiments cannot answer, because they +hold the observed waveform fixed; the repeated-realisation calibration +of Section~\ref{sec:bayes} is the first step toward it. The problem is +consequential but tractable. We suggest the following responses. \textbf{Report the choices.} At minimum, a \dvv~study should state the estimator and its parameters, the frequency band(s) and coda window(s) @@ -1266,9 +1772,10 @@ \section{Discussion}\label{sec:discussion} weighting}, and --- critically --- the exact definition of the quoted uncertainty (within-measurement error, between-component/pair standard error, or standard deviation). Our results show that the last item alone -can change a stated \(1\sigma\) by \(\sqrt{N}\). -Table\textasciitilde{}\ref{tab:checklist} collects this into a minimal -reporting checklist, and Appendix\textasciitilde{}\ref{app:survey} shows +changes the number quoted as \(1\sigma\) by \(\sqrt{N}\), because the +two conventions estimate different quantities +(Table~\ref{tab:estimands}). Table~\ref{tab:checklist} collects this +into a minimal reporting checklist, and Appendix~\ref{app:survey} shows how unevenly these items are reported across the literature today. \begin{table} @@ -1305,56 +1812,103 @@ \section{Discussion}\label{sec:discussion} \textbf{Quantify the choice-induced uncertainty.} Where a choice is not forced by the physics, it can be sampled. Pushing a distribution of -reasonable processing choices through the measurement-error floors of -\citeauthor{Clarke2011} -\citetext{\citeyear{Clarke2011}; \citealp{Weaver2011}} yields, by the -law of total variance, a marginal \dvv~uncertainty that includes the -processing-choice spread --- a more honest error bar than any single -pipeline provides, and the natural input to a depth/stress inversion. -Section\textasciitilde{}\ref{sec:bayes} makes this a Bayesian -measurement model whose deliverable is a time-dependent data covariance -\(C_d\). - -\textbf{Make it executable.} All synthetics, estimators and figures in -this paper are released in the open codameter package, which reproduces -every result with a single command and is unit-tested. An executable -record turns an undocumented choice into a versioned, inspectable one, -and lets a reader re-run a study's pipeline on the truth-known synthetic -to see its bias before trusting it on data. +reasonable processing choices through the same correlations measures +conditional sensitivity. A probabilistic mixture would combine +conditional variances and the variance of conditional means. The joint +likelihood in Section~\ref{sec:bayes} instead defines a working Bayesian +model whose deliverable is a time-dependent single-measurement +covariance \(C_d\). Its limitations are as important as its +construction. The prior over pipelines is a menu, not a representative +sample of practice, and the covariance is conditional on it. Every +configuration transforms the same waveforms, so an error they all share +(a source change, a contaminated reference, a clock drift measured on +one branch) leaves no trace in their spread: on the shared-source +scenario of Table~\ref{tab:calibration} the ensemble agrees with itself, +the error of its mean doubles, and \(C_d\) cannot see it. Configurations +in different bands sample different depths and may not estimate the same +physical quantity, so the configuration axis should be marginalised only +over pipelines that target one estimand. And the coherence floor of +\citet{Weaver2011} is a lower bound: on our synthetic the residual +scatter about the ensemble mean is an order of magnitude above it, which +the fitted rescale \(s\) reports rather than hides. The pointwise tests +in Table~\ref{tab:calibration} support the 95,\% member intervals on the +listed scenarios. They also expose 68,\% overcoverage and poor coverage +of the combined estimate. They do not establish temporal covariance +calibration, convergence across independent chains, or valid downstream +intervals. + +\textbf{Make it executable.} All synthetics, estimators and generated +figures in this paper are released in the open codameter package; one +driver regenerates every generated figure together with a numerical +sidecar holding every plotted array and the run's provenance, and the +package is unit-tested. The three real-data figures were produced by the +cloud run and are archived, not regenerated +(Section~\ref{sec:deployment}). An executable record turns an +undocumented choice into a versioned, inspectable one, and lets a reader +re-run a study's pipeline on the truth-known synthetic to see its bias +before trusting it on data. + +\textbf{Validate against something you did not generate.} Every +synthetic test in this paper passed before the discovery below, and that +is exactly the danger: a synthetic built under the same sign convention +as the estimator reading it will always agree, whether the convention is +physically correct or not. Testing codameter's estimators against a real +cross-network deployment (Section~\ref{sec:deployment}), recovered +\dvv~anticorrelated with the published \citet{Clements2023} product and +with seasonal hydrology at three stations (\(r=-0.69,-0.45,-0.40\) under +the rule used at the time, recorded in the codameter v0.4.0 release +notes). Ground-truthing through the exact call path made the cause +obvious: imposing a \(+0.5\,\%\) velocity change returned \(-0.50\,\%\). +The synthetic generator and all seven estimators had consistently used +the stretch factor \(\varepsilon\) (positive for a coda dilation, i.e.~a +slowdown), not physical \dvv~(positive for a speedup) --- internally +coherent, so every synthetic-recovery test in the sections above passed, +but opposite to the sign convention the field expects and to the +published product it was compared against. The fix is the convention +boxed in Section~\ref{sec:intro}, shipped as codameter v0.4.0. Internal +consistency is not correctness: a pipeline that only checks itself will +confirm whatever convention it started with, and only the comparison +against an independently-produced result caught this one. The fix and +its ground-truthing procedure are documented in the codameter release +history. \textbf{Propagate the covariance, do not truncate it.} The measurement covariance is not the end of the analysis but its first input. -Section\textasciitilde{}\ref{sec:depth} sets out the next step of the -chain: invert the per-band \(C_d\) through sensitivity kernels for a -depth profile and its covariance, separating the shear-velocity and -density contributions where the ground is partially saturated. -Converting that depth-resolved posterior to stress or strain -(Section\textasciitilde{}\ref{sec:stress}) requires material priors this -paper does not attempt to constrain, and is left to other work; what we -deliver is the depth posterior and its covariance, the object any such -conversion must consume. Building and testing the depth-propagation -stage on truth-known synthetics is the natural continuation of this -work, and is under way in the open codameter framework. +Section~\ref{sec:depth} sets out the next step of the chain: invert the +per-band \(C_d\) through sensitivity kernels for a depth profile and its +covariance, separating the shear-velocity and density contributions +where the ground is partially saturated. Converting that depth-resolved +posterior to stress or strain requires material priors this paper does +not attempt to constrain, and is left to other work. What codameter +provides today is the interface that consumes \(C_d\); the depth +posterior itself, its resolution, and the calibration of its covariance +are not demonstrated in this paper. Building and testing the +depth-propagation stage on truth-known synthetics with overlapping +kernels is the natural continuation of this work. \section{Conclusions}\label{sec:conclusions} Ambient-noise \dvv~monitoring rests on a chain of processing choices that are made ad hoc and reported incompletely. Using a truth-known synthetic and the full estimator suite of an open toolbox, we have shown -that these choices change the recovered \dvv~and, more consequentially, -change the reported uncertainty by a factor of \(\sim\!\sqrt{N}\) --- -enough to flip the significance of a result --- all without touching the -data. The remedy is not a single mandated pipeline but transparency: -report every choice, sample the ones the physics does not fix, carry the -resulting measurement covariance into the inference, and release the -pipeline as executable code. The same discipline extends down the -inference chain: the measurement covariance is the input a depth -inversion consumes, and only a pipeline that carries the covariance that -far can attach an honest uncertainty to a depth-resolved velocity-change -profile. Converting that profile to stress or strain is a further step -this paper does not attempt (Section\textasciitilde{}\ref{sec:stress}). -We offer codameter as one such record, and as the package in which the -depth stage is being built. +that these choices change the recovered \dvv~by up to two orders of +magnitude in RMS across reasonable pipelines and, more consequentially, +change the number reported as its uncertainty by a factor of +\(\sim\!\sqrt{N}\) depending on which of two different quantities a +study calls \(1\sigma\), all without touching the data. The remedy is +not a single mandated pipeline but transparency: report every choice and +name the quantity each error bar estimates, sample the choices the +physics does not fix, carry the resulting measurement covariance into +the inference after validating its target, and release the pipeline as +executable code. Repeated synthetic realisations support the proposed +95,\% pointwise member intervals, while the nominal 68,\% intervals +overcover and the combined estimate's credible band undercovers +(Table~\ref{tab:calibration}). Temporal and cross-band covariance and +shared errors remain unvalidated. A depth inversion also needs kernel +uncertainty and the covariance of the actual observations it consumes. +Converting a depth profile to stress or strain is a further step this +paper does not attempt. We offer codameter as one such record; its depth +stage is an interface awaiting evaluation. \appendix @@ -1363,42 +1917,91 @@ \section{Estimator definitions}\label{app:estimators} Let \(r(t)\) and \(c(t)\) be the reference and current cross-correlations, band-passed to \([f_1,f_2]\) (central frequency \(f_c\), bandwidth \(B\)) and read over the coda window \(W=[t_1,t_2]\) -on one or both branches. We use the convention \(\delta t/t = -\,\dvv\), -and write \(\varepsilon\) for the recovered \dvv. - -\textbf{Trace stretching (TS).} For a trial stretch \(s\), define -\(r_s(t)=r\!\left(t/(1+s)\right)\) and the windowed correlation -coefficient \begin{equation} -\mathrm{CC}(s) = \frac{\int_W c(t)\,r_s(t)\,\mathrm{d}t} -{\left(\int_W c^2\,\mathrm{d}t\int_W r_s^2\,\mathrm{d}t\right)^{1/2}}, -\qquad \varepsilon = \arg\max_s \mathrm{CC}(s). -\end{equation} The single-measurement error decreases with the coherence -\(\mathrm{CC}\), the bandwidth \(B\), and the window length, -approximately as \(\sigma_{\varepsilon} \propto -\sqrt{(1-\mathrm{CC}^2)/\mathrm{CC}^2}\, \big/\!\left[f_c\sqrt{B\,(t_2^3-t_1^3)}\right]\) -\citep{Weaver2011}. +on one or both branches. Each method below estimates a trial stretch +factor \(\varepsilon\), the fractional dilation of the current coda +relative to the reference; physical \dvv~follows via the convention +boxed in Section~\ref{sec:intro}, \(\dvv=-\varepsilon/(1+\varepsilon)\). + +\textbf{Trace stretching (TS).} For each trial stretch factor +\(\varepsilon\), the current correlation is interpolated as +\(c_\varepsilon(t)=\mathcal{I}[c]\big((1+\varepsilon)t\big)\) +(interpolation on current only) while the reference \(r(t)\) remains +fixed. The windowed correlation coefficient is \begin{equation} +\mathrm{CC}(\varepsilon) = \frac{\int_W r(t)\,c_\varepsilon(t)\,\mathrm{d}t} +{\left(\int_W r^2\,\mathrm{d}t\int_W c_\varepsilon^2\,\mathrm{d}t\right)^{1/2}}, +\qquad \varepsilon^\star = \arg\max_\varepsilon \mathrm{CC}(\varepsilon). +\end{equation} The best-fit stretch \(\varepsilon^\star\) is then +converted to physical \(\dvv\) via +\(\dvv^\star = -\varepsilon^\star/(1+\varepsilon^\star)\) as boxed in +the Introduction. The single-measurement error decreases with the +coherence \(\mathrm{CC}\), the bandwidth \(B\), and the window length. +We use eq.~20 of \citet{Weaver2011}, \begin{equation} +\sigma_{\varepsilon} = \frac{\sqrt{1-\mathrm{CC}^2}}{2\,\mathrm{CC}} +\sqrt{\frac{6\sqrt{\pi/2}\;T}{\omega_c^2\,(t_2^3-t_1^3)}}, +\qquad T=\frac{\sqrt{\ln 10}}{\pi B}, +\label{eq:weaver} +\end{equation} with \(\omega_c=2\pi f_c\) and \(T\) the spectral +timescale of Weaver et al.'s Gaussian spectrum, fixed here by placing +the band edges at that spectrum's \(-10\),dB points; any convention with +\(T\propto 1/B\) gives the same \(1/\sqrt{B}\) scaling and differs by a +constant that the rescale \(s\) of Section~\ref{sec:bayes} absorbs. The +corresponding error on \dvv~follows from the exact map, +\(\sigma_{\dvv}=\sigma_{\varepsilon}/(1+\varepsilon)^2\), which equals +\(\sigma_{\varepsilon}\) to first order. (The codameter implementation +before this revision omitted \(T\) and used a variance prefactor twice +this one; the fitted \(s\) absorbed the constant, and only the relative +weighting of configurations in different bands changed when it was +corrected.) + +\emph{Interpolation direction and convention.} The interpolation is +applied to the current waveform and not the reference so that the +high-SNR reference stack remains invariant throughout the epsilon +search, which is particularly important when the reference is built as a +long-term or moving average. In the continuous-signal, infinite-support +limit the two conventions (interpolating current versus interpolating +reference) are mathematically equivalent after their fitted parameters +are converted to the same physical \(\dvv\) through the exact relation +\(\dvv = -\varepsilon/(1+\varepsilon)\). In sampled, finite-window +signals, that symmetry is broken: interpolation error, edge truncation, +and the finite support of the data cause the two conventions to give +slightly different numerical results even when both use the exact +conversion. Therefore the interpolation direction must be reported +explicitly and treated as a fixed processing choice. For diffuse codas +in ambient-noise and volcanic monitoring, we have verified that the +choice has a measurable but small effect: truth-known synthetics recover +\(\dvv\) with sub-\(10^{-4}\) bias when the signal-to-noise ratio is +high and the changes are small, with the effect growing as a few percent +at landslide-scale perturbations (\(\dvv\sim4\,\%\)). + +Throughout this appendix a delay \(\delta t\) is the lag of the current +trace relative to the reference, positive when the current arrival is +later, so for the pure dilation \(c(t)=r(t/(1+\varepsilon))\) a phase at +reference lapse \(t_i\) appears at \((1+\varepsilon)t_i\) and +\(\delta t_i=+\varepsilon\,t_i\); with that sign every estimator below +returns the dilation \(\varepsilon\) of the Introduction, and a +regression test in codameter holds each of them to it in both signs. \textbf{Windowed cross-correlation (WCC).} In sub-windows centred at lapse \(t_i\) the delay is \(\delta t_i=\arg\max_{\tau}\int c(t)\,r(t-\tau)\,\mathrm{d}t\); a -least-squares fit of \(\delta t_i=-\varepsilon\,t_i\) gives +least-squares fit of \(\delta t_i=\varepsilon\,t_i\) gives \(\varepsilon\). \textbf{Moving-window cross-spectrum (MWCS).} In each sub-window the cross-spectrum is \(X(f)=\hat c(f)\,\hat r^{*}(f)\) with phase \(\varphi(f)=\arg X(f)\approx 2\pi f\,\delta t_i\); a coherence-weighted linear fit of \(\varphi(f)\) over -\([f_1,f_2]\) yields \(\delta t_i\), and \(\varepsilon\) is minus the -slope of \(\delta t_i\) versus \(t_i\) \citep{Clarke2011}. Because -\(\varphi\) is defined modulo \(2\pi\), the estimate cycle-skips once +\([f_1,f_2]\) yields \(\delta t_i\), and \(\varepsilon\) is the slope of +\(\delta t_i\) versus \(t_i\) \citep{Clarke2011}. Because \(\varphi\) is +defined modulo \(2\pi\), the estimate cycle-skips once \(|\delta t_i|>1/(2f)\). \textbf{Dynamic time warping (DTW).} A lag path \(l(i)\) minimises \begin{equation} \sum_i \big(c_i - r_{i+l(i)}\big)^2 \;+\; \gamma\sum_i \big(l(i{+}1)-l(i)\big)^2, \end{equation} where \(\gamma\) penalises strain (limits the lag's rate -of change); \(\varepsilon\) is minus the slope of \(l(i)/f_s\) versus -lapse. +of change); \(\varepsilon\) is the slope of the lag \(l(i)/f_s\) +(current relative to reference) versus lapse. \textbf{Wavelet cross-spectrum (WCS).} With continuous wavelet transforms \(W_c,W_r\), the cross-wavelet spectrum is @@ -1407,7 +2010,7 @@ \section{Estimator definitions}\label{app:estimators} dimensions --- along lapse (anchored at \(\tau\!\to\!0\), where \(\delta t\!\to\!0\)) then along frequency --- removes the cycle-skip; \(\varepsilon\) follows from the \(|W_{xy}|\)-weighted regression -\(\delta t=-\varepsilon\,\tau\) over the time--frequency window +\(\delta t=\varepsilon\,\tau\) over the time--frequency window \citep{Mao2020}. \textbf{Wavelet stretching / warping (WTS, WTDTW).} TS (respectively @@ -1418,17 +2021,20 @@ \section{Estimator definitions}\label{app:estimators} \section{Aggregation and uncertainty conventions}\label{app:aggregation} For component \(k\) of a station pair, stretching yields the image -\(\mathrm{CC}_k(\varepsilon,t)\). +\(\mathrm{CC}_k(\varepsilon,t)\); each per-component stretch factor +converts to physical \(\dvv_k\) via the boxed relation. -\textbf{Approach A (average the \dvv).} -\(\varepsilon_k(t)=\arg\max_{\varepsilon} \mathrm{CC}_k(\varepsilon,t)\) -and the pair estimate is the (possibly weighted) mean -\(x_p(t)=\sum_k w_k\,\varepsilon_k/\sum_k -w_k\), with \(w_k=\max_{\varepsilon} \mathrm{CC}_k\) -(coherence-weighted) or \(w_k=1\) (unweighted). +\textbf{Approach A (average the per-component \dvv).} \(\dvv_k(t)\) +follows from \(\varepsilon_k(t)=\arg\max_{\varepsilon} +\mathrm{CC}_k(\varepsilon,t)\), and the pair estimate is the (possibly +weighted) mean \(x_p(t)=\sum_k w_k\,\dvv_k/\sum_k w_k\), with +\(w_k=\max_{\varepsilon} +\mathrm{CC}_k\) (coherence-weighted) or \(w_k=1\) (unweighted). -\textbf{Approach B (average the images).} -\(x_p(t)=\arg\max_{\varepsilon}\big[\tfrac1{N_c}\sum_k \mathrm{CC}_k(\varepsilon,t)\big]\). +\textbf{Approach B (average the images).} The pair stretch factor +\(\varepsilon_p(t)=\arg\max_{\varepsilon}\big[\tfrac1{N_c}\sum_k +\mathrm{CC}_k(\varepsilon,t)\big]\) converts to \(x_p(t)=\dvv_p(t)\) via +the same relation. \textbf{Network over pairs.} With pair weights \(W_p\) (e.g.~mean coherence), \begin{equation} @@ -1436,25 +2042,25 @@ \section{Aggregation and uncertainty conventions}\label{app:aggregation} s^2=\frac{\sum_p W_p (x_p-\bar x)^2}{\sum_p W_p},\quad N_{\mathrm{eff}}=\frac{(\sum_p W_p)^2}{\sum_p W_p^2}. \end{equation} The three uncertainty conventions used in -Section\textasciitilde{}\ref{sec:uncertainty} are the weighted standard -error \(\sigma_{\mathrm{SE},w}=s/\sqrt{N_{\mathrm{eff}}}\), the -unweighted standard error -\(\sigma_{\mathrm{SE}}=\mathrm{std}(x_p)/\sqrt{N}\), and the standard -deviation \(\sigma_{\mathrm{SD}}=\mathrm{std}(x_p)\). They share the -mean \(\bar x\) but obey +Section~\ref{sec:uncertainty} are the weighted standard error +\(\sigma_{\mathrm{SE},w}=s/\sqrt{N_{\mathrm{eff}}}\), the unweighted +standard error \(\sigma_{\mathrm{SE}}=\mathrm{std}(x_p)/\sqrt{N}\), and +the standard deviation \(\sigma_{\mathrm{SD}}=\mathrm{std}(x_p)\). They +share the mean \(\bar x\) but obey \(\sigma_{\mathrm{SD}}/\sigma_{\mathrm{SE}}=\sqrt{N}\). \section{Survey of processing choices across the literature}\label{app:survey} -Table\textasciitilde{}\ref{tab:survey} catalogues the processing choices -of the 103 ambient-noise \dvv~monitoring studies we surveyed (full -machine-readable version and provenance in the codameter -\texttt{literature/} directory). It is the empirical basis for the -paper's claim that no convention is shared: the estimator, the frequency -band, the coda window, the reference scheme and --- most unevenly of all ---- the uncertainty treatment vary study to study, and the last is -frequently unreported. Every study is cited here. +Table~\ref{tab:survey} catalogues the processing choices of the +ambient-noise \dvv~monitoring studies we surveyed: 103 rows for 102 +publications, one publication \citep{Obermann2013} contributing two rows +for two distinct measurement set-ups (the full machine-readable version +and provenance are distributed with the codameter package). It is the +empirical basis for the paper's claim that no convention is shared: the +estimator, the frequency band, the coda window, the reference scheme and +--- most unevenly of all --- the uncertainty treatment vary study to +study, and the last is frequently unreported. Every study is cited here. The four measurement fields (frequency band, coda window, estimator and uncertainty treatment) were re-checked against the \emph{full text} for @@ -1464,33 +2070,53 @@ \section{Survey of processing choices across the means only that the value was not found in the abstract, not that the study failed to report it; those cells are flagged in the machine-readable table (\texttt{measurement\_source}) and remain to be -filled from the paywalled full texts. The apparent under-reporting in -the table is therefore a lower bound on what the literature actually -states. +filled from the paywalled full texts. Because a cell populated from an +abstract can only move from ``n/r'\,' to reported once the full text is +read, the apparent under-reporting in the table is an upper bound on the +true under-reporting; the verified rate is the one among the 82 +full-text rows. \input{appendix_table.tex} \section*{Data availability}\label{data-availability} \addcontentsline{toc}{section}{Data availability} -The codameter package, including the synthetic-demonstration module, the -figure-generating scripts, and the literature survey that motivates this -work, is openly available at -\url{https://github.com/Denolle-Lab/codameter}. All figures are -reproduced by \texttt{python\ literature/synthetic\_dvv\_demo.py}, the -multiverse and deviation ranking by -\texttt{python\ -m\ codameter.deviations}, and the Bayesian measurement -model by \texttt{python\ -m\ codameter.uq\_bayes}. The manuscript itself -is rendered from \texttt{paper/manuscript\_marine.qmd} by -\texttt{python\ paper/build.py}. +All synthetics, estimators, and generated figures in this paper are +implemented in the open-source Python package codameter (MIT license), +openly available at \url{https://github.com/Denolle-Lab/codameter}; each +generated figure's sidecar records its generating commit and numerical +arrays. The figures and manuscript can originate from different +revisions. \texttt{python -m codameter.figures} regenerates every +generated figure with a \texttt{.npz} sidecar of its plotted arrays and +a \texttt{.json} sidecar of its provenance; +\texttt{python -m codameter.calibration} reproduces +Table~\ref{tab:calibration} (\texttt{paper/data/calibration/}); +\texttt{scripts/compare\_gate1.py} reproduces Table~\ref{tab:gate1} from +the daily products under \texttt{paper/data/gate1/} and the published +\citet{Clements2023} series archived there. The daily products and the +three real-data figures were produced by the noisepy-dvv-cloud Gate 1 +run from public Southern California Earthquake Data Center waveforms; +the products are available locally during this analysis but are not +tracked in the repository. The exact Gate 1 run commit, run +configuration and redistribution archive remain to be supplied; their +current provenance limits are recorded in +\texttt{paper/data/gate1/README.md}. A versioned archive is planned but +has not yet been deposited. \section*{Acknowledgements}\label{acknowledgements} \addcontentsline{toc}{section}{Acknowledgements} -{[}To be completed.{]} - -\section*{REFERENCES}\label{references} -\addcontentsline{toc}{section}{REFERENCES} +{[}Funding, contributions and thanks to be completed by the author.{]} +AI assistance: this manuscript was checked with the Denolle Group +Pre-Submission Reviewer (v2.4, model Codex/GPT-6), an advisory AI tool, +through one review iteration and a subsequent evidence reconciliation; +final author adjudication remains to be recorded. The tool does not +endorse manuscript validity. Code revisions and text edits in response +to that review were drafted with Claude (Anthropic) and Codex (OpenAI) +under the author's direction and are recorded in the repository history. + +\section*{References}\label{references} +\addcontentsline{toc}{section}{References} \renewcommand{\bibsection}{} \bibliography{references.bib,survey.bib} diff --git a/paper/references.bib b/paper/references.bib index 434a7da..ad119b4 100644 --- a/paper/references.bib +++ b/paper/references.bib @@ -1,3 +1,19 @@ +@article{poupinet84, + author = {Poupinet, G. and Ellsworth, W. L. and Frechet, J.}, + title = {Monitoring velocity variations in the crust using earthquake doublets: An application to the {Calaveras} Fault, {California}}, + journal = {Journal of Geophysical Research: Solid Earth}, + volume = {89}, number = {B7}, pages = {5719--5731}, year = {1984}, + doi = {10.1029/jb089ib07p05719} +} + +@article{lobkis03, + author = {Lobkis, Oleg I. and Weaver, Richard L.}, + title = {Coda-Wave Interferometry in Finite Solids: Recovery of {P}-to-{S} Conversion Rates in an Elastodynamic Billiard}, + journal = {Physical Review Letters}, + volume = {90}, number = {25}, pages = {254302}, year = {2003}, + doi = {10.1103/PhysRevLett.90.254302} +} + @article{SensSchonfelder2006, author = {Sens-Sch{\"o}nfelder, Christoph and Wegler, Ulrich}, title = {Passive image interferometry and seasonal variations of seismic velocities at {Merapi} Volcano, {Indonesia}}, @@ -203,6 +219,19 @@ @article{Okubo2024 doi = {10.1029/2023JB028084} } +@article{Denolle25b, + author = {Denolle, Marine A. and Shi, Qibin and Clements, Tim and Viens, Lo{\"\i}c and Rodriguez-Tribaldos, Veronica and Cotton, Fabrice}, + title = {Ambient field seismology in critical zone hydrological sciences}, + journal = {Comptes Rendus. G\'eoscience}, + pages = {425--451}, + year = {2025}, + publisher = {Acad\'emie des sciences, Paris}, + volume = {357}, + doi = {10.5802/crgeos.310}, + language = {en} + } + + @article{Kidiwela2026, author = {Kidiwela, Maleen and Denolle, Marine A. and Wilcock, William S. D. and Feng, K. F.}, title = {Active protothrusts and fluid highways: Seismic noise reveals hidden subduction dynamics in Cascadia}, @@ -229,3 +258,134 @@ @book{Mavko2009 year = {2009}, doi = {10.1017/CBO9780511626753} } + +% Deployment examples cited narratively in the Introduction (not part of +% the 103-study processing-choice survey, so kept here rather than in the +% auto-generated survey.bib). +@article{CubukSabuncu2021, + author = {Cubuk-Sabuncu, Ye{\c s}im and J{\'o}nsd{\'o}ttir, Kristín and Caudron, Corentin and Lecocq, Thomas and Parks, Michelle and Geirsson, Halld{\'o}r and Mordret, Aur{\'e}lien}, + title = {Temporal Seismic Velocity Changes During the 2020 Rapid Inflation at Mt. {\th}orbj{\"o}rn-Svartsengi, Iceland, Using Seismic Ambient Noise}, + journal = {Geophysical Research Letters}, + year = {2021}, + volume = {48}, + pages = {e2020GL092265}, + doi = {10.1029/2020GL092265} +} + +@article{Ouellet2022, + author = {Ouellet, Susanne M. and Dettmer, Jan and Olivier, Gerrit and de Wit, Tjaart and Lato, Matt}, + title = {Advanced monitoring of tailings dam performance using seismic noise and stress models}, + journal = {Communications Earth \& Environment}, + year = {2022}, + volume = {3}, + pages = {301}, + doi = {10.1038/s43247-022-00629-w} +} + +@article{Planes2016, + author = {Plan{\`e}s, Thomas and Mooney, Michael A. and Rittgers, Jacob B. R. and Parekh, Malcolm L. and Behm, Michael and Snieder, Roel}, + title = {Time-lapse monitoring of internal erosion in earthen dams and levees using ambient seismic noise}, + journal = {G{\'e}otechnique}, + year = {2016}, + volume = {66}, + number = {4}, + pages = {301--312}, + doi = {10.1680/jgeot.14.P.268} +} + +@article{Tsuji2021, + author = {Tsuji, Takeshi and Ikeda, Tatsunori and Matsuura, Ryosuke and Mukumoto, Kota and Hutapea, Fernando Lawrens and Kimura, Tsunehisa and Yamaoka, Koshun and Shinohara, Masanao}, + title = {Continuous monitoring system for safe managements of {CO2} storage and geothermal reservoirs}, + journal = {Scientific Reports}, + year = {2021}, + volume = {11}, + pages = {19120}, + doi = {10.1038/s41598-021-97881-5} +} + +@article{Rivet2014, + author = {Rivet, Diane and Brenguier, Florent and Clarke, Daniel and Shapiro, Nikola{\"i} M. and Peltier, Aline}, + title = {Long-term dynamics of {Piton de la Fournaise} volcano from 13 years of seismic velocity change measurements and {GPS} observations}, + journal = {Journal of Geophysical Research: Solid Earth}, + volume = {119}, + number = {10}, + pages = {7654--7666}, + year = {2014}, + doi = {10.1002/2014JB011307} +} + +@article{SensSchonfelder2014, + author = {Sens-Sch{\"o}nfelder, Christoph and Pomponi, Eraldo and Peltier, Aline}, + title = {Dynamics of {Piton de la Fournaise} volcano observed by passive image interferometry with multiple references}, + journal = {Journal of Volcanology and Geothermal Research}, + volume = {276}, + pages = {32--45}, + year = {2014}, + doi = {10.1016/j.jvolgeores.2014.02.012} +} + +@article{James2017, + author = {James, S. R. and Knox, H. A. and Abbott, R. E. and Screaton, E. J.}, + title = {Improved moving window cross-spectral analysis for resolving large temporal seismic velocity changes in permafrost}, + journal = {Geophysical Research Letters}, + volume = {44}, + number = {9}, + pages = {4018--4026}, + year = {2017}, + doi = {10.1002/2016GL072468} +} + +@article{ZotzWilson2019, + author = {Zotz-Wilson, Reuben and Boerrigter, Thijs and Barnhoorn, Auke}, + title = {Coda-wave monitoring of continuously evolving material properties and the precursory detection of yielding}, + journal = {The Journal of the Acoustical Society of America}, + volume = {145}, + number = {2}, + pages = {1060--1068}, + year = {2019}, + doi = {10.1121/1.5091012} +} + +@article{Hadziioannou2011, + author = {Hadziioannou, C. and Larose, E. and Baig, A. and Roux, P. and Campillo, M.}, + title = {Improving temporal resolution in ambient noise monitoring of seismic wave speed}, + journal = {Journal of Geophysical Research: Solid Earth}, + volume = {116}, + number = {B7}, + pages = {B07304}, + year = {2011}, + doi = {10.1029/2011JB008200} +} + +@article{Moreau2017, + author = {Moreau, L. and Stehly, L. and Boué, P. and Lu, Y. and Larose, E. and Campillo, M.}, + title = {Improving ambient noise correlation functions with an {SVD}-based {W}iener filter}, + journal = {Geophysical Journal International}, + volume = {211}, + number = {1}, + pages = {418--426}, + year = {2017}, + doi = {10.1093/gji/ggx306} +} + +@article{Mao2019, + author = {Mao, Shujuan and Campillo, Michel and van der Hilst, Robert D. and Brenguier, Florent and Stehly, Laurent and Hillers, Gregor}, + title = {High temporal resolution monitoring of small variations in crustal strain by dense seismic arrays}, + journal = {Geophysical Research Letters}, + volume = {46}, + number = {1}, + pages = {128--137}, + year = {2019}, + doi = {10.1029/2018GL079944} +} + +@article{Viens2020, + author = {Viens, Loïc and Van Houtte, Chris}, + title = {Denoising ambient seismic field correlation functions with convolutional autoencoders}, + journal = {Geophysical Journal International}, + volume = {220}, + number = {3}, + pages = {1521--1535}, + year = {2020}, + doi = {10.1093/gji/ggz509} +} diff --git a/paper/survey.bib b/paper/survey.bib index bd70472..77e12b3 100644 --- a/paper/survey.bib +++ b/paper/survey.bib @@ -772,15 +772,6 @@ @misc{Kristjansdottir2019 note = {dv/v monitoring study (Geothermal wastewater reinjection (water-volume / pore-pressure increase))} } -@article{Hadziioannou2011, - author = {Hadziioannou, C. and Larose, E. and Baig, A. and Roux, P. and Campillo, M.}, - title = {Improving temporal resolution in ambient noise monitoring of seismic wave speed}, - journal = {Journal of Geophysical Research}, - year = {2011}, - volume = {116}, - doi = {10.1029/2011jb008200} -} - @article{Daskalakis2016, author = {Daskalakis, E. and Evangelidis, C.P. and Garnier, J. and Melis, N.S. and Papanicolaou, G. and Tsogka, C.}, title = {Robust seismic velocity change estimation using ambient noise recordings}, diff --git a/pyproject.toml b/pyproject.toml index c8264ae..2842a9c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -146,10 +146,27 @@ disable_error_code = ["no-any-return"] module = [ "codameter.coupling.tier2_damage", "codameter.coupling.decision_tree", - "codameter.inverse.linear_fit", ] disable_error_code = ["arg-type"] +[[tool.mypy.overrides]] +module = "codameter.inverse.linear_fit" +disable_error_code = ["arg-type", "assignment"] + +# Surfaced 2026-09-10, the first time the mypy hook checked the golden/scorer +# import path. Same rule as above: per file, per error code, shrink as fixed. +[[tool.mypy.overrides]] +module = "codameter.golden" +disable_error_code = ["no-any-return", "has-type", "misc"] + +[[tool.mypy.overrides]] +module = "codameter.frugalmind" +disable_error_code = ["operator", "no-any-return"] + +[[tool.mypy.overrides]] +module = ["codameter.use_cases", "codameter.bench"] +disable_error_code = ["no-any-return"] + [[tool.mypy.overrides]] module = "codameter.data.loaders" disable_error_code = ["arg-type", "no-any-return"] diff --git a/review/.gitignore b/review/.gitignore new file mode 100644 index 0000000..78bdc1d --- /dev/null +++ b/review/.gitignore @@ -0,0 +1,4 @@ +# Local compilation copies and generated font caches. +/evidence/reproduction_workspace/ +/evidence/tex_cache/ +/evidence/probe_cache/ diff --git a/review/01_manuscript_and_figures.md b/review/01_manuscript_and_figures.md new file mode 100644 index 0000000..1a679cf --- /dev/null +++ b/review/01_manuscript_and_figures.md @@ -0,0 +1,140 @@ +# Manuscript scientific and presentation review + +**Recommendation: major revision before GJI submission.** The central premise is useful and relevant. Processing choices should be explicit and their effects measured. The present evidence establishes conditional processing sensitivity. It does not yet establish calibrated total measurement uncertainty, depth inference, or robust advisor performance. + +Reviewed source: `paper/manuscript_marine.qmd`. The README identifies it as authoritative. The older manuscript files were excluded as stale. The existing PDF has 74 pages, dated 2026-08-17. This review treats the manuscript as a research paper. Its scope exceeds a short letter's intended format. + +## Specific strengths + +- The exact physical dv/v sign convention is explicit. See source lines 95–125. +- Synthetic experiments make processing assumptions inspectable. See lines 180–222 and the multiverse section. +- The study distinguishes component aggregation from network averaging. That distinction matters for reproducible observations. +- Independent product comparison exposed a consequential sign error. The discussion documents a valuable validation lesson. +- The reporting checklist provides practical community guidance. See lines 1212–1252. +- Source code, tests, and a literature catalogue are available. They provide a strong foundation for revision. + +## SCI-01: Define the scientific estimand before uncertainty + +**Major.** The square-root-N headline compares different statistical targets. SD describes dispersion; SE describes precision of a mean. Their ratio is largely an algebraic identity. It does not establish conflicting valid significance conclusions. + +See lines 446–480, 1392–1402, and Figures 3–4. The network synthetic additionally imposes 15% pair-amplitude heterogeneity. Thus pair spread contains physical variability and observational noise. A weighted network can also change the target average. + +State whether the target is a specific pair, a finite-network mean, a population mean, or a depth-weighted physical property. Specify the null hypothesis. For normalized network weights \(a\), propagate \(a^T\Sigma a\). Include dependence from shared stations, reference data, and illumination. Neither SD nor SE universally substitutes for that calculation. + +Table 2 compounds the problem. Its network row compares network SE with an individual-pair range under an RMS heading. Replace the mixed metrics with separately named quantities. + +## SCI-02: Bound the inference from constructed experiments + +**Major.** A processing sweep holds one waveform realization fixed. It can establish conditional sensitivity to the chosen menu. It cannot show that processing generally dominates observational variability. See lines 838–911 and 1207–1209. + +Add independent waveforms and noise realizations to estimate both contributions. Use paired seeds when comparing pipelines. Report interactions, failures, and uncertainty on metric differences. Identify the configuration distribution behind each variance attribution. + +The two-layer examples assign distinct truths to separated frequency bands. This is a controlled spectral-mixture experiment. It does not establish actual depth resolution. Branch-specific truths are also imposed directly. Their physical sensitivity kernels are not estimated. + +Describe the coda envelope as radiative-transfer-inspired. The implementation modifies onset, ballistic scaling, and normalization. Claims about physical transport should distinguish this surrogate from full wave propagation. + +## SCI-03: Compare equivalent reference observables + +**Major.** Fixed references alter the zero point. Raw trailing-reference outputs have a different temporal response. Comparing both directly against an absolute truth confounds measurement error with the chosen observable. + +See lines 540–613 and Table 3. The text acknowledges no surveyed study reports uncumulated trailing outputs. Calling this a common reasonable practice therefore overstates the survey evidence. Present it as a deliberately incomplete ablation. + +Define a common datum and target response. Include reference linking or increment inversion used in practice. Match baseline alignment across synthetic and field comparisons. A trailing-average residual is not generally a daily increment; simply accumulating it does not undo its averaging operator. + +## SCI-04: Replace universal estimator prescriptions + +**Major.** The stretching recommendation needs scenario-specific evidence. The cited seven-method comparison ranks TS noise resistance low and DTW high under its conditions. That does not establish a universal opposite ranking either. It establishes the need to explain different settings. See manuscript lines 309–312, 933–936, and [Yuan et al., Table B3](https://academic.oup.com/gji/article/226/2/828/6224864). + +Compare tuned estimators under matched bands, windows, noise spectra, amplitudes, and computational budgets. Distinguish estimator limitations from this implementation's tuning. The strongest potential novelty is joint choice accounting, beyond another seven-estimator comparison. + +The branch-selection recommendation also needs revision. Figure 10 demonstrates maximum-selection bias. Lines 788–792 nevertheless permit choosing the largest magnitude and imply coherence selection avoids bias. Coherence is estimated from the same observations. Predefine branch rules or validate selection using independent data. + +## SCI-05: Calibration is a missing central experiment + +**Submission blocker, alongside implementation corrections.** Figure 14 shows one synthetic realization. The statement that its band restores nominal coverage is unsupported as a repeated-sampling claim. Neither wider intervals nor positive-definite covariance establishes calibration. + +The [software audit](02_software_and_uncertainty.md) identifies formula and covariance problems. Fix those first. Then evaluate independent held-out realizations. Report 68% and 95% pointwise coverage, simultaneous coverage where claimed, width, bias, and failures. Separate posterior inference under an assumed model from empirical error coverage under misspecification. + +Include common source drift and clock errors. Include errors all pipelines share. Include transient attenuation from stacks and smoothing priors. Show that downstream parameter intervals retain calibrated coverage. + +## SCI-06: Match abstract claims to completed evidence + +**Major.** Abstract lines 36–43 promise depth propagation and robust advisor evaluation. The depth section and conclusion describe stages still being built. No depth-recovery figure or actual agent-results table supports those promises. + +| Abstract claim | Available evidence | Necessary revision | +|---|---|---| +| Individual and combined processing effects | Constructed experiments and factorial sweep | State tested scenarios and conditional scope | +| Square-root-N change in reported uncertainty | SD/SE comparison | Define different estimands and hypotheses | +| Bayesian measurement covariance | Implemented hierarchy and posthoc covariance | Correct derivation and demonstrate calibration | +| Demonstrated depth-error propagation | Equations and implementation framework | Add kernels, recovered profiles, resolution, and coverage | +| Independent California reproduction | Smoothed/demeaned curve comparison | Reconcile data, masks, figures, and metric provenance | +| Laptop-to-cloud scalability | Optimization and execution infrastructure | Add runtime, memory, throughput, and failure measurements | +| Robust advisor evaluation | Skill, synthetic recipes, scorers, tests | Add executed model evaluation after scorer repair | + +Either supply the missing evidence or narrow the claims consistently. A covariance interface is a useful deliverable by itself. It should not be described as a completed inference validation. + +## SCI-07: Strengthen the observational validation + +**Major.** Product agreement is valuable consistency evidence. Correlation alone does not validate amplitude, bias, uncertainty, or physical attribution. Demeaning and 90-day smoothing further narrow what is being validated. + +The reported sample count needs reconciliation. For 2018–2019, excluding the first 150 days leaves at most 580 dates. The text reports 681 LJR overlapping days. The reproduction audit finds 578 available LJR product dates after that exclusion. A burn-in applied to older reference history could change this calculation. The manuscript needs that exact interval and mask. Recompute the comparison from an explicit date-and-mask table. + +ARV correlations depend on unspecified joining choices. Prespecify the joining, interpolation, smoothing, and exclusion rules. Report each sensitivity analysis separately. Include paired residuals, amplitude slopes, RMS, effective temporal information, and measurement uncertainty. + +The RXH interferogram suggests a different waveform history. It does not identify its cause. Check station responses, component labels, clocks, and source changes before physical attribution. + +## SCI-08: Audit the literature survey's denominator + +**Major for reporting-prevalence claims.** The source distinguishes full-text extraction from abstract-only records. Missing information in an abstract cannot establish nonreporting in the publication. Lines 1414–1423 incorrectly describe apparent underreporting as a lower bound. + +Report verified reporting, verified nonreporting, and inaccessible status separately. Supply search dates, queries, inclusion rules, deduplication, and extraction provenance. Reconcile 103 appendix citations against 102 unique citation keys. This may represent multiple rows per publication; it requires a declared study-count definition. + +The groundwater discussion also needs narrower attribution. The cited review allows physical hydrological variation. Processing differences are one possible explanation for scatter. Replace the unresolved “Figure x” and specify correlation sign. See lines 140–145 and [Denolle et al., 2025](https://comptes-rendus.academie-sciences.fr/geoscience/articles/10.5802/crgeos.310/). + +## Figure and design audit + +All 17 figure pages were visually inspected. The title, five main tables, and appendix endpoints were inspected too. In total, 26 pages were rendered. Other pages received text review. No simulated color-vision audit was performed. + +An isolated current-source build subsequently produced another 74-page PDF. Six selected pages received fresh visual checks. The Figure 1, 13, 14, 15, and 16 findings persisted. Existing numerical figure assets were reused during compilation. + +The referee layout is generally readable. Line numbering and spacing help review. Sequential color maps are sensible. The larger problems are mismatched claims, hidden data, and missing statistical labels. + +| Priority | Figure or table | Finding and correction | +|---|---|---| +| Major | Fig. 1c, PDF p11 | Red WCS curve jumps positive; caption says it tracks truth. Reconcile traces, labels, and claim. | +| Major | Table 2, p10 | Network row compares incompatible statistics. Give distinct columns and targets. | +| Major | Fig. 15, p36 | Displayed correlations differ from headline matched analysis. Plot the exact analysis supporting the claim. | +| Major | Fig. 16, p37 | Plot says NZ; caption describes NE. Resolve component provenance before interpretation. | +| Moderate | Fig. 12, p28 | RMS axis is described as bias. Separate signed bias from RMSE. | +| Moderate | Fig. 13, p29 | Ensemble and quantiles exceed axis limits. Add full-range view and failure summary. Label RMS units. | +| Moderate | Fig. 14, p32 | Label covariance in fractional dv/v squared or percent squared. Distinguish empirical error bands from credible intervals. | +| Moderate | Figs. 2, 8, 10, 14 | Legends obscure trajectories, troughs, or uncertainty. Move legends outside data regions. | +| Moderate | Fig. 16 | Add amplitude scale, normalization definition, and measurement windows. | +| Moderate | Fig. 17, p38 | Title says 5/5 members; panels say 4/5. Explain timing or reconcile. Remove development labels. | +| Minor | Fig. 8 | Add panel letters. Consider removing duplication with dedicated experiment figures. | +| Minor | Tables and figure calls | Repair first-citation order. Early tables reference later figures first. | + +Prefer vector exports for line plots and text. Keep raster interferograms at adequate final-size resolution. Use redundant line styles for estimator categories. Export numerical values and experiment metadata beside every figure. + +A tighter main-paper sequence would follow the evidence: + +1. Define the observation target and processing operators. +2. Compare conditional effects under matched configurations. +3. Quantify replicated sensitivity and interactions. +4. Derive and calibrate the measurement model. +5. Validate against independent observational products. +6. Demonstrate depth or advisor results only if retained. + +Place the complete survey and secondary diagnostics in supplements. This is organizational advice, not a journal length violation. + +## GJI format, references, and end matter + +The approximately 362-word source summary meets the current 500-word research-paper limit. GJI requires a single summary paragraph. The source contains three. The 250-word limit applies to Express Letters. A Data Availability statement is required. AI assistance should be disclosed in the cover letter and manuscript. See [current GJI instructions](https://academic.oup.com/gji/pages/general_instructions). + +Acknowledgements remain a placeholder at line 1436. Finalize authorship, funding, contributions, and relevant disclosures. The available data statement omits the field products and external generation dependencies. A future Zenodo archive is not a presently reviewable versioned release. Avoid treating a DOI alone as a substitute for complete accessible artifacts. + +The bibliography contains 129 unique cited entries. No missing or duplicate citation keys were found. Nine entries include Denolle, 7.0% overall. Main-text citations include eight such works among 59, 13.6%. No inflation was established. The references span 1951–2026. GJI, JGR Solid Earth, and GRL together account for 53.5%. + +These are awareness signals, not diversity scores. Geographic author coverage was not quantified. Study location was not treated as author identity. No gender, race, or nationality inference was performed. + +The complete nine-scope findings remain in [paper sections](evidence/paper_sections.md), [methods and figures](evidence/methods_figures.md), and [reproducibility](evidence/reproducibility.md). diff --git a/review/02_software_and_uncertainty.md b/review/02_software_and_uncertainty.md new file mode 100644 index 0000000..99e322e --- /dev/null +++ b/review/02_software_and_uncertainty.md @@ -0,0 +1,163 @@ +# Software and measurement uncertainty audit + +The project exposes important, usually hidden processing choices. Seeded waveforms, explicit configurations, and modular estimators support inspection. Those strengths do not establish calibrated measurement uncertainty. Several implemented uncertainty calculations require correction before scientific use. + +Evidence refers to the audited checkout, commit `b6dbbd03ad3a9e7b8daac3847a470b93b6918cc8`. Line numbers refer to original source files. Executable probes and numerical outputs reside in [evidence](evidence/). No scientific source was changed. + +## What each uncertainty object actually represents + +| Object | Current meaning | Necessary qualification | +|---|---|---| +| One seeded recovery RMS | Error for one waveform realization | Not expected bias or calibrated uncertainty | +| OAT/factorial variation | Sensitivity to the selected configuration menu | Depends on menu, metric, seed, and time support | +| Across-pipeline SD | Disagreement among transformations of shared data | Cannot reveal an artifact shared by every pipeline | +| `mu_cov` | Posterior covariance under the implemented hierarchical likelihood | Shared-data independence assumptions require justification | +| `Cd` | Posthoc covariance using fitted scales and an exponential kernel | Not the sampled posterior covariance or a derived mixture covariance | +| Depth posterior | Conditional inference given kernels, priors, and supplied covariance | Does not include uncertain kernels automatically | + +Determinism answers whether execution repeats. Calibration answers whether uncertainty predicts errors. They require separate validation. + +## UQ-01: The Weaver floor is dimensionally incomplete + +**Submission blocker.** `src/codameter/uq_measurement.py:76–124` calculates + +\[ +\sigma^2=\frac{1-CC^2}{2CC^2} +\frac{6\sqrt{\pi/2}}{\omega_c^2(t_2^3-t_1^3)}. +\] + +The denominator has units of seconds. The numerator is dimensionless. Therefore the returned quantity lacks dimensionless fractional-velocity units. + +Weaver et al.'s Gaussian-spectrum expression includes a bandwidth timescale, here denoted \(T_B\): + +\[ +\operatorname{rms}(\epsilon)=\frac{\sqrt{1-X^2}}{2X} +\sqrt{\frac{6\sqrt{\pi/2}\,T_B} +{\omega_c^2(t_2^3-t_1^3)}}. +\] + +The code also differs in the squared coherence prefactor. Establish the bandwidth convention and branch-count normalization explicitly. See [Weaver et al., equation 20, preprint page 7](https://arxiv.org/pdf/1103.1785). + +The dimensional probe gives a factor `0.0316228` under equivalent time-unit reexpression. This diagnoses the formula, not an advertised milliseconds API. More directly, its arguments contain no bandwidth information. Equal center frequencies and coherence therefore produce identical floors for differently wide bands. + +**Required correction:** implement and document the spectral correlation timescale. Derive the prefactor for the actual measurement setup. Validate against independent noise realizations across bandwidths. Recalculate all dependent uncertainty results, including depth examples. A fitted global scale cannot establish bandwidth-specific calibration. + +## UQ-02: Variability of error bars is misclassified + +**Submission blocker for this propagation path.** `uq_processing.py:220–266` adds `var(floors)` to `mean(floors**2)`. A fixed supplied `band_bias` adds its square too. + +For a mixture with identical conditional means, + +\[ +\operatorname{Var}(Y)=E_c[\sigma_c^2], +\qquad \operatorname{Var}_c(E[Y\mid c])=0. +\] + +Different conditional precisions do not imply different conditional means. The extra variance therefore has no stated probabilistic basis. A known fixed bias belongs in the mean correction. Its square contributes to mean-squared error, not centered variance, unless an explicit random-bias model is supplied. + +Our two-choice probe gives `1.79521e-6` for the zero-mean mixture variance. The implementation returns `2.46206e-6`, about 37% larger. This is a mathematical counterexample, not waveform calibration. + +**Required correction:** compute conditional central estimates by reprocessing. Alternatively, specify and validate a bias distribution. Keep variance, bias, and MSE separately named. + +## UQ-03: The hierarchical likelihood counts shared evidence repeatedly + +**Major.** `uq_bayes.py:297–317` sums independent precisions across configurations and epochs. Yet every configuration transforms the same CCF matrix. Overlapping bands, windows, stacks, and the reference share noise. + +The implementation fits all outputs jointly as repeated observations. It does not implement a discrete mixture over alternative pipelines. These statistical constructions are different. A constant configuration offset cannot represent configuration-specific smoothing, transient attenuation, or different depth sensitivity. + +The same inverse-gamma hyperparameters govern `tau²` and dimensionless `s²`. With shape 2 and scale `1e-8`, their prior mean is `1e-8`. Calling these priors weakly informative needs scale-specific justification. Report prior-predictive behavior and sensitivity, especially for the purported error-floor multiplier. + +**Required correction:** define the observation target before combining pipelines. Use a joint error model, calibrated generalized likelihood, or a clearly defined weighted model mixture. Model each pipeline's temporal and depth response where necessary. Check invariance to duplicating identical configurations. Compare independent waveform ensembles, not just additional pipelines. + +## UQ-04: `Cd` is an uncalibrated covariance construction + +**Major.** `uq_bayes.py:328–344` samples `mu_cov`, then separately constructs + +\[ +C_d=D R(L)D+\tau^2\mathbf1\mathbf1^T, +\quad D_{tt}^2=s^2\overline{\sigma_k^2(t)} ++\operatorname{Var}_k[m_k(t)]. +\] + +The module introduction calls `Cd` the posterior covariance at lines 37–39. The dataclass correctly distinguishes those objects at lines 175–186. The documentation therefore contradicts itself. + +Across-member variance includes variation from within-method noise. Adding a noise floor may double-count it. Configuration offsets already contribute to member variance; adding `tau²` needs a separate derivation. Between-configuration offsets cannot identify bias shared across all configurations. The fitted correlation length is also treated as known downstream. + +The common-artifact probe uses four identical sinusoidal measurements. The true signal is zero. It yields: + +| Diagnostic | Result | +|---|---:| +| RMS estimation error | `0.00212136` fractional dv/v | +| Median `sqrt(diag(Cd))` | `0.0000599802` | +| Epochs containing zero within ±2 SD | `2/30` | + +This is a constructed failure case. It is **not** an estimated population coverage rate. It disproves the general claim that agreement plus this covariance necessarily covers shared errors. + +**Required correction:** choose a clear target distribution. Derive its covariance without counting components twice. Calibrate against shared source drift, timing errors, reference contamination, and waveform-model mismatch. Distinguish posterior credible intervals from prediction or measurement-error intervals. + +## UQ-05: Configuration and time semantics differ between engines + +**Major.** `uq_bayes.run_processing_ensemble`, lines 125–157, always creates a fixed reference. It ignores supplied `reference` and `gate`. The probe confirms identical outputs for fixed/gated and moving/ungated configurations. Their labels are identical too. + +Both the Bayesian ensemble and multiverse subsample CCFs before stacking. See `uq_bayes.py:121–129` and `deviations.py:344–354`. A ten-record stack at three-day cadence spans 27 elapsed days. It is not a ten-day trailing stack. A 45-record moving reference similarly changes its physical duration. Cadence changes the experiment, not merely computation cost. + +`gibbs_dvv` constructs second differences in index space. Its latent posterior ignores actual time intervals. Adding a 1,000-day gap leaves the posterior mean bitwise identical. Times enter the later covariance calculation, producing inconsistent time treatment. + +The ensemble also clips peak coherence upward to 0.5. Low coherence cannot then increase the floor without bound. This needs rejection or explicit failure handling. + +**Required correction:** use one canonical pipeline implementation. Reject unsupported options. Specify stack/reference durations in physical time. Stack before decimating output, or convert durations explicitly. Either support irregular timestamps properly or reject them. + +## DET-01: Deterministic comparisons need matched targets and support + +**Major.** `deviations.metrics:243–255` compares raw reference-relative outputs with absolute synthetic truth. `golden._rms:578–596` instead removes a baseline offset. Rankings therefore depend on which metric path executes. + +Each configuration also supplies its own valid mask. Gating or missing estimates can change the evaluated epochs. The drop metric selects a post-event minimum, increasing sensitivity to noise and search duration. The first-order variance fractions are valid sensitivity summaries for a complete balanced design. Dropping failed runs can unbalance that design. + +The reference implementation adds further confounding. At `deviations.py:213–216`, selecting `inversion` always calls a stretching implementation. The requested estimator and stack are not honored. Gating applies only to fixed-reference stretching when a peak correlation exists. + +**Required correction:** define a shared datum, observation operator, and evaluation interval. Report common-support recovery alongside availability. Report rejected epochs and event misses. Use repeated paired seeds for contrasts. Retain failed configurations in failure-rate summaries. Explicitly list unsupported combinations. + +## DET-02: Golden cache changes numerical inputs + +**Major for exact reproducibility; numerical impact still bounded only at input level.** `golden.py:508–553` hashes recipes but not generator code. A cold call returns newly generated float64 CCFs. A warm call reads float32 arrays. + +The probe finds maximum difference `4.7683e-7`. No claim is made that this difference materially changes published estimates. However, cold and warm runs are not bitwise identical. Generator edits can also leave old arrays under unchanged recipe hashes. Manifest regeneration deliberately bypasses that cache, so the scorer and oracle may consume different artifacts. + +**Required correction:** include generator, dependency, and dtype versions in cache identities. Return a consistent dtype. Write caches atomically. Pin immutable input checksums and retain benchmark thresholds separately from estimator updates. + +## INV-01: Downstream uncertainty is not connected consistently + +**Major.** `inverse/linear_fit.py:430–502` accepts diagonal errors only. It cannot directly consume temporal `Cd`. `uq_depth.invert_depth_profile:165–225` accepts cross-band covariance for one depth inversion. A temporal covariance is a different-shaped object. Neither fact alone implements a joint time-band-depth inference chain. + +The bound-constrained linear solver also zeros covariance rows at active bounds, lines 544–549. A parameter constrained to be nonnegative can have a one-sided uncertain posterior. An optimizer touching zero does not establish zero uncertainty. The audit probe returns exactly zero variance at such a bound. + +`global_reference_inversion:419–429` uses a pseudoinverse without checking graph connectivity. For three epochs and only one connected pair, the isolated epoch receives zero reported SD. That epoch is unidentified. The global datum does not remove disconnected-component null spaces. + +**Required correction:** add explicit GLS whitening and covariance shape metadata. Handle reference gauges and connected components explicitly. Return unidentified directions honestly. For bounded parameters, use constrained posterior sampling or justified one-sided intervals. Distinguish conditional curvature from posterior uncertainty. + +## SCALE-01: The covariance path needs structural algorithms + +**Major for large deployment.** Gibbs sampling builds dense `T×T` matrices. Each iteration performs Cholesky plus generic solves at `uq_bayes.py:299–303`. This costs approximately `O(iterations × T³)` time and `O(T²)` memory. The second-difference precision is banded; dense algebra discards that structure. + +One float64 covariance needs roughly 107 MB for 3,650 epochs. At 36,500 epochs, it needs 10.7 GB. Multiple matrices and chains multiply those costs. These are storage calculations, not measured runtime forecasts. + +Use banded precision solvers or state-space inference. Represent exponential temporal correlation structurally. Apply common-reference effects as low-rank updates. Retain dense covariances only for small exported subsets. Report cost against epochs, lag samples, configurations, and station pairs. + +Shardable execution exists in `bench.py`. However, the reproduction probe accepts duplicate rows with missing shards. Require unique task identifiers, complete expected inventories, configuration hashes, and matching code/data versions before aggregation. Distributed execution is not sufficient evidence of distributed reproducibility. + +## Necessary validation before large deployment + +1. Separate generator validation from estimator regression tests. +2. Use independent simulator families and multiple paired seeds. +3. Include no-change cases with shared waveform artifacts. +4. Vary source direction, spectra, gaps, clocks, and reference quality. +5. Include overlapping depth kernels and multiple wave types. +6. Measure bias, RMSE, coverage, width, failures, and availability. +7. Report transient amplitude, timing, and trend-slope errors separately. +8. Estimate coverage uncertainty across independent realizations. +9. Test duplicate-pipeline and timestamp-unit invariance. +10. Validate downstream parameter coverage with known synthetic truth. + +For nominal 95% coverage, 100 independent realizations give an approximate binomial standard error of 2.2 percentage points. Five hundred give about one point. Correlated epochs cannot replace independent realizations. Predefine acceptable calibration tolerances and failure rates for each scientific use case. + +Existing tests are valuable regression evidence. Full test and build outcomes are recorded in [the reproduction audit](evidence/reproducibility.md). They should not be interpreted as uncertainty calibration. diff --git a/review/03_advisor_and_golden_dataset.md b/review/03_advisor_and_golden_dataset.md new file mode 100644 index 0000000..c8c3f83 --- /dev/null +++ b/review/03_advisor_and_golden_dataset.md @@ -0,0 +1,114 @@ +# Advisor and golden-dataset audit + +The advisor has a useful design principle: execute recommendations. Its central configuration map prevents silent value drift. The documentation also acknowledges synthetic-to-field limitations. However, its current examples, scorer, and validation evidence do not support a claim of robust agent evaluation. + +This audit inspected the advisor as an artifact. It did not invoke it for operational recommendations. No external model benchmark or private corpus was accessed. + +## AG-01: The six-application validation example is incomplete + +**Major.** The skill promises six application families. Its standard validation calls `MAINSTREAM_BY_USE_CASE[key]`. The public checkout contains only three cases: + +| Application | Public validation route | +|---|---| +| Volcano | `easy-volcano-01` | +| Earthquake/fault | `medium-earthquake_fault-02` | +| Groundwater | `hard-groundwater-04` | +| Landslide | `KeyError` | +| Cryosphere | `KeyError` | +| Geothermal | `KeyError` | + +See `golden.py:317–365` and advisor `references/validation_loop.md:37–46`. A fallback to `generate` cannot create an unregistered recipe. The advisor needs public development cases for every supported route. + +The groundwater fallback is also a deep-targeted hard case. Its manifest overrides the band to `0.55–1.2 Hz`. The example instead uses the generic recommendation, `2–4 Hz`. It runs on averaged CCFs, although `golden.recover` measures channels separately before averaging. The advisor therefore does not reproduce the benchmark's target or aggregation protocol. + +**Fix:** provide explicit public development recipes per application. Respect case-level target metadata and use `golden.recover`. Distinguish a broad application default from a site-specific recommendation. Add executable smoke checks for every documented route. + +## AG-02: Recommendation quality is not evaluated directly + +**Major.** The skill elicits geometry, cadence, amplitude, and noise conditions. Most are descriptive mappings for the language model. The config contains only six axes. It omits timing checks, aggregation, explicit reference dates, and search-width provenance. + +The standard example fixes `eps_max` by application. It does not propagate a user's amplitude answer. `recommend` checks unknown keys but does not fully validate values. Invalid bands, windows, durations, and unsupported combinations need explicit checks. + +The example reports one realization's RMS and valid count. It supplies neither repeated-seed uncertainty nor a measured error-bar comparison. Calling choices equivalent within 20% RMS is a heuristic, not an equivalence test. See `validation_loop.md:45–53`. + +**Fix:** record elicited constraints and resulting overrides. Add tests for conflicting inputs, missing information, abstention, search saturation, and unavailable bands. Compare paired-seed differences with uncertainty. Specify scientifically meaningful equivalence margins beforehand. + +## AG-03: Synthetic ranking does not prove field suitability + +**Major.** The skill description says the synthetic engine “proves” the recommendation. Its governance section correctly limits the claim. These instructions conflict. + +The application recommendation and simulator geometry share `use_cases.py`. Hard cases generate two separated frequency bands and explicitly identify them as layers. This validates spectral selection under a designed signal separation. It does not validate depth resolution in a scattering Earth. + +See `golden.py:190–213,381–445`. Real depth sensitivity can overlap across frequencies and depend on wave type, lapse time, velocity structure, and scattering. An empirical field claim needs independent observations or controlled signal injection into measured CCFs. + +**Fix:** describe results as conditional synthetic checks. Require field-data diagnostics before claiming site suitability. Test smooth overlapping kernels, mixed wavefields, seasonal source changes, and common artifacts. Compare against a fixed literature default and exhaustive configuration search. Measure recommendation regret on held-out scenarios. + +## EV-01: Missing predictions can earn perfect scores + +**Submission blocker for evaluation claims.** `frugalmind.score_dvv_series:299–307` marks finite predictions as valid. `golden._rms:578–596` requires only ten valid epochs. It evaluates only those epochs and chooses its baseline from them. + +The probe submits valid JSON: ten zeros followed by `null`. NumPy converts the null entries to missing values. Results: + +| Public case | Full zero-series score | Ten zeros, remaining values missing | +|---|---:|---:| +| Easy volcano, 1,095 days | 0.0 | **1.0** | +| Medium fault, 1,095 days | 0.0 | **1.0** | +| Hard groundwater, 913 days | 0.0 | **1.0** | + +The submission observes no waveform and estimates under 1.1% of dates. This is a scorer defect, not evidence that any evaluated model exploited it. The parameter scorer also evaluates a pipeline's own valid mask. It needs availability safeguards too. + +**Fix:** define the scoring support independently of model output. Require finite predictions where the task requires daily estimates. If abstention is allowed, score availability and scientific error jointly. Fix baseline epochs beforehand. Add adversarial tests for nulls, NaNs, selective event omission, and sparse constants. Re-score any existing results after fixing the scorer. + +## EV-02: Truth stripping is not an isolation boundary + +**Major deployment requirement; no private leak demonstrated.** `golden.observed` removes truth keys, but calls `generate` in the same module. The series prompt directs the agent to import that module. In a process with private recipes available, the agent could call `generate` directly or inspect `CASES_BY_ID`. + +The private-dataset documentation recognizes this risk. It requires scorer credentials and recipes outside the agent sandbox. That isolation is a requirement, not an implemented guarantee demonstrated by the repository's key-removal test. + +Exported rows also contain `metadata.recommended_config`, at `frugalmind.py:193–196`. This can remain useful scorer metadata. It must not enter agent-visible context. Public cases are explicitly reconstructible and cannot establish hidden generalization. + +**Fix:** materialize observables in a separate preparation process. Give the agent an artifact identifier and a truth-free reader. Keep recipes, secrets, scorer thresholds, and recommended configurations outside its environment. Test this boundary with an adversarial filesystem/API audit. Record precisely what the agent can access. + +## EV-03: A regression corpus is not an independent gold standard + +**Major.** The generator defines 30 templates. The public manifest contains three cases. Default private generation excludes those three, leaving 27. Documentation variously describes 30 cases and ten cases per suite. See `private_golden.py:85–91`, advisor `references/golden_datasets.md:3–5`, and integration README lines 19–22. + +The hidden set randomizes amplitudes, phases, and event timing. It retains generator families, physical sign patterns, synthesis geometry, and difficulty recipes. This is useful parameter holdout. It does not establish simulator-family or field-domain generalization. + +Easy and medium cases are validation; hard cases are test. Difficulty and split are therefore confounded. A benchmark should report within-regime holdout separately from harder-domain transfer. + +The oracle is the recommended implementation's RMS. Tolerances range from 35% to 60%. These are broad regression drift guards. They are not scientific accuracy criteria. Regenerating expected metrics alongside code changes can normalize a regression unless independent acceptance limits are retained. + +**Fix:** freeze a release-specific benchmark before evaluating models. Hash recipes, observable arrays, truth, scoring code, and thresholds. Use separate development, calibration, and locked test corpora. Hold out source/noise/kernel families as well as parameters. Report paired uncertainty intervals across cases and seeds. + +## EV-04: No executed agent evaluation supports the abstract + +**Major evidence gap.** The reviewed tree provides skill instructions, export adapters, and deterministic scorer tests. It does not provide a model-result table, execution transcripts, prompt/version hashes, or repeated agent runs supporting the abstract's robust-evaluation claim. + +`tests/test_frugalmind_export.py` checks schema and scorer behavior. It does not evaluate elicitation, citation grounding, tool use, reasoning, uncertainty reporting, or adherence to user constraints. A passing scorer test cannot establish advisor reliability. + +**Fix:** run and archive a real evaluation after scorer repair. Compare: + +1. A fixed application-default lookup. +2. A random feasible configuration baseline. +3. Exhaustive or budget-matched configuration search. +4. The same model without the advisor skill. +5. The model with the advisor skill. + +Report recovery, availability, failures, constraint adherence, calibration, latency, and cost. Include uncertainty across repeated runs. Keep assessment of physical measurement separate from conversational correctness. + +## Minimum evaluation record + +| Field | Required content | +|---|---| +| Dataset identity | Version, split, hashes, generator family | +| Execution identity | Code SHA, dependencies, hardware, precision | +| Advisor identity | Skill hash, reference hashes, prompt hash | +| Model identity | Provider identifier, settings, date | +| Tool access | Allowed files/APIs and denied truth access | +| Output | Full response, config, series, masks, errors | +| Score | Metric version, fixed support, component scores | +| Repetition | Scenario seed and agent-run index | +| Failures | Exceptions, timeout, abstention, missing predictions | + +The project can support a useful advisor benchmark. Its strongest current evidence is executable infrastructure. Scientific generalization and agent reliability remain to be demonstrated. diff --git a/review/EXECUTION_PLAN.md b/review/EXECUTION_PLAN.md new file mode 100644 index 0000000..ce6c35a --- /dev/null +++ b/review/EXECUTION_PLAN.md @@ -0,0 +1,74 @@ +# Execution plan for Astra's iteration-1 findings + +Owner: Fable (Claude), with Marine Denolle. +Approved: 2026-09-10 (Marine: "I like the plan, write it somewhere and execute it"). +Supersedes the "Next implementation task" section of `REVISION_PLAN.md`; the package definitions there remain the reference for finding groupings. +Live ledger: `reviews/codameter-gji.review.json`. Audit: `PLAN_AUDIT.md`. + +## Decisions taken (defaults, approved with the plan) + +1. Depth propagation stays a framework section; the abstract no longer claims a demonstrated propagation. Closes SCI-06 (depth), INV-01 by changed text. +2. Advisor and golden set are described as infrastructure; "robust evaluation" is dropped from the abstract. Closes EV-04, AG-02, AG-03 by changed text. EV-02 and EV-03 are stated as future work. +3. Laptop-to-cloud scalability is replaced by the one workload that ran. Closes the claim half of SCALE-01. +4. The Clements and Denolle comparison script in noisepy-dvv-cloud is an external dependency, pinned by commit in the data README (REP-02, needs the commit from Marine). + +Consequence: `REVISION_PLAN.md` packages R8 and R9 reduce to the code items listed under Phase 1. + +## Phase 1: correctness (independent steps, one commit each) + +- [x] **A. Weaver floor (UQ-01).** Required `bandwidth_hz` argument; eq. 20 prefactor; T = sqrt(ln 10)/(pi B), matching band edges to Weaver's -10 dB points; core function taking T directly. Tests: eq. 21 anchor, unit-rescaling invariance, bandwidth monotonicity, existing monotonicity. Update `uq_bayes` and `uq_processing` callers. Regenerate `demo_12_bayes.png`. CHANGELOG entry. +- [x] **B. Mixture variance (UQ-02).** `per_band_marginal_error` returns within, processing (zero unless conditional means are supplied), bias, sd and rmse as separate fields. Test against the probe value 1.79521e-6. +- [x] **C. Scorer (EV-01).** Gold record carries a fixed support (epochs where the reference pipeline is valid) and fixed baseline epochs; missing values inside the support count as error; scorer spec versioned; availability rule shared with the parameter scorer. Tests: ten zeros plus nulls scores 0; truth on support scores 1; sparse constants score low. +- [x] **D. Figure build (REP-01).** `paper/build.py --figures` runs the deviations, multiverse and Bayes generators; every generator writes arrays and metadata beside its PNG. Real-data figures are documented as externally generated with their source run. +- [x] **E. Small fixes.** INV-02: no covariance zeroing at active bounds, flag `at_bound`; connectivity check in `global_reference_inversion` with NaN sigma for unidentified epochs. DET-02: cache key includes package version and generator source hash; one dtype on both routes; atomic writes. SCALE-02: aggregation rejects duplicate task ids and missing shards. SCALE-01: banded solve in `gibbs_dvv`; docstring says what `Cd` is. + +## Phase 2: semantics and calibration + +- [x] **F. Ensemble semantics (UQ-05).** Honor `reference` and `gate` or raise; stack in physical days before decimating; mask low coherence instead of clipping; time-aware second-difference prior or reject irregular grids. +- [x] **G. Measurement covariance (UQ-03/04).** Between-configuration variance with within-method variance removed; prior-sensitivity test; shared-artifact limitation stated with the four-sinusoids case. +- [x] **H. Calibration (SCI-05).** Driver, tests, 20-realisation pilots and locked 200-realisation runs done for clean, shared_source and clock_drift; the manuscript quotes the locked values. Script over independent realizations: 68/95 percent pointwise coverage, width, bias, failures, plus one shared-drift scenario. Pilot 20 seeds, then 200. Predefined margin: coverage within 3 points of nominal. Table replaces the single-realization sentence. + +## Phase 3: manuscript pass (R1 + R10) + +- [x] Estimand table cited by every caption (SCI-01); Table 2 split. +- [x] Single-paragraph abstract narrowed per the decisions (SCI-06, EV-04, FMT-01). +- [x] WCC/MWCS sign (SCI-10); signed recovery errors (SCI-11); predefined branch rule (SCI-09). +- [x] Trailing reference presented as an ablation (SCI-03); estimator prescriptions qualified against Yuan et al. 2021 (SCI-04); conditional wording for dominance and the surrogate (SCI-02). +- [x] LJR count from an explicit mask, NZ/NE label, statistics from one output (SCI-07, FIG-02); survey bound direction and extraction statuses (SCI-08). +- [x] Figure 1c trace vs caption, units, legends, full-range views (FIG-01, FIG-03). +- [~] Data availability and end matter (COMP-01, REP-02, REP-03): availability statement and AI disclosure drafted; funding, contributions, archive DOI and the noisepy-dvv-cloud commit need Marine. + +## Phase 4 + +- [ ] Diff against `b6dbbd0`; run the reviewer in reconciliation mode; reconcile the ledger. + +## Inputs needed from Marine + +| Input | Blocks | +|---|---| +| Gate 1 member configurations (windows per member) or the run manifest | Recomputing field `dvv_err_within` from `cc` | +| noisepy-dvv-cloud commit for `scripts/compare_cd2022.py` and the real-data figure scripts | REP-02, SCI-07 recomputation, real-data figure provenance | +| Archive destination and rights for the field products | Data availability | +| Authorship, funding, contributions | End matter | + +## Log + +- 2026-09-10: plan written; Phase 1 started on branch `docs/sign-convention-manuscript`. +- 2026-09-10: step A done. Bayes demo before/after the corrected floor: s 6.16 -> 10.35, tau 3.85e-4 -> 3.72e-4, L 21.2 -> 21.3 d, N_eff 18.0 -> 18.6 of 229, median calibrated within-method sigma 1.87e-3 -> 1.89e-3 (s absorbs the constant, as predicted). Raw floor medians now 2.7e-4 (0.4-1.0 Hz) and 1.8e-4 (0.6-1.4 Hz). The Cd +-1.96 sigma band covers 100% of truth epochs before and after, the posterior band 49-50%: the "nominal rate" sentence in the Bayes section is wrong in the over-wide direction (Phase 2, step G). s of 10 means the residual scatter is an order of magnitude above the coherence floor; report it in Phase 3. +- 2026-09-10: step B done. No figure or manuscript number depended on the function. +- 2026-09-10: step C done. Ten zeros plus nulls now score exactly as all zeros on the public cases; manifest expected metrics unchanged. Found on the way: the cached float32 CCFs shift the oracle RMS by 2.4e-8 relative (DET-02, step E), and the mypy hook env had drifted to numpy 2.5 (pinned). +- 2026-09-10: step E done (INV-02 bounds and connectivity, DET-02 exact versioned cache, SCALE-02 aggregation checks, SCALE-01 banded sampler). Step D code and tests are in; the full figure regeneration with sidecars is running and its outputs land in the next commit. +- 2026-09-10: steps F, G and the H driver done; all generated figures regenerated with sidecars. Bayes demo under the corrected ensemble: s 12.1, L 39 d, N_eff 22.8 of 229, no missing epochs (default prior has no gating). Three coverages of the truth on that realization: member level 0.955 at 95% and 0.80 at 68% (Cd as a per-measurement covariance is close to calibrated); credible band 0.64 (under-covers: shared bias mean(mu - truth) = -1.5e-4, RMS 7.5e-4); mu +- sigma_Cd 1.00 (over-wide by construction, this is the comparison the manuscript currently quotes and it must go). Prior shares: tau^2 a few percent, lambda up to ~10% for very smooth series (reported in prior_weight). demo_7_reference.png differs from the committed render with unchanged code: check in the Phase 3 figure pass. Pilot calibration (20 clean + 20 shared-drift) running. +- 2026-09-10, Phase 3 in progress. Pilot calibration, clean scenario, 20 realisations: member-level coverage 0.955 +- 0.001 at 95% (within the predefined 3-point margin) and 0.804 +- 0.003 at 68%; credible band on mu covers the truth 0.593 +- 0.011; mu +- sigma_Cd covers 1.000 (the comparison the draft quoted; dropped); s = 11.7 +- 0.1; tau^2 prior share 0.10 +- 0.03; N_eff 33 +- 2 of 229. Field comparison recomputed by scripts/compare_gate1.py under stated rules: LJR 0.985 on 579 d (slope 1.07), ARV 0.905 on 357 d (slope 2.15), RXH 0.829 on 446 d (slope 0.81); the draft's 681 days was the raw daily overlap. Figure 1c checked from its sidecar: WCS fails on the noisy landslide signal (3.8% RMS) and the caption now says so. Manuscript part 1 applied (abstract, introduction, estimand table, results wording, branches, stacking, deployment, discussion, conclusions, appendices, availability, AI disclosure draft); part 2 (Bayes section) waits for the shared-drift pilot. Legends moved off the data in seven figures; deviations panel retitled RMS. +- 2026-09-10, calibration scenarios. The clock-drift pilot (20 realisations) is indistinguishable from clean (member 95% coverage 0.953, credible band 0.61, no shared bias): a lapse-independent shift has opposite signs on the two branches and every default configuration measures both, so it cancels, as Section 3.9 says. The scenario is kept under its real name (clock_drift) as an immunity test, the manuscript sentences that asserted a shared drift bias were removed before any commit, and a genuine shared artefact (seasonal late-coda source noise beyond 6 s lapse, 0.2% spurious seasonal dv/v) is added as shared_source and piloted. Locked 200-realisation runs will use single-threaded BLAS; six workers with default threading drove the load average past 200. +- 2026-09-10: full test suite after Phases 1-3 code: 327 passed, 1 skipped (disba present), 19 min on a loaded machine. Closure re-runs of Astra's probes are under review/evidence/closure/. +- 2026-09-10: Phase 3 committed (b426c4e). Manuscript builds to 80 pages with no unresolved references. Locked calibration runs (200 realisations, seeds 2000-2199, single-threaded BLAS, 6 workers) started 12:54 for clean, shared_source, clock_drift in that order; when they land, regenerate calibration_table.tex, refresh the abstract and Bayes-section numbers, rebuild, commit. Phase 4 (reviewer iteration 2 against b6dbbd0) is ready to run. +- 2026-09-10: Gate 1 error columns rescaled to the corrected floor (scripts/correct_gate1_within_error.py; factor 0.328 at 2-4 Hz, originals kept, log in dvv2y/correction.json); the member windows were not needed because all members share the band. noisepy-dvv-cloud/src/noisepy_dvv_cloud/dvv.py switched to weaver_stretching_error_band (edited in that repository, left uncommitted for Marine). Still needed from Marine: the Gate 1 run commit and --use-case. +- 2026-09-10: locked runs done (200 realisations each, seeds 2000-2199, 56-58 min per scenario). Clean: member 95% 0.956 +- 0.000, 68% 0.808, credible band 0.590 +- 0.004, s 11.67. Shared source: member 95% 0.950, credible band 0.340, RMSE(mu) 0.161% vs 0.067%. Clock drift: member 95% 0.954, credible band 0.604 (immune, as stated). Table regenerated from the locked runs; manuscript numbers refreshed; PDF 80 pages, clean. Phase 4 is next and is Marine's call. + +- 2026-09-10, Codex reconciliation: inspected commits through `62b63b5` against + the original audit. Repaired advisor routes, non-daily input acceptance, + moving-reference gating, missing-member coverage, and cache geometry identity. + Narrowed covariance and availability claims further. See `REVISION_STATUS.md` + for all 37 findings and outstanding tasks. This bounded check does not mark + the full reviewer iteration complete or close the historical ledger. diff --git a/review/PLAN_AUDIT.md b/review/PLAN_AUDIT.md new file mode 100644 index 0000000..d5e1295 --- /dev/null +++ b/review/PLAN_AUDIT.md @@ -0,0 +1,88 @@ +# Audit of the revision plan + +Author: Fable (Claude), for Marine Denolle. +Date: 2026-09-10. +Audited: `review/REVISION_PLAN.md` and the iteration-1 review at `bc47511`. +Manuscript hash at audit: `sha256:582a09ee...` (unchanged since the review). + +## Bottom line + +The review's fatal findings hold. I re-derived UQ-01 against Weaver et al. (2011) eq. 20 and UQ-02 and EV-01 against the source, and re-read the code behind UQ-03/04/05 and INV-02. Nothing I checked is wrong. One tier is overstated (UQ-02), and the numerical reach of UQ-01 into the paper is smaller than the plan assumes. + +The plan's working rules are good. Its shape is not. It schedules the expensive "supply the missing evidence" branch for the depth, advisor and cloud-scaling claims and only allows "narrow the claim" in the last package, although the review offered both branches for each. It puts the two one-file fatal fixes third, behind a specification package, when they are independent of it and everything downstream must be regenerated from them. And it never inventories which figures each fatal finding touches, so it cannot size the regeneration. + +Decide the three scope questions now. If the answer is to narrow, the four packages that need external inputs or new experiments (R5 in part, R8, R9, the depth items of R6) shrink to code hygiene and the rest is a revision measured in weeks. + +## What I verified + +| ID | How | Verdict | Reach into the paper | +|---|---|---|---| +| UQ-01 | Weaver eq. 20, arXiv 1103.1785 p. 7; `uq_measurement.py:76-124` | Holds. Code omits T and its variance prefactor is (1-X^2)/(2X^2) against Weaver's (1-X^2)/(4X^2). Manuscript line 1340 already writes the correct 1/sqrt(B) dependence, so the paper is right and the code disagrees with it. | `demo_12_bayes` (ensemble bands 0.4-1.0 and 0.6-1.4 Hz, so member weights shift about 15%; the 2x prefactor is absorbed by the fitted s^2), the N_eff statement, and the field `dvv_err_within` column (constant factor at 2-4 Hz). Recovery-RMS figures, the sqrt(N) figure and the field r values do not depend on it. | +| UQ-02 | `uq_processing.py:220-266` | Holds; the code comment admits the proxy. | None. `per_band_marginal_error` has no caller outside tests and the depth section has no figure. Tier should be Major (code), not Fatal (paper). Five-line fix. | +| EV-01 | `frugalmind.py:299-307`, `golden.py:578-596` | Holds. Ten zeros land on pre-event days, the baseline is drawn from them, RMS is zero. | Advisor evaluation claim only. Existing test `test_series_scorer_truth_vs_null` does not cover it. | +| UQ-03/04 | `uq_bayes.py:297-344` | Holds. `method_std` is the raw across-member SD, which already contains within-method noise, then `within_std` is added again. Docstring at lines 37-39 contradicts the dataclass at 175-186. | `demo_12_bayes` diagonal and the "covers the truth at the nominal rate" sentence at line 1010. | +| UQ-05 | `uq_bayes.py:121-157` | Holds. `reference` and `gate` keys are ignored; CCFs are subsampled by cadence before stacking; cc is clipped to 0.5. | `demo_12_bayes`. | +| INV-02 | `linear_fit.py:544-549`, `uq_measurement.py:419-429` | Holds. Covariance zeroed at active bounds; pseudoinverse without a connectivity check. | No figure. Code hygiene. | +| SCI-10 | Manuscript lines 95-125 and 1349-1351 | Holds. With eps > 0 meaning a delayed phase, argmax of the integral of c(t) r(t - tau) sits at tau = +eps t_i, not -eps t_i. One-line fix. | Appendix text. | +| SCI-07 | `reproduction_probes.json`, manuscript line 1139 | Holds, and I can say where 681 probably comes from: 727 rows minus 46 lost to a 45-day centred window. The sentence attributes the count to the 150-day burn-in comparison, which leaves 578. Confirm in R7. | Deployment section and Fig. realdata_1. | +| SCI-08 | Manuscript line 1422 | Holds, and it is a direction error. Abstract-only "n/r" cells can only flip to "reported", so the apparent under-reporting is an upper bound on true under-reporting. The text calls it a lower bound. One sentence. | Appendix survey. | + +Not independently verified: SCI-02/03/04/05/09, the FIG and FMT items, AG-02/03, EV-02/03/04, REP-02/03, DET-01, SCALE-02, COMP-01. I read the passages behind SCI-01 and SCI-06 and agree with both; the fix for SCI-01 is textual (abstract, Table 2, section 3.3), not experimental, because lines 476-480 already state the SD-versus-SE distinction. + +## Critique of the plan + +**1. It defers the decision that sets its size.** The abstract promises depth propagation, robust advisor evaluation, and laptop-to-cloud scalability. The review gave each an "add the evidence" branch and a "narrow the claim" branch. The plan takes the first for all three and leaves narrowing to R10. That is backwards: the decision determines whether R5, R8 and R9 exist. My recommendation is to narrow all three. Keep the depth section as the framework it already says it is, and cut "illustrate its use by propagating errors" from the abstract. Describe the advisor and golden set as infrastructure and cut "robust evaluation". Replace "scalability from laptop to cloud" with the one workload that was run. Under that decision the closure modes are: + +| Mode | Findings | +|---|---| +| Fix | UQ-01, UQ-02, UQ-05, DET-02, INV-02, EV-01, AG-01 routes, SCI-01/03/07/08/09/10/11, FIG-01/02/03, FMT-01, REP-01/03, COMP-01, SCALE-02, the double-count and docstring parts of UQ-03/04, SCI-05 | +| Narrow | SCI-06, EV-04, AG-02/03, INV-01, SCALE-01, SCI-02 (conditional wording), SCI-04 (qualify prescriptions) | +| Defer as stated future work | EV-02, EV-03, the joint-likelihood question in UQ-03 | +| Needs Marine's input | REP-02 (external comparison driver) | + +The reviewer skill has no "claim withdrawn" verdict, but a C4 finding is RESOLVED when the changed text no longer makes the claim. Each package should name the mode it intends per finding so iteration 2 checks the right thing. + +**2. The order is wrong for the fatal math.** R3's two fixes are one file each, analytically testable, and independent of R1. Putting an eight-item specification package ahead of them delays the corrections that the Bayes figure, the field error bars and the calibration experiment all depend on. Run R3 and R2 as the first two pull requests, in parallel, and write the R1 specification alongside them. + +**3. Inventory before derivation.** R3's last checkbox, "Inventory affected figures", should be its first. The table above is that inventory. The finding that s^2 absorbs the prefactor and that only the two-band ensemble and the error-bar scale change is what tells you the regeneration is one figure and two columns, not the paper. + +**4. The field error bars do not need the external pipeline.** REP-02 is listed as an input the plan waits on. For UQ-01 it is not: the parquet files carry a per-epoch `cc` column, the band is fixed at 2-4 Hz and the window is known, so `dvv_err_within` can be recomputed from the corrected formula without rerunning correlations. The r values do not change. The external driver is still needed to regenerate the comparison statistics, but that is a separate finding. + +**5. R4 breaks the plan's own splitting rule.** DET-02 (cache identity, atomic writes, dtype) is infrastructure. UQ-05 (stack durations under cadence, ignored reference axis) is science. The plan says to split such packages; R4 combines them. + +**6. The acceptance criteria are mostly not testable.** "Every reported quantity has units, assumptions, and target" and "code and manuscript use the same definitions" cannot fail. R6 says to predefine margins and then does not. Proposals: R1 closes with a single estimand table in the manuscript (quantity, units, datum, evaluation support, target) that every figure caption cites. R3 closes when a test reproduces Weaver's own numeric example (eq. 21: t1 = 12.5 us, t2 = 50 us, omega_c = 15 rad/us, T = 0.56 us gives 4e-4 times sqrt(1-X^2)/(2X)) and a unit-rescaling test returns the same fraction. R6 margins: 95% pointwise coverage within 3 points of nominal at 200 or more independent realizations, bias below 10% of the event amplitude, width reported as a ratio to truth RMS, and failure rate reported alongside. + +**7. R5 as written is a research program.** "Compare a dependence-aware joint model with a pipeline mixture", "represent shared waveform and reference errors explicitly", GLS in the stress inversion, and time-band covariance shapes are a second paper. The minimum this paper needs for its C_d claim is smaller: remove the double count (the between-configuration term should come from the beta_k spread or from member means with within-method noise subtracted, not from the raw member SD); fix the docstring; replace the single-realization "covers at the nominal rate" sentence with the R6 coverage number; and state the shared-artifact limitation, using the reviewer's four-identical-sinusoids counterexample as the stated limit of what agreement can detect. + +**8. R9's banded solver is small; the scaling study is not.** The Gibbs precision matrix is a diagonal plus a pentadiagonal second-difference term. `scipy.linalg.solveh_banded` turns the cubic step into a linear one in a few dozen lines. Do that regardless. Do not run scaling experiments unless the claim stays. + +**9. Items the plan lacks.** + +- The reviewer skill reads its manifest from `reviews/.review.json`. Astra wrote `review/codameter-gji.review.json`. Unless the file is moved, linked, or the skill is pointed at it, iteration 2 starts a fresh iteration 1 and the ledger is lost. +- The local skill is now v2.5 (commit `c6f09c9`, adds the scientific-register subagent); the review ran v2.4. Expect an INTRODUCED-BY-RECALIBRATION bucket. That is not a regression. +- No effort estimates or target date, so feasibility cannot be judged. +- The full suite does not finish in the 540 s budget. Add a slow marker so the pre-push check actually runs. +- REP-01: six figure generators are outside `paper/build.py`. "Regenerate derived artifacts" means nothing until they are wired in. That is week-one plumbing, not an R7 item after R6. + +## What the plan gets right + +Never refresh golden thresholds to pass. Preserve the review and its probes as regression evidence. Separate mathematical correctness from calibration. Pilot before expensive runs. Small commits. The inputs table. Keep all of that. + +## Proposed first two weeks + +Week one, in parallel: + +1. Marine answers the three scope questions. +2. PR: Weaver floor takes a bandwidth argument, uses the eq. 20 prefactor, documents the T convention; tests for the eq. 21 anchor, unit invariance and bandwidth dependence; update the two callers; recompute the field `dvv_err_within` column from `cc`. +3. PR: `per_band_marginal_error` drops the floor-variance term, returns bias and RMSE as separately named fields. +4. PR: scorer evaluates on a support fixed by the task, treats missing values as failure or as an availability penalty, draws the baseline from truth-defined epochs; add Astra's ten-zero probe as a test. +5. PR: `paper/build.py` runs every figure generator and writes the numerical arrays beside each figure. +6. Move or link the manifest to `reviews/codameter-gji.review.json`. + +Week two: UQ-05 (honor or reject `reference` and `gate`; stack before decimating), INV-02, the C_d double count and docstring, regenerate `demo_12_bayes`, then the R6 pilot for coverage on the Bayes synthetic. + +Then one manuscript pass merging R1 and R10: estimand table, abstract, SCI-07 count, SCI-08 direction, SCI-10 sign, captions. Then iteration 2 of the reviewer. + +## Readiness for iteration 2 + +The manuscript hash is unchanged since the review, so the iteration-2 diff will be exactly the revision. Name ledger IDs in every commit message so the reconciliation can cite changed text. Re-run `review/evidence/audit_probes.py` and `downstream_probes.py` as the closure evidence for the code findings; their JSON outputs are the before, the re-run is the after. diff --git a/review/README.md b/review/README.md new file mode 100644 index 0000000..0ab4074 --- /dev/null +++ b/review/README.md @@ -0,0 +1,90 @@ +# Codameter scientific audit + +This page preserves the iteration-1 assessment. See the current +[revision reconciliation](REVISION_STATUS.md) for implemented repairs, +verification evidence, and remaining submission work. + +**Major revision is required before GJI submission.** + +The premise is scientifically useful: quantify processing sensitivity explicitly. Seeded experiments, inspectable configurations, and independent product comparisons are strengths. However, the current uncertainty calculations contain substantive defects. The golden scorer can reward nearly empty predictions perfectly. Several manuscript claims exceed the demonstrated evidence. + +This is an advisory review for the authors. It covers the current paper, software, and advisor. It does not determine a journal decision. + +## Read the review + +1. [Manuscript, experimental design, and figure styling](01_manuscript_and_figures.md). +2. [Deterministic errors, probabilistic uncertainty, and scalability](02_software_and_uncertainty.md). +3. [Advisor skill and golden evaluation dataset](03_advisor_and_golden_dataset.md). + +The [issue ledger](issue_ledger.csv) records 37 actionable findings. The [review manifest](codameter-gji.review.json) preserves their status and provenance. Raw focused findings, scripts, logs, and renders accompany [the evidence index](evidence/README.md). + +The [revision work plan](REVISION_PLAN.md) assigns staged Codex tasks. +It records dependencies, acceptance criteria, and required author inputs. + +## Findings requiring attention first + +| Priority | Finding | Evidence | +|---|---|---| +| Submission blocker | Weaver error floor omits a bandwidth timescale | Dimensional analysis, primary equation, executable probe; UQ-01 | +| Submission blocker | Floor variability is incorrectly added as methodological variance | Exact zero-mean mixture counterexample; UQ-02 | +| Evaluation blocker | Ten zeros plus missing predictions score perfectly | All three public golden cases return 1.0; EV-01 | +| Major | Pipeline dependence and shared bias invalidate universal covariance claims | Likelihood inspection and common-artifact counterexample; UQ-03/04 | +| Major | Abstract promises unshown depth and agent validation | Abstract-to-results trace; SCI-06, EV-04 | +| Major | Field comparison and figure provenance are inconsistent | Date counts, component labels, omitted generators; SCI-07, REP-01/02 | + +“Blocker” means resolve before relying on that claim. These are repairable findings, not rejection of the premise. + +## Eight-criterion assessment + +| Criterion | Tier | Assessment | +|---|---|---| +| C1 Scientific question and novelty | Good | Valuable joint-choice question; sharpen novelty against existing comparisons. | +| C2 Methods and soundness | Fatal for present UQ claims | Correct formulas, dependence, estimands, and calibration before submission. | +| C3 Reproducibility and open science | Poor | Local code runs; complete published-result reconstruction remains blocked. | +| C4 Evidence and conclusions | Poor | Depth, advisor, coverage, and operational claims exceed evidence. | +| C5 Presentation and communication | Fair | Readable layout; consequential figure contradictions and missing units. | +| C6 Literature integration | Fair | Broad bibliography; estimator prescriptions and survey denominators need correction. | +| C7 Impact and significance | Good | Reporting and calibrated propagation could materially improve monitoring. | +| C8 Ethics and compliance | Fair | Final acknowledgements, disclosures, and data-access details remain unfinished. | + +Tiers describe the current draft, not author capability. Citation diversity is surfaced without scoring or identity inference. + +## Recommended revision sequence + +1. **Define the observation target.** Separate pair measurements, network means, spatial heterogeneity, reference offsets, and depth sensitivity. +2. **Repair uncertainty and scoring mathematics.** Correct the floor, mixture variance, shared-data treatment, missingness scoring, and unidentified directions. +3. **Validate calibration independently.** Use repeated held-out wavefields, common artifacts, source changes, gaps, and event transients. Report coverage, width, bias, and failures. +4. **Complete the reproduction bundle.** Pin inputs, environments, configurations, figures, comparison masks, and numerical outputs. Reconcile field counts and labels. +5. **Align manuscript scope.** Add actual depth and advisor evaluations or narrow those claims. Then finalize figure styling and end matter. + +## Verification scope + +The existing targeted numerical suite passed **144 tests**. The current source compiled into a **74-page PDF**. All 17 existing figure pages received visual inspection. Six selected pages were checked again after fresh compilation. + +Compilation reused existing figure assets. It did not regenerate every experiment. The advertised build omits six figure generators. + +The full suite reached its 540-second audit limit. Captured progress shows 261 passes and one skip. Thirty-nine tests remained unfinished; no failures were visible. These are partial progress counts, not completed pytest totals. The 144-test targeted suite overlaps those tests. Exact commands and outcomes appear in [the reproduction evidence](evidence/reproducibility.md). + +The audit reproduced defects using saved scripts. It did not access private golden recipes, run external models, deploy cloud jobs, or reproduce raw field waveforms. No scientific source files were changed. + +## Provenance and disclosure + +- Audit date: 2026-09-10. +- Source: `paper/manuscript_marine.qmd`. +- Repository commit: `b6dbbd03ad3a9e7b8daac3847a470b93b6918cc8`. +- Review skill: Pre-Submission Reviewer v2.4, commit `f230303`. +- Author profile: default; review iteration: 1. +- Reviewer: Codex/GPT-6; exact runtime model identifier unavailable. +- Method: nine focused review scopes plus executable audits. + +Suggested process disclosure: + +> This draft received an advisory AI-assisted pre-submission review. The workflow used Denolle Group Pre-Submission Reviewer v2.4 with Codex/GPT-6, iteration 1. The audit included local code execution and selected primary-source checks. It does not endorse the manuscript's validity. The authors retain responsibility for adjudicating findings and final content. + +Author adjudication has not yet been recorded. The statement deliberately does not claim completed human approval. It also reflects actual execution, unlike the skill's generic non-execution template. + +## Ledger for the next iteration + +Use [codameter-gji.review.json](codameter-gji.review.json) as the authoritative ledger. Every finding is currently `OPEN`. Preserve the manuscript hash and provide a revision diff. Reconcile findings using their stable identifiers and required evidence. The CSV offers a readable working view. + +Live copy for the reviewer skill: `reviews/codameter-gji.review.json` (converted 2026-09-10; this file stays frozen as the iteration-1 record). diff --git a/review/REVISION_PLAN.md b/review/REVISION_PLAN.md new file mode 100644 index 0000000..e06ed6a --- /dev/null +++ b/review/REVISION_PLAN.md @@ -0,0 +1,299 @@ +# Codameter revision work plan + +Owner: Codex, working with Marine Denolle. +Created: 2026-09-10. +Baseline: `b6dbbd03ad3a9e7b8daac3847a470b93b6918cc8`. +Status: planned; scientific implementation has not started. + +## Objective and scope + +Prepare a scientifically defensible, reproducible GJI research submission. +Correct measurement-error calculations and validate their stated interpretation. +Make the advisor executable and its scoring trustworthy. +Keep deployment claims proportional to measured scaling evidence. + +The immediate deliverable is the measurement-methods paper. +Depth inference and actual model evaluations are conditional extensions. +Keep their claims provisional until supporting experiments exist. + +## Working rules + +- Confirm each review finding before changing scientific behavior. +- Preserve the original review and its numerical evidence. +- Add focused regression tests for demonstrated scientific defects. +- Separate mathematical correctness from empirical uncertainty calibration. +- Never refresh golden thresholds merely to pass tests. +- Edit `paper/manuscript_marine.qmd`, then regenerate derived artifacts. +- Record changed results, reasons, and downstream consequences. +- Close findings only with linked evidence. +- Use small commits and the repository's pre-push checks. +- Run local pilots before expensive calibration or scaling runs. + +Keep the original iteration-1 review manifest unchanged. +Track implementation through the checkboxes below. +Create a new reconciliation manifest after substantive revisions. +Preserve earlier ledger states when closing findings. + +## Execution order + +`R1 → R2 → R3 → R4 → R5 → R6 → R7 → R8 → R9 → R10` + +R2 does not depend on statistical model selection. +R7's data inventory can begin before calibration finishes. +Execute sequentially unless parallel agent work is requested. +Each package produces a reviewable change set. +Split larger packages when infrastructure and science changes diverge. + +| Package | Deliverable | Dependencies | Status | +|---|---|---|---| +| R1 | Observation and uncertainty specification | Audit baseline | Queued first | +| R2 | Scoring rejects incomplete predictions | Audit probes | Queued | +| R3 | Correct floor and variance accounting | R1 | Queued | +| R4 | Consistent configurations, time, references, caches | R1 | Queued | +| R5 | Defensible covariance and downstream inference | R3, R4 | Queued | +| R6 | Independent calibration benchmark | R2–R5 | Queued | +| R7 | Field and figure reproduction pipeline | Inventory now; results after R6 | Queued | +| R8 | Executable advisor and isolated evaluation | R2, R4, R6 | Queued | +| R9 | Structured computation and deployment checks | R5, R6 | Queued | +| R10 | Revised manuscript and submission package | R6–R9 | Queued | + +## R1. Define observations and uncertainty targets + +Files: `docs/`, manuscript methods, measurement-module documentation. +Findings: SCI-01/02/03/04/09/10/11, DET-01, UQ-03/04. + +- [ ] Recheck mathematical findings against primary sources. +- [ ] Define physical dv/v, reference datum, and delay conventions. +- [ ] Distinguish pair, network, temporal, and depth estimands. +- [ ] Separate spatial heterogeneity, measurement variance, and systematic bias. +- [ ] Identify configurations measuring the same physical target. +- [ ] Specify alignment, scoring masks, events, and failure metrics. +- [ ] Define branch selection and reference linking explicitly. +- [ ] Document the surrogate wavefield's physical limitations. + +**Acceptance:** every reported quantity has units, assumptions, and target. +Analytic pulse examples reconcile the delay-sign conventions. +Code and manuscript use the same definitions. + +## R2. Repair scoring before evaluating agents + +Files: `frugalmind.py`, `golden.py`, scorer tests. +Findings: EV-01, part of EV-03. + +- [ ] Reproduce the ten-zero-plus-null shortcut unchanged. +- [ ] Define scoring support independently of returned predictions. +- [ ] Reject missing values under the daily-series contract. +- [ ] Define separate availability-aware scoring where abstention is allowed. +- [ ] Fix baseline epochs independently of submitted valid masks. +- [ ] Validate finite numbers, lengths, units, and configuration values. +- [ ] Test nulls, NaNs, sparse constants, and event omission. +- [ ] Apply availability rules to parameter scoring too. +- [ ] Version scoring changes and preserve original thresholds. + +**Acceptance:** the shortcut fails on all public cases. +Legitimate recovery retains meaningful scores on fixed support. +Failures and abstentions remain visible in exported results. + +## R3. Correct measurement-error calculations + +Files: `uq_measurement.py`, `uq_processing.py`, associated tests. +Findings: UQ-01/02; prerequisites for SCI-05. + +- [ ] Derive bandwidth timescale, prefactor, and branch normalization. +- [ ] Add required spectral information to the floor API. +- [ ] Document compatibility changes and update callers. +- [ ] Test dimensions, limiting cases, and bandwidth dependence. +- [ ] Replace floor-spread substitution with justified variance accounting. +- [ ] Separate bias correction, bias uncertainty, variance, and MSE. +- [ ] Verify total variance using analytically known mixtures. +- [ ] Inventory affected figures, tutorials, and depth examples. + +**Acceptance:** independent analytic tests pass. +Noise realizations reproduce the expected precision scaling. +Changed expectations have documented scientific explanations. + +## R4. Make pipeline semantics consistent + +Files: `deviations.py`, `uq_bayes.py`, `golden.py`, `use_cases.py`. +Findings: UQ-05, DET-01/02, part of AG-02. + +- [ ] Route measurements through one canonical pipeline contract. +- [ ] Honor configuration axes or reject unsupported combinations. +- [ ] Preserve stack and reference durations under output decimation. +- [ ] Support physical timestamps or reject unsupported irregular grids. +- [ ] Make reference construction and warm-up masks explicit. +- [ ] Handle low coherence without improving its reported quality. +- [ ] Match comparison metrics, reference datum, and evaluation support. +- [ ] Include generator version and precision in cache identity. +- [ ] Return consistent cold, warm, and cache-bypassed arrays. +- [ ] Write caches atomically and record input hashes. + +**Acceptance:** configuration changes have their documented scientific effects. +Cadence changes cannot silently redefine stack durations. +Cache routes agree within declared tolerances. +Invalid configurations fail before expensive execution. + +## R5. Derive defensible uncertainty propagation + +Files: `uq_bayes.py`, `inverse/`, `uq_depth.py`. +Findings: UQ-03/04, INV-01/02, SCI-05/06. + +- [ ] Compare a dependence-aware joint model with a pipeline mixture. +- [ ] Select the model using the R1 observation target. +- [ ] Represent shared waveform and reference errors explicitly. +- [ ] Account for configuration-specific temporal response where necessary. +- [ ] Distinguish posterior covariance from constructed error covariance. +- [ ] Prevent double-counting noise and configuration offsets. +- [ ] Check prior-predictive behavior and prior sensitivity. +- [ ] Add chain diagnostics where sampling remains necessary. +- [ ] Test duplicate configurations and shared-artifact counterexamples. +- [ ] Add GLS support for temporal covariance. +- [ ] Detect disconnected references and unidentified directions. +- [ ] Replace zero-boundary variance with justified constrained uncertainty. +- [ ] Define time-band covariance shapes for depth extensions. + +**Acceptance:** each covariance follows a documented probability model. +Analytic limits and identifiability checks pass. +Shared-error limitations remain explicit and experimentally tested. + +Retained depth claims require kernels, recovery, resolution, and coverage. +Otherwise describe the interface and defer empirical depth claims. + +## R6. Establish independent calibration evidence + +Deliverables: versioned experiment configurations, runner, and numerical tables. +Findings: SCI-02/05, UQ-04, EV-03, AG-03. + +- [ ] Separate development, calibration, and locked test scenarios. +- [ ] Hold out waveform families as well as parameters. +- [ ] Include null, trend, seasonal, and transient truths. +- [ ] Vary bandwidth, coherence, references, stacks, and independent seeds. +- [ ] Include source drift, timing errors, gaps, and shared artifacts. +- [ ] Include overlapping kernels when making depth claims. +- [ ] Measure bias, RMSE, coverage, width, availability, and failures. +- [ ] Report event amplitude, timing, and trend errors separately. +- [ ] Quantify uncertainty across independent realizations. +- [ ] Predefine acceptance margins before examining locked-test results. +- [ ] Preserve failed runs and configuration-level numerical outputs. + +Start with a small local pilot for runtime estimation. +Choose replicate counts from desired coverage precision. +For example, 500 independent runs give roughly one percentage +point standard error near 95% coverage. +That example is not a mandatory count for every scenario. + +**Acceptance:** retained claims hold on locked scenarios. +Coverage has reported precision and practically useful interval width. +Misspecified scenarios expose limitations instead of disappearing from summaries. + +## R7. Reproduce field comparisons and every figure + +Files: `paper/build.py`, `paper/data/gate1/`, figure generators. +Findings: REP-01/02/03, SCI-07/08, FIG-01/02/03. + +- [ ] Inventory field archives, products, licenses, and checksums. +- [ ] Locate and pin the external comparison implementation. +- [ ] Record stations, components, bands, dates, and preprocessing. +- [ ] Reconcile LJR's count with the actual burn-in mask. +- [ ] Resolve NZ/NE labels and reference-product dates. +- [ ] Prespecify joins, smoothing, interpolation, and exclusions. +- [ ] Generate plotted and written statistics from identical outputs. +- [ ] Add all six omitted figure generators to orchestration. +- [ ] Save numerical arrays and metadata beside every figure. +- [ ] Reconcile survey extraction status and unique-study counts. +- [ ] Record source, dependencies, hardware, settings, and invocations. +- [ ] Verify clean-checkout reproduction with declared inputs. + +**Acceptance:** one driver reproduces the retained scientific results. +Missing inputs and dependencies fail loudly and specifically. +Required artifacts are archived or accessible through pinned fetch routes. +Rendering remains distinguishable from numerical regeneration. + +## R8. Make the advisor and evaluation contract reliable + +Files: `.claude/skills/codameter-advisor/`, `use_cases.py`, `golden.py`. +Findings: AG-01/02/03, EV-02/03/04. + +- [ ] Provide public development cases for every supported application. +- [ ] Respect case-specific targets and channel aggregation. +- [ ] Propagate elicited constraints into validated executable settings. +- [ ] Replace claims that one synthetic proves field suitability. +- [ ] Compare repeated paired-seed results with uncertainty. +- [ ] Separate truth-bearing scorer and observables-only agent environments. +- [ ] Keep answers and recommended configurations outside agent context. +- [ ] Test filesystem and API boundaries adversarially. +- [ ] Reconcile documentation with actual corpus sizes and splits. +- [ ] Freeze benchmark identity independently of estimator updates. +- [ ] Add lookup, random, search, and skill-ablation baselines. +- [ ] Record prompts, versions, tools, responses, failures, and costs. + +**Acceptance:** all documented application routes execute correctly. +Scoring resists known shortcuts and isolation checks pass. +Agent reliability claims require archived actual model evaluations. +Otherwise, describe infrastructure pending that evaluation. + +## R9. Validate scaling without changing the science + +Files: `uq_bayes.py`, `bench.py`, execution manifests. +Findings: SCALE-01/02, REP-03. + +- [ ] Profile corrected inference on increasing epoch counts. +- [ ] Exploit banded precision or state-space structure where applicable. +- [ ] Apply shared-reference terms through low-rank operations. +- [ ] Retain a small dense reference for equivalence checks. +- [ ] Reject duplicate cells, missing shards, and mixed versions. +- [ ] Verify retries preserve unique scientific results. +- [ ] Measure runtime, peak memory, throughput, and failures. +- [ ] Document tested scales and supported execution environments. + +**Acceptance:** scaling preserves corrected scientific outputs within tolerances. +Aggregation verifies complete, unique results with matching provenance. +Deployment claims name measured workloads and resources. + +## R10. Revise and reconcile the submission package + +Files: manuscript QMD, figures, bibliography, release metadata. +Findings: all remaining SCI, FIG, FMT, COMP entries. + +- [ ] Rewrite the abstract around demonstrated final results. +- [ ] Distinguish SD, SE, uncertainty, bias, and RMSE throughout. +- [ ] Qualify novelty and estimator prescriptions against cited evidence. +- [ ] Correct branch-selection, delay-sign, and stacking statements. +- [ ] Align depth, advisor, and operational claims consistently. +- [ ] Replace contradictory captions and development labels. +- [ ] Add units, visible legends, full-range summaries, calibration plots. +- [ ] Resolve figure order, duplicate presentation, and placeholders. +- [ ] Finalize authorship, funding, contributions, and AI disclosure. +- [ ] Complete data availability and accurate release citation metadata. +- [ ] Render and inspect the final submission PDF. +- [ ] Complete relevant tests, including previously unfinished paths. +- [ ] Reconcile every finding against changed evidence. + +**Acceptance:** all submission blockers are resolved or scoped out. +Every retained quantitative claim has a reproducible result. +The manuscript, release, and archive agree. +Marine adjudicates final scientific and authorship decisions. + +## Inputs needed when their tasks become actionable + +| Input | Needed for | Independent work continues with | +|---|---|---| +| Comparison source or accessible pinned repository | R7 observational replay | Local inventory and dependency manifest | +| Field-product rights and archive destination | R7 publication bundle | Hashes, metadata, fetch-interface preparation | +| Model access and spending limit | R8 actual model runs | Local scorers, baselines, isolation, export checks | +| Cloud target and resource budget | Cloud scaling experiments | Local correctness and scaling pilots | +| Final authorship, funding, contributions | R10 end matter | Scientific text and artifact preparation | + +Ask for specific missing inputs only when needed. +Do not describe unavailable experiments as completed. + +## Next implementation task + +Start R1 with a concise observation-model specification. +Use existing audit probes as unchanged baseline evidence. +Then repair sparse scoring in R2 as the first code patch. +These establish clear contracts before larger statistical changes. + +Superseded on 2026-09-10 by `EXECUTION_PLAN.md` (Fable), which records the scope decisions and the step order actually being executed. + +Current implementation evidence and remaining tasks: [REVISION_STATUS.md](REVISION_STATUS.md). diff --git a/review/REVISION_STATUS.md b/review/REVISION_STATUS.md new file mode 100644 index 0000000..4d73ea3 --- /dev/null +++ b/review/REVISION_STATUS.md @@ -0,0 +1,138 @@ +# Revision reconciliation and remaining work + +The principal formula and sparse-scoring defects have been repaired. +The paper is still not ready for submission. Full covariance validation, +deterministic comparison semantics, field provenance, and author end matter +remain incomplete. + +This is a bounded evidence reconciliation, dated 2026-09-10. It checks the +revision commits through `62b63b5` and the subsequent Codex corrections in this +working tree against the 37 original findings. It is not a second full review +under the nine-scope reviewer workflow. The original reports and manifests +remain unchanged; their `OPEN` states are historical review states. + +## Changes completed in this pass + +- Added `golden.advisory_case` for all six applications. It uses public seasonal + templates independently of installed evaluation recipes. Documentation uses + per-channel recovery, fixed scoring support, and explicit availability. +- Removed claims that synthetic advice proves field performance, that one RMS + comparison establishes equivalence, or that elicited site metadata is + automatically simulated. Explained the three public cases, 30 templates, + and limits of hidden recipes and the observables-only API. +- Rejected irregular/non-daily CCF rows before day-based stacking. Preserved + irregular-time support for already measured inputs to `gibbs_dvv`. + Applied coherence gating to moving-reference and non-stretching ensemble + members, beyond the legacy pipeline's fixed-reference gate. +- Excluded unavailable member epochs and unusable coherence floors from + conditional coverage; reported the observed count and missing fraction. + All 600 archived locked realizations report zero missing fraction, so their + published coverage values are unaffected. +- Included the use-case geometry source in golden cache identity. +- Corrected the manuscript and model documentation: joint hierarchical fitting + is not discrete pipeline-mixture marginalization; member coverage does not + validate the combined estimate, temporal covariance, or cross-band input. +- Enlarged the calibration table by transposing scenarios into columns; + corrected abstract percent formatting and shortened the clipped running title. +- Removed unsupported statements that field products are already archived, + the originating run commit is pinned, and author adjudication is complete. + Small nonzero calibration standard errors are no longer printed as zero. + The prior-rate diagnostic is distinguished from total prior influence. + +## Scientific interpretation of the locked calibration + +| Scenario | Realizations | Member 68% | Member 95% | Combined-estimate 95% | +|---|---:|---:|---:|---:| +| Clean | 200 | 0.808 | 0.956 | 0.590 | +| Shared source | 200 | 0.795 | 0.950 | 0.340 | +| Clock drift | 200 | 0.804 | 0.954 | 0.604 | + +Source: `paper/data/calibration/locked_*.json`. Standard errors across independent +noise realizations are retained in those records and the manuscript table. +These are repeated realizations of specified scenarios, not validation across +independent field sites or waveform-physics families. The source coda is fixed +within the experiment; random seeds change daily noise and decorrelation. + +The 95% member intervals pass the stated pointwise margin. The 68% member +intervals fail it. The combined estimate's credible band undercovers strongly. +Pointwise coverage contains no direct test of off-diagonal covariance. No +multi-chain convergence evidence or calibrated downstream interval follows +from these results. The revised text now keeps these distinctions explicit. + +## Finding-by-finding reconciliation + +“Verified” means the stated defect has direct local code or text evidence. +“Narrowed” means the unsupported claim was limited or withdrawn; it does not +mean the unperformed experiment succeeded. “Partial” retains outstanding work. +These assessments do not overwrite formal reviewer-ledger verdicts. + +| Finding | Assessment | Evidence and remaining limitation | +|---|---|---| +| UQ-01 | Verified formula repair | `uq_measurement.py`; Eq. 21, unit-rescaling and bandwidth tests. Gaussian bandwidth convention remains an assumption. | +| UQ-02 | Verified variance repair | `uq_processing.py`; zero-mean mixture test; bias, SD and RMSE separated. | +| UQ-03 | Partial | Independence and joint-fit versus mixture distinction now explicit in manuscript and module. A dependence-aware likelihood is not implemented. | +| UQ-04 | Partial | Excess-spread subtraction and shared-artifact test exist. Temporal covariance and common-error scale remain unvalidated; 95% coverage alone is not closure. | +| UQ-05 | Verified for supported inputs | Daily-grid rejection, output-only decimation, moving-reference gate and missing-member tests. Inversion references explicitly rejected by the ensemble. | +| DET-01 | Partial | Estimand table names raw RMS and support. Canonical inversion still ignores requested estimator/stack; gates and valid supports vary across deterministic comparisons. | +| DET-02 | Verified cache repair | Exact cold/warm arrays and generator identity tests, now including use-case geometry. | +| INV-01 | Narrowed | Depth remains a framework. Manuscript distinguishes temporal from cross-band covariance and the member from combined-estimate target. GLS propagation remains unimplemented. | +| INV-02 | Verified defect repair | Nonzero local covariance and active-bound flags; disconnected epochs flagged. Local Gaussian curvature at a bound is not a bounded posterior interval. | +| SCALE-01 | Partial | Banded sampler update agrees with dense reference. Stored posterior and output covariance remain dense; no cloud-scaling study is claimed. | +| SCALE-02 | Verified shard checks | Missing/duplicate shard rejection and explicit partial manifest tests. No large deployment was executed here. | +| AG-01 | Verified advisor route repair | All six public development scenarios execute through `recover`; no dependence on missing mappings or hard groundwater fallback. | +| AG-02 | Narrowed | Six executable axes distinguished from contextual site metadata; single-seed equivalence rule removed. No site-conditioned agent evaluation supplied. | +| AG-03 | Narrowed | Synthetic support described as conditional; separated bands do not validate physical depth resolution. | +| EV-01 | Verified original exploit repair | Fixed support and baseline; ten-zero-plus-null regression. Null replacement can still improve a poor prediction; availability must accompany scores. | +| EV-02 | Deferred, explicit | Truth-key removal is not isolation. Private files, generator access and scorer metadata still require an isolated evaluation harness. | +| EV-03 | Deferred, explicit | Three public cases versus 30 templates documented; shared families and regression-derived thresholds remain. | +| EV-04 | Narrowed | Completed agent evaluation no longer claimed. No model transcripts or performance estimates added. | +| SCI-01 | Improved text | Estimand table separates pair spread, finite-network mean precision and posterior uncertainty. No new network covariance calibration. | +| SCI-02 | Narrowed | Scenario-conditional sensitivity and surrogate depth interpretation stated. Broad observational dominance remains unsupported. | +| SCI-03 | Narrowed | Raw trailing references described as an ablation. They still do not represent accumulated changes on a common datum. | +| SCI-04 | Partial | Estimator prescriptions qualified in prior revision. This pass does not repeat the independent literature assessment. | +| SCI-05 | Partial | 600 locked realizations, width/bias/failures and coverage records; missing-data metric repaired. Multi-chain diagnostics and broader calibration remain. | +| SCI-06 | Narrowed | Depth evaluation, agent performance and generalized cloud scalability withdrawn from demonstrated results. | +| SCI-07 | Partial | In-repo product comparison and explicit masks replace inconsistent counts. Original run provenance and raw-waveform replay still missing. | +| SCI-08 | Partial | Abstract-only nonreporting caveat corrected. Study-key deduplication and survey denominators still need reconciliation. | +| SCI-09 | Improved text | Branch rule predefined; same-data coherence-selection bias acknowledged. No new independent selection experiment. | +| SCI-10 | Verified text repair | Appendix WCC delay sign corrected against the defined dilation convention. | +| SCI-11 | Verified text repair | Signed, scenario-dependent stacking recovery replaces universal underestimation. | +| FIG-01 | Verified caption repair | WCS failure acknowledged against saved traces in the methods figure. | +| FIG-02 | Partial | Field masks and labels reconciled in captions/table. External figures retain historical annotations and uncorrected error bars, explicitly disclosed. | +| FIG-03 | Partial | Units, legend placement and sidecars improved. External field bars require regeneration; not all figure pages re-reviewed in this pass. | +| FMT-01 | Partial | Single-paragraph abstract and estimand table added. Author placeholders and full presentation review remain. | +| REP-01 | Partial | All synthetic generators registered with numerical sidecars. Three external field figures remain outside the executable build. | +| REP-02 | Partial, author input | Comparison code and correction log exist. Exact originating run, redistribution rights and archived field inputs remain missing. | +| REP-03 | Partial | Figure sidecars and locked settings improve replay. Release metadata, dirty-source/input hashes and a complete reconstruction manifest remain incomplete. | +| COMP-01 | Partial, author input | Availability and AI disclosure now describe actual state. Funding, contributions, archive details and final adjudication remain to be supplied. | + +## Next revision tasks + +1. **DET-01: make deterministic comparisons executable on a common target.** + Reject unsupported inversion estimator/stack settings or implement them; + apply a stated gate consistently; report raw and fixed-datum RMS on fixed + support with availability. Regenerate affected OAT/factorial figures only + after locking this specification. Preserve original metrics for comparison. +2. **SCI-05/UQ-03/04: validate the object actually used downstream.** + Choose a single member, a mixture, or a combined estimator explicitly. + Test covariance with contrasts and whitened errors, not only pointwise + intervals; include shared artifacts and independent-chain diagnostics. + Keep the current limited claims until this evidence exists. +3. **REP-02/FIG-02: complete field reproduction.** Obtain the original Gate 1 + commit and run configuration, archive the permitted inputs with hashes, + and regenerate the three field figures using corrected uncertainty columns. +4. **SCI-08/REP-03/COMP-01: finish submission metadata.** Reconcile unique study + counts; synchronize release/citation metadata; complete funding, + contributions, data rights, archive identifier and human adjudication. +5. Run the complete reviewer reconciliation workflow after these changes. + Preserve the iteration-1 manifest; update the live ledger from evidence. + +## Verification + +Exact test and build outputs are saved under `evidence/revision2/`. +Final suite: **342 passed, 1 skipped**, with no failures or errors. All configured pre-commit hooks passed. The manuscript rebuilt to **82 pages** with no unresolved-reference markers; pages 1, 2, 33, 37 and 62 were visually checked. +The first focused pass completed with 32 passing tests. Detailed versions and +source hashes are in `evidence/revision2/verification.json`. +No private corpus, external model, cloud deployment, or raw field waveform +reproduction was executed in this pass. Existing locked calibration records +and historical audit evidence were preserved. diff --git a/review/codameter-gji.review.json b/review/codameter-gji.review.json new file mode 100644 index 0000000..fd0e9c5 --- /dev/null +++ b/review/codameter-gji.review.json @@ -0,0 +1,691 @@ +{ + "manuscript_id": "codameter-gji", + "title": "The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring", + "skill_version": "2.4", + "skill_commit": "f230303", + "model": "GPT-6 / Codex; exact runtime model identifier not exposed", + "profile": "default", + "target_journal": "Geophysical Journal International", + "manuscript_type": "Research paper with methods emphasis", + "iteration": 1, + "manuscript_hash": "sha256:582a09ee97ca6f86d80ac3a61301bab8dd5089477fe780cd86c70452dbba0ec0", + "manuscript_file_hash": "sha256:582a09ee97ca6f86d80ac3a61301bab8dd5089477fe780cd86c70452dbba0ec0", + "created": "2026-09-10", + "updated": "2026-09-10", + "repository_commit": "b6dbbd03ad3a9e7b8daac3847a470b93b6918cc8", + "readiness": "Major revision required; UQ and evaluation claims blocked pending correction", + "history": [], + "ledger": [ + { + "id": "UQ-01", + "criterion": "C2", + "tier": "Fatal", + "status": "OPEN", + "summary": "Weaver floor omits bandwidth timescale and differs in prefactor.", + "location": "src/codameter/uq_measurement.py:76", + "required_evidence": "Correct formula; verify dimensional consistency and independent bandwidth calibration.", + "report": "02_software_and_uncertainty.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "UQ-02", + "criterion": "C2", + "tier": "Fatal", + "status": "OPEN", + "summary": "Floor variability is substituted for conditional-mean variability.", + "location": "src/codameter/uq_processing.py:220", + "required_evidence": "Recover exact zero-mean mixture variance; separate bias and MSE.", + "report": "02_software_and_uncertainty.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "UQ-03", + "criterion": "C2", + "tier": "Poor", + "status": "OPEN", + "summary": "Shared-data pipeline estimates are treated as independent observations.", + "location": "src/codameter/uq_bayes.py:297", + "required_evidence": "Derive joint likelihood or mixture; check duplicate-pipeline invariance.", + "report": "02_software_and_uncertainty.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "UQ-04", + "criterion": "C2", + "tier": "Poor", + "status": "OPEN", + "summary": "Constructed Cd is not derived or calibrated for shared errors.", + "location": "src/codameter/uq_bayes.py:328", + "required_evidence": "Derive covariance; test shared bias, temporal dependence, and component accounting.", + "report": "02_software_and_uncertainty.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "UQ-05", + "criterion": "C2", + "tier": "Fair", + "status": "OPEN", + "summary": "Bayesian pipeline ignores config axes and changes physical stacking durations.", + "location": "src/codameter/uq_bayes.py:121", + "required_evidence": "Honor or reject config; preserve physical time under cadence and gaps.", + "report": "02_software_and_uncertainty.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "DET-01", + "criterion": "C2", + "tier": "Fair", + "status": "OPEN", + "summary": "RMS, valid supports, reference observables, and requested estimators differ.", + "location": "src/codameter/deviations.py:174", + "required_evidence": "Align datum/support; expose unsupported configurations; replicate paired comparisons.", + "report": "02_software_and_uncertainty.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "DET-02", + "criterion": "C3", + "tier": "Fair", + "status": "OPEN", + "summary": "Cache inputs depend on warmth and lack generator-code identity.", + "location": "src/codameter/golden.py:508", + "required_evidence": "Consistent precision, versioned cache key, and atomic writes.", + "report": "02_software_and_uncertainty.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "INV-01", + "criterion": "C2", + "tier": "Poor", + "status": "OPEN", + "summary": "Temporal Cd is not connected to diagonal stress inversion or cross-band depth input.", + "location": "src/codameter/inverse/linear_fit.py:430", + "required_evidence": "Demonstrate GLS and explicit time-band covariance propagation.", + "report": "02_software_and_uncertainty.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "INV-02", + "criterion": "C2", + "tier": "Poor", + "status": "OPEN", + "summary": "Bounds and disconnected reference nodes can have zero reported uncertainty.", + "location": "src/codameter/inverse/linear_fit.py:544; src/codameter/uq_measurement.py:419", + "required_evidence": "Use bounded uncertainty; identify graph components and null spaces.", + "report": "02_software_and_uncertainty.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "SCALE-01", + "criterion": "C3", + "tier": "Fair", + "status": "OPEN", + "summary": "Dense Gibbs covariance path is cubic in epoch count.", + "location": "src/codameter/uq_bayes.py:299", + "required_evidence": "Use structured algebra; report memory/runtime scaling and equivalence.", + "report": "02_software_and_uncertainty.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "SCALE-02", + "criterion": "C3", + "tier": "Fair", + "status": "OPEN", + "summary": "Shard aggregation accepts duplicates and missing shards.", + "location": "src/codameter/bench.py:314", + "required_evidence": "Require complete unique task inventory and matched provenance.", + "report": "02_software_and_uncertainty.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "AG-01", + "criterion": "C3", + "tier": "Fair", + "status": "OPEN", + "summary": "Public advisor routes fail for three applications and mismatch hard-case targets.", + "location": ".claude/skills/codameter-advisor/references/validation_loop.md:37", + "required_evidence": "Provide executable matched public cases for all applications.", + "report": "03_advisor_and_golden_dataset.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "AG-02", + "criterion": "C2", + "tier": "Fair", + "status": "OPEN", + "summary": "Elicited constraints and error-bar comparisons lack executable evaluation.", + "location": ".claude/skills/codameter-advisor/references/validation_loop.md:45", + "required_evidence": "Validate overrides, safeguards, equivalence, and repeated-seed differences.", + "report": "03_advisor_and_golden_dataset.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "AG-03", + "criterion": "C4", + "tier": "Fair", + "status": "OPEN", + "summary": "Matched synthetic recommendations are described as proven field choices.", + "location": ".claude/skills/codameter-advisor/SKILL.md:3", + "required_evidence": "State conditional scope; validate independent field/simulator transfer.", + "report": "03_advisor_and_golden_dataset.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "EV-01", + "criterion": "C4", + "tier": "Fatal", + "status": "OPEN", + "summary": "Sparse zero predictions score perfectly on all public cases.", + "location": "src/codameter/frugalmind.py:299; src/codameter/golden.py:578", + "required_evidence": "Fix score support and missingness; rerun adversarial and model evaluations.", + "report": "03_advisor_and_golden_dataset.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "EV-02", + "criterion": "C3", + "tier": "Fair", + "status": "OPEN", + "summary": "Truth-free function is not demonstrated sandbox isolation.", + "location": "src/codameter/golden.py:560; src/codameter/frugalmind.py:117", + "required_evidence": "Prove separate scorer/agent access boundaries with observables-only artifacts.", + "report": "03_advisor_and_golden_dataset.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "EV-03", + "criterion": "C2", + "tier": "Fair", + "status": "OPEN", + "summary": "Gold corpus shares generator families and derives thresholds from baseline implementation.", + "location": "src/codameter/private_golden.py:85; src/codameter/golden.py:604", + "required_evidence": "Freeze independent benchmark; distinguish parameter and simulator holdout.", + "report": "03_advisor_and_golden_dataset.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "EV-04", + "criterion": "C4", + "tier": "Poor", + "status": "OPEN", + "summary": "No executed agent evaluation supports the robust-evaluation claim.", + "location": "paper/manuscript_marine.qmd:41", + "required_evidence": "Archive model protocols, runs, baselines, scores, costs, and uncertainties.", + "report": "03_advisor_and_golden_dataset.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "SCI-01", + "criterion": "C2", + "tier": "Poor", + "status": "OPEN", + "summary": "SD/SE/network heterogeneity are conflated with one measurement uncertainty.", + "location": "paper/manuscript_marine.qmd:446", + "required_evidence": "Define estimands and hypotheses; use network covariance propagation.", + "report": "01_manuscript_and_figures.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "SCI-02", + "criterion": "C4", + "tier": "Fair", + "status": "OPEN", + "summary": "Conditional surrogate experiments are generalized to observational dominance and depth.", + "location": "paper/manuscript_marine.qmd:180; paper/manuscript_marine.qmd:1207", + "required_evidence": "Add independent wavefields and qualify surrogate physical interpretations.", + "report": "01_manuscript_and_figures.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "SCI-03", + "criterion": "C4", + "tier": "Fair", + "status": "OPEN", + "summary": "Raw trailing references are presented as common defensible comparisons.", + "location": "paper/manuscript_marine.qmd:540", + "required_evidence": "Benchmark comparable registered observables and surveyed reference workflows.", + "report": "01_manuscript_and_figures.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "SCI-04", + "criterion": "C6", + "tier": "Fair", + "status": "OPEN", + "summary": "Estimator prescriptions and novelty boundary exceed cited conditional evidence.", + "location": "paper/manuscript_marine.qmd:309", + "required_evidence": "Compare tuned methods; delimit contribution relative to Yuan2021 and other work.", + "report": "01_manuscript_and_figures.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "SCI-05", + "criterion": "C2", + "tier": "Poor", + "status": "OPEN", + "summary": "Nominal interval coverage lacks repeated independent validation and chain diagnostics.", + "location": "paper/manuscript_marine.qmd:995", + "required_evidence": "Report held-out coverage, uncertainty, width, convergence, and failure rates.", + "report": "01_manuscript_and_figures.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "SCI-06", + "criterion": "C4", + "tier": "Poor", + "status": "OPEN", + "summary": "Depth and operational claims exceed demonstrated results.", + "location": "paper/manuscript_marine.qmd:36; paper/manuscript_marine.qmd:1298", + "required_evidence": "Add actual depth/resolution and scaling results or narrow claims consistently.", + "report": "01_manuscript_and_figures.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "SCI-07", + "criterion": "C4", + "tier": "Poor", + "status": "OPEN", + "summary": "Field comparison counts, masks, correlations, and physical attribution are inconsistent.", + "location": "paper/manuscript_marine.qmd:1133", + "required_evidence": "Publish exact comparison driver and date masks; recompute statistics and labels.", + "report": "01_manuscript_and_figures.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "SCI-08", + "criterion": "C6", + "tier": "Fair", + "status": "OPEN", + "summary": "Abstract-only survey gaps cannot establish full-paper nonreporting.", + "location": "paper/manuscript_marine.qmd:1414", + "required_evidence": "Separate extraction statuses and deduplicate study denominators; repair groundwater attribution.", + "report": "01_manuscript_and_figures.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "SCI-09", + "criterion": "C2", + "tier": "Fair", + "status": "OPEN", + "summary": "Largest-magnitude and coherence branch selection can bias inference.", + "location": "paper/manuscript_marine.qmd:788", + "required_evidence": "Predefine selection or validate it on independent data.", + "report": "01_manuscript_and_figures.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "SCI-10", + "criterion": "C2", + "tier": "Fair", + "status": "OPEN", + "summary": "Appendix WCC delay sign contradicts the defined dilation convention.", + "location": "paper/manuscript_marine.qmd:1345", + "required_evidence": "Correct analytical pulse example and propagate finite-change Jacobian.", + "report": "evidence/methods_figures.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "SCI-11", + "criterion": "C4", + "tier": "Good", + "status": "OPEN", + "summary": "Universal stack underestimation contradicts reported bias zero crossing.", + "location": "paper/manuscript_marine.qmd:669", + "required_evidence": "Describe signed, scenario-specific recovery errors.", + "report": "evidence/methods_figures.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "FIG-01", + "criterion": "C4", + "tier": "Fair", + "status": "OPEN", + "summary": "Figure1 WCS trajectory contradicts its caption.", + "location": "paper/manuscript_marine.qmd:367; PDF p11", + "required_evidence": "Reconcile saved numerical traces and recovery claim.", + "report": "01_manuscript_and_figures.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "FIG-02", + "criterion": "C5", + "tier": "Fair", + "status": "OPEN", + "summary": "Real-data figures conflict on components, dates, statistics, and counts.", + "location": "paper/manuscript_marine.qmd:1176; PDF pp36\u201338", + "required_evidence": "Generate labels and reported metrics from the same validated products.", + "report": "01_manuscript_and_figures.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "FIG-03", + "criterion": "C5", + "tier": "Fair", + "status": "OPEN", + "summary": "Missing units, clipped ensembles, occluding legends, and mixed RMS/bias labels.", + "location": "PDF pp13,22,25,28,29,32,37", + "required_evidence": "Add units and full-range views; move legends; label statistical objects.", + "report": "01_manuscript_and_figures.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "FMT-01", + "criterion": "C5", + "tier": "Good", + "status": "OPEN", + "summary": "Summary paragraphs, figure order, duplicated presentation, and placeholders need revision.", + "location": "paper/manuscript_marine.qmd:10; paper/manuscript_marine.qmd:140", + "required_evidence": "Single summary paragraph; resolve placeholders and figure order; clarify acronyms/history.", + "report": "01_manuscript_and_figures.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "REP-01", + "criterion": "C3", + "tier": "Poor", + "status": "OPEN", + "summary": "Advertised figure build omits six graphics and can preserve stale results.", + "location": "paper/build.py:124", + "required_evidence": "One driver regenerates all graphics from versioned numerical manifests.", + "report": "evidence/reproducibility.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "REP-02", + "criterion": "C3", + "tier": "Poor", + "status": "OPEN", + "summary": "Field products are ignored by Git and comparison driver is external.", + "location": "paper/data/gate1/README.md:25", + "required_evidence": "Archive field products and dependencies with exact hashes and executable driver.", + "report": "evidence/reproducibility.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "REP-03", + "criterion": "C3", + "tier": "Fair", + "status": "OPEN", + "summary": "Paper experiment settings, version metadata, and replay manifests are incomplete.", + "location": "CITATION.cff; src/codameter/workflow.py:696", + "required_evidence": "Pin environments, settings, hardware, source and input hashes, seeds, and invocation.", + "report": "evidence/reproducibility.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + }, + { + "id": "COMP-01", + "criterion": "C8", + "tier": "Fair", + "status": "OPEN", + "summary": "Acknowledgements, AI disclosure, and full data access/licensing statements are unfinished.", + "location": "paper/manuscript_marine.qmd:1427", + "required_evidence": "Complete authorship/funding/disclosure and actual data/software access statements.", + "report": "01_manuscript_and_figures.md", + "first_seen": 1, + "last_changed": 1, + "bucket": null + } + ], + "review_mode": "Full first review; nine focused scopes across three subagents, primary scientific code/scorer audit", + "prior_manifest_found": false, + "author_verification_performed": false, + "source_file_hashes": { + ".claude/skills/codameter-advisor/SKILL.md": "sha256:6daf68288e89f93cfe46ab57a54300228bd9536d17af9c529d4a92c0e101716b", + ".claude/skills/codameter-advisor/references/golden_datasets.md": "sha256:7aaf3fd20e26d84bf1ba7aead158f3cd5cb7aebf9c0a0c20de3f3937a032065c", + ".claude/skills/codameter-advisor/references/parameter_map.md": "sha256:bf008b1e0922a56b13251d24ca4477d4c9d927325e7fb4597ee002a599435434", + ".claude/skills/codameter-advisor/references/report_format.md": "sha256:53b4ad8d26caada2c149f2ea9d96bbed8cf11b3ed2787d287a1ae3b4ead155c7", + ".claude/skills/codameter-advisor/references/use_case_elicitation.md": "sha256:20f21a64396abaa19786e0b5396f466be6843697a045e32c9c5ca9f377f5b90e", + ".claude/skills/codameter-advisor/references/validation_loop.md": "sha256:a8e51cf050463a141680976bcc0bf06fd2ca6be0bd07f304a41eb56bf8162806", + "literature/.crossref_cache.json": "sha256:2ba8ffbb03257794a241f7489ef9819968a15780d960e1ed5b4b01f12590b84b", + "literature/ACCESS.md": "sha256:c2344c9ce6632b60871be3eb8053954d823ef91f2012c03cafe00b59ca14654e", + "literature/README.md": "sha256:69418a72b0b72dbd920c8bc08c9f792e61c0bcfaacee9e7423d943fb34149848", + "literature/best_practices.md": "sha256:08dff657c576aabcc986e8d6e46c5fb4943bad9db5d2c2acf62b8e170739e247", + "literature/build_quarto_refs.py": "sha256:62cf6f90bbd525f321048a83fd35c76309236a9d5bb7d58109f009c2a06af6e1", + "literature/build_table.py": "sha256:5a66dfcd167da2fcae8e16074956fa676a0ab54eba821aaf78187c76d4eb53b0", + "literature/dvv_processing_parameters.csv": "sha256:d1178a1b3a6e442a0638491236adfaa9d995f4722a629d30c86e31af2678aae2", + "literature/dvv_processing_parameters.md": "sha256:55f00c094e6f675c2c4c1761a9374045007a1550f5a8d420b84c6f54aefb4405", + "literature/figs/demo_10_deviations.png": "sha256:6fa18f678925cdc261f191a296ed932e32c72aa769659883ba421d604c06340b", + "literature/figs/demo_11_multiverse.png": "sha256:75f3a557e8d2b900522959f89cabb6ef86b753d16e0bf44bc35432b7181adf48", + "literature/figs/demo_12_bayes.png": "sha256:5ec259557489329b35d56a966e47683d4206a68d9fd97047eedfb0abcad2cdc3", + "literature/figs/demo_13_branch_asymmetry.png": "sha256:d167a4ff35df6bfab45bc1dd928135feaa014f2a1cc177f308411ccf99196daa", + "literature/figs/demo_14_network_pairs.png": "sha256:d0d01f5a273edd52c709a13e5e821551560d909bf92a42f6a9e69ad8c15f2bdc", + "literature/figs/demo_15_window_envelope.png": "sha256:bc88316402dcb5a7c841c996ec6a110322157b72e9af5a8f92871f8d14befce8", + "literature/figs/demo_16_band_sensitivity.png": "sha256:5622d8a45989a020f4522c497888d26a94ccad94b7192e9fb8773c2c95b99220", + "literature/figs/demo_17_reference_schemes.png": "sha256:ea87965d83f242d406c9315c6b570285af0859984228b92180c31a88e849fd72", + "literature/figs/demo_18_stack_coherence.png": "sha256:defa8771b14540add4279723f7e7a0e08a172da7c503b97e765f39c322aa4f5b", + "literature/figs/demo_1_methods.png": "sha256:864d7835944d42158992ada370c8da05623527de62a139d08f54a68367a691b4", + "literature/figs/demo_2_aggregation.png": "sha256:713828944d7d893cccd488be242088704aacfd7e4abfc09e3a28cb0b4e66b807", + "literature/figs/demo_3_uncertainty.png": "sha256:38574d2b102c67a1330925dd2c9fbebb2897d21cb0329612d66bf698c2e8ab61", + "literature/figs/demo_4_frequency_depth.png": "sha256:2cc5f4615e22525720a843e35225a9cd5b27c8351778b4a51a9e21ed4c361c20", + "literature/figs/demo_5_window_band.png": "sha256:490ef1c7f1962020f84b4298ffef349adc76850cbefa787f8b81c4a9278e4f82", + "literature/figs/demo_6_stacking.png": "sha256:9a23225d91a027e339ffbf1da990edff84167c150a0086c5640a026f5826e653", + "literature/figs/demo_7_reference.png": "sha256:d04da8057f9e00a872f656b400fc305761a67701624b6f2a7bf623556a497616", + "literature/figs/demo_8_artifacts.png": "sha256:5dd57681749c9924f9b07b1d635e8c16e6b7054ddec53d4ae8a614372d897477", + "literature/figs/demo_9_multiverse.png": "sha256:0e2bd424d1dd921f1546dd4095e34d6fbc26beef72e54211d5274c9c13ded353", + "literature/figs/realdata_1_validation.png": "sha256:9f74681a0ddefc6a6d9b80dd2eef15a856f5bff4f0503b66e25a58e28ccaddb8", + "literature/figs/realdata_2_interferograms.png": "sha256:a15d51eae10aac10b5f5dba48fb4b19a439cbededb1cb29f36f6f098e2598a81", + "literature/figs/realdata_3_warmup.png": "sha256:00df9e0f5632013f0dd97c8a2143e60c3348530b05b37756c7ca9f0b89bec83b", + "literature/merge_verified.py": "sha256:261c1238bb039c83b1d7de26b030ec206b4b8476a81c8aeeea1f8983e8c132a6", + "literature/raw/cryosphere_geothermal.json": "sha256:f71f77982ec57ec3ea43a07ce5cc6ba121dd32bba79d29fb983c9c5dee78f5c2", + "literature/raw/earthquake.json": "sha256:7447031b92216341d104367de5599dd2c055c2a9d4a4aed37e5bf29e9d5e52b2", + "literature/raw/groundwater.json": "sha256:3f3c092f00a984c033bebfac3965ff1be14565353abc6a6b544df4b22da1df59", + "literature/raw/landslide.json": "sha256:b52509a914372f4027979f584fa5fe2c1bf92dc61ac1b92ae65dc3d18c13d5cf", + "literature/raw/methodology.json": "sha256:d7975b35d826e748accb1b329dc66e1abc63b8e6a57ce33b7fbe9aef1de801b9", + "literature/raw/volcano.json": "sha256:4b1cad33974bda5dcdacb01716a2974c62f26f39ddef3707dfa0b683836ecd16", + "literature/synthetic_dvv_demo.py": "sha256:acdc072a152128236a25f9252d272488dc3f531b3c12271885c70cc0041dfa37", + "literature/verified_fulltext.jsonl": "sha256:91d275aa20a4c85d2aaad978688d279ec44370733e1d8874b67a1e1add9209ae", + "paper/README.md": "sha256:cf85ea212054426cfa19f6fd75850480eece828db580e28c8019462dcc289e97", + "paper/_preamble.tex": "sha256:1b908dc23177955883d2e790ba50af4828b29ca42351439ee5e5b70daa5f724a", + "paper/appendix_table.tex": "sha256:1536016349243c060be06d8a47eaa0424aae72af0b7a81579daab623b41d346d", + "paper/build.py": "sha256:e5d71be0c524dfc29194b3d6d4b137273dcd0b6f1ebbd44e434e5900977c4a65", + "paper/build_survey.py": "sha256:c259d46f25b29a61e6f6f5d7791ab68d3bfd25a60a70339c8669db49b3b507cd", + "paper/data/gate1/README.md": "sha256:6dbfc6332c3b6c2dc1865cc0cacfc427781dfd03cf1442402a4183a51305849a", + "paper/data/gate1/legacy_cd2022/CI.ARV.arrow": "sha256:7956fc2e2b070a1dc3933ff818efd4f34f0c2d2e695260d1a532d8fd47906c65", + "paper/data/gate1/legacy_cd2022/CI.LJR.arrow": "sha256:85e33fa2611f6b7a3beccbfb368abc42573a0f9da142df346a71b8cb9d6658f7", + "paper/data/gate1/legacy_cd2022/CI.RXH.arrow": "sha256:f0ab6c687b75e06ae19fa5a10668bc95515c8fdeab00e2d8a0ab5787772ccc19", + "paper/figures/gate1/dvv_smoke_check_90d.png": "sha256:00df9e0f5632013f0dd97c8a2143e60c3348530b05b37756c7ca9f0b89bec83b", + "paper/figures/gate1/gate1_final_2y.png": "sha256:9f74681a0ddefc6a6d9b80dd2eef15a856f5bff4f0503b66e25a58e28ccaddb8", + "paper/figures/gate1/gate1_heatmaps_zoom.png": "sha256:a15d51eae10aac10b5f5dba48fb4b19a439cbededb1cb29f36f6f098e2598a81", + "paper/figures/gate1/gate1_validation.png": "sha256:9f442edaff04e16b7e128906787b614192e4e9bcfaad73576671d744da6e0d6f", + "paper/manuscript.tex": "sha256:9bb7332eeee4a702c86c3659bc5548d6b77e49764ae80e3c43998ce4350834fe", + "paper/manuscript_marine.qmd": "sha256:582a09ee97ca6f86d80ac3a61301bab8dd5089477fe780cd86c70452dbba0ec0", + "paper/manuscript_marine.tex": "sha256:a60d872160bbb418b71093932c486d5f420a10008dd210441191118051542dc0", + "paper/references.bib": "sha256:f5263a55a6fd3ee7ad5bbd536ea492ef8c841583590f85e636b957dfc8f7e1fb", + "paper/survey.bib": "sha256:7acfc0836dcf4924ea98fdc2d493ddd53246454eb71194d7ce2bae9a16ddd6a9", + "src/codameter/__init__.py": "sha256:692e434d63a1752f08bf7ce7abce9fcee2dd4d2a4627b599316f85e2ffee86cc", + "src/codameter/_version.py": "sha256:db4a8260ba9c834fb069e7425479b3ece5d95afb06478a3f08c119acbc64b4a0", + "src/codameter/anomaly/__init__.py": "sha256:255edcc88170406cfca35319211f9880ee0e4791edd6548a0c787a7c928e373d", + "src/codameter/anomaly/attribution.py": "sha256:ef52decf86eb7c303a3b80eeb6930ba9ea078ae4f77e4315a73bcd8bcec55fbc", + "src/codameter/anomaly/detection.py": "sha256:a2ca317c98fba066123a8efdccd64f3249d0ddc63ace033c589bf198fb2f4d94", + "src/codameter/anomaly/residual_patterns.py": "sha256:91c9534ad5cf7a31eddf02f367c71ceeeccbade915358a3c31157722943fde86", + "src/codameter/bench.py": "sha256:cd2fb3d9fe31ab5a7cadb3834b4871a9af33ac08f2d84cd24e6d84cceb2fd8d1", + "src/codameter/cli.py": "sha256:ab0054ebfae035f5627513d7338bdaf0d0b93d7fe846114d2245d6d9233ee71c", + "src/codameter/config.py": "sha256:94180cce8f6c5c397e27339caa698b6d54e24c57e34421fcedfc048f7c48b86d", + "src/codameter/coupling/__init__.py": "sha256:5e804b1f0d7ad8f1e53891b5aac1436b86d25694101344f72e23651ddd78b32f", + "src/codameter/coupling/decision_tree.py": "sha256:58d290e1931622bc500c77c2ebac01c88f48ea43ffc1d130d13538355b1b6621", + "src/codameter/coupling/tier1_poroelastic.py": "sha256:3d09e1f9bb38a7fc7794f4ed363b2405dff42c0fe6e0d7ba786bf9c2b89bfa5f", + "src/codameter/coupling/tier2_damage.py": "sha256:45c3f07f5d704a26523c8eee2c96b8fcee254f4c4fee2e7b97f560203bffa51d", + "src/codameter/coupling/tier3_saturation.py": "sha256:25e23ee88f29b94a9f6b357e43a5c7c476ba57816e69184e2daf2fde86927b4b", + "src/codameter/coupling/tier4_thermo_capillary.py": "sha256:d40141149d37b7a2382df532925485bffdb0bc490955302ca10895b2e0e8cb8c", + "src/codameter/data/__init__.py": "sha256:642bba2e6b9a28ff42cf95aacaca2a08062cbc6a09e8e2d34bcee1531af0a7bb", + "src/codameter/data/covariates.py": "sha256:eb2e43b8d888c23a7c7947fc1d2811c321ccf23e5fd7ad85e3eaa26955aaa3d3", + "src/codameter/data/loaders.py": "sha256:9ed451225a0e219223ff089503f415118a63bebbf7f75703e518b8daeb42db38", + "src/codameter/data/property_providers.py": "sha256:08044fc0500b73c33af9c37cc37e1efab05615e7f631075d488ef20220310d11", + "src/codameter/data/qc.py": "sha256:26a4a3dbd645a429a97e43db00e2e9423d1132e9d96f8fe96fff80043c712c22", + "src/codameter/data/readiness.py": "sha256:733aaae0a323065f934cf42f261739c6675ae586e00e396069edc9aac2aee1ff", + "src/codameter/deviations.py": "sha256:fd7c3c2965d8c281035f516c9afd5a13f32209f7f825a64daf95167a8e3c7387", + "src/codameter/forcing_models.py": "sha256:ebd5f7879cba31a4a50fca8a6bb20f7e1aab5ae07cd63a3a2b967d6abe800988", + "src/codameter/forward/__init__.py": "sha256:8fdf2cac2650a750ee24c396061de761612d8bbbdb0a30642d44f82ea167040b", + "src/codameter/forward/capillary.py": "sha256:9cb8cbb2faaf37fd5b017da5784cfe9229a04404691df7a587acae1abb2875c6", + "src/codameter/forward/damage.py": "sha256:5cf75bf0b28c4e0807d516ec90491ea784630a6b11801d0128239388377217b0", + "src/codameter/forward/loading.py": "sha256:def69d6ea560e1af691ed47afcf5df0feb58e4ffe7296dcc06ee4da55a1e1061", + "src/codameter/forward/poroelastic.py": "sha256:ab886b9db53292ef80d62c6e2bc81f4e7a235b2fdd5cb8073f5dfc22a6f2d384", + "src/codameter/forward/thermoelastic.py": "sha256:61446165c22a84378ca606160841cad78d5517d9f519276f0c023b100c225d30", + "src/codameter/frugalmind.py": "sha256:8203df997d814b9fcdccd663a6ed2eb9947f79d0586e75439e16ed39f0c8db94", + "src/codameter/golden.py": "sha256:430dcf6b3640a4bb1d02e2c6fb4be3e98b60e32b03b62c70273f8dbb7573649b", + "src/codameter/interpretation/__init__.py": "sha256:10ef78d1dda57756eacc2c767ef92c6e38bdb32bc1e6942e3dec395fab412314", + "src/codameter/interpretation/stress_at_depth.py": "sha256:47ad193ad7e499df36700c0e84996978eb655692c2d6ee941ef00b1ebdaaf9e8", + "src/codameter/interpretation/water_table.py": "sha256:d21eb5c713017c40c9c62bfc4ab9c2602fdae41618290413d6e92adbeee7758d", + "src/codameter/inverse/__init__.py": "sha256:a88b0ec206fde27babff959b8965366f7c23b11c7de7fb24733ede6d10e416fb", + "src/codameter/inverse/coupled_inversion.py": "sha256:bf7a4e4b12244642c73b51547c9d81c7cc28c432a288cefc7c512c8d6ca4e5f3", + "src/codameter/inverse/linear_fit.py": "sha256:8af574f45cdf3efcf77420911a55b4f24c33e5326ca889635fc06f5a7d6cd78a", + "src/codameter/inverse/posterior.py": "sha256:2f2f5cc5a1db8ba82bb8de90a8a2518f039238fdb0d9d40e76f5b0fb7ec3dbb5", + "src/codameter/inverse/priors.py": "sha256:98fff20b216a75aaf270ce391ea2f0867efc345234bddcf6e8577438f470b0a7", + "src/codameter/kernels/__init__.py": "sha256:a736590dd5d00d4347c90c2ec9fa33debf1e216f3536bde8406b642d00ec302f", + "src/codameter/kernels/depth_resolution.py": "sha256:2071660152fd6d78849a1a39b1cd3a155eb308bd9d1ab860be0073d400a505c6", + "src/codameter/kernels/disba_wrapper.py": "sha256:a8d02a10a0ec829dd75ab7a2b6c97e7ba5e1015d566677af05827c1b8c24a8d9", + "src/codameter/kernels/velocity_models.py": "sha256:7e7984a15e546a346806701824aa3e611891ece3719a4aa4f3d1e6332a35af38", + "src/codameter/plotting.py": "sha256:824f8c9fd004ae9de8e8503fdccde504a4922fe19ab68f5e050c2a4ad9850d35", + "src/codameter/private_golden.py": "sha256:a94ec6d930e8b987fb2f1effc234045f1e7975224a9cfdfaf134b16aada94959", + "src/codameter/synthetic_demo.py": "sha256:ca8bb17a57df8712ee8d1019389ddfa718aaf034b9faa0df610d530dd9cee871", + "src/codameter/uq-measurement.py": "sha256:7bc7fd441d494935cb6f7ba4ead86bc0b9d357ddaced7890dadbc7d4243c6ada", + "src/codameter/uq_bayes.py": "sha256:f0822286e6794a908e0cb5adb1c303bca20e6c9d214647a50e252a1d72753d37", + "src/codameter/uq_depth.py": "sha256:e956d77cf0306b1f731d09a6c2039271968928da0763623b619ccc9d92a5cef3", + "src/codameter/uq_measurement.py": "sha256:010c68110aa963d9bdd382d8a4445a73e72d2c0f7ceec357d744df27c16b2b3a", + "src/codameter/uq_processing.py": "sha256:ce650937591e67ff46a0bde018ae9d26d79e3ea316fac06db720ae3f74ac8fd3", + "src/codameter/use_cases.py": "sha256:981ebead6a158e09a943c50d7ad9238921075b32b6cc737967df0d70b3694fe9", + "src/codameter/workflow.py": "sha256:a037eb72a98f54388953e371ea53c9d38d61492242f108f41e955b259c474871", + "tests/conftest.py": "sha256:7125550878e4080d47c85ad06f0596ac72815757dca12e855a3a2facb9a37ee6", + "tests/data/golden/manifest.json": "sha256:fb0abc1057a577bce1b68e73e0e684a2b871d2a70bbc4ebe04dcfa770f8ca5a1", + "tests/test_bench.py": "sha256:92d8dbcd534e2979e3cac1ffe18c4063b799c832b1b8e9faf101f35d0676c96b", + "tests/test_cli.py": "sha256:43f942ef2b7a68ab0f37f1912913d7d6edced54dc26a86cd426958cf2c73edcf", + "tests/test_coupling.py": "sha256:600fd0fcdf919568864f0b446577b977a89680ec94f1c73f084901d92feb880e", + "tests/test_coupling_tiers.py": "sha256:3e861e12bdb0bffd0c1c1dd2fe5aadf1e3535e06951a94932807a58f3db80d7e", + "tests/test_data_loaders.py": "sha256:b763795081ee19dd4ecd35e46b73682b38d5947109ad02626e62fad6a9e7fb5e", + "tests/test_data_readiness.py": "sha256:25f54eb9920ff4ac4cccf34a43e12bae39a52775e7b894a0ea5884d443cc1c61", + "tests/test_deviations.py": "sha256:e36c9f83d314b604af930c381fa9058fffea401710585cb207c7feca49328860", + "tests/test_forcing_models.py": "sha256:d6cfaef86b667d71987a4cd4fd5371d35e868d99d1e793fb457b8ee4aef0af48", + "tests/test_forward_models.py": "sha256:0a8514e648e8c216664f6c7b29431b733e87f9756ee3703c54af51e8cf32e989", + "tests/test_frugalmind_export.py": "sha256:3a63e24a4f6eac884c25e299012da8febe1cc7cd8903cfced97752b1f72a51e8", + "tests/test_golden.py": "sha256:e5bf032f3ffe1a1b11dbebbc311355c3f4dec3c81fa6491a93638232a5aa2d61", + "tests/test_kernels.py": "sha256:4a4b72d7469a1dd758c1107367358c6826ba330931ebab3f92b899506ccbf2f0", + "tests/test_linear_inversion.py": "sha256:27e98bd63a592f7e001364d6f0503c59a340966fb4a071d7693b1544495c036f", + "tests/test_private_golden.py": "sha256:bafcad630f9a59e2cfee1665a168fc90f462bd7e48ee3b4874c0f999267989e0", + "tests/test_property_providers.py": "sha256:a01cdc179fb0237c427bf87937bb6e51bb775a4da95a220c5c3d74b7f36659a1", + "tests/test_sign_convention.py": "sha256:ce9d272ca44b8ed119afbd20af1f22268e97a95cfc7c9991abf56d5b3f0938e4", + "tests/test_staged_workflow.py": "sha256:ba0842d261e858c9678605f85dbec77bb25122edf69d11fd1238ce4c7fe49f32", + "tests/test_stretching_interpolation.py": "sha256:a7770b6198ab437e2d96c5bd6e0a7f758e1b25e0e7f80e0653ec62257c9daec4", + "tests/test_synthetic_demo.py": "sha256:569e59c69d86394dca2c227438120f3a404cf4e89d1d949a3ef023612da5cc1a", + "tests/test_synthetic_parkfield.py": "sha256:e396e4c18d31c9bc6ea1ad014134fe0d679c0906458153247fbff852cd6429e9", + "tests/test_uq_bayes.py": "sha256:90a3469cbf275353eab666cd8f0c619dd425acf5ab9f307f0d6e84bedbeed097", + "tests/test_uq_depth.py": "sha256:b06dba43ffe88467f2006ca43b449580794936da1c488cf497a0fdb1fc0f2cef", + "tests/test_uq_measurement.py": "sha256:710fb57836ba0c4514cf60a8361540f02b5ed7aa324c0e85de88bef70f79ca71", + "tests/test_uq_processing.py": "sha256:9aa29e01010e30d36103c2f6b6f59c675857f6303cd821a3bad7f1b8f7ad1e7f", + "tests/test_use_cases.py": "sha256:d71d01f78877720faef8312018b4d3ae31f05195fc88134bd114b35fade1784d" + }, + "verification": { + "numerical_probes": "evidence/audit_probes.json", + "downstream_probes": "evidence/downstream_probes.json", + "reproduction_probes": "evidence/reproduction_probes.json", + "test_metadata": "evidence/pytest_targeted_metadata.json", + "full_test_metadata": "evidence/pytest_metadata.json", + "render_metadata": "evidence/paper_build_cached_metadata.json", + "targeted_tests": { + "passed": 144, + "skipped": 0, + "complete": true + }, + "full_suite": { + "status": "timeout", + "limit_seconds": 540, + "visible_passes": 261, + "visible_skips": 1, + "unfinished": 39, + "complete": false, + "note": "Partial progress counts; targeted suite overlaps." + }, + "fresh_pdf_pages": 74, + "visual_qa": { + "existing_pages": 26, + "all_17_figure_pages_inspected": true, + "fresh_pages": [ + 1, + 11, + 29, + 32, + 36, + 37 + ] + } + }, + "limits": [ + "No hidden corpus accessed", + "No external model evaluation performed", + "No cloud deployment or benchmark performed", + "Existing figures reused for isolated manuscript compilation", + "No full raw-waveform real-data reproduction performed" + ], + "disclosure": "This draft received an advisory AI-assisted review using Denolle Group Pre-Submission Reviewer v2.4 with Codex/GPT-6, iteration 1. The audit included local code execution and selected primary-source checks. It does not endorse manuscript validity. Authors must adjudicate findings before submission; that adjudication has not yet been recorded." +} diff --git a/review/evidence/README.md b/review/evidence/README.md new file mode 100644 index 0000000..8eb219f --- /dev/null +++ b/review/evidence/README.md @@ -0,0 +1,40 @@ +# Audit evidence index + +## Focused reviews + +- [Paper sections](paper_sections.md): Abstract, Introduction, Discussion, Conclusions, Citation Diversity. +- [Methods and figures](methods_figures.md): Methods, Results, Figures/Data; visual QA. +- [Reproducibility](reproducibility.md): reconstruction, test runs, build, scaling, provenance. +- [Citation inventory](citation_inventory.json): bibliography counts and extraction. + +## Executable audit cases + +- [audit_probes.py](audit_probes.py) and [results](audit_probes.json): sparse scoring, advisor routes, dimensions, variance, shared bias, time semantics, cache precision. +- [downstream_probes.py](downstream_probes.py) and [results](downstream_probes.json): boundary covariance and disconnected reference graph. +- [reproduction_probes.py](reproduction_probes.py) and [results](reproduction_probes.json): figure orchestration, local data inventory, date counts, sharding. + +From the repository root: + +```sh +MPLCONFIGDIR=/tmp/codameter-review-mpl .pixi/envs/default/bin/python review/evidence/audit_probes.py +MPLCONFIGDIR=/tmp/codameter-review-mpl .pixi/envs/default/bin/python review/evidence/downstream_probes.py +MPLCONFIGDIR=/tmp/codameter-review-mpl .pixi/envs/test/bin/python review/evidence/reproduction_probes.py +``` + +These probes use existing local environments. They are diagnostics, not a new calibrated benchmark. The sparse-scoring probe supplies freshly generated arrays to the actual scorer. No private truth or external evaluation is used. + +## Tests and document build + +- [Targeted test log](pytest_targeted.log), [JUnit results](pytest_targeted.xml), [execution metadata](pytest_targeted_metadata.json). +- [Full-suite log](pytest.log) and [execution metadata](pytest_metadata.json): 540-second timeout. Partial progress: 261 passed, one skipped, 39 unfinished. No completed full-suite verdict. +- [Initial build log](paper_build.log): LuaTeX cache-permission failure. +- [Successful build log](paper_build_cached.log), [execution metadata](paper_build_cached_metadata.json). +- Fresh compiled manuscript: `reproduction_workspace/paper/manuscript_marine.pdf`. +- Visual QA: `figures/page_*.png` and `figures/fresh_page_*.png`. + +The fresh PDF uses current source and pre-existing numerical graphics. Successful compilation does not establish experiment reproduction. + +Reports, probe outputs, logs, and page renders are versioned. +The duplicate compilation workspace and font caches stay local. +They are excluded by `review/.gitignore`. +The fresh PDF path above describes a local audit artifact. diff --git a/review/evidence/aggregation_probe/aggregate/sweep.jsonl b/review/evidence/aggregation_probe/aggregate/sweep.jsonl new file mode 100644 index 0000000..1409e1e --- /dev/null +++ b/review/evidence/aggregation_probe/aggregate/sweep.jsonl @@ -0,0 +1,2 @@ +{"case_id": "probe", "config_index": 0, "ok": false, "rms": null} +{"case_id": "probe", "config_index": 0, "ok": false, "rms": null} diff --git a/review/evidence/aggregation_probe/shard-00000-of-00002.jsonl b/review/evidence/aggregation_probe/shard-00000-of-00002.jsonl new file mode 100644 index 0000000..1409e1e --- /dev/null +++ b/review/evidence/aggregation_probe/shard-00000-of-00002.jsonl @@ -0,0 +1,2 @@ +{"case_id": "probe", "config_index": 0, "ok": false, "rms": null} +{"case_id": "probe", "config_index": 0, "ok": false, "rms": null} diff --git a/review/evidence/audit_probes.json b/review/evidence/audit_probes.json new file mode 100644 index 0000000..851ed2a --- /dev/null +++ b/review/evidence/audit_probes.json @@ -0,0 +1,69 @@ +{ + "python": "3.12.13 | packaged by conda-forge | (main, Mar 5 2026, 17:06:14) [Clang 19.1.7 ]", + "numpy": "2.4.3", + "scipy": "1.17.1", + "sparse_score": { + "easy-volcano-01": { + "n_days": 1095, + "n_finite_sparse": 10, + "all_zero_score": 0.0, + "ten_zero_rest_null_score": 1.0 + }, + "medium-earthquake_fault-02": { + "n_days": 1095, + "n_finite_sparse": 10, + "all_zero_score": 0.0, + "ten_zero_rest_null_score": 1.0 + }, + "hard-groundwater-04": { + "n_days": 913, + "n_finite_sparse": 10, + "all_zero_score": 0.0, + "ten_zero_rest_null_score": 1.0 + } + }, + "advisor_mapping": { + "volcano": "easy-volcano-01", + "earthquake_fault": "medium-earthquake_fault-02", + "landslide": "KeyError: 'landslide'", + "groundwater": "hard-groundwater-04", + "cryosphere": "KeyError: 'cryosphere'", + "geothermal": "KeyError: 'geothermal'" + }, + "floor_time_unit_probe": { + "seconds": 0.0009269543467363752, + "milliseconds_reexpression": 2.9312870226804134e-05, + "ratio": 0.0316227766016838, + "note": "Dimensional diagnostic, not a supported milliseconds API call." + }, + "mixture_variance": { + "zero_mean_mixture_true_variance": 1.7952069683788366e-06, + "reported_variance": 2.4620556958918783e-06, + "extra_floor_variance": 6.668487275130417e-07, + "note": "No conditional-mean difference is supplied." + }, + "shared_bias_counterexample": { + "true_signal": "zero; all pipelines share the same sinusoidal artifact", + "error_rms": 0.00212135623401608, + "median_Cd_std": 5.998023899798922e-05, + "fraction_zero_inside_mu_plusminus_2sd": 0.06666666666666667, + "note": "Constructed counterexample, not an empirical coverage estimate." + }, + "irregular_time": { + "mu_identical_after_1000_day_gap": true, + "note": "Times affect posthoc Cd, not the index-based smoothness prior." + }, + "bayes_config_semantics": { + "fixed_gated_equals_moving_ungated": true, + "labels_identical": true, + "cadence_days": 3, + "stack_records": 10, + "window_span_days": 27 + }, + "cache_consistency": { + "cold_dtype": "float64", + "warm_dtype": "float32", + "array_equal": false, + "max_absolute_difference": 4.768302961366544e-07 + } +} diff --git a/review/evidence/audit_probes.py b/review/evidence/audit_probes.py new file mode 100644 index 0000000..d7ae16d --- /dev/null +++ b/review/evidence/audit_probes.py @@ -0,0 +1,139 @@ +"""Bounded audit probes. Writes only inside review/evidence. + +Run from the repository root: +MPLCONFIGDIR=/tmp/codameter-review-mpl .pixi/envs/default/bin/python review/evidence/audit_probes.py +""" +import json +import sys +import tempfile +from pathlib import Path + +import numpy as np +import scipy +from codameter import frugalmind, golden, uq_bayes, use_cases +from codameter.uq_measurement import weaver_stretching_error +from codameter.uq_processing import ( + ProcessingChoice, + choice_floor, + per_band_marginal_error, +) + +outdir = Path(__file__).resolve().parent +temporary_cache = tempfile.TemporaryDirectory(prefix="codameter-audit-") +golden.CACHE_DIR = Path(temporary_cache.name) +results = {"python": sys.version, "numpy": np.__version__, "scipy": scipy.__version__} + +# Test actual agent-facing scorer with a valid JSON null array. +scores = {} +for case in golden.CASES: + d = golden.generate(case["id"], cache=False) + # Avoid writing a second large cache. Scorer receives identical generated data. + original_generate = golden.generate + golden.generate = lambda case_id, _data=d, **kw: _data + try: + gold = frugalmind._gold(case, "dvv_series") + n = len(d["days"]) + sparse = [0.0] * 10 + [None] * (n - 10) + scores[case["id"]] = { + "n_days": n, + "n_finite_sparse": 10, + "all_zero_score": frugalmind.score_dvv_series(json.dumps([0.0] * n), gold), + "ten_zero_rest_null_score": frugalmind.score_dvv_series( + json.dumps(sparse), gold + ), + } + finally: + golden.generate = original_generate +results["sparse_score"] = scores + +# Check all six application mappings without private data. +results["advisor_mapping"] = {} +for key in use_cases.USE_CASES: + try: + results["advisor_mapping"][key] = golden.MAINSTREAM_BY_USE_CASE[key] + except KeyError as exc: + results["advisor_mapping"][key] = "KeyError: " + str(exc) + +# A time-unit change should not alter fractional uncertainty. +s_seconds = weaver_stretching_error(0.9, 1.0, 10.0, 30.0) +s_milliseconds = weaver_stretching_error(0.9, 0.001, 10000.0, 30000.0) +results["floor_time_unit_probe"] = { + "seconds": s_seconds, + "milliseconds_reexpression": s_milliseconds, + "ratio": s_milliseconds / s_seconds, + "note": "Dimensional diagnostic, not a supported milliseconds API call.", +} + +# Exact zero-mean Gaussian mixture: marginal variance is mean(sigma_c^2). +choices = [ + ProcessingChoice("fixed", 1.0, 10.0, 20.0, 0.9), + ProcessingChoice("fixed", 1.0, 20.0, 40.0, 0.9), +] +floors = np.array([choice_floor(c) for c in choices]) +reported = per_band_marginal_error(choices)[1.0] +results["mixture_variance"] = { + "zero_mean_mixture_true_variance": float(np.mean(floors**2)), + "reported_variance": reported["total"] ** 2, + "extra_floor_variance": float(np.var(floors, ddof=1)), + "note": "No conditional-mean difference is supplied.", +} + +# Shared systematic drift cannot be learned from agreement among pipelines. +t = np.arange(30, dtype=float) +shared_drift = 0.003 * np.sin(2 * np.pi * t / 30) +members = np.tile(shared_drift, (4, 1)) +sigmas = np.full_like(members, 0.0002) +res = uq_bayes.gibbs_dvv(members, sigmas, t, n_iter=600, burn=200, thin=2, seed=11) +sd = np.sqrt(np.diag(res.Cd)) +results["shared_bias_counterexample"] = { + "true_signal": "zero; all pipelines share the same sinusoidal artifact", + "error_rms": float(np.sqrt(np.mean(res.mu_mean**2))), + "median_Cd_std": float(np.median(sd)), + "fraction_zero_inside_mu_plusminus_2sd": float( + np.mean(np.abs(res.mu_mean) <= 2 * sd) + ), + "note": "Constructed counterexample, not an empirical coverage estimate.", +} + +# The sampler's latent estimate ignores actual time spacing. +irregular_t = t.copy() +irregular_t[15:] += 1000 +irr = uq_bayes.gibbs_dvv( + members, sigmas, irregular_t, n_iter=600, burn=200, thin=2, seed=11 +) +results["irregular_time"] = { + "mu_identical_after_1000_day_gap": bool(np.array_equal(res.mu_mean, irr.mu_mean)), + "note": "Times affect posthoc Cd, not the index-based smoothness prior.", +} + +# Check ignored configuration axes in the Bayesian ensemble. +d = golden.generate("easy-volcano-01", cache=False) +cfg = use_cases.recommend("volcano") +other = dict(cfg, reference="moving", gate=False) +ens = uq_bayes.run_processing_ensemble( + d["ccfs"][:60], d["t"], d["fs"], [cfg, other], cadence=3, days=d["days"][:60] +) +results["bayes_config_semantics"] = { + "fixed_gated_equals_moving_ungated": bool( + np.array_equal(ens.members[0], ens.members[1]) + ), + "labels_identical": ens.labels[0] == ens.labels[1], + "cadence_days": 3, + "stack_records": cfg["stack"], + "window_span_days": (cfg["stack"] - 1) * 3, +} + +# A cold cache returns float64; warm cache returns downcast float32. +cold = golden.generate("easy-volcano-01", cache=True) +warm = golden.generate("easy-volcano-01", cache=True) +results["cache_consistency"] = { + "cold_dtype": str(cold["ccfs"].dtype), + "warm_dtype": str(warm["ccfs"].dtype), + "array_equal": bool(np.array_equal(cold["ccfs"], warm["ccfs"])), + "max_absolute_difference": float(np.max(np.abs(cold["ccfs"] - warm["ccfs"]))), +} + +output = json.dumps(results, indent=2, allow_nan=False) +(outdir / "audit_probes.json").write_text(output + "\n") +print(output) +temporary_cache.cleanup() diff --git a/review/evidence/citation_inventory.json b/review/evidence/citation_inventory.json new file mode 100644 index 0000000..0c996ac --- /dev/null +++ b/review/evidence/citation_inventory.json @@ -0,0 +1,1274 @@ +{ + "entries": { + "poupinet84": { + "author": "Poupinet, G. and Ellsworth, W. L. and Frechet, J.", + "year": "1984", + "journal": "Journal of Geophysical Research: Solid Earth", + "title": "Monitoring velocity variations in the crust using earthquake doublets: An application to the {Calaveras} Fault, {California}", + "doi": "10.1029/jb089ib07p05719" + }, + "lobkis03": { + "author": "Lobkis, Oleg I. and Weaver, Richard L.", + "year": "2003", + "journal": "Physical Review Letters", + "title": "Coda-Wave Interferometry in Finite Solids: Recovery of {P}-to-{S} Conversion Rates in an Elastodynamic Billiard", + "doi": "10.1103/PhysRevLett.90.254302" + }, + "SensSchonfelder2006": { + "author": "Sens-Sch{\\\"o}nfelder, Christoph and Wegler, Ulrich", + "year": "2006", + "journal": "Geophysical Research Letters", + "title": "Passive image interferometry and seasonal variations of seismic velocities at {Merapi} Volcano, {Indonesia}", + "doi": "10.1029/2006GL027797" + }, + "Snieder2002": { + "author": "Snieder, Roel and Gr{\\^e}t, Alexandre and Douma, Huub and Scales, John", + "year": "2002", + "journal": "Science", + "title": "Coda wave interferometry for estimating nonlinear behavior in seismic velocity", + "doi": "10.1126/science.1070015" + }, + "Bensen2007": { + "author": "Bensen, G. D. and Ritzwoller, M. H. and Barmin, M. P. and Levshin, A. L. and Lin, F. and Moschetti, M. P. and Shapiro, N. M. and Yang, Y.", + "year": "2007", + "journal": "Geophysical Journal International", + "title": "Processing seismic ambient noise data to obtain reliable broad-band surface wave dispersion measurements", + "doi": "10.1111/j.1365-246X.2007.03374.x" + }, + "Clarke2011": { + "author": "Clarke, D. and Zaccarelli, L. and Shapiro, N. M. and Brenguier, F.", + "year": "2011", + "journal": "Geophysical Journal International", + "title": "Assessment of resolution and accuracy of the Moving Window Cross Spectral technique for monitoring crustal temporal variations using ambient seismic noise", + "doi": "10.1111/j.1365-246X.2011.05074.x" + }, + "Weaver2011": { + "author": "Weaver, Richard L. and Hadziioannou, C{\\'e}line and Larose, Eric and Campillo, Michel", + "year": "2011", + "journal": "Geophysical Journal International", + "title": "On the precision of noise correlation interferometry", + "doi": "10.1111/j.1365-246X.2011.05015.x" + }, + "Brenguier2014": { + "author": "Brenguier, F. and Campillo, M. and Takeda, T. and Aoki, Y. and Shapiro, N. M. and Briand, X. and Emoto, K. and Miyake, H.", + "year": "2014", + "journal": "Science", + "title": "Mapping pressurized volcanic fluids from induced crustal seismic velocity drops", + "doi": "10.1126/science.1254073" + }, + "Mikesell2015": { + "author": "Mikesell, T. Dylan and Malcolm, Alison E. and Yang, Di and Haney, Matthew M.", + "year": "2015", + "journal": "Geophysical Journal International", + "title": "A comparison of methods to estimate seismic phase delays: numerical examples for coda wave interferometry", + "doi": "10.1093/gji/ggv138" + }, + "Lecocq2014": { + "author": "Lecocq, Thomas and Caudron, Corentin and Brenguier, Florent", + "year": "2014", + "journal": "Seismological Research Letters", + "title": "{MSNoise}, a {Python} package for monitoring seismic velocity changes using ambient seismic noise", + "doi": "10.1785/0220130073" + }, + "Jiang2020": { + "author": "Jiang, Chengxin and Denolle, Marine A.", + "year": "2020", + "journal": "Seismological Research Letters", + "title": "{NoisePy}: a new high-performance python tool for ambient-noise seismology", + "doi": "10.1785/0220190364" + }, + "Yuan2021": { + "author": "Yuan, Congcong and Bryan, Jared and Denolle, Marine", + "year": "2021", + "journal": "Geophysical Journal International", + "title": "Numerical comparison of time-, frequency- and wavelet-domain methods for coda wave interferometry", + "doi": "10.1093/gji/ggab140" + }, + "Mao2020": { + "author": "Mao, Shujuan and Mordret, Aur{\\'e}lien and Campillo, Michel and Fang, Hongjian and van der Hilst, Robert D.", + "year": "2020", + "journal": "Geophysical Journal International", + "title": "On the measurement of seismic traveltime changes in the time--frequency domain with wavelet cross-spectrum analysis", + "doi": "10.1093/gji/ggz495" + }, + "Sato1993": { + "author": "Sato, Haruo", + "year": "1993", + "journal": "Geophysical Journal International", + "title": "Energy transportation in one- and two-dimensional scattering media: analytic solutions of the multiple isotropic scattering model", + "doi": "10.1111/j.1365-246X.1993.tb01443.x" + }, + "Paasschens1997": { + "author": "Paasschens, J. C. J.", + "year": "1997", + "journal": "Physical Review E", + "title": "Solution of the time-dependent Boltzmann equation", + "doi": "10.1103/PhysRevE.56.1135" + }, + "Margerin1998": { + "author": "Margerin, Ludovic and Campillo, Michel and Van Tiggelen, Bart", + "year": "1998", + "journal": "Geophysical Journal International", + "title": "Radiative transfer and diffusion of waves in a layered medium: new insight into coda Q", + "doi": "10.1046/j.1365-246x.1998.00571.x" + }, + "Obermann2013": { + "author": "Obermann, Anne and Plan{\\`e}s, Thomas and Larose, Eric and Sens-Sch{\\\"o}nfelder, Christoph and Campillo, Michel", + "year": "2013", + "journal": "Geophysical Journal International", + "title": "Depth sensitivity of seismic coda waves to velocity perturbations in an elastic heterogeneous medium", + "doi": "10.1093/gji/ggt043" + }, + "Obermann2016": { + "author": "Obermann, Anne and Plan{\\`e}s, Thomas and Hadziioannou, C{\\'e}line and Campillo, Michel", + "year": "2016", + "journal": "Geophysical Journal International", + "title": "Lapse-time-dependent coda-wave depth sensitivity to local velocity perturbations in 3-D heterogeneous elastic media", + "doi": "10.1093/gji/ggw264" + }, + "Zhan2013": { + "author": "Zhan, Zhongwen and Tsai, Victor C. and Clayton, Robert W.", + "year": "2013", + "journal": "Geophysical Journal International", + "title": "Spurious velocity changes caused by temporal variations in ambient noise frequency content", + "doi": "10.1093/gji/ggt170" + }, + "Clements2018": { + "author": "Clements, Timothy and Denolle, Marine A.", + "year": "2018", + "journal": "Geophysical Research Letters", + "title": "Tracking groundwater levels using the ambient seismic field", + "doi": "10.1029/2018GL077706" + }, + "Stehly2015": { + "author": "Stehly, L. and Froment, B. and Campillo, M. and Liu, Q. Y. and Chen, J. H.", + "year": "2015", + "journal": "Geophysical Journal International", + "title": "Monitoring seismic wave velocity changes associated with the {Mw} 7.9 {Wenchuan} earthquake: increasing the temporal resolution using curvelet filters", + "doi": "10.1093/gji/ggv110" + }, + "Lin2008": { + "author": "Lin, Fan-Chi and Moschetti, Morgan P. and Ritzwoller, Michael H.", + "year": "2008", + "journal": "Geophysical Journal International", + "title": "Surface wave tomography of the western {United States} from ambient seismic noise: {Rayleigh} and {Love} wave phase velocity maps", + "doi": "10.1111/j.1365-246X.2008.03720.x" + }, + "Stehly2006": { + "author": "Stehly, Laurent and Campillo, Michel and Shapiro, Nikolai M.", + "year": "2006", + "journal": "Journal of Geophysical Research", + "title": "A study of the seismic noise from its long-range correlation properties", + "doi": "10.1029/2005JB004237" + }, + "Hennino2001": { + "author": "Hennino, R. and Tr{\\'e}gour{\\`e}s, N. and Shapiro, N. M. and Margerin, L. and Campillo, M. and van Tiggelen, B. A. and Weaver, R. L.", + "year": "2001", + "journal": "Physical Review Letters", + "title": "Observation of Equipartition of Seismic Waves", + "doi": "10.1103/PhysRevLett.86.3447" + }, + "Margerin2019": { + "author": "Margerin, Ludovic and Bajaras, Andres and Campillo, Michel", + "year": "2019", + "journal": "Geophysical Journal International", + "title": "A scalar radiative transfer model including the coupling between surface and body waves", + "doi": "10.1093/gji/ggz348" + }, + "Steegen2016": { + "author": "Steegen, Sara and Tuerlinckx, Francis and Gelman, Andrew and Vanpaemel, Wolf", + "year": "2016", + "journal": "Perspectives on Psychological Science", + "title": "Increasing transparency through a multiverse analysis", + "doi": "10.1177/1745691616658637" + }, + "Gelman2013": { + "author": "Gelman, Andrew and Loken, Eric", + "year": "2013", + "journal": "Department of Statistics, Columbia University (working paper)", + "title": "The garden of forking paths", + "doi": "" + }, + "Pacheco2005": { + "author": "Pacheco, Carlos and Snieder, Roel", + "year": "2005", + "journal": "The Journal of the Acoustical Society of America", + "title": "Time-lapse travel time change of multiply scattered acoustic waves", + "doi": "10.1121/1.1979437" + }, + "Okubo2024": { + "author": "Okubo, Kurama and Delbridge, Brent G. and Denolle, Marine A.", + "year": "2024", + "journal": "Journal of Geophysical Research: Solid Earth", + "title": "Monitoring Velocity Change Over 20 Years at Parkfield", + "doi": "10.1029/2023JB028084" + }, + "Denolle25b": { + "author": "Denolle, Marine A. and Shi, Qibin and Clements, Tim and Viens, Lo{\\\"\\i}c and Rodriguez-Tribaldos, Veronica and Cotton, Fabrice", + "year": "2025", + "journal": "Comptes Rendus. G\\'eoscience", + "title": "Ambient field seismology in critical zone hydrological sciences", + "doi": "10.5802/crgeos.310" + }, + "Kidiwela2026": { + "author": "Kidiwela, Maleen and Denolle, Marine A. and Wilcock, William S. D. and Feng, K. F.", + "year": "2026", + "journal": "Science Advances", + "title": "Active protothrusts and fluid highways: Seismic noise reveals hidden subduction dynamics in Cascadia", + "doi": "10.1126/sciadv.aea3684" + }, + "Gassmann1951": { + "author": "Gassmann, Fritz", + "year": "1951", + "journal": "Vierteljahrsschrift der Naturforschenden Gesellschaft in Z{\\\"u}rich", + "title": "{\\\"U}ber die Elastizit{\\\"a}t por{\\\"o}ser Medien", + "doi": "" + }, + "Mavko2009": { + "author": "Mavko, Gary and Mukerji, Tapan and Dvorkin, Jack", + "year": "2009", + "journal": "", + "title": "The Rock Physics Handbook: Tools for Seismic Analysis of Porous Media", + "doi": "10.1017/CBO9780511626753" + }, + "CubukSabuncu2021": { + "author": "Cubuk-Sabuncu, Ye{\\c s}im and J{\\'o}nsd{\\'o}ttir, Krist\u00edn and Caudron, Corentin and Lecocq, Thomas and Parks, Michelle and Geirsson, Halld{\\'o}r and Mordret, Aur{\\'e}lien", + "year": "2021", + "journal": "Geophysical Research Letters", + "title": "Temporal Seismic Velocity Changes During the 2020 Rapid Inflation at Mt. {\\th}orbj{\\\"o}rn-Svartsengi, Iceland, Using Seismic Ambient Noise", + "doi": "10.1029/2020GL092265" + }, + "Ouellet2022": { + "author": "Ouellet, Susanne M. and Dettmer, Jan and Olivier, Gerrit and de Wit, Tjaart and Lato, Matt", + "year": "2022", + "journal": "Communications Earth \\& Environment", + "title": "Advanced monitoring of tailings dam performance using seismic noise and stress models", + "doi": "10.1038/s43247-022-00629-w" + }, + "Planes2016": { + "author": "Plan{\\`e}s, Thomas and Mooney, Michael A. and Rittgers, Jacob B. R. and Parekh, Malcolm L. and Behm, Michael and Snieder, Roel", + "year": "2016", + "journal": "G{\\'e}otechnique", + "title": "Time-lapse monitoring of internal erosion in earthen dams and levees using ambient seismic noise", + "doi": "10.1680/jgeot.14.P.268" + }, + "Tsuji2021": { + "author": "Tsuji, Takeshi and Ikeda, Tatsunori and Matsuura, Ryosuke and Mukumoto, Kota and Hutapea, Fernando Lawrens and Kimura, Tsunehisa and Yamaoka, Koshun and Shinohara, Masanao", + "year": "2021", + "journal": "Scientific Reports", + "title": "Continuous monitoring system for safe managements of {CO2} storage and geothermal reservoirs", + "doi": "10.1038/s41598-021-97881-5" + }, + "Rivet2014": { + "author": "Rivet, Diane and Brenguier, Florent and Clarke, Daniel and Shapiro, Nikola{\\\"i} M. and Peltier, Aline", + "year": "2014", + "journal": "Journal of Geophysical Research: Solid Earth", + "title": "Long-term dynamics of {Piton de la Fournaise} volcano from 13 years of seismic velocity change measurements and {GPS} observations", + "doi": "10.1002/2014JB011307" + }, + "SensSchonfelder2014": { + "author": "Sens-Sch{\\\"o}nfelder, Christoph and Pomponi, Eraldo and Peltier, Aline", + "year": "2014", + "journal": "Journal of Volcanology and Geothermal Research", + "title": "Dynamics of {Piton de la Fournaise} volcano observed by passive image interferometry with multiple references", + "doi": "10.1016/j.jvolgeores.2014.02.012" + }, + "James2017": { + "author": "James, S. R. and Knox, H. A. and Abbott, R. E. and Screaton, E. J.", + "year": "2017", + "journal": "Geophysical Research Letters", + "title": "Improved moving window cross-spectral analysis for resolving large temporal seismic velocity changes in permafrost", + "doi": "10.1002/2016GL072468" + }, + "ZotzWilson2019": { + "author": "Zotz-Wilson, Reuben and Boerrigter, Thijs and Barnhoorn, Auke", + "year": "2019", + "journal": "The Journal of the Acoustical Society of America", + "title": "Coda-wave monitoring of continuously evolving material properties and the precursory detection of yielding", + "doi": "10.1121/1.5091012" + }, + "Hadziioannou2011": { + "author": "Hadziioannou, C. and Larose, E. and Baig, A. and Roux, P. and Campillo, M.", + "year": "2011", + "journal": "Journal of Geophysical Research: Solid Earth", + "title": "Improving temporal resolution in ambient noise monitoring of seismic wave speed", + "doi": "10.1029/2011JB008200" + }, + "Moreau2017": { + "author": "Moreau, L. and Stehly, L. and Bou\u00e9, P. and Lu, Y. and Larose, E. and Campillo, M.", + "year": "2017", + "journal": "Geophysical Journal International", + "title": "Improving ambient noise correlation functions with an {SVD}-based {W}iener filter", + "doi": "10.1093/gji/ggx306" + }, + "Mao2019": { + "author": "Mao, Shujuan and Campillo, Michel and van der Hilst, Robert D. and Brenguier, Florent and Stehly, Laurent and Hillers, Gregor", + "year": "2019", + "journal": "Geophysical Research Letters", + "title": "High temporal resolution monitoring of small variations in crustal strain by dense seismic arrays", + "doi": "10.1029/2018GL079944" + }, + "Viens2020": { + "author": "Viens, Lo\u00efc and Van Houtte, Chris", + "year": "2020", + "journal": "Geophysical Journal International", + "title": "Denoising ambient seismic field correlation functions with convolutional autoencoders", + "doi": "10.1093/gji/ggz509" + }, + "Brenguier2008": { + "author": "Brenguier, Florent and Shapiro, Nikolai M. and Campillo, Michel and Ferrazzini, Val{\\'e}rie and Duputel, Zacharie and Coutant, Olivier and Nercessian, Alexandre", + "year": "2008", + "journal": "Nature Geoscience", + "title": "Towards forecasting volcanic eruptions using seismic noise", + "doi": "10.1038/ngeo104" + }, + "Duputel2009": { + "author": "Duputel, Zacharie and Ferrazzini, Val{\\'e}rie and Brenguier, Florent and Shapiro, Nikolai and Campillo, Michel and Nercessian, Alexandre", + "year": "2009", + "journal": "Journal of Volcanology and Geothermal Research", + "title": "Real time monitoring of relative velocity changes using ambient seismic noise at the Piton de la Fournaise volcano (La R{\\'e}union) from January 2006 to June 2007", + "doi": "10.1016/j.jvolgeores.2008.11.024" + }, + "HotovecEllis2014": { + "author": "HotovecEllis, A. J. and Gomberg, J. and Vidale, J. E. and Creager, K. C.", + "year": "2014", + "journal": "Journal of Geophysical Research: Solid Earth", + "title": "A continuous record of intereruption velocity change at Mount St. Helens from coda wave interferometry", + "doi": "10.1002/2013jb010742" + }, + "HotovecEllis2015": { + "author": "HotovecEllis, A. J. and Vidale, J. E. and Gomberg, J. and Thelen, W. and Moran, S. C.", + "year": "2015", + "journal": "Journal of Geophysical Research: Solid Earth", + "title": "Changes in seismic velocity during the first 14 months of the 20042008 eruption of Mount St. Helens, Washington", + "doi": "10.1002/2015jb012101" + }, + "Rivet2015": { + "author": "Rivet, Diane and Brenguier, Florent and Cappa, Fr{\\'e}d{\\'e}ric", + "year": "2015", + "journal": "Geophysical Research Letters", + "title": "Improved detection of preeruptive seismic velocity drops at the Piton de La Fournaise volcano", + "doi": "10.1002/2015gl064835" + }, + "DePlaen2016": { + "author": "De Plaen, Raphael S. M. and Lecocq, Thomas and Caudron, Corentin and Ferrazzini, Val{\\'e}rie and Francis, Olivier", + "year": "2016", + "journal": "Geophysical Research Letters", + "title": "Singlestation monitoring of volcanoes using seismic ambient noise", + "doi": "10.1002/2016gl070078" + }, + "Donaldson2017": { + "author": "Donaldson, Clare and Caudron, Corentin and Green, Robert G. and Thelen, Weston A. and White, Robert S.", + "year": "2017", + "journal": "Science Advances", + "title": "Relative seismic velocity variations correlate with deformation at K{\\=i}lauea volcano", + "doi": "10.1126/sciadv.1700219" + }, + "Takano2017": { + "author": "Takano, Tomoya and Nishimura, Takeshi and Nakahara, Hisashi", + "year": "2017", + "journal": "Journal of Geophysical Research: Solid Earth", + "title": "Seismic velocity changes concentrated at the shallow structure as inferred from correlation analyses of ambient noise during volcano deformation at IzuOshima, Japan", + "doi": "10.1002/2017jb014340" + }, + "Lesage2018": { + "author": "Lesage, Philippe and Carrara, Alexandre and Pinel, Virginie and Ar{\\'a}mbula-Mendoza, Raul", + "year": "2018", + "journal": "Frontiers in Earth Science", + "title": "Absence of Detectable Precursory Deformation and Velocity Variation Before the Large Dome Collapse of July 2015 at Volc{\\'a}n de Colima, Mexico", + "doi": "10.3389/feart.2018.00093" + }, + "DePlaen2019": { + "author": "De Plaen, Raphael S. M. and Cannata, Andrea and Cannavo', Flavio and Caudron, Corentin and Lecocq, Thomas and Francis, Olivier", + "year": "2019", + "journal": "Frontiers in Earth Science", + "title": "Temporal Changes of Seismic Velocity Caused by Volcanic Activity at Mt. Etna Revealed by the Autocorrelation of Ambient Seismic Noise", + "doi": "10.3389/feart.2018.00251" + }, + "Donaldson2019": { + "author": "Donaldson, C. and Winder, T. and Caudron, C. and White, R. S.", + "year": "2019", + "journal": "Science Advances", + "title": "Crustal seismic velocity responds to a magmatic intrusion and seasonal loading in Icelands Northern Volcanic Zone", + "doi": "10.1126/sciadv.aax6642" + }, + "Olivier2019": { + "author": "Olivier, G. and Brenguier, F. and Carey, R. and Okubo, P. and Donaldson, C.", + "year": "2019", + "journal": "Geophysical Research Letters", + "title": "Decrease in Seismic Velocity Observed Prior to the 2018 Eruption of K{\\=i}lauea Volcano With Ambient Seismic Noise Interferometry", + "doi": "10.1029/2018gl081609" + }, + "Yates2019": { + "author": "Yates, A. S. and Savage, M. K. and Jolly, A. D. and Caudron, C. and Hamling, I. J.", + "year": "2019", + "journal": "Geophysical Research Letters", + "title": "Volcanic, Coseismic, and Seasonal Changes Detected at White Island (Whakaari) Volcano, New Zealand, Using Seismic Ambient Noise", + "doi": "10.1029/2018gl080580" + }, + "Feng2020": { + "author": "Feng, Kuan-Fu and Huang, Hsin-Hua and Wu, Yih-Min", + "year": "2020", + "journal": "Earth, Planets and Space", + "title": "Detecting pre-eruptive magmatic processes of the 2018 eruption at Kilauea, Hawaii volcano with ambient noise interferometry", + "doi": "10.1186/s40623-020-01199-x" + }, + "HotovecEllis2022": { + "author": "HotovecEllis, Alicia J. and Shiro, Brian R. and Shelly, David R. and Anderson, Kyle R. and Haney, Matthew M. and Thelen, Weston A. and MontgomeryBrown, Emily K. and Johanson, Ingrid A.", + "year": "2022", + "journal": "Journal of Geophysical Research: Solid Earth", + "title": "EarthquakeDerived Seismic Velocity Changes During the 2018 Caldera Collapse of K{\\=i}lauea Volcano", + "doi": "10.1029/2021jb023324" + }, + "Kopfli2024": { + "author": "K{\\\"o}pfli, Manuela and Denolle, Marine A. and Thelen, Weston A. and Makus, Peter and Malone, Stephen D.", + "year": "2024", + "journal": "Seismological Research Letters", + "title": "Examining 22 Years of Ambient Seismic Wavefield at Mount St. Helens", + "doi": "10.1785/0220240079" + }, + "Yates2024": { + "author": "Yates, Alexander S. and Caudron, Corentin and Mordret, Aur{\\'e}lien and Lesage, Philippe and Pinel, Virginie and Lecocq, Thomas and Miller, Craig A. and Lamb, Oliver D. and Fournier, Nicolas", + "year": "2024", + "journal": "Journal of Geophysical Research: Solid Earth", + "title": "Seasonal Snow Cycles and Their Possible Influence on Seismic Velocity Changes and Eruptive Activity at Ruapehu Volcano, New Zealand", + "doi": "10.1029/2024jb029568" + }, + "Yukutake2025": { + "author": "Yukutake, Yohei and Taira, Taka'aki and Onizawa, Shin'ya and Morita, Yuichi", + "year": "2025", + "journal": "Journal of Geophysical Research: Solid Earth", + "title": "Decadal Monitoring of Seismic Velocity Changes Beneath IzuOshima, Central Japan, Using Ambient Seismic Noise Records", + "doi": "10.1029/2025jb031170" + }, + "Schaff2004": { + "author": "Schaff, David P. and Beroza, Gregory C.", + "year": "2004", + "journal": "Journal of Geophysical Research: Solid Earth", + "title": "Coseismic and postseismic velocity changes measured by repeating earthquakes", + "doi": "10.1029/2004jb003011" + }, + "Rubinstein2005": { + "author": "Rubinstein, Justin L. and Beroza, Gregory C.", + "year": "2005", + "journal": "Geophysical Research Letters", + "title": "Depth constraints on nonlinear strong ground motion from the 2004 Parkfield earthquake", + "doi": "10.1029/2005gl023189" + }, + "Wegler2007": { + "author": "Wegler, U. and Sens-Sch{\\\"o}nfelder, C.", + "year": "2007", + "journal": "Geophysical Journal International", + "title": "Fault zone monitoring with passive image interferometry", + "doi": "10.1111/j.1365-246x.2006.03284.x" + }, + "Brenguier2008b": { + "author": "Brenguier, F. and Campillo, M. and Hadziioannou, C. and Shapiro, N. M. and Nadeau, R. M. and Larose, E.", + "year": "2008", + "journal": "Science", + "title": "Postseismic Relaxation Along the San Andreas Fault at Parkfield from Continuous Seismological Observations", + "doi": "10.1126/science.1160943" + }, + "Hadziioannou2009": { + "author": "Hadziioannou, C{\\'e}line and Larose, Eric and Coutant, Olivier and Roux, Philippe and Campillo, Michel", + "year": "2009", + "journal": "The Journal of the Acoustical Society of America", + "title": "Stability of monitoring weak changes in multiply scattering media with ambient noise correlation: Laboratory experiments", + "doi": "10.1121/1.3125345" + }, + "Sawazaki2009": { + "author": "Sawazaki, K. and Sato, H. and Nakahara, H. and Nishimura, T.", + "year": "2009", + "journal": "Bulletin of the Seismological Society of America", + "title": "Time-Lapse Changes of Seismic Velocity in the Shallow Ground Caused by Strong Ground Motion Shock of the 2000 Western-Tottori Earthquake, Japan, as Revealed from Coda Deconvolution Analysis", + "doi": "10.1785/0120080058" + }, + "Wegler2009": { + "author": "Wegler, U. and Nakahara, H. and SensSch{\\\"o}nfelder, C. and Korn, M. and Shiomi, K.", + "year": "2009", + "journal": "Journal of Geophysical Research: Solid Earth", + "title": "Sudden drop of seismic velocity after the 2004 M\\textsubscript{w} 6.6 midNiigata earthquake, Japan, observed with Passive Image Interferometry", + "doi": "10.1029/2008jb005869" + }, + "Chen2010": { + "author": "Chen, Jiu Hui and Froment, B{\\'e}r{\\'e}nice and Liu, Qi Yuan and Campillo, Michel", + "year": "2010", + "journal": "Geophysical Research Letters", + "title": "Distribution of seismic wave speed changes associated with the 12 May 2008 Mw 7.9 Wenchuan earthquake", + "doi": "10.1029/2010gl044582" + }, + "Nakata2011": { + "author": "Nakata, N. and Snieder, R.", + "year": "2011", + "journal": "Geophysical Research Letters", + "title": "Near-surface weakening in Japan after the 2011 Tohoku-Oki earthquake", + "doi": "10.1029/2011gl048800" + }, + "Rivet2011": { + "author": "Rivet, Diane and Campillo, Michel and Shapiro, Nikolai M. and Cruz-Atienza, Victor and Radiguet, Mathilde and Cotte, Nathalie and Kostoglodov, Vladimir", + "year": "2011", + "journal": "Geophysical Research Letters", + "title": "Seismic evidence of nonlinear crustal deformation during a large slow slip event in Mexico", + "doi": "10.1029/2011gl047151" + }, + "Hobiger2012": { + "author": "Hobiger, M. and Wegler, U. and Shiomi, K. and Nakahara, H.", + "year": "2012", + "journal": "Journal of Geophysical Research: Solid Earth", + "title": "Coseismic and postseismic elastic wave velocity variations caused by the 2008 IwateMiyagi Nairiku earthquake, Japan", + "doi": "10.1029/2012jb009402" + }, + "Minato2012": { + "author": "Minato, Shohei and Tsuji, Takeshi and Ohmi, Shiro and Matsuoka, Toshifumi", + "year": "2012", + "journal": "Geophysical Research Letters", + "title": "Monitoring seismic velocity change caused by the 2011 Tohokuoki earthquake using ambient noise records", + "doi": "10.1029/2012gl051405" + }, + "Liu2014": { + "author": "Liu, Zhikun and Huang, Jinli and Peng, Zhigang and Su, Jinrong", + "year": "2014", + "journal": "Geophysical Research Letters", + "title": "Seismic velocity changes in the epicentral region of the 2008 Wenchuan earthquake measured from threecomponent ambient noise correlation techniques", + "doi": "10.1002/2013gl058682" + }, + "Taira2015": { + "author": "Taira, Taka'aki and Brenguier, Florent and Kong, Qingkai", + "year": "2015", + "journal": "Geophysical Research Letters", + "title": "Ambient noisebased monitoring of seismic velocity changes associated with the 2014 M\\textsubscript{w} 6.0 South Napa earthquake", + "doi": "10.1002/2015gl065308" + }, + "Gassenmeier2016": { + "author": "Gassenmeier, M. and Sens-Sch{\\\"o}nfelder, C. and Eulenfeld, T. and Bartsch, M. and Victor, P. and Tilmann, F. and Korn, M.", + "year": "2016", + "journal": "Geophysical Journal International", + "title": "Field observations of seismic velocity changes caused by shaking-induced damage and healing due to mesoscopic nonlinearity", + "doi": "10.1093/gji/ggv529" + }, + "Hillers2019": { + "author": "Hillers, G. and Campillo, M. and Brenguier, F. and Moreau, L. and Agnew, D. C. and BenZion, Y.", + "year": "2019", + "journal": "Journal of Geophysical Research: Solid Earth", + "title": "Seismic Velocity Change Patterns Along the San Jacinto Fault Zone Following the 2010 M7.2 El MayorCucapah and M5.4 Collins Valley Earthquakes", + "doi": "10.1029/2018jb017143" + }, + "Wang2019": { + "author": "Wang, QingYu and Campillo, Michel and Brenguier, Florent and Lecointre, Albanne and Takeda, Tetsuya and Hashima, Akinori", + "year": "2019", + "journal": "Journal of Geophysical Research: Solid Earth", + "title": "Evidence of Changes of Seismic Properties in the Entire Crust Beneath Japan After the M\\textsubscript{w} 9.0, 2011 Tohokuoki Earthquake", + "doi": "10.1029/2019jb017803" + }, + "Poli2020": { + "author": "Poli, Piero and Marguin, Valentin and Wang, Qingyu and D'Agostino, Nicola and Johnson, Paul", + "year": "2020", + "journal": "Journal of Geophysical Research: Solid Earth", + "title": "Seasonal and Coseismic Velocity Variation in the Region of L'Aquila From Single Station Measurements and Implications for Crustal Rheology", + "doi": "10.1029/2019jb019316" + }, + "Boschelli2021": { + "author": "Boschelli, Joshua and Moschetti, Morgan P. and SensSch{\\\"o}nfelder, Christoph", + "year": "2021", + "journal": "Journal of Geophysical Research: Solid Earth", + "title": "Temporal Seismic Velocity Variations: Recovery Following From the 2019 M\\textsubscript{w} 7.1 Ridgecrest, California Earthquake", + "doi": "10.1029/2020jb021465" + }, + "Lu2021": { + "author": "Lu, Y and Ben-Zion, Y", + "year": "2021", + "journal": "Geophysical Journal International", + "title": "Regional seismic velocity changes following the 2019 Mw 7.1 Ridgecrest, California earthquake from autocorrelations and P/S converted waves", + "doi": "10.1093/gji/ggab350" + }, + "Sheng2022": { + "author": "Sheng, Y. and Mordret, A. and Sager, K. and Brenguier, F. and Bou{\\'e}, P. and Rousset, B. and Vernon, F. and Higueret, Q. and BenZion, Y.", + "year": "2022", + "journal": "Geophysical Research Letters", + "title": "Monitoring Seismic Velocity Changes Across the San Jacinto Fault Using TrainGenerated Seismic Tremors", + "doi": "10.1029/2022gl098509" + }, + "Mainsant2012": { + "author": "Mainsant, Gu{\\'e}nol{\\'e} and Larose, Eric and Br{\\\"o}nnimann, Cornelia and Jongmans, Denis and Michoud, Cl{\\'e}ment and Jaboyedoff, Michel", + "year": "2012", + "journal": "Journal of Geophysical Research: Earth Surface", + "title": "Ambient seismic noise monitoring of a clay landslide: Toward failure prediction", + "doi": "10.1029/2011jf002159" + }, + "Voisin2016": { + "author": "Voisin, Christophe and Garambois, St{\\'e}phane and Massey, Chris and Brossier, Romain", + "year": "2016", + "journal": "Interpretation", + "title": "Seismic noise monitoring of the water table in a deep-seated, slow-moving landslide", + "doi": "10.1190/int-2016-0010.1" + }, + "Harba2017": { + "author": "Harba, Paulina and Pilecki, Zenon", + "year": "2016", + "journal": "Landslides", + "title": "Assessment of timespatial changes of shear wave velocities of flysch formation prone to mass movements by seismic interferometry with the use of ambient noise", + "doi": "10.1007/s10346-016-0779-2" + }, + "Bertello2018": { + "author": "Bertello, Lara and Berti, Matteo and Castellaro, Silvia and Squarzoni, Gabriela", + "year": "2018", + "journal": "Journal of Geophysical Research: Earth Surface", + "title": "Dynamics of an Active Earthflow Inferred From Surface Wave Monitoring", + "doi": "10.1029/2017jf004233" + }, + "Bievre2018": { + "author": "Bi{\\`e}vre, Gr{\\'e}gory and Franz, Martin and Larose, Eric and Carri{\\`e}re, Simon and Jongmans, Denis and Jaboyedoff, Michel", + "year": "2018", + "journal": "Engineering Geology", + "title": "Influence of environmental parameters on the seismic velocity changes in a clayey mudflow (Pont-Bourquin Landslide, Switzerland)", + "doi": "10.1016/j.enggeo.2018.08.013" + }, + "Colombero2018": { + "author": "Colombero, C and Baillet, L and Comina, C and Jongmans, D and Larose, E and Valentin, J and Vinciguerra, S", + "year": "2018", + "journal": "Geophysical Journal International", + "title": "Integration of ambient seismic noise monitoring, displacement and meteorological measurements to infer the temperature-controlled long-term evolution of a complex prone-to-fall cliff", + "doi": "10.1093/gji/ggy090" + }, + "Bontemps2020": { + "author": "Bontemps, No{\\'e}lie and Lacroix, Pascal and Larose, Eric and Jara, Jorge and Taipe, Edu", + "year": "2020", + "journal": "Nature Communications", + "title": "Rain and small earthquakes maintain a slow-moving landslide in a persistent critical state", + "doi": "10.1038/s41467-020-14445-3" + }, + "Fiolleau2020": { + "author": "Fiolleau, S and Jongmans, D and Bi{\\`e}vre, G and Chambon, G and Baillet, L and Vial, B", + "year": "2020", + "journal": "Geophysical Journal International", + "title": "Seismic characterization of a clay-block rupture in Harmali{\\`e}re landslide, French Western Alps", + "doi": "10.1093/gji/ggaa050" + }, + "LeBreton2021": { + "author": "Le Breton, Mathieu and Bontemps, No{\\'e}lie and Guillemot, Antoine and Baillet, Laurent and Larose, {\\'E}ric", + "year": "2021", + "journal": "Earth-Science Reviews", + "title": "Landslide monitoring using seismic ambient noise correlation: challenges and applications", + "doi": "10.1016/j.earscirev.2021.103518" + }, + "Fan2023": { + "author": "Xie, Fan and Larose, Eric and Wang, Qingyu and Zhang, Yuxiang", + "year": "2023", + "journal": "Engineering Geology", + "title": "In-situ monitoring of rock slope destabilization with ambient seismic noise interferometry in southwest China", + "doi": "10.1016/j.enggeo.2022.106922" + }, + "Liu2025": { + "author": "Liu, Zhiqiang and Li, Huailiang and Liang, Chuntao and Zhang, Tuo and Jiang, Hao and Huang, Huixuan", + "year": "2026", + "journal": "Geophysical Journal International", + "title": "Enhanced visualization of rainfall infiltration in landslides using high-resolution 4-D noise-based velocity change imaging", + "doi": "10.1093/gji/ggag037" + }, + "Whiteley2026": { + "author": "Watlet, Arnaud and Whiteley, Jim and Dashwood, Ben and Morgan, Dave and Lane, Victoria and Finch, Lucy and Gunn, David and Lecocq, Thomas and Chambers, Jonathan", + "year": "2026", + "journal": "Seismica", + "title": "Seismic response of a slow-moving landslide: exploring data from two years of seismic monitoring at the Hollin Hill Landslide Observatory (UK)", + "doi": "10.26443/seismica.v5i1.1478" + }, + "deWit2026": { + "author": "De Wit, Tjaart and Snieder, Roelof", + "year": "2026", + "journal": "Seismica", + "title": "Did they blow it? Time-lapse velocity variations during an open-pit mine slope failure using seismic noise interferometry", + "doi": "10.26443/seismica.v5i1.1902" + }, + "Tsai2011": { + "author": "Tsai, Victor C.", + "year": "2011", + "journal": "Journal of Geophysical Research", + "title": "A model for seasonal changes in GPS positions and seismic wave speeds due to thermoelastic and hydrologic variations", + "doi": "10.1029/2010jb008156" + }, + "Hillers2014": { + "author": "Hillers, G. and Campillo, M. and Ma, K.-F.", + "year": "2014", + "journal": "Earth and Planetary Science Letters", + "title": "Seismic velocity variations at TCDP are controlled by MJO driven precipitation pattern and high fluid discharge properties", + "doi": "10.1016/j.epsl.2014.01.040" + }, + "Lecocq2017": { + "author": "Lecocq, Thomas and Longuevergne, Laurent and Pedersen, Helle Anette and Brenguier, Florent and Stammler, Klaus", + "year": "2017", + "journal": "Scientific Reports", + "title": "Monitoring ground water storage at mesoscale using seismic noise: 30 years of continuous observation and thermo-elastic and hydrological modeling", + "doi": "10.1038/s41598-017-14468-9" + }, + "Nimiya2017": { + "author": "Nimiya, Hiro and Ikeda, Tatsunori and Tsuji, Takeshi", + "year": "2017", + "journal": "Science Advances", + "title": "Spatial and temporal seismic velocity changes on Kyushu Island during the 2016 Kumamoto earthquake", + "doi": "10.1126/sciadv.1700813" + }, + "Wang2017": { + "author": "Wang, QingYu and Brenguier, Florent and Campillo, Michel and Lecointre, Albanne and Takeda, Tetsuya and Aoki, Yosuke", + "year": "2017", + "journal": "Journal of Geophysical Research: Solid Earth", + "title": "Seasonal Crustal Seismic Velocity Changes Throughout Japan", + "doi": "10.1002/2017jb014307" + }, + "Kim2019": { + "author": "Kim, D. and Lekic, V.", + "year": "2019", + "journal": "Geophysical Research Letters", + "title": "Groundwater Variations From Autocorrelation and Receiver Functions", + "doi": "10.1029/2019gl084719" + }, + "Andajani2020": { + "author": "Andajani, Rezkia Dewi and Tsuji, Takeshi and Snieder, Roel and Ikeda, Tatsunori", + "year": "2020", + "journal": "Earth, Planets and Space", + "title": "Spatial and temporal influence of rainfall on crustal pore pressure based on seismic velocity monitoring", + "doi": "10.1186/s40623-020-01311-1" + }, + "GaubertBastide2022": { + "author": "GaubertBastide, T. and Garambois, S. and Bordes, C. and Voisin, C. and Oxarango, L. and Brito, D. and Roux, P.", + "year": "2022", + "journal": "Water Resources Research", + "title": "HighResolution Monitoring of Controlled Water Table Variations From Dense SeismicNoise Acquisitions", + "doi": "10.1029/2021wr030680" + }, + "Illien2022": { + "author": "Illien, Luc and SensSch{\\\"o}nfelder, Christoph and Andermann, Christoff and Marc, Odin and Cook, Kristen L. and Adhikari, Lok B. and Hovius, Niels", + "year": "2022", + "journal": "Journal of Geophysical Research: Solid Earth", + "title": "Seismic Velocity Recovery in the Subsurface: Transient Damage and Groundwater Drainage Following the 2015 Gorkha Earthquake, Nepal", + "doi": "10.1029/2021jb023402" + }, + "Mao2022": { + "author": "Mao, Shujuan and Lecointre, Albanne and van der Hilst, Robert D. and Campillo, Michel", + "year": "2022", + "journal": "Nature Communications", + "title": "Space-time monitoring of groundwater fluctuations with passive seismic interferometry", + "doi": "10.1038/s41467-022-32194-3" + }, + "Clements2023": { + "author": "Clements, T. and Denolle, M. A.", + "year": "2023", + "journal": "Journal of Geophysical Research: Solid Earth", + "title": "The Seismic Signature of California's Earthquakes, Droughts, and Floods", + "doi": "10.1029/2022jb025553" + }, + "Delouche2023": { + "author": "Delouche, E. and Stehly, L.", + "year": "2023", + "journal": "Journal of Geophysical Research: Solid Earth", + "title": "Seasonal Seismic Velocity Variations Measured Using Seismic Noise Autocorrelations to Monitor the Dynamic of Aquifers in Greece", + "doi": "10.1029/2023jb026759" + }, + "Ermert2023": { + "author": "Ermert, Laura A. and Cabral-Cano, Enrique and Chaussard, Estelle and Solano-Rojas, Dar{\\'i}o and Quintanar, Luis and Morales Padilla, Diana and Fern{\\'a}ndez-Torres, Enrique A. and Denolle, Marine A.", + "year": "2023", + "journal": "Solid Earth", + "title": "Probing environmental and tectonic changes underneath Mexico City with the urban seismic field", + "doi": "10.5194/se-14-529-2023" + }, + "Fokker2023": { + "author": "Fokker, Eldert and Ruigrok, Elmer and Hawkins, Rhys and Trampert, Jeannot", + "year": "2023", + "journal": "Geophysical Research Letters", + "title": "4D PhysicsBased Pore Pressure Monitoring Using Passive Image Interferometry", + "doi": "10.1029/2022gl101254" + }, + "Zhang2023": { + "author": "Zhang, Shuo and Luo, Bingxu and BenZion, Yehuda and Lumley, David E. and Zhu, Hejun", + "year": "2023", + "journal": "Geophysical Research Letters", + "title": "Monitoring Terrestrial Water Storage, Drought and Seasonal Changes in Central Oklahoma With Ambient Seismic Noise", + "doi": "10.1029/2023gl103419" + }, + "Mao2025": { + "author": "Mao, Shujuan and Ellsworth, William L. and Zheng, Yujie and Beroza, Gregory C.", + "year": "2025", + "journal": "Science", + "title": "Depth-dependent seismic sensing of groundwater recovery from the atmospheric-river storms of 2023", + "doi": "10.1126/science.adr6139" + }, + "Mordret2016": { + "author": "Mordret, Aur{\\'e}lien and Mikesell, T. Dylan and Harig, Christopher and Lipovsky, Bradley P. and Prieto, Germ{\\'a}n A.", + "year": "2016", + "journal": "Science Advances", + "title": "Monitoring southwest Greenlands ice sheet melt with ambient seismic noise", + "doi": "10.1126/sciadv.1501538" + }, + "James2019": { + "author": "James, S. R. and Knox, H. A. and Abbott, R. E. and Panning, M. P. and Screaton, E. J.", + "year": "2019", + "journal": "Journal of Geophysical Research: Earth Surface", + "title": "Insights Into Permafrost and Seasonal ActiveLayer Dynamics From Ambient Seismic Noise Monitoring", + "doi": "10.1029/2019jf005051" + }, + "Guillemot2020": { + "author": "Guillemot, Antoine and Helmstetter, Agn{\\`e}s and Larose, {\\'E}ric and Baillet, Laurent and Garambois, St{\\'e}phane and Mayoraz, Rapha{\\\"e}l and Delaloye, Reynald", + "year": "2020", + "journal": "Geophysical Journal International", + "title": "Seismic monitoring in the Gugla rock glacier (Switzerland): ambient noise correlation, microseismicity and modelling", + "doi": "10.1093/gji/ggaa097" + }, + "Guillemot2021": { + "author": "Guillemot, Antoine and Baillet, Laurent and Garambois, St{\\'e}phane and Bodin, Xavier and Helmstetter, Agn{\\`e}s and Mayoraz, Rapha{\\\"e}l and Larose, Eric", + "year": "2021", + "journal": "The Cryosphere", + "title": "Modal sensitivity of rock glaciers to elastic changes from spectral seismic noise monitoring and modeling", + "doi": "10.5194/tc-15-501-2021" + }, + "Lindner2021": { + "author": "Lindner, Fabian and Wassermann, Joachim and Igel, Heiner", + "year": "2021", + "journal": "Geophysical Research Letters", + "title": "Seasonal FreezeThaw Cycles and Permafrost Degradation on Mt. Zugspitze (German/Austrian Alps) Revealed by SingleStation Seismic Monitoring", + "doi": "10.1029/2021gl094659" + }, + "Luo2023": { + "author": "Luo, Bingxu and Zhang, Shuo and Zhu, Hejun", + "year": "2023", + "journal": "Geophysical Research Letters", + "title": "Monitoring Seasonal Fluctuation and LongTerm Trends for the Greenland Ice Sheet Using Seismic Noise AutoCorrelations", + "doi": "10.1029/2022gl102146" + }, + "Gassenmeier2015": { + "author": "Gassenmeier, M. and Sens-Sch{\\\"o}nfelder, C. and Delatre, M. and Korn, M.", + "year": "2014", + "journal": "Geophysical Journal International", + "title": "Monitoring of environmental influences on seismic velocity at the geological storage site for CO2 in Ketzin (Germany) with ambient seismic noise", + "doi": "10.1093/gji/ggu413" + }, + "Hillers2015": { + "author": "Hillers, Gregor and Husen, Stephan and Obermann, Anne and Plan{\\`e}s, Thomas and Larose, Eric and Campillo, Michel", + "year": "2015", + "journal": "Geophysics", + "title": "Noise-based monitoring and imaging of aseismic transient deformation induced by the 2006 Basel reservoir stimulation", + "doi": "10.1190/geo2014-0455.1" + }, + "Obermann2015": { + "author": "Obermann, A. and Kraft, T. and Larose, E. and Wiemer, S.", + "year": "2015", + "journal": "Journal of Geophysical Research: Solid Earth", + "title": "Potential of ambient seismic noise techniques to monitor the St. Gallen geothermal site (Switzerland)", + "doi": "10.1002/2014jb011817" + }, + "Czarny2016": { + "author": "Czarny, Rafa{\\l} and Marcak, Henryk and Nakata, Nori and Pilecki, Zenon and Isakow, Zbigniew", + "year": "2016", + "journal": "Pure and Applied Geophysics", + "title": "Monitoring Velocity Changes Caused By Underground Coal Mining Using Seismic Noise", + "doi": "10.1007/s00024-015-1234-3" + }, + "Olivier2017": { + "author": "Olivier, Gerrit and Brenguier, Florent and de Wit, Tjaart and Lynch, Richard", + "year": "2017", + "journal": "The Leading Edge", + "title": "Monitoring the stability of tailings dam walls with ambient seismic noise", + "doi": "10.1190/tle36040350a1.1" + }, + "Taira2018": { + "author": "Taira, Takaaki and Nayak, Avinash and Brenguier, Florent and Manga, Michael", + "year": "2018", + "journal": "Science Advances", + "title": "Monitoring reservoir response to earthquakes and fluid extraction, Salton Sea geothermal field, California", + "doi": "10.1126/sciadv.1701536" + }, + "Kristjansdottir2019": { + "author": "Kristj{\\'a}nsd{\\'o}ttir and others", + "year": "2019", + "journal": "", + "title": "", + "doi": "" + }, + "Daskalakis2016": { + "author": "Daskalakis, E. and Evangelidis, C.P. and Garnier, J. and Melis, N.S. and Papanicolaou, G. and Tsogka, C.", + "year": "2016", + "journal": "Geophysical Journal International", + "title": "Robust seismic velocity change estimation using ambient noise recordings", + "doi": "10.1093/gji/ggw142" + }, + "Obermann2019": { + "author": "Obermann and Hillers", + "year": "2019", + "journal": "Advances in Geophysics", + "title": "Seismic time-lapse interferometry across scales", + "doi": "10.1016/bs.agph.2019.06.001" + }, + "Wang2020": { + "author": "Wang, Qing-Yu and Yao, HuaJian", + "year": "2020", + "journal": "Earth and Planetary Physics", + "title": "Monitoring of velocity changes based on seismic ambient noise: A brief review and perspective", + "doi": "10.26464/epp2020048" + } + }, + "cited_keys": [ + "Andajani2020", + "Bensen2007", + "Bertello2018", + "Bievre2018", + "Bontemps2020", + "Boschelli2021", + "Brenguier2008", + "Brenguier2008b", + "Brenguier2014", + "Chen2010", + "Clarke2011", + "Clements2018", + "Clements2023", + "Colombero2018", + "CubukSabuncu2021", + "Czarny2016", + "Daskalakis2016", + "DePlaen2016", + "DePlaen2019", + "Delouche2023", + "Denolle25b", + "Donaldson2017", + "Donaldson2019", + "Duputel2009", + "Ermert2023", + "Fan2023", + "Feng2020", + "Fiolleau2020", + "Fokker2023", + "Gassenmeier2015", + "Gassenmeier2016", + "Gassmann1951", + "GaubertBastide2022", + "Gelman2013", + "Guillemot2020", + "Guillemot2021", + "Hadziioannou2009", + "Hadziioannou2011", + "Harba2017", + "Hennino2001", + "Hillers2014", + "Hillers2015", + "Hillers2019", + "Hobiger2012", + "HotovecEllis2014", + "HotovecEllis2015", + "HotovecEllis2022", + "Illien2022", + "James2017", + "James2019", + "Jiang2020", + "Kidiwela2026", + "Kim2019", + "Kopfli2024", + "Kristjansdottir2019", + "LeBreton2021", + "Lecocq2014", + "Lecocq2017", + "Lesage2018", + "Lin2008", + "Lindner2021", + "Liu2014", + "Liu2025", + "Lu2021", + "Luo2023", + "Mainsant2012", + "Mao2019", + "Mao2020", + "Mao2022", + "Mao2025", + "Margerin1998", + "Margerin2019", + "Mavko2009", + "Mikesell2015", + "Minato2012", + "Mordret2016", + "Moreau2017", + "Nakata2011", + "Nimiya2017", + "Obermann2013", + "Obermann2015", + "Obermann2016", + "Obermann2019", + "Okubo2024", + "Olivier2017", + "Olivier2019", + "Ouellet2022", + "Paasschens1997", + "Pacheco2005", + "Planes2016", + "Poli2020", + "Rivet2011", + "Rivet2014", + "Rivet2015", + "Rubinstein2005", + "Sato1993", + "Sawazaki2009", + "Schaff2004", + "SensSchonfelder2006", + "SensSchonfelder2014", + "Sheng2022", + "Snieder2002", + "Steegen2016", + "Stehly2006", + "Stehly2015", + "Taira2015", + "Taira2018", + "Takano2017", + "Tsai2011", + "Tsuji2021", + "Viens2020", + "Voisin2016", + "Wang2017", + "Wang2019", + "Wang2020", + "Weaver2011", + "Wegler2007", + "Wegler2009", + "Whiteley2026", + "Yates2019", + "Yates2024", + "Yuan2021", + "Yukutake2025", + "Zhan2013", + "Zhang2023", + "ZotzWilson2019", + "deWit2026", + "lobkis03", + "poupinet84" + ], + "qmd_citations": [ + "Brenguier2008", + "Duputel2009", + "CubukSabuncu2021", + "Olivier2017", + "Ouellet2022", + "Clements2018", + "Mao2022", + "LeBreton2021", + "Planes2016", + "Tsuji2021", + "Mikesell2015", + "Mao2020", + "Yuan2021", + "Obermann2013", + "Obermann2016", + "Brenguier2014", + "Ermert2023", + "Okubo2024", + "Hadziioannou2011", + "Moreau2017", + "Mao2019", + "Viens2020", + "Hobiger2012", + "Zhan2013", + "Clarke2011", + "Weaver2011", + "Denolle25b", + "Gelman2013", + "Steegen2016", + "Obermann2013", + "Sato1993", + "Paasschens1997", + "Margerin1998", + "Obermann2013", + "Obermann2016", + "Yuan2021", + "Jiang2020", + "lobkis03", + "poupinet84", + "Mikesell2015", + "Clarke2011", + "Mao2020", + "Yuan2021", + "Mikesell2015", + "Yuan2021", + "Clarke2011", + "Weaver2011", + "Wang2017", + "Obermann2019", + "Jiang2020", + "Lin2008", + "Stehly2006", + "Hennino2001", + "Margerin2019", + "Liu2014", + "Hobiger2012", + "DePlaen2016", + "Clarke2011", + "Brenguier2008", + "Clements2018", + "Clements2018", + "Brenguier2014", + "James2017", + "Rivet2011", + "James2017", + "ZotzWilson2019", + "Rivet2014", + "SensSchonfelder2014", + "Ermert2023", + "Hadziioannou2011", + "Moreau2017", + "Mao2019", + "Viens2020", + "Stehly2006", + "Snieder2002", + "Hadziioannou2009", + "Kidiwela2026", + "Obermann2013", + "Zhan2013", + "Brenguier2008", + "Brenguier2014", + "Weaver2011", + "Clarke2011", + "Snieder2002", + "Clarke2011", + "Weaver2011", + "Brenguier2014", + "Wang2017", + "Obermann2019", + "Weaver2011", + "Clarke2011", + "Obermann2013", + "Obermann2016", + "Takano2017", + "Feng2020", + "Mao2022", + "Mao2025", + "Rubinstein2005", + "Gassmann1951", + "Mavko2009", + "Clements2018", + "James2019", + "Clements2023", + "Jiang2020", + "Clements2023", + "Clements2023", + "Clarke2011", + "Weaver2011", + "Clements2023", + "Weaver2011", + "Clarke2011", + "Mao2020", + "Zhan2013", + "Mikesell2015", + "Yuan2021", + "Clarke2011", + "Mao2020", + "Obermann2013", + "Obermann2016", + "Obermann2013", + "Wang2017", + "Brenguier2014", + "Wang2017", + "Clarke2011", + "Weaver2011", + "Clarke2011", + "Clements2023" + ], + "appendix_citations": [ + "Brenguier2008", + "Duputel2009", + "Obermann2013", + "HotovecEllis2014", + "HotovecEllis2015", + "Rivet2015", + "DePlaen2016", + "Donaldson2017", + "Takano2017", + "Lesage2018", + "DePlaen2019", + "Donaldson2019", + "Olivier2019", + "Yates2019", + "Feng2020", + "HotovecEllis2022", + "Kopfli2024", + "Yates2024", + "Yukutake2025", + "Schaff2004", + "Pacheco2005", + "Rubinstein2005", + "Wegler2007", + "Brenguier2008b", + "Hadziioannou2009", + "Sawazaki2009", + "Wegler2009", + "Chen2010", + "Nakata2011", + "Rivet2011", + "Hobiger2012", + "Minato2012", + "Obermann2013", + "Brenguier2014", + "Liu2014", + "Taira2015", + "Gassenmeier2016", + "Hillers2019", + "Wang2019", + "Mao2020", + "Poli2020", + "Boschelli2021", + "Lu2021", + "Sheng2022", + "Mainsant2012", + "Voisin2016", + "Harba2017", + "Bertello2018", + "Bievre2018", + "Colombero2018", + "Bontemps2020", + "Fiolleau2020", + "LeBreton2021", + "Fan2023", + "Liu2025", + "Whiteley2026", + "deWit2026", + "SensSchonfelder2006", + "Tsai2011", + "Hillers2014", + "Lecocq2017", + "Nimiya2017", + "Wang2017", + "Clements2018", + "Kim2019", + "Andajani2020", + "GaubertBastide2022", + "Illien2022", + "Mao2022", + "Clements2023", + "Delouche2023", + "Ermert2023", + "Fokker2023", + "Zhang2023", + "Mao2025", + "Mordret2016", + "James2019", + "Guillemot2020", + "Guillemot2021", + "Lindner2021", + "Luo2023", + "Gassenmeier2015", + "Hillers2015", + "Obermann2015", + "Czarny2016", + "Olivier2017", + "Taira2018", + "Kristjansdottir2019", + "Snieder2002", + "Bensen2007", + "Clarke2011", + "Hadziioannou2011", + "Weaver2011", + "Zhan2013", + "Lecocq2014", + "Mikesell2015", + "Stehly2015", + "Daskalakis2016", + "Obermann2016", + "Obermann2019", + "Jiang2020", + "Wang2020", + "Yuan2021" + ], + "missing": [], + "duplicates": [] +} diff --git a/review/evidence/closure/README.md b/review/evidence/closure/README.md new file mode 100644 index 0000000..b949c8c --- /dev/null +++ b/review/evidence/closure/README.md @@ -0,0 +1,25 @@ +# Closure evidence for the iteration-1 findings + +Re-runs of the iteration-1 probes against the revised code, for the +reconciliation pass of the pre-submission reviewer. The "before" values are +`../audit_probes.json` and `../downstream_probes.json`; the "after" values +are produced here by `audit_probes_after.py` and `downstream_probes_after.py` +(same probes, adapted to the revised API). + +| Finding | Before | After | Where fixed | +|---|---|---|---| +| EV-01 sparse scorer | ten zeros plus nulls scored 1.0 on all three public cases | 0.0 on all three; truth scores 1.0 | `golden.rms_on_support`, `frugalmind._gold` | +| UQ-01 Weaver floor | ms re-expression changed the result by 0.0316; no band dependence | ratio 1.000; floor ratio 2.0 for a 4x band-width change; Weaver eq. 21 anchor reproduced to 2.5% | `uq_measurement.weaver_rms_dilation`, `bandwidth_timescale` | +| UQ-02 mixture variance | reported variance 37% above the zero-mean mixture value | equal; processing term 0 | `uq_processing.per_band_marginal_error` | +| UQ-04 shared artefact | zero inside +-2 sd on 2 of 30 epochs | unchanged by design; now a documented, tested limitation and a calibration scenario | `tests/test_uq_bayes.py::test_shared_artifact_is_not_detected`, `codameter.calibration` | +| UQ-05 time grid | posterior mean bitwise identical after a 1000-day gap | differs (gap-aware prior) | `uq_bayes.second_difference_operator` | +| UQ-05 config axes | fixed/gated and moving/ungated members identical, labels identical | different members and labels; moving member has a warm-up NaN | `uq_bayes.run_processing_ensemble` | +| DET-02 cache | cold float64 vs warm float32, max difference 4.8e-7 | both float64, bitwise equal, generator hash in the key | `golden.generate` | +| INV-02 bounds | zero covariance at an active bound | covariance kept (0.05), `at_bound` flagged | `inverse.linear_fit` | +| INV-02 connectivity | isolated epoch reported with sd 0 | NaN with a warning; `n_components` 2 | `uq_measurement.global_reference_inversion` | +| AG-01 advisor routes | KeyError for landslide, cryosphere, geothermal | unchanged (out of scope for the paper revision; advisor hygiene) | not fixed | + +Calibration runs: `paper/data/calibration/` (pilots with 20 realisations; +locked runs with 200). Field comparison: `paper/data/gate1/comparison.json` +from `scripts/compare_gate1.py`. Full test suite after the code changes: +327 passed, 1 skipped (2026-09-10). diff --git a/review/evidence/closure/audit_probes_after.json b/review/evidence/closure/audit_probes_after.json new file mode 100644 index 0000000..d034f74 --- /dev/null +++ b/review/evidence/closure/audit_probes_after.json @@ -0,0 +1,72 @@ +{ + "python": "3.12.13 | packaged by conda-forge | (main, Mar 5 2026, 17:06:14) [Clang 19.1.7 ]", + "numpy": "2.4.3", + "scipy": "1.17.1", + "sparse_score": { + "easy-volcano-01": { + "n_days": 1095, + "all_zero_score": 0.0, + "ten_zero_rest_null_score": 0.0, + "truth_score": 1.0, + "support_epochs": 1095 + }, + "medium-earthquake_fault-02": { + "n_days": 1095, + "all_zero_score": 0.0, + "ten_zero_rest_null_score": 0.0, + "truth_score": 1.0, + "support_epochs": 1095 + }, + "hard-groundwater-04": { + "n_days": 913, + "all_zero_score": 0.0, + "ten_zero_rest_null_score": 0.0, + "truth_score": 1.0, + "support_epochs": 913 + } + }, + "advisor_mapping": { + "volcano": "easy-volcano-01", + "earthquake_fault": "medium-earthquake_fault-02", + "landslide": "KeyError: 'landslide'", + "groundwater": "hard-groundwater-04", + "cryosphere": "KeyError: 'cryosphere'", + "geothermal": "KeyError: 'geothermal'" + }, + "floor_time_unit_probe": { + "seconds": 0.00046347717336818765, + "milliseconds_reexpression": 0.0004634771733681876, + "ratio": 0.9999999999999999, + "band_dependence_ratio_B0.5_over_B2": 2.0, + "weaver_eq21_anchor_over_4e-4": 0.9750189652898391 + }, + "mixture_variance": { + "zero_mean_mixture_true_variance": 4.33553305131169e-07, + "reported_variance": 4.33553305131169e-07, + "reported_processing_term": 0.0 + }, + "shared_bias_counterexample": { + "error_rms": 0.00212135623401608, + "median_Cd_std": 5.998023899798946e-05, + "fraction_zero_inside_mu_plusminus_2sd": 0.06666666666666667, + "note": "Unchanged by design; documented as a limitation and tested." + }, + "irregular_time": { + "mu_identical_after_1000_day_gap": false, + "max_abs_difference": 1.2128780700808528e-07 + }, + "bayes_config_semantics": { + "fixed_gated_equals_moving_ungated": false, + "labels": [ + "stretching (TS) 0.4-1Hz 10-30s stack10d fixed gated", + "stretching (TS) 0.4-1Hz 10-30s stack10d moving" + ], + "moving_member_has_warmup_nan": true + }, + "cache_consistency": { + "cold_dtype": "float64", + "warm_dtype": "float64", + "array_equal": true, + "generator_hash": "0225266e" + } +} diff --git a/review/evidence/closure/audit_probes_after.py b/review/evidence/closure/audit_probes_after.py new file mode 100644 index 0000000..a29ee4a --- /dev/null +++ b/review/evidence/closure/audit_probes_after.py @@ -0,0 +1,150 @@ +"""Re-run of review/evidence/audit_probes.py against the revised code. + +Same probes as the iteration-1 audit, adapted to the revised API (the Weaver +floor takes a band width; ProcessingChoice carries one). Writes only inside +review/evidence/closure. Run from the repository root: + + MPLCONFIGDIR=/tmp/mpl .pixi/envs/dev/bin/python review/evidence/closure/audit_probes_after.py + +The iteration-1 values are in ../audit_probes.json for comparison. +""" + +import json +import sys +import tempfile +from pathlib import Path + +import numpy as np +import scipy +from codameter import frugalmind, golden, uq_bayes, use_cases +from codameter.uq_measurement import weaver_rms_dilation, weaver_stretching_error +from codameter.uq_processing import ( + ProcessingChoice, + choice_floor, + per_band_marginal_error, +) + +outdir = Path(__file__).resolve().parent +temporary_cache = tempfile.TemporaryDirectory(prefix="codameter-closure-") +golden.CACHE_DIR = Path(temporary_cache.name) +results = {"python": sys.version, "numpy": np.__version__, "scipy": scipy.__version__} + +# EV-01: the sparse submission must score like all zeros. +scores = {} +for case in golden.CASES: + d = golden.generate(case["id"], cache=False) + original_generate = golden.generate + golden.generate = lambda case_id, _data=d, **kw: _data + try: + gold = frugalmind._gold(case, "dvv_series") + n = len(d["days"]) + sparse = [0.0] * 10 + [None] * (n - 10) + scores[case["id"]] = { + "n_days": n, + "all_zero_score": frugalmind.score_dvv_series(json.dumps([0.0] * n), gold), + "ten_zero_rest_null_score": frugalmind.score_dvv_series( + json.dumps(sparse), gold + ), + "truth_score": frugalmind.score_dvv_series( + json.dumps(list(map(float, d["truth"]))), gold + ), + "support_epochs": len(gold["support"]), + } + finally: + golden.generate = original_generate +results["sparse_score"] = scores + +# AG-01: unchanged in this revision (advisor routes are Phase 3/R8 hygiene). +results["advisor_mapping"] = {} +for key in use_cases.USE_CASES: + try: + results["advisor_mapping"][key] = golden.MAINSTREAM_BY_USE_CASE[key] + except KeyError as exc: + results["advisor_mapping"][key] = "KeyError: " + str(exc) + +# UQ-01: a time-unit change must not alter the fractional uncertainty. +s_seconds = weaver_rms_dilation(0.9, 2 * np.pi * 1.0, 10.0, 30.0, 0.5) +s_milliseconds = weaver_rms_dilation(0.9, 2 * np.pi * 1e-3, 1e4, 3e4, 500.0) +results["floor_time_unit_probe"] = { + "seconds": s_seconds, + "milliseconds_reexpression": s_milliseconds, + "ratio": s_milliseconds / s_seconds, + "band_dependence_ratio_B0.5_over_B2": float( + weaver_stretching_error(0.9, 1.0, 10.0, 30.0, 0.5) + / weaver_stretching_error(0.9, 1.0, 10.0, 30.0, 2.0) + ), + "weaver_eq21_anchor_over_4e-4": float( + weaver_rms_dilation(0.9, 15.0, 12.5, 50.0, 0.56) + / (4e-4 * np.sqrt(1 - 0.81) / 1.8) + ), +} + +# UQ-02: zero-mean mixture variance is the mean of the floors squared. +choices = [ + ProcessingChoice("fixed", 1.0, 1.0, 10.0, 20.0, 0.9), + ProcessingChoice("fixed", 1.0, 1.0, 20.0, 40.0, 0.9), +] +floors = np.array([choice_floor(c) for c in choices]) +reported = per_band_marginal_error(choices)[1.0] +results["mixture_variance"] = { + "zero_mean_mixture_true_variance": float(np.mean(floors**2)), + "reported_variance": reported["sd"] ** 2, + "reported_processing_term": reported["processing"], +} + +# UQ-04: a shared artefact is still invisible (documented limitation). +t = np.arange(30, dtype=float) +shared_drift = 0.003 * np.sin(2 * np.pi * t / 30) +members = np.tile(shared_drift, (4, 1)) +sigmas = np.full_like(members, 0.0002) +res = uq_bayes.gibbs_dvv(members, sigmas, t, n_iter=600, burn=200, thin=2, seed=11) +sd = np.sqrt(np.diag(res.Cd)) +results["shared_bias_counterexample"] = { + "error_rms": float(np.sqrt(np.mean(res.mu_mean**2))), + "median_Cd_std": float(np.median(sd)), + "fraction_zero_inside_mu_plusminus_2sd": float( + np.mean(np.abs(res.mu_mean) <= 2 * sd) + ), + "note": "Unchanged by design; documented as a limitation and tested.", +} + +# UQ-05: the smoothness prior now sees a 1000-day gap. +irregular_t = t.copy() +irregular_t[15:] += 1000 +irr = uq_bayes.gibbs_dvv( + members, sigmas, irregular_t, n_iter=600, burn=200, thin=2, seed=11 +) +results["irregular_time"] = { + "mu_identical_after_1000_day_gap": bool(np.array_equal(res.mu_mean, irr.mu_mean)), + "max_abs_difference": float(np.max(np.abs(res.mu_mean - irr.mu_mean))), +} + +# UQ-05: configuration axes are honoured in the ensemble. +d = golden.generate("easy-volcano-01", cache=False) +cfg = use_cases.recommend("volcano") +other = dict(cfg, reference="moving", gate=False) +ens = uq_bayes.run_processing_ensemble( + d["ccfs"][:120], d["t"], d["fs"], [cfg, other], cadence=3, days=d["days"][:120] +) +results["bayes_config_semantics"] = { + "fixed_gated_equals_moving_ungated": bool( + np.array_equal(ens.members[0], ens.members[1], equal_nan=True) + ), + "labels": ens.labels, + "moving_member_has_warmup_nan": bool(np.isnan(ens.members[1][0])), +} + +# DET-02: cold and warm cache routes agree exactly. +cold = golden.generate("easy-volcano-01", cache=True) +warm = golden.generate("easy-volcano-01", cache=True) +results["cache_consistency"] = { + "cold_dtype": str(cold["ccfs"].dtype), + "warm_dtype": str(warm["ccfs"].dtype), + "array_equal": bool(np.array_equal(cold["ccfs"], warm["ccfs"])), + "generator_hash": cold["generator_hash"], +} + +output = json.dumps(results, indent=2, allow_nan=False, default=str) +(outdir / "audit_probes_after.json").write_text(output + "\n") +print(output) +temporary_cache.cleanup() diff --git a/review/evidence/closure/downstream_probes_after.json b/review/evidence/closure/downstream_probes_after.json new file mode 100644 index 0000000..736e82b --- /dev/null +++ b/review/evidence/closure/downstream_probes_after.json @@ -0,0 +1,25 @@ +{ + "bounded_fit_mean": [ + 0.0 + ], + "bounded_fit_covariance": [ + [ + 0.05 + ] + ], + "bounded_fit_at_bound": [ + true + ], + "disconnected_reference_solution": [ + 0.004999999999999999, + -0.004999999999999999, + null + ], + "disconnected_reference_std": [ + 0.0004999999999999999, + 0.0004999999999999999, + null + ], + "n_components": 2, + "warning": "pair graph has 2 connected components (1 isolated epoch(s)); offsets between components are unidentified and are set to a per-component datum" +} diff --git a/review/evidence/closure/downstream_probes_after.py b/review/evidence/closure/downstream_probes_after.py new file mode 100644 index 0000000..27dcb38 --- /dev/null +++ b/review/evidence/closure/downstream_probes_after.py @@ -0,0 +1,32 @@ +"""Re-run of review/evidence/downstream_probes.py against the revised code (INV-02).""" + +import json +import warnings +from pathlib import Path + +import numpy as np +from codameter.inverse.linear_fit import PredictorMatrix, linear_fit +from codameter.uq_measurement import global_reference_inversion + +p = PredictorMatrix(X=np.ones((20, 1)), parameter_names=["amplitude"]) +r = linear_fit( + -np.ones(20) * 0.1, p, sigma_dvv=1.0, parameter_bounds={"amplitude": (0.0, np.inf)} +) +with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") + g = global_reference_inversion( + np.array([0]), np.array([1]), np.array([0.01]), np.array([0.001]), 3 + ) +assert r.posterior.cov is not None and r.at_bound is not None +out = { + "bounded_fit_mean": r.posterior.mean.tolist(), + "bounded_fit_covariance": r.posterior.cov.tolist(), + "bounded_fit_at_bound": [bool(b) for b in r.at_bound], + "disconnected_reference_solution": [None if np.isnan(x) else x for x in g.dvv], + "disconnected_reference_std": [None if np.isnan(x) else x for x in g.sigma], + "n_components": g.n_components, + "warning": str(w[0].message) if w else None, +} +path = Path(__file__).resolve().parent / "downstream_probes_after.json" +path.write_text(json.dumps(out, indent=2) + "\n") +print(json.dumps(out, indent=2)) diff --git a/review/evidence/downstream_probes.json b/review/evidence/downstream_probes.json new file mode 100644 index 0000000..b827e6e --- /dev/null +++ b/review/evidence/downstream_probes.json @@ -0,0 +1,20 @@ +{ + "bounded_fit_mean": [ + 0.0 + ], + "bounded_fit_covariance": [ + [ + 0.0 + ] + ], + "disconnected_reference_solution": [ + 0.004999999999999999, + -0.004999999999999998, + -2.8912057932946783e-19 + ], + "disconnected_reference_std": [ + 0.0004999999999999999, + 0.0004999999999999999, + 0.0 + ] +} diff --git a/review/evidence/downstream_probes.py b/review/evidence/downstream_probes.py new file mode 100644 index 0000000..618ea6f --- /dev/null +++ b/review/evidence/downstream_probes.py @@ -0,0 +1,24 @@ +"""Reproduce constrained and disconnected uncertainty audit cases.""" +import json +from pathlib import Path + +import numpy as np +from codameter.inverse.linear_fit import PredictorMatrix, linear_fit +from codameter.uq_measurement import global_reference_inversion + +p = PredictorMatrix(X=np.ones((20, 1)), parameter_names=["amplitude"]) +r = linear_fit( + -np.ones(20) * 0.1, p, sigma_dvv=1.0, parameter_bounds={"amplitude": (0.0, np.inf)} +) +g = global_reference_inversion( + np.array([0]), np.array([1]), np.array([0.01]), np.array([0.001]), 3 +) +out = { + "bounded_fit_mean": r.posterior.mean.tolist(), + "bounded_fit_covariance": r.posterior.cov.tolist(), + "disconnected_reference_solution": g.dvv.tolist(), + "disconnected_reference_std": g.sigma.tolist(), +} +path = Path(__file__).resolve().parent / "downstream_probes.json" +path.write_text(json.dumps(out, indent=2) + "\n") +print(json.dumps(out, indent=2)) diff --git a/review/evidence/figures/fresh_manuscript_layout.txt b/review/evidence/figures/fresh_manuscript_layout.txt new file mode 100644 index 0000000..19452a0 --- /dev/null +++ b/review/evidence/figures/fresh_manuscript_layout.txt @@ -0,0 +1,3534 @@ + submitted to Geophys. J. Int. + + + + +1 The reproducibility cost of ad-hoc processing choices + +2 in ambient-noise seismic velocity-change monitoring + + + +3 M. A. Denolle + + + +4 2026-09-10 + + + +5 SUMMARY + +6 Relative seismic velocity changes (𝛿𝑣/𝑣) from repeated coda waves are becoming a + +7 standard observable for volcanoes, faults, landslides, aquifers and the cryosphere and are + +8 increasingly regarded as new measurements of strain changes. Yet turning cross-correlation + +9 functions into a 𝛿𝑣/𝑣 time series involves a long sequence of choices — the estimator, the + +10 frequency band, the coda window, the reference, the stacking, and how cross-components + +11 and station pairs are aggregated and weighted — made ad hoc, their impact on the + +12 measurement uncertainty unclear. These hidden choices clearly limit reproducibility of + +13 the research and importantly the inter-study comparison. + +14 We demonstrate here how to turn repeated wavefield measurement into agent-ready, + +15 scalable-ready, uncertainty-aware measurement of changes in seismic properties. We + +16 quantify the individual and combined effects of these choices using a controlled synthetic + +17 in which the ground-truth 𝛿𝑣/𝑣 is known exactly. We show that at large 𝛿𝑣/𝑣 methods + +18 split by family with distinct failure modes; that the same station pair yields different + +19 𝛿𝑣/𝑣 depending only on whether one averages the per-component 𝛿𝑣/𝑣 or the correlation- + +20 coefficient images; and, most consequentially, that the reported 1𝜎 on a network-averaged + 2 M. A. Denolle + √ +21 𝛿𝑣/𝑣 varies by ∼ 𝑁 from the standard-error-versus-standard-deviation and weighting + +22 conventions — so a change that is “3𝜎 significant” in one study is “not significant” in + +23 another, from identical data. + +24 Running the full breadth of parameter choices, we estimate each by the bias and error- + +25 bar change it induces. We propose a Bayesian measurement model that marginalises + +26 the ensemble into a single time-dependent data covariance 𝐶𝑑 and illustrate its use by + +27 propagating errors in a depth-inversion of shear wave perturbation. We provide a real data + +28 examples from a California data set and reproduce previous results that were generated + +29 with a different computing language and processing pipeline, demonstrating at the same + +30 time the integration of codameter with noisepy and its portability and scalability from + +31 laptop to cloud systems. We also generate a codameter agent advisor that can guide + +32 researchers or agents in their parameter choices, accompanied with a robust evaluation + +33 of the agent against a golden data set. Our method and associated software package, + +34 codameter turns repeated coda waves into time series of 𝛿𝑣/𝑣 and its covariance making + +35 it coda-wave interferometry uncertainty-aware and reproducible. + + +36 Key words: Coda-wave Interferometry; Seismic noise; Coda waves; Inverse theory; + +37 Statistical methods. + + + + +38 1 INTRODUCTION + + +39 Changes in subsurface properties occur due to geodynamics, which drive earthquake damage + +40 and volcanic eruption, and hydrodynamics, which controls fluid exchange between the + +41 atmosphere and the solid Earth. These processes influence the mechanical properties of Earth + +42 materials, which directly affect the speed at which seismic waves propagate. Changes in + +43 seismic velocity, often measured and referred to as 𝛿𝑣/𝑣, can be tracked by measuring changes + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 3 +44 in arrival times of seismic waves, especially scattered waves such as coda waves, provided + +45 that the source and receivers are at the same location. + + +46 Due to the sensitivity of coda waves to small perturbations in the material properties, + +47 𝛿𝑣/𝑣 was discovered as an effective method to monitor changes during volcanic unrest since + +48 its discovery at Piton de la Fournaise (Brenguier et al., 2008b) and is now calculated in + +49 continuous along side of more conventional seismic monitoring methods in the same volcano + +50 observatory (Duputel et al., 2009) and was a determining early warning parameter: the + +51 Icelandic Meteorological Office used 𝛿𝑣/𝑣 in its response to the 2020 Reykjanes unrest + +52 (Cubuk-Sabuncu et al., 2021). The Institute of Mine Seismology also uses 𝛿𝑣/𝑣 to monitor + +53 the internal state of tens of tailings dams and mines to flag instability before failure (Olivier + +54 et al., 2017; Ouellet et al., 2022). A broader set of operations is emerging around the same + +55 signal: groundwater storage for water management (Clements & Denolle, 2018; Mao et al., + +56 2022), landslide early warning (Le Breton et al., 2021), levee and embankment integrity + +57 (Planès et al., 2016), and geothermal and CO2 reservoir surveillance (Tsuji et al., 2021). Each + +58 of these deployments rests on the same fragile assumption: that the 𝛿𝑣/𝑣 curve an operator + +59 acts on is a property of the subsurface, not of the analyst’s processing choices. + + +60 𝛿𝑣/𝑣 is the fractional seismic velocity change, positive for a velocity increase. The stretching + +61 family of estimators measures the stretch factor 𝜀 that maps the current coda onto the + +62 reference coda. Throughout this work, the reference correlation is held fixed and trial dilations + +63 are applied to the current correlation, + + + 𝑐𝜖 (𝑡) = 𝑐[(1 + 𝜖)𝑡], + + +64 where interpolation is performed only on (c). Thus (𝜖 = 𝑡𝑐𝑢𝑟 /𝑡𝑟𝑒𝑓 − 1) is a fractional travel- + +65 time dilation: 𝜖 > 0 denotes a delayed phase in the current coda (slower) and 𝜖 < 0 denotes + 4 M. A. Denolle +66 an earlier arrival time (faster). For unchanged propagation geometry, + + 𝑡𝑐𝑢𝑟 𝑣𝑟𝑒𝑓 + 1+𝜖= = , + 𝑡𝑟𝑒𝑓 𝑣𝑐𝑢𝑟 + +67 and therefore the physical fractional velocity change reported throughout this work is + + 𝛿𝑣 𝑣𝑐𝑢𝑟 − 𝑣𝑟𝑒𝑓 𝜖 + ≡ =− . + 𝑣 𝑣𝑟𝑒𝑓 1+𝜖 + +68 The commonly used relation (𝛿𝑣/𝑣 ≃ −𝜖 ≃ −𝛿𝑡/𝑡) is its first-order approximation and + +69 used in the majority of published work. We retain the exact finite-change transformation + +70 because its computational cost is negligible and because the distinction becomes measurable + +71 for velocity perturbations of several percent measured in large strain phenomena such as + +72 landslides. The current coda is stretched rather than the reference correlation so that the + +73 high-SNR reference stack remains unchanged throughout the search. While the reciprocal + +74 formulations are mathematically equivalent; in sampled, finite-window data they can differ + +75 because interpolation and boundary truncation break that symmetry. + + +76 The elevated sensitivity comes at the price of a long series of processing choices, and + +77 at almost every step the analyst makes a choice. Among these are choices of estimators + +78 between windowed phase measurements or stretching (Mikesell et al., 2015, Mao et al. (2020), + +79 Yuan et al. (2021)), frequency band and coda window (which together set the sampled + +80 depth; Obermann et al. (2013; Obermann et al., 2016)), reference window (Brenguier et al., + +81 2014, Ermert et al. (2023), Okubo et al. (2024)), increasing the temporal resolution of the + +82 measurement through substacking-filtering-denoising (Hadziioannou et al., 2011, Moreau + +83 et al. (2017),Mao et al. (2019),Viens & Van Houtte (2020)), and how to aggregate and weight + +84 the many cross-component and station-pair measurements that make up a single reported + +85 𝛿𝑣/𝑣 time series (e.g., Hobiger et al. (2012)). These choices are made by habit, justified + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 5 +86 briefly if at all, and rarely reported in enough detail to reproduce. The community has long + +87 flagged individual pitfalls (spurious changes from non-stationary noise, Zhan et al. (2013); + +88 measurement-error formulae, Clarke et al. (2011; Weaver et al., 2011)), but the cumulative + +89 effect of the full choice set on both the value and its stated uncertainty has not been quantified + +90 in the literature. A striking example of such their cumulative effects can be seen in Figure x of + +91 (Denolle et al., 2025) who demonstrated that most studies found a direct correlation between + +92 𝛿𝑣/𝑣 and groundwater level change, but the scatter around the mean was easily explained by + +93 frequency choices, single-vs-inter station correlations, and likely the other signal-processing + +94 parameters chosen by the authors, which speak of the robust correlation but not rigorously + +95 established enough to be useful in downstream hydrological research. + + +96 This is a reproducibility problem of exactly the “garden of forking paths” type identified + +97 in the statistical sciences (Gelman & Loken, 2013; Steegen et al., 2016): many individually + +98 reasonable analyses of the same data give different answers, and without full reporting of + +99 parameter choices we cannot interpret a reported 𝛿𝑣/𝑣 as a robust value. Here we make the + +100 problem concrete for 𝛿𝑣/𝑣 monitoring. We use purely synthetic correlation time series to + +101 test the methods (estimators) and parameter choices that the community makes to estimate + +102 𝛿𝑣/𝑣 which we report over 103 studies in Appendix~C. We do not aim to report the “best” + +103 pipeline, which is most often the one reported in scientific papers, but instead document the + +104 parameter impacts (Section~3). We then propose a new measurement error that incorporates + +105 these effects into a data covariance matrix 𝐶𝑑 (Section~5). Throughout this paper, key + +106 notation includes: 𝜎 (measurement uncertainty of a recovered 𝛿𝑣/𝑣 estimate), 𝐵 (frequency + +107 bandwidth), and 𝑊 = [𝑡1 , 𝑡2 ] (coda window); subscripts distinguish specific contexts (e.g., + +108 𝜎𝑘 for per-component uncertainty), each defined where first introduced. + + +109 One example of propagating such error into downstream science is the migration of the surface + 6 M. A. Denolle +110 𝛿𝑣/𝑣 measurement to depth profiles of perturbations in shear wave velocity Δ𝑉𝑆 (𝑧)/𝑉𝑆 (𝑧), + +111 which often depends on the wavefield constituting the coda waves, such as surface waves + +112 or body waves, and that depend on the source-receiver pair geometry. We illustrate the + +113 propagation of errors to a depth profile (Section~6). We use synthetic examples for ground + +114 truthing on the signal processing parameters, since the concepts behind the observations of + +115 phase lags in scattered waves is well established (Obermann et al., 2013). + + +116 We further validate using real obervations that the estimates of 𝛿𝑣/𝑣 and their uncertainty + +117 reproduces well those of observed time series by reproducing previous studies. We package + +118 this new methodology in a Python software, codameter, which we also recast as an agentic + +119 skill: an AI agent can be asked to recommend a processing configuration or recover a 𝛿𝑣/𝑣(t) + +120 series, and its answer is scored against seeded synthetic golden cases with known ground + +121 truth, including a hidden-truth variant that withholds the answer from the public package + +122 so it cannot be reconstructed rather than measured. + + + + +123 2 SYNTHETIC FRAMEWORK + + +124 We build each synthetic reference coda wave as a band-limited random-phase wavefield + +125 modulated by a physically grounded coda envelope. We model the envelope from the exact + +126 single-scattering solution of the two-dimensional radiative transfer equation for isotropic + +127 scattering (Sato, 1993; Paasschens, 1997), which underlies coda-envelope modelling of scatter- + +128 ing and intrinsic attenuation (Margerin et al., 1998). The energy density at source–receiver + +129 distance 𝑟 and lapse time 𝑡 is + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 7 + + + 1 + √ + 2 2 2 + 𝑒−𝑐𝑡/ℓ 𝑟 𝑒 ℓ ( 𝑐 𝑡 −𝑟 −𝑐𝑡) 𝑟 +130 𝐸(𝑟, 𝑡) = [ 𝛿(𝑡 − ) + √ 𝐻(𝑡 − )] 𝑒−𝑏𝑡 , (1) + 2𝜋𝑐𝑟 𝑐 2𝜋ℓ 𝑐2 𝑡2 − 𝑟2 𝑐 + + +131 where 𝑐 is the (Rayleigh-wave) velocity, ℓ the scattering mean free path, 𝑏 the intrinsic + +132 absorption rate, and 𝛿 and 𝐻 the Dirac and Heaviside functions. The first term is the + +133 coherent ballistic arrival at 𝑡 = 𝑟/𝑐; the second is the multiply-scattered diffuse coda, + +134 which switches on at that arrival, builds up under scattering, and decays under intrinsic + +135 absorption. We fill random phases under the amplitude envelope √𝐸(𝑟, 𝑡), band-limit, and + +136 symmetrize the causal and acausal branches as for an evenly illuminated noise correlation. + +137 The modeled synthetic coda depends only on three time constants: the ballistic onset 𝑟/𝑐, + +138 the scattering mean free time ℓ/𝑐, and the absorption time 1/𝑏. The late-coda amplitude + +139 decays as 𝑒−𝑏𝑡/2 , recovering an apparent coda 𝑄𝑐 while the envelope shape is determined + +140 by scattering physics. A frequency-dependent absorption 𝑏(𝑓) = 2𝜋𝑓/𝑄𝑐 , which can still be + +141 modeled as an frequency-independent attenuation factor 𝑄𝑐 , reproduces the observation that + +142 high frequencies are retained only at short lag times, so a fixed late window samples different + +143 depths at different bands. + + +144 A homogeneous velocity change is imposed exactly by stretching the lapse-time axis, 𝑢𝑐𝑢𝑟 (𝑡) = + +145 𝑢𝑟𝑒𝑓 (𝑡 (1 + 𝛿𝑣/𝑣)), and a repeated time series is produced by generating this stretched coda + +146 with a prescribed ground-truth 𝛿𝑣/𝑣(𝑡) and additive band-limited noise at a controlled + +147 signal-to-noise ratio. The concept has been demonstrated using full waveform modeling in + +148 several previous studies (Obermann et al., 2013, 2016; Yuan et al., 2021), so we do not repeat + +149 that full-waveform modeling here. Because the imposed 𝛿𝑣/𝑣(𝑡) is known, every departure of + +150 a recovered series from it is an artefact of the processing, not of the data. + + +151 We use seven 𝛿𝑣/𝑣 estimators that were implemented in noisepy (Jiang & Denolle, 2020): + 8 M. A. Denolle +152 trace stretching (TS, Lobkis & Weaver (2003)), windowed cross-correlation (WCC, Poupinet + +153 et al. (1984)), dynamic time warping (DTW, Mikesell et al. (2015)), the moving-window + +154 cross-spectrum (MWCS; Clarke et al. (2011)), and three wavelet-domain methods, the wavelet + +155 cross-spectrum (WCS, Mao et al. (2020)) and the two wavelet stretching (WTS) and wavelet + +156 DTW (WTDTW) introduced and benchmarked numerically by Yuan et al. (2021). The + +157 framework, the figures below, and an implementation are released in the open codameter + +158 package (Section~8). Formal definitions of all seven methods, of the two aggregation pathways, + +159 and of the uncertainty conventions are described in Appendices~A and~B. + + +160 Each of these methods require specific parameter choices, which we categorize and reference + +161 in Table~1. The work presented below measure the impacts of each of these parameter choices + +162 on the resulting 𝛿𝑣/𝑣. + + + + +163 3 PARAMETER-DEPENDENT 𝛿𝑣/𝑣 AND ITS ERRORS + + +164 The literature agrees on the components of a well-posed 𝛿𝑣/𝑣 measurement: a stretching- + +165 family estimator for robustness at low SNR and large change (Mikesell et al., 2015; Yuan et al., + +166 2021), a coherence-based error model (Clarke et al., 2011; Weaver et al., 2011), a long stable + +167 reference (Wang et al., 2017), and cross-validation against a second estimator (Obermann & + +168 Hillers, 2019). Yet studies do not always report the same set, and the uncertainty convention + +169 is rarely, if ever, quantified (Appendix~C). The sections below address each component in + +170 turn and quantify, against a known truth, how far a parameter choice impacts the recovered + +171 𝛿𝑣/𝑣 and its error. + + +172 Table~2 previews the RMS error against the known synthetic ground truth for the best- and + +173 worst-case option on each axis covered in this section, each derived in its own dedicated + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 9 + + Table 1. Processing choices (“hyper-parameters”) and their effect on the recovered value and + the reported uncertainty. Key notation: 𝐵 (frequency bandwidth), 𝑊 = [𝑡1 , 𝑡2 ] (coda window), 𝑁 + (measurement count), 𝑁eff (weighted effective count), 𝜎 (measurement uncertainty). + + Choice Options / typical range Effect on the value Effect on the uncertainty + + Estimator TS, WCC, DTW, MWCS, WCS, Agree at small 𝛿𝑣/𝑣; at large Each has its own error model; + WTS, WTDTW 𝛿𝑣/𝑣 phase methods cycle-skip, inter-method spread is an + warps under-shoot (Fig. 1) uncertainty + Phase unwrapping on / off (phase methods) Decides whether MWCS/WCS Sets the usable 𝛿𝑣/𝑣 range + cycle-skip (Fig. 1b) + 𝐵 0.1–2 Hz (volcano), 2–4 Hz Selects the sampled depth, hence 𝜎 decreases with increasing 𝐵 + (aquifer), 4–12 Hz (landslide) which signal (Fig. 8a) + 𝑊 a few to tens of mean free times Later lapse → deeper, larger 𝜎 ∝ (𝑡3 3 −1/2 (duration + 2 − 𝑡1 ) + sensitivity effect), but late coda is low-SNR + 𝑊-𝐵 coupling fixed vs scaled with 𝑓 A fixed late window at high 𝑓 inceases 𝜎 due to decorrelation + measures noise (Fig. 8b) at high 𝑓 + Reference total stack / trailing / joint Trailing reference gives Reference noise propagates; + inversion increments: the trend is absent inversion lowers it + unless they are cumulated, which + then drifts; joint inversion + preserves it directly (Fig. 8c) + Stacking / 1–30+ days Smears and delays transients 𝜎 and resolution decreases with + substack (Fig. 8d) stacking length + Component A (average 𝛿𝑣/𝑣) vs B (average Different time series (Fig. 2) Different uncertainty object + aggregation CC images); weighted vs not (ensemble spread vs CC-peak + width) + Pair / network coherence-weighted vs Small change in value Changes 𝑁eff + weighting unweighted + √ + Uncertainty within-measurement (Weaver) / — Factor 𝑁 or more (Fig. 3) + definition SE / SD + Quality control min CC, min SNR, max 𝛿𝑡 error Rejects or keeps measurements Sets the effective 𝑁 and any + selection bias + Pre-processing one-bit / running-mean; Bias if the noise field is Spurious 𝛿𝑣/𝑣 when the noise + whitening band non-stationary spectrum drifts (Zhan et al., + 2013) + Clock / timing causal vs acausal branch A clock error fabricates 𝛿𝑣/𝑣 Branch asymmetry diagnoses it + handling (Fig. 11a) + + +174 synthetic exercise (detailed in the corresponding subsection below); it is a synthesis of this + +175 section’s per-choice numbers, distinct from Table~3’s one-at-a-time sweep on a single shared + +176 scenario in Section~4. + + + +177 3.1 Estimator family + + +178 We implement all methods as in previous work (Jiang & Denolle, 2020). + + +179 As of codameter v0.4.0, all seven estimators return physical 𝛿𝑣/𝑣 under the sign convention + +180 above rather than the raw stretch factor 𝜀; the synthetic generator imposes changes in the + 10 M. A. Denolle + + Table 2. Synthesis of Section 3: RMS error against the known synthetic truth for the best- and worst- + case option on each axis, each from its own dedicated synthetic scenario (see the cross-referenced + subsection). + + Axis Best-case RMS Worst-case RMS Section + + Estimator (family split) < 0.01 % (TS, up to 5 % true cycle-skip > 0.5 % past Section 3.1 + 𝛿𝑣/𝑣) ∼ 1.5 % true 𝛿𝑣/𝑣 (MWCS) + Cross-component ∼ 0.03 % (Approach B, ∼ 0.31 % (Approach A, Section 3.2 + aggregation averaged images) unweighted) + Network aggregation ∼ 0.005 % (network SE) ∼ 0.05 % (individual-pair Section 3.3 + (per-pair spread) range) + Frequency band ∼ 0.028–0.031 % (within ∼ 0.10 % (center off by Section 3.4 + ±0.3 Hz of the true band) > 0.5 Hz) + Coda window ∼ 0.01 % (adapted to band) ∼ 3.9 % (fixed, wrong band) Section 3.7 + Reference scheme ∼ 0.03 % (whole record, ∼ 0.15–0.16 % (end-of-record Section 3.5 + earliest period, or joint fixed, or moving) + inversion) + Stack length ∼ 0.020 % (7–10-day, workable ∼ 0.044 % (1-day, same Section 3.6 + deployment) deployment) + + +181 same convention, so a positive imposed 𝛿𝑣/𝑣 recovers as positive. A dedicated regression + +182 test holds every estimator to this convention in both signs, end to end through the full + +183 measurement pipeline, so the convention cannot silently drift back. + + +184 On small, clean 𝛿𝑣/𝑣 all seven estimators agree (Fig.~1a). Sweeping the same clean recovery + +185 out to ±5 % (Fig.~1b) shows exactly where and how each family first departs from the 1:1 + +186 line, and the estimator choice becomes consequential at large, noisy 𝛿𝑣/𝑣 (Fig.~1c), where the + +187 effect of the methods is split according to their phase measurement approaches. The stretching + +188 family (TS, WTS) and WCC match the whole dilated coda and remain accurate for high + +189 SNR coda waves; the phase methods (MWCS) read a wrapped phase and may cycle-skips, + +190 while the same cross-wavelet phase (WCS), once unwrapped in 2-D, recovers the change. The + +191 warping methods (DTW, WTDTW) track but under-shoot the largest strains. No estimator + +192 is simply “right”; the choice of estimator materially changes the 𝛿𝑣/𝑣 measurement at larger + +193 strain. + + +194 On a clean, noiseless sweep of true 𝛿𝑣/𝑣 from −5 to 5 % (Fig.~1b), the phase-wrapped MWCS + +195 estimator is the first to break on either branch: its error stays below 0.1 % out to ∼ 1.3 % + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 1 + + + + + Figure 1. Estimator choice across the seven NoisePy methods. (a) Clean, small 𝛿𝑣/𝑣: all agree. + (b) The same clean recovery swept over ±5 % true 𝛿𝑣/𝑣: MWCS cycle-skips past ∼ 1.5 % on either + branch; TS and WTS track the 1:1 line throughout; WCC tracks just as tightly on the negative + branch but breaks sharply near the positive edge; DTW and WTDTW break asymmetrically, + WTDTW near +1 % but only near −3 % on the other branch; WCS degrades smoothly, crossing + 1 % error beyond ±4 %. (c) Large, noisy 𝛿𝑣/𝑣 (a pre-failure landslide signal): MWCS cycle-skips, + 2-D-unwrapped WCS and the stretching family track, the warping methods under-shoot. + +196 true 𝛿𝑣/𝑣, then exceeds 1 % error by ∼ 1.5 % — the cycle-skip, essentially symmetric in + +197 sign. The stretching family (TS, WTS) stays below 0.1 % error out to the full 5 % tested, + +198 on both branches. WCC is just as accurate on the negative branch (error stays below 0.1 % + +199 throughout) but breaks sharply on the positive branch, crossing both 0.1 % and 1 % error + +200 abruptly at the edge of the tested range (∼ 4.75 %) — a sign asymmetry from the physical + +201 convention itself (Section~1), not a processing artefact. The warping methods develop large + +202 (> 1 %) errors asymmetrically as the warp path becomes ill-conditioned: WTDTW crosses + +203 1 % error already at ∼ 1 % true 𝛿𝑣/𝑣 on the positive branch but only at ∼ 3 % on the negative + +204 branch, and DTW crosses at ∼ 2.5 % versus ∼ 3 %. WCS degrades smoothly rather than + +205 catastrophically, crossing 1 % error beyond ±4 % true 𝛿𝑣/𝑣 on either branch. + 12 M. A. Denolle +206 3.2 Aggregating cross-component results + + +207 Each three-component seismic station (e.g., Z, N, E) carries 6 cross-component correlations + +208 (ZZ, NN, EE, ZE, ZN, NE), whether they are calculated at a single station or an inter-station + +209 pair. Each carries a signature of the changes in velocity; components may be dominated by + +210 Love or Rayleigh waves (Lin et al., 2008; Stehly et al., 2006), but scattering and non-straight + +211 ray paths induce cross-component leakage between modes (Hennino et al., 2001; Margerin + +212 et al., 2019), and thus it is often assumed in practice that coda waves of cross-components with + +213 multi-scattering characteristics (e.g., no clearly separated phases) are composed of “surface + +214 waves” with strong S-wave sensitivity. Combining them together requires parameter choices, + +215 such as averaging them directly (Liu et al., 2014), or weighted (e.g., using coherence-based + +216 weighting Hobiger et al. (2012), De Plaen et al. (2016)). + + +217 Combining is another workflow choice that can change both the value and the uncertainty + +218 (Fig.~2). One may peak-pick each component’s correlation-coefficient curve CC(𝜀, 𝑡) and then + +219 average the per-component 𝛿𝑣/𝑣 (Approach A) — unweighted, a few poor components bias + +220 the mean; coherence-weighted, they are suppressed — or one may average the CC(𝜀, 𝑡) images + +221 across components first and peak-pick once (Approach B). All three conventions appear in + +222 the literature; on the same pair they give visibly different time series, and they propagate + +223 uncertainty along incompatible pathways (the ensemble spread of the per-component picks for + +224 A, the width of the averaged correlation peak for B). On our six-component synthetic (three + +225 good, three poor SNR), the RMS error against the known truth is ∼ 0.31 % for unweighted + +226 Approach A, ∼ 0.08 % for coherence-weighted Approach A (the poor components suppressed, + +227 ∼ 4× better), and ∼ 0.03 % for Approach B (averaging the images before peak-picking, ∼ 11× + +228 better than the unweighted mean and ∼ 3× better than the weighted one). + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 1 + + + + + Figure 2. Cross-component aggregation for one station pair, both panels on the same 𝛿𝑣/𝑣 axis. + (a) Unweighted 𝛿𝑣/𝑣-averaging (Approach A) is biased by the poor components (grey), while + coherence-weighting and image-averaging (Approach B) track the truth; the shaded band is B’s + local peak-width uncertainty. (b) The averaged CC(𝛿𝑣/𝑣, 𝑡) image of Approach B (dark = high + coherence) with its peak ridge (white) tracking the truth (black, dashed). + +229 3.3 Aggregating across station pairs + + +230 Adding the next layer up — combining many station pairs into a unified network series + +231 — exposes the most consequential and least-reported choice of all: how to summarize the + +232 uncertainty. Three conventions are common: a coherence-weighted standard error (e.g., Clarke + √ +233 et al. (2011)), an unweighted standard error (𝜎 = std/ 𝑁; e.g., Brenguier et al. (2008b)), + +234 and the between-pair standard deviation (e.g., Clements & Denolle (2018)). On the same + +235 synthetic network the recovered means nearly coincide, but the reported 1𝜎 spans a factor + √ +236 of ∼ 𝑁 (Fig.~3). A velocity change that is “3𝜎 significant” under the tightest convention + +237 is “1𝜎, not significant” under the most conservative one — from identical data. Error bars + +238 on published 𝛿𝑣/𝑣 are therefore not comparable across studies unless the aggregation, the + +239 weighting, and the standard-error-versus-standard-deviation convention are all stated. + + +240 Figure~3 plots only the network-aggregate series, which hides how much the individual + 14 M. A. Denolle + + + + + Figure 3. Station-pair aggregation and uncertainty for a nine-pair network. (a) The recovered + √ 𝛿𝑣/𝑣 + agrees across conventions; the shaded 1𝜎 bands do not. (b) The reported 1𝜎 differs by ∼ 𝑁 purely + from the weighting and SE-versus-SD choices. + +241 pairs actually disagree. Fig.~4 plots the same nine-pair network’s individual 𝛿𝑣/𝑣(t) curves, + +242 styled after a basin-scale, urban ambient-noise deployment such as the San Gabriel Valley + +243 groundwater network (Clements & Denolle, 2018) — an illustrative geometry rather than + +244 a literal reproduction of that network’s exact station spacing. The individual pairs range + +245 in quality from a coherence-weighted SNR of ∼ 2.5 to ∼ 11, and their spread at any given + +246 day (median range ∼ 0.053 %) is nearly 10× wider than the coherence-weighted network + +247 standard error (median ∼ 0.005 %) and more than 3× wider than the more conservative + +248 between-pair standard deviation (median ∼ 0.017 %). A network-level error bar, however + +249 it is computed, describes the precision of the mean, not the dispersion of what individual + +250 pairs actually report — the two are routinely conflated when a single station-pair result is + +251 compared against a published network value. + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 1 + + + + + Figure 4. Individual station-pair 𝛿𝑣/𝑣(t) for the same nine-pair network as Fig. 3, coloured by + pair SNR. The pair-to-pair spread (grey band) is far wider than any of the three network-level 1𝜎 + conventions in Fig. 3b. + +252 3.4 Frequency band + + +253 The remaining choices are no less consequential. The frequency band sets the sampled + +254 depth: in a two-layer medium, high frequencies recover shallow, often seasonal signals and + +255 low frequencies recover a deeper, maybe more tectonic, signal (Fig.~8a). In practice a band + +256 often gets reused from a neighboring deployment or an earlier study at the same site without + +257 re-checking that it still matches the target depth — exactly the error this section quantifies. + + +258 On our synthetic two-layer groundwater scenario, holding the recovery band’s width fixed + +259 (0.6 Hz) and sweeping its center away from the deep layer’s true 0.2–0.8 Hz band shows the + +260 cost is not gradual: RMS error against the known truth stays flat, ∼ 0.028–0.031 %, for a + +261 center offset within ∼ 0.3 Hz of the true center, then rises by a factor of ∼ 3–4 once the offset + +262 passes ∼ 0.5 Hz — the point at which the assumed band starts sampling the shallow layer’s + +263 signal instead of the deep one — and plateaus near ∼ 0.10 % beyond that (Fig.~5). The band + 16 M. A. Denolle +264 choice is forgiving up to the edge of the layer it targets, and expensive immediately past it, + +265 not gradually worse the further off it drifts. + + + + + Figure 5. Frequency-band sensitivity: RMS error against the known groundwater deep-layer truth + as the recovery band’s center is swept away from the true 0.2–0.8 Hz band, holding its 0.6 Hz width + fixed. Error is flat within ∼ ±0.3 Hz of the true center, then rises sharply once the assumed band + drifts into the shallow layer’s territory. + + + +266 Scale of effect: a band-center error under ∼ 0.3 Hz costs essentially nothing here; past + +267 ∼ 0.5 Hz it costs a factor of ∼ 3–4 in RMS, from ∼ 0.03 % to ∼ 0.10 %. + + + +268 3.5 Reference + + +269 The reference defines what survives: a moving reference re-baselines continuously and erases + +270 slow trends that a fixed reference or a joint inversion (Brenguier et al., 2014) preserve + +271 (Fig.~8c). In practice the choice is rarely just fixed-versus-moving: an analyst also decides + +272 which period of the record a fixed reference is built from, and that choice alone can dominate + +273 the error — for instance when a deployment barely predates the process of interest, or when + +274 the only quiet-looking period available sits close in time to the process itself. + + +275 We compare five named schemes on the volcano synthetic: a reference built from the begin- + +276 ning of the pre-eruptive record (its earliest 15%), from the end of that record (its latest 15%, + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 1 +277 immediately before the eruption), from the whole pre-eruptive record, a 60-day moving + +278 (trailing) reference, and no single reference at all — the Brenguier et al. (2014)-style joint + +279 inversion, which measures relative dv/v between many short stacks instead of referencing + +280 every day to one (Fig.~6a). The whole-record, beginning, and inversion schemes all recover + +281 the truth to RMS ∼ 0.03 %. The end-of-record reference does far worse, RMS ∼ 0.15 % — + +282 not because it tracks the dynamics any less faithfully (its residual scatter around the truth, + +283 ∼ 0.029 %, matches every other fixed scheme) but because the reference epoch itself already + +284 sits ∼ 0.15 % into the developing pre-eruptive ramp, and every dv/v value is reported relative + +285 to whatever the reference was doing. Reference choice sets the zero point, not just the noise + +286 floor: comparing dv/v across studies, or across deployments that started at different times, + +287 requires knowing what the reference period itself was doing, not just how well each pipeline + +288 scores against a single truth. + + +289 The 60-day moving reference gives RMS ∼ 0.16 % — comparable to the worst fixed case, but + +290 for the opposite reason: it re-baselines away the trend continuously rather than sitting at one + +291 biased epoch. Lengthening the trailing window helps only slowly and never converges to the + +292 fixed-reference baseline: RMS falls from ∼ 0.168 % at a 10-day trailing window to ∼ 0.151 % + +293 at 240 days, still ∼ 4–5× the whole-record RMS (Fig.~6b) — the erasure is structural, not a + +294 noise effect that more averaging fixes. + + +295 Read carefully, though, that erasure is a property of the uncumulated increment, not of a + +296 non-fixed reference as such — and the published alternatives to a fixed reference do not take + +297 the form the sweep assumes. They fall into two families, neither of which re-baselines every + +298 epoch and reports the raw increment. + + +299 The first cumulates. James et al. (2017) re-baseline each day against the immediately + 18 M. A. Denolle +300 preceding day-stack and sum the daily 𝛿𝑡/𝑡 from a fixed start date, recovering a seasonal + +301 freeze–thaw trend in Alaskan permafrost that a stationary reference could not detect at + +302 all: the frozen-to-thawed velocity contrast made the stationary comparison cycle-skip, while + +303 adjacent days stayed coherent. Rivet et al. (2011) likewise reference each epoch to the previous + +304 one. The cost is that summation integrates the measurement error — James et al. (2017) + +305 report a positive drift in the cumulated series that their quadrature error budget could not + +306 account for, and correct it linearly against a stationary-reference anchor. The same rolling + +307 construction appears in laboratory coda monitoring of rock deforming to failure, where the + +308 scattering properties change too much for a fixed reference to stay valid (Zotz-Wilson et al., + +309 2019). + + +310 The second holds the reference fixed within a segment and stitches the segments together. + +311 Rivet et al. (2014) define a separate reference stack for each of three multi-year periods at + +312 Piton de la Fournaise, then merge the three series by measuring the relative velocity change + +313 between the adjacent segment references, using station pairs that occupied the same sites + +314 across the network change. Sens-Schönfelder et al. (2014) develop the multiple-reference form + +315 of the same idea at the same volcano, and Ermert et al. (2023) adopt a multiple-reference + +316 approach for urban single-station autocorrelations in Mexico City, where long-term waveform + +317 coherence is simply unavailable, stabilising the stacks by clustering correlation windows with + +318 a Gaussian mixture model so that day-time and night-time noise regimes stack separately. + + +319 That second family is worth naming precisely, because it is not a separate method from the + +320 joint inversion — it is a restriction of it. Stitching two segments by measuring the relative + +321 dv/v between their references is exactly the adjacent-pair case of the over-determined system + +322 the inversion solves over all pairs of block stacks. The reference axis is therefore better read + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 1 +323 as a single continuum, from one global reference, through segment references joined pairwise, + +324 to the fully coupled inversion, than as a menu of unrelated choices. + + +325 Against that, the uncumulated day-by-day trailing reference swept above is a limit case rather + +326 than a practice: we found no surveyed study that re-baselines continuously and reports the + +327 increments without summing them. It is retained here because it isolates what re-baselining + +328 costs when the trend is not reconstructed, which is the failure mode the two families above + +329 exist to avoid. codameter implements the joint inversion but neither the cumulated trailing + +330 reference nor cluster-based reference selection. + + + + + Figure 6. Reference construction on the volcano synthetic. (a) Five named schemes, each scored + by RMS against the known truth over the whole record and over the pre-eruptive ramp alone. (b) + RMS for the moving reference as a function of its trailing length; the dashed line is the whole-record + fixed reference’s RMS, which the moving reference never reaches. + + + +331 Scale of effect: which period a fixed reference is drawn from can cost as much as switching + +332 to a moving reference altogether (∼ 0.15–0.16 % RMS either way); a reference from the + +333 quietest available period, of any length, recovers the trend to ∼ 0.03 %. + 20 M. A. Denolle +334 3.6 Substacking + + +335 The stacking length trades noise against temporal resolution, rounding off and delaying a + +336 coseismic step (Fig.~8d). In practice the decision is rarely “how many days” in the abstract; + +337 it is “how long until the coda is coherent enough to trust” — stacking only as long as needed + +338 to clear a working correlation-coefficient (CC) threshold, then stopping. codameter’s own + +339 quality-control gate uses CC~> 0.6 (Section~3), and how quickly a station clears that bar + +340 depends entirely on its data quality. + + +341 Substack duration therefore defines a fundamental precision–temporal-resolution tradeoff. + +342 Longer stacks suppress incoherent noise fluctuations and accelerate the convergence of + +343 noise correlation functions, whereas shorter substacks preserve transient changes that would + +344 otherwise be averaged within the stacking window. The reduced signal-to-noise ratio of + +345 shorter correlations can be partially compensated through adaptive filtering, SVD-based or + +346 learned denoising, or through redundancy across dense seismic arrays, enabling 𝛿𝑣/𝑣 + +347 measurements at daily, hourly, and even sub-hourly resolution (Hadziioannou et al., 2011, + +348 Moreau et al. (2017),Mao et al. (2019),Viens & Van Houtte (2020)). + + +349 In this paper, the choice of substack length is guided by data-dependent quality gates (the + +350 CC threshold above) rather than a fixed duration, which allows stations with high coherence + +351 to preserve shorter temporal windows and thereby track rapid changes, while stations with + +352 lower SNR substack as needed to achieve stable estimates. + + +353 On the earthquake synthetic, a workable deployment (SNR 4, the same setting used through- + +354 out this section) clears CC~> 0.6 already at a 1-day stack (median CC 0.86); a poor, + +355 coherence-limited deployment (SNR 0.5) needs 14 days of substacking to clear the same + +356 bar (Fig.~7a). The two regimes behave differently past that point, too. For the workable + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 2 +357 deployment, RMS is U-shaped: it falls from ∼ 0.044 % at 1 day to a minimum ∼ 0.020 % + +358 around 7–10 days, then rises again to ∼ 0.038 % by 60 days as the stack smears the step + +359 (Fig.~7b) — the classic noise-versus-smearing tradeoff, and the reason “longer is always + +360 better” is wrong even once the coherence gate is satisfied. For the poor deployment, RMS is + +361 still falling at 60 days (∼ 0.067 %, down from ∼ 0.71 % at 1 day): the noise floor dominates + +362 over the whole tested range, and the smearing penalty never gets the chance to show up. + +363 Both regimes underestimate the coseismic step’s amplitude at every stack length tested here + +364 (the bias stays negative throughout for the poor deployment, and only crosses zero past 45 + +365 days for the workable one), so a recovered step should be read as a lower bound on the true + +366 drop, more so the longer the stack. + + + + + Figure 7. Substacking on the earthquake synthetic, at two deployment qualities. (a) Median + stretching correlation coefficient versus stack length; the dashed line is codameter’s own CC-gate + threshold (Section 3). (b) RMS error and the absolute bias in the recovered coseismic-step amplitude, + both against the known truth, log scale. + + + +367 Scale of effect: for a workable deployment, the noise/smearing tradeoff bottoms out around + +368 7–10 days at RMS ∼ 0.02 %; for a poor deployment, substack at least ∼ 2 weeks just to clear + +369 the coherence gate, and expect RMS an order of magnitude worse even after clearing it. + + +370 The accepted range for each of these parameters across the published literature is catalogued + 22 M. A. Denolle + + + + + Figure 8. Parameter choices. (a) Frequency band selects depth and signal. (b) A coda window + does not transfer across bands. (c) Reference strategy: a moving reference differences the trend + away unless its increments are cumulated; a fixed reference and the joint inversion retain it. (d) + Stacking length smears the coseismic step. + +371 directly, study by study, in the survey of Appendix~C (Table~A1): the frequency band, + +372 coda window, estimator, and uncertainty treatment actually reported by 103 ambient-noise + +373 𝛿𝑣/𝑣 studies. + + + +374 3.7 Coda window + + +375 The coda window is not independent of the frequency band — it deserves its own treatment + +376 because the two covary strongly, and getting this wrong is one of the larger, more avoidable + +377 sources of error in §3. Because intrinsic and scattering attenuation both grow with frequency, + +378 high-frequency coda energy falls into the noise floor much sooner than low-frequency coda: + +379 a coda window that is well past the direct arrival for a ∼ 0.3–0.8 Hz band is, at ∼ 3–6 Hz, + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 2 +380 sampling almost pure noise (Fig.~8b). On our synthetic, a fixed 20–40 s window at the high + +381 band gives RMS error ∼ 3.9 % (the noise floor, not the signal), while a window hand-adapted + +382 to the band (3–12 s) recovers the truth at ∼ 0.01 % — nearly a 400× difference from this + +383 one choice alone. This is itself an instance of a literature-documented tension: band-matched + +384 windowing is recommended, but Table~A1 shows many surveyed studies instead reuse one + +385 fixed window across bands. + + +386 Hand-adapting the window per band, as above, requires knowing the band in advance and + +387 re-tuning per deployment. A more principled alternative — used in our group — is to track + +388 the coda envelope directly and stop the window where it flattens onto the noise floor, rather + +389 than pre-specifying a window from a rule of thumb. We implement this by band-passing a + +390 long-term reference stack, smoothing its envelope, estimating the noise floor from a common + +391 late-lapse window, and taking the window end as the first lapse time past a short onset where + +392 the envelope stays within a factor of that floor for a sustained interval (not a single noisy + +393 dip). Applied blind (without being told which band it is) to three bands spanning low, mid, + +394 and high frequency (Fig.~9a), the detector recovers windows of ∼ (3, 29) s, ∼ (3, 37) s, and + +395 ∼ (3, 14) s respectively — correctly shrinking at the high band, though the low-versus-mid + +396 ordering is not perfectly monotonic on this synthetic (an artifact of how the fixed additive + +397 noise floor interacts with each band’s filter, not a claim that the detector is exact). Recovering + +398 𝛿𝑣/𝑣 with each band’s own detected window instead of one universal fixed (10–30 s) window + +399 (Fig.~9b) gives RMS ∼ 0.030 % vs. ∼ 0.036 % at the low band (a modest, ∼ 1.2× gain), + +400 ∼ 0.017 % vs. ∼ 0.035 % at the mid band (∼ 2×), and ∼ 0.020 % vs. ∼ 2.0 % at the high + +401 band (∼ 100×) — the fixed window is adequate at low frequency and catastrophic at high + +402 frequency, while the envelope-derived window is close to the best achievable at every band + +403 without ever being told what band it is measuring. + 24 M. A. Denolle + + + + + Figure 9. Coda window / frequency-band covariation. (a) Smoothed coda envelopes at three bands + (log scale), shaded by each band’s envelope-detected window — shrinking automatically at higher + frequency. (b) RMS error against the known truth for a single universal fixed window versus each + band’s own envelope-derived window: comparable at low frequency, ∼ 93× better at high frequency. + +404 3.8 Causal and acausal branches + + +405 In a symmetric cross-correlation, both sides of the coda (positive or negative lags) should + +406 exhibit the same 𝛿𝑣/𝑣. Due to the directionality of the wavefield recorded at the two stations, + +407 the correlated wavefield in the coda may differ (Stehly et al., 2006). While the interpretation + +408 of such coda in terms of Earth’s structure effect is difficult (Snieder et al., 2002), the stability + +409 of the wavefield excited in the coda is the main requirement for stable 𝛿𝑣/𝑣 measurements + +410 (Hadziioannou et al., 2009). Given the challenge in interpreting both sides independently, + +411 researchers typically measure 𝛿𝑣/𝑣 on each lag and then report its average (Kidiwela et al., + +412 2026). The causal (positive-lag) and acausal (negative-lag) branches sample opposite-direction + +413 paths with different source-side illumination, and in a 3D medium their sensitivity kernels + +414 sample partly different volumes, so the two can report genuinely different 𝛿𝑣/𝑣 without either + +415 being wrong. Two regimes bound the choice (Fig.~10). When a change is localized to the + +416 volume one branch samples, symmetrizing or averaging the branches — the common default + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 2 +417 — dilutes it toward zero, while the branch that carries the change recovers it (Fig.~10a); here + +418 preferring the branch of greatest change is a researcher’s judgement. When instead both + +419 branches share the same change, their difference is measurement noise, and selecting the + +420 branch of greatest change over-reports it — a max-of-two-estimators selection bias that grows + +421 as SNR falls (Fig.~10b). When both sides exhibit the same change (sign, coherence) but with + +422 different magnitude, it is reasonable to use the 𝛿𝑣/𝑣 of greatest change given the already low + +423 sensitivity in coda waves (Obermann et al., 2013). An acceptable workflow is to measure + +424 both branches, evaluate on that consistency, select by the coherence of the change rather + +425 than its amplitude (a criterion independent of the answer, so it carries no selection bias), + +426 and carry the between-branch difference as an explicit term of the measurement covariance + +427 𝐶𝑑 (Section~5) rather than discarding it by averaging. + + + + + Figure 10. Combining the causal and acausal branches. (a) A change localized to the volume the + causal branch samples: averaging the branches dilutes it to about half, while the branch carrying + it recovers the truth. (b) The same change on both branches: selecting the branch of greatest + change over-reports the drop, worsening as SNR falls (a selection bias), while the branch mean + stays unbiased. + 26 M. A. Denolle +428 3.9 Choices that create spurious 𝛿𝑣/𝑣 + + +429 Some choices may create spurious signal. A station clock error delays the whole correlation + +430 by a lapse-independent shift, producing an apparent 𝛿𝑣/𝑣 that appears with opposite sign + +431 on the causal and acausal branches; measuring the two branches separately is the diagnostic + +432 (Fig.~11a). Seasonally varying noise sources warp the low-SNR late coda, so a late measure- + +433 ment window reports a coherent spurious seasonal 𝛿𝑣/𝑣 many times the real signal while an + +434 earlier window stays clean (the waveform-level version of Zhan et al., 2013) (Fig.~11b). + + +435 Biases from spurious arrivals could be quantified but mostly we should decontaminate our + +436 workflow from these artefacts or not interpret the results. + + + + + Figure 11. Deviations that create spurious 𝛿𝑣/𝑣. (a) A clock drift splits the causal and acausal + branches with opposite sign. (b) Seasonal late-coda noise injects a spurious seasonal 𝛿𝑣/𝑣 into a + late window but not an early one. + + + +437 Taken together, the choices compound. We make this concrete in Section~4 by running the + +438 full multiverse of best-practice and deviation choices on one synthetic dataset and ranking + +439 each by the bias and the error-bar change it induces. + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 2 +440 4 THE COMBINED IMPACT OF PROCESSING CHOICES + + +441 The scenario is a single representative station pair monitoring a shallow volcanic edifice, + +442 in the style of the permanent broadband deployments used at effusive/dome volcanoes + +443 such as Piton de la Fournaise (Brenguier et al., 2008b): a coda band matched to shallow + +444 depths (0.4–1.0 Hz), a coda window past the direct arrival (10–30 s), and daily correlations + +445 sampled every 3 days over 2.5 years at a per-day correlation-coefficient SNR of 7, typical of + +446 a continuously operating station. The synthetic ground truth combines an annual seasonal + +447 𝛿𝑣/𝑣 cycle (as from near-surface thermoelastic/hydrologic effects), a slow pre-eruptive inflation + +448 ramp, and a sharp co-eruptive velocity drop with partial recovery. This single-pair scenario + +449 isolates the measurement-step choices from the network-aggregation choices already covered + +450 in Sections~3.2–3.3. + + +451 The previous sections only identified single choices, but the overall research workflow involves + +452 them all. We now estimate the combined effects of these parametric choices. Starting from + +453 a single best-practice baseline (trace stretching, a band matched to the target depth, a + +454 coda window well past the direct arrival, a 10-day stack, a long stable reference, coherence + +455 gating; the cross-cutting rules of Brenguier et al. (2014; Weaver et al., 2011; Clarke et al., + +456 2011) as distilled in our survey), we change one parameter at a time to a deviation from best + +457 practice documented in the literature and measure the resulting error against the known truth + +458 (Fig.~12). The ranking is unambiguous: relative to a best-practice RMS error of ∼ 0.03 %, + +459 the two-dimensionally-unwrapped WCS estimator is catastrophic here (∼ 50× worse), a + +460 wrapped-phase MWCS inflates the error by roughly an order of magnitude (∼ 12×), and + +461 DTW by ∼ 6×; among the non-estimator choices a moving reference is worst (∼ 5×, and + +462 most distorts the recovered drop), while stack length, coda window, and frequency band + 28 M. A. Denolle +463 deviations are each more modest (1.5–2.5×). The joint-inversion reference stays closest to + +464 the fixed-reference baseline among the reference-scheme deviations. + + + + + Figure 12. One-at-a-time deviations from a best-practice baseline, ranked by the bias they inject + (a, log scale) and by how they distort the recovered co-eruptive drop (b, symlog). Bars are coloured + red when the error exceeds three times the baseline. The estimator and reference choices dominate; + the band and gating are minor for this scenario. + + + +465 We test the compounding effects of these choices through 108 reasonable workflows selecting + +466 three estimators, two frequency bands, three coda windows, three stacking lengths and + +467 two reference schemes on a synthetic “volcano” dv/v time series that includes a seasonal + +468 oscillation, a slow pre-eruptive inflation ramp, and a sharp co-eruptive drop with partial + +469 exponential recovery (Fig.~13a). The per-day standard deviation across the 108 pipelines + +470 varies by a factor of ∼ 4–5 over the time series (from ∼ 0.4 % to ∼ 1.7 %), and is widest + +471 exactly at the sharp co-eruptive drop; the RMS error against the known truth spans over + +472 two orders of magnitude across pipelines (∼ 0.02–2.8 %). + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 2 +473 Attributing the variance of the outcome to each axis with a first-order (main-effect) sensitivity + +474 index (Fig.~13b) shows that, for this dataset, the coda window controls the RMS error + +475 most, with the estimator second and the stack length third; for the recovered drop amplitude + +476 the order changes to stack length first, window second, and estimator third. The first-order + +477 indices sum to well under one in both cases (∼ 0.66 for RMS, ∼ 0.63 for the drop), so a large + +478 part of the spread is interaction between choices compounding. The appropriate object is + +479 therefore not a single curve but a distribution of 𝛿𝑣/𝑣 over the processing choices. + + + + + Figure 13. The full multiverse. (a) 108 reasonable pipelines on one dataset, each coloured by its + RMS error against the truth on a colourblind-safe scale (bright accurate, dark biased; the worst + run off the clipped axis); the grey band is the 10–90% inter-pipeline spread, widest at the velocity + drop. (b) First-order variance attribution: which choice controls the RMS error and the recovered + drop. Window, estimator, and stack length dominate, in that order for RMS and reordered for the + drop; the sub-unity sum signals strong interactions. + + + +480 Table~3 summarizes this into the measurement-step best practice and the documented + +481 deviation for each choice, with the consequence the synthetic makes concrete. The baseline + +482 and deviation sets are the ones our survey extracts from the literature (the cross-cutting + +483 rules of Snieder et al. (2002; Clarke et al., 2011; Weaver et al., 2011; Brenguier et al., 2014; + +484 Wang et al., 2017; Obermann & Hillers, 2019)) and are implemented in codameter. + 30 M. A. Denolle + + Table 3. Measurement step: best practice versus the common deviation and its consequence. Rows + are the axes swept in Fig. 13; the sets follow the literature survey (Appendix C). + + Choice Best practice Common deviation Consequence + + Estimator Stretching family Wrapped-phase MWCS (Clarke Cycle-skips at large 𝛿𝑣/𝑣; error + (TS/WTS/WCC), robust at low et al., 2011) without 2-D inflated ∼ 10× or catastrophic + SNR and large 𝛿𝑣/𝑣 (Mikesell unwrapping (Mao et al., 2020) + et al., 2015; Yuan et al., 2021) + Frequency band Matched to the target depth: Off-target or a single wide band Mixes depths; here mostly sets + ∼ 0.1–2 Hz (volcano, crust), precision + 2–4 Hz (aquifer), 4–12 Hz + (shallow damage) (Obermann + et al., 2013, 2016) + Coda window Lapse window past the direct Fixed late window reused across Measures noise at high 𝑓; bias + arrival, scaled with the band: bands and inflated 𝜎 + ∼ 5–30 s (crustal) up to ∼ 100 s + (station pairs) (Obermann et al., + 2013) + Stack length Short enough to resolve the Over-long stack (∼ 45 d) Smears and delays a step; + transient (∼ 10 d), on a long, distorts the recovered drop + stable reference span (Wang + et al., 2017) + Reference Long fixed stack or all-to-all Moving / trailing reference Erases slow trends + joint inversion (Brenguier et al., + 2014; Wang et al., 2017) + Coherence gating Discard low-coherence epochs No gating Keeps corrupted epochs; changes + (CC / SNR threshold) (Clarke the effective 𝑁 + et al., 2011) + √ + Uncertainty State it explicitly: Left unstated Factor 𝑁 ambiguity in + definition within-measurement (Weaver significance (Fig. 3) + et al., 2011; Clarke et al., 2011) / + SE / SD + + +485 Running this many pipelines is only practical if each one is cheap. Testing codameter against + +486 a larger, multi-year deployment surfaced real bottlenecks in the per-day estimator loop, + +487 which we removed with three vectorized fast paths: a trailing stack built from a difference + +488 of cumulative sums instead of a per-day mean (roughly 2× at a 45-day stack length), a + +489 vectorized moving-reference stretching estimator that computes the stretch-interpolation + +490 weights once per trial epsilon instead of once per day (roughly 3× on a 3-year synthetic), + +491 and, for ensembles that share a band, a single shared band-pass instead of one per pipeline + +492 member (roughly 3× on a 5-member ensemble). All three reproduce the loops they replace to + +493 within 10−15 in 𝛿𝑣/𝑣 (regression-tested at atol = 10−12 ); the reported ratios are wall-clock, + +494 vary with system load, and should be read as “roughly 𝑁 ×,” not exact. + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 3 +495 5 A BAYESIAN MEASUREMENT MODEL AND ITS DATA + +496 COVARIANCE + + +497 If the processing choice controls the answer, the principled response is not to select a single + +498 pipeline but to treat the choice as a nuisance parameter with a prior and marginalise it + +499 out. We propose this as the new best practice for the 𝛿𝑣/𝑣 measurement, and implement it + +500 as a Bayesian hierarchical inversion. For configuration 𝑘 drawn from a prior over reasonable + +501 pipelines we obtain a measured series 𝑚𝑘 (𝑡) with a coherence-limited within-method floor + +502 𝜎𝑘 (𝑡) (Weaver et al., 2011; Clarke et al., 2011), and posit + + + 𝑚𝑘 (𝑡) = 𝜇(𝑡) + 𝛽𝑘 + 𝜀𝑘 (𝑡), 𝛽𝑘 ∼ 𝒩(0, 𝜏 2 ), 𝜀𝑘 (𝑡) ∼ 𝒩(0, 𝑠2 𝜎𝑘 (𝑡)2 ), (2) + + +503 with a second-difference random-walk smoothness prior on the latent true series 𝜇(𝑡). Here + +504 𝛽𝑘 is configuration 𝑘’s methodological bias (the systematic offset between, say, MWCS and + +505 stretching), 𝜏 its scale across the ensemble, and 𝑠 rescales the Weaver floor so the data report + +506 whether it is calibrated. A conjugate Gibbs sampler, implemented in codameter with no + +507 external sampler dependency, returns the joint posterior. + + +508 The model yields two distinct objects, and conflating them is the error the field makes + +509 (Fig.~14). The posterior of 𝜇 is the precision of the combined estimate: it is tight and shrinks + +510 with ensemble size — yet it under-covers the truth, because the configurations share a + +511 common-mode bias that averaging cannot remove. The object a downstream depth or stress + +512 inversion must consume is the marginal measurement covariance + + + 𝐶𝑑 (𝑡, 𝑡′ ) = 𝐷𝑅𝐷 + ⏟ + 2 11⊤ , + 𝜏⏟ 𝐷 = diag(𝜎tot (𝑡)), + within ⊕ methodological, temporally correlated common mode + (3) + +513 with 𝜎tot + 2 + = 𝑠2 𝜎𝑘2 -average + methodological variance and 𝑅𝑖𝑗 = 𝑒−|𝑡𝑖 −𝑡𝑗 |/𝐿 for a correlation + 32 M. A. Denolle +514 length 𝐿 estimated from the ensemble residuals. This 𝐶𝑑 is time-dependent — wider at + +515 the sharp drop and at low coherence — and its temporal correlation plus common-mode + +516 term collapse the effective number of independent epochs by an order of magnitude. On our + +517 synthetic the marginal 𝐶𝑑 covers the truth at the nominal rate while the naive posterior + +518 band does not, making concrete that the measurement covariance, not the posterior of the + +519 averaged series, is what must be propagated. + + + + + Figure 14. The Bayesian measurement model. (a) The processing ensemble (grey) is marginalised + into a posterior mean (purple) with a narrow credible band (the estimator precision) and a much + wider ±2𝜎 band from the marginal 𝐶𝑑 (the honest data error), which covers the truth where the + credible band does not. (b) The resulting time-dependent data covariance 𝐶𝑑 . (c) Its diagonal 𝜎𝑑 (𝑡) + decomposed into within-method and methodological parts, rising at the eruption; the posterior-of- + the-mean (dotted) is far tighter, and 𝑁eff is a fraction of the epoch count. + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 3 +520 6 PROPAGATING 𝛿𝑣/𝑣 ERRORS AT DEPTH Δ𝛽/𝐵𝐸𝑇 𝐴(𝑍) + + +521 The remaining sections present a framework rather than new synthetics: they set out how + +522 the covariance of Section~5 propagates down the inference chain, and ground each step in + +523 what the monitoring literature does and does not yet report. The executable stages are in + +524 development in the open codameter package (Section~8). + + +525 The field has converged on one physical rule for depth — depth is set by the frequency band + +526 and the coda lapse time, it is not assumed (Obermann et al., 2013, 2016) — and, increasingly, + +527 on multi-band measurement as the means to resolve it (Takano et al., 2017; Feng et al., 2020; + +528 Mao et al., 2022, 2025). The step from a set of per-band 𝛿𝑣/𝑣 series to a depth profile is + +529 where reporting is least consistent: many studies read a single band as a single depth, only + +530 a few invert several bands against surface-wave sensitivity kernels, and the propagation of + +531 the measurement error into the depth estimate is seldom shown. The depth assignment is + +532 frequently the scientific claim itself — whether the change lies in the aquifer or the overlying + +533 soil, whether coseismic softening is a shallow site response or slip on the fault at depth + +534 (Rubinstein & Beroza, 2005) — so a depth reported without its uncertainty cannot support + +535 that claim. + + +536 A 𝛿𝑣/𝑣 measured in band 𝑏 is not a point sample but a weighted integral over depth, + + ∞ + 𝛿𝑉𝑆 + ( 𝛿𝑣 + 𝑣 ) =∫ 𝐾𝑏 (𝑧) (𝑧) d𝑧 + 𝜀𝑏 , (4) + 𝑏 0 + 𝑉𝑆 + +537 where 𝐾𝑏 (𝑧) is the (Rayleigh-wave) depth-sensitivity kernel for band 𝑏 and 𝜀𝑏 carries + +538 that band’s measurement covariance from Section~5. Stacking bands gives a linear sys- + +539 tem d = G m + 𝜀 with G𝑏𝑧 = 𝐾𝑏 (𝑧) and data covariance 𝐶𝑑 ; the Bayesian solution under a + +540 smoothness prior returns a depth profile 𝛿𝑉𝑆 /𝑉𝑆 (𝑧) together with its posterior covariance + 34 M. A. Denolle +541 𝐶𝑚 (𝑧), implemented in codameter. The bands must sit where the kernels resolve: too low + +542 and the kernel leaks into the half-space, too high and the coda is incoherent (Section~3.4). + +543 The width of 𝐶𝑚 (𝑧) — not the profile alone — is the deliverable, and it inherits the temporal + +544 correlation and common-mode structure of 𝐶𝑑 . + + +545 One assumption is usually left implicit: that a 𝛿𝑣/𝑣 change is a shear-velocity change alone. + +546 In partially saturated ground it is not. Filling or draining pore space changes both the shear + +547 modulus and the bulk density, so for the shear-dominated coda the observed change mixes + +548 the two, + + 𝛿𝑣 𝛿𝜇 𝛿𝜌 + ≈ 12 − 12 , (5) + 𝑣 𝜇 𝜌 + +549 and velocity alone cannot separate them. A petrophysical model — Gassmann fluid substitu- + +550 tion for the modulus and a porosity–saturation relation for the density (Gassmann, 1951; + +551 Mavko et al., 2009) — is what breaks the degeneracy, at the cost of its own prior uncertainty + +552 on porosity, fluid modulus, and the saturation path. Hydrological and cryospheric targets, + +553 where saturation varies strongly (Clements & Denolle, 2018; James et al., 2019), are precisely + +554 where neglecting the density term biases the inferred velocity change and, downstream, the + +555 stress. The framework carries 𝛿𝜌/𝜌 as a second inverted field with its own kernel and reports + +556 how much of the surface 𝛿𝑣/𝑣 each explains; the executable version is a documented extension + +557 (Section~8). + + + + +558 7 TOWARD A SCALABLE DEPLOYMENT + + +559 Every result so far is on a truth-known synthetic, by design (Section~2): it is the only way to + +560 separate a processing artefact from a real signal. The next step is to test whether the same + +561 measurement machinery holds up against real data at deployment scale, not just against a + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 3 + + Table 4. Depth step: best practice versus the common deviation in going from per-band 𝛿𝑣/𝑣 to a + depth profile, and the consequence for the interpretation. + + Choice Best practice Common deviation Consequence + + Depth assignment Invert several bands against Read one band as one depth No depth resolution and no + sensitivity kernels depth error + Band selection Bands where the kernels resolve Convenience band Kernel leaks; unstable inversion + (no half-space leak, coherent + coda) + Measurement error Propagate the per-band 𝐶𝑑 into Plot a profile with no covariance Overconfident depth attribution + the profile + Saturation Separate 𝛿𝑉𝑆 /𝑉𝑆 and 𝛿𝜌/𝜌 Assume a pure 𝛿𝑉𝑆 /𝑉𝑆 change Biased velocity change and + with a petrophysical model in stress in hydrological and + partly saturated ground cryospheric targets + Velocity model State the reference 𝑉𝑃 , 𝑉𝑆 (𝑧) Fixed, unstated model Hidden systematic in the kernels + and its uncertainty and the moduli + + +562 synthetic that was built to resemble it. We are building a companion cloud pipeline that + +563 correlates real continuous waveforms for station CI.LJR (Lake Hughes, California) — the + +564 reference station of Clements & Denolle (2023) — pulled from the public Southern California + +565 Earthquake Data Center S3 archive, using the NoisePy package (Jiang & Denolle, 2020) + +566 for the correlation step. Correlation and dv/v estimation each run as a cloud batch job on + +567 spot compute; dv/v estimation itself is handed to the same codameter measurement and + +568 uncertainty functions this paper’s synthetic results are built on, with baseline processing + +569 configurations drawn from the same recommendation logic — not a separate reimplementation. + +570 The retrospective run is validated against the already-published Clements & Denolle (2023) + +571 CI.LJR result before any new claim is drawn from it. + + +572 After the correction, single-station 𝛿𝑣/𝑣 (NoisePy correlations, a codameter 5-member + +573 ensemble, 2–4 Hz, 2018–2019) validates against the published Clements & Denolle (2023) + +574 product. The comparison is not trivial to get right: the CD2023 90-day-comp product is + +575 a trailing 90-day stack, so it lags a centered-smoothed daily series by about 45 days, and + +576 comparing without matching that smoothing caps the correlation near 0.7 even on a real + +577 annual cycle (Fig.~15). We match by applying the same trailing 90-day mean to the daily + +578 series, compare demeaned — the two products reference different epochs, and a constant offset + 36 M. A. Denolle +579 is bookkeeping, not error — and exclude the first 150 days of each station’s series as reference + +580 burn-in. Under this matched comparison, CI.LJR reaches 𝑟 = 0.990 (681 overlapping days); + +581 CI.ARV reaches 𝑟 = 0.66–0.92 depending on the join method, reflecting real 2018 data gaps; + +582 CI.RXH reaches 𝑟 = 0.68, the weakest of the three, on a station whose recovered 𝛿𝑣/𝑣 is + +583 nearly flat and whose signal is low to begin with. + + + + + Figure 15. Single-station 𝛿𝑣/𝑣 at three CI stations, 2018–2019, against the published Clements & + Denolle (2023) product (dashed, reference-shifted). Daily 𝛿𝑣/𝑣 (points) with the ensemble spread + (shaded, epistemic) and measurement error bars, and a 45-day-smoothed curve. The annotated 𝑟 is + computed on this 45-day-smoothed comparison, not the smoothing-matched comparison reported + in the text; matching CD2023’s own trailing 90-day window instead of a centered 45-day one raises + 𝑟 at every station (to 0.990/0.66–0.92/0.68 for LJR/ARV/RXH), which is why the two numbers + differ. + + +584 Why validation quality differs so much by station is visible in the correlation function itself + +585 (Fig.~16). CI.LJR shows a stable, narrow coda near zero lag through the year. CI.RXH + +586 shows multipath, several coherent arrivals spread across the full ±8 s of lag shown, and a + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 3 +587 visible shift in that pattern in April–May 2019, consistent with a site change rather than a + +588 processing artefact. CI.ARV’s coherent energy is compact and concentrated near zero lag but + +589 comparatively sparse, consistent with its higher scatter and join-method sensitivity. + + + + + Figure 16. Daily north-south/east-west cross-component correlation functions, 2–4 Hz, ±8 s lag, + 2019. CI.LJR’s coda is stable and narrow. CI.RXH shows multipath (several coherent bands across + the full lag range) and a shift in that pattern in April–May 2019. CI.ARV’s coherent energy is + compact and near zero lag but comparatively sparse. The visual difference is the reason validation + quality differs by station in Fig. 15. + + + +590 As an optional supplement, Fig.~17 shows the ensemble’s warm-up behaviour on a separate + +591 90-day smoke run at CI.LJR: 𝛿𝑣/𝑣 is undefined until enough history has accumulated for + +592 the moving-reference member to compute a trailing reference, and each band’s per-epoch + +593 stretching correlation coefficient is reported alongside the recovered series. + + + + +594 8 DISCUSSION + + +595 The experiments above share one finding: for ambient-noise 𝛿𝑣/𝑣, the dominant control on + +596 both the reported value and its uncertainty is frequently the processing choice, not the data. + +597 This is a consequential but tractable problem. We suggest three responses. + + +598 Report the choices. At minimum, a 𝛿𝑣/𝑣 study should state the estimator and its param- + 38 M. A. Denolle + + + + +Figure 17. CI.LJR single-station 𝛿𝑣/𝑣, a separate 90-day smoke run (January–April 2023), four +frequency bands. The ensemble spread (shaded) and measurement error bars are reported once at +least one member is defined; the annotated member count grows as the moving-reference member’s +warm-up period elapses, reaching all 5 members later in the window. Bottom panel: per-band +stretching correlation coefficient. + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 3 + + Table 5. A minimal reporting checklist for an ambient-noise 𝛿𝑣/𝑣 study. Stating these turns an + undocumented, irreproducible choice into an inspectable one and makes error bars comparable + across studies. + + Step What to report + + Pre-processing Time-domain normalization (one-bit / running-mean), spectral whitening band, sampling rate + Correlation & stacking Components computed, segment length, daily/sub-stack length, total reference span + Estimator Method (TS / WCC / DTW / MWCS / WCS / WTS / WTDTW), its parameters (𝜀-grid, or + sub-window length and step), and whether the phase is unwrapped + Frequency band(s) [𝑓1 , 𝑓2 ] for every reported measurement + Coda window(s) [𝑡1 , 𝑡2 ], the branch(es) used, and how 𝑡1 , 𝑡2 were set relative to the band + Reference Scheme (total stack / trailing / inversion) and period + Component aggregation Approach A or B; weighted (by what) or unweighted + Pair / network Spatial averaging and weighting scheme + aggregation + Uncertainty The exact definition of the quoted error: within-measurement (e.g. Weaver), + between-component/pair standard error, or standard deviation + Quality control CC / SNR thresholds, rejection criteria, resulting effective 𝑁 + Software Package, version, and the parameter file or its DOI + + +599 eters, the frequency band(s) and coda window(s) and how the window was set relative to the + +600 band, the reference scheme, the stacking, the cross-component and station-pair aggregation + +601 and weighting, and — critically — the exact definition of the quoted uncertainty (within- + +602 measurement error, between-component/pair standard error, or standard deviation). Our + √ +603 results show that the last item alone can change a stated 1𝜎 by 𝑁. Table~5 collects this + +604 into a minimal reporting checklist, and Appendix~C shows how unevenly these items are + +605 reported across the literature today. + + +606 Quantify the choice-induced uncertainty. Where a choice is not forced by the physics, + +607 it can be sampled. Pushing a distribution of reasonable processing choices through the + +608 measurement-error floors of Clarke et al. (2011; Weaver et al., 2011) yields, by the law + +609 of total variance, a marginal 𝛿𝑣/𝑣 uncertainty that includes the processing-choice spread + +610 — a more honest error bar than any single pipeline provides, and the natural input to a + +611 depth/stress inversion. Section~5 makes this a Bayesian measurement model whose deliverable + +612 is a time-dependent data covariance 𝐶𝑑 . + + +613 Make it executable. All synthetics, estimators and figures in this paper are released in + 40 M. A. Denolle +614 the open codameter package, which reproduces every result with a single command and is + +615 unit-tested. An executable record turns an undocumented choice into a versioned, inspectable + +616 one, and lets a reader re-run a study’s pipeline on the truth-known synthetic to see its bias + +617 before trusting it on data. + + +618 Validate against something you did not generate. Every synthetic test in this paper + +619 passed before the discovery below, and that is exactly the danger: a synthetic built under the + +620 same sign convention as the estimator reading it will always agree, whether the convention + +621 is physically correct or not. Testing codameter’s estimators against a real cross-network + +622 deployment (Section~7), recovered 𝛿𝑣/𝑣 anticorrelated with the published Clements & Denolle + +623 (2023) product and with seasonal hydrology at three stations (𝑟 = −0.69, −0.45, −0.40). + +624 Ground-truthing through the exact call path made the cause obvious: imposing a +0.5 % + +625 velocity change returned −0.50 %. The synthetic generator and all seven estimators had + +626 consistently used the stretch factor 𝜀 (positive for a coda dilation, i.e. a slowdown), not + +627 physical 𝛿𝑣/𝑣 (positive for a speedup) — internally coherent, so every synthetic-recovery test + +628 in the sections above passed, but opposite to the sign convention the field expects and to the + +629 published product it was compared against. The fix is the convention boxed in Section~1, + +630 shipped as codameter v0.4.0. Internal consistency is not correctness: a pipeline that only + +631 checks itself will confirm whatever convention it started with, and only the comparison + +632 against an independently-produced result caught this one. The fix and its ground-truthing + +633 procedure are documented in the codameter release history. + + +634 Propagate the covariance, do not truncate it. The measurement covariance is not the + +635 end of the analysis but its first input. Section~6 sets out the next step of the chain: invert the + +636 per-band 𝐶𝑑 through sensitivity kernels for a depth profile and its covariance, separating the + +637 shear-velocity and density contributions where the ground is partially saturated. Converting + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 4 +638 that depth-resolved posterior to stress or strain requires material priors this paper does + +639 not attempt to constrain, and is left to other work; what we deliver is the depth posterior + +640 and its covariance, the object any such conversion must consume. Building and testing the + +641 depth-propagation stage on truth-known synthetics is the natural continuation of this work, + +642 and is under way in the open codameter framework. + + + + +643 9 CONCLUSIONS + + +644 Ambient-noise 𝛿𝑣/𝑣 monitoring rests on a chain of processing choices that are made ad hoc + +645 and reported incompletely. Using a truth-known synthetic and the full estimator suite of + +646 an open toolbox, we have shown that these choices change the recovered 𝛿𝑣/𝑣 and, more + √ +647 consequentially, change the reported uncertainty by a factor of ∼ 𝑁 — enough to flip the + +648 significance of a result — all without touching the data. The remedy is not a single mandated + +649 pipeline but transparency: report every choice, sample the ones the physics does not fix, + +650 carry the resulting measurement covariance into the inference, and release the pipeline as + +651 executable code. The same discipline extends down the inference chain: the measurement + +652 covariance is the input a depth inversion consumes, and only a pipeline that carries the + +653 covariance that far can attach an honest uncertainty to a depth-resolved velocity-change + +654 profile. Converting that profile to stress or strain is a further step this paper does not attempt. + +655 We offer codameter as one such record, and as the package in which the depth stage is being + +656 built. + 42 M. A. Denolle +657 APPENDIX A: ESTIMATOR DEFINITIONS + + +658 Let 𝑟(𝑡) and 𝑐(𝑡) be the reference and current cross-correlations, band-passed to [𝑓1 , 𝑓2 ] + +659 (central frequency 𝑓𝑐 , bandwidth 𝐵) and read over the coda window 𝑊 = [𝑡1 , 𝑡2 ] on one or + +660 both branches. Each method below estimates a trial stretch factor 𝜀, the fractional dilation + +661 of the current coda relative to the reference; physical 𝛿𝑣/𝑣 follows via the convention boxed + +662 in Section~1, 𝛿𝑣/𝑣 = −𝜀/(1 + 𝜀). + + +663 Trace stretching (TS). For each trial stretch factor 𝜀, the current correlation is interpolated + +664 as 𝑐𝜀 (𝑡) = ℐ[𝑐]((1 + 𝜀)𝑡) (interpolation on current only) while the reference 𝑟(𝑡) remains + +665 fixed. The windowed correlation coefficient is + + ∫ 𝑟(𝑡) 𝑐𝜀 (𝑡) d𝑡 + CC(𝜀) = 𝑊 + 1/2 + , 𝜀⋆ = arg max CC(𝜀). (A.1) + (∫ 𝑟2 d𝑡 ∫ 𝑐𝜀2 d𝑡) + 𝜀 + 𝑊 𝑊 + + +666 The best-fit stretch 𝜀⋆ is then converted to physical 𝛿𝑣/𝑣 via 𝛿𝑣/𝑣⋆ = −𝜀⋆ /(1 + 𝜀⋆ ) + +667 as boxed in the Introduction. The single-measurement error decreases with the co- + +668 herence CC, the bandwidth 𝐵, and the window length, approximately as 𝜎𝜀 ∝ + +669 √(1 − CC2 )/CC2 /[𝑓𝑐 √𝐵 (𝑡32 − 𝑡31 )] (Weaver et al., 2011). + + +670 Interpolation direction and convention. The interpolation is applied to the current waveform + +671 and not the reference so that the high-SNR reference stack remains invariant throughout + +672 the epsilon search, which is particularly important when the reference is built as a long- + +673 term or moving average. In the continuous-signal, infinite-support limit the two conventions + +674 (interpolating current versus interpolating reference) are mathematically equivalent after + +675 their fitted parameters are converted to the same physical 𝛿𝑣/𝑣 through the exact relation + +676 𝛿𝑣/𝑣 = −𝜀/(1 + 𝜀). In sampled, finite-window signals, that symmetry is broken: interpolation + +677 error, edge truncation, and the finite support of the data cause the two conventions to give + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 4 +678 slightly different numerical results even when both use the exact conversion. Therefore the + +679 interpolation direction must be reported explicitly and treated as a fixed processing choice. + +680 For diffuse codas in ambient-noise and volcanic monitoring, we have verified that the choice + +681 has a measurable but small effect: truth-known synthetics recover 𝛿𝑣/𝑣 with sub-10−4 bias + +682 when the signal-to-noise ratio is high and the changes are small, with the effect growing as a + +683 few percent at landslide-scale perturbations (𝛿𝑣/𝑣 ∼ 4 %). + + +684 Windowed cross-correlation (WCC). In sub-windows centred at lapse 𝑡𝑖 the delay is + +685 𝛿𝑡𝑖 = arg max𝜏 ∫ 𝑐(𝑡) 𝑟(𝑡 − 𝜏 ) d𝑡; a least-squares fit of 𝛿𝑡𝑖 = −𝜀 𝑡𝑖 gives 𝜀. + + +686 Moving-window cross-spectrum (MWCS). In each sub-window the cross-spectrum is + +687 ̂ 𝑟∗̂ (𝑓) with phase 𝜑(𝑓) = arg 𝑋(𝑓) ≈ 2𝜋𝑓 𝛿𝑡𝑖 ; a coherence-weighted linear fit of + 𝑋(𝑓) = 𝑐(𝑓) + +688 𝜑(𝑓) over [𝑓1 , 𝑓2 ] yields 𝛿𝑡𝑖 , and 𝜀 is minus the slope of 𝛿𝑡𝑖 versus 𝑡𝑖 (Clarke et al., 2011). + +689 Because 𝜑 is defined modulo 2𝜋, the estimate cycle-skips once |𝛿𝑡𝑖 | > 1/(2𝑓). + + +690 Dynamic time warping (DTW). A lag path 𝑙(𝑖) minimises + + + 2 2 + ∑ (𝑐𝑖 − 𝑟𝑖+𝑙(𝑖) ) + 𝛾 ∑ (𝑙(𝑖+1) − 𝑙(𝑖)) , (A.2) + 𝑖 𝑖 + + +691 where 𝛾 penalises strain (limits the lag’s rate of change); 𝜀 is minus the slope of 𝑙(𝑖)/𝑓𝑠 versus + +692 lapse. + + +693 Wavelet cross-spectrum (WCS). With continuous wavelet transforms 𝑊𝑐 , 𝑊𝑟 , the cross- + +694 wavelet spectrum is 𝑊𝑥𝑦 (𝑓, 𝜏 ) = 𝑊𝑐 𝑊𝑟∗ and the delay 𝛿𝑡(𝑓, 𝜏 ) = 𝜑(𝑓, 𝜏 )/(2𝜋𝑓). Unwrapping + +695 𝜑 in two dimensions — along lapse (anchored at 𝜏 → 0, where 𝛿𝑡 → 0) then along frequency + +696 — removes the cycle-skip; 𝜀 follows from the |𝑊𝑥𝑦 |-weighted regression 𝛿𝑡 = −𝜀 𝜏 over the + +697 time–frequency window (Mao et al., 2020). + 44 M. A. Denolle +698 Wavelet stretching / warping (WTS, WTDTW). TS (respectively DTW) is applied + +699 per wavelet scale (respectively to the wavelet-reconstructed band) and the per-scale estimates + +700 are pooled with cross-wavelet-power weights. + + + + +701 APPENDIX B: AGGREGATION AND UNCERTAINTY CONVENTIONS + + +702 For component 𝑘 of a station pair, stretching yields the image CC𝑘 (𝜀, 𝑡); each per-component + +703 stretch factor converts to physical 𝛿𝑣/𝑣𝑘 via the boxed relation. + + +704 Approach A (average the per-component 𝛿𝑣/𝑣). 𝛿𝑣/𝑣𝑘 (𝑡) follows from 𝜀𝑘 (𝑡) = + +705 arg max𝜀 CC𝑘 (𝜀, 𝑡), and the pair estimate is the (possibly weighted) mean 𝑥𝑝 (𝑡) = + +706 ∑𝑘 𝑤𝑘 𝛿𝑣/𝑣𝑘 / ∑𝑘 𝑤𝑘 , with 𝑤𝑘 = max𝜀 CC𝑘 (coherence-weighted) or 𝑤𝑘 = 1 (unweighted). + + +707 Approach B (average the images). The pair stretch factor 𝜀𝑝 (𝑡) = arg max𝜀 [ 𝑁1 ∑𝑘 CC𝑘 (𝜀, 𝑡)] + 𝑐 + + +708 converts to 𝑥𝑝 (𝑡) = 𝛿𝑣/𝑣𝑝 (𝑡) via the same relation. + + +709 Network over pairs. With pair weights 𝑊𝑝 (e.g. mean coherence), + + ∑𝑝 𝑊𝑝 𝑥𝑝 ∑𝑝 𝑊𝑝 (𝑥𝑝 − 𝑥)̄ 2 (∑𝑝 𝑊𝑝 )2 + 𝑥̄ = , 2 + 𝑠 = , 𝑁eff = . (B.1) + ∑𝑝 𝑊𝑝 ∑𝑝 𝑊𝑝 ∑𝑝 𝑊𝑝2 + +710 The three uncertainty conventions used in Section~3.3 are the weighted standard error + √ +711 𝜎SE,𝑤 = 𝑠/√𝑁eff , the unweighted standard error 𝜎SE = std(𝑥𝑝 )/ 𝑁, and the standard + √ +712 deviation 𝜎SD = std(𝑥𝑝 ). They share the mean 𝑥̄ but obey 𝜎SD /𝜎SE = 𝑁. + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 4 +713 APPENDIX C: SURVEY OF PROCESSING CHOICES ACROSS THE + +714 LITERATURE + + +715 Table~A1 catalogues the processing choices of the 103 ambient-noise 𝛿𝑣/𝑣 monitoring studies + +716 we surveyed (the full machine-readable version and provenance are distributed with the + +717 codameter package). It is the empirical basis for the paper’s claim that no convention is + +718 shared: the estimator, the frequency band, the coda window, the reference scheme and + +719 — most unevenly of all — the uncertainty treatment vary study to study, and the last is + +720 frequently unreported. Every study is cited here. + + +721 The four measurement fields (frequency band, coda window, estimator and uncertainty + +722 treatment) were re-checked against the full text for the 82 studies we could read (open + +723 access plus institutional access); for those rows a blank or n/r'' means the value is + +724 genuinely not stated in the paper. The remaining rows were populated from + +725 abstracts and search metadata, wheren/r’ ’ means only that the value was not found + +726 in the abstract, not that the study failed to report it; those cells are flagged in the + +727 machine-readable table (measurement_source) and remain to be filled from the paywalled + +728 full texts. The apparent under-reporting in the table is therefore a lower bound on what the + +729 literature actually states. + + Table A1: Processing choices of the 103 surveyed 𝛿𝑣/𝑣 studies (the literature survey under- + pinning this paper). Every study is cited; n/r = not reported in the source. Frequency band, + coda window, estimator, reference/stack scheme and uncertainty treatment are the choices + Section 3 shows to control the result. + + Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + + Brenguier et al. Piton de la 0.1-0.9 n/r (slope MWCS Daily stacks linear-slope + (2008b) Fournaise, La of dtau vs (doublet) referenced to uncertainty; exclude + Réunion tau; short long-term stack >0.04% + scanning + window) + + continued on next page + 46 M. A. Denolle + Table A1 continued + Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + + Duputel et al. Piton de la 0.1–1 n/r Other Quasi-real-time n/r + (2009) Fournaise, La stacks vs reference + Réunion + Obermann et al. Piton de la 0.1-1.0 10-45 stretching Daily stacks, Weaver et al. + (2013) Fournaise, La referenced; coda coherence-based error + Réunion at increasing lapse formula + times + HotovecEllis Mount St. 1-10 (also windows doublet Stack across ~0.1% from SD of + et al. (2014) Helens, WA, 1-5, 5-10) after S (Snieder several hundred velocity fit + USA arrival; 2002) repeating- + >=5 with earthquake + CCC>0.65 families + (multiplets) + HotovecEllis Mount St. 0.5-10 15 s stretching Combines reduced similarity (CC) + et al. (2015) Helens, WA, window repeating- in stretching window + USA starting 2 earthquake CWI + s after with + first ambient-noise + motion interferometry + Rivet et al. Piton de la 0.25-2 n/r MWCS Daily stacks vs coherency + + (2015) Fournaise, La reference; linear-regression error + Réunion network-averaged + dv/v + De Plaen et al. Piton de la 0.1-1.0, 5-35 MWCS n/r coherency + + (2016) Fournaise, La 0.5-1.0, (both linear-regression error + Réunion 1.0-2.0, branches) QC + (method also 2.0-4.0 + re Kawah Ijen) + Donaldson et al. Kīlauea 0.33-1.0 30 s MWCS Daily NCFs weighted dt-t + (2017) summit, window, (doublet) stacked over 3-day regression; + Hawaii, USA min lag = moving window coherence>0.65, + intersta- err<0.1 s thresholds + tion dist / + 0.8 km/s + Takano et al. Izu-Oshima, 0.5-1, 1-2, -20 to MWCS Cross-correlations error bars from + (2017) Japan 2-4 +20 2012–2015, coherency + multiple bands + Lesage et al. Volcán de 0.125-2 10-80 stretching Daily empirical noise from + (2018) Colima, cross-correlations; AVV fluctuations + Mexico 2013 stack as (~0.05%) + reference + De Plaen et al. Mt. Etna, 1.0-2.0 5-35 MWCS Daily cross-coherence + + (2019) Italy autocorrelations, squared misfit; reject + (2013–2014) 2-day linear stack dt err>0.1 s or + coh<0.6 + Donaldson et al. Northern 0.1-0.4, per-band stretching n/r reject dv/v when + (2019) Volcanic Zone 0.4-1.0, 1-2, (suppl. + MWCS stretched-ref CC<0.4 + (Askja/Bárðar- 2-4, 4-16 Table S1) + bunga), + Iceland + Olivier et al. Kīlauea, 0.08-1.2 30 s MWCS n/r (passive image CCF-coherence-based + (2019) Hawaii, USA windows; interferometry, uncertainty + (2018 start = daily) + eruption) dist/700 + m/s + 30 + s + + continued on next page + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 4 + Table A1 continued + Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + + Yates et al. Whakaari / 0.1-1.0 16 s MWCS n/r QC (err<0.1 s, + (2019) White Island, moving coh>0.7); + New Zealand windows error-weighted mean + within + 20-80 s + Feng et al. Kīlauea, 3-8 [-2.8:-0.4] stretching Jan 2017–Jun absolute error from + (2020) Hawaii, USA and 2018 NCFs stretching CC + [0.4:2.8] + (=[- + 14Dt:2Dt],[2Dt:14Dt]) + HotovecEllis Kīlauea, n/r n/r CWIRE Coda Wave n/r + et al. (2022) Hawaii, USA (stretchingInterferometry + (2018 collapse) + damped with Repeating + LSQ) Earthquakes + (CWIRE), + per-cluster pairs + Köpfli et al. Mount St. n/a n/a n/a (no Long-term NCF n/a + (2024) Helens, WA, (wavefield dv/v; stacks; many dv/v + USA amplitude companion series on a + features, is Makus common grid + not dv/v) 2024) + Yates et al. Mt. Ruapehu, 0.25-2.5 min lag 5 CWT n/r slope SD from + (2024) New Zealand (wavelet s, length (cross- covariance; coherence + (2005–2009) 0.1-8.0) 20 cycles wavelet) weighting + (e.g. 5-25 + at 1 Hz) + Yukutake et al. Izu-Oshima, 0.1-0.9, 20-40 MWCS Long-term 1-2 sigma errors as + (2025) Japan 0.5-2.0, interferometry inversion weights + (2003–2020) 1.0-4.0 stacks, 2003–2020 + Schaff & Beroza 1989 Mw 6.9 n/r 1.4 s doublet Repeating- formal slope SE; CC + (2004) Loma Prieta (unfiltered) moving earthquake weighting + aftershock windows doublets; delays vs + zone, through pre-mainshock + California coda repeaters + (also Parkfield + repeaters) + Pacheco & Theory / n/r n/r Other n/r n/r (analytical kernel) + Snieder (2005) acoustic + diffusion + model + Rubinstein & 2004 M6 n/r n/a doublet Repeating- CC>0.8 and SNR>4:1 + Beroza (2005) Parkfield (direct-S (moving- earthquake QC + earthquake, delays, window travel-time delays + San Andreas not coda) CC) before vs after + fault, mainshock + California + Wegler & Sens- Mid-Niigata 2-100 (2 Hz 5-14 stretching Daily day-to-day fluctuation + Schönfelder (Chuetsu) high-pass) autocorrelations ~0.1%; CC>0.5 + (2007) earthquake vs ~two-week + source region, pre-event + Japan; F-Net reference; grid + station KZK search (10000 + (~24 km) trials, dv/v… + Brenguier et al. Parkfield, San 0.1–0.9 n/r Stretching 1550-day reference Averaged over 78 + (2008a) Andreas fault, vs overlapping receiver pairs plus + California, 5-day moving 5-day segments + USA windows; 30-day + time resolution + + continued on next page + 48 M. A. Denolle + Table A1 continued + Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + + Hadziioannou Laboratory 2.5 MHz 12.5-50 us stretching Noise-correlation analytic std of + et al. (2009) scattering gel ultrasonic (lab) + doublet stacking stretching-CC + (ultrasonic) (lab, not (compared) fluctuations + seismic + band) + Sawazaki et al. Western- n/r n/r Other Coda n/r + (2009) Tottori region, deconvolution of + Japan; surface vs 100-m + KiK-net borehole records + borehole + (surface + 100 + m); 2000 Mw + 6.6 mainshock + Wegler et al. 2004 Mw 6.6 2-8 and 5-14 (2-8 stretching Daily auto-/cross- SD over Green’s-tensor + (2009) Mid-Niigata 0.1-0.5 Hz); correlations components; R>0.5 + earthquake 10-100 inverted daily for + source region, (0.1-0.5 2 months pre/post; + Japan; 6 Hz) pre-event reference + Hi-net/F-Net + stations <25 + km + Chen et al. Sichuan, n/r ~25 s MWCS Noise n/r + (2010) China — 2008 after cross-correlation + Mw 7.9 ballistic, stacking; + Wenchuan up to sub-array + earthquake +-200 s comparison (156 + fault zone lapse broadband + stations) + Nakata & NE Japan 1-13 n/a n/a (not >300 earthquakes SD of travel times over + Snieder (2011) (Honshu), (deconvo- coda/noise (Jan 1–May 26 events + KiK-net; 2011 lution dv/v) 2011); borehole-to- + Tohoku-Oki interfer- surface + earthquake ometry, deconvolution + direct + S-wave) + Rivet etal. Guerrero, 0.037-0.27 n/r (coda doublet n/r previous-epoch + (2011) Mexico (periods used, no (MWCS) referencing; no explicit + subduction 3.7-27 s) length) error bars + zone (2006 + M7.5 slow slip + event) + Hobiger et al. 2008 0.125-0.25, ten stretching Daily CC weighting; + (2012) Iwate-Miyagi 0.25-0.5, periods, cross-correlations 18-component weighted + Nairiku 0.5-1.0 starting vs long-term average + earthquake 7.5 reference Green’s + (Mw 6.9), NE periods function + Japan after + direct + wave + Minato etal. Southern 2-5 2-10 lag stretching n/r SD from + (2012) Tohoku pre/post-seismic values + (Fukushima/Ibaraki), + Japan; 58 + Hi-net + stations; 2011 + Tohoku-Oki + Obermann et al. Numerical 2-D 20 Hz 1.5 s stretching Averaged over 10 std over ten + (2013) elastic media central, ~12 windows, random medium random-media + (lunar-data Hz bw centered realizations per realizations + illustration) (numerical) ~1.8-6.6 s configuration + + continued on next page + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 4 + Table A1 continued + Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + + Brenguier et al. Vol- 0.1–0.9 n/r MWCS Daily Stress sensitivity + (2014) canic/geother- cross-correlations; ~0.001 MPa^-1 + mal regions of linear inferred; detailed dv/v + Honshu, inversion/regular- uncertainty n/r + Japan; 2011 ization for + Mw 9.0 continuous time + Tohoku-Oki series + Liu et al. (2014) Epicentral 0.125-1 (1-8 30-130 MWCS Noise 2-sigma SD across nine + region of 2008 s; subbands cross-correlation components + Mw 7.9 1-2,2-4,4-8 stacking (Aug + Wenchuan s) 2004 – Sep 2011) + earthquake, + China + Taira et al. South Napa, 0.1-0.9 -60 to -20 MWCS MSNoise Jackknife 95% CI; + (2015) California and +20 cross-correlations; 2-sigma SD + (2014 Mw 6.0 to +60 decimated to 20 + South Napa Hz + earthquake) + Gassenmeier Station 1-3, 4-6, 10-15 (for stretching Daily Gaussian fit to + et al. (2016) PATCX, 7-10 4-6 Hz) (autocorre- autocorrelations; correlation values (CIs) + Atacama (primary lation two-step iterative + Desert, 4-6) CWI) reference + Northern + Chile (IPOC) + Hillers et al. San Jacinto 0.2-2 20-50 stretching Average-waveform P-value QC; cc>=0.85 + (2019) fault zone, (sub-bands (also and MWCS reference for inversion + California 0.2-0.4,0.4- 20-40,30- (doublet) stretching; MWCS + (after 2010 0.8,0.8- 50,40-60) also applied + M7.2 El 1.6,0.3-1.5) + Mayor- + Cucapah, + M5.4 Collins + Valley) + Wang et al. NE Honshu, period -400 to doublet Monthly SD error bars from + (2019) Japan (2011 bands 8-30 400 velocity-change 2009-2010 + Mw 9.0 s and 15-50 (moving estimates + Tohoku-Oki s 30 & 50 s) + earthquake) + Mao et al. Salton Sea 0.5-2.0, n/r (real wavelet Noise wavelet cross-spectrum + (2020) Geothermal 0.75-3.0, data); cross- cross-correlation amplitude weighting; + Field, 1.1-2.2, synthetic spectrum stacking coherence threshold + California 1.5-6.0, 18.65-35 (WCS) + (2009–2011) 2.0-8.0 + Poli et al. (2020) L’Aquila 0.5-1 start stretching n/r CC-weighting; cc>0.9 + region, central 10/20/30 (doublet retained + Italy (2009 s, length tested) + Mw 6.3 20/40/60 + L’Aquila s + earthquake) + Boschelli et al. Ridgecrest >1 (1 Hz n/r stretching Daily SD across + (2021) fault zone, high-pass) (variable autocorrelation non-overlapping + California lapse functions vs mean windows + (2019 Mw 7.1 window) waveform + Ridgecrest + earthquake) + Lu & Ben-Zion Ridgecrest, 8.0–12.0 3 (moving Other 10-min stacks; Standard deviations + (2021) California windows, adaptive Gaussian tracked; stabilized via + (2019 Mw 7.1 1.5 s step) smoothing (20 smoothing + Ridgecrest min growing to 24 + earthquake) hr over 3 days) + + continued on next page + 50 M. A. Denolle + Table A1 continued + Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + + Sheng et al. San Jacinto >1 n/r wavelet Weekly stacked dt uncertainty as + (2022) fault, Anza (WTS) correlations with inverse weight + seismic gap, ~2-month + Southern smoothing + California + Mainsant et al. Pont-Bourquin 10-12 0.2-2 stretching Daily noise Weaver et al. (2011) + (2012) landslide, (analyzed (both correlograms CC-based error + Swiss Alps 4-25) sides) (cross-correlation (~1-2%) + (Switzerland) functions) + Voisin et al. Avignonet / ~6-8 n/r Stretching Daily/seasonal Correlation-coefficient + (2016) Mas (annual stacks vs reference weighting; comparison + d’Avignonet dv/v with piezometer + landslide, pattern + Trièves best + (French Alps), resolved) + France + Harba & Pilecki Just- High- n/r (inter- Other Cross-correlation / Dispersion-inversion + (2016) Tęgoborze frequency ferometric interferometric misfit; comparison + landslide, seismic Green’s- stacks; dispersion with MASW + Carpathian noise function inversion + flysch, (~5-20+, retrieval) (neighbourhood + southern dispersion- algorithm) + Poland curve + range) + Bertello et al. Montaguto n/a (active- n/a n/a Time-lapse n/a + (2018) earthflow, source interferometry + + southern Italy ReMi/MASW time-lapse active + dispersion, MASW + not coda + dv/v) + Bièvre et al. Pont-Bourquin ~5-15 n/r Stretching Daily correlations, Correlation coefficient; + (2018) landslide, (surface- multi-year seasonal-cycle + Swiss Alps wave band; reference modeling to separate + (4.5-yr record) reported from precursors + sensitivity + to shallow + layer <=2 + m) + Colombero et al. Madonna del 2-20 0.5-2 (and Stretching Daily correlations, Correlation coefficient + (2018) Sasso cliff, (analysis); symmet- multi-year (~0.9 at low freq) as + NW Italian 2-4 ric -2 to reference reliability metric + Alps (Orta strongest -0.5) (2013-2016) + Lake), Italy annual + signal + Bontemps et al. Maca n/r n/r n/r Daily stacks vs n/r + (2020) slow-moving reference + Andean + landslide, + southern Peru + (3-yr dataset) + Fiolleau et al. Harmalière 1-12 (moni- 0.05-1.5 Stretching Hourly records, Correlation-coefficient + (2020) landslide, toring); daily averaging vs degradation tracked + French dv/v in 2-4 reference across bands; + Western Alps and 8-10 multi-parameter + (collapsed Nov bands; precursor timing + 2016) block + resonance + ~9-16 + + continued on next page + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 5 + Table A1 continued + Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + + Le Breton et al. Global review 1.3-20 end of stretching Daily stacks vs Weaver et al. (2011) + (2021) (9 landslides (commonly direct and long-term rms + SD over + monitored to 10-14; 0.1-1 waves to doublet reference pairs/windows; discard + date) for 5-10 (MWCS) CC<0.6 + large/deep) periods + (site- + dependent) + Xie et al. (2023) Rock slope, High- Sub- Stretching Short-window Decorrelation/CC + southwest frequency second to stacks for rapid checks; rapid-detection + China (~5-20) a few s detection confidence discussion + Liu et al. (2026) Xishan Village 5-25 (raw 0.4-2.0 Stretching 20-min interval 95% confidence interval + landslide, 1-30); 15 CCFs vs reference (~0.05% uncertainty at + Sichuan Hz top ~15 (SNR>4 5 Hz) + Province, m, 5 Hz wave-packet + China 15-40 m selection) + Watlet et al. Hollin Hill 6-10 (plus n/r MWCS Time-lapse none (data report) + (2026) Landslide two interferometry + + Observatory, unspecified MASW between + North bands) recording periods + Yorkshire, UK + (2-yr) + De Wit & Open-pit mine n/r (high- n/r Stretching Time-lapse stacks Decorrelation/CC; + Snieder (2026) slope, frequency vs reference comparison with radar + Australia near- surface deformation + surface) + Sens- Merapi 0.5 Hz 2-8 stretching Daily autocorr vs SD over + Schönfelder Volcano, high-pass yearly reference non-overlapping + & Wegler (2006) Indonesia windows + Tsai (2011) Theoretical n/a (theory n/a n/a n/r n/a + model, applied of thermoe- (analytic + to southern lastic/hy- model, no + California drologic measure- + velocity ment) + change) + Hillers et al. TCDP n/r n/r n/r n/r n/r + (2014) borehole array, + Chelungpu + fault, Taiwan + Lecocq et al. Gräfenberg 0.1-0.8 20-100 MWCS Daily CCFs, LSQ slope error as + (2017) Array (and -20 (Brenguier 31-day rolling inverse-variance weight; + (GRA1-4), SE to -100) all-pairs) window bootstrap + Germany + (karst + limestone + aquifer) + Nimiya et al. Kyushu Island, 0.1-0.9 100 stretching Daily CCFs from SD over six 50-s + (2017) Japan (2016 (+MWCS 30-min segments; subwindows + Kumamoto check) 1-yr reference, + region) 30-day moving + stack + Wang et al. Japan 0.1-0.25 30 s MWCS Daily CCFs; ~1-yr none (QC only: + (2017) (nationwide; and 0.5-2.0 (0.1-0.25 reference, dt<=0.2 s, coh>=0.5) + strongest in Hz), 10 s moving-window + Kyushu/vol- (0.5-2 Hz) current stack + canic + zones) + Clements & De- San Gabriel 0.1-0.25 30 s MWCS Daily stacks vs none (QC only: + nolle (2018) Valley, and 0.5-2.0 (0.1-0.25 reference dt<=0.2 s, coh>=0.5) + California, Hz), 10 s + USA (0.5-2 Hz) + + continued on next page + 52 M. A. Denolle + Table A1 continued + Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + + Kim & Lekic Gulf Coast 0.01-8 n/r stretching Multi-year (~20 none (grid-search CC + (2019) Aquifer, yr) record; max) + southern yearly-scale + Texas comparisons + (IU.HKT near + Houston), + USA + Andajani et al. Chugoku & 0.1-0.9 100 stretching n/r stretching CC as + (2020) Shikoku, SW quality indicator (no + Japan (Hi-net) error bars) + GaubertBastide Crépieux- 2-5 n/a stretching Hourly eps_max +- sigma + et al. (2022) Charmy (ballistic correlations over (stretching variance) + water- Love- 19 days, two + production wave fill/drain cycles + field, Lyon, window, + France not coda) + Illien et al. Nepal 4-8 12 stretching ~3-yr continuous none (multi-reference + (2022) Himalaya (Chaku); periods time series stack) + (2015 Mw7.8 2-4 (~3 s) + Gorkha (Gumba) after + aftermath) 4-period + skip + Mao et al. Coastal Los 2-4 2-8 stretching Daily CCFs cc^2-weighted channel + (2022) Angeles basins, stacked over 20 mean (no explicit error + California, days, 5-day step; bars) + USA pairs <50 km + Clements & De- Statewide 2-4 2-8 stretching Daily stacks across cc^2-weighted channel + nolle (2023) California, ~700 stations vs mean (no explicit error + USA reference bars) + (1999-2021) + Delouche & Greece 0.33-1 (1-3 15-55 stretching n/r Weaver et al. (2011) + Stehly (2023) (aquifer s period) RMS error + monitoring + sites) + Ermert et al. Mexico City 0.5-1, 1-2, 4-10x and stretching Clustered (GMM) CC_best>0.6 QC; no + (2023) basin / Valley 2-4, 4-8 8-20x autocorrelation formal dv/v error + of Mexico longest stacks + period + (e.g. 8-16 + & 16-40 + s) + Fokker et al. Groningen, 1.3-1.6 n/r (coda stretching n/r standard error + (2023) The of cross- sigma/sqrt(n) + Netherlands coherence) + Zhang et al. Central 0.1-1.0 n/r MWCS Continuous SD (avg ~0.009%) + (2023) Oklahoma, (also (dynamic 2013-2022 record + USA 0.3-1.2, windows, + 0.5-1.5, 3.0 & 2.0 + 1.0-2.0) km/s) + Mao etal. Greater Los 0.1-0.3 300 s stretching Daily CCFs Weaver et al. (2011) + (2025) Angeles, window stacked, multi-day error formula + California, from step; two-decade + USA 1.3*t0 record + Mordret et al. Southwest 0.1-0.3 300 s stretching Daily Weaver et al. (2011) + (2016) Greenland ice window cross-correlations error formula + sheet from over ~2-year + 1.3*t0 record + + continued on next page + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 5 + Table A1 continued + Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + + James et al. Interior 3-30 (18 +-0.2 to MWCS Daily 95% CI from posterior + (2019) Alaska (Poker bands; 13 2.0 cross-correlations + Flat / Hz (center stacked; reference + Fairbanks inversion) lag) relative to Jan + area), USA 2014 + Guillemot et al. Gugla rock n/a n/a n/a (no Daily n/a + (2020) glacier, Valais, (resonance- dv/v correlograms from + Switzerland freq computed) hourly raw data + tracking, + not dv/v) + Guillemot et al. Laurichard n/a n/a n/a (no PSD-based; n/a + (2021) (French Alps) (resonance- dv/v finite-element + and Gugla freq computed) modal modeling + (Swiss Alps) tracking, + rock glaciers not dv/v) + Lindner et al. Mt. Zugspitze, 2-8 -5 to 5 lag wavelet 15-year continuous 1 SD + (2021) German/Aus- (analysis cross- record; + trian 1-20) spectrum daily/seasonal + Alps (Morlet) stacks + Luo et al. (2023) Greenland Ice 0.1-1 (also 20-70 MWCS Daily fitted +-sigma; 95% CI + Sheet (GLISN 0.1-0.5, autocorrelations + stations) 1-2) stacked + Gassenmeier Ketzin CO2 1.5-3 moving stretching 1-hour segments Weaver et al. (2011); + et al. (2014) storage site windows cross-correlated, scaling-coeff CIs + (CO2SINK), after 300 stacked to daily + Brandenburg, m/s + Germany phase + Hillers et al. Basel deep n/r Coda of Stretching Daily noise Sensitivity-kernel + (2015) geothermal noise cor- correlations imaging of + (EGS) relations around 2006 velocity-change + reservoir, stimulation location + Switzerland + Obermann et al. St. Gallen 0.1-1 20 s stretching Daily none + (2015) geothermal window cross-correlations; + site, centered reference stacks + Switzerland ~15 s in + coda + Czarny et al. Underground 0.6-1.2 n/r Stretching Continuous n/r + (2016) coal mine, cross-correlations + Upper Silesia, over ~42 days + Poland + Olivier et al. Active tailings 0.25-1.0, 20 s (-40 MWCS Daily two-sigma SD; + (2017) storage facility 0.5-2.0, to -20 and (MSNoise) cross-correlations CC>0.85 rejection + (mine), South 0.75-3.0, 20 to 40) across array + Africa 1.0-4.0, + 1.5-6.0, + 2.0-8.0 + Taira et al. Salton Sea 0.25-1.0, 20 s (-40 MWCS Daily NCFs from two-sigma SD; + (2018) Geothermal 0.5-2.0, to -20 and (MSNoise) 30-min segments; CC>0.85 rejection + Field, 0.75-3.0, 20 to 40) 5-day stacks + California, 1.0-4.0, + USA 1.5-6.0, + 2.0-8.0 + Kristjánsdóttir Hellisheidi n/r n/r Stretching Daily correlations Seasonal and + et al. (2019) geothermal (MSNoise noise-source effects + field, SW workflow) discussed as caveats + Iceland + + continued on next page + 54 M. A. Denolle + Table A1 continued + Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + + Snieder et al. theory + n/a (disper- n/a n/a (not a n/r n/a + (2002) ultrasonic lab sion/pre- velocity- + processing change + paper, no study) + dv/v) + Bensen et al. USArray test 0.1-0.9 6s MWCS daily WLS phase-fit error + (2007) data windows cross-correlation + (corrected ~6x) + overlap- temporal stacking + ping 3 + s + Clarke et al. synthetic + 0.1-0.9 6s MWCS current stack vs WLS phase-fit error + (2011) real noise tests windows reference, (corrected ~6x) + overlap- weighted linear + ping 3 regression dt vs t + s + Hadziioannou urban noise 0.1-0.9 n/r stretching waveform remnant coherence + et al. (2011) autocorrela- (whole (and clustering to (CC) + tions coda doublet) enhance daily + t1-t2) stacks + Weaver et al. theory 0.05-0.5 up to stretching reference vs max CC>0.9 (no + (2011) t0=30 current correlation formal error) + Zhan et al. synthetic + 0.05-0.5 up to stretching reference vs max CC>0.9 (no + (2013) field examples t0=30 current formal error) + Lecocq et al. Piton de la synthetic 1-10 windowed daily CCF + WLS lag-vs-lapse; + (2014) Fournaise (Ricker lapse; sub- CC, reference stack CC>=0.6 + (validation) 12.5; noise windows stretching, + 0.5-30) 0.1-1.0 s DTW + (compared) + Mikesell et al. numerical 0.33-1.0 (dist/1.8)+20 + stretching n/a Weaver et al. (2011) + (2015) CWI examples (1-3 s) to 120 rms formula + Stehly et al. Wenchuan Mw 0.1-1.0 [15,35] stretching daily correlations CC>0.7 rejection; + (2015) 7.9 region (real); and (+MWCS curvelet-filtered ~+-0.1% significance + (test dataset) 0.15-0.65 [-35,-15] compare) before stacking + (synthetic) + Daskalakis et al. synthetic + n/r 1 s over- stretching normalized SD over 20 receivers + (2016) real noise (numerical lapping cross-correlation + study) windows functions + Obermann et al. 3-D wavefield 0.15-0.90 -60 to doublet + n/a Bayesian least-squares + (2016) simulations +60 Bayesian inversion; error bars + (doublet least- from inversion + over squares + coda) inversion + (Brenguier + 2014) + Obermann & review scale- lapse- Other reference and synthesizes error + Hillers (2019) dependent time/depth moving-stack sources: noise-source + depen- strategies reviewed variability, processing + dent choices, sensitivity + ker… + Jiang & Denolle benchmark vs user- user- Other linear/PWS/ro- offers multiple dv/v + (2020) MSNoise defined defined bust stacking; estimators so users can + reference + cross-check; + moving stacks parallel/HDF5 + reproducible pip… + Wang & Yao review n/r n/r stretching, reference and Bayesian least-squares + (2020) (review) (review) MWCS, stacking strategies / MCMC (review) + DTW, reviewed + WCS + (review) + + continued on next page + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 5 + Table A1 continued + Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + + Yuan et al. 2-D varies (e.g. 45-75 WCC, TS, n/a residuals vs truth over + (2021) heterogeneous 0.5-2.2) (example) DTW, realizations + half-space MWCS, + simulations WCS, + WTS, + WTDTW + (7 + compared) + + + + +730 DATA AVAILABILITY + + +731 All synthetics, estimators, and figures in this paper are implemented in the open-source + +732 Python package codameter (version 0.4.0, MIT license), openly available at https://github.c + +733 om/Denolle-Lab/codameter. A versioned archive with a Zenodo DOI will be issued alongside + +734 publication. + + + + +735 Acknowledgements + + +736 [To be completed.] + + + + +737 References + + +738 Andajani, R. D., Tsuji, T., Snieder, R., & Ikeda, T., 2020. Spatial and temporal influence + +739 of rainfall on crustal pore pressure based on seismic velocity monitoring, Earth, Planets + +740 and Space, 72, doi: 10.1186/s40623-020-01311-1. + + +741 Bensen, G. D., Ritzwoller, M. H., Barmin, M. P., Levshin, A. L., Lin, F., Moschetti, M. P., + +742 Shapiro, N. M., & Yang, Y., 2007. Processing seismic ambient noise data to obtain reliable + 56 M. A. Denolle +743 broad-band surface wave dispersion measurements, Geophysical Journal International, + +744 169(3), 1239–1260, doi: 10.1111/j.1365-246X.2007.03374.x. + + +745 Bertello, L., Berti, M., Castellaro, S., & Squarzoni, G., 2018. Dynamics of an active earthflow + +746 inferred from surface wave monitoring, Journal of Geophysical Research: Earth Surface, + +747 123, 1811–1834, doi: 10.1029/2017jf004233. + + +748 Bièvre, G., Franz, M., Larose, E., Carrière, S., Jongmans, D., & Jaboyedoff, M., 2018. + +749 Influence of environmental parameters on the seismic velocity changes in a clayey mud- + +750 flow (pont-bourquin landslide, switzerland), Engineering Geology, 245, 248–257, doi: + +751 10.1016/j.enggeo.2018.08.013. + + +752 Bontemps, N., Lacroix, P., Larose, E., Jara, J., & Taipe, E., 2020. Rain and small earthquakes + +753 maintain a slow-moving landslide in a persistent critical state, Nature Communications, + +754 11, doi: 10.1038/s41467-020-14445-3. + + +755 Boschelli, J., Moschetti, M. P., & SensSchönfelder, C., 2021. Temporal seismic velocity + +756 variations: Recovery following from the 2019 mw 7.1 ridgecrest, california earthquake, + +757 Journal of Geophysical Research: Solid Earth, 126, doi: 10.1029/2020jb021465. + + +758 Brenguier, F., Campillo, M., Hadziioannou, C., Shapiro, N. M., Nadeau, R. M., & Larose, + +759 E., 2008a. Postseismic relaxation along the san andreas fault at parkfield from continuous + +760 seismological observations, Science, 321, 1478–1481, doi: 10.1126/science.1160943. + + +761 Brenguier, F., Shapiro, N. M., Campillo, M., Ferrazzini, V., Duputel, Z., Coutant, O., & + +762 Nercessian, A., 2008b. Towards forecasting volcanic eruptions using seismic noise, Nature + +763 Geoscience, 1, 126–130, doi: 10.1038/ngeo104. + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 5 +764 Brenguier, F., Campillo, M., Takeda, T., Aoki, Y., Shapiro, N. M., Briand, X., Emoto, K., + +765 & Miyake, H., 2014. Mapping pressurized volcanic fluids from induced crustal seismic + +766 velocity drops, Science, 345(6192), 80–82, doi: 10.1126/science.1254073. + + +767 Chen, J. H., Froment, B., Liu, Q. Y., & Campillo, M., 2010. Distribution of seismic wave + +768 speed changes associated with the 12 may 2008 mw 7.9 wenchuan earthquake, Geophysical + +769 Research Letters, 37, doi: 10.1029/2010gl044582. + + +770 Clarke, D., Zaccarelli, L., Shapiro, N. M., & Brenguier, F., 2011. Assessment of resolution + +771 and accuracy of the moving window cross spectral technique for monitoring crustal temporal + +772 variations using ambient seismic noise, Geophysical Journal International, 186(2), 867–882, + +773 doi: 10.1111/j.1365-246X.2011.05074.x. + + +774 Clements, T. & Denolle, M. A., 2018. Tracking groundwater levels using the ambient seismic + +775 field, Geophysical Research Letters, 45(13), 6459–6465, doi: 10.1029/2018GL077706. + + +776 Clements, T. & Denolle, M. A., 2023. The seismic signature of california’s earth- + +777 quakes, droughts, and floods, Journal of Geophysical Research: Solid Earth, 128, doi: + +778 10.1029/2022jb025553. + + +779 Colombero, C., Baillet, L., Comina, C., Jongmans, D., Larose, E., Valentin, J., & Vinciguerra, + +780 S., 2018. Integration of ambient seismic noise monitoring, displacement and meteorological + +781 measurements to infer the temperature-controlled long-term evolution of a complex prone- + +782 to-fall cliff, Geophysical Journal International, 213, 1876–1897, doi: 10.1093/gji/ggy090. + + +783 Cubuk-Sabuncu, Y., Jónsdóttir, K., Caudron, C., Lecocq, T., Parks, M., Geirsson, H., & + +784 Mordret, A., 2021. Temporal seismic velocity changes during the 2020 rapid inflation at + 58 M. A. Denolle +785 mt. þorbjörn-svartsengi, iceland, using seismic ambient noise, Geophysical Research Letters, + +786 48, e2020GL092265, doi: 10.1029/2020GL092265. + + +787 Czarny, R., Marcak, H., Nakata, N., Pilecki, Z., & Isakow, Z., 2016. Monitoring veloc- + +788 ity changes caused by underground coal mining using seismic noise, Pure and Applied + +789 Geophysics, 173, 1907–1916, doi: 10.1007/s00024-015-1234-3. + + +790 Daskalakis, E., Evangelidis, C., Garnier, J., Melis, N., Papanicolaou, G., & Tsogka, C., 2016. + +791 Robust seismic velocity change estimation using ambient noise recordings, Geophysical + +792 Journal International, 205, 1926–1936, doi: 10.1093/gji/ggw142. + + +793 De Plaen, R. S. M., Lecocq, T., Caudron, C., Ferrazzini, V., & Francis, O., 2016. Singlestation + +794 monitoring of volcanoes using seismic ambient noise, Geophysical Research Letters, 43, + +795 8511–8518, doi: 10.1002/2016gl070078. + + +796 De Plaen, R. S. M., Cannata, A., Cannavo’, F., Caudron, C., Lecocq, T., & Francis, + +797 O., 2019. Temporal changes of seismic velocity caused by volcanic activity at mt. etna + +798 revealed by the autocorrelation of ambient seismic noise, Frontiers in Earth Science, 6, + +799 doi: 10.3389/feart.2018.00251. + + +800 De Wit, T. & Snieder, R., 2026. Did they blow it? time-lapse velocity variations dur- + +801 ing an open-pit mine slope failure using seismic noise interferometry, Seismica, 5, doi: + +802 10.26443/seismica.v5i1.1902. + + +803 Delouche, E. & Stehly, L., 2023. Seasonal seismic velocity variations measured using seismic + +804 noise autocorrelations to monitor the dynamic of aquifers in greece, Journal of Geophysical + +805 Research: Solid Earth, 128, doi: 10.1029/2023jb026759. + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 5 +806 Denolle, M. A., Shi, Q., Clements, T., Viens, L., Rodriguez-Tribaldos, V., & Cotton, F., + +807 2025. Ambient field seismology in critical zone hydrological sciences, Comptes Rendus. + +808 Géoscience, 357, 425–451, doi: 10.5802/crgeos.310. + + +809 Donaldson, C., Caudron, C., Green, R. G., Thelen, W. A., & White, R. S., 2017. Relative + +810 seismic velocity variations correlate with deformation at kīlauea volcano, Science Advances, + +811 3, doi: 10.1126/sciadv.1700219. + + +812 Donaldson, C., Winder, T., Caudron, C., & White, R. S., 2019. Crustal seismic velocity + +813 responds to a magmatic intrusion and seasonal loading in icelands northern volcanic zone, + +814 Science Advances, 5, doi: 10.1126/sciadv.aax6642. + + +815 Duputel, Z., Ferrazzini, V., Brenguier, F., Shapiro, N., Campillo, M., & Nercessian, A., + +816 2009. Real time monitoring of relative velocity changes using ambient seismic noise at + +817 the piton de la fournaise volcano (la réunion) from january 2006 to june 2007, Journal of + +818 Volcanology and Geothermal Research, 184, 164–173, doi: 10.1016/j.jvolgeores.2008.11.024. + + +819 Ermert, L. A., Cabral-Cano, E., Chaussard, E., Solano-Rojas, D., Quintanar, L., + +820 Morales Padilla, D., Fernández-Torres, E. A., & Denolle, M. A., 2023. Probing envi- + +821 ronmental and tectonic changes underneath mexico city with the urban seismic field, Solid + +822 Earth, 14, 529–549, doi: 10.5194/se-14-529-2023. + + +823 Feng, K.-F., Huang, H.-H., & Wu, Y.-M., 2020. Detecting pre-eruptive magmatic processes + +824 of the 2018 eruption at kilauea, hawaii volcano with ambient noise interferometry, Earth, + +825 Planets and Space, 72, doi: 10.1186/s40623-020-01199-x. + + +826 Fiolleau, S., Jongmans, D., Bièvre, G., Chambon, G., Baillet, L., & Vial, B., 2020. Seismic + 60 M. A. Denolle +827 characterization of a clay-block rupture in harmalière landslide, french western alps, + +828 Geophysical Journal International, 221, 1777–1788, doi: 10.1093/gji/ggaa050. + + +829 Fokker, E., Ruigrok, E., Hawkins, R., & Trampert, J., 2023. 4d physicsbased pore pressure + +830 monitoring using passive image interferometry, Geophysical Research Letters, 50, doi: + +831 10.1029/2022gl101254. + + +832 Gassenmeier, M., Sens-Schönfelder, C., Delatre, M., & Korn, M., 2014. Monitoring of + +833 environmental influences on seismic velocity at the geological storage site for co2 in ketzin + +834 (germany) with ambient seismic noise, Geophysical Journal International, 200, 524–533, + +835 doi: 10.1093/gji/ggu413. + + +836 Gassenmeier, M., Sens-Schönfelder, C., Eulenfeld, T., Bartsch, M., Victor, P., Tilmann, F., + +837 & Korn, M., 2016. Field observations of seismic velocity changes caused by shaking-induced + +838 damage and healing due to mesoscopic nonlinearity, Geophysical Journal International, + +839 204, 1490–1502, doi: 10.1093/gji/ggv529. + + +840 Gassmann, F., 1951. Über die elastizität poröser medien, Vierteljahrsschrift der Natur- + +841 forschenden Gesellschaft in Zürich, 96, 1–23. + + +842 GaubertBastide, T., Garambois, S., Bordes, C., Voisin, C., Oxarango, L., Brito, D., & + +843 Roux, P., 2022. Highresolution monitoring of controlled water table variations from dense + +844 seismicnoise acquisitions, Water Resources Research, 58, doi: 10.1029/2021wr030680. + + +845 Gelman, A. & Loken, E., 2013. The garden of forking paths, Department of Statistics, + +846 Columbia University (working paper). + + +847 Guillemot, A., Helmstetter, A., Larose, É., Baillet, L., Garambois, S., Mayoraz, R., & + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 6 +848 Delaloye, R., 2020. Seismic monitoring in the gugla rock glacier (switzerland): ambient + +849 noise correlation, microseismicity and modelling, Geophysical Journal International, 221, + +850 1719–1735, doi: 10.1093/gji/ggaa097. + + +851 Guillemot, A., Baillet, L., Garambois, S., Bodin, X., Helmstetter, A., Mayoraz, R., & Larose, + +852 E., 2021. Modal sensitivity of rock glaciers to elastic changes from spectral seismic noise + +853 monitoring and modeling, The Cryosphere, 15, 501–529, doi: 10.5194/tc-15-501-2021. + + +854 Hadziioannou, C., Larose, E., Coutant, O., Roux, P., & Campillo, M., 2009. Stability of + +855 monitoring weak changes in multiply scattering media with ambient noise correlation: + +856 Laboratory experiments, The Journal of the Acoustical Society of America, 125, 3688–3695, + +857 doi: 10.1121/1.3125345. + + +858 Hadziioannou, C., Larose, E., Baig, A., Roux, P., & Campillo, M., 2011. Improving temporal + +859 resolution in ambient noise monitoring of seismic wave speed, Journal of Geophysical + +860 Research: Solid Earth, 116(B7), B07304, doi: 10.1029/2011JB008200. + + +861 Harba, P. & Pilecki, Z., 2016. Assessment of timespatial changes of shear wave velocities + +862 of flysch formation prone to mass movements by seismic interferometry with the use of + +863 ambient noise, Landslides, 14, 1225–1233, doi: 10.1007/s10346-016-0779-2. + + +864 Hennino, R., Trégourès, N., Shapiro, N. M., Margerin, L., Campillo, M., van Tiggelen, B. A., + +865 & Weaver, R. L., 2001. Observation of equipartition of seismic waves, Physical Review + +866 Letters, 86, 3447–3450, doi: 10.1103/PhysRevLett.86.3447. + + +867 Hillers, G., Campillo, M., & Ma, K.-F., 2014. Seismic velocity variations at tcdp are + +868 controlled by mjo driven precipitation pattern and high fluid discharge properties, Earth + +869 and Planetary Science Letters, 391, 121–127, doi: 10.1016/j.epsl.2014.01.040. + 62 M. A. Denolle +870 Hillers, G., Husen, S., Obermann, A., Planès, T., Larose, E., & Campillo, M., 2015. Noise- + +871 based monitoring and imaging of aseismic transient deformation induced by the 2006 basel + +872 reservoir stimulation, Geophysics, 80, KS51–KS68, doi: 10.1190/geo2014-0455.1. + + +873 Hillers, G., Campillo, M., Brenguier, F., Moreau, L., Agnew, D. C., & BenZion, Y., 2019. + +874 Seismic velocity change patterns along the san jacinto fault zone following the 2010 m7.2 + +875 el mayorcucapah and m5.4 collins valley earthquakes, Journal of Geophysical Research: + +876 Solid Earth, 124, 7171–7192, doi: 10.1029/2018jb017143. + + +877 Hobiger, M., Wegler, U., Shiomi, K., & Nakahara, H., 2012. Coseismic and postseismic + +878 elastic wave velocity variations caused by the 2008 iwatemiyagi nairiku earthquake, japan, + +879 Journal of Geophysical Research: Solid Earth, 117, doi: 10.1029/2012jb009402. + + +880 HotovecEllis, A. J., Gomberg, J., Vidale, J. E., & Creager, K. C., 2014. A continuous + +881 record of intereruption velocity change at mount st. helens from coda wave interferometry, + +882 Journal of Geophysical Research: Solid Earth, 119, 2199–2214, doi: 10.1002/2013jb010742. + + +883 HotovecEllis, A. J., Vidale, J. E., Gomberg, J., Thelen, W., & Moran, S. C., 2015. Changes + +884 in seismic velocity during the first 14 months of the 20042008 eruption of mount st. + +885 helens, washington, Journal of Geophysical Research: Solid Earth, 120, 6226–6240, doi: + +886 10.1002/2015jb012101. + + +887 HotovecEllis, A. J., Shiro, B. R., Shelly, D. R., Anderson, K. R., Haney, M. M., Thelen, + +888 W. A., MontgomeryBrown, E. K., & Johanson, I. A., 2022. Earthquakederived seismic + +889 velocity changes during the 2018 caldera collapse of kīlauea volcano, Journal of Geophysical + +890 Research: Solid Earth, 127, doi: 10.1029/2021jb023324. + + +891 Illien, L., SensSchönfelder, C., Andermann, C., Marc, O., Cook, K. L., Adhikari, L. B., + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 6 +892 & Hovius, N., 2022. Seismic velocity recovery in the subsurface: Transient damage and + +893 groundwater drainage following the 2015 gorkha earthquake, nepal, Journal of Geophysical + +894 Research: Solid Earth, 127, doi: 10.1029/2021jb023402. + + +895 James, S. R., Knox, H. A., Abbott, R. E., & Screaton, E. J., 2017. Improved moving window + +896 cross-spectral analysis for resolving large temporal seismic velocity changes in permafrost, + +897 Geophysical Research Letters, 44(9), 4018–4026, doi: 10.1002/2016GL072468. + + +898 James, S. R., Knox, H. A., Abbott, R. E., Panning, M. P., & Screaton, E. J., 2019. Insights + +899 into permafrost and seasonal activelayer dynamics from ambient seismic noise monitoring, + +900 Journal of Geophysical Research: Earth Surface, 124, 1798–1816, doi: 10.1029/2019jf005051. + + +901 Jiang, C. & Denolle, M. A., 2020. NoisePy: a new high-performance python tool + +902 for ambient-noise seismology, Seismological Research Letters, 91(3), 1853–1866, doi: + +903 10.1785/0220190364. + + +904 Kidiwela, M., Denolle, M. A., Wilcock, W. S. D., & Feng, K. F., 2026. Active protothrusts + +905 and fluid highways: Seismic noise reveals hidden subduction dynamics in cascadia, Science + +906 Advances, 12(9), eaea3684, doi: 10.1126/sciadv.aea3684. + + +907 Kim, D. & Lekic, V., 2019. Groundwater variations from autocorrelation and receiver + +908 functions, Geophysical Research Letters, 46, 13722–13729, doi: 10.1029/2019gl084719. + + +909 Köpfli, M., Denolle, M. A., Thelen, W. A., Makus, P., & Malone, S. D., 2024. Examining + +910 22 years of ambient seismic wavefield at mount st. helens, Seismological Research Letters, + +911 95, 2622–2636, doi: 10.1785/0220240079. + + +912 Kristjánsdóttir et al., 2019. https://ui.adsabs.harvard.edu/abs/2019EGUGA..2118643K/ + 64 M. A. Denolle +913 abstract, dv/v monitoring study (Geothermal wastewater reinjection (water-volume / + +914 pore-pressure increase)). + + +915 Le Breton, M., Bontemps, N., Guillemot, A., Baillet, L., & Larose, É., 2021. Landslide + +916 monitoring using seismic ambient noise correlation: challenges and applications, Earth- + +917 Science Reviews, 216, 103518, doi: 10.1016/j.earscirev.2021.103518. + + +918 Lecocq, T., Caudron, C., & Brenguier, F., 2014. MSNoise, a Python package for monitoring + +919 seismic velocity changes using ambient seismic noise, Seismological Research Letters, 85(3), + +920 715–726, doi: 10.1785/0220130073. + + +921 Lecocq, T., Longuevergne, L., Pedersen, H. A., Brenguier, F., & Stammler, K., 2017. + +922 Monitoring ground water storage at mesoscale using seismic noise: 30 years of continuous + +923 observation and thermo-elastic and hydrological modeling, Scientific Reports, 7, doi: + +924 10.1038/s41598-017-14468-9. + + +925 Lesage, P., Carrara, A., Pinel, V., & Arámbula-Mendoza, R., 2018. Absence of detectable + +926 precursory deformation and velocity variation before the large dome collapse of july 2015 + +927 at volcán de colima, mexico, Frontiers in Earth Science, 6, doi: 10.3389/feart.2018.00093. + + +928 Lin, F.-C., Moschetti, M. P., & Ritzwoller, M. H., 2008. Surface wave tomography of + +929 the western United States from ambient seismic noise: Rayleigh and Love wave phase + +930 velocity maps, Geophysical Journal International, 173(1), 281–298, doi: 10.1111/j.1365- + +931 246X.2008.03720.x. + + +932 Lindner, F., Wassermann, J., & Igel, H., 2021. Seasonal freezethaw cycles and permafrost + +933 degradation on mt. zugspitze (german/austrian alps) revealed by singlestation seismic + +934 monitoring, Geophysical Research Letters, 48, doi: 10.1029/2021gl094659. + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 6 +935 Liu, Z., Huang, J., Peng, Z., & Su, J., 2014. Seismic velocity changes in the epicentral region + +936 of the 2008 wenchuan earthquake measured from threecomponent ambient noise correlation + +937 techniques, Geophysical Research Letters, 41, 37–42, doi: 10.1002/2013gl058682. + + +938 Liu, Z., Li, H., Liang, C., Zhang, T., Jiang, H., & Huang, H., 2026. Enhanced visualization + +939 of rainfall infiltration in landslides using high-resolution 4-d noise-based velocity change + +940 imaging, Geophysical Journal International, 245, doi: 10.1093/gji/ggag037. + + +941 Lobkis, O. I. & Weaver, R. L., 2003. Coda-wave interferometry in finite solids: Recovery + +942 of P-to-S conversion rates in an elastodynamic billiard, Physical Review Letters, 90(25), + +943 254302, doi: 10.1103/PhysRevLett.90.254302. + + +944 Lu, Y. & Ben-Zion, Y., 2021. Regional seismic velocity changes following the 2019 mw 7.1 + +945 ridgecrest, california earthquake from autocorrelations and p/s converted waves, Geophysical + +946 Journal International, 228, 620–630, doi: 10.1093/gji/ggab350. + + +947 Luo, B., Zhang, S., & Zhu, H., 2023. Monitoring seasonal fluctuation and longterm trends + +948 for the greenland ice sheet using seismic noise autocorrelations, Geophysical Research + +949 Letters, 50, doi: 10.1029/2022gl102146. + + +950 Mainsant, G., Larose, E., Brönnimann, C., Jongmans, D., Michoud, C., & Jaboyedoff, M., + +951 2012. Ambient seismic noise monitoring of a clay landslide: Toward failure prediction, + +952 Journal of Geophysical Research: Earth Surface, 117, doi: 10.1029/2011jf002159. + + +953 Mao, S., Campillo, M., van der Hilst, R. D., Brenguier, F., Stehly, L., & Hillers, G., 2019. + +954 High temporal resolution monitoring of small variations in crustal strain by dense seismic + +955 arrays, Geophysical Research Letters, 46(1), 128–137, doi: 10.1029/2018GL079944. + 66 M. A. Denolle +956 Mao, S., Mordret, A., Campillo, M., Fang, H., & van der Hilst, R. D., 2020. On + +957 the measurement of seismic traveltime changes in the time–frequency domain with + +958 wavelet cross-spectrum analysis, Geophysical Journal International, 221(1), 550–568, + +959 doi: 10.1093/gji/ggz495. + + +960 Mao, S., Lecointre, A., van der Hilst, R. D., & Campillo, M., 2022. Space-time monitoring + +961 of groundwater fluctuations with passive seismic interferometry, Nature Communications, + +962 13, doi: 10.1038/s41467-022-32194-3. + + +963 Mao, S., Ellsworth, W. L., Zheng, Y., & Beroza, G. C., 2025. Depth-dependent seismic + +964 sensing of groundwater recovery from the atmospheric-river storms of 2023, Science, 387, + +965 758–763, doi: 10.1126/science.adr6139. + + +966 Margerin, L., Campillo, M., & Van Tiggelen, B., 1998. Radiative transfer and diffusion of + +967 waves in a layered medium: new insight into coda q, Geophysical Journal International, + +968 134(2), 596–612, doi: 10.1046/j.1365-246x.1998.00571.x. + + +969 Margerin, L., Bajaras, A., & Campillo, M., 2019. A scalar radiative transfer model including + +970 the coupling between surface and body waves, Geophysical Journal International, 219(2), + +971 1092–1108, doi: 10.1093/gji/ggz348. + + +972 Mavko, G., Mukerji, T., & Dvorkin, J., 2009. The Rock Physics Handbook: Tools + +973 for Seismic Analysis of Porous Media, Cambridge University Press, 2nd edition., doi: + +974 10.1017/CBO9780511626753. + + +975 Mikesell, T. D., Malcolm, A. E., Yang, D., & Haney, M. M., 2015. A comparison of + +976 methods to estimate seismic phase delays: numerical examples for coda wave interferometry, + +977 Geophysical Journal International, 202(1), 347–360, doi: 10.1093/gji/ggv138. + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 6 +978 Minato, S., Tsuji, T., Ohmi, S., & Matsuoka, T., 2012. Monitoring seismic velocity change + +979 caused by the 2011 tohokuoki earthquake using ambient noise records, Geophysical Research + +980 Letters, 39, doi: 10.1029/2012gl051405. + + +981 Mordret, A., Mikesell, T. D., Harig, C., Lipovsky, B. P., & Prieto, G. A., 2016. Monitoring + +982 southwest greenlands ice sheet melt with ambient seismic noise, Science Advances, 2, doi: + +983 10.1126/sciadv.1501538. + + +984 Moreau, L., Stehly, L., Boué, P., Lu, Y., Larose, E., & Campillo, M., 2017. Improving + +985 ambient noise correlation functions with an SVD-based Wiener filter, Geophysical Journal + +986 International, 211(1), 418–426, doi: 10.1093/gji/ggx306. + + +987 Nakata, N. & Snieder, R., 2011. Near-surface weakening in japan after the 2011 tohoku-oki + +988 earthquake, Geophysical Research Letters, 38, n/a–n/a, doi: 10.1029/2011gl048800. + + +989 Nimiya, H., Ikeda, T., & Tsuji, T., 2017. Spatial and temporal seismic velocity changes on + +990 kyushu island during the 2016 kumamoto earthquake, Science Advances, 3, doi: 10.1126/sci- + +991 adv.1700813. + + +992 Obermann & Hillers, 2019. Seismic time-lapse interferometry across scales, Advances in + +993 Geophysics, pp. 65–143, doi: 10.1016/bs.agph.2019.06.001. + + +994 Obermann, A., Planès, T., Larose, E., Sens-Schönfelder, C., & Campillo, M., 2013. Depth + +995 sensitivity of seismic coda waves to velocity perturbations in an elastic heterogeneous + +996 medium, Geophysical Journal International, 194(1), 372–382, doi: 10.1093/gji/ggt043. + + +997 Obermann, A., Kraft, T., Larose, E., & Wiemer, S., 2015. Potential of ambient seismic noise + +998 techniques to monitor the st. gallen geothermal site (switzerland), Journal of Geophysical + 68 M. A. Denolle +999 Research: Solid Earth, 120, 4301–4316, doi: 10.1002/2014jb011817. + + +1000 Obermann, A., Planès, T., Hadziioannou, C., & Campillo, M., 2016. Lapse-time-dependent + +1001 coda-wave depth sensitivity to local velocity perturbations in 3-d heterogeneous elastic + +1002 media, Geophysical Journal International, 207(1), 59–66, doi: 10.1093/gji/ggw264. + + +1003 Okubo, K., Delbridge, B. G., & Denolle, M. A., 2024. Monitoring velocity change over 20 + +1004 years at parkfield, Journal of Geophysical Research: Solid Earth, 129(4), e2023JB028084, + +1005 doi: 10.1029/2023JB028084. + + +1006 Olivier, G., Brenguier, F., de Wit, T., & Lynch, R., 2017. Monitoring the stability of + +1007 tailings dam walls with ambient seismic noise, The Leading Edge, 36, 350a1–350a6, doi: + +1008 10.1190/tle36040350a1.1. + + +1009 Olivier, G., Brenguier, F., Carey, R., Okubo, P., & Donaldson, C., 2019. Decrease in seismic + +1010 velocity observed prior to the 2018 eruption of kīlauea volcano with ambient seismic noise + +1011 interferometry, Geophysical Research Letters, 46, 3734–3744, doi: 10.1029/2018gl081609. + + +1012 Ouellet, S. M., Dettmer, J., Olivier, G., de Wit, T., & Lato, M., 2022. Advanced monitoring + +1013 of tailings dam performance using seismic noise and stress models, Communications Earth + +1014 & Environment, 3, 301, doi: 10.1038/s43247-022-00629-w. + + +1015 Paasschens, J. C. J., 1997. Solution of the time-dependent boltzmann equation, Physical + +1016 Review E, 56(1), 1135–1141, doi: 10.1103/PhysRevE.56.1135. + + +1017 Pacheco, C. & Snieder, R., 2005. Time-lapse travel time change of multiply scattered + +1018 acoustic waves, The Journal of the Acoustical Society of America, 118(3), 1300–1310, doi: + +1019 10.1121/1.1979437. + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 6 +1020 Planès, T., Mooney, M. A., Rittgers, J. B. R., Parekh, M. L., Behm, M., & Snieder, R., + +1021 2016. Time-lapse monitoring of internal erosion in earthen dams and levees using ambient + +1022 seismic noise, Géotechnique, 66(4), 301–312, doi: 10.1680/jgeot.14.P.268. + + +1023 Poli, P., Marguin, V., Wang, Q., D’Agostino, N., & Johnson, P., 2020. Seasonal and + +1024 coseismic velocity variation in the region of l’aquila from single station measurements and + +1025 implications for crustal rheology, Journal of Geophysical Research: Solid Earth, 125, doi: + +1026 10.1029/2019jb019316. + + +1027 Poupinet, G., Ellsworth, W. L., & Frechet, J., 1984. Monitoring velocity variations in the + +1028 crust using earthquake doublets: An application to the Calaveras fault, California, Journal + +1029 of Geophysical Research: Solid Earth, 89(B7), 5719–5731, doi: 10.1029/jb089ib07p05719. + + +1030 Rivet, D., Campillo, M., Shapiro, N. M., Cruz-Atienza, V., Radiguet, M., Cotte, N., & + +1031 Kostoglodov, V., 2011. Seismic evidence of nonlinear crustal deformation during a large slow + +1032 slip event in mexico, Geophysical Research Letters, 38, n/a–n/a, doi: 10.1029/2011gl047151. + + +1033 Rivet, D., Brenguier, F., Clarke, D., Shapiro, N. M., & Peltier, A., 2014. Long-term dynamics + +1034 of Piton de la Fournaise volcano from 13 years of seismic velocity change measurements + +1035 and GPS observations, Journal of Geophysical Research: Solid Earth, 119(10), 7654–7666, + +1036 doi: 10.1002/2014JB011307. + + +1037 Rivet, D., Brenguier, F., & Cappa, F., 2015. Improved detection of preeruptive seismic + +1038 velocity drops at the piton de la fournaise volcano, Geophysical Research Letters, 42, + +1039 6332–6339, doi: 10.1002/2015gl064835. + + +1040 Rubinstein, J. L. & Beroza, G. C., 2005. Depth constraints on nonlinear strong ground + 70 M. A. Denolle +1041 motion from the 2004 parkfield earthquake, Geophysical Research Letters, 32, doi: + +1042 10.1029/2005gl023189. + + +1043 Sato, H., 1993. Energy transportation in one- and two-dimensional scattering media: analytic + +1044 solutions of the multiple isotropic scattering model, Geophysical Journal International, + +1045 112(1), 141–146, doi: 10.1111/j.1365-246X.1993.tb01443.x. + + +1046 Sawazaki, K., Sato, H., Nakahara, H., & Nishimura, T., 2009. Time-lapse changes of + +1047 seismic velocity in the shallow ground caused by strong ground motion shock of the 2000 + +1048 western-tottori earthquake, japan, as revealed from coda deconvolution analysis, Bulletin + +1049 of the Seismological Society of America, 99, 352–366, doi: 10.1785/0120080058. + + +1050 Schaff, D. P. & Beroza, G. C., 2004. Coseismic and postseismic velocity changes mea- + +1051 sured by repeating earthquakes, Journal of Geophysical Research: Solid Earth, 109, doi: + +1052 10.1029/2004jb003011. + + +1053 Sens-Schönfelder, C. & Wegler, U., 2006. Passive image interferometry and seasonal + +1054 variations of seismic velocities at Merapi volcano, Indonesia, Geophysical Research Letters, + +1055 33(21), L21302, doi: 10.1029/2006GL027797. + + +1056 Sens-Schönfelder, C., Pomponi, E., & Peltier, A., 2014. Dynamics of Piton de la Fournaise + +1057 volcano observed by passive image interferometry with multiple references, Journal of + +1058 Volcanology and Geothermal Research, 276, 32–45, doi: 10.1016/j.jvolgeores.2014.02.012. + + +1059 Sheng, Y., Mordret, A., Sager, K., Brenguier, F., Boué, P., Rousset, B., Vernon, F., + +1060 Higueret, Q., & BenZion, Y., 2022. Monitoring seismic velocity changes across the + +1061 san jacinto fault using traingenerated seismic tremors, Geophysical Research Letters, 49, + +1062 doi: 10.1029/2022gl098509. + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 7 +1063 Snieder, R., Grêt, A., Douma, H., & Scales, J., 2002. Coda wave interferometry for + +1064 estimating nonlinear behavior in seismic velocity, Science, 295(5563), 2253–2255, doi: + +1065 10.1126/science.1070015. + + +1066 Steegen, S., Tuerlinckx, F., Gelman, A., & Vanpaemel, W., 2016. Increasing transparency + +1067 through a multiverse analysis, Perspectives on Psychological Science, 11(5), 702–712, doi: + +1068 10.1177/1745691616658637. + + +1069 Stehly, L., Campillo, M., & Shapiro, N. M., 2006. A study of the seismic noise from its + +1070 long-range correlation properties, Journal of Geophysical Research, 111, B10306, doi: + +1071 10.1029/2005JB004237. + + +1072 Stehly, L., Froment, B., Campillo, M., Liu, Q. Y., & Chen, J. H., 2015. Monitoring seismic + +1073 wave velocity changes associated with the Mw 7.9 Wenchuan earthquake: increasing + +1074 the temporal resolution using curvelet filters, Geophysical Journal International, 201(3), + +1075 1939–1949, doi: 10.1093/gji/ggv110. + + +1076 Taira, T., Brenguier, F., & Kong, Q., 2015. Ambient noisebased monitoring of seismic + +1077 velocity changes associated with the 2014 mw 6.0 south napa earthquake, Geophysical + +1078 Research Letters, 42, 6997–7004, doi: 10.1002/2015gl065308. + + +1079 Taira, T., Nayak, A., Brenguier, F., & Manga, M., 2018. Monitoring reservoir response to + +1080 earthquakes and fluid extraction, salton sea geothermal field, california, Science Advances, + +1081 4, doi: 10.1126/sciadv.1701536. + + +1082 Takano, T., Nishimura, T., & Nakahara, H., 2017. Seismic velocity changes concentrated + +1083 at the shallow structure as inferred from correlation analyses of ambient noise during + 72 M. A. Denolle +1084 volcano deformation at izuoshima, japan, Journal of Geophysical Research: Solid Earth, + +1085 122, 6721–6736, doi: 10.1002/2017jb014340. + + +1086 Tsai, V. C., 2011. A model for seasonal changes in gps positions and seismic wave speeds + +1087 due to thermoelastic and hydrologic variations, Journal of Geophysical Research, 116, doi: + +1088 10.1029/2010jb008156. + + +1089 Tsuji, T., Ikeda, T., Matsuura, R., Mukumoto, K., Hutapea, F. L., Kimura, T., Yamaoka, K., + +1090 & Shinohara, M., 2021. Continuous monitoring system for safe managements of CO2 storage + +1091 and geothermal reservoirs, Scientific Reports, 11, 19120, doi: 10.1038/s41598-021-97881-5. + + +1092 Viens, L. & Van Houtte, C., 2020. Denoising ambient seismic field correlation functions + +1093 with convolutional autoencoders, Geophysical Journal International, 220(3), 1521–1535, + +1094 doi: 10.1093/gji/ggz509. + + +1095 Voisin, C., Garambois, S., Massey, C., & Brossier, R., 2016. Seismic noise monitoring of + +1096 the water table in a deep-seated, slow-moving landslide, Interpretation, 4, SJ67–SJ76, doi: + +1097 10.1190/int-2016-0010.1. + + +1098 Wang, Q., Brenguier, F., Campillo, M., Lecointre, A., Takeda, T., & Aoki, Y., 2017. Seasonal + +1099 crustal seismic velocity changes throughout japan, Journal of Geophysical Research: Solid + +1100 Earth, 122, 7987–8002, doi: 10.1002/2017jb014307. + + +1101 Wang, Q., Campillo, M., Brenguier, F., Lecointre, A., Takeda, T., & Hashima, A., 2019. + +1102 Evidence of changes of seismic properties in the entire crust beneath japan after the mw 9.0, + +1103 2011 tohokuoki earthquake, Journal of Geophysical Research: Solid Earth, 124, 8924–8941, + +1104 doi: 10.1029/2019jb017803. + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 7 +1105 Wang, Q.-Y. & Yao, H., 2020. Monitoring of velocity changes based on seismic ambi- + +1106 ent noise: A brief review and perspective, Earth and Planetary Physics, 4, 1–11, doi: + +1107 10.26464/epp2020048. + + +1108 Watlet, A., Whiteley, J., Dashwood, B., Morgan, D., Lane, V., Finch, L., Gunn, D., Lecocq, + +1109 T., & Chambers, J., 2026. Seismic response of a slow-moving landslide: exploring data + +1110 from two years of seismic monitoring at the hollin hill landslide observatory (uk), Seismica, + +1111 5, doi: 10.26443/seismica.v5i1.1478. + + +1112 Weaver, R. L., Hadziioannou, C., Larose, E., & Campillo, M., 2011. On the precision of + +1113 noise correlation interferometry, Geophysical Journal International, 185(3), 1384–1392, + +1114 doi: 10.1111/j.1365-246X.2011.05015.x. + + +1115 Wegler, U. & Sens-Schönfelder, C., 2007. Fault zone monitoring with passive image + +1116 interferometry, Geophysical Journal International, 168, 1029–1033, doi: 10.1111/j.1365- + +1117 246x.2006.03284.x. + + +1118 Wegler, U., Nakahara, H., SensSchönfelder, C., Korn, M., & Shiomi, K., 2009. Sudden + +1119 drop of seismic velocity after the 2004 mw 6.6 midniigata earthquake, japan, observed + +1120 with passive image interferometry, Journal of Geophysical Research: Solid Earth, 114, doi: + +1121 10.1029/2008jb005869. + + +1122 Xie, F., Larose, E., Wang, Q., & Zhang, Y., 2023. In-situ monitoring of rock slope + +1123 destabilization with ambient seismic noise interferometry in southwest china, Engineering + +1124 Geology, 312, 106922, doi: 10.1016/j.enggeo.2022.106922. + + +1125 Yates, A. S., Savage, M. K., Jolly, A. D., Caudron, C., & Hamling, I. J., 2019. Volcanic, coseis- + 74 M. A. Denolle +1126 mic, and seasonal changes detected at white island (whakaari) volcano, new zealand, using + +1127 seismic ambient noise, Geophysical Research Letters, 46, 99–108, doi: 10.1029/2018gl080580. + + +1128 Yates, A. S., Caudron, C., Mordret, A., Lesage, P., Pinel, V., Lecocq, T., Miller, C. A., + +1129 Lamb, O. D., & Fournier, N., 2024. Seasonal snow cycles and their possible influence on + +1130 seismic velocity changes and eruptive activity at ruapehu volcano, new zealand, Journal + +1131 of Geophysical Research: Solid Earth, 129, doi: 10.1029/2024jb029568. + + +1132 Yuan, C., Bryan, J., & Denolle, M., 2021. Numerical comparison of time-, frequency- and + +1133 wavelet-domain methods for coda wave interferometry, Geophysical Journal International, + +1134 226(2), 828–846, doi: 10.1093/gji/ggab140. + + +1135 Yukutake, Y., Taira, T., Onizawa, S., & Morita, Y., 2025. Decadal monitoring of seismic + +1136 velocity changes beneath izuoshima, central japan, using ambient seismic noise records, + +1137 Journal of Geophysical Research: Solid Earth, 130, doi: 10.1029/2025jb031170. + + +1138 Zhan, Z., Tsai, V. C., & Clayton, R. W., 2013. Spurious velocity changes caused by temporal + +1139 variations in ambient noise frequency content, Geophysical Journal International, 194(3), + +1140 1574–1581, doi: 10.1093/gji/ggt170. + + +1141 Zhang, S., Luo, B., BenZion, Y., Lumley, D. E., & Zhu, H., 2023. Monitoring terrestrial + +1142 water storage, drought and seasonal changes in central oklahoma with ambient seismic + +1143 noise, Geophysical Research Letters, 50, doi: 10.1029/2023gl103419. + + +1144 Zotz-Wilson, R., Boerrigter, T., & Barnhoorn, A., 2019. Coda-wave monitoring of continu- + +1145 ously evolving material properties and the precursory detection of yielding, The Journal + +1146 of the Acoustical Society of America, 145(2), 1060–1068, doi: 10.1121/1.5091012. diff --git a/review/evidence/figures/fresh_page_01.png b/review/evidence/figures/fresh_page_01.png new file mode 100644 index 0000000..35ecd79 Binary files /dev/null and b/review/evidence/figures/fresh_page_01.png differ diff --git a/review/evidence/figures/fresh_page_11.png b/review/evidence/figures/fresh_page_11.png new file mode 100644 index 0000000..1634d58 Binary files /dev/null and b/review/evidence/figures/fresh_page_11.png differ diff --git a/review/evidence/figures/fresh_page_29.png b/review/evidence/figures/fresh_page_29.png new file mode 100644 index 0000000..34f365f Binary files /dev/null and b/review/evidence/figures/fresh_page_29.png differ diff --git a/review/evidence/figures/fresh_page_32.png b/review/evidence/figures/fresh_page_32.png new file mode 100644 index 0000000..1681980 Binary files /dev/null and b/review/evidence/figures/fresh_page_32.png differ diff --git a/review/evidence/figures/fresh_page_36.png b/review/evidence/figures/fresh_page_36.png new file mode 100644 index 0000000..2f97560 Binary files /dev/null and b/review/evidence/figures/fresh_page_36.png differ diff --git a/review/evidence/figures/fresh_page_37.png b/review/evidence/figures/fresh_page_37.png new file mode 100644 index 0000000..21e6896 Binary files /dev/null and b/review/evidence/figures/fresh_page_37.png differ diff --git a/review/evidence/figures/manuscript_layout.txt b/review/evidence/figures/manuscript_layout.txt new file mode 100644 index 0000000..0a04d06 --- /dev/null +++ b/review/evidence/figures/manuscript_layout.txt @@ -0,0 +1,3534 @@ + submitted to Geophys. J. Int. + + + + +1 The reproducibility cost of ad-hoc processing choices + +2 in ambient-noise seismic velocity-change monitoring + + + +3 M. A. Denolle + + + +4 2026-08-17 + + + +5 SUMMARY + +6 Relative seismic velocity changes (𝛿𝑣/𝑣) from repeated coda waves are becoming a + +7 standard observable for volcanoes, faults, landslides, aquifers and the cryosphere and are + +8 increasingly regarded as new measurements of strain changes. Yet turning cross-correlation + +9 functions into a 𝛿𝑣/𝑣 time series involves a long sequence of choices — the estimator, the + +10 frequency band, the coda window, the reference, the stacking, and how cross-components + +11 and station pairs are aggregated and weighted — made ad hoc, their impact on the + +12 measurement uncertainty unclear. These hidden choices clearly limit reproducibility of + +13 the research and importantly the inter-study comparison. + +14 We demonstrate here how to turn repeated wavefield measurement into agent-ready, + +15 scalable-ready, uncertainty-aware measurement of changes in seismic properties. We + +16 quantify the individual and combined effects of these choices using a controlled synthetic + +17 in which the ground-truth 𝛿𝑣/𝑣 is known exactly. We show that at large 𝛿𝑣/𝑣 methods + +18 split by family with distinct failure modes; that the same station pair yields different + +19 𝛿𝑣/𝑣 depending only on whether one averages the per-component 𝛿𝑣/𝑣 or the correlation- + +20 coefficient images; and, most consequentially, that the reported 1𝜎 on a network-averaged + 2 M. A. Denolle + √ +21 𝛿𝑣/𝑣 varies by ∼ 𝑁 from the standard-error-versus-standard-deviation and weighting + +22 conventions — so a change that is “3𝜎 significant” in one study is “not significant” in + +23 another, from identical data. + +24 Running the full breadth of parameter choices, we estimate each by the bias and error- + +25 bar change it induces. We propose a Bayesian measurement model that marginalises + +26 the ensemble into a single time-dependent data covariance 𝐶𝑑 and illustrate its use by + +27 propagating errors in a depth-inversion of shear wave perturbation. We provide a real data + +28 examples from a California data set and reproduce previous results that were generated + +29 with a different computing language and processing pipeline, demonstrating at the same + +30 time the integration of codameter with noisepy and its portability and scalability from + +31 laptop to cloud systems. We also generate a codameter agent advisor that can guide + +32 researchers or agents in their parameter choices, accompanied with a robust evaluation + +33 of the agent against a golden data set. Our method and associated software package, + +34 codameter turns repeated coda waves into time series of 𝛿𝑣/𝑣 and its covariance making + +35 it coda-wave interferometry uncertainty-aware and reproducible. + + +36 Key words: Coda-wave Interferometry; Seismic noise; Coda waves; Inverse theory; + +37 Statistical methods. + + + + +38 1 INTRODUCTION + + +39 Changes in subsurface properties occur due to geodynamics, which drive earthquake damage + +40 and volcanic eruption, and hydrodynamics, which controls fluid exchange between the + +41 atmosphere and the solid Earth. These processes influence the mechanical properties of Earth + +42 materials, which directly affect the speed at which seismic waves propagate. Changes in + +43 seismic velocity, often measured and referred to as 𝛿𝑣/𝑣, can be tracked by measuring changes + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 3 +44 in arrival times of seismic waves, especially scattered waves such as coda waves, provided + +45 that the source and receivers are at the same location. + + +46 Due to the sensitivity of coda waves to small perturbations in the material properties, + +47 𝛿𝑣/𝑣 was discovered as an effective method to monitor changes during volcanic unrest since + +48 its discovery at Piton de la Fournaise (Brenguier et al., 2008b) and is now calculated in + +49 continuous along side of more conventional seismic monitoring methods in the same volcano + +50 observatory (Duputel et al., 2009) and was a determining early warning parameter: the + +51 Icelandic Meteorological Office used 𝛿𝑣/𝑣 in its response to the 2020 Reykjanes unrest + +52 (Cubuk-Sabuncu et al., 2021). The Institute of Mine Seismology also uses 𝛿𝑣/𝑣 to monitor + +53 the internal state of tens of tailings dams and mines to flag instability before failure (Olivier + +54 et al., 2017; Ouellet et al., 2022). A broader set of operations is emerging around the same + +55 signal: groundwater storage for water management (Clements & Denolle, 2018; Mao et al., + +56 2022), landslide early warning (Le Breton et al., 2021), levee and embankment integrity + +57 (Planès et al., 2016), and geothermal and CO2 reservoir surveillance (Tsuji et al., 2021). Each + +58 of these deployments rests on the same fragile assumption: that the 𝛿𝑣/𝑣 curve an operator + +59 acts on is a property of the subsurface, not of the analyst’s processing choices. + + +60 𝛿𝑣/𝑣 is the fractional seismic velocity change, positive for a velocity increase. The stretching + +61 family of estimators measures the stretch factor 𝜀 that maps the current coda onto the + +62 reference coda. Throughout this work, the reference correlation is held fixed and trial dilations + +63 are applied to the current correlation, + + + 𝑐𝜖 (𝑡) = 𝑐[(1 + 𝜖)𝑡], + + +64 where interpolation is performed only on (c). Thus (𝜖 = 𝑡𝑐𝑢𝑟 /𝑡𝑟𝑒𝑓 − 1) is a fractional travel- + +65 time dilation: 𝜖 > 0 denotes a delayed phase in the current coda (slower) and 𝜖 < 0 denotes + 4 M. A. Denolle +66 an earlier arrival time (faster). For unchanged propagation geometry, + + 𝑡𝑐𝑢𝑟 𝑣𝑟𝑒𝑓 + 1+𝜖= = , + 𝑡𝑟𝑒𝑓 𝑣𝑐𝑢𝑟 + +67 and therefore the physical fractional velocity change reported throughout this work is + + 𝛿𝑣 𝑣𝑐𝑢𝑟 − 𝑣𝑟𝑒𝑓 𝜖 + ≡ =− . + 𝑣 𝑣𝑟𝑒𝑓 1+𝜖 + +68 The commonly used relation (𝛿𝑣/𝑣 ≃ −𝜖 ≃ −𝛿𝑡/𝑡) is its first-order approximation and + +69 used in the majority of published work. We retain the exact finite-change transformation + +70 because its computational cost is negligible and because the distinction becomes measurable + +71 for velocity perturbations of several percent measured in large strain phenomena such as + +72 landslides. The current coda is stretched rather than the reference correlation so that the + +73 high-SNR reference stack remains unchanged throughout the search. While the reciprocal + +74 formulations are mathematically equivalent; in sampled, finite-window data they can differ + +75 because interpolation and boundary truncation break that symmetry. + + +76 The elevated sensitivity comes at the price of a long series of processing choices, and + +77 at almost every step the analyst makes a choice. Among these are choices of estimators + +78 between windowed phase measurements or stretching (Mikesell et al., 2015, Mao et al. (2020), + +79 Yuan et al. (2021)), frequency band and coda window (which together set the sampled + +80 depth; Obermann et al. (2013; Obermann et al., 2016)), reference window (Brenguier et al., + +81 2014, Ermert et al. (2023), Okubo et al. (2024)), increasing the temporal resolution of the + +82 measurement through substacking-filtering-denoising (Hadziioannou et al., 2011, Moreau + +83 et al. (2017),Mao et al. (2019),Viens & Van Houtte (2020)), and how to aggregate and weight + +84 the many cross-component and station-pair measurements that make up a single reported + +85 𝛿𝑣/𝑣 time series (e.g., Hobiger et al. (2012)). These choices are made by habit, justified + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 5 +86 briefly if at all, and rarely reported in enough detail to reproduce. The community has long + +87 flagged individual pitfalls (spurious changes from non-stationary noise, Zhan et al. (2013); + +88 measurement-error formulae, Clarke et al. (2011; Weaver et al., 2011)), but the cumulative + +89 effect of the full choice set on both the value and its stated uncertainty has not been quantified + +90 in the literature. A striking example of such their cumulative effects can be seen in Figure x of + +91 (Denolle et al., 2025) who demonstrated that most studies found a direct correlation between + +92 𝛿𝑣/𝑣 and groundwater level change, but the scatter around the mean was easily explained by + +93 frequency choices, single-vs-inter station correlations, and likely the other signal-processing + +94 parameters chosen by the authors, which speak of the robust correlation but not rigorously + +95 established enough to be useful in downstream hydrological research. + + +96 This is a reproducibility problem of exactly the “garden of forking paths” type identified + +97 in the statistical sciences (Gelman & Loken, 2013; Steegen et al., 2016): many individually + +98 reasonable analyses of the same data give different answers, and without full reporting of + +99 parameter choices we cannot interpret a reported 𝛿𝑣/𝑣 as a robust value. Here we make the + +100 problem concrete for 𝛿𝑣/𝑣 monitoring. We use purely synthetic correlation time series to + +101 test the methods (estimators) and parameter choices that the community makes to estimate + +102 𝛿𝑣/𝑣 which we report over 103 studies in Appendix~C. We do not aim to report the “best” + +103 pipeline, which is most often the one reported in scientific papers, but instead document the + +104 parameter impacts (Section~3). We then propose a new measurement error that incorporates + +105 these effects into a data covariance matrix 𝐶𝑑 (Section~5). Throughout this paper, key + +106 notation includes: 𝜎 (measurement uncertainty of a recovered 𝛿𝑣/𝑣 estimate), 𝐵 (frequency + +107 bandwidth), and 𝑊 = [𝑡1 , 𝑡2 ] (coda window); subscripts distinguish specific contexts (e.g., + +108 𝜎𝑘 for per-component uncertainty), each defined where first introduced. + + +109 One example of propagating such error into downstream science is the migration of the surface + 6 M. A. Denolle +110 𝛿𝑣/𝑣 measurement to depth profiles of perturbations in shear wave velocity Δ𝑉𝑆 (𝑧)/𝑉𝑆 (𝑧), + +111 which often depends on the wavefield constituting the coda waves, such as surface waves + +112 or body waves, and that depend on the source-receiver pair geometry. We illustrate the + +113 propagation of errors to a depth profile (Section~6). We use synthetic examples for ground + +114 truthing on the signal processing parameters, since the concepts behind the observations of + +115 phase lags in scattered waves is well established (Obermann et al., 2013). + + +116 We further validate using real obervations that the estimates of 𝛿𝑣/𝑣 and their uncertainty + +117 reproduces well those of observed time series by reproducing previous studies. We package + +118 this new methodology in a Python software, codameter, which we also recast as an agentic + +119 skill: an AI agent can be asked to recommend a processing configuration or recover a 𝛿𝑣/𝑣(t) + +120 series, and its answer is scored against seeded synthetic golden cases with known ground + +121 truth, including a hidden-truth variant that withholds the answer from the public package + +122 so it cannot be reconstructed rather than measured. + + + + +123 2 SYNTHETIC FRAMEWORK + + +124 We build each synthetic reference coda wave as a band-limited random-phase wavefield + +125 modulated by a physically grounded coda envelope. We model the envelope from the exact + +126 single-scattering solution of the two-dimensional radiative transfer equation for isotropic + +127 scattering (Sato, 1993; Paasschens, 1997), which underlies coda-envelope modelling of scatter- + +128 ing and intrinsic attenuation (Margerin et al., 1998). The energy density at source–receiver + +129 distance 𝑟 and lapse time 𝑡 is + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 7 + + + 1 + √ + 2 2 2 + 𝑒−𝑐𝑡/ℓ 𝑟 𝑒 ℓ ( 𝑐 𝑡 −𝑟 −𝑐𝑡) 𝑟 +130 𝐸(𝑟, 𝑡) = [ 𝛿(𝑡 − ) + √ 𝐻(𝑡 − )] 𝑒−𝑏𝑡 , (1) + 2𝜋𝑐𝑟 𝑐 2𝜋ℓ 𝑐2 𝑡2 − 𝑟2 𝑐 + + +131 where 𝑐 is the (Rayleigh-wave) velocity, ℓ the scattering mean free path, 𝑏 the intrinsic + +132 absorption rate, and 𝛿 and 𝐻 the Dirac and Heaviside functions. The first term is the + +133 coherent ballistic arrival at 𝑡 = 𝑟/𝑐; the second is the multiply-scattered diffuse coda, + +134 which switches on at that arrival, builds up under scattering, and decays under intrinsic + +135 absorption. We fill random phases under the amplitude envelope √𝐸(𝑟, 𝑡), band-limit, and + +136 symmetrize the causal and acausal branches as for an evenly illuminated noise correlation. + +137 The modeled synthetic coda depends only on three time constants: the ballistic onset 𝑟/𝑐, + +138 the scattering mean free time ℓ/𝑐, and the absorption time 1/𝑏. The late-coda amplitude + +139 decays as 𝑒−𝑏𝑡/2 , recovering an apparent coda 𝑄𝑐 while the envelope shape is determined + +140 by scattering physics. A frequency-dependent absorption 𝑏(𝑓) = 2𝜋𝑓/𝑄𝑐 , which can still be + +141 modeled as an frequency-independent attenuation factor 𝑄𝑐 , reproduces the observation that + +142 high frequencies are retained only at short lag times, so a fixed late window samples different + +143 depths at different bands. + + +144 A homogeneous velocity change is imposed exactly by stretching the lapse-time axis, 𝑢𝑐𝑢𝑟 (𝑡) = + +145 𝑢𝑟𝑒𝑓 (𝑡 (1 + 𝛿𝑣/𝑣)), and a repeated time series is produced by generating this stretched coda + +146 with a prescribed ground-truth 𝛿𝑣/𝑣(𝑡) and additive band-limited noise at a controlled + +147 signal-to-noise ratio. The concept has been demonstrated using full waveform modeling in + +148 several previous studies (Obermann et al., 2013, 2016; Yuan et al., 2021), so we do not repeat + +149 that full-waveform modeling here. Because the imposed 𝛿𝑣/𝑣(𝑡) is known, every departure of + +150 a recovered series from it is an artefact of the processing, not of the data. + + +151 We use seven 𝛿𝑣/𝑣 estimators that were implemented in noisepy (Jiang & Denolle, 2020): + 8 M. A. Denolle +152 trace stretching (TS, Lobkis & Weaver (2003)), windowed cross-correlation (WCC, Poupinet + +153 et al. (1984)), dynamic time warping (DTW, Mikesell et al. (2015)), the moving-window + +154 cross-spectrum (MWCS; Clarke et al. (2011)), and three wavelet-domain methods, the wavelet + +155 cross-spectrum (WCS, Mao et al. (2020)) and the two wavelet stretching (WTS) and wavelet + +156 DTW (WTDTW) introduced and benchmarked numerically by Yuan et al. (2021). The + +157 framework, the figures below, and an implementation are released in the open codameter + +158 package (Section~8). Formal definitions of all seven methods, of the two aggregation pathways, + +159 and of the uncertainty conventions are described in Appendices~A and~B. + + +160 Each of these methods require specific parameter choices, which we categorize and reference + +161 in Table~1. The work presented below measure the impacts of each of these parameter choices + +162 on the resulting 𝛿𝑣/𝑣. + + + + +163 3 PARAMETER-DEPENDENT 𝛿𝑣/𝑣 AND ITS ERRORS + + +164 The literature agrees on the components of a well-posed 𝛿𝑣/𝑣 measurement: a stretching- + +165 family estimator for robustness at low SNR and large change (Mikesell et al., 2015; Yuan et al., + +166 2021), a coherence-based error model (Clarke et al., 2011; Weaver et al., 2011), a long stable + +167 reference (Wang et al., 2017), and cross-validation against a second estimator (Obermann & + +168 Hillers, 2019). Yet studies do not always report the same set, and the uncertainty convention + +169 is rarely, if ever, quantified (Appendix~C). The sections below address each component in + +170 turn and quantify, against a known truth, how far a parameter choice impacts the recovered + +171 𝛿𝑣/𝑣 and its error. + + +172 Table~2 previews the RMS error against the known synthetic ground truth for the best- and + +173 worst-case option on each axis covered in this section, each derived in its own dedicated + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 9 + + Table 1. Processing choices (“hyper-parameters”) and their effect on the recovered value and + the reported uncertainty. Key notation: 𝐵 (frequency bandwidth), 𝑊 = [𝑡1 , 𝑡2 ] (coda window), 𝑁 + (measurement count), 𝑁eff (weighted effective count), 𝜎 (measurement uncertainty). + + Choice Options / typical range Effect on the value Effect on the uncertainty + + Estimator TS, WCC, DTW, MWCS, WCS, Agree at small 𝛿𝑣/𝑣; at large Each has its own error model; + WTS, WTDTW 𝛿𝑣/𝑣 phase methods cycle-skip, inter-method spread is an + warps under-shoot (Fig. 1) uncertainty + Phase unwrapping on / off (phase methods) Decides whether MWCS/WCS Sets the usable 𝛿𝑣/𝑣 range + cycle-skip (Fig. 1b) + 𝐵 0.1–2 Hz (volcano), 2–4 Hz Selects the sampled depth, hence 𝜎 decreases with increasing 𝐵 + (aquifer), 4–12 Hz (landslide) which signal (Fig. 8a) + 𝑊 a few to tens of mean free times Later lapse → deeper, larger 𝜎 ∝ (𝑡3 3 −1/2 (duration + 2 − 𝑡1 ) + sensitivity effect), but late coda is low-SNR + 𝑊-𝐵 coupling fixed vs scaled with 𝑓 A fixed late window at high 𝑓 inceases 𝜎 due to decorrelation + measures noise (Fig. 8b) at high 𝑓 + Reference total stack / trailing / joint Trailing reference gives Reference noise propagates; + inversion increments: the trend is absent inversion lowers it + unless they are cumulated, which + then drifts; joint inversion + preserves it directly (Fig. 8c) + Stacking / 1–30+ days Smears and delays transients 𝜎 and resolution decreases with + substack (Fig. 8d) stacking length + Component A (average 𝛿𝑣/𝑣) vs B (average Different time series (Fig. 2) Different uncertainty object + aggregation CC images); weighted vs not (ensemble spread vs CC-peak + width) + Pair / network coherence-weighted vs Small change in value Changes 𝑁eff + weighting unweighted + √ + Uncertainty within-measurement (Weaver) / — Factor 𝑁 or more (Fig. 3) + definition SE / SD + Quality control min CC, min SNR, max 𝛿𝑡 error Rejects or keeps measurements Sets the effective 𝑁 and any + selection bias + Pre-processing one-bit / running-mean; Bias if the noise field is Spurious 𝛿𝑣/𝑣 when the noise + whitening band non-stationary spectrum drifts (Zhan et al., + 2013) + Clock / timing causal vs acausal branch A clock error fabricates 𝛿𝑣/𝑣 Branch asymmetry diagnoses it + handling (Fig. 11a) + + +174 synthetic exercise (detailed in the corresponding subsection below); it is a synthesis of this + +175 section’s per-choice numbers, distinct from Table~3’s one-at-a-time sweep on a single shared + +176 scenario in Section~4. + + + +177 3.1 Estimator family + + +178 We implement all methods as in previous work (Jiang & Denolle, 2020). + + +179 As of codameter v0.4.0, all seven estimators return physical 𝛿𝑣/𝑣 under the sign convention + +180 above rather than the raw stretch factor 𝜀; the synthetic generator imposes changes in the + 10 M. A. Denolle + + Table 2. Synthesis of Section 3: RMS error against the known synthetic truth for the best- and worst- + case option on each axis, each from its own dedicated synthetic scenario (see the cross-referenced + subsection). + + Axis Best-case RMS Worst-case RMS Section + + Estimator (family split) < 0.01 % (TS, up to 5 % true cycle-skip > 0.5 % past Section 3.1 + 𝛿𝑣/𝑣) ∼ 1.5 % true 𝛿𝑣/𝑣 (MWCS) + Cross-component ∼ 0.03 % (Approach B, ∼ 0.31 % (Approach A, Section 3.2 + aggregation averaged images) unweighted) + Network aggregation ∼ 0.005 % (network SE) ∼ 0.05 % (individual-pair Section 3.3 + (per-pair spread) range) + Frequency band ∼ 0.028–0.031 % (within ∼ 0.10 % (center off by Section 3.4 + ±0.3 Hz of the true band) > 0.5 Hz) + Coda window ∼ 0.01 % (adapted to band) ∼ 3.9 % (fixed, wrong band) Section 3.7 + Reference scheme ∼ 0.03 % (whole record, ∼ 0.15–0.16 % (end-of-record Section 3.5 + earliest period, or joint fixed, or moving) + inversion) + Stack length ∼ 0.020 % (7–10-day, workable ∼ 0.044 % (1-day, same Section 3.6 + deployment) deployment) + + +181 same convention, so a positive imposed 𝛿𝑣/𝑣 recovers as positive. A dedicated regression + +182 test holds every estimator to this convention in both signs, end to end through the full + +183 measurement pipeline, so the convention cannot silently drift back. + + +184 On small, clean 𝛿𝑣/𝑣 all seven estimators agree (Fig.~1a). Sweeping the same clean recovery + +185 out to ±5 % (Fig.~1b) shows exactly where and how each family first departs from the 1:1 + +186 line, and the estimator choice becomes consequential at large, noisy 𝛿𝑣/𝑣 (Fig.~1c), where the + +187 effect of the methods is split according to their phase measurement approaches. The stretching + +188 family (TS, WTS) and WCC match the whole dilated coda and remain accurate for high + +189 SNR coda waves; the phase methods (MWCS) read a wrapped phase and may cycle-skips, + +190 while the same cross-wavelet phase (WCS), once unwrapped in 2-D, recovers the change. The + +191 warping methods (DTW, WTDTW) track but under-shoot the largest strains. No estimator + +192 is simply “right”; the choice of estimator materially changes the 𝛿𝑣/𝑣 measurement at larger + +193 strain. + + +194 On a clean, noiseless sweep of true 𝛿𝑣/𝑣 from −5 to 5 % (Fig.~1b), the phase-wrapped MWCS + +195 estimator is the first to break on either branch: its error stays below 0.1 % out to ∼ 1.3 % + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 1 + + + + + Figure 1. Estimator choice across the seven NoisePy methods. (a) Clean, small 𝛿𝑣/𝑣: all agree. + (b) The same clean recovery swept over ±5 % true 𝛿𝑣/𝑣: MWCS cycle-skips past ∼ 1.5 % on either + branch; TS and WTS track the 1:1 line throughout; WCC tracks just as tightly on the negative + branch but breaks sharply near the positive edge; DTW and WTDTW break asymmetrically, + WTDTW near +1 % but only near −3 % on the other branch; WCS degrades smoothly, crossing + 1 % error beyond ±4 %. (c) Large, noisy 𝛿𝑣/𝑣 (a pre-failure landslide signal): MWCS cycle-skips, + 2-D-unwrapped WCS and the stretching family track, the warping methods under-shoot. + +196 true 𝛿𝑣/𝑣, then exceeds 1 % error by ∼ 1.5 % — the cycle-skip, essentially symmetric in + +197 sign. The stretching family (TS, WTS) stays below 0.1 % error out to the full 5 % tested, + +198 on both branches. WCC is just as accurate on the negative branch (error stays below 0.1 % + +199 throughout) but breaks sharply on the positive branch, crossing both 0.1 % and 1 % error + +200 abruptly at the edge of the tested range (∼ 4.75 %) — a sign asymmetry from the physical + +201 convention itself (Section~1), not a processing artefact. The warping methods develop large + +202 (> 1 %) errors asymmetrically as the warp path becomes ill-conditioned: WTDTW crosses + +203 1 % error already at ∼ 1 % true 𝛿𝑣/𝑣 on the positive branch but only at ∼ 3 % on the negative + +204 branch, and DTW crosses at ∼ 2.5 % versus ∼ 3 %. WCS degrades smoothly rather than + +205 catastrophically, crossing 1 % error beyond ±4 % true 𝛿𝑣/𝑣 on either branch. + 12 M. A. Denolle +206 3.2 Aggregating cross-component results + + +207 Each three-component seismic station (e.g., Z, N, E) carries 6 cross-component correlations + +208 (ZZ, NN, EE, ZE, ZN, NE), whether they are calculated at a single station or an inter-station + +209 pair. Each carries a signature of the changes in velocity; components may be dominated by + +210 Love or Rayleigh waves (Lin et al., 2008; Stehly et al., 2006), but scattering and non-straight + +211 ray paths induce cross-component leakage between modes (Hennino et al., 2001; Margerin + +212 et al., 2019), and thus it is often assumed in practice that coda waves of cross-components with + +213 multi-scattering characteristics (e.g., no clearly separated phases) are composed of “surface + +214 waves” with strong S-wave sensitivity. Combining them together requires parameter choices, + +215 such as averaging them directly (Liu et al., 2014), or weighted (e.g., using coherence-based + +216 weighting Hobiger et al. (2012), De Plaen et al. (2016)). + + +217 Combining is another workflow choice that can change both the value and the uncertainty + +218 (Fig.~2). One may peak-pick each component’s correlation-coefficient curve CC(𝜀, 𝑡) and then + +219 average the per-component 𝛿𝑣/𝑣 (Approach A) — unweighted, a few poor components bias + +220 the mean; coherence-weighted, they are suppressed — or one may average the CC(𝜀, 𝑡) images + +221 across components first and peak-pick once (Approach B). All three conventions appear in + +222 the literature; on the same pair they give visibly different time series, and they propagate + +223 uncertainty along incompatible pathways (the ensemble spread of the per-component picks for + +224 A, the width of the averaged correlation peak for B). On our six-component synthetic (three + +225 good, three poor SNR), the RMS error against the known truth is ∼ 0.31 % for unweighted + +226 Approach A, ∼ 0.08 % for coherence-weighted Approach A (the poor components suppressed, + +227 ∼ 4× better), and ∼ 0.03 % for Approach B (averaging the images before peak-picking, ∼ 11× + +228 better than the unweighted mean and ∼ 3× better than the weighted one). + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 1 + + + + + Figure 2. Cross-component aggregation for one station pair, both panels on the same 𝛿𝑣/𝑣 axis. + (a) Unweighted 𝛿𝑣/𝑣-averaging (Approach A) is biased by the poor components (grey), while + coherence-weighting and image-averaging (Approach B) track the truth; the shaded band is B’s + local peak-width uncertainty. (b) The averaged CC(𝛿𝑣/𝑣, 𝑡) image of Approach B (dark = high + coherence) with its peak ridge (white) tracking the truth (black, dashed). + +229 3.3 Aggregating across station pairs + + +230 Adding the next layer up — combining many station pairs into a unified network series + +231 — exposes the most consequential and least-reported choice of all: how to summarize the + +232 uncertainty. Three conventions are common: a coherence-weighted standard error (e.g., Clarke + √ +233 et al. (2011)), an unweighted standard error (𝜎 = std/ 𝑁; e.g., Brenguier et al. (2008b)), + +234 and the between-pair standard deviation (e.g., Clements & Denolle (2018)). On the same + +235 synthetic network the recovered means nearly coincide, but the reported 1𝜎 spans a factor + √ +236 of ∼ 𝑁 (Fig.~3). A velocity change that is “3𝜎 significant” under the tightest convention + +237 is “1𝜎, not significant” under the most conservative one — from identical data. Error bars + +238 on published 𝛿𝑣/𝑣 are therefore not comparable across studies unless the aggregation, the + +239 weighting, and the standard-error-versus-standard-deviation convention are all stated. + + +240 Figure~3 plots only the network-aggregate series, which hides how much the individual + 14 M. A. Denolle + + + + + Figure 3. Station-pair aggregation and uncertainty for a nine-pair network. (a) The recovered + √ 𝛿𝑣/𝑣 + agrees across conventions; the shaded 1𝜎 bands do not. (b) The reported 1𝜎 differs by ∼ 𝑁 purely + from the weighting and SE-versus-SD choices. + +241 pairs actually disagree. Fig.~4 plots the same nine-pair network’s individual 𝛿𝑣/𝑣(t) curves, + +242 styled after a basin-scale, urban ambient-noise deployment such as the San Gabriel Valley + +243 groundwater network (Clements & Denolle, 2018) — an illustrative geometry rather than + +244 a literal reproduction of that network’s exact station spacing. The individual pairs range + +245 in quality from a coherence-weighted SNR of ∼ 2.5 to ∼ 11, and their spread at any given + +246 day (median range ∼ 0.053 %) is nearly 10× wider than the coherence-weighted network + +247 standard error (median ∼ 0.005 %) and more than 3× wider than the more conservative + +248 between-pair standard deviation (median ∼ 0.017 %). A network-level error bar, however + +249 it is computed, describes the precision of the mean, not the dispersion of what individual + +250 pairs actually report — the two are routinely conflated when a single station-pair result is + +251 compared against a published network value. + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 1 + + + + + Figure 4. Individual station-pair 𝛿𝑣/𝑣(t) for the same nine-pair network as Fig. 3, coloured by + pair SNR. The pair-to-pair spread (grey band) is far wider than any of the three network-level 1𝜎 + conventions in Fig. 3b. + +252 3.4 Frequency band + + +253 The remaining choices are no less consequential. The frequency band sets the sampled + +254 depth: in a two-layer medium, high frequencies recover shallow, often seasonal signals and + +255 low frequencies recover a deeper, maybe more tectonic, signal (Fig.~8a). In practice a band + +256 often gets reused from a neighboring deployment or an earlier study at the same site without + +257 re-checking that it still matches the target depth — exactly the error this section quantifies. + + +258 On our synthetic two-layer groundwater scenario, holding the recovery band’s width fixed + +259 (0.6 Hz) and sweeping its center away from the deep layer’s true 0.2–0.8 Hz band shows the + +260 cost is not gradual: RMS error against the known truth stays flat, ∼ 0.028–0.031 %, for a + +261 center offset within ∼ 0.3 Hz of the true center, then rises by a factor of ∼ 3–4 once the offset + +262 passes ∼ 0.5 Hz — the point at which the assumed band starts sampling the shallow layer’s + +263 signal instead of the deep one — and plateaus near ∼ 0.10 % beyond that (Fig.~5). The band + 16 M. A. Denolle +264 choice is forgiving up to the edge of the layer it targets, and expensive immediately past it, + +265 not gradually worse the further off it drifts. + + + + + Figure 5. Frequency-band sensitivity: RMS error against the known groundwater deep-layer truth + as the recovery band’s center is swept away from the true 0.2–0.8 Hz band, holding its 0.6 Hz width + fixed. Error is flat within ∼ ±0.3 Hz of the true center, then rises sharply once the assumed band + drifts into the shallow layer’s territory. + + + +266 Scale of effect: a band-center error under ∼ 0.3 Hz costs essentially nothing here; past + +267 ∼ 0.5 Hz it costs a factor of ∼ 3–4 in RMS, from ∼ 0.03 % to ∼ 0.10 %. + + + +268 3.5 Reference + + +269 The reference defines what survives: a moving reference re-baselines continuously and erases + +270 slow trends that a fixed reference or a joint inversion (Brenguier et al., 2014) preserve + +271 (Fig.~8c). In practice the choice is rarely just fixed-versus-moving: an analyst also decides + +272 which period of the record a fixed reference is built from, and that choice alone can dominate + +273 the error — for instance when a deployment barely predates the process of interest, or when + +274 the only quiet-looking period available sits close in time to the process itself. + + +275 We compare five named schemes on the volcano synthetic: a reference built from the begin- + +276 ning of the pre-eruptive record (its earliest 15%), from the end of that record (its latest 15%, + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 1 +277 immediately before the eruption), from the whole pre-eruptive record, a 60-day moving + +278 (trailing) reference, and no single reference at all — the Brenguier et al. (2014)-style joint + +279 inversion, which measures relative dv/v between many short stacks instead of referencing + +280 every day to one (Fig.~6a). The whole-record, beginning, and inversion schemes all recover + +281 the truth to RMS ∼ 0.03 %. The end-of-record reference does far worse, RMS ∼ 0.15 % — + +282 not because it tracks the dynamics any less faithfully (its residual scatter around the truth, + +283 ∼ 0.029 %, matches every other fixed scheme) but because the reference epoch itself already + +284 sits ∼ 0.15 % into the developing pre-eruptive ramp, and every dv/v value is reported relative + +285 to whatever the reference was doing. Reference choice sets the zero point, not just the noise + +286 floor: comparing dv/v across studies, or across deployments that started at different times, + +287 requires knowing what the reference period itself was doing, not just how well each pipeline + +288 scores against a single truth. + + +289 The 60-day moving reference gives RMS ∼ 0.16 % — comparable to the worst fixed case, but + +290 for the opposite reason: it re-baselines away the trend continuously rather than sitting at one + +291 biased epoch. Lengthening the trailing window helps only slowly and never converges to the + +292 fixed-reference baseline: RMS falls from ∼ 0.168 % at a 10-day trailing window to ∼ 0.151 % + +293 at 240 days, still ∼ 4–5× the whole-record RMS (Fig.~6b) — the erasure is structural, not a + +294 noise effect that more averaging fixes. + + +295 Read carefully, though, that erasure is a property of the uncumulated increment, not of a + +296 non-fixed reference as such — and the published alternatives to a fixed reference do not take + +297 the form the sweep assumes. They fall into two families, neither of which re-baselines every + +298 epoch and reports the raw increment. + + +299 The first cumulates. James et al. (2017) re-baseline each day against the immediately + 18 M. A. Denolle +300 preceding day-stack and sum the daily 𝛿𝑡/𝑡 from a fixed start date, recovering a seasonal + +301 freeze–thaw trend in Alaskan permafrost that a stationary reference could not detect at + +302 all: the frozen-to-thawed velocity contrast made the stationary comparison cycle-skip, while + +303 adjacent days stayed coherent. Rivet et al. (2011) likewise reference each epoch to the previous + +304 one. The cost is that summation integrates the measurement error — James et al. (2017) + +305 report a positive drift in the cumulated series that their quadrature error budget could not + +306 account for, and correct it linearly against a stationary-reference anchor. The same rolling + +307 construction appears in laboratory coda monitoring of rock deforming to failure, where the + +308 scattering properties change too much for a fixed reference to stay valid (Zotz-Wilson et al., + +309 2019). + + +310 The second holds the reference fixed within a segment and stitches the segments together. + +311 Rivet et al. (2014) define a separate reference stack for each of three multi-year periods at + +312 Piton de la Fournaise, then merge the three series by measuring the relative velocity change + +313 between the adjacent segment references, using station pairs that occupied the same sites + +314 across the network change. Sens-Schönfelder et al. (2014) develop the multiple-reference form + +315 of the same idea at the same volcano, and Ermert et al. (2023) adopt a multiple-reference + +316 approach for urban single-station autocorrelations in Mexico City, where long-term waveform + +317 coherence is simply unavailable, stabilising the stacks by clustering correlation windows with + +318 a Gaussian mixture model so that day-time and night-time noise regimes stack separately. + + +319 That second family is worth naming precisely, because it is not a separate method from the + +320 joint inversion — it is a restriction of it. Stitching two segments by measuring the relative + +321 dv/v between their references is exactly the adjacent-pair case of the over-determined system + +322 the inversion solves over all pairs of block stacks. The reference axis is therefore better read + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 1 +323 as a single continuum, from one global reference, through segment references joined pairwise, + +324 to the fully coupled inversion, than as a menu of unrelated choices. + + +325 Against that, the uncumulated day-by-day trailing reference swept above is a limit case rather + +326 than a practice: we found no surveyed study that re-baselines continuously and reports the + +327 increments without summing them. It is retained here because it isolates what re-baselining + +328 costs when the trend is not reconstructed, which is the failure mode the two families above + +329 exist to avoid. codameter implements the joint inversion but neither the cumulated trailing + +330 reference nor cluster-based reference selection. + + + + + Figure 6. Reference construction on the volcano synthetic. (a) Five named schemes, each scored + by RMS against the known truth over the whole record and over the pre-eruptive ramp alone. (b) + RMS for the moving reference as a function of its trailing length; the dashed line is the whole-record + fixed reference’s RMS, which the moving reference never reaches. + + + +331 Scale of effect: which period a fixed reference is drawn from can cost as much as switching + +332 to a moving reference altogether (∼ 0.15–0.16 % RMS either way); a reference from the + +333 quietest available period, of any length, recovers the trend to ∼ 0.03 %. + 20 M. A. Denolle +334 3.6 Substacking + + +335 The stacking length trades noise against temporal resolution, rounding off and delaying a + +336 coseismic step (Fig.~8d). In practice the decision is rarely “how many days” in the abstract; + +337 it is “how long until the coda is coherent enough to trust” — stacking only as long as needed + +338 to clear a working correlation-coefficient (CC) threshold, then stopping. codameter’s own + +339 quality-control gate uses CC~> 0.6 (Section~3), and how quickly a station clears that bar + +340 depends entirely on its data quality. + + +341 Substack duration therefore defines a fundamental precision–temporal-resolution tradeoff. + +342 Longer stacks suppress incoherent noise fluctuations and accelerate the convergence of + +343 noise correlation functions, whereas shorter substacks preserve transient changes that would + +344 otherwise be averaged within the stacking window. The reduced signal-to-noise ratio of + +345 shorter correlations can be partially compensated through adaptive filtering, SVD-based or + +346 learned denoising, or through redundancy across dense seismic arrays, enabling 𝛿𝑣/𝑣 + +347 measurements at daily, hourly, and even sub-hourly resolution (Hadziioannou et al., 2011, + +348 Moreau et al. (2017),Mao et al. (2019),Viens & Van Houtte (2020)). + + +349 In this paper, the choice of substack length is guided by data-dependent quality gates (the + +350 CC threshold above) rather than a fixed duration, which allows stations with high coherence + +351 to preserve shorter temporal windows and thereby track rapid changes, while stations with + +352 lower SNR substack as needed to achieve stable estimates. + + +353 On the earthquake synthetic, a workable deployment (SNR 4, the same setting used through- + +354 out this section) clears CC~> 0.6 already at a 1-day stack (median CC 0.86); a poor, + +355 coherence-limited deployment (SNR 0.5) needs 14 days of substacking to clear the same + +356 bar (Fig.~7a). The two regimes behave differently past that point, too. For the workable + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 2 +357 deployment, RMS is U-shaped: it falls from ∼ 0.044 % at 1 day to a minimum ∼ 0.020 % + +358 around 7–10 days, then rises again to ∼ 0.038 % by 60 days as the stack smears the step + +359 (Fig.~7b) — the classic noise-versus-smearing tradeoff, and the reason “longer is always + +360 better” is wrong even once the coherence gate is satisfied. For the poor deployment, RMS is + +361 still falling at 60 days (∼ 0.067 %, down from ∼ 0.71 % at 1 day): the noise floor dominates + +362 over the whole tested range, and the smearing penalty never gets the chance to show up. + +363 Both regimes underestimate the coseismic step’s amplitude at every stack length tested here + +364 (the bias stays negative throughout for the poor deployment, and only crosses zero past 45 + +365 days for the workable one), so a recovered step should be read as a lower bound on the true + +366 drop, more so the longer the stack. + + + + + Figure 7. Substacking on the earthquake synthetic, at two deployment qualities. (a) Median + stretching correlation coefficient versus stack length; the dashed line is codameter’s own CC-gate + threshold (Section 3). (b) RMS error and the absolute bias in the recovered coseismic-step amplitude, + both against the known truth, log scale. + + + +367 Scale of effect: for a workable deployment, the noise/smearing tradeoff bottoms out around + +368 7–10 days at RMS ∼ 0.02 %; for a poor deployment, substack at least ∼ 2 weeks just to clear + +369 the coherence gate, and expect RMS an order of magnitude worse even after clearing it. + + +370 The accepted range for each of these parameters across the published literature is catalogued + 22 M. A. Denolle + + + + + Figure 8. Parameter choices. (a) Frequency band selects depth and signal. (b) A coda window + does not transfer across bands. (c) Reference strategy: a moving reference differences the trend + away unless its increments are cumulated; a fixed reference and the joint inversion retain it. (d) + Stacking length smears the coseismic step. + +371 directly, study by study, in the survey of Appendix~C (Table~A1): the frequency band, + +372 coda window, estimator, and uncertainty treatment actually reported by 103 ambient-noise + +373 𝛿𝑣/𝑣 studies. + + + +374 3.7 Coda window + + +375 The coda window is not independent of the frequency band — it deserves its own treatment + +376 because the two covary strongly, and getting this wrong is one of the larger, more avoidable + +377 sources of error in §3. Because intrinsic and scattering attenuation both grow with frequency, + +378 high-frequency coda energy falls into the noise floor much sooner than low-frequency coda: + +379 a coda window that is well past the direct arrival for a ∼ 0.3–0.8 Hz band is, at ∼ 3–6 Hz, + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 2 +380 sampling almost pure noise (Fig.~8b). On our synthetic, a fixed 20–40 s window at the high + +381 band gives RMS error ∼ 3.9 % (the noise floor, not the signal), while a window hand-adapted + +382 to the band (3–12 s) recovers the truth at ∼ 0.01 % — nearly a 400× difference from this + +383 one choice alone. This is itself an instance of a literature-documented tension: band-matched + +384 windowing is recommended, but Table~A1 shows many surveyed studies instead reuse one + +385 fixed window across bands. + + +386 Hand-adapting the window per band, as above, requires knowing the band in advance and + +387 re-tuning per deployment. A more principled alternative — used in our group — is to track + +388 the coda envelope directly and stop the window where it flattens onto the noise floor, rather + +389 than pre-specifying a window from a rule of thumb. We implement this by band-passing a + +390 long-term reference stack, smoothing its envelope, estimating the noise floor from a common + +391 late-lapse window, and taking the window end as the first lapse time past a short onset where + +392 the envelope stays within a factor of that floor for a sustained interval (not a single noisy + +393 dip). Applied blind (without being told which band it is) to three bands spanning low, mid, + +394 and high frequency (Fig.~9a), the detector recovers windows of ∼ (3, 29) s, ∼ (3, 37) s, and + +395 ∼ (3, 14) s respectively — correctly shrinking at the high band, though the low-versus-mid + +396 ordering is not perfectly monotonic on this synthetic (an artifact of how the fixed additive + +397 noise floor interacts with each band’s filter, not a claim that the detector is exact). Recovering + +398 𝛿𝑣/𝑣 with each band’s own detected window instead of one universal fixed (10–30 s) window + +399 (Fig.~9b) gives RMS ∼ 0.030 % vs. ∼ 0.036 % at the low band (a modest, ∼ 1.2× gain), + +400 ∼ 0.017 % vs. ∼ 0.035 % at the mid band (∼ 2×), and ∼ 0.020 % vs. ∼ 2.0 % at the high + +401 band (∼ 100×) — the fixed window is adequate at low frequency and catastrophic at high + +402 frequency, while the envelope-derived window is close to the best achievable at every band + +403 without ever being told what band it is measuring. + 24 M. A. Denolle + + + + + Figure 9. Coda window / frequency-band covariation. (a) Smoothed coda envelopes at three bands + (log scale), shaded by each band’s envelope-detected window — shrinking automatically at higher + frequency. (b) RMS error against the known truth for a single universal fixed window versus each + band’s own envelope-derived window: comparable at low frequency, ∼ 93× better at high frequency. + +404 3.8 Causal and acausal branches + + +405 In a symmetric cross-correlation, both sides of the coda (positive or negative lags) should + +406 exhibit the same 𝛿𝑣/𝑣. Due to the directionality of the wavefield recorded at the two stations, + +407 the correlated wavefield in the coda may differ (Stehly et al., 2006). While the interpretation + +408 of such coda in terms of Earth’s structure effect is difficult (Snieder et al., 2002), the stability + +409 of the wavefield excited in the coda is the main requirement for stable 𝛿𝑣/𝑣 measurements + +410 (Hadziioannou et al., 2009). Given the challenge in interpreting both sides independently, + +411 researchers typically measure 𝛿𝑣/𝑣 on each lag and then report its average (Kidiwela et al., + +412 2026). The causal (positive-lag) and acausal (negative-lag) branches sample opposite-direction + +413 paths with different source-side illumination, and in a 3D medium their sensitivity kernels + +414 sample partly different volumes, so the two can report genuinely different 𝛿𝑣/𝑣 without either + +415 being wrong. Two regimes bound the choice (Fig.~10). When a change is localized to the + +416 volume one branch samples, symmetrizing or averaging the branches — the common default + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 2 +417 — dilutes it toward zero, while the branch that carries the change recovers it (Fig.~10a); here + +418 preferring the branch of greatest change is a researcher’s judgement. When instead both + +419 branches share the same change, their difference is measurement noise, and selecting the + +420 branch of greatest change over-reports it — a max-of-two-estimators selection bias that grows + +421 as SNR falls (Fig.~10b). When both sides exhibit the same change (sign, coherence) but with + +422 different magnitude, it is reasonable to use the 𝛿𝑣/𝑣 of greatest change given the already low + +423 sensitivity in coda waves (Obermann et al., 2013). An acceptable workflow is to measure + +424 both branches, evaluate on that consistency, select by the coherence of the change rather + +425 than its amplitude (a criterion independent of the answer, so it carries no selection bias), + +426 and carry the between-branch difference as an explicit term of the measurement covariance + +427 𝐶𝑑 (Section~5) rather than discarding it by averaging. + + + + + Figure 10. Combining the causal and acausal branches. (a) A change localized to the volume the + causal branch samples: averaging the branches dilutes it to about half, while the branch carrying + it recovers the truth. (b) The same change on both branches: selecting the branch of greatest + change over-reports the drop, worsening as SNR falls (a selection bias), while the branch mean + stays unbiased. + 26 M. A. Denolle +428 3.9 Choices that create spurious 𝛿𝑣/𝑣 + + +429 Some choices may create spurious signal. A station clock error delays the whole correlation + +430 by a lapse-independent shift, producing an apparent 𝛿𝑣/𝑣 that appears with opposite sign + +431 on the causal and acausal branches; measuring the two branches separately is the diagnostic + +432 (Fig.~11a). Seasonally varying noise sources warp the low-SNR late coda, so a late measure- + +433 ment window reports a coherent spurious seasonal 𝛿𝑣/𝑣 many times the real signal while an + +434 earlier window stays clean (the waveform-level version of Zhan et al., 2013) (Fig.~11b). + + +435 Biases from spurious arrivals could be quantified but mostly we should decontaminate our + +436 workflow from these artefacts or not interpret the results. + + + + + Figure 11. Deviations that create spurious 𝛿𝑣/𝑣. (a) A clock drift splits the causal and acausal + branches with opposite sign. (b) Seasonal late-coda noise injects a spurious seasonal 𝛿𝑣/𝑣 into a + late window but not an early one. + + + +437 Taken together, the choices compound. We make this concrete in Section~4 by running the + +438 full multiverse of best-practice and deviation choices on one synthetic dataset and ranking + +439 each by the bias and the error-bar change it induces. + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 2 +440 4 THE COMBINED IMPACT OF PROCESSING CHOICES + + +441 The scenario is a single representative station pair monitoring a shallow volcanic edifice, + +442 in the style of the permanent broadband deployments used at effusive/dome volcanoes + +443 such as Piton de la Fournaise (Brenguier et al., 2008b): a coda band matched to shallow + +444 depths (0.4–1.0 Hz), a coda window past the direct arrival (10–30 s), and daily correlations + +445 sampled every 3 days over 2.5 years at a per-day correlation-coefficient SNR of 7, typical of + +446 a continuously operating station. The synthetic ground truth combines an annual seasonal + +447 𝛿𝑣/𝑣 cycle (as from near-surface thermoelastic/hydrologic effects), a slow pre-eruptive inflation + +448 ramp, and a sharp co-eruptive velocity drop with partial recovery. This single-pair scenario + +449 isolates the measurement-step choices from the network-aggregation choices already covered + +450 in Sections~3.2–3.3. + + +451 The previous sections only identified single choices, but the overall research workflow involves + +452 them all. We now estimate the combined effects of these parametric choices. Starting from + +453 a single best-practice baseline (trace stretching, a band matched to the target depth, a + +454 coda window well past the direct arrival, a 10-day stack, a long stable reference, coherence + +455 gating; the cross-cutting rules of Brenguier et al. (2014; Weaver et al., 2011; Clarke et al., + +456 2011) as distilled in our survey), we change one parameter at a time to a deviation from best + +457 practice documented in the literature and measure the resulting error against the known truth + +458 (Fig.~12). The ranking is unambiguous: relative to a best-practice RMS error of ∼ 0.03 %, + +459 the two-dimensionally-unwrapped WCS estimator is catastrophic here (∼ 50× worse), a + +460 wrapped-phase MWCS inflates the error by roughly an order of magnitude (∼ 12×), and + +461 DTW by ∼ 6×; among the non-estimator choices a moving reference is worst (∼ 5×, and + +462 most distorts the recovered drop), while stack length, coda window, and frequency band + 28 M. A. Denolle +463 deviations are each more modest (1.5–2.5×). The joint-inversion reference stays closest to + +464 the fixed-reference baseline among the reference-scheme deviations. + + + + + Figure 12. One-at-a-time deviations from a best-practice baseline, ranked by the bias they inject + (a, log scale) and by how they distort the recovered co-eruptive drop (b, symlog). Bars are coloured + red when the error exceeds three times the baseline. The estimator and reference choices dominate; + the band and gating are minor for this scenario. + + + +465 We test the compounding effects of these choices through 108 reasonable workflows selecting + +466 three estimators, two frequency bands, three coda windows, three stacking lengths and + +467 two reference schemes on a synthetic “volcano” dv/v time series that includes a seasonal + +468 oscillation, a slow pre-eruptive inflation ramp, and a sharp co-eruptive drop with partial + +469 exponential recovery (Fig.~13a). The per-day standard deviation across the 108 pipelines + +470 varies by a factor of ∼ 4–5 over the time series (from ∼ 0.4 % to ∼ 1.7 %), and is widest + +471 exactly at the sharp co-eruptive drop; the RMS error against the known truth spans over + +472 two orders of magnitude across pipelines (∼ 0.02–2.8 %). + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 2 +473 Attributing the variance of the outcome to each axis with a first-order (main-effect) sensitivity + +474 index (Fig.~13b) shows that, for this dataset, the coda window controls the RMS error + +475 most, with the estimator second and the stack length third; for the recovered drop amplitude + +476 the order changes to stack length first, window second, and estimator third. The first-order + +477 indices sum to well under one in both cases (∼ 0.66 for RMS, ∼ 0.63 for the drop), so a large + +478 part of the spread is interaction between choices compounding. The appropriate object is + +479 therefore not a single curve but a distribution of 𝛿𝑣/𝑣 over the processing choices. + + + + + Figure 13. The full multiverse. (a) 108 reasonable pipelines on one dataset, each coloured by its + RMS error against the truth on a colourblind-safe scale (bright accurate, dark biased; the worst + run off the clipped axis); the grey band is the 10–90% inter-pipeline spread, widest at the velocity + drop. (b) First-order variance attribution: which choice controls the RMS error and the recovered + drop. Window, estimator, and stack length dominate, in that order for RMS and reordered for the + drop; the sub-unity sum signals strong interactions. + + + +480 Table~3 summarizes this into the measurement-step best practice and the documented + +481 deviation for each choice, with the consequence the synthetic makes concrete. The baseline + +482 and deviation sets are the ones our survey extracts from the literature (the cross-cutting + +483 rules of Snieder et al. (2002; Clarke et al., 2011; Weaver et al., 2011; Brenguier et al., 2014; + +484 Wang et al., 2017; Obermann & Hillers, 2019)) and are implemented in codameter. + 30 M. A. Denolle + + Table 3. Measurement step: best practice versus the common deviation and its consequence. Rows + are the axes swept in Fig. 13; the sets follow the literature survey (Appendix C). + + Choice Best practice Common deviation Consequence + + Estimator Stretching family Wrapped-phase MWCS (Clarke Cycle-skips at large 𝛿𝑣/𝑣; error + (TS/WTS/WCC), robust at low et al., 2011) without 2-D inflated ∼ 10× or catastrophic + SNR and large 𝛿𝑣/𝑣 (Mikesell unwrapping (Mao et al., 2020) + et al., 2015; Yuan et al., 2021) + Frequency band Matched to the target depth: Off-target or a single wide band Mixes depths; here mostly sets + ∼ 0.1–2 Hz (volcano, crust), precision + 2–4 Hz (aquifer), 4–12 Hz + (shallow damage) (Obermann + et al., 2013, 2016) + Coda window Lapse window past the direct Fixed late window reused across Measures noise at high 𝑓; bias + arrival, scaled with the band: bands and inflated 𝜎 + ∼ 5–30 s (crustal) up to ∼ 100 s + (station pairs) (Obermann et al., + 2013) + Stack length Short enough to resolve the Over-long stack (∼ 45 d) Smears and delays a step; + transient (∼ 10 d), on a long, distorts the recovered drop + stable reference span (Wang + et al., 2017) + Reference Long fixed stack or all-to-all Moving / trailing reference Erases slow trends + joint inversion (Brenguier et al., + 2014; Wang et al., 2017) + Coherence gating Discard low-coherence epochs No gating Keeps corrupted epochs; changes + (CC / SNR threshold) (Clarke the effective 𝑁 + et al., 2011) + √ + Uncertainty State it explicitly: Left unstated Factor 𝑁 ambiguity in + definition within-measurement (Weaver significance (Fig. 3) + et al., 2011; Clarke et al., 2011) / + SE / SD + + +485 Running this many pipelines is only practical if each one is cheap. Testing codameter against + +486 a larger, multi-year deployment surfaced real bottlenecks in the per-day estimator loop, + +487 which we removed with three vectorized fast paths: a trailing stack built from a difference + +488 of cumulative sums instead of a per-day mean (roughly 2× at a 45-day stack length), a + +489 vectorized moving-reference stretching estimator that computes the stretch-interpolation + +490 weights once per trial epsilon instead of once per day (roughly 3× on a 3-year synthetic), + +491 and, for ensembles that share a band, a single shared band-pass instead of one per pipeline + +492 member (roughly 3× on a 5-member ensemble). All three reproduce the loops they replace to + +493 within 10−15 in 𝛿𝑣/𝑣 (regression-tested at atol = 10−12 ); the reported ratios are wall-clock, + +494 vary with system load, and should be read as “roughly 𝑁 ×,” not exact. + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 3 +495 5 A BAYESIAN MEASUREMENT MODEL AND ITS DATA + +496 COVARIANCE + + +497 If the processing choice controls the answer, the principled response is not to select a single + +498 pipeline but to treat the choice as a nuisance parameter with a prior and marginalise it + +499 out. We propose this as the new best practice for the 𝛿𝑣/𝑣 measurement, and implement it + +500 as a Bayesian hierarchical inversion. For configuration 𝑘 drawn from a prior over reasonable + +501 pipelines we obtain a measured series 𝑚𝑘 (𝑡) with a coherence-limited within-method floor + +502 𝜎𝑘 (𝑡) (Weaver et al., 2011; Clarke et al., 2011), and posit + + + 𝑚𝑘 (𝑡) = 𝜇(𝑡) + 𝛽𝑘 + 𝜀𝑘 (𝑡), 𝛽𝑘 ∼ 𝒩(0, 𝜏 2 ), 𝜀𝑘 (𝑡) ∼ 𝒩(0, 𝑠2 𝜎𝑘 (𝑡)2 ), (2) + + +503 with a second-difference random-walk smoothness prior on the latent true series 𝜇(𝑡). Here + +504 𝛽𝑘 is configuration 𝑘’s methodological bias (the systematic offset between, say, MWCS and + +505 stretching), 𝜏 its scale across the ensemble, and 𝑠 rescales the Weaver floor so the data report + +506 whether it is calibrated. A conjugate Gibbs sampler, implemented in codameter with no + +507 external sampler dependency, returns the joint posterior. + + +508 The model yields two distinct objects, and conflating them is the error the field makes + +509 (Fig.~14). The posterior of 𝜇 is the precision of the combined estimate: it is tight and shrinks + +510 with ensemble size — yet it under-covers the truth, because the configurations share a + +511 common-mode bias that averaging cannot remove. The object a downstream depth or stress + +512 inversion must consume is the marginal measurement covariance + + + 𝐶𝑑 (𝑡, 𝑡′ ) = 𝐷𝑅𝐷 + ⏟ + 2 11⊤ , + 𝜏⏟ 𝐷 = diag(𝜎tot (𝑡)), + within ⊕ methodological, temporally correlated common mode + (3) + +513 with 𝜎tot + 2 + = 𝑠2 𝜎𝑘2 -average + methodological variance and 𝑅𝑖𝑗 = 𝑒−|𝑡𝑖 −𝑡𝑗 |/𝐿 for a correlation + 32 M. A. Denolle +514 length 𝐿 estimated from the ensemble residuals. This 𝐶𝑑 is time-dependent — wider at + +515 the sharp drop and at low coherence — and its temporal correlation plus common-mode + +516 term collapse the effective number of independent epochs by an order of magnitude. On our + +517 synthetic the marginal 𝐶𝑑 covers the truth at the nominal rate while the naive posterior + +518 band does not, making concrete that the measurement covariance, not the posterior of the + +519 averaged series, is what must be propagated. + + + + + Figure 14. The Bayesian measurement model. (a) The processing ensemble (grey) is marginalised + into a posterior mean (purple) with a narrow credible band (the estimator precision) and a much + wider ±2𝜎 band from the marginal 𝐶𝑑 (the honest data error), which covers the truth where the + credible band does not. (b) The resulting time-dependent data covariance 𝐶𝑑 . (c) Its diagonal 𝜎𝑑 (𝑡) + decomposed into within-method and methodological parts, rising at the eruption; the posterior-of- + the-mean (dotted) is far tighter, and 𝑁eff is a fraction of the epoch count. + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 3 +520 6 PROPAGATING 𝛿𝑣/𝑣 ERRORS AT DEPTH Δ𝛽/𝐵𝐸𝑇 𝐴(𝑍) + + +521 The remaining sections present a framework rather than new synthetics: they set out how + +522 the covariance of Section~5 propagates down the inference chain, and ground each step in + +523 what the monitoring literature does and does not yet report. The executable stages are in + +524 development in the open codameter package (Section~8). + + +525 The field has converged on one physical rule for depth — depth is set by the frequency band + +526 and the coda lapse time, it is not assumed (Obermann et al., 2013, 2016) — and, increasingly, + +527 on multi-band measurement as the means to resolve it (Takano et al., 2017; Feng et al., 2020; + +528 Mao et al., 2022, 2025). The step from a set of per-band 𝛿𝑣/𝑣 series to a depth profile is + +529 where reporting is least consistent: many studies read a single band as a single depth, only + +530 a few invert several bands against surface-wave sensitivity kernels, and the propagation of + +531 the measurement error into the depth estimate is seldom shown. The depth assignment is + +532 frequently the scientific claim itself — whether the change lies in the aquifer or the overlying + +533 soil, whether coseismic softening is a shallow site response or slip on the fault at depth + +534 (Rubinstein & Beroza, 2005) — so a depth reported without its uncertainty cannot support + +535 that claim. + + +536 A 𝛿𝑣/𝑣 measured in band 𝑏 is not a point sample but a weighted integral over depth, + + ∞ + 𝛿𝑉𝑆 + ( 𝛿𝑣 + 𝑣 ) =∫ 𝐾𝑏 (𝑧) (𝑧) d𝑧 + 𝜀𝑏 , (4) + 𝑏 0 + 𝑉𝑆 + +537 where 𝐾𝑏 (𝑧) is the (Rayleigh-wave) depth-sensitivity kernel for band 𝑏 and 𝜀𝑏 carries + +538 that band’s measurement covariance from Section~5. Stacking bands gives a linear sys- + +539 tem d = G m + 𝜀 with G𝑏𝑧 = 𝐾𝑏 (𝑧) and data covariance 𝐶𝑑 ; the Bayesian solution under a + +540 smoothness prior returns a depth profile 𝛿𝑉𝑆 /𝑉𝑆 (𝑧) together with its posterior covariance + 34 M. A. Denolle +541 𝐶𝑚 (𝑧), implemented in codameter. The bands must sit where the kernels resolve: too low + +542 and the kernel leaks into the half-space, too high and the coda is incoherent (Section~3.4). + +543 The width of 𝐶𝑚 (𝑧) — not the profile alone — is the deliverable, and it inherits the temporal + +544 correlation and common-mode structure of 𝐶𝑑 . + + +545 One assumption is usually left implicit: that a 𝛿𝑣/𝑣 change is a shear-velocity change alone. + +546 In partially saturated ground it is not. Filling or draining pore space changes both the shear + +547 modulus and the bulk density, so for the shear-dominated coda the observed change mixes + +548 the two, + + 𝛿𝑣 𝛿𝜇 𝛿𝜌 + ≈ 12 − 12 , (5) + 𝑣 𝜇 𝜌 + +549 and velocity alone cannot separate them. A petrophysical model — Gassmann fluid substitu- + +550 tion for the modulus and a porosity–saturation relation for the density (Gassmann, 1951; + +551 Mavko et al., 2009) — is what breaks the degeneracy, at the cost of its own prior uncertainty + +552 on porosity, fluid modulus, and the saturation path. Hydrological and cryospheric targets, + +553 where saturation varies strongly (Clements & Denolle, 2018; James et al., 2019), are precisely + +554 where neglecting the density term biases the inferred velocity change and, downstream, the + +555 stress. The framework carries 𝛿𝜌/𝜌 as a second inverted field with its own kernel and reports + +556 how much of the surface 𝛿𝑣/𝑣 each explains; the executable version is a documented extension + +557 (Section~8). + + + + +558 7 TOWARD A SCALABLE DEPLOYMENT + + +559 Every result so far is on a truth-known synthetic, by design (Section~2): it is the only way to + +560 separate a processing artefact from a real signal. The next step is to test whether the same + +561 measurement machinery holds up against real data at deployment scale, not just against a + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 3 + + Table 4. Depth step: best practice versus the common deviation in going from per-band 𝛿𝑣/𝑣 to a + depth profile, and the consequence for the interpretation. + + Choice Best practice Common deviation Consequence + + Depth assignment Invert several bands against Read one band as one depth No depth resolution and no + sensitivity kernels depth error + Band selection Bands where the kernels resolve Convenience band Kernel leaks; unstable inversion + (no half-space leak, coherent + coda) + Measurement error Propagate the per-band 𝐶𝑑 into Plot a profile with no covariance Overconfident depth attribution + the profile + Saturation Separate 𝛿𝑉𝑆 /𝑉𝑆 and 𝛿𝜌/𝜌 Assume a pure 𝛿𝑉𝑆 /𝑉𝑆 change Biased velocity change and + with a petrophysical model in stress in hydrological and + partly saturated ground cryospheric targets + Velocity model State the reference 𝑉𝑃 , 𝑉𝑆 (𝑧) Fixed, unstated model Hidden systematic in the kernels + and its uncertainty and the moduli + + +562 synthetic that was built to resemble it. We are building a companion cloud pipeline that + +563 correlates real continuous waveforms for station CI.LJR (Lake Hughes, California) — the + +564 reference station of Clements & Denolle (2023) — pulled from the public Southern California + +565 Earthquake Data Center S3 archive, using the NoisePy package (Jiang & Denolle, 2020) + +566 for the correlation step. Correlation and dv/v estimation each run as a cloud batch job on + +567 spot compute; dv/v estimation itself is handed to the same codameter measurement and + +568 uncertainty functions this paper’s synthetic results are built on, with baseline processing + +569 configurations drawn from the same recommendation logic — not a separate reimplementation. + +570 The retrospective run is validated against the already-published Clements & Denolle (2023) + +571 CI.LJR result before any new claim is drawn from it. + + +572 After the correction, single-station 𝛿𝑣/𝑣 (NoisePy correlations, a codameter 5-member + +573 ensemble, 2–4 Hz, 2018–2019) validates against the published Clements & Denolle (2023) + +574 product. The comparison is not trivial to get right: the CD2023 90-day-comp product is + +575 a trailing 90-day stack, so it lags a centered-smoothed daily series by about 45 days, and + +576 comparing without matching that smoothing caps the correlation near 0.7 even on a real + +577 annual cycle (Fig.~15). We match by applying the same trailing 90-day mean to the daily + +578 series, compare demeaned — the two products reference different epochs, and a constant offset + 36 M. A. Denolle +579 is bookkeeping, not error — and exclude the first 150 days of each station’s series as reference + +580 burn-in. Under this matched comparison, CI.LJR reaches 𝑟 = 0.990 (681 overlapping days); + +581 CI.ARV reaches 𝑟 = 0.66–0.92 depending on the join method, reflecting real 2018 data gaps; + +582 CI.RXH reaches 𝑟 = 0.68, the weakest of the three, on a station whose recovered 𝛿𝑣/𝑣 is + +583 nearly flat and whose signal is low to begin with. + + + + + Figure 15. Single-station 𝛿𝑣/𝑣 at three CI stations, 2018–2019, against the published Clements & + Denolle (2023) product (dashed, reference-shifted). Daily 𝛿𝑣/𝑣 (points) with the ensemble spread + (shaded, epistemic) and measurement error bars, and a 45-day-smoothed curve. The annotated 𝑟 is + computed on this 45-day-smoothed comparison, not the smoothing-matched comparison reported + in the text; matching CD2023’s own trailing 90-day window instead of a centered 45-day one raises + 𝑟 at every station (to 0.990/0.66–0.92/0.68 for LJR/ARV/RXH), which is why the two numbers + differ. + + +584 Why validation quality differs so much by station is visible in the correlation function itself + +585 (Fig.~16). CI.LJR shows a stable, narrow coda near zero lag through the year. CI.RXH + +586 shows multipath, several coherent arrivals spread across the full ±8 s of lag shown, and a + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 3 +587 visible shift in that pattern in April–May 2019, consistent with a site change rather than a + +588 processing artefact. CI.ARV’s coherent energy is compact and concentrated near zero lag but + +589 comparatively sparse, consistent with its higher scatter and join-method sensitivity. + + + + + Figure 16. Daily north-south/east-west cross-component correlation functions, 2–4 Hz, ±8 s lag, + 2019. CI.LJR’s coda is stable and narrow. CI.RXH shows multipath (several coherent bands across + the full lag range) and a shift in that pattern in April–May 2019. CI.ARV’s coherent energy is + compact and near zero lag but comparatively sparse. The visual difference is the reason validation + quality differs by station in Fig. 15. + + + +590 As an optional supplement, Fig.~17 shows the ensemble’s warm-up behaviour on a separate + +591 90-day smoke run at CI.LJR: 𝛿𝑣/𝑣 is undefined until enough history has accumulated for + +592 the moving-reference member to compute a trailing reference, and each band’s per-epoch + +593 stretching correlation coefficient is reported alongside the recovered series. + + + + +594 8 DISCUSSION + + +595 The experiments above share one finding: for ambient-noise 𝛿𝑣/𝑣, the dominant control on + +596 both the reported value and its uncertainty is frequently the processing choice, not the data. + +597 This is a consequential but tractable problem. We suggest three responses. + + +598 Report the choices. At minimum, a 𝛿𝑣/𝑣 study should state the estimator and its param- + 38 M. A. Denolle + + + + +Figure 17. CI.LJR single-station 𝛿𝑣/𝑣, a separate 90-day smoke run (January–April 2023), four +frequency bands. The ensemble spread (shaded) and measurement error bars are reported once at +least one member is defined; the annotated member count grows as the moving-reference member’s +warm-up period elapses, reaching all 5 members later in the window. Bottom panel: per-band +stretching correlation coefficient. + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 3 + + Table 5. A minimal reporting checklist for an ambient-noise 𝛿𝑣/𝑣 study. Stating these turns an + undocumented, irreproducible choice into an inspectable one and makes error bars comparable + across studies. + + Step What to report + + Pre-processing Time-domain normalization (one-bit / running-mean), spectral whitening band, sampling rate + Correlation & stacking Components computed, segment length, daily/sub-stack length, total reference span + Estimator Method (TS / WCC / DTW / MWCS / WCS / WTS / WTDTW), its parameters (𝜀-grid, or + sub-window length and step), and whether the phase is unwrapped + Frequency band(s) [𝑓1 , 𝑓2 ] for every reported measurement + Coda window(s) [𝑡1 , 𝑡2 ], the branch(es) used, and how 𝑡1 , 𝑡2 were set relative to the band + Reference Scheme (total stack / trailing / inversion) and period + Component aggregation Approach A or B; weighted (by what) or unweighted + Pair / network Spatial averaging and weighting scheme + aggregation + Uncertainty The exact definition of the quoted error: within-measurement (e.g. Weaver), + between-component/pair standard error, or standard deviation + Quality control CC / SNR thresholds, rejection criteria, resulting effective 𝑁 + Software Package, version, and the parameter file or its DOI + + +599 eters, the frequency band(s) and coda window(s) and how the window was set relative to the + +600 band, the reference scheme, the stacking, the cross-component and station-pair aggregation + +601 and weighting, and — critically — the exact definition of the quoted uncertainty (within- + +602 measurement error, between-component/pair standard error, or standard deviation). Our + √ +603 results show that the last item alone can change a stated 1𝜎 by 𝑁. Table~5 collects this + +604 into a minimal reporting checklist, and Appendix~C shows how unevenly these items are + +605 reported across the literature today. + + +606 Quantify the choice-induced uncertainty. Where a choice is not forced by the physics, + +607 it can be sampled. Pushing a distribution of reasonable processing choices through the + +608 measurement-error floors of Clarke et al. (2011; Weaver et al., 2011) yields, by the law + +609 of total variance, a marginal 𝛿𝑣/𝑣 uncertainty that includes the processing-choice spread + +610 — a more honest error bar than any single pipeline provides, and the natural input to a + +611 depth/stress inversion. Section~5 makes this a Bayesian measurement model whose deliverable + +612 is a time-dependent data covariance 𝐶𝑑 . + + +613 Make it executable. All synthetics, estimators and figures in this paper are released in + 40 M. A. Denolle +614 the open codameter package, which reproduces every result with a single command and is + +615 unit-tested. An executable record turns an undocumented choice into a versioned, inspectable + +616 one, and lets a reader re-run a study’s pipeline on the truth-known synthetic to see its bias + +617 before trusting it on data. + + +618 Validate against something you did not generate. Every synthetic test in this paper + +619 passed before the discovery below, and that is exactly the danger: a synthetic built under the + +620 same sign convention as the estimator reading it will always agree, whether the convention + +621 is physically correct or not. Testing codameter’s estimators against a real cross-network + +622 deployment (Section~7), recovered 𝛿𝑣/𝑣 anticorrelated with the published Clements & Denolle + +623 (2023) product and with seasonal hydrology at three stations (𝑟 = −0.69, −0.45, −0.40). + +624 Ground-truthing through the exact call path made the cause obvious: imposing a +0.5 % + +625 velocity change returned −0.50 %. The synthetic generator and all seven estimators had + +626 consistently used the stretch factor 𝜀 (positive for a coda dilation, i.e. a slowdown), not + +627 physical 𝛿𝑣/𝑣 (positive for a speedup) — internally coherent, so every synthetic-recovery test + +628 in the sections above passed, but opposite to the sign convention the field expects and to the + +629 published product it was compared against. The fix is the convention boxed in Section~1, + +630 shipped as codameter v0.4.0. Internal consistency is not correctness: a pipeline that only + +631 checks itself will confirm whatever convention it started with, and only the comparison + +632 against an independently-produced result caught this one. The fix and its ground-truthing + +633 procedure are documented in the codameter release history. + + +634 Propagate the covariance, do not truncate it. The measurement covariance is not the + +635 end of the analysis but its first input. Section~6 sets out the next step of the chain: invert the + +636 per-band 𝐶𝑑 through sensitivity kernels for a depth profile and its covariance, separating the + +637 shear-velocity and density contributions where the ground is partially saturated. Converting + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 4 +638 that depth-resolved posterior to stress or strain requires material priors this paper does + +639 not attempt to constrain, and is left to other work; what we deliver is the depth posterior + +640 and its covariance, the object any such conversion must consume. Building and testing the + +641 depth-propagation stage on truth-known synthetics is the natural continuation of this work, + +642 and is under way in the open codameter framework. + + + + +643 9 CONCLUSIONS + + +644 Ambient-noise 𝛿𝑣/𝑣 monitoring rests on a chain of processing choices that are made ad hoc + +645 and reported incompletely. Using a truth-known synthetic and the full estimator suite of + +646 an open toolbox, we have shown that these choices change the recovered 𝛿𝑣/𝑣 and, more + √ +647 consequentially, change the reported uncertainty by a factor of ∼ 𝑁 — enough to flip the + +648 significance of a result — all without touching the data. The remedy is not a single mandated + +649 pipeline but transparency: report every choice, sample the ones the physics does not fix, + +650 carry the resulting measurement covariance into the inference, and release the pipeline as + +651 executable code. The same discipline extends down the inference chain: the measurement + +652 covariance is the input a depth inversion consumes, and only a pipeline that carries the + +653 covariance that far can attach an honest uncertainty to a depth-resolved velocity-change + +654 profile. Converting that profile to stress or strain is a further step this paper does not attempt. + +655 We offer codameter as one such record, and as the package in which the depth stage is being + +656 built. + 42 M. A. Denolle +657 APPENDIX A: ESTIMATOR DEFINITIONS + + +658 Let 𝑟(𝑡) and 𝑐(𝑡) be the reference and current cross-correlations, band-passed to [𝑓1 , 𝑓2 ] + +659 (central frequency 𝑓𝑐 , bandwidth 𝐵) and read over the coda window 𝑊 = [𝑡1 , 𝑡2 ] on one or + +660 both branches. Each method below estimates a trial stretch factor 𝜀, the fractional dilation + +661 of the current coda relative to the reference; physical 𝛿𝑣/𝑣 follows via the convention boxed + +662 in Section~1, 𝛿𝑣/𝑣 = −𝜀/(1 + 𝜀). + + +663 Trace stretching (TS). For each trial stretch factor 𝜀, the current correlation is interpolated + +664 as 𝑐𝜀 (𝑡) = ℐ[𝑐]((1 + 𝜀)𝑡) (interpolation on current only) while the reference 𝑟(𝑡) remains + +665 fixed. The windowed correlation coefficient is + + ∫ 𝑟(𝑡) 𝑐𝜀 (𝑡) d𝑡 + CC(𝜀) = 𝑊 + 1/2 + , 𝜀⋆ = arg max CC(𝜀). (A.1) + (∫ 𝑟2 d𝑡 ∫ 𝑐𝜀2 d𝑡) + 𝜀 + 𝑊 𝑊 + + +666 The best-fit stretch 𝜀⋆ is then converted to physical 𝛿𝑣/𝑣 via 𝛿𝑣/𝑣⋆ = −𝜀⋆ /(1 + 𝜀⋆ ) + +667 as boxed in the Introduction. The single-measurement error decreases with the co- + +668 herence CC, the bandwidth 𝐵, and the window length, approximately as 𝜎𝜀 ∝ + +669 √(1 − CC2 )/CC2 /[𝑓𝑐 √𝐵 (𝑡32 − 𝑡31 )] (Weaver et al., 2011). + + +670 Interpolation direction and convention. The interpolation is applied to the current waveform + +671 and not the reference so that the high-SNR reference stack remains invariant throughout + +672 the epsilon search, which is particularly important when the reference is built as a long- + +673 term or moving average. In the continuous-signal, infinite-support limit the two conventions + +674 (interpolating current versus interpolating reference) are mathematically equivalent after + +675 their fitted parameters are converted to the same physical 𝛿𝑣/𝑣 through the exact relation + +676 𝛿𝑣/𝑣 = −𝜀/(1 + 𝜀). In sampled, finite-window signals, that symmetry is broken: interpolation + +677 error, edge truncation, and the finite support of the data cause the two conventions to give + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 4 +678 slightly different numerical results even when both use the exact conversion. Therefore the + +679 interpolation direction must be reported explicitly and treated as a fixed processing choice. + +680 For diffuse codas in ambient-noise and volcanic monitoring, we have verified that the choice + +681 has a measurable but small effect: truth-known synthetics recover 𝛿𝑣/𝑣 with sub-10−4 bias + +682 when the signal-to-noise ratio is high and the changes are small, with the effect growing as a + +683 few percent at landslide-scale perturbations (𝛿𝑣/𝑣 ∼ 4 %). + + +684 Windowed cross-correlation (WCC). In sub-windows centred at lapse 𝑡𝑖 the delay is + +685 𝛿𝑡𝑖 = arg max𝜏 ∫ 𝑐(𝑡) 𝑟(𝑡 − 𝜏 ) d𝑡; a least-squares fit of 𝛿𝑡𝑖 = −𝜀 𝑡𝑖 gives 𝜀. + + +686 Moving-window cross-spectrum (MWCS). In each sub-window the cross-spectrum is + +687 ̂ 𝑟∗̂ (𝑓) with phase 𝜑(𝑓) = arg 𝑋(𝑓) ≈ 2𝜋𝑓 𝛿𝑡𝑖 ; a coherence-weighted linear fit of + 𝑋(𝑓) = 𝑐(𝑓) + +688 𝜑(𝑓) over [𝑓1 , 𝑓2 ] yields 𝛿𝑡𝑖 , and 𝜀 is minus the slope of 𝛿𝑡𝑖 versus 𝑡𝑖 (Clarke et al., 2011). + +689 Because 𝜑 is defined modulo 2𝜋, the estimate cycle-skips once |𝛿𝑡𝑖 | > 1/(2𝑓). + + +690 Dynamic time warping (DTW). A lag path 𝑙(𝑖) minimises + + + 2 2 + ∑ (𝑐𝑖 − 𝑟𝑖+𝑙(𝑖) ) + 𝛾 ∑ (𝑙(𝑖+1) − 𝑙(𝑖)) , (A.2) + 𝑖 𝑖 + + +691 where 𝛾 penalises strain (limits the lag’s rate of change); 𝜀 is minus the slope of 𝑙(𝑖)/𝑓𝑠 versus + +692 lapse. + + +693 Wavelet cross-spectrum (WCS). With continuous wavelet transforms 𝑊𝑐 , 𝑊𝑟 , the cross- + +694 wavelet spectrum is 𝑊𝑥𝑦 (𝑓, 𝜏 ) = 𝑊𝑐 𝑊𝑟∗ and the delay 𝛿𝑡(𝑓, 𝜏 ) = 𝜑(𝑓, 𝜏 )/(2𝜋𝑓). Unwrapping + +695 𝜑 in two dimensions — along lapse (anchored at 𝜏 → 0, where 𝛿𝑡 → 0) then along frequency + +696 — removes the cycle-skip; 𝜀 follows from the |𝑊𝑥𝑦 |-weighted regression 𝛿𝑡 = −𝜀 𝜏 over the + +697 time–frequency window (Mao et al., 2020). + 44 M. A. Denolle +698 Wavelet stretching / warping (WTS, WTDTW). TS (respectively DTW) is applied + +699 per wavelet scale (respectively to the wavelet-reconstructed band) and the per-scale estimates + +700 are pooled with cross-wavelet-power weights. + + + + +701 APPENDIX B: AGGREGATION AND UNCERTAINTY CONVENTIONS + + +702 For component 𝑘 of a station pair, stretching yields the image CC𝑘 (𝜀, 𝑡); each per-component + +703 stretch factor converts to physical 𝛿𝑣/𝑣𝑘 via the boxed relation. + + +704 Approach A (average the per-component 𝛿𝑣/𝑣). 𝛿𝑣/𝑣𝑘 (𝑡) follows from 𝜀𝑘 (𝑡) = + +705 arg max𝜀 CC𝑘 (𝜀, 𝑡), and the pair estimate is the (possibly weighted) mean 𝑥𝑝 (𝑡) = + +706 ∑𝑘 𝑤𝑘 𝛿𝑣/𝑣𝑘 / ∑𝑘 𝑤𝑘 , with 𝑤𝑘 = max𝜀 CC𝑘 (coherence-weighted) or 𝑤𝑘 = 1 (unweighted). + + +707 Approach B (average the images). The pair stretch factor 𝜀𝑝 (𝑡) = arg max𝜀 [ 𝑁1 ∑𝑘 CC𝑘 (𝜀, 𝑡)] + 𝑐 + + +708 converts to 𝑥𝑝 (𝑡) = 𝛿𝑣/𝑣𝑝 (𝑡) via the same relation. + + +709 Network over pairs. With pair weights 𝑊𝑝 (e.g. mean coherence), + + ∑𝑝 𝑊𝑝 𝑥𝑝 ∑𝑝 𝑊𝑝 (𝑥𝑝 − 𝑥)̄ 2 (∑𝑝 𝑊𝑝 )2 + 𝑥̄ = , 2 + 𝑠 = , 𝑁eff = . (B.1) + ∑𝑝 𝑊𝑝 ∑𝑝 𝑊𝑝 ∑𝑝 𝑊𝑝2 + +710 The three uncertainty conventions used in Section~3.3 are the weighted standard error + √ +711 𝜎SE,𝑤 = 𝑠/√𝑁eff , the unweighted standard error 𝜎SE = std(𝑥𝑝 )/ 𝑁, and the standard + √ +712 deviation 𝜎SD = std(𝑥𝑝 ). They share the mean 𝑥̄ but obey 𝜎SD /𝜎SE = 𝑁. + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 4 +713 APPENDIX C: SURVEY OF PROCESSING CHOICES ACROSS THE + +714 LITERATURE + + +715 Table~A1 catalogues the processing choices of the 103 ambient-noise 𝛿𝑣/𝑣 monitoring studies + +716 we surveyed (the full machine-readable version and provenance are distributed with the + +717 codameter package). It is the empirical basis for the paper’s claim that no convention is + +718 shared: the estimator, the frequency band, the coda window, the reference scheme and + +719 — most unevenly of all — the uncertainty treatment vary study to study, and the last is + +720 frequently unreported. Every study is cited here. + + +721 The four measurement fields (frequency band, coda window, estimator and uncertainty + +722 treatment) were re-checked against the full text for the 82 studies we could read (open + +723 access plus institutional access); for those rows a blank or n/r'' means the value is + +724 genuinely not stated in the paper. The remaining rows were populated from + +725 abstracts and search metadata, wheren/r’ ’ means only that the value was not found + +726 in the abstract, not that the study failed to report it; those cells are flagged in the + +727 machine-readable table (measurement_source) and remain to be filled from the paywalled + +728 full texts. The apparent under-reporting in the table is therefore a lower bound on what the + +729 literature actually states. + + Table A1: Processing choices of the 103 surveyed 𝛿𝑣/𝑣 studies (the literature survey under- + pinning this paper). Every study is cited; n/r = not reported in the source. Frequency band, + coda window, estimator, reference/stack scheme and uncertainty treatment are the choices + Section 3 shows to control the result. + + Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + + Brenguier et al. Piton de la 0.1-0.9 n/r (slope MWCS Daily stacks linear-slope + (2008b) Fournaise, La of dtau vs (doublet) referenced to uncertainty; exclude + Réunion tau; short long-term stack >0.04% + scanning + window) + + continued on next page + 46 M. A. Denolle + Table A1 continued + Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + + Duputel et al. Piton de la 0.1–1 n/r Other Quasi-real-time n/r + (2009) Fournaise, La stacks vs reference + Réunion + Obermann et al. Piton de la 0.1-1.0 10-45 stretching Daily stacks, Weaver et al. + (2013) Fournaise, La referenced; coda coherence-based error + Réunion at increasing lapse formula + times + HotovecEllis Mount St. 1-10 (also windows doublet Stack across ~0.1% from SD of + et al. (2014) Helens, WA, 1-5, 5-10) after S (Snieder several hundred velocity fit + USA arrival; 2002) repeating- + >=5 with earthquake + CCC>0.65 families + (multiplets) + HotovecEllis Mount St. 0.5-10 15 s stretching Combines reduced similarity (CC) + et al. (2015) Helens, WA, window repeating- in stretching window + USA starting 2 earthquake CWI + s after with + first ambient-noise + motion interferometry + Rivet et al. Piton de la 0.25-2 n/r MWCS Daily stacks vs coherency + + (2015) Fournaise, La reference; linear-regression error + Réunion network-averaged + dv/v + De Plaen et al. Piton de la 0.1-1.0, 5-35 MWCS n/r coherency + + (2016) Fournaise, La 0.5-1.0, (both linear-regression error + Réunion 1.0-2.0, branches) QC + (method also 2.0-4.0 + re Kawah Ijen) + Donaldson et al. Kīlauea 0.33-1.0 30 s MWCS Daily NCFs weighted dt-t + (2017) summit, window, (doublet) stacked over 3-day regression; + Hawaii, USA min lag = moving window coherence>0.65, + intersta- err<0.1 s thresholds + tion dist / + 0.8 km/s + Takano et al. Izu-Oshima, 0.5-1, 1-2, -20 to MWCS Cross-correlations error bars from + (2017) Japan 2-4 +20 2012–2015, coherency + multiple bands + Lesage et al. Volcán de 0.125-2 10-80 stretching Daily empirical noise from + (2018) Colima, cross-correlations; AVV fluctuations + Mexico 2013 stack as (~0.05%) + reference + De Plaen et al. Mt. Etna, 1.0-2.0 5-35 MWCS Daily cross-coherence + + (2019) Italy autocorrelations, squared misfit; reject + (2013–2014) 2-day linear stack dt err>0.1 s or + coh<0.6 + Donaldson et al. Northern 0.1-0.4, per-band stretching n/r reject dv/v when + (2019) Volcanic Zone 0.4-1.0, 1-2, (suppl. + MWCS stretched-ref CC<0.4 + (Askja/Bárðar- 2-4, 4-16 Table S1) + bunga), + Iceland + Olivier et al. Kīlauea, 0.08-1.2 30 s MWCS n/r (passive image CCF-coherence-based + (2019) Hawaii, USA windows; interferometry, uncertainty + (2018 start = daily) + eruption) dist/700 + m/s + 30 + s + + continued on next page + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 4 + Table A1 continued + Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + + Yates et al. Whakaari / 0.1-1.0 16 s MWCS n/r QC (err<0.1 s, + (2019) White Island, moving coh>0.7); + New Zealand windows error-weighted mean + within + 20-80 s + Feng et al. Kīlauea, 3-8 [-2.8:-0.4] stretching Jan 2017–Jun absolute error from + (2020) Hawaii, USA and 2018 NCFs stretching CC + [0.4:2.8] + (=[- + 14Dt:2Dt],[2Dt:14Dt]) + HotovecEllis Kīlauea, n/r n/r CWIRE Coda Wave n/r + et al. (2022) Hawaii, USA (stretchingInterferometry + (2018 collapse) + damped with Repeating + LSQ) Earthquakes + (CWIRE), + per-cluster pairs + Köpfli et al. Mount St. n/a n/a n/a (no Long-term NCF n/a + (2024) Helens, WA, (wavefield dv/v; stacks; many dv/v + USA amplitude companion series on a + features, is Makus common grid + not dv/v) 2024) + Yates et al. Mt. Ruapehu, 0.25-2.5 min lag 5 CWT n/r slope SD from + (2024) New Zealand (wavelet s, length (cross- covariance; coherence + (2005–2009) 0.1-8.0) 20 cycles wavelet) weighting + (e.g. 5-25 + at 1 Hz) + Yukutake et al. Izu-Oshima, 0.1-0.9, 20-40 MWCS Long-term 1-2 sigma errors as + (2025) Japan 0.5-2.0, interferometry inversion weights + (2003–2020) 1.0-4.0 stacks, 2003–2020 + Schaff & Beroza 1989 Mw 6.9 n/r 1.4 s doublet Repeating- formal slope SE; CC + (2004) Loma Prieta (unfiltered) moving earthquake weighting + aftershock windows doublets; delays vs + zone, through pre-mainshock + California coda repeaters + (also Parkfield + repeaters) + Pacheco & Theory / n/r n/r Other n/r n/r (analytical kernel) + Snieder (2005) acoustic + diffusion + model + Rubinstein & 2004 M6 n/r n/a doublet Repeating- CC>0.8 and SNR>4:1 + Beroza (2005) Parkfield (direct-S (moving- earthquake QC + earthquake, delays, window travel-time delays + San Andreas not coda) CC) before vs after + fault, mainshock + California + Wegler & Sens- Mid-Niigata 2-100 (2 Hz 5-14 stretching Daily day-to-day fluctuation + Schönfelder (Chuetsu) high-pass) autocorrelations ~0.1%; CC>0.5 + (2007) earthquake vs ~two-week + source region, pre-event + Japan; F-Net reference; grid + station KZK search (10000 + (~24 km) trials, dv/v… + Brenguier et al. Parkfield, San 0.1–0.9 n/r Stretching 1550-day reference Averaged over 78 + (2008a) Andreas fault, vs overlapping receiver pairs plus + California, 5-day moving 5-day segments + USA windows; 30-day + time resolution + + continued on next page + 48 M. A. Denolle + Table A1 continued + Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + + Hadziioannou Laboratory 2.5 MHz 12.5-50 us stretching Noise-correlation analytic std of + et al. (2009) scattering gel ultrasonic (lab) + doublet stacking stretching-CC + (ultrasonic) (lab, not (compared) fluctuations + seismic + band) + Sawazaki et al. Western- n/r n/r Other Coda n/r + (2009) Tottori region, deconvolution of + Japan; surface vs 100-m + KiK-net borehole records + borehole + (surface + 100 + m); 2000 Mw + 6.6 mainshock + Wegler et al. 2004 Mw 6.6 2-8 and 5-14 (2-8 stretching Daily auto-/cross- SD over Green’s-tensor + (2009) Mid-Niigata 0.1-0.5 Hz); correlations components; R>0.5 + earthquake 10-100 inverted daily for + source region, (0.1-0.5 2 months pre/post; + Japan; 6 Hz) pre-event reference + Hi-net/F-Net + stations <25 + km + Chen et al. Sichuan, n/r ~25 s MWCS Noise n/r + (2010) China — 2008 after cross-correlation + Mw 7.9 ballistic, stacking; + Wenchuan up to sub-array + earthquake +-200 s comparison (156 + fault zone lapse broadband + stations) + Nakata & NE Japan 1-13 n/a n/a (not >300 earthquakes SD of travel times over + Snieder (2011) (Honshu), (deconvo- coda/noise (Jan 1–May 26 events + KiK-net; 2011 lution dv/v) 2011); borehole-to- + Tohoku-Oki interfer- surface + earthquake ometry, deconvolution + direct + S-wave) + Rivet etal. Guerrero, 0.037-0.27 n/r (coda doublet n/r previous-epoch + (2011) Mexico (periods used, no (MWCS) referencing; no explicit + subduction 3.7-27 s) length) error bars + zone (2006 + M7.5 slow slip + event) + Hobiger et al. 2008 0.125-0.25, ten stretching Daily CC weighting; + (2012) Iwate-Miyagi 0.25-0.5, periods, cross-correlations 18-component weighted + Nairiku 0.5-1.0 starting vs long-term average + earthquake 7.5 reference Green’s + (Mw 6.9), NE periods function + Japan after + direct + wave + Minato etal. Southern 2-5 2-10 lag stretching n/r SD from + (2012) Tohoku pre/post-seismic values + (Fukushima/Ibaraki), + Japan; 58 + Hi-net + stations; 2011 + Tohoku-Oki + Obermann et al. Numerical 2-D 20 Hz 1.5 s stretching Averaged over 10 std over ten + (2013) elastic media central, ~12 windows, random medium random-media + (lunar-data Hz bw centered realizations per realizations + illustration) (numerical) ~1.8-6.6 s configuration + + continued on next page + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 4 + Table A1 continued + Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + + Brenguier et al. Vol- 0.1–0.9 n/r MWCS Daily Stress sensitivity + (2014) canic/geother- cross-correlations; ~0.001 MPa^-1 + mal regions of linear inferred; detailed dv/v + Honshu, inversion/regular- uncertainty n/r + Japan; 2011 ization for + Mw 9.0 continuous time + Tohoku-Oki series + Liu et al. (2014) Epicentral 0.125-1 (1-8 30-130 MWCS Noise 2-sigma SD across nine + region of 2008 s; subbands cross-correlation components + Mw 7.9 1-2,2-4,4-8 stacking (Aug + Wenchuan s) 2004 – Sep 2011) + earthquake, + China + Taira et al. South Napa, 0.1-0.9 -60 to -20 MWCS MSNoise Jackknife 95% CI; + (2015) California and +20 cross-correlations; 2-sigma SD + (2014 Mw 6.0 to +60 decimated to 20 + South Napa Hz + earthquake) + Gassenmeier Station 1-3, 4-6, 10-15 (for stretching Daily Gaussian fit to + et al. (2016) PATCX, 7-10 4-6 Hz) (autocorre- autocorrelations; correlation values (CIs) + Atacama (primary lation two-step iterative + Desert, 4-6) CWI) reference + Northern + Chile (IPOC) + Hillers et al. San Jacinto 0.2-2 20-50 stretching Average-waveform P-value QC; cc>=0.85 + (2019) fault zone, (sub-bands (also and MWCS reference for inversion + California 0.2-0.4,0.4- 20-40,30- (doublet) stretching; MWCS + (after 2010 0.8,0.8- 50,40-60) also applied + M7.2 El 1.6,0.3-1.5) + Mayor- + Cucapah, + M5.4 Collins + Valley) + Wang et al. NE Honshu, period -400 to doublet Monthly SD error bars from + (2019) Japan (2011 bands 8-30 400 velocity-change 2009-2010 + Mw 9.0 s and 15-50 (moving estimates + Tohoku-Oki s 30 & 50 s) + earthquake) + Mao et al. Salton Sea 0.5-2.0, n/r (real wavelet Noise wavelet cross-spectrum + (2020) Geothermal 0.75-3.0, data); cross- cross-correlation amplitude weighting; + Field, 1.1-2.2, synthetic spectrum stacking coherence threshold + California 1.5-6.0, 18.65-35 (WCS) + (2009–2011) 2.0-8.0 + Poli et al. (2020) L’Aquila 0.5-1 start stretching n/r CC-weighting; cc>0.9 + region, central 10/20/30 (doublet retained + Italy (2009 s, length tested) + Mw 6.3 20/40/60 + L’Aquila s + earthquake) + Boschelli et al. Ridgecrest >1 (1 Hz n/r stretching Daily SD across + (2021) fault zone, high-pass) (variable autocorrelation non-overlapping + California lapse functions vs mean windows + (2019 Mw 7.1 window) waveform + Ridgecrest + earthquake) + Lu & Ben-Zion Ridgecrest, 8.0–12.0 3 (moving Other 10-min stacks; Standard deviations + (2021) California windows, adaptive Gaussian tracked; stabilized via + (2019 Mw 7.1 1.5 s step) smoothing (20 smoothing + Ridgecrest min growing to 24 + earthquake) hr over 3 days) + + continued on next page + 50 M. A. Denolle + Table A1 continued + Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + + Sheng et al. San Jacinto >1 n/r wavelet Weekly stacked dt uncertainty as + (2022) fault, Anza (WTS) correlations with inverse weight + seismic gap, ~2-month + Southern smoothing + California + Mainsant et al. Pont-Bourquin 10-12 0.2-2 stretching Daily noise Weaver et al. (2011) + (2012) landslide, (analyzed (both correlograms CC-based error + Swiss Alps 4-25) sides) (cross-correlation (~1-2%) + (Switzerland) functions) + Voisin et al. Avignonet / ~6-8 n/r Stretching Daily/seasonal Correlation-coefficient + (2016) Mas (annual stacks vs reference weighting; comparison + d’Avignonet dv/v with piezometer + landslide, pattern + Trièves best + (French Alps), resolved) + France + Harba & Pilecki Just- High- n/r (inter- Other Cross-correlation / Dispersion-inversion + (2016) Tęgoborze frequency ferometric interferometric misfit; comparison + landslide, seismic Green’s- stacks; dispersion with MASW + Carpathian noise function inversion + flysch, (~5-20+, retrieval) (neighbourhood + southern dispersion- algorithm) + Poland curve + range) + Bertello et al. Montaguto n/a (active- n/a n/a Time-lapse n/a + (2018) earthflow, source interferometry + + southern Italy ReMi/MASW time-lapse active + dispersion, MASW + not coda + dv/v) + Bièvre et al. Pont-Bourquin ~5-15 n/r Stretching Daily correlations, Correlation coefficient; + (2018) landslide, (surface- multi-year seasonal-cycle + Swiss Alps wave band; reference modeling to separate + (4.5-yr record) reported from precursors + sensitivity + to shallow + layer <=2 + m) + Colombero et al. Madonna del 2-20 0.5-2 (and Stretching Daily correlations, Correlation coefficient + (2018) Sasso cliff, (analysis); symmet- multi-year (~0.9 at low freq) as + NW Italian 2-4 ric -2 to reference reliability metric + Alps (Orta strongest -0.5) (2013-2016) + Lake), Italy annual + signal + Bontemps et al. Maca n/r n/r n/r Daily stacks vs n/r + (2020) slow-moving reference + Andean + landslide, + southern Peru + (3-yr dataset) + Fiolleau et al. Harmalière 1-12 (moni- 0.05-1.5 Stretching Hourly records, Correlation-coefficient + (2020) landslide, toring); daily averaging vs degradation tracked + French dv/v in 2-4 reference across bands; + Western Alps and 8-10 multi-parameter + (collapsed Nov bands; precursor timing + 2016) block + resonance + ~9-16 + + continued on next page + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 5 + Table A1 continued + Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + + Le Breton et al. Global review 1.3-20 end of stretching Daily stacks vs Weaver et al. (2011) + (2021) (9 landslides (commonly direct and long-term rms + SD over + monitored to 10-14; 0.1-1 waves to doublet reference pairs/windows; discard + date) for 5-10 (MWCS) CC<0.6 + large/deep) periods + (site- + dependent) + Xie et al. (2023) Rock slope, High- Sub- Stretching Short-window Decorrelation/CC + southwest frequency second to stacks for rapid checks; rapid-detection + China (~5-20) a few s detection confidence discussion + Liu et al. (2026) Xishan Village 5-25 (raw 0.4-2.0 Stretching 20-min interval 95% confidence interval + landslide, 1-30); 15 CCFs vs reference (~0.05% uncertainty at + Sichuan Hz top ~15 (SNR>4 5 Hz) + Province, m, 5 Hz wave-packet + China 15-40 m selection) + Watlet et al. Hollin Hill 6-10 (plus n/r MWCS Time-lapse none (data report) + (2026) Landslide two interferometry + + Observatory, unspecified MASW between + North bands) recording periods + Yorkshire, UK + (2-yr) + De Wit & Open-pit mine n/r (high- n/r Stretching Time-lapse stacks Decorrelation/CC; + Snieder (2026) slope, frequency vs reference comparison with radar + Australia near- surface deformation + surface) + Sens- Merapi 0.5 Hz 2-8 stretching Daily autocorr vs SD over + Schönfelder Volcano, high-pass yearly reference non-overlapping + & Wegler (2006) Indonesia windows + Tsai (2011) Theoretical n/a (theory n/a n/a n/r n/a + model, applied of thermoe- (analytic + to southern lastic/hy- model, no + California drologic measure- + velocity ment) + change) + Hillers et al. TCDP n/r n/r n/r n/r n/r + (2014) borehole array, + Chelungpu + fault, Taiwan + Lecocq et al. Gräfenberg 0.1-0.8 20-100 MWCS Daily CCFs, LSQ slope error as + (2017) Array (and -20 (Brenguier 31-day rolling inverse-variance weight; + (GRA1-4), SE to -100) all-pairs) window bootstrap + Germany + (karst + limestone + aquifer) + Nimiya et al. Kyushu Island, 0.1-0.9 100 stretching Daily CCFs from SD over six 50-s + (2017) Japan (2016 (+MWCS 30-min segments; subwindows + Kumamoto check) 1-yr reference, + region) 30-day moving + stack + Wang et al. Japan 0.1-0.25 30 s MWCS Daily CCFs; ~1-yr none (QC only: + (2017) (nationwide; and 0.5-2.0 (0.1-0.25 reference, dt<=0.2 s, coh>=0.5) + strongest in Hz), 10 s moving-window + Kyushu/vol- (0.5-2 Hz) current stack + canic + zones) + Clements & De- San Gabriel 0.1-0.25 30 s MWCS Daily stacks vs none (QC only: + nolle (2018) Valley, and 0.5-2.0 (0.1-0.25 reference dt<=0.2 s, coh>=0.5) + California, Hz), 10 s + USA (0.5-2 Hz) + + continued on next page + 52 M. A. Denolle + Table A1 continued + Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + + Kim & Lekic Gulf Coast 0.01-8 n/r stretching Multi-year (~20 none (grid-search CC + (2019) Aquifer, yr) record; max) + southern yearly-scale + Texas comparisons + (IU.HKT near + Houston), + USA + Andajani et al. Chugoku & 0.1-0.9 100 stretching n/r stretching CC as + (2020) Shikoku, SW quality indicator (no + Japan (Hi-net) error bars) + GaubertBastide Crépieux- 2-5 n/a stretching Hourly eps_max +- sigma + et al. (2022) Charmy (ballistic correlations over (stretching variance) + water- Love- 19 days, two + production wave fill/drain cycles + field, Lyon, window, + France not coda) + Illien et al. Nepal 4-8 12 stretching ~3-yr continuous none (multi-reference + (2022) Himalaya (Chaku); periods time series stack) + (2015 Mw7.8 2-4 (~3 s) + Gorkha (Gumba) after + aftermath) 4-period + skip + Mao et al. Coastal Los 2-4 2-8 stretching Daily CCFs cc^2-weighted channel + (2022) Angeles basins, stacked over 20 mean (no explicit error + California, days, 5-day step; bars) + USA pairs <50 km + Clements & De- Statewide 2-4 2-8 stretching Daily stacks across cc^2-weighted channel + nolle (2023) California, ~700 stations vs mean (no explicit error + USA reference bars) + (1999-2021) + Delouche & Greece 0.33-1 (1-3 15-55 stretching n/r Weaver et al. (2011) + Stehly (2023) (aquifer s period) RMS error + monitoring + sites) + Ermert et al. Mexico City 0.5-1, 1-2, 4-10x and stretching Clustered (GMM) CC_best>0.6 QC; no + (2023) basin / Valley 2-4, 4-8 8-20x autocorrelation formal dv/v error + of Mexico longest stacks + period + (e.g. 8-16 + & 16-40 + s) + Fokker et al. Groningen, 1.3-1.6 n/r (coda stretching n/r standard error + (2023) The of cross- sigma/sqrt(n) + Netherlands coherence) + Zhang et al. Central 0.1-1.0 n/r MWCS Continuous SD (avg ~0.009%) + (2023) Oklahoma, (also (dynamic 2013-2022 record + USA 0.3-1.2, windows, + 0.5-1.5, 3.0 & 2.0 + 1.0-2.0) km/s) + Mao etal. Greater Los 0.1-0.3 300 s stretching Daily CCFs Weaver et al. (2011) + (2025) Angeles, window stacked, multi-day error formula + California, from step; two-decade + USA 1.3*t0 record + Mordret et al. Southwest 0.1-0.3 300 s stretching Daily Weaver et al. (2011) + (2016) Greenland ice window cross-correlations error formula + sheet from over ~2-year + 1.3*t0 record + + continued on next page + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 5 + Table A1 continued + Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + + James et al. Interior 3-30 (18 +-0.2 to MWCS Daily 95% CI from posterior + (2019) Alaska (Poker bands; 13 2.0 cross-correlations + Flat / Hz (center stacked; reference + Fairbanks inversion) lag) relative to Jan + area), USA 2014 + Guillemot et al. Gugla rock n/a n/a n/a (no Daily n/a + (2020) glacier, Valais, (resonance- dv/v correlograms from + Switzerland freq computed) hourly raw data + tracking, + not dv/v) + Guillemot et al. Laurichard n/a n/a n/a (no PSD-based; n/a + (2021) (French Alps) (resonance- dv/v finite-element + and Gugla freq computed) modal modeling + (Swiss Alps) tracking, + rock glaciers not dv/v) + Lindner et al. Mt. Zugspitze, 2-8 -5 to 5 lag wavelet 15-year continuous 1 SD + (2021) German/Aus- (analysis cross- record; + trian 1-20) spectrum daily/seasonal + Alps (Morlet) stacks + Luo et al. (2023) Greenland Ice 0.1-1 (also 20-70 MWCS Daily fitted +-sigma; 95% CI + Sheet (GLISN 0.1-0.5, autocorrelations + stations) 1-2) stacked + Gassenmeier Ketzin CO2 1.5-3 moving stretching 1-hour segments Weaver et al. (2011); + et al. (2014) storage site windows cross-correlated, scaling-coeff CIs + (CO2SINK), after 300 stacked to daily + Brandenburg, m/s + Germany phase + Hillers et al. Basel deep n/r Coda of Stretching Daily noise Sensitivity-kernel + (2015) geothermal noise cor- correlations imaging of + (EGS) relations around 2006 velocity-change + reservoir, stimulation location + Switzerland + Obermann et al. St. Gallen 0.1-1 20 s stretching Daily none + (2015) geothermal window cross-correlations; + site, centered reference stacks + Switzerland ~15 s in + coda + Czarny et al. Underground 0.6-1.2 n/r Stretching Continuous n/r + (2016) coal mine, cross-correlations + Upper Silesia, over ~42 days + Poland + Olivier et al. Active tailings 0.25-1.0, 20 s (-40 MWCS Daily two-sigma SD; + (2017) storage facility 0.5-2.0, to -20 and (MSNoise) cross-correlations CC>0.85 rejection + (mine), South 0.75-3.0, 20 to 40) across array + Africa 1.0-4.0, + 1.5-6.0, + 2.0-8.0 + Taira et al. Salton Sea 0.25-1.0, 20 s (-40 MWCS Daily NCFs from two-sigma SD; + (2018) Geothermal 0.5-2.0, to -20 and (MSNoise) 30-min segments; CC>0.85 rejection + Field, 0.75-3.0, 20 to 40) 5-day stacks + California, 1.0-4.0, + USA 1.5-6.0, + 2.0-8.0 + Kristjánsdóttir Hellisheidi n/r n/r Stretching Daily correlations Seasonal and + et al. (2019) geothermal (MSNoise noise-source effects + field, SW workflow) discussed as caveats + Iceland + + continued on next page + 54 M. A. Denolle + Table A1 continued + Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + + Snieder et al. theory + n/a (disper- n/a n/a (not a n/r n/a + (2002) ultrasonic lab sion/pre- velocity- + processing change + paper, no study) + dv/v) + Bensen et al. USArray test 0.1-0.9 6s MWCS daily WLS phase-fit error + (2007) data windows cross-correlation + (corrected ~6x) + overlap- temporal stacking + ping 3 + s + Clarke et al. synthetic + 0.1-0.9 6s MWCS current stack vs WLS phase-fit error + (2011) real noise tests windows reference, (corrected ~6x) + overlap- weighted linear + ping 3 regression dt vs t + s + Hadziioannou urban noise 0.1-0.9 n/r stretching waveform remnant coherence + et al. (2011) autocorrela- (whole (and clustering to (CC) + tions coda doublet) enhance daily + t1-t2) stacks + Weaver et al. theory 0.05-0.5 up to stretching reference vs max CC>0.9 (no + (2011) t0=30 current correlation formal error) + Zhan et al. synthetic + 0.05-0.5 up to stretching reference vs max CC>0.9 (no + (2013) field examples t0=30 current formal error) + Lecocq et al. Piton de la synthetic 1-10 windowed daily CCF + WLS lag-vs-lapse; + (2014) Fournaise (Ricker lapse; sub- CC, reference stack CC>=0.6 + (validation) 12.5; noise windows stretching, + 0.5-30) 0.1-1.0 s DTW + (compared) + Mikesell et al. numerical 0.33-1.0 (dist/1.8)+20 + stretching n/a Weaver et al. (2011) + (2015) CWI examples (1-3 s) to 120 rms formula + Stehly et al. Wenchuan Mw 0.1-1.0 [15,35] stretching daily correlations CC>0.7 rejection; + (2015) 7.9 region (real); and (+MWCS curvelet-filtered ~+-0.1% significance + (test dataset) 0.15-0.65 [-35,-15] compare) before stacking + (synthetic) + Daskalakis et al. synthetic + n/r 1 s over- stretching normalized SD over 20 receivers + (2016) real noise (numerical lapping cross-correlation + study) windows functions + Obermann et al. 3-D wavefield 0.15-0.90 -60 to doublet + n/a Bayesian least-squares + (2016) simulations +60 Bayesian inversion; error bars + (doublet least- from inversion + over squares + coda) inversion + (Brenguier + 2014) + Obermann & review scale- lapse- Other reference and synthesizes error + Hillers (2019) dependent time/depth moving-stack sources: noise-source + depen- strategies reviewed variability, processing + dent choices, sensitivity + ker… + Jiang & Denolle benchmark vs user- user- Other linear/PWS/ro- offers multiple dv/v + (2020) MSNoise defined defined bust stacking; estimators so users can + reference + cross-check; + moving stacks parallel/HDF5 + reproducible pip… + Wang & Yao review n/r n/r stretching, reference and Bayesian least-squares + (2020) (review) (review) MWCS, stacking strategies / MCMC (review) + DTW, reviewed + WCS + (review) + + continued on next page + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 5 + Table A1 continued + Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + + Yuan et al. 2-D varies (e.g. 45-75 WCC, TS, n/a residuals vs truth over + (2021) heterogeneous 0.5-2.2) (example) DTW, realizations + half-space MWCS, + simulations WCS, + WTS, + WTDTW + (7 + compared) + + + + +730 DATA AVAILABILITY + + +731 All synthetics, estimators, and figures in this paper are implemented in the open-source + +732 Python package codameter (version 0.4.0, MIT license), openly available at https://github.c + +733 om/Denolle-Lab/codameter. A versioned archive with a Zenodo DOI will be issued alongside + +734 publication. + + + + +735 Acknowledgements + + +736 [To be completed.] + + + + +737 REFERENCES + + +738 Andajani, R. D., Tsuji, T., Snieder, R., & Ikeda, T., 2020. Spatial and temporal influence + +739 of rainfall on crustal pore pressure based on seismic velocity monitoring, Earth, Planets + +740 and Space, 72, doi: 10.1186/s40623-020-01311-1. + + +741 Bensen, G. D., Ritzwoller, M. H., Barmin, M. P., Levshin, A. L., Lin, F., Moschetti, M. P., + +742 Shapiro, N. M., & Yang, Y., 2007. Processing seismic ambient noise data to obtain reliable + 56 M. A. Denolle +743 broad-band surface wave dispersion measurements, Geophysical Journal International, + +744 169(3), 1239–1260, doi: 10.1111/j.1365-246X.2007.03374.x. + + +745 Bertello, L., Berti, M., Castellaro, S., & Squarzoni, G., 2018. Dynamics of an active earthflow + +746 inferred from surface wave monitoring, Journal of Geophysical Research: Earth Surface, + +747 123, 1811–1834, doi: 10.1029/2017jf004233. + + +748 Bièvre, G., Franz, M., Larose, E., Carrière, S., Jongmans, D., & Jaboyedoff, M., 2018. + +749 Influence of environmental parameters on the seismic velocity changes in a clayey mud- + +750 flow (pont-bourquin landslide, switzerland), Engineering Geology, 245, 248–257, doi: + +751 10.1016/j.enggeo.2018.08.013. + + +752 Bontemps, N., Lacroix, P., Larose, E., Jara, J., & Taipe, E., 2020. Rain and small earthquakes + +753 maintain a slow-moving landslide in a persistent critical state, Nature Communications, + +754 11, doi: 10.1038/s41467-020-14445-3. + + +755 Boschelli, J., Moschetti, M. P., & SensSchönfelder, C., 2021. Temporal seismic velocity + +756 variations: Recovery following from the 2019 mw 7.1 ridgecrest, california earthquake, + +757 Journal of Geophysical Research: Solid Earth, 126, doi: 10.1029/2020jb021465. + + +758 Brenguier, F., Campillo, M., Hadziioannou, C., Shapiro, N. M., Nadeau, R. M., & Larose, + +759 E., 2008a. Postseismic relaxation along the san andreas fault at parkfield from continuous + +760 seismological observations, Science, 321, 1478–1481, doi: 10.1126/science.1160943. + + +761 Brenguier, F., Shapiro, N. M., Campillo, M., Ferrazzini, V., Duputel, Z., Coutant, O., & + +762 Nercessian, A., 2008b. Towards forecasting volcanic eruptions using seismic noise, Nature + +763 Geoscience, 1, 126–130, doi: 10.1038/ngeo104. + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 5 +764 Brenguier, F., Campillo, M., Takeda, T., Aoki, Y., Shapiro, N. M., Briand, X., Emoto, K., + +765 & Miyake, H., 2014. Mapping pressurized volcanic fluids from induced crustal seismic + +766 velocity drops, Science, 345(6192), 80–82, doi: 10.1126/science.1254073. + + +767 Chen, J. H., Froment, B., Liu, Q. Y., & Campillo, M., 2010. Distribution of seismic wave + +768 speed changes associated with the 12 may 2008 mw 7.9 wenchuan earthquake, Geophysical + +769 Research Letters, 37, doi: 10.1029/2010gl044582. + + +770 Clarke, D., Zaccarelli, L., Shapiro, N. M., & Brenguier, F., 2011. Assessment of resolution + +771 and accuracy of the moving window cross spectral technique for monitoring crustal temporal + +772 variations using ambient seismic noise, Geophysical Journal International, 186(2), 867–882, + +773 doi: 10.1111/j.1365-246X.2011.05074.x. + + +774 Clements, T. & Denolle, M. A., 2018. Tracking groundwater levels using the ambient seismic + +775 field, Geophysical Research Letters, 45(13), 6459–6465, doi: 10.1029/2018GL077706. + + +776 Clements, T. & Denolle, M. A., 2023. The seismic signature of california’s earth- + +777 quakes, droughts, and floods, Journal of Geophysical Research: Solid Earth, 128, doi: + +778 10.1029/2022jb025553. + + +779 Colombero, C., Baillet, L., Comina, C., Jongmans, D., Larose, E., Valentin, J., & Vinciguerra, + +780 S., 2018. Integration of ambient seismic noise monitoring, displacement and meteorological + +781 measurements to infer the temperature-controlled long-term evolution of a complex prone- + +782 to-fall cliff, Geophysical Journal International, 213, 1876–1897, doi: 10.1093/gji/ggy090. + + +783 Cubuk-Sabuncu, Y., Jónsdóttir, K., Caudron, C., Lecocq, T., Parks, M., Geirsson, H., & + +784 Mordret, A., 2021. Temporal seismic velocity changes during the 2020 rapid inflation at + 58 M. A. Denolle +785 mt. þorbjörn-svartsengi, iceland, using seismic ambient noise, Geophysical Research Letters, + +786 48, e2020GL092265, doi: 10.1029/2020GL092265. + + +787 Czarny, R., Marcak, H., Nakata, N., Pilecki, Z., & Isakow, Z., 2016. Monitoring veloc- + +788 ity changes caused by underground coal mining using seismic noise, Pure and Applied + +789 Geophysics, 173, 1907–1916, doi: 10.1007/s00024-015-1234-3. + + +790 Daskalakis, E., Evangelidis, C., Garnier, J., Melis, N., Papanicolaou, G., & Tsogka, C., 2016. + +791 Robust seismic velocity change estimation using ambient noise recordings, Geophysical + +792 Journal International, 205, 1926–1936, doi: 10.1093/gji/ggw142. + + +793 De Plaen, R. S. M., Lecocq, T., Caudron, C., Ferrazzini, V., & Francis, O., 2016. Singlestation + +794 monitoring of volcanoes using seismic ambient noise, Geophysical Research Letters, 43, + +795 8511–8518, doi: 10.1002/2016gl070078. + + +796 De Plaen, R. S. M., Cannata, A., Cannavo’, F., Caudron, C., Lecocq, T., & Francis, + +797 O., 2019. Temporal changes of seismic velocity caused by volcanic activity at mt. etna + +798 revealed by the autocorrelation of ambient seismic noise, Frontiers in Earth Science, 6, + +799 doi: 10.3389/feart.2018.00251. + + +800 De Wit, T. & Snieder, R., 2026. Did they blow it? time-lapse velocity variations dur- + +801 ing an open-pit mine slope failure using seismic noise interferometry, Seismica, 5, doi: + +802 10.26443/seismica.v5i1.1902. + + +803 Delouche, E. & Stehly, L., 2023. Seasonal seismic velocity variations measured using seismic + +804 noise autocorrelations to monitor the dynamic of aquifers in greece, Journal of Geophysical + +805 Research: Solid Earth, 128, doi: 10.1029/2023jb026759. + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 5 +806 Denolle, M. A., Shi, Q., Clements, T., Viens, L., Rodriguez-Tribaldos, V., & Cotton, F., + +807 2025. Ambient field seismology in critical zone hydrological sciences, Comptes Rendus. + +808 Géoscience, 357, 425–451, doi: 10.5802/crgeos.310. + + +809 Donaldson, C., Caudron, C., Green, R. G., Thelen, W. A., & White, R. S., 2017. Relative + +810 seismic velocity variations correlate with deformation at kīlauea volcano, Science Advances, + +811 3, doi: 10.1126/sciadv.1700219. + + +812 Donaldson, C., Winder, T., Caudron, C., & White, R. S., 2019. Crustal seismic velocity + +813 responds to a magmatic intrusion and seasonal loading in icelands northern volcanic zone, + +814 Science Advances, 5, doi: 10.1126/sciadv.aax6642. + + +815 Duputel, Z., Ferrazzini, V., Brenguier, F., Shapiro, N., Campillo, M., & Nercessian, A., + +816 2009. Real time monitoring of relative velocity changes using ambient seismic noise at + +817 the piton de la fournaise volcano (la réunion) from january 2006 to june 2007, Journal of + +818 Volcanology and Geothermal Research, 184, 164–173, doi: 10.1016/j.jvolgeores.2008.11.024. + + +819 Ermert, L. A., Cabral-Cano, E., Chaussard, E., Solano-Rojas, D., Quintanar, L., + +820 Morales Padilla, D., Fernández-Torres, E. A., & Denolle, M. A., 2023. Probing envi- + +821 ronmental and tectonic changes underneath mexico city with the urban seismic field, Solid + +822 Earth, 14, 529–549, doi: 10.5194/se-14-529-2023. + + +823 Feng, K.-F., Huang, H.-H., & Wu, Y.-M., 2020. Detecting pre-eruptive magmatic processes + +824 of the 2018 eruption at kilauea, hawaii volcano with ambient noise interferometry, Earth, + +825 Planets and Space, 72, doi: 10.1186/s40623-020-01199-x. + + +826 Fiolleau, S., Jongmans, D., Bièvre, G., Chambon, G., Baillet, L., & Vial, B., 2020. Seismic + 60 M. A. Denolle +827 characterization of a clay-block rupture in harmalière landslide, french western alps, + +828 Geophysical Journal International, 221, 1777–1788, doi: 10.1093/gji/ggaa050. + + +829 Fokker, E., Ruigrok, E., Hawkins, R., & Trampert, J., 2023. 4d physicsbased pore pressure + +830 monitoring using passive image interferometry, Geophysical Research Letters, 50, doi: + +831 10.1029/2022gl101254. + + +832 Gassenmeier, M., Sens-Schönfelder, C., Delatre, M., & Korn, M., 2014. Monitoring of + +833 environmental influences on seismic velocity at the geological storage site for co2 in ketzin + +834 (germany) with ambient seismic noise, Geophysical Journal International, 200, 524–533, + +835 doi: 10.1093/gji/ggu413. + + +836 Gassenmeier, M., Sens-Schönfelder, C., Eulenfeld, T., Bartsch, M., Victor, P., Tilmann, F., + +837 & Korn, M., 2016. Field observations of seismic velocity changes caused by shaking-induced + +838 damage and healing due to mesoscopic nonlinearity, Geophysical Journal International, + +839 204, 1490–1502, doi: 10.1093/gji/ggv529. + + +840 Gassmann, F., 1951. Über die elastizität poröser medien, Vierteljahrsschrift der Natur- + +841 forschenden Gesellschaft in Zürich, 96, 1–23. + + +842 GaubertBastide, T., Garambois, S., Bordes, C., Voisin, C., Oxarango, L., Brito, D., & + +843 Roux, P., 2022. Highresolution monitoring of controlled water table variations from dense + +844 seismicnoise acquisitions, Water Resources Research, 58, doi: 10.1029/2021wr030680. + + +845 Gelman, A. & Loken, E., 2013. The garden of forking paths, Department of Statistics, + +846 Columbia University (working paper). + + +847 Guillemot, A., Helmstetter, A., Larose, É., Baillet, L., Garambois, S., Mayoraz, R., & + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 6 +848 Delaloye, R., 2020. Seismic monitoring in the gugla rock glacier (switzerland): ambient + +849 noise correlation, microseismicity and modelling, Geophysical Journal International, 221, + +850 1719–1735, doi: 10.1093/gji/ggaa097. + + +851 Guillemot, A., Baillet, L., Garambois, S., Bodin, X., Helmstetter, A., Mayoraz, R., & Larose, + +852 E., 2021. Modal sensitivity of rock glaciers to elastic changes from spectral seismic noise + +853 monitoring and modeling, The Cryosphere, 15, 501–529, doi: 10.5194/tc-15-501-2021. + + +854 Hadziioannou, C., Larose, E., Coutant, O., Roux, P., & Campillo, M., 2009. Stability of + +855 monitoring weak changes in multiply scattering media with ambient noise correlation: + +856 Laboratory experiments, The Journal of the Acoustical Society of America, 125, 3688–3695, + +857 doi: 10.1121/1.3125345. + + +858 Hadziioannou, C., Larose, E., Baig, A., Roux, P., & Campillo, M., 2011. Improving temporal + +859 resolution in ambient noise monitoring of seismic wave speed, Journal of Geophysical + +860 Research: Solid Earth, 116(B7), B07304, doi: 10.1029/2011JB008200. + + +861 Harba, P. & Pilecki, Z., 2016. Assessment of timespatial changes of shear wave velocities + +862 of flysch formation prone to mass movements by seismic interferometry with the use of + +863 ambient noise, Landslides, 14, 1225–1233, doi: 10.1007/s10346-016-0779-2. + + +864 Hennino, R., Trégourès, N., Shapiro, N. M., Margerin, L., Campillo, M., van Tiggelen, B. A., + +865 & Weaver, R. L., 2001. Observation of equipartition of seismic waves, Physical Review + +866 Letters, 86, 3447–3450, doi: 10.1103/PhysRevLett.86.3447. + + +867 Hillers, G., Campillo, M., & Ma, K.-F., 2014. Seismic velocity variations at tcdp are + +868 controlled by mjo driven precipitation pattern and high fluid discharge properties, Earth + +869 and Planetary Science Letters, 391, 121–127, doi: 10.1016/j.epsl.2014.01.040. + 62 M. A. Denolle +870 Hillers, G., Husen, S., Obermann, A., Planès, T., Larose, E., & Campillo, M., 2015. Noise- + +871 based monitoring and imaging of aseismic transient deformation induced by the 2006 basel + +872 reservoir stimulation, Geophysics, 80, KS51–KS68, doi: 10.1190/geo2014-0455.1. + + +873 Hillers, G., Campillo, M., Brenguier, F., Moreau, L., Agnew, D. C., & BenZion, Y., 2019. + +874 Seismic velocity change patterns along the san jacinto fault zone following the 2010 m7.2 + +875 el mayorcucapah and m5.4 collins valley earthquakes, Journal of Geophysical Research: + +876 Solid Earth, 124, 7171–7192, doi: 10.1029/2018jb017143. + + +877 Hobiger, M., Wegler, U., Shiomi, K., & Nakahara, H., 2012. Coseismic and postseismic + +878 elastic wave velocity variations caused by the 2008 iwatemiyagi nairiku earthquake, japan, + +879 Journal of Geophysical Research: Solid Earth, 117, doi: 10.1029/2012jb009402. + + +880 HotovecEllis, A. J., Gomberg, J., Vidale, J. E., & Creager, K. C., 2014. A continuous + +881 record of intereruption velocity change at mount st. helens from coda wave interferometry, + +882 Journal of Geophysical Research: Solid Earth, 119, 2199–2214, doi: 10.1002/2013jb010742. + + +883 HotovecEllis, A. J., Vidale, J. E., Gomberg, J., Thelen, W., & Moran, S. C., 2015. Changes + +884 in seismic velocity during the first 14 months of the 20042008 eruption of mount st. + +885 helens, washington, Journal of Geophysical Research: Solid Earth, 120, 6226–6240, doi: + +886 10.1002/2015jb012101. + + +887 HotovecEllis, A. J., Shiro, B. R., Shelly, D. R., Anderson, K. R., Haney, M. M., Thelen, + +888 W. A., MontgomeryBrown, E. K., & Johanson, I. A., 2022. Earthquakederived seismic + +889 velocity changes during the 2018 caldera collapse of kīlauea volcano, Journal of Geophysical + +890 Research: Solid Earth, 127, doi: 10.1029/2021jb023324. + + +891 Illien, L., SensSchönfelder, C., Andermann, C., Marc, O., Cook, K. L., Adhikari, L. B., + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 6 +892 & Hovius, N., 2022. Seismic velocity recovery in the subsurface: Transient damage and + +893 groundwater drainage following the 2015 gorkha earthquake, nepal, Journal of Geophysical + +894 Research: Solid Earth, 127, doi: 10.1029/2021jb023402. + + +895 James, S. R., Knox, H. A., Abbott, R. E., & Screaton, E. J., 2017. Improved moving window + +896 cross-spectral analysis for resolving large temporal seismic velocity changes in permafrost, + +897 Geophysical Research Letters, 44(9), 4018–4026, doi: 10.1002/2016GL072468. + + +898 James, S. R., Knox, H. A., Abbott, R. E., Panning, M. P., & Screaton, E. J., 2019. Insights + +899 into permafrost and seasonal activelayer dynamics from ambient seismic noise monitoring, + +900 Journal of Geophysical Research: Earth Surface, 124, 1798–1816, doi: 10.1029/2019jf005051. + + +901 Jiang, C. & Denolle, M. A., 2020. NoisePy: a new high-performance python tool + +902 for ambient-noise seismology, Seismological Research Letters, 91(3), 1853–1866, doi: + +903 10.1785/0220190364. + + +904 Kidiwela, M., Denolle, M. A., Wilcock, W. S. D., & Feng, K. F., 2026. Active protothrusts + +905 and fluid highways: Seismic noise reveals hidden subduction dynamics in cascadia, Science + +906 Advances, 12(9), eaea3684, doi: 10.1126/sciadv.aea3684. + + +907 Kim, D. & Lekic, V., 2019. Groundwater variations from autocorrelation and receiver + +908 functions, Geophysical Research Letters, 46, 13722–13729, doi: 10.1029/2019gl084719. + + +909 Köpfli, M., Denolle, M. A., Thelen, W. A., Makus, P., & Malone, S. D., 2024. Examining + +910 22 years of ambient seismic wavefield at mount st. helens, Seismological Research Letters, + +911 95, 2622–2636, doi: 10.1785/0220240079. + + +912 Kristjánsdóttir et al., 2019. https://ui.adsabs.harvard.edu/abs/2019EGUGA..2118643K/ + 64 M. A. Denolle +913 abstract, dv/v monitoring study (Geothermal wastewater reinjection (water-volume / + +914 pore-pressure increase)). + + +915 Le Breton, M., Bontemps, N., Guillemot, A., Baillet, L., & Larose, É., 2021. Landslide + +916 monitoring using seismic ambient noise correlation: challenges and applications, Earth- + +917 Science Reviews, 216, 103518, doi: 10.1016/j.earscirev.2021.103518. + + +918 Lecocq, T., Caudron, C., & Brenguier, F., 2014. MSNoise, a Python package for monitoring + +919 seismic velocity changes using ambient seismic noise, Seismological Research Letters, 85(3), + +920 715–726, doi: 10.1785/0220130073. + + +921 Lecocq, T., Longuevergne, L., Pedersen, H. A., Brenguier, F., & Stammler, K., 2017. + +922 Monitoring ground water storage at mesoscale using seismic noise: 30 years of continuous + +923 observation and thermo-elastic and hydrological modeling, Scientific Reports, 7, doi: + +924 10.1038/s41598-017-14468-9. + + +925 Lesage, P., Carrara, A., Pinel, V., & Arámbula-Mendoza, R., 2018. Absence of detectable + +926 precursory deformation and velocity variation before the large dome collapse of july 2015 + +927 at volcán de colima, mexico, Frontiers in Earth Science, 6, doi: 10.3389/feart.2018.00093. + + +928 Lin, F.-C., Moschetti, M. P., & Ritzwoller, M. H., 2008. Surface wave tomography of + +929 the western United States from ambient seismic noise: Rayleigh and Love wave phase + +930 velocity maps, Geophysical Journal International, 173(1), 281–298, doi: 10.1111/j.1365- + +931 246X.2008.03720.x. + + +932 Lindner, F., Wassermann, J., & Igel, H., 2021. Seasonal freezethaw cycles and permafrost + +933 degradation on mt. zugspitze (german/austrian alps) revealed by singlestation seismic + +934 monitoring, Geophysical Research Letters, 48, doi: 10.1029/2021gl094659. + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 6 +935 Liu, Z., Huang, J., Peng, Z., & Su, J., 2014. Seismic velocity changes in the epicentral region + +936 of the 2008 wenchuan earthquake measured from threecomponent ambient noise correlation + +937 techniques, Geophysical Research Letters, 41, 37–42, doi: 10.1002/2013gl058682. + + +938 Liu, Z., Li, H., Liang, C., Zhang, T., Jiang, H., & Huang, H., 2026. Enhanced visualization + +939 of rainfall infiltration in landslides using high-resolution 4-d noise-based velocity change + +940 imaging, Geophysical Journal International, 245, doi: 10.1093/gji/ggag037. + + +941 Lobkis, O. I. & Weaver, R. L., 2003. Coda-wave interferometry in finite solids: Recovery + +942 of P-to-S conversion rates in an elastodynamic billiard, Physical Review Letters, 90(25), + +943 254302, doi: 10.1103/PhysRevLett.90.254302. + + +944 Lu, Y. & Ben-Zion, Y., 2021. Regional seismic velocity changes following the 2019 mw 7.1 + +945 ridgecrest, california earthquake from autocorrelations and p/s converted waves, Geophysical + +946 Journal International, 228, 620–630, doi: 10.1093/gji/ggab350. + + +947 Luo, B., Zhang, S., & Zhu, H., 2023. Monitoring seasonal fluctuation and longterm trends + +948 for the greenland ice sheet using seismic noise autocorrelations, Geophysical Research + +949 Letters, 50, doi: 10.1029/2022gl102146. + + +950 Mainsant, G., Larose, E., Brönnimann, C., Jongmans, D., Michoud, C., & Jaboyedoff, M., + +951 2012. Ambient seismic noise monitoring of a clay landslide: Toward failure prediction, + +952 Journal of Geophysical Research: Earth Surface, 117, doi: 10.1029/2011jf002159. + + +953 Mao, S., Campillo, M., van der Hilst, R. D., Brenguier, F., Stehly, L., & Hillers, G., 2019. + +954 High temporal resolution monitoring of small variations in crustal strain by dense seismic + +955 arrays, Geophysical Research Letters, 46(1), 128–137, doi: 10.1029/2018GL079944. + 66 M. A. Denolle +956 Mao, S., Mordret, A., Campillo, M., Fang, H., & van der Hilst, R. D., 2020. On + +957 the measurement of seismic traveltime changes in the time–frequency domain with + +958 wavelet cross-spectrum analysis, Geophysical Journal International, 221(1), 550–568, + +959 doi: 10.1093/gji/ggz495. + + +960 Mao, S., Lecointre, A., van der Hilst, R. D., & Campillo, M., 2022. Space-time monitoring + +961 of groundwater fluctuations with passive seismic interferometry, Nature Communications, + +962 13, doi: 10.1038/s41467-022-32194-3. + + +963 Mao, S., Ellsworth, W. L., Zheng, Y., & Beroza, G. C., 2025. Depth-dependent seismic + +964 sensing of groundwater recovery from the atmospheric-river storms of 2023, Science, 387, + +965 758–763, doi: 10.1126/science.adr6139. + + +966 Margerin, L., Campillo, M., & Van Tiggelen, B., 1998. Radiative transfer and diffusion of + +967 waves in a layered medium: new insight into coda q, Geophysical Journal International, + +968 134(2), 596–612, doi: 10.1046/j.1365-246x.1998.00571.x. + + +969 Margerin, L., Bajaras, A., & Campillo, M., 2019. A scalar radiative transfer model including + +970 the coupling between surface and body waves, Geophysical Journal International, 219(2), + +971 1092–1108, doi: 10.1093/gji/ggz348. + + +972 Mavko, G., Mukerji, T., & Dvorkin, J., 2009. The Rock Physics Handbook: Tools + +973 for Seismic Analysis of Porous Media, Cambridge University Press, 2nd edition., doi: + +974 10.1017/CBO9780511626753. + + +975 Mikesell, T. D., Malcolm, A. E., Yang, D., & Haney, M. M., 2015. A comparison of + +976 methods to estimate seismic phase delays: numerical examples for coda wave interferometry, + +977 Geophysical Journal International, 202(1), 347–360, doi: 10.1093/gji/ggv138. + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 6 +978 Minato, S., Tsuji, T., Ohmi, S., & Matsuoka, T., 2012. Monitoring seismic velocity change + +979 caused by the 2011 tohokuoki earthquake using ambient noise records, Geophysical Research + +980 Letters, 39, doi: 10.1029/2012gl051405. + + +981 Mordret, A., Mikesell, T. D., Harig, C., Lipovsky, B. P., & Prieto, G. A., 2016. Monitoring + +982 southwest greenlands ice sheet melt with ambient seismic noise, Science Advances, 2, doi: + +983 10.1126/sciadv.1501538. + + +984 Moreau, L., Stehly, L., Boué, P., Lu, Y., Larose, E., & Campillo, M., 2017. Improving + +985 ambient noise correlation functions with an SVD-based Wiener filter, Geophysical Journal + +986 International, 211(1), 418–426, doi: 10.1093/gji/ggx306. + + +987 Nakata, N. & Snieder, R., 2011. Near-surface weakening in japan after the 2011 tohoku-oki + +988 earthquake, Geophysical Research Letters, 38, n/a–n/a, doi: 10.1029/2011gl048800. + + +989 Nimiya, H., Ikeda, T., & Tsuji, T., 2017. Spatial and temporal seismic velocity changes on + +990 kyushu island during the 2016 kumamoto earthquake, Science Advances, 3, doi: 10.1126/sci- + +991 adv.1700813. + + +992 Obermann & Hillers, 2019. Seismic time-lapse interferometry across scales, Advances in + +993 Geophysics, pp. 65–143, doi: 10.1016/bs.agph.2019.06.001. + + +994 Obermann, A., Planès, T., Larose, E., Sens-Schönfelder, C., & Campillo, M., 2013. Depth + +995 sensitivity of seismic coda waves to velocity perturbations in an elastic heterogeneous + +996 medium, Geophysical Journal International, 194(1), 372–382, doi: 10.1093/gji/ggt043. + + +997 Obermann, A., Kraft, T., Larose, E., & Wiemer, S., 2015. Potential of ambient seismic noise + +998 techniques to monitor the st. gallen geothermal site (switzerland), Journal of Geophysical + 68 M. A. Denolle +999 Research: Solid Earth, 120, 4301–4316, doi: 10.1002/2014jb011817. + + +1000 Obermann, A., Planès, T., Hadziioannou, C., & Campillo, M., 2016. Lapse-time-dependent + +1001 coda-wave depth sensitivity to local velocity perturbations in 3-d heterogeneous elastic + +1002 media, Geophysical Journal International, 207(1), 59–66, doi: 10.1093/gji/ggw264. + + +1003 Okubo, K., Delbridge, B. G., & Denolle, M. A., 2024. Monitoring velocity change over 20 + +1004 years at parkfield, Journal of Geophysical Research: Solid Earth, 129(4), e2023JB028084, + +1005 doi: 10.1029/2023JB028084. + + +1006 Olivier, G., Brenguier, F., de Wit, T., & Lynch, R., 2017. Monitoring the stability of + +1007 tailings dam walls with ambient seismic noise, The Leading Edge, 36, 350a1–350a6, doi: + +1008 10.1190/tle36040350a1.1. + + +1009 Olivier, G., Brenguier, F., Carey, R., Okubo, P., & Donaldson, C., 2019. Decrease in seismic + +1010 velocity observed prior to the 2018 eruption of kīlauea volcano with ambient seismic noise + +1011 interferometry, Geophysical Research Letters, 46, 3734–3744, doi: 10.1029/2018gl081609. + + +1012 Ouellet, S. M., Dettmer, J., Olivier, G., de Wit, T., & Lato, M., 2022. Advanced monitoring + +1013 of tailings dam performance using seismic noise and stress models, Communications Earth + +1014 & Environment, 3, 301, doi: 10.1038/s43247-022-00629-w. + + +1015 Paasschens, J. C. J., 1997. Solution of the time-dependent boltzmann equation, Physical + +1016 Review E, 56(1), 1135–1141, doi: 10.1103/PhysRevE.56.1135. + + +1017 Pacheco, C. & Snieder, R., 2005. Time-lapse travel time change of multiply scattered + +1018 acoustic waves, The Journal of the Acoustical Society of America, 118(3), 1300–1310, doi: + +1019 10.1121/1.1979437. + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 6 +1020 Planès, T., Mooney, M. A., Rittgers, J. B. R., Parekh, M. L., Behm, M., & Snieder, R., + +1021 2016. Time-lapse monitoring of internal erosion in earthen dams and levees using ambient + +1022 seismic noise, Géotechnique, 66(4), 301–312, doi: 10.1680/jgeot.14.P.268. + + +1023 Poli, P., Marguin, V., Wang, Q., D’Agostino, N., & Johnson, P., 2020. Seasonal and + +1024 coseismic velocity variation in the region of l’aquila from single station measurements and + +1025 implications for crustal rheology, Journal of Geophysical Research: Solid Earth, 125, doi: + +1026 10.1029/2019jb019316. + + +1027 Poupinet, G., Ellsworth, W. L., & Frechet, J., 1984. Monitoring velocity variations in the + +1028 crust using earthquake doublets: An application to the Calaveras fault, California, Journal + +1029 of Geophysical Research: Solid Earth, 89(B7), 5719–5731, doi: 10.1029/jb089ib07p05719. + + +1030 Rivet, D., Campillo, M., Shapiro, N. M., Cruz-Atienza, V., Radiguet, M., Cotte, N., & + +1031 Kostoglodov, V., 2011. Seismic evidence of nonlinear crustal deformation during a large slow + +1032 slip event in mexico, Geophysical Research Letters, 38, n/a–n/a, doi: 10.1029/2011gl047151. + + +1033 Rivet, D., Brenguier, F., Clarke, D., Shapiro, N. M., & Peltier, A., 2014. Long-term dynamics + +1034 of Piton de la Fournaise volcano from 13 years of seismic velocity change measurements + +1035 and GPS observations, Journal of Geophysical Research: Solid Earth, 119(10), 7654–7666, + +1036 doi: 10.1002/2014JB011307. + + +1037 Rivet, D., Brenguier, F., & Cappa, F., 2015. Improved detection of preeruptive seismic + +1038 velocity drops at the piton de la fournaise volcano, Geophysical Research Letters, 42, + +1039 6332–6339, doi: 10.1002/2015gl064835. + + +1040 Rubinstein, J. L. & Beroza, G. C., 2005. Depth constraints on nonlinear strong ground + 70 M. A. Denolle +1041 motion from the 2004 parkfield earthquake, Geophysical Research Letters, 32, doi: + +1042 10.1029/2005gl023189. + + +1043 Sato, H., 1993. Energy transportation in one- and two-dimensional scattering media: analytic + +1044 solutions of the multiple isotropic scattering model, Geophysical Journal International, + +1045 112(1), 141–146, doi: 10.1111/j.1365-246X.1993.tb01443.x. + + +1046 Sawazaki, K., Sato, H., Nakahara, H., & Nishimura, T., 2009. Time-lapse changes of + +1047 seismic velocity in the shallow ground caused by strong ground motion shock of the 2000 + +1048 western-tottori earthquake, japan, as revealed from coda deconvolution analysis, Bulletin + +1049 of the Seismological Society of America, 99, 352–366, doi: 10.1785/0120080058. + + +1050 Schaff, D. P. & Beroza, G. C., 2004. Coseismic and postseismic velocity changes mea- + +1051 sured by repeating earthquakes, Journal of Geophysical Research: Solid Earth, 109, doi: + +1052 10.1029/2004jb003011. + + +1053 Sens-Schönfelder, C. & Wegler, U., 2006. Passive image interferometry and seasonal + +1054 variations of seismic velocities at Merapi volcano, Indonesia, Geophysical Research Letters, + +1055 33(21), L21302, doi: 10.1029/2006GL027797. + + +1056 Sens-Schönfelder, C., Pomponi, E., & Peltier, A., 2014. Dynamics of Piton de la Fournaise + +1057 volcano observed by passive image interferometry with multiple references, Journal of + +1058 Volcanology and Geothermal Research, 276, 32–45, doi: 10.1016/j.jvolgeores.2014.02.012. + + +1059 Sheng, Y., Mordret, A., Sager, K., Brenguier, F., Boué, P., Rousset, B., Vernon, F., + +1060 Higueret, Q., & BenZion, Y., 2022. Monitoring seismic velocity changes across the + +1061 san jacinto fault using traingenerated seismic tremors, Geophysical Research Letters, 49, + +1062 doi: 10.1029/2022gl098509. + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 7 +1063 Snieder, R., Grêt, A., Douma, H., & Scales, J., 2002. Coda wave interferometry for + +1064 estimating nonlinear behavior in seismic velocity, Science, 295(5563), 2253–2255, doi: + +1065 10.1126/science.1070015. + + +1066 Steegen, S., Tuerlinckx, F., Gelman, A., & Vanpaemel, W., 2016. Increasing transparency + +1067 through a multiverse analysis, Perspectives on Psychological Science, 11(5), 702–712, doi: + +1068 10.1177/1745691616658637. + + +1069 Stehly, L., Campillo, M., & Shapiro, N. M., 2006. A study of the seismic noise from its + +1070 long-range correlation properties, Journal of Geophysical Research, 111, B10306, doi: + +1071 10.1029/2005JB004237. + + +1072 Stehly, L., Froment, B., Campillo, M., Liu, Q. Y., & Chen, J. H., 2015. Monitoring seismic + +1073 wave velocity changes associated with the Mw 7.9 Wenchuan earthquake: increasing + +1074 the temporal resolution using curvelet filters, Geophysical Journal International, 201(3), + +1075 1939–1949, doi: 10.1093/gji/ggv110. + + +1076 Taira, T., Brenguier, F., & Kong, Q., 2015. Ambient noisebased monitoring of seismic + +1077 velocity changes associated with the 2014 mw 6.0 south napa earthquake, Geophysical + +1078 Research Letters, 42, 6997–7004, doi: 10.1002/2015gl065308. + + +1079 Taira, T., Nayak, A., Brenguier, F., & Manga, M., 2018. Monitoring reservoir response to + +1080 earthquakes and fluid extraction, salton sea geothermal field, california, Science Advances, + +1081 4, doi: 10.1126/sciadv.1701536. + + +1082 Takano, T., Nishimura, T., & Nakahara, H., 2017. Seismic velocity changes concentrated + +1083 at the shallow structure as inferred from correlation analyses of ambient noise during + 72 M. A. Denolle +1084 volcano deformation at izuoshima, japan, Journal of Geophysical Research: Solid Earth, + +1085 122, 6721–6736, doi: 10.1002/2017jb014340. + + +1086 Tsai, V. C., 2011. A model for seasonal changes in gps positions and seismic wave speeds + +1087 due to thermoelastic and hydrologic variations, Journal of Geophysical Research, 116, doi: + +1088 10.1029/2010jb008156. + + +1089 Tsuji, T., Ikeda, T., Matsuura, R., Mukumoto, K., Hutapea, F. L., Kimura, T., Yamaoka, K., + +1090 & Shinohara, M., 2021. Continuous monitoring system for safe managements of CO2 storage + +1091 and geothermal reservoirs, Scientific Reports, 11, 19120, doi: 10.1038/s41598-021-97881-5. + + +1092 Viens, L. & Van Houtte, C., 2020. Denoising ambient seismic field correlation functions + +1093 with convolutional autoencoders, Geophysical Journal International, 220(3), 1521–1535, + +1094 doi: 10.1093/gji/ggz509. + + +1095 Voisin, C., Garambois, S., Massey, C., & Brossier, R., 2016. Seismic noise monitoring of + +1096 the water table in a deep-seated, slow-moving landslide, Interpretation, 4, SJ67–SJ76, doi: + +1097 10.1190/int-2016-0010.1. + + +1098 Wang, Q., Brenguier, F., Campillo, M., Lecointre, A., Takeda, T., & Aoki, Y., 2017. Seasonal + +1099 crustal seismic velocity changes throughout japan, Journal of Geophysical Research: Solid + +1100 Earth, 122, 7987–8002, doi: 10.1002/2017jb014307. + + +1101 Wang, Q., Campillo, M., Brenguier, F., Lecointre, A., Takeda, T., & Hashima, A., 2019. + +1102 Evidence of changes of seismic properties in the entire crust beneath japan after the mw 9.0, + +1103 2011 tohokuoki earthquake, Journal of Geophysical Research: Solid Earth, 124, 8924–8941, + +1104 doi: 10.1029/2019jb017803. + The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring 7 +1105 Wang, Q.-Y. & Yao, H., 2020. Monitoring of velocity changes based on seismic ambi- + +1106 ent noise: A brief review and perspective, Earth and Planetary Physics, 4, 1–11, doi: + +1107 10.26464/epp2020048. + + +1108 Watlet, A., Whiteley, J., Dashwood, B., Morgan, D., Lane, V., Finch, L., Gunn, D., Lecocq, + +1109 T., & Chambers, J., 2026. Seismic response of a slow-moving landslide: exploring data + +1110 from two years of seismic monitoring at the hollin hill landslide observatory (uk), Seismica, + +1111 5, doi: 10.26443/seismica.v5i1.1478. + + +1112 Weaver, R. L., Hadziioannou, C., Larose, E., & Campillo, M., 2011. On the precision of + +1113 noise correlation interferometry, Geophysical Journal International, 185(3), 1384–1392, + +1114 doi: 10.1111/j.1365-246X.2011.05015.x. + + +1115 Wegler, U. & Sens-Schönfelder, C., 2007. Fault zone monitoring with passive image + +1116 interferometry, Geophysical Journal International, 168, 1029–1033, doi: 10.1111/j.1365- + +1117 246x.2006.03284.x. + + +1118 Wegler, U., Nakahara, H., SensSchönfelder, C., Korn, M., & Shiomi, K., 2009. Sudden + +1119 drop of seismic velocity after the 2004 mw 6.6 midniigata earthquake, japan, observed + +1120 with passive image interferometry, Journal of Geophysical Research: Solid Earth, 114, doi: + +1121 10.1029/2008jb005869. + + +1122 Xie, F., Larose, E., Wang, Q., & Zhang, Y., 2023. In-situ monitoring of rock slope + +1123 destabilization with ambient seismic noise interferometry in southwest china, Engineering + +1124 Geology, 312, 106922, doi: 10.1016/j.enggeo.2022.106922. + + +1125 Yates, A. S., Savage, M. K., Jolly, A. D., Caudron, C., & Hamling, I. J., 2019. Volcanic, coseis- + 74 M. A. Denolle +1126 mic, and seasonal changes detected at white island (whakaari) volcano, new zealand, using + +1127 seismic ambient noise, Geophysical Research Letters, 46, 99–108, doi: 10.1029/2018gl080580. + + +1128 Yates, A. S., Caudron, C., Mordret, A., Lesage, P., Pinel, V., Lecocq, T., Miller, C. A., + +1129 Lamb, O. D., & Fournier, N., 2024. Seasonal snow cycles and their possible influence on + +1130 seismic velocity changes and eruptive activity at ruapehu volcano, new zealand, Journal + +1131 of Geophysical Research: Solid Earth, 129, doi: 10.1029/2024jb029568. + + +1132 Yuan, C., Bryan, J., & Denolle, M., 2021. Numerical comparison of time-, frequency- and + +1133 wavelet-domain methods for coda wave interferometry, Geophysical Journal International, + +1134 226(2), 828–846, doi: 10.1093/gji/ggab140. + + +1135 Yukutake, Y., Taira, T., Onizawa, S., & Morita, Y., 2025. Decadal monitoring of seismic + +1136 velocity changes beneath izuoshima, central japan, using ambient seismic noise records, + +1137 Journal of Geophysical Research: Solid Earth, 130, doi: 10.1029/2025jb031170. + + +1138 Zhan, Z., Tsai, V. C., & Clayton, R. W., 2013. Spurious velocity changes caused by temporal + +1139 variations in ambient noise frequency content, Geophysical Journal International, 194(3), + +1140 1574–1581, doi: 10.1093/gji/ggt170. + + +1141 Zhang, S., Luo, B., BenZion, Y., Lumley, D. E., & Zhu, H., 2023. Monitoring terrestrial + +1142 water storage, drought and seasonal changes in central oklahoma with ambient seismic + +1143 noise, Geophysical Research Letters, 50, doi: 10.1029/2023gl103419. + + +1144 Zotz-Wilson, R., Boerrigter, T., & Barnhoorn, A., 2019. Coda-wave monitoring of continu- + +1145 ously evolving material properties and the precursory detection of yielding, The Journal + +1146 of the Acoustical Society of America, 145(2), 1060–1068, doi: 10.1121/1.5091012. diff --git a/review/evidence/figures/page_01.png b/review/evidence/figures/page_01.png new file mode 100644 index 0000000..8b77a24 Binary files /dev/null and b/review/evidence/figures/page_01.png differ diff --git a/review/evidence/figures/page_09.png b/review/evidence/figures/page_09.png new file mode 100644 index 0000000..b5036d8 Binary files /dev/null and b/review/evidence/figures/page_09.png differ diff --git a/review/evidence/figures/page_10.png b/review/evidence/figures/page_10.png new file mode 100644 index 0000000..88a7612 Binary files /dev/null and b/review/evidence/figures/page_10.png differ diff --git a/review/evidence/figures/page_11.png b/review/evidence/figures/page_11.png new file mode 100644 index 0000000..1634d58 Binary files /dev/null and b/review/evidence/figures/page_11.png differ diff --git a/review/evidence/figures/page_13.png b/review/evidence/figures/page_13.png new file mode 100644 index 0000000..b94b11e Binary files /dev/null and b/review/evidence/figures/page_13.png differ diff --git a/review/evidence/figures/page_14.png b/review/evidence/figures/page_14.png new file mode 100644 index 0000000..0474a11 Binary files /dev/null and b/review/evidence/figures/page_14.png differ diff --git a/review/evidence/figures/page_15.png b/review/evidence/figures/page_15.png new file mode 100644 index 0000000..8890cd1 Binary files /dev/null and b/review/evidence/figures/page_15.png differ diff --git a/review/evidence/figures/page_16.png b/review/evidence/figures/page_16.png new file mode 100644 index 0000000..d740ebc Binary files /dev/null and b/review/evidence/figures/page_16.png differ diff --git a/review/evidence/figures/page_19.png b/review/evidence/figures/page_19.png new file mode 100644 index 0000000..7887daa Binary files /dev/null and b/review/evidence/figures/page_19.png differ diff --git a/review/evidence/figures/page_21.png b/review/evidence/figures/page_21.png new file mode 100644 index 0000000..cd6757a Binary files /dev/null and b/review/evidence/figures/page_21.png differ diff --git a/review/evidence/figures/page_22.png b/review/evidence/figures/page_22.png new file mode 100644 index 0000000..f4dae8f Binary files /dev/null and b/review/evidence/figures/page_22.png differ diff --git a/review/evidence/figures/page_24.png b/review/evidence/figures/page_24.png new file mode 100644 index 0000000..973af6f Binary files /dev/null and b/review/evidence/figures/page_24.png differ diff --git a/review/evidence/figures/page_25.png b/review/evidence/figures/page_25.png new file mode 100644 index 0000000..c79fdb4 Binary files /dev/null and b/review/evidence/figures/page_25.png differ diff --git a/review/evidence/figures/page_26.png b/review/evidence/figures/page_26.png new file mode 100644 index 0000000..2d6d4f1 Binary files /dev/null and b/review/evidence/figures/page_26.png differ diff --git a/review/evidence/figures/page_28.png b/review/evidence/figures/page_28.png new file mode 100644 index 0000000..8fe7d90 Binary files /dev/null and b/review/evidence/figures/page_28.png differ diff --git a/review/evidence/figures/page_29.png b/review/evidence/figures/page_29.png new file mode 100644 index 0000000..34f365f Binary files /dev/null and b/review/evidence/figures/page_29.png differ diff --git a/review/evidence/figures/page_30.png b/review/evidence/figures/page_30.png new file mode 100644 index 0000000..5b5e36a Binary files /dev/null and b/review/evidence/figures/page_30.png differ diff --git a/review/evidence/figures/page_32.png b/review/evidence/figures/page_32.png new file mode 100644 index 0000000..1681980 Binary files /dev/null and b/review/evidence/figures/page_32.png differ diff --git a/review/evidence/figures/page_34.png b/review/evidence/figures/page_34.png new file mode 100644 index 0000000..5217012 Binary files /dev/null and b/review/evidence/figures/page_34.png differ diff --git a/review/evidence/figures/page_35.png b/review/evidence/figures/page_35.png new file mode 100644 index 0000000..bf4c290 Binary files /dev/null and b/review/evidence/figures/page_35.png differ diff --git a/review/evidence/figures/page_36.png b/review/evidence/figures/page_36.png new file mode 100644 index 0000000..2f97560 Binary files /dev/null and b/review/evidence/figures/page_36.png differ diff --git a/review/evidence/figures/page_37.png b/review/evidence/figures/page_37.png new file mode 100644 index 0000000..21e6896 Binary files /dev/null and b/review/evidence/figures/page_37.png differ diff --git a/review/evidence/figures/page_38.png b/review/evidence/figures/page_38.png new file mode 100644 index 0000000..0d47e24 Binary files /dev/null and b/review/evidence/figures/page_38.png differ diff --git a/review/evidence/figures/page_39.png b/review/evidence/figures/page_39.png new file mode 100644 index 0000000..8a73581 Binary files /dev/null and b/review/evidence/figures/page_39.png differ diff --git a/review/evidence/figures/page_45.png b/review/evidence/figures/page_45.png new file mode 100644 index 0000000..495dc86 Binary files /dev/null and b/review/evidence/figures/page_45.png differ diff --git a/review/evidence/figures/page_55.png b/review/evidence/figures/page_55.png new file mode 100644 index 0000000..ac8f605 Binary files /dev/null and b/review/evidence/figures/page_55.png differ diff --git a/review/evidence/methods_figures.md b/review/evidence/methods_figures.md new file mode 100644 index 0000000..ef8537b --- /dev/null +++ b/review/evidence/methods_figures.md @@ -0,0 +1,458 @@ +# Methods, results, and figure audit + +Scope: `paper/manuscript_marine.qmd` and its existing PDF. +Review date: 2026-09-10. Author profile: default. +Target: GJI research/methods article. First focused review. +No manuscript or production source was edited. + +Three focused passes followed the supplied skill references. +S-ME preceded S-RE, which preceded S-FD. +Code reads checked selected scientific claims and figure construction. +This evidence file does not replace independent reproduction. + +## Strengths + +- The central reproducibility question is scientifically valuable. +- The exact stretching convention is explicitly defined. +- Synthetic ground truth enables direct algorithmic error measurements. +- The paper separates component and network aggregation. +- The reference discussion acknowledges important alternative workflows. +- The real-data comparison caught an internally consistent sign error. +- Figure colours usually encode interpretable quantities and categories. +- The reporting checklist would benefit observational studies. + +## S-ME: Methods + +Six questions: who yes; what yes; when partial. +Where partial; how partial; why partial. +Software/version inventory: partial. Uncertainty treatment: substantial but uncalibrated. + +### Checklist + +| ID | Status | Evidence | +|---|---|---| +| S-ME.1 | PASS | Controlled recovery design, qmd178–241. | +| S-ME.2 | FAIL | Delay conventions and uncertainty objects conflict; see M2/M3/M7. | +| S-ME.3 | PARTIAL | Baseline choices are motivated, qmd854–867. Priors and estimator parameters remain underspecified. | +| S-ME.4 | PARTIAL | Appropriate for conditional sensitivity experiments. Physical and probabilistic claims exceed this design. | +| S-ME.5 | FAIL | Coverage and shared-data dependence remain unestablished; M1–M3. | +| S-ME.6 | PARTIAL | Uniform stretching is explicit, qmd214–221. Common-mode identifiability and kernel approximations need treatment. | +| S-ME.7 | PARTIAL | Stations and archive named, qmd1114–1147. Exact filtering, joins, exclusions, and waveform manifest need disclosure. | +| S-ME.8 | PARTIAL | Execution sequence understandable. Exact parameter tables and comparison operators absent. | +| S-ME.9 | PARTIAL | codameter v0.4.0 named, qmd1430. NoisePy/dependency versions absent in methods. | +| S-ME.10 | PARTIAL | Readable framework. Several terms denote incompatible statistical objects. | + +### M1. Major: the covariance is not derived from the likelihood + +Locations: qmd973–1014; PDF31–32; `uq_bayes.py:294–344`. + +The likelihood treats configuration residuals as conditionally independent. +However, configurations process the same underlying waveforms. +Their errors therefore share substantial observational information. +Increasing configuration count does not create independent measurements. + +The returned covariance is constructed after Gibbs sampling. +Code335 uses the observed cross-configuration sample standard deviation. +Code336 estimates another within-method standard deviation. +Code337 adds both variances under total-variance terminology. +Code344 adds a rank-one term using fitted tau. + +Observed cross-configuration spread already contains measurement noise. +It also contains different temporal filtering and offsets. +Adding within-method variance can therefore double-count uncertainty. +Moreover, tau describes between-configuration constant offsets in Eq2. +It does not identify bias shared by every configuration. +An identical bias across configurations leaves their spread unchanged. +The added common-mode term needs independent calibration or priors. + +Required: define the downstream estimand and joint sampling model. +Represent shared errors and configuration transfer operators explicitly. +Derive covariance under that model, including cross-band blocks. +Report prior sensitivity and dependence on configuration duplication. +A posterior predictive covariance differs from mean-estimation uncertainty. +Neither is automatically the uniquely correct downstream object. + +### M2. Major: nominal coverage is asserted without calibration + +Locations: qmd995–1026; PDF32; `uq_bayes.py:251–263,328–344`. + +One displayed synthetic cannot establish nominal repeated-sampling coverage. +Temporally correlated epochs are not independent simulation replicates. +The manuscript supplies no replicate count or coverage uncertainty. +It also omits chain diagnostics and sensitivity to hyperpriors. +The second-difference prior can smooth genuine abrupt changes. +A constant configuration offset cannot represent transient-specific failures. + +Required: independent seeded experiments across held-out truth classes. +Report bias, RMSE, coverage, interval width, and failure rates. +Evaluate 68%, 95%, and simultaneous-band coverage separately. +Stratify by coherence, transient timing, reference, and source perturbation. +Include posterior predictive checks and convergence diagnostics. +Avoid calling broad bands “honest” before those checks. + +### M3. Major: SD, SE, and measurement error are conflated + +Locations: qmd446–480,1392–1402; PDF13–15 and Appendix B. +Code: `synthetic_demo.py:1640–1675`. + +SD describes dispersion; SE describes an estimator's precision. +Their square-root-N ratio is an algebraic distinction. +It does not establish uncertainty miscalibration by itself. +The claim that any network bar describes mean precision +is directly contradicted by the included SD convention. + +The synthetic introduces real pair-dependent amplitude variability. +Specifically, pair_scale varies by 15% before adding noise. +Between-pair scatter consequently mixes heterogeneity and measurement error. +Weights further change the network estimand when sensitivity varies. +The weighted effective count assumes more than unequal weights. +Shared stations and shared noise require covariance between pairs. + +Required: define finite-network mean versus population mean explicitly. +Separate spatial variability from within-pair observational uncertainty. +Use Var(weighted mean)=aᵀΣa for normalized weights a. +Demonstrate interval calibration before claims about statistical significance. +Report hypotheses, reference uncertainty, and temporal dependence. + +### M4. Major: synthetic physics and inference targets need separation + +Locations: qmd180–222,494–521,775–794,1039–1087. +Code: `synthetic_demo.py:129–167,190–200,2076–2095,2461–2467`. + +The surrogate is useful for controlled measurement experiments. +It is not full waveform propagation through heterogeneous structure. +The implementation softens the diffuse onset and broadens the delta. +It also freely scales the ballistic contribution. +It omits the exact relative normalization of ballistic/diffuse terms. +The manuscript should call this an RT-inspired envelope. +“Single scattering” conflicts with the described multiply scattered coda. + +The “two-layer” example assigns separate signals to separate bands. +Its code contains no depth model or sensitivity kernel. +Recovering those signals demonstrates spectral separation under that construction. +It does not establish actual layer resolution or frequency-depth tolerances. +Likewise, branch-specific truth is imposed directly on each branch. +Physical branch kernels are asserted rather than calculated. + +Required: state these conditional constructions and their limitations. +Add an independently generated heterogeneous-wavefield benchmark before generalization. +Vary envelope, illumination, attenuation, geometry, and waveform decorrelation. +Classify additive-noise departures as stochastic observational error too. +Known truth does not make every residual a processing artefact. + +### M5. Major: reference comparisons include different observables + +Locations: qmd540–613,626–629,947–948; PDF17–19,30. + +Fixed references change the velocity-change zero point. +The manuscript correctly identifies this at qmd549–557. +However, raw RMS still ranks those offsets as errors. +Real-data validation removes equivalent offsets through demeaning, qmd1140–1142. +Apply a consistent target convention in both comparisons. + +The paper acknowledges no surveyed uncumulated trailing workflow. +Nevertheless, Table3 labels moving references a common deviation. +Raw trailing increments should be identified as an ablation. +A trailing-average residual is also not a one-day increment. +Simply cumulatively summing it does not generally invert averaging. + +Required: compare registered common-reference observables and transient recovery. +Benchmark cumulative-adjacent and segmented-reference approaches actually used. +Keep deliberately incomplete workflows outside “reasonable pipeline” priors. + +### M6. Major: branch selection advice contradicts its own experiment + +Locations: qmd784–794; PDF25, Fig10. + +The simulation demonstrates maximum-amplitude selection bias. +The subsequent recommendation permits maximum selection nevertheless. +Matched sign and similar coherence do not eliminate this bias. +Coherence estimated from the same observations is data-dependent. +It cannot automatically be called independent of the answer. + +Required: predefine branch handling using external physical information. +Alternatively evaluate selection on independent or held-out data. +Report both branches and their covariance before combining them. +Any selection rule needs conditional coverage and false-alarm checks. + +### M7. Major: Appendix WCC delay sign contradicts epsilon + +Locations: qmd95–119 and1345–1347. + +For delayed current c(t)=r(t−d), the stated correlation peaks +at positive tau=d in integral c(t)r(t−tau)dt. +The introduction defines positive epsilon for delayed current arrivals. +Thus delay versus reference lapse has positive epsilon slope. +The Appendix instead writes delta_t=−epsilon*t_i. +An analytic single-pulse example exposes this inconsistency. + +Required: define all delay and Fourier conventions consistently. +Trace each estimator's fitted slope into physical dv/v. +State the finite-change mapping for each regression coordinate. +Propagate errors through dv/v=−epsilon/(1+epsilon). +Its Jacobian magnitude is 1/(1+epsilon)². +The Appendix's small-error scaling concerns epsilon, not automatically dv/v. + +### M8. Major: depth claims precede a demonstrated inversion + +Locations: qmd33–37,1031–1087,1291–1301; PDF33–35. + +The summary promises illustrated depth propagation. +The depth section instead describes work still in development. +No depth-recovery figure, resolution test, or covariance comparison appears. +The discrete kernel matrix also needs integration weights. +A depth covariance requires two depth coordinates, plus time indexing. +Per-time single-band covariance alone cannot supply cross-band uncertainty. + +Required: either scope this as future work consistently, +or include the actual forward model and synthetic inversion. +Show kernels, resolution, posterior covariance, and model uncertainty. +Distinguish shear-wave speed from shear modulus and density effects. +Fluid-substitution assumptions need explicit parameterization and identifiability analysis. + +### M9. Major: omitted experimental details prevent fair comparisons + +Locations: qmd178–241,357–399,840–970,973–993. + +Most figure captions omit seeds, SNR definitions, and replicates. +Estimator-specific windows, lag limits, regularization, and grids matter. +The code supplies many details absent from the manuscript. +For example, Fig1 uses different bands and windows across panels. +See `synthetic_demo.py:1397–1425`. + +Required: provide a machine-readable experiment manifest per figure. +Include exact configuration sets, priors, masks, and metric definitions. +Distinguish RMSE, mean bias, residual scatter, and drop error. +Version the numerical results alongside the plots. + +## S-RE: Results + +Quantitative reporting: partial. Figure/table order: fails first-citation order. +Results deliberately mixes empirical results with interpretation and recommendations. +Treat section organization as minor; scientific contradictions remain major. + +| ID | Status | Evidence | +|---|---|---| +| S-RE.1 | PASS | qmd309–325 previews the parameter experiments. | +| S-RE.2 | PARTIAL | Clear axes; repeated overview plots interrupt progression. | +| S-RE.3 | PARTIAL | Table2, subsection numbers, and “Scale of effect” paragraphs repeat results. | +| S-RE.4 | PARTIAL | Explicitly mixed explanatory results. Interpretive blocks listed below. | +| S-RE.5 | PARTIAL | External comparisons embedded in reference subsection. | +| S-RE.6 | FAIL | Replicates, uncertainty on metrics, and masked counts mostly absent. | +| S-RE.7 | FAIL | Error-band interpretation unvalidated; see M1–M3. | +| S-RE.8 | PARTIAL | All main figures cited. Fig8 discussed before Fig5, qmd499–510. | +| S-RE.9 | PARTIAL | Fig17 is called optional supplement but stays main-text. | + +Interpretive blocks, minimum 16: qmd381–385,395–399,416–427, +450–456,475–482,496–512,547–557,559–566,599–613,650–653, +665–673,741–752,775–794,811–821,859–867,890–898. +This is a block inventory, not exhaustive sentence counting. +External comparison clusters, minimum six: qmd449–450,471–473, +574–585,587–597,645–647,725–727. +No language/register revision is necessary solely for mixed structure. + +### R1. Major: Figure1 contradicts its recovery claim + +Locations: qmd367–385; PDF11, Fig1c. +Code: `synthetic_demo.py:1381–1388,1415–1425,1466–1469`. + +The red dashed WCS curve visibly jumps to positive values. +The true landslide change becomes strongly negative. +The caption nevertheless claims unwrapped WCS tracks the truth. +Colour assignments in code confirm the red curve is WCS. +The method discussion should describe the plotted failure accurately. +Regenerate the numerical trace and derive claims directly from it. + +### R2. Major: RMS is repeatedly called bias + +Locations: qmd869–876; PDF28, Fig12 title and horizontal axis. + +The panel title describes injected bias. +Its horizontal axis measures RMS error against truth. +RMS mixes bias and variance, with different scientific implications. +Report both or label this panel as RMSE throughout. + +Table2 is additionally dimensionally consistent but statistically inconsistent. +Its network row compares SE with individual-pair range as RMS. +See qmd335–337 and PDF10. +Replace these with a common metric or separate columns. + +### R3. Major: real-data agreement does not validate uncertainty + +Locations: qmd1133–1182; PDF36–37, Figs15–16. + +A high correlation can coexist with wrong amplitude and uncertainty. +Demeaning and 90-day smoothing further limit the validation target. +681 overlapping days are not 681 independent observations. +Two calendar years contain 730 days before exclusions. +After 150-day burn-in, at most 580 remain within 2018–2019. +The claimed 681 needs reconciliation with the actual date range. +Duplicate joins or external dates are possible, not established here. + +The ARV range 0.66–0.92 depends on unspecified joining choices. +Missingness and interpolation require prespecified sensitivity analyses. +Report bias after alignment, slope, RMSE, residual correlation, +and uncertainty calibration against appropriate independent information. +Give station coordinates, masks, dates, components, and join definitions. + +The RXH pattern may reflect site or source changes. +An interferogram alone cannot discriminate instrument or processing effects. +“The visual difference is the reason” overstates causal identification. +Check station metadata, response changes, and processing logs. + +### R4. Moderate: internally inconsistent stacking conclusions + +Locations: qmd669–673; PDF21. + +The paragraph says every stack underestimates the drop. +It immediately acknowledges a bias zero crossing after 45 days. +Consequently the asserted universal lower bound is unsupported. +Report signed amplitude error and its scenario-dependent interpretation. + +## S-FD: Figures and data presentation + +Counts: 17 figures; five main tables; one appendix table. +Eight numbered equation environments, plus unnumbered displayed equations. +No independent colour-vision simulation was performed. +The visual palette appears broadly suitable for quantitative plotting. +Viridis-family and sequential maps avoid rainbow encodings. +Some categorical curves still depend heavily on colour. + +Visual inspection: all 17 figure pages inspected at 1800px. +Also inspected title, every main table, and appendix endpoints. +Pages: 1,9,10,11,13,14,15,16,19,21,22,24,25,26, +28,29,30,32,34,35,36,37,38,39,45,55. +These 26 renders are retained under `evidence/figures/`. +Other PDF pages were text-reviewed, not visually inspected. +The existing PDF has 74 pages, dated 2026-08-17. +No fresh manuscript build was performed in this pass. + +| ID | Status | Evidence | +|---|---|---| +| S-FD.1 | PARTIAL | Fig8 repeats four stories; Fig17 belongs in supplement. | +| S-FD.2 | PARTIAL | Useful time series and matrices; duplicated synthesis tables. | +| S-FD.3 | FAIL | Early Table1 cites Figs8/11 before Figs2/3. Main prose introduces Fig8 before Fig5. | +| S-FD.4 | PARTIAL | Analytical captions listed below; descriptive scope preferred. | +| S-FD.5 | FAIL | Missing covariance/RMS units; Fig16 lacks amplitude scale. | +| S-FD.6 | PARTIAL | Fig2 shared axes succeed. Fig13 mixes fractions and percentages. | +| S-FD.7 | PARTIAL | Sequential maps suitable; full accessibility simulation not performed. | +| S-FD.8 | PARTIAL | Table2 mixes statistical objects; experiment counts absent. | +| S-FD.9 | FAIL | WCC sign and covariance definitions require corrections. | +| S-FD.10 | PARTIAL | General code link provided; per-figure numerical provenance absent. | + +Analytical captions: Figs1,2,3,4,5,6,8,9,10,11,12,13,14,16. +These 14 flags concern clarity and evidential boundaries. +Moving interpretation into prose is optional editorial restructuring. +The contradictions within captions require correction regardless of structure. + +### F1. Major: Figure16 identifies conflicting components + +PDF37 plot title reads “Daily NZ cross-component CCFs”. +Caption says north-south/east-west, indicating NE correlations. +Source caption: qmd1176–1182. +Resolve component provenance before interpreting station differences. +Add an amplitude colourbar and normalization definition. +Near-zero-lag energy alone does not identify coda windows. +Overlay the actual measured lag windows. + +### F2. Moderate: real-data figures retain development annotations + +PDF36 Fig15 calls the reference “Clements–Denolle 2022”. +Its caption cites the 2023 product instead. +The plot says “smoothing-matched” while the caption says otherwise. +Displayed r values are 0.86,0.58,0.37. +The text instead emphasizes 0.990,0.68,0.66–0.92. +The caption acknowledges two analyses but forces reader reconciliation. +Show the matched comparison supporting the central claim. +Retain the unmatched comparison as a supplementary sensitivity check. + +PDF38 Fig17 title says 5/5 later members. +Its upper panels annotate 4/5 members. +Define whether these annotations describe instantaneous or maximum counts. +Replace “smoke store”, “Gate1 final”, and debugging titles. +Enlarge legends and annotations at final publication size. + +### F3. Moderate: legends hide signal and comparison features + +PDF13 Fig2a legend covers the recovered trajectory. +PDF22 Fig8 legends cover troughs and the transient. +PDF25 Fig10a legend obscures the largest drop. +PDF32 Fig14a legend covers the negative excursion and bands. +Use shared exterior legends or a dedicated legend strip. +Use direct labels where only a few curves remain. +Add panel letters to Fig8's four separate plots. + +### F4. Moderate: clipping conceals the multiverse result + +PDF29 Fig13a truncates much of the pipeline ensemble. +Its 10–90% band also exceeds the visible range. +Dense vertical traces obscure both the distribution and event. +The caption admits clipping, which is helpful but insufficient. +Show a full-range inset or separate failure-rate distribution. +Plot a density/quantile summary instead of every failed trajectory. +Label RMS colourbar as fraction or percentage explicitly. +PDF32 Fig14 covariance colourbar also needs squared units. + +### F5. Moderate: figure content lacks calibration evidence + +Most RMS curves and bars have no replicate uncertainty. +This is not solved by finer graphic styling. +Add independent-seed intervals and declared experiment counts first. +Show coverage-versus-nominal plots for the proposed covariance. +Show cross-band covariance and depth-resolution results if claimed. + +### F6. Minor: layout is readable but unnecessarily long + +The referee layout provides useful spacing and line numbers. +No gross clipping was observed on the inspected pages. +The running title nearly spans the full page width. +Use an abbreviated running title if the class supports it. +The long survey begins with one row on PDF45. +Consider a separate supplementary table with full provenance fields. +Avoid duplicating Fig8 with four dedicated experiment figures. +Keep main figures focused on testable central contributions. + +## Prioritized fixes and hand-off + +1. Repair covariance derivation and uncertainty calibration first. +2. Define shared estimands across references, bands, and pairs. +3. Correct estimator, component, and real-data figure contradictions. +4. Add independent synthetic replications and physical transfer tests. +5. Align completed depth/agent claims with demonstrated results. +6. Rebuild plots from versioned numerical output and manifests. + +Tier feeds: C2 Poor; C4 Poor; C5 Fair. +C3 methodological completeness: Fair, pending independent reproduction. +These are advisory section-level judgments, not editorial decisions. + +Root code audit additionally identified Weaver-floor implementation discrepancies. +Manuscript Appendix qmd1338–1341 includes bandwidth dependence explicitly. +That displayed dependence must match the executed uncertainty function. +The code audit owns the verified dimensional and prefactor evidence. + +## Fresh-build visual QA addendum + +The reproduction pass subsequently built the current manuscript successfully. +Fresh PDF: `evidence/reproduction_workspace/paper/manuscript_marine.pdf`. +Its metadata records 2026-09-10, with 74 pages unchanged. +The title page now prints 2026-09-10. + +Six fresh pages were rendered and visually inspected. +Pages1,11,29,32,36,37 correspond to the title and requested figures. +Renders: `evidence/figures/fresh_page_01.png` and corresponding numbered files. +This supplements the earlier 26-page visual inspection. +The selected figure pages retain their original page numbers. + +All checked substantive figure findings persist: + +- Fig1c, page11: WCS visibly fails despite its tracking claim. +- Fig13, page29: ensemble clipping and ambiguous RMS units persist. +- Fig14, page32: covariance units remain absent; legend obscures signals. +- Fig15, page36: 2022/2023 and smoothing annotations still conflict. +- Fig15 still displays r=0.86,0.58,0.37 beside different textual results. +- Fig16, page37: NZ title still contradicts the NE caption. +- Fig16 still lacks amplitude normalization and a colourbar. + +No inspected issue was resolved by rebuilding the document. +This checks rendering consistency, not fresh numerical figure generation. +See the reproduction evidence for that separate execution scope. diff --git a/review/evidence/paper_build.log b/review/evidence/paper_build.log new file mode 100644 index 0000000..9d1a00e --- /dev/null +++ b/review/evidence/paper_build.log @@ -0,0 +1,95 @@ +pandoc + to: latex + output-file: manuscript_marine.tex + standalone: true + pdf-engine: lualatex + variables: + graphics: true + tables: true + default-image-extension: pdf + number-sections: true + cite-method: natbib + +metadata + block-headings: true + engines: + - path: /Applications/quarto/share/extension-subtrees/julia-engine/_extensions/julia-engine/julia-engine.js + title: The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring + author: + - name: M. A. Denolle + email: mdenolle@uw.edu + affiliations: + - name: Department of Earth and Space Sciences, University of Washington, Seattle, WA, USA + date: today + abstract: | + Relative seismic velocity changes (\dvv) from repeated coda waves are becoming + a standard observable for volcanoes, faults, landslides, aquifers and the + cryosphere and are increasingly regarded as new measurements of strain changes. + Yet turning cross-correlation functions into a \dvv\ time series + involves a long sequence of choices --- the estimator, the frequency band, the + coda window, the reference, the stacking, and how cross-components and station + pairs are aggregated and weighted --- made *ad hoc*, their impact on the measurement + uncertainty unclear. These hidden choices clearly limit reproducibility of the + research and importantly the inter-study comparison. + + We demonstrate here how to turn repeated wavefield measurement into agent-ready, + scalable-ready, uncertainty-aware measurement of changes in seismic properties. + We quantify the individual and combined effects of these choices + using a controlled synthetic in which the ground-truth \dvv\ is known exactly. + We show that at large \dvv\ methods split by family with distinct failure modes; that the same station + pair yields different \dvv\ depending only on whether one averages the + per-component \dvv\ or the correlation-coefficient images; and, most + consequentially, that the reported $1\sigma$ on a network-averaged \dvv\ varies by + $\sim\!\sqrt{N}$ + from the standard-error-versus-standard-deviation and weighting conventions --- + so a change that is "$3\sigma$ significant" in one study is "not significant" in + another, from identical data. + + Running the full breadth of parameter choices, we estimate + each by the bias and error-bar change it induces. We propose a Bayesian + measurement model that marginalises the ensemble into a single time-dependent + data covariance $C_d$ and illustrate its use by propagating errors in a + depth-inversion of shear wave perturbation. We provide a real data examples from a California data set and reproduce + previous results that were generated with a different computing language + and processing pipeline, demonstrating at the same time the integration + of codameter with noisepy and its portability and scalability from laptop + to cloud systems. We also generate a codameter agent advisor that can guide researchers or agents + in their parameter choices, accompanied with a robust evaluation of the agent against + a golden data set. Our method and associated software package, ``codameter`` turns + repeated coda waves into time series of \dvv\ and its covariance + making it coda-wave interferometry uncertainty-aware and reproducible. + bibliography: + - references.bib + - survey.bib + biblio-style: gji + documentclass: gji + classoption: + - referee + colorlinks: true + + +Rendering PDF +running lualatex - 1 + This is LuaTeX, Version 1.07.0 (TeX Live 2018) + restricted system commands enabled. + +updating tlmgr + +updating existing packages +ERROR: +compilation failed- error +see manuscript_marine.log for more information. +WARN: Error encountered when rendering files +manuscript source: paper/manuscript_marine.qmd +$ quarto render manuscript_marine.qmd --to pdf (in /Users/marinedenolle/GitHub/codameter/review/evidence/reproduction_workspace/paper) +Traceback (most recent call last): + File "/Users/marinedenolle/GitHub/codameter/review/evidence/reproduction_workspace/paper/build.py", line 144, in + raise SystemExit(main()) + ^^^^^^ + File "/Users/marinedenolle/GitHub/codameter/review/evidence/reproduction_workspace/paper/build.py", line 131, in main + run(["quarto", "render", source.name, "--to", "pdf"], HERE) + File "/Users/marinedenolle/GitHub/codameter/review/evidence/reproduction_workspace/paper/build.py", line 44, in run + subprocess.run(cmd, cwd=cwd, check=True) + File "/Users/marinedenolle/GitHub/codameter/.pixi/envs/test/lib/python3.12/subprocess.py", line 571, in run + raise CalledProcessError(retcode, process.args, +subprocess.CalledProcessError: Command '['quarto', 'render', 'manuscript_marine.qmd', '--to', 'pdf']' returned non-zero exit status 1. diff --git a/review/evidence/paper_build_cached.log b/review/evidence/paper_build_cached.log new file mode 100644 index 0000000..46a6672 --- /dev/null +++ b/review/evidence/paper_build_cached.log @@ -0,0 +1,103 @@ +pandoc + to: latex + output-file: manuscript_marine.tex + standalone: true + pdf-engine: lualatex + variables: + graphics: true + tables: true + default-image-extension: pdf + number-sections: true + cite-method: natbib + +metadata + block-headings: true + engines: + - path: /Applications/quarto/share/extension-subtrees/julia-engine/_extensions/julia-engine/julia-engine.js + title: The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring + author: + - name: M. A. Denolle + email: mdenolle@uw.edu + affiliations: + - name: Department of Earth and Space Sciences, University of Washington, Seattle, WA, USA + date: today + abstract: | + Relative seismic velocity changes (\dvv) from repeated coda waves are becoming + a standard observable for volcanoes, faults, landslides, aquifers and the + cryosphere and are increasingly regarded as new measurements of strain changes. + Yet turning cross-correlation functions into a \dvv\ time series + involves a long sequence of choices --- the estimator, the frequency band, the + coda window, the reference, the stacking, and how cross-components and station + pairs are aggregated and weighted --- made *ad hoc*, their impact on the measurement + uncertainty unclear. These hidden choices clearly limit reproducibility of the + research and importantly the inter-study comparison. + + We demonstrate here how to turn repeated wavefield measurement into agent-ready, + scalable-ready, uncertainty-aware measurement of changes in seismic properties. + We quantify the individual and combined effects of these choices + using a controlled synthetic in which the ground-truth \dvv\ is known exactly. + We show that at large \dvv\ methods split by family with distinct failure modes; that the same station + pair yields different \dvv\ depending only on whether one averages the + per-component \dvv\ or the correlation-coefficient images; and, most + consequentially, that the reported $1\sigma$ on a network-averaged \dvv\ varies by + $\sim\!\sqrt{N}$ + from the standard-error-versus-standard-deviation and weighting conventions --- + so a change that is "$3\sigma$ significant" in one study is "not significant" in + another, from identical data. + + Running the full breadth of parameter choices, we estimate + each by the bias and error-bar change it induces. We propose a Bayesian + measurement model that marginalises the ensemble into a single time-dependent + data covariance $C_d$ and illustrate its use by propagating errors in a + depth-inversion of shear wave perturbation. We provide a real data examples from a California data set and reproduce + previous results that were generated with a different computing language + and processing pipeline, demonstrating at the same time the integration + of codameter with noisepy and its portability and scalability from laptop + to cloud systems. We also generate a codameter agent advisor that can guide researchers or agents + in their parameter choices, accompanied with a robust evaluation of the agent against + a golden data set. Our method and associated software package, ``codameter`` turns + repeated coda waves into time series of \dvv\ and its covariance + making it coda-wave interferometry uncertainty-aware and reproducible. + bibliography: + - references.bib + - survey.bib + biblio-style: gji + documentclass: gji + classoption: + - referee + colorlinks: true + latex-auto-install: false + + +Rendering PDF +running lualatex - 1 + This is LuaTeX, Version 1.07.0 (TeX Live 2018) + restricted system commands enabled. + + luaotfload | main : initialization completed in 0.113 seconds + luaotfload | db : Font names database not found, generating new one. + luaotfload | db : This can take several minutes; please be patient. +generating bibliography + This is BibTeX, Version 0.99d (TeX Live 2018) + The top-level auxiliary file: manuscript_marine.aux + The style file: gji.bst + Database file #1: references.bib + Database file #2: survey.bib + +running lualatex - 2 + This is LuaTeX, Version 1.07.0 (TeX Live 2018) + restricted system commands enabled. + + luaotfload | main : initialization completed in 0.106 seconds +running lualatex - 3 + This is LuaTeX, Version 1.07.0 (TeX Live 2018) + restricted system commands enabled. + + luaotfload | main : initialization completed in 0.108 seconds +running lualatex - 4 + This is LuaTeX, Version 1.07.0 (TeX Live 2018) + restricted system commands enabled. + + luaotfload | main : initialization completed in 0.090 seconds + +Output created: manuscript_marine.pdf diff --git a/review/evidence/paper_build_cached_metadata.json b/review/evidence/paper_build_cached_metadata.json new file mode 100644 index 0000000..23597fc --- /dev/null +++ b/review/evidence/paper_build_cached_metadata.json @@ -0,0 +1,16 @@ +{ + "command": [ + "quarto", + "render", + "manuscript_marine.qmd", + "--to", + "pdf", + "-M", + "latex-auto-install:false" + ], + "cwd": "/Users/marinedenolle/GitHub/codameter/review/evidence/reproduction_workspace/paper", + "tex_cache": "/Users/marinedenolle/GitHub/codameter/review/evidence/tex_cache", + "returncode": 0, + "status": "completed", + "elapsed_seconds": 60.975 +} diff --git a/review/evidence/paper_build_metadata.json b/review/evidence/paper_build_metadata.json new file mode 100644 index 0000000..65e698e --- /dev/null +++ b/review/evidence/paper_build_metadata.json @@ -0,0 +1,12 @@ +{ + "command": [ + "/Users/marinedenolle/GitHub/codameter/.pixi/envs/test/bin/python", + "paper/build.py", + "--no-survey" + ], + "cwd": "/Users/marinedenolle/GitHub/codameter/review/evidence/reproduction_workspace", + "scope": "Current manuscript render; preserves checked-in survey and figure artifacts. Does not regenerate results.", + "returncode": 1, + "status": "completed", + "elapsed_seconds": 13.896 +} diff --git a/review/evidence/paper_sections.md b/review/evidence/paper_sections.md new file mode 100644 index 0000000..07e4b96 --- /dev/null +++ b/review/evidence/paper_sections.md @@ -0,0 +1,311 @@ +# Focused paper findings + +Date: 2026-09-10. +Target: GJI research paper, with methods emphasis. +Source: `paper/manuscript_marine.qmd`. +Profile: pre-submission-reviewer `profiles/default.md`. +Scopes: S-AB, S-IN, S-DI, S-CO, S-CD. +Mode: sequential focused review; first-pass evidence. +These are raw findings for the review orchestrator. +Source files were not changed. +Line references refer to the QMD source. +Code, figures, and reproduction have separate reviewers. + +## Strengths + +- The processing-choice question has clear practical relevance. See 127–158. +- The exact sign convention is explicitly defined. See 95–125. +- The multiverse connects methods with uncertainty propagation. See 838–1027. +- Independent comparison exposed a consequential sign error. See 1270–1289. +- The reporting checklist supports inspectable observational workflows. See 1212–1252. +- Stress conversion limitations are acknowledged explicitly. See 1296–1301. + +## S-AB: title and abstract + +Inventory: title present; abstract present; no plain-language summary. +Abstract length: 362 whitespace-delimited source tokens, approximately. +Problem, approach, result, and significance are all present. +The quantitative headline is the square-root-N uncertainty ratio. + +1. **S-AB.1 PASS / MINOR FORMAT.** Length satisfies GJI's 500-word cap. + GJI requires one paragraph for research-paper summaries. + This source contains three paragraphs, lines 10–45. + Join paragraphs after resolving the scientific overclaims. + [GJI author instructions](https://academic.oup.com/gji/pages/General_Instructions). +2. **S-AB.2 PASS.** The processing uncertainty gap is explicit, 13–18. +3. **S-AB.3 PARTIAL.** The approach appears at 22–36. + The treatment of pipeline choices needs qualification. + Specify which configurations share the same physical estimand. +4. **S-AB.4 PARTIAL / MAJOR.** The numeric headline needs its estimand, 27–31. + Standard deviation describes dispersion among observations. + Standard error describes precision of an estimated mean. + Their square-root-N ratio is definitional under independence. + It does not establish two valid significance answers. + Name the tested null and the target quantity. + State independence requirements and pair dependence limitations. +5. **S-AB.5 PARTIAL / MAJOR.** Operational readiness exceeds demonstrated scope, 20–21, 39–43. + The body presents three stations and computational optimizations. + It does not present operational reliability or agent evaluation. + Separate demonstrated capability from intended future deployment. +6. **S-AB.6 PASS.** The ensemble covariance contribution is identifiable, 33–36. + Its calibration and probabilistic interpretation remain separate questions. +7. **S-AB.7 PARTIAL / MINOR.** The title fits processing sensitivity, line 2. + “Reproducibility cost” could imply measured reproducibility failure rates. + Define that phrase through sensitivity and incomplete reporting. + A title change is optional, following scope clarification. +8. **S-AB.8 FAIL / MAJOR.** Several promised results lack paper evidence. + See the claim trace below. +9. **S-AB.9 FAIL / MAJOR.** Depth demonstration and agent robustness overreach. + Lines 36–43 promise results absent from the body. + Add completed experiments or narrow those claims. +10. **S-AB.10 PARTIAL / MINOR.** Delta-v/v is defined clearly. + Explain covariance notation when retaining it in the abstract. + “Agent-ready” needs an observable capability definition. +11. **S-AB.11 N/A.** No plain-language summary is supplied. + +### Abstract claim trace + +| Claim location | Claimed result | Body support | Verdict | +|---|---|---|---| +| 20–21 | Scalable, uncertainty-aware, agent-ready observations | Optimizations, 959–971; deployment, 1114–1201 | Partial; readiness criteria absent | +| 22–24 | Individual and combined processing effects | Results; multiverse, 838–911 | Shown on selected synthetic scenarios | +| 24 | Estimator families fail differently at large changes | Estimator section; `fig:methods`, 359–409 | Supported conditionally; verify plotted numbers separately | +| 24–26 | Component averaging changes identical-pair estimates | Aggregation; `fig:aggregation`, 412–440 | Supported on constructed component mixture | +| 27–31 | Significance changes by approximately square-root-N | Uncertainty section; appendix, 1392–1402 | Demonstrated convention difference; interpretation overstates equivalence | +| 33–36 | Ensemble becomes Bayesian data covariance | Bayesian model; `fig:bayes`, 973–1027 | Implemented claim; derivation/calibration requires methods audit | +| 36–37 | Errors propagated through depth inversion | Framework, 1031–1087 | UNSUPPORTED as demonstrated result | +| 37–40 | California product reproduced across pipelines | Deployment; `fig:realdata-validation`, 1133 onward | Partial; waveform agreement differs from uncertainty validation | +| 40–41 | Portability and laptop-to-cloud scalability demonstrated | 959–971; proposed cloud pipeline, 1120–1128 | Partial; no scaling curve or deployment success statistics | +| 41–43 | Advisor robustly evaluated against golden data | Intro mentions scoring, 171–176 | UNSUPPORTED in manuscript; no evaluation protocol/results section | +| 43–45 | Reproducible uncertainty-aware measurement package | Whole paper; availability, 1429–1432 | Conditional on reproduction and calibration results | + +Depth contradiction is explicit, not inferred from missing figures. +Lines 1033–1037 describe executable stages as under development. +Line 1064 instead says depth covariance is implemented. +Lines 1298–1301 simultaneously promise delivery and future testing. +Conclusions 1317–1318 again describe the depth stage being built. + +Top fixes: align delivered scope; define uncertainty estimands. +Then add measured agent and deployment evaluation results. +Tier feed: C1 Good; C4 Fair; C5 Good; C7 Fair. + +## S-IN: introduction + +Swales moves: M1 PASS, 72–93; M2 PASS, 127–145. +M3 PASS structurally, 147–176; scientific scope needs tightening. +Five questions: problem, prior work, limitations, aim, setup present. +Length: 107 source lines, including three displayed equations. +The introduction remains motivated rather than purely historical. + +1. **S-IN.1 PARTIAL / MINOR.** History needs precise attribution, 80–85. + Piton de la Fournaise was not the technique's discovery. + Distinguish eruption forecasting from earlier passive monitoring. + Merapi monitoring predates the cited 2008 deployment. + The 2006 reference already exists in `references.bib`. + [Sens-Schönfelder and Wegler, 2006](https://agupubs.onlinelibrary.wiley.com/doi/abs/10.1029/2006gl027797). +2. **S-IN.2 PARTIAL / MAJOR.** The novelty boundary is unsupported, 135–145. + “Cumulative effect” needs an explicit literature-search boundary. + Existing estimator comparisons already test multiple processing dimensions. + Claim the particular joint design and covariance contribution. + Avoid implying earlier uncertainty quantification was absent. +3. **S-IN.3 PARTIAL / MAJOR.** Stated scope exceeds shown work, 160–176. + Depth illustration and advisor evaluation need corresponding results. + Distinguish reproduction of curves from calibrated error reproduction. +4. **S-IN.4 PASS.** The central objective is explicit, 151–158. +5. **S-IN.5 PASS, WITH QUALIFICATION.** Operational relevance is clear, 80–93. + “Determining early warning” requires operational decision evidence. + “Tens of tailings dams” requires deployment-count evidence. + The cited studies support applications and monitoring potential. + They do not establish every stronger operational claim. + [Çubuk-Sabuncu et al., 2021](https://agupubs.onlinelibrary.wiley.com/doi/abs/10.1029/2020GL092265). + [Ouellet et al., 2022](https://doi.org/10.1038/s43247-022-00629-w). +6. **S-IN.6 PARTIAL / OPTIONAL CLARITY.** The convention derivation interrupts motivation. + Lines 95–125 could move into the synthetic framework. + Retain the physical sign definition in the introduction. + This is structural advice, not a length violation. +7. **S-IN.7 PARTIAL.** General-to-specific progression is otherwise clear. +8. **S-IN.8 PARTIAL / MINOR.** Define SNR before line 123. +9. **S-IN.9 PARTIAL / MAJOR EVIDENCE.** Hydrological attribution overstates the source, 140–145. + “Figure x” remains an unresolved placeholder. + “Direct correlation” obscures the reported anticorrelation sign. + Processing differences do not exclude genuine geological differences. + The cited review discusses both hydrological and physical variability. + Present processing as one possible source of scatter. + Identify the actual figure and support attribution quantitatively. + [Denolle et al., 2025, sections 2 and 5](https://comptes-rendus.academie-sciences.fr/geoscience/articles/10.5802/crgeos.310/). +10. **S-IN.10 PASS.** All introduction citation keys resolve locally. + Bibliographic resolution does not validate each associated claim. + +Novelty assessment: plausible, bounded methodological contribution. +The strongest novelty is joint processing-sensitivity accounting. +It is not the seven-estimator comparison by itself. +Yuan et al. already compare those seven methods. +They use heterogeneous full-wave simulations and depth-dependent perturbations. +[Yuan et al., 2021](https://academic.oup.com/gji/article/226/2/828/6224864). + +Top fixes: bound novelty; align scope; repair hydrological attribution. +Tier feed: C1 Good/Fair; C6 Fair; C7 Good. + +## S-DI: discussion + +Moves: summary YES; interpretation YES; implications YES; future YES. +Comparison: self YES; foundational global methods YES; competing results limited. +Alternatives: PARTIAL. Explicit synthetic limitations: INSUFFICIENT. +The named “three responses” actually contains five responses. +This is minor organization, lines 1210–1291. + +1. **S-DI.1 PASS.** Opens with the central finding, 1207–1209. +2. **S-DI.2 PASS.** Connects observations with reporting and propagation. +3. **S-DI.3 PARTIAL.** No explicit falsifiable hypothesis was specified. + Give a bounded answer for the scenarios actually tested. +4. **S-DI.4 PARTIAL / MAJOR.** Comparison remains mostly prescriptive, 1255–1268. + Compare the proposed uncertainty with independent established approaches. + State what improves beyond Clarke, Weaver, and Yuan. +5. **S-DI.5 FAIL / MAJOR.** Discuss contradictory estimator performance evidence. + The manuscript promotes stretching for low SNR, 309–312. + Table 933–936 repeats this as best practice. + Yet cited Yuan Table B3 ranks TS noise resistance low. + The same table ranks DTW noise resistance high. + Those rankings themselves depend on the tested scenario. + Explain the different noise, windows, tuning, and targets. + Compare tuned estimators under matched conditions before generalizing. + [Yuan et al., 2021, Table B3](https://academic.oup.com/gji/article/226/2/828/6224864). +6. **S-DI.6 FAIL / MAJOR.** Dominance over data is not identified, 1207–1209. + A conditional processing sweep fixes the observed waveform. + It cannot partition variability across possible observed waveforms. + Add replicated wavefields, source changes, and noise realizations. + Separate physical heterogeneity from preprocessing sensitivity explicitly. +7. **S-DI.7 FAIL / MAJOR.** Missing limitations qualify the central method. + No representativeness guarantee exists for the pipeline prior. + Shared waveforms induce dependence among pipeline estimates. + An ensemble can share bias while remaining tightly clustered. + Different bands can target different physical properties. + Selecting ensemble members using truth risks optimistic calibration. + State these limitations beside the covariance recommendation, 1255–1262. +8. **S-DI.8 PARTIAL.** Interpretations sometimes become universal prescriptions. + “More honest” at 1259 needs demonstrated coverage conditions. + Marginalizing configurations alone does not guarantee calibrated errors. +9. **S-DI.9 PARTIAL / MINOR.** New historical numbers appear, 1277–1279. + The negative validation correlations need an archived result table. + Move the diagnostic before/after comparison into Results. +10. **S-DI.10 FAIL / MAJOR.** Reported significance is overgeneralized, 1216–1218. + Distinguish mean precision, population spread, and common systematic error. + Neither SD nor SE universally replaces the other. + State the desired inferential target before computing significance. +11. **S-DI.11 PARTIAL / MAJOR.** Depth delivery remains internally contradictory. + Lines 1298–1301 claim delivery and ongoing construction together. + Propagated covariance cannot repair misspecified sensitivity kernels. + Retain depth as a qualified roadmap unless demonstrated. + +Independent validation remains a substantial positive finding. +The sign-error example is concrete and scientifically useful. +Avoid claiming agreement with published products proves physical truth. +Agreement establishes consistency against one independent processing product. + +Top fixes: add limitations; compare competing methods; define calibration. +Tier feed: C4 Fair; C6 Fair; C7 Good/Fair. + +## S-CO: conclusions + +Pols framework: six elements present; substantiation is partial. +Score: 6/7, using only fully supported elements. +Independent readability YES; new results NO; verbatim copying NO. + +1. **S-CO.1 PASS.** The paragraph is independently understandable, 1305–1318. +2. **S-CO.2 PASS.** It restates the processing uncertainty objective. +3. **S-CO.3 PASS.** The reproducibility problem remains clear. +4. **S-CO.4 PASS.** The synthetic estimator comparison is identified. +5. **S-CO.5 PARTIAL / MAJOR.** The square-root-N conclusion needs conditions. + Lines 1308–1310 conflate spread with mean uncertainty. + State the estimand and dependence assumptions explicitly. +6. **S-CO.6 PARTIAL / MINOR.** Add a genuinely empirical quantitative result. + The current headline mostly repeats an algebraic identity. + Prefer a bounded processing-effect or held-out coverage result. +7. **S-CO.7 PASS.** Reporting and covariance recommendations are concrete. +8. **S-CO.8 PASS.** No new numerical result appears here. +9. **S-CO.9 PARTIAL / MAJOR.** Covariance propagation is necessary but insufficient. + Lines 1314–1316 imply it ensures honest depth uncertainty. + Include kernel uncertainty and calibrated measurement-model assumptions. +10. **S-CO.10 PASS.** No empty opening or verbatim restatement identified. +11. **S-CO.11 FAIL / MAJOR.** Contribution conflicts with the abstract. + Here the depth stage is still being built. + The abstract says its error propagation is illustrated. + +Top fixes: align depth status; qualify significance; substantiate empirically. +Tier feed: C1 Good; C4 Fair; C7 Good/Fair. + +## S-CD: citation and idea diversity + +These signals are surfaced, never scored as diversity quotas. +Identity inference was disabled by the default author profile. +The inventory is `review/evidence/citation_inventory.json`. +Counts combine QMD citations and the included appendix table. +Email text was excluded from citation parsing. + +1. **S-CD.1 INFORMATIONAL.** Nine of 129 references include Denolle. + That is 7.0% of the combined reference list. + Main QMD citations: eight of 59, or 13.6%. + These counts use explicit author strings, not inferred identity. + There is no demonstrated self-citation inflation. +2. **S-CD.2 INFORMATIONAL.** Years span 1951–2026; median 2017. + Counts: 1950s 1; 1980s 1; 1990s 3. + Counts: 2000s 18; 2010s 65; 2020s 41. + The list combines foundational and recent research. +3. **S-CD.3 INFORMATIONAL.** GJI supplies 25 references, or 19.4%. + JGR Solid Earth supplies 22; GRL supplies 22. + Those three venues comprise 53.5% of references. + There are 39 raw venue/metadata categories. + Shannon entropy is 4.14 bits over those categories. + Two entries lack journal fields, including one book. + Venue labels were not fully standardized across historical names. +4. **S-CD.4 CANNOT ASSESS COMPLETELY.** Author-country metadata are absent locally. + No complete OpenAlex affiliation enrichment was performed. + Study location is not author affiliation or nationality. + Do not derive demographic coverage from surnames or sites. +5. **S-CD.5 PARTIAL INFORMATIONAL.** The combination is interdisciplinary. + Seismology, scattering physics, statistics, and rock physics appear. + Formal OpenAlex field counts were not computed. +6. **S-CD.6 INFORMATIONAL.** Main QMD has 59 unique cited works. + Those works receive 127 citation occurrences. + Clarke appears 12 times; Weaver 8; Obermann2013 7. + Thirty-four main-text works appear once. + Seventy works appear only through the survey appendix. + That is expected for an explicitly cited evidence catalogue. + It is not independently evidence of ornamental citation. +7. **S-CD.7 DISABLED.** No gender, race, or nationality inference. +8. **S-CD.8 MIXED / STRENGTH.** Methodology and multiverse analysis combine productively. + No co-citation baseline was computed for quantitative novelty. + Existing seven-estimator comparison is conventional prior work. + Joint choice accounting is the stronger candidate contribution. +9. **S-CD.9 PASS.** Cross-disciplinary framing is scientifically legitimate. + Statistical validity, not unfamiliarity, determines the required revisions. + +All 129 unique bibliography entries are cited somewhere. +There are no duplicate keys or missing citation keys. +The appendix contains 103 citations to 102 unique keys. +This may reflect multiple rows for one publication. +Reconcile “103 studies” against unique study definitions. +The dedicated survey audit should determine the correct denominator. + +The survey caveat also reverses its uncertainty direction. +Lines 1414–1423 distinguish full-text and metadata-only extraction. +Missing metadata cannot establish nonreporting in inaccessible papers. +Apparent nonreporting can therefore be inflated, not understated. +Report verified and inaccessible denominators separately. +This is an evidence-quality concern, not a diversity penalty. + +## Primary-source verification scope + +Checked sources support bounded comparisons, not exhaustive novelty claims. +The search did not establish absence of prior joint analyses. +The main references below resolve through publisher sources. + +- [GJI instructions](https://academic.oup.com/gji/pages/General_Instructions): summary requirements. +- [Yuan et al., 2021](https://academic.oup.com/gji/article/226/2/828/6224864): seven-method comparison and Table B3. +- [Sens-Schönfelder and Wegler, 2006](https://agupubs.onlinelibrary.wiley.com/doi/abs/10.1029/2006gl027797): earlier passive volcano monitoring. +- [Denolle et al., 2025](https://comptes-rendus.academie-sciences.fr/geoscience/articles/10.5802/crgeos.310/): groundwater anticorrelation and physical alternatives. +- [Çubuk-Sabuncu et al., 2021](https://agupubs.onlinelibrary.wiley.com/doi/abs/10.1029/2020GL092265): Reykjanes monitoring study. +- [Ouellet et al., 2022](https://doi.org/10.1038/s43247-022-00629-w): instrumented Canadian tailings-dam study. + +Suggested synthesis priority: C4 scope, then probabilistic validity. +Preserve the multiverse premise while testing its calibration. diff --git a/review/evidence/pytest.log b/review/evidence/pytest.log new file mode 100644 index 0000000..a670a3c --- /dev/null +++ b/review/evidence/pytest.log @@ -0,0 +1,28 @@ +============================= test session starts ============================== +platform darwin -- Python 3.12.13, pytest-9.0.3, pluggy-1.6.0 +rootdir: /Users/marinedenolle/GitHub/codameter +configfile: pyproject.toml +testpaths: tests +plugins: cov-7.1.0, nbval-0.11.0, hypothesis-6.152.4 +collected 301 items + +tests/test_bench.py ......... [ 2%] +tests/test_cli.py .... [ 4%] +tests/test_coupling.py ............... [ 9%] +tests/test_coupling_tiers.py ....... [ 11%] +tests/test_data_loaders.py ............ [ 15%] +tests/test_data_readiness.py ... [ 16%] +tests/test_deviations.py ............... [ 21%] +tests/test_forcing_models.py ........... [ 25%] +tests/test_forward_models.py ......................... [ 33%] +tests/test_frugalmind_export.py ......... [ 36%] +tests/test_golden.py ...................... [ 43%] +tests/test_kernels.py .........s [ 47%] +tests/test_linear_inversion.py ............. [ 51%] +tests/test_private_golden.py ...... [ 53%] +tests/test_property_providers.py ......... [ 56%] +tests/test_sign_convention.py ............... [ 61%] +tests/test_staged_workflow.py .... [ 62%] +tests/test_stretching_interpolation.py ................................. [ 73%] +...................... [ 81%] +tests/test_synthetic_demo.py .................. diff --git a/review/evidence/pytest_metadata.json b/review/evidence/pytest_metadata.json new file mode 100644 index 0000000..048f695 --- /dev/null +++ b/review/evidence/pytest_metadata.json @@ -0,0 +1,30 @@ +{ + "command": [ + ".pixi/envs/test/bin/python", + "-m", + "pytest", + "-ra", + "-p", + "no:cacheprovider", + "--junitxml=review/evidence/pytest.xml" + ], + "python": "3.12.13", + "platform": "macOS-15.7.4-arm64-arm-64bit", + "versions": { + "codameter": "0.2.1", + "numpy": "2.4.3", + "scipy": "1.17.1", + "pandas": "3.0.2", + "pytest": "9.0.3", + "disba": "0.7.0" + }, + "status": "timeout", + "timeout_seconds": 540, + "elapsed_seconds": 540.088, + "visible_pass_marks": 261, + "visible_skip_marks": 1, + "collected": 301, + "uncompleted": 39, + "skip_reason_from_source": "tests/test_kernels.py:136: disba is installed; cannot test missing-import path", + "no_failures_visible": true +} diff --git a/review/evidence/pytest_targeted.log b/review/evidence/pytest_targeted.log new file mode 100644 index 0000000..8a4d054 --- /dev/null +++ b/review/evidence/pytest_targeted.log @@ -0,0 +1,21 @@ +============================= test session starts ============================== +platform darwin -- Python 3.12.13, pytest-9.0.3, pluggy-1.6.0 +rootdir: /Users/marinedenolle/GitHub/codameter +configfile: pyproject.toml +plugins: cov-7.1.0, nbval-0.11.0, hypothesis-6.152.4 +collected 144 items + +tests/test_uq_bayes.py ..... [ 3%] +tests/test_uq_depth.py ..... [ 6%] +tests/test_uq_measurement.py ....... [ 11%] +tests/test_uq_processing.py .... [ 14%] +tests/test_sign_convention.py ............... [ 25%] +tests/test_stretching_interpolation.py ................................. [ 47%] +...................... [ 63%] +tests/test_linear_inversion.py ............. [ 72%] +tests/test_staged_workflow.py .... [ 75%] +tests/test_forcing_models.py ........... [ 82%] +tests/test_forward_models.py ......................... [100%] + +- generated xml file: /Users/marinedenolle/GitHub/codameter/review/evidence/pytest_targeted.xml - +============================= 144 passed in 38.02s ============================= diff --git a/review/evidence/pytest_targeted.xml b/review/evidence/pytest_targeted.xml new file mode 100644 index 0000000..ecbf687 --- /dev/null +++ b/review/evidence/pytest_targeted.xml @@ -0,0 +1 @@ + diff --git a/review/evidence/pytest_targeted_metadata.json b/review/evidence/pytest_targeted_metadata.json new file mode 100644 index 0000000..a16c65f --- /dev/null +++ b/review/evidence/pytest_targeted_metadata.json @@ -0,0 +1,25 @@ +{ + "command": [ + ".pixi/envs/test/bin/python", + "-m", + "pytest", + "-ra", + "-p", + "no:cacheprovider", + "--junitxml=review/evidence/pytest_targeted.xml", + "tests/test_uq_bayes.py", + "tests/test_uq_depth.py", + "tests/test_uq_measurement.py", + "tests/test_uq_processing.py", + "tests/test_sign_convention.py", + "tests/test_stretching_interpolation.py", + "tests/test_linear_inversion.py", + "tests/test_staged_workflow.py", + "tests/test_forcing_models.py", + "tests/test_forward_models.py" + ], + "thread_limits": 1, + "returncode": 0, + "status": "completed", + "elapsed_seconds": 41.449 +} diff --git a/review/evidence/reproducibility.md b/review/evidence/reproducibility.md new file mode 100644 index 0000000..70fd570 --- /dev/null +++ b/review/evidence/reproducibility.md @@ -0,0 +1,250 @@ +# Reproducibility and scalability evidence + +Audit date: 2026-09-10 UTC. Author profile: default. +Scope: current `paper/manuscript_marine.qmd`, source, artifacts, and tests. +No project source or published figures were changed. +Runtime caches may be generated by existing tests. + +## Principal findings + +1. **Major: the advertised build omits six figures.** + `paper/build.py:124–128` invokes only `literature/synthetic_dvv_demo.py`. + That wrapper invokes `synthetic_demo.build_all`. + Its registry excludes six manuscript graphics. + See `src/codameter/synthetic_demo.py:2569–2597`. + Missing generators cover deviations, multiverse, Bayesian, and real-data figures. + Their filenames appear in `reproduction_probes.json`. + Separate synthetic builders exist at `deviations.py:511–540`. + Bayesian generation exists at `uq_bayes.py:500–525`. + Neither is invoked by the advertised build. + Consequently, rebuilding can silently retain stale central results. + This contradicts the one-command claim at manuscript lines 1264–1268. + +2. **Major: primary real-data products are locally available only.** + Gate1 Parquet files exist in this workspace. + However, `git ls-files` does not include them. + `git check-ignore` attributes exclusion to `.gitignore:55`. + The repository tracks legacy Arrow products and figures. + The current manuscript promises a future archive DOI. + Its availability statement lacks a primary-data archive citation. + See manuscript lines 1427–1432 and Gate1 README lines 8–16. + The comparison driver belongs to another project. + See `paper/data/gate1/README.md:25–29`. + No local `compare_cd2022.py` was found. + A Git checkout cannot regenerate these real-data figures. + +3. **Major: the reported validation count contradicts supplied dates.** + Manuscript lines 1133–1144 specify 2018–2019 observations. + They also remove 150 initial reference days. + Yet CI.LJR supposedly retains 681 overlapping days. + Its local Parquet contains 727 unique dates. + Those span 2018-01-01 through 2019-12-30. + Only 578 dates remain after 150 calendar days. + Even complete daily coverage permits at most 580. + Therefore 681 cannot describe the stated unique-day comparison. + This assumes burn-in starts with the 2018 observations. + Earlier legacy-history burn-in would define a different mask. + A different mask, interval, or duplicated join may explain it. + The missing comparison driver prevents identifying which explanation. + CI.ARV also retains 578; CI.RXH retains 489. + All observed-date counts and hashes accompany the probe output. + These counts do not independently test the correlation coefficients. + +4. **Major: posterior calibration is not established by existing tests.** + `tests/test_uq_bayes.py:12–61` uses one synthetic realization. + It tests shapes, PSD, width, positivity, and RMS. + It does not test repeated-realization interval coverage. + Neither chain mixing nor held-out calibration is tested there. + Manuscript lines 1011–1023 claim nominal truth coverage. + That statement needs independent repeated datasets and diagnostics. + Structural model violations require separate coverage reporting. + Root audit probes examine concrete common-bias counterexamples separately. + +5. **Major for deployment: Bayesian computation remains dense.** + `uq_bayes.py:245–248` builds a dense second-difference operator. + Lines 284–285 form its dense cross-product. + Lines 299–303 perform Cholesky and generic solves each iteration. + Algorithmic cost grows cubically with epoch count. + Matrix storage grows quadratically with epoch count. + A single ten-year daily covariance occupies approximately 107 MB. + Several such matrices and posterior samples coexist. + The benchmarked estimator speedups do not establish Bayesian scalability. + See manuscript lines 959–971 for their actual scope. + Banded precision solves could exploit the existing prior structure. + Record memory, throughput, and scientific equivalence before deployment claims. + +6. **Moderate: shard aggregation lacks integrity checks.** + Stable work partitioning and process pools already exist. + See `bench.py:130–144` and `208–230`. + However, aggregation simply concatenates available JSONL rows. + See `bench.py:259–277` and `314–327`. + A controlled probe declared two shards but supplied one. + That shard contained the same row twice. + Aggregation accepted both rows and returned exit code zero. + Results preserve configuration values but omit environment fingerprints. + See `bench.py:177–195` for the emitted row schema. + Add unique cell identities and expected-shard completeness checks. + Reject mixed generator versions, duplicate cells, and incompatible grids. + Partial failures should remain visible in final dataset manifests. + +7. **Moderate: version and environment provenance diverge.** + Runtime source version is 0.4.0. + Installed metadata reports 0.2.1 in this environment. + `CITATION.cff` declares 0.1.0 and another JGR manuscript. + The present manuscript targets GJI and specifies 0.4.0. + `pixi.lock` and `uv.lock` provide useful pinned resolutions. + However, CI installs floating dependency ranges from pyproject. + See `.github/workflows/ci.yml:47–52`. + Docker also installs floating requirements and an unpinned image. + See `docker/Dockerfile:5–19`. + Native Quarto and TeX versions remain outside those locks. + Archive the actual environment, source commit, and input hashes. + +8. **Moderate: exported interpretation results lack complete replay manifests.** + `workflow.py:696–731` preserves summaries and decision trails. + `workflow.py:733–754` exports results and residual tables. + These are valuable diagnostic artifacts. + They do not capture every input or resolved configuration. + Software fingerprints, input checksums, and invocation are also absent. + A standalone result directory therefore cannot establish full provenance. + +9. **Major: active parameter bounds can erase reported uncertainty.** + `inverse/linear_fit.py:544–549` zeroes active covariance rows and columns. + This makes the corresponding reported standard deviation zero. + A fitted boundary does not establish an exactly known parameter. + Bounded posterior intervals require truncated or constrained uncertainty treatment. + Existing passing regression tests do not establish interval calibration. + The root scientific audit evaluates this downstream consequence separately. + +## Pass 1: open-science checklist + +| Item | Assessment | Evidence | +|---|---|---| +| S-RP.1 Availability statement | PASS | Manuscript 1427–1432 | +| S-RP.2 Persistent primary-data citations | FAIL | Statement identifies software; primary products lack an archive DOI | +| S-RP.3 Citation/link resolution | PARTIAL | GitHub URL is well formed; release accessibility remains unverified here | +| S-RP.4 Persistent software identifier | FAIL | Zenodo DOI promised for publication, not supplied | +| S-RP.5 Pinned versions | PARTIAL | Two lockfiles exist; publication environment unspecified and metadata divergent | +| S-RP.6 Executable driver | PARTIAL | Repository build exists; it omits six figure generators | +| S-RP.7 Derived-data archival | FAIL | Primary Gate1 Parquet files are ignored and unarchived in supplied citations | +| S-RP.8 FAIR | PARTIAL | Open formats and MIT code license; incomplete findability and replay provenance | +| S-RP.9 Restrictions and licenses | PARTIAL | MIT code explicit; waveform/product redistribution licenses not identified here | +| S-RP.10 Randomness controls | PARTIAL | Source seeds supplied; manuscript lacks exact stochastic run settings | +| S-RP.11 Compute environment | PARTIAL | Python environments and Docker exist; paper benchmarks omit exact execution hardware | + +This checklist evaluates supplied artifacts, not journal-policy compliance. +It does not assert that GJI mandates software DOIs. + +## Pass 2: reconstruction from manuscript text + +| Step | Input identity/access | Operation | Parameters | Sequence | Expected output | +|---|---|---|---|---|---| +| 1. Generate reference codas | Synthetic model described | Envelope and band-limited random wavefield | Missing exact seeds and per-experiment envelope settings | Described | Qualitative coda | +| 2. Generate monitoring series | Reference and specified synthetic signals | Time dilation plus noise | Several bands/SNRs stated; complete machine configuration absent | Described | Ground-truth dv/v and noisy CCFs | +| 3. Sweep measurement choices | Same synthetic inputs | Seven estimators and factorial choices | Several fixed values stated; full method-specific settings deferred to software | Described | Curves, RMS, drop errors, sensitivity indices | +| 4. Infer measurement covariance | Per-configuration measurements/errors | Gibbs model plus constructed covariance | Missing exact prior scales, chain lengths, burn-in, seeds, diagnostics | Described | Posterior and data covariance | +| 5. Validate real observations | SCEDC and published products identified generally | NoisePy correlation, ensemble estimation, smoothing, joins | Exact channels, inventories, preprocessing, joins and masks incomplete | Partly described | Reported correlations and three figures | +| 6. Propagate into depth | Hypothetical per-band observations | Kernel inversion | No complete demonstrated site, kernels, priors, or experiment | Conceptual | Claimed depth posterior, elsewhere described as development | +| 7. Regenerate article | Source and six missing figure recipes | Build and render | Build documented only in repository | Partly reproducible | PDF and numerical result manifests | + +**REPRODUCTION-STOP S-RP.R1: seeded synthetic realization.** +Missing: exact input realization and complete experiment parameters. +Location: manuscript 180–220 and 234–277. +Consequence: independent synthetics cannot recreate the reported numerical curves. +Severity: BLOCKING for exact text-only reproduction. +Code supplies defaults, making reconstruction partly recoverable locally. + +**REPRODUCTION-STOP S-RP.R2: Bayesian experiment.** +Missing: prior hyperparameters, chain settings, and convergence criteria. +Location: manuscript 979–1014. +Consequence: the published covariance is not numerically specified. +Severity: BLOCKING for text-only covariance reproduction. +Local defaults: `uq_bayes.py:256–263` and `382–400`. + +**REPRODUCTION-STOP S-RP.R3: real-waveform processing and comparison.** +Missing: exact input manifests, preprocessing settings, and comparison driver. +Location: manuscript 1120–1160; Gate1 README 25–29. +Consequence: reported real-data validation cannot be independently reconstructed. +Severity: BLOCKING, including the provided repository snapshot. +No exact station-channel-day manifest or comparable raw CCF release exists here. +Response removal, gap handling, whitening, and normalization need explicit settings. +The joins and exclusion mask require executable specification. + +**REPRODUCTION-STOP S-RP.R4: regenerating all manuscript figures.** +Missing: complete orchestration and numerical result provenance. +Location: manuscript 1264–1268; `paper/build.py:124–131`. +Consequence: a successful PDF build may preserve stale plots. +Severity: BLOCKING for the advertised one-command result reproduction. + +**REPRODUCTION-STOP S-RP.R5: depth demonstration.** +Missing: actual illustrated inversion inputs and posterior results. +Location: abstract 35–37 versus manuscript 1033–1037, 1298–1301. +Consequence: the abstract's demonstrated propagation cannot be reproduced. +Severity: BLOCKING if retained as a completed scientific claim. +Otherwise explicitly present this section as future framework development. + +**REPRODUCTION VERDICT: NOT RECONSTRUCTABLE; five blocking claim-path stops.** + +Tier feed: **Poor** for current reproducibility readiness. +The supplied skill's strict archive gate would imply **Fatal**. +That gate combines an unreproduced central result and missing DOI. +This concerns submission readiness, not intrinsic scientific impossibility. +Executable synthetic infrastructure remains a substantial strength. + +## Highest-value repairs + +1. Publish a versioned, complete article reproduction bundle. +2. Archive real products and release the comparison driver. +3. Generate every figure from saved numerical result manifests. +4. Add independent uncertainty calibration and deployment integrity benchmarks. + +## Verification and limits + +Existing targeted tests: **144 passed, zero skipped**. +Pytest runtime: **38.02 seconds**; wrapper runtime: **41.449 seconds**. +Modules cover UQ, signs, interpolation, inversion, and forward models. +Exact invocation: `pytest_targeted_metadata.json`. +Full logs: `pytest_targeted.log`; machine results: `pytest_targeted.xml`. +No scientific adequacy claim follows merely from passing tests. + +**Full-suite attempt timed out at 540 seconds.** +The suite collected 301 tests. +Captured output shows 261 passes and one skip. +Thirty-nine tests remained uncompleted at termination. +No failures appeared before termination. +The interruption occurred during `tests/test_synthetic_demo.py`. +The skip checks missing-disba behavior with disba already installed. +Its reason appears at `tests/test_kernels.py:136`. +These are captured progress counts, not a completed pytest summary. +The full-suite JUnit file was not finalized. +Do not add overlapping targeted-test counts to these numbers. +Full-suite outcomes: `pytest_metadata.json` and `pytest.log`. +Isolated-render outcomes: `paper_build_cached_metadata.json`. +The initial isolated render failed on LuaTeX cache permissions. +`paper_build.log` records that environment failure. +A writable cache rerun disables automatic package installation. +It preserves the existing figures and survey bibliography. +Thus a successful render verifies compilation, not numerical reproduction. + +**Current-source compilation passed after correcting the cache location.** +Quarto exit code: zero; elapsed time: 60.975 seconds. +The fresh PDF contains 74 pages. +Artifact: `reproduction_workspace/paper/manuscript_marine.pdf`. +Exact command, working directory, and cache location accompany metadata. +The rendered artifact still embeds pre-existing numerical figures. + +Probe replay command: + +```sh +MPLCONFIGDIR=/tmp/codameter-review-mpl .pixi/envs/test/bin/python review/evidence/reproduction_probes.py +``` + +Local scientific environment: Python 3.12.13; NumPy 2.4.3. +SciPy 1.17.1; pandas 3.0.2; pytest 9.0.3; disba 0.7.0. +These are observed installed versions, not recommended versions. +No dependency installation was deliberately requested for this audit. +The failed default Quarto run attempted package maintenance. +The successful retry explicitly disabled automatic installation. +No cloud jobs or external data downloads were attempted. +External URL resolution and archive availability require separate verification. +The root audit records additional deterministic/probabilistic failure probes. diff --git a/review/evidence/reproduction_probes.json b/review/evidence/reproduction_probes.json new file mode 100644 index 0000000..bbcac23 --- /dev/null +++ b/review/evidence/reproduction_probes.json @@ -0,0 +1,104 @@ +{ + "source_version": "0.4.0", + "installed_metadata_version": "0.2.1", + "figures_not_regenerated_by_build_figures": [ + "demo_10_deviations.png", + "demo_11_multiverse.png", + "demo_12_bayes.png", + "realdata_1_validation.png", + "realdata_2_interferograms.png", + "realdata_3_warmup.png" + ], + "realdata": { + "LJR": { + "rows": 727, + "date_min": "2018-01-01 00:00:00", + "date_max": "2019-12-30 00:00:00", + "unique_dates": 727, + "duplicates": 0, + "rows_after_150_calendar_days": 578, + "columns": [ + "date", + "dvv", + "dvv_err", + "dvv_err_within", + "dvv_err_method", + "cc", + "n_members", + "network", + "station", + "band", + "config_hash" + ], + "legacy_rows": 6596, + "legacy_columns": [ + "DATE", + "DVV", + "CC" + ], + "parquet_sha256": "288412098cc8174dc1dd4ec9c725b9648e18478bd6acc9590e0339e38ddf72b9" + }, + "ARV": { + "rows": 727, + "date_min": "2018-01-01 00:00:00", + "date_max": "2019-12-30 00:00:00", + "unique_dates": 727, + "duplicates": 0, + "rows_after_150_calendar_days": 578, + "columns": [ + "date", + "dvv", + "dvv_err", + "dvv_err_within", + "dvv_err_method", + "cc", + "n_members", + "network", + "station", + "band", + "config_hash" + ], + "legacy_rows": 5979, + "legacy_columns": [ + "DATE", + "DVV", + "CC" + ], + "parquet_sha256": "d31df2f2b2adde81acaeab25008d68ceac992c5618e9454c133972a22c2ea7b3" + }, + "RXH": { + "rows": 639, + "date_min": "2018-01-01 00:00:00", + "date_max": "2019-12-30 00:00:00", + "unique_dates": 639, + "duplicates": 0, + "rows_after_150_calendar_days": 489, + "columns": [ + "date", + "dvv", + "dvv_err", + "dvv_err_within", + "dvv_err_method", + "cc", + "n_members", + "network", + "station", + "band", + "config_hash" + ], + "legacy_rows": 5954, + "legacy_columns": [ + "DATE", + "DVV", + "CC" + ], + "parquet_sha256": "36360595c608585637068890c8818269bbd58249ff88020b1d4b6f4fc916612b" + } + }, + "aggregate_incomplete_duplicate_probe": { + "declared_shards": 2, + "present_shards": 1, + "duplicate_rows": 2, + "exit_code": 0 + } +} diff --git a/review/evidence/reproduction_probes.py b/review/evidence/reproduction_probes.py new file mode 100644 index 0000000..4c62a8d --- /dev/null +++ b/review/evidence/reproduction_probes.py @@ -0,0 +1,61 @@ +"""Read-only artifact inventory; writes an aggregation probe under review/.""" +import hashlib +import importlib.metadata as im +import json +import re +from argparse import Namespace +from pathlib import Path + +import codameter +import pandas as pd +import pyarrow.ipc as ipc +from codameter import bench, synthetic_demo + +out = Path("review/evidence") +figs = re.findall( + r"\\includegraphics(?:\[[^\]]*\])?\{([^}]+)\}", + Path("paper/manuscript_marine.qmd").read_text(), +) +report = { + "source_version": codameter.__version__, + "installed_metadata_version": im.version("codameter"), + "figures_not_regenerated_by_build_figures": [ + f for f in figs if Path(f).stem not in synthetic_demo.FIGURES + ], + "realdata": {}, +} +for sta in ["LJR", "ARV", "RXH"]: + p = Path(f"paper/data/gate1/dvv2y/band=2.0-4.0/CI.{sta}.parquet") + d = pd.read_parquet(p) + date = pd.to_datetime(d["date"]) + a = Path(f"paper/data/gate1/legacy_cd2022/CI.{sta}.arrow") + legacy = ipc.open_file(a).read_all().to_pandas() + report["realdata"][sta] = { + "rows": len(d), + "date_min": str(date.min()), + "date_max": str(date.max()), + "unique_dates": int(date.nunique()), + "duplicates": int(date.duplicated().sum()), + "rows_after_150_calendar_days": int( + (date >= date.min() + pd.Timedelta(days=150)).sum() + ), + "columns": list(d.columns), + "legacy_rows": len(legacy), + "legacy_columns": list(legacy.columns), + "parquet_sha256": hashlib.sha256(p.read_bytes()).hexdigest(), + } +probe = out / "aggregation_probe" +probe.mkdir(exist_ok=True) +row = {"case_id": "probe", "config_index": 0, "ok": False, "rms": None} +(probe / "shard-00000-of-00002.jsonl").write_text( + json.dumps(row) + "\n" + json.dumps(row) + "\n" +) +exitcode = bench._cmd_aggregate(Namespace(src=str(probe), out=str(probe / "aggregate"))) +report["aggregate_incomplete_duplicate_probe"] = { + "declared_shards": 2, + "present_shards": 1, + "duplicate_rows": 2, + "exit_code": exitcode, +} +(out / "reproduction_probes.json").write_text(json.dumps(report, indent=2) + "\n") +print(json.dumps(report, indent=2)) diff --git a/review/evidence/revision2/README.md b/review/evidence/revision2/README.md new file mode 100644 index 0000000..c44d8d1 --- /dev/null +++ b/review/evidence/revision2/README.md @@ -0,0 +1,30 @@ +# Revision-pass evidence + +This directory records the Codex reconciliation after `62b63b5`. +It preserves earlier evidence under `review/evidence/closure/` and the +iteration-1 reports rather than replacing their outputs. + +- `reconciliation.json`: all 37 findings with bounded assessments and limits. +- `code_changes.diff`: zero-context changes in this pass, relative to its starting HEAD. +- `manuscript_changes.diff`: zero-context manuscript changes since the original audit. +- `locked_calibration_checks.json`: hashes and summaries of the three locked + 200-realization runs; every recorded missing fraction is zero. +- `pytest.log`, `pytest.xml`: complete-suite execution on the revised source. +- `pre_commit.log`: configured formatter, linter and typing checks. +- `paper_build.log`: Quarto PDF rebuild, reusing committed figure assets. +- `manuscript_layout.txt`: text extracted from the final rendered PDF. +- `page_*.png`: selected full pages inspected for abstract typography, + covariance wording, calibration-table readability, running headers and + availability/end matter. +- `verification.json`: final checks, versions and source hashes. + +Initial focused check: 32 passed in 154.97 seconds. The later full suite +includes the subsequently added moving-reference gate and geometry-cache +regressions. No locked 200-realization experiment was repeated in this pass; +those archived values were checked for compatibility with the missingness +correction. No raw field waveform or external figure was regenerated. + +The formal reviewer manifest remains at iteration 1. This is a bounded +reconciliation, not a completed second nine-scope manuscript review. + +Logs and extracted text have trailing whitespace normalized by repository hooks. diff --git a/review/evidence/revision2/code_changes.diff b/review/evidence/revision2/code_changes.diff new file mode 100644 index 0000000..53f80d6 --- /dev/null +++ b/review/evidence/revision2/code_changes.diff @@ -0,0 +1,332 @@ +diff --git a/src/codameter/calibration.py b/src/codameter/calibration.py +index 5504625..ff63097 100644 +--- a/src/codameter/calibration.py ++++ b/src/codameter/calibration.py +@@ -153,0 +154,12 @@ def run_realization( ++ observed = ( ++ np.isfinite(member_err) ++ & np.isfinite(run.within_sigma) ++ & (run.within_sigma > 0) ++ & np.isfinite(sd[None, :]) ++ ) ++ if not observed.any(): ++ raise ValueError("no observed member epochs for coverage calibration") ++ # Comparing NaN with a width returns False, not NaN. Mask before the ++ # comparison so warm-up / gated cells are not counted as misses. ++ member_abs_error = np.abs(member_err[observed]) ++ member_sd = np.broadcast_to(sd, member_err.shape)[observed] +@@ -157,7 +169,4 @@ def run_realization( +- member_coverage68=float( +- np.nanmean(np.abs(member_err) <= Z68 * sd[None, :]) +- ), +- member_coverage95=float( +- np.nanmean(np.abs(member_err) <= Z95 * sd[None, :]) +- ), +- member_rmse=float(np.sqrt(np.nanmean(member_err**2))), ++ n_member_epochs=int(observed.sum()), ++ member_coverage68=float(np.mean(member_abs_error <= Z68 * member_sd)), ++ member_coverage95=float(np.mean(member_abs_error <= Z95 * member_sd)), ++ member_rmse=float(np.sqrt(np.mean(member_abs_error**2))), +@@ -177 +186 @@ def run_realization( +- missing_fraction=float(np.mean(~np.isfinite(run.members))), ++ missing_fraction=float(np.mean(~observed)), +diff --git a/src/codameter/golden.py b/src/codameter/golden.py +index 1d98d9c..0662d0b 100644 +--- a/src/codameter/golden.py ++++ b/src/codameter/golden.py +@@ -506,0 +507,22 @@ def recover(d: dict, cfg: dict, eps_max: float): ++def advisory_case(use_case: str, *, years: float = 3.0, seed: int | None = None): ++ """Build a public seasonal development example for any supported application. ++ ++ This route is independent of the installed evaluation corpus. It never ++ opens private recipes or substitutes a depth-targeted case for the generic ++ application. The returned ``recipe`` records the settings for replay. ++ Synthetic recovery is conditional evidence, not field validation. ++ """ ++ app = uc.resolve(use_case) ++ if not np.isfinite(years) or years <= 0: ++ raise ValueError("years must be finite and positive") ++ recipe = next( ++ dict(c) for c in _build_cases() if c["use_case"] == app and c["grade"] == "easy" ++ ) ++ recipe["years"] = float(years) ++ if seed is not None: ++ recipe["seed"] = int(seed) ++ data = _build(recipe) ++ data["recipe"] = recipe ++ return data ++ ++ +@@ -520 +542 @@ def _generator_hash() -> str: +- this module and :mod:`codameter.synthetic_demo`. Part of the cache key, so ++ this module, :mod:`codameter.synthetic_demo` and :mod:`codameter.use_cases`. Part of the cache key, so +@@ -528 +550 @@ def _generator_hash() -> str: +- for src in (__file__, synthetic_demo.__file__): ++ for src in (__file__, synthetic_demo.__file__, uc.__file__): +@@ -659,3 +681,3 @@ def rms_on_support(dvv, truth, support, baseline) -> tuple[float, float]: +- prediction**, i.e. zero change from the baseline, so abstaining on an +- epoch can never improve the score and omitting every epoch scores like a +- series of zeros. The prediction's own baseline mean is taken over its ++ prediction**, i.e. zero change from the baseline, so missing epochs do not disappear from the error denominator. Replacing ++ a poor prediction by null can still improve the score; availability must ++ be reported separately. The prediction's own baseline mean is taken over its +diff --git a/src/codameter/uq_bayes.py b/src/codameter/uq_bayes.py +index b648704..663a677 100644 +--- a/src/codameter/uq_bayes.py ++++ b/src/codameter/uq_bayes.py +@@ -1 +1 @@ +-r"""A Bayesian measurement model for :math:`\delta v/v` — the *new* best practice. ++r"""A working Bayesian model for an ensemble of dv/v processing outputs. +@@ -3,6 +3,5 @@ r"""A Bayesian measurement model for :math:`\delta v/v` — the *new* best pract +-The deviation/multiverse experiments (:mod:`codameter.deviations`) show that the +-processing choice, not the data, often controls a :math:`\delta v/v` estimate. +-The honest response is not to crown one pipeline but to treat the choice as a +-**nuisance parameter** with a prior, run an ensemble of defensible pipelines, and +-*marginalise* the choice out. This module does exactly that, as a Bayesian +-hierarchical inversion. ++The likelihood is ``m_k(t) = mu(t) + beta_k + epsilon_k(t)``, with normal ++configuration offsets of variance ``tau**2`` and conditionally independent ++residuals of variance ``s**2 * sigma_k(t)**2``. ``sigma_k`` is the Weaver ++floor. A second-difference prior on the physical time grid smooths ``mu``; ++missing observations carry zero precision. +@@ -10,7 +9,3 @@ hierarchical inversion. +-Model +------ +-For configuration :math:`k` (an estimator/band/window/stack/reference choice +-drawn from a prior over defensible pipelines) we obtain a measured series +-:math:`m_k(t)` with a coherence-limited within-method standard error +-:math:`\sigma_k(t)` (Weaver/Clarke; :func:`codameter.uq_measurement.weaver_stretching_error`). +-We posit ++All configurations reuse the same waveform data. Conditional independence is ++therefore a working assumption, not an established property. Jointly fitting ++these outputs is not discrete mixture marginalization over pipelines. +@@ -18,6 +13,5 @@ We posit +-.. math:: +- m_k(t) = \mu(t) + \beta_k + \varepsilon_k(t), +- \qquad +- \beta_k \sim \mathcal N(0,\tau^2), +- \quad +- \varepsilon_k(t) \sim \mathcal N\!\big(0,\, s^2\,\sigma_k(t)^2\big), ++``mu_cov`` and the credible band describe the combined estimate under that ++likelihood. ``Cd`` is constructed separately from the fitted floor, excess ++configuration spread, a fitted exponential temporal correlation, and a rank-one ++term using ``tau``. It targets a randomly selected member's error, not the ++combined estimate. Between-configuration offsets cannot identify common bias. +@@ -25,24 +19,5 @@ We posit +-with a smoothness (2nd-difference random-walk) prior of precision :math:`\lambda` +-on the latent true series :math:`\mu(t)`, built on the physical time grid so +-gaps are gaps. Missing members (warm-up, gated epochs) carry no information. Here :math:`\beta_k` is the +-configuration's **methodological bias** (e.g. the systematic MWCS-vs-stretching +-offset), :math:`\tau^2` its variance across the ensemble, and :math:`s^2` +-rescales the Weaver floor so the data tell us whether it is calibrated. +- +-The posterior is sampled by a conjugate **Gibbs sampler** (pure NumPy, no +-external sampler). Its two deliverables are +- +-1. the marginal posterior :math:`p(\mu(t)\mid\{m_k\})` — a single +- :math:`\delta v/v` series with an uncertainty that *includes* the +- processing-choice spread; and +-2. a **measurement covariance** :math:`C_d`, *constructed* (not sampled) from +- the posterior-calibrated within-method floor, the between-configuration +- spread, an exponential temporal correlation fitted to the ensemble residuals +- and the common-mode scale :math:`\tau` (see :class:`BayesResult`). It is the +- object a downstream depth/stress inversion (:mod:`codameter.inverse`) should +- consume instead of a diagonal ``dvv_err``. It is **not** +- :math:`\operatorname{Cov}(\mu\mid\text{data})`: that is ``mu_cov``, the +- precision of the combined estimate, which shrinks with ensemble size. Its +- time dependence is real: it is wider where the ensemble disagrees (sharp +- transients, low coherence) and its off-diagonals carry the temporal +- correlation the stacking and the shared methodological bias induce. ++Repeated waveform realizations give near-nominal 95 percent pointwise member ++coverage, but 68 percent intervals overcover and the combined estimate's ++credible band undercovers. These checks do not validate temporal covariance, ++cross-band covariance, or downstream inversion intervals. See ++:mod:`codameter.calibration` and the manuscript's calibration table. +@@ -142 +117,2 @@ def run_processing_ensemble( +- per-epoch coherence and is rejected. ++ per-epoch coherence and is rejected. Input CCF rows must form a complete ++ daily grid; irregular already-measured series can be passed to ``gibbs_dvv``. +@@ -150,0 +127,9 @@ def run_processing_ensemble( ++ if not np.isfinite(days_arr).all() or not np.allclose( ++ np.diff(days_arr), 1.0, rtol=0.0, atol=1e-8 ++ ): ++ raise ValueError( ++ "CCFs must be on a complete daily grid for day-based stacking; " ++ "gibbs_dvv accepts irregular times for already measured series" ++ ) ++ if not isinstance(cadence, int | np.integer) or cadence < 1: ++ raise ValueError("cadence must be a positive integer") +@@ -175,2 +160,5 @@ def run_processing_ensemble( +- if cfg["gate"]: +- valid = valid & valid_ts # gate every estimator on the same coherence ++ if cfg["gate"]: ++ # The legacy pipeline gates fixed-reference stretching only. ++ # Apply the same observed-coherence threshold to every ensemble ++ # estimator and reference, including moving-reference estimates. ++ valid = valid & valid_ts & np.isfinite(cc) & (cc > 0.6) +@@ -213,2 +201,3 @@ class BayesResult: +- uncertainty of the *combined* estimate. It shrinks with ensemble size and +- is **not** the object to propagate downstream. ++ model-conditional uncertainty of the *combined* estimate. It shrinks ++ with ensemble size under the working likelihood, but does not include ++ shared model error. Its downstream use requires separate calibration. +@@ -216,2 +205 @@ class BayesResult: +- The **constructed measurement covariance** to hand a downstream +- depth/stress inversion: :math:`C_d = D R D + \tau^2 \mathbf{1}\mathbf{1}^T` ++ A **constructed single-member error covariance**: :math:`C_d = D R D + \tau^2 \mathbf{1}\mathbf{1}^T` +@@ -226 +214 @@ class BayesResult: +- Posterior-mean scale of the per-configuration offsets :math:`\beta_k` ++ Square root of posterior-mean variance of the per-configuration offsets :math:`\beta_k` +@@ -247,2 +235,2 @@ class BayesResult: +- Share of each scale posterior that comes from its hyper-prior rather +- than the data, evaluated at the posterior means: ++ Prior scale contribution to each conditional posterior rate, evaluated ++ at the posterior means. This is not the total influence of the prior: +@@ -252,3 +240,3 @@ class BayesResult: +- mean data-dominated; a value near one means the prior scale is setting +- the answer, which happens for tau^2 with few configurations and tiny +- offsets. ++ mean the prior rate term is small. The shape parameters and ++ smoothness assumptions can still matter; this is not a convergence ++ diagnostic or a substitute for prior sensitivity checks. +diff --git a/tests/test_advisor_validation.py b/tests/test_advisor_validation.py +new file mode 100644 +index 0000000..ea68f79 +--- /dev/null ++++ b/tests/test_advisor_validation.py +@@ -0,0 +1,34 @@ ++"""Executable coverage for the advisor's public development route (AG-01).""" ++ ++import numpy as np ++import pytest ++from codameter import golden ++from codameter import use_cases as uc ++ ++ ++@pytest.mark.parametrize("app", list(uc.USE_CASES)) ++def test_advisory_case_recovers_every_application(app, monkeypatch): ++ # The advisor must work without a matching public or private gold record. ++ monkeypatch.setattr(golden, "CASES_BY_ID", {}) ++ data = golden.advisory_case(app, years=0.3, seed=41) ++ assert data["use_case"] == app ++ assert data["recipe"]["grade"] == "easy" ++ assert data["recipe"]["seed"] == 41 ++ assert "truth_other" not in data ++ cfg = uc.recommend(app) ++ dvv, valid = golden.recover(data, cfg, uc.eps_max(app)) ++ assert valid.sum() >= 10 ++ assert np.isfinite(dvv[valid]).all() ++ support = golden.scoring_support(data, cfg, uc.eps_max(app)) ++ rms, availability = golden.rms_on_support( ++ np.where(valid, dvv, np.nan), data["truth"], **support ++ ) ++ assert np.isfinite(rms) and availability == 1.0 ++ ++ ++def test_advisory_case_alias_and_replay(): ++ a = golden.advisory_case("glacier", years=0.1, seed=19) ++ b = golden.advisory_case("cryosphere", years=0.1, seed=19) ++ np.testing.assert_array_equal(a["ccfs"], b["ccfs"]) ++ with pytest.raises(ValueError, match="years"): ++ golden.advisory_case("volcano", years=np.nan) +diff --git a/tests/test_audit_small_fixes.py b/tests/test_audit_small_fixes.py +index 952ca03..ed5f01c 100644 +--- a/tests/test_audit_small_fixes.py ++++ b/tests/test_audit_small_fixes.py +@@ -68,0 +69,9 @@ def test_golden_cache_is_exact_and_versioned(tmp_path, monkeypatch): ++ ++ ++def test_golden_cache_identity_includes_application_geometry(tmp_path, monkeypatch): ++ source = tmp_path / "use_cases.py" ++ source.write_text("geometry = 1\n") ++ monkeypatch.setattr(golden.uc, "__file__", str(source)) ++ before = golden._generator_hash() ++ source.write_text("geometry = 2\n") ++ assert golden._generator_hash() != before +diff --git a/tests/test_calibration.py b/tests/test_calibration.py +index ee99d9a..3aec5ae 100644 +--- a/tests/test_calibration.py ++++ b/tests/test_calibration.py +@@ -5,0 +6 @@ import json ++from types import SimpleNamespace +@@ -9,0 +11 @@ from codameter import calibration as C ++from codameter import uq_bayes +@@ -32,0 +35,39 @@ _BASE = { ++def test_missing_members_do_not_count_as_coverage_misses(monkeypatch): ++ # Two of six cells are observed. One covers truth, one misses. A finite ++ # member without a usable coherence floor is also unobserved by the fit. ++ members = np.array([[0.0, np.nan, 0.0], [3.0, np.nan, np.nan]]) ++ sigmas = np.ones_like(members) ++ sigmas[0, 2] = np.nan ++ run = SimpleNamespace(truth=np.zeros(3), members=members, within_sigma=sigmas) ++ result = SimpleNamespace( ++ mu_mean=np.zeros(3), ++ Cd=np.eye(3), ++ mu_lo=-np.ones(3), ++ mu_hi=np.ones(3), ++ tau=0.0, ++ s=1.0, ++ corr_length_days=1.0, ++ n_eff=3, ++ prior_weight={}, ++ ) ++ monkeypatch.setattr( ++ C, ++ "make_realization", ++ lambda *a, **kw: ( ++ SimpleNamespace(t=np.arange(5), fs=1), ++ np.arange(3), ++ np.zeros(3), ++ np.zeros((3, 5)), ++ ), ++ ) ++ monkeypatch.setattr(uq_bayes, "bayes_dvv_from_ccfs", lambda *a, **kw: (result, run)) ++ row = C.run_realization(1) ++ assert row["ok"] ++ assert row["n_member_epochs"] == 2 ++ assert row["member_coverage68"] == row["member_coverage95"] == 0.5 ++ assert row["missing_fraction"] == pytest.approx(2 / 3) ++ assert row["member_rmse"] == pytest.approx(np.sqrt(4.5)) ++ members[:] = np.nan ++ assert not C.run_realization(1)["ok"] ++ ++ +diff --git a/tests/test_uq_bayes.py b/tests/test_uq_bayes.py +index 4930215..0e281c0 100644 +--- a/tests/test_uq_bayes.py ++++ b/tests/test_uq_bayes.py +@@ -145,0 +146,34 @@ def test_stack_is_in_days_and_output_is_decimated_after(small_ccfs): ++@pytest.mark.parametrize("days", [[0, 1, 3], [0, 2, 4], [2, 1, 0], [0, 1, np.nan]]) ++def test_ensemble_rejects_non_daily_ccfs(days): ++ with pytest.raises(ValueError, match="complete daily grid"): ++ B.run_processing_ensemble(np.zeros((3, 5)), np.arange(5), 1.0, [], days=days) ++ ++ ++@pytest.mark.parametrize("estimator", ["stretching (TS)", "MWCS"]) ++def test_moving_reference_gate_masks_low_coherence(estimator, monkeypatch): ++ from codameter import deviations ++ ++ def measured(*args, return_cc=False, **kwargs): ++ values, valid = np.ones(3), np.ones(3, dtype=bool) ++ return ( ++ (values, valid, np.array([0.55, 0.65, 0.8])) ++ if return_cc ++ else (values, valid) ++ ) ++ ++ monkeypatch.setattr(deviations, "run_pipeline", measured) ++ config = dict( ++ estimator=estimator, ++ band=(0.4, 1), ++ window=(8, 28), ++ stack=5, ++ reference="moving", ++ gate=True, ++ ) ++ result = B.run_processing_ensemble( ++ np.zeros((3, 5)), np.arange(5), 1.0, [config], cadence=1 ++ ) ++ assert np.isnan(result.members[0, 0]) ++ assert np.isfinite(result.members[0, 1:]).all() ++ ++ diff --git a/review/evidence/revision2/locked_calibration_checks.json b/review/evidence/revision2/locked_calibration_checks.json new file mode 100644 index 0000000..b6c4d6d --- /dev/null +++ b/review/evidence/revision2/locked_calibration_checks.json @@ -0,0 +1,344 @@ +[ + { + "file": "paper/data/calibration/locked_clean_n200.json", + "sha256": "96764e9a05419f3d7e3e5b5e80832a986c6a46c971e7c49db4a6c1ff354d03b8", + "realizations": 200, + "missing_member_realizations": 0, + "summary": { + "n_realizations": 200, + "n_failed": 0, + "failures": [], + "margin": 0.03, + "member_coverage68": { + "mean": 0.807920305676856, + "se": 0.0007261762794585474, + "n": 200 + }, + "member_coverage95": { + "mean": 0.9561244541484716, + "se": 0.0003102369938492323, + "n": 200 + }, + "member_rmse": { + "mean": 0.0022935367636978676, + "se": 8.59449577553801e-06, + "n": 200 + }, + "shared_bias": { + "mean": -0.00017097815708316076, + "se": 5.349323923496784e-06, + "n": 200 + }, + "coverage68": { + "mean": 0.9975545851528385, + "se": 0.0001821910006491242, + "n": 200 + }, + "coverage95": { + "mean": 0.9999781659388646, + "se": 2.1834061135371218e-05, + "n": 200 + }, + "coverage95_posterior": { + "mean": 0.5899781659388647, + "se": 0.003691423287111879, + "n": 200 + }, + "median_sd": { + "mean": 0.0022542694726094526, + "se": 6.261568589018551e-06, + "n": 200 + }, + "median_halfwidth95": { + "mean": 0.004418287012613513, + "se": 1.2272449018007158e-05, + "n": 200 + }, + "bias": { + "mean": -0.00017097815708316076, + "se": 5.349323923496784e-06, + "n": 200 + }, + "rmse": { + "mean": 0.000668837656225284, + "se": 4.598936463593073e-06, + "n": 200 + }, + "max_abs_err": { + "mean": 0.002597001055585071, + "se": 4.015044100047297e-05, + "n": 200 + }, + "tau": { + "mean": 0.00024280825391082957, + "se": 7.320078421765792e-06, + "n": 200 + }, + "s": { + "mean": 11.665754049283839, + "se": 0.03135772018801208, + "n": 200 + }, + "corr_length_days": { + "mean": 30.14387295108152, + "se": 0.8627435290075752, + "n": 200 + }, + "n_eff": { + "mean": 32.31681393789955, + "se": 0.6417892519935303, + "n": 200 + }, + "missing_fraction": { + "mean": 0.0, + "se": 0.0, + "n": 200 + }, + "prior_weight_tau2": { + "mean": 0.08898616629409556, + "se": 0.008468411290270143, + "n": 200 + }, + "prior_weight_s2": { + "mean": 5.553086076197376e-14, + "se": 3.0136573501188545e-16, + "n": 200 + }, + "prior_weight_lambda": { + "mean": 2.0436428089713247e-05, + "se": 1.0968623191806546e-06, + "n": 200 + }, + "member_coverage95_within_margin": true, + "member_coverage68_within_margin": false + } + }, + { + "file": "paper/data/calibration/locked_clock_drift_n200.json", + "sha256": "4b6dcc8f7e78e68c84dcf177dcf3cd856a789c769f990de610345ed34f011829", + "realizations": 200, + "missing_member_realizations": 0, + "summary": { + "n_realizations": 200, + "n_failed": 0, + "failures": [], + "margin": 0.03, + "member_coverage68": { + "mean": 0.8038555312954877, + "se": 0.0007899533075598508, + "n": 200 + }, + "member_coverage95": { + "mean": 0.9543413391557496, + "se": 0.0003318196204736724, + "n": 200 + }, + "member_rmse": { + "mean": 0.0022905301120412108, + "se": 8.520021103333328e-06, + "n": 200 + }, + "shared_bias": { + "mean": -0.0001860509174779412, + "se": 5.312595417824318e-06, + "n": 200 + }, + "coverage68": { + "mean": 0.998122270742358, + "se": 0.00016528619731370097, + "n": 200 + }, + "coverage95": { + "mean": 1.0, + "se": 0.0, + "n": 200 + }, + "coverage95_posterior": { + "mean": 0.6043449781659389, + "se": 0.003806634018768227, + "n": 200 + }, + "median_sd": { + "mean": 0.0022243873495228802, + "se": 6.529750797552057e-06, + "n": 200 + }, + "median_halfwidth95": { + "mean": 0.004359719127120263, + "se": 1.2798076492173322e-05, + "n": 200 + }, + "bias": { + "mean": -0.0001860509174779412, + "se": 5.312595417824318e-06, + "n": 200 + }, + "rmse": { + "mean": 0.0006562279066809316, + "se": 4.700894391034319e-06, + "n": 200 + }, + "max_abs_err": { + "mean": 0.0024996090443816068, + "se": 3.85952692960486e-05, + "n": 200 + }, + "tau": { + "mean": 0.00024557373653242133, + "se": 7.305013459945172e-06, + "n": 200 + }, + "s": { + "mean": 10.882459108645099, + "se": 0.03153730492639741, + "n": 200 + }, + "corr_length_days": { + "mean": 29.385197564047974, + "se": 0.8717482608128544, + "n": 200 + }, + "n_eff": { + "mean": 32.438931923608706, + "se": 0.6620043163346215, + "n": 200 + }, + "missing_fraction": { + "mean": 0.0, + "se": 0.0, + "n": 200 + }, + "prior_weight_tau2": { + "mean": 0.0849718380229744, + "se": 0.008154641100002807, + "n": 200 + }, + "prior_weight_s2": { + "mean": 6.372640064716824e-14, + "se": 3.7249316455067295e-16, + "n": 200 + }, + "prior_weight_lambda": { + "mean": 3.884222388790273e-05, + "se": 1.1626877725726795e-05, + "n": 200 + }, + "member_coverage95_within_margin": true, + "member_coverage68_within_margin": false + } + }, + { + "file": "paper/data/calibration/locked_shared_source_n200.json", + "sha256": "0915a5409f5119509cc892e8ab5e81202a6f5030fbcb3fb0e8fcf2856ab57217", + "realizations": 200, + "missing_member_realizations": 0, + "summary": { + "n_realizations": 200, + "n_failed": 0, + "failures": [], + "margin": 0.03, + "member_coverage68": { + "mean": 0.7945123726346435, + "se": 0.000944941871924279, + "n": 200 + }, + "member_coverage95": { + "mean": 0.949561499272198, + "se": 0.0003750220524867418, + "n": 200 + }, + "member_rmse": { + "mean": 0.0035139165299497644, + "se": 1.0773159246632899e-05, + "n": 200 + }, + "shared_bias": { + "mean": -0.00045443441962889373, + "se": 7.963688526075521e-06, + "n": 200 + }, + "coverage68": { + "mean": 0.9763973799126637, + "se": 0.0013253505480707282, + "n": 200 + }, + "coverage95": { + "mean": 1.0, + "se": 0.0, + "n": 200 + }, + "coverage95_posterior": { + "mean": 0.3403275109170306, + "se": 0.0038972087996702477, + "n": 200 + }, + "median_sd": { + "mean": 0.003300896641952251, + "se": 9.702527232567708e-06, + "n": 200 + }, + "median_halfwidth95": { + "mean": 0.006469638585947302, + "se": 1.9016604084852336e-05, + "n": 200 + }, + "bias": { + "mean": -0.00045443441962889373, + "se": 7.963688526075521e-06, + "n": 200 + }, + "rmse": { + "mean": 0.0016128235682199667, + "se": 8.318774631720938e-06, + "n": 200 + }, + "max_abs_err": { + "mean": 0.004064167813162548, + "se": 4.31489155954433e-05, + "n": 200 + }, + "tau": { + "mean": 0.0004579240479937903, + "se": 1.0633896408167719e-05, + "n": 200 + }, + "s": { + "mean": 12.69841941154758, + "se": 0.0378348941360989, + "n": 200 + }, + "corr_length_days": { + "mean": 29.93779008492537, + "se": 0.9166651010427155, + "n": 200 + }, + "n_eff": { + "mean": 26.440478925411142, + "se": 0.574465100391262, + "n": 200 + }, + "missing_fraction": { + "mean": 0.0, + "se": 0.0, + "n": 200 + }, + "prior_weight_tau2": { + "mean": 0.024580127148341933, + "se": 0.0046761323546567046, + "n": 200 + }, + "prior_weight_s2": { + "mean": 4.6786274250638935e-14, + "se": 2.755564068273868e-16, + "n": 200 + }, + "prior_weight_lambda": { + "mean": 2.6233956764316734e-05, + "se": 6.825029156419385e-06, + "n": 200 + }, + "member_coverage95_within_margin": true, + "member_coverage68_within_margin": false + } + } +] diff --git a/review/evidence/revision2/manuscript_changes.diff b/review/evidence/revision2/manuscript_changes.diff new file mode 100644 index 0000000..0c537d4 --- /dev/null +++ b/review/evidence/revision2/manuscript_changes.diff @@ -0,0 +1,977 @@ +diff --git a/paper/manuscript_marine.qmd b/paper/manuscript_marine.qmd +index 04d8172..44b38b6 100644 +--- a/paper/manuscript_marine.qmd ++++ b/paper/manuscript_marine.qmd +@@ -10,36 +10,39 @@ abstract: | +- Relative seismic velocity changes (\dvv) from repeated coda waves are becoming +- a standard observable for volcanoes, faults, landslides, aquifers and the +- cryosphere and are increasingly regarded as new measurements of strain changes. +- Yet turning cross-correlation functions into a \dvv\ time series +- involves a long sequence of choices --- the estimator, the frequency band, the +- coda window, the reference, the stacking, and how cross-components and station +- pairs are aggregated and weighted --- made *ad hoc*, their impact on the measurement +- uncertainty unclear. These hidden choices clearly limit reproducibility of the +- research and importantly the inter-study comparison. +- +- We demonstrate here how to turn repeated wavefield measurement into agent-ready, +- scalable-ready, uncertainty-aware measurement of changes in seismic properties. +- We quantify the individual and combined effects of these choices +- using a controlled synthetic in which the ground-truth \dvv\ is known exactly. +- We show that at large \dvv\ methods split by family with distinct failure modes; that the same station +- pair yields different \dvv\ depending only on whether one averages the +- per-component \dvv\ or the correlation-coefficient images; and, most +- consequentially, that the reported $1\sigma$ on a network-averaged \dvv\ varies by +- $\sim\!\sqrt{N}$ +- from the standard-error-versus-standard-deviation and weighting conventions --- +- so a change that is "$3\sigma$ significant" in one study is "not significant" in +- another, from identical data. +- +- Running the full breadth of parameter choices, we estimate +- each by the bias and error-bar change it induces. We propose a Bayesian +- measurement model that marginalises the ensemble into a single time-dependent +- data covariance $C_d$ and illustrate its use by propagating errors in a +- depth-inversion of shear wave perturbation. We provide a real data examples from a California data set and reproduce +- previous results that were generated with a different computing language +- and processing pipeline, demonstrating at the same time the integration +- of codameter with noisepy and its portability and scalability from laptop +- to cloud systems. We also generate a codameter agent advisor that can guide researchers or agents +- in their parameter choices, accompanied with a robust evaluation of the agent against +- a golden data set. Our method and associated software package, ``codameter`` turns +- repeated coda waves into time series of \dvv\ and its covariance +- making it coda-wave interferometry uncertainty-aware and reproducible. ++ Relative seismic velocity changes (\dvv) from repeated coda waves are a ++ standard observable for volcanoes, faults, landslides, aquifers and the ++ cryosphere. Turning cross-correlation functions into a \dvv\ time series ++ involves a long sequence of choices, the estimator, the frequency band, the ++ coda window, the reference, the stacking, and how cross-components and ++ station pairs are aggregated and weighted, made ad hoc and reported ++ incompletely, so the same data can support different values and different ++ error bars. We quantify the individual and combined effects of these choices ++ on synthetic correlation functions in which the ground-truth \dvv\ is known ++ exactly. On these synthetics, at large \dvv\ the estimators split by family ++ with distinct failure modes; the same station pair yields different \dvv\ depending only on whether one averages per-component \dvv\ or the ++ correlation-coefficient images; and the number quoted as the $1\sigma$ ++ uncertainty of a network-averaged \dvv\ differs by $\sim\!\sqrt{N}$ between ++ the standard error of the network mean and the between-pair standard ++ deviation, two different quantities that studies rarely distinguish. A ++ one-at-a-time sweep and a 108-pipeline factorial on one scenario rank the ++ choices by the error they induce. We then propose a hierarchical Bayesian ++ measurement model that runs an ensemble of defensible pipelines on the same ++ correlations and combines their estimates into a single \dvv\ series. A separate construction proposes a time-dependent single-member error covariance $C_d$. ++ On 200 independent synthetic realisations of a volcano scenario, $C_d$ covers ++ 95.6% of individual member errors at the 95% level, whereas the ++ credible band on the ensemble mean covers the truth only 59% of the time ++ because the configurations share time-varying biases; a seasonal source ++ artefact seen by every configuration reduces that coverage to 34% and more than doubles ++ the error of the ensemble mean while leaving member coverage near 95%. ++ The nominal 68% member intervals cover 81% in the clean case; ++ these pointwise checks do not validate the full covariance. Shared errors ++ require diagnostics beyond agreement among processing choices. We set out how $C_d$ enters a depth inversion of ++ shear-velocity change; that stage is described, not evaluated, here. On three ++ California stations the same measurement code, run on NoisePy correlations in ++ a cloud batch pipeline, reproduces a published \dvv\ product (correlation ++ 0.83--0.99 on 360--580 matched days, with a reproducible comparison script), ++ a comparison that also exposed and corrected a sign-convention error. The ++ framework, estimators, figures with their numerical sidecars, and the ++ calibration experiments are released in the open Python package ++ ``codameter``, together with a processing-choice advisor and a seeded ++ golden dataset with fixed scoring support and a null-change penalty for ++ missing predictions; an ++ evaluation of agents against that dataset is left to future work. +@@ -81,7 +84,8 @@ Due to the sensitivity of coda waves to small perturbations in the material prop +-\dvv\ was discovered as an effective method to monitor changes during volcanic unrest since its +-discovery at Piton de la Fournaise [@Brenguier2008] and is now calculated in continuous +-along side of more conventional seismic monitoring methods in the same volcano observatory +- [@Duputel2009] and was a determining early warning parameter: the Icelandic Meteorological +- Office used \dvv\ in its response to the 2020 Reykjanes unrest [@CubukSabuncu2021]. +- The Institute of Mine Seismology also uses \dvv\ to monitor the internal state of tens of tailings +- dams and mines to flag instability before failure [@Olivier2017; @Ouellet2022]. ++\dvv\ has become an effective way to monitor volcanic unrest, from the first ++passive monitoring at Merapi [@SensSchonfelder2006] to the pre-eruptive ++velocity drops at Piton de la Fournaise [@Brenguier2008], where it is now ++computed continuously alongside conventional observatory monitoring ++[@Duputel2009]; the Icelandic Meteorological Office included \dvv\ among the ++parameters it followed during the 2020 Reykjanes unrest [@CubukSabuncu2021]. ++The same signal is used to monitor the internal state of tailings dams and ++mines and to flag instability before failure [@Olivier2017; @Ouellet2022]. +@@ -138,8 +142,11 @@ enough detail to reproduce. The community has long flagged *individual* pitfalls +-formulae, @Clarke2011 [@Weaver2011]), but the *cumulative* effect of the full +-choice set on both the value and its stated uncertainty has not been quantified +-in the literature. A striking example of such their cumulative effects can be seen in Figure x +-of [@Denolle25b] who demonstrated that most studies found a direct correlation between +-\dvv\ and groundwater level change, but the scatter around the mean was easily +-explained by frequency choices, single-vs-inter station correlations, and likely +-the other signal-processing parameters chosen by the authors, which speak of the robust +-correlation but not rigorously established enough to be useful in downstream hydrological research. ++formulae, @Clarke2011 [@Weaver2011]) and has compared estimators against one ++another on simulated data [@Yuan2021]. What has not been done, to our ++knowledge, is to quantify on one truth-known dataset the *joint* effect of the ++full choice set on both the value and its stated uncertainty, and to carry ++that spread into a measurement covariance. One indication of the stakes is the ++compilation of @Denolle25b, in which most studies find \dvv\ anticorrelated ++with groundwater level, but with a scatter across studies that differences in ++frequency band, single-station versus inter-station correlations and other ++processing choices can explain in part, alongside genuine hydrogeological ++differences between sites; that scatter limits how far the compiled relation ++can be used quantitatively in hydrological work. +@@ -154 +161 @@ time series to test the methods (estimators) and parameter choices that the comm +-makes to estimate \dvv$\,$which we report over 103 studies in Appendix~\ref{app:survey}. ++makes to estimate \dvv$\,$which we report over 103 studies in Appendix\ \ref{app:survey}. +@@ -156 +163 @@ We do not aim to report the "best" pipeline, which is most often the one reporte +-scientific papers, but instead document the parameter impacts (Section~\ref{sec:results}). ++scientific papers, but instead document the parameter impacts (Section\ \ref{sec:results}). +@@ -158 +165 @@ We then propose a new measurement error that incorporates these effects into a d +-covariance matrix $C_d$ (Section~\ref{sec:bayes}). Throughout this paper, key notation includes: $\sigma$ (measurement uncertainty of a recovered \dvv\ estimate), $B$ (frequency bandwidth), and $W=[t_1,t_2]$ (coda window); subscripts distinguish specific contexts (e.g., $\sigma_k$ for per-component uncertainty), each defined where first introduced. ++covariance matrix $C_d$ (Section\ \ref{sec:bayes}). Throughout this paper, key notation includes: $\sigma$ (measurement uncertainty of a recovered \dvv\ estimate), $B$ (frequency bandwidth), and $W=[t_1,t_2]$ (coda window); subscripts distinguish specific contexts (e.g., $\sigma_k$ for per-component uncertainty), each defined where first introduced. +@@ -162,15 +169,17 @@ migration of the surface \dvv\ measurement to depth profiles of perturbations in +-shear wave velocity $\Delta V_S(z)/V_S(z)$, which often depends on the wavefield +-constituting the coda waves, such as surface waves or body waves, and that depend +-on the source-receiver pair geometry. We illustrate the propagation of errors to a +-depth profile (Section~\ref{sec:depth}). We use synthetic examples for +-ground truthing on the signal processing parameters, since the concepts behind +-the observations of phase lags in scattered waves is well established [@Obermann2013]. +- +-We further validate using real obervations that the estimates of \dvv\ and their uncertainty +-reproduces well those of observed time series by reproducing previous studies. +-We package this new methodology in a Python software, ``codameter``, which we also +-recast as an agentic skill: an AI agent can be asked to recommend a processing +-configuration or recover a \dvv(t) series, and its answer is scored against +-seeded synthetic golden cases with known ground truth, including a +-hidden-truth variant that withholds the answer from the public package so it +-cannot be reconstructed rather than measured. ++shear wave velocity $\Delta V_S(z)/V_S(z)$, which depends on the wavefield ++constituting the coda waves, surface or body waves, and on the source-receiver ++geometry. We set out how the measurement covariance enters such a depth ++inversion (Section\ \ref{sec:depth}); the executable depth stage is described ++there, not evaluated. We use synthetic examples for ground truthing of the ++signal-processing parameters, since the physics of phase lags in scattered ++waves is well established [@Obermann2013]. ++ ++We then compare single-station \dvv\ from the same measurement code, run on ++NoisePy correlations for three California stations, with a published product ++(Section\ \ref{sec:deployment}). We package the methodology in a Python ++software, ``codameter``, which also ships an advisor skill: an AI agent can be ++asked to recommend a processing configuration or recover a \dvv(t) series, ++and its answer can be scored against seeded synthetic golden cases with known ++ground truth, including a hidden-truth variant that withholds the answer from ++the public package. The scorer and dataset are part of the release; an ++evaluation of agents against them is not part of this paper. +@@ -230 +239 @@ implementation are released in the open ``codameter`` package +-(Section~\ref{sec:discussion}). Formal definitions of all seven methods, of ++(Section\ \ref{sec:discussion}). Formal definitions of all seven methods, of +@@ -232 +241 @@ the two aggregation pathways, and of the uncertainty conventions are described i +-Appendices~\ref{app:estimators} and~\ref{app:aggregation}. ++Appendices\ \ref{app:estimators} and\ \ref{app:aggregation}. +@@ -235 +244 @@ Each of these methods require specific parameter choices, which we categorize an +-reference in Table~\ref{tab:hyperparams}. The work presented below measure the impacts ++reference in Table\ \ref{tab:hyperparams}. The work presented below measure the impacts +@@ -288,0 +298,43 @@ Clock / timing & causal vs acausal branch handling & A clock error fabricates ++Several quantities in this paper are reported with the same symbol $\sigma$ ++but estimate different things. Table\ \ref{tab:estimands} fixes, for each, what ++it is an estimate of, its units, and the datum and epochs it is evaluated on; ++figure captions refer to it. ++ ++```{=latex} ++\begin{table} ++\footnotesize ++\caption{Reported quantities, what each estimates, and how it is evaluated. ++All \dvv\ quantities are fractions of velocity; figures show percent.} ++\label{tab:estimands} ++\begin{tabularx}{\textwidth}{@{}>{\raggedright\arraybackslash}p{3.1cm} L L@{}} ++\toprule ++\textbf{Quantity} & \textbf{Estimate of} & \textbf{Datum and support} \\ ++\midrule ++Recovery RMS (Sections~\ref{sec:results}--\ref{sec:multiverse}) & Root mean ++square of (recovered $-$ imposed) \dvv\ for one configuration on one waveform ++realisation & Raw recovered series, no baseline alignment; epochs the pipeline ++produced; fixed reference from the first 60\% of the record \\ \hline ++Within-measurement $\sigma_k(t)$ & Standard error of one dilation estimate from ++finite coda coherence, eq.~\ref{eq:weaver} & Per epoch and configuration; ++depends on coherence, band, window; a lower bound (Section~\ref{sec:bayes}) \\ \hline ++Between-pair SD, $\sigma_{\mathrm{SD}}$ & Dispersion of the $N$ pair estimates ++at one epoch (physical heterogeneity plus pair noise) & Finite network; no datum ++change \\ \hline ++Network SE, $\sigma_{\mathrm{SE}}$, $\sigma_{\mathrm{SE},w}$ & Precision of the ++network mean under independent pairs; shared stations or noise make it ++optimistic & Same epochs; the target is the finite-network mean \\ \hline ++Posterior credible band on $\mu(t)$ & Precision of the ensemble-combined ++estimate under the model of Section~\ref{sec:bayes} & Decimated epochs; under-covers ++when configurations share a bias \\ \hline ++$C_d$ & Proposed error covariance of one ensemble member: fitted ++floor, excess spread, temporal correlation, offset scale $\tau$ & Same ++epochs; 95\% pointwise member coverage supported, 68\% overcoverage; ++temporal covariance unvalidated (Table~\ref{tab:calibration}) \\ \hline ++Field comparison $r$, slope & Agreement with a published product after matched ++smoothing & Calendar-day join, 150-day burn-in, trailing 90-day mean ++(Section~\ref{sec:deployment}) \\ ++\bottomrule ++\end{tabularx} ++\end{table} ++``` ++ +@@ -291,5 +343,8 @@ Clock / timing & causal vs acausal branch handling & A clock error fabricates +-The literature agrees on the components of a well-posed \dvv\ measurement: a +-stretching-family estimator for robustness at low SNR and large change +-[@Mikesell2015; @Yuan2021], a coherence-based error model +-[@Clarke2011; @Weaver2011], a long stable reference [@Wang2017], and +-cross-validation against a second estimator [@Obermann2019]. Yet ++The literature agrees on the components of a well-posed \dvv\ measurement: an ++estimator matched to the expected size of the change (the stretching family ++remains accurate at large \dvv, Section\ \ref{sec:methods-fig}; its noise ++robustness relative to the warping methods depends on the setting, and ++@Yuan2021 rank it below DTW in that respect on their heterogeneous full-wave ++simulations), a coherence-based error model [@Clarke2011; @Weaver2011], a ++long stable reference [@Wang2017], and cross-validation against a second ++estimator [@Obermann2019]. Yet +@@ -297 +352 @@ studies do not always report the same set, and the uncertainty convention +-is rarely, if ever, quantified (Appendix~\ref{app:survey}). The sections below address each ++is rarely, if ever, quantified (Appendix\ \ref{app:survey}). The sections below address each +@@ -302 +357 @@ impacts the recovered \dvv\ and its error. +-Table~\ref{tab:results-synthesis} previews the RMS error against the known ++Table\ \ref{tab:results-synthesis} previews the RMS error against the known +@@ -306,2 +361,8 @@ in the corresponding subsection below); it is a synthesis of *this section's* +-per-choice numbers, distinct from Table~\ref{tab:bp-measure}'s one-at-a-time +-sweep on a single shared scenario in Section~\ref{sec:multiverse}. ++per-choice numbers, distinct from Table\ \ref{tab:bp-measure}'s one-at-a-time ++sweep on a single shared scenario in Section\ \ref{sec:multiverse}. Every RMS ++in this section is computed on the raw recovered series against the imposed ++truth over the epochs the pipeline produced, with no baseline alignment, so a ++reference offset counts as error (Section\ \ref{sec:param_ref} shows that ++explicitly); the network-level uncertainty conventions of ++Section\ \ref{sec:uncertainty} are reported quantities, not recovery errors, ++and are listed in Table\ \ref{tab:estimands} rather than here. +@@ -325,2 +385,0 @@ $\sim\!0.31\,\%$ (Approach A, unweighted) & Section~\ref{sec:aggregation} \\ \hl +-Network aggregation (per-pair spread) & $\sim\!0.005\,\%$ (network SE) & +-$\sim\!0.05\,\%$ (individual-pair range) & Section~\ref{sec:uncertainty} \\ \hline +@@ -355,3 +414,3 @@ measurement pipeline, so the convention cannot silently drift back. +-On small, clean \dvv$\,$all seven estimators agree +-(Fig.~\ref{fig:methods}a). Sweeping the same clean recovery out to +-$\pm 5\,\%$ (Fig.~\ref{fig:methods}b) shows exactly where and how each family ++On small, clean \dvv$\,$all seven estimators agree to within 0.04\,\% RMS ++(Fig.\ \ref{fig:methods}a). Sweeping the same clean recovery out to ++$\pm 5\,\%$ (Fig.\ \ref{fig:methods}b) shows exactly where and how each family +@@ -359,7 +418,11 @@ first departs from the 1:1 line, and the estimator choice becomes consequential +-at large, noisy \dvv\ (Fig.~\ref{fig:methods}c), where the effect of the methods +-is split according to their phase measurement approaches. The stretching family (TS, WTS) and WCC match the whole dilated +-coda and remain accurate for high SNR coda waves; the phase methods (MWCS) read a wrapped phase and may +-cycle-skips, while the *same* cross-wavelet phase (WCS), once unwrapped in 2-D, +-recovers the change. The warping methods (DTW, WTDTW) track but under-shoot the largest +-strains. No estimator is simply "right"; the choice of estimator materially changes +-the \dvv\ measurement at larger strain. ++at large, noisy \dvv\ (Fig.\ \ref{fig:methods}c), where the effect of the methods ++is split according to their phase measurement approaches. The stretching family ++(TS, WTS) and WCC match the whole dilated coda and stay within 0.05\,\% RMS of ++the truth on the noisy landslide signal (0.005, 0.010 and 0.046\,\%); the ++warping methods (DTW, WTDTW) track but under-shoot the largest strains (0.16 and ++0.08\,\% RMS); both phase methods fail on this noisy, large-strain signal, ++MWCS by cycle-skipping (2.9\,\% RMS) and WCS, whose 2-D unwrapping recovers ++the clean sweep of panel (b), by losing the phase track once noise is added ++(3.8\,\% RMS; the numbers are computed from the figure's numerical sidecar). ++No estimator is simply "right"; the choice of estimator materially changes the ++\dvv\ measurement at larger strain. +@@ -378,3 +441,6 @@ the \dvv\ measurement at larger strain. +- (c) Large, noisy \dvv\ (a pre-failure landslide signal): +- MWCS cycle-skips, 2-D-unwrapped WCS and the stretching family track, the +- warping methods under-shoot.} ++ (c) Large, noisy \dvv\ (a pre-failure landslide signal): the stretching ++ family and WCC track, the warping methods under-shoot, and both phase ++ methods fail (MWCS cycle-skips; WCS loses the phase track in noise despite ++ the 2-D unwrapping that carries it through the clean sweep in b). RMS ++ errors are given in the text; the plotted arrays are in the figure's ++ sidecar (Table~\ref{tab:estimands}).} +@@ -384 +450 @@ the \dvv\ measurement at larger strain. +-On a clean, noiseless sweep of true \dvv\ from $-5$ to $5\,\%$ (Fig.~\ref{fig:methods}b), ++On a clean, noiseless sweep of true \dvv\ from $-5$ to $5\,\%$ (Fig.\ \ref{fig:methods}b), +@@ -393 +459 @@ edge of the tested range ($\sim\!4.75\,\%$) --- a sign asymmetry from the +-physical convention itself (Section~\ref{sec:intro}), not a processing ++physical convention itself (Section\ \ref{sec:intro}), not a processing +@@ -416 +482 @@ choice that can change both the value and the uncertainty +-(Fig.~\ref{fig:aggregation}). One may peak-pick each component's ++(Fig.\ \ref{fig:aggregation}). One may peak-pick each component's +@@ -450,7 +516,19 @@ standard error (e.g., @Clarke2011), an unweighted standard error ($\sigma=\mathr +-and the between-pair standard deviation (e.g., @Clements2018). On the same synthetic network the recovered means nearly coincide, +-but the reported $1\sigma$ spans a factor of $\sim\!\sqrt{N}$ +-(Fig.~\ref{fig:uncertainty}). A velocity change that is "$3\sigma$ significant" +-under the tightest convention is "$1\sigma$, not significant" under the most +-conservative one --- from identical data. Error bars on published \dvv\ are +-therefore not comparable across studies unless the aggregation, the weighting, +-and the standard-error-versus-standard-deviation convention are all stated. ++and the between-pair standard deviation (e.g., @Clements2018). These are ++estimates of different quantities (Table\ \ref{tab:estimands}): the standard ++error is the precision of the network mean under independent pairs, the ++standard deviation is the dispersion of the pairs, which on this synthetic ++mixes the 15\,\% pair-to-pair amplitude heterogeneity we impose with the pair ++noise, and the two are related by $\sqrt{N}$ by construction. On the same ++synthetic network the recovered means nearly coincide, but the number reported ++as $1\sigma$ spans a factor of $\sim\!\sqrt{N}$ (Fig.\ \ref{fig:uncertainty}). ++A velocity change that is three times the coherence-weighted standard error is ++about one between-pair standard deviation, from identical data; neither ++statement is wrong, but a study that reports only "$1\sigma$" leaves the reader ++unable to tell which is meant. Error bars on published \dvv\ are therefore not ++comparable across studies unless the aggregation, the weighting, and the ++standard-error-versus-standard-deviation convention are all stated. Neither ++convention is the precision of the mean when pairs share stations or noise; ++that requires the pair covariance, $\mathbf{a}^\top\Sigma\mathbf{a}$ for ++normalised weights $\mathbf{a}$, which the Bayesian ensemble of ++Section\ \ref{sec:bayes} supplies for the configuration axis and which a ++network extension would supply for the pair axis. +@@ -468,2 +546,2 @@ and the standard-error-versus-standard-deviation convention are all stated. +-Figure~\ref{fig:uncertainty} plots only the *network-aggregate* series, which +-hides how much the individual pairs actually disagree. Fig.~\ref{fig:network-pairs} ++Figure\ \ref{fig:uncertainty} plots only the *network-aggregate* series, which ++hides how much the individual pairs actually disagree. Fig.\ \ref{fig:network-pairs} +@@ -499 +577 @@ signals and low frequencies recover a deeper, maybe more tectonic, signal +-(Fig.~\ref{fig:params}a). In practice a band often gets reused from a neighboring ++(Fig.\ \ref{fig:params}a). In practice a band often gets reused from a neighboring +@@ -510 +588 @@ sampling the shallow layer's signal instead of the deep one --- and plateaus +-near $\sim\!0.10\,\%$ beyond that (Fig.~\ref{fig:band-sensitivity}). The band ++near $\sim\!0.10\,\%$ beyond that (Fig.\ \ref{fig:band-sensitivity}). The band +@@ -533 +611 @@ continuously and erases slow trends that a fixed reference or a joint inversion +-[@Brenguier2014] preserve (Fig.~\ref{fig:params}c). In practice the choice is ++[@Brenguier2014] preserve (Fig.\ \ref{fig:params}c). In practice the choice is +@@ -546 +624 @@ reference, and **no single reference at all** --- the Brenguier et al. +-stacks instead of referencing every day to one (Fig.~\ref{fig:reference-schemes}a). ++stacks instead of referencing every day to one (Fig.\ \ref{fig:reference-schemes}a). +@@ -565 +643 @@ at 240 days, still $\sim\!4$--$5\times$ the whole-record RMS +-(Fig.~\ref{fig:reference-schemes}b) --- the erasure is structural, not a noise ++(Fig.\ \ref{fig:reference-schemes}b) --- the erasure is structural, not a noise +@@ -634 +712 @@ The **stacking length** trades noise against temporal resolution, rounding off +-and delaying a coseismic step (Fig.~\ref{fig:params}d). In practice the ++and delaying a coseismic step (Fig.\ \ref{fig:params}d). In practice the +@@ -638 +716 @@ a working correlation-coefficient (CC) threshold, then stopping. codameter's +-own quality-control gate uses CC~$>0.6$ (Section~\ref{sec:results}), and how ++own quality-control gate uses CC~$>0.6$ (Section\ \ref{sec:results}), and how +@@ -646,2 +724 @@ of shorter correlations can be partially compensated through adaptive filtering, +-or learned denoising, or through redundancy across dense seismic arrays, enabling \dvv\ +-measurements at daily, hourly, and even sub-hourly resolution [@Hadziioannou2011,@Moreau2017,@Mao2019,@Viens2020]. ++or learned denoising, or through redundancy across dense seismic arrays, enabling \dvv\ measurements at daily, hourly, and even sub-hourly resolution [@Hadziioannou2011,@Moreau2017,@Mao2019,@Viens2020]. +@@ -659 +736 @@ used throughout this section) clears CC~$>0.6$ already at a 1-day stack +-of substacking to clear the same bar (Fig.~\ref{fig:stack-coherence}a). The ++of substacking to clear the same bar (Fig.\ \ref{fig:stack-coherence}a). The +@@ -664 +741 @@ $\sim\!0.038\,\%$ by 60 days as the stack smears the step +-(Fig.~\ref{fig:stack-coherence}b) --- the classic noise-versus-smearing ++(Fig.\ \ref{fig:stack-coherence}b) --- the classic noise-versus-smearing +@@ -669,5 +746,6 @@ floor dominates over the whole tested range, and the smearing penalty never +-gets the chance to show up. Both regimes underestimate the coseismic step's +-amplitude at every stack length tested here (the bias stays negative +-throughout for the poor deployment, and only crosses zero past 45 days for the +-workable one), so a recovered step should be read as a lower bound on the true +-drop, more so the longer the stack. ++gets the chance to show up. The signed error in the recovered step amplitude ++is negative (an under-estimate) at every stack length for the poor deployment, ++and for the workable deployment up to about 45 days, past which it crosses ++zero and the step is over-estimated. A recovered step is therefore a lower ++bound on the true drop only in the noise-limited regime; the sign of the error ++depends on the deployment and the stack length, and both should be reported. +@@ -708 +786 @@ is catalogued directly, study by study, in the survey of +-Appendix~\ref{app:survey} (Table~\ref{tab:survey}): the frequency band, coda ++Appendix\ \ref{app:survey} (Table\ \ref{tab:survey}): the frequency band, coda +@@ -720 +798 @@ that is well past the direct arrival for a $\sim\!0.3$--$0.8\,$Hz band is, at +-$\sim\!3$--$6\,$Hz, sampling almost pure noise (Fig.~\ref{fig:params}b). On our ++$\sim\!3$--$6\,$Hz, sampling almost pure noise (Fig.\ \ref{fig:params}b). On our +@@ -726 +804 @@ of a literature-documented tension: band-matched windowing is recommended, but +-Table~\ref{tab:survey} shows many surveyed studies instead reuse one fixed ++Table\ \ref{tab:survey} shows many surveyed studies instead reuse one fixed +@@ -739 +817 @@ which band it is) to three bands spanning low, mid, and high frequency +-(Fig.~\ref{fig:window-envelope}a), the detector recovers windows of ++(Fig.\ \ref{fig:window-envelope}a), the detector recovers windows of +@@ -745 +823 @@ exact). Recovering \dvv\ with each band's own detected window instead of one +-universal fixed (10--30$\,$s) window (Fig.~\ref{fig:window-envelope}b) gives RMS ++universal fixed (10--30$\,$s) window (Fig.\ \ref{fig:window-envelope}b) gives RMS +@@ -779 +857 @@ genuinely different \dvv\ without either being wrong. Two regimes bound the +-choice (Fig.~\ref{fig:branches}). When a change is *localized* to the volume one ++choice (Fig.\ \ref{fig:branches}). When a change is *localized* to the volume one +@@ -782 +860 @@ dilutes it toward zero, while the branch that carries the change recovers it +-(Fig.~\ref{fig:branches}a); here preferring the branch of greatest change is ++(Fig.\ \ref{fig:branches}a); here preferring the branch of greatest change is +@@ -787,7 +865,9 @@ change over-reports it --- a max-of-two-estimators selection bias that grows as +-SNR falls (Fig.~\ref{fig:branches}b). When both sides exhibit the same change +-(sign, coherence) but with different magnitude, it is reasonable to use the +-\dvv\ of greatest change given the already low sensitivity in coda waves [@Obermann2013]. +-An acceptable workflow is to measure both branches, evaluate on that consistency, +-select by the coherence of the change rather than its amplitude (a criterion independent of the answer, so +-it carries no selection bias), and carry the between-branch difference as an +-explicit term of the measurement covariance $C_d$ (Section~\ref{sec:bayes}) ++SNR falls (Fig.\ \ref{fig:branches}b). Choosing the branch of greatest change ++after seeing the data is therefore a selection rule that Fig.\ \ref{fig:branches}b ++shows to be biased, and the coherence of each branch is estimated from the same ++observations, so selecting on coherence reduces but does not remove that bias. ++The rule we adopt is fixed before the data are seen: measure both branches and ++report both; combine them by their mean unless independent physical ++information (source-side illumination, a change known to be confined to one ++side) designates a branch beforehand; and carry the between-branch difference as ++an explicit term of the measurement covariance $C_d$ (Section\ \ref{sec:bayes}) +@@ -815 +895 @@ branches; measuring the two branches separately is the diagnostic +-(Fig.~\ref{fig:artifacts}a). Seasonally varying noise sources warp the low-SNR ++(Fig.\ \ref{fig:artifacts}a). Seasonally varying noise sources warp the low-SNR +@@ -818 +898 @@ late coda, so a late measurement window reports a coherent spurious *seasonal* +-[the waveform-level version of @Zhan2013] (Fig.~\ref{fig:artifacts}b). ++[the waveform-level version of @Zhan2013] (Fig.\ \ref{fig:artifacts}b). +@@ -834 +914 @@ Taken together, the choices compound. We make this concrete in +-Section~\ref{sec:multiverse} by running the full *multiverse* of best-practice ++Section\ \ref{sec:multiverse} by running the full *multiverse* of best-practice +@@ -850 +930 @@ scenario isolates the measurement-step choices from the network-aggregation choi +-already covered in Sections~\ref{sec:aggregation}--\ref{sec:uncertainty}. ++already covered in Sections\ \ref{sec:aggregation}--\ref{sec:uncertainty}. +@@ -859 +939 @@ one parameter at a time to a deviation from best practice documented in the lite +- and measure the resulting error against the known truth (Fig.~\ref{fig:deviations}). The ranking is unambiguous: relative ++ and measure the resulting error against the known truth (Fig.\ \ref{fig:deviations}). The ranking is unambiguous: relative +@@ -863,2 +943,4 @@ inflates the error by roughly an order of magnitude ($\sim\!12\times$), and DTW +-$\sim\!6\times$; among the non-estimator choices a moving reference is worst +-($\sim\!5\times$, and most distorts the recovered drop), while stack length, coda ++$\sim\!6\times$; among the non-estimator choices the uncumulated trailing ++reference is worst ($\sim\!5\times$, and most distorts the recovered drop; it ++is an ablation of re-baselining without trend reconstruction, not a surveyed ++workflow, Section\ \ref{sec:param_ref}), while stack length, coda +@@ -872,3 +954,3 @@ fixed-reference baseline among the reference-scheme deviations. +- \caption{One-at-a-time deviations from a best-practice baseline, ranked by the +- bias they inject (a, log scale) and by how they distort the recovered +- co-eruptive drop (b, symlog). Bars are coloured red when the error exceeds ++ \caption{One-at-a-time deviations from a best-practice baseline, ranked by ++ their RMS error against the truth (a, log scale; RMS mixes bias and ++ scatter) and by how they distort the recovered co-eruptive drop (b, symlog). Bars are coloured red when the error exceeds +@@ -884 +966 @@ that includes a seasonal oscillation, a slow pre-eruptive inflation ramp, and a +-sharp co-eruptive drop with partial exponential recovery (Fig.~\ref{fig:multiverse}a). ++sharp co-eruptive drop with partial exponential recovery (Fig.\ \ref{fig:multiverse}a). +@@ -891 +973 @@ Attributing the variance of the outcome to each axis with a first-order (main-ef +-(Fig.~\ref{fig:multiverse}b) shows that, for this dataset, the **coda window** ++(Fig.\ \ref{fig:multiverse}b) shows that, for this dataset, the **coda window** +@@ -905,3 +987,5 @@ but a distribution of \dvv\ over the processing choices. +- each coloured by its RMS error against the truth on a colourblind-safe scale +- (bright accurate, dark biased; the worst run off the clipped axis); the grey band +- is the 10--90\% inter-pipeline spread, widest at the velocity drop. (b) First-order variance attribution: which ++ each coloured by its RMS error against the truth (a fraction of velocity) on ++ a colourblind-safe scale (bright accurate, dark biased); the axis is clipped ++ at $\pm0.8\,\%$ and the number of pipelines that leave it is printed on the ++ panel; the grey band is the 10--90\% inter-pipeline spread, widest at the ++ velocity drop. (b) First-order variance attribution: which +@@ -914 +998 @@ but a distribution of \dvv\ over the processing choices. +-Table~\ref{tab:bp-measure} summarizes this into the measurement-step best practice ++Table\ \ref{tab:bp-measure} summarizes this into the measurement-step best practice +@@ -933,2 +1017 @@ follow the literature survey (Appendix~\ref{app:survey}).} +-Estimator & Stretching family (TS/WTS/WCC), robust at low SNR and large \dvv\ +-\citep{Mikesell2015,Yuan2021} & Wrapped-phase MWCS \citep{Clarke2011} without 2-D ++Estimator & Stretching family (TS/WTS/WCC), robust at low SNR and large \dvv\ \citep{Mikesell2015,Yuan2021} & Wrapped-phase MWCS \citep{Clarke2011} without 2-D +@@ -948 +1031,3 @@ Reference & Long fixed stack or all-to-all joint inversion +-\citep{Brenguier2014,Wang2017} & Moving / trailing reference & Erases slow trends \\ \hline ++\citep{Brenguier2014,Wang2017} & Uncumulated trailing reference (an ablation: ++published moving-reference workflows cumulate or stitch, ++Section~\ref{sec:param_ref}) & Erases slow trends \\ \hline +@@ -977,2 +1062,2 @@ select a single pipeline but to treat the choice as a **nuisance parameter** wit +-prior and marginalise it out. We propose this as the new best practice for the +-\dvv\ *measurement*, and implement it as a Bayesian hierarchical inversion. For ++prior and assess its influence. We explore a Bayesian hierarchical model ++for the \dvv\ *measurement*, conditional on a specified pipeline menu. For +@@ -988,13 +1073,30 @@ m_k(t) = \mu(t) + \beta_k + \varepsilon_k(t), \qquad +-with a second-difference random-walk smoothness prior on the latent true series +-$\mu(t)$. Here $\beta_k$ is configuration $k$'s methodological bias (the +-systematic offset between, say, MWCS and stretching), $\tau$ its scale across the +-ensemble, and $s$ rescales the Weaver floor so the data report whether it is +-calibrated. A conjugate Gibbs sampler, implemented in codameter with no +-external sampler dependency, returns the joint posterior. +- +-The model yields two distinct objects, and conflating them is the error the +-field makes (Fig.~\ref{fig:bayes}). The posterior of $\mu$ is the precision of +-the *combined* estimate: it is tight and shrinks with ensemble size --- yet it +-\emph{under-covers the truth}, because the configurations share a common-mode +-bias that averaging cannot remove. The object a downstream depth or stress +-inversion must consume is the **marginal measurement covariance** ++The likelihood treats residuals as conditionally independent across ++configurations and epochs. Shared input waveforms do not ensure this ++assumption. Fitting all member outputs jointly is not the same operation as ++marginalising a discrete mixture of alternative pipelines. The posterior is ++therefore conditional on this working likelihood. We use a ++second-difference smoothness prior of precision $\lambda$ on the latent ++true series $\mu(t)$, built on the physical time grid so that a gap in the ++record is a gap in the prior. Here $\beta_k$ is configuration $k$'s constant ++offset (the systematic offset between, say, MWCS and stretching), $\tau$ its ++scale across the ensemble, and $s$ rescales the coherence floor of ++eq.\ \ref{eq:weaver} so that the data report whether that floor is calibrated. ++Every configuration is run through the same pipeline code as the rest of the ++paper, so the estimator, band, window, stack length in days, reference scheme ++and coherence gate all take effect; an epoch a configuration does not produce ++(reference warm-up, a gated coherence) is simply missing and carries no ++information. The hyper-priors on $\tau^2$, $s^2$ and $\lambda$ are conjugate ++inverse-gamma and gamma distributions whose scales are small against the data ++terms. Codameter reports the prior scale term divided by the conditional ++posterior rate, evaluated at posterior means. The ratio is about 0.09 for ++$\tau^2$ in the clean scenario and below 0.01 for $s^2$ and $\lambda$ ++(Table\ \ref{tab:calibration}). This diagnostic does not measure the total ++influence of the prior or establish sampler convergence. A conjugate Gibbs sampler, ++implemented in codameter with no external sampler dependency and with a banded ++solve for the smoothness update, returns the joint posterior. ++ ++The model yields two distinct objects, and conflating them is a common ++error (Fig.\ \ref{fig:bayes}; Table\ \ref{tab:estimands}). The posterior of ++$\mu$ is the precision of the *combined* estimate: it is tight and shrinks ++with ensemble size under the working likelihood. Separately, we construct ++a candidate **single-member error covariance** +@@ -1002 +1104 @@ inversion must consume is the **marginal measurement covariance** +-C_d(t,t') = \underbrace{D R D}_{\text{within}\,\oplus\,\text{methodological},\ \text{temporally correlated}} ++C_d(t,t') = \underbrace{D R D}_{\text{calibrated floor}\,\oplus\,\text{excess spread},\ \text{temporally correlated}} +@@ -1007,8 +1109,62 @@ C_d(t,t') = \underbrace{D R D}_{\text{within}\,\oplus\,\text{methodological},\ \ +-with $\sigma_{\mathrm{tot}}^2 = s^2\sigma_k^2$-average $+$ methodological variance and +-$R_{ij}=e^{-|t_i-t_j|/L}$ for a correlation length $L$ estimated from the +-ensemble residuals. This $C_d$ is **time-dependent** --- wider at the sharp drop +-and at low coherence --- and its temporal correlation plus common-mode term +-collapse the effective number of independent epochs by an order of magnitude. On +-our synthetic the marginal $C_d$ covers the truth at the nominal rate while the +-naive posterior band does not, making concrete that the *measurement covariance*, +-not the posterior of the averaged series, is what must be propagated. ++with $\sigma_{\mathrm{tot}}^2(t) = s^2\,\overline{\sigma_k^2(t)} + ++\max\!\big[\operatorname{Var}_k(m_k(t)-\beta_k) - s^2\,\overline{\sigma_k^2(t)},\,0\big]$, ++the calibrated floor plus whatever spread across configurations exceeds it ++(so that the floor is not counted twice), and $R_{ij}=e^{-|t_i-t_j|/L}$ for a ++correlation length $L$ estimated from the ensemble residuals. $C_d$ is ++constructed from the fitted model, not sampled. It targets the error of one ++measurement drawn from the ensemble, not of $\mu$. The between-configuration ++offset scale $\tau$ does not identify an error shared by all configurations. ++Pointwise coverage tests only the diagonal scale; it does not validate $R$ ++or the rank-one term. A downstream inversion needs the error covariance of ++its actual input estimate. Neither using this $C_d$ for the ensemble mean ++nor interpreting its time axes as frequency-band axes is justified here. ++ ++Two properties of the fit deserve to be stated plainly. First, $s\approx 12$ ++on this synthetic: the residual scatter of the members about the ensemble mean ++is an order of magnitude above the coherence floor of eq.\ \ref{eq:weaver}, ++which treats the reference as noise-free and knows nothing of the estimator. ++The floor is a lower bound, and the rescale is what makes it usable. Second, ++once $s$ is fitted on those residuals, the calibrated floor absorbs nearly all ++of the between-configuration spread, and the excess term of eq.\ \ref{eq:cd} is ++non-zero only at the epochs where the configurations disagree more than they ++usually do (Fig.\ \ref{fig:bayes}c). The assumed temporal correlation ($L\approx 40$ ++days at a 4-day cadence) and the common-mode term collapse the effective ++number of independent epochs from 229 to a few tens. ++ ++Whether these intervals mean what they say is a question one realisation ++cannot answer, so we repeat the whole measurement on independent ++realisations of the same scenario (Table\ \ref{tab:calibration}; the driver ++is \texttt{codameter.calibration}). Three coverages answer three different ++questions. The fraction of member epochs whose error against the truth lies ++within $1.96\,\sigma_{C_d}$ is 0.956 on 200 realisations, within the margin of $\pm 0.03$ fixed ++before the run. This supports the 95\,\% pointwise interval on this ++scenario, not calibration of the entire covariance. At the 68\,\% level ++it covers 0.81 and fails the same margin. One Gaussian scale therefore does ++not calibrate both interval levels. The 95\,\% credible band on ++$\mu$ contains the truth at only 0.59 of the epochs: the ensemble mean ++inherits the biases its members share (the stacking that rounds the drop, the ++estimator biases at low coherence), and no amount of averaging over ++configurations removes them, which is what the posterior's precision cannot ++know. Comparing $\mu$ with $\pm 2\sigma_{C_d}$ mixes the ensemble mean with ++a single-member scale and yields nearly complete coverage here; it does ++not validate the uncertainty of the combined estimate. The other two scenarios of Table\ \ref{tab:calibration} inject artefacts that ++every configuration sees identically. A station clock drift leaves every ++statistic unchanged, because a lapse-independent shift appears with opposite ++signs on the causal and acausal branches (Section\ \ref{sec:artifacts}) and ++every configuration in this ensemble measures both branches together, so the ++drift cancels in the estimate; that is a property of the two-branch ++measurement, not evidence that the ensemble could have detected it. ++A seasonal source effect confined to the late coda, the waveform-level ++artefact of @Zhan2013 (Section\ \ref{sec:artifacts}), is the genuine shared ++error: it warps the coda every configuration measures, and on that scenario ++the credible band covers the truth at only 0.34 of the epochs and the RMSE of ++$\mu$ more than doubles, from 0.067 to 0.161\,\%, while the member-level coverage of ++$C_d$ stays at 0.95. That last number is right for a reason that gives no ++comfort: the artefact also inflates the scatter that $s$ absorbs, so $C_d$ ++widens, but its coherent part biases every member and the ensemble mean ++together and leaves no trace in their spread. That is the limit of the ++method, not a defect of the fit: an ensemble over processing choices can only reveal the errors on which ++its members disagree, and an error shared by every pipeline (a source change, ++a contaminated reference, a clock drift measured on one branch) needs an ++independent diagnostic, such as the branch asymmetry of ++Section\ \ref{sec:artifacts}. +@@ -1019 +1175,3 @@ not the posterior of the averaged series, is what must be propagated. +- \caption{The Bayesian measurement model. (a) The processing ensemble (grey) ++ \caption{The Bayesian measurement model on one realisation of the volcano ++ scenario (12 configurations: three estimators, two bands, two windows, 10-day ++ stacks, fixed reference, 4-day cadence). (a) The processing ensemble (grey) +@@ -1021,6 +1179,10 @@ not the posterior of the averaged series, is what must be propagated. +- (the estimator precision) and a much wider $\pm2\sigma$ band from the marginal +- $C_d$ (the honest data error), which covers the truth where the credible band +- does not. (b) The resulting time-dependent data covariance $C_d$. (c) Its +- diagonal $\sigma_d(t)$ decomposed into within-method and methodological parts, +- rising at the eruption; the posterior-of-the-mean (dotted) is far tighter, and +- $N_{\mathrm{eff}}$ is a fraction of the epoch count.} ++ (the estimator precision) and a wider $\pm2\sigma$ band from $C_d$, the ++ single-measurement error, which encloses the individual members ++ (Table~\ref{tab:calibration} gives the coverages over repeated realisations). ++ (b) The time-dependent covariance $C_d$, in squared fractional \dvv. ++ (c) Its diagonal $\sigma_d(t)$, in percent, split into the calibrated ++ coherence floor ($s\,\overline{\sigma_k}$, which with $s\approx12$ carries ++ almost all of the spread) and the excess between-configuration spread, which ++ is non-zero only where the configurations disagree more than usual; the ++ posterior-of-the-mean (dotted) is far tighter, and $N_{\mathrm{eff}}$ is a ++ small fraction of the epoch count.} +@@ -1029,0 +1192,2 @@ not the posterior of the averaged series, is what must be propagated. ++\input{calibration_table.tex} ++ +@@ -1031 +1195 @@ not the posterior of the averaged series, is what must be propagated. +-# Propagating \dvv\ errors at depth $\Delta\beta/beta(z)${#sec:depth} ++# Propagating \dvv\ errors at depth $\Delta\beta/\beta(z)$ {#sec:depth} +@@ -1034 +1198 @@ The remaining sections present a framework rather than new synthetics: they set +-out how the covariance of Section~\ref{sec:bayes} propagates down the inference ++out how the covariance of Section\ \ref{sec:bayes} propagates down the inference +@@ -1037 +1201 @@ yet report. The executable stages are in development in the open codameter packa +-(Section~\ref{sec:discussion}). ++(Section\ \ref{sec:discussion}). +@@ -1059,2 +1223 @@ where $K_b(z)$ is the (Rayleigh-wave) depth-sensitivity kernel for band $b$ and +-$\varepsilon_b$ carries that band's measurement covariance from +-Section~\ref{sec:bayes}. Stacking bands gives a linear system ++$\varepsilon_b$ is that band's observation error. Stacking bands gives a linear system +@@ -1062 +1225,4 @@ $\mathbf{d}=\mathbf{G}\,\mathbf{m}+\boldsymbol\varepsilon$ with +-$\mathbf{G}_{bz}=K_b(z)$ and data covariance $C_d$; the Bayesian solution under a ++$\mathbf{G}_{bz}=K_b(z)$ and cross-band data covariance $C_d^{\mathrm{band}}$. ++This covariance must describe the band estimates actually supplied. The ++temporal $C_d$ in Section\ \ref{sec:bayes} does not supply its cross-band ++entries. Given such a covariance, the Bayesian solution under a +@@ -1066 +1232 @@ must sit where the kernels resolve: too low and the kernel leaks into the +-half-space, too high and the coda is incoherent (Section~\ref{sec:params_freq}). The ++half-space, too high and the coda is incoherent (Section\ \ref{sec:params_freq}). The +@@ -1087 +1253 @@ much of the surface \dvv\ each explains; the executable version is a documented +-extension (Section~\ref{sec:discussion}). ++extension (Section\ \ref{sec:discussion}). +@@ -1114 +1280 @@ unstated model & Hidden systematic in the kernels and the moduli \\ +-# Toward a scalable deployment {#sec:deployment} ++# Real-data comparison and deployment {#sec:deployment} +@@ -1116 +1282 @@ unstated model & Hidden systematic in the kernels and the moduli \\ +-Every result so far is on a truth-known synthetic, by design (Section~\ref{sec:methods}): ++Every result so far is on a truth-known synthetic, by design (Section\ \ref{sec:methods}): +@@ -1119,2 +1285 @@ next step is to test whether the same measurement machinery holds up against +-real data at deployment scale, not just against a synthetic that was built to +-resemble it. We are building a companion cloud pipeline that ++real data, not just against a synthetic that was built to resemble it. We are building a companion cloud pipeline that +@@ -1129 +1294 @@ configurations drawn from the same recommendation logic --- not a separate +-reimplementation. The retrospective run is validated against the ++reimplementation. The retrospective run is compared with the +@@ -1134 +1299 @@ After the correction, single-station \dvv\ (NoisePy correlations, a +-codameter 5-member ensemble, 2--4$\,$Hz, 2018--2019) validates against the ++codameter 5-member ensemble, 2--4$\,$Hz, 2018--2019) agrees in shape with the +@@ -1139,9 +1304,45 @@ matching that smoothing caps the correlation near 0.7 even on a real annual +-cycle (Fig.~\ref{fig:realdata-validation}). We match by applying the same +-trailing 90-day mean to the daily series, compare demeaned --- the two +-products reference different epochs, and a constant offset is bookkeeping, +-not error --- and exclude the first 150 days of each station's series as +-reference burn-in. Under this matched comparison, CI.LJR reaches $r=0.990$ +-(681 overlapping days); CI.ARV reaches $r=0.66$--$0.92$ depending on the join +-method, reflecting real 2018 data gaps; CI.RXH reaches $r=0.68$, the weakest +-of the three, on a station whose recovered \dvv\ is nearly flat and whose +-signal is low to begin with. ++cycle (Fig.\ \ref{fig:realdata-validation}). We match by applying the same ++trailing 90-day mean to the daily series (at least 45 finite days in the ++window), compare demeaned --- the two products reference different epochs, ++and a constant offset is bookkeeping, not error --- and exclude the first 150 ++days of each station's series as reference burn-in. The comparison is ++computed by a script archived with the paper ++(\texttt{scripts/compare\_gate1.py}) from the daily products and the ++published series, with the join, smoothing and mask stated in its output ++(\texttt{paper/data/gate1/comparison.json}); Table\ \ref{tab:gate1} lists the ++result. Under the matched rule CI.LJR reaches $r=0.985$ on 579 days with an ++amplitude slope of 1.07 (published on codameter); CI.ARV reaches $r=0.905$ on ++357 days, the 2018 data gaps reducing the overlap, but with a slope of 2.15, ++so the published product has twice the amplitude of ours there; CI.RXH ++reaches $r=0.829$ on 446 days with a slope of 0.81 on a station whose ++recovered \dvv\ is nearly flat. Correlation measures the shape of the annual ++cycle after smoothing; it does not validate the amplitude (the ARV slope) or ++the error bars, which the published product does not carry, and the earlier ++draft's quoted 681 days was the raw daily overlap, not the count under the ++stated mask. ++ ++```{=latex} ++\begin{table} ++\footnotesize ++\caption{Comparison of codameter single-station \dvv\ (2--4\,Hz, 2018--2019) ++with the published \citet{Clements2023} product, from ++\texttt{scripts/compare\_gate1.py}. Matched: trailing 90-day mean, 150-day ++burn-in. Centred: centred 45-day mean, no burn-in (the rule behind the ++annotation on Fig.~\ref{fig:realdata-validation}). Slope is the OLS slope of ++the published product on codameter; RMS is the RMS difference after removing ++each series' mean over the overlap.} ++\label{tab:gate1} ++\begin{tabular}{@{}llrrrr@{}} ++\toprule ++Station & Rule & Days & $r$ & RMS diff (\%) & Slope \\ ++\midrule ++CI.LJR & matched & 579 & 0.985 & 0.046 & 1.07 \\ ++CI.LJR & centred & 682 & 0.865 & 0.120 & 0.88 \\ ++CI.ARV & matched & 357 & 0.905 & 0.150 & 2.15 \\ ++CI.ARV & centred & 424 & 0.369 & 0.214 & 0.80 \\ ++CI.RXH & matched & 446 & 0.829 & 0.020 & 0.81 \\ ++CI.RXH & centred & 554 & 0.620 & 0.035 & 0.52 \\ ++\bottomrule ++\end{tabular} ++\end{table} ++``` +@@ -1153,8 +1354,13 @@ signal is low to begin with. +- published \citet{Clements2023} product (dashed, reference-shifted). +- Daily \dvv\ (points) with the ensemble spread (shaded, epistemic) and +- measurement error bars, and a 45-day-smoothed curve. The annotated $r$ is +- computed on this 45-day-smoothed comparison, not the smoothing-matched +- comparison reported in the text; matching CD2023's own trailing 90-day +- window instead of a centered 45-day one raises $r$ at every station (to +- 0.990/0.66--0.92/0.68 for LJR/ARV/RXH), which is why the two numbers +- differ.} ++ published \citet{Clements2023} product (dashed, reference-shifted; the ++ panel labels name it by its 2022 data release). Daily \dvv\ (points) with the ++ between-configuration spread of the five-member ensemble (shaded) and the ++ within-measurement error bars (Table~\ref{tab:estimands}), and a centred ++ 45-day-smoothed curve. This figure was produced by the Gate 1 cloud run ++ itself and is not regenerated from this repository; its annotated $r$ values ++ correspond to the centred rule of Table~\ref{tab:gate1} (0.87, 0.37 and ++ 0.62 for LJR, ARV and RXH from the archived products), not to the matched ++ rule quoted in the text. The error bars drawn here predate the Weaver-floor ++ correction of the present revision and are too large by a factor of 3.1 at ++ 2--4\,Hz (the archived columns have since been rescaled by ++ \texttt{scripts/correct\_gate1\_within\_error.py}; the externally produced ++ figure has not been regenerated).} +@@ -1164,2 +1370,5 @@ signal is low to begin with. +-Why validation quality differs so much by station is visible in the +-correlation function itself (Fig.~\ref{fig:realdata-interferograms}). CI.LJR ++Part of why agreement differs by station is visible in the correlation ++function itself (Fig.\ \ref{fig:realdata-interferograms}), although an ++interferogram alone cannot separate a site change from an instrument or ++processing change, which station metadata and processing logs would be needed ++to rule out. CI.LJR +@@ -1176,6 +1385,8 @@ sparse, consistent with its higher scatter and join-method sensitivity. +- \caption{Daily north-south/east-west cross-component correlation +- functions, 2--4$\,$Hz, $\pm 8\,$s lag, 2019. CI.LJR's coda is stable and +- narrow. CI.RXH shows multipath (several coherent bands across the full lag +- range) and a shift in that pattern in April--May 2019. CI.ARV's coherent +- energy is compact and near zero lag but comparatively sparse. The visual +- difference is the reason validation quality differs by station in ++ \caption{Daily NZ (north-vertical) cross-component correlation functions, ++ 2--4$\,$Hz, $\pm 8\,$s lag, 2019, each day normalised to its maximum ++ absolute amplitude (colour scale unlabelled on this externally produced ++ figure). CI.LJR's coda is stable and narrow. CI.RXH shows multipath (several ++ coherent bands across the full lag range) and a shift in that pattern in ++ April--May 2019. CI.ARV's coherent energy is compact and near zero lag but ++ comparatively sparse. These differences are consistent with, but do not by ++ themselves explain, the station-to-station agreement in +@@ -1186 +1397 @@ sparse, consistent with its higher scatter and join-method sensitivity. +-As an optional supplement, Fig.~\ref{fig:realdata-warmup} shows the ++As an optional supplement, Fig.\ \ref{fig:realdata-warmup} shows the +@@ -1197,4 +1408,5 @@ correlation coefficient is reported alongside the recovered series. +- error bars are reported once at least one member is defined; the annotated +- member count grows as the moving-reference member's warm-up period +- elapses, reaching all 5 members later in the window. Bottom panel: +- per-band stretching correlation coefficient.} ++ error bars are reported once at least one member is defined; the member ++ count annotated on each panel is the number of members defined on the last ++ day shown, which is below five where the moving-reference member's warm-up ++ had not yet elapsed. Bottom panel: per-band stretching correlation ++ coefficient. Produced by the cloud run, not regenerated here.} +@@ -1207,4 +1419,10 @@ correlation coefficient is reported alongside the recovered series. +-The experiments above share one finding: for ambient-noise \dvv, the dominant +-control on both the reported value and its uncertainty is frequently the +-*processing choice*, not the data. This is a consequential but tractable problem. We +-suggest three responses. ++The experiments above share one finding: on these synthetics, with one ++waveform realisation held fixed, the processing choice moves both the ++recovered \dvv\ and its stated uncertainty by more than the measurement noise ++does, by two orders of magnitude in RMS across the 108-pipeline multiverse and ++by a factor $\sqrt{N}$ in the reported network error bar. Whether processing ++also dominates the variability between real deployments is a question these ++experiments cannot answer, because they hold the observed waveform fixed; the ++repeated-realisation calibration of Section\ \ref{sec:bayes} is the first step ++toward it. The problem is consequential but tractable. We suggest the ++following responses. +@@ -1218,3 +1436,5 @@ between-component/pair standard error, or standard deviation). Our results show +-that the last item alone can change a stated $1\sigma$ by $\sqrt{N}$. +-Table~\ref{tab:checklist} collects this into a minimal reporting checklist, and +-Appendix~\ref{app:survey} shows how unevenly these items are reported across the ++that the last item alone changes the number quoted as $1\sigma$ by $\sqrt{N}$, ++because the two conventions estimate different quantities ++(Table\ \ref{tab:estimands}). ++Table\ \ref{tab:checklist} collects this into a minimal reporting checklist, and ++Appendix\ \ref{app:survey} shows how unevenly these items are reported across the +@@ -1257,10 +1477,29 @@ physics, it can be sampled. Pushing a distribution of reasonable processing +-choices through the measurement-error floors of @Clarke2011 [@Weaver2011] yields, +-by the law of total variance, a marginal \dvv\ uncertainty that includes the +-processing-choice spread --- a more honest error bar than any single pipeline +-provides, and the natural input to a depth/stress inversion. Section~\ref{sec:bayes} +-makes this a Bayesian measurement model whose deliverable is a time-dependent +-data covariance $C_d$. +- +-**Make it executable.** All synthetics, estimators and figures in this paper are +-released in the open codameter package, which reproduces every result with a +-single command and is unit-tested. An executable record turns an undocumented ++choices through the same correlations measures conditional sensitivity. ++A probabilistic mixture would combine conditional variances and the variance ++of conditional means. The joint likelihood in ++Section\ \ref{sec:bayes} instead defines a working Bayesian model whose ++deliverable is a time-dependent single-measurement covariance $C_d$. Its ++limitations are as important as its construction. The prior over pipelines is ++a menu, not a representative sample of practice, and the covariance is ++conditional on it. Every configuration transforms the same waveforms, so an ++error they all share (a source change, a contaminated reference, a clock ++drift measured on one branch) leaves no trace in their spread: on the ++shared-source scenario of Table\ \ref{tab:calibration} the ensemble agrees with ++itself, the error of its mean doubles, and $C_d$ cannot see it. Configurations in different bands sample ++different depths and may not estimate the same physical quantity, so the ++configuration axis should be marginalised only over pipelines that target ++one estimand. And the coherence floor of @Weaver2011 is a lower bound: on our ++synthetic the residual scatter about the ensemble mean is an order of ++magnitude above it, which the fitted rescale $s$ reports rather than hides. ++The pointwise tests in Table\ \ref{tab:calibration} support the 95\,\% ++member intervals on the listed scenarios. They also expose 68\,\% ++overcoverage and poor coverage of the combined estimate. They do not establish ++temporal covariance calibration, convergence across independent chains, or ++valid downstream intervals. ++ ++**Make it executable.** All synthetics, estimators and generated figures in ++this paper are released in the open codameter package; one driver regenerates ++every generated figure together with a numerical sidecar holding every plotted ++array and the run's provenance, and the package is unit-tested. The three ++real-data figures were produced by the cloud run and are archived, not ++regenerated (Section\ \ref{sec:deployment}). An executable record turns an undocumented +@@ -1275,3 +1514,4 @@ Testing codameter's estimators against a real cross-network deployment +-(Section~\ref{sec:deployment}), recovered \dvv\ anticorrelated with the +-published @Clements2023 product and with seasonal hydrology at +-three stations ($r=-0.69,-0.45,-0.40$). Ground-truthing through the exact ++(Section\ \ref{sec:deployment}), recovered \dvv\ anticorrelated with the ++published @Clements2023 product and with seasonal hydrology at three ++stations ($r=-0.69,-0.45,-0.40$ under the rule used at the time, recorded in ++the codameter v0.4.0 release notes). Ground-truthing through the exact +@@ -1285 +1525 @@ published product it was compared against. The fix is the convention boxed +-in Section~\ref{sec:intro}, shipped as codameter v0.4.0. Internal consistency ++in Section\ \ref{sec:intro}, shipped as codameter v0.4.0. Internal consistency +@@ -1292 +1532 @@ ground-truthing procedure are documented in the codameter release history. +-not the end of the analysis but its first input. Section~\ref{sec:depth} sets out ++not the end of the analysis but its first input. Section\ \ref{sec:depth} sets out +@@ -1298,4 +1538,5 @@ material priors this paper does not attempt to constrain, and is left to other +-work; what we deliver is the depth posterior and its covariance, the object any +-such conversion must consume. Building and testing the depth-propagation stage on +-truth-known synthetics is the natural continuation of this work, and is under way +-in the open codameter framework. ++work. What codameter provides today is the interface that consumes $C_d$; the ++depth posterior itself, its resolution, and the calibration of its covariance ++are not demonstrated in this paper. Building and testing the depth-propagation ++stage on truth-known synthetics with overlapping kernels is the natural ++continuation of this work. +@@ -1308,11 +1549,17 @@ estimator suite of an open toolbox, we have shown that these choices change the +-recovered \dvv\ and, more consequentially, change the reported uncertainty by a +-factor of $\sim\!\sqrt{N}$ --- enough to flip the significance of a result --- all +-without touching the data. The remedy is not a single mandated pipeline but +-transparency: report every choice, sample the ones the physics does not fix, +-carry the resulting measurement covariance into the inference, and release the +-pipeline as executable code. The same discipline extends down the inference +-chain: the measurement covariance is the input a depth inversion consumes, and +-only a pipeline that carries the covariance that far can attach an honest +-uncertainty to a depth-resolved velocity-change profile. Converting that profile +-to stress or strain is a further step this paper does not attempt. We offer codameter as one such record, and as the +-package in which the depth stage is being built. ++recovered \dvv\ by up to two orders of magnitude in RMS across reasonable ++pipelines and, more consequentially, change the number reported as its ++uncertainty by a factor of $\sim\!\sqrt{N}$ depending on which of two ++different quantities a study calls $1\sigma$, all without touching the data. ++The remedy is not a single mandated pipeline but transparency: report every ++choice and name the quantity each error bar estimates, sample the choices the ++physics does not fix, carry the resulting measurement covariance into the ++inference after validating its target, and release the pipeline as executable ++code. Repeated synthetic realisations support the proposed 95\,\% ++pointwise member intervals, while the nominal 68\,\% intervals overcover ++and the combined estimate's credible band undercovers ++(Table\ \ref{tab:calibration}). Temporal and cross-band covariance and ++shared errors remain unvalidated. A depth inversion also needs kernel ++uncertainty and the covariance of the actual observations it consumes. ++Converting a depth profile to stress or strain is a further step this paper ++does not attempt. We offer codameter as one such record; its depth stage is an ++interface awaiting evaluation. +@@ -1329 +1576 @@ the current coda relative to the reference; physical \dvv\ follows via the +-convention boxed in Section~\ref{sec:intro}, $\dvv=-\varepsilon/(1+\varepsilon)$. ++convention boxed in Section\ \ref{sec:intro}, $\dvv=-\varepsilon/(1+\varepsilon)$. +@@ -1339,3 +1586,18 @@ The single-measurement error decreases with the coherence $\mathrm{CC}$, the +-bandwidth $B$, and the window length, approximately as $\sigma_{\varepsilon} \propto +-\sqrt{(1-\mathrm{CC}^2)/\mathrm{CC}^2}\, \big/\!\left[f_c\sqrt{B\,(t_2^3-t_1^3)}\right]$ +-[@Weaver2011]. ++bandwidth $B$, and the window length. We use eq.\ 20 of @Weaver2011, ++\begin{equation} ++\sigma_{\varepsilon} = \frac{\sqrt{1-\mathrm{CC}^2}}{2\,\mathrm{CC}} ++\sqrt{\frac{6\sqrt{\pi/2}\;T}{\omega_c^2\,(t_2^3-t_1^3)}}, ++\qquad T=\frac{\sqrt{\ln 10}}{\pi B}, ++\label{eq:weaver} ++\end{equation} ++with $\omega_c=2\pi f_c$ and $T$ the spectral timescale of Weaver et al.'s ++Gaussian spectrum, fixed here by placing the band edges at that spectrum's ++$-10$\,dB points; any convention with $T\propto 1/B$ gives the same ++$1/\sqrt{B}$ scaling and differs by a constant that the rescale $s$ of ++Section\ \ref{sec:bayes} absorbs. The corresponding error on \dvv\ follows ++from the exact map, $\sigma_{\dvv}=\sigma_{\varepsilon}/(1+\varepsilon)^2$, ++which equals $\sigma_{\varepsilon}$ to first order. (The codameter ++implementation before this revision omitted $T$ and used a variance prefactor ++twice this one; the fitted $s$ absorbed the constant, and only the relative ++weighting of configurations in different bands changed when it was ++corrected.) +@@ -1344,0 +1607,8 @@ bandwidth $B$, and the window length, approximately as $\sigma_{\varepsilon} \pr ++Throughout this appendix a delay $\delta t$ is the lag of the current trace ++relative to the reference, positive when the current arrival is later, so for ++the pure dilation $c(t)=r(t/(1+\varepsilon))$ a phase at reference lapse ++$t_i$ appears at $(1+\varepsilon)t_i$ and $\delta t_i=+\varepsilon\,t_i$; with ++that sign every estimator below returns the dilation $\varepsilon$ of the ++Introduction, and a regression test in codameter holds each of them to it in ++both signs. ++ +@@ -1347 +1617 @@ delay is $\delta t_i=\arg\max_{\tau}\int c(t)\,r(t-\tau)\,\mathrm{d}t$; a +-least-squares fit of $\delta t_i=-\varepsilon\,t_i$ gives $\varepsilon$. ++least-squares fit of $\delta t_i=\varepsilon\,t_i$ gives $\varepsilon$. +@@ -1352 +1622 @@ f\,\delta t_i$; a coherence-weighted linear fit of $\varphi(f)$ over $[f_1,f_2]$ +-yields $\delta t_i$, and $\varepsilon$ is minus the slope of $\delta t_i$ versus ++yields $\delta t_i$, and $\varepsilon$ is the slope of $\delta t_i$ versus +@@ -1361 +1631 @@ where $\gamma$ penalises strain (limits the lag's rate of change); $\varepsilon$ +-is minus the slope of $l(i)/f_s$ versus lapse. ++is the slope of the lag $l(i)/f_s$ (current relative to reference) versus lapse. +@@ -1368 +1638 @@ frequency --- removes the cycle-skip; $\varepsilon$ follows from the +-$|W_{xy}|$-weighted regression $\delta t=-\varepsilon\,\tau$ over the ++$|W_{xy}|$-weighted regression $\delta t=\varepsilon\,\tau$ over the +@@ -1398 +1668 @@ N_{\mathrm{eff}}=\frac{(\sum_p W_p)^2}{\sum_p W_p^2}. +-The three uncertainty conventions used in Section~\ref{sec:uncertainty} are the ++The three uncertainty conventions used in Section\ \ref{sec:uncertainty} are the +@@ -1406,3 +1676,5 @@ mean $\bar x$ but obey $\sigma_{\mathrm{SD}}/\sigma_{\mathrm{SE}}=\sqrt{N}$. +-Table~\ref{tab:survey} catalogues the processing choices of the 103 ambient-noise +-\dvv\ monitoring studies we surveyed (the full machine-readable version and +-provenance are distributed with the codameter package). It is the empirical basis ++Table\ \ref{tab:survey} catalogues the processing choices of the ambient-noise ++\dvv\ monitoring studies we surveyed: 103 rows for 102 publications, one ++publication [@Obermann2013] contributing two rows for two distinct ++measurement set-ups (the full machine-readable version and provenance are ++distributed with the codameter package). It is the empirical basis +@@ -1422,2 +1694,4 @@ are flagged in the machine-readable table (\texttt{measurement\_source}) and +-remain to be filled from the paywalled full texts. The apparent under-reporting +-in the table is therefore a lower bound on what the literature actually states. ++remain to be filled from the paywalled full texts. Because a cell populated from ++an abstract can only move from ``n/r'' to reported once the full text is read, ++the apparent under-reporting in the table is an upper bound on the true ++under-reporting; the verified rate is the one among the 82 full-text rows. +@@ -1429,4 +1703,19 @@ in the table is therefore a lower bound on what the literature actually states. +-All synthetics, estimators, and figures in this paper are implemented in the +-open-source Python package codameter (version 0.4.0, MIT license), openly +-available at . A versioned archive +-with a Zenodo DOI will be issued alongside publication. ++All synthetics, estimators, and generated figures in this paper are implemented ++in the open-source Python package codameter (MIT license), openly available at ++; each generated figure's sidecar ++records its generating commit and numerical arrays. The figures and manuscript ++can originate from different revisions. \texttt{python -m codameter.figures} ++regenerates every generated figure with a \texttt{.npz} sidecar of its plotted ++arrays and a \texttt{.json} sidecar of its provenance; ++\texttt{python -m codameter.calibration} reproduces ++Table\ \ref{tab:calibration} (\texttt{paper/data/calibration/}); ++\texttt{scripts/compare\_gate1.py} reproduces Table\ \ref{tab:gate1} from the ++daily products under \texttt{paper/data/gate1/} and the published ++\citet{Clements2023} series archived there. The daily products and the three ++real-data figures were produced by the noisepy-dvv-cloud Gate 1 run from ++public Southern California Earthquake Data Center waveforms; the products are ++available locally during this analysis but are not tracked in the repository. ++The exact Gate 1 run commit, run configuration and redistribution archive ++remain to be supplied; their current provenance limits are recorded in ++\texttt{paper/data/gate1/README.md}. A versioned archive is planned but ++has not yet been deposited. +@@ -1436 +1725,8 @@ with a Zenodo DOI will be issued alongside publication. +-[To be completed.] ++[Funding, contributions and thanks to be completed by the author.] AI ++assistance: this manuscript was checked with the Denolle Group Pre-Submission ++Reviewer (v2.4, model Codex/GPT-6), an advisory AI tool, through one review ++iteration and a subsequent evidence reconciliation; final author adjudication ++remains to be recorded. The tool does not endorse manuscript validity. Code ++revisions and text edits in response to that review were drafted with Claude ++(Anthropic) and Codex (OpenAI) under the author's direction and are recorded ++in the repository history. diff --git a/review/evidence/revision2/manuscript_layout.txt b/review/evidence/revision2/manuscript_layout.txt new file mode 100644 index 0000000..45abe0a --- /dev/null +++ b/review/evidence/revision2/manuscript_layout.txt @@ -0,0 +1,3910 @@ + submitted to Geophys. J. Int. + + + + +1 The reproducibility cost of ad-hoc processing choices + +2 in ambient-noise seismic velocity-change monitoring + + + +3 M. A. Denolle + + + +4 2026-09-10 + + + +5 SUMMARY + +6 Relative seismic velocity changes (𝛿𝑣/𝑣) from repeated coda waves are a standard observ- + +7 able for volcanoes, faults, landslides, aquifers and the cryosphere. Turning cross-correlation + +8 functions into a 𝛿𝑣/𝑣 time series involves a long sequence of choices, the estimator, the + +9 frequency band, the coda window, the reference, the stacking, and how cross-components + +10 and station pairs are aggregated and weighted, made ad hoc and reported incompletely, + +11 so the same data can support different values and different error bars. We quantify the + +12 individual and combined effects of these choices on synthetic correlation functions in which + +13 the ground-truth 𝛿𝑣/𝑣 is known exactly. On these synthetics, at large 𝛿𝑣/𝑣 the estimators + +14 split by family with distinct failure modes; the same station pair yields different 𝛿𝑣/𝑣 de- + +15 pending only on whether one averages per-component 𝛿𝑣/𝑣 or the correlation-coefficient + +16 images; and the number quoted as the 1𝜎 uncertainty of a network-averaged 𝛿𝑣/𝑣 differs + √ +17 by ∼ 𝑁 between the standard error of the network mean and the between-pair standard + +18 deviation, two different quantities that studies rarely distinguish. A one-at-a-time sweep + +19 and a 108-pipeline factorial on one scenario rank the choices by the error they induce. + +20 We then propose a hierarchical Bayesian measurement model that runs an ensemble of + 2 M. A. Denolle +21 defensible pipelines on the same correlations and combines their estimates into a single + +22 𝛿𝑣/𝑣 series. A separate construction proposes a time-dependent single-member error + +23 covariance 𝐶𝑑 . On 200 independent synthetic realisations of a volcano scenario, 𝐶𝑑 covers + +24 95.6% of individual member errors at the 95% level, whereas the credible band on the + +25 ensemble mean covers the truth only 59% of the time because the configurations share + +26 time-varying biases; a seasonal source artefact seen by every configuration reduces that + +27 coverage to 34% and more than doubles the error of the ensemble mean while leaving + +28 member coverage near 95%. The nominal 68% member intervals cover 81% in the clean + +29 case; these pointwise checks do not validate the full covariance. Shared errors require + +30 diagnostics beyond agreement among processing choices. We set out how 𝐶𝑑 enters a + +31 depth inversion of shear-velocity change; that stage is described, not evaluated, here. On + +32 three California stations the same measurement code, run on NoisePy correlations in + +33 a cloud batch pipeline, reproduces a published 𝛿𝑣/𝑣 product (correlation 0.83–0.99 on + +34 360–580 matched days, with a reproducible comparison script), a comparison that also + +35 exposed and corrected a sign-convention error. The framework, estimators, figures with + +36 their numerical sidecars, and the calibration experiments are released in the open Python + +37 package codameter, together with a processing-choice advisor and a seeded golden dataset + +38 with fixed scoring support and a null-change penalty for missing predictions; an evaluation + +39 of agents against that dataset is left to future work. + + +40 Key words: Coda-wave Interferometry; Seismic noise; Coda waves; Inverse theory; + +41 Statistical methods. + + + + +42 1 INTRODUCTION + + +43 Changes in subsurface properties occur due to geodynamics, which drive earthquake damage + +44 and volcanic eruption, and hydrodynamics, which controls fluid exchange between the + Processing choices in seismic velocity monitoring 3 +45 atmosphere and the solid Earth. These processes influence the mechanical properties of Earth + +46 materials, which directly affect the speed at which seismic waves propagate. Changes in + +47 seismic velocity, often measured and referred to as 𝛿𝑣/𝑣, can be tracked by measuring changes + +48 in arrival times of seismic waves, especially scattered waves such as coda waves, provided + +49 that the source and receivers are at the same location. + + +50 Due to the sensitivity of coda waves to small perturbations in the material properties, 𝛿𝑣/𝑣 has + +51 become an effective way to monitor volcanic unrest, from the first passive monitoring at + +52 Merapi (Sens-Schönfelder & Wegler, 2006) to the pre-eruptive velocity drops at Piton de + +53 la Fournaise (Brenguier et al., 2008b), where it is now computed continuously alongside + +54 conventional observatory monitoring (Duputel et al., 2009); the Icelandic Meteorological + +55 Office included 𝛿𝑣/𝑣 among the parameters it followed during the 2020 Reykjanes unrest + +56 (Cubuk-Sabuncu et al., 2021). The same signal is used to monitor the internal state of + +57 tailings dams and mines and to flag instability before failure (Olivier et al., 2017; Ouellet + +58 et al., 2022). A broader set of operations is emerging around the same signal: groundwater + +59 storage for water management (Clements & Denolle, 2018; Mao et al., 2022), landslide early + +60 warning (Le Breton et al., 2021), levee and embankment integrity (Planès et al., 2016), and + +61 geothermal and CO2 reservoir surveillance (Tsuji et al., 2021). Each of these deployments + +62 rests on the same fragile assumption: that the 𝛿𝑣/𝑣 curve an operator acts on is a property + +63 of the subsurface, not of the analyst’s processing choices. + + +64 𝛿𝑣/𝑣 is the fractional seismic velocity change, positive for a velocity increase. The stretching + +65 family of estimators measures the stretch factor 𝜀 that maps the current coda onto the + +66 reference coda. Throughout this work, the reference correlation is held fixed and trial dilations + 4 M. A. Denolle +67 are applied to the current correlation, + + + 𝑐𝜖 (𝑡) = 𝑐[(1 + 𝜖)𝑡], + + +68 where interpolation is performed only on (c). Thus (𝜖 = 𝑡𝑐𝑢𝑟 /𝑡𝑟𝑒𝑓 − 1) is a fractional travel- + +69 time dilation: 𝜖 > 0 denotes a delayed phase in the current coda (slower) and 𝜖 < 0 denotes + +70 an earlier arrival time (faster). For unchanged propagation geometry, + + 𝑡𝑐𝑢𝑟 𝑣𝑟𝑒𝑓 + 1+𝜖= = , + 𝑡𝑟𝑒𝑓 𝑣𝑐𝑢𝑟 + +71 and therefore the physical fractional velocity change reported throughout this work is + + 𝛿𝑣 𝑣𝑐𝑢𝑟 − 𝑣𝑟𝑒𝑓 𝜖 + ≡ =− . + 𝑣 𝑣𝑟𝑒𝑓 1+𝜖 + +72 The commonly used relation (𝛿𝑣/𝑣 ≃ −𝜖 ≃ −𝛿𝑡/𝑡) is its first-order approximation and + +73 used in the majority of published work. We retain the exact finite-change transformation + +74 because its computational cost is negligible and because the distinction becomes measurable + +75 for velocity perturbations of several percent measured in large strain phenomena such as + +76 landslides. The current coda is stretched rather than the reference correlation so that the + +77 high-SNR reference stack remains unchanged throughout the search. While the reciprocal + +78 formulations are mathematically equivalent; in sampled, finite-window data they can differ + +79 because interpolation and boundary truncation break that symmetry. + + +80 The elevated sensitivity comes at the price of a long series of processing choices, and + +81 at almost every step the analyst makes a choice. Among these are choices of estimators + +82 between windowed phase measurements or stretching (Mikesell et al., 2015, Mao et al. (2020), + +83 Yuan et al. (2021)), frequency band and coda window (which together set the sampled + +84 depth; Obermann et al. (2013; Obermann et al., 2016)), reference window (Brenguier et al., + Processing choices in seismic velocity monitoring 5 +85 2014, Ermert et al. (2023), Okubo et al. (2024)), increasing the temporal resolution of the + +86 measurement through substacking-filtering-denoising (Hadziioannou et al., 2011, Moreau + +87 et al. (2017),Mao et al. (2019),Viens & Van Houtte (2020)), and how to aggregate and weight + +88 the many cross-component and station-pair measurements that make up a single reported + +89 𝛿𝑣/𝑣 time series (e.g., Hobiger et al. (2012)). These choices are made by habit, justified + +90 briefly if at all, and rarely reported in enough detail to reproduce. The community has long + +91 flagged individual pitfalls (spurious changes from non-stationary noise, Zhan et al. (2013); + +92 measurement-error formulae, Clarke et al. (2011; Weaver et al., 2011)) and has compared + +93 estimators against one another on simulated data (Yuan et al., 2021). What has not been done, + +94 to our knowledge, is to quantify on one truth-known dataset the joint effect of the full choice + +95 set on both the value and its stated uncertainty, and to carry that spread into a measurement + +96 covariance. One indication of the stakes is the compilation of Denolle et al. (2025), in which + +97 most studies find 𝛿𝑣/𝑣 anticorrelated with groundwater level, but with a scatter across + +98 studies that differences in frequency band, single-station versus inter-station correlations and + +99 other processing choices can explain in part, alongside genuine hydrogeological differences + +100 between sites; that scatter limits how far the compiled relation can be used quantitatively in + +101 hydrological work. + + +102 This is a reproducibility problem of exactly the “garden of forking paths” type identified + +103 in the statistical sciences (Gelman & Loken, 2013; Steegen et al., 2016): many individually + +104 reasonable analyses of the same data give different answers, and without full reporting of + +105 parameter choices we cannot interpret a reported 𝛿𝑣/𝑣 as a robust value. Here we make the + +106 problem concrete for 𝛿𝑣/𝑣 monitoring. We use purely synthetic correlation time series to + +107 test the methods (estimators) and parameter choices that the community makes to estimate + +108 𝛿𝑣/𝑣 which we report over 103 studies in Appendix C. We do not aim to report the “best” + 6 M. A. Denolle +109 pipeline, which is most often the one reported in scientific papers, but instead document the + +110 parameter impacts (Section 3). We then propose a new measurement error that incorporates + +111 these effects into a data covariance matrix 𝐶𝑑 (Section 5). Throughout this paper, key + +112 notation includes: 𝜎 (measurement uncertainty of a recovered 𝛿𝑣/𝑣 estimate), 𝐵 (frequency + +113 bandwidth), and 𝑊 = [𝑡1 , 𝑡2 ] (coda window); subscripts distinguish specific contexts (e.g., + +114 𝜎𝑘 for per-component uncertainty), each defined where first introduced. + + +115 One example of propagating such error into downstream science is the migration of the surface + +116 𝛿𝑣/𝑣 measurement to depth profiles of perturbations in shear wave velocity Δ𝑉𝑆 (𝑧)/𝑉𝑆 (𝑧), + +117 which depends on the wavefield constituting the coda waves, surface or body waves, and + +118 on the source-receiver geometry. We set out how the measurement covariance enters such a + +119 depth inversion (Section 6); the executable depth stage is described there, not evaluated. We + +120 use synthetic examples for ground truthing of the signal-processing parameters, since the + +121 physics of phase lags in scattered waves is well established (Obermann et al., 2013). + + +122 We then compare single-station 𝛿𝑣/𝑣 from the same measurement code, run on NoisePy + +123 correlations for three California stations, with a published product (Section 7). We package + +124 the methodology in a Python software, codameter, which also ships an advisor skill: an AI + +125 agent can be asked to recommend a processing configuration or recover a 𝛿𝑣/𝑣(t) series, and + +126 its answer can be scored against seeded synthetic golden cases with known ground truth, + +127 including a hidden-truth variant that withholds the answer from the public package. The + +128 scorer and dataset are part of the release; an evaluation of agents against them is not part of + +129 this paper. + Processing choices in seismic velocity monitoring 7 +130 2 SYNTHETIC FRAMEWORK + + +131 We build each synthetic reference coda wave as a band-limited random-phase wavefield + +132 modulated by a physically grounded coda envelope. We model the envelope from the exact + +133 single-scattering solution of the two-dimensional radiative transfer equation for isotropic + +134 scattering (Sato, 1993; Paasschens, 1997), which underlies coda-envelope modelling of scatter- + +135 ing and intrinsic attenuation (Margerin et al., 1998). The energy density at source–receiver + +136 distance 𝑟 and lapse time 𝑡 is + + + + 1 + √ + 2 2 2 + 𝑒−𝑐𝑡/ℓ 𝑟 𝑒 ℓ ( 𝑐 𝑡 −𝑟 −𝑐𝑡) 𝑟 +137 𝐸(𝑟, 𝑡) = [ 𝛿(𝑡 − ) + √ 𝐻(𝑡 − )] 𝑒−𝑏𝑡 , (1) + 2𝜋𝑐𝑟 𝑐 2𝜋ℓ 𝑐2 𝑡2 − 𝑟2 𝑐 + + +138 where 𝑐 is the (Rayleigh-wave) velocity, ℓ the scattering mean free path, 𝑏 the intrinsic + +139 absorption rate, and 𝛿 and 𝐻 the Dirac and Heaviside functions. The first term is the + +140 coherent ballistic arrival at 𝑡 = 𝑟/𝑐; the second is the multiply-scattered diffuse coda, + +141 which switches on at that arrival, builds up under scattering, and decays under intrinsic + +142 absorption. We fill random phases under the amplitude envelope √𝐸(𝑟, 𝑡), band-limit, and + +143 symmetrize the causal and acausal branches as for an evenly illuminated noise correlation. + +144 The modeled synthetic coda depends only on three time constants: the ballistic onset 𝑟/𝑐, + +145 the scattering mean free time ℓ/𝑐, and the absorption time 1/𝑏. The late-coda amplitude + +146 decays as 𝑒−𝑏𝑡/2 , recovering an apparent coda 𝑄𝑐 while the envelope shape is determined + +147 by scattering physics. A frequency-dependent absorption 𝑏(𝑓) = 2𝜋𝑓/𝑄𝑐 , which can still be + +148 modeled as an frequency-independent attenuation factor 𝑄𝑐 , reproduces the observation that + +149 high frequencies are retained only at short lag times, so a fixed late window samples different + +150 depths at different bands. + 8 M. A. Denolle +151 A homogeneous velocity change is imposed exactly by stretching the lapse-time axis, 𝑢𝑐𝑢𝑟 (𝑡) = + +152 𝑢𝑟𝑒𝑓 (𝑡 (1 + 𝛿𝑣/𝑣)), and a repeated time series is produced by generating this stretched coda + +153 with a prescribed ground-truth 𝛿𝑣/𝑣(𝑡) and additive band-limited noise at a controlled + +154 signal-to-noise ratio. The concept has been demonstrated using full waveform modeling in + +155 several previous studies (Obermann et al., 2013, 2016; Yuan et al., 2021), so we do not repeat + +156 that full-waveform modeling here. Because the imposed 𝛿𝑣/𝑣(𝑡) is known, every departure of + +157 a recovered series from it is an artefact of the processing, not of the data. + + +158 We use seven 𝛿𝑣/𝑣 estimators that were implemented in noisepy (Jiang & Denolle, 2020): + +159 trace stretching (TS, Lobkis & Weaver (2003)), windowed cross-correlation (WCC, Poupinet + +160 et al. (1984)), dynamic time warping (DTW, Mikesell et al. (2015)), the moving-window + +161 cross-spectrum (MWCS; Clarke et al. (2011)), and three wavelet-domain methods, the wavelet + +162 cross-spectrum (WCS, Mao et al. (2020)) and the two wavelet stretching (WTS) and wavelet + +163 DTW (WTDTW) introduced and benchmarked numerically by Yuan et al. (2021). The + +164 framework, the figures below, and an implementation are released in the open codameter + +165 package (Section 8). Formal definitions of all seven methods, of the two aggregation pathways, + +166 and of the uncertainty conventions are described in Appendices A and B. + + +167 Each of these methods require specific parameter choices, which we categorize and reference + +168 in Table 1. The work presented below measure the impacts of each of these parameter choices + +169 on the resulting 𝛿𝑣/𝑣. + + +170 Several quantities in this paper are reported with the same symbol 𝜎 but estimate different + +171 things. Table 2 fixes, for each, what it is an estimate of, its units, and the datum and epochs + +172 it is evaluated on; figure captions refer to it. + Processing choices in seismic velocity monitoring 9 + +Table 1. Processing choices (“hyper-parameters”) and their effect on the recovered value and +the reported uncertainty. Key notation: 𝐵 (frequency bandwidth), 𝑊 = [𝑡1 , 𝑡2 ] (coda window), 𝑁 +(measurement count), 𝑁eff (weighted effective count), 𝜎 (measurement uncertainty). + +Choice Options / typical range Effect on the value Effect on the uncertainty + +Estimator TS, WCC, DTW, MWCS, WCS, Agree at small 𝛿𝑣/𝑣; at large Each has its own error model; + WTS, WTDTW 𝛿𝑣/𝑣 phase methods cycle-skip, inter-method spread is an + warps under-shoot (Fig. 1) uncertainty +Phase unwrapping on / off (phase methods) Decides whether MWCS/WCS Sets the usable 𝛿𝑣/𝑣 range + cycle-skip (Fig. 1b) +𝐵 0.1–2 Hz (volcano), 2–4 Hz Selects the sampled depth, hence 𝜎 decreases with increasing 𝐵 + (aquifer), 4–12 Hz (landslide) which signal (Fig. 8a) +𝑊 a few to tens of mean free times Later lapse → deeper, larger 𝜎 ∝ (𝑡3 3 −1/2 (duration + 2 − 𝑡1 ) + sensitivity effect), but late coda is low-SNR +𝑊-𝐵 coupling fixed vs scaled with 𝑓 A fixed late window at high 𝑓 inceases 𝜎 due to decorrelation + measures noise (Fig. 8b) at high 𝑓 +Reference total stack / trailing / joint Trailing reference gives Reference noise propagates; + inversion increments: the trend is absent inversion lowers it + unless they are cumulated, which + then drifts; joint inversion + preserves it directly (Fig. 8c) +Stacking / 1–30+ days Smears and delays transients 𝜎 and resolution decreases with +substack (Fig. 8d) stacking length +Component A (average 𝛿𝑣/𝑣) vs B (average Different time series (Fig. 2) Different uncertainty object +aggregation CC images); weighted vs not (ensemble spread vs CC-peak + width) +Pair / network coherence-weighted vs Small change in value Changes 𝑁eff +weighting unweighted + √ +Uncertainty within-measurement (Weaver) / — Factor 𝑁 or more (Fig. 3) +definition SE / SD +Quality control min CC, min SNR, max 𝛿𝑡 error Rejects or keeps measurements Sets the effective 𝑁 and any + selection bias +Pre-processing one-bit / running-mean; Bias if the noise field is Spurious 𝛿𝑣/𝑣 when the noise + whitening band non-stationary spectrum drifts (Zhan et al., + 2013) +Clock / timing causal vs acausal branch A clock error fabricates 𝛿𝑣/𝑣 Branch asymmetry diagnoses it + handling (Fig. 11a) + + + +Table 2. Reported quantities, what each estimates, and how it is evaluated. All 𝛿𝑣/𝑣 quantities +are fractions of velocity; figures show percent. + +Quantity Estimate of Datum and support + +Recovery RMS Root mean square of (recovered − imposed) Raw recovered series, no baseline alignment; +(Sections 3–4) 𝛿𝑣/𝑣 for one configuration on one waveform epochs the pipeline produced; fixed reference + realisation from the first 60% of the record +Within-measurement Standard error of one dilation estimate from Per epoch and configuration; depends on +𝜎𝑘 (𝑡) finite coda coherence, eq. A.2 coherence, band, window; a lower bound + (Section 5) +Between-pair SD, 𝜎SD Dispersion of the 𝑁 pair estimates at one epoch Finite network; no datum change + (physical heterogeneity plus pair noise) +Network SE, 𝜎SE , Precision of the network mean under Same epochs; the target is the finite-network +𝜎SE,𝑤 independent pairs; shared stations or noise make mean + it optimistic +Posterior credible band Precision of the ensemble-combined estimate Decimated epochs; under-covers when +on 𝜇(𝑡) under the model of Section 5 configurations share a bias +𝐶𝑑 Proposed error covariance of one ensemble Same epochs; 95% pointwise member coverage + member: fitted floor, excess spread, temporal supported, 68% overcoverage; temporal + correlation, offset scale 𝜏 covariance unvalidated (Table 5) +Field comparison 𝑟, Agreement with a published product after Calendar-day join, 150-day burn-in, trailing +slope matched smoothing 90-day mean (Section 7) + 10 M. A. Denolle +173 3 PARAMETER-DEPENDENT 𝛿𝑣/𝑣 AND ITS ERRORS + + +174 The literature agrees on the components of a well-posed 𝛿𝑣/𝑣 measurement: an estimator + +175 matched to the expected size of the change (the stretching family remains accurate at large + +176 𝛿𝑣/𝑣, Section 3.1; its noise robustness relative to the warping methods depends on the + +177 setting, and Yuan et al. (2021) rank it below DTW in that respect on their heterogeneous + +178 full-wave simulations), a coherence-based error model (Clarke et al., 2011; Weaver et al., + +179 2011), a long stable reference (Wang et al., 2017), and cross-validation against a second + +180 estimator (Obermann & Hillers, 2019). Yet studies do not always report the same set, and + +181 the uncertainty convention is rarely, if ever, quantified (Appendix C). The sections below + +182 address each component in turn and quantify, against a known truth, how far a parameter + +183 choice impacts the recovered 𝛿𝑣/𝑣 and its error. + + +184 Table 3 previews the RMS error against the known synthetic ground truth for the best- and + +185 worst-case option on each axis covered in this section, each derived in its own dedicated + +186 synthetic exercise (detailed in the corresponding subsection below); it is a synthesis of this + +187 section’s per-choice numbers, distinct from Table 4’s one-at-a-time sweep on a single shared + +188 scenario in Section 4. Every RMS in this section is computed on the raw recovered series + +189 against the imposed truth over the epochs the pipeline produced, with no baseline alignment, + +190 so a reference offset counts as error (Section 3.5 shows that explicitly); the network-level + +191 uncertainty conventions of Section 3.3 are reported quantities, not recovery errors, and are + +192 listed in Table 2 rather than here. + + + +193 3.1 Estimator family + + +194 We implement all methods as in previous work (Jiang & Denolle, 2020). + Processing choices in seismic velocity monitoring 11 + + Table 3. Synthesis of Section 3: RMS error against the known synthetic truth for the best- and worst- + case option on each axis, each from its own dedicated synthetic scenario (see the cross-referenced + subsection). + + Axis Best-case RMS Worst-case RMS Section + + Estimator (family split) < 0.01 % (TS, up to 5 % true cycle-skip > 0.5 % past Section 3.1 + 𝛿𝑣/𝑣) ∼ 1.5 % true 𝛿𝑣/𝑣 (MWCS) + Cross-component ∼ 0.03 % (Approach B, ∼ 0.31 % (Approach A, Section 3.2 + aggregation averaged images) unweighted) + Frequency band ∼ 0.028–0.031 % (within ∼ 0.10 % (center off by Section 3.4 + ±0.3 Hz of the true band) > 0.5 Hz) + Coda window ∼ 0.01 % (adapted to band) ∼ 3.9 % (fixed, wrong band) Section 3.7 + Reference scheme ∼ 0.03 % (whole record, ∼ 0.15–0.16 % (end-of-record Section 3.5 + earliest period, or joint fixed, or moving) + inversion) + Stack length ∼ 0.020 % (7–10-day, workable ∼ 0.044 % (1-day, same Section 3.6 + deployment) deployment) + + +195 As of codameter v0.4.0, all seven estimators return physical 𝛿𝑣/𝑣 under the sign convention + +196 above rather than the raw stretch factor 𝜀; the synthetic generator imposes changes in the + +197 same convention, so a positive imposed 𝛿𝑣/𝑣 recovers as positive. A dedicated regression + +198 test holds every estimator to this convention in both signs, end to end through the full + +199 measurement pipeline, so the convention cannot silently drift back. + + +200 On small, clean 𝛿𝑣/𝑣 all seven estimators agree to within 0.04,% RMS (Fig. 1a). Sweeping + +201 the same clean recovery out to ±5 % (Fig. 1b) shows exactly where and how each family first + +202 departs from the 1:1 line, and the estimator choice becomes consequential at large, noisy + +203 𝛿𝑣/𝑣 (Fig. 1c), where the effect of the methods is split according to their phase measurement + +204 approaches. The stretching family (TS, WTS) and WCC match the whole dilated coda + +205 and stay within 0.05,% RMS of the truth on the noisy landslide signal (0.005, 0.010 and + +206 0.046,%); the warping methods (DTW, WTDTW) track but under-shoot the largest strains + +207 (0.16 and 0.08,% RMS); both phase methods fail on this noisy, large-strain signal, MWCS + +208 by cycle-skipping (2.9,% RMS) and WCS, whose 2-D unwrapping recovers the clean sweep + +209 of panel (b), by losing the phase track once noise is added (3.8,% RMS; the numbers are + 12 M. A. Denolle +210 computed from the figure’s numerical sidecar). No estimator is simply “right”; the choice of + +211 estimator materially changes the 𝛿𝑣/𝑣 measurement at larger strain. + + + + + Figure 1. Estimator choice across the seven NoisePy methods. (a) Clean, small 𝛿𝑣/𝑣: all agree. + (b) The same clean recovery swept over ±5 % true 𝛿𝑣/𝑣: MWCS cycle-skips past ∼ 1.5 % on either + branch; TS and WTS track the 1:1 line throughout; WCC tracks just as tightly on the negative + branch but breaks sharply near the positive edge; DTW and WTDTW break asymmetrically, + WTDTW near +1 % but only near −3 % on the other branch; WCS degrades smoothly, crossing 1 % + error beyond ±4 %. (c) Large, noisy 𝛿𝑣/𝑣 (a pre-failure landslide signal): the stretching family and + WCC track, the warping methods under-shoot, and both phase methods fail (MWCS cycle-skips; + WCS loses the phase track in noise despite the 2-D unwrapping that carries it through the clean + sweep in b). RMS errors are given in the text; the plotted arrays are in the figure’s sidecar (Table 2). + + + +212 On a clean, noiseless sweep of true 𝛿𝑣/𝑣 from −5 to 5 % (Fig. 1b), the phase-wrapped MWCS + +213 estimator is the first to break on either branch: its error stays below 0.1 % out to ∼ 1.3 % + +214 true 𝛿𝑣/𝑣, then exceeds 1 % error by ∼ 1.5 % — the cycle-skip, essentially symmetric in + +215 sign. The stretching family (TS, WTS) stays below 0.1 % error out to the full 5 % tested, + +216 on both branches. WCC is just as accurate on the negative branch (error stays below 0.1 % + +217 throughout) but breaks sharply on the positive branch, crossing both 0.1 % and 1 % error + +218 abruptly at the edge of the tested range (∼ 4.75 %) — a sign asymmetry from the physical + +219 convention itself (Section 1), not a processing artefact. The warping methods develop large + +220 (> 1 %) errors asymmetrically as the warp path becomes ill-conditioned: WTDTW crosses + +221 1 % error already at ∼ 1 % true 𝛿𝑣/𝑣 on the positive branch but only at ∼ 3 % on the negative + Processing choices in seismic velocity monitoring 13 +222 branch, and DTW crosses at ∼ 2.5 % versus ∼ 3 %. WCS degrades smoothly rather than + +223 catastrophically, crossing 1 % error beyond ±4 % true 𝛿𝑣/𝑣 on either branch. + + + +224 3.2 Aggregating cross-component results + + +225 Each three-component seismic station (e.g., Z, N, E) carries 6 cross-component correlations + +226 (ZZ, NN, EE, ZE, ZN, NE), whether they are calculated at a single station or an inter-station + +227 pair. Each carries a signature of the changes in velocity; components may be dominated by + +228 Love or Rayleigh waves (Lin et al., 2008; Stehly et al., 2006), but scattering and non-straight + +229 ray paths induce cross-component leakage between modes (Hennino et al., 2001; Margerin + +230 et al., 2019), and thus it is often assumed in practice that coda waves of cross-components with + +231 multi-scattering characteristics (e.g., no clearly separated phases) are composed of “surface + +232 waves” with strong S-wave sensitivity. Combining them together requires parameter choices, + +233 such as averaging them directly (Liu et al., 2014), or weighted (e.g., using coherence-based + +234 weighting Hobiger et al. (2012), De Plaen et al. (2016)). + + +235 Combining is another workflow choice that can change both the value and the uncertainty + +236 (Fig. 2). One may peak-pick each component’s correlation-coefficient curve CC(𝜀, 𝑡) and then + +237 average the per-component 𝛿𝑣/𝑣 (Approach A) — unweighted, a few poor components bias + +238 the mean; coherence-weighted, they are suppressed — or one may average the CC(𝜀, 𝑡) images + +239 across components first and peak-pick once (Approach B). All three conventions appear in + +240 the literature; on the same pair they give visibly different time series, and they propagate + +241 uncertainty along incompatible pathways (the ensemble spread of the per-component picks for + +242 A, the width of the averaged correlation peak for B). On our six-component synthetic (three + +243 good, three poor SNR), the RMS error against the known truth is ∼ 0.31 % for unweighted + 14 M. A. Denolle +244 Approach A, ∼ 0.08 % for coherence-weighted Approach A (the poor components suppressed, + +245 ∼ 4× better), and ∼ 0.03 % for Approach B (averaging the images before peak-picking, ∼ 11× + +246 better than the unweighted mean and ∼ 3× better than the weighted one). + + + + + Figure 2. Cross-component aggregation for one station pair, both panels on the same 𝛿𝑣/𝑣 axis. + (a) Unweighted 𝛿𝑣/𝑣-averaging (Approach A) is biased by the poor components (grey), while + coherence-weighting and image-averaging (Approach B) track the truth; the shaded band is B’s + local peak-width uncertainty. (b) The averaged CC(𝛿𝑣/𝑣, 𝑡) image of Approach B (dark = high + coherence) with its peak ridge (white) tracking the truth (black, dashed). + + + + +247 3.3 Aggregating across station pairs + + +248 Adding the next layer up — combining many station pairs into a unified network series + +249 — exposes the most consequential and least-reported choice of all: how to summarize the + +250 uncertainty. Three conventions are common: a coherence-weighted standard error (e.g., Clarke + √ +251 et al. (2011)), an unweighted standard error (𝜎 = std/ 𝑁; e.g., Brenguier et al. (2008b)), and + +252 the between-pair standard deviation (e.g., Clements & Denolle (2018)). These are estimates + +253 of different quantities (Table 2): the standard error is the precision of the network mean + +254 under independent pairs, the standard deviation is the dispersion of the pairs, which on + +255 this synthetic mixes the 15,% pair-to-pair amplitude heterogeneity we impose with the pair + Processing choices in seismic velocity monitoring 15 + √ +256 noise, and the two are related by 𝑁 by construction. On the same synthetic network the + √ +257 recovered means nearly coincide, but the number reported as 1𝜎 spans a factor of ∼ 𝑁 + +258 (Fig. 3). A velocity change that is three times the coherence-weighted standard error is + +259 about one between-pair standard deviation, from identical data; neither statement is wrong, + +260 but a study that reports only “1𝜎” leaves the reader unable to tell which is meant. Error + +261 bars on published 𝛿𝑣/𝑣 are therefore not comparable across studies unless the aggregation, + +262 the weighting, and the standard-error-versus-standard-deviation convention are all stated. + +263 Neither convention is the precision of the mean when pairs share stations or noise; that + +264 requires the pair covariance, a⊤ Σa for normalised weights a, which the Bayesian ensemble of + +265 Section 5 supplies for the configuration axis and which a network extension would supply for + +266 the pair axis. + + + + + Figure 3. Station-pair aggregation and uncertainty for a nine-pair network. (a) The recovered + √ 𝛿𝑣/𝑣 + agrees across conventions; the shaded 1𝜎 bands do not. (b) The reported 1𝜎 differs by ∼ 𝑁 purely + from the weighting and SE-versus-SD choices. + + + +267 Figure 3 plots only the network-aggregate series, which hides how much the individual + +268 pairs actually disagree. Fig. 4 plots the same nine-pair network’s individual 𝛿𝑣/𝑣(t) curves, + +269 styled after a basin-scale, urban ambient-noise deployment such as the San Gabriel Valley + 16 M. A. Denolle +270 groundwater network (Clements & Denolle, 2018) — an illustrative geometry rather than + +271 a literal reproduction of that network’s exact station spacing. The individual pairs range + +272 in quality from a coherence-weighted SNR of ∼ 2.5 to ∼ 11, and their spread at any given + +273 day (median range ∼ 0.053 %) is nearly 10× wider than the coherence-weighted network + +274 standard error (median ∼ 0.005 %) and more than 3× wider than the more conservative + +275 between-pair standard deviation (median ∼ 0.017 %). A network-level error bar, however + +276 it is computed, describes the precision of the mean, not the dispersion of what individual + +277 pairs actually report — the two are routinely conflated when a single station-pair result is + +278 compared against a published network value. + + + + + Figure 4. Individual station-pair 𝛿𝑣/𝑣(t) for the same nine-pair network as Fig. 3, coloured by + pair SNR. The pair-to-pair spread (grey band) is far wider than any of the three network-level 1𝜎 + conventions in Fig. 3b. + + + + +279 3.4 Frequency band + + +280 The remaining choices are no less consequential. The frequency band sets the sampled + +281 depth: in a two-layer medium, high frequencies recover shallow, often seasonal signals and + Processing choices in seismic velocity monitoring 17 +282 low frequencies recover a deeper, maybe more tectonic, signal (Fig. 8a). In practice a band + +283 often gets reused from a neighboring deployment or an earlier study at the same site without + +284 re-checking that it still matches the target depth — exactly the error this section quantifies. + + +285 On our synthetic two-layer groundwater scenario, holding the recovery band’s width fixed + +286 (0.6 Hz) and sweeping its center away from the deep layer’s true 0.2–0.8 Hz band shows the + +287 cost is not gradual: RMS error against the known truth stays flat, ∼ 0.028–0.031 %, for a + +288 center offset within ∼ 0.3 Hz of the true center, then rises by a factor of ∼ 3–4 once the offset + +289 passes ∼ 0.5 Hz — the point at which the assumed band starts sampling the shallow layer’s + +290 signal instead of the deep one — and plateaus near ∼ 0.10 % beyond that (Fig. 5). The band + +291 choice is forgiving up to the edge of the layer it targets, and expensive immediately past it, + +292 not gradually worse the further off it drifts. + + + + + Figure 5. Frequency-band sensitivity: RMS error against the known groundwater deep-layer truth + as the recovery band’s center is swept away from the true 0.2–0.8 Hz band, holding its 0.6 Hz width + fixed. Error is flat within ∼ ±0.3 Hz of the true center, then rises sharply once the assumed band + drifts into the shallow layer’s territory. + + + +293 Scale of effect: a band-center error under ∼ 0.3 Hz costs essentially nothing here; past + +294 ∼ 0.5 Hz it costs a factor of ∼ 3–4 in RMS, from ∼ 0.03 % to ∼ 0.10 %. + 18 M. A. Denolle +295 3.5 Reference + + +296 The reference defines what survives: a moving reference re-baselines continuously and erases + +297 slow trends that a fixed reference or a joint inversion (Brenguier et al., 2014) preserve (Fig. 8c). + +298 In practice the choice is rarely just fixed-versus-moving: an analyst also decides which period + +299 of the record a fixed reference is built from, and that choice alone can dominate the error — + +300 for instance when a deployment barely predates the process of interest, or when the only + +301 quiet-looking period available sits close in time to the process itself. + + +302 We compare five named schemes on the volcano synthetic: a reference built from the begin- + +303 ning of the pre-eruptive record (its earliest 15%), from the end of that record (its latest 15%, + +304 immediately before the eruption), from the whole pre-eruptive record, a 60-day moving + +305 (trailing) reference, and no single reference at all — the Brenguier et al. (2014)-style joint + +306 inversion, which measures relative dv/v between many short stacks instead of referencing + +307 every day to one (Fig. 6a). The whole-record, beginning, and inversion schemes all recover + +308 the truth to RMS ∼ 0.03 %. The end-of-record reference does far worse, RMS ∼ 0.15 % — + +309 not because it tracks the dynamics any less faithfully (its residual scatter around the truth, + +310 ∼ 0.029 %, matches every other fixed scheme) but because the reference epoch itself already + +311 sits ∼ 0.15 % into the developing pre-eruptive ramp, and every dv/v value is reported relative + +312 to whatever the reference was doing. Reference choice sets the zero point, not just the noise + +313 floor: comparing dv/v across studies, or across deployments that started at different times, + +314 requires knowing what the reference period itself was doing, not just how well each pipeline + +315 scores against a single truth. + + +316 The 60-day moving reference gives RMS ∼ 0.16 % — comparable to the worst fixed case, but + +317 for the opposite reason: it re-baselines away the trend continuously rather than sitting at one + Processing choices in seismic velocity monitoring 19 +318 biased epoch. Lengthening the trailing window helps only slowly and never converges to the + +319 fixed-reference baseline: RMS falls from ∼ 0.168 % at a 10-day trailing window to ∼ 0.151 % + +320 at 240 days, still ∼ 4–5× the whole-record RMS (Fig. 6b) — the erasure is structural, not a + +321 noise effect that more averaging fixes. + + +322 Read carefully, though, that erasure is a property of the uncumulated increment, not of a + +323 non-fixed reference as such — and the published alternatives to a fixed reference do not take + +324 the form the sweep assumes. They fall into two families, neither of which re-baselines every + +325 epoch and reports the raw increment. + + +326 The first cumulates. James et al. (2017) re-baseline each day against the immediately + +327 preceding day-stack and sum the daily 𝛿𝑡/𝑡 from a fixed start date, recovering a seasonal + +328 freeze–thaw trend in Alaskan permafrost that a stationary reference could not detect at + +329 all: the frozen-to-thawed velocity contrast made the stationary comparison cycle-skip, while + +330 adjacent days stayed coherent. Rivet et al. (2011) likewise reference each epoch to the previous + +331 one. The cost is that summation integrates the measurement error — James et al. (2017) + +332 report a positive drift in the cumulated series that their quadrature error budget could not + +333 account for, and correct it linearly against a stationary-reference anchor. The same rolling + +334 construction appears in laboratory coda monitoring of rock deforming to failure, where the + +335 scattering properties change too much for a fixed reference to stay valid (Zotz-Wilson et al., + +336 2019). + + +337 The second holds the reference fixed within a segment and stitches the segments together. + +338 Rivet et al. (2014) define a separate reference stack for each of three multi-year periods at + +339 Piton de la Fournaise, then merge the three series by measuring the relative velocity change + +340 between the adjacent segment references, using station pairs that occupied the same sites + 20 M. A. Denolle +341 across the network change. Sens-Schönfelder et al. (2014) develop the multiple-reference form + +342 of the same idea at the same volcano, and Ermert et al. (2023) adopt a multiple-reference + +343 approach for urban single-station autocorrelations in Mexico City, where long-term waveform + +344 coherence is simply unavailable, stabilising the stacks by clustering correlation windows with + +345 a Gaussian mixture model so that day-time and night-time noise regimes stack separately. + + +346 That second family is worth naming precisely, because it is not a separate method from the + +347 joint inversion — it is a restriction of it. Stitching two segments by measuring the relative + +348 dv/v between their references is exactly the adjacent-pair case of the over-determined system + +349 the inversion solves over all pairs of block stacks. The reference axis is therefore better read + +350 as a single continuum, from one global reference, through segment references joined pairwise, + +351 to the fully coupled inversion, than as a menu of unrelated choices. + + +352 Against that, the uncumulated day-by-day trailing reference swept above is a limit case rather + +353 than a practice: we found no surveyed study that re-baselines continuously and reports the + +354 increments without summing them. It is retained here because it isolates what re-baselining + +355 costs when the trend is not reconstructed, which is the failure mode the two families above + +356 exist to avoid. codameter implements the joint inversion but neither the cumulated trailing + +357 reference nor cluster-based reference selection. + + +358 Scale of effect: which period a fixed reference is drawn from can cost as much as switching + +359 to a moving reference altogether (∼ 0.15–0.16 % RMS either way); a reference from the + +360 quietest available period, of any length, recovers the trend to ∼ 0.03 %. + Processing choices in seismic velocity monitoring 21 + + + + + Figure 6. Reference construction on the volcano synthetic. (a) Five named schemes, each scored + by RMS against the known truth over the whole record and over the pre-eruptive ramp alone. (b) + RMS for the moving reference as a function of its trailing length; the dashed line is the whole-record + fixed reference’s RMS, which the moving reference never reaches. + +361 3.6 Substacking + + +362 The stacking length trades noise against temporal resolution, rounding off and delaying a + +363 coseismic step (Fig. 8d). In practice the decision is rarely “how many days” in the abstract; + +364 it is “how long until the coda is coherent enough to trust” — stacking only as long as needed + +365 to clear a working correlation-coefficient (CC) threshold, then stopping. codameter’s own + +366 quality-control gate uses CC~> 0.6 (Section 3), and how quickly a station clears that bar + +367 depends entirely on its data quality. + + +368 Substack duration therefore defines a fundamental precision–temporal-resolution tradeoff. + +369 Longer stacks suppress incoherent noise fluctuations and accelerate the convergence of + +370 noise correlation functions, whereas shorter substacks preserve transient changes that would + +371 otherwise be averaged within the stacking window. The reduced signal-to-noise ratio of shorter + +372 correlations can be partially compensated through adaptive filtering, SVD-based or learned + +373 denoising, or through redundancy across dense seismic arrays, enabling 𝛿𝑣/𝑣 measurements + 22 M. A. Denolle +374 at daily, hourly, and even sub-hourly resolution (Hadziioannou et al., 2011, Moreau et al. + +375 (2017),Mao et al. (2019),Viens & Van Houtte (2020)). + + +376 In this paper, the choice of substack length is guided by data-dependent quality gates (the + +377 CC threshold above) rather than a fixed duration, which allows stations with high coherence + +378 to preserve shorter temporal windows and thereby track rapid changes, while stations with + +379 lower SNR substack as needed to achieve stable estimates. + + +380 On the earthquake synthetic, a workable deployment (SNR 4, the same setting used through- + +381 out this section) clears CC~> 0.6 already at a 1-day stack (median CC 0.86); a poor, + +382 coherence-limited deployment (SNR 0.5) needs 14 days of substacking to clear the same + +383 bar (Fig. 7a). The two regimes behave differently past that point, too. For the workable + +384 deployment, RMS is U-shaped: it falls from ∼ 0.044 % at 1 day to a minimum ∼ 0.020 % + +385 around 7–10 days, then rises again to ∼ 0.038 % by 60 days as the stack smears the step + +386 (Fig. 7b) — the classic noise-versus-smearing tradeoff, and the reason “longer is always better” + +387 is wrong even once the coherence gate is satisfied. For the poor deployment, RMS is still + +388 falling at 60 days (∼ 0.067 %, down from ∼ 0.71 % at 1 day): the noise floor dominates over + +389 the whole tested range, and the smearing penalty never gets the chance to show up. The + +390 signed error in the recovered step amplitude is negative (an under-estimate) at every stack + +391 length for the poor deployment, and for the workable deployment up to about 45 days, past + +392 which it crosses zero and the step is over-estimated. A recovered step is therefore a lower + +393 bound on the true drop only in the noise-limited regime; the sign of the error depends on the + +394 deployment and the stack length, and both should be reported. + + +395 Scale of effect: for a workable deployment, the noise/smearing tradeoff bottoms out around + Processing choices in seismic velocity monitoring 23 + + + + + Figure 7. Substacking on the earthquake synthetic, at two deployment qualities. (a) Median + stretching correlation coefficient versus stack length; the dashed line is codameter’s own CC-gate + threshold (Section 3). (b) RMS error and the absolute bias in the recovered coseismic-step amplitude, + both against the known truth, log scale. + +396 7–10 days at RMS ∼ 0.02 %; for a poor deployment, substack at least ∼ 2 weeks just to clear + +397 the coherence gate, and expect RMS an order of magnitude worse even after clearing it. + + + + + Figure 8. Parameter choices. (a) Frequency band selects depth and signal. (b) A coda window + does not transfer across bands. (c) Reference strategy: a moving reference differences the trend + away unless its increments are cumulated; a fixed reference and the joint inversion retain it. (d) + Stacking length smears the coseismic step. + 24 M. A. Denolle +398 The accepted range for each of these parameters across the published literature is catalogued + +399 directly, study by study, in the survey of Appendix C (Table A1): the frequency band, + +400 coda window, estimator, and uncertainty treatment actually reported by 103 ambient-noise + +401 𝛿𝑣/𝑣 studies. + + + +402 3.7 Coda window + + +403 The coda window is not independent of the frequency band — it deserves its own treatment + +404 because the two covary strongly, and getting this wrong is one of the larger, more avoidable + +405 sources of error in §3. Because intrinsic and scattering attenuation both grow with frequency, + +406 high-frequency coda energy falls into the noise floor much sooner than low-frequency coda: + +407 a coda window that is well past the direct arrival for a ∼ 0.3–0.8 Hz band is, at ∼ 3–6 Hz, + +408 sampling almost pure noise (Fig. 8b). On our synthetic, a fixed 20–40 s window at the high + +409 band gives RMS error ∼ 3.9 % (the noise floor, not the signal), while a window hand-adapted + +410 to the band (3–12 s) recovers the truth at ∼ 0.01 % — nearly a 400× difference from this + +411 one choice alone. This is itself an instance of a literature-documented tension: band-matched + +412 windowing is recommended, but Table A1 shows many surveyed studies instead reuse one + +413 fixed window across bands. + + +414 Hand-adapting the window per band, as above, requires knowing the band in advance and + +415 re-tuning per deployment. A more principled alternative — used in our group — is to track + +416 the coda envelope directly and stop the window where it flattens onto the noise floor, rather + +417 than pre-specifying a window from a rule of thumb. We implement this by band-passing a + +418 long-term reference stack, smoothing its envelope, estimating the noise floor from a common + +419 late-lapse window, and taking the window end as the first lapse time past a short onset where + Processing choices in seismic velocity monitoring 25 +420 the envelope stays within a factor of that floor for a sustained interval (not a single noisy + +421 dip). Applied blind (without being told which band it is) to three bands spanning low, mid, + +422 and high frequency (Fig. 9a), the detector recovers windows of ∼ (3, 29) s, ∼ (3, 37) s, and + +423 ∼ (3, 14) s respectively — correctly shrinking at the high band, though the low-versus-mid + +424 ordering is not perfectly monotonic on this synthetic (an artifact of how the fixed additive + +425 noise floor interacts with each band’s filter, not a claim that the detector is exact). Recovering + +426 𝛿𝑣/𝑣 with each band’s own detected window instead of one universal fixed (10–30 s) window + +427 (Fig. 9b) gives RMS ∼ 0.030 % vs. ∼ 0.036 % at the low band (a modest, ∼ 1.2× gain), + +428 ∼ 0.017 % vs. ∼ 0.035 % at the mid band (∼ 2×), and ∼ 0.020 % vs. ∼ 2.0 % at the high + +429 band (∼ 100×) — the fixed window is adequate at low frequency and catastrophic at high + +430 frequency, while the envelope-derived window is close to the best achievable at every band + +431 without ever being told what band it is measuring. + + + + + Figure 9. Coda window / frequency-band covariation. (a) Smoothed coda envelopes at three bands + (log scale), shaded by each band’s envelope-detected window — shrinking automatically at higher + frequency. (b) RMS error against the known truth for a single universal fixed window versus each + band’s own envelope-derived window: comparable at low frequency, ∼ 93× better at high frequency. + 26 M. A. Denolle +432 3.8 Causal and acausal branches + + +433 In a symmetric cross-correlation, both sides of the coda (positive or negative lags) should + +434 exhibit the same 𝛿𝑣/𝑣. Due to the directionality of the wavefield recorded at the two stations, + +435 the correlated wavefield in the coda may differ (Stehly et al., 2006). While the interpretation + +436 of such coda in terms of Earth’s structure effect is difficult (Snieder et al., 2002), the stability + +437 of the wavefield excited in the coda is the main requirement for stable 𝛿𝑣/𝑣 measurements + +438 (Hadziioannou et al., 2009). Given the challenge in interpreting both sides independently, + +439 researchers typically measure 𝛿𝑣/𝑣 on each lag and then report its average (Kidiwela et al., + +440 2026). The causal (positive-lag) and acausal (negative-lag) branches sample opposite-direction + +441 paths with different source-side illumination, and in a 3D medium their sensitivity kernels + +442 sample partly different volumes, so the two can report genuinely different 𝛿𝑣/𝑣 without either + +443 being wrong. Two regimes bound the choice (Fig. 10). When a change is localized to the + +444 volume one branch samples, symmetrizing or averaging the branches — the common default + +445 — dilutes it toward zero, while the branch that carries the change recovers it (Fig. 10a); + +446 here preferring the branch of greatest change is a researcher’s judgement. When instead + +447 both branches share the same change, their difference is measurement noise, and selecting + +448 the branch of greatest change over-reports it — a max-of-two-estimators selection bias that + +449 grows as SNR falls (Fig. 10b). Choosing the branch of greatest change after seeing the + +450 data is therefore a selection rule that Fig. 10b shows to be biased, and the coherence of + +451 each branch is estimated from the same observations, so selecting on coherence reduces but + +452 does not remove that bias. The rule we adopt is fixed before the data are seen: measure + +453 both branches and report both; combine them by their mean unless independent physical + +454 information (source-side illumination, a change known to be confined to one side) designates + Processing choices in seismic velocity monitoring 27 +455 a branch beforehand; and carry the between-branch difference as an explicit term of the + +456 measurement covariance 𝐶𝑑 (Section 5) rather than discarding it by averaging. + + + + + Figure 10. Combining the causal and acausal branches. (a) A change localized to the volume the + causal branch samples: averaging the branches dilutes it to about half, while the branch carrying + it recovers the truth. (b) The same change on both branches: selecting the branch of greatest + change over-reports the drop, worsening as SNR falls (a selection bias), while the branch mean + stays unbiased. + + + + +457 3.9 Choices that create spurious 𝛿𝑣/𝑣 + + +458 Some choices may create spurious signal. A station clock error delays the whole correlation + +459 by a lapse-independent shift, producing an apparent 𝛿𝑣/𝑣 that appears with opposite sign + +460 on the causal and acausal branches; measuring the two branches separately is the diagnostic + +461 (Fig. 11a). Seasonally varying noise sources warp the low-SNR late coda, so a late measurement + +462 window reports a coherent spurious seasonal 𝛿𝑣/𝑣 many times the real signal while an earlier + +463 window stays clean (the waveform-level version of Zhan et al., 2013) (Fig. 11b). + + +464 Biases from spurious arrivals could be quantified but mostly we should decontaminate our + +465 workflow from these artefacts or not interpret the results. + + +466 Taken together, the choices compound. We make this concrete in Section 4 by running the + 28 M. A. Denolle + + + + + Figure 11. Deviations that create spurious 𝛿𝑣/𝑣. (a) A clock drift splits the causal and acausal + branches with opposite sign. (b) Seasonal late-coda noise injects a spurious seasonal 𝛿𝑣/𝑣 into a + late window but not an early one. + +467 full multiverse of best-practice and deviation choices on one synthetic dataset and ranking + +468 each by the bias and the error-bar change it induces. + + + + +469 4 THE COMBINED IMPACT OF PROCESSING CHOICES + + +470 The scenario is a single representative station pair monitoring a shallow volcanic edifice, + +471 in the style of the permanent broadband deployments used at effusive/dome volcanoes + +472 such as Piton de la Fournaise (Brenguier et al., 2008b): a coda band matched to shallow + +473 depths (0.4–1.0 Hz), a coda window past the direct arrival (10–30 s), and daily correlations + +474 sampled every 3 days over 2.5 years at a per-day correlation-coefficient SNR of 7, typical of + +475 a continuously operating station. The synthetic ground truth combines an annual seasonal + +476 𝛿𝑣/𝑣 cycle (as from near-surface thermoelastic/hydrologic effects), a slow pre-eruptive inflation + +477 ramp, and a sharp co-eruptive velocity drop with partial recovery. This single-pair scenario + Processing choices in seismic velocity monitoring 29 +478 isolates the measurement-step choices from the network-aggregation choices already covered + +479 in Sections 3.2–3.3. + + +480 The previous sections only identified single choices, but the overall research workflow involves + +481 them all. We now estimate the combined effects of these parametric choices. Starting from + +482 a single best-practice baseline (trace stretching, a band matched to the target depth, a + +483 coda window well past the direct arrival, a 10-day stack, a long stable reference, coherence + +484 gating; the cross-cutting rules of Brenguier et al. (2014; Weaver et al., 2011; Clarke et al., + +485 2011) as distilled in our survey), we change one parameter at a time to a deviation from best + +486 practice documented in the literature and measure the resulting error against the known truth + +487 (Fig. 12). The ranking is unambiguous: relative to a best-practice RMS error of ∼ 0.03 %, + +488 the two-dimensionally-unwrapped WCS estimator is catastrophic here (∼ 50× worse), a + +489 wrapped-phase MWCS inflates the error by roughly an order of magnitude (∼ 12×), and + +490 DTW by ∼ 6×; among the non-estimator choices the uncumulated trailing reference is worst + +491 (∼ 5×, and most distorts the recovered drop; it is an ablation of re-baselining without trend + +492 reconstruction, not a surveyed workflow, Section 3.5), while stack length, coda window, and + +493 frequency band deviations are each more modest (1.5–2.5×). The joint-inversion reference + +494 stays closest to the fixed-reference baseline among the reference-scheme deviations. + + +495 We test the compounding effects of these choices through 108 reasonable workflows selecting + +496 three estimators, two frequency bands, three coda windows, three stacking lengths and + +497 two reference schemes on a synthetic “volcano” dv/v time series that includes a seasonal + +498 oscillation, a slow pre-eruptive inflation ramp, and a sharp co-eruptive drop with partial + +499 exponential recovery (Fig. 13a). The per-day standard deviation across the 108 pipelines + +500 varies by a factor of ∼ 4–5 over the time series (from ∼ 0.4 % to ∼ 1.7 %), and is widest + 30 M. A. Denolle + + + + + Figure 12. One-at-a-time deviations from a best-practice baseline, ranked by their RMS error + against the truth (a, log scale; RMS mixes bias and scatter) and by how they distort the recovered + co-eruptive drop (b, symlog). Bars are coloured red when the error exceeds three times the baseline. + The estimator and reference choices dominate; the band and gating are minor for this scenario. + +501 exactly at the sharp co-eruptive drop; the RMS error against the known truth spans over + +502 two orders of magnitude across pipelines (∼ 0.02–2.8 %). + + +503 Attributing the variance of the outcome to each axis with a first-order (main-effect) sensitivity + +504 index (Fig. 13b) shows that, for this dataset, the coda window controls the RMS error + +505 most, with the estimator second and the stack length third; for the recovered drop amplitude + +506 the order changes to stack length first, window second, and estimator third. The first-order + +507 indices sum to well under one in both cases (∼ 0.66 for RMS, ∼ 0.63 for the drop), so a large + +508 part of the spread is interaction between choices compounding. The appropriate object is + +509 therefore not a single curve but a distribution of 𝛿𝑣/𝑣 over the processing choices. + + +510 Table 4 summarizes this into the measurement-step best practice and the documented + Processing choices in seismic velocity monitoring 31 + + + + + Figure 13. The full multiverse. (a) 108 reasonable pipelines on one dataset, each coloured by its + RMS error against the truth (a fraction of velocity) on a colourblind-safe scale (bright accurate, + dark biased); the axis is clipped at ±0.8 % and the number of pipelines that leave it is printed + on the panel; the grey band is the 10–90% inter-pipeline spread, widest at the velocity drop. (b) + First-order variance attribution: which choice controls the RMS error and the recovered drop. + Window, estimator, and stack length dominate, in that order for RMS and reordered for the drop; + the sub-unity sum signals strong interactions. + +511 deviation for each choice, with the consequence the synthetic makes concrete. The baseline + +512 and deviation sets are the ones our survey extracts from the literature (the cross-cutting + +513 rules of Snieder et al. (2002; Clarke et al., 2011; Weaver et al., 2011; Brenguier et al., 2014; + +514 Wang et al., 2017; Obermann & Hillers, 2019)) and are implemented in codameter. + + +515 Running this many pipelines is only practical if each one is cheap. Testing codameter against + +516 a larger, multi-year deployment surfaced real bottlenecks in the per-day estimator loop, + +517 which we removed with three vectorized fast paths: a trailing stack built from a difference + +518 of cumulative sums instead of a per-day mean (roughly 2× at a 45-day stack length), a + +519 vectorized moving-reference stretching estimator that computes the stretch-interpolation + +520 weights once per trial epsilon instead of once per day (roughly 3× on a 3-year synthetic), + +521 and, for ensembles that share a band, a single shared band-pass instead of one per pipeline + +522 member (roughly 3× on a 5-member ensemble). All three reproduce the loops they replace to + 32 M. A. Denolle + + Table 4. Measurement step: best practice versus the common deviation and its consequence. Rows + are the axes swept in Fig. 13; the sets follow the literature survey (Appendix C). + + Choice Best practice Common deviation Consequence + + Estimator Stretching family Wrapped-phase MWCS (Clarke Cycle-skips at large 𝛿𝑣/𝑣; error + (TS/WTS/WCC), robust at low et al., 2011) without 2-D inflated ∼ 10× or catastrophic + SNR and large 𝛿𝑣/𝑣 (Mikesell unwrapping (Mao et al., 2020) + et al., 2015; Yuan et al., 2021) + Frequency band Matched to the target depth: Off-target or a single wide band Mixes depths; here mostly sets + ∼ 0.1–2 Hz (volcano, crust), precision + 2–4 Hz (aquifer), 4–12 Hz + (shallow damage) (Obermann + et al., 2013, 2016) + Coda window Lapse window past the direct Fixed late window reused across Measures noise at high 𝑓; bias + arrival, scaled with the band: bands and inflated 𝜎 + ∼ 5–30 s (crustal) up to ∼ 100 s + (station pairs) (Obermann et al., + 2013) + Stack length Short enough to resolve the Over-long stack (∼ 45 d) Smears and delays a step; + transient (∼ 10 d), on a long, distorts the recovered drop + stable reference span (Wang + et al., 2017) + Reference Long fixed stack or all-to-all Uncumulated trailing reference Erases slow trends + joint inversion (Brenguier et al., (an ablation: published + 2014; Wang et al., 2017) moving-reference workflows + cumulate or stitch, Section 3.5) + Coherence gating Discard low-coherence epochs No gating Keeps corrupted epochs; changes + (CC / SNR threshold) (Clarke the effective 𝑁 + et al., 2011) + √ + Uncertainty State it explicitly: Left unstated Factor 𝑁 ambiguity in + definition within-measurement (Weaver significance (Fig. 3) + et al., 2011; Clarke et al., 2011) / + SE / SD + + +523 within 10−15 in 𝛿𝑣/𝑣 (regression-tested at atol = 10−12 ); the reported ratios are wall-clock, + +524 vary with system load, and should be read as “roughly 𝑁 ×,” not exact. + + + + +525 5 A BAYESIAN MEASUREMENT MODEL AND ITS DATA + +526 COVARIANCE + + +527 If the processing choice controls the answer, the principled response is not to select a single + +528 pipeline but to treat the choice as a nuisance parameter with a prior and assess its + +529 influence. We explore a Bayesian hierarchical model for the 𝛿𝑣/𝑣 measurement, conditional on + +530 a specified pipeline menu. For configuration 𝑘 drawn from a prior over reasonable pipelines we + +531 obtain a measured series 𝑚𝑘 (𝑡) with a coherence-limited within-method floor 𝜎𝑘 (𝑡) (Weaver + Processing choices in seismic velocity monitoring 33 +532 et al., 2011; Clarke et al., 2011), and posit + + + 𝑚𝑘 (𝑡) = 𝜇(𝑡) + 𝛽𝑘 + 𝜀𝑘 (𝑡), 𝛽𝑘 ∼ 𝒩(0, 𝜏 2 ), 𝜀𝑘 (𝑡) ∼ 𝒩(0, 𝑠2 𝜎𝑘 (𝑡)2 ), (2) + + +533 The likelihood treats residuals as conditionally independent across configurations and epochs. + +534 Shared input waveforms do not ensure this assumption. Fitting all member outputs jointly + +535 is not the same operation as marginalising a discrete mixture of alternative pipelines. The + +536 posterior is therefore conditional on this working likelihood. We use a second-difference + +537 smoothness prior of precision 𝜆 on the latent true series 𝜇(𝑡), built on the physical time grid + +538 so that a gap in the record is a gap in the prior. Here 𝛽𝑘 is configuration 𝑘’s constant offset + +539 (the systematic offset between, say, MWCS and stretching), 𝜏 its scale across the ensemble, + +540 and 𝑠 rescales the coherence floor of eq. A.2 so that the data report whether that floor is + +541 calibrated. Every configuration is run through the same pipeline code as the rest of the + +542 paper, so the estimator, band, window, stack length in days, reference scheme and coherence + +543 gate all take effect; an epoch a configuration does not produce (reference warm-up, a gated + +544 coherence) is simply missing and carries no information. The hyper-priors on 𝜏 2 , 𝑠2 and 𝜆 + +545 are conjugate inverse-gamma and gamma distributions whose scales are small against the + +546 data terms. Codameter reports the prior scale term divided by the conditional posterior rate, + +547 evaluated at posterior means. The ratio is about 0.09 for 𝜏 2 in the clean scenario and below + +548 0.01 for 𝑠2 and 𝜆 (Table 5). This diagnostic does not measure the total influence of the prior + +549 or establish sampler convergence. A conjugate Gibbs sampler, implemented in codameter + +550 with no external sampler dependency and with a banded solve for the smoothness update, + +551 returns the joint posterior. + + +552 The model yields two distinct objects, and conflating them is a common error (Fig. 14; + +553 Table 2). The posterior of 𝜇 is the precision of the combined estimate: it is tight and + 34 M. A. Denolle +554 shrinks with ensemble size under the working likelihood. Separately, we construct a candidate + +555 single-member error covariance + + + 𝐶𝑑 (𝑡, 𝑡′ ) = 𝐷𝑅𝐷 + ⏟ + 2 11⊤ , + 𝜏⏟ 𝐷 = diag(𝜎tot (𝑡)), + calibrated floor ⊕ excess spread, temporally correlated common mode + (3) + +556 with 𝜎tot + 2 + (𝑡) = 𝑠2 𝜎𝑘2 (𝑡) + max[ Var𝑘 (𝑚𝑘 (𝑡) − 𝛽𝑘 ) − 𝑠2 𝜎𝑘2 (𝑡), 0], the calibrated floor plus + +557 whatever spread across configurations exceeds it (so that the floor is not counted twice), + +558 and 𝑅𝑖𝑗 = 𝑒−|𝑡𝑖 −𝑡𝑗 |/𝐿 for a correlation length 𝐿 estimated from the ensemble residuals. 𝐶𝑑 + +559 is constructed from the fitted model, not sampled. It targets the error of one measurement + +560 drawn from the ensemble, not of 𝜇. The between-configuration offset scale 𝜏 does not identify + +561 an error shared by all configurations. Pointwise coverage tests only the diagonal scale; it does + +562 not validate 𝑅 or the rank-one term. A downstream inversion needs the error covariance of + +563 its actual input estimate. Neither using this 𝐶𝑑 for the ensemble mean nor interpreting its + +564 time axes as frequency-band axes is justified here. + + +565 Two properties of the fit deserve to be stated plainly. First, 𝑠 ≈ 12 on this synthetic: the + +566 residual scatter of the members about the ensemble mean is an order of magnitude above the + +567 coherence floor of eq. A.2, which treats the reference as noise-free and knows nothing of the + +568 estimator. The floor is a lower bound, and the rescale is what makes it usable. Second, once 𝑠 + +569 is fitted on those residuals, the calibrated floor absorbs nearly all of the between-configuration + +570 spread, and the excess term of eq. 3 is non-zero only at the epochs where the configurations + +571 disagree more than they usually do (Fig. 14c). The assumed temporal correlation (𝐿 ≈ 40 + +572 days at a 4-day cadence) and the common-mode term collapse the effective number of + +573 independent epochs from 229 to a few tens. + + +574 Whether these intervals mean what they say is a question one realisation cannot answer, so + Processing choices in seismic velocity monitoring 35 +575 we repeat the whole measurement on independent realisations of the same scenario (Table 5; + +576 the driver is codameter.calibration). Three coverages answer three different questions. + +577 The fraction of member epochs whose error against the truth lies within 1.96 𝜎𝐶𝑑 is 0.956 on + +578 200 realisations, within the margin of ±0.03 fixed before the run. This supports the 95,% + +579 pointwise interval on this scenario, not calibration of the entire covariance. At the 68,% level + +580 it covers 0.81 and fails the same margin. One Gaussian scale therefore does not calibrate both + +581 interval levels. The 95,% credible band on 𝜇 contains the truth at only 0.59 of the epochs: the + +582 ensemble mean inherits the biases its members share (the stacking that rounds the drop, the + +583 estimator biases at low coherence), and no amount of averaging over configurations removes + +584 them, which is what the posterior’s precision cannot know. Comparing 𝜇 with ±2𝜎𝐶𝑑 mixes + +585 the ensemble mean with a single-member scale and yields nearly complete coverage here; + +586 it does not validate the uncertainty of the combined estimate. The other two scenarios of + +587 Table 5 inject artefacts that every configuration sees identically. A station clock drift leaves + +588 every statistic unchanged, because a lapse-independent shift appears with opposite signs + +589 on the causal and acausal branches (Section 3.9) and every configuration in this ensemble + +590 measures both branches together, so the drift cancels in the estimate; that is a property of the + +591 two-branch measurement, not evidence that the ensemble could have detected it. A seasonal + +592 source effect confined to the late coda, the waveform-level artefact of Zhan et al. (2013) + +593 (Section 3.9), is the genuine shared error: it warps the coda every configuration measures, + +594 and on that scenario the credible band covers the truth at only 0.34 of the epochs and the + +595 RMSE of 𝜇 more than doubles, from 0.067 to 0.161,%, while the member-level coverage of + +596 𝐶𝑑 stays at 0.95. That last number is right for a reason that gives no comfort: the artefact + +597 also inflates the scatter that 𝑠 absorbs, so 𝐶𝑑 widens, but its coherent part biases every + +598 member and the ensemble mean together and leaves no trace in their spread. That is the + +599 limit of the method, not a defect of the fit: an ensemble over processing choices can only + 36 M. A. Denolle +600 reveal the errors on which its members disagree, and an error shared by every pipeline (a + +601 source change, a contaminated reference, a clock drift measured on one branch) needs an + +602 independent diagnostic, such as the branch asymmetry of Section 3.9. + + + + + Figure 14. The Bayesian measurement model on one realisation of the volcano scenario (12 + configurations: three estimators, two bands, two windows, 10-day stacks, fixed reference, 4-day + cadence). (a) The processing ensemble (grey) is marginalised into a posterior mean (purple) with + a narrow credible band (the estimator precision) and a wider ±2𝜎 band from 𝐶𝑑 , the single- + measurement error, which encloses the individual members (Table 5 gives the coverages over + repeated realisations). (b) The time-dependent covariance 𝐶𝑑 , in squared fractional 𝛿𝑣/𝑣. (c) Its + diagonal 𝜎𝑑 (𝑡), in percent, split into the calibrated coherence floor (𝑠 𝜎𝑘 , which with 𝑠 ≈ 12 carries + almost all of the spread) and the excess between-configuration spread, which is non-zero only where + the configurations disagree more than usual; the posterior-of-the-mean (dotted) is far tighter, and + 𝑁eff is a small fraction of the epoch count. + Processing choices in seismic velocity monitoring 37 + + Table 5. Coverage calibration of the Bayesian measurement model over independent synthetic + realisations of the volcano scenario (2.5 years, SNR 7, 4-day cadence, 12-member ensemble). Member + coverage: fraction of member epochs with |𝑚𝑘 (𝑡) − truth(𝑡)| ≤ 𝑧 𝜎𝐶𝑑 (𝑡), the target of the proposed + single-member error scale. These pointwise tests do not validate the temporal covariance. Nominal + 68% intervals overcover. Posterior: fraction of epochs whose 95% credible band on 𝜇 contains the + truth. Means with standard errors across realisations; no realisation failed; 𝜎𝐶𝑑 , bias and RMSE + in percent; prior 𝜏 2 is the fraction of conditional posterior rate supplied by the prior scale term + (the 𝜆 ratio is below 0.01 throughout). Clock drift: 4 × 10−5 s/day from 40% of the record; the + two-branch measurement cancels it. Shared source: a seasonal source effect warping the coda + beyond 6 s lapse with a spurious 0.2% seasonal 𝛿𝑣/𝑣, seen by every configuration. Generated from + paper/data/calibration/ by paper/build_calibration_table.py. + + Quantity clean (𝑛 = 200) shared source (𝑛 = 200) clock drift (𝑛 = 200) + + Member 68% 0.808 ± 0.001 0.795 ± 0.001 0.804 ± 0.001 + Member 95% 0.9561 ± 0.0003 0.9496 ± 0.0004 0.9543 ± 0.0003 + Posterior 95% 0.590 ± 0.004 0.340 ± 0.004 0.604 ± 0.004 + Median 𝜎𝐶𝑑 (%) 0.225 ± 0.001 0.330 ± 0.001 0.222 ± 0.001 + Bias (%) -0.017 ± 0.001 -0.045 ± 0.001 -0.019 ± 0.001 + RMSE(𝜇) (%) 0.0669 ± 0.0005 0.161 ± 0.001 0.0656 ± 0.0005 + Prior scale share 𝜏 2 0.09 ± 0.01 0.025 ± 0.005 0.08 ± 0.01 + + +603 6 PROPAGATING 𝛿𝑣/𝑣 ERRORS AT DEPTH Δ𝛽/𝛽(𝑍) + + +604 The remaining sections present a framework rather than new synthetics: they set out how + +605 the covariance of Section 5 propagates down the inference chain, and ground each step in + +606 what the monitoring literature does and does not yet report. The executable stages are in + +607 development in the open codameter package (Section 8). + + +608 The field has converged on one physical rule for depth — depth is set by the frequency band + +609 and the coda lapse time, it is not assumed (Obermann et al., 2013, 2016) — and, increasingly, + +610 on multi-band measurement as the means to resolve it (Takano et al., 2017; Feng et al., 2020; + +611 Mao et al., 2022, 2025). The step from a set of per-band 𝛿𝑣/𝑣 series to a depth profile is + +612 where reporting is least consistent: many studies read a single band as a single depth, only + +613 a few invert several bands against surface-wave sensitivity kernels, and the propagation of + +614 the measurement error into the depth estimate is seldom shown. The depth assignment is + +615 frequently the scientific claim itself — whether the change lies in the aquifer or the overlying + +616 soil, whether coseismic softening is a shallow site response or slip on the fault at depth + 38 M. A. Denolle +617 (Rubinstein & Beroza, 2005) — so a depth reported without its uncertainty cannot support + +618 that claim. + + +619 A 𝛿𝑣/𝑣 measured in band 𝑏 is not a point sample but a weighted integral over depth, + + ∞ + 𝛿𝑉𝑆 + ( 𝛿𝑣 + 𝑣 ) =∫ 𝐾𝑏 (𝑧) (𝑧) d𝑧 + 𝜀𝑏 , (4) + 𝑏 0 + 𝑉𝑆 + +620 where 𝐾𝑏 (𝑧) is the (Rayleigh-wave) depth-sensitivity kernel for band 𝑏 and 𝜀𝑏 is that band’s + +621 observation error. Stacking bands gives a linear system d = G m + 𝜀 with G𝑏𝑧 = 𝐾𝑏 (𝑧) and + +622 cross-band data covariance 𝐶𝑑band . This covariance must describe the band estimates actually + +623 supplied. The temporal 𝐶𝑑 in Section 5 does not supply its cross-band entries. Given such a + +624 covariance, the Bayesian solution under a smoothness prior returns a depth profile 𝛿𝑉𝑆 /𝑉𝑆 (𝑧) + +625 together with its posterior covariance 𝐶𝑚 (𝑧), implemented in codameter. The bands must + +626 sit where the kernels resolve: too low and the kernel leaks into the half-space, too high and + +627 the coda is incoherent (Section 3.4). The width of 𝐶𝑚 (𝑧) — not the profile alone — is the + +628 deliverable, and it inherits the temporal correlation and common-mode structure of 𝐶𝑑 . + + +629 One assumption is usually left implicit: that a 𝛿𝑣/𝑣 change is a shear-velocity change alone. + +630 In partially saturated ground it is not. Filling or draining pore space changes both the shear + +631 modulus and the bulk density, so for the shear-dominated coda the observed change mixes + +632 the two, + + 𝛿𝑣 𝛿𝜇 𝛿𝜌 + ≈ 12 − 12 , (5) + 𝑣 𝜇 𝜌 + +633 and velocity alone cannot separate them. A petrophysical model — Gassmann fluid substitu- + +634 tion for the modulus and a porosity–saturation relation for the density (Gassmann, 1951; + +635 Mavko et al., 2009) — is what breaks the degeneracy, at the cost of its own prior uncertainty + +636 on porosity, fluid modulus, and the saturation path. Hydrological and cryospheric targets, + Processing choices in seismic velocity monitoring 39 + + Table 6. Depth step: best practice versus the common deviation in going from per-band 𝛿𝑣/𝑣 to a + depth profile, and the consequence for the interpretation. + + Choice Best practice Common deviation Consequence + + Depth assignment Invert several bands against Read one band as one depth No depth resolution and no + sensitivity kernels depth error + Band selection Bands where the kernels resolve Convenience band Kernel leaks; unstable inversion + (no half-space leak, coherent + coda) + Measurement error Propagate the per-band 𝐶𝑑 into Plot a profile with no covariance Overconfident depth attribution + the profile + Saturation Separate 𝛿𝑉𝑆 /𝑉𝑆 and 𝛿𝜌/𝜌 Assume a pure 𝛿𝑉𝑆 /𝑉𝑆 change Biased velocity change and + with a petrophysical model in stress in hydrological and + partly saturated ground cryospheric targets + Velocity model State the reference 𝑉𝑃 , 𝑉𝑆 (𝑧) Fixed, unstated model Hidden systematic in the kernels + and its uncertainty and the moduli + + +637 where saturation varies strongly (Clements & Denolle, 2018; James et al., 2019), are precisely + +638 where neglecting the density term biases the inferred velocity change and, downstream, the + +639 stress. The framework carries 𝛿𝜌/𝜌 as a second inverted field with its own kernel and reports + +640 how much of the surface 𝛿𝑣/𝑣 each explains; the executable version is a documented extension + +641 (Section 8). + + + + +642 7 REAL-DATA COMPARISON AND DEPLOYMENT + + +643 Every result so far is on a truth-known synthetic, by design (Section 2): it is the only way + +644 to separate a processing artefact from a real signal. The next step is to test whether the + +645 same measurement machinery holds up against real data, not just against a synthetic that + +646 was built to resemble it. We are building a companion cloud pipeline that correlates real + +647 continuous waveforms for station CI.LJR (Lake Hughes, California) — the reference station + +648 of Clements & Denolle (2023) — pulled from the public Southern California Earthquake Data + +649 Center S3 archive, using the NoisePy package (Jiang & Denolle, 2020) for the correlation + +650 step. Correlation and dv/v estimation each run as a cloud batch job on spot compute; dv/v + +651 estimation itself is handed to the same codameter measurement and uncertainty functions + 40 M. A. Denolle +652 this paper’s synthetic results are built on, with baseline processing configurations drawn + +653 from the same recommendation logic — not a separate reimplementation. The retrospective + +654 run is compared with the already-published Clements & Denolle (2023) CI.LJR result before + +655 any new claim is drawn from it. + + +656 After the correction, single-station 𝛿𝑣/𝑣 (NoisePy correlations, a codameter 5-member + +657 ensemble, 2–4 Hz, 2018–2019) agrees in shape with the published Clements & Denolle + +658 (2023) product. The comparison is not trivial to get right: the CD2023 90-day-comp product + +659 is a trailing 90-day stack, so it lags a centered-smoothed daily series by about 45 days, + +660 and comparing without matching that smoothing caps the correlation near 0.7 even on + +661 a real annual cycle (Fig. 15). We match by applying the same trailing 90-day mean to + +662 the daily series (at least 45 finite days in the window), compare demeaned — the two + +663 products reference different epochs, and a constant offset is bookkeeping, not error — and + +664 exclude the first 150 days of each station’s series as reference burn-in. The comparison + +665 is computed by a script archived with the paper (scripts/compare_gate1.py) from the + +666 daily products and the published series, with the join, smoothing and mask stated in its + +667 output (paper/data/gate1/comparison.json); Table 7 lists the result. Under the matched + +668 rule CI.LJR reaches 𝑟 = 0.985 on 579 days with an amplitude slope of 1.07 (published on + +669 codameter); CI.ARV reaches 𝑟 = 0.905 on 357 days, the 2018 data gaps reducing the overlap, + +670 but with a slope of 2.15, so the published product has twice the amplitude of ours there; + +671 CI.RXH reaches 𝑟 = 0.829 on 446 days with a slope of 0.81 on a station whose recovered + +672 𝛿𝑣/𝑣 is nearly flat. Correlation measures the shape of the annual cycle after smoothing; it + +673 does not validate the amplitude (the ARV slope) or the error bars, which the published + +674 product does not carry, and the earlier draft’s quoted 681 days was the raw daily overlap, + +675 not the count under the stated mask. + Processing choices in seismic velocity monitoring 41 + +Table 7. Comparison of codameter single-station 𝛿𝑣/𝑣 (2–4 Hz, 2018–2019) with the published +Clements & Denolle (2023) product, from scripts/compare_gate1.py. Matched: trailing 90-day +mean, 150-day burn-in. Centred: centred 45-day mean, no burn-in (the rule behind the annotation +on Fig. 15). Slope is the OLS slope of the published product on codameter; RMS is the RMS +difference after removing each series’ mean over the overlap. + +Station Rule Days 𝑟 RMS diff (%) Slope + +CI.LJR matched 579 0.985 0.046 1.07 +CI.LJR centred 682 0.865 0.120 0.88 +CI.ARV matched 357 0.905 0.150 2.15 +CI.ARV centred 424 0.369 0.214 0.80 +CI.RXH matched 446 0.829 0.020 0.81 +CI.RXH centred 554 0.620 0.035 0.52 + + + + +Figure 15. Single-station 𝛿𝑣/𝑣 at three CI stations, 2018–2019, against the published Clements & +Denolle (2023) product (dashed, reference-shifted; the panel labels name it by its 2022 data release). +Daily 𝛿𝑣/𝑣 (points) with the between-configuration spread of the five-member ensemble (shaded) and +the within-measurement error bars (Table 2), and a centred 45-day-smoothed curve. This figure was +produced by the Gate 1 cloud run itself and is not regenerated from this repository; its annotated 𝑟 +values correspond to the centred rule of Table 7 (0.87, 0.37 and 0.62 for LJR, ARV and RXH from the +archived products), not to the matched rule quoted in the text. The error bars drawn here predate +the Weaver-floor correction of the present revision and are too large by a factor of 3.1 at 2–4 Hz +(the archived columns have since been rescaled by scripts/correct_gate1_within_error.py; the +externally produced figure has not been regenerated). + 42 M. A. Denolle +676 Part of why agreement differs by station is visible in the correlation function itself (Fig. 16), + +677 although an interferogram alone cannot separate a site change from an instrument or + +678 processing change, which station metadata and processing logs would be needed to rule out. + +679 CI.LJR shows a stable, narrow coda near zero lag through the year. CI.RXH shows multipath, + +680 several coherent arrivals spread across the full ±8 s of lag shown, and a visible shift in that + +681 pattern in April–May 2019, consistent with a site change rather than a processing artefact. + +682 CI.ARV’s coherent energy is compact and concentrated near zero lag but comparatively + +683 sparse, consistent with its higher scatter and join-method sensitivity. + + + + + Figure 16. Daily NZ (north-vertical) cross-component correlation functions, 2–4 Hz, ±8 s lag, 2019, + each day normalised to its maximum absolute amplitude (colour scale unlabelled on this externally + produced figure). CI.LJR’s coda is stable and narrow. CI.RXH shows multipath (several coherent + bands across the full lag range) and a shift in that pattern in April–May 2019. CI.ARV’s coherent + energy is compact and near zero lag but comparatively sparse. These differences are consistent with, + but do not by themselves explain, the station-to-station agreement in Fig. 15. + + + +684 As an optional supplement, Fig. 17 shows the ensemble’s warm-up behaviour on a separate + +685 90-day smoke run at CI.LJR: 𝛿𝑣/𝑣 is undefined until enough history has accumulated for + +686 the moving-reference member to compute a trailing reference, and each band’s per-epoch + +687 stretching correlation coefficient is reported alongside the recovered series. + Processing choices in seismic velocity monitoring 43 + + + + +Figure 17. CI.LJR single-station 𝛿𝑣/𝑣, a separate 90-day smoke run (January–April 2023), four +frequency bands. The ensemble spread (shaded) and measurement error bars are reported once at +least one member is defined; the member count annotated on each panel is the number of members +defined on the last day shown, which is below five where the moving-reference member’s warm-up +had not yet elapsed. Bottom panel: per-band stretching correlation coefficient. Produced by the +cloud run, not regenerated here. + 44 M. A. Denolle +688 8 DISCUSSION + + +689 The experiments above share one finding: on these synthetics, with one waveform realisation + +690 held fixed, the processing choice moves both the recovered 𝛿𝑣/𝑣 and its stated uncertainty by + +691 more than the measurement noise does, by two orders of magnitude in RMS across the 108- + √ +692 pipeline multiverse and by a factor 𝑁 in the reported network error bar. Whether processing + +693 also dominates the variability between real deployments is a question these experiments + +694 cannot answer, because they hold the observed waveform fixed; the repeated-realisation + +695 calibration of Section 5 is the first step toward it. The problem is consequential but tractable. + +696 We suggest the following responses. + + +697 Report the choices. At minimum, a 𝛿𝑣/𝑣 study should state the estimator and its param- + +698 eters, the frequency band(s) and coda window(s) and how the window was set relative to the + +699 band, the reference scheme, the stacking, the cross-component and station-pair aggregation + +700 and weighting, and — critically — the exact definition of the quoted uncertainty (within- + +701 measurement error, between-component/pair standard error, or standard deviation). Our + √ +702 results show that the last item alone changes the number quoted as 1𝜎 by 𝑁, because the + +703 two conventions estimate different quantities (Table 2). Table 8 collects this into a minimal + +704 reporting checklist, and Appendix C shows how unevenly these items are reported across the + +705 literature today. + + +706 Quantify the choice-induced uncertainty. Where a choice is not forced by the physics, + +707 it can be sampled. Pushing a distribution of reasonable processing choices through the + +708 same correlations measures conditional sensitivity. A probabilistic mixture would combine + +709 conditional variances and the variance of conditional means. The joint likelihood in Section 5 + +710 instead defines a working Bayesian model whose deliverable is a time-dependent single- + Processing choices in seismic velocity monitoring 45 + + Table 8. A minimal reporting checklist for an ambient-noise 𝛿𝑣/𝑣 study. Stating these turns an + undocumented, irreproducible choice into an inspectable one and makes error bars comparable + across studies. + + Step What to report + + Pre-processing Time-domain normalization (one-bit / running-mean), spectral whitening band, sampling rate + Correlation & stacking Components computed, segment length, daily/sub-stack length, total reference span + Estimator Method (TS / WCC / DTW / MWCS / WCS / WTS / WTDTW), its parameters (𝜀-grid, or + sub-window length and step), and whether the phase is unwrapped + Frequency band(s) [𝑓1 , 𝑓2 ] for every reported measurement + Coda window(s) [𝑡1 , 𝑡2 ], the branch(es) used, and how 𝑡1 , 𝑡2 were set relative to the band + Reference Scheme (total stack / trailing / inversion) and period + Component aggregation Approach A or B; weighted (by what) or unweighted + Pair / network Spatial averaging and weighting scheme + aggregation + Uncertainty The exact definition of the quoted error: within-measurement (e.g. Weaver), + between-component/pair standard error, or standard deviation + Quality control CC / SNR thresholds, rejection criteria, resulting effective 𝑁 + Software Package, version, and the parameter file or its DOI + + +711 measurement covariance 𝐶𝑑 . Its limitations are as important as its construction. The prior + +712 over pipelines is a menu, not a representative sample of practice, and the covariance is + +713 conditional on it. Every configuration transforms the same waveforms, so an error they all + +714 share (a source change, a contaminated reference, a clock drift measured on one branch) leaves + +715 no trace in their spread: on the shared-source scenario of Table 5 the ensemble agrees with + +716 itself, the error of its mean doubles, and 𝐶𝑑 cannot see it. Configurations in different bands + +717 sample different depths and may not estimate the same physical quantity, so the configuration + +718 axis should be marginalised only over pipelines that target one estimand. And the coherence + +719 floor of Weaver et al. (2011) is a lower bound: on our synthetic the residual scatter about the + +720 ensemble mean is an order of magnitude above it, which the fitted rescale 𝑠 reports rather + +721 than hides. The pointwise tests in Table 5 support the 95,% member intervals on the listed + +722 scenarios. They also expose 68,% overcoverage and poor coverage of the combined estimate. + +723 They do not establish temporal covariance calibration, convergence across independent chains, + +724 or valid downstream intervals. + + +725 Make it executable. All synthetics, estimators and generated figures in this paper are + +726 released in the open codameter package; one driver regenerates every generated figure together + 46 M. A. Denolle +727 with a numerical sidecar holding every plotted array and the run’s provenance, and the + +728 package is unit-tested. The three real-data figures were produced by the cloud run and + +729 are archived, not regenerated (Section 7). An executable record turns an undocumented + +730 choice into a versioned, inspectable one, and lets a reader re-run a study’s pipeline on the + +731 truth-known synthetic to see its bias before trusting it on data. + + +732 Validate against something you did not generate. Every synthetic test in this paper + +733 passed before the discovery below, and that is exactly the danger: a synthetic built under the + +734 same sign convention as the estimator reading it will always agree, whether the convention + +735 is physically correct or not. Testing codameter’s estimators against a real cross-network + +736 deployment (Section 7), recovered 𝛿𝑣/𝑣 anticorrelated with the published Clements & Denolle + +737 (2023) product and with seasonal hydrology at three stations (𝑟 = −0.69, −0.45, −0.40 under + +738 the rule used at the time, recorded in the codameter v0.4.0 release notes). Ground-truthing + +739 through the exact call path made the cause obvious: imposing a +0.5 % velocity change + +740 returned −0.50 %. The synthetic generator and all seven estimators had consistently used the + +741 stretch factor 𝜀 (positive for a coda dilation, i.e. a slowdown), not physical 𝛿𝑣/𝑣 (positive for a + +742 speedup) — internally coherent, so every synthetic-recovery test in the sections above passed, + +743 but opposite to the sign convention the field expects and to the published product it was + +744 compared against. The fix is the convention boxed in Section 1, shipped as codameter v0.4.0. + +745 Internal consistency is not correctness: a pipeline that only checks itself will confirm whatever + +746 convention it started with, and only the comparison against an independently-produced + +747 result caught this one. The fix and its ground-truthing procedure are documented in the + +748 codameter release history. + + +749 Propagate the covariance, do not truncate it. The measurement covariance is not the + +750 end of the analysis but its first input. Section 6 sets out the next step of the chain: invert the + Processing choices in seismic velocity monitoring 47 +751 per-band 𝐶𝑑 through sensitivity kernels for a depth profile and its covariance, separating the + +752 shear-velocity and density contributions where the ground is partially saturated. Converting + +753 that depth-resolved posterior to stress or strain requires material priors this paper does + +754 not attempt to constrain, and is left to other work. What codameter provides today is the + +755 interface that consumes 𝐶𝑑 ; the depth posterior itself, its resolution, and the calibration of its + +756 covariance are not demonstrated in this paper. Building and testing the depth-propagation + +757 stage on truth-known synthetics with overlapping kernels is the natural continuation of this + +758 work. + + + + +759 9 CONCLUSIONS + + +760 Ambient-noise 𝛿𝑣/𝑣 monitoring rests on a chain of processing choices that are made ad + +761 hoc and reported incompletely. Using a truth-known synthetic and the full estimator suite + +762 of an open toolbox, we have shown that these choices change the recovered 𝛿𝑣/𝑣 by up + +763 to two orders of magnitude in RMS across reasonable pipelines and, more consequentially, + √ +764 change the number reported as its uncertainty by a factor of ∼ 𝑁 depending on which of + +765 two different quantities a study calls 1𝜎, all without touching the data. The remedy is not + +766 a single mandated pipeline but transparency: report every choice and name the quantity + +767 each error bar estimates, sample the choices the physics does not fix, carry the resulting + +768 measurement covariance into the inference after validating its target, and release the pipeline + +769 as executable code. Repeated synthetic realisations support the proposed 95,% pointwise + +770 member intervals, while the nominal 68,% intervals overcover and the combined estimate’s + +771 credible band undercovers (Table 5). Temporal and cross-band covariance and shared errors + +772 remain unvalidated. A depth inversion also needs kernel uncertainty and the covariance of + +773 the actual observations it consumes. Converting a depth profile to stress or strain is a further + 48 M. A. Denolle +774 step this paper does not attempt. We offer codameter as one such record; its depth stage is + +775 an interface awaiting evaluation. + + + + +776 APPENDIX A: ESTIMATOR DEFINITIONS + + +777 Let 𝑟(𝑡) and 𝑐(𝑡) be the reference and current cross-correlations, band-passed to [𝑓1 , 𝑓2 ] + +778 (central frequency 𝑓𝑐 , bandwidth 𝐵) and read over the coda window 𝑊 = [𝑡1 , 𝑡2 ] on one or + +779 both branches. Each method below estimates a trial stretch factor 𝜀, the fractional dilation + +780 of the current coda relative to the reference; physical 𝛿𝑣/𝑣 follows via the convention boxed + +781 in Section 1, 𝛿𝑣/𝑣 = −𝜀/(1 + 𝜀). + + +782 Trace stretching (TS). For each trial stretch factor 𝜀, the current correlation is interpolated + +783 as 𝑐𝜀 (𝑡) = ℐ[𝑐]((1 + 𝜀)𝑡) (interpolation on current only) while the reference 𝑟(𝑡) remains + +784 fixed. The windowed correlation coefficient is + + ∫ 𝑟(𝑡) 𝑐𝜀 (𝑡) d𝑡 + CC(𝜀) = 𝑊 + 1/2 + , 𝜀⋆ = arg max CC(𝜀). (A.1) + (∫ 𝑟2 d𝑡 ∫ 𝑐𝜀2 d𝑡) + 𝜀 + 𝑊 𝑊 + + +785 The best-fit stretch 𝜀⋆ is then converted to physical 𝛿𝑣/𝑣 via 𝛿𝑣/𝑣⋆ = −𝜀⋆ /(1 + 𝜀⋆ ) as boxed + +786 in the Introduction. The single-measurement error decreases with the coherence CC, the + +787 bandwidth 𝐵, and the window length. We use eq. 20 of Weaver et al. (2011), + + √ √ + 1 − CC2 6√𝜋/2 𝑇 ln 10 + 𝜎𝜀 = √ , 𝑇 = , (A.2) + 2 CC 𝜔𝑐2 (𝑡32 − 𝑡31 ) 𝜋𝐵 + +788 with 𝜔𝑐 = 2𝜋𝑓𝑐 and 𝑇 the spectral timescale of Weaver et al.’s Gaussian spectrum, fixed here + +789 by placing the band edges at that spectrum’s −10,dB points; any convention with 𝑇 ∝ 1/𝐵 + √ +790 gives the same 1/ 𝐵 scaling and differs by a constant that the rescale 𝑠 of Section 5 absorbs. + +791 The corresponding error on 𝛿𝑣/𝑣 follows from the exact map, 𝜎𝛿𝑣/𝑣 = 𝜎𝜀 /(1 + 𝜀)2 , which + Processing choices in seismic velocity monitoring 49 +792 equals 𝜎𝜀 to first order. (The codameter implementation before this revision omitted 𝑇 and + +793 used a variance prefactor twice this one; the fitted 𝑠 absorbed the constant, and only the + +794 relative weighting of configurations in different bands changed when it was corrected.) + + +795 Interpolation direction and convention. The interpolation is applied to the current waveform + +796 and not the reference so that the high-SNR reference stack remains invariant throughout + +797 the epsilon search, which is particularly important when the reference is built as a long- + +798 term or moving average. In the continuous-signal, infinite-support limit the two conventions + +799 (interpolating current versus interpolating reference) are mathematically equivalent after + +800 their fitted parameters are converted to the same physical 𝛿𝑣/𝑣 through the exact relation + +801 𝛿𝑣/𝑣 = −𝜀/(1 + 𝜀). In sampled, finite-window signals, that symmetry is broken: interpolation + +802 error, edge truncation, and the finite support of the data cause the two conventions to give + +803 slightly different numerical results even when both use the exact conversion. Therefore the + +804 interpolation direction must be reported explicitly and treated as a fixed processing choice. + +805 For diffuse codas in ambient-noise and volcanic monitoring, we have verified that the choice + +806 has a measurable but small effect: truth-known synthetics recover 𝛿𝑣/𝑣 with sub-10−4 bias + +807 when the signal-to-noise ratio is high and the changes are small, with the effect growing as a + +808 few percent at landslide-scale perturbations (𝛿𝑣/𝑣 ∼ 4 %). + + +809 Throughout this appendix a delay 𝛿𝑡 is the lag of the current trace relative to the reference, + +810 positive when the current arrival is later, so for the pure dilation 𝑐(𝑡) = 𝑟(𝑡/(1 + 𝜀)) a phase + +811 at reference lapse 𝑡𝑖 appears at (1 + 𝜀)𝑡𝑖 and 𝛿𝑡𝑖 = +𝜀 𝑡𝑖 ; with that sign every estimator + +812 below returns the dilation 𝜀 of the Introduction, and a regression test in codameter holds + +813 each of them to it in both signs. + 50 M. A. Denolle +814 Windowed cross-correlation (WCC). In sub-windows centred at lapse 𝑡𝑖 the delay is + +815 𝛿𝑡𝑖 = arg max𝜏 ∫ 𝑐(𝑡) 𝑟(𝑡 − 𝜏 ) d𝑡; a least-squares fit of 𝛿𝑡𝑖 = 𝜀 𝑡𝑖 gives 𝜀. + + +816 Moving-window cross-spectrum (MWCS). In each sub-window the cross-spectrum is + +817 ̂ 𝑟∗̂ (𝑓) with phase 𝜑(𝑓) = arg 𝑋(𝑓) ≈ 2𝜋𝑓 𝛿𝑡𝑖 ; a coherence-weighted linear fit of + 𝑋(𝑓) = 𝑐(𝑓) + +818 𝜑(𝑓) over [𝑓1 , 𝑓2 ] yields 𝛿𝑡𝑖 , and 𝜀 is the slope of 𝛿𝑡𝑖 versus 𝑡𝑖 (Clarke et al., 2011). Because + +819 𝜑 is defined modulo 2𝜋, the estimate cycle-skips once |𝛿𝑡𝑖 | > 1/(2𝑓). + + +820 Dynamic time warping (DTW). A lag path 𝑙(𝑖) minimises + + + 2 2 + ∑ (𝑐𝑖 − 𝑟𝑖+𝑙(𝑖) ) + 𝛾 ∑ (𝑙(𝑖+1) − 𝑙(𝑖)) , (A.3) + 𝑖 𝑖 + + +821 where 𝛾 penalises strain (limits the lag’s rate of change); 𝜀 is the slope of the lag 𝑙(𝑖)/𝑓𝑠 + +822 (current relative to reference) versus lapse. + + +823 Wavelet cross-spectrum (WCS). With continuous wavelet transforms 𝑊𝑐 , 𝑊𝑟 , the cross- + +824 wavelet spectrum is 𝑊𝑥𝑦 (𝑓, 𝜏 ) = 𝑊𝑐 𝑊𝑟∗ and the delay 𝛿𝑡(𝑓, 𝜏 ) = 𝜑(𝑓, 𝜏 )/(2𝜋𝑓). Unwrapping + +825 𝜑 in two dimensions — along lapse (anchored at 𝜏 → 0, where 𝛿𝑡 → 0) then along frequency + +826 — removes the cycle-skip; 𝜀 follows from the |𝑊𝑥𝑦 |-weighted regression 𝛿𝑡 = 𝜀 𝜏 over the + +827 time–frequency window (Mao et al., 2020). + + +828 Wavelet stretching / warping (WTS, WTDTW). TS (respectively DTW) is applied + +829 per wavelet scale (respectively to the wavelet-reconstructed band) and the per-scale estimates + +830 are pooled with cross-wavelet-power weights. + Processing choices in seismic velocity monitoring 51 +831 APPENDIX B: AGGREGATION AND UNCERTAINTY CONVENTIONS + + +832 For component 𝑘 of a station pair, stretching yields the image CC𝑘 (𝜀, 𝑡); each per-component + +833 stretch factor converts to physical 𝛿𝑣/𝑣𝑘 via the boxed relation. + + +834 Approach A (average the per-component 𝛿𝑣/𝑣). 𝛿𝑣/𝑣𝑘 (𝑡) follows from 𝜀𝑘 (𝑡) = + +835 arg max𝜀 CC𝑘 (𝜀, 𝑡), and the pair estimate is the (possibly weighted) mean 𝑥𝑝 (𝑡) = + +836 ∑𝑘 𝑤𝑘 𝛿𝑣/𝑣𝑘 / ∑𝑘 𝑤𝑘 , with 𝑤𝑘 = max𝜀 CC𝑘 (coherence-weighted) or 𝑤𝑘 = 1 (unweighted). + + +837 Approach B (average the images). The pair stretch factor 𝜀𝑝 (𝑡) = arg max𝜀 [ 𝑁1 ∑𝑘 CC𝑘 (𝜀, 𝑡)] + 𝑐 + + +838 converts to 𝑥𝑝 (𝑡) = 𝛿𝑣/𝑣𝑝 (𝑡) via the same relation. + + +839 Network over pairs. With pair weights 𝑊𝑝 (e.g. mean coherence), + + ∑𝑝 𝑊𝑝 𝑥𝑝 ∑𝑝 𝑊𝑝 (𝑥𝑝 − 𝑥)̄ 2 (∑𝑝 𝑊𝑝 )2 + 𝑥̄ = , 2 + 𝑠 = , 𝑁eff = . (B.1) + ∑𝑝 𝑊𝑝 ∑𝑝 𝑊𝑝 ∑𝑝 𝑊𝑝2 + +840 The three uncertainty conventions used in Section 3.3 are the weighted standard error + √ +841 𝜎SE,𝑤 = 𝑠/√𝑁eff , the unweighted standard error 𝜎SE = std(𝑥𝑝 )/ 𝑁, and the standard + √ +842 deviation 𝜎SD = std(𝑥𝑝 ). They share the mean 𝑥̄ but obey 𝜎SD /𝜎SE = 𝑁. + + + + +843 APPENDIX C: SURVEY OF PROCESSING CHOICES ACROSS THE + +844 LITERATURE + + +845 Table A1 catalogues the processing choices of the ambient-noise 𝛿𝑣/𝑣 monitoring studies we + +846 surveyed: 103 rows for 102 publications, one publication (Obermann et al., 2013) contributing + +847 two rows for two distinct measurement set-ups (the full machine-readable version and + +848 provenance are distributed with the codameter package). It is the empirical basis for the + +849 paper’s claim that no convention is shared: the estimator, the frequency band, the coda + 52 M. A. Denolle +850 window, the reference scheme and — most unevenly of all — the uncertainty treatment vary + +851 study to study, and the last is frequently unreported. Every study is cited here. + + +852 The four measurement fields (frequency band, coda window, estimator and uncertainty + +853 treatment) were re-checked against the full text for the 82 studies we could read (open + +854 access plus institutional access); for those rows a blank or n/r'' means the value is + +855 genuinely not stated in the paper. The remaining rows were populated from + +856 abstracts and search metadata, wheren/r’ ’ means only that the value was not found + +857 in the abstract, not that the study failed to report it; those cells are flagged in the + +858 machine-readable table (measurement_source) and remain to be filled from the paywalled + +859 full texts. Because a cell populated from an abstract can only move from “n/r’ ’ to reported + +860 once the full text is read, the apparent under-reporting in the table is an upper bound on + +861 the true under-reporting; the verified rate is the one among the 82 full-text rows. + + Table A1: Processing choices of the 103 surveyed 𝛿𝑣/𝑣 studies (the literature survey under- + pinning this paper). Every study is cited; n/r = not reported in the source. Frequency band, + coda window, estimator, reference/stack scheme and uncertainty treatment are the choices + Section 3 shows to control the result. + + Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + + Brenguier et al. Piton de la 0.1-0.9 n/r (slope MWCS Daily stacks linear-slope + (2008b) Fournaise, La of dtau vs (doublet) referenced to uncertainty; exclude + Réunion tau; short long-term stack >0.04% + scanning + window) + Duputel et al. Piton de la 0.1–1 n/r Other Quasi-real-time n/r + (2009) Fournaise, La stacks vs reference + Réunion + Obermann et al. Piton de la 0.1-1.0 10-45 stretching Daily stacks, Weaver et al. + (2013) Fournaise, La referenced; coda coherence-based error + Réunion at increasing lapse formula + times + HotovecEllis Mount St. 1-10 (also windows doublet Stack across ~0.1% from SD of + et al. (2014) Helens, WA, 1-5, 5-10) after S (Snieder several hundred velocity fit + USA arrival; 2002) repeating- + >=5 with earthquake + CCC>0.65 families + (multiplets) + + continued on next page + Processing choices in seismic velocity monitoring 53 +Table A1 continued +Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + +HotovecEllis Mount St. 0.5-10 15 s stretching Combines reduced similarity (CC) +et al. (2015) Helens, WA, window repeating- in stretching window + USA starting 2 earthquake CWI + s after with + first ambient-noise + motion interferometry +Rivet et al. Piton de la 0.25-2 n/r MWCS Daily stacks vs coherency + +(2015) Fournaise, La reference; linear-regression error + Réunion network-averaged + dv/v +De Plaen et al. Piton de la 0.1-1.0, 5-35 MWCS n/r coherency + +(2016) Fournaise, La 0.5-1.0, (both linear-regression error + Réunion 1.0-2.0, branches) QC + (method also 2.0-4.0 + re Kawah Ijen) +Donaldson et al. Kīlauea 0.33-1.0 30 s MWCS Daily NCFs weighted dt-t +(2017) summit, window, (doublet) stacked over 3-day regression; + Hawaii, USA min lag = moving window coherence>0.65, + intersta- err<0.1 s thresholds + tion dist / + 0.8 km/s +Takano et al. Izu-Oshima, 0.5-1, 1-2, -20 to MWCS Cross-correlations error bars from +(2017) Japan 2-4 +20 2012–2015, coherency + multiple bands +Lesage et al. Volcán de 0.125-2 10-80 stretching Daily empirical noise from +(2018) Colima, cross-correlations; AVV fluctuations + Mexico 2013 stack as (~0.05%) + reference +De Plaen et al. Mt. Etna, 1.0-2.0 5-35 MWCS Daily cross-coherence + +(2019) Italy autocorrelations, squared misfit; reject + (2013–2014) 2-day linear stack dt err>0.1 s or + coh<0.6 +Donaldson et al. Northern 0.1-0.4, per-band stretching n/r reject dv/v when +(2019) Volcanic Zone 0.4-1.0, 1-2, (suppl. + MWCS stretched-ref CC<0.4 + (Askja/Bárðar- 2-4, 4-16 Table S1) + bunga), + Iceland +Olivier et al. Kīlauea, 0.08-1.2 30 s MWCS n/r (passive image CCF-coherence-based +(2019) Hawaii, USA windows; interferometry, uncertainty + (2018 start = daily) + eruption) dist/700 + m/s + 30 + s +Yates et al. Whakaari / 0.1-1.0 16 s MWCS n/r QC (err<0.1 s, +(2019) White Island, moving coh>0.7); + New Zealand windows error-weighted mean + within + 20-80 s +Feng et al. Kīlauea, 3-8 [-2.8:-0.4] stretching Jan 2017–Jun absolute error from +(2020) Hawaii, USA and 2018 NCFs stretching CC + [0.4:2.8] + (=[- + 14Dt:2Dt],[2Dt:14Dt]) +HotovecEllis Kīlauea, n/r n/r CWIRE Coda Wave n/r +et al. (2022) Hawaii, USA (stretching Interferometry + (2018 collapse) + damped with Repeating + LSQ) Earthquakes + (CWIRE), + per-cluster pairs + + continued on next page + 54 M. A. Denolle + Table A1 continued + Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + + Köpfli et al. Mount St. n/a n/a n/a (no Long-term NCF n/a + (2024) Helens, WA, (wavefield dv/v; stacks; many dv/v + USA amplitude companion series on a + features, is Makus common grid + not dv/v) 2024) + Yates et al. Mt. Ruapehu, 0.25-2.5 min lag 5 CWT n/r slope SD from + (2024) New Zealand (wavelet s, length (cross- covariance; coherence + (2005–2009) 0.1-8.0) 20 cycles wavelet) weighting + (e.g. 5-25 + at 1 Hz) + Yukutake et al. Izu-Oshima, 0.1-0.9, 20-40 MWCS Long-term 1-2 sigma errors as + (2025) Japan 0.5-2.0, interferometry inversion weights + (2003–2020) 1.0-4.0 stacks, 2003–2020 + Schaff & Beroza 1989 Mw 6.9 n/r 1.4 s doublet Repeating- formal slope SE; CC + (2004) Loma Prieta (unfiltered) moving earthquake weighting + aftershock windows doublets; delays vs + zone, through pre-mainshock + California coda repeaters + (also Parkfield + repeaters) + Pacheco & Theory / n/r n/r Other n/r n/r (analytical kernel) + Snieder (2005) acoustic + diffusion + model + Rubinstein & 2004 M6 n/r n/a doublet Repeating- CC>0.8 and SNR>4:1 + Beroza (2005) Parkfield (direct-S (moving- earthquake QC + earthquake, delays, window travel-time delays + San Andreas not coda) CC) before vs after + fault, mainshock + California + Wegler & Sens- Mid-Niigata 2-100 (2 Hz 5-14 stretching Daily day-to-day fluctuation + Schönfelder (Chuetsu) high-pass) autocorrelations ~0.1%; CC>0.5 + (2007) earthquake vs ~two-week + source region, pre-event + Japan; F-Net reference; grid + station KZK search (10000 + (~24 km) trials, dv/v… + Brenguier et al. Parkfield, San 0.1–0.9 n/r Stretching 1550-day reference Averaged over 78 + (2008a) Andreas fault, vs overlapping receiver pairs plus + California, 5-day moving 5-day segments + USA windows; 30-day + time resolution + Hadziioannou Laboratory 2.5 MHz 12.5-50 us stretching Noise-correlation analytic std of + et al. (2009) scattering gel ultrasonic (lab) + doublet stacking stretching-CC + (ultrasonic) (lab, not (compared) fluctuations + seismic + band) + Sawazaki et al. Western- n/r n/r Other Coda n/r + (2009) Tottori region, deconvolution of + Japan; surface vs 100-m + KiK-net borehole records + borehole + (surface + 100 + m); 2000 Mw + 6.6 mainshock + + continued on next page + Processing choices in seismic velocity monitoring 55 +Table A1 continued +Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + +Wegler et al. 2004 Mw 6.6 2-8 and 5-14 (2-8 stretching Daily auto-/cross- SD over Green’s-tensor +(2009) Mid-Niigata 0.1-0.5 Hz); correlations components; R>0.5 + earthquake 10-100 inverted daily for + source region, (0.1-0.5 2 months pre/post; + Japan; 6 Hz) pre-event reference + Hi-net/F-Net + stations <25 + km +Chen et al. Sichuan, n/r ~25 s MWCS Noise n/r +(2010) China — 2008 after cross-correlation + Mw 7.9 ballistic, stacking; + Wenchuan up to sub-array + earthquake +-200 s comparison (156 + fault zone lapse broadband + stations) +Nakata & NE Japan 1-13 n/a n/a (not >300 earthquakes SD of travel times over +Snieder (2011) (Honshu), (deconvo- coda/noise (Jan 1–May 26 events + KiK-net; 2011 lution dv/v) 2011); borehole-to- + Tohoku-Oki interfer- surface + earthquake ometry, deconvolution + direct + S-wave) +Rivet etal. Guerrero, 0.037-0.27 n/r (coda doublet n/r previous-epoch +(2011) Mexico (periods used, no (MWCS) referencing; no explicit + subduction 3.7-27 s) length) error bars + zone (2006 + M7.5 slow slip + event) +Hobiger et al. 2008 0.125-0.25, ten stretching Daily CC weighting; +(2012) Iwate-Miyagi 0.25-0.5, periods, cross-correlations 18-component weighted + Nairiku 0.5-1.0 starting vs long-term average + earthquake 7.5 reference Green’s + (Mw 6.9), NE periods function + Japan after + direct + wave +Minato et al. Southern 2-5 2-10 lag stretching n/r SD from +(2012) Tohoku pre/post-seismic values + (Fukushima/Ibaraki), + Japan; 58 + Hi-net + stations; 2011 + Tohoku-Oki +Obermann et al. Numerical 2-D 20 Hz 1.5 s stretching Averaged over 10 std over ten +(2013) elastic media central, ~12 windows, random medium random-media + (lunar-data Hz bw centered realizations per realizations + illustration) (numerical) ~1.8-6.6 s configuration +Brenguier et al. Vol- 0.1–0.9 n/r MWCS Daily Stress sensitivity +(2014) canic/geother- cross-correlations; ~0.001 MPa^-1 + mal regions of linear inferred; detailed dv/v + Honshu, inversion/regular- uncertainty n/r + Japan; 2011 ization for + Mw 9.0 continuous time + Tohoku-Oki series +Liu et al. (2014) Epicentral 0.125-1 (1-8 30-130 MWCS Noise 2-sigma SD across nine + region of 2008 s; subbands cross-correlation components + Mw 7.9 1-2,2-4,4-8 stacking (Aug + Wenchuan s) 2004 – Sep 2011) + earthquake, + China + + continued on next page + 56 M. A. Denolle + Table A1 continued + Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + + Taira et al. South Napa, 0.1-0.9 -60 to -20 MWCS MSNoise Jackknife 95% CI; + (2015) California and +20 cross-correlations; 2-sigma SD + (2014 Mw 6.0 to +60 decimated to 20 + South Napa Hz + earthquake) + Gassenmeier Station 1-3, 4-6, 10-15 (for stretching Daily Gaussian fit to + et al. (2016) PATCX, 7-10 4-6 Hz) (autocorre- autocorrelations; correlation values (CIs) + Atacama (primary lation two-step iterative + Desert, 4-6) CWI) reference + Northern + Chile (IPOC) + Hillers et al. San Jacinto 0.2-2 20-50 stretching Average-waveform P-value QC; cc>=0.85 + (2019) fault zone, (sub-bands (also and MWCS reference for inversion + California 0.2-0.4,0.4- 20-40,30- (doublet) stretching; MWCS + (after 2010 0.8,0.8- 50,40-60) also applied + M7.2 El 1.6,0.3-1.5) + Mayor- + Cucapah, + M5.4 Collins + Valley) + Wang et al. NE Honshu, period -400 to doublet Monthly SD error bars from + (2019) Japan (2011 bands 8-30 400 velocity-change 2009-2010 + Mw 9.0 s and 15-50 (moving estimates + Tohoku-Oki s 30 & 50 s) + earthquake) + Mao et al. Salton Sea 0.5-2.0, n/r (real wavelet Noise wavelet cross-spectrum + (2020) Geothermal 0.75-3.0, data); cross- cross-correlation amplitude weighting; + Field, 1.1-2.2, synthetic spectrum stacking coherence threshold + California 1.5-6.0, 18.65-35 (WCS) + (2009–2011) 2.0-8.0 + Poli et al. (2020) L’Aquila 0.5-1 start stretching n/r CC-weighting; cc>0.9 + region, central 10/20/30 (doublet retained + Italy (2009 s, length tested) + Mw 6.3 20/40/60 + L’Aquila s + earthquake) + Boschelli et al. Ridgecrest >1 (1 Hz n/r stretching Daily SD across + (2021) fault zone, high-pass) (variable autocorrelation non-overlapping + California lapse functions vs mean windows + (2019 Mw 7.1 window) waveform + Ridgecrest + earthquake) + Lu & Ben-Zion Ridgecrest, 8.0–12.0 3 (moving Other 10-min stacks; Standard deviations + (2021) California windows, adaptive Gaussian tracked; stabilized via + (2019 Mw 7.1 1.5 s step) smoothing (20 smoothing + Ridgecrest min growing to 24 + earthquake) hr over 3 days) + Sheng et al. San Jacinto >1 n/r wavelet Weekly stacked dt uncertainty as + (2022) fault, Anza (WTS) correlations with inverse weight + seismic gap, ~2-month + Southern smoothing + California + Mainsant et al. Pont-Bourquin 10-12 0.2-2 stretching Daily noise Weaver et al. (2011) + (2012) landslide, (analyzed (both correlograms CC-based error + Swiss Alps 4-25) sides) (cross-correlation (~1-2%) + (Switzerland) functions) + + continued on next page + Processing choices in seismic velocity monitoring 57 +Table A1 continued +Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + +Voisin et al. Avignonet / ~6-8 n/r Stretching Daily/seasonal Correlation-coefficient +(2016) Mas (annual stacks vs reference weighting; comparison + d’Avignonet dv/v with piezometer + landslide, pattern + Trièves best + (French Alps), resolved) + France +Harba & Pilecki Just- High- n/r (inter- Other Cross-correlation / Dispersion-inversion +(2016) Tęgoborze frequency ferometric interferometric misfit; comparison + landslide, seismic Green’s- stacks; dispersion with MASW + Carpathian noise function inversion + flysch, (~5-20+, retrieval) (neighbourhood + southern dispersion- algorithm) + Poland curve + range) +Bertello et al. Montaguto n/a (active- n/a n/a Time-lapse n/a +(2018) earthflow, source interferometry + + southern Italy ReMi/MASW time-lapse active + dispersion, MASW + not coda + dv/v) +Bièvre et al. Pont-Bourquin ~5-15 n/r Stretching Daily correlations, Correlation coefficient; +(2018) landslide, (surface- multi-year seasonal-cycle + Swiss Alps wave band; reference modeling to separate + (4.5-yr record) reported from precursors + sensitivity + to shallow + layer <=2 + m) +Colombero et al. Madonna del 2-20 0.5-2 (and Stretching Daily correlations, Correlation coefficient +(2018) Sasso cliff, (analysis); symmet- multi-year (~0.9 at low freq) as + NW Italian 2-4 ric -2 to reference reliability metric + Alps (Orta strongest -0.5) (2013-2016) + Lake), Italy annual + signal +Bontemps et al. Maca n/r n/r n/r Daily stacks vs n/r +(2020) slow-moving reference + Andean + landslide, + southern Peru + (3-yr dataset) +Fiolleau et al. Harmalière 1-12 (moni- 0.05-1.5 Stretching Hourly records, Correlation-coefficient +(2020) landslide, toring); daily averaging vs degradation tracked + French dv/v in 2-4 reference across bands; + Western Alps and 8-10 multi-parameter + (collapsed Nov bands; precursor timing + 2016) block + resonance + ~9-16 +Le Breton et al. Global review 1.3-20 end of stretching Daily stacks vs Weaver et al. (2011) +(2021) (9 landslides (commonly direct and long-term rms + SD over + monitored to 10-14; 0.1-1 waves to doublet reference pairs/windows; discard + date) for 5-10 (MWCS) CC<0.6 + large/deep) periods + (site- + dependent) +Xie et al. (2023) Rock slope, High- Sub- Stretching Short-window Decorrelation/CC + southwest frequency second to stacks for rapid checks; rapid-detection + China (~5-20) a few s detection confidence discussion + + continued on next page + 58 M. A. Denolle + Table A1 continued + Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + + Liu et al. (2026) Xishan Village 5-25 (raw 0.4-2.0 Stretching 20-min interval 95% confidence interval + landslide, 1-30); 15 CCFs vs reference (~0.05% uncertainty at + Sichuan Hz top ~15 (SNR>4 5 Hz) + Province, m, 5 Hz wave-packet + China 15-40 m selection) + Watlet et al. Hollin Hill 6-10 (plus n/r MWCS Time-lapse none (data report) + (2026) Landslide two interferometry + + Observatory, unspecified MASW between + North bands) recording periods + Yorkshire, UK + (2-yr) + De Wit & Open-pit mine n/r (high- n/r Stretching Time-lapse stacks Decorrelation/CC; + Snieder (2026) slope, frequency vs reference comparison with radar + Australia near- surface deformation + surface) + Sens- Merapi 0.5 Hz 2-8 stretching Daily autocorr vs SD over + Schönfelder Volcano, high-pass yearly reference non-overlapping + & Wegler (2006) Indonesia windows + Tsai (2011) Theoretical n/a (theory n/a n/a n/r n/a + model, applied of thermoe- (analytic + to southern lastic/hy- model, no + California drologic measure- + velocity ment) + change) + Hillers et al. TCDP n/r n/r n/r n/r n/r + (2014) borehole array, + Chelungpu + fault, Taiwan + Lecocq et al. Gräfenberg 0.1-0.8 20-100 MWCS Daily CCFs, LSQ slope error as + (2017) Array (and -20 (Brenguier 31-day rolling inverse-variance weight; + (GRA1-4), SE to -100) all-pairs) window bootstrap + Germany + (karst + limestone + aquifer) + Nimiya et al. Kyushu Island, 0.1-0.9 100 stretching Daily CCFs from SD over six 50-s + (2017) Japan (2016 (+MWCS 30-min segments; subwindows + Kumamoto check) 1-yr reference, + region) 30-day moving + stack + Wang et al. Japan 0.1-0.25 30 s MWCS Daily CCFs; ~1-yr none (QC only: + (2017) (nationwide; and 0.5-2.0 (0.1-0.25 reference, dt<=0.2 s, coh>=0.5) + strongest in Hz), 10 s moving-window + Kyushu/vol- (0.5-2 Hz) current stack + canic + zones) + Clements & De- San Gabriel 0.1-0.25 30 s MWCS Daily stacks vs none (QC only: + nolle (2018) Valley, and 0.5-2.0 (0.1-0.25 reference dt<=0.2 s, coh>=0.5) + California, Hz), 10 s + USA (0.5-2 Hz) + Kim & Lekic Gulf Coast 0.01-8 n/r stretching Multi-year (~20 none (grid-search CC + (2019) Aquifer, yr) record; max) + southern yearly-scale + Texas comparisons + (IU.HKT near + Houston), + USA + Andajani et al. Chugoku & 0.1-0.9 100 stretching n/r stretching CC as + (2020) Shikoku, SW quality indicator (no + Japan (Hi-net) error bars) + + continued on next page + Processing choices in seismic velocity monitoring 59 +Table A1 continued +Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + +GaubertBastide Crépieux- 2-5 n/a stretching Hourly eps_max +- sigma +et al. (2022) Charmy (ballistic correlations over (stretching variance) + water- Love- 19 days, two + production wave fill/drain cycles + field, Lyon, window, + France not coda) +Illien et al. Nepal 4-8 12 stretching ~3-yr continuous none (multi-reference +(2022) Himalaya (Chaku); periods time series stack) + (2015 Mw7.8 2-4 (~3 s) + Gorkha (Gumba) after + aftermath) 4-period + skip +Mao et al. Coastal Los 2-4 2-8 stretching Daily CCFs cc^2-weighted channel +(2022) Angeles basins, stacked over 20 mean (no explicit error + California, days, 5-day step; bars) + USA pairs <50 km +Clements & De- Statewide 2-4 2-8 stretching Daily stacks across cc^2-weighted channel +nolle (2023) California, ~700 stations vs mean (no explicit error + USA reference bars) + (1999-2021) +Delouche & Greece 0.33-1 (1-3 15-55 stretching n/r Weaver et al. (2011) +Stehly (2023) (aquifer s period) RMS error + monitoring + sites) +Ermert et al. Mexico City 0.5-1, 1-2, 4-10x and stretching Clustered (GMM) CC_best>0.6 QC; no +(2023) basin / Valley 2-4, 4-8 8-20x autocorrelation formal dv/v error + of Mexico longest stacks + period + (e.g. 8-16 + & 16-40 + s) +Fokker et al. Groningen, 1.3-1.6 n/r (coda stretching n/r standard error +(2023) The of cross- sigma/sqrt(n) + Netherlands coherence) +Zhang et al. Central 0.1-1.0 n/r MWCS Continuous SD (avg ~0.009%) +(2023) Oklahoma, (also (dynamic 2013-2022 record + USA 0.3-1.2, windows, + 0.5-1.5, 3.0 & 2.0 + 1.0-2.0) km/s) +Mao etal. Greater Los 0.1-0.3 300 s stretching Daily CCFs Weaver et al. (2011) +(2025) Angeles, window stacked, multi-day error formula + California, from step; two-decade + USA 1.3*t0 record +Mordret et al. Southwest 0.1-0.3 300 s stretching Daily Weaver et al. (2011) +(2016) Greenland ice window cross-correlations error formula + sheet from over ~2-year + 1.3*t0 record +James et al. Interior 3-30 (18 +-0.2 to MWCS Daily 95% CI from posterior +(2019) Alaska (Poker bands; 13 2.0 cross-correlations + Flat / Hz (center stacked; reference + Fairbanks inversion) lag) relative to Jan + area), USA 2014 +Guillemot et al. Gugla rock n/a n/a n/a (no Daily n/a +(2020) glacier, Valais, (resonance- dv/v correlograms from + Switzerland freq computed) hourly raw data + tracking, + not dv/v) + + continued on next page + 60 M. A. Denolle + Table A1 continued + Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + + Guillemot et al. Laurichard n/a n/a n/a (no PSD-based; n/a + (2021) (French Alps) (resonance- dv/v finite-element + and Gugla freq computed) modal modeling + (Swiss Alps) tracking, + rock glaciers not dv/v) + Lindner et al. Mt. Zugspitze, 2-8 -5 to 5 lag wavelet 15-year continuous 1 SD + (2021) German/Aus- (analysis cross- record; + trian 1-20) spectrum daily/seasonal + Alps (Morlet) stacks + Luo et al. (2023) Greenland Ice 0.1-1 (also 20-70 MWCS Daily fitted +-sigma; 95% CI + Sheet (GLISN 0.1-0.5, autocorrelations + stations) 1-2) stacked + Gassenmeier Ketzin CO2 1.5-3 moving stretching 1-hour segments Weaver et al. (2011); + et al. (2014) storage site windows cross-correlated, scaling-coeff CIs + (CO2SINK), after 300 stacked to daily + Brandenburg, m/s + Germany phase + Hillers et al. Basel deep n/r Coda of Stretching Daily noise Sensitivity-kernel + (2015) geothermal noise cor- correlations imaging of + (EGS) relations around 2006 velocity-change + reservoir, stimulation location + Switzerland + Obermann et al. St. Gallen 0.1-1 20 s stretching Daily none + (2015) geothermal window cross-correlations; + site, centered reference stacks + Switzerland ~15 s in + coda + Czarny et al. Underground 0.6-1.2 n/r Stretching Continuous n/r + (2016) coal mine, cross-correlations + Upper Silesia, over ~42 days + Poland + Olivier et al. Active tailings 0.25-1.0, 20 s (-40 MWCS Daily two-sigma SD; + (2017) storage facility 0.5-2.0, to -20 and (MSNoise) cross-correlations CC>0.85 rejection + (mine), South 0.75-3.0, 20 to 40) across array + Africa 1.0-4.0, + 1.5-6.0, + 2.0-8.0 + Taira et al. Salton Sea 0.25-1.0, 20 s (-40 MWCS Daily NCFs from two-sigma SD; + (2018) Geothermal 0.5-2.0, to -20 and (MSNoise) 30-min segments; CC>0.85 rejection + Field, 0.75-3.0, 20 to 40) 5-day stacks + California, 1.0-4.0, + USA 1.5-6.0, + 2.0-8.0 + Kristjánsdóttir Hellisheidi n/r n/r Stretching Daily correlations Seasonal and + et al. (2019) geothermal (MSNoise noise-source effects + field, SW workflow) discussed as caveats + Iceland + Snieder et al. theory + n/a (disper- n/a n/a (not a n/r n/a + (2002) ultrasonic lab sion/pre- velocity- + processing change + paper, no study) + dv/v) + Bensen et al. USArray test 0.1-0.9 6s MWCS daily WLS phase-fit error + (2007) data windows cross-correlation + (corrected ~6x) + overlap- temporal stacking + ping 3 + s + + continued on next page + Processing choices in seismic velocity monitoring 61 +Table A1 continued +Study Site / region Freq (Hz) Coda (s) Method Reference / Uncertainty + stack treatment + +Clarke et al. synthetic + 0.1-0.9 6s MWCS current stack vs WLS phase-fit error +(2011) real noise tests windows reference, (corrected ~6x) + overlap- weighted linear + ping 3 regression dt vs t + s +Hadziioannou urban noise 0.1-0.9 n/r stretching waveform remnant coherence +et al. (2011) autocorrela- (whole (and clustering to (CC) + tions coda doublet) enhance daily + t1-t2) stacks +Weaver et al. theory 0.05-0.5 up to stretching reference vs max CC>0.9 (no +(2011) t0=30 current correlation formal error) +Zhan et al. synthetic + 0.05-0.5 up to stretching reference vs max CC>0.9 (no +(2013) field examples t0=30 current formal error) +Lecocq et al. Piton de la synthetic 1-10 windowed daily CCF + WLS lag-vs-lapse; +(2014) Fournaise (Ricker lapse; sub- CC, reference stack CC>=0.6 + (validation) 12.5; noise windows stretching, + 0.5-30) 0.1-1.0 s DTW + (compared) +Mikesell et al. numerical 0.33-1.0 (dist/1.8)+20 + stretching n/a Weaver et al. (2011) +(2015) CWI examples (1-3 s) to 120 rms formula +Stehly et al. Wenchuan Mw 0.1-1.0 [15,35] stretching daily correlations CC>0.7 rejection; +(2015) 7.9 region (real); and (+MWCS curvelet-filtered ~+-0.1% significance + (test dataset) 0.15-0.65 [-35,-15] compare) before stacking + (synthetic) +Daskalakis et al. synthetic + n/r 1 s over- stretching normalized SD over 20 receivers +(2016) real noise (numerical lapping cross-correlation + study) windows functions +Obermann et al. 3-D wavefield 0.15-0.90 -60 to doublet + n/a Bayesian least-squares +(2016) simulations +60 Bayesian inversion; error bars + (doublet least- from inversion + over squares + coda) inversion + (Brenguier + 2014) +Obermann & review scale- lapse- Other reference and synthesizes error +Hillers (2019) dependent time/depth moving-stack sources: noise-source + depen- strategies reviewed variability, processing + dent choices, sensitivity + ker… +Jiang & Denolle benchmark vs user- user- Other linear/PWS/ro- offers multiple dv/v +(2020) MSNoise defined defined bust stacking; estimators so users can + reference + cross-check; + moving stacks parallel/HDF5 + reproducible pip… +Wang & Yao review n/r n/r stretching, reference and Bayesian least-squares +(2020) (review) (review)MWCS, stacking strategies / MCMC (review) + DTW, reviewed + WCS + (review) +Yuan et al. 2-D varies (e.g. 45-75 WCC, TS, n/a residuals vs truth over +(2021) heterogeneous 0.5-2.2) (example) DTW, realizations + half-space MWCS, + simulations WCS, + WTS, + WTDTW + (7 + compared) + 62 M. A. Denolle +862 DATA AVAILABILITY + + +863 All synthetics, estimators, and generated figures in this paper are implemented in the + +864 open-source Python package codameter (MIT license), openly available at https://github.c + +865 om/Denolle-Lab/codameter; each generated figure’s sidecar records its generating commit + +866 and numerical arrays. The figures and manuscript can originate from different revisions. + +867 python -m codameter.figures regenerates every generated figure with a .npz sidecar of its + +868 plotted arrays and a .json sidecar of its provenance; python -m codameter.calibration + +869 reproduces Table 5 (paper/data/calibration/); scripts/compare_gate1.py reproduces + +870 Table 7 from the daily products under paper/data/gate1/ and the published Clements + +871 & Denolle (2023) series archived there. The daily products and the three real-data figures + +872 were produced by the noisepy-dvv-cloud Gate 1 run from public Southern California Earth- + +873 quake Data Center waveforms; the products are available locally during this analysis but + +874 are not tracked in the repository. The exact Gate 1 run commit, run configuration and + +875 redistribution archive remain to be supplied; their current provenance limits are recorded + +876 in paper/data/gate1/README.md. A versioned archive is planned but has not yet been + +877 deposited. + + + + +878 Acknowledgements + + +879 [Funding, contributions and thanks to be completed by the author.] AI assistance: this + +880 manuscript was checked with the Denolle Group Pre-Submission Reviewer (v2.4, model + +881 Codex/GPT-6), an advisory AI tool, through one review iteration and a subsequent evidence + +882 reconciliation; final author adjudication remains to be recorded. The tool does not endorse + +883 manuscript validity. Code revisions and text edits in response to that review were drafted + Processing choices in seismic velocity monitoring 63 +884 with Claude (Anthropic) and Codex (OpenAI) under the author’s direction and are recorded + +885 in the repository history. + + + + +886 References + + +887 Andajani, R. D., Tsuji, T., Snieder, R., & Ikeda, T., 2020. Spatial and temporal influence + +888 of rainfall on crustal pore pressure based on seismic velocity monitoring, Earth, Planets + +889 and Space, 72, doi: 10.1186/s40623-020-01311-1. + + +890 Bensen, G. D., Ritzwoller, M. H., Barmin, M. P., Levshin, A. L., Lin, F., Moschetti, M. P., + +891 Shapiro, N. M., & Yang, Y., 2007. Processing seismic ambient noise data to obtain reliable + +892 broad-band surface wave dispersion measurements, Geophysical Journal International, + +893 169(3), 1239–1260, doi: 10.1111/j.1365-246X.2007.03374.x. + + +894 Bertello, L., Berti, M., Castellaro, S., & Squarzoni, G., 2018. Dynamics of an active earthflow + +895 inferred from surface wave monitoring, Journal of Geophysical Research: Earth Surface, + +896 123, 1811–1834, doi: 10.1029/2017jf004233. + + +897 Bièvre, G., Franz, M., Larose, E., Carrière, S., Jongmans, D., & Jaboyedoff, M., 2018. + +898 Influence of environmental parameters on the seismic velocity changes in a clayey mud- + +899 flow (pont-bourquin landslide, switzerland), Engineering Geology, 245, 248–257, doi: + +900 10.1016/j.enggeo.2018.08.013. + + +901 Bontemps, N., Lacroix, P., Larose, E., Jara, J., & Taipe, E., 2020. Rain and small earthquakes + +902 maintain a slow-moving landslide in a persistent critical state, Nature Communications, + +903 11, doi: 10.1038/s41467-020-14445-3. + 64 M. A. Denolle +904 Boschelli, J., Moschetti, M. P., & SensSchönfelder, C., 2021. Temporal seismic velocity + +905 variations: Recovery following from the 2019 mw 7.1 ridgecrest, california earthquake, + +906 Journal of Geophysical Research: Solid Earth, 126, doi: 10.1029/2020jb021465. + + +907 Brenguier, F., Campillo, M., Hadziioannou, C., Shapiro, N. M., Nadeau, R. M., & Larose, + +908 E., 2008a. Postseismic relaxation along the san andreas fault at parkfield from continuous + +909 seismological observations, Science, 321, 1478–1481, doi: 10.1126/science.1160943. + + +910 Brenguier, F., Shapiro, N. M., Campillo, M., Ferrazzini, V., Duputel, Z., Coutant, O., & + +911 Nercessian, A., 2008b. Towards forecasting volcanic eruptions using seismic noise, Nature + +912 Geoscience, 1, 126–130, doi: 10.1038/ngeo104. + + +913 Brenguier, F., Campillo, M., Takeda, T., Aoki, Y., Shapiro, N. M., Briand, X., Emoto, K., + +914 & Miyake, H., 2014. Mapping pressurized volcanic fluids from induced crustal seismic + +915 velocity drops, Science, 345(6192), 80–82, doi: 10.1126/science.1254073. + + +916 Chen, J. H., Froment, B., Liu, Q. Y., & Campillo, M., 2010. Distribution of seismic wave + +917 speed changes associated with the 12 may 2008 mw 7.9 wenchuan earthquake, Geophysical + +918 Research Letters, 37, doi: 10.1029/2010gl044582. + + +919 Clarke, D., Zaccarelli, L., Shapiro, N. M., & Brenguier, F., 2011. Assessment of resolution + +920 and accuracy of the moving window cross spectral technique for monitoring crustal temporal + +921 variations using ambient seismic noise, Geophysical Journal International, 186(2), 867–882, + +922 doi: 10.1111/j.1365-246X.2011.05074.x. + + +923 Clements, T. & Denolle, M. A., 2018. Tracking groundwater levels using the ambient seismic + +924 field, Geophysical Research Letters, 45(13), 6459–6465, doi: 10.1029/2018GL077706. + Processing choices in seismic velocity monitoring 65 +925 Clements, T. & Denolle, M. A., 2023. The seismic signature of california’s earth- + +926 quakes, droughts, and floods, Journal of Geophysical Research: Solid Earth, 128, doi: + +927 10.1029/2022jb025553. + + +928 Colombero, C., Baillet, L., Comina, C., Jongmans, D., Larose, E., Valentin, J., & Vinciguerra, + +929 S., 2018. Integration of ambient seismic noise monitoring, displacement and meteorological + +930 measurements to infer the temperature-controlled long-term evolution of a complex prone- + +931 to-fall cliff, Geophysical Journal International, 213, 1876–1897, doi: 10.1093/gji/ggy090. + + +932 Cubuk-Sabuncu, Y., Jónsdóttir, K., Caudron, C., Lecocq, T., Parks, M., Geirsson, H., & + +933 Mordret, A., 2021. Temporal seismic velocity changes during the 2020 rapid inflation at + +934 mt. þorbjörn-svartsengi, iceland, using seismic ambient noise, Geophysical Research Letters, + +935 48, e2020GL092265, doi: 10.1029/2020GL092265. + + +936 Czarny, R., Marcak, H., Nakata, N., Pilecki, Z., & Isakow, Z., 2016. Monitoring veloc- + +937 ity changes caused by underground coal mining using seismic noise, Pure and Applied + +938 Geophysics, 173, 1907–1916, doi: 10.1007/s00024-015-1234-3. + + +939 Daskalakis, E., Evangelidis, C., Garnier, J., Melis, N., Papanicolaou, G., & Tsogka, C., 2016. + +940 Robust seismic velocity change estimation using ambient noise recordings, Geophysical + +941 Journal International, 205, 1926–1936, doi: 10.1093/gji/ggw142. + + +942 De Plaen, R. S. M., Lecocq, T., Caudron, C., Ferrazzini, V., & Francis, O., 2016. Singlestation + +943 monitoring of volcanoes using seismic ambient noise, Geophysical Research Letters, 43, + +944 8511–8518, doi: 10.1002/2016gl070078. + + +945 De Plaen, R. S. M., Cannata, A., Cannavo’, F., Caudron, C., Lecocq, T., & Francis, + +946 O., 2019. Temporal changes of seismic velocity caused by volcanic activity at mt. etna + 66 M. A. Denolle +947 revealed by the autocorrelation of ambient seismic noise, Frontiers in Earth Science, 6, + +948 doi: 10.3389/feart.2018.00251. + + +949 De Wit, T. & Snieder, R., 2026. Did they blow it? time-lapse velocity variations dur- + +950 ing an open-pit mine slope failure using seismic noise interferometry, Seismica, 5, doi: + +951 10.26443/seismica.v5i1.1902. + + +952 Delouche, E. & Stehly, L., 2023. Seasonal seismic velocity variations measured using seismic + +953 noise autocorrelations to monitor the dynamic of aquifers in greece, Journal of Geophysical + +954 Research: Solid Earth, 128, doi: 10.1029/2023jb026759. + + +955 Denolle, M. A., Shi, Q., Clements, T., Viens, L., Rodriguez-Tribaldos, V., & Cotton, F., + +956 2025. Ambient field seismology in critical zone hydrological sciences, Comptes Rendus. + +957 Géoscience, 357, 425–451, doi: 10.5802/crgeos.310. + + +958 Donaldson, C., Caudron, C., Green, R. G., Thelen, W. A., & White, R. S., 2017. Relative + +959 seismic velocity variations correlate with deformation at kīlauea volcano, Science Advances, + +960 3, doi: 10.1126/sciadv.1700219. + + +961 Donaldson, C., Winder, T., Caudron, C., & White, R. S., 2019. Crustal seismic velocity + +962 responds to a magmatic intrusion and seasonal loading in icelands northern volcanic zone, + +963 Science Advances, 5, doi: 10.1126/sciadv.aax6642. + + +964 Duputel, Z., Ferrazzini, V., Brenguier, F., Shapiro, N., Campillo, M., & Nercessian, A., + +965 2009. Real time monitoring of relative velocity changes using ambient seismic noise at + +966 the piton de la fournaise volcano (la réunion) from january 2006 to june 2007, Journal of + +967 Volcanology and Geothermal Research, 184, 164–173, doi: 10.1016/j.jvolgeores.2008.11.024. + Processing choices in seismic velocity monitoring 67 +968 Ermert, L. A., Cabral-Cano, E., Chaussard, E., Solano-Rojas, D., Quintanar, L., + +969 Morales Padilla, D., Fernández-Torres, E. A., & Denolle, M. A., 2023. Probing envi- + +970 ronmental and tectonic changes underneath mexico city with the urban seismic field, Solid + +971 Earth, 14, 529–549, doi: 10.5194/se-14-529-2023. + + +972 Feng, K.-F., Huang, H.-H., & Wu, Y.-M., 2020. Detecting pre-eruptive magmatic processes + +973 of the 2018 eruption at kilauea, hawaii volcano with ambient noise interferometry, Earth, + +974 Planets and Space, 72, doi: 10.1186/s40623-020-01199-x. + + +975 Fiolleau, S., Jongmans, D., Bièvre, G., Chambon, G., Baillet, L., & Vial, B., 2020. Seismic + +976 characterization of a clay-block rupture in harmalière landslide, french western alps, + +977 Geophysical Journal International, 221, 1777–1788, doi: 10.1093/gji/ggaa050. + + +978 Fokker, E., Ruigrok, E., Hawkins, R., & Trampert, J., 2023. 4d physicsbased pore pressure + +979 monitoring using passive image interferometry, Geophysical Research Letters, 50, doi: + +980 10.1029/2022gl101254. + + +981 Gassenmeier, M., Sens-Schönfelder, C., Delatre, M., & Korn, M., 2014. Monitoring of + +982 environmental influences on seismic velocity at the geological storage site for co2 in ketzin + +983 (germany) with ambient seismic noise, Geophysical Journal International, 200, 524–533, + +984 doi: 10.1093/gji/ggu413. + + +985 Gassenmeier, M., Sens-Schönfelder, C., Eulenfeld, T., Bartsch, M., Victor, P., Tilmann, F., + +986 & Korn, M., 2016. Field observations of seismic velocity changes caused by shaking-induced + +987 damage and healing due to mesoscopic nonlinearity, Geophysical Journal International, + +988 204, 1490–1502, doi: 10.1093/gji/ggv529. + + +989 Gassmann, F., 1951. Über die elastizität poröser medien, Vierteljahrsschrift der Natur- + 68 M. A. Denolle +990 forschenden Gesellschaft in Zürich, 96, 1–23. + + +991 GaubertBastide, T., Garambois, S., Bordes, C., Voisin, C., Oxarango, L., Brito, D., & + +992 Roux, P., 2022. Highresolution monitoring of controlled water table variations from dense + +993 seismicnoise acquisitions, Water Resources Research, 58, doi: 10.1029/2021wr030680. + + +994 Gelman, A. & Loken, E., 2013. The garden of forking paths, Department of Statistics, + +995 Columbia University (working paper). + + +996 Guillemot, A., Helmstetter, A., Larose, É., Baillet, L., Garambois, S., Mayoraz, R., & + +997 Delaloye, R., 2020. Seismic monitoring in the gugla rock glacier (switzerland): ambient + +998 noise correlation, microseismicity and modelling, Geophysical Journal International, 221, + +999 1719–1735, doi: 10.1093/gji/ggaa097. + + +1000 Guillemot, A., Baillet, L., Garambois, S., Bodin, X., Helmstetter, A., Mayoraz, R., & Larose, + +1001 E., 2021. Modal sensitivity of rock glaciers to elastic changes from spectral seismic noise + +1002 monitoring and modeling, The Cryosphere, 15, 501–529, doi: 10.5194/tc-15-501-2021. + + +1003 Hadziioannou, C., Larose, E., Coutant, O., Roux, P., & Campillo, M., 2009. Stability of + +1004 monitoring weak changes in multiply scattering media with ambient noise correlation: + +1005 Laboratory experiments, The Journal of the Acoustical Society of America, 125, 3688–3695, + +1006 doi: 10.1121/1.3125345. + + +1007 Hadziioannou, C., Larose, E., Baig, A., Roux, P., & Campillo, M., 2011. Improving temporal + +1008 resolution in ambient noise monitoring of seismic wave speed, Journal of Geophysical + +1009 Research: Solid Earth, 116(B7), B07304, doi: 10.1029/2011JB008200. + + +1010 Harba, P. & Pilecki, Z., 2016. Assessment of timespatial changes of shear wave velocities + Processing choices in seismic velocity monitoring 69 +1011 of flysch formation prone to mass movements by seismic interferometry with the use of + +1012 ambient noise, Landslides, 14, 1225–1233, doi: 10.1007/s10346-016-0779-2. + + +1013 Hennino, R., Trégourès, N., Shapiro, N. M., Margerin, L., Campillo, M., van Tiggelen, B. A., + +1014 & Weaver, R. L., 2001. Observation of equipartition of seismic waves, Physical Review + +1015 Letters, 86, 3447–3450, doi: 10.1103/PhysRevLett.86.3447. + + +1016 Hillers, G., Campillo, M., & Ma, K.-F., 2014. Seismic velocity variations at tcdp are + +1017 controlled by mjo driven precipitation pattern and high fluid discharge properties, Earth + +1018 and Planetary Science Letters, 391, 121–127, doi: 10.1016/j.epsl.2014.01.040. + + +1019 Hillers, G., Husen, S., Obermann, A., Planès, T., Larose, E., & Campillo, M., 2015. Noise- + +1020 based monitoring and imaging of aseismic transient deformation induced by the 2006 basel + +1021 reservoir stimulation, Geophysics, 80, KS51–KS68, doi: 10.1190/geo2014-0455.1. + + +1022 Hillers, G., Campillo, M., Brenguier, F., Moreau, L., Agnew, D. C., & BenZion, Y., 2019. + +1023 Seismic velocity change patterns along the san jacinto fault zone following the 2010 m7.2 + +1024 el mayorcucapah and m5.4 collins valley earthquakes, Journal of Geophysical Research: + +1025 Solid Earth, 124, 7171–7192, doi: 10.1029/2018jb017143. + + +1026 Hobiger, M., Wegler, U., Shiomi, K., & Nakahara, H., 2012. Coseismic and postseismic + +1027 elastic wave velocity variations caused by the 2008 iwatemiyagi nairiku earthquake, japan, + +1028 Journal of Geophysical Research: Solid Earth, 117, doi: 10.1029/2012jb009402. + + +1029 HotovecEllis, A. J., Gomberg, J., Vidale, J. E., & Creager, K. C., 2014. A continuous + +1030 record of intereruption velocity change at mount st. helens from coda wave interferometry, + +1031 Journal of Geophysical Research: Solid Earth, 119, 2199–2214, doi: 10.1002/2013jb010742. + 70 M. A. Denolle +1032 HotovecEllis, A. J., Vidale, J. E., Gomberg, J., Thelen, W., & Moran, S. C., 2015. Changes + +1033 in seismic velocity during the first 14 months of the 20042008 eruption of mount st. + +1034 helens, washington, Journal of Geophysical Research: Solid Earth, 120, 6226–6240, doi: + +1035 10.1002/2015jb012101. + + +1036 HotovecEllis, A. J., Shiro, B. R., Shelly, D. R., Anderson, K. R., Haney, M. M., Thelen, + +1037 W. A., MontgomeryBrown, E. K., & Johanson, I. A., 2022. Earthquakederived seismic + +1038 velocity changes during the 2018 caldera collapse of kīlauea volcano, Journal of Geophysical + +1039 Research: Solid Earth, 127, doi: 10.1029/2021jb023324. + + +1040 Illien, L., SensSchönfelder, C., Andermann, C., Marc, O., Cook, K. L., Adhikari, L. B., + +1041 & Hovius, N., 2022. Seismic velocity recovery in the subsurface: Transient damage and + +1042 groundwater drainage following the 2015 gorkha earthquake, nepal, Journal of Geophysical + +1043 Research: Solid Earth, 127, doi: 10.1029/2021jb023402. + + +1044 James, S. R., Knox, H. A., Abbott, R. E., & Screaton, E. J., 2017. Improved moving window + +1045 cross-spectral analysis for resolving large temporal seismic velocity changes in permafrost, + +1046 Geophysical Research Letters, 44(9), 4018–4026, doi: 10.1002/2016GL072468. + + +1047 James, S. R., Knox, H. A., Abbott, R. E., Panning, M. P., & Screaton, E. J., 2019. Insights + +1048 into permafrost and seasonal activelayer dynamics from ambient seismic noise monitoring, + +1049 Journal of Geophysical Research: Earth Surface, 124, 1798–1816, doi: 10.1029/2019jf005051. + + +1050 Jiang, C. & Denolle, M. A., 2020. NoisePy: a new high-performance python tool + +1051 for ambient-noise seismology, Seismological Research Letters, 91(3), 1853–1866, doi: + +1052 10.1785/0220190364. + + +1053 Kidiwela, M., Denolle, M. A., Wilcock, W. S. D., & Feng, K. F., 2026. Active protothrusts + Processing choices in seismic velocity monitoring 71 +1054 and fluid highways: Seismic noise reveals hidden subduction dynamics in cascadia, Science + +1055 Advances, 12(9), eaea3684, doi: 10.1126/sciadv.aea3684. + + +1056 Kim, D. & Lekic, V., 2019. Groundwater variations from autocorrelation and receiver + +1057 functions, Geophysical Research Letters, 46, 13722–13729, doi: 10.1029/2019gl084719. + + +1058 Köpfli, M., Denolle, M. A., Thelen, W. A., Makus, P., & Malone, S. D., 2024. Examining + +1059 22 years of ambient seismic wavefield at mount st. helens, Seismological Research Letters, + +1060 95, 2622–2636, doi: 10.1785/0220240079. + + +1061 Kristjánsdóttir et al., 2019. https://ui.adsabs.harvard.edu/abs/2019EGUGA..2118643K/ + +1062 abstract, dv/v monitoring study (Geothermal wastewater reinjection (water-volume / + +1063 pore-pressure increase)). + + +1064 Le Breton, M., Bontemps, N., Guillemot, A., Baillet, L., & Larose, É., 2021. Landslide + +1065 monitoring using seismic ambient noise correlation: challenges and applications, Earth- + +1066 Science Reviews, 216, 103518, doi: 10.1016/j.earscirev.2021.103518. + + +1067 Lecocq, T., Caudron, C., & Brenguier, F., 2014. MSNoise, a Python package for monitoring + +1068 seismic velocity changes using ambient seismic noise, Seismological Research Letters, 85(3), + +1069 715–726, doi: 10.1785/0220130073. + + +1070 Lecocq, T., Longuevergne, L., Pedersen, H. A., Brenguier, F., & Stammler, K., 2017. + +1071 Monitoring ground water storage at mesoscale using seismic noise: 30 years of continuous + +1072 observation and thermo-elastic and hydrological modeling, Scientific Reports, 7, doi: + +1073 10.1038/s41598-017-14468-9. + + +1074 Lesage, P., Carrara, A., Pinel, V., & Arámbula-Mendoza, R., 2018. Absence of detectable + 72 M. A. Denolle +1075 precursory deformation and velocity variation before the large dome collapse of july 2015 + +1076 at volcán de colima, mexico, Frontiers in Earth Science, 6, doi: 10.3389/feart.2018.00093. + + +1077 Lin, F.-C., Moschetti, M. P., & Ritzwoller, M. H., 2008. Surface wave tomography of + +1078 the western United States from ambient seismic noise: Rayleigh and Love wave phase + +1079 velocity maps, Geophysical Journal International, 173(1), 281–298, doi: 10.1111/j.1365- + +1080 246X.2008.03720.x. + + +1081 Lindner, F., Wassermann, J., & Igel, H., 2021. Seasonal freezethaw cycles and permafrost + +1082 degradation on mt. zugspitze (german/austrian alps) revealed by singlestation seismic + +1083 monitoring, Geophysical Research Letters, 48, doi: 10.1029/2021gl094659. + + +1084 Liu, Z., Huang, J., Peng, Z., & Su, J., 2014. Seismic velocity changes in the epicentral region + +1085 of the 2008 wenchuan earthquake measured from threecomponent ambient noise correlation + +1086 techniques, Geophysical Research Letters, 41, 37–42, doi: 10.1002/2013gl058682. + + +1087 Liu, Z., Li, H., Liang, C., Zhang, T., Jiang, H., & Huang, H., 2026. Enhanced visualization + +1088 of rainfall infiltration in landslides using high-resolution 4-d noise-based velocity change + +1089 imaging, Geophysical Journal International, 245, doi: 10.1093/gji/ggag037. + + +1090 Lobkis, O. I. & Weaver, R. L., 2003. Coda-wave interferometry in finite solids: Recovery + +1091 of P-to-S conversion rates in an elastodynamic billiard, Physical Review Letters, 90(25), + +1092 254302, doi: 10.1103/PhysRevLett.90.254302. + + +1093 Lu, Y. & Ben-Zion, Y., 2021. Regional seismic velocity changes following the 2019 mw 7.1 + +1094 ridgecrest, california earthquake from autocorrelations and p/s converted waves, Geophysical + +1095 Journal International, 228, 620–630, doi: 10.1093/gji/ggab350. + Processing choices in seismic velocity monitoring 73 +1096 Luo, B., Zhang, S., & Zhu, H., 2023. Monitoring seasonal fluctuation and longterm trends + +1097 for the greenland ice sheet using seismic noise autocorrelations, Geophysical Research + +1098 Letters, 50, doi: 10.1029/2022gl102146. + + +1099 Mainsant, G., Larose, E., Brönnimann, C., Jongmans, D., Michoud, C., & Jaboyedoff, M., + +1100 2012. Ambient seismic noise monitoring of a clay landslide: Toward failure prediction, + +1101 Journal of Geophysical Research: Earth Surface, 117, doi: 10.1029/2011jf002159. + + +1102 Mao, S., Campillo, M., van der Hilst, R. D., Brenguier, F., Stehly, L., & Hillers, G., 2019. + +1103 High temporal resolution monitoring of small variations in crustal strain by dense seismic + +1104 arrays, Geophysical Research Letters, 46(1), 128–137, doi: 10.1029/2018GL079944. + + +1105 Mao, S., Mordret, A., Campillo, M., Fang, H., & van der Hilst, R. D., 2020. On + +1106 the measurement of seismic traveltime changes in the time–frequency domain with + +1107 wavelet cross-spectrum analysis, Geophysical Journal International, 221(1), 550–568, + +1108 doi: 10.1093/gji/ggz495. + + +1109 Mao, S., Lecointre, A., van der Hilst, R. D., & Campillo, M., 2022. Space-time monitoring + +1110 of groundwater fluctuations with passive seismic interferometry, Nature Communications, + +1111 13, doi: 10.1038/s41467-022-32194-3. + + +1112 Mao, S., Ellsworth, W. L., Zheng, Y., & Beroza, G. C., 2025. Depth-dependent seismic + +1113 sensing of groundwater recovery from the atmospheric-river storms of 2023, Science, 387, + +1114 758–763, doi: 10.1126/science.adr6139. + + +1115 Margerin, L., Campillo, M., & Van Tiggelen, B., 1998. Radiative transfer and diffusion of + +1116 waves in a layered medium: new insight into coda q, Geophysical Journal International, + +1117 134(2), 596–612, doi: 10.1046/j.1365-246x.1998.00571.x. + 74 M. A. Denolle +1118 Margerin, L., Bajaras, A., & Campillo, M., 2019. A scalar radiative transfer model including + +1119 the coupling between surface and body waves, Geophysical Journal International, 219(2), + +1120 1092–1108, doi: 10.1093/gji/ggz348. + + +1121 Mavko, G., Mukerji, T., & Dvorkin, J., 2009. The Rock Physics Handbook: Tools + +1122 for Seismic Analysis of Porous Media, Cambridge University Press, 2nd edition., doi: + +1123 10.1017/CBO9780511626753. + + +1124 Mikesell, T. D., Malcolm, A. E., Yang, D., & Haney, M. M., 2015. A comparison of + +1125 methods to estimate seismic phase delays: numerical examples for coda wave interferometry, + +1126 Geophysical Journal International, 202(1), 347–360, doi: 10.1093/gji/ggv138. + + +1127 Minato, S., Tsuji, T., Ohmi, S., & Matsuoka, T., 2012. Monitoring seismic velocity change + +1128 caused by the 2011 tohokuoki earthquake using ambient noise records, Geophysical Research + +1129 Letters, 39, doi: 10.1029/2012gl051405. + + +1130 Mordret, A., Mikesell, T. D., Harig, C., Lipovsky, B. P., & Prieto, G. A., 2016. Monitoring + +1131 southwest greenlands ice sheet melt with ambient seismic noise, Science Advances, 2, doi: + +1132 10.1126/sciadv.1501538. + + +1133 Moreau, L., Stehly, L., Boué, P., Lu, Y., Larose, E., & Campillo, M., 2017. Improving + +1134 ambient noise correlation functions with an SVD-based Wiener filter, Geophysical Journal + +1135 International, 211(1), 418–426, doi: 10.1093/gji/ggx306. + + +1136 Nakata, N. & Snieder, R., 2011. Near-surface weakening in japan after the 2011 tohoku-oki + +1137 earthquake, Geophysical Research Letters, 38, n/a–n/a, doi: 10.1029/2011gl048800. + + +1138 Nimiya, H., Ikeda, T., & Tsuji, T., 2017. Spatial and temporal seismic velocity changes on + Processing choices in seismic velocity monitoring 75 +1139 kyushu island during the 2016 kumamoto earthquake, Science Advances, 3, doi: 10.1126/sci- + +1140 adv.1700813. + + +1141 Obermann & Hillers, 2019. Seismic time-lapse interferometry across scales, Advances in + +1142 Geophysics, pp. 65–143, doi: 10.1016/bs.agph.2019.06.001. + + +1143 Obermann, A., Planès, T., Larose, E., Sens-Schönfelder, C., & Campillo, M., 2013. Depth + +1144 sensitivity of seismic coda waves to velocity perturbations in an elastic heterogeneous + +1145 medium, Geophysical Journal International, 194(1), 372–382, doi: 10.1093/gji/ggt043. + + +1146 Obermann, A., Kraft, T., Larose, E., & Wiemer, S., 2015. Potential of ambient seismic noise + +1147 techniques to monitor the st. gallen geothermal site (switzerland), Journal of Geophysical + +1148 Research: Solid Earth, 120, 4301–4316, doi: 10.1002/2014jb011817. + + +1149 Obermann, A., Planès, T., Hadziioannou, C., & Campillo, M., 2016. Lapse-time-dependent + +1150 coda-wave depth sensitivity to local velocity perturbations in 3-d heterogeneous elastic + +1151 media, Geophysical Journal International, 207(1), 59–66, doi: 10.1093/gji/ggw264. + + +1152 Okubo, K., Delbridge, B. G., & Denolle, M. A., 2024. Monitoring velocity change over 20 + +1153 years at parkfield, Journal of Geophysical Research: Solid Earth, 129(4), e2023JB028084, + +1154 doi: 10.1029/2023JB028084. + + +1155 Olivier, G., Brenguier, F., de Wit, T., & Lynch, R., 2017. Monitoring the stability of + +1156 tailings dam walls with ambient seismic noise, The Leading Edge, 36, 350a1–350a6, doi: + +1157 10.1190/tle36040350a1.1. + + +1158 Olivier, G., Brenguier, F., Carey, R., Okubo, P., & Donaldson, C., 2019. Decrease in seismic + +1159 velocity observed prior to the 2018 eruption of kīlauea volcano with ambient seismic noise + 76 M. A. Denolle +1160 interferometry, Geophysical Research Letters, 46, 3734–3744, doi: 10.1029/2018gl081609. + + +1161 Ouellet, S. M., Dettmer, J., Olivier, G., de Wit, T., & Lato, M., 2022. Advanced monitoring + +1162 of tailings dam performance using seismic noise and stress models, Communications Earth + +1163 & Environment, 3, 301, doi: 10.1038/s43247-022-00629-w. + + +1164 Paasschens, J. C. J., 1997. Solution of the time-dependent boltzmann equation, Physical + +1165 Review E, 56(1), 1135–1141, doi: 10.1103/PhysRevE.56.1135. + + +1166 Pacheco, C. & Snieder, R., 2005. Time-lapse travel time change of multiply scattered + +1167 acoustic waves, The Journal of the Acoustical Society of America, 118(3), 1300–1310, doi: + +1168 10.1121/1.1979437. + + +1169 Planès, T., Mooney, M. A., Rittgers, J. B. R., Parekh, M. L., Behm, M., & Snieder, R., + +1170 2016. Time-lapse monitoring of internal erosion in earthen dams and levees using ambient + +1171 seismic noise, Géotechnique, 66(4), 301–312, doi: 10.1680/jgeot.14.P.268. + + +1172 Poli, P., Marguin, V., Wang, Q., D’Agostino, N., & Johnson, P., 2020. Seasonal and + +1173 coseismic velocity variation in the region of l’aquila from single station measurements and + +1174 implications for crustal rheology, Journal of Geophysical Research: Solid Earth, 125, doi: + +1175 10.1029/2019jb019316. + + +1176 Poupinet, G., Ellsworth, W. L., & Frechet, J., 1984. Monitoring velocity variations in the + +1177 crust using earthquake doublets: An application to the Calaveras fault, California, Journal + +1178 of Geophysical Research: Solid Earth, 89(B7), 5719–5731, doi: 10.1029/jb089ib07p05719. + + +1179 Rivet, D., Campillo, M., Shapiro, N. M., Cruz-Atienza, V., Radiguet, M., Cotte, N., & + +1180 Kostoglodov, V., 2011. Seismic evidence of nonlinear crustal deformation during a large slow + Processing choices in seismic velocity monitoring 77 +1181 slip event in mexico, Geophysical Research Letters, 38, n/a–n/a, doi: 10.1029/2011gl047151. + + +1182 Rivet, D., Brenguier, F., Clarke, D., Shapiro, N. M., & Peltier, A., 2014. Long-term dynamics + +1183 of Piton de la Fournaise volcano from 13 years of seismic velocity change measurements + +1184 and GPS observations, Journal of Geophysical Research: Solid Earth, 119(10), 7654–7666, + +1185 doi: 10.1002/2014JB011307. + + +1186 Rivet, D., Brenguier, F., & Cappa, F., 2015. Improved detection of preeruptive seismic + +1187 velocity drops at the piton de la fournaise volcano, Geophysical Research Letters, 42, + +1188 6332–6339, doi: 10.1002/2015gl064835. + + +1189 Rubinstein, J. L. & Beroza, G. C., 2005. Depth constraints on nonlinear strong ground + +1190 motion from the 2004 parkfield earthquake, Geophysical Research Letters, 32, doi: + +1191 10.1029/2005gl023189. + + +1192 Sato, H., 1993. Energy transportation in one- and two-dimensional scattering media: analytic + +1193 solutions of the multiple isotropic scattering model, Geophysical Journal International, + +1194 112(1), 141–146, doi: 10.1111/j.1365-246X.1993.tb01443.x. + + +1195 Sawazaki, K., Sato, H., Nakahara, H., & Nishimura, T., 2009. Time-lapse changes of + +1196 seismic velocity in the shallow ground caused by strong ground motion shock of the 2000 + +1197 western-tottori earthquake, japan, as revealed from coda deconvolution analysis, Bulletin + +1198 of the Seismological Society of America, 99, 352–366, doi: 10.1785/0120080058. + + +1199 Schaff, D. P. & Beroza, G. C., 2004. Coseismic and postseismic velocity changes mea- + +1200 sured by repeating earthquakes, Journal of Geophysical Research: Solid Earth, 109, doi: + +1201 10.1029/2004jb003011. + 78 M. A. Denolle +1202 Sens-Schönfelder, C. & Wegler, U., 2006. Passive image interferometry and seasonal + +1203 variations of seismic velocities at Merapi volcano, Indonesia, Geophysical Research Letters, + +1204 33(21), L21302, doi: 10.1029/2006GL027797. + + +1205 Sens-Schönfelder, C., Pomponi, E., & Peltier, A., 2014. Dynamics of Piton de la Fournaise + +1206 volcano observed by passive image interferometry with multiple references, Journal of + +1207 Volcanology and Geothermal Research, 276, 32–45, doi: 10.1016/j.jvolgeores.2014.02.012. + + +1208 Sheng, Y., Mordret, A., Sager, K., Brenguier, F., Boué, P., Rousset, B., Vernon, F., + +1209 Higueret, Q., & BenZion, Y., 2022. Monitoring seismic velocity changes across the + +1210 san jacinto fault using traingenerated seismic tremors, Geophysical Research Letters, 49, + +1211 doi: 10.1029/2022gl098509. + + +1212 Snieder, R., Grêt, A., Douma, H., & Scales, J., 2002. Coda wave interferometry for + +1213 estimating nonlinear behavior in seismic velocity, Science, 295(5563), 2253–2255, doi: + +1214 10.1126/science.1070015. + + +1215 Steegen, S., Tuerlinckx, F., Gelman, A., & Vanpaemel, W., 2016. Increasing transparency + +1216 through a multiverse analysis, Perspectives on Psychological Science, 11(5), 702–712, doi: + +1217 10.1177/1745691616658637. + + +1218 Stehly, L., Campillo, M., & Shapiro, N. M., 2006. A study of the seismic noise from its + +1219 long-range correlation properties, Journal of Geophysical Research, 111, B10306, doi: + +1220 10.1029/2005JB004237. + + +1221 Stehly, L., Froment, B., Campillo, M., Liu, Q. Y., & Chen, J. H., 2015. Monitoring seismic + +1222 wave velocity changes associated with the Mw 7.9 Wenchuan earthquake: increasing + Processing choices in seismic velocity monitoring 79 +1223 the temporal resolution using curvelet filters, Geophysical Journal International, 201(3), + +1224 1939–1949, doi: 10.1093/gji/ggv110. + + +1225 Taira, T., Brenguier, F., & Kong, Q., 2015. Ambient noisebased monitoring of seismic + +1226 velocity changes associated with the 2014 mw 6.0 south napa earthquake, Geophysical + +1227 Research Letters, 42, 6997–7004, doi: 10.1002/2015gl065308. + + +1228 Taira, T., Nayak, A., Brenguier, F., & Manga, M., 2018. Monitoring reservoir response to + +1229 earthquakes and fluid extraction, salton sea geothermal field, california, Science Advances, + +1230 4, doi: 10.1126/sciadv.1701536. + + +1231 Takano, T., Nishimura, T., & Nakahara, H., 2017. Seismic velocity changes concentrated + +1232 at the shallow structure as inferred from correlation analyses of ambient noise during + +1233 volcano deformation at izuoshima, japan, Journal of Geophysical Research: Solid Earth, + +1234 122, 6721–6736, doi: 10.1002/2017jb014340. + + +1235 Tsai, V. C., 2011. A model for seasonal changes in gps positions and seismic wave speeds + +1236 due to thermoelastic and hydrologic variations, Journal of Geophysical Research, 116, doi: + +1237 10.1029/2010jb008156. + + +1238 Tsuji, T., Ikeda, T., Matsuura, R., Mukumoto, K., Hutapea, F. L., Kimura, T., Yamaoka, K., + +1239 & Shinohara, M., 2021. Continuous monitoring system for safe managements of CO2 storage + +1240 and geothermal reservoirs, Scientific Reports, 11, 19120, doi: 10.1038/s41598-021-97881-5. + + +1241 Viens, L. & Van Houtte, C., 2020. Denoising ambient seismic field correlation functions + +1242 with convolutional autoencoders, Geophysical Journal International, 220(3), 1521–1535, + +1243 doi: 10.1093/gji/ggz509. + 80 M. A. Denolle +1244 Voisin, C., Garambois, S., Massey, C., & Brossier, R., 2016. Seismic noise monitoring of + +1245 the water table in a deep-seated, slow-moving landslide, Interpretation, 4, SJ67–SJ76, doi: + +1246 10.1190/int-2016-0010.1. + + +1247 Wang, Q., Brenguier, F., Campillo, M., Lecointre, A., Takeda, T., & Aoki, Y., 2017. Seasonal + +1248 crustal seismic velocity changes throughout japan, Journal of Geophysical Research: Solid + +1249 Earth, 122, 7987–8002, doi: 10.1002/2017jb014307. + + +1250 Wang, Q., Campillo, M., Brenguier, F., Lecointre, A., Takeda, T., & Hashima, A., 2019. + +1251 Evidence of changes of seismic properties in the entire crust beneath japan after the mw 9.0, + +1252 2011 tohokuoki earthquake, Journal of Geophysical Research: Solid Earth, 124, 8924–8941, + +1253 doi: 10.1029/2019jb017803. + + +1254 Wang, Q.-Y. & Yao, H., 2020. Monitoring of velocity changes based on seismic ambi- + +1255 ent noise: A brief review and perspective, Earth and Planetary Physics, 4, 1–11, doi: + +1256 10.26464/epp2020048. + + +1257 Watlet, A., Whiteley, J., Dashwood, B., Morgan, D., Lane, V., Finch, L., Gunn, D., Lecocq, + +1258 T., & Chambers, J., 2026. Seismic response of a slow-moving landslide: exploring data + +1259 from two years of seismic monitoring at the hollin hill landslide observatory (uk), Seismica, + +1260 5, doi: 10.26443/seismica.v5i1.1478. + + +1261 Weaver, R. L., Hadziioannou, C., Larose, E., & Campillo, M., 2011. On the precision of + +1262 noise correlation interferometry, Geophysical Journal International, 185(3), 1384–1392, + +1263 doi: 10.1111/j.1365-246X.2011.05015.x. + + +1264 Wegler, U. & Sens-Schönfelder, C., 2007. Fault zone monitoring with passive image + Processing choices in seismic velocity monitoring 81 +1265 interferometry, Geophysical Journal International, 168, 1029–1033, doi: 10.1111/j.1365- + +1266 246x.2006.03284.x. + + +1267 Wegler, U., Nakahara, H., SensSchönfelder, C., Korn, M., & Shiomi, K., 2009. Sudden + +1268 drop of seismic velocity after the 2004 mw 6.6 midniigata earthquake, japan, observed + +1269 with passive image interferometry, Journal of Geophysical Research: Solid Earth, 114, doi: + +1270 10.1029/2008jb005869. + + +1271 Xie, F., Larose, E., Wang, Q., & Zhang, Y., 2023. In-situ monitoring of rock slope + +1272 destabilization with ambient seismic noise interferometry in southwest china, Engineering + +1273 Geology, 312, 106922, doi: 10.1016/j.enggeo.2022.106922. + + +1274 Yates, A. S., Savage, M. K., Jolly, A. D., Caudron, C., & Hamling, I. J., 2019. Volcanic, coseis- + +1275 mic, and seasonal changes detected at white island (whakaari) volcano, new zealand, using + +1276 seismic ambient noise, Geophysical Research Letters, 46, 99–108, doi: 10.1029/2018gl080580. + + +1277 Yates, A. S., Caudron, C., Mordret, A., Lesage, P., Pinel, V., Lecocq, T., Miller, C. A., + +1278 Lamb, O. D., & Fournier, N., 2024. Seasonal snow cycles and their possible influence on + +1279 seismic velocity changes and eruptive activity at ruapehu volcano, new zealand, Journal + +1280 of Geophysical Research: Solid Earth, 129, doi: 10.1029/2024jb029568. + + +1281 Yuan, C., Bryan, J., & Denolle, M., 2021. Numerical comparison of time-, frequency- and + +1282 wavelet-domain methods for coda wave interferometry, Geophysical Journal International, + +1283 226(2), 828–846, doi: 10.1093/gji/ggab140. + + +1284 Yukutake, Y., Taira, T., Onizawa, S., & Morita, Y., 2025. Decadal monitoring of seismic + +1285 velocity changes beneath izuoshima, central japan, using ambient seismic noise records, + +1286 Journal of Geophysical Research: Solid Earth, 130, doi: 10.1029/2025jb031170. + 82 M. A. Denolle +1287 Zhan, Z., Tsai, V. C., & Clayton, R. W., 2013. Spurious velocity changes caused by temporal + +1288 variations in ambient noise frequency content, Geophysical Journal International, 194(3), + +1289 1574–1581, doi: 10.1093/gji/ggt170. + + +1290 Zhang, S., Luo, B., BenZion, Y., Lumley, D. E., & Zhu, H., 2023. Monitoring terrestrial + +1291 water storage, drought and seasonal changes in central oklahoma with ambient seismic + +1292 noise, Geophysical Research Letters, 50, doi: 10.1029/2023gl103419. + + +1293 Zotz-Wilson, R., Boerrigter, T., & Barnhoorn, A., 2019. Coda-wave monitoring of continu- + +1294 ously evolving material properties and the precursory detection of yielding, The Journal + +1295 of the Acoustical Society of America, 145(2), 1060–1068, doi: 10.1121/1.5091012. diff --git a/review/evidence/revision2/page_1.png b/review/evidence/revision2/page_1.png new file mode 100644 index 0000000..a95673d Binary files /dev/null and b/review/evidence/revision2/page_1.png differ diff --git a/review/evidence/revision2/page_2.png b/review/evidence/revision2/page_2.png new file mode 100644 index 0000000..f079f69 Binary files /dev/null and b/review/evidence/revision2/page_2.png differ diff --git a/review/evidence/revision2/page_33.png b/review/evidence/revision2/page_33.png new file mode 100644 index 0000000..a3703a9 Binary files /dev/null and b/review/evidence/revision2/page_33.png differ diff --git a/review/evidence/revision2/page_37.png b/review/evidence/revision2/page_37.png new file mode 100644 index 0000000..769b0f0 Binary files /dev/null and b/review/evidence/revision2/page_37.png differ diff --git a/review/evidence/revision2/page_62.png b/review/evidence/revision2/page_62.png new file mode 100644 index 0000000..dc37941 Binary files /dev/null and b/review/evidence/revision2/page_62.png differ diff --git a/review/evidence/revision2/paper_build.log b/review/evidence/revision2/paper_build.log new file mode 100644 index 0000000..b44de9f --- /dev/null +++ b/review/evidence/revision2/paper_build.log @@ -0,0 +1,106 @@ +pandoc + to: latex + output-file: manuscript_marine.tex + standalone: true + pdf-engine: lualatex + variables: + graphics: true + tables: true + default-image-extension: pdf + number-sections: true + cite-method: natbib + +metadata + block-headings: true + engines: + - path: /Applications/quarto/share/extension-subtrees/julia-engine/_extensions/julia-engine/julia-engine.js + title: The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring + author: + - name: M. A. Denolle + email: mdenolle@uw.edu + affiliations: + - name: Department of Earth and Space Sciences, University of Washington, Seattle, WA, USA + date: today + abstract: | + Relative seismic velocity changes (\dvv) from repeated coda waves are a + standard observable for volcanoes, faults, landslides, aquifers and the + cryosphere. Turning cross-correlation functions into a \dvv\ time series + involves a long sequence of choices, the estimator, the frequency band, the + coda window, the reference, the stacking, and how cross-components and + station pairs are aggregated and weighted, made ad hoc and reported + incompletely, so the same data can support different values and different + error bars. We quantify the individual and combined effects of these choices + on synthetic correlation functions in which the ground-truth \dvv\ is known + exactly. On these synthetics, at large \dvv\ the estimators split by family + with distinct failure modes; the same station pair yields different \dvv\ depending only on whether one averages per-component \dvv\ or the + correlation-coefficient images; and the number quoted as the $1\sigma$ + uncertainty of a network-averaged \dvv\ differs by $\sim\!\sqrt{N}$ between + the standard error of the network mean and the between-pair standard + deviation, two different quantities that studies rarely distinguish. A + one-at-a-time sweep and a 108-pipeline factorial on one scenario rank the + choices by the error they induce. We then propose a hierarchical Bayesian + measurement model that runs an ensemble of defensible pipelines on the same + correlations and combines their estimates into a single \dvv\ series. A separate construction proposes a time-dependent single-member error covariance $C_d$. + On 200 independent synthetic realisations of a volcano scenario, $C_d$ covers + 95.6% of individual member errors at the 95% level, whereas the + credible band on the ensemble mean covers the truth only 59% of the time + because the configurations share time-varying biases; a seasonal source + artefact seen by every configuration reduces that coverage to 34% and more than doubles + the error of the ensemble mean while leaving member coverage near 95%. + The nominal 68% member intervals cover 81% in the clean case; + these pointwise checks do not validate the full covariance. Shared errors + require diagnostics beyond agreement among processing choices. We set out how $C_d$ enters a depth inversion of + shear-velocity change; that stage is described, not evaluated, here. On three + California stations the same measurement code, run on NoisePy correlations in + a cloud batch pipeline, reproduces a published \dvv\ product (correlation + 0.83--0.99 on 360--580 matched days, with a reproducible comparison script), + a comparison that also exposed and corrected a sign-convention error. The + framework, estimators, figures with their numerical sidecars, and the + calibration experiments are released in the open Python package + ``codameter``, together with a processing-choice advisor and a seeded + golden dataset with fixed scoring support and a null-change penalty for + missing predictions; an + evaluation of agents against that dataset is left to future work. + bibliography: + - references.bib + - survey.bib + biblio-style: gji + documentclass: gji + classoption: + - referee + colorlinks: true + latex-auto-install: false + +WARNING (/Applications/quarto/share/filters/main.lua:18344) Raw LaTeX table found with non-tbl label: tab:gate1 +Won't be able to cross-reference this table using Quarto's native crossref system. + +Rendering PDF +running lualatex - 1 + This is LuaTeX, Version 1.07.0 (TeX Live 2018) + restricted system commands enabled. + + luaotfload | main : initialization completed in 0.116 seconds +generating bibliography + This is BibTeX, Version 0.99d (TeX Live 2018) + The top-level auxiliary file: manuscript_marine.aux + The style file: gji.bst + Database file #1: references.bib + Database file #2: survey.bib + +running lualatex - 2 + This is LuaTeX, Version 1.07.0 (TeX Live 2018) + restricted system commands enabled. + + luaotfload | main : initialization completed in 0.096 seconds +running lualatex - 3 + This is LuaTeX, Version 1.07.0 (TeX Live 2018) + restricted system commands enabled. + + luaotfload | main : initialization completed in 0.094 seconds +running lualatex - 4 + This is LuaTeX, Version 1.07.0 (TeX Live 2018) + restricted system commands enabled. + + luaotfload | main : initialization completed in 0.091 seconds + +Output created: manuscript_marine.pdf diff --git a/review/evidence/revision2/pre_commit.log b/review/evidence/revision2/pre_commit.log new file mode 100644 index 0000000..af6392f --- /dev/null +++ b/review/evidence/revision2/pre_commit.log @@ -0,0 +1,10 @@ +trim trailing whitespace.................................................Passed +fix end of files.........................................................Passed +check yaml...........................................(no files to check)Skipped +check toml...........................................(no files to check)Skipped +check for added large files..............................................Passed +debug statements (python)................................................Passed +ruff.....................................................................Passed +ruff-format..............................................................Passed +black....................................................................Passed +mypy.....................................................................Passed diff --git a/review/evidence/revision2/pre_push_review.md b/review/evidence/revision2/pre_push_review.md new file mode 100644 index 0000000..f332a75 --- /dev/null +++ b/review/evidence/revision2/pre_push_review.md @@ -0,0 +1,15 @@ +# Pre-push review + +READY TO PUSH as work-in-progress revisions. This is not submission approval. + +No new push-blocking correctness, credential, or unsafe-deserialization issue +was identified in this pass. Changes have direct regression coverage. +Known scientific and reproduction limits remain listed in +`review/REVISION_STATUS.md`, especially DET-01, UQ-03/04, SCI-05 and REP-02. +No golden thresholds, private recipes, or frozen audit evidence were changed. + +Final suite: **342 passed, 1 skipped**, with no failures or errors. All configured pre-commit hooks passed. The manuscript rebuilt to **82 pages** with no unresolved-reference markers; pages 1, 2, 33, 37 and 62 were visually checked. + +Scope: current code/skill/manuscript changes plus the 14 prior revision commits +on `docs/sign-convention-manuscript`. Existing scientific limitations are +explicitly documented; the push preserves that unfinished state for review. diff --git a/review/evidence/revision2/pytest.log b/review/evidence/revision2/pytest.log new file mode 100644 index 0000000..f5e9c2f --- /dev/null +++ b/review/evidence/revision2/pytest.log @@ -0,0 +1,15 @@ +........................................................................ [ 20%] +........................................................................ [ 41%] +.....................s.................................................. [ 62%] +........................................................................ [ 83%] +....................................................... [100%] +=============================== warnings summary =============================== +tests/test_cli.py::test_data_check_reports_missing_goal_inputs +tests/test_cli.py::test_data_check_can_fail_on_missing + /Users/marinedenolle/GitHub/codameter/src/codameter/cli.py:397: UserWarning: dvv_err column not found in dvv.csv; defaulting to dvv_err = 0.001 (0.1 %). Provide an err column for proper WLS weighting in Phase 3. + dvv_data = load_dvv(args.dvv, units=args.dvv_units) + +-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html +=========================== short test summary info ============================ +SKIPPED [1] tests/test_kernels.py:136: disba is installed; cannot test missing-import path +342 passed, 1 skipped, 2 warnings in 754.52s (0:12:34) diff --git a/review/evidence/revision2/pytest.xml b/review/evidence/revision2/pytest.xml new file mode 100644 index 0000000..a8f6a5b --- /dev/null +++ b/review/evidence/revision2/pytest.xml @@ -0,0 +1 @@ +/Users/marinedenolle/GitHub/codameter/tests/test_kernels.py:136: disba is installed; cannot test missing-import path diff --git a/review/evidence/revision2/reconciliation.json b/review/evidence/revision2/reconciliation.json new file mode 100644 index 0000000..21d18e6 --- /dev/null +++ b/review/evidence/revision2/reconciliation.json @@ -0,0 +1,195 @@ +{ + "date": "2026-09-10", + "mode": "bounded evidence reconciliation, not formal reviewer iteration 2", + "reviewed_baseline": "b6dbbd03ad3a9e7b8daac3847a470b93b6918cc8", + "revision_head_before_this_pass": "62b63b5f8a455bf9c7c3c9a5414ca444acd48734", + "source_manifest": "review/codameter-gji.review.json", + "source_manifest_sha256": "1167b56f31450fb79ac2042f7c5814872d658608e073a85a336755835a593be0", + "findings": [ + { + "id": "UQ-01", + "assessment": "Verified formula repair", + "evidence_and_limit": "`uq_measurement.py`; Eq. 21, unit-rescaling and bandwidth tests. Gaussian bandwidth convention remains an assumption." + }, + { + "id": "UQ-02", + "assessment": "Verified variance repair", + "evidence_and_limit": "`uq_processing.py`; zero-mean mixture test; bias, SD and RMSE separated." + }, + { + "id": "UQ-03", + "assessment": "Partial", + "evidence_and_limit": "Independence and joint-fit versus mixture distinction now explicit in manuscript and module. A dependence-aware likelihood is not implemented." + }, + { + "id": "UQ-04", + "assessment": "Partial", + "evidence_and_limit": "Excess-spread subtraction and shared-artifact test exist. Temporal covariance and common-error scale remain unvalidated; 95% coverage alone is not closure." + }, + { + "id": "UQ-05", + "assessment": "Verified for supported inputs", + "evidence_and_limit": "Daily-grid rejection, output-only decimation, moving-reference gate and missing-member tests. Inversion references explicitly rejected by the ensemble." + }, + { + "id": "DET-01", + "assessment": "Partial", + "evidence_and_limit": "Estimand table names raw RMS and support. Canonical inversion still ignores requested estimator/stack; gates and valid supports vary across deterministic comparisons." + }, + { + "id": "DET-02", + "assessment": "Verified cache repair", + "evidence_and_limit": "Exact cold/warm arrays and generator identity tests, now including use-case geometry." + }, + { + "id": "INV-01", + "assessment": "Narrowed", + "evidence_and_limit": "Depth remains a framework. Manuscript distinguishes temporal from cross-band covariance and the member from combined-estimate target. GLS propagation remains unimplemented." + }, + { + "id": "INV-02", + "assessment": "Verified defect repair", + "evidence_and_limit": "Nonzero local covariance and active-bound flags; disconnected epochs flagged. Local Gaussian curvature at a bound is not a bounded posterior interval." + }, + { + "id": "SCALE-01", + "assessment": "Partial", + "evidence_and_limit": "Banded sampler update agrees with dense reference. Stored posterior and output covariance remain dense; no cloud-scaling study is claimed." + }, + { + "id": "SCALE-02", + "assessment": "Verified shard checks", + "evidence_and_limit": "Missing/duplicate shard rejection and explicit partial manifest tests. No large deployment was executed here." + }, + { + "id": "AG-01", + "assessment": "Verified advisor route repair", + "evidence_and_limit": "All six public development scenarios execute through `recover`; no dependence on missing mappings or hard groundwater fallback." + }, + { + "id": "AG-02", + "assessment": "Narrowed", + "evidence_and_limit": "Six executable axes distinguished from contextual site metadata; single-seed equivalence rule removed. No site-conditioned agent evaluation supplied." + }, + { + "id": "AG-03", + "assessment": "Narrowed", + "evidence_and_limit": "Synthetic support described as conditional; separated bands do not validate physical depth resolution." + }, + { + "id": "EV-01", + "assessment": "Verified original exploit repair", + "evidence_and_limit": "Fixed support and baseline; ten-zero-plus-null regression. Null replacement can still improve a poor prediction; availability must accompany scores." + }, + { + "id": "EV-02", + "assessment": "Deferred, explicit", + "evidence_and_limit": "Truth-key removal is not isolation. Private files, generator access and scorer metadata still require an isolated evaluation harness." + }, + { + "id": "EV-03", + "assessment": "Deferred, explicit", + "evidence_and_limit": "Three public cases versus 30 templates documented; shared families and regression-derived thresholds remain." + }, + { + "id": "EV-04", + "assessment": "Narrowed", + "evidence_and_limit": "Completed agent evaluation no longer claimed. No model transcripts or performance estimates added." + }, + { + "id": "SCI-01", + "assessment": "Improved text", + "evidence_and_limit": "Estimand table separates pair spread, finite-network mean precision and posterior uncertainty. No new network covariance calibration." + }, + { + "id": "SCI-02", + "assessment": "Narrowed", + "evidence_and_limit": "Scenario-conditional sensitivity and surrogate depth interpretation stated. Broad observational dominance remains unsupported." + }, + { + "id": "SCI-03", + "assessment": "Narrowed", + "evidence_and_limit": "Raw trailing references described as an ablation. They still do not represent accumulated changes on a common datum." + }, + { + "id": "SCI-04", + "assessment": "Partial", + "evidence_and_limit": "Estimator prescriptions qualified in prior revision. This pass does not repeat the independent literature assessment." + }, + { + "id": "SCI-05", + "assessment": "Partial", + "evidence_and_limit": "600 locked realizations, width/bias/failures and coverage records; missing-data metric repaired. Multi-chain diagnostics and broader calibration remain." + }, + { + "id": "SCI-06", + "assessment": "Narrowed", + "evidence_and_limit": "Depth evaluation, agent performance and generalized cloud scalability withdrawn from demonstrated results." + }, + { + "id": "SCI-07", + "assessment": "Partial", + "evidence_and_limit": "In-repo product comparison and explicit masks replace inconsistent counts. Original run provenance and raw-waveform replay still missing." + }, + { + "id": "SCI-08", + "assessment": "Partial", + "evidence_and_limit": "Abstract-only nonreporting caveat corrected. Study-key deduplication and survey denominators still need reconciliation." + }, + { + "id": "SCI-09", + "assessment": "Improved text", + "evidence_and_limit": "Branch rule predefined; same-data coherence-selection bias acknowledged. No new independent selection experiment." + }, + { + "id": "SCI-10", + "assessment": "Verified text repair", + "evidence_and_limit": "Appendix WCC delay sign corrected against the defined dilation convention." + }, + { + "id": "SCI-11", + "assessment": "Verified text repair", + "evidence_and_limit": "Signed, scenario-dependent stacking recovery replaces universal underestimation." + }, + { + "id": "FIG-01", + "assessment": "Verified caption repair", + "evidence_and_limit": "WCS failure acknowledged against saved traces in the methods figure." + }, + { + "id": "FIG-02", + "assessment": "Partial", + "evidence_and_limit": "Field masks and labels reconciled in captions/table. External figures retain historical annotations and uncorrected error bars, explicitly disclosed." + }, + { + "id": "FIG-03", + "assessment": "Partial", + "evidence_and_limit": "Units, legend placement and sidecars improved. External field bars require regeneration; not all figure pages re-reviewed in this pass." + }, + { + "id": "FMT-01", + "assessment": "Partial", + "evidence_and_limit": "Single-paragraph abstract and estimand table added. Author placeholders and full presentation review remain." + }, + { + "id": "REP-01", + "assessment": "Partial", + "evidence_and_limit": "All synthetic generators registered with numerical sidecars. Three external field figures remain outside the executable build." + }, + { + "id": "REP-02", + "assessment": "Partial, author input", + "evidence_and_limit": "Comparison code and correction log exist. Exact originating run, redistribution rights and archived field inputs remain missing." + }, + { + "id": "REP-03", + "assessment": "Partial", + "evidence_and_limit": "Figure sidecars and locked settings improve replay. Release metadata, dirty-source/input hashes and a complete reconstruction manifest remain incomplete." + }, + { + "id": "COMP-01", + "assessment": "Partial, author input", + "evidence_and_limit": "Availability and AI disclosure now describe actual state. Funding, contributions, archive details and final adjudication remain to be supplied." + } + ] +} diff --git a/review/evidence/revision2/verification.json b/review/evidence/revision2/verification.json new file mode 100644 index 0000000..e405807 --- /dev/null +++ b/review/evidence/revision2/verification.json @@ -0,0 +1,61 @@ +{ + "date": "2026-09-10", + "starting_head": "62b63b5", + "test_command": "MPLCONFIGDIR=/tmp/codameter-review-mpl OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 MKL_NUM_THREADS=1 VECLIB_MAXIMUM_THREADS=1 .pixi/envs/test/bin/python -m pytest -q -p no:cacheprovider --junitxml=review/evidence/revision2/pytest.xml", + "tests": { + "tests": 343, + "failures": 0, + "errors": 0, + "skipped": 1, + "passed": 342, + "seconds": 754.425 + }, + "python": "3.12.13", + "numpy": "2.4.3", + "scipy": "1.17.1", + "algorithm_changes_after_full_test_start": false, + "note": "Final documentation, formatting and PDF-layout edits followed the test start; no measurement/scoring algorithm changed during the full run.", + "hooks": "all configured hooks passed", + "build_command": "MPLCONFIGDIR=/tmp/codameter-review-mpl TEXMFVAR=/tmp/codameter-tex-var TEXMFCACHE=/tmp/codameter-tex-cache quarto render manuscript_marine.qmd --to pdf -M latex-auto-install:false (cwd paper)", + "pdf_pages": 82, + "pdf_sha256": "be5fc63ab9f4b8308956846c41c9dddbcd575b7d278b7b3289081d303eb8ebfc", + "unresolved_reference_markers": 0, + "visually_checked_pages": [ + 1, + 2, + 33, + 37, + 62 + ], + "build_limits": [ + "Existing figure assets reused", + "External field figures not regenerated", + "Author end-matter placeholders remain" + ], + "source_sha256": { + ".claude/skills/codameter-advisor/SKILL.md": "9cb9fd15e5762edc0ccb3610af5b9b2844c9c9dfa10b867a1f6fcb4bedb5612e", + ".claude/skills/codameter-advisor/references/golden_datasets.md": "050bb5f8aeeed1241d1e92f77e22a139b33bbd084b2ed3e93e35c0806fc1b5b3", + ".claude/skills/codameter-advisor/references/report_format.md": "4480d804a03feb6bd27afa0f3351f90c42e2c41f95b8948d3925f473cdb8e39b", + ".claude/skills/codameter-advisor/references/validation_loop.md": "441b9d61f171143f17aeca46e8223067aaf00caa40082bdc8a909e0c8c454c5c", + "CHANGELOG.md": "f67504f4ecbebd31d872b9d93902481be49d3f6c86baff886aa8ebfea9214f73", + "paper/_preamble.tex": "bd7e3ddec2f0a6e0686140080f7cfb696875768241c6a6e65b4be47c81737740", + "paper/build_calibration_table.py": "db98416c104e8c390836cd7c6918ba7451084a0ee8ce417996c20c3becade989", + "paper/calibration_table.tex": "157f5fb588a288767d42e5faf798383fd5cec2832b653d22e20590b1d1618d92", + "paper/manuscript_marine.qmd": "6b4b9eb91fb2c0701d0f3cca9e8279ae8bcc1a29795de3b5d563556a86059ae4", + "paper/manuscript_marine.tex": "c8b2ee0fae6b00a1d25c73a380ee585e4a7dd2ab220198ad852421f38ba45aca", + "review/EXECUTION_PLAN.md": "ce1f709d29ed7407d053e7c554f397850a920442fe7a3863fae0d904cf034efb", + "review/README.md": "6a1fe8b43c5a70b72527d0e4b137cbbca3cb590150ea27a15bacf0f3c207dd27", + "review/REVISION_PLAN.md": "f3678c9ba277a923f6efbb0806d86ce12fb77b11fc9e0f9b6536c8a91b46c2ab", + "src/codameter/calibration.py": "224ef90577d82edc05202cd00afef3557e749f2a25351144e9138c528a948c65", + "src/codameter/golden.py": "aee53dd5a17be57de31238d9ba71fa25f5e3af71fd21ef981a8491881cee5b2a", + "src/codameter/uq_bayes.py": "42c601714e9746af3833b5c73db0a0c15c6f6288fdcf1e1b11cc21f057bc6595", + "tests/test_advisor_validation.py": "0de5956bdcec6198d5c927f05cc6fd01e895c6387cc14c3117c8c9ba4492dc36", + "tests/test_audit_small_fixes.py": "4ad808a52cbb71a97c1bb17fff4da64ee6998a6a8414753fb706c960ab4c87ea", + "tests/test_calibration.py": "386ae94c055a887163632f50f3167961552b7e994cbc75d20fb4bceb373f6fa2", + "tests/test_uq_bayes.py": "18a6dcdd54fa4bd74837f5d9ee9381e50aba410777ab528d1245f681acacd2b9" + }, + "test_warnings": { + "count": 2, + "note": "CLI missing-error-column tests warn that the loader defaults to dvv_err=0.001; no new runtime warning came from the revised paths." + } +} diff --git a/review/issue_ledger.csv b/review/issue_ledger.csv new file mode 100644 index 0000000..58b1aa5 --- /dev/null +++ b/review/issue_ledger.csv @@ -0,0 +1,38 @@ +id,criterion,tier,status,summary,location,required_evidence,report +UQ-01,C2,Fatal,OPEN,Weaver floor omits bandwidth timescale and differs in prefactor.,src/codameter/uq_measurement.py:76,Correct formula; verify dimensional consistency and independent bandwidth calibration.,02_software_and_uncertainty.md +UQ-02,C2,Fatal,OPEN,Floor variability is substituted for conditional-mean variability.,src/codameter/uq_processing.py:220,Recover exact zero-mean mixture variance; separate bias and MSE.,02_software_and_uncertainty.md +UQ-03,C2,Poor,OPEN,Shared-data pipeline estimates are treated as independent observations.,src/codameter/uq_bayes.py:297,Derive joint likelihood or mixture; check duplicate-pipeline invariance.,02_software_and_uncertainty.md +UQ-04,C2,Poor,OPEN,Constructed Cd is not derived or calibrated for shared errors.,src/codameter/uq_bayes.py:328,"Derive covariance; test shared bias, temporal dependence, and component accounting.",02_software_and_uncertainty.md +UQ-05,C2,Fair,OPEN,Bayesian pipeline ignores config axes and changes physical stacking durations.,src/codameter/uq_bayes.py:121,Honor or reject config; preserve physical time under cadence and gaps.,02_software_and_uncertainty.md +DET-01,C2,Fair,OPEN,"RMS, valid supports, reference observables, and requested estimators differ.",src/codameter/deviations.py:174,Align datum/support; expose unsupported configurations; replicate paired comparisons.,02_software_and_uncertainty.md +DET-02,C3,Fair,OPEN,Cache inputs depend on warmth and lack generator-code identity.,src/codameter/golden.py:508,"Consistent precision, versioned cache key, and atomic writes.",02_software_and_uncertainty.md +INV-01,C2,Poor,OPEN,Temporal Cd is not connected to diagonal stress inversion or cross-band depth input.,src/codameter/inverse/linear_fit.py:430,Demonstrate GLS and explicit time-band covariance propagation.,02_software_and_uncertainty.md +INV-02,C2,Poor,OPEN,Bounds and disconnected reference nodes can have zero reported uncertainty.,src/codameter/inverse/linear_fit.py:544; src/codameter/uq_measurement.py:419,Use bounded uncertainty; identify graph components and null spaces.,02_software_and_uncertainty.md +SCALE-01,C3,Fair,OPEN,Dense Gibbs covariance path is cubic in epoch count.,src/codameter/uq_bayes.py:299,Use structured algebra; report memory/runtime scaling and equivalence.,02_software_and_uncertainty.md +SCALE-02,C3,Fair,OPEN,Shard aggregation accepts duplicates and missing shards.,src/codameter/bench.py:314,Require complete unique task inventory and matched provenance.,02_software_and_uncertainty.md +AG-01,C3,Fair,OPEN,Public advisor routes fail for three applications and mismatch hard-case targets.,.claude/skills/codameter-advisor/references/validation_loop.md:37,Provide executable matched public cases for all applications.,03_advisor_and_golden_dataset.md +AG-02,C2,Fair,OPEN,Elicited constraints and error-bar comparisons lack executable evaluation.,.claude/skills/codameter-advisor/references/validation_loop.md:45,"Validate overrides, safeguards, equivalence, and repeated-seed differences.",03_advisor_and_golden_dataset.md +AG-03,C4,Fair,OPEN,Matched synthetic recommendations are described as proven field choices.,.claude/skills/codameter-advisor/SKILL.md:3,State conditional scope; validate independent field/simulator transfer.,03_advisor_and_golden_dataset.md +EV-01,C4,Fatal,OPEN,Sparse zero predictions score perfectly on all public cases.,src/codameter/frugalmind.py:299; src/codameter/golden.py:578,Fix score support and missingness; rerun adversarial and model evaluations.,03_advisor_and_golden_dataset.md +EV-02,C3,Fair,OPEN,Truth-free function is not demonstrated sandbox isolation.,src/codameter/golden.py:560; src/codameter/frugalmind.py:117,Prove separate scorer/agent access boundaries with observables-only artifacts.,03_advisor_and_golden_dataset.md +EV-03,C2,Fair,OPEN,Gold corpus shares generator families and derives thresholds from baseline implementation.,src/codameter/private_golden.py:85; src/codameter/golden.py:604,Freeze independent benchmark; distinguish parameter and simulator holdout.,03_advisor_and_golden_dataset.md +EV-04,C4,Poor,OPEN,No executed agent evaluation supports the robust-evaluation claim.,paper/manuscript_marine.qmd:41,"Archive model protocols, runs, baselines, scores, costs, and uncertainties.",03_advisor_and_golden_dataset.md +SCI-01,C2,Poor,OPEN,SD/SE/network heterogeneity are conflated with one measurement uncertainty.,paper/manuscript_marine.qmd:446,Define estimands and hypotheses; use network covariance propagation.,01_manuscript_and_figures.md +SCI-02,C4,Fair,OPEN,Conditional surrogate experiments are generalized to observational dominance and depth.,paper/manuscript_marine.qmd:180; paper/manuscript_marine.qmd:1207,Add independent wavefields and qualify surrogate physical interpretations.,01_manuscript_and_figures.md +SCI-03,C4,Fair,OPEN,Raw trailing references are presented as common defensible comparisons.,paper/manuscript_marine.qmd:540,Benchmark comparable registered observables and surveyed reference workflows.,01_manuscript_and_figures.md +SCI-04,C6,Fair,OPEN,Estimator prescriptions and novelty boundary exceed cited conditional evidence.,paper/manuscript_marine.qmd:309,Compare tuned methods; delimit contribution relative to Yuan2021 and other work.,01_manuscript_and_figures.md +SCI-05,C2,Poor,OPEN,Nominal interval coverage lacks repeated independent validation and chain diagnostics.,paper/manuscript_marine.qmd:995,"Report held-out coverage, uncertainty, width, convergence, and failure rates.",01_manuscript_and_figures.md +SCI-06,C4,Poor,OPEN,Depth and operational claims exceed demonstrated results.,paper/manuscript_marine.qmd:36; paper/manuscript_marine.qmd:1298,Add actual depth/resolution and scaling results or narrow claims consistently.,01_manuscript_and_figures.md +SCI-07,C4,Poor,OPEN,"Field comparison counts, masks, correlations, and physical attribution are inconsistent.",paper/manuscript_marine.qmd:1133,Publish exact comparison driver and date masks; recompute statistics and labels.,01_manuscript_and_figures.md +SCI-08,C6,Fair,OPEN,Abstract-only survey gaps cannot establish full-paper nonreporting.,paper/manuscript_marine.qmd:1414,Separate extraction statuses and deduplicate study denominators; repair groundwater attribution.,01_manuscript_and_figures.md +SCI-09,C2,Fair,OPEN,Largest-magnitude and coherence branch selection can bias inference.,paper/manuscript_marine.qmd:788,Predefine selection or validate it on independent data.,01_manuscript_and_figures.md +SCI-10,C2,Fair,OPEN,Appendix WCC delay sign contradicts the defined dilation convention.,paper/manuscript_marine.qmd:1345,Correct analytical pulse example and propagate finite-change Jacobian.,evidence/methods_figures.md +SCI-11,C4,Good,OPEN,Universal stack underestimation contradicts reported bias zero crossing.,paper/manuscript_marine.qmd:669,"Describe signed, scenario-specific recovery errors.",evidence/methods_figures.md +FIG-01,C4,Fair,OPEN,Figure1 WCS trajectory contradicts its caption.,paper/manuscript_marine.qmd:367; PDF p11,Reconcile saved numerical traces and recovery claim.,01_manuscript_and_figures.md +FIG-02,C5,Fair,OPEN,"Real-data figures conflict on components, dates, statistics, and counts.",paper/manuscript_marine.qmd:1176; PDF pp36–38,Generate labels and reported metrics from the same validated products.,01_manuscript_and_figures.md +FIG-03,C5,Fair,OPEN,"Missing units, clipped ensembles, occluding legends, and mixed RMS/bias labels.","PDF pp13,22,25,28,29,32,37",Add units and full-range views; move legends; label statistical objects.,01_manuscript_and_figures.md +FMT-01,C5,Good,OPEN,"Summary paragraphs, figure order, duplicated presentation, and placeholders need revision.",paper/manuscript_marine.qmd:10; paper/manuscript_marine.qmd:140,Single summary paragraph; resolve placeholders and figure order; clarify acronyms/history.,01_manuscript_and_figures.md +REP-01,C3,Poor,OPEN,Advertised figure build omits six graphics and can preserve stale results.,paper/build.py:124,One driver regenerates all graphics from versioned numerical manifests.,evidence/reproducibility.md +REP-02,C3,Poor,OPEN,Field products are ignored by Git and comparison driver is external.,paper/data/gate1/README.md:25,Archive field products and dependencies with exact hashes and executable driver.,evidence/reproducibility.md +REP-03,C3,Fair,OPEN,"Paper experiment settings, version metadata, and replay manifests are incomplete.",CITATION.cff; src/codameter/workflow.py:696,"Pin environments, settings, hardware, source and input hashes, seeds, and invocation.",evidence/reproducibility.md +COMP-01,C8,Fair,OPEN,"Acknowledgements, AI disclosure, and full data access/licensing statements are unfinished.",paper/manuscript_marine.qmd:1427,Complete authorship/funding/disclosure and actual data/software access statements.,01_manuscript_and_figures.md diff --git a/reviews/README.md b/reviews/README.md new file mode 100644 index 0000000..404b975 --- /dev/null +++ b/reviews/README.md @@ -0,0 +1,15 @@ +# Live review ledger + +`codameter-gji.review.json` is the manifest the pre-submission-reviewer skill reads at Step 0.5 and rewrites at Step 5. It is the live state of the review loop: iteration count, readiness, and the per-finding ledger with reconciliation verdicts. + +It was converted on 2026-09-10 from Astra's iteration-1 manifest at `review/codameter-gji.review.json`, which stays frozen as the original record together with the three reports and the evidence directory. The converter is not checked in; the `conversion_note` field lists exactly what was added (section, scope, plan_package, hash_method, manuscript_ref, open) and what was renamed (verification to execution_evidence). No finding text, tier, status, or ID was changed. + +Running iteration 2: + +- The skill needs a diff of the manuscript against the reviewed version. Produce it with `git diff b6dbbd0 -- paper/manuscript_marine.qmd`, or a before/after pair from `git show b6dbbd0:paper/manuscript_marine.qmd`. +- `manuscript_hash` is the sha256 of the raw file bytes, no normalization. Recompute the same way. +- The `scope` field names the subagents that own each finding, so unchanged scopes carry their verdicts forward and changed ones are re-dispatched. +- Closure evidence for code findings is a re-run of `review/evidence/audit_probes.py` and `downstream_probes.py`; their committed JSON is the before state. +- Do not hand-edit statuses. A C2/C3/C4 finding closes only when changed text or code demonstrably fixes it. + +The local skill is v2.5; the review ran under v2.4. Expect new register findings in an `INTRODUCED-BY-RECALIBRATION` bucket rather than as regressions. diff --git a/reviews/codameter-gji.review.json b/reviews/codameter-gji.review.json new file mode 100644 index 0000000..aeeb887 --- /dev/null +++ b/reviews/codameter-gji.review.json @@ -0,0 +1,1005 @@ +{ + "manuscript_id": "codameter-gji", + "title": "The reproducibility cost of ad-hoc processing choices in ambient-noise seismic velocity-change monitoring", + "skill_version": "2.4", + "skill_commit": "f230303", + "model": "GPT-6 / Codex; exact runtime model identifier not exposed", + "profile": "default", + "target_journal": "GJI (Geophysical Journal International)", + "manuscript_type": "Research paper with methods emphasis", + "iteration": 1, + "manuscript_hash": "sha256:582a09ee97ca6f86d80ac3a61301bab8dd5089477fe780cd86c70452dbba0ec0", + "hash_method": "sha256 of the raw bytes of paper/manuscript_marine.qmd (no normalization)", + "manuscript_path": "paper/manuscript_marine.qmd", + "manuscript_ref": "b6dbbd03ad3a9e7b8daac3847a470b93b6918cc8:paper/manuscript_marine.qmd", + "repository_commit": "b6dbbd03ad3a9e7b8daac3847a470b93b6918cc8", + "created": "2026-09-10", + "updated": "2026-09-10", + "readiness": "Major revision required", + "readiness_note": "Major revision required; UQ and evaluation claims blocked pending correction", + "open": 37, + "history": [], + "ledger": [ + { + "id": "UQ-01", + "criterion": "C2", + "tier": "Fatal", + "status": "OPEN", + "summary": "Weaver floor omits bandwidth timescale and differs in prefactor.", + "location": "src/codameter/uq_measurement.py:76", + "section": "code / repository", + "scope": [ + "S-RP", + "S-ME" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Correct formula; verify dimensional consistency and independent bandwidth calibration.", + "report": "review/02_software_and_uncertainty.md", + "plan_package": [ + "R3" + ] + }, + { + "id": "UQ-02", + "criterion": "C2", + "tier": "Fatal", + "status": "OPEN", + "summary": "Floor variability is substituted for conditional-mean variability.", + "location": "src/codameter/uq_processing.py:220", + "section": "code / repository", + "scope": [ + "S-RP", + "S-ME" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Recover exact zero-mean mixture variance; separate bias and MSE.", + "report": "review/02_software_and_uncertainty.md", + "plan_package": [ + "R3" + ] + }, + { + "id": "UQ-03", + "criterion": "C2", + "tier": "Poor", + "status": "OPEN", + "summary": "Shared-data pipeline estimates are treated as independent observations.", + "location": "src/codameter/uq_bayes.py:297", + "section": "code / repository", + "scope": [ + "S-RP", + "S-ME" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Derive joint likelihood or mixture; check duplicate-pipeline invariance.", + "report": "review/02_software_and_uncertainty.md", + "plan_package": [ + "R1", + "R5" + ] + }, + { + "id": "UQ-04", + "criterion": "C2", + "tier": "Poor", + "status": "OPEN", + "summary": "Constructed Cd is not derived or calibrated for shared errors.", + "location": "src/codameter/uq_bayes.py:328", + "section": "code / repository", + "scope": [ + "S-RP", + "S-ME" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Derive covariance; test shared bias, temporal dependence, and component accounting.", + "report": "review/02_software_and_uncertainty.md", + "plan_package": [ + "R1", + "R5", + "R6" + ] + }, + { + "id": "UQ-05", + "criterion": "C2", + "tier": "Fair", + "status": "OPEN", + "summary": "Bayesian pipeline ignores config axes and changes physical stacking durations.", + "location": "src/codameter/uq_bayes.py:121", + "section": "code / repository", + "scope": [ + "S-RP", + "S-ME" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Honor or reject config; preserve physical time under cadence and gaps.", + "report": "review/02_software_and_uncertainty.md", + "plan_package": [ + "R4" + ] + }, + { + "id": "DET-01", + "criterion": "C2", + "tier": "Fair", + "status": "OPEN", + "summary": "RMS, valid supports, reference observables, and requested estimators differ.", + "location": "src/codameter/deviations.py:174", + "section": "code / repository", + "scope": [ + "S-RP", + "S-ME" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Align datum/support; expose unsupported configurations; replicate paired comparisons.", + "report": "review/02_software_and_uncertainty.md", + "plan_package": [ + "R1", + "R4" + ] + }, + { + "id": "DET-02", + "criterion": "C3", + "tier": "Fair", + "status": "OPEN", + "summary": "Cache inputs depend on warmth and lack generator-code identity.", + "location": "src/codameter/golden.py:508", + "section": "code / repository", + "scope": [ + "S-RP" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Consistent precision, versioned cache key, and atomic writes.", + "report": "review/02_software_and_uncertainty.md", + "plan_package": [ + "R4" + ] + }, + { + "id": "INV-01", + "criterion": "C2", + "tier": "Poor", + "status": "OPEN", + "summary": "Temporal Cd is not connected to diagonal stress inversion or cross-band depth input.", + "location": "src/codameter/inverse/linear_fit.py:430", + "section": "code / repository", + "scope": [ + "S-RP", + "S-ME" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Demonstrate GLS and explicit time-band covariance propagation.", + "report": "review/02_software_and_uncertainty.md", + "plan_package": [ + "R5" + ] + }, + { + "id": "INV-02", + "criterion": "C2", + "tier": "Poor", + "status": "OPEN", + "summary": "Bounds and disconnected reference nodes can have zero reported uncertainty.", + "location": "src/codameter/inverse/linear_fit.py:544; src/codameter/uq_measurement.py:419", + "section": "code / repository", + "scope": [ + "S-RP", + "S-ME" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Use bounded uncertainty; identify graph components and null spaces.", + "report": "review/02_software_and_uncertainty.md", + "plan_package": [ + "R5" + ] + }, + { + "id": "SCALE-01", + "criterion": "C3", + "tier": "Fair", + "status": "OPEN", + "summary": "Dense Gibbs covariance path is cubic in epoch count.", + "location": "src/codameter/uq_bayes.py:299", + "section": "code / repository", + "scope": [ + "S-RP" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Use structured algebra; report memory/runtime scaling and equivalence.", + "report": "review/02_software_and_uncertainty.md", + "plan_package": [ + "R9" + ] + }, + { + "id": "SCALE-02", + "criterion": "C3", + "tier": "Fair", + "status": "OPEN", + "summary": "Shard aggregation accepts duplicates and missing shards.", + "location": "src/codameter/bench.py:314", + "section": "code / repository", + "scope": [ + "S-RP" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Require complete unique task inventory and matched provenance.", + "report": "review/02_software_and_uncertainty.md", + "plan_package": [ + "R9" + ] + }, + { + "id": "AG-01", + "criterion": "C3", + "tier": "Fair", + "status": "OPEN", + "summary": "Public advisor routes fail for three applications and mismatch hard-case targets.", + "location": ".claude/skills/codameter-advisor/references/validation_loop.md:37", + "section": "code / repository", + "scope": [ + "S-RP" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Provide executable matched public cases for all applications.", + "report": "review/03_advisor_and_golden_dataset.md", + "plan_package": [ + "R8" + ] + }, + { + "id": "AG-02", + "criterion": "C2", + "tier": "Fair", + "status": "OPEN", + "summary": "Elicited constraints and error-bar comparisons lack executable evaluation.", + "location": ".claude/skills/codameter-advisor/references/validation_loop.md:45", + "section": "code / repository", + "scope": [ + "S-RP" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Validate overrides, safeguards, equivalence, and repeated-seed differences.", + "report": "review/03_advisor_and_golden_dataset.md", + "plan_package": [ + "R4", + "R8" + ] + }, + { + "id": "AG-03", + "criterion": "C4", + "tier": "Fair", + "status": "OPEN", + "summary": "Matched synthetic recommendations are described as proven field choices.", + "location": ".claude/skills/codameter-advisor/SKILL.md:3", + "section": "code / repository", + "scope": [ + "S-RP", + "S-DI" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "State conditional scope; validate independent field/simulator transfer.", + "report": "review/03_advisor_and_golden_dataset.md", + "plan_package": [ + "R6", + "R8" + ] + }, + { + "id": "EV-01", + "criterion": "C4", + "tier": "Fatal", + "status": "OPEN", + "summary": "Sparse zero predictions score perfectly on all public cases.", + "location": "src/codameter/frugalmind.py:299; src/codameter/golden.py:578", + "section": "code / repository", + "scope": [ + "S-RP" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Fix score support and missingness; rerun adversarial and model evaluations.", + "report": "review/03_advisor_and_golden_dataset.md", + "plan_package": [ + "R2" + ] + }, + { + "id": "EV-02", + "criterion": "C3", + "tier": "Fair", + "status": "OPEN", + "summary": "Truth-free function is not demonstrated sandbox isolation.", + "location": "src/codameter/golden.py:560; src/codameter/frugalmind.py:117", + "section": "code / repository", + "scope": [ + "S-RP" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Prove separate scorer/agent access boundaries with observables-only artifacts.", + "report": "review/03_advisor_and_golden_dataset.md", + "plan_package": [ + "R8" + ] + }, + { + "id": "EV-03", + "criterion": "C2", + "tier": "Fair", + "status": "OPEN", + "summary": "Gold corpus shares generator families and derives thresholds from baseline implementation.", + "location": "src/codameter/private_golden.py:85; src/codameter/golden.py:604", + "section": "code / repository", + "scope": [ + "S-RP" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Freeze independent benchmark; distinguish parameter and simulator holdout.", + "report": "review/03_advisor_and_golden_dataset.md", + "plan_package": [ + "R2", + "R6", + "R8" + ] + }, + { + "id": "EV-04", + "criterion": "C4", + "tier": "Poor", + "status": "OPEN", + "summary": "No executed agent evaluation supports the robust-evaluation claim.", + "location": "paper/manuscript_marine.qmd:41", + "section": "Front matter / Abstract", + "scope": [ + "S-AB", + "S-RP" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Archive model protocols, runs, baselines, scores, costs, and uncertainties.", + "report": "review/03_advisor_and_golden_dataset.md", + "plan_package": [ + "R8" + ] + }, + { + "id": "SCI-01", + "criterion": "C2", + "tier": "Poor", + "status": "OPEN", + "summary": "SD/SE/network heterogeneity are conflated with one measurement uncertainty.", + "location": "paper/manuscript_marine.qmd:446", + "section": "Results 3.3 Station-pair aggregation and uncertainty", + "scope": [ + "S-RE", + "S-FD" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Define estimands and hypotheses; use network covariance propagation.", + "report": "review/01_manuscript_and_figures.md", + "plan_package": [ + "R1", + "R10" + ] + }, + { + "id": "SCI-02", + "criterion": "C4", + "tier": "Fair", + "status": "OPEN", + "summary": "Conditional surrogate experiments are generalized to observational dominance and depth.", + "location": "paper/manuscript_marine.qmd:180; paper/manuscript_marine.qmd:1207", + "section": "Synthetic framework; Discussion", + "scope": [ + "S-ME", + "S-DI" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Add independent wavefields and qualify surrogate physical interpretations.", + "report": "review/01_manuscript_and_figures.md", + "plan_package": [ + "R1", + "R6", + "R10" + ] + }, + { + "id": "SCI-03", + "criterion": "C4", + "tier": "Fair", + "status": "OPEN", + "summary": "Raw trailing references are presented as common defensible comparisons.", + "location": "paper/manuscript_marine.qmd:540", + "section": "Results 3.5 Reference", + "scope": [ + "S-RE" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Benchmark comparable registered observables and surveyed reference workflows.", + "report": "review/01_manuscript_and_figures.md", + "plan_package": [ + "R1", + "R10" + ] + }, + { + "id": "SCI-04", + "criterion": "C6", + "tier": "Fair", + "status": "OPEN", + "summary": "Estimator prescriptions and novelty boundary exceed cited conditional evidence.", + "location": "paper/manuscript_marine.qmd:309", + "section": "Results: parameter-dependent dv/v", + "scope": [ + "S-RE", + "S-DI", + "S-CD" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Compare tuned methods; delimit contribution relative to Yuan2021 and other work.", + "report": "review/01_manuscript_and_figures.md", + "plan_package": [ + "R1", + "R10" + ] + }, + { + "id": "SCI-05", + "criterion": "C2", + "tier": "Poor", + "status": "OPEN", + "summary": "Nominal interval coverage lacks repeated independent validation and chain diagnostics.", + "location": "paper/manuscript_marine.qmd:995", + "section": "Bayesian measurement model", + "scope": [ + "S-RE", + "S-ME" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Report held-out coverage, uncertainty, width, convergence, and failure rates.", + "report": "review/01_manuscript_and_figures.md", + "plan_package": [ + "R3", + "R5", + "R6" + ] + }, + { + "id": "SCI-06", + "criterion": "C4", + "tier": "Poor", + "status": "OPEN", + "summary": "Depth and operational claims exceed demonstrated results.", + "location": "paper/manuscript_marine.qmd:36; paper/manuscript_marine.qmd:1298", + "section": "Front matter / Abstract; Discussion", + "scope": [ + "S-AB", + "S-DI", + "S-CO" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Add actual depth/resolution and scaling results or narrow claims consistently.", + "report": "review/01_manuscript_and_figures.md", + "plan_package": [ + "R5", + "R10" + ] + }, + { + "id": "SCI-07", + "criterion": "C4", + "tier": "Poor", + "status": "OPEN", + "summary": "Field comparison counts, masks, correlations, and physical attribution are inconsistent.", + "location": "paper/manuscript_marine.qmd:1133", + "section": "Scalable deployment / real data", + "scope": [ + "S-RE", + "S-RP" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Publish exact comparison driver and date masks; recompute statistics and labels.", + "report": "review/01_manuscript_and_figures.md", + "plan_package": [ + "R7" + ] + }, + { + "id": "SCI-08", + "criterion": "C6", + "tier": "Fair", + "status": "OPEN", + "summary": "Abstract-only survey gaps cannot establish full-paper nonreporting.", + "location": "paper/manuscript_marine.qmd:1414", + "section": "Appendix C Literature survey", + "scope": [ + "S-CD" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Separate extraction statuses and deduplicate study denominators; repair groundwater attribution.", + "report": "review/01_manuscript_and_figures.md", + "plan_package": [ + "R7" + ] + }, + { + "id": "SCI-09", + "criterion": "C2", + "tier": "Fair", + "status": "OPEN", + "summary": "Largest-magnitude and coherence branch selection can bias inference.", + "location": "paper/manuscript_marine.qmd:788", + "section": "Results 3.8 Causal/acausal branches", + "scope": [ + "S-RE" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Predefine selection or validate it on independent data.", + "report": "review/01_manuscript_and_figures.md", + "plan_package": [ + "R1", + "R10" + ] + }, + { + "id": "SCI-10", + "criterion": "C2", + "tier": "Fair", + "status": "OPEN", + "summary": "Appendix WCC delay sign contradicts the defined dilation convention.", + "location": "paper/manuscript_marine.qmd:1345", + "section": "Appendix A Estimator definitions", + "scope": [ + "S-ME" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Correct analytical pulse example and propagate finite-change Jacobian.", + "report": "review/evidence/methods_figures.md", + "plan_package": [ + "R1", + "R10" + ] + }, + { + "id": "SCI-11", + "criterion": "C4", + "tier": "Good", + "status": "OPEN", + "summary": "Universal stack underestimation contradicts reported bias zero crossing.", + "location": "paper/manuscript_marine.qmd:669", + "section": "Results 3.6 Substacking", + "scope": [ + "S-RE" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Describe signed, scenario-specific recovery errors.", + "report": "review/evidence/methods_figures.md", + "plan_package": [ + "R1", + "R10" + ] + }, + { + "id": "FIG-01", + "criterion": "C4", + "tier": "Fair", + "status": "OPEN", + "summary": "Figure1 WCS trajectory contradicts its caption.", + "location": "paper/manuscript_marine.qmd:367; PDF p11", + "section": "Results 3.1 Estimator family", + "scope": [ + "S-FD" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Reconcile saved numerical traces and recovery claim.", + "report": "review/01_manuscript_and_figures.md", + "plan_package": [ + "R7", + "R10" + ] + }, + { + "id": "FIG-02", + "criterion": "C5", + "tier": "Fair", + "status": "OPEN", + "summary": "Real-data figures conflict on components, dates, statistics, and counts.", + "location": "paper/manuscript_marine.qmd:1176; PDF pp36–38", + "section": "Scalable deployment / real data", + "scope": [ + "S-FD" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Generate labels and reported metrics from the same validated products.", + "report": "review/01_manuscript_and_figures.md", + "plan_package": [ + "R7", + "R10" + ] + }, + { + "id": "FIG-03", + "criterion": "C5", + "tier": "Fair", + "status": "OPEN", + "summary": "Missing units, clipped ensembles, occluding legends, and mixed RMS/bias labels.", + "location": "PDF pp13,22,25,28,29,32,37", + "section": "code / repository", + "scope": [ + "S-FD" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Add units and full-range views; move legends; label statistical objects.", + "report": "review/01_manuscript_and_figures.md", + "plan_package": [ + "R7", + "R10" + ] + }, + { + "id": "FMT-01", + "criterion": "C5", + "tier": "Good", + "status": "OPEN", + "summary": "Summary paragraphs, figure order, duplicated presentation, and placeholders need revision.", + "location": "paper/manuscript_marine.qmd:10; paper/manuscript_marine.qmd:140", + "section": "Front matter / Abstract; Introduction", + "scope": [ + "S-AB", + "S-IN", + "S-FD" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Single summary paragraph; resolve placeholders and figure order; clarify acronyms/history.", + "report": "review/01_manuscript_and_figures.md", + "plan_package": [ + "R10" + ] + }, + { + "id": "REP-01", + "criterion": "C3", + "tier": "Poor", + "status": "OPEN", + "summary": "Advertised figure build omits six graphics and can preserve stale results.", + "location": "paper/build.py:124", + "section": "code / repository", + "scope": [ + "S-RP" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "One driver regenerates all graphics from versioned numerical manifests.", + "report": "review/evidence/reproducibility.md", + "plan_package": [ + "R7" + ] + }, + { + "id": "REP-02", + "criterion": "C3", + "tier": "Poor", + "status": "OPEN", + "summary": "Field products are ignored by Git and comparison driver is external.", + "location": "paper/data/gate1/README.md:25", + "section": "code / repository", + "scope": [ + "S-RP" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Archive field products and dependencies with exact hashes and executable driver.", + "report": "review/evidence/reproducibility.md", + "plan_package": [ + "R7" + ] + }, + { + "id": "REP-03", + "criterion": "C3", + "tier": "Fair", + "status": "OPEN", + "summary": "Paper experiment settings, version metadata, and replay manifests are incomplete.", + "location": "CITATION.cff; src/codameter/workflow.py:696", + "section": "code / repository", + "scope": [ + "S-RP" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Pin environments, settings, hardware, source and input hashes, seeds, and invocation.", + "report": "review/evidence/reproducibility.md", + "plan_package": [ + "R7", + "R9" + ] + }, + { + "id": "COMP-01", + "criterion": "C8", + "tier": "Fair", + "status": "OPEN", + "summary": "Acknowledgements, AI disclosure, and full data access/licensing statements are unfinished.", + "location": "paper/manuscript_marine.qmd:1427", + "section": "Data availability", + "scope": [ + "S-RP" + ], + "first_seen": 1, + "last_changed": 1, + "bucket": null, + "required_evidence": "Complete authorship/funding/disclosure and actual data/software access statements.", + "report": "review/01_manuscript_and_figures.md", + "plan_package": [ + "R10" + ] + } + ], + "review_mode": "Full first review; nine focused scopes across three subagents, primary scientific code/scorer audit", + "prior_manifest_found": false, + "author_verification_performed": false, + "review_reports": [ + "review/README.md", + "review/01_manuscript_and_figures.md", + "review/02_software_and_uncertainty.md", + "review/03_advisor_and_golden_dataset.md" + ], + "evidence_dir": "review/evidence", + "execution_evidence": { + "numerical_probes": "evidence/audit_probes.json", + "downstream_probes": "evidence/downstream_probes.json", + "reproduction_probes": "evidence/reproduction_probes.json", + "test_metadata": "evidence/pytest_targeted_metadata.json", + "full_test_metadata": "evidence/pytest_metadata.json", + "render_metadata": "evidence/paper_build_cached_metadata.json", + "targeted_tests": { + "passed": 144, + "skipped": 0, + "complete": true + }, + "full_suite": { + "status": "timeout", + "limit_seconds": 540, + "visible_passes": 261, + "visible_skips": 1, + "unfinished": 39, + "complete": false, + "note": "Partial progress counts; targeted suite overlaps." + }, + "fresh_pdf_pages": 74, + "visual_qa": { + "existing_pages": 26, + "all_17_figure_pages_inspected": true, + "fresh_pages": [ + 1, + 11, + 29, + 32, + 36, + 37 + ] + } + }, + "limits": [ + "No hidden corpus accessed", + "No external model evaluation performed", + "No cloud deployment or benchmark performed", + "Existing figures reused for isolated manuscript compilation", + "No full raw-waveform real-data reproduction performed" + ], + "disclosure": "This draft received an advisory AI-assisted review using Denolle Group Pre-Submission Reviewer v2.4 with Codex/GPT-6, iteration 1. The audit included local code execution and selected primary-source checks. It does not endorse manuscript validity. Authors must adjudicate findings before submission; that adjudication has not yet been recorded.", + "source_file_hashes": { + ".claude/skills/codameter-advisor/SKILL.md": "sha256:6daf68288e89f93cfe46ab57a54300228bd9536d17af9c529d4a92c0e101716b", + ".claude/skills/codameter-advisor/references/golden_datasets.md": "sha256:7aaf3fd20e26d84bf1ba7aead158f3cd5cb7aebf9c0a0c20de3f3937a032065c", + ".claude/skills/codameter-advisor/references/parameter_map.md": "sha256:bf008b1e0922a56b13251d24ca4477d4c9d927325e7fb4597ee002a599435434", + ".claude/skills/codameter-advisor/references/report_format.md": "sha256:53b4ad8d26caada2c149f2ea9d96bbed8cf11b3ed2787d287a1ae3b4ead155c7", + ".claude/skills/codameter-advisor/references/use_case_elicitation.md": "sha256:20f21a64396abaa19786e0b5396f466be6843697a045e32c9c5ca9f377f5b90e", + ".claude/skills/codameter-advisor/references/validation_loop.md": "sha256:a8e51cf050463a141680976bcc0bf06fd2ca6be0bd07f304a41eb56bf8162806", + "literature/.crossref_cache.json": "sha256:2ba8ffbb03257794a241f7489ef9819968a15780d960e1ed5b4b01f12590b84b", + "literature/ACCESS.md": "sha256:c2344c9ce6632b60871be3eb8053954d823ef91f2012c03cafe00b59ca14654e", + "literature/README.md": "sha256:69418a72b0b72dbd920c8bc08c9f792e61c0bcfaacee9e7423d943fb34149848", + "literature/best_practices.md": "sha256:08dff657c576aabcc986e8d6e46c5fb4943bad9db5d2c2acf62b8e170739e247", + "literature/build_quarto_refs.py": "sha256:62cf6f90bbd525f321048a83fd35c76309236a9d5bb7d58109f009c2a06af6e1", + "literature/build_table.py": "sha256:5a66dfcd167da2fcae8e16074956fa676a0ab54eba821aaf78187c76d4eb53b0", + "literature/dvv_processing_parameters.csv": "sha256:d1178a1b3a6e442a0638491236adfaa9d995f4722a629d30c86e31af2678aae2", + "literature/dvv_processing_parameters.md": "sha256:55f00c094e6f675c2c4c1761a9374045007a1550f5a8d420b84c6f54aefb4405", + "literature/figs/demo_10_deviations.png": "sha256:6fa18f678925cdc261f191a296ed932e32c72aa769659883ba421d604c06340b", + "literature/figs/demo_11_multiverse.png": "sha256:75f3a557e8d2b900522959f89cabb6ef86b753d16e0bf44bc35432b7181adf48", + "literature/figs/demo_12_bayes.png": "sha256:5ec259557489329b35d56a966e47683d4206a68d9fd97047eedfb0abcad2cdc3", + "literature/figs/demo_13_branch_asymmetry.png": "sha256:d167a4ff35df6bfab45bc1dd928135feaa014f2a1cc177f308411ccf99196daa", + "literature/figs/demo_14_network_pairs.png": "sha256:d0d01f5a273edd52c709a13e5e821551560d909bf92a42f6a9e69ad8c15f2bdc", + "literature/figs/demo_15_window_envelope.png": "sha256:bc88316402dcb5a7c841c996ec6a110322157b72e9af5a8f92871f8d14befce8", + "literature/figs/demo_16_band_sensitivity.png": "sha256:5622d8a45989a020f4522c497888d26a94ccad94b7192e9fb8773c2c95b99220", + "literature/figs/demo_17_reference_schemes.png": "sha256:ea87965d83f242d406c9315c6b570285af0859984228b92180c31a88e849fd72", + "literature/figs/demo_18_stack_coherence.png": "sha256:defa8771b14540add4279723f7e7a0e08a172da7c503b97e765f39c322aa4f5b", + "literature/figs/demo_1_methods.png": "sha256:864d7835944d42158992ada370c8da05623527de62a139d08f54a68367a691b4", + "literature/figs/demo_2_aggregation.png": "sha256:713828944d7d893cccd488be242088704aacfd7e4abfc09e3a28cb0b4e66b807", + "literature/figs/demo_3_uncertainty.png": "sha256:38574d2b102c67a1330925dd2c9fbebb2897d21cb0329612d66bf698c2e8ab61", + "literature/figs/demo_4_frequency_depth.png": "sha256:2cc5f4615e22525720a843e35225a9cd5b27c8351778b4a51a9e21ed4c361c20", + "literature/figs/demo_5_window_band.png": "sha256:490ef1c7f1962020f84b4298ffef349adc76850cbefa787f8b81c4a9278e4f82", + "literature/figs/demo_6_stacking.png": "sha256:9a23225d91a027e339ffbf1da990edff84167c150a0086c5640a026f5826e653", + "literature/figs/demo_7_reference.png": "sha256:d04da8057f9e00a872f656b400fc305761a67701624b6f2a7bf623556a497616", + "literature/figs/demo_8_artifacts.png": "sha256:5dd57681749c9924f9b07b1d635e8c16e6b7054ddec53d4ae8a614372d897477", + "literature/figs/demo_9_multiverse.png": "sha256:0e2bd424d1dd921f1546dd4095e34d6fbc26beef72e54211d5274c9c13ded353", + "literature/figs/realdata_1_validation.png": "sha256:9f74681a0ddefc6a6d9b80dd2eef15a856f5bff4f0503b66e25a58e28ccaddb8", + "literature/figs/realdata_2_interferograms.png": "sha256:a15d51eae10aac10b5f5dba48fb4b19a439cbededb1cb29f36f6f098e2598a81", + "literature/figs/realdata_3_warmup.png": "sha256:00df9e0f5632013f0dd97c8a2143e60c3348530b05b37756c7ca9f0b89bec83b", + "literature/merge_verified.py": "sha256:261c1238bb039c83b1d7de26b030ec206b4b8476a81c8aeeea1f8983e8c132a6", + "literature/raw/cryosphere_geothermal.json": "sha256:f71f77982ec57ec3ea43a07ce5cc6ba121dd32bba79d29fb983c9c5dee78f5c2", + "literature/raw/earthquake.json": "sha256:7447031b92216341d104367de5599dd2c055c2a9d4a4aed37e5bf29e9d5e52b2", + "literature/raw/groundwater.json": "sha256:3f3c092f00a984c033bebfac3965ff1be14565353abc6a6b544df4b22da1df59", + "literature/raw/landslide.json": "sha256:b52509a914372f4027979f584fa5fe2c1bf92dc61ac1b92ae65dc3d18c13d5cf", + "literature/raw/methodology.json": "sha256:d7975b35d826e748accb1b329dc66e1abc63b8e6a57ce33b7fbe9aef1de801b9", + "literature/raw/volcano.json": "sha256:4b1cad33974bda5dcdacb01716a2974c62f26f39ddef3707dfa0b683836ecd16", + "literature/synthetic_dvv_demo.py": "sha256:acdc072a152128236a25f9252d272488dc3f531b3c12271885c70cc0041dfa37", + "literature/verified_fulltext.jsonl": "sha256:91d275aa20a4c85d2aaad978688d279ec44370733e1d8874b67a1e1add9209ae", + "paper/README.md": "sha256:cf85ea212054426cfa19f6fd75850480eece828db580e28c8019462dcc289e97", + "paper/_preamble.tex": "sha256:1b908dc23177955883d2e790ba50af4828b29ca42351439ee5e5b70daa5f724a", + "paper/appendix_table.tex": "sha256:1536016349243c060be06d8a47eaa0424aae72af0b7a81579daab623b41d346d", + "paper/build.py": "sha256:e5d71be0c524dfc29194b3d6d4b137273dcd0b6f1ebbd44e434e5900977c4a65", + "paper/build_survey.py": "sha256:c259d46f25b29a61e6f6f5d7791ab68d3bfd25a60a70339c8669db49b3b507cd", + "paper/data/gate1/README.md": "sha256:6dbfc6332c3b6c2dc1865cc0cacfc427781dfd03cf1442402a4183a51305849a", + "paper/data/gate1/legacy_cd2022/CI.ARV.arrow": "sha256:7956fc2e2b070a1dc3933ff818efd4f34f0c2d2e695260d1a532d8fd47906c65", + "paper/data/gate1/legacy_cd2022/CI.LJR.arrow": "sha256:85e33fa2611f6b7a3beccbfb368abc42573a0f9da142df346a71b8cb9d6658f7", + "paper/data/gate1/legacy_cd2022/CI.RXH.arrow": "sha256:f0ab6c687b75e06ae19fa5a10668bc95515c8fdeab00e2d8a0ab5787772ccc19", + "paper/figures/gate1/dvv_smoke_check_90d.png": "sha256:00df9e0f5632013f0dd97c8a2143e60c3348530b05b37756c7ca9f0b89bec83b", + "paper/figures/gate1/gate1_final_2y.png": "sha256:9f74681a0ddefc6a6d9b80dd2eef15a856f5bff4f0503b66e25a58e28ccaddb8", + "paper/figures/gate1/gate1_heatmaps_zoom.png": "sha256:a15d51eae10aac10b5f5dba48fb4b19a439cbededb1cb29f36f6f098e2598a81", + "paper/figures/gate1/gate1_validation.png": "sha256:9f442edaff04e16b7e128906787b614192e4e9bcfaad73576671d744da6e0d6f", + "paper/manuscript.tex": "sha256:9bb7332eeee4a702c86c3659bc5548d6b77e49764ae80e3c43998ce4350834fe", + "paper/manuscript_marine.qmd": "sha256:582a09ee97ca6f86d80ac3a61301bab8dd5089477fe780cd86c70452dbba0ec0", + "paper/manuscript_marine.tex": "sha256:a60d872160bbb418b71093932c486d5f420a10008dd210441191118051542dc0", + "paper/references.bib": "sha256:f5263a55a6fd3ee7ad5bbd536ea492ef8c841583590f85e636b957dfc8f7e1fb", + "paper/survey.bib": "sha256:7acfc0836dcf4924ea98fdc2d493ddd53246454eb71194d7ce2bae9a16ddd6a9", + "src/codameter/__init__.py": "sha256:692e434d63a1752f08bf7ce7abce9fcee2dd4d2a4627b599316f85e2ffee86cc", + "src/codameter/_version.py": "sha256:db4a8260ba9c834fb069e7425479b3ece5d95afb06478a3f08c119acbc64b4a0", + "src/codameter/anomaly/__init__.py": "sha256:255edcc88170406cfca35319211f9880ee0e4791edd6548a0c787a7c928e373d", + "src/codameter/anomaly/attribution.py": "sha256:ef52decf86eb7c303a3b80eeb6930ba9ea078ae4f77e4315a73bcd8bcec55fbc", + "src/codameter/anomaly/detection.py": "sha256:a2ca317c98fba066123a8efdccd64f3249d0ddc63ace033c589bf198fb2f4d94", + "src/codameter/anomaly/residual_patterns.py": "sha256:91c9534ad5cf7a31eddf02f367c71ceeeccbade915358a3c31157722943fde86", + "src/codameter/bench.py": "sha256:cd2fb3d9fe31ab5a7cadb3834b4871a9af33ac08f2d84cd24e6d84cceb2fd8d1", + "src/codameter/cli.py": "sha256:ab0054ebfae035f5627513d7338bdaf0d0b93d7fe846114d2245d6d9233ee71c", + "src/codameter/config.py": "sha256:94180cce8f6c5c397e27339caa698b6d54e24c57e34421fcedfc048f7c48b86d", + "src/codameter/coupling/__init__.py": "sha256:5e804b1f0d7ad8f1e53891b5aac1436b86d25694101344f72e23651ddd78b32f", + "src/codameter/coupling/decision_tree.py": "sha256:58d290e1931622bc500c77c2ebac01c88f48ea43ffc1d130d13538355b1b6621", + "src/codameter/coupling/tier1_poroelastic.py": "sha256:3d09e1f9bb38a7fc7794f4ed363b2405dff42c0fe6e0d7ba786bf9c2b89bfa5f", + "src/codameter/coupling/tier2_damage.py": "sha256:45c3f07f5d704a26523c8eee2c96b8fcee254f4c4fee2e7b97f560203bffa51d", + "src/codameter/coupling/tier3_saturation.py": "sha256:25e23ee88f29b94a9f6b357e43a5c7c476ba57816e69184e2daf2fde86927b4b", + "src/codameter/coupling/tier4_thermo_capillary.py": "sha256:d40141149d37b7a2382df532925485bffdb0bc490955302ca10895b2e0e8cb8c", + "src/codameter/data/__init__.py": "sha256:642bba2e6b9a28ff42cf95aacaca2a08062cbc6a09e8e2d34bcee1531af0a7bb", + "src/codameter/data/covariates.py": "sha256:eb2e43b8d888c23a7c7947fc1d2811c321ccf23e5fd7ad85e3eaa26955aaa3d3", + "src/codameter/data/loaders.py": "sha256:9ed451225a0e219223ff089503f415118a63bebbf7f75703e518b8daeb42db38", + "src/codameter/data/property_providers.py": "sha256:08044fc0500b73c33af9c37cc37e1efab05615e7f631075d488ef20220310d11", + "src/codameter/data/qc.py": "sha256:26a4a3dbd645a429a97e43db00e2e9423d1132e9d96f8fe96fff80043c712c22", + "src/codameter/data/readiness.py": "sha256:733aaae0a323065f934cf42f261739c6675ae586e00e396069edc9aac2aee1ff", + "src/codameter/deviations.py": "sha256:fd7c3c2965d8c281035f516c9afd5a13f32209f7f825a64daf95167a8e3c7387", + "src/codameter/forcing_models.py": "sha256:ebd5f7879cba31a4a50fca8a6bb20f7e1aab5ae07cd63a3a2b967d6abe800988", + "src/codameter/forward/__init__.py": "sha256:8fdf2cac2650a750ee24c396061de761612d8bbbdb0a30642d44f82ea167040b", + "src/codameter/forward/capillary.py": "sha256:9cb8cbb2faaf37fd5b017da5784cfe9229a04404691df7a587acae1abb2875c6", + "src/codameter/forward/damage.py": "sha256:5cf75bf0b28c4e0807d516ec90491ea784630a6b11801d0128239388377217b0", + "src/codameter/forward/loading.py": "sha256:def69d6ea560e1af691ed47afcf5df0feb58e4ffe7296dcc06ee4da55a1e1061", + "src/codameter/forward/poroelastic.py": "sha256:ab886b9db53292ef80d62c6e2bc81f4e7a235b2fdd5cb8073f5dfc22a6f2d384", + "src/codameter/forward/thermoelastic.py": "sha256:61446165c22a84378ca606160841cad78d5517d9f519276f0c023b100c225d30", + "src/codameter/frugalmind.py": "sha256:8203df997d814b9fcdccd663a6ed2eb9947f79d0586e75439e16ed39f0c8db94", + "src/codameter/golden.py": "sha256:430dcf6b3640a4bb1d02e2c6fb4be3e98b60e32b03b62c70273f8dbb7573649b", + "src/codameter/interpretation/__init__.py": "sha256:10ef78d1dda57756eacc2c767ef92c6e38bdb32bc1e6942e3dec395fab412314", + "src/codameter/interpretation/stress_at_depth.py": "sha256:47ad193ad7e499df36700c0e84996978eb655692c2d6ee941ef00b1ebdaaf9e8", + "src/codameter/interpretation/water_table.py": "sha256:d21eb5c713017c40c9c62bfc4ab9c2602fdae41618290413d6e92adbeee7758d", + "src/codameter/inverse/__init__.py": "sha256:a88b0ec206fde27babff959b8965366f7c23b11c7de7fb24733ede6d10e416fb", + "src/codameter/inverse/coupled_inversion.py": "sha256:bf7a4e4b12244642c73b51547c9d81c7cc28c432a288cefc7c512c8d6ca4e5f3", + "src/codameter/inverse/linear_fit.py": "sha256:8af574f45cdf3efcf77420911a55b4f24c33e5326ca889635fc06f5a7d6cd78a", + "src/codameter/inverse/posterior.py": "sha256:2f2f5cc5a1db8ba82bb8de90a8a2518f039238fdb0d9d40e76f5b0fb7ec3dbb5", + "src/codameter/inverse/priors.py": "sha256:98fff20b216a75aaf270ce391ea2f0867efc345234bddcf6e8577438f470b0a7", + "src/codameter/kernels/__init__.py": "sha256:a736590dd5d00d4347c90c2ec9fa33debf1e216f3536bde8406b642d00ec302f", + "src/codameter/kernels/depth_resolution.py": "sha256:2071660152fd6d78849a1a39b1cd3a155eb308bd9d1ab860be0073d400a505c6", + "src/codameter/kernels/disba_wrapper.py": "sha256:a8d02a10a0ec829dd75ab7a2b6c97e7ba5e1015d566677af05827c1b8c24a8d9", + "src/codameter/kernels/velocity_models.py": "sha256:7e7984a15e546a346806701824aa3e611891ece3719a4aa4f3d1e6332a35af38", + "src/codameter/plotting.py": "sha256:824f8c9fd004ae9de8e8503fdccde504a4922fe19ab68f5e050c2a4ad9850d35", + "src/codameter/private_golden.py": "sha256:a94ec6d930e8b987fb2f1effc234045f1e7975224a9cfdfaf134b16aada94959", + "src/codameter/synthetic_demo.py": "sha256:ca8bb17a57df8712ee8d1019389ddfa718aaf034b9faa0df610d530dd9cee871", + "src/codameter/uq-measurement.py": "sha256:7bc7fd441d494935cb6f7ba4ead86bc0b9d357ddaced7890dadbc7d4243c6ada", + "src/codameter/uq_bayes.py": "sha256:f0822286e6794a908e0cb5adb1c303bca20e6c9d214647a50e252a1d72753d37", + "src/codameter/uq_depth.py": "sha256:e956d77cf0306b1f731d09a6c2039271968928da0763623b619ccc9d92a5cef3", + "src/codameter/uq_measurement.py": "sha256:010c68110aa963d9bdd382d8a4445a73e72d2c0f7ceec357d744df27c16b2b3a", + "src/codameter/uq_processing.py": "sha256:ce650937591e67ff46a0bde018ae9d26d79e3ea316fac06db720ae3f74ac8fd3", + "src/codameter/use_cases.py": "sha256:981ebead6a158e09a943c50d7ad9238921075b32b6cc737967df0d70b3694fe9", + "src/codameter/workflow.py": "sha256:a037eb72a98f54388953e371ea53c9d38d61492242f108f41e955b259c474871", + "tests/conftest.py": "sha256:7125550878e4080d47c85ad06f0596ac72815757dca12e855a3a2facb9a37ee6", + "tests/data/golden/manifest.json": "sha256:fb0abc1057a577bce1b68e73e0e684a2b871d2a70bbc4ebe04dcfa770f8ca5a1", + "tests/test_bench.py": "sha256:92d8dbcd534e2979e3cac1ffe18c4063b799c832b1b8e9faf101f35d0676c96b", + "tests/test_cli.py": "sha256:43f942ef2b7a68ab0f37f1912913d7d6edced54dc26a86cd426958cf2c73edcf", + "tests/test_coupling.py": "sha256:600fd0fcdf919568864f0b446577b977a89680ec94f1c73f084901d92feb880e", + "tests/test_coupling_tiers.py": "sha256:3e861e12bdb0bffd0c1c1dd2fe5aadf1e3535e06951a94932807a58f3db80d7e", + "tests/test_data_loaders.py": "sha256:b763795081ee19dd4ecd35e46b73682b38d5947109ad02626e62fad6a9e7fb5e", + "tests/test_data_readiness.py": "sha256:25f54eb9920ff4ac4cccf34a43e12bae39a52775e7b894a0ea5884d443cc1c61", + "tests/test_deviations.py": "sha256:e36c9f83d314b604af930c381fa9058fffea401710585cb207c7feca49328860", + "tests/test_forcing_models.py": "sha256:d6cfaef86b667d71987a4cd4fd5371d35e868d99d1e793fb457b8ee4aef0af48", + "tests/test_forward_models.py": "sha256:0a8514e648e8c216664f6c7b29431b733e87f9756ee3703c54af51e8cf32e989", + "tests/test_frugalmind_export.py": "sha256:3a63e24a4f6eac884c25e299012da8febe1cc7cd8903cfced97752b1f72a51e8", + "tests/test_golden.py": "sha256:e5bf032f3ffe1a1b11dbebbc311355c3f4dec3c81fa6491a93638232a5aa2d61", + "tests/test_kernels.py": "sha256:4a4b72d7469a1dd758c1107367358c6826ba330931ebab3f92b899506ccbf2f0", + "tests/test_linear_inversion.py": "sha256:27e98bd63a592f7e001364d6f0503c59a340966fb4a071d7693b1544495c036f", + "tests/test_private_golden.py": "sha256:bafcad630f9a59e2cfee1665a168fc90f462bd7e48ee3b4874c0f999267989e0", + "tests/test_property_providers.py": "sha256:a01cdc179fb0237c427bf87937bb6e51bb775a4da95a220c5c3d74b7f36659a1", + "tests/test_sign_convention.py": "sha256:ce9d272ca44b8ed119afbd20af1f22268e97a95cfc7c9991abf56d5b3f0938e4", + "tests/test_staged_workflow.py": "sha256:ba0842d261e858c9678605f85dbec77bb25122edf69d11fd1238ce4c7fe49f32", + "tests/test_stretching_interpolation.py": "sha256:a7770b6198ab437e2d96c5bd6e0a7f758e1b25e0e7f80e0653ec62257c9daec4", + "tests/test_synthetic_demo.py": "sha256:569e59c69d86394dca2c227438120f3a404cf4e89d1d949a3ef023612da5cc1a", + "tests/test_synthetic_parkfield.py": "sha256:e396e4c18d31c9bc6ea1ad014134fe0d679c0906458153247fbff852cd6429e9", + "tests/test_uq_bayes.py": "sha256:90a3469cbf275353eab666cd8f0c619dd425acf5ab9f307f0d6e84bedbeed097", + "tests/test_uq_depth.py": "sha256:b06dba43ffe88467f2006ca43b449580794936da1c488cf497a0fdb1fc0f2cef", + "tests/test_uq_measurement.py": "sha256:710fb57836ba0c4514cf60a8361540f02b5ed7aa324c0e85de88bef70f79ca71", + "tests/test_uq_processing.py": "sha256:9aa29e01010e30d36103c2f6b6f59c675857f6303cd821a3bad7f1b8f7ad1e7f", + "tests/test_use_cases.py": "sha256:d71d01f78877720faef8312018b4d3ae31f05195fc88134bd114b35fade1784d" + }, + "conversion_note": "Converted 2026-09-10 from review/codameter-gji.review.json (Astra, iteration 1, frozen). Added section, scope, plan_package, hash_method, manuscript_ref, open; renamed verification -> execution_evidence to avoid collision with the S-AV verification log. No finding text, tier, status or ID changed." +} diff --git a/scripts/compare_gate1.py b/scripts/compare_gate1.py new file mode 100644 index 0000000..1b2b2f0 --- /dev/null +++ b/scripts/compare_gate1.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python3 +"""Compare the Gate 1 codameter single-station dv/v products with the published +Clements and Denolle (2022) product under explicit, stated rules. + +Inputs (see paper/data/gate1/README.md): + paper/data/gate1/dvv2y/band=2.0-4.0/CI..parquet daily ensemble dv/v (%) + paper/data/gate1/legacy_cd2022/CI..arrow published 90-day-comp product + +Rules (each reported separately): + matched codameter daily series placed on a calendar-day grid, trailing + 90-day mean (at least 45 finite days in the window, matching the + published product's own trailing 90-day construction), the first + 150 days of each station's record excluded as reference burn-in, + inner join on calendar dates with the published product restricted + to 2018-2019. + centered as above but a centred 45-day mean and no burn-in (the smoothing + used for the annotation on the Gate 1 figure). + raw daily values, no smoothing, no burn-in. + +Statistics: number of overlapping days, Pearson r, RMS of the difference +after removing each series' mean over the overlap, and the OLS slope of the +published product on the codameter series (amplitude ratio). Output: +paper/data/gate1/comparison.json and a Markdown table on stdout. +Every number about this comparison quoted in the manuscript comes from here. +""" + +from __future__ import annotations + +import json +import sys +from pathlib import Path + +import numpy as np +import pandas as pd +import pyarrow.ipc as ipc + +ROOT = Path(__file__).resolve().parents[1] +GATE1 = ROOT / "paper" / "data" / "gate1" +STATIONS = ("LJR", "ARV", "RXH") +BAND = "2.0-4.0" +BURN_IN_DAYS = 150 +TRAILING_DAYS = 90 +TRAILING_MIN = 45 +CENTERED_DAYS = 45 +CENTERED_MIN = 23 + + +def load(sta: str): + d = pd.read_parquet(GATE1 / "dvv2y" / f"band={BAND}" / f"CI.{sta}.parquet") + d["date"] = pd.to_datetime(d["date"]) + daily = d.set_index("date")["dvv"].sort_index() + daily = daily.reindex(pd.date_range(daily.index.min(), daily.index.max(), freq="D")) + legacy = ( + ipc.open_file(GATE1 / "legacy_cd2022" / f"CI.{sta}.arrow") + .read_all() + .to_pandas() + ) + legacy["DATE"] = pd.to_datetime(legacy["DATE"]) + legacy = legacy.set_index("DATE")["DVV"].sort_index() + legacy = legacy[(legacy.index >= "2018-01-01") & (legacy.index <= "2019-12-31")] + return daily, legacy + + +def stats(a: pd.Series, b: pd.Series) -> dict: + m = pd.DataFrame({"a": a, "b": b}).dropna() + if len(m) < 3: + return {"n": int(len(m)), "r": None, "rms_diff": None, "slope": None} + a0, b0 = m["a"] - m["a"].mean(), m["b"] - m["b"].mean() + slope = float(np.polyfit(a0, b0, 1)[0]) + return { + "n": int(len(m)), + "first": str(m.index.min().date()), + "last": str(m.index.max().date()), + "r": float(a0.corr(b0)), + "rms_diff": float(np.sqrt(np.mean((a0 - b0) ** 2))), + "slope": slope, + } + + +def compare(sta: str) -> dict: + daily, legacy = load(sta) + burn = daily.index.min() + pd.Timedelta(days=BURN_IN_DAYS) + trailing = daily.rolling(f"{TRAILING_DAYS}D", min_periods=TRAILING_MIN).mean() + centered = daily.rolling( + CENTERED_DAYS, center=True, min_periods=CENTERED_MIN + ).mean() + return { + "station": f"CI.{sta}", + "daily_rows": int(daily.notna().sum()), + "daily_first": str(daily.index.min().date()), + "daily_last": str(daily.index.max().date()), + "legacy_rows_2018_2019": int(legacy.notna().sum()), + "burn_in_until": str(burn.date()), + "matched": stats(trailing[trailing.index >= burn], legacy), + "matched_no_burn_in": stats(trailing, legacy), + "centered": stats(centered, legacy), + "raw": stats(daily, legacy), + } + + +def main() -> int: + out = { + "rules": { + "band_hz": BAND, + "burn_in_days": BURN_IN_DAYS, + "trailing_days": TRAILING_DAYS, + "trailing_min_finite": TRAILING_MIN, + "centered_days": CENTERED_DAYS, + "centered_min_finite": CENTERED_MIN, + "join": "inner join on calendar date; published product restricted to 2018-2019", + "r": "Pearson, on the overlap, after removing each series' overlap mean", + "slope": "OLS slope of the published product on the codameter series", + }, + "stations": [compare(s) for s in STATIONS], + } + (GATE1 / "comparison.json").write_text(json.dumps(out, indent=1) + "\n") + print("| Station | Rule | n days | r | RMS diff (%) | slope |") + print("|---|---|---:|---:|---:|---:|") + for s in out["stations"]: + for rule in ("matched", "matched_no_burn_in", "centered", "raw"): + t = s[rule] + if t["r"] is None: + continue + print( + f"| {s['station']} | {rule} | {t['n']} | {t['r']:.3f} | {t['rms_diff']:.3f} | {t['slope']:.2f} |" + ) + print(f"wrote {GATE1 / 'comparison.json'}", file=sys.stderr) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/correct_gate1_within_error.py b/scripts/correct_gate1_within_error.py new file mode 100644 index 0000000..7adec03 --- /dev/null +++ b/scripts/correct_gate1_within_error.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python3 +"""Rescale the archived Gate 1 within-measurement error column to the corrected +Weaver floor. + +The Gate 1 dv/v products (paper/data/gate1/dvv2y/band=-/CI..parquet) +were produced with codameter 0.4, whose Weaver floor omitted the spectral +timescale T and used a variance prefactor twice Weaver et al.'s (audit +finding UQ-01), and with the geometric mean of the band edges as centre +frequency where codameter now uses the arithmetic mean. Every ensemble member +shares the band, so the corrected floor is the old one times a constant: + + factor = sqrt(T / 2) * f_geo / f_arith, T = sqrt(ln 10) / (pi * (f2 - f1)) + +for every epoch and member. This script rescales ``dvv_err_within`` by that +factor, recomputes ``dvv_err = sqrt(within^2 + method^2)``, leaves every other +column untouched, keeps the original file as ``CI..v040.parquet``, and +writes ``correction.json`` beside the products. Idempotent: a file whose +sidecar records the correction is skipped. +""" + +from __future__ import annotations + +import json +import sys +from datetime import datetime, timezone +from pathlib import Path + +import numpy as np +import pandas as pd +from codameter import __version__ +from codameter.uq_measurement import bandwidth_timescale + +ROOT = Path(__file__).resolve().parents[1] +GATE1 = ROOT / "paper" / "data" / "gate1" / "dvv2y" + + +def factor_for_band(f1: float, f2: float) -> dict: + T = bandwidth_timescale(f2 - f1) + f_geo, f_arith = float(np.sqrt(f1 * f2)), 0.5 * (f1 + f2) + return { + "T_s": T, + "prefactor_and_T": float(np.sqrt(T / 2.0)), + "centre_frequency": f_geo / f_arith, + "factor": float(np.sqrt(T / 2.0) * f_geo / f_arith), + } + + +def main() -> int: + log_path = GATE1 / "correction.json" + log = json.loads(log_path.read_text()) if log_path.exists() else {"files": {}} + for band_dir in sorted(GATE1.glob("band=*")): + f1, f2 = (float(x) for x in band_dir.name.split("=")[1].split("-")) + fac = factor_for_band(f1, f2) + for p in sorted(band_dir.glob("CI.*.parquet")): + if p.name.endswith(".v040.parquet"): + continue + key = str(p.relative_to(GATE1)) + if key in log["files"]: + print(f"skip {key}: already corrected on {log['files'][key]['date']}") + continue + backup = p.with_name(p.name.replace(".parquet", ".v040.parquet")) + d = pd.read_parquet(p) + before = ( + d[["dvv_err", "dvv_err_within", "dvv_err_method"]].median().to_dict() + ) + d["dvv_err_within"] = d["dvv_err_within"] * fac["factor"] + d["dvv_err"] = np.sqrt(d["dvv_err_within"] ** 2 + d["dvv_err_method"] ** 2) + after = ( + d[["dvv_err", "dvv_err_within", "dvv_err_method"]].median().to_dict() + ) + if not backup.exists(): + p.rename(backup) + d.to_parquet(p, index=False) + log["files"][key] = { + "date": datetime.now(timezone.utc).isoformat(timespec="seconds"), + "codameter_version": __version__, + "band_hz": [f1, f2], + **fac, + "original": backup.name, + "median_before_percent": before, + "median_after_percent": after, + } + print( + f"{key}: factor {fac['factor']:.4f}; within {before['dvv_err_within']:.4f} -> " + f"{after['dvv_err_within']:.4f} %, total {before['dvv_err']:.4f} -> {after['dvv_err']:.4f} %" + ) + log["note"] = ( + "dvv_err_within rescaled to the corrected Weaver floor (codameter >= 0.5): " + "sqrt(T/2) for the missing spectral timescale and the eq. 20 prefactor, " + "times f_geo/f_arith for the centre-frequency convention; dvv_err recomputed." + ) + log_path.write_text(json.dumps(log, indent=1) + "\n") + print(f"wrote {log_path}", file=sys.stderr) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/src/codameter/__init__.py b/src/codameter/__init__.py index 84244e9..4367f1d 100644 --- a/src/codameter/__init__.py +++ b/src/codameter/__init__.py @@ -31,12 +31,15 @@ from .uq_measurement import ( EnsembleResult, GlobalReferenceSolution, + bandwidth_timescale, effective_sample_size, global_reference_inversion, processing_ensemble, single_reference_dvv, temporal_error_covariance, + weaver_rms_dilation, weaver_stretching_error, + weaver_stretching_error_band, ) from .uq_processing import ( ProcessingChoice, @@ -70,6 +73,9 @@ "GoalReadiness", # Measurement (aleatoric) uncertainty of the dv/v observation "weaver_stretching_error", + "weaver_stretching_error_band", + "weaver_rms_dilation", + "bandwidth_timescale", "processing_ensemble", "EnsembleResult", "temporal_error_covariance", diff --git a/src/codameter/bench.py b/src/codameter/bench.py index db7810d..d4950c1 100644 --- a/src/codameter/bench.py +++ b/src/codameter/bench.py @@ -22,21 +22,26 @@ Run ``codameter-bench --help``. """ + from __future__ import annotations import argparse import json import os +import re import sys -from functools import lru_cache +from collections import Counter +from collections.abc import Iterator +from functools import cache from itertools import product from pathlib import Path -from typing import Any, Iterator +from typing import Any import numpy as np from . import golden from . import use_cases as uc +from ._version import __version__ from .deviations import metrics # --------------------------------------------------------------------------- @@ -52,20 +57,29 @@ # Small, fast: for `plan`, tests, and smoke runs. "compact": { "estimator": ["stretching (TS)", "MWCS"], - "band": "rec", "window": "rec", "stack": "rec", - "reference": ["fixed", "moving"], "gate": [True], + "band": "rec", + "window": "rec", + "stack": "rec", + "reference": ["fixed", "moving"], + "gate": [True], }, # The default massive sweep: hundreds of cells per case. "multiverse": { "estimator": ESTIMATORS_ALL, - "band": "variants", "window": "variants", "stack": [None, 1, 45], - "reference": ["fixed", "moving", "inversion"], "gate": [True, False], + "band": "variants", + "window": "variants", + "stack": [None, 1, 45], + "reference": ["fixed", "moving", "inversion"], + "gate": [True, False], }, # Everything, for an overnight run. "wide": { "estimator": ESTIMATORS_ALL, - "band": "variants", "window": "variants", "stack": [None, 1, 5, 20, 60], - "reference": ["fixed", "moving", "inversion"], "gate": [True, False], + "band": "variants", + "window": "variants", + "stack": [None, 1, 5, 20, 60], + "reference": ["fixed", "moving", "inversion"], + "gate": [True, False], }, } @@ -113,15 +127,24 @@ def build_grid(case: dict, grid: str = "multiverse") -> list[dict]: else: bands = _axis_values(rec["band"], spec["band"], _band_variants) windows = _axis_values(rec["window"], spec["window"], _window_variants) - stacks = [rec["stack"] if s is None else s for s in - _axis_values(rec["stack"], spec["stack"], None)] + stacks = [ + rec["stack"] if s is None else s + for s in _axis_values(rec["stack"], spec["stack"], None) + ] configs = [] for est, band, window, stack, ref, gate in product( spec["estimator"], bands, windows, stacks, spec["reference"], spec["gate"] ): - configs.append({"estimator": est, "band": tuple(band), - "window": tuple(window), "stack": int(stack), - "reference": ref, "gate": bool(gate)}) + configs.append( + { + "estimator": est, + "band": tuple(band), + "window": tuple(window), + "stack": int(stack), + "reference": ref, + "gate": bool(gate), + } + ) return configs @@ -154,7 +177,9 @@ def parse_shard(spec: str | None) -> tuple[int, int]: if spec: k, n = spec.split("/") return int(k), int(n) - idx = os.environ.get("AWS_BATCH_JOB_ARRAY_INDEX") or os.environ.get("CODAMETER_SHARD_INDEX") + idx = os.environ.get("AWS_BATCH_JOB_ARRAY_INDEX") or os.environ.get( + "CODAMETER_SHARD_INDEX" + ) cnt = os.environ.get("CODAMETER_SHARDS") if idx is not None and cnt is not None: return int(idx), int(cnt) @@ -164,7 +189,7 @@ def parse_shard(spec: str | None) -> tuple[int, int]: # --------------------------------------------------------------------------- # Scoring one cell # --------------------------------------------------------------------------- -@lru_cache(maxsize=None) +@cache def _case(case_id: str) -> dict: """Load a case's arrays once per process (deterministic, disk-cached).""" return golden.generate(case_id) @@ -175,13 +200,19 @@ def score_cell(case_id: str, config_index: int, cfg: dict) -> dict: case = golden.CASES_BY_ID[case_id] use_case = case["use_case"] row = { - "case_id": case_id, "use_case": use_case, "grade": case["grade"], + "case_id": case_id, + "use_case": use_case, + "grade": case["grade"], "config_index": config_index, - "estimator": cfg["estimator"], "band": list(cfg["band"]), - "window": list(cfg["window"]), "stack": cfg["stack"], - "reference": cfg["reference"], "gate": cfg["gate"], + "estimator": cfg["estimator"], + "band": list(cfg["band"]), + "window": list(cfg["window"]), + "stack": cfg["stack"], + "reference": cfg["reference"], + "gate": cfg["gate"], "target": case.get("target"), "eps_max": uc.eps_max(use_case), + "codameter_version": __version__, } try: d = _case(case_id) @@ -190,9 +221,13 @@ def score_cell(case_id: str, config_index: int, cfg: dict) -> dict: # to the plain pipeline for single-channel ones. dvv, valid = golden.recover(d, cfg, row["eps_max"]) m = metrics(dvv, d["truth"], d["days"], valid) - row.update(rms=golden._rms(dvv, d["truth"], d["days"], valid), - drop_err=m["drop_err"], n_valid=int(np.sum(valid)), ok=True, - error=None) + row.update( + rms=golden._rms(dvv, d["truth"], d["days"], valid), + drop_err=m["drop_err"], + n_valid=int(np.sum(valid)), + ok=True, + error=None, + ) except Exception as exc: # a bad cell must not kill the shard row.update(rms=None, drop_err=None, n_valid=0, ok=False, error=str(exc)) return row @@ -205,8 +240,15 @@ def _score_star(args): # --------------------------------------------------------------------------- # Sweep driver # --------------------------------------------------------------------------- -def run_sweep(*, case_ids: list[str], grid: str, k: int, n: int, - jobs: int = 1, progress_every: int = 200) -> list[dict]: +def run_sweep( + *, + case_ids: list[str], + grid: str, + k: int, + n: int, + jobs: int = 1, + progress_every: int = 200, +) -> list[dict]: """Score this shard's cells and return the rows (unwritten).""" items = shard(work_items(case_ids, grid), k, n) # Pre-generate the shard's unique cases to disk once, so parallel workers @@ -217,6 +259,7 @@ def run_sweep(*, case_ids: list[str], grid: str, k: int, n: int, rows: list[dict] = [] if jobs and jobs > 1: from concurrent.futures import ProcessPoolExecutor + with ProcessPoolExecutor(max_workers=jobs) as ex: for i, row in enumerate(ex.map(_score_star, items, chunksize=4), 1): rows.append(row) @@ -236,12 +279,16 @@ def run_sweep(*, case_ids: list[str], grid: str, k: int, n: int, def _write_jsonl(rows: list[dict], out: str, name: str) -> str: """Write ``rows`` to ``/``; ``out`` may be a local dir or s3://.""" body = "".join(json.dumps(r, ensure_ascii=False) + "\n" for r in rows) + return _write_text(body, out, name) + + +def _write_text(body: str, out: str, name: str) -> str: if out.startswith("s3://"): import tempfile import boto3 # optional; only needed for s3 output - bucket, _, prefix = out[len("s3://"):].partition("/") + bucket, _, prefix = out[len("s3://") :].partition("/") key = f"{prefix.rstrip('/')}/{name}" if prefix else name with tempfile.NamedTemporaryFile("w", suffix=".jsonl", delete=False) as fh: fh.write(body) @@ -256,25 +303,80 @@ def _write_jsonl(rows: list[dict], out: str, name: str) -> str: return str(path) -def _read_jsonl_dir(src: str) -> Iterator[dict]: +_SHARD_RE = re.compile(r"shard-(\d+)-of-(\d+)\.jsonl$") + + +def _read_jsonl_dir(src: str) -> Iterator[tuple[str, dict]]: + """Yield ``(shard_file_name, row)`` for every row under ``src``.""" if src.startswith("s3://"): import boto3 - bucket, _, prefix = src[len("s3://"):].partition("/") + bucket, _, prefix = src[len("s3://") :].partition("/") s3 = boto3.client("s3") for obj in s3.get_paginator("list_objects_v2").paginate( - Bucket=bucket, Prefix=prefix): + Bucket=bucket, Prefix=prefix + ): for it in obj.get("Contents", []): if it["Key"].endswith(".jsonl"): body = s3.get_object(Bucket=bucket, Key=it["Key"])["Body"].read() for line in body.decode().splitlines(): if line.strip(): - yield json.loads(line) + yield Path(it["Key"]).name, json.loads(line) else: for path in sorted(Path(src).glob("shard-*.jsonl")): for line in path.read_text().splitlines(): if line.strip(): - yield json.loads(line) + yield path.name, json.loads(line) + + +def check_shards(pairs: list[tuple[str, dict]]) -> dict: + """Inventory a set of shard rows and list what stops them being merged. + + A merge is complete only if every shard ``k`` of the declared ``N`` is + present, every ``(case_id, config_index)`` cell appears exactly once, and + all rows come from one codameter version (audit SCALE-02). Retries that + rewrite a shard file are fine; a shard appended twice is not. + """ + names = sorted({n for n, _ in pairs}) + ks: set[int] = set() + ns: set[int] = set() + unparsed = [] + for n in names: + m = _SHARD_RE.search(n) + if not m: + unparsed.append(n) + continue + ks.add(int(m.group(1))) + ns.add(int(m.group(2))) + problems = [] + if unparsed: + problems.append(f"unrecognised shard file name(s): {unparsed}") + if len(ns) > 1: + problems.append(f"shard files declare different shard counts: {sorted(ns)}") + n_shards = next(iter(ns)) if len(ns) == 1 else 0 + missing = sorted(set(range(n_shards)) - ks) + if missing: + problems.append(f"missing shard(s) {missing} of {n_shards}") + cells = Counter((r.get("case_id"), r.get("config_index")) for _, r in pairs) + dups = sorted(c for c, k in cells.items() if k > 1) + if dups: + problems.append( + f"duplicate cell(s): {dups[:10]}{' ...' if len(dups) > 10 else ''}" + ) + versions = sorted({str(r.get("codameter_version")) for _, r in pairs}) + if len(versions) > 1: + problems.append(f"rows from different codameter versions: {versions}") + return { + "n_shards": n_shards, + "shards_present": sorted(ks), + "missing": missing, + "duplicate_cells": len(dups), + "codameter_versions": versions, + "n_rows": len(pairs), + "unique_cells": len(cells), + "problems": problems, + "complete": not problems, + } # --------------------------------------------------------------------------- @@ -291,18 +393,24 @@ def _cmd_plan(args) -> int: items = work_items(case_ids, args.grid) k, n = parse_shard(args.shard) per = [len(shard(items, i, n)) for i in range(n)] - print(f"grid={args.grid} cases={len(case_ids)} configs/case=" - f"{len(build_grid(golden.CASES_BY_ID[case_ids[0]], args.grid))}") - print(f"total cells={len(items)} shards={n} " - f"cells/shard: min={min(per)} max={max(per)}") + print( + f"grid={args.grid} cases={len(case_ids)} configs/case=" + f"{len(build_grid(golden.CASES_BY_ID[case_ids[0]], args.grid))}" + ) + print( + f"total cells={len(items)} shards={n} " + f"cells/shard: min={min(per)} max={max(per)}" + ) return 0 def _cmd_sweep(args) -> int: case_ids = _all_case_ids(args.cases) k, n = parse_shard(args.shard) - print(f"sweep grid={args.grid} shard={k}/{n} cases={len(case_ids)} " - f"jobs={args.jobs}", file=sys.stderr) + print( + f"sweep grid={args.grid} shard={k}/{n} cases={len(case_ids)} jobs={args.jobs}", + file=sys.stderr, + ) rows = run_sweep(case_ids=case_ids, grid=args.grid, k=k, n=n, jobs=args.jobs) name = f"shard-{k:05d}-of-{n:05d}.jsonl" where = _write_jsonl(rows, args.out, name) @@ -312,11 +420,32 @@ def _cmd_sweep(args) -> int: def _cmd_aggregate(args) -> int: - rows = list(_read_jsonl_dir(args.src)) - if not rows: + pairs = list(_read_jsonl_dir(args.src)) + if not pairs: print("no shard rows found", file=sys.stderr) return 1 + inventory = check_shards(pairs) + allow_partial = bool(getattr(args, "allow_partial", False)) + for problem in inventory["problems"]: + print(f"aggregate: {problem}", file=sys.stderr) + fatal = [ + p + for p in inventory["problems"] + if not (allow_partial and p.startswith("missing shard")) + ] + if fatal: + print( + "aggregate: refusing to merge; --allow-partial accepts missing " + "shards only, never duplicates or mixed versions", + file=sys.stderr, + ) + return 1 + rows = [r for _, r in pairs] where = _write_jsonl(rows, args.out, "sweep.jsonl") + inventory["n_ok"] = sum(bool(r.get("ok")) for r in rows) + _write_text( + json.dumps(inventory, indent=1) + "\n", args.out, "aggregate_manifest.json" + ) # Compact per-case summary: best config by RMS. best: dict[str, dict] = {} for r in rows: @@ -328,34 +457,52 @@ def _cmd_aggregate(args) -> int: print(f"aggregated {len(rows)} rows -> {where}") for cid in sorted(best): b = best[cid] - print(f" {cid:<24} best rms={b['rms']*100:.4f}% " - f"{b['estimator']} band={b['band']} ref={b['reference']}") + print( + f" {cid:<24} best rms={b['rms'] * 100:.4f}% " + f"{b['estimator']} band={b['band']} ref={b['reference']}" + ) return 0 def main(argv: list[str] | None = None) -> int: - p = argparse.ArgumentParser(prog="codameter-bench", description=__doc__.split("\n")[0]) + p = argparse.ArgumentParser( + prog="codameter-bench", description=__doc__.split("\n")[0] + ) sub = p.add_subparsers(dest="command", required=True) common = argparse.ArgumentParser(add_help=False) common.add_argument("--grid", default="multiverse", choices=sorted(GRIDS)) - common.add_argument("--cases", default="all", - help="'all' or a comma-separated list of case ids") - common.add_argument("--shard", default=None, - help="k/N; else read AWS_BATCH_JOB_ARRAY_INDEX + CODAMETER_SHARDS") + common.add_argument( + "--cases", default="all", help="'all' or a comma-separated list of case ids" + ) + common.add_argument( + "--shard", + default=None, + help="k/N; else read AWS_BATCH_JOB_ARRAY_INDEX + CODAMETER_SHARDS", + ) sp = sub.add_parser("plan", parents=[common], help="count work items / shards") sp.set_defaults(func=_cmd_plan) ss = sub.add_parser("sweep", parents=[common], help="score this shard's cells") ss.add_argument("--out", required=True, help="local dir or s3:// prefix") - ss.add_argument("--jobs", type=int, default=int(os.environ.get("CODAMETER_JOBS", "1")), - help="parallel worker processes for this shard") + ss.add_argument( + "--jobs", + type=int, + default=int(os.environ.get("CODAMETER_JOBS", "1")), + help="parallel worker processes for this shard", + ) ss.set_defaults(func=_cmd_sweep) sa = sub.add_parser("aggregate", help="merge shard-*.jsonl into one table") sa.add_argument("--src", required=True, help="dir or s3:// prefix of shard files") sa.add_argument("--out", required=True, help="local dir or s3:// prefix") + sa.add_argument( + "--allow-partial", + action="store_true", + help="merge even if shards are missing (recorded in " + "aggregate_manifest.json); duplicates still refuse", + ) sa.set_defaults(func=_cmd_aggregate) args = p.parse_args(argv) diff --git a/src/codameter/calibration.py b/src/codameter/calibration.py new file mode 100644 index 0000000..ff63097 --- /dev/null +++ b/src/codameter/calibration.py @@ -0,0 +1,364 @@ +"""Coverage calibration of the Bayesian measurement covariance (audit SCI-05). + +A single synthetic realisation cannot show that an interval is calibrated. +This module repeats the end-to-end Bayesian measurement +(:func:`codameter.uq_bayes.bayes_dvv_from_ccfs`) over independent waveform and +noise realisations of the same truth and reports, per realisation and in +aggregate, three coverages that answer three different questions: + +``member_coverage68/95`` + Fraction of member epochs with ``|m_k(t) - truth(t)| <= z sqrt(Cd_tt)``. + This is what ``Cd`` claims to be: the covariance of *one* measurement + drawn from the ensemble. It is the calibration target for ``Cd`` and the + quantity the acceptance margin is applied to. +``coverage95_posterior`` + Fraction of epochs where the 95 percent credible band on ``mu`` contains + the truth. This is the precision of the *combined* estimate under the + model; it under-covers whenever the configurations share a bias that + averaging cannot remove. +``coverage68/95`` + Fraction of epochs with ``|mu(t) - truth(t)| <= z sqrt(Cd_tt)``. Reported + because the manuscript used to quote it, but it mixes the ensemble mean + with a single-measurement scale and over-covers by construction. + +Also reported: interval width, bias, RMSE of ``mu`` and of the members, the +shared bias ``mean(mu - truth)``, the prior shares, and failures. Aggregate +values are means over realisations with standard errors across them +(realisations are independent; epochs within one are not). + +Scenarios:: + + clean independent noise only (the model's own assumptions) + clock_drift plus a station clock drift every configuration sees. A + lapse-independent shift appears with opposite signs on the + causal and acausal branches, and every configuration in + the default ensemble measures both branches together, so + the drift cancels: this scenario tests that immunity, not + a shared bias (the 20-realisation pilot was + indistinguishable from clean). + shared_source plus a seasonally varying noise source that warps the + late coda every configuration measures (the + waveform-level version of Zhan et al. 2013): a bias + every member shares, which the ensemble spread cannot + reveal. + +Run:: + + python -m codameter.calibration --n 20 --jobs 4 --scenario clean \ + --out paper/data/calibration/clean.json + +The predefined acceptance margin is member-level 95 percent coverage within +``COVERAGE_MARGIN`` of nominal (set before the locked run, see +review/EXECUTION_PLAN.md). +""" + +from __future__ import annotations + +import argparse +import json +import multiprocessing as mp +import subprocess +from datetime import datetime, timezone +from functools import partial +from pathlib import Path +from typing import Any + +import numpy as np + +from ._version import __version__ + +__all__ = [ + "SCENARIOS", + "COVERAGE_MARGIN", + "make_realization", + "run_realization", + "run_calibration", + "summarize", +] + +SCENARIOS = ("clean", "clock_drift", "shared_source") +#: Predefined acceptance margin on 95 percent pointwise coverage. +COVERAGE_MARGIN = 0.03 +Z68, Z95 = 1.0, 1.959964 + + +def make_realization( + seed: int, scenario: str = "clean", *, years: float = 2.5, snr: float = 7.0 +): + """Synthetic CCFs for one realisation: ``(synth, days, truth, ccfs)``.""" + from .synthetic_demo import ( + Synth, + _days, + add_clock_drift, + add_seasonal_late_noise, + daily_ccfs, + volcano_truth, + ) + + if scenario not in SCENARIOS: + raise ValueError(f"scenario must be one of {SCENARIOS}") + s = Synth() + days = _days(years) + truth = volcano_truth(days) + ccfs = daily_ccfs(s.t, [s.ref], [truth], fs=s.fs, snr=snr, seed=seed) + if scenario == "clock_drift": + # A clock drift of 4e-5 s/day from 40% of the record: ~0.02 s by the + # end, an apparent dv/v of order 1e-3 per branch in a ~18 s coda + # window, with opposite signs on the two branches. + ccfs = add_clock_drift( + ccfs, s.t, drift_s_per_day=4e-5, onset_day=int(0.4 * days.size) + ) + elif scenario == "shared_source": + # A seasonal source effect confined to lapse > 6 s, i.e. to the whole + # of every configuration's coda window (8-28 s and 12-34 s): a + # spurious seasonal dv/v of 0.2% amplitude that every member sees. + ccfs = add_seasonal_late_noise( + ccfs, s.t, days, fs=s.fs, onset_s=6.0, dvv_amp=0.002, seed=seed + ) + return s, days, truth, ccfs + + +def run_realization( + seed: int, + scenario: str = "clean", + *, + years: float = 2.5, + snr: float = 7.0, + cadence: int = 4, + n_iter: int = 1200, + burn: int = 400, + thin: int = 2, +) -> dict[str, Any]: + """One realisation end to end; never raises (failures are recorded).""" + from .uq_bayes import bayes_dvv_from_ccfs + + out: dict[str, Any] = {"seed": int(seed), "scenario": scenario, "ok": False} + try: + s, days, truth, ccfs = make_realization(seed, scenario, years=years, snr=snr) + res, run = bayes_dvv_from_ccfs( + ccfs, + s.t, + s.fs, + truth=truth, + days=days, + cadence=cadence, + n_iter=n_iter, + burn=burn, + thin=thin, + seed=seed, + ) + tr = np.asarray(run.truth, float) + err = res.mu_mean - tr + sd = np.sqrt(np.diag(res.Cd)) + member_err = run.members - tr[None, :] + observed = ( + np.isfinite(member_err) + & np.isfinite(run.within_sigma) + & (run.within_sigma > 0) + & np.isfinite(sd[None, :]) + ) + if not observed.any(): + raise ValueError("no observed member epochs for coverage calibration") + # Comparing NaN with a width returns False, not NaN. Mask before the + # comparison so warm-up / gated cells are not counted as misses. + member_abs_error = np.abs(member_err[observed]) + member_sd = np.broadcast_to(sd, member_err.shape)[observed] + out.update( + ok=True, + n_epochs=int(tr.size), + n_member_epochs=int(observed.sum()), + member_coverage68=float(np.mean(member_abs_error <= Z68 * member_sd)), + member_coverage95=float(np.mean(member_abs_error <= Z95 * member_sd)), + member_rmse=float(np.sqrt(np.mean(member_abs_error**2))), + shared_bias=float(np.mean(err)), + coverage68=float(np.mean(np.abs(err) <= Z68 * sd)), + coverage95=float(np.mean(np.abs(err) <= Z95 * sd)), + coverage95_posterior=float(np.mean((tr >= res.mu_lo) & (tr <= res.mu_hi))), + median_sd=float(np.median(sd)), + median_halfwidth95=float(Z95 * np.median(sd)), + bias=float(np.mean(err)), + rmse=float(np.sqrt(np.mean(err**2))), + max_abs_err=float(np.max(np.abs(err))), + tau=float(res.tau), + s=float(res.s), + corr_length_days=float(res.corr_length_days), + n_eff=float(res.n_eff), + missing_fraction=float(np.mean(~observed)), + prior_weight_tau2=float((res.prior_weight or {}).get("tau2", np.nan)), + prior_weight_s2=float((res.prior_weight or {}).get("s2", np.nan)), + prior_weight_lambda=float((res.prior_weight or {}).get("lambda", np.nan)), + ) + except Exception as exc: # a failed realisation is a result, not a crash + out.update(error=f"{type(exc).__name__}: {exc}") + return out + + +def run_calibration( + seeds, scenario: str = "clean", *, jobs: int = 1, **kw +) -> list[dict[str, Any]]: + """Run :func:`run_realization` over ``seeds`` (in parallel if ``jobs > 1``).""" + fn = partial(run_realization, scenario=scenario, **kw) + seeds = [int(x) for x in seeds] + if jobs <= 1: + return [fn(x) for x in seeds] + with mp.get_context("spawn").Pool(jobs) as pool: + return list(pool.map(fn, seeds)) + + +def _mean_se(values): + v = np.asarray(values, float) + v = v[np.isfinite(v)] + if v.size == 0: + return {"mean": None, "se": None, "n": 0} + se = float(v.std(ddof=1) / np.sqrt(v.size)) if v.size > 1 else None + return {"mean": float(v.mean()), "se": se, "n": int(v.size)} + + +def summarize(results, *, margin: float = COVERAGE_MARGIN) -> dict[str, Any]: + """Aggregate per-realisation results; coverage SE is across realisations.""" + ok = [r for r in results if r.get("ok")] + summary: dict[str, Any] = { + "n_realizations": len(results), + "n_failed": len(results) - len(ok), + "failures": [r.get("error") for r in results if not r.get("ok")], + "margin": margin, + } + for key in ( + "member_coverage68", + "member_coverage95", + "member_rmse", + "shared_bias", + "coverage68", + "coverage95", + "coverage95_posterior", + "median_sd", + "median_halfwidth95", + "bias", + "rmse", + "max_abs_err", + "tau", + "s", + "corr_length_days", + "n_eff", + "missing_fraction", + "prior_weight_tau2", + "prior_weight_s2", + "prior_weight_lambda", + ): + summary[key] = ( + _mean_se([r.get(key, np.nan) for r in ok]) if ok else _mean_se([]) + ) + c95 = summary["member_coverage95"]["mean"] + c68 = summary["member_coverage68"]["mean"] + summary["member_coverage95_within_margin"] = ( + bool(abs(c95 - 0.95) <= margin) if c95 is not None else None + ) + summary["member_coverage68_within_margin"] = ( + bool(abs(c68 - 0.68) <= margin) if c68 is not None else None + ) + return summary + + +def _git_commit() -> str | None: + try: + out = subprocess.run( + ["git", "rev-parse", "HEAD"], + capture_output=True, + text=True, + cwd=Path(__file__).resolve().parent, + timeout=10, + check=False, + ) + except (OSError, subprocess.SubprocessError): + return None + sha = out.stdout.strip() + return sha if out.returncode == 0 and sha else None + + +def main(argv: list[str] | None = None) -> int: + ap = argparse.ArgumentParser(description=__doc__.split("\n\n")[0]) + ap.add_argument("--n", type=int, default=20, help="number of realisations") + ap.add_argument("--start-seed", type=int, default=1000) + ap.add_argument("--scenario", default="clean", choices=SCENARIOS) + ap.add_argument("--jobs", type=int, default=1) + ap.add_argument("--years", type=float, default=2.5) + ap.add_argument("--snr", type=float, default=7.0) + ap.add_argument("--cadence", type=int, default=4) + ap.add_argument("--n-iter", type=int, default=1200) + ap.add_argument("--burn", type=int, default=400) + ap.add_argument("--thin", type=int, default=2) + ap.add_argument("--out", required=True, help="JSON output path") + args = ap.parse_args(argv) + + seeds = range(args.start_seed, args.start_seed + args.n) + settings = { + k: getattr(args, k) + for k in ("scenario", "years", "snr", "cadence", "n_iter", "burn", "thin") + } + started = datetime.now(timezone.utc) + results = run_calibration( + seeds, + args.scenario, + jobs=args.jobs, + years=args.years, + snr=args.snr, + cadence=args.cadence, + n_iter=args.n_iter, + burn=args.burn, + thin=args.thin, + ) + finished = datetime.now(timezone.utc) + summary = summarize(results) + payload = { + "codameter_version": __version__, + "git_commit": _git_commit(), + "started_utc": started.isoformat(timespec="seconds"), + "finished_utc": finished.isoformat(timespec="seconds"), + "wall_seconds": (finished - started).total_seconds(), + "settings": settings, + "seeds": [int(x) for x in seeds], + "summary": summary, + "results": results, + } + out = Path(args.out) + out.parent.mkdir(parents=True, exist_ok=True) + out.write_text(json.dumps(payload, indent=1) + "\n") + + def fmt(key): + m = summary[key] + if m["mean"] is None: + return "n/a" + return f"{m['mean']:.3f}" + ( + f" +- {m['se']:.3f}" if m["se"] is not None else "" + ) + + print( + f"scenario={args.scenario} n={args.n} failed={summary['n_failed']} " + f"wall={payload['wall_seconds']:.0f}s" + ) + for key in ( + "member_coverage68", + "member_coverage95", + "coverage95_posterior", + "coverage95", + "median_sd", + "shared_bias", + "rmse", + "member_rmse", + "s", + "tau", + "n_eff", + "prior_weight_tau2", + "prior_weight_lambda", + ): + print(f" {key:<22} {fmt(key)}") + print( + f" member 95% within +-{summary['margin']:.0%}: " + f"{summary['member_coverage95_within_margin']}" + ) + print(f"wrote {out}") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/src/codameter/deviations.py b/src/codameter/deviations.py index c2a184e..b04d2e2 100644 --- a/src/codameter/deviations.py +++ b/src/codameter/deviations.py @@ -23,6 +23,7 @@ departure is an artefact of a choice, not of nature. The baseline and the deviation menus are taken from ``literature/best_practices.md``. """ + from __future__ import annotations from dataclasses import dataclass @@ -35,6 +36,7 @@ YEAR_D, C, Synth, + _boost_fonts, _days, _trailing_stack, daily_ccfs, @@ -134,10 +136,11 @@ def run_pipeline(ccfs, t, fs, cfg, *, eps_max=0.05, return_cc=False, prefiltered **Sign convention (v0.4.0, physical dv/v)**: a velocity *increase* is positive. All estimators return ``dv/v = -eps / (1 + eps)`` where - ``eps`` is the stretch factor that maps the reference onto the current - waveform (a coda that must be dilated to match means the medium slowed - down). Before v0.4.0 this function returned ``eps`` itself, labeled - dv/v — anticorrelated with the physical convention. + ``eps`` is the stretch factor that resamples the *current* waveform to + match the fixed reference (a current trace that must be dilated to + match means the medium slowed down). Before v0.4.0 this function + returned ``eps`` itself, labeled dv/v — anticorrelated with the + physical convention. Returns ``(dvv, valid)``: the per-day series and a boolean mask of epochs the pipeline actually produced (moving/inversion references have a warm-up gap; @@ -403,16 +406,16 @@ def fig_deviation_ranking(rows=None): color=C["truth"], ls="--", lw=1.2, - label=f"best practice ({base.rms*PCT:.3f}%)", + label=f"best practice ({base.rms * PCT:.3f}%)", ) ax[0].set( yticks=y, xlabel="RMS error vs truth (dv/v, %, log)", - title="(a) Bias injected by each deviation", + title="(a) RMS error of each deviation", ) - ax[0].set_yticklabels(labels, fontsize=8.5) + ax[0].set_yticklabels(labels, fontsize=10.5) ax[0].invert_yaxis() - ax[0].legend(fontsize=8.5, frameon=False, loc="lower right") + ax[0].legend(fontsize=10.5, frameon=False, loc="lower right") drop = [r.drop_err * PCT for r in items] ax[1].barh(y, drop, color=cols) ax[1].axvline(0, color=C["truth"], lw=1) @@ -424,6 +427,7 @@ def fig_deviation_ranking(rows=None): title="(b) Distortion of the drop", ) ax[1].invert_yaxis() + _boost_fonts(ax[0], ax[1], tick=10.5, label=12, title=13) fig.tight_layout() return fig @@ -431,6 +435,7 @@ def fig_deviation_ranking(rows=None): def fig_multiverse_full(mv=None): """The ultimate multiverse: every pipeline + the variance attribution.""" import matplotlib.pyplot as plt + from matplotlib.colors import Normalize if mv is None: mv = multiverse() @@ -444,7 +449,7 @@ def fig_multiverse_full(mv=None): # (a) fan of pipelines, coloured by RMS error with a colourblind-safe, # perceptually uniform sequential map (dark = accurate, bright = biased). order = np.argsort(-np.nan_to_num(rms)) - norm = plt.Normalize(np.nanpercentile(rms, 5), np.nanpercentile(rms, 95)) + norm = Normalize(np.nanpercentile(rms, 5), np.nanpercentile(rms, 95)) cmap = plt.cm.viridis_r for i in order: ax[0].plot(yrs, curves[i] * PCT, color=cmap(norm(rms[i])), lw=0.3, alpha=0.16) @@ -463,28 +468,40 @@ def fig_multiverse_full(mv=None): ) ax[0].plot(yrs, truth * PCT, color=C["truth"], lw=2.6, label="ground truth") ax[0].axvline(2.0, color="0.6", ls="--", lw=1) - # Clip tightly to the truth scale; the cycle-skipping pipelines run off-axis - # (that is the point — the colourbar flags them) but would otherwise swamp the + # Fixed, symmetric range: the cycle-skipping pipelines run off-axis (that is + # the point -- the colourbar flags them) but would otherwise swamp the # signal and make the panel unreadable. - span = (np.nanmax(truth) - np.nanmin(truth)) * PCT - ax[0].set_ylim( - (np.nanmin(truth) * PCT - 0.35 * span, np.nanmax(truth) * PCT + 0.35 * span) - ) + ax[0].set_ylim((-0.8, 0.8)) + n_off = int(np.sum(np.nanmax(np.abs(curves * PCT), axis=1) > 0.8)) ax[0].set( xlabel="time (years)", ylabel="dv/v (%)", title=f"(a) {mv['n_pipelines']} pipelines (colour = RMS error)", ) - leg = ax[0].legend(fontsize=8.5, loc="lower left", frameon=True) - leg.get_frame().set_facecolor("white") - leg.get_frame().set_alpha(0.9) - leg.get_frame().set_edgecolor("0.7") - fig.colorbar( + ax[0].text( + 0.02, + 0.97, + f"{n_off} of {mv['n_pipelines']} pipelines leave the axis range", + transform=ax[0].transAxes, + fontsize=9.5, + va="top", + color="0.25", + ) + ax[0].legend( + fontsize=10, + loc="upper center", + bbox_to_anchor=(0.5, -0.18), + ncol=3, + frameon=False, + ) + cbar = fig.colorbar( plt.cm.ScalarMappable(norm=norm, cmap=cmap), ax=ax[0], fraction=0.046, - label="RMS vs truth", + label="RMS vs truth (dv/v, fraction)", ) + cbar.set_label("RMS vs truth (dv/v, fraction)", fontsize=12) + cbar.ax.tick_params(labelsize=10.5) # (b) first-order variance attribution. axes = mv["axes"] @@ -498,8 +515,9 @@ def fig_multiverse_full(mv=None): ylabel="first-order variance fraction", title="(b) Which choice controls the answer", ) - ax[1].set_xticklabels(axes, rotation=30, ha="right", fontsize=8.5) - ax[1].legend(fontsize=8.5, frameon=False) + ax[1].set_xticklabels(axes, rotation=30, ha="right", fontsize=10.5) + ax[1].legend(fontsize=10.5, frameon=False) + _boost_fonts(ax[0], ax[1], tick=10.5, label=12, title=13) fig.tight_layout() return fig @@ -518,13 +536,13 @@ def build_figs(outdir): fig_deviation_ranking(rows).savefig( outdir / "demo_10_deviations.png", bbox_inches="tight" ) - print(f"wrote {outdir/'demo_10_deviations.png'}") + print(f"wrote {outdir / 'demo_10_deviations.png'}") print("running the full factorial multiverse (this takes a few minutes) ...") mv = multiverse() fig_multiverse_full(mv).savefig( outdir / "demo_11_multiverse.png", bbox_inches="tight" ) - print(f"wrote {outdir/'demo_11_multiverse.png'}") + print(f"wrote {outdir / 'demo_11_multiverse.png'}") import matplotlib.pyplot as plt plt.close("all") diff --git a/src/codameter/figures.py b/src/codameter/figures.py new file mode 100644 index 0000000..3ef3b09 --- /dev/null +++ b/src/codameter/figures.py @@ -0,0 +1,330 @@ +"""One driver for every generated figure in the paper, with a numerical sidecar. + +Run:: + + python -m codameter.figures --out literature/figs # everything + python -m codameter.figures --out literature/figs --skip-slow + python -m codameter.figures --out literature/figs --only demo_12_bayes + python -m codameter.figures --list + +For each figure ```` this writes ``.png``, ``.npz`` (every +plotted array: line x/y, image arrays and extents, collection vertices and +offsets, bar rectangles, plus the generator's own result arrays under +``data/``) and ``.json`` (generator, codameter version, git commit, +timestamp, library versions, and an inventory of axes and arrays). The +sidecars are what a caption or a sentence in the manuscript should be +computed from, so plotted and quoted numbers come from one output +(audit findings REP-01, FIG-02, SCI-07). + +The three real-data figures (:data:`EXTERNAL`) are not produced here; their +provenance is recorded in ``literature/figs/SOURCES.md``. +""" + +from __future__ import annotations + +import argparse +import dataclasses +import json +import platform +import subprocess +from collections.abc import Callable, Iterable +from datetime import datetime, timezone +from pathlib import Path +from typing import Any + +import matplotlib +import numpy as np + +from ._version import __version__ + +__all__ = [ + "EXTERNAL", + "SLOW", + "generators", + "figure_arrays", + "compact_array", + "figure_inventory", + "save_figure", + "build_all_figures", +] + +#: Figures the paper includes that are produced outside this repository. +EXTERNAL = ( + "realdata_1_validation", + "realdata_2_interferograms", + "realdata_3_warmup", +) +#: Generators that take minutes rather than seconds. +SLOW = {"demo_10_deviations", "demo_11_multiverse", "demo_12_bayes"} +#: float64 arrays with more elements than this are stored as float32 in the +#: sidecar (seven significant digits); smaller arrays are stored exactly. +LARGE_ARRAY = 50_000 + +Generator = Callable[[], tuple[Any, dict[str, Any], dict[str, Any]]] + + +def _git_commit() -> str | None: + try: + out = subprocess.run( + ["git", "rev-parse", "HEAD"], + capture_output=True, + text=True, + cwd=Path(__file__).resolve().parent, + timeout=10, + check=False, + ) + except (OSError, subprocess.SubprocessError): + return None + sha = out.stdout.strip() + return sha if out.returncode == 0 and sha else None + + +def _jsonable(obj: Any) -> Any: + if dataclasses.is_dataclass(obj) and not isinstance(obj, type): + return _jsonable(dataclasses.asdict(obj)) + if isinstance(obj, dict): + return {str(k): _jsonable(v) for k, v in obj.items()} + if isinstance(obj, list | tuple): + return [_jsonable(v) for v in obj] + if isinstance(obj, np.ndarray): + return obj.tolist() + if isinstance(obj, np.generic): + return obj.item() + return obj + + +# --------------------------------------------------------------------------- +# Extracting what a figure actually plots. +# --------------------------------------------------------------------------- +def figure_arrays(fig) -> dict[str, np.ndarray]: + """Every plotted array in ``fig``, keyed ``ax{i}/{artist}{j}/{field}``.""" + out: dict[str, np.ndarray] = {} + for i, ax in enumerate(fig.axes): + for j, ln in enumerate(ax.get_lines()): + out[f"ax{i}/line{j}/x"] = np.asarray(ln.get_xdata(orig=False), float) + out[f"ax{i}/line{j}/y"] = np.asarray(ln.get_ydata(orig=False), float) + for j, im in enumerate(ax.get_images()): + out[f"ax{i}/image{j}"] = np.asarray(im.get_array()) + out[f"ax{i}/image{j}/extent"] = np.asarray(im.get_extent(), float) + for j, coll in enumerate(ax.collections): + offsets = np.asarray(coll.get_offsets(), float) + if offsets.size: + out[f"ax{i}/collection{j}/offsets"] = offsets + paths = coll.get_paths() + if paths: + verts = [np.asarray(p.vertices, float) for p in paths] + out[f"ax{i}/collection{j}/vertices"] = np.concatenate(verts, axis=0) + out[f"ax{i}/collection{j}/path_lengths"] = np.array( + [len(v) for v in verts], int + ) + for j, patch in enumerate(ax.patches): + if hasattr(patch, "get_x") and hasattr(patch, "get_height"): + out[f"ax{i}/patch{j}/xywh"] = np.array( + [ + patch.get_x(), + patch.get_y(), + patch.get_width(), + patch.get_height(), + ], + float, + ) + return out + + +def compact_array(a: np.ndarray) -> np.ndarray: + """Store large float64 arrays as float32 (see :data:`LARGE_ARRAY`).""" + a = np.asarray(a) + if a.dtype == np.float64 and a.size > LARGE_ARRAY: + return a.astype(np.float32) + return a + + +def figure_inventory(fig) -> list[dict[str, Any]]: + """Axes titles, labels and artist labels, aligned with :func:`figure_arrays`.""" + inv = [] + for i, ax in enumerate(fig.axes): + inv.append( + { + "axes": f"ax{i}", + "title": ax.get_title(), + "xlabel": ax.get_xlabel(), + "ylabel": ax.get_ylabel(), + "lines": [ln.get_label() for ln in ax.get_lines()], + "images": len(ax.get_images()), + "collections": [c.get_label() for c in ax.collections], + "patches": len(ax.patches), + } + ) + return inv + + +def save_figure( + fig, + outdir: str | Path, + name: str, + *, + generator: str, + extra_arrays: dict[str, Any] | None = None, + extra_meta: dict[str, Any] | None = None, +) -> Path: + """Write ``.png`` with its ``.npz`` and ``.json`` sidecars.""" + outdir = Path(outdir) + outdir.mkdir(parents=True, exist_ok=True) + png = outdir / f"{name}.png" + fig.savefig(png, bbox_inches="tight") + arrays: dict[str, Any] = dict(figure_arrays(fig)) + for k, v in (extra_arrays or {}).items(): + arrays[f"data/{k}"] = np.asarray(v) + arrays = {k: compact_array(v) for k, v in arrays.items()} + np.savez_compressed(outdir / f"{name}.npz", **arrays) + meta: dict[str, Any] = { + "figure": name, + "generator": generator, + "codameter_version": __version__, + "git_commit": _git_commit(), + "generated_utc": datetime.now(timezone.utc).isoformat(timespec="seconds"), + "python": platform.python_version(), + "numpy": np.__version__, + "matplotlib": matplotlib.__version__, + "axes": figure_inventory(fig), + "arrays": sorted(arrays), + } + meta.update(_jsonable(extra_meta or {})) + (outdir / f"{name}.json").write_text(json.dumps(meta, indent=1) + "\n") + return png + + +# --------------------------------------------------------------------------- +# The registry: name -> generator returning (fig, extra_arrays, extra_meta). +# --------------------------------------------------------------------------- +def _gen_demo_10(): + from . import deviations as dv + + rows, _ = dv.oat_effects() + fig = dv.fig_deviation_ranking(rows) + return fig, {}, {"oat_rows": _jsonable(rows)} + + +def _gen_demo_11(): + from . import deviations as dv + + mv = dv.multiverse() + fig = dv.fig_multiverse_full(mv) + arrays = {k: mv[k] for k in ("curves", "rms", "drop") if k in mv} + meta = {k: v for k, v in mv.items() if k not in arrays} + return fig, arrays, {"multiverse": meta} + + +def _gen_demo_12(): + from . import uq_bayes as ub + + res, run = ub._build_bayes() + fig = ub._fig_bayes(res, run) + arrays = { + "times_days": res.times_days, + "mu_mean": res.mu_mean, + "mu_lo": res.mu_lo, + "mu_hi": res.mu_hi, + "mu_cov": res.mu_cov, + "Cd": res.Cd, + "total_std": res.total_std, + "method_std": res.method_std, + "within_std": res.within_std, + "members": run.members, + "within_sigma": run.within_sigma, + } + if run.truth is not None: + arrays["truth"] = run.truth + meta = { + "bayes": { + "tau": res.tau, + "s": res.s, + "corr_length_days": res.corr_length_days, + "n_eff": res.n_eff, + "n_epochs": int(res.times_days.size), + "labels": list(run.labels), + } + } + return fig, arrays, meta + + +def generators() -> dict[str, tuple[str, Generator]]: + """Every generated figure: ``name -> (generator description, callable)``.""" + from . import synthetic_demo as sd + + gens: dict[str, tuple[str, Generator]] = {} + for name, builder in sd.FIGURES.items(): + + def _gen(b=builder): + return b(), {}, {} + + gens[name] = (f"codameter.synthetic_demo.{builder.__name__}", _gen) + gens["demo_10_deviations"] = ( + "codameter.deviations.oat_effects + fig_deviation_ranking", + _gen_demo_10, + ) + gens["demo_11_multiverse"] = ( + "codameter.deviations.multiverse + fig_multiverse_full", + _gen_demo_11, + ) + gens["demo_12_bayes"] = ( + "codameter.uq_bayes._build_bayes + _fig_bayes", + _gen_demo_12, + ) + return gens + + +def build_all_figures( + outdir: str | Path, + *, + only: Iterable[str] | None = None, + skip_slow: bool = False, +) -> list[Path]: + """Render the selected figures with sidecars; returns the PNG paths.""" + import matplotlib.pyplot as plt + + from .synthetic_demo import apply_style + + gens = generators() + wanted = list(gens) if only is None else list(only) + unknown = sorted(set(wanted) - set(gens)) + if unknown: + raise KeyError(f"unknown figure(s): {unknown}; known: {sorted(gens)}") + if skip_slow: + wanted = [n for n in wanted if n not in SLOW] + apply_style() + written = [] + for name in wanted: + desc, gen = gens[name] + print(f"[{name}] {desc}", flush=True) + fig, arrays, meta = gen() + written.append( + save_figure( + fig, outdir, name, generator=desc, extra_arrays=arrays, extra_meta=meta + ) + ) + plt.close(fig) + print(f" wrote {written[-1]} (+ .npz, .json)", flush=True) + return written + + +def main(argv: list[str] | None = None) -> int: + ap = argparse.ArgumentParser(description=__doc__.split("\n\n")[0]) + ap.add_argument("--out", default="literature/figs", help="output directory") + ap.add_argument("--only", default=None, help="comma-separated figure names") + ap.add_argument("--skip-slow", action="store_true", help=f"skip {sorted(SLOW)}") + ap.add_argument("--list", action="store_true", help="list figures and exit") + args = ap.parse_args(argv) + if args.list: + for name, (desc, _) in generators().items(): + print(f"{name:<28} {desc}{' (slow)' if name in SLOW else ''}") + for name in EXTERNAL: + print(f"{name:<28} external; see literature/figs/SOURCES.md") + return 0 + only = [s.strip() for s in args.only.split(",")] if args.only else None + build_all_figures(args.out, only=only, skip_slow=args.skip_slow) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/src/codameter/frugalmind.py b/src/codameter/frugalmind.py index 23a73c1..f38174e 100644 --- a/src/codameter/frugalmind.py +++ b/src/codameter/frugalmind.py @@ -28,23 +28,41 @@ Both are scored by recovery against ground truth, not by matching a fixed answer, so a different-but-good pipeline scores well. Negatives are first-class: a config that cycle-skips or picks the wrong depth band scores near zero. + +Scoring support (scorer version 2). Each gold record fixes, per case, the epochs +on which the submission is evaluated (``support``: where the case's reference +pipeline is valid) and the datum epochs (``baseline``: the earliest 20% of the +support) over which truth and prediction are demeaned. A missing or non-finite +prediction inside the support is scored as the null prediction (no change), via +:func:`codameter.golden.rms_on_support`. Version 1 took both the support and the +datum from the submission's own finite values, so ten zeros followed by nulls +scored 1.0 on every public case (2026-09-10 audit, EV-01). """ + from __future__ import annotations import ast import json import re +from collections.abc import Callable from pathlib import Path -from typing import Any, Callable +from typing import Any import numpy as np from . import golden from . import use_cases as uc -DATASET_ID = "codameter" # the name the suites appear under in FrugalMind -VERSION = "v0.1" +DATASET_ID = "codameter" # the name the suites appear under in FrugalMind +VERSION = "v0.2" TASKS = ("param_recommendation", "dvv_series") +# Scoring rule carried in every row's scorer_spec so an exported dataset is +# self-describing. Bump when the rule changes; keep the thresholds in the manifest. +SCORER_CONFIG = { + "version": 2, + "support": "reference_pipeline_valid", + "missing": "null_prediction", +} # Task kind (FrugalMind TaskKind value) per suite. Both are framed as the agent # generating something the scorer executes/regresses, i.e. code_generation. @@ -57,29 +75,41 @@ # band/window, so the agent must supply the domain knowledge. The scorer grades # on recovery, never on matching these. SCENARIO = { - "volcano": ("Ambient-noise monitoring of an active volcanic edifice. You want " - "to track a slow pre-eruptive velocity change and a sharp " - "co-eruptive drop in the shallow, crack-rich edifice (roughly the " - "upper few km). Station pairs are available."), - "earthquake_fault": ("Ambient-noise monitoring across a crustal fault zone. " - "You want to resolve a coseismic velocity drop and its " - "gradual, partial healing, dominated by the shallow " - "(top ~100 m to a few km) nonlinear site response."), - "landslide": ("Dense-array monitoring of a clay-rich landslide body. " - "Inter-sensor distances are tens of meters, the failure surface " - "is in the top few meters to ~40 m, and you expect a large " - "(several percent) accelerating velocity drop before failure, on " - "top of a rainfall-driven seasonal swing."), - "groundwater": ("Single-station and small-array monitoring of a shallow " - "aquifer, roughly the upper few hundred meters. You want the " - "seasonal hydrologic velocity change and a slow multi-year " - "drought trend."), - "cryosphere": ("Shallow high-frequency array monitoring of a permafrost active " - "layer / rock glacier, top ~0-10 m. You expect a large, sharply " - "seasonal freeze-thaw velocity swing."), - "geothermal": ("Monitoring of a geothermal reservoir at depths of hundreds of " - "meters to a few km, tracking a slow injection-driven velocity " - "decline. Station pairs are available."), + "volcano": ( + "Ambient-noise monitoring of an active volcanic edifice. You want " + "to track a slow pre-eruptive velocity change and a sharp " + "co-eruptive drop in the shallow, crack-rich edifice (roughly the " + "upper few km). Station pairs are available." + ), + "earthquake_fault": ( + "Ambient-noise monitoring across a crustal fault zone. " + "You want to resolve a coseismic velocity drop and its " + "gradual, partial healing, dominated by the shallow " + "(top ~100 m to a few km) nonlinear site response." + ), + "landslide": ( + "Dense-array monitoring of a clay-rich landslide body. " + "Inter-sensor distances are tens of meters, the failure surface " + "is in the top few meters to ~40 m, and you expect a large " + "(several percent) accelerating velocity drop before failure, on " + "top of a rainfall-driven seasonal swing." + ), + "groundwater": ( + "Single-station and small-array monitoring of a shallow " + "aquifer, roughly the upper few hundred meters. You want the " + "seasonal hydrologic velocity change and a slow multi-year " + "drought trend." + ), + "cryosphere": ( + "Shallow high-frequency array monitoring of a permafrost active " + "layer / rock glacier, top ~0-10 m. You expect a large, sharply " + "seasonal freeze-thaw velocity swing." + ), + "geothermal": ( + "Monitoring of a geothermal reservoir at depths of hundreds of " + "meters to a few km, tracking a slow injection-driven velocity " + "decline. Station pairs are available." + ), } _ESTIMATORS = {"stretching (TS)", "MWCS", "WCS", "DTW", "WCC", "WTS", "WTDTW"} @@ -123,7 +153,7 @@ def _series_prompt(case: dict) -> str: f'codameter as golden.observed("{case["id"]}") -> {{"ccfs", "t", "days", ' '"fs", ...}}. (That is the observables-only view; it does not contain the ' "answer.) Choose an appropriate pipeline, recover the dv/v(t) series, " - f'and return ONLY a JSON array of {golden.observed(case["id"])["days"].size} ' + f"and return ONLY a JSON array of {golden.observed(case['id'])['days'].size} " "floats: the fractional dv/v for each day in order. No prose." ) @@ -147,22 +177,35 @@ def _thresholds(case_id: str) -> dict: def _gold(case: dict, task: str) -> dict: + """Scorer-side record: thresholds plus the fixed evaluation support. + + ``support`` and ``baseline`` come from the case's reference pipeline (the + use-case recommendation with the case's own config overrides), never from + the submission; see :func:`codameter.golden.scoring_support`. + """ g = {"case_id": case["id"], "use_case": case["use_case"], **_thresholds(case["id"])} + d = golden.generate(case["id"]) + cfg = uc.recommend(case["use_case"], **case.get("config", {})) + sup = golden.scoring_support(d, cfg, uc.eps_max(case["use_case"])) + g["n_days"] = int(d["days"].size) + g["support"] = sup["support"] + g["baseline"] = sup["baseline"] if task == "dvv_series": - d = golden.generate(case["id"]) - g["n_days"] = int(d["days"].size) - # Anchor "clearly wrong" to the null (no-change) prediction: a returned - # series of zeros should score ~0. For a low-amplitude target the fixed - # rms_bad is too lenient, so use the larger of the two. - null_rms = golden._rms(np.zeros_like(d["truth"]), d["truth"], d["days"], - np.ones_like(d["truth"], bool)) + # Anchor "clearly wrong" to the null (no-change) prediction, which is + # also what a missing prediction is scored as: a series of zeros should + # score ~0. For a low-amplitude target the fixed rms_bad is too lenient, + # so use the larger of the two. + null_rms, _ = golden.rms_on_support( + np.zeros_like(d["truth"]), d["truth"], g["support"], g["baseline"] + ) if np.isfinite(null_rms) and null_rms > g["rms_ceiling"]: g["rms_bad"] = float(null_rms) return g -def build_rows(task: str, *, split: str | None = None, - visibility: str | None = None) -> list[dict]: +def build_rows( + task: str, *, split: str | None = None, visibility: str | None = None +) -> list[dict]: """Return BenchmarkRow-shaped dicts for one task over the golden cases. Filter by ``split`` ("validation"/"test") and/or ``visibility`` @@ -171,31 +214,37 @@ def build_rows(task: str, *, split: str | None = None, if task not in TASKS: raise ValueError(f"task must be one of {TASKS}; got {task!r}") prompt_fn = _param_prompt if task == "param_recommendation" else _series_prompt - scorer_name = ("dvv_recovery" if task == "param_recommendation" - else "dvv_series_regression") + scorer_name = ( + "dvv_recovery" if task == "param_recommendation" else "dvv_series_regression" + ) rows = [] for case in golden.CASES: if split is not None and golden.case_split(case) != split: continue if visibility is not None and golden.case_visibility(case) != visibility: continue - rows.append({ - "id": f"{DATASET_ID}/{task}/{case['id']}", - "dataset_id": DATASET_ID, - "suite_id": task, - "version": VERSION, - "task_kind": TASK_KIND[task], - "split": golden.case_split(case), - "visibility": golden.case_visibility(case), - "prompt": prompt_fn(case), - "gold": _gold(case, task), - "scorer_spec": {"name": scorer_name, "config": {}}, - "metadata": { - "case_id": case["id"], "use_case": case["use_case"], - "grade": case["grade"], - "recommended_config": golden._jsonable(uc.recommend(case["use_case"])), - }, - }) + rows.append( + { + "id": f"{DATASET_ID}/{task}/{case['id']}", + "dataset_id": DATASET_ID, + "suite_id": task, + "version": VERSION, + "task_kind": TASK_KIND[task], + "split": golden.case_split(case), + "visibility": golden.case_visibility(case), + "prompt": prompt_fn(case), + "gold": _gold(case, task), + "scorer_spec": {"name": scorer_name, "config": dict(SCORER_CONFIG)}, + "metadata": { + "case_id": case["id"], + "use_case": case["use_case"], + "grade": case["grade"], + "recommended_config": golden._jsonable( + uc.recommend(case["use_case"]) + ), + }, + } + ) return rows @@ -214,7 +263,7 @@ def _first_json(text: str, opener: str, closer: str): elif text[i] == closer: depth -= 1 if depth == 0: - blob = text[start:i + 1] + blob = text[start : i + 1] for loader in (json.loads, ast.literal_eval): try: return loader(blob) @@ -231,7 +280,7 @@ def parse_config(text: str) -> dict | None: def _as_pair(v): - if isinstance(v, (list, tuple)) and len(v) == 2: + if isinstance(v, list | tuple) and len(v) == 2: return (float(v[0]), float(v[1])) if isinstance(v, str): m = re.findall(r"[-+]?\d*\.?\d+", v) @@ -292,7 +341,11 @@ def score_param_recommendation(output_text: str, gold: dict) -> float: dvv, valid = golden.recover(d, cfg, uc.eps_max(gold["use_case"])) except Exception: return 0.0 - rms = golden._rms(dvv, d["truth"], d["days"], valid) + # Epochs the submitted pipeline could not estimate are scored as the null + # prediction on the case's fixed support (they are not dropped). + rms, _availability = golden.rms_on_support( + np.where(valid, dvv, np.nan), d["truth"], gold["support"], gold["baseline"] + ) return _score_from_rms(rms, gold["rms_ceiling"], gold["rms_bad"]) @@ -302,8 +355,9 @@ def score_dvv_series(output_text: str, gold: dict) -> float: series = parse_series(output_text, n=int(gold["n_days"])) if series is None: return 0.0 - valid = np.isfinite(series) - rms = golden._rms(series, d["truth"], d["days"], valid) + rms, _availability = golden.rms_on_support( + series, d["truth"], gold["support"], gold["baseline"] + ) return _score_from_rms(rms, gold["rms_ceiling"], gold["rms_bad"]) @@ -326,8 +380,9 @@ def make_scorer_from_spec(spec: dict) -> Callable[[str, Any], float]: # --------------------------------------------------------------------------- # Self-hosted JSONL export (mirrors frugalmind.export, no FrugalMind import) # --------------------------------------------------------------------------- -def export_jsonl(out_dir: str | Path, *, version: str = VERSION, - visibility: str | None = None) -> dict: +def export_jsonl( + out_dir: str | Path, *, version: str = VERSION, visibility: str | None = None +) -> dict: """Write ``///.jsonl`` + a sha256 manifest. This lets codameter self-host the benchmark in the canonical FrugalMind @@ -357,8 +412,12 @@ def main(argv: list[str] | None = None) -> int: ap = argparse.ArgumentParser(description="Export the dv/v benchmark as JSONL.") ap.add_argument("--out", default="datasets", help="output root directory") - ap.add_argument("--visibility", default=None, choices=[None, "public", "private"], - help="export only rows with this visibility") + ap.add_argument( + "--visibility", + default=None, + choices=[None, "public", "private"], + help="export only rows with this visibility", + ) args = ap.parse_args(argv) manifest = export_jsonl(args.out, visibility=args.visibility) dest = Path(args.out) / DATASET_ID / VERSION diff --git a/src/codameter/golden.py b/src/codameter/golden.py index 5a635a9..0662d0b 100644 --- a/src/codameter/golden.py +++ b/src/codameter/golden.py @@ -28,6 +28,7 @@ (:mod:`codameter.frugalmind`). All score through :func:`recover`, so a single code path handles both single- and multi-channel cases. """ + from __future__ import annotations import json @@ -38,8 +39,9 @@ import numpy as np from . import use_cases as uc +from ._version import __version__ from .deviations import run_pipeline -from .synthetic_demo import YEAR_D, _days, _seasonal, daily_ccfs, make_coda +from .synthetic_demo import _days, _seasonal, daily_ccfs, make_coda def _default_data_dir() -> Path: @@ -71,7 +73,12 @@ def _default_data_dir() -> Path: DATA_DIR = _default_data_dir() MANIFEST = DATA_DIR / "manifest.json" CACHE_DIR = DATA_DIR / "cache" -MANIFEST_VERSION = 2 +# Bumped whenever a change to the estimator/generator numerics can move the +# frozen "expected" metrics (e.g. the current-vs-reference interpolation +# fix below) -- forces per-user caches to regenerate rather than silently +# comparing against stale expectations. Not bumped for the v0.4.0 sign-flip +# itself; see CHANGELOG.md. +MANIFEST_VERSION = 3 # Whether DATA_DIR is the regenerable per-user cache (pip-installed, no source # tree, no explicit override) as opposed to an authoritative committed source or @@ -88,12 +95,48 @@ def _default_data_dir() -> Path: # the physical scale of each motif; they stay within the application's eps_max. # --------------------------------------------------------------------------- AMP = { - "volcano": {"seasonal": 0.0010, "drop": -0.0040, "trend": -0.0015, "tau": 90.0, "phase": 60.0}, - "earthquake_fault": {"seasonal": 0.0006, "drop": -0.0025, "trend": -0.0010, "tau": 160.0, "phase": 30.0}, - "landslide": {"seasonal": 0.0100, "drop": -0.0300, "trend": -0.0050, "tau": 60.0, "phase": 120.0}, - "groundwater": {"seasonal": 0.0015, "drop": -0.0020, "trend": -0.0012, "tau": 120.0, "phase": 250.0}, - "cryosphere": {"seasonal": 0.0300, "drop": -0.0150, "trend": -0.0040, "tau": 45.0, "phase": 200.0}, - "geothermal": {"seasonal": 0.0005, "drop": -0.0060, "trend": -0.0100, "tau": 120.0, "phase": 30.0}, + "volcano": { + "seasonal": 0.0010, + "drop": -0.0040, + "trend": -0.0015, + "tau": 90.0, + "phase": 60.0, + }, + "earthquake_fault": { + "seasonal": 0.0006, + "drop": -0.0025, + "trend": -0.0010, + "tau": 160.0, + "phase": 30.0, + }, + "landslide": { + "seasonal": 0.0100, + "drop": -0.0300, + "trend": -0.0050, + "tau": 60.0, + "phase": 120.0, + }, + "groundwater": { + "seasonal": 0.0015, + "drop": -0.0020, + "trend": -0.0012, + "tau": 120.0, + "phase": 250.0, + }, + "cryosphere": { + "seasonal": 0.0300, + "drop": -0.0150, + "trend": -0.0040, + "tau": 45.0, + "phase": 200.0, + }, + "geothermal": { + "seasonal": 0.0005, + "drop": -0.0060, + "trend": -0.0100, + "tau": 120.0, + "phase": 30.0, + }, } @@ -110,7 +153,9 @@ def amp_for(case: dict) -> dict: return {**AMP[case["use_case"]], **case.get("amp", {})} -def _step_heal(days: np.ndarray, amp: dict, onset_frac: float | None = None) -> np.ndarray: +def _step_heal( + days: np.ndarray, amp: dict, onset_frac: float | None = None +) -> np.ndarray: """A sharp drop at ~``onset_frac`` of the record with logarithmic partial heal.""" onset_frac = amp.get("onset_frac", 0.5) if onset_frac is None else onset_frac onset = onset_frac * float(days[-1]) @@ -136,8 +181,11 @@ def _motif_composite(days: np.ndarray, amp: dict) -> np.ndarray: return _step_heal(days, amp) + _motif_seasonal(days, amp) + trend -MOTIF = {"seasonal": _motif_seasonal, "transient": _motif_transient, - "composite": _motif_composite} +MOTIF = { + "seasonal": _motif_seasonal, + "transient": _motif_transient, + "composite": _motif_composite, +} # --------------------------------------------------------------------------- @@ -172,18 +220,48 @@ def _depth_bands(app: str) -> tuple[tuple[float, float], tuple[float, float]]: # spans volcano / fault / aquifer / glacier / reservoir at that difficulty. # --------------------------------------------------------------------------- GRADES = { - "easy": {"motif": "seasonal", "snr": (8.0, 12.0), "channels": 1, "decorr": 0.00, - "years": 3.0, "split": "validation", "rms_rel_tol": 0.35}, - "medium": {"motif": "transient", "snr": (3.0, 5.0), "channels": 1, "decorr": 0.05, - "years": 3.0, "split": "validation", "rms_rel_tol": 0.45}, - "hard": {"motif": "depth", "snr": (2.0, 4.0), "channels": 4, "decorr": 0.20, - "years": 2.5, "split": "test", "rms_rel_tol": 0.60}, + "easy": { + "motif": "seasonal", + "snr": (8.0, 12.0), + "channels": 1, + "decorr": 0.00, + "years": 3.0, + "split": "validation", + "rms_rel_tol": 0.35, + }, + "medium": { + "motif": "transient", + "snr": (3.0, 5.0), + "channels": 1, + "decorr": 0.05, + "years": 3.0, + "split": "validation", + "rms_rel_tol": 0.45, + }, + "hard": { + "motif": "depth", + "snr": (2.0, 4.0), + "channels": 4, + "decorr": 0.20, + "years": 2.5, + "split": "test", + "rms_rel_tol": 0.60, + }, } # 10 application slots per grade (the 6 applications, some repeated). -APP_CYCLE = ["volcano", "earthquake_fault", "landslide", "groundwater", - "cryosphere", "geothermal", "volcano", "groundwater", - "landslide", "earthquake_fault"] +APP_CYCLE = [ + "volcano", + "earthquake_fault", + "landslide", + "groundwater", + "cryosphere", + "geothermal", + "volcano", + "groundwater", + "landslide", + "earthquake_fault", +] _SEED_BASE = {"easy": 100, "medium": 200, "hard": 300} @@ -193,13 +271,20 @@ def _build_cases() -> list[dict]: for grade, spec in GRADES.items(): snr_lo, snr_hi = spec["snr"] for i, app in enumerate(APP_CYCLE): - snr = round(float(np.interp(i, [0, len(APP_CYCLE) - 1], [snr_hi, snr_lo])), 2) + snr = round( + float(np.interp(i, [0, len(APP_CYCLE) - 1], [snr_hi, snr_lo])), 2 + ) case = { "id": f"{grade}-{app}-{i + 1:02d}", - "grade": grade, "use_case": app, "motif": spec["motif"], - "snr": snr, "seed": _SEED_BASE[grade] + i, - "channels": spec["channels"], "decorr": spec["decorr"], - "years": spec["years"], "split": spec["split"], + "grade": grade, + "use_case": app, + "motif": spec["motif"], + "snr": snr, + "seed": _SEED_BASE[grade] + i, + "channels": spec["channels"], + "decorr": spec["decorr"], + "years": spec["years"], + "split": spec["split"], "rms_rel_tol": spec["rms_rel_tol"], } if grade == "hard": @@ -209,14 +294,18 @@ def _build_cases() -> list[dict]: target = "shallow" if i % 2 == 0 else "deep" case["two_layer"] = True case["target"] = target - case["config"] = {"band": shallow_band if target == "shallow" else deep_band} + case["config"] = { + "band": shallow_band if target == "shallow" else deep_band + } case["note"] = ( "The medium is depth-dependent: a shallow near-surface layer " "(coseismic drop + hydrological seasonal) sits above a deep layer " "(long-term trend). " - + ("You must resolve the SHALLOW near-surface response." - if target == "shallow" else - "You must resolve the DEEP long-term trend.") + + ( + "You must resolve the SHALLOW near-surface response." + if target == "shallow" + else "You must resolve the DEEP long-term trend." + ) + " The band selects the depth." ) cases.append(case) @@ -227,8 +316,11 @@ def _build_cases() -> list[dict]: # tests, tutorials and the paper figures. The full evaluation corpus is *hidden* # (see load_cases): its recipes carry secret `amp` truth parameters, so it cannot # be reconstructed from this source. -PUBLIC_SAMPLE_IDS = ("easy-volcano-01", "medium-earthquake_fault-02", - "hard-groundwater-04") +PUBLIC_SAMPLE_IDS = ( + "easy-volcano-01", + "medium-earthquake_fault-02", + "hard-groundwater-04", +) CASES_FILE = "cases.json" @@ -264,7 +356,7 @@ def representative_case(use_case: str, grade: str = "easy") -> str: for c in CASES: if c["use_case"] == key and c["grade"] == grade: return c["id"] - for c in CASES: # fall back to any grade + for c in CASES: # fall back to any grade if c["use_case"] == key: return c["id"] raise KeyError(f"no golden case for use case {use_case!r}") @@ -297,12 +389,18 @@ def _build(recipe: dict) -> dict: seed, snr = recipe["seed"], recipe["snr"] decorr = recipe.get("decorr", 0.0) nchan = int(recipe.get("channels", 1)) - amp = amp_for(recipe) # public table, or the case's secret override + amp = amp_for(recipe) # public table, or the case's secret override - t, coda0 = make_coda(maxlag_s=sp["maxlag_s"], fs=fs, band=gen, - t_coda_s=sp["t_coda_s"], seed=0) - out: dict = {"fs": fs, "days": days, "use_case": app, "grade": recipe["grade"], - "t": t} + t, coda0 = make_coda( + maxlag_s=sp["maxlag_s"], fs=fs, band=gen, t_coda_s=sp["t_coda_s"], seed=0 + ) + out: dict = { + "fs": fs, + "days": days, + "use_case": app, + "grade": recipe["grade"], + "t": t, + } if recipe.get("two_layer"): # Depth-dependent medium: shallow (high-freq) and deep (low-freq) layers, @@ -314,17 +412,38 @@ def _build(recipe: dict) -> dict: truth_deep = _truth_deep(days, amp) chans = [] for c in range(nchan): - _, cod_s = make_coda(maxlag_s=sp["maxlag_s"], fs=fs, band=shallow_band, - t_coda_s=sp["t_coda_s"], seed=2 * c) - _, cod_d = make_coda(maxlag_s=sp["maxlag_s"], fs=fs, band=deep_band, - t_coda_s=sp["t_coda_s"], seed=2 * c + 1) - chans.append(daily_ccfs(t, [cod_s, cod_d], [truth_shallow, truth_deep], - fs=fs, snr=snr, decorr=decorr, gen_band=gen, - seed=seed + 7 * c)) + _, cod_s = make_coda( + maxlag_s=sp["maxlag_s"], + fs=fs, + band=shallow_band, + t_coda_s=sp["t_coda_s"], + seed=2 * c, + ) + _, cod_d = make_coda( + maxlag_s=sp["maxlag_s"], + fs=fs, + band=deep_band, + t_coda_s=sp["t_coda_s"], + seed=2 * c + 1, + ) + chans.append( + daily_ccfs( + t, + [cod_s, cod_d], + [truth_shallow, truth_deep], + fs=fs, + snr=snr, + decorr=decorr, + gen_band=gen, + seed=seed + 7 * c, + ) + ) out["channels"] = np.stack(chans) out["ccfs"] = out["channels"].mean(axis=0) out["truth"] = truth_shallow if recipe["target"] == "shallow" else truth_deep - out["truth_other"] = truth_deep if recipe["target"] == "shallow" else truth_shallow + out["truth_other"] = ( + truth_deep if recipe["target"] == "shallow" else truth_shallow + ) return out truth = MOTIF[recipe["motif"]](days, amp) @@ -332,17 +451,35 @@ def _build(recipe: dict) -> dict: if nchan > 1: # Independent cross-component channels: distinct coda + distinct noise, # sharing the medium's truth. Measured per channel, aggregated later. - codas = [coda0] + [make_coda(maxlag_s=sp["maxlag_s"], fs=fs, band=gen, - t_coda_s=sp["t_coda_s"], seed=c)[1] - for c in range(1, nchan)] - chans = [daily_ccfs(t, [cod], [truth], fs=fs, snr=snr, decorr=decorr, - gen_band=gen, seed=seed + 7 * c) - for c, cod in enumerate(codas)] + codas = [coda0] + [ + make_coda( + maxlag_s=sp["maxlag_s"], + fs=fs, + band=gen, + t_coda_s=sp["t_coda_s"], + seed=c, + )[1] + for c in range(1, nchan) + ] + chans = [ + daily_ccfs( + t, + [cod], + [truth], + fs=fs, + snr=snr, + decorr=decorr, + gen_band=gen, + seed=seed + 7 * c, + ) + for c, cod in enumerate(codas) + ] out["channels"] = np.stack(chans) out["ccfs"] = out["channels"].mean(axis=0) # a 2D view for plotting else: - out["ccfs"] = daily_ccfs(t, [coda0], [truth], fs=fs, snr=snr, - decorr=decorr, gen_band=gen, seed=seed) + out["ccfs"] = daily_ccfs( + t, [coda0], [truth], fs=fs, snr=snr, decorr=decorr, gen_band=gen, seed=seed + ) return out @@ -356,8 +493,9 @@ def recover(d: dict, cfg: dict, eps_max: float): if "channels" in d and np.ndim(d["channels"]) == 3: per = [] for c in range(d["channels"].shape[0]): - dvv_c, val_c = run_pipeline(d["channels"][c], d["t"], d["fs"], cfg, - eps_max=eps_max) + dvv_c, val_c = run_pipeline( + d["channels"][c], d["t"], d["fs"], cfg, eps_max=eps_max + ) per.append(np.where(val_c, dvv_c, np.nan)) with warnings.catch_warnings(): warnings.simplefilter("ignore", RuntimeWarning) # all-NaN columns @@ -366,6 +504,28 @@ def recover(d: dict, cfg: dict, eps_max: float): return run_pipeline(d["ccfs"], d["t"], d["fs"], cfg, eps_max=eps_max) +def advisory_case(use_case: str, *, years: float = 3.0, seed: int | None = None): + """Build a public seasonal development example for any supported application. + + This route is independent of the installed evaluation corpus. It never + opens private recipes or substitutes a depth-targeted case for the generic + application. The returned ``recipe`` records the settings for replay. + Synthetic recovery is conditional evidence, not field validation. + """ + app = uc.resolve(use_case) + if not np.isfinite(years) or years <= 0: + raise ValueError("years must be finite and positive") + recipe = next( + dict(c) for c in _build_cases() if c["use_case"] == app and c["grade"] == "easy" + ) + recipe["years"] = float(years) + if seed is not None: + recipe["seed"] = int(seed) + data = _build(recipe) + data["recipe"] = recipe + return data + + # --------------------------------------------------------------------------- # Cache # --------------------------------------------------------------------------- @@ -377,39 +537,71 @@ def _recipe_hash(recipe: dict) -> str: return hashlib.sha1(blob.encode()).hexdigest()[:8] -def generate(case_id: str, *, cache: bool = True) -> dict: - """Return the arrays for a case: ``{ccfs, t, days, truth, fs, use_case, grade}`` - plus ``channels`` (3D) for multi-channel cases. +def _generator_hash() -> str: + """Short digest of the synthesis code: package version plus the source of + this module, :mod:`codameter.synthetic_demo` and :mod:`codameter.use_cases`. Part of the cache key, so + a generator edit can never serve arrays built by older code (audit DET-02). + """ + import hashlib + + from . import synthetic_demo - Deterministic in the seed. Cached to ``cache/-.npz`` (the hash - busts the cache when a recipe changes). ``regenerate_manifest`` uses - ``cache=False`` so a synthesis-*code* change (not captured by the hash) never - scores against stale arrays. + h = hashlib.sha1(__version__.encode()) + for src in (__file__, synthetic_demo.__file__, uc.__file__): + h.update(Path(src).read_bytes()) + return h.hexdigest()[:8] + + +def generate(case_id: str, *, cache: bool = True) -> dict: + """Return the arrays for a case: ``{ccfs, t, days, truth, fs, use_case, grade, + recipe_hash, generator_hash}`` plus ``channels`` (3D) for multi-channel cases. + + Deterministic in the seed. Cached to + ``cache/--.npz``: the recipe hash busts the + cache when a recipe changes, the generator hash when the synthesis code or + the package version changes. Arrays are stored at full precision and the + file is written atomically, so the cold, warm and ``cache=False`` routes + return identical arrays. Stale cache files for the same case are removed. """ recipe = CASES_BY_ID[case_id] - cache_file = CACHE_DIR / f"{case_id}-{_recipe_hash(recipe)}.npz" + rhash, ghash = _recipe_hash(recipe), _generator_hash() + cache_file = CACHE_DIR / f"{case_id}-{rhash}-{ghash}.npz" if cache and cache_file.exists(): z = np.load(cache_file, allow_pickle=False) d = {k: z[k] for k in z.files} d["fs"] = float(d["fs"]) - d["use_case"] = str(d["use_case"]) - d["grade"] = str(d["grade"]) + for key in ("use_case", "grade", "recipe_hash", "generator_hash"): + d[key] = str(d[key]) return d d = _build(recipe) + d["recipe_hash"], d["generator_hash"] = rhash, ghash if cache: + import os + import tempfile + CACHE_DIR.mkdir(parents=True, exist_ok=True) - # Downcast the large CCF arrays to float32 to keep the cache small; the - # lapse/day/truth axes stay float64. - payload = {"t": d["t"], "days": d["days"], "truth": d["truth"], - "ccfs": np.asarray(d["ccfs"], np.float32), - "fs": np.asarray(d["fs"]), - "use_case": np.asarray(d["use_case"]), - "grade": np.asarray(d["grade"])} + payload = { + "t": d["t"], + "days": d["days"], + "truth": d["truth"], + "ccfs": np.asarray(d["ccfs"], np.float64), + "fs": np.asarray(d["fs"]), + "use_case": np.asarray(d["use_case"]), + "grade": np.asarray(d["grade"]), + "recipe_hash": np.asarray(rhash), + "generator_hash": np.asarray(ghash), + } if "channels" in d: - payload["channels"] = np.asarray(d["channels"], np.float32) + payload["channels"] = np.asarray(d["channels"], np.float64) if "truth_other" in d: payload["truth_other"] = d["truth_other"] - np.savez_compressed(cache_file, **payload) + fd, tmp = tempfile.mkstemp(dir=CACHE_DIR, suffix=".npz.tmp") + with os.fdopen(fd, "wb") as fh: + np.savez_compressed(fh, **payload) + os.replace(tmp, cache_file) + for stale in CACHE_DIR.glob(f"{case_id}-*.npz"): + if stale != cache_file: + stale.unlink(missing_ok=True) return d @@ -427,8 +619,9 @@ def observed(case_id: str, *, cache: bool = True) -> dict: ``generate()`` can simply return ``d["truth"]`` and score a perfect 1.0. Anything the agent touches should go through this function. """ - return {k: v for k, v in generate(case_id, cache=cache).items() - if k not in TRUTH_KEYS} + return { + k: v for k, v in generate(case_id, cache=cache).items() if k not in TRUTH_KEYS + } # --------------------------------------------------------------------------- @@ -455,6 +648,59 @@ def _rms(dvv, truth, days, valid, baseline_frac: float = 0.2) -> float: return float(np.sqrt(np.mean((d0 - tr0) ** 2))) +def scoring_support( + d: dict, cfg: dict, eps_max: float, baseline_frac: float = 0.2 +) -> dict: + """Fixed evaluation support for a case, defined by its reference pipeline. + + ``support`` is the sorted list of epoch indices where ``cfg`` (the case's + reference configuration) returns a valid estimate; ``baseline`` is the + earliest ``baseline_frac`` of those epochs, the datum over which truth and + prediction are demeaned in :func:`rms_on_support`. Both are properties of + the case, never of a submission, so a submission cannot choose where it is + evaluated or where its zero point is taken (audit finding EV-01). + """ + _, valid = recover(d, cfg, eps_max) + idx = np.flatnonzero(np.asarray(valid, bool)) + if idx.size < 10: + raise ValueError("reference pipeline valid on fewer than 10 epochs") + dd = np.asarray(d["days"], float)[idx] + cut = np.quantile(dd, baseline_frac) + base = idx[dd <= cut] + if base.size < 2: + base = idx + return {"support": idx.tolist(), "baseline": base.tolist()} + + +def rms_on_support(dvv, truth, support, baseline) -> tuple[float, float]: + """Baseline-aligned RMS of ``dvv`` against ``truth`` on a fixed support. + + Truth and prediction are demeaned over the fixed ``baseline`` epochs (the + DC offset of a reference-relative dv/v is unobservable). A missing + (non-finite) prediction inside the support is scored as the **null + prediction**, i.e. zero change from the baseline, so missing epochs do not disappear from the error denominator. Replacing + a poor prediction by null can still improve the score; availability must + be reported separately. The prediction's own baseline mean is taken over its + finite baseline epochs; fewer than two of those means no datum and an + RMS of ``nan``. + + Returns ``(rms, availability)`` with ``availability`` the finite fraction + of the support. + """ + sup = np.asarray(support, int) + base = np.asarray(baseline, int) + dv = np.asarray(dvv, float)[sup] + tr = np.asarray(truth, float)[sup] + finite = np.isfinite(dv) + availability = float(finite.mean()) if sup.size else 0.0 + in_base = np.isin(sup, base) + if (finite & in_base).sum() < 2: + return float("nan"), availability + d0 = np.where(finite, dv - dv[finite & in_base].mean(), 0.0) + tr0 = tr - tr[in_base].mean() + return float(np.sqrt(np.mean((d0 - tr0) ** 2))), availability + + def _jsonable(cfg: dict) -> dict: """Tuples (band, window) -> lists so the config round-trips through JSON.""" return {k: (list(v) if isinstance(v, tuple) else v) for k, v in cfg.items()} @@ -468,8 +714,11 @@ def compute_metrics(case_id: str, data: dict | None = None) -> dict: cfg = uc.recommend(app, **recipe.get("config", {})) eps = uc.eps_max(app) dvv, valid = recover(d, cfg, eps) - res = {"config": _jsonable(cfg), "eps_max": eps, - "rms": _rms(dvv, d["truth"], d["days"], valid)} + res = { + "config": _jsonable(cfg), + "eps_max": eps, + "rms": _rms(dvv, d["truth"], d["days"], valid), + } if "truth_other" in d: # The error a config would incur by recovering the WRONG depth layer: # the "clearly wrong" anchor for scoring depth-band selection. @@ -485,24 +734,32 @@ def regenerate_manifest() -> dict: """Recompute every case's expected metrics and rewrite ``manifest.json``.""" cases = [] for c in CASES: - d = generate(c["id"], cache=False) # always from current code + d = generate(c["id"], cache=False) # always from current code m = compute_metrics(c["id"], d) entry = { - "id": c["id"], "grade": c["grade"], "use_case": c["use_case"], - "motif": c["motif"], "split": case_split(c), - "visibility": case_visibility(c), "years": c["years"], "snr": c["snr"], - "seed": c["seed"], "channels": c["channels"], "decorr": c["decorr"], - "rms_rel_tol": c["rms_rel_tol"], "n_days": int(len(d["days"])), + "id": c["id"], + "grade": c["grade"], + "use_case": c["use_case"], + "motif": c["motif"], + "split": case_split(c), + "visibility": case_visibility(c), + "years": c["years"], + "snr": c["snr"], + "seed": c["seed"], + "channels": c["channels"], + "decorr": c["decorr"], + "rms_rel_tol": c["rms_rel_tol"], + "n_days": int(len(d["days"])), "expected": m, } if c.get("two_layer"): entry["two_layer"] = True entry["target"] = c["target"] cases.append(entry) - print(f" {c['id']:<26} ch={c['channels']} snr={c['snr']:<4} " - f"rms={m['rms']:.5f}") - manifest = {"version": MANIFEST_VERSION, "grades": list(GRADES), - "cases": cases} + print( + f" {c['id']:<26} ch={c['channels']} snr={c['snr']:<4} rms={m['rms']:.5f}" + ) + manifest = {"version": MANIFEST_VERSION, "grades": list(GRADES), "cases": cases} DATA_DIR.mkdir(parents=True, exist_ok=True) MANIFEST.write_text(json.dumps(manifest, indent=2) + "\n") return manifest @@ -510,10 +767,9 @@ def regenerate_manifest() -> dict: def _manifest_is_current(manifest: dict) -> bool: """True if an on-disk manifest matches the current code (version + case ids).""" - return ( - manifest.get("version") == MANIFEST_VERSION - and [c["id"] for c in manifest.get("cases", [])] == [c["id"] for c in CASES] - ) + return manifest.get("version") == MANIFEST_VERSION and [ + c["id"] for c in manifest.get("cases", []) + ] == [c["id"] for c in CASES] def load_manifest() -> dict: @@ -559,8 +815,10 @@ def expected_metrics(case_id: str) -> dict: def main() -> int: - print(f"Regenerating golden manifest ({len(CASES)} cases, " - f"{len(GRADES)} grades) -> {MANIFEST}") + print( + f"Regenerating golden manifest ({len(CASES)} cases, " + f"{len(GRADES)} grades) -> {MANIFEST}" + ) regenerate_manifest() print("done.") return 0 diff --git a/src/codameter/inverse/linear_fit.py b/src/codameter/inverse/linear_fit.py index b745fee..362d300 100644 --- a/src/codameter/inverse/linear_fit.py +++ b/src/codameter/inverse/linear_fit.py @@ -32,6 +32,7 @@ - Aster, R. C., Borchers, B., & Thurber, C. H. (2018). *Parameter Estimation and Inverse Problems*. Elsevier, 3rd ed. """ + from __future__ import annotations from dataclasses import dataclass, field @@ -41,6 +42,7 @@ import pandas as pd from scipy.optimize import lsq_linear +from ..forcing_models import canonical_model from ..forward.damage import snieder_healing from ..forward.loading import surface_load_dvv from ..forward.poroelastic import ( @@ -49,7 +51,6 @@ talwani_precipitation_response, ) from ..forward.thermoelastic import thermoelastic_dvv -from ..forcing_models import canonical_model from .posterior import Posterior DEFAULT_TIME_SHIFT_GRID_DAYS = np.arange(0.0, 200.0 + 1.0, 1.0) @@ -97,6 +98,7 @@ def n_par(self) -> int: _LOADING_MODELS = frozenset({"instantaneous", "snowpack"}) + def build_predictor_matrix( times_s: np.ndarray, *, @@ -361,7 +363,9 @@ def build_predictor_matrix( "time_shift_days": time_shift_days, "tau_min_s": tau_min_s, "tau_max_s": tau_max_s, - "earthquake_times_s": list(earthquake_times_s) if earthquake_times_s else [], + "earthquake_times_s": ( + list(earthquake_times_s) if earthquake_times_s else [] + ), }, ) @@ -383,6 +387,10 @@ class LinearFitResult: n_obs: int n_par: int predictor_matrix: PredictorMatrix + #: Per-parameter flag: the bound-constrained solution sits on a bound. The + #: reported std for such a parameter is the unconstrained curvature at the + #: constrained solution, not a one-sided interval (see :func:`linear_fit`). + at_bound: np.ndarray | None = None @property def parameter_names(self) -> list[str]: @@ -405,6 +413,9 @@ def to_dict(self) -> dict[str, Any]: "rank": int(self.rank), "n_obs": int(self.n_obs), "n_par": int(self.n_par), + "at_bound": ( + [bool(b) for b in self.at_bound] if self.at_bound is not None else None + ), "metadata": self.predictor_matrix.metadata, } @@ -420,8 +431,7 @@ def summary(self) -> pd.DataFrame: "ci95_low": m - 1.96 * s, "ci95_high": m + 1.96 * s, "units": [ - self.predictor_matrix.units.get(n, "") - for n in self.parameter_names + self.predictor_matrix.units.get(n, "") for n in self.parameter_names ], } ) @@ -512,6 +522,7 @@ def linear_fit( lb[idx] = float(lo) if lo is not None else -np.inf ub[idx] = float(hi) if hi is not None else +np.inf constrained = bool(np.isfinite(lb).any() or np.isfinite(ub).any()) + active = np.zeros(p, dtype=bool) if constrained: sol = lsq_linear(Xw, dw, bounds=(lb, ub), method="bvls") @@ -541,12 +552,11 @@ def linear_fit( # Unweighted: rescale cov by residual variance cov = cov * (float(np.sum(res**2)) / dof) - # When a bound is active, that parameter is no longer free: zero its - # row/column in the covariance so the reported std is 0 (clamped). - if constrained and active.any(): - cov = cov.copy() - cov[active, :] = 0.0 - cov[:, active] = 0.0 + # A parameter on an active bound is not "known exactly": the data still + # constrain it with the same curvature, the bound only truncates the + # posterior on one side. Report that curvature and flag the parameter in + # ``at_bound`` rather than zeroing its row (which reported zero uncertainty; + # audit INV-02). A one-sided interval needs a truncated-normal treatment. posterior = Posterior( mean=p_hat, @@ -562,6 +572,7 @@ def linear_fit( n_obs=int(n), n_par=int(p), predictor_matrix=predictor_matrix, + at_bound=active, ) diff --git a/src/codameter/synthetic_demo.py b/src/codameter/synthetic_demo.py index 5ecdf83..310e701 100644 --- a/src/codameter/synthetic_demo.py +++ b/src/codameter/synthetic_demo.py @@ -24,12 +24,21 @@ --------------- ``dv/v`` is the fractional velocity change. A velocity *decrease* (``dv/v < 0``) lengthens travel times, so the coda dilates to later lapse times: -a feature at reference lapse :math:`t` appears at :math:`t/(1+dv/v)`. The -recovered estimate uses the same convention, so a correct measurement returns +a feature at reference lapse :math:`t` appears at :math:`t/(1+dv/v)` on the +*current* waveform (equivalently, ``current(t) = reference(t*(1+dv/v))`` -- +this is exactly what :func:`impose_dvv` implements). The stretching +estimators (:func:`stretching_cc` and everything built on it) invert this by +resampling the *current* waveform at trial positions ``(1+eps)*t``, holding +the *reference* fixed, and converting the fitted stretch factor ``eps`` to +physical ``dv/v`` via the exact map ``dv/v = -eps/(1+eps)`` +(:func:`eps_to_dvv`) -- never the first-order ``dv/v ~= -eps`` alone, which +is only accurate to :math:`O(\mathrm{eps}^2)`. A correct measurement returns the imposed value (verified in :func:`_self_check`). """ + from __future__ import annotations +import warnings from dataclasses import dataclass, field from pathlib import Path @@ -198,11 +207,18 @@ def impose_dvv(ref: np.ndarray, t: np.ndarray, dvv: float) -> np.ndarray: **Sign convention (physical dv/v)**: ``dvv`` is the fractional velocity change. A velocity *increase* (``dvv > 0``) shortens travel times, so a - feature at reference lapse ``tau`` appears at ``tau / (1 + dvv)`` — the - coda compresses toward zero lag. Equivalently - ``dvv = -epsilon / (1 + epsilon)`` where ``epsilon`` is the stretch - factor that maps the reference onto the current waveform (see - :func:`eps_to_dvv`; ``-epsilon`` alone is only first-order accurate). (Before v0.4.0 this function used the epsilon + feature at reference lapse ``tau`` appears at ``tau / (1 + dvv)`` on the + current waveform -- equivalently, ``current(t) = reference(t*(1+dvv))`` + for every ``t``, which is exactly the ``np.interp`` call below: the + output at time ``t`` is the reference sampled at ``t*(1+dvv)``. This is + the exact time-ratio relation implied by ``t_current/t_reference = + 1/(1+dvv)``, not a first-order approximation. + + The stretching estimators invert this relation the other way: they + resample the *current* waveform (not the reference) at trial positions + ``(1+eps)*t`` and recover ``dvv = -eps/(1+eps)`` exactly (see + :func:`stretching_cc`, :func:`eps_to_dvv`; ``-eps`` alone is only + first-order accurate). (Before v0.4.0 this function used the epsilon convention: positive argument meant coda dilation, i.e. a slowdown.) """ return np.interp(t * (1.0 + dvv), t, ref) @@ -335,6 +351,51 @@ def _window_mask( return (np.abs(t) >= w0) & (np.abs(t) <= w1) +def _stretch_window( + t: np.ndarray, + window: tuple[float, float], + eps_max: float, + branch: str = "both", +) -> tuple[np.ndarray, tuple[float, float]]: + """Window mask shared by every trial epsilon in a stretching search. + + The stretching estimators resample *current* at ``(1+eps)*t``; the query + point furthest from zero lag for a window ``[w0, w1]`` and trial range + ``[-eps_max, eps_max]`` is ``(1+eps_max)*w1``, reached at the largest + dilation. If that would fall outside ``t``'s recorded support, the + window's upper edge is shrunk (never silently extrapolated) to the + largest value that stays in-bounds for *every* trial epsilon, and a + ``UserWarning`` is raised naming the shrunk window. The same (w0, w1) is + then used to build the mask for the *entire* epsilon grid, so every + trial candidate is evaluated against an identical sample count -- a + changing valid-support size cannot spuriously change which epsilon + looks like the best-correlated one. + + Returns ``(sel, (w0, w1))``: ``sel`` is the boolean mask on ``t``, and + ``(w0, w1)`` is the (possibly shrunk) window actually used. + """ + w0, w1 = window + tmax = float(np.max(np.abs(t))) if t.size else 0.0 + safe_w1 = min(w1, tmax / (1.0 + eps_max)) if eps_max > -1.0 else w1 + if safe_w1 < w0: + raise ValueError( + f"window {window} cannot be evaluated for any trial epsilon up " + f"to eps_max={eps_max} within the trace's recorded support " + f"(max |t| = {tmax}); shrink eps_max/window or extend the trace." + ) + if safe_w1 < w1 - 1e-9: + warnings.warn( + f"coda window upper edge {w1:g} shrunk to {safe_w1:.6g} so every " + f"trial epsilon (|eps| <= {eps_max:g}) stays within the current " + "trace's recorded support (t_current = (1+eps)*t); no sample is " + "extrapolated. Pass a narrower window or a smaller eps_max to " + "silence this.", + stacklevel=3, + ) + w1 = safe_w1 + return _window_mask(t, (w0, w1), branch), (w0, w1) + + def _parabolic(y: np.ndarray, i: int) -> float: """Sub-sample peak offset (in index units) from a 3-point parabola fit.""" if i <= 0 or i >= len(y) - 1: @@ -359,6 +420,16 @@ def stretching_cc( ) -> tuple[np.ndarray, np.ndarray]: """The full correlation-coefficient image ``CC(epsilon, time)``. + For each trial ``epsilon`` the *current* waveform is resampled at + ``(1 + epsilon) * t`` and correlated against the unchanged, windowed + *reference* (:func:`eps_to_dvv` converts the fitted ``epsilon`` to + physical dv/v; reference stays fixed, never resampled). The coda window + is shrunk, with a loud warning, if needed so every trial in + ``[-eps_max, eps_max]`` stays within the current trace's recorded + support and no sample is silently extrapolated — see + :func:`_stretch_window`; the same window is then used for the whole + epsilon grid, so every candidate is scored on an identical sample count. + Returns ``(es, cc)`` where ``cc`` has shape ``[ndays, n_eps]`` — the object that aggregation workflows either reduce to a per-trace peak *before* averaging, or average *as images* before peak-picking (see @@ -369,25 +440,41 @@ def stretching_cc( because band-passing is linear and commutes with the linear stacking that builds references — see :func:`codameter.deviations.run_pipeline`). """ - cur_mat = np.atleast_2d(cur_mat) + cur_mat = np.atleast_2d(np.asarray(cur_mat, float)) + curf_full = cur_mat if prefiltered else bandpass(cur_mat, fs, *band) reff = ref if prefiltered else bandpass(ref, fs, *band) es = np.linspace(-eps_max, eps_max, n_eps) - sel = _window_mask(t, window, branch) - trials = np.stack([np.interp(t / (1.0 + e), t, reff)[sel] for e in es]) - trials = trials / (np.linalg.norm(trials, axis=1, keepdims=True) + 1e-12) - curf = (cur_mat if prefiltered else bandpass(cur_mat, fs, *band))[:, sel] - curf = curf / (np.linalg.norm(curf, axis=1, keepdims=True) + 1e-12) - return es, curf @ trials.T # [ndays, n_eps] + sel, _ = _stretch_window(t, window, eps_max, branch) + tsel = t[sel] + + refw = reff[sel] + refw = refw / (np.linalg.norm(refw) + 1e-12) + + cc = np.empty((curf_full.shape[0], n_eps)) + for ei, e in enumerate(es): + # Gather indices/weights of np.interp((1+e)*t, t, .) on the window, + # clamped at the grid ends exactly as np.interp clamps -- unreached + # in practice since _stretch_window keeps every trial in-bounds. + q = (1.0 + e) * tsel + j = np.clip(np.searchsorted(t, q, side="right") - 1, 0, t.size - 2) + w = np.clip((q - t[j]) / (t[j + 1] - t[j]), 0.0, 1.0) + trials = curf_full[:, j] * (1.0 - w) + curf_full[:, j + 1] * w + trials = trials / (np.linalg.norm(trials, axis=1, keepdims=True) + 1e-12) + cc[:, ei] = trials @ refw + return es, cc # [ndays, n_eps] def eps_to_dvv(eps): """Exact stretch-to-velocity map: ``dv/v = -eps / (1 + eps)``. - The stretching trial maps the reference through ``t / (1 + eps)``; the - physical change maps arrivals through ``t / (1 + dv/v)`` on the *current* - waveform. Matching the two gives ``1 + dv/v = 1 / (1 + eps)``. The - first-order ``dv/v = -eps`` is accurate to ~eps^2 (fine below 1%%), but - at landslide-scale changes (several %%) the quadratic term matters. + The stretching trial resamples the *current* waveform through + ``(1 + eps) * t``, holding the reference fixed (see :func:`stretching_cc`); + the physical change maps ``current(t) = reference(t * (1 + dv/v))``. + Matching the two trial-vs-physical forms gives ``1 + eps = 1 / (1 + dv/v)``, + i.e. ``dv/v = -eps / (1 + eps)`` exactly, for every ``eps``. The + first-order ``dv/v = -eps`` is accurate to ~eps^2 only (fine below 1%%), + but at landslide-scale changes (several %%) the quadratic term matters — + do not substitute it where the exact form is available. """ eps = np.asarray(eps, dtype=float) if np.any(eps <= -1.0): @@ -398,13 +485,31 @@ def eps_to_dvv(eps): return -eps / (1.0 + eps) +def dvv_to_epsilon(dvv): + """Exact velocity-to-stretch map: ``eps = -dv/v / (1 + dv/v)``. + + The inverse of :func:`eps_to_dvv` (``dvv_to_epsilon(eps_to_dvv(e)) == e`` + for every valid ``e``): given a desired physical ``dv/v``, this is the + trial stretch ``eps`` whose current-interpolated correlation peak, + :func:`eps_to_dvv`, would report that ``dv/v`` back exactly. + """ + dvv = np.asarray(dvv, dtype=float) + if np.any(dvv <= -1.0): + raise ValueError( + "dv/v <= -1 is unphysical (zero or negative velocity); got " + "min dv/v = " + str(float(np.min(dvv))) + ) + return -dvv / (1.0 + dvv) + + def peak_dvv(es: np.ndarray, cc: np.ndarray) -> tuple[np.ndarray, np.ndarray]: """Peak-pick a ``CC(epsilon, time)`` image → (dv/v per time, peak CC). Returns **physical dv/v** = ``-epsilon / (1 + epsilon)`` at the correlation peak (the exact map, :func:`eps_to_dvv`): the - grid ``es`` holds stretch factors (the trial maps the reference through - ``t / (1 + epsilon)``), and a coda that had to be *dilated* to match + grid ``es`` holds stretch factors (the trial resamples *current* through + ``(1 + epsilon) * t``, reference fixed — see :func:`stretching_cc`), and + a current waveform that had to be *dilated* to match the reference (``epsilon > 0``) means travel times lengthened, i.e. the velocity *dropped*. (Before v0.4.0 this returned epsilon itself, labeled dv/v.) """ @@ -463,8 +568,14 @@ def measure_stretching_moving( ) -> np.ndarray: """Stretching dv/v against a *trailing* reference (previous ``ref_days``). - A moving reference re-baselines continuously, so it removes slow trends — - the canonical reason a moving reference and a fixed reference disagree. + Returns the *uncumulated* per-epoch increment: each day is referenced to + the mean of the preceding ``ref_days``, so a slow trend is differenced away + rather than measured. Published trailing-reference workflows do not stop + here — James et al. (2017) sum these increments from a fixed start date to + reconstruct the trend, at the cost of a random-walk drift that needs an + independent anchor. That summation is not applied here; this function is the + increment alone, which is what makes it a clean isolation of the cost of + re-baselining. """ cur_mat = np.atleast_2d(cur_mat) ndays = cur_mat.shape[0] @@ -495,12 +606,14 @@ def measure_stretching_trailing( Numerically equivalent (to float rounding, ~1e-15 in dv/v) to calling :func:`measure_stretching` day by day against - ``cur_mat[d - ref_days : d].mean(axis=0)``, but ~5x faster: the stretched - sample positions ``t / (1 + eps)`` are data-independent, so the - linear-interpolation gather indices and weights are computed once per - epsilon and applied to every day's band-passed trailing reference at once. - The trailing references are built as a difference of cumulative sums and - the band-pass runs over the whole matrix in one FFT. + ``cur_mat[d - ref_days : d].mean(axis=0)``, but ~5x faster: for each + trial epsilon the *current* trace is resampled at ``(1 + eps) * t`` + (reference fixed, as in :func:`stretching_cc`); since that query axis is + the same for every day, the linear-interpolation gather indices and + weights are computed once per epsilon and applied to every day's + band-passed current trace at once. The trailing references (fixed with + respect to epsilon) are built as a difference of cumulative sums and the + band-pass runs over the whole matrix in one FFT. Returns ``(dvv, cc)`` over the full length of ``cur_mat``; the ``ref_days`` warm-up epochs are NaN. @@ -518,24 +631,27 @@ def measure_stretching_trailing( refs = (head - tail) / float(ref_days) reffs = refs if prefiltered else bandpass(refs, fs, *band) - sel = _window_mask(t, window, branch) + sel, _ = _stretch_window(t, window, eps_max, branch) tsel = t[sel] + refw = reffs[:, sel] + refw = refw / (np.linalg.norm(refw, axis=1, keepdims=True) + 1e-12) + curf = ( cur_mat[ref_days:] if prefiltered else bandpass(cur_mat[ref_days:], fs, *band) - )[:, sel] - curf = curf / (np.linalg.norm(curf, axis=1, keepdims=True) + 1e-12) + ) es = np.linspace(-eps_max, eps_max, n_eps) cc_img = np.empty((ndays - ref_days, n_eps)) for ei, e in enumerate(es): - # Gather indices/weights of np.interp(t / (1 + e), t, .) on the window, - # clamped at the grid ends exactly as np.interp clamps. - q = tsel / (1.0 + e) + # Gather indices/weights of np.interp((1+e)*t, t, .) on the window, + # clamped at the grid ends exactly as np.interp clamps -- unreached + # in practice since _stretch_window keeps every trial in-bounds. + q = (1.0 + e) * tsel j = np.clip(np.searchsorted(t, q, side="right") - 1, 0, t.size - 2) w = np.clip((q - t[j]) / (t[j + 1] - t[j]), 0.0, 1.0) - trials = reffs[:, j] * (1.0 - w) + reffs[:, j + 1] * w + trials = curf[:, j] * (1.0 - w) + curf[:, j + 1] * w trials = trials / (np.linalg.norm(trials, axis=1, keepdims=True) + 1e-12) - cc_img[:, ei] = np.einsum("ij,ij->i", curf, trials) + cc_img[:, ei] = np.einsum("ij,ij->i", trials, refw) dvv[ref_days:], cc_peak[ref_days:] = peak_dvv(es, cc_img) return dvv, cc_peak @@ -805,28 +921,30 @@ def measure_wts( ) -> np.ndarray: """WTS dv/v: stretching applied per scale of the wavelet transform. - Each frequency row of the (real part of the) CWT is a narrow-band trace; the - stretch that best aligns current to reference is found per scale and pooled, - power-weighted (NoisePy ``wts_dvv``). Being a stretching variant it is robust - to large dv/v, like time-domain TS. + Each frequency row of the (real part of the) CWT is a narrow-band trace; + for each trial epsilon the *current* row is resampled at + ``(1 + eps) * t`` and correlated against the unchanged reference row + (reference fixed, as in :func:`stretching_cc`) -- the stretch that best + aligns them is found per scale and pooled, power-weighted (NoisePy + ``wts_dvv``). Being a stretching variant it is robust to large dv/v, + like time-domain TS. """ cur_mat = np.atleast_2d(cur_mat) - reg, tt, freqs, wsel = _cwt_setup(t, window, band, nfreq) + reg, tt, freqs, _ = _cwt_setup(t, window, band, nfreq) + wsel, _ = _stretch_window(tt, window, eps_max, branch="causal") Wref = _morlet_cwt(ref[reg], fs, freqs, w0).real + refbank = Wref[:, wsel] + refbank = refbank / (np.linalg.norm(refbank, axis=1, keepdims=True) + 1e-12) es = np.linspace(-eps_max, eps_max, n_eps) - banks = [] - for k in range(freqs.size): - trials = np.stack([np.interp(tt / (1.0 + e), tt, Wref[k])[wsel] for e in es]) - trials /= np.linalg.norm(trials, axis=1, keepdims=True) + 1e-12 - banks.append(trials) + ttsel = tt[wsel] out = np.full(cur_mat.shape[0], np.nan) for d in range(cur_mat.shape[0]): Wcur = _morlet_cwt(cur_mat[d, reg], fs, freqs, w0).real num = den = 0.0 for k in range(freqs.size): - seg = Wcur[k, wsel] - seg = seg / (np.linalg.norm(seg) + 1e-12) - cc = banks[k] @ seg + trials = np.stack([np.interp((1.0 + e) * ttsel, tt, Wcur[k]) for e in es]) + trials /= np.linalg.norm(trials, axis=1, keepdims=True) + 1e-12 + cc = trials @ refbank[k] i = int(np.argmax(cc)) wgt = np.linalg.norm(Wcur[k, wsel]) num += wgt * (es[i] + _parabolic(cc, i) * (es[1] - es[0])) @@ -1173,6 +1291,24 @@ def _yrs(days: np.ndarray) -> np.ndarray: return days / YEAR_D +def _boost_fonts(*axes, tick=13.0, label=15.0, title=16.0): + """Set explicit tick/label/title sizes on each axis. + + Figures are authored at a native size well above their final + ``\\includegraphics`` width in the manuscript (multi-panel figures need + the extra canvas width to avoid overlapping subplots), which shrinks + every point size by roughly (embed width / native width) once placed on + the page. The defaults here assume a substantial shrink and are picked + per call to land near a ~9.5 pt tick/legend and ~11-12 pt label/title on + the printed page; callers with a milder shrink pass smaller values. + """ + for ax in axes: + ax.tick_params(labelsize=tick) + ax.xaxis.label.set_size(label) + ax.yaxis.label.set_size(label) + ax.title.set_size(title) + + def _trailing_stack(ccfs: np.ndarray, k: int) -> np.ndarray: if k <= 1: return ccfs @@ -1289,7 +1425,7 @@ def fig_methods(seed: int = 11): kw.update(sub) recL[m] = measure(m, ccfs, s.ref, s.t, **kw) - fig, (axA, axB, axC) = plt.subplots(1, 3, figsize=(9.8, 3.6)) + fig, (axA, axB, axC) = plt.subplots(1, 3, figsize=(11.8, 4.9)) axA.plot([-0.5, 0.5], [-0.5, 0.5], color="0.6", lw=1, ls=":", label="1:1 (truth)") for m in METHODS: col, ls = _MSTYLE[m] @@ -1308,7 +1444,6 @@ def fig_methods(seed: int = 11): ylabel="recovered dv/v (%)", title="(a) clean, small dv/v", ) - axA.legend(loc="upper left", fontsize=8, ncol=2) axB.plot([-5, 5], [-5, 5], color="0.6", lw=1, ls=":", label="1:1 (truth)") for m in METHODS: col, ls = _MSTYLE[m] @@ -1326,8 +1461,9 @@ def fig_methods(seed: int = 11): ylabel="recovered dv/v (%)", title="(b) clean, $\\pm 5\\,\\%$ sweep", ) - axB.legend(loc="upper left", fontsize=7.5, ncol=2) - axC.plot(_yrs(days), truth * PCT, color=C["truth"], lw=2.6, label="truth") + axC.plot( + _yrs(days), truth * PCT, color=C["truth"], lw=2.6, label="truth (landslide)" + ) for m in METHODS: col, ls = _MSTYLE[m] axC.plot( @@ -1338,8 +1474,24 @@ def fig_methods(seed: int = 11): ylabel="dv/v (%)", title="(c) large dv/v — MWCS cycle-skips", ) - axC.legend(loc="lower left", fontsize=8, ncol=2) - fig.tight_layout() + # One shared legend for all three panels (they plot the same 9 series) — + # per-panel legends at a legible size would cover the data in a figure + # this dense. + handles, labels = axA.get_legend_handles_labels() + h2, l2 = axC.get_legend_handles_labels() + handles.append(h2[0]) + labels.append(l2[0]) + fig.legend( + handles, + labels, + loc="lower center", + bbox_to_anchor=(0.5, -0.08), + ncol=5, + fontsize=15, + frameon=False, + ) + _boost_fonts(axA, axB, axC, tick=15, label=17, title=18) + fig.tight_layout(rect=(0, 0.1, 1, 1)) return fig @@ -1389,7 +1541,7 @@ def fig_aggregation(seed: int = 88): # context, not the point, so they are allowed to clip at the edges. ylim = (-1.4, 1.4) - fig, (axA, axB) = plt.subplots(1, 2, figsize=(6.9, 3.6)) + fig, (axA, axB) = plt.subplots(1, 2, figsize=(8.6, 4.4)) for d in dvv_c: axA.plot(_yrs(days), d * PCT, color="0.8", lw=0.4) axA.plot( @@ -1431,8 +1583,13 @@ def fig_aggregation(seed: int = 88): ylim=ylim, title="(a) Component aggregation: three recipes", ) - leg = axA.legend(loc="lower left", fontsize=7.5, frameon=True) - leg.get_frame().set(facecolor="white", alpha=0.9, edgecolor="0.7") + axA.legend( + fontsize=12, + loc="upper center", + bbox_to_anchor=(0.5, -0.16), + ncol=2, + frameon=False, + ) extent = [_yrs(days)[0], _yrs(days)[-1], es[0] * PCT, es[-1] * PCT] im = axB.imshow( mean_img.T, @@ -1443,7 +1600,8 @@ def fig_aggregation(seed: int = 88): vmin=0, ) cbar = fig.colorbar(im, ax=axB, pad=0.02) - cbar.set_label("coherence CC (dark = high)") + cbar.set_label("coherence CC (dark = high)", fontsize=15) + cbar.ax.tick_params(labelsize=13) axB.plot(_yrs(days), B * PCT, color="white", lw=1.2, label="peak of mean CC (B)") axB.plot(_yrs(days), truth * PCT, color="black", lw=1.0, ls="--", label="truth") axB.set( @@ -1452,7 +1610,8 @@ def fig_aggregation(seed: int = 88): ylim=ylim, title="(b) averaged CC(dv/v, t) image (B)", ) - axB.legend(loc="upper right", fontsize=8) + axB.legend(loc="upper right", fontsize=13) + _boost_fonts(axA, axB, tick=13, label=15, title=16) fig.tight_layout() return fig @@ -1539,7 +1698,7 @@ def fig_uncertainty(seed: int = 123): ] yr = _yrs(days) - fig, (axA, axB) = plt.subplots(1, 2, figsize=(6.9, 3.6)) + fig, (axA, axB) = plt.subplots(1, 2, figsize=(8.6, 4.4)) axA.plot(yr, truth * PCT, color=C["truth"], lw=2.4, label="network truth") for key, col, lab in schemes: m, sg = R[key]["dvv"], R[key]["sigma"] @@ -1553,7 +1712,8 @@ def fig_uncertainty(seed: int = 123): ylim=(-0.35, 0.3), title="(a) same mean, different error bands", ) - axA.legend(loc="lower left", fontsize=8) + leg = axA.legend(loc="lower left", fontsize=13, frameon=True) + leg.get_frame().set(facecolor="white", alpha=0.9, edgecolor="0.7") meds = {} for key, col, lab in schemes: sg = R[key]["sigma"] * PCT @@ -1565,7 +1725,9 @@ def fig_uncertainty(seed: int = 123): ylabel=r"reported 1$\sigma$ on dv/v (%)", title=f"(b) the error bar is a choice (≈{ratio:.1f}× range)", ) - axB.legend(loc="upper left", fontsize=8) + leg = axB.legend(loc="upper left", fontsize=13, frameon=True) + leg.get_frame().set(facecolor="white", alpha=0.9, edgecolor="0.7") + _boost_fonts(axA, axB, tick=13, label=15, title=15.5) fig.tight_layout() return fig @@ -1592,7 +1754,7 @@ def fig_network_pairs(seed: int = 123): pair_dvv, pair_snr = R["pair_dvv"], R["pair_snr"] yr = _yrs(days) - fig, ax = plt.subplots(figsize=(6.0, 4.0)) + fig, ax = plt.subplots(figsize=(7.2, 4.8)) order = np.argsort(-pair_snr) # best SNR first, for a readable legend/colour ramp cmap = plt.get_cmap("viridis") for rank, p in enumerate(order): @@ -1613,86 +1775,65 @@ def fig_network_pairs(seed: int = 123): cmap=cmap, norm=Normalize(vmin=pair_snr.min(), vmax=pair_snr.max()) ) cbar = fig.colorbar(sm, ax=ax, pad=0.02) - cbar.set_label("pair SNR") + cbar.set_label("pair SNR", fontsize=16) + cbar.ax.tick_params(labelsize=14) ax.set( xlabel="time (years)", ylabel="dv/v (%)", title="Individual station-pair dv/v -- wider than the network error bar", ) - ax.legend(loc="lower left", fontsize=8.5) + ax.legend(loc="lower left", fontsize=14) + _boost_fonts(ax, tick=14, label=16, title=17) fig.tight_layout() return fig def fig_window_band(seed: int = 66): """Coda window must scale with frequency band: a fixed late window is full of - signal at low frequency but pure noise at high frequency.""" + signal at low frequency but pure noise at high frequency. + + Single panel by design -- embedded as one quadrant of Fig. fig:params + alongside three other single-panel figures, so it needs to match their + footprint. The companion dv/v-recovery comparison this used to carry as a + second panel is covered more rigorously (RMS against a known truth, three + bands) by the dedicated :func:`fig_window_envelope` figure. + """ import matplotlib.pyplot as plt s = Synth() tf, cf = make_freqdep_coda(fs=s.fs, seed=2) - days = _days(2.0) - truth = _seasonal(days, 0.0015, 60) - 0.0008 * days / days[-1] - ccfs = daily_ccfs( - tf, [cf], [truth], fs=s.fs, snr=15.0, gen_band=(0.2, 8.0), seed=seed - ) lowb, hib = (0.3, 0.8), (3.0, 6.0) fixed_w, adapt_w = (20.0, 40.0), (3.0, 12.0) - hi_fixed, _ = measure_stretching(ccfs, cf, tf, band=hib, fs=s.fs, window=fixed_w) - hi_adapt, _ = measure_stretching(ccfs, cf, tf, band=hib, fs=s.fs, window=adapt_w) env_lo = _envelope(bandpass(cf, s.fs, *lowb), s.fs) env_hi = _envelope(bandpass(cf, s.fs, *hib), s.fs) norm = env_lo.max() floor = env_lo[(np.abs(tf) > 45)].mean() / norm # late-lapse noise proxy - fig, (axA, axB) = plt.subplots(1, 2, figsize=(6.9, 3.6)) + fig, ax = plt.subplots(figsize=(4.2, 3.1)) m = tf >= 0 - axA.semilogy( - tf[m], env_lo[m] / norm, color=C["alt"], lw=1.5, label="low band 0.3–0.8 Hz" - ) - axA.semilogy( - tf[m], - env_hi[m] / norm, - color=C["groundwater"], - lw=1.5, - label="high band 3–6 Hz", + ax.semilogy(tf[m], env_lo[m] / norm, color=C["alt"], lw=1.5, label="low band") + ax.semilogy( + tf[m], env_hi[m] / norm, color=C["groundwater"], lw=1.5, label="high band" ) - axA.axhline(max(floor, 1e-3), color="0.5", ls=":", lw=1, label="noise floor") - axA.axvspan(*fixed_w, color=C["bad"], alpha=0.15, lw=0) - axA.axvspan(*adapt_w, color=C["groundwater"], alpha=0.12, lw=0) - axA.set( + ax.axhline(max(floor, 1e-3), color="0.5", ls=":", lw=1, label="noise floor") + ax.axvspan(*fixed_w, color=C["bad"], alpha=0.15, lw=0) + ax.axvspan(*adapt_w, color=C["groundwater"], alpha=0.12, lw=0) + ax.set( xlabel="lapse time (s)", ylabel="coda envelope (norm.)", ylim=(1e-3, 2), - title="(a) high-frequency coda decays first", - ) - axA.legend(loc="upper right", fontsize=8.5) - axA.text(30, 1.1e-3, "fixed 20–40 s\n= noise here", color=C["bad"], fontsize=8) - axB.plot(_yrs(days), truth * PCT, color=C["truth"], lw=2.4, label="truth") - axB.plot( - _yrs(days), - hi_fixed * PCT, - color=C["bad"], - lw=1.0, - alpha=0.9, - label="high band, fixed 20–40 s window", + title="High-frequency coda\ndecays first", ) - axB.plot( - _yrs(days), - hi_adapt * PCT, - color=C["groundwater"], - lw=1.0, - alpha=0.9, - label="high band, adapted 3–12 s window", + ax.legend( + fontsize=12, + loc="upper center", + bbox_to_anchor=(0.5, -0.16), + ncol=3, + frameon=False, ) - axB.set( - xlabel="time (years)", - ylabel="dv/v (%)", - title="(b) low-band window at high band -> noise", - ) - leg = axB.legend(loc="lower left", fontsize=8.5, frameon=True) - leg.get_frame().set(facecolor="white", alpha=0.9, edgecolor="0.7") + ax.text(28, 1.4e-3, "fixed 20–40 s\n= noise here", color=C["bad"], fontsize=11) + _boost_fonts(ax, tick=12, label=13.5, title=14) fig.tight_layout() return fig @@ -1727,7 +1868,7 @@ def fig_window_envelope(seed: int = 71): truth = _seasonal(days, 0.0015, 60) windows, rms_fixed, rms_adapt = [], [], [] - fig, (axA, axB) = plt.subplots(1, 2, figsize=(6.9, 3.6)) + fig, (axA, axB) = plt.subplots(1, 2, figsize=(8.6, 4.6)) m = tf >= 0 for band, lab, col in zip(bands, band_labels, band_cols, strict=True): t1, t2 = coda_window_from_envelope(tf, ref_stack, fs, band) @@ -1753,7 +1894,7 @@ def fig_window_envelope(seed: int = 71): ylim=(1e-3, 2), title="(a) window shrinks with frequency", ) - axA.legend(loc="upper right", fontsize=8) + axA.legend(loc="upper right", fontsize=13) x = np.arange(len(bands)) w = 0.35 @@ -1774,8 +1915,9 @@ def fig_window_envelope(seed: int = 71): ylabel="RMS error vs truth (dv/v, %, log)", title="(b) fixed window fails at high band", ) - axB.tick_params(axis="x", labelsize=7.5, rotation=15) - axB.legend(loc="upper left", fontsize=8) + axB.tick_params(axis="x", labelsize=13, rotation=15) + axB.legend(loc="upper left", fontsize=13) + _boost_fonts(axA, axB, tick=13, label=15, title=16) fig.tight_layout() return fig @@ -1789,7 +1931,7 @@ def fig_stacking(seed: int = 22): truth = earthquake_truth(days) ccfs = daily_ccfs(s.t, [s.ref], [truth], fs=s.fs, snr=4.0, seed=seed) band, window = (0.5, 2.0), (8.0, 40.0) - fig, ax = plt.subplots(figsize=(5.8, 3.8)) + fig, ax = plt.subplots(figsize=(4.0, 3.0)) ax.plot(_yrs(days), truth * PCT, color=C["truth"], lw=2.4, label="ground truth") for k, col in [(1, C["bad"]), (10, C["earthquake"]), (45, C["alt"])]: rec, _ = measure_stretching( @@ -1803,7 +1945,14 @@ def fig_stacking(seed: int = 22): ylabel="dv/v (%)", title="Stack length trades noise vs coseismic-step sharpness", ) - ax.legend(loc="lower left") + ax.legend( + fontsize=12, + loc="upper center", + bbox_to_anchor=(0.5, -0.16), + ncol=4, + frameon=False, + ) + _boost_fonts(ax, tick=12, label=14, title=14.5) fig.tight_layout() return fig @@ -1827,7 +1976,7 @@ def fig_reference(seed: int = 33): rec_inv = measure_inversion( ccfs, s.t, band=band, fs=s.fs, window=window, block_days=10 ) - fig, ax = plt.subplots(figsize=(5.8, 3.8)) + fig, ax = plt.subplots(figsize=(4.0, 3.0)) ax.plot(_yrs(days), truth * PCT, color=C["truth"], lw=2.4, label="ground truth") ax.plot( _yrs(days), @@ -1835,29 +1984,36 @@ def fig_reference(seed: int = 33): color="0.6", lw=0.9, alpha=0.8, - label="total-stack reference (noisy)", + label="fixed reference", ) ax.plot( _yrs(days), rec_move * PCT, color=C["bad"], lw=1.4, - label="60-day moving reference (trend erased)", + label="60-day moving ref.", ) ax.plot( _yrs(days), rec_inv * PCT, color=C["groundwater"], lw=1.8, - label="Brenguier 2014 inversion (keeps trend)", + label="joint inversion", ) ax.axvline(2.0, color="0.6", ls="--", lw=1) ax.set( xlabel="time (years)", ylabel="dv/v (%)", - title="Reference strategy: moving reference erases the trend", + title="Uncumulated moving reference removes the trend", ) - ax.legend(loc="lower left", fontsize=8.5) + ax.legend( + fontsize=12, + loc="upper center", + bbox_to_anchor=(0.5, -0.16), + ncol=4, + frameon=False, + ) + _boost_fonts(ax, tick=12, label=14, title=13.5) fig.tight_layout() return fig @@ -1903,7 +2059,8 @@ def fig_artifacts(seed: int = 77): ylabel="apparent dv/v (%)", title="(a) clock drift splits the branches", ) - axA.legend(loc="upper left", fontsize=8.5) + leg = axA.legend(loc="upper left", fontsize=10.5, frameon=True) + leg.get_frame().set(facecolor="white", alpha=0.9, edgecolor="0.7") axB.plot(_yrs(days2), truth2 * PCT, color=C["truth"], lw=2.2, label="truth") axB.plot( _yrs(days2), @@ -1926,8 +2083,9 @@ def fig_artifacts(seed: int = 77): ylabel="dv/v (%)", title="(b) late-coda noise -> spurious cycle", ) - leg = axB.legend(loc="lower left", fontsize=8.5, frameon=True) + leg = axB.legend(loc="lower left", fontsize=10.5, frameon=True) leg.get_frame().set(facecolor="white", alpha=0.9, edgecolor="0.7") + _boost_fonts(axA, axB, tick=10.5, label=12, title=13) fig.tight_layout() return fig @@ -1956,13 +2114,13 @@ def fig_frequency_depth(seed: int = 44): rec_lo, _ = measure_stretching( ccfs, ref_lo + ref_hi, s.t, band=(0.2, 0.8), fs=s.fs, window=(12.0, 45.0) ) - fig, ax = plt.subplots(figsize=(5.8, 3.8)) + fig, ax = plt.subplots(figsize=(4.6, 3.4)) ax.plot( _yrs(days), shallow * PCT, color=C["truth"], lw=2.2, - label="truth — shallow (seasonal)", + label="truth: shallow", ) ax.plot( _yrs(days), @@ -1970,7 +2128,7 @@ def fig_frequency_depth(seed: int = 44): color="0.55", lw=2.2, ls="--", - label="truth — deep (drought trend)", + label="truth: deep", ) ax.plot( _yrs(days), @@ -1978,7 +2136,7 @@ def fig_frequency_depth(seed: int = 44): color=C["groundwater"], lw=1.4, alpha=0.9, - label="high band 1.5-6 Hz -> shallow", + label="high band -> shallow", ) ax.plot( _yrs(days), @@ -1986,14 +2144,262 @@ def fig_frequency_depth(seed: int = 44): color=C["alt"], lw=1.4, alpha=0.9, - label="low band 0.2-0.8 Hz -> deep", + label="low band -> deep", ) ax.set( xlabel="time (years)", ylabel="dv/v (%)", - title="Frequency band selects depth — and a different signal", + title="Frequency band selects depth,\nand a different signal", ) - ax.legend(loc="lower left", ncol=2, fontsize=8.5) + ax.legend( + fontsize=11, + loc="upper center", + bbox_to_anchor=(0.5, -0.16), + ncol=2, + frameon=False, + ) + _boost_fonts(ax, tick=12, label=14, title=13.5) + fig.tight_layout() + return fig + + +def fig_band_sensitivity(seed: int = 141): + """Frequency band: RMS against truth as a continuous function of band mismatch. + + Reuses the two-layer groundwater synthetic of :func:`fig_frequency_depth` + (same ccfs, same components) but instead of the two named "shallow" vs + "deep" bands, sweeps the recovery band's center frequency continuously + across and past the true deep-layer band (0.2-0.8 Hz, center 0.5 Hz, + width 0.6 Hz held fixed) and scores each against the deep-layer truth -- + a dose-response curve instead of a single matched/mismatched anecdote. + """ + s = Synth() + days = _days(3.0) + shallow, deep = groundwater_truth(days) + _, ref_lo = make_coda(maxlag_s=s.maxlag_s, fs=s.fs, band=(0.2, 0.8), seed=4) + _, ref_hi = make_coda(maxlag_s=s.maxlag_s, fs=s.fs, band=(1.5, 6.0), seed=5) + ccfs = daily_ccfs( + s.t, + [ref_lo, ref_hi], + [deep, shallow], + fs=s.fs, + snr=12.0, + gen_band=(0.1, 8.0), + seed=seed, + ) + true_center, half_width, window = 0.5, 0.3, (12.0, 45.0) + centers = np.array([0.35, 0.5, 0.65, 0.8, 1.0, 1.25, 1.5, 1.75, 2.0]) + rms = np.empty_like(centers) + for i, c in enumerate(centers): + band = (max(0.05, c - half_width), c + half_width) + rec, _ = measure_stretching( + ccfs, ref_lo + ref_hi, s.t, band=band, fs=s.fs, window=window + ) + v = np.isfinite(rec) + rms[i] = float(np.sqrt(np.mean((rec[v] - deep[v]) ** 2))) * PCT + + import matplotlib.pyplot as plt + + fig, ax = plt.subplots(figsize=(6.6, 4.3)) + ax.plot(centers - true_center, rms, "o-", color=C["groundwater"], lw=2.2, ms=7) + ax.axvline(0, color="0.6", ls="--", lw=1.2, label="true band center") + ax.set( + xlabel=r"band-center offset from the true band, $\Delta f$ (Hz)", + ylabel="RMS error vs truth (dv/v, %)", + title="RMS is flat within the layer's band, then rises sharply past its edge", + ) + _boost_fonts(ax, tick=14, label=16, title=17.5) + ax.legend(fontsize=14) + fig.tight_layout() + return fig + + +def fig_reference_schemes(seed: int = 142): + """Reference construction: five named schemes, plus a continuous + moving-reference length sweep, on the volcano synthetic. + + Compares a reference built from the beginning, the end, or the whole of + the pre-eruptive record, a moving (trailing) reference, and no reference + at all (Brenguier et al. 2014-style joint inversion). Reports both the + whole-record RMS and the RMS restricted to the pre-eruptive ramp (the + slow trend this axis is really about preserving or erasing). + """ + s = Synth() + days = _days(3.0) + truth = volcano_truth(days) + ccfs = daily_ccfs(s.t, [s.ref], [truth], fs=s.fs, snr=6.0, seed=seed) + band, window = (0.5, 2.0), (8.0, 40.0) + erupt = int(2.0 * YEAR_D) + n_edge = int(0.15 * erupt) # beginning/end reference: earliest/latest 15% + ramp_sel = (days >= erupt - 200) & (days < erupt) + + def _rms(rec, sel=None): + m = np.isfinite(rec) + if sel is not None: + m = m & sel + return float(np.sqrt(np.mean((rec[m] - truth[m]) ** 2))) * PCT + + schemes: dict[str, np.ndarray] = {} + rec, _ = measure_stretching( + ccfs, ccfs[:n_edge].mean(axis=0), s.t, band=band, fs=s.fs, window=window + ) + schemes["beginning\n(15%)"] = rec + rec, _ = measure_stretching( + ccfs, + ccfs[erupt - n_edge : erupt].mean(axis=0), + s.t, + band=band, + fs=s.fs, + window=window, + ) + schemes["end\n(15%)"] = rec + rec, _ = measure_stretching( + ccfs, ccfs[:erupt].mean(axis=0), s.t, band=band, fs=s.fs, window=window + ) + schemes["whole"] = rec + schemes["moving\n(60 d)"] = measure_stretching_moving( + ccfs, s.t, band=band, fs=s.fs, window=window, ref_days=60 + ) + schemes["no ref.\n(inversion)"] = measure_inversion( + ccfs, s.t, band=band, fs=s.fs, window=window, block_days=10 + ) + + names = list(schemes) + rms_whole = [_rms(schemes[n]) for n in names] + rms_ramp = [_rms(schemes[n], ramp_sel) for n in names] + + ref_days_grid = np.array([10, 20, 30, 45, 60, 90, 120, 180, 240]) + rms_moving = np.array( + [ + _rms( + measure_stretching_moving( + ccfs, s.t, band=band, fs=s.fs, window=window, ref_days=int(rd) + ) + ) + for rd in ref_days_grid + ] + ) + + import matplotlib.pyplot as plt + + fig, (axA, axB) = plt.subplots(1, 2, figsize=(10.6, 4.9)) + x = np.arange(len(names)) + w = 0.38 + axA.bar(x - w / 2, rms_whole, width=w, color=C["alt"], label="whole record") + axA.bar( + x + w / 2, rms_ramp, width=w, color=C["bad"], label="pre-eruptive ramp only" + ) + axA.set_yscale("log") + axA.set( + xticks=x, + ylabel="RMS error vs truth (dv/v, %, log)", + title="(a) five reference schemes", + ) + axA.set_xticklabels(names, fontsize=16) + axA.tick_params(axis="y", labelsize=16) + axA.yaxis.label.set_size(18) + axA.title.set_size(20) + lo, hi = axA.get_ylim() + axA.set_ylim(lo, hi * 2.8) # headroom so the legend clears the tallest bars + axA.legend(fontsize=16, loc="upper left") + + axB.plot(ref_days_grid, rms_moving, "o-", color=C["bad"], lw=2.2, ms=6) + axB.axhline( + rms_whole[names.index("whole")], + color="0.55", + ls="--", + lw=1.2, + label="whole-record reference", + ) + axB.set( + xlabel="moving-reference length (days)", + ylabel="RMS error vs truth (dv/v, %)", + title="(b) a longer trailing window helps,\nbut never converges", + ) + _boost_fonts(axB, tick=16, label=18, title=20) + axB.legend(fontsize=16) + fig.tight_layout() + return fig + + +def fig_stack_coherence(seed: int = 143): + """Substacking: the practitioner's actual stopping rule -- stack until the + coda's coherence (correlation coefficient) crosses a working threshold -- + rather than an arbitrary day count. Uses the same CC-gate threshold + (0.6) already hardcoded in :func:`codameter.deviations.run_pipeline`. + + Two SNR levels on the earthquake synthetic: a poor, coherence-limited + deployment (snr=0.5) versus the paper's own noisy-but-workable baseline + (snr=4.0, the same value :func:`fig_stacking` uses). + """ + s = Synth() + days = _days(3.0) + truth = earthquake_truth(days) + band, window = (0.5, 2.0), (8.0, 40.0) + eq = int(1.5 * YEAR_D) + stack_days = np.array([1, 2, 3, 5, 7, 10, 14, 21, 30, 45, 60]) + cc_threshold = 0.6 + + def _step_bias(dvv, valid): + pre = (days < eq) & (days > eq - 120) & valid + post = (days >= eq) & (days < eq + 120) & valid + if pre.sum() < 3 or post.sum() < 3: + return np.nan + rec_drop = np.nanmin(dvv[post]) - np.nanmedian(dvv[pre]) + true_drop = np.nanmin(truth[post]) - np.nanmedian(truth[pre]) + return float(rec_drop - true_drop) + + import matplotlib.pyplot as plt + + fig, (axA, axB) = plt.subplots(1, 2, figsize=(11.0, 5.0)) + for snr, col, lab in [ + (0.5, C["bad"], "SNR 0.5 (poor)"), + (4.0, C["earthquake"], "SNR 4 (workable)"), + ]: + ccfs = daily_ccfs(s.t, [s.ref], [truth], fs=s.fs, snr=snr, seed=seed) + med_cc, rms, bias = [], [], [] + for k in stack_days: + rec, cc = measure_stretching( + _trailing_stack(ccfs, int(k)), + s.ref, + s.t, + band=band, + fs=s.fs, + window=window, + ) + v = np.isfinite(rec) + med_cc.append(float(np.nanmedian(cc[v]))) + rms.append(float(np.sqrt(np.mean((rec[v] - truth[v]) ** 2))) * PCT) + bias.append(_step_bias(rec, v) * PCT) + axA.plot(stack_days, med_cc, "o-", color=col, lw=2.2, ms=6, label=lab) + axB.plot(stack_days, rms, "o-", color=col, lw=2.2, ms=6, label=f"{lab}: RMS") + axB.plot( + stack_days, + np.abs(bias), + "s--", + color=col, + lw=1.6, + ms=5, + alpha=0.8, + label=f"{lab}: |bias|", + ) + axA.axhline(cc_threshold, color="0.35", ls="--", lw=1.4, label="CC gate (0.6)") + axA.set( + xlabel="stack length (days)", + ylabel="median stretching CC", + title="(a) coherence rises with stack length", + ) + leg = axA.legend(fontsize=16, loc="lower right", frameon=True) + leg.get_frame().set(facecolor="white", alpha=0.9, edgecolor="0.7") + axB.set_yscale("log") + axB.set( + xlabel="stack length (days)", + ylabel="dv/v error (%, log)", + title="(b) noise floor vs step-smearing tradeoff", + ) + leg = axB.legend(fontsize=14, loc="lower left", ncol=1, frameon=True) + leg.get_frame().set(facecolor="white", alpha=0.9, edgecolor="0.7") + _boost_fonts(axA, axB, tick=16, label=18, title=20) fig.tight_layout() return fig @@ -2154,8 +2560,13 @@ def fig_branch_asymmetry(seed: int = 131): yr, truth_c * PCT, color=C["truth"], lw=2.2, ls="--", label="truth (structural)" ) axA.set(xlabel="time (years)", ylabel="dv/v (%)", title="(a) one-sided change") - leg = axA.legend(loc="lower left", fontsize=7.5, frameon=True) - leg.get_frame().set(facecolor="white", alpha=0.9, edgecolor="0.7") + axA.legend( + fontsize=10.5, + loc="upper center", + bbox_to_anchor=(0.5, -0.16), + ncol=2, + frameon=False, + ) axB.axhline( truth_h * PCT, color=C["truth"], lw=2.0, label="true drop (both branches)" @@ -2180,7 +2591,8 @@ def fig_branch_asymmetry(seed: int = 131): ) axB.set_xticks(snrs) axB.set_xticklabels([f"{v:g}" for v in snrs]) - axB.legend(loc="lower right", fontsize=8) + axB.legend(loc="lower right", fontsize=10.5) + _boost_fonts(axA, axB, tick=10.5, label=12, title=13) fig.tight_layout() return fig @@ -2198,6 +2610,9 @@ def fig_branch_asymmetry(seed: int = 131): "demo_8_artifacts": fig_artifacts, "demo_9_multiverse": fig_multiverse, "demo_13_branch_asymmetry": fig_branch_asymmetry, + "demo_16_band_sensitivity": fig_band_sensitivity, + "demo_17_reference_schemes": fig_reference_schemes, + "demo_18_stack_coherence": fig_stack_coherence, } diff --git a/src/codameter/uq_bayes.py b/src/codameter/uq_bayes.py index d202852..663a677 100644 --- a/src/codameter/uq_bayes.py +++ b/src/codameter/uq_bayes.py @@ -1,60 +1,45 @@ -r"""A Bayesian measurement model for :math:`\delta v/v` — the *new* best practice. - -The deviation/multiverse experiments (:mod:`codameter.deviations`) show that the -processing choice, not the data, often controls a :math:`\delta v/v` estimate. -The honest response is not to crown one pipeline but to treat the choice as a -**nuisance parameter** with a prior, run an ensemble of defensible pipelines, and -*marginalise* the choice out. This module does exactly that, as a Bayesian -hierarchical inversion. - -Model ------ -For configuration :math:`k` (an estimator/band/window/stack/reference choice -drawn from a prior over defensible pipelines) we obtain a measured series -:math:`m_k(t)` with a coherence-limited within-method standard error -:math:`\sigma_k(t)` (Weaver/Clarke; :func:`codameter.uq_measurement.weaver_stretching_error`). -We posit - -.. math:: - m_k(t) = \mu(t) + \beta_k + \varepsilon_k(t), - \qquad - \beta_k \sim \mathcal N(0,\tau^2), - \quad - \varepsilon_k(t) \sim \mathcal N\!\big(0,\, s^2\,\sigma_k(t)^2\big), - -with a smoothness (2nd-difference random-walk) prior of precision :math:`\lambda` -on the latent true series :math:`\mu(t)`. Here :math:`\beta_k` is the -configuration's **methodological bias** (e.g. the systematic MWCS-vs-stretching -offset), :math:`\tau^2` its variance across the ensemble, and :math:`s^2` -rescales the Weaver floor so the data tell us whether it is calibrated. - -The posterior is sampled by a conjugate **Gibbs sampler** (pure NumPy, no -external sampler). Its two deliverables are - -1. the marginal posterior :math:`p(\mu(t)\mid\{m_k\})` — a single - :math:`\delta v/v` series with an uncertainty that *includes* the - processing-choice spread; and -2. the **data covariance** :math:`C_d = \operatorname{Cov}(\mu\mid\text{data})` - — a full, time-dependent :math:`T\times T` matrix, exactly the object a - downstream depth/stress inversion (:mod:`codameter.inverse`) should consume - instead of a diagonal ``dvv_err``. Its time dependence is real: the posterior - is wider where the ensemble disagrees (sharp transients, low coherence) and - its off-diagonals encode the temporal correlation the smoothness and the - shared methodological bias induce. +r"""A working Bayesian model for an ensemble of dv/v processing outputs. + +The likelihood is ``m_k(t) = mu(t) + beta_k + epsilon_k(t)``, with normal +configuration offsets of variance ``tau**2`` and conditionally independent +residuals of variance ``s**2 * sigma_k(t)**2``. ``sigma_k`` is the Weaver +floor. A second-difference prior on the physical time grid smooths ``mu``; +missing observations carry zero precision. + +All configurations reuse the same waveform data. Conditional independence is +therefore a working assumption, not an established property. Jointly fitting +these outputs is not discrete mixture marginalization over pipelines. + +``mu_cov`` and the credible band describe the combined estimate under that +likelihood. ``Cd`` is constructed separately from the fitted floor, excess +configuration spread, a fitted exponential temporal correlation, and a rank-one +term using ``tau``. It targets a randomly selected member's error, not the +combined estimate. Between-configuration offsets cannot identify common bias. + +Repeated waveform realizations give near-nominal 95 percent pointwise member +coverage, but 68 percent intervals overcover and the combined estimate's +credible band undercovers. These checks do not validate temporal covariance, +cross-band covariance, or downstream inversion intervals. See +:mod:`codameter.calibration` and the manuscript's calibration table. """ + from __future__ import annotations +import warnings from dataclasses import dataclass import numpy as np +from scipy.linalg import cho_solve_banded, cholesky_banded, solve_banded +from scipy.sparse import coo_matrix from .uq_measurement import ( effective_sample_size, temporal_error_covariance, - weaver_stretching_error, + weaver_stretching_error_band, ) __all__ = [ + "MIN_COHERENCE", "default_prior", "run_processing_ensemble", "BayesResult", @@ -62,6 +47,10 @@ "bayes_dvv_from_ccfs", ] +#: Peak stretching coherence below which an epoch has no usable Weaver floor +#: and is treated as missing in the ensemble (not clipped to a fixed floor). +MIN_COHERENCE = 0.5 + # --------------------------------------------------------------------------- # A prior over defensible processing configurations. @@ -105,58 +94,92 @@ class EnsembleRun: def run_processing_ensemble( - ccfs, t, fs, prior, *, cadence=3, years=2.5, truth=None, days=None + ccfs, t, fs, prior, *, cadence=3, years=2.5, truth=None, days=None, eps_max=0.06 ): - """Measure dv/v for every configuration in ``prior`` on shared CCFs. - - The within-method floor :math:`\\sigma_k(t)` is computed from the *coherence* - (peak stretching CC for the band/window of the configuration, a property of - the data and window, not of the estimator) via the Weaver/Clarke formula, so - the floor tracks the time-varying SNR. + """Measure dv/v for every configuration in ``prior`` on shared daily CCFs. + + Every configuration runs through the canonical pipeline + (:func:`codameter.deviations.run_pipeline`), so ``estimator``, ``band``, + ``window``, ``stack`` (in days), ``reference`` (``"fixed"`` or + ``"moving"``) and ``gate`` all take effect. Epochs a configuration does not + produce (reference warm-up, gated coherence) are NaN in ``members`` and are + treated as missing by :func:`gibbs_dvv`. Stacking happens on the daily grid + and only the *output* is decimated by ``cadence``, so a 10-day stack is ten + days at any cadence. (Before the 2026-09 revision the CCFs were decimated + first, which silently stretched stack and reference durations, and + ``reference`` and ``gate`` were ignored; audit UQ-05.) + + The within-method floor :math:`\\sigma_k(t)` comes from the peak stretching + coherence for the configuration's band, window, stack and reference (a + property of the data and window, not of the estimator) through the Weaver + floor. Coherence below :data:`MIN_COHERENCE` gives a NaN floor and the + epoch is missing rather than clipped. ``reference="inversion"`` has no + per-epoch coherence and is rejected. Input CCF rows must form a complete + daily grid; irregular already-measured series can be passed to ``gibbs_dvv``. """ - from .synthetic_demo import _trailing_stack, measure, peak_dvv, stretching_cc - - if days is None: - days = np.arange(ccfs.shape[0]) - idx = np.arange(0, ccfs.shape[0], cadence) - ccfs_s, days_s = ccfs[idx], days[idx] - truth_s = None if truth is None else np.asarray(truth)[idx] + from .deviations import run_pipeline + + ccfs = np.asarray(ccfs, float) + n = ccfs.shape[0] + days_arr = np.arange(n, dtype=float) if days is None else np.asarray(days, float) + if days_arr.shape != (n,): + raise ValueError("days must have one entry per CCF row") + if not np.isfinite(days_arr).all() or not np.allclose( + np.diff(days_arr), 1.0, rtol=0.0, atol=1e-8 + ): + raise ValueError( + "CCFs must be on a complete daily grid for day-based stacking; " + "gibbs_dvv accepts irregular times for already measured series" + ) + if not isinstance(cadence, int | np.integer) or cadence < 1: + raise ValueError("cadence must be a positive integer") + idx = np.arange(0, n, cadence) + truth_s = None if truth is None else np.asarray(truth, float)[idx] labels, members, sigmas = [], [], [] - for cfg in prior: - band, win, k = cfg["band"], cfg["window"], cfg["stack"] - stacked = _trailing_stack(ccfs_s, k) - ref = ccfs_s[: int(0.6 * len(ccfs_s))].mean(axis=0) - # Coherence (and dv/v if stretching) from the stretching CC image. - es, cc_img = stretching_cc( - stacked, ref, t, band=band, fs=fs, window=win, eps_max=0.06 + for raw in prior: + cfg = dict(raw) + cfg.setdefault("reference", "fixed") + cfg.setdefault("gate", False) + if cfg["reference"] not in ("fixed", "moving"): + raise ValueError( + f"reference={cfg['reference']!r} is not supported by the Bayesian " + "ensemble: it has no per-epoch coherence for the Weaver floor" + ) + band, win = tuple(cfg["band"]), tuple(cfg["window"]) + # Coherence (and dv/v for stretching) from the stretching pipeline at + # the same band / window / stack / reference / gate. + probe = dict(cfg, estimator="stretching (TS)") + dvv_ts, valid_ts, cc = run_pipeline( + ccfs, t, fs, probe, eps_max=eps_max, return_cc=True ) - dvv_ts, cc_peak = peak_dvv(es, cc_img) if cfg["estimator"] == "stretching (TS)": - dvv = dvv_ts + dvv, valid = dvv_ts, valid_ts else: - extra = {"eps_max": 0.06} if cfg["estimator"] == "WTS" else {} - dvv = np.atleast_1d( - measure( - cfg["estimator"], - stacked, - ref, - t, - band=band, - fs=fs, - window=win, - **extra, - ) + dvv, valid = run_pipeline(ccfs, t, fs, cfg, eps_max=eps_max) + if cfg["gate"]: + # The legacy pipeline gates fixed-reference stretching only. + # Apply the same observed-coherence threshold to every ensemble + # estimator and reference, including moving-reference estimates. + valid = valid & valid_ts & np.isfinite(cc) & (cc > 0.6) + dvv = np.where(valid, np.asarray(dvv, float), np.nan) + cc = np.asarray(cc, float) + ok = np.isfinite(cc) & (cc >= MIN_COHERENCE) + sig = np.full(n, np.nan) + if ok.any(): + sig[ok] = weaver_stretching_error_band( + np.minimum(cc[ok], 0.999), band, win[0], win[1] ) - fc = float(np.mean(band)) - sig = weaver_stretching_error(np.clip(cc_peak, 0.5, 0.999), fc, win[0], win[1]) labels.append( - f"{cfg['estimator']} {band[0]:g}-{band[1]:g}Hz {win[0]:g}-{win[1]:g}s" + f"{cfg['estimator']} {band[0]:g}-{band[1]:g}Hz {win[0]:g}-{win[1]:g}s " + f"stack{cfg['stack']}d {cfg['reference']}{' gated' if cfg['gate'] else ''}" ) - members.append(np.asarray(dvv, float)) - sigmas.append(np.asarray(sig, float)) + members.append(dvv[idx]) + sigmas.append(sig[idx]) - return EnsembleRun(labels, np.vstack(members), np.vstack(sigmas), days_s, truth_s) + return EnsembleRun( + labels, np.vstack(members), np.vstack(sigmas), days_arr[idx], truth_s + ) # --------------------------------------------------------------------------- @@ -175,25 +198,48 @@ class BayesResult: Central 95% credible band on :math:`\mu` (the *estimator* precision). mu_cov : np.ndarray (T, T) Posterior covariance :math:`\operatorname{Cov}(\mu\mid\text{data})` — the - uncertainty of the *combined* estimate. It shrinks with ensemble size and - is **not** the object to propagate downstream. + model-conditional uncertainty of the *combined* estimate. It shrinks + with ensemble size under the working likelihood, but does not include + shared model error. Its downstream use requires separate calibration. Cd : np.ndarray (T, T) - The **marginal measurement covariance** to hand a downstream depth/stress - inversion: per-epoch total error (within-method ⊕ methodological) with an - exponential temporal correlation (length ``corr_length_days``) and a - common-mode floor ``tau`` (the constant-in-time methodological bias that - averaging cannot remove). Time-dependent by construction — wider where the - ensemble disagrees. + A **constructed single-member error covariance**: :math:`C_d = D R D + \tau^2 \mathbf{1}\mathbf{1}^T` + with :math:`D = \operatorname{diag}(\text{total\_std})`, an exponential + temporal correlation of length ``corr_length_days`` fitted to the + ensemble residuals, and the common-mode scale ``tau``. It is derived + from the fitted model, not sampled, and it cannot represent an error + that every configuration shares (a common source or clock artefact + moves all members together and leaves no trace in their spread; see + ``tests/test_uq_bayes.py::test_shared_artifact_is_not_detected``). tau, s : float - Posterior-mean methodological common-mode bias scale and Weaver-floor - rescale. + Square root of posterior-mean variance of the per-configuration offsets :math:`\beta_k` + and of the Weaver-floor rescale. corr_length_days : float Temporal correlation length estimated from the ensemble residuals. n_eff : float Effective number of independent epochs implied by ``Cd``. total_std, method_std, within_std : np.ndarray (T,) - Per-epoch total / methodological / within-method standard deviations - (``total_std`` is the diagonal scale of ``Cd`` before the common mode). + Per-epoch decomposition of the diagonal of ``D``: + ``within_std**2 = s**2 * mean_k sigma_k(t)**2`` (calibrated floor over + the configurations observed at ``t``); ``method_std**2`` is the + between-configuration variance of ``m_k(t) - beta_k`` *minus* the + within-method variance, floored at zero, so within-method noise is not + counted twice and the constant offsets are carried by ``tau`` instead + (audit UQ-03/04); ``total_std**2`` is their sum, i.e. the larger of the + observed spread and the calibrated floor. Epochs with fewer than two + observed configurations take the median over time. + beta_mean : np.ndarray (K,) + Posterior-mean configuration offsets. + n_obs : np.ndarray (T,) + Number of configurations observed (finite member and floor) per epoch. + prior_weight : dict + Prior scale contribution to each conditional posterior rate, evaluated + at the posterior means. This is not the total influence of the prior: + ``b0 / (b0 + 0.5 * sum(beta**2))`` for tau^2, + ``b0 / (b0 + 0.5 * sum(resid**2 / sigma**2))`` for s^2, and + ``lam_b / (lam_b + 0.5 * sum((D mu)**2))`` for lambda. Small values + mean the prior rate term is small. The shape parameters and + smoothness assumptions can still matter; this is not a convergence + diagnostic or a substitute for prior sensitivity checks. samples_mu : np.ndarray (n_keep, T) """ @@ -211,6 +257,9 @@ class BayesResult: method_std: np.ndarray within_std: np.ndarray samples_mu: np.ndarray + beta_mean: np.ndarray | None = None + n_obs: np.ndarray | None = None + prior_weight: dict[str, float] | None = None def _estimate_corr_length(residuals: np.ndarray, times_days: np.ndarray) -> float: @@ -221,15 +270,18 @@ def _estimate_corr_length(residuals: np.ndarray, times_days: np.ndarray) -> floa configurations. Returns ``L`` in days. """ R = np.asarray(residuals, float) - R = R - R.mean(axis=1, keepdims=True) - K, T = R.shape - var = np.mean(R**2, axis=1, keepdims=True) - maxlag = min(T - 1, 40) - rho = np.zeros(maxlag + 1) - for lag in range(maxlag + 1): - c = np.mean(R[:, : T - lag] * R[:, lag:], axis=1, keepdims=True) / (var + 1e-30) - rho[lag] = np.mean(c) - rho = np.clip(rho, 1e-3, 1.0) + with warnings.catch_warnings(): + warnings.simplefilter("ignore", RuntimeWarning) # all-NaN rows/lags + R = R - np.nanmean(R, axis=1, keepdims=True) + K, T = R.shape + var = np.nanmean(R**2, axis=1, keepdims=True) + maxlag = min(T - 1, 40) + rho = np.zeros(maxlag + 1) + for lag in range(maxlag + 1): + prod = R[:, : T - lag] * R[:, lag:] + c = np.nanmean(prod, axis=1, keepdims=True) / (var + 1e-30) + rho[lag] = np.nanmean(c) + rho = np.clip(np.nan_to_num(rho, nan=1e-3), 1e-3, 1.0) dt = float(np.median(np.diff(times_days))) if T > 1 else 1.0 lags_days = np.arange(maxlag + 1) * dt # Linear fit of log(rho) vs lag (weight early, well-determined lags). @@ -241,18 +293,59 @@ def _estimate_corr_length(residuals: np.ndarray, times_days: np.ndarray) -> floa def _second_difference(T: int) -> np.ndarray: - """(T-2)xT second-difference operator for the random-walk smoothness prior.""" + """(T-2)xT second-difference operator on a regular grid (dense; tests).""" D = np.zeros((T - 2, T)) for k in range(T - 2): D[k, k : k + 3] = (1.0, -2.0, 1.0) return D +def second_difference_operator(times_days): + r"""Sparse ``(T-2) x T`` second-difference operator on an irregular grid. + + Row :math:`k` approximates :math:`h_0^2\,\mu''(t_k)\sqrt{\bar h_k/h_0}` from the + three points :math:`t_{k-1}, t_k, t_{k+1}` with intervals + :math:`h_l, h_r` and :math:`\bar h_k = (h_l + h_r)/2`, where :math:`h_0` is + the median interval. On a regular grid this is exactly ``[1, -2, 1]``, so + the smoothness precision :math:`\lambda` keeps its meaning; across a gap + the curvature penalty scales with the physical spacing instead of the + sample index (audit UQ-05: a 1000-day gap used to be invisible to the + prior). + """ + t = np.asarray(times_days, float) + T = t.size + if T < 3: + raise ValueError("need at least three epochs") + h = np.diff(t) + if np.any(h <= 0): + raise ValueError("times_days must be strictly increasing") + h0 = float(np.median(h)) + hl, hr = h[:-1], h[1:] + scale = h0**2 * np.sqrt((hl + hr) / (2.0 * h0)) + c0 = scale * 2.0 / (hl * (hl + hr)) + c1 = -scale * 2.0 / (hl * hr) + c2 = scale * 2.0 / (hr * (hl + hr)) + rows = np.repeat(np.arange(T - 2), 3) + cols = (np.arange(T - 2)[:, None] + np.arange(3)[None, :]).ravel() + vals = np.stack([c0, c1, c2], axis=1).ravel() + return coo_matrix((vals, (rows, cols)), shape=(T - 2, T)).tocsr() + + +def _fill_nan(x: np.ndarray, t: np.ndarray) -> np.ndarray: + ok = np.isfinite(x) + if ok.all(): + return x + if not ok.any(): + return np.zeros_like(x) + return np.asarray(np.interp(t, t[ok], x[ok]), float) + + def gibbs_dvv( members, within_sigma, times_days, *, + solver: str = "banded", n_iter=1500, burn=500, thin=2, @@ -267,63 +360,109 @@ def gibbs_dvv( Parameters ---------- members : (K, T) - Ensemble of measured dv/v series. + Ensemble of measured dv/v series. NaN marks an epoch a configuration + did not produce; it carries no information (zero precision). within_sigma : (K, T) - Per-configuration within-method standard errors (Weaver floor). + Per-configuration within-method standard errors (Weaver floor). NaN or + non-positive entries also mark the observation as missing. times_days : (T,) + Strictly increasing epoch times. The smoothness prior is built on this + grid (:func:`second_difference_operator`), so gaps are physical. + solver + ``"banded"`` (default, O(T) per sweep) or ``"dense"`` (explicit + matrices, for equivalence tests). n_iter, burn, thin Total sweeps, burn-in, and thinning. a0, b0, lam_a, lam_b - InvGamma/Gamma hyper-priors for :math:`\tau^2, s^2` and the smoothness - precision :math:`\lambda` (weakly informative). + InvGamma/Gamma hyper-priors for tau^2, s^2 and the smoothness precision + lambda. ``b0`` is a scale in the units of the quantity: it is negligible + only when it is small against the data term (``0.5 * sum(beta**2)`` for + tau^2, of order ``K * offset**2``; ``0.5 * sum(resid**2 / sigma**2)`` + for s^2, of order ``K * T``). The result reports the actual prior share + in ``prior_weight``; with the defaults and a few configurations whose + offsets are ~1e-4, the tau^2 share is a few percent. See + ``tests/test_uq_bayes.py::test_prior_sensitivity``. """ rng = np.random.default_rng(seed) M = np.asarray(members, float) - S2 = np.clip(np.asarray(within_sigma, float), 1e-9, None) ** 2 + S = np.asarray(within_sigma, float) + if M.ndim != 2 or S.shape != M.shape: + raise ValueError("members and within_sigma must both be (K, T)") K, T = M.shape - D = _second_difference(T) - DtD = D.T @ D + times = np.asarray(times_days, float) + if times.shape != (T,): + raise ValueError("times_days must have one entry per epoch") + if solver not in ("banded", "dense"): + raise ValueError("solver must be 'banded' or 'dense'") + obs = np.isfinite(M) & np.isfinite(S) & (S > 0) + n_obs_t = obs.sum(axis=0) + if (n_obs_t > 0).sum() < 3: + raise ValueError("need finite observations at three or more epochs") + S2 = np.where(obs, np.clip(S, 1e-9, None) ** 2, np.inf) # inf = no information + Mz = np.where(obs, M, 0.0) + + # Second-difference smoothness operator on the physical time grid. Its + # normal matrix D^T D is pentadiagonal, so the mu-update is a banded solve: + # O(T) per sweep instead of O(T^3) time and O(T^2) memory (audit SCALE-01). + Dsp = second_difference_operator(times) + DtD_sp = (Dsp.T @ Dsp).tocsr() + dtd_diag = [DtD_sp.diagonal(k) for k in (0, 1, 2)] + if solver == "dense": + DtD = DtD_sp.toarray() # Initialise. - mu = M.mean(axis=0) + with warnings.catch_warnings(): + warnings.simplefilter("ignore", RuntimeWarning) + mu = _fill_nan(np.nanmean(np.where(obs, M, np.nan), axis=0), times) + tau2 = float(np.nanvar(np.nanmean(np.where(obs, M, np.nan), axis=1))) + 1e-12 beta = np.zeros(K) - tau2 = np.var(M.mean(axis=1)) + 1e-12 s2 = 1.0 - lam = 1.0 / (np.var(np.diff(mu, 2)) + 1e-12) + lam = 1.0 / (np.var(Dsp @ mu) + 1e-12) - keep_mu, keep_tau, keep_s = [], [], [] + keep_mu, keep_tau, keep_s, keep_beta = [], [], [], [] for it in range(n_iter): # 1. mu | rest : Gaussian with precision Q = diag(prec_t) + lam*DtD. - prec_t = np.sum(1.0 / (s2 * S2), axis=0) # (T,) - rhs = np.sum((M - beta[:, None]) / (s2 * S2), axis=0) # (T,) - Q = np.diag(prec_t) + lam * DtD - L = np.linalg.cholesky(Q) - mean_mu = np.linalg.solve(Q, rhs) + w = 1.0 / (s2 * S2) # zero where unobserved + prec_t = np.sum(w, axis=0) + rhs = np.sum(w * (Mz - beta[:, None]), axis=0) z = rng.standard_normal(T) - mu = mean_mu + np.linalg.solve(L.T, z) # ~ N(Q^{-1}rhs, Q^{-1}) - - # 2. beta_k | rest : Gaussian. + if solver == "dense": + Q = np.diag(prec_t) + lam * DtD + L = np.linalg.cholesky(Q) + mean_mu = np.linalg.solve(Q, rhs) + mu = mean_mu + np.linalg.solve(L.T, z) # ~ N(Q^{-1}rhs, Q^{-1}) + else: + ab = np.zeros((3, T)) # upper banded storage, two superdiagonals + ab[2] = prec_t + lam * dtd_diag[0] + ab[1, 1:] = lam * dtd_diag[1] + ab[0, 2:] = lam * dtd_diag[2] + c = cholesky_banded(ab, lower=False) # Q = U^T U + mean_mu = cho_solve_banded((c, False), rhs) + mu = mean_mu + solve_banded((0, 2), c, z) # U^{-1} z ~ N(0, Q^{-1}) + + # 2. beta_k | rest : Gaussian (only observed epochs contribute). for k in range(K): - prec = 1.0 / tau2 + np.sum(1.0 / (s2 * S2[k])) - m = np.sum((M[k] - mu) / (s2 * S2[k])) / prec + prec = 1.0 / tau2 + np.sum(w[k]) + m = np.sum(w[k] * (Mz[k] - mu)) / prec beta[k] = m + rng.standard_normal() / np.sqrt(prec) # 3. tau2 | beta : InvGamma. tau2 = 1.0 / rng.gamma(a0 + K / 2.0, 1.0 / (b0 + 0.5 * np.sum(beta**2))) - # 4. s2 | rest : InvGamma over standardized residuals. - resid = M - mu[None, :] - beta[:, None] - ss = np.sum(resid**2 / S2) - s2 = 1.0 / rng.gamma(a0 + K * T / 2.0, 1.0 / (b0 + 0.5 * ss)) + # 4. s2 | rest : InvGamma over standardized residuals of observed cells. + resid = np.where(obs, M - mu[None, :] - beta[:, None], 0.0) + ss = np.sum(np.where(obs, resid**2 / np.where(obs, S2, 1.0), 0.0)) + s2 = 1.0 / rng.gamma(a0 + obs.sum() / 2.0, 1.0 / (b0 + 0.5 * ss)) # 5. lambda | mu : Gamma (random-walk precision). - dm = D @ mu + dm = Dsp @ mu lam = rng.gamma(lam_a + (T - 2) / 2.0, 1.0 / (lam_b + 0.5 * np.sum(dm**2))) if it >= burn and (it - burn) % thin == 0: keep_mu.append(mu.copy()) keep_tau.append(tau2) keep_s.append(s2) + keep_beta.append(beta.copy()) samples = np.array(keep_mu) mu_mean = samples.mean(axis=0) @@ -332,17 +471,38 @@ def gibbs_dvv( tau = float(np.sqrt(np.mean(keep_tau))) s = float(np.sqrt(np.mean(keep_s))) - method_std = M.std(axis=0, ddof=1) if K > 1 else np.zeros(T) - within_std = s * np.sqrt(np.mean(S2, axis=0)) # calibrated Weaver floor - total_std = np.sqrt(within_std**2 + method_std**2) # law of total variance - - times = np.asarray(times_days, float) - L = _estimate_corr_length(M - mu_mean[None, :], times) - # The honest *measurement* covariance for downstream use: per-epoch total - # error, exponential temporal correlation, plus a common-mode floor (the - # constant-in-time methodological bias that averaging cannot remove). + beta_mean = np.mean(keep_beta, axis=0) + + # Decomposition of the per-epoch measurement variance (audit UQ-03/04): + # calibrated floor, plus the between-configuration spread of the + # offset-corrected members with the floor removed (never negative). + with warnings.catch_warnings(): + warnings.simplefilter("ignore", RuntimeWarning) + within_var = s**2 * np.nanmean(np.where(obs, S2, np.nan), axis=0) + resid_obs = np.where(obs, M - beta_mean[:, None], np.nan) + raw_var = np.nanvar(resid_obs, axis=0, ddof=1) + within_var = np.where(np.isfinite(within_var), within_var, np.nanmedian(within_var)) + raw_var = np.where(np.isfinite(raw_var), raw_var, np.nanmedian(raw_var)) + if not np.isfinite(raw_var).any(): # a single configuration: no spread + raw_var = np.zeros(T) + method_var = np.maximum(raw_var - within_var, 0.0) + within_std = np.sqrt(within_var) + method_std = np.sqrt(method_var) + total_std = np.sqrt(within_var + method_var) + + L = _estimate_corr_length(resid_obs - mu_mean[None, :], times) Cd = temporal_error_covariance(total_std, times, L, common_mode_sigma=tau) + # How much of each scale posterior the hyper-prior supplies (at the means). + resid_hat = np.where(obs, M - mu_mean[None, :] - beta_mean[:, None], 0.0) + ss_hat = float(np.sum(np.where(obs, resid_hat**2 / np.where(obs, S2, 1.0), 0.0))) + dmu_hat = Dsp @ mu_mean + prior_weight = { + "tau2": float(b0 / (b0 + 0.5 * np.sum(beta_mean**2))), + "s2": float(b0 / (b0 + 0.5 * ss_hat)), + "lambda": float(lam_b / (lam_b + 0.5 * np.sum(dmu_hat**2))), + } + return BayesResult( times_days=times, mu_mean=mu_mean, @@ -358,6 +518,9 @@ def gibbs_dvv( method_std=method_std, within_std=within_std, samples_mu=samples, + beta_mean=beta_mean, + n_obs=n_obs_t, + prior_weight=prior_weight, ) @@ -403,17 +566,17 @@ def _build_bayes(seed: int = 55, cadence: int = 4): def _fig_bayes(res, run): import matplotlib.pyplot as plt - from .synthetic_demo import YEAR_D, C + from .synthetic_demo import YEAR_D, C, _boost_fonts yrs = res.times_days / YEAR_D truth = run.truth sd_cd = np.sqrt(np.diag(res.Cd)) sd_post = np.sqrt(np.diag(res.mu_cov)) - fig = plt.figure(figsize=(7.2, 3.0), layout="constrained") - gs = fig.add_gridspec(1, 3, width_ratios=[1.5, 1.0, 1.1]) + fig = plt.figure(figsize=(7.2, 5.6), layout="constrained") + gs = fig.add_gridspec(2, 2, height_ratios=[1.0, 1.0]) # (a) ensemble + posterior + the two bands. - ax0 = fig.add_subplot(gs[0]) + ax0 = fig.add_subplot(gs[0, 0]) for k in range(run.members.shape[0]): ax0.plot(yrs, run.members[k] * 100, lw=0.5, color="0.7", alpha=0.6) if truth is not None: @@ -425,7 +588,7 @@ def _fig_bayes(res, run): color=C["volcano"], alpha=0.18, lw=0, - label=r"$\pm2\sigma$ of $C_d$ (data error)", + label=r"$\pm2\sigma$ of $C_d$ (single-measurement error)", ) ax0.fill_between( yrs, @@ -439,8 +602,8 @@ def _fig_bayes(res, run): ax0.plot(yrs, res.mu_mean * 100, color=C["alt"], lw=1.5, label="posterior mean") ax0.set(xlabel="time (years)", ylabel="dv/v (%)", title="(a) Ensemble to posterior") ax0.legend( - fontsize=7.5, - loc="lower left", + fontsize=9, + loc="upper right", frameon=True, facecolor="white", framealpha=0.85, @@ -448,7 +611,7 @@ def _fig_bayes(res, run): ) # (b) the data covariance matrix. - ax1 = fig.add_subplot(gs[1]) + ax1 = fig.add_subplot(gs[0, 1]) vmax = float(np.percentile(np.diag(res.Cd), 85)) # robust to the warm-up spike im = ax1.imshow( res.Cd, @@ -465,18 +628,24 @@ def _fig_bayes(res, run): 0.92, f"corr. length {res.corr_length_days:.0f} d", transform=ax1.transAxes, - fontsize=8, + fontsize=11, color="white", va="top", ) - fig.colorbar(im, ax=ax1, fraction=0.046) + cbar1 = fig.colorbar(im, ax=ax1, fraction=0.046) + cbar1.set_label(r"$C_d$ (dv/v fraction)$^2$", fontsize=11) + cbar1.ax.tick_params(labelsize=11) # (c) time-dependent sigma_d(t) and the effective-sample-size collapse. - ax2 = fig.add_subplot(gs[2]) + # Full width on its own row: it carries four legend entries and was too + # horizontally squeezed sharing a row with (a) and (b). + ax2 = fig.add_subplot(gs[1, :]) ax2.plot( yrs, sd_cd * 100, color=C["volcano"], lw=1.6, label=r"$\sigma_d(t)$ (total)" ) - ax2.plot(yrs, res.method_std * 100, color=C["bad"], lw=1.0, label="methodological") + ax2.plot( + yrs, res.method_std * 100, color=C["bad"], lw=1.0, label="between-configuration" + ) ax2.plot( yrs, res.within_std * 100, color=C["landslide"], lw=1.0, label="within-method" ) @@ -487,9 +656,10 @@ def _fig_bayes(res, run): ax2.set( xlabel="time (years)", ylabel=r"$\sigma$ (dv/v, %)", - title=f"(c) time-dependent error; " f"$N_{{eff}}$={res.n_eff:.0f}/{len(yrs)}", + title=f"(c) time-dependent error; $N_{{eff}}$={res.n_eff:.0f}/{len(yrs)}", ) - ax2.legend(fontsize=7.5) + ax2.legend(fontsize=11) + _boost_fonts(ax0, ax1, ax2, tick=11, label=12, title=13.5) return fig @@ -506,7 +676,7 @@ def build_figs(outdir): res, run = _build_bayes() _fig_bayes(res, run).savefig(outdir / "demo_12_bayes.png", bbox_inches="tight") print( - f"wrote {outdir/'demo_12_bayes.png'} " + f"wrote {outdir / 'demo_12_bayes.png'} " f"(tau={res.tau:.2e}, s={res.s:.2f}, L={res.corr_length_days:.0f}d, " f"N_eff={res.n_eff:.0f}/{len(run.times_days)})" ) diff --git a/src/codameter/uq_measurement.py b/src/codameter/uq_measurement.py index 33b73ce..95562b0 100644 --- a/src/codameter/uq_measurement.py +++ b/src/codameter/uq_measurement.py @@ -51,13 +51,17 @@ from __future__ import annotations +import warnings from collections.abc import Mapping from dataclasses import dataclass import numpy as np __all__ = [ + "bandwidth_timescale", + "weaver_rms_dilation", "weaver_stretching_error", + "weaver_stretching_error_band", "EnsembleResult", "processing_ensemble", "temporal_error_covariance", @@ -73,28 +77,109 @@ # --------------------------------------------------------------------------- +def bandwidth_timescale(bandwidth_hz: float) -> float: + r"""Weaver's spectral timescale :math:`T` for a band-pass of width ``bandwidth_hz``. + + Weaver et al. (2011, eqs 17-20) take the signal spectrum to be Gaussian, + :math:`\propto \exp[-(\omega-\omega_c)^2 T^2]`, whose -10 dB points sit at + :math:`\omega_c \pm \sqrt{\ln 10}/T`; they call :math:`T` "the inverse of + the frequency bandwidth". We identify the band-pass edges :math:`f_1, f_2` + with those -10 dB points, so the half-width :math:`\pi (f_2 - f_1)` rad/s + gives + + .. math:: + T = \frac{\sqrt{\ln 10}}{\pi\,(f_2 - f_1)} . + + Any convention with :math:`T \propto 1/B` yields the same + :math:`1/\sqrt{B}` scaling of the floor; the constant is fixed here so + that floors are comparable across bands and so that the rescale ``s`` + fitted in :mod:`codameter.uq_bayes` reports calibration against a stated + convention. + + Parameters + ---------- + bandwidth_hz + Band width :math:`f_2 - f_1` in Hz. + + Returns + ------- + float + :math:`T` in seconds. + """ + if bandwidth_hz <= 0: + raise ValueError("bandwidth_hz must be positive") + return float(np.sqrt(np.log(10.0)) / (np.pi * bandwidth_hz)) + + +def weaver_rms_dilation( + cc: np.ndarray | float, + omega_c: float, + t1: float, + t2: float, + T: float, +) -> np.ndarray | float: + r"""Weaver et al. (2011) eq. 20 in its native variables. + + .. math:: + \operatorname{rms}\,\varepsilon = + \frac{\sqrt{1 - X^2}}{2X}\; + \sqrt{\frac{6\sqrt{\pi/2}\;T}{\omega_c^2\,(t_2^3 - t_1^3)}} + + with ``cc`` the dilation correlation coefficient :math:`X`, ``omega_c`` + the central angular frequency, ``t1``/``t2`` the coda window and ``T`` + the spectral timescale (:func:`bandwidth_timescale`). Use one consistent + time unit throughout; the result is dimensionless. Weaver's own example + (their eq. 21: ``t1=12.5``, ``t2=50`` us, ``omega_c=15`` rad/us, + ``T=0.56`` us) gives ``4e-4 * sqrt(1-X^2)/(2X)``. + """ + if omega_c <= 0: + raise ValueError("omega_c must be positive") + if T <= 0: + raise ValueError("T must be positive") + if not (0 < t1 < t2): + raise ValueError("require 0 < t1 < t2") + cc_arr = np.asarray(cc, dtype=float) + if np.any((cc_arr <= 0) | (cc_arr > 1.0)): + raise ValueError("cc must lie in (0, 1]") + var = (1.0 - cc_arr**2) / (4.0 * cc_arr**2) + var = var * (6.0 * np.sqrt(np.pi / 2.0) * T) / (omega_c**2 * (t2**3 - t1**3)) + out = np.sqrt(var) + return float(out) if out.ndim == 0 else out + + def weaver_stretching_error( cc: np.ndarray | float, f_center_hz: float, t1_s: float, t2_s: float, + bandwidth_hz: float, ) -> np.ndarray | float: - r"""Coherence-based standard error of a single :math:`\delta v / v` estimate. + r"""Coherence-based standard error of a single stretch / :math:`\delta v / v` estimate. - Implements the Weaver et al. (2011) / Clarke et al. (2011) bound on the - precision of a relative time shift (hence :math:`\delta v / v`) estimated - from a coda window :math:`[t_1, t_2]` with mean correlation coefficient - ``cc`` at central angular frequency :math:`\omega_c = 2\pi f_c`: + Implements the Weaver et al. (2011) eq. 20 bound (see also Clarke et al., + 2011) on the precision of a relative dilation :math:`\varepsilon` estimated + from a coda window :math:`[t_1, t_2]` with dilation correlation coefficient + ``cc``, central angular frequency :math:`\omega_c = 2\pi f_c` and spectral + timescale :math:`T` set by the band width (:func:`bandwidth_timescale`): .. math:: - \sigma_{\delta v/v}^2 = - \frac{1 - CC^2}{2\,CC^2}\; - \frac{6\,\sqrt{\pi/2}}{\omega_c^2\,(t_2^3 - t_1^3)} . - - This is the **aleatoric floor** for a fixed processing configuration: the - irreducible scatter from finite coda coherence. It captures the levers - practitioners actually turn — higher ``cc`` and a longer, later coda window - (larger :math:`t_2^3 - t_1^3`) and higher frequency all shrink the error. + \sigma_{\varepsilon}^2 = + \frac{1 - CC^2}{4\,CC^2}\; + \frac{6\,\sqrt{\pi/2}\;T}{\omega_c^2\,(t_2^3 - t_1^3)} . + + Since :math:`\delta v/v = -\varepsilon/(1+\varepsilon)`, this is the + :math:`\delta v/v` standard error to first order in :math:`\varepsilon`. + It is the **aleatoric floor** for a fixed processing configuration: the + irreducible scatter from finite coda coherence. Higher ``cc``, a longer or + later coda window (larger :math:`t_2^3 - t_1^3`), higher centre frequency + and a wider band all shrink it; the band-width dependence is + :math:`1/\sqrt{B}`. + + .. note:: + Before v0.5 this function omitted :math:`T` (so the result was not + dimensionless and did not depend on band width) and used + :math:`(1-CC^2)/(2CC^2)`, twice Weaver's prefactor. Corrected after the + 2026-09-10 pre-submission audit (finding UQ-01). Parameters ---------- @@ -104,25 +189,36 @@ def weaver_stretching_error( Central frequency of the measurement band, Hz. t1_s, t2_s Coda window start and end lapse times, seconds (``t2_s > t1_s > 0``). + bandwidth_hz + Width of the measurement band :math:`f_2 - f_1`, Hz. For a band + tuple use :func:`weaver_stretching_error_band`. Returns ------- np.ndarray or float - Standard error on :math:`\delta v / v` (fraction), matching ``cc``. + Standard error on :math:`\varepsilon` (fraction), matching ``cc``. """ if f_center_hz <= 0: raise ValueError("f_center_hz must be positive") - if not (0 < t1_s < t2_s): - raise ValueError("require 0 < t1_s < t2_s") - cc_arr = np.asarray(cc, dtype=float) - if np.any((cc_arr <= 0) | (cc_arr > 1.0)): - raise ValueError("cc must lie in (0, 1]") omega_c = 2.0 * np.pi * f_center_hz - numerator = 6.0 * np.sqrt(np.pi / 2.0) - denom = omega_c**2 * (t2_s**3 - t1_s**3) - var = (1.0 - cc_arr**2) / (2.0 * cc_arr**2) * (numerator / denom) - out = np.sqrt(var) - return float(out) if out.ndim == 0 else out + T = bandwidth_timescale(bandwidth_hz) + return weaver_rms_dilation(cc, omega_c, t1_s, t2_s, T) + + +def weaver_stretching_error_band( + cc: np.ndarray | float, + band_hz: tuple[float, float], + t1_s: float, + t2_s: float, +) -> np.ndarray | float: + """:func:`weaver_stretching_error` for a band given as ``(f1, f2)`` in Hz. + + Uses the arithmetic centre :math:`(f_1+f_2)/2` and width :math:`f_2-f_1`. + """ + f1, f2 = float(band_hz[0]), float(band_hz[1]) + if not (0 < f1 < f2): + raise ValueError("band_hz must satisfy 0 < f1 < f2") + return weaver_stretching_error(cc, 0.5 * (f1 + f2), t1_s, t2_s, f2 - f1) # --------------------------------------------------------------------------- @@ -349,12 +445,21 @@ class GlobalReferenceSolution: Number of window pairs used. residual_rms : float RMS weighted residual of the fit. + component : np.ndarray, shape (n_epoch,) + Connected-component label of each epoch in the pair graph. Offsets + between components are unidentified; each component carries its own + sum-zero datum. An epoch in a component of size one is unidentified + altogether and has ``dvv`` and ``sigma`` equal to NaN (audit INV-02). + n_components : int + Number of connected components. """ dvv: np.ndarray cov: np.ndarray n_pairs: int residual_rms: float + component: np.ndarray | None = None + n_components: int = 1 @property def sigma(self) -> np.ndarray: @@ -416,22 +521,49 @@ def global_reference_inversion( if np.any(s <= 0): raise ValueError("pair_sigma must be positive") + from scipy.sparse import coo_matrix + from scipy.sparse.csgraph import connected_components + g = np.zeros((n_pairs, n_epoch)) rows = np.arange(n_pairs) g[rows, i_idx] = 1.0 g[rows, j_idx] = -1.0 w = 1.0 / s**2 + # Identifiability: the pair graph must connect the epochs. Each connected + # component has its own unidentified offset; a lone epoch is unidentified. + adjacency = coo_matrix((np.ones(n_pairs), (i_idx, j_idx)), shape=(n_epoch, n_epoch)) + n_components, labels = connected_components(adjacency, directed=False) + isolated = np.bincount(labels, minlength=n_components)[labels] == 1 + if n_components > 1: + warnings.warn( + f"pair graph has {n_components} connected components " + f"({int(isolated.sum())} isolated epoch(s)); offsets between " + "components are unidentified and are set to a per-component datum", + UserWarning, + stacklevel=2, + ) + gtwg = g.T @ (w[:, None] * g) gtwd = g.T @ (w * d) cov = np.linalg.pinv(gtwg) m = cov @ gtwd - m = m - m.mean() # impose the sum-zero datum (min-norm gauge) + for c in range(n_components): # per-component sum-zero datum (min-norm gauge) + sel = labels == c + m[sel] = m[sel] - m[sel].mean() + m[isolated] = np.nan + cov[isolated, :] = np.nan + cov[:, isolated] = np.nan resid = g @ m - d residual_rms = float(np.sqrt(np.mean(w * resid**2))) return GlobalReferenceSolution( - dvv=m, cov=cov, n_pairs=n_pairs, residual_rms=residual_rms + dvv=m, + cov=cov, + n_pairs=n_pairs, + residual_rms=residual_rms, + component=labels, + n_components=int(n_components), ) diff --git a/src/codameter/uq_processing.py b/src/codameter/uq_processing.py index f63be30..e20a26b 100644 --- a/src/codameter/uq_processing.py +++ b/src/codameter/uq_processing.py @@ -31,6 +31,15 @@ = \underbrace{\mathbb{E}_c[\operatorname{Var}(\delta v/v \mid c)]}_{\text{within-choice floor}} + \underbrace{\operatorname{Var}_c[\mathbb{E}(\delta v/v \mid c)]}_{\text{processing-choice spread}} . +The second term needs the **conditional means** :math:`\mathbb{E}(\delta v/v +\mid c)`, i.e. the estimate each choice returns on the same data. The floor +alone cannot supply it: choices with different precisions do not thereby +have different means, and for a zero-mean mixture the spread term is exactly +zero. :func:`per_band_marginal_error` therefore reports the processing-choice +spread only when conditional means are passed in, and keeps a known +systematic bias separate from the centred variance (it enters the RMSE, not +the SD). + Grouping the samples **by frequency band** yields one marginal error per band — the input the depth inversion in :mod:`codameter.uq_depth` needs to turn frequency-resolved measurements into a depth profile with propagated error. @@ -96,6 +105,11 @@ class ProcessingPrior: Coda correlation coefficient near the start lapse. coherence_decay_s E-folding lapse over which the coda coherence decays. + relative_bandwidth + Band width as a fraction of the centre frequency, + :math:`B = \text{relative\_bandwidth}\times f_c`, needed by the + Weaver floor. The default 2/3 is a one-octave band :math:`[f, 2f]` + (centre :math:`1.5f`, width :math:`f`). """ bands_hz: Sequence[float] @@ -114,10 +128,13 @@ class ProcessingPrior: snr0: float = 80.0 coherence_at_start: float = 0.98 coherence_decay_s: float = 80.0 + relative_bandwidth: float = 2.0 / 3.0 def __post_init__(self) -> None: if len(self.bands_hz) == 0: raise ValueError("bands_hz must be non-empty") + if self.relative_bandwidth <= 0: + raise ValueError("relative_bandwidth must be positive") bad = set(self.rule_weights) - set(WINDOW_RULES) if bad: raise ValueError(f"unknown window rules: {sorted(bad)}") @@ -133,6 +150,7 @@ class ProcessingChoice: rule: str f_center_hz: float + bandwidth_hz: float t1_s: float t2_s: float cc: float @@ -206,29 +224,61 @@ def sample_processing_choices( else: # pragma: no cover - guarded by ProcessingPrior raise ValueError(f"unknown rule {rule!r}") cc = _coherence(0.5 * (t1 + t2), prior) - out.append(ProcessingChoice(rule=rule, f_center_hz=f, t1_s=t1, t2_s=t2, cc=cc)) + out.append( + ProcessingChoice( + rule=rule, + f_center_hz=f, + bandwidth_hz=prior.relative_bandwidth * f, + t1_s=t1, + t2_s=t2, + cc=cc, + ) + ) return out def choice_floor(choice: ProcessingChoice) -> float: """Within-choice Weaver/Clarke standard error for one processing choice.""" return float( - weaver_stretching_error(choice.cc, choice.f_center_hz, choice.t1_s, choice.t2_s) + weaver_stretching_error( + choice.cc, + choice.f_center_hz, + choice.t1_s, + choice.t2_s, + choice.bandwidth_hz, + ) ) def per_band_marginal_error( choices: Sequence[ProcessingChoice], band_bias: Mapping[float, float] | None = None, + *, + conditional_means: Sequence[float] | None = None, ) -> dict[float, dict[str, float]]: r"""Marginal :math:`\delta v / v` error per frequency band. - Groups the sampled choices by band and applies the law of total variance: - the **within-choice** variance is the mean squared Weaver floor; the - **processing-choice** variance is the spread of the (optional) per-choice - systematic ``band_bias`` plus the floor's own variability across choices. - The returned ``total`` is the marginal standard error that the depth - inversion uses as the per-band measurement uncertainty. + Groups the sampled choices by band and applies the law of total variance + (module docstring): + + * ``within``: :math:`\sqrt{\mathbb{E}_c[\sigma_c^2]}`, the root mean + squared Weaver floor over the band's choices; + * ``processing``: :math:`\sqrt{\operatorname{Var}_c[m_c]}` of the + supplied conditional means :math:`m_c` (sample variance, ``ddof=1``). + Without ``conditional_means`` this is **zero**: a mixture of + zero-mean components with different precisions has marginal variance + :math:`\mathbb{E}_c[\sigma_c^2]` and no spread term. (Before v0.5 the + floor's own variability across choices was added here; that quantity + has no probabilistic meaning. Audit finding UQ-02.) + * ``sd``: the centred marginal standard deviation + :math:`\sqrt{\text{within}^2 + \text{processing}^2}`; ``total`` is + kept as an alias; + * ``bias``: the known systematic offset from ``band_bias`` (0 if none); + * ``rmse``: :math:`\sqrt{\text{sd}^2 + \text{bias}^2}`. + + ``sd`` is the per-band measurement uncertainty for a depth inversion + after the bias has been corrected; ``rmse`` is the expected error if it + has not. Parameters ---------- @@ -236,34 +286,43 @@ def per_band_marginal_error( Sampled processing choices (typically from :func:`sample_processing_choices`). band_bias - Optional mapping ``f_center -> systematic offset`` used to inject a - known per-band methodological bias for demonstration; if omitted, the - processing-choice variance is estimated from the floor spread alone. + Optional mapping ``f_center -> known systematic offset`` per band. + conditional_means + Optional per-choice central estimates aligned with ``choices`` + (the :math:`\delta v/v` each configuration returns on the same + data), from which the processing-choice spread is computed. Returns ------- dict - ``{f_center: {"within": .., "processing": .., "total": .., "n": ..}}``. + ``{f_center: {"within", "processing", "sd", "total", "bias", "rmse", "n"}}``. """ - by_band: dict[float, list[ProcessingChoice]] = {} - for c in choices: - by_band.setdefault(c.f_center_hz, []).append(c) + means: np.ndarray | None = None + if conditional_means is not None: + means = np.asarray(conditional_means, dtype=float) + if means.shape != (len(choices),): + raise ValueError("conditional_means must align with choices") + + by_band: dict[float, list[int]] = {} + for i, c in enumerate(choices): + by_band.setdefault(c.f_center_hz, []).append(i) result: dict[float, dict[str, float]] = {} - for f, group in by_band.items(): - floors = np.array([choice_floor(c) for c in group], dtype=float) + for f, idx in by_band.items(): + floors = np.array([choice_floor(choices[i]) for i in idx], dtype=float) within_var = float(np.mean(floors**2)) - # processing-choice variance: spread of the per-choice central estimate. - # Without reprocessing we proxy it by the spread of the floors (choices - # that yield different precisions also yield different estimates); a - # supplied band_bias adds a known systematic component. - proc_var = float(np.var(floors, ddof=1)) if floors.size > 1 else 0.0 - if band_bias is not None and f in band_bias: - proc_var += float(band_bias[f]) ** 2 + proc_var = 0.0 + if means is not None and len(idx) > 1: + proc_var = float(np.var(means[idx], ddof=1)) + bias = float(band_bias[f]) if band_bias is not None and f in band_bias else 0.0 + sd = (within_var + proc_var) ** 0.5 result[f] = { "within": within_var**0.5, "processing": proc_var**0.5, - "total": (within_var + proc_var) ** 0.5, - "n": float(len(group)), + "sd": sd, + "total": sd, + "bias": bias, + "rmse": (sd**2 + bias**2) ** 0.5, + "n": float(len(idx)), } return result diff --git a/tests/data/golden/manifest.json b/tests/data/golden/manifest.json index 6daa6b0..eb7ddce 100644 --- a/tests/data/golden/manifest.json +++ b/tests/data/golden/manifest.json @@ -1,5 +1,5 @@ { - "version": 2, + "version": 3, "grades": [ "easy", "medium", @@ -36,7 +36,7 @@ "gate": true }, "eps_max": 0.06, - "rms": 0.00014974043201662195 + "rms": 0.00016366904839408612 } }, { @@ -69,7 +69,7 @@ "gate": true }, "eps_max": 0.05, - "rms": 0.00022195874555143113 + "rms": 0.00023685666694590966 } }, { @@ -102,7 +102,7 @@ "gate": true }, "eps_max": 0.03, - "rms": 0.00034382897480019815, + "rms": 0.0003411112016349412, "rms_wrong_layer": 0.0010007890743546153 }, "two_layer": true, diff --git a/tests/test_advisor_validation.py b/tests/test_advisor_validation.py new file mode 100644 index 0000000..ea68f79 --- /dev/null +++ b/tests/test_advisor_validation.py @@ -0,0 +1,34 @@ +"""Executable coverage for the advisor's public development route (AG-01).""" + +import numpy as np +import pytest +from codameter import golden +from codameter import use_cases as uc + + +@pytest.mark.parametrize("app", list(uc.USE_CASES)) +def test_advisory_case_recovers_every_application(app, monkeypatch): + # The advisor must work without a matching public or private gold record. + monkeypatch.setattr(golden, "CASES_BY_ID", {}) + data = golden.advisory_case(app, years=0.3, seed=41) + assert data["use_case"] == app + assert data["recipe"]["grade"] == "easy" + assert data["recipe"]["seed"] == 41 + assert "truth_other" not in data + cfg = uc.recommend(app) + dvv, valid = golden.recover(data, cfg, uc.eps_max(app)) + assert valid.sum() >= 10 + assert np.isfinite(dvv[valid]).all() + support = golden.scoring_support(data, cfg, uc.eps_max(app)) + rms, availability = golden.rms_on_support( + np.where(valid, dvv, np.nan), data["truth"], **support + ) + assert np.isfinite(rms) and availability == 1.0 + + +def test_advisory_case_alias_and_replay(): + a = golden.advisory_case("glacier", years=0.1, seed=19) + b = golden.advisory_case("cryosphere", years=0.1, seed=19) + np.testing.assert_array_equal(a["ccfs"], b["ccfs"]) + with pytest.raises(ValueError, match="years"): + golden.advisory_case("volcano", years=np.nan) diff --git a/tests/test_audit_small_fixes.py b/tests/test_audit_small_fixes.py new file mode 100644 index 0000000..ed5f01c --- /dev/null +++ b/tests/test_audit_small_fixes.py @@ -0,0 +1,128 @@ +"""Regression tests for the small fixes from the 2026-09-10 pre-submission audit +(INV-02, DET-02, SCALE-01, SCALE-02).""" + +from __future__ import annotations + +import json +from argparse import Namespace + +import numpy as np +import pytest +from codameter import bench, golden, uq_bayes +from codameter.inverse.linear_fit import PredictorMatrix, linear_fit +from codameter.uq_measurement import global_reference_inversion + + +def test_bounded_fit_reports_uncertainty_and_flags_bound(): + """INV-02: a parameter clamped at a bound is not known exactly.""" + p = PredictorMatrix(X=np.ones((20, 1)), parameter_names=["amplitude"]) + r = linear_fit( + -np.ones(20) * 0.1, + p, + sigma_dvv=1.0, + parameter_bounds={"amplitude": (0.0, np.inf)}, + ) + assert r.mean[0] == 0.0 + assert r.std[0] > 0 + assert r.at_bound is not None and bool(r.at_bound[0]) + assert r.to_dict()["at_bound"] == [True] + free = linear_fit(-np.ones(20) * 0.1, p, sigma_dvv=1.0) + assert free.at_bound is not None and not free.at_bound.any() + assert free.std[0] == pytest.approx(r.std[0]) + + +def test_disconnected_reference_epoch_is_unidentified(): + """INV-02: an epoch with no pairs gets NaN, not zero uncertainty.""" + with pytest.warns(UserWarning, match="connected components"): + g = global_reference_inversion( + np.array([0]), np.array([1]), np.array([0.01]), np.array([0.001]), 3 + ) + assert g.n_components == 2 + assert np.isnan(g.dvv[2]) and np.isnan(g.sigma[2]) + assert np.isfinite(g.sigma[:2]).all() + assert g.dvv[0] - g.dvv[1] == pytest.approx(0.01) + assert list(g.component) == [0, 0, 1] + + +def test_golden_cache_is_exact_and_versioned(tmp_path, monkeypatch): + """DET-02: cold, warm and cache-bypassed routes return identical arrays.""" + monkeypatch.setattr(golden, "CACHE_DIR", tmp_path) + cold = golden.generate("easy-volcano-01", cache=True) + files = list(tmp_path.glob("easy-volcano-01-*.npz")) + assert len(files) == 1 + assert files[0].stem.endswith(f"-{golden._generator_hash()}") + assert not list(tmp_path.glob("*.tmp")) + warm = golden.generate("easy-volcano-01", cache=True) + fresh = golden.generate("easy-volcano-01", cache=False) + for a in (cold, warm, fresh): + assert a["ccfs"].dtype == np.float64 + assert np.array_equal(cold["ccfs"], warm["ccfs"]) + assert np.array_equal(cold["ccfs"], fresh["ccfs"]) + assert set(cold) == set(warm) == set(fresh) + assert cold["generator_hash"] == warm["generator_hash"] == fresh["generator_hash"] + # A stale file for the same case is removed when a new key is written. + stale = tmp_path / "easy-volcano-01-deadbeef-00000000.npz" + stale.write_bytes(b"x") + files[0].unlink() + golden.generate("easy-volcano-01", cache=True) + assert not stale.exists() + + +def test_golden_cache_identity_includes_application_geometry(tmp_path, monkeypatch): + source = tmp_path / "use_cases.py" + source.write_text("geometry = 1\n") + monkeypatch.setattr(golden.uc, "__file__", str(source)) + before = golden._generator_hash() + source.write_text("geometry = 2\n") + assert golden._generator_hash() != before + + +def test_aggregate_rejects_missing_shards_and_duplicates(tmp_path, capsys): + """SCALE-02: an incomplete or duplicated shard set is not merged silently.""" + row = { + "case_id": "x", + "config_index": 0, + "ok": True, + "rms": 1e-4, + "estimator": "e", + "band": [1, 2], + "reference": "fixed", + "codameter_version": "0", + } + src = tmp_path / "src" + src.mkdir() + shard = src / "shard-00000-of-00002.jsonl" + shard.write_text(json.dumps(row) + "\n" + json.dumps(row) + "\n") + args = Namespace(src=str(src), out=str(tmp_path / "agg"), allow_partial=False) + assert bench._cmd_aggregate(args) == 1 + err = capsys.readouterr().err + assert "missing shard" in err and "duplicate" in err + shard.write_text(json.dumps(row) + "\n") + assert bench._cmd_aggregate(args) == 1 # still one shard missing + args.allow_partial = True + assert bench._cmd_aggregate(args) == 0 + man = json.loads((tmp_path / "agg" / "aggregate_manifest.json").read_text()) + assert man["complete"] is False + assert man["n_shards"] == 2 and man["shards_present"] == [0] + assert man["missing"] == [1] and man["n_rows"] == 1 + + +def test_gibbs_banded_matches_dense(): + """SCALE-01: the banded mu-update reproduces the dense one draw for draw.""" + rng = np.random.default_rng(3) + T, K = 60, 4 + t = np.arange(T, dtype=float) + truth = 1e-3 * np.sin(2 * np.pi * t / T) + members = ( + truth[None, :] + + 2e-4 * rng.standard_normal((K, T)) + + 1e-4 * rng.standard_normal((K, 1)) + ) + sig = np.full((K, T), 2e-4) + kw = dict(n_iter=200, burn=50, thin=1, seed=7) + a = uq_bayes.gibbs_dvv(members, sig, t, solver="dense", **kw) + b = uq_bayes.gibbs_dvv(members, sig, t, solver="banded", **kw) + np.testing.assert_allclose(a.mu_mean, b.mu_mean, rtol=1e-6, atol=1e-10) + np.testing.assert_allclose(a.Cd, b.Cd, rtol=1e-6, atol=1e-14) + with pytest.raises(ValueError): + uq_bayes.gibbs_dvv(members, sig, t, n_iter=10, burn=2, solver="nope") diff --git a/tests/test_bench.py b/tests/test_bench.py index ba245df..781e36d 100644 --- a/tests/test_bench.py +++ b/tests/test_bench.py @@ -5,9 +5,7 @@ import json import numpy as np - -from codameter import bench -from codameter import golden +from codameter import bench, golden EASY = "easy-volcano-01" HARD = next(c["id"] for c in golden.CASES if c["grade"] == "hard") @@ -16,7 +14,9 @@ def test_build_grid_shapes_and_counts(): case = golden.CASES_BY_ID[EASY] cfgs = bench.build_grid(case, "compact") - assert len(cfgs) == 4 # 2 estimators x 2 references; rec band/window/stack, gate=[True] + assert ( + len(cfgs) == 4 + ) # 2 estimators x 2 references; rec band/window/stack, gate=[True] for c in cfgs: assert set(c) == {"estimator", "band", "window", "stack", "reference", "gate"} assert isinstance(c["band"], tuple) and isinstance(c["window"], tuple) @@ -88,7 +88,7 @@ def test_score_cell_aggregates_multichannel_and_grades_depth(): miss = bench.score_cell(HARD, 1, uc.recommend(app, band=wrong)) assert hit["ok"] and miss["ok"] assert hit["target"] in ("shallow", "deep") - assert hit["rms"] < miss["rms"] # picking the right depth wins + assert hit["rms"] < miss["rms"] # picking the right depth wins def test_run_sweep_and_roundtrip(tmp_path): @@ -97,8 +97,9 @@ def test_run_sweep_and_roundtrip(tmp_path): assert all(r["case_id"] == EASY for r in rows) dest = bench._write_jsonl(rows, str(tmp_path), "shard-00000-of-00001.jsonl") assert dest.endswith(".jsonl") - back = list(bench._read_jsonl_dir(str(tmp_path))) + back = [r for _, r in bench._read_jsonl_dir(str(tmp_path))] assert len(back) == 4 + assert all(r["codameter_version"] for r in back) json.dumps(back) # serializable diff --git a/tests/test_calibration.py b/tests/test_calibration.py new file mode 100644 index 0000000..3aec5ae --- /dev/null +++ b/tests/test_calibration.py @@ -0,0 +1,144 @@ +"""Tests for the coverage-calibration driver (audit SCI-05).""" + +from __future__ import annotations + +import json +from types import SimpleNamespace + +import numpy as np +import pytest +from codameter import calibration as C +from codameter import uq_bayes + +_BASE = { + "coverage68": 0.9, + "coverage95": 1.0, + "coverage95_posterior": 0.5, + "median_sd": 1e-3, + "median_halfwidth95": 2e-3, + "bias": 0.0, + "rmse": 1e-3, + "member_rmse": 2e-3, + "shared_bias": -1e-4, + "max_abs_err": 3e-3, + "tau": 1e-4, + "s": 5.0, + "corr_length_days": 20.0, + "n_eff": 15.0, + "missing_fraction": 0.1, + "prior_weight_tau2": 0.03, + "prior_weight_s2": 1e-10, + "prior_weight_lambda": 0.05, +} + + +def test_missing_members_do_not_count_as_coverage_misses(monkeypatch): + # Two of six cells are observed. One covers truth, one misses. A finite + # member without a usable coherence floor is also unobserved by the fit. + members = np.array([[0.0, np.nan, 0.0], [3.0, np.nan, np.nan]]) + sigmas = np.ones_like(members) + sigmas[0, 2] = np.nan + run = SimpleNamespace(truth=np.zeros(3), members=members, within_sigma=sigmas) + result = SimpleNamespace( + mu_mean=np.zeros(3), + Cd=np.eye(3), + mu_lo=-np.ones(3), + mu_hi=np.ones(3), + tau=0.0, + s=1.0, + corr_length_days=1.0, + n_eff=3, + prior_weight={}, + ) + monkeypatch.setattr( + C, + "make_realization", + lambda *a, **kw: ( + SimpleNamespace(t=np.arange(5), fs=1), + np.arange(3), + np.zeros(3), + np.zeros((3, 5)), + ), + ) + monkeypatch.setattr(uq_bayes, "bayes_dvv_from_ccfs", lambda *a, **kw: (result, run)) + row = C.run_realization(1) + assert row["ok"] + assert row["n_member_epochs"] == 2 + assert row["member_coverage68"] == row["member_coverage95"] == 0.5 + assert row["missing_fraction"] == pytest.approx(2 / 3) + assert row["member_rmse"] == pytest.approx(np.sqrt(4.5)) + members[:] = np.nan + assert not C.run_realization(1)["ok"] + + +def test_summarize_reports_mean_se_and_margin(): + results = [ + {"ok": True, "member_coverage68": 0.70, "member_coverage95": 0.94, **_BASE}, + {"ok": True, "member_coverage68": 0.66, "member_coverage95": 0.98, **_BASE}, + {"ok": False, "error": "boom"}, + ] + s = C.summarize(results) + assert s["n_realizations"] == 3 and s["n_failed"] == 1 + assert s["failures"] == ["boom"] + assert s["member_coverage95"]["mean"] == pytest.approx(0.96) + assert s["member_coverage95"]["se"] == pytest.approx( + np.std([0.94, 0.98], ddof=1) / np.sqrt(2) + ) + assert s["member_coverage95_within_margin"] is True + assert ( + C.summarize(results, margin=0.005)["member_coverage95_within_margin"] is False + ) + only_failed = C.summarize([{"ok": False, "error": "x"}]) + assert only_failed["member_coverage95_within_margin"] is None + + +def test_run_realization_smoke_and_failure_path(): + r = C.run_realization(1, "clean", years=0.5, cadence=6, n_iter=60, burn=20, thin=1) + assert r["ok"], r.get("error") + for k in ( + "member_coverage68", + "member_coverage95", + "coverage68", + "coverage95", + "coverage95_posterior", + ): + assert 0.0 <= r[k] <= 1.0 + assert ( + r["n_epochs"] > 10 and np.isfinite(r["rmse"]) and np.isfinite(r["member_rmse"]) + ) + assert 0.0 <= r["prior_weight_tau2"] <= 1.0 + bad = C.run_realization( + 1, "clean", years=0.01, cadence=6, n_iter=10, burn=2, thin=1 + ) + assert bad["ok"] is False and "error" in bad + with pytest.raises(ValueError): + C.make_realization(1, "no_such_scenario") + + +def test_cli_writes_json(tmp_path): + out = tmp_path / "cal.json" + rc = C.main( + [ + "--n", + "2", + "--scenario", + "clock_drift", + "--years", + "0.5", + "--cadence", + "6", + "--n-iter", + "40", + "--burn", + "10", + "--thin", + "1", + "--out", + str(out), + ] + ) + assert rc == 0 + payload = json.loads(out.read_text()) + assert payload["settings"]["scenario"] == "clock_drift" + assert len(payload["results"]) == 2 and payload["summary"]["n_realizations"] == 2 + assert "member_coverage95_within_margin" in payload["summary"] diff --git a/tests/test_figures.py b/tests/test_figures.py new file mode 100644 index 0000000..782a8d7 --- /dev/null +++ b/tests/test_figures.py @@ -0,0 +1,78 @@ +"""Tests for the figure driver and its numerical sidecars (audit REP-01).""" + +from __future__ import annotations + +import json +import re +from pathlib import Path + +import matplotlib +import numpy as np +import pytest + +matplotlib.use("Agg") + +from codameter import figures as F # noqa: E402 + +ROOT = Path(__file__).resolve().parents[1] + + +def test_sidecar_round_trips_every_plotted_array(tmp_path): + import matplotlib.pyplot as plt + + fig, (a, b) = plt.subplots(1, 2) + x = np.linspace(0, 1, 7) + a.plot(x, x**2, label="quad") + a.fill_between(x, 0, x, label="band") + a.scatter(x, 1 - x) + a.set(title="left", xlabel="t", ylabel="v") + b.imshow(np.arange(6.0).reshape(2, 3), extent=[0, 3, 0, 2]) + b.bar([0, 1], [2.0, 3.0]) + png = F.save_figure( + fig, + tmp_path, + "unit", + generator="test", + extra_arrays={"truth": x}, + extra_meta={"note": {"n": np.int64(7)}}, + ) + assert png.exists() + z = np.load(tmp_path / "unit.npz") + np.testing.assert_allclose(z["ax0/line0/y"], x**2) + assert "ax0/collection0/vertices" in z # fill_between polygon + assert "ax0/collection1/offsets" in z # scatter + np.testing.assert_allclose(z["ax1/image0"], np.arange(6.0).reshape(2, 3)) + assert z["ax1/patch0/xywh"][3] == pytest.approx(2.0) + np.testing.assert_allclose(z["data/truth"], x) + assert z["data/truth"].dtype == np.float64 # small arrays are exact + big = np.random.default_rng(0).standard_normal(F.LARGE_ARRAY + 1) + F.save_figure(fig, tmp_path, "big", generator="test", extra_arrays={"big": big}) + zb = np.load(tmp_path / "big.npz") + assert zb["data/big"].dtype == np.float32 + np.testing.assert_allclose(zb["data/big"], big, rtol=1e-6) + meta = json.loads((tmp_path / "unit.json").read_text()) + assert meta["generator"] == "test" and meta["note"] == {"n": 7} + assert meta["axes"][0]["lines"] == ["quad"] and meta["axes"][0]["title"] == "left" + assert set(meta["arrays"]) == set(z.files) + plt.close(fig) + + +def test_every_manuscript_figure_has_a_generator_or_a_declared_source(): + qmd = ROOT / "paper" / "manuscript_marine.qmd" + if not qmd.exists(): + pytest.skip("manuscript not present") + included = re.findall( + r"\\includegraphics(?:\[[^\]]*\])?\{([^}]+)\}", qmd.read_text() + ) + stems = {Path(p).stem for p in included} + known = set(F.generators()) | set(F.EXTERNAL) + assert stems <= known, sorted(stems - known) + assert F.SLOW <= set(F.generators()) + + +def test_cli_lists_and_rejects_unknown(tmp_path, capsys): + assert F.main(["--list"]) == 0 + out = capsys.readouterr().out + assert "demo_12_bayes" in out and "realdata_1_validation" in out + with pytest.raises(KeyError): + F.build_all_figures(tmp_path, only=["no_such_figure"]) diff --git a/tests/test_frugalmind_export.py b/tests/test_frugalmind_export.py index 9ddf1a0..e801ef9 100644 --- a/tests/test_frugalmind_export.py +++ b/tests/test_frugalmind_export.py @@ -11,13 +11,23 @@ import numpy as np import pytest - from codameter import frugalmind as fm from codameter import golden from codameter import use_cases as uc -_ROW_KEYS = {"id", "dataset_id", "suite_id", "version", "task_kind", "split", - "visibility", "prompt", "gold", "scorer_spec", "metadata"} +_ROW_KEYS = { + "id", + "dataset_id", + "suite_id", + "version", + "task_kind", + "split", + "visibility", + "prompt", + "gold", + "scorer_spec", + "metadata", +} @pytest.mark.parametrize("task", fm.TASKS) @@ -56,11 +66,13 @@ def test_param_scorer_rewards_recovery_and_punishes_wrong_choice(): bad = json.dumps(golden._jsonable(uc.recommend(app, band=wrong_band))) assert scorer(good, gold) == pytest.approx(1.0) - assert scorer(bad, gold) < 0.2 # wrong depth -> near zero + assert scorer(bad, gold) < 0.2 # wrong depth -> near zero assert scorer("sorry, no idea", gold) == 0.0 # Missing a core scientific choice (band) scores zero, not a default freebie. - assert scorer(json.dumps({"estimator": "stretching (TS)", "window": [2.0, 8.0]}), - gold) == 0.0 + assert ( + scorer(json.dumps({"estimator": "stretching (TS)", "window": [2.0, 8.0]}), gold) + == 0.0 + ) def test_param_scorer_accepts_partial_config_filling_noncore_axes(): @@ -69,8 +81,9 @@ def test_param_scorer_accepts_partial_config_filling_noncore_axes(): gold = fm._gold(case, "param_recommendation") # Only the three scientific choices; stack/reference/gate fall back to the # use-case default and the pipeline still recovers. - partial = json.dumps({"estimator": "stretching (TS)", "band": [0.4, 1.0], - "window": [10, 30]}) + partial = json.dumps( + {"estimator": "stretching (TS)", "band": [0.4, 1.0], "window": [10, 30]} + ) assert scorer(partial, gold) > 0.8 @@ -88,15 +101,91 @@ def test_series_scorer_truth_vs_null(): assert scorer(json.dumps([0.0, 0.1, 0.2]), gold) == 0.0 +def _series_txt(values): + return json.dumps([float(x) if np.isfinite(x) else None for x in values]) + + +def test_series_scorer_scores_missing_predictions_as_null(): + """Audit EV-01: ten finite values plus nulls scored 1.0 when the support and + the datum were taken from the submission. They now score like all zeros.""" + scorer = fm.make_scorer_from_spec({"name": "dvv_series_regression"}) + case = golden.CASES_BY_ID["easy-volcano-01"] + gold = fm._gold(case, "dvv_series") + n = int(gold["n_days"]) + assert len(gold["support"]) >= 10 + assert set(gold["baseline"]) <= set(gold["support"]) + zeros = scorer(json.dumps([0.0] * n), gold) + sparse_null = scorer(json.dumps([0.0] * 10 + [None] * (n - 10)), gold) + sparse_nan = scorer("[" + ", ".join(["0.0"] * 10 + ["NaN"] * (n - 10)) + "]", gold) + assert zeros < 0.1 + assert sparse_null == pytest.approx(zeros, abs=1e-9) + assert sparse_nan == pytest.approx(zeros, abs=1e-9) + + +def test_series_scorer_selective_omission_cannot_help(): + scorer = fm.make_scorer_from_spec({"name": "dvv_series_regression"}) + case = golden.CASES_BY_ID["easy-volcano-01"] + gold = fm._gold(case, "dvv_series") + d = golden.generate("easy-volcano-01") + truth = np.asarray(d["truth"], float) + n = truth.size + full = scorer(_series_txt(truth), gold) + assert full == pytest.approx(1.0) + # Omitting the epochs that depart most from the datum is scored as + # predicting no change there, and costs accordingly. + dev = np.abs(truth - truth[gold["baseline"]].mean()) + partial = truth.copy() + partial[np.argsort(dev)[-int(0.3 * n) :]] = np.nan + assert scorer(_series_txt(partial), gold) < 0.9 + # A legitimate warm-up gap costs little because the truth is near the datum. + warm = truth.copy() + warm[:45] = np.nan + assert scorer(_series_txt(warm), gold) > 0.8 + # No datum at all (every baseline epoch missing) scores zero. + nodatum = truth.copy() + nodatum[gold["baseline"]] = np.nan + assert scorer(_series_txt(nodatum), gold) == 0.0 + + +def test_rms_on_support_matches_oracle_for_reference_pipeline(): + """The manifest's expected RMS is unchanged by the fixed-support rule: the + reference pipeline has no missing values on its own support.""" + case = golden.CASES_BY_ID["easy-volcano-01"] + d = golden.generate(case["id"]) + cfg = uc.recommend(case["use_case"], **case.get("config", {})) + eps = uc.eps_max(case["use_case"]) + dvv, valid = golden.recover(d, cfg, eps) + sup = golden.scoring_support(d, cfg, eps) + rms_new, avail = golden.rms_on_support( + np.where(valid, dvv, np.nan), d["truth"], sup["support"], sup["baseline"] + ) + assert avail == 1.0 + assert rms_new == pytest.approx( + golden._rms(dvv, d["truth"], d["days"], valid), rel=1e-12 + ) + assert rms_new == pytest.approx( + golden.expected_metrics(case["id"])["rms"], rel=1e-9 + ) + + +def test_scorer_spec_carries_the_scoring_rule(): + row = fm.build_rows("dvv_series")[0] + assert row["scorer_spec"]["config"]["version"] == 2 + assert row["gold"]["support"] and row["gold"]["baseline"] + assert row["version"] == "v0.2" + + def test_unknown_scorer_name_raises(): with pytest.raises(ValueError): fm.make_scorer_from_spec({"name": "not_a_scorer"}) def test_parse_config_from_messy_text(): - txt = ("Here is my recommendation:\n```json\n" - '{"estimator": "MWCS", "band": [0.5, 1.5], "window": [8, 25]}\n```\n' - "Hope this helps.") + txt = ( + "Here is my recommendation:\n```json\n" + '{"estimator": "MWCS", "band": [0.5, 1.5], "window": [8, 25]}\n```\n' + "Hope this helps." + ) cfg = fm.parse_config(txt) assert cfg["estimator"] == "MWCS" and cfg["band"] == [0.5, 1.5] diff --git a/tests/test_stretching_interpolation.py b/tests/test_stretching_interpolation.py new file mode 100644 index 0000000..2ea5cf1 --- /dev/null +++ b/tests/test_stretching_interpolation.py @@ -0,0 +1,314 @@ +"""Interpolation direction and exactness of the stretching-family estimators. + +``tests/test_sign_convention.py`` locks the *sign* every estimator reports. +This file is about a narrower, related property: the trial-epsilon search +resamples the **current** waveform at ``(1 + eps) * t`` and leaves the +**reference** fixed (never the other way around), and the fitted ``eps`` is +converted to physical ``dv/v`` via the *exact* map ``-eps / (1 + eps)``, not +the first-order ``-eps``. + +Every "recovers truth" test elsewhere in this repo builds its truth-known +input with :func:`codameter.synthetic_demo.impose_dvv` and then checks +recovery with an estimator from the same module -- a self-consistency check +that would pass even if generator and estimator were *both* wrong in the +same way (this is exactly the pre-v0.4.0 failure mode: internally coherent, +anticorrelated with reality). ``test_independent_analytic_oracle_*`` below +is deliberately built without calling ``impose_dvv`` or ``make_coda`` at +all, so it does not share that blind spot. +""" + +from __future__ import annotations + +import contextlib +import warnings as _warnings_module + +import numpy as np +import pytest +from codameter.synthetic_demo import ( + Synth, + _stretch_window, + _window_mask, + bandpass, + daily_ccfs, + dvv_to_epsilon, + eps_to_dvv, + impose_dvv, + make_coda, + measure_stretching, + measure_stretching_trailing, + peak_dvv, + stretching_cc, +) + +BAND = (0.3, 2.0) +WINDOW = (8.0, 35.0) +FS = 50.0 + + +# --------------------------------------------------------------------------- +# 1. Truth-known regression, both signs, small and large (requirement 8) +# --------------------------------------------------------------------------- +DVV_GRID = [0.0, 0.001, -0.001, 0.01, -0.01, 0.04, -0.04, 0.05, -0.05] + + +@pytest.mark.parametrize("dvv_true", DVV_GRID) +def test_stretching_recovers_physical_dvv(dvv_true): + """dv/v in {0, +/-0.001, +/-0.01, +/-0.04, +/-0.05}, both signs.""" + s = Synth() + cur = impose_dvv(s.ref, s.t, dvv_true)[None, :] + rec, cc = measure_stretching( + cur, s.ref, s.t, band=BAND, fs=FS, window=WINDOW, eps_max=0.06 + ) + assert rec[0] == pytest.approx(dvv_true, abs=2e-4) + assert cc[0] > 0.99 + + +# --------------------------------------------------------------------------- +# 2. Independent analytic oracle -- NOT impose_dvv/make_coda (requirement 9) +# --------------------------------------------------------------------------- +def _handbuilt_coda(t: np.ndarray) -> np.ndarray: + """A closed-form multi-tone damped coda -- no random phases, no + radiative-transfer envelope, nothing shared with synthetic_demo's coda + machinery (:func:`make_coda`/:func:`rt_envelope_2d`).""" + freqs = np.array([0.6, 0.9, 1.3, 1.7]) + phases = np.array([0.3, 1.1, 2.4, 0.7]) + ref = np.zeros_like(t) + for f, p in zip(freqs, phases, strict=True): + ref += np.sin(2 * np.pi * f * t + p) + ref *= np.exp(-np.abs(t) / 8.0) + return ref + + +@pytest.mark.parametrize("dvv_true", [-0.04, -0.01, 0.001, 0.0, 0.01, 0.04]) +def test_independent_analytic_oracle_recovers_dvv(dvv_true): + """Truth built without impose_dvv/make_coda: a shared generator+estimator + bug (the actual pre-v0.4.0 failure) cannot hide behind this test.""" + t = np.arange(-2500, 2501) / FS # +/-50 s, independent of Synth() + reference = _handbuilt_coda(t) + # Physical relation applied by hand: current(t) = reference(t*(1+dvv)). + current = np.interp(t * (1.0 + dvv_true), t, reference)[None, :] + rec, cc = measure_stretching( + current, reference, t, band=BAND, fs=FS, window=WINDOW, eps_max=0.06 + ) + assert rec[0] == pytest.approx(dvv_true, abs=2e-3) + assert cc[0] > 0.99 + + +# --------------------------------------------------------------------------- +# 3. Reciprocity: current-interpolated vs. reference-interpolated (req. 10) +# --------------------------------------------------------------------------- +def _reference_interpolated_stretching_cc( + cur_mat, ref, t, *, band, fs, window, eps_max, n_eps +): + """Test-local re-implementation of the *old* (pre-this-change) operator: + resample REFERENCE at t/(1+e), hold CURRENT fixed. Not part of the + public API -- exists only so this test can compare the two conventions + against each other on the same data.""" + cur_mat = np.atleast_2d(cur_mat) + reff = bandpass(ref, fs, *band) + es = np.linspace(-eps_max, eps_max, n_eps) + sel = _window_mask(t, window, "both") + trials = np.stack([np.interp(t / (1.0 + e), t, reff)[sel] for e in es]) + trials = trials / (np.linalg.norm(trials, axis=1, keepdims=True) + 1e-12) + curf = bandpass(cur_mat, fs, *band)[:, sel] + curf = curf / (np.linalg.norm(curf, axis=1, keepdims=True) + 1e-12) + return es, curf @ trials.T + + +@pytest.mark.parametrize("dvv_true", [-0.03, -0.005, 0.005, 0.03]) +def test_current_and_reference_interpolation_agree(dvv_true, capsys): + """Both conventions, converted through the same exact eps_to_dvv map, + must agree on an ideal continuously-dilated synthetic up to + finite-window/interpolation error. Report the discrepancy.""" + s = Synth() + cur = impose_dvv(s.ref, s.t, dvv_true) + + es_new, cc_new = stretching_cc( + cur[None, :], + s.ref, + s.t, + band=BAND, + fs=FS, + window=WINDOW, + eps_max=0.06, + n_eps=161, + ) + dvv_new, _ = peak_dvv(es_new, cc_new) + + es_old, cc_old = _reference_interpolated_stretching_cc( + cur[None, :], + s.ref, + s.t, + band=BAND, + fs=FS, + window=WINDOW, + eps_max=0.06, + n_eps=161, + ) + dvv_old, _ = peak_dvv(es_old, cc_old) + + discrepancy = float(dvv_new[0] - dvv_old[0]) + print( + f"dvv_true={dvv_true:+.4f} current-interp={dvv_new[0]:+.6f} " + f"reference-interp={dvv_old[0]:+.6f} discrepancy={discrepancy:+.2e}" + ) + assert abs(discrepancy) < 5e-4, ( + f"current-interp ({dvv_new[0]:+.6f}) and reference-interp " + f"({dvv_old[0]:+.6f}) disagree by {discrepancy:+.2e}, more than the " + "finite-window/interpolation tolerance" + ) + + +# --------------------------------------------------------------------------- +# 4. Bias-characterization sweeps (requirement 11) +# --------------------------------------------------------------------------- +def _recover( + dvv_true, *, fs=FS, band=BAND, window=WINDOW, snr=None, seed=0, eps_max=0.06 +): + t, ref = make_coda(fs=fs, band=(0.05, min(10.0, fs / 2 - 0.5)), seed=seed) + cur = impose_dvv(ref, t, dvv_true) + if snr is not None: + ccfs = daily_ccfs(t, [ref], [np.array([dvv_true])], fs=fs, snr=snr, seed=seed) + cur = ccfs[0] + rec, cc = measure_stretching( + cur[None, :], ref, t, band=band, fs=fs, window=window, eps_max=eps_max + ) + return float(rec[0]), float(cc[0]) + + +@pytest.mark.parametrize("dvv_true", [0.001, 0.01, 0.02, 0.03, 0.04, 0.05]) +def test_bias_vs_epsilon_magnitude(dvv_true): + rec, cc = _recover(dvv_true) + bias = rec - dvv_true + print( + f"eps sweep: dvv_true={dvv_true:+.4f} recovered={rec:+.6f} bias={bias:+.2e} cc={cc:.4f}" + ) + assert abs(bias) < 5e-4 + + +@pytest.mark.parametrize("fs", [20.0, 50.0, 100.0, 200.0]) +def test_bias_vs_sampling_interval(fs): + rec, cc = _recover(0.02, fs=fs) + bias = rec - 0.02 + print(f"fs sweep: fs={fs:g} recovered={rec:+.6f} bias={bias:+.2e} cc={cc:.4f}") + assert abs(bias) < 1.5e-3 + + +@pytest.mark.parametrize( + "window", [(3.0, 12.0), (8.0, 35.0), (5.0, 45.0), (20.0, 45.0)] +) +def test_bias_vs_window_position_and_length(window): + rec, cc = _recover(0.02, window=window) + bias = rec - 0.02 + print( + f"window sweep: window={window} recovered={rec:+.6f} bias={bias:+.2e} cc={cc:.4f}" + ) + assert abs(bias) < 2e-3 + + +@pytest.mark.parametrize("band", [(0.2, 0.8), (0.3, 2.0), (1.0, 4.0), (3.0, 8.0)]) +def test_bias_vs_bandwidth(band): + window = (8.0, 35.0) if band[1] <= 2.0 else (3.0, 12.0) + rec, cc = _recover(0.02, band=band, window=window) + bias = rec - 0.02 + print(f"band sweep: band={band} recovered={rec:+.6f} bias={bias:+.2e} cc={cc:.4f}") + assert abs(bias) < 3e-3 + + +@pytest.mark.parametrize("snr", [1.0, 3.0, 8.0, 20.0]) +def test_bias_vs_additive_noise(snr): + rec, cc = _recover(0.02, snr=snr, seed=11) + bias = rec - 0.02 + print(f"noise sweep: snr={snr:g} recovered={rec:+.6f} bias={bias:+.2e} cc={cc:.4f}") + # Noise widens scatter, not bias, for the stretching estimator; allow more + # slack at low SNR since a single noisy day is being measured. + assert abs(bias) < (0.02 if snr < 2 else 0.01) + + +# --------------------------------------------------------------------------- +# 5. eps_to_dvv / dvv_to_epsilon: inverses + domain guards +# --------------------------------------------------------------------------- +@pytest.mark.parametrize("eps", [-0.5, -0.1, -0.01, 0.0, 0.01, 0.1, 0.5]) +def test_eps_dvv_round_trip(eps): + dvv = eps_to_dvv(eps) + assert dvv_to_epsilon(dvv) == pytest.approx(eps, abs=1e-12) + + +def test_eps_to_dvv_domain_guard(): + with pytest.raises(ValueError): + eps_to_dvv(-1.0) + with pytest.raises(ValueError): + eps_to_dvv(-1.5) + + +def test_dvv_to_epsilon_domain_guard(): + with pytest.raises(ValueError): + dvv_to_epsilon(-1.0) + with pytest.raises(ValueError): + dvv_to_epsilon(-2.0) + + +def test_eps_to_dvv_matches_first_order_only_for_small_eps(): + """dv/v = -eps is a first-order approximation, not exact; the deviation + from the exact map is eps^2/(1+eps) ~ +eps^2 for small eps (exact = + -eps/(1+eps) = -eps + eps^2 - eps^3 + ... = approx + eps^2 - ...).""" + eps = np.array([0.001, 0.01, 0.02, 0.04]) + exact = eps_to_dvv(eps) + approx = -eps + deviation = exact - approx + assert np.allclose(deviation, eps**2 / (1.0 + eps), atol=1e-10) + + +# --------------------------------------------------------------------------- +# 6. Common valid-support window: no silent extrapolation +# --------------------------------------------------------------------------- +@contextlib.contextmanager +def warnings_as_errors(): + with _warnings_module.catch_warnings(): + _warnings_module.simplefilter("error") + yield + + +def test_stretch_window_shrinks_and_warns_when_unsafe(): + t = np.arange(-500, 501) / 50.0 # +/-10 s + with pytest.warns(UserWarning, match="shrunk"): + sel, (w0, w1) = _stretch_window(t, (2.0, 9.8), eps_max=0.06, branch="both") + assert w1 < 9.8 + assert w1 * 1.06 <= 10.0 + 1e-9 + + +def test_stretch_window_no_warning_when_safe(): + t = np.arange(-2500, 2501) / 50.0 # +/-50 s + with warnings_as_errors(): + sel, (w0, w1) = _stretch_window(t, WINDOW, eps_max=0.06, branch="both") + assert (w0, w1) == WINDOW + + +def test_stretch_window_raises_if_no_window_fits(): + t = np.arange(-100, 101) / 50.0 # +/-2 s + with pytest.raises(ValueError): + _stretch_window(t, (5.0, 10.0), eps_max=0.06, branch="both") + + +# --------------------------------------------------------------------------- +# 7. measure_stretching_trailing matches the day-by-day loop it replaces +# --------------------------------------------------------------------------- +def test_trailing_matches_day_by_day_loop(): + """Documented contract: numerically equivalent (float rounding) to + calling measure_stretching day by day against the trailing mean.""" + s = Synth() + days = np.arange(0, 200) + truth = 0.005 * np.sin(2 * np.pi * days / 60) + 0.01 * (days > 120) + ccfs = daily_ccfs(s.t, [s.ref], [truth], fs=s.fs, snr=8.0, seed=5) + + ref_days = 30 + dvv_vec, cc_vec = measure_stretching_trailing( + ccfs, s.t, band=BAND, fs=FS, window=WINDOW, ref_days=ref_days, eps_max=0.06 + ) + for d in (50, 100, 130, 150, 190): + ref = ccfs[d - ref_days : d].mean(axis=0) + dvv_loop, cc_loop = measure_stretching( + ccfs[d], ref, s.t, band=BAND, fs=FS, window=WINDOW, eps_max=0.06 + ) + assert dvv_vec[d] == pytest.approx(dvv_loop[0], abs=1e-10) + assert cc_vec[d] == pytest.approx(cc_loop[0], abs=1e-10) diff --git a/tests/test_uq_bayes.py b/tests/test_uq_bayes.py index c0c1510..0e281c0 100644 --- a/tests/test_uq_bayes.py +++ b/tests/test_uq_bayes.py @@ -4,7 +4,6 @@ import numpy as np import pytest - from codameter import uq_bayes as B from codameter.synthetic_demo import Synth, _days, daily_ccfs, volcano_truth @@ -16,8 +15,17 @@ def bayes_run(): truth = volcano_truth(days) ccfs = daily_ccfs(s.t, [s.ref], [truth], fs=s.fs, snr=8.0, seed=5) res, run = B.bayes_dvv_from_ccfs( - ccfs, s.t, s.fs, truth=truth, days=days, cadence=6, - n_iter=400, burn=150, thin=2, seed=0) + ccfs, + s.t, + s.fs, + truth=truth, + days=days, + cadence=6, + n_iter=400, + burn=150, + thin=2, + seed=0, + ) return res, run @@ -59,3 +67,194 @@ def test_posterior_tracks_truth(bayes_run): v = np.isfinite(res.mu_mean) & np.isfinite(run.truth) rms = np.sqrt(np.mean((res.mu_mean[v] - run.truth[v]) ** 2)) assert rms < 2e-3 + + +def test_decomposition_is_floor_plus_excess_spread(bayes_run): + """UQ-03/04: total^2 = within^2 + method^2 with method the spread in excess + of the calibrated floor, so the floor is never counted twice.""" + res, run = bayes_run + np.testing.assert_allclose( + res.total_std**2, res.within_std**2 + res.method_std**2, rtol=1e-10 + ) + assert np.all(res.total_std + 1e-15 >= res.within_std) + assert res.beta_mean is not None and res.beta_mean.shape == (run.members.shape[0],) + assert res.n_obs is not None and res.n_obs.max() <= run.members.shape[0] + + +# --------------------------------------------------------------------------- +# Ensemble semantics (UQ-05) +# --------------------------------------------------------------------------- +@pytest.fixture(scope="module") +def small_ccfs(): + s = Synth() + days = _days(0.7) + truth = volcano_truth(days) + ccfs = daily_ccfs(s.t, [s.ref], [truth], fs=s.fs, snr=8.0, seed=11) + return s, days, truth, ccfs + + +def test_ensemble_honors_reference_and_gate(small_ccfs): + s, days, truth, ccfs = small_ccfs + base = { + "estimator": "stretching (TS)", + "band": (0.4, 1.0), + "window": (8, 28), + "stack": 5, + "reference": "fixed", + "gate": False, + } + fixed_gated = dict(base, gate=True) + moving = dict(base, reference="moving") + run = B.run_processing_ensemble( + ccfs, s.t, s.fs, [base, fixed_gated, moving], cadence=3, days=days + ) + assert len(set(run.labels)) == 3 + assert not np.array_equal(run.members[0], run.members[2], equal_nan=True) + # The moving reference has a warm-up gap; it is NaN, not a number. + assert np.isnan(run.members[2][0]) + assert np.isfinite(run.members[0][0]) + with pytest.raises(ValueError, match="inversion"): + B.run_processing_ensemble( + ccfs, s.t, s.fs, [dict(base, reference="inversion")], days=days + ) + + +def test_stack_is_in_days_and_output_is_decimated_after(small_ccfs): + """A 5-day stack is five days at every cadence: the cadence-3 members are + exactly the cadence-1 members subsampled (audit UQ-05).""" + s, days, truth, ccfs = small_ccfs + cfg = { + "estimator": "stretching (TS)", + "band": (0.4, 1.0), + "window": (8, 28), + "stack": 5, + "reference": "fixed", + "gate": False, + } + r1 = B.run_processing_ensemble(ccfs, s.t, s.fs, [cfg], cadence=1, days=days) + r3 = B.run_processing_ensemble(ccfs, s.t, s.fs, [cfg], cadence=3, days=days) + np.testing.assert_array_equal(r3.members[0], r1.members[0][::3]) + np.testing.assert_array_equal(r3.within_sigma[0], r1.within_sigma[0][::3]) + np.testing.assert_array_equal(r3.times_days, r1.times_days[::3]) + # Floors are NaN (missing), never clipped, where coherence is too low. + assert np.all(np.isnan(r1.within_sigma[0]) | (r1.within_sigma[0] > 0)) + + +# --------------------------------------------------------------------------- +# Sampler semantics: missing data, physical time, priors, shared artefacts +# --------------------------------------------------------------------------- +@pytest.mark.parametrize("days", [[0, 1, 3], [0, 2, 4], [2, 1, 0], [0, 1, np.nan]]) +def test_ensemble_rejects_non_daily_ccfs(days): + with pytest.raises(ValueError, match="complete daily grid"): + B.run_processing_ensemble(np.zeros((3, 5)), np.arange(5), 1.0, [], days=days) + + +@pytest.mark.parametrize("estimator", ["stretching (TS)", "MWCS"]) +def test_moving_reference_gate_masks_low_coherence(estimator, monkeypatch): + from codameter import deviations + + def measured(*args, return_cc=False, **kwargs): + values, valid = np.ones(3), np.ones(3, dtype=bool) + return ( + (values, valid, np.array([0.55, 0.65, 0.8])) + if return_cc + else (values, valid) + ) + + monkeypatch.setattr(deviations, "run_pipeline", measured) + config = dict( + estimator=estimator, + band=(0.4, 1), + window=(8, 28), + stack=5, + reference="moving", + gate=True, + ) + result = B.run_processing_ensemble( + np.zeros((3, 5)), np.arange(5), 1.0, [config], cadence=1 + ) + assert np.isnan(result.members[0, 0]) + assert np.isfinite(result.members[0, 1:]).all() + + +def _two_level_members(rng, t, K=4, noise=1e-4): + truth = np.where(t < t[len(t) // 2], 0.0, 1e-3) + M = truth[None, :] + noise * rng.standard_normal((K, t.size)) + return truth, M, np.full_like(M, noise) + + +def test_gibbs_prior_is_gap_aware(): + """UQ-05: a 1000-day gap must not be smoothed like one sample interval.""" + rng = np.random.default_rng(0) + t_gap = np.concatenate([np.arange(20.0), 1000.0 + np.arange(20.0)]) + truth, M, S = _two_level_members(rng, t_gap) + gap = B.gibbs_dvv(M, S, t_gap, n_iter=300, burn=100, thin=1, seed=1) + idx = B.gibbs_dvv(M, S, np.arange(40.0), n_iter=300, burn=100, thin=1, seed=1) + edge = slice(17, 23) + err_gap = np.max(np.abs(gap.mu_mean[edge] - truth[edge])) + err_idx = np.max(np.abs(idx.mu_mean[edge] - truth[edge])) + assert err_gap < 2e-4 + assert err_gap < err_idx + with pytest.raises(ValueError): + B.gibbs_dvv(M, S, t_gap[::-1], n_iter=10, burn=2) + + +def test_gibbs_handles_missing_members(): + rng = np.random.default_rng(2) + t = np.arange(50.0) + truth = 1e-3 * np.sin(2 * np.pi * t / 50) + M = truth[None, :] + 1e-4 * rng.standard_normal((3, 50)) + S = np.full_like(M, 1e-4) + M[0, :10] = np.nan # warm-up + M[1, 20:25] = np.nan # gated + S[2, 30:33] = np.nan # no usable coherence + res = B.gibbs_dvv(M, S, t, n_iter=300, burn=100, thin=1, seed=3) + assert np.isfinite(res.mu_mean).all() and np.isfinite(res.Cd).all() + assert res.n_obs is not None and list(res.n_obs[:3]) == [2, 2, 2] + assert np.max(np.abs(res.mu_mean - truth)) < 3e-4 + with pytest.raises(ValueError): + B.gibbs_dvv(np.full((2, 5), np.nan), S[:2, :5], t[:5], n_iter=10, burn=2) + + +def test_prior_sensitivity(): + """The hyper-priors are data-dominated at the defaults for a realistic + ensemble (prior share reported in ``prior_weight``); a tenfold change of + the scales moves tau and s by percent-level amounts and mu by far less + than sigma. A hundredfold b0 is *not* negligible for tau^2 with six + configurations and 3e-4 offsets; that limit is what prior_weight exposes.""" + rng = np.random.default_rng(4) + t = np.arange(80.0) + truth = 1e-3 * np.sin(2 * np.pi * t / 80) + M = ( + truth[None, :] + + 2e-4 * rng.standard_normal((6, 80)) + + 3e-4 * rng.standard_normal((6, 1)) + ) + S = np.full_like(M, 2e-4) + kw = dict(n_iter=600, burn=200, thin=1, seed=5) + a = B.gibbs_dvv(M, S, t, **kw) + assert a.prior_weight is not None + assert a.prior_weight["tau2"] < 0.1 + assert a.prior_weight["s2"] < 1e-3 + # The smoothness prior's scale matters more the smoother the truth: for + # this pure sinusoid the curvature term is tiny and lam_b supplies ~9%. + assert a.prior_weight["lambda"] < 0.2 + b = B.gibbs_dvv(M, S, t, a0=3.0, b0=1e-7, lam_b=1e-9, **kw) + assert abs(b.s / a.s - 1) < 0.15 + assert abs(b.tau / a.tau - 1) < 0.25 + assert np.max(np.abs(a.mu_mean - b.mu_mean)) < 0.3 * np.median(a.total_std) + c = B.gibbs_dvv(M, S, t, b0=1e-6, **kw) + assert c.prior_weight is not None and c.prior_weight["tau2"] > 0.5 + + +def test_shared_artifact_is_not_detected(): + """Documented limitation (UQ-04): an error every configuration shares leaves + no trace in the ensemble spread, so Cd cannot cover it. Four identical + sinusoidal members with a zero truth: the error is ~30x the Cd sigma.""" + t = np.arange(30.0) + shared = 0.003 * np.sin(2 * np.pi * t / 30) + M = np.tile(shared, (4, 1)) + S = np.full_like(M, 2e-4) + res = B.gibbs_dvv(M, S, t, n_iter=600, burn=200, thin=2, seed=11) + err_rms = np.sqrt(np.mean(res.mu_mean**2)) + assert err_rms > 10 * np.median(np.sqrt(np.diag(res.Cd))) diff --git a/tests/test_uq_measurement.py b/tests/test_uq_measurement.py index bdf8ff2..a772b54 100644 --- a/tests/test_uq_measurement.py +++ b/tests/test_uq_measurement.py @@ -4,35 +4,79 @@ import numpy as np import pytest - from codameter.uq_measurement import ( + bandwidth_timescale, effective_sample_size, global_reference_inversion, processing_ensemble, single_reference_dvv, temporal_error_covariance, + weaver_rms_dilation, weaver_stretching_error, + weaver_stretching_error_band, ) def test_weaver_error_monotone_in_coherence(): """Lower coda coherence -> larger error; longer window -> smaller error.""" - assert weaver_stretching_error(0.8, 1.0, 5, 30) > weaver_stretching_error( - 0.99, 1.0, 5, 30 + assert weaver_stretching_error(0.8, 1.0, 5, 30, 1.0) > weaver_stretching_error( + 0.99, 1.0, 5, 30, 1.0 ) - assert weaver_stretching_error(0.95, 1.0, 5, 10) > weaver_stretching_error( - 0.95, 1.0, 5, 40 + assert weaver_stretching_error(0.95, 1.0, 5, 10, 1.0) > weaver_stretching_error( + 0.95, 1.0, 5, 40, 1.0 ) def test_weaver_error_vectorised_and_validated(): - out = weaver_stretching_error(np.array([0.9, 0.95, 0.99]), 1.0, 5, 30) + out = weaver_stretching_error(np.array([0.9, 0.95, 0.99]), 1.0, 5, 30, 1.0) assert out.shape == (3,) assert np.all(np.diff(out) < 0) # decreasing with coherence with pytest.raises(ValueError): - weaver_stretching_error(1.5, 1.0, 5, 30) + weaver_stretching_error(1.5, 1.0, 5, 30, 1.0) + with pytest.raises(ValueError): + weaver_stretching_error(0.9, 1.0, 30, 5, 1.0) + with pytest.raises(ValueError): + weaver_stretching_error(0.9, 1.0, 5, 30, 0.0) + + +def test_weaver_eq20_prefactor_matches_weaver_eq21(): + """Weaver et al. (2011) eq. 21: t1=12.5, t2=50 us, omega_c=15 rad/us, T=0.56 us + give rms(eps) = 4e-4 * sqrt(1-X^2)/(2X) (their rounding).""" + for X in (0.5, 0.9, 0.99): + expect = 4e-4 * np.sqrt(1 - X**2) / (2 * X) + assert weaver_rms_dilation(X, 15.0, 12.5, 50.0, 0.56) == pytest.approx( + expect, rel=0.05 + ) + + +def test_weaver_error_is_dimensionless(): + """The same physical setup in seconds and in milliseconds gives one number + (audit UQ-01: the pre-0.5 formula lacked the bandwidth timescale and scaled + with the time unit).""" + a = weaver_rms_dilation(0.9, 2 * np.pi * 1.0, 10.0, 30.0, 0.5) + b = weaver_rms_dilation(0.9, 2 * np.pi * 1e-3, 1e4, 3e4, 500.0) + assert a == pytest.approx(b, rel=1e-12) + + +def test_weaver_bandwidth_scaling(): + """Floor scales as 1/sqrt(B); band tuple and (centre, width) forms agree.""" + narrow = weaver_stretching_error(0.9, 1.0, 5, 30, bandwidth_hz=0.5) + wide = weaver_stretching_error(0.9, 1.0, 5, 30, bandwidth_hz=2.0) + assert narrow / wide == pytest.approx(2.0, rel=1e-12) + assert weaver_stretching_error_band(0.9, (0.5, 1.5), 5, 30) == pytest.approx( + weaver_stretching_error(0.9, 1.0, 5, 30, 1.0) + ) + with pytest.raises(ValueError): + weaver_stretching_error_band(0.9, (1.5, 0.5), 5, 30) + + +def test_bandwidth_timescale_convention(): + """Band edges sit at the -10 dB points of Weaver's Gaussian spectrum.""" + B = 2.0 + T = bandwidth_timescale(B) + assert np.sqrt(np.log(10.0)) / T == pytest.approx(np.pi * B) with pytest.raises(ValueError): - weaver_stretching_error(0.9, 1.0, 30, 5) + bandwidth_timescale(-1.0) def test_processing_ensemble_total_variance(): diff --git a/tests/test_uq_processing.py b/tests/test_uq_processing.py index dd13379..c01c973 100644 --- a/tests/test_uq_processing.py +++ b/tests/test_uq_processing.py @@ -4,9 +4,10 @@ import numpy as np import pytest - from codameter.uq_processing import ( + ProcessingChoice, ProcessingPrior, + choice_floor, flatten_end_lapse, per_band_marginal_error, sample_processing_choices, @@ -28,23 +29,56 @@ def test_sample_choices_are_valid_windows(): assert len(choices) == 500 assert all(c.t2_s > c.t1_s for c in choices) assert all(c.f_center_hz in (0.7, 1.5, 3.0) for c in choices) + assert all( + c.bandwidth_hz == pytest.approx(prior.relative_bandwidth * c.f_center_hz) + for c in choices + ) assert all(0.6 <= c.cc <= 0.999 for c in choices) assert {c.rule for c in choices} <= {"fixed", "envelope_pick_flatten", "moving"} -def test_per_band_total_variance_decomposition(): +def test_per_band_zero_mean_mixture_has_no_spread_term(): + """Audit UQ-02: with no conditional means, Var(Y) = E_c[sigma_c^2] exactly; + the floor's own variability across choices must not be added.""" + choices = [ + ProcessingChoice("fixed", 1.0, 1.0, 10.0, 20.0, 0.9), + ProcessingChoice("fixed", 1.0, 1.0, 20.0, 40.0, 0.9), + ] + floors = np.array([choice_floor(c) for c in choices]) + assert floors[0] != floors[1] + out = per_band_marginal_error(choices)[1.0] + assert out["processing"] == 0.0 + assert out["sd"] ** 2 == pytest.approx(np.mean(floors**2), rel=1e-12) + assert out["total"] == out["sd"] + assert out["bias"] == 0.0 and out["rmse"] == out["sd"] + + +def test_per_band_spread_from_conditional_means_and_bias_kept_separate(): prior = ProcessingPrior(bands_hz=[0.7, 1.5, 3.0]) rng = np.random.default_rng(1) choices = sample_processing_choices(prior, 3000, rng) - pbe = per_band_marginal_error(choices, band_bias={0.7: 5e-4, 1.5: 5e-4, 3.0: 5e-4}) - for _f, stats in pbe.items(): + means = [1e-3 * c.f_center_hz + 2e-4 * rng.standard_normal() for c in choices] + pbe = per_band_marginal_error( + choices, band_bias={0.7: 5e-4}, conditional_means=means + ) + for f, stats in pbe.items(): + idx = [i for i, c in enumerate(choices) if c.f_center_hz == f] + assert stats["processing"] == pytest.approx( + np.std(np.asarray(means)[idx], ddof=1), rel=1e-9 + ) np.testing.assert_allclose( - stats["total"] ** 2, - stats["within"] ** 2 + stats["processing"] ** 2, - rtol=1e-9, + stats["sd"] ** 2, stats["within"] ** 2 + stats["processing"] ** 2 ) + np.testing.assert_allclose( + stats["rmse"] ** 2, stats["sd"] ** 2 + stats["bias"] ** 2 + ) + assert pbe[0.7]["bias"] == 5e-4 and pbe[1.5]["bias"] == 0.0 + # a known bias changes the RMSE, never the centred SD + assert pbe[0.7]["rmse"] > pbe[0.7]["sd"] # higher frequency -> smaller floor (more cycles in the window) assert pbe[3.0]["within"] < pbe[0.7]["within"] + with pytest.raises(ValueError): + per_band_marginal_error(choices, conditional_means=means[:-1]) def test_processing_prior_validation(): diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..9f30837 --- /dev/null +++ b/uv.lock @@ -0,0 +1,3072 @@ +version = 1 +revision = 3 +requires-python = ">=3.10" +resolution-markers = [ + "python_full_version >= '3.15' and sys_platform == 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'win32'", + "python_full_version >= '3.15' and sys_platform == 'emscripten'", + "python_full_version == '3.14.*' and sys_platform == 'emscripten'", + "python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'emscripten'", + "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version < '3.11'", +] + +[[package]] +name = "ast-serialize" +version = "0.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e1/a9/11851c3e02a3fea2ddc9932d1fdc7d2edaeecc0d2e11bc5f2a7fde2b0934/ast_serialize-0.8.0.tar.gz", hash = "sha256:6c37c43e4004dfb42d321ddedc569dc17ff4259296f3af577c9ea46a809bc010", size = 845638, upload-time = "2026-08-07T11:29:02.152Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/34/16/6e520b57cd8c75914b38c670ad4593d13c22911e4306cc7165dab8b0789b/ast_serialize-0.8.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl", hash = "sha256:3d822605fa7bb326ef868d25fafced7fc660fa46d9b90c02ea86d5e2f5d325f7", size = 863924, upload-time = "2026-08-07T11:27:34.579Z" }, + { url = "https://files.pythonhosted.org/packages/03/e1/48802de9b22a2bcad42ec80601a17e3f69172fe4f590e6311bcc2b323aeb/ast_serialize-0.8.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:2efa40b068197d5efb62655b43baadb842ed71c4958cccd3e8b86a35726f0119", size = 1177662, upload-time = "2026-08-07T11:27:36.196Z" }, + { url = "https://files.pythonhosted.org/packages/38/d4/323438db76bded3a1f3523a3167b8325916b2ddceb2107a330c6ec9fcf4d/ast_serialize-0.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:db1b957291bca08c7e72f43a12357b2948e20775d970e3fc3dac0aa3160ab725", size = 1167072, upload-time = "2026-08-07T11:27:37.646Z" }, + { url = "https://files.pythonhosted.org/packages/77/82/53c5400b54144b56de8ed7f957fd1ccd97e42482009292ab46121d15f8dd/ast_serialize-0.8.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdc0d5b18ff8fb364e87923e47c0a91d0d69dbcaeaa274591f7fd26892cc3a3a", size = 1225497, upload-time = "2026-08-07T11:27:39.225Z" }, + { url = "https://files.pythonhosted.org/packages/44/5f/36c07327a8b91303fbf1382c7c3e8a2902072dbe1b9546138a5288e75ff0/ast_serialize-0.8.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9da7330f3e235bf7da89b8d39205c6350fc0c08a85379743f2df9fff87d6d980", size = 1227101, upload-time = "2026-08-07T11:27:40.799Z" }, + { url = "https://files.pythonhosted.org/packages/9d/48/5adf5c67addc7ddb328122208c6d375a84cf154984f412b4087330a157bd/ast_serialize-0.8.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f3186969ee66a9863b00acc6523ace44c56974eecb348a7ea4b228d9f0b80e19", size = 1424001, upload-time = "2026-08-07T11:27:42.708Z" }, + { url = "https://files.pythonhosted.org/packages/38/a1/70074dd3869d2b0e934f91891d8d6b734361cd3b80f85ca7ece2e668ecdd/ast_serialize-0.8.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40a57b73731be45da4fa41430c4d5dc94a24b3a4faba7b9e069978c0402064ea", size = 1245545, upload-time = "2026-08-07T11:27:44.4Z" }, + { url = "https://files.pythonhosted.org/packages/e3/be/53b9c0a8a6399950c2e3546bdfab96d2b299d5b114b47eb94fd3c49c4054/ast_serialize-0.8.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5075b9da3ef807eda752502446dfecea3b381c4900b7e27a5d5f4f899eb39951", size = 1248961, upload-time = "2026-08-07T11:27:45.781Z" }, + { url = "https://files.pythonhosted.org/packages/eb/13/3651d3812548a2bda15e26e5dd51aadb48cf682d0865370255fcf0e367dd/ast_serialize-0.8.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:293cc1c5bfa741f8e3fbe8175b9c07beee487c9a6fdbb25a5acad9f1df2d30a9", size = 1243877, upload-time = "2026-08-07T11:27:47.325Z" }, + { url = "https://files.pythonhosted.org/packages/21/a0/521f0bf000f675e9312a4aae2c8ba7a992405d072a85c485e08fd59433b9/ast_serialize-0.8.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e0910c3442a75216dde0f102d854ba2aaa71d2482e0ee213630b9bf29584fba3", size = 1293903, upload-time = "2026-08-07T11:27:49.264Z" }, + { url = "https://files.pythonhosted.org/packages/b1/7e/402fc902568aa2ee65865a3e151f000db0153da8ce6b1be4c9c349025f8d/ast_serialize-0.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:43dd6d596879bb1cb8a12cc9dae7bb10090a39a35883026c24f82488a195619a", size = 1401070, upload-time = "2026-08-07T11:27:50.947Z" }, + { url = "https://files.pythonhosted.org/packages/ff/7c/97d4b66c057f1706fc8be6dd532cc77c988794357c8f4ffdb6adabb39562/ast_serialize-0.8.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:8c9d537f59e936392cfd3597789d1390304dd659efc3c486ce7f40fb6b8a9f53", size = 1502602, upload-time = "2026-08-07T11:27:52.364Z" }, + { url = "https://files.pythonhosted.org/packages/89/6f/72cc3b71562001bba46e898ccfbf1844f7939b3e28912736206102f2e5a8/ast_serialize-0.8.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:f0190a33d7f97c65e9069f7a7f40499eea6b5cbe260c558378109caf20ce934b", size = 1495848, upload-time = "2026-08-07T11:27:53.803Z" }, + { url = "https://files.pythonhosted.org/packages/a0/53/d6f629d1e49308b2f363dae028baa213ec222c9106fa1f7f0d1f7b41499a/ast_serialize-0.8.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:77308ae6c5cf5264cc0f01a7c556ec77a9e68eb1f61b093534d698139fdc3b14", size = 1556556, upload-time = "2026-08-07T11:27:55.342Z" }, + { url = "https://files.pythonhosted.org/packages/ee/22/340f35dd8dfc6d412d53dc20699ca014b8d228db923e8ed4759c512b162c/ast_serialize-0.8.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:8d53a23f27e1ed3a36b2d26fd2a1a6228c8e85a1ed62ff7cdb44bd610769f20a", size = 1417822, upload-time = "2026-08-07T11:27:56.712Z" }, + { url = "https://files.pythonhosted.org/packages/11/29/6dde5c13fbebc051d3a6df4ec0a6fd1d5359333cc1193f7f609f3410b4d8/ast_serialize-0.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ffa5e7cb08f96fed9121f77b224151e41caf88feab9d652bb46c78202b6fbeda", size = 1445153, upload-time = "2026-08-07T11:27:58.275Z" }, + { url = "https://files.pythonhosted.org/packages/62/c5/f473a8ed030f7a0ca24b9849cca184677a50c053867a7b808c2e1289bbd3/ast_serialize-0.8.0-cp314-cp314t-win32.whl", hash = "sha256:fa70ed4dea0bb18b30a1789c77baa701d0ef30c474f2ccabdea61e25623a8827", size = 1063711, upload-time = "2026-08-07T11:27:59.793Z" }, + { url = "https://files.pythonhosted.org/packages/23/63/39e171fcd38ca057c2e1979d5ee81ac7a3502784abe3d83df7454f7a0978/ast_serialize-0.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d8b3c8eee4c1baef9d4e84d2a59a805501617127be42615cb48970b15b0892b6", size = 1103740, upload-time = "2026-08-07T11:28:01.405Z" }, + { url = "https://files.pythonhosted.org/packages/21/1c/d00762b399e7726d68d0a088cc946e3a4c60f1c6176f557608f672f627f3/ast_serialize-0.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:ac4f0a83c55a9b782f79ad55a5247b7db123c1db405959791c2ef886e9710c9f", size = 1076021, upload-time = "2026-08-07T11:28:02.947Z" }, + { url = "https://files.pythonhosted.org/packages/4c/11/911210c3c78923273a9211a2b6cfc4c8aa723b30dab3e1c8d19afb983b40/ast_serialize-0.8.0-cp315-abi3.abi3t-macosx_10_12_x86_64.whl", hash = "sha256:86b8a1e6d90467345356098b040150e82fbc26d24a7a202224b13dc1f6264ca0", size = 1177715, upload-time = "2026-08-07T11:28:04.654Z" }, + { url = "https://files.pythonhosted.org/packages/77/89/6282881c8587606638db153cbe21e1e0c4d1f3970dee1aa0610a1c62a026/ast_serialize-0.8.0-cp315-abi3.abi3t-macosx_11_0_arm64.whl", hash = "sha256:39e92ff8e8cb45947fe9007174b2950e1fb098e6abd00266a13cd3bcf6675068", size = 1169347, upload-time = "2026-08-07T11:28:06.1Z" }, + { url = "https://files.pythonhosted.org/packages/97/78/a9f846a03a340ff3728c915f23338ca742742f3292700559cdb3ad999b1e/ast_serialize-0.8.0-cp315-abi3.abi3t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c85d8d18db5b2dfcb3b7e38a4d600ca35504c0ed8a6f75cd1c811e4ffe248a15", size = 1225916, upload-time = "2026-08-07T11:28:07.654Z" }, + { url = "https://files.pythonhosted.org/packages/c0/15/aba6ef8a988a6eceb6f0359589aac509e29ae2dba67fd9bfd5af0c3f13e7/ast_serialize-0.8.0-cp315-abi3.abi3t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9830ff7e764f74d9eefb01170c61a9f0fd2c027dac5fcb72e064decd57d56371", size = 1227135, upload-time = "2026-08-07T11:28:09.504Z" }, + { url = "https://files.pythonhosted.org/packages/94/29/3f63d696ea7c5b8abadcecc3505be51bd900daaccc522ed8322fa5b05a93/ast_serialize-0.8.0-cp315-abi3.abi3t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6479d9722a4cd21b578f5478074c41e6169f04811996ec881655560f703a5bba", size = 1425040, upload-time = "2026-08-07T11:28:11.044Z" }, + { url = "https://files.pythonhosted.org/packages/e2/5d/0aac338604ff59df5774d4304307898982252f325ff7cafe31d52fedcb65/ast_serialize-0.8.0-cp315-abi3.abi3t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a63bed264e818cd83eec11feed0f50aa162542b91132ef58afebc857182763a5", size = 1246278, upload-time = "2026-08-07T11:28:12.519Z" }, + { url = "https://files.pythonhosted.org/packages/23/ca/9f1ef795bb724719532bd86dbec11e5b66857d3fbe9b6772baec0191a6ed/ast_serialize-0.8.0-cp315-abi3.abi3t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d187197d234aa45d6cfa2b096be5f666e8cc2e7eb3722d0ab8926293cf5720c", size = 1250029, upload-time = "2026-08-07T11:28:13.896Z" }, + { url = "https://files.pythonhosted.org/packages/dc/25/5e061372d2ed953b9ba3b9c4f73de3b8e9234cda3f6c088db4686801d0e1/ast_serialize-0.8.0-cp315-abi3.abi3t-manylinux_2_31_riscv64.whl", hash = "sha256:2d39a56282cfcc0d8eeea37267c754be59c98d48505c23b1dae5c6011f3813dd", size = 1243575, upload-time = "2026-08-07T11:28:15.37Z" }, + { url = "https://files.pythonhosted.org/packages/a8/c1/ae7da218053120635a4ca802366c69f707203641af95372eeb83f70dfd52/ast_serialize-0.8.0-cp315-abi3.abi3t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f7cc5f10386994c0f4844f1e6d6a97127e9b478660eb6dec2b257644f0acab64", size = 1294396, upload-time = "2026-08-07T11:28:16.813Z" }, + { url = "https://files.pythonhosted.org/packages/2e/89/271d1f49c5269fcddcc789ea3f25be401f6723fc1138aeda539f4d05516d/ast_serialize-0.8.0-cp315-abi3.abi3t-musllinux_1_2_aarch64.whl", hash = "sha256:6102f2f985c2e542be85cd857678ec9356fefa792b93cadfadd31139f5696f27", size = 1401987, upload-time = "2026-08-07T11:28:18.333Z" }, + { url = "https://files.pythonhosted.org/packages/55/be/4e7d77fcf571ac7cb5cf7115a20c36642bd7d29473b45dfaaefeb9618f90/ast_serialize-0.8.0-cp315-abi3.abi3t-musllinux_1_2_armv7l.whl", hash = "sha256:3a8660fe66667b76a6e9dccd1d33e66b229fde3b308db991c041609226c005b6", size = 1502904, upload-time = "2026-08-07T11:28:20.039Z" }, + { url = "https://files.pythonhosted.org/packages/8b/ae/ed1de2db7e019d4236fbc164ffa5ef9a6022a300a342bbf142d21b7c141e/ast_serialize-0.8.0-cp315-abi3.abi3t-musllinux_1_2_i686.whl", hash = "sha256:e7266307e5fba39836edb79def8608887af48820508bff3c5f2941e1e04d1534", size = 1496967, upload-time = "2026-08-07T11:28:21.734Z" }, + { url = "https://files.pythonhosted.org/packages/92/89/5fea507fae5c5f18b7dc7f95e5c00956574b8c717b8fd2049c504fab0b18/ast_serialize-0.8.0-cp315-abi3.abi3t-musllinux_1_2_ppc64le.whl", hash = "sha256:4ca7e6fd1ad845d1cc649dc2ecd499db2f8f46af5bf8da7b70dd858774cc038b", size = 1559041, upload-time = "2026-08-07T11:28:23.194Z" }, + { url = "https://files.pythonhosted.org/packages/42/71/478d69df21b64e064554a68134c94be304270316ca676a94e63c389a636a/ast_serialize-0.8.0-cp315-abi3.abi3t-musllinux_1_2_riscv64.whl", hash = "sha256:2880350b13d3eae69a0d70bc1fb6c9bfaca4dbd0e20ba8cd1aa483080b56ff06", size = 1417367, upload-time = "2026-08-07T11:28:24.601Z" }, + { url = "https://files.pythonhosted.org/packages/5e/2d/8962dc8d5b3a9dc27b36f9db199afa25264c741505469d9ec10ffbfd2ba7/ast_serialize-0.8.0-cp315-abi3.abi3t-musllinux_1_2_x86_64.whl", hash = "sha256:ab0f9a59f7d63d0d441b56b9a818b273705264352d5115cfee12e940e816d958", size = 1446178, upload-time = "2026-08-07T11:28:26.152Z" }, + { url = "https://files.pythonhosted.org/packages/4f/22/14d2ad4fd1d1bcd0dc687ca268e0630069f45162496260c0efb70ee0ea72/ast_serialize-0.8.0-cp315-abi3.abi3t-win32.whl", hash = "sha256:0485a25ef519c62e749ee3c1ad8070e591b380d67226349eb5a70b228dc1ac4a", size = 1063811, upload-time = "2026-08-07T11:28:27.864Z" }, + { url = "https://files.pythonhosted.org/packages/18/1d/84a327c0202a41aa5fdba3ade33904d6d8f3b9e6806fa83568d835395850/ast_serialize-0.8.0-cp315-abi3.abi3t-win_amd64.whl", hash = "sha256:bd84d60bca7079e741be4ac5dbe237751a59d7f6f9f0126b11880d63822cbe16", size = 1105518, upload-time = "2026-08-07T11:28:29.691Z" }, + { url = "https://files.pythonhosted.org/packages/8c/92/74556dec52fde85a2ad84ed159991b916241043788609c15d8b77e14570b/ast_serialize-0.8.0-cp315-abi3.abi3t-win_arm64.whl", hash = "sha256:057769b5921336eb2d9124f2a731b42ed05ffdac559b840dbdf6f3937cf153dc", size = 1076319, upload-time = "2026-08-07T11:28:31.282Z" }, + { url = "https://files.pythonhosted.org/packages/d1/5d/c650b1f2cc1e75193358da95a080261422e8cd10b66d7370b1688c9915c5/ast_serialize-0.8.0-cp315-cp315-pyemscripten_2026_5_wasm32.whl", hash = "sha256:a02cbed7d8bfdcdee88edaac12bd50d53d9953aaa2e1852ef078625be5f1c0b5", size = 852914, upload-time = "2026-08-07T11:28:32.929Z" }, + { url = "https://files.pythonhosted.org/packages/d9/e3/6142e920fec6ef7bccabd8c24ed8ed99f8bdc6cb8b065e1df7c6a3b2d667/ast_serialize-0.8.0-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:e1bd223df0f6c96b396975fa604cb33bce53d9b4a0185490be4c4a289f7c9c87", size = 1184007, upload-time = "2026-08-07T11:28:34.654Z" }, + { url = "https://files.pythonhosted.org/packages/a6/e9/6e8be8df02b35d85e2b8809f7f1cfa290bdf5882b55127a539d049482db0/ast_serialize-0.8.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:ddd3b61f45c132da66c5476b281891e08c1fd87fbdabe8a6973e1622efc85f06", size = 1177588, upload-time = "2026-08-07T11:28:36.318Z" }, + { url = "https://files.pythonhosted.org/packages/8c/80/7e0fd2e2e2aba257820db4a8657c4c356844d36b914b20a4af294bcfb902/ast_serialize-0.8.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f9caa63fad8241257ae401b5ff0a64026c6adb36b8e86cbe8782d9ea505daf6", size = 1234575, upload-time = "2026-08-07T11:28:37.772Z" }, + { url = "https://files.pythonhosted.org/packages/b0/6a/3bae0af06f9b1bae3001c44d64215f5b567877e7aae9ffd45db11c3a7647/ast_serialize-0.8.0-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3926fa117b5e65019853a2969966d11c7175af377a3425991f3fe73784412405", size = 1236015, upload-time = "2026-08-07T11:28:39.14Z" }, + { url = "https://files.pythonhosted.org/packages/6f/c4/ce2d41a1bc22508e82618901f7e10f2a5e2f9556553fea90624daf9875e2/ast_serialize-0.8.0-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:485f1113af805e9e170b95ef993ca3fbd4f89c04bab25c58b4fc632d854801ab", size = 1432808, upload-time = "2026-08-07T11:28:40.664Z" }, + { url = "https://files.pythonhosted.org/packages/1a/90/f5058f209756dd70e958b7538aaa82d25d24944baf9ec8ae6f27b06fcacc/ast_serialize-0.8.0-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ccebbed24f1281062d5852353c72c47502955926cfcb8345ffb3a44d87ff3d3", size = 1256251, upload-time = "2026-08-07T11:28:42.223Z" }, + { url = "https://files.pythonhosted.org/packages/bf/32/7f77ea87fa0836daab706ed5cb7f903bb25fa26a77439011aee626af11d8/ast_serialize-0.8.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:252f883290d1cdb728eb7fe1d9a7221b88af5a329aae0bc91ddee4dafb820331", size = 1258574, upload-time = "2026-08-07T11:28:43.751Z" }, + { url = "https://files.pythonhosted.org/packages/eb/5a/75b82ad2725b5e8e8c742732f9e76c6738a292d0709e1f60d10a973730b4/ast_serialize-0.8.0-cp39-abi3-manylinux_2_31_riscv64.whl", hash = "sha256:96abc072ad29db8d02194afd47d68987322622787daceae82398d7b69f3ba2e6", size = 1254075, upload-time = "2026-08-07T11:28:45.28Z" }, + { url = "https://files.pythonhosted.org/packages/4e/54/8c20ed4eea805516a3fd23dd4a721ce28c64f50f0e4b359969f60a8c97a6/ast_serialize-0.8.0-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9118ad3e369727060b2696fc4078f250ecffca4248ba87f537f55cea9f9dce06", size = 1301018, upload-time = "2026-08-07T11:28:46.851Z" }, + { url = "https://files.pythonhosted.org/packages/cb/5b/9f14430f12fe830b656fb38f8e2e05ee13b02a88967660bef46af0ab22a8/ast_serialize-0.8.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:f359df4bd921918af8bebd142a376c77511d7151cc8ba852760b587b5a4a54f3", size = 1409951, upload-time = "2026-08-07T11:28:48.312Z" }, + { url = "https://files.pythonhosted.org/packages/2d/3d/084882eca93c842bd4262591a071ec7f825340644035e51501208cc5a8d4/ast_serialize-0.8.0-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:e94f9121d13fa36cbf21314783c77d05ae3a0868decd18cf5233fdcc6de49ac8", size = 1509544, upload-time = "2026-08-07T11:28:49.847Z" }, + { url = "https://files.pythonhosted.org/packages/ce/73/ea84852096c2036c61cc0b2f97b90242207419f534dc671060ee1c8e05cb/ast_serialize-0.8.0-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:54f95b486018d262bcb387a9afd96f0da74508b442762b80c769454a6fbb3ee3", size = 1505671, upload-time = "2026-08-07T11:28:51.239Z" }, + { url = "https://files.pythonhosted.org/packages/cb/88/287b9a5300c1f2f651d259f670931b63110adc265b7613c885b44c5bc53d/ast_serialize-0.8.0-cp39-abi3-musllinux_1_2_ppc64le.whl", hash = "sha256:4c38b915511e32bc718c49dbce98ff9af36bac0ad6a604f58000cd5e3aecdba7", size = 1563685, upload-time = "2026-08-07T11:28:53.112Z" }, + { url = "https://files.pythonhosted.org/packages/ee/f3/1bc3a79afcf0c2a8d2c37182d0d659d1545a9d7f7f6dc9cf3e63d6c17135/ast_serialize-0.8.0-cp39-abi3-musllinux_1_2_riscv64.whl", hash = "sha256:9a2ef9cf12f2de4f1028c42c1dd7d775255e0fb3e5bb48896c97e35ef52366fe", size = 1427977, upload-time = "2026-08-07T11:28:54.418Z" }, + { url = "https://files.pythonhosted.org/packages/5c/cd/440c798957e14e31776bfeb024d8fafe0bb1d5b89c51c2f067e69938f7b0/ast_serialize-0.8.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6f18048fe9f6dd266bd577cdec48bdcecb74faaa01fe941324435483b013ed2a", size = 1454335, upload-time = "2026-08-07T11:28:55.968Z" }, + { url = "https://files.pythonhosted.org/packages/4f/4a/587eb36dcc240a54c8660f599464516b469ecad96f0dbdb6bccbedb50745/ast_serialize-0.8.0-cp39-abi3-win32.whl", hash = "sha256:31883542dd6c94d178f5db3d32fbd69c5eb88b3a7c018e7ac8cc0c45195ddbed", size = 1068858, upload-time = "2026-08-07T11:28:57.541Z" }, + { url = "https://files.pythonhosted.org/packages/5f/a4/3e887bbd92164e183cb6e412c6a3e9198ddd446d7fe405958293ef5ef49c/ast_serialize-0.8.0-cp39-abi3-win_amd64.whl", hash = "sha256:861794565b06337005c1447ef23103a3d5a627d08bdc827870d00d0b28ef5f51", size = 1111839, upload-time = "2026-08-07T11:28:59Z" }, + { url = "https://files.pythonhosted.org/packages/25/6c/b400476d3ceba681ab929787edc9554f6d88fcc69435eb681b00fc0457a5/ast_serialize-0.8.0-cp39-abi3-win_arm64.whl", hash = "sha256:b2a5978662fd4db463dfb4b974d2b10ac6430b98f5333aabc7051909df3561d0", size = 1083655, upload-time = "2026-08-07T11:29:00.349Z" }, +] + +[[package]] +name = "babel" +version = "2.18.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/b2/51899539b6ceeeb420d40ed3cd4b7a40519404f9baf3d4ac99dc413a834b/babel-2.18.0.tar.gz", hash = "sha256:b80b99a14bd085fcacfa15c9165f651fbb3406e66cc603abf11c5750937c992d", size = 9959554, upload-time = "2026-02-01T12:30:56.078Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl", hash = "sha256:e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35", size = 10196845, upload-time = "2026-02-01T12:30:53.445Z" }, +] + +[[package]] +name = "backrefs" +version = "8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ec/56/4744bcd0c82184e80c52b0ac4076c261a8ffa1f1b343ff2f6e89ce0e1cef/backrefs-8.0.tar.gz", hash = "sha256:b556cd7d36c3a3a2f256b89590b176b8eddfb73bcfaee3a3ddd84ea66d21ce50", size = 7013081, upload-time = "2026-07-26T19:54:24.638Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e3/fd/9bf53b6a6f6f519ffaac765df2f2a25e5c2fc6d32cfd2b2747099e72c911/backrefs-8.0-py310-none-any.whl", hash = "sha256:4a627b817fd2dce43b79ab48da63613340509381cd8ce0897078a0bce79a2ab8", size = 380377, upload-time = "2026-07-26T19:54:17.457Z" }, + { url = "https://files.pythonhosted.org/packages/e1/29/4bd7ae72a2634da00379c2b3bcc5439e7c94620235c6afea8af15229a973/backrefs-8.0-py311-none-any.whl", hash = "sha256:f0c35cf0102ba6b6070c12a492be3c1c1d3f5839529784b9a9565d6d04569a01", size = 392169, upload-time = "2026-07-26T19:54:18.782Z" }, + { url = "https://files.pythonhosted.org/packages/29/13/232505664e8e2a0c7a2eb0c505cfade9d715538f89a5d62bc4c272968f62/backrefs-8.0-py312-none-any.whl", hash = "sha256:87f0fae8c5f207fe9f4b2887efc71d42f4900ac78faa1af08d675ef303692dc5", size = 398084, upload-time = "2026-07-26T19:54:19.954Z" }, + { url = "https://files.pythonhosted.org/packages/8a/69/47a3dc20abc4fa5486655fde681bd55e63211b46c886d8c02223d6468431/backrefs-8.0-py313-none-any.whl", hash = "sha256:601ce68ca12385dbda06ce264406b4c4210cf5b79fd0fd627592365c92f29a88", size = 400040, upload-time = "2026-07-26T19:54:21.194Z" }, + { url = "https://files.pythonhosted.org/packages/1c/cf/e5f9b68a5b0e939a2fb933a66c20180d0c9241bf8927f7a47fa48c1675e9/backrefs-8.0-py314-none-any.whl", hash = "sha256:9ec96efa080938be92323e8e730e57718c9c88eb15ad70bbef4e1766df591408", size = 411903, upload-time = "2026-07-26T19:54:23.221Z" }, +] + +[[package]] +name = "black" +version = "26.5.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "mypy-extensions" }, + { name = "packaging" }, + { name = "pathspec" }, + { name = "platformdirs" }, + { name = "pytokens" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/37/5628dd55bf2b34257fc7603f0fe97c40e3aaf24265f416a9c85c95ca1436/black-26.5.1.tar.gz", hash = "sha256:dd321f668053961824bcc1be1cc1df748b2d7e4fa28086b08331e577b0100a73", size = 679439, upload-time = "2026-05-18T16:53:36.107Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/be/84/b3f55026206a9e8820a91503308075ca48eadc515e436731ca01dbe043b3/black-26.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9942db8888e06943c5dde66ca0037dcff82a2a4ec1ad0ada9e0d2ee9d9823893", size = 1987719, upload-time = "2026-05-18T17:05:02.757Z" }, + { url = "https://files.pythonhosted.org/packages/c6/34/7db312c5e5783d6e76cffd9d5ac8972a32badae4c6e3288dac0eed8d3bed/black-26.5.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:89c93167a74d3a75dfaa38a5c7cca015537d5820dd7f17d63267d674a61cae90", size = 1810083, upload-time = "2026-05-18T17:05:04.302Z" }, + { url = "https://files.pythonhosted.org/packages/33/e2/e0101e73c2c8727634e2efcb35e2b34bd23ad70dfa673789f5773a591b21/black-26.5.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22f2cd76d069cc54c71f10360744ba8983fbb616903b4304a85b734915c8e1b4", size = 1860633, upload-time = "2026-05-18T17:05:06.391Z" }, + { url = "https://files.pythonhosted.org/packages/b0/4c/e15c0c5b23cf3651035fe5addcce90e283af3548a3f91bb03d81b83106ab/black-26.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:87ed5c6f450580a2f6790bc7cbfb016dfc73bc750249762268a3695361315eef", size = 1477886, upload-time = "2026-05-18T17:05:07.96Z" }, + { url = "https://files.pythonhosted.org/packages/9f/3f/59d43ade98d2ce5c8dc34a4e46cbecd177e6d55d7d4092969c6003ccc655/black-26.5.1-cp310-cp310-win_arm64.whl", hash = "sha256:58b4bd92cf88aacf83d88479c8f9caee044b1ec55f2451a337354a7ea2590a22", size = 1277111, upload-time = "2026-05-18T17:05:09.473Z" }, + { url = "https://files.pythonhosted.org/packages/4b/96/3c3e09f09f44a37aac36b178a279cd19aa7001bd796187a7b162a294c81f/black-26.5.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:96ae2c733b2aabdd9986e2c5df628ff3473676cd1c5faded1ff496cf6d74083c", size = 1970639, upload-time = "2026-05-18T17:05:11.461Z" }, + { url = "https://files.pythonhosted.org/packages/83/ea/5ad117b9ee3ecd933c712bcbae610006e5b7cc9f41c526cd7ed3b6c4124c/black-26.5.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0e48b87e03bf109288e55cfceadcfa15ff5470aca2851a851950ed2926f450d7", size = 1792130, upload-time = "2026-05-18T17:05:12.983Z" }, + { url = "https://files.pythonhosted.org/packages/06/3a/7c448bc623fcdfa96672531beb5a616ea5e64f6975955254d7731ffb0ad9/black-26.5.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5119fa92ae61f786e8c3662fd60aece1d0a2dd5cca5d0c79417a95e7a4272a59", size = 1846134, upload-time = "2026-05-18T17:05:14.506Z" }, + { url = "https://files.pythonhosted.org/packages/a1/5b/0b39b3a5917f0657ac014ad2edb58c139553a478adfe7f817abf1622ff6e/black-26.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:30d3c14661f2792e9142cce3eeeb1cbc175b3eb5f733be0c8eeb99651e52b0c3", size = 1478883, upload-time = "2026-05-18T17:05:16.542Z" }, + { url = "https://files.pythonhosted.org/packages/4c/48/dc222692e0f95030db1bbfb6c857e76858bad09058221ea7aae815255327/black-26.5.1-cp311-cp311-win_arm64.whl", hash = "sha256:1ef92b76f7733f282fd096ea406200b5a286c42947412b0eaff3a74e3616cefe", size = 1277776, upload-time = "2026-05-18T17:05:18.029Z" }, + { url = "https://files.pythonhosted.org/packages/24/99/7744b906703228264ef73bdd534df88ec1ef3de45c4e78f6d31b9e32d0c9/black-26.5.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4ad6fa01f941920f54f2bbb35f3df7673428a0ef98a0b0840c2eaef3b110efa8", size = 2012518, upload-time = "2026-05-18T17:05:20.108Z" }, + { url = "https://files.pythonhosted.org/packages/b7/c0/c5a3b1636dfd09c42534f2b3cf33506814f6d3e066fb0879ffa16c1ae860/black-26.5.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3915f256e75a2d7cf88d8953d37f780455dc586cc72dee059c528fe77f581217", size = 1816016, upload-time = "2026-05-18T17:05:21.84Z" }, + { url = "https://files.pythonhosted.org/packages/1f/0e/36044316b65ca471d3bb6d3703fd06fb50c6b727c3562f6a5a3153634f88/black-26.5.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d98d4137277c75dfb898ec8d846c4fd68ba1e9cf77f95e2865c203dc18f4c3d", size = 1884150, upload-time = "2026-05-18T17:05:23.546Z" }, + { url = "https://files.pythonhosted.org/packages/b3/33/dafc5808c2af43672912111d7c3354af1615f7e2be3bed7a878461abbe4d/black-26.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:a1dca32d9f1784af512a13410ec204c6f7f0aa9797a111c42e1c03449821c264", size = 1486825, upload-time = "2026-05-18T17:05:25.004Z" }, + { url = "https://files.pythonhosted.org/packages/82/14/b965ee6ad2a311f28bdbf692def3ee9848d2ae289dab28b27657fcee3e78/black-26.5.1-cp312-cp312-win_arm64.whl", hash = "sha256:1037d5ac7b7b310b2632ad867ec8d0e4c4819dcdb0b820f63135da746a24e418", size = 1288646, upload-time = "2026-05-18T17:05:26.477Z" }, + { url = "https://files.pythonhosted.org/packages/3f/5c/c384363980e11e25ca6b93205949bb331fbf35f4e0dbec376dfa6326cec8/black-26.5.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2b36cf2ddf5566e205f6535f782a62194a184d33e175b64ae8c40b1737522be3", size = 2009020, upload-time = "2026-05-18T17:05:28.132Z" }, + { url = "https://files.pythonhosted.org/packages/0b/df/9f31c5e0babbfed77d505fc5d120beb98b21b33feaeded3924ea941fe360/black-26.5.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1f7ea64ebfa01b50f693508fc39f875e264446d3b097088f84f203b9d09618a0", size = 1813335, upload-time = "2026-05-18T17:05:31.266Z" }, + { url = "https://files.pythonhosted.org/packages/fb/24/8e7b9a2fa61b0afd82209efe937557d180a1fa055bd7f6161eb9defc3719/black-26.5.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecb3e624844c798144e9bd986954e0adc81d8911a1f30f375e1252fe26e8c294", size = 1881614, upload-time = "2026-05-18T17:05:32.718Z" }, + { url = "https://files.pythonhosted.org/packages/49/ad/b4e0d9365ba8ac34f6bbab62a4b1b2dd5d618fac3fa1b8db968c844201b5/black-26.5.1-cp313-cp313-win_amd64.whl", hash = "sha256:e1a26503279b6b310669fb0b219c39e4820b77e8189fe80f522bb511f247db0a", size = 1488925, upload-time = "2026-05-18T17:05:34.259Z" }, + { url = "https://files.pythonhosted.org/packages/a1/4b/652b859bf5df88a751c30451b09338f7fd26a77d1271c666992f836b7711/black-26.5.1-cp313-cp313-win_arm64.whl", hash = "sha256:5c34b25da232ead53a6f335b76dbea124f4d152ad568b9080d6f944bc2b34b52", size = 1289883, upload-time = "2026-05-18T17:05:36.019Z" }, + { url = "https://files.pythonhosted.org/packages/a6/16/a8da8eb208c51c7f4ce74609a45d0dcc6d8a2141e45e81ee5289d1bb0d59/black-26.5.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:e88976690a64b0af98312ca958415849cb42423423c5f2ee74af4b49a97a2168", size = 2004800, upload-time = "2026-05-18T17:05:38.182Z" }, + { url = "https://files.pythonhosted.org/packages/11/8a/a479296a19e383b70a725882a6cf3d786540601ff03cabbaaf1cce864c5a/black-26.5.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:32d5ea7f6c8bdfa6e648326ebca1f02b0764e2a029edc6f8dce2627e19d468c3", size = 1815576, upload-time = "2026-05-18T17:05:40.309Z" }, + { url = "https://files.pythonhosted.org/packages/81/6b/cfaf3d39f25132c156a068f6b805576c9103a84086019507c70e1911ee7d/black-26.5.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ea8d16dc41655aa113cd64665e7219446cd7e4ff2248d7178eaa905190c86b18", size = 1877927, upload-time = "2026-05-18T17:05:42.463Z" }, + { url = "https://files.pythonhosted.org/packages/66/76/302e313964bcff7e28df329d39f84f5270095730d85ff0acc260610a0d82/black-26.5.1-cp314-cp314-win_amd64.whl", hash = "sha256:577f21094ea469ef92ec1adaf2c9441a226d2144d01a5be2fa823cecf6543e50", size = 1511860, upload-time = "2026-05-18T17:05:43.943Z" }, + { url = "https://files.pythonhosted.org/packages/27/4e/a3827e35e0e567f9f9ee59e2a0ab979267dca98718f25547ca8c6733afd4/black-26.5.1-cp314-cp314-win_arm64.whl", hash = "sha256:ed1a20af114c301a0269bf01163d51dbef72737fd65f850001e7cbe7f3c7abae", size = 1316632, upload-time = "2026-05-18T17:05:45.521Z" }, + { url = "https://files.pythonhosted.org/packages/94/51/f975cae76d44274cc2868dc9040ac5d58d464784610234455b4e7b19c6ef/black-26.5.1-py3-none-any.whl", hash = "sha256:4ed7f7da04046d2e488437170797d3b4a4ad83906683bcb7dfc68b673bbce5e2", size = 213693, upload-time = "2026-05-18T16:53:33.964Z" }, +] + +[[package]] +name = "boto3" +version = "1.43.71" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "botocore" }, + { name = "jmespath" }, + { name = "s3transfer" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e0/ed/3220ca6396a7ce00a49aa6f43f20cae05ec6ac386e2b5d668adfad0b3eed/boto3-1.43.71.tar.gz", hash = "sha256:e3eddb6346ee23c895dd98e5c2cfc72cb5e5ed111aa6d4331f9e903a3e3bf4ee", size = 112630, upload-time = "2026-08-13T19:20:35.332Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4f/16/7b54e7f5271756ab13beaaf6da03f62edcc3ee5ded651c2b17297e107040/boto3-1.43.71-py3-none-any.whl", hash = "sha256:3bb46661dc33121e56e3706753069d18f8dbcb644599cf098206546338602e16", size = 140024, upload-time = "2026-08-13T19:20:32.542Z" }, +] + +[[package]] +name = "botocore" +version = "1.43.71" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jmespath" }, + { name = "python-dateutil" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d6/c2/98b8ff6a21a9ed99b0699f468446f26a679443b2bca46fcd6aaa0cfbae75/botocore-1.43.71.tar.gz", hash = "sha256:2cde7a55aaac86a2e9a3bcd2ce3fad1a31a4711749e10f350af231e55ccef7ed", size = 15943777, upload-time = "2026-08-13T19:20:29.292Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/2f/700d973e3f0a37a275900be1a389af5a4ab67dd9362d17782b17f1045f0b/botocore-1.43.71-py3-none-any.whl", hash = "sha256:7bc3d5ddaca6f68e2eef707714264789048a6f496d375d976c560674f0cd1d1b", size = 15635728, upload-time = "2026-08-13T19:20:26.302Z" }, +] + +[[package]] +name = "certifi" +version = "2026.7.22" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a3/c2/24167ea9858356b47a87a50d39908bfdb72ceeefe0041586e704e5376b3a/certifi-2026.7.22.tar.gz", hash = "sha256:741e2c3b351ddf169a738da9f2c048608ff7f2c5cc02f1ebc6b118bb090d5d55", size = 138112, upload-time = "2026-07-22T03:35:12.644Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0b/a7/71ac2cff56fec219ed242bb11b8efb69fcc4bec75db06fb7bfe35de520e6/certifi-2026.7.22-py3-none-any.whl", hash = "sha256:62f22742b58a1a33014a2b6b706588a8d7e2a88ae7bd1a6ebe8c992928483775", size = 136983, upload-time = "2026-07-22T03:35:11.276Z" }, +] + +[[package]] +name = "cfgv" +version = "3.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4e/b5/721b8799b04bf9afe054a3899c6cf4e880fcf8563cc71c15610242490a0c/cfgv-3.5.0.tar.gz", hash = "sha256:d5b1034354820651caa73ede66a6294d6e95c1b00acc5e9b098e917404669132", size = 7334, upload-time = "2025-11-19T20:55:51.612Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl", hash = "sha256:a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0", size = 7445, upload-time = "2025-11-19T20:55:50.744Z" }, +] + +[[package]] +name = "charset-normalizer" +version = "3.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cb/31/4971872b3ed8715346231fb6eb4da8fcba65a4143c189db151ee28a2812b/charset_normalizer-3.5.0.tar.gz", hash = "sha256:49bd5feb59b0bf3cbf6ebcf4352e371c95b9da9bacd4449f8b64d0ad2c10a26e", size = 169295, upload-time = "2026-08-12T14:35:31.624Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/8e/1e9a03657c2f12960c67b05e0550059787d4c8fc3fae822672f4fe7f40c5/charset_normalizer-3.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d2478bd3b2ead3962a484fb802891be40d10049fb74f83e09cb4463fad023fea", size = 349795, upload-time = "2026-08-12T14:31:47.546Z" }, + { url = "https://files.pythonhosted.org/packages/76/e5/a42c8884ec0321c56124a5b43c135efe75260dad4f70ea0ffba4dcac85ec/charset_normalizer-3.5.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7cdded069549b5eae3d5d9bb6c2e5bb4fe83f9b81863e2a193cd747bf197aebb", size = 250677, upload-time = "2026-08-12T14:31:48.918Z" }, + { url = "https://files.pythonhosted.org/packages/5d/21/d94021b005d2e660fd13634eecfe4ad378b0d0bbb45134809aed42b94a99/charset_normalizer-3.5.0-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:aff38231e3171c578b2c449a01afa44e9ff40844597a32873da102394f63d28e", size = 239868, upload-time = "2026-08-12T14:31:50.107Z" }, + { url = "https://files.pythonhosted.org/packages/47/d0/8b9b07e41501bfcdfe380b826481033ca2eb5fa4b5507eb64dbc4cba9885/charset_normalizer-3.5.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4346a693c08b1d0cfc0e3325bfb0ecd4322fb1a6904d68cf416f8da5e981b234", size = 280688, upload-time = "2026-08-12T14:31:51.182Z" }, + { url = "https://files.pythonhosted.org/packages/a8/29/b83b3469e596adff778bf3c8ca8f705822c1c3c0ada8477a0d00113bfa59/charset_normalizer-3.5.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b787efadba00f5da6fe89513bfbe3852d52ca3a448fdec165765cb3b44a80248", size = 277133, upload-time = "2026-08-12T14:31:52.362Z" }, + { url = "https://files.pythonhosted.org/packages/0c/aa/a080c4facaab4ece837558649eb6e2c760867d1c0ea52220cbbc4e89dcaa/charset_normalizer-3.5.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:143792a43e06dc3b27fc891948406e251502dc19ff9216cd80182b79131be5c5", size = 261492, upload-time = "2026-08-12T14:31:53.628Z" }, + { url = "https://files.pythonhosted.org/packages/f9/24/e23bcc9d4bc897bd620bc39c6b6052574f5ef93b85b50b175dd427a7dc07/charset_normalizer-3.5.0-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d74bcf1cdd8ac8267fb216473ce6b112efa07b163536288094541415084d131c", size = 259739, upload-time = "2026-08-12T14:31:54.86Z" }, + { url = "https://files.pythonhosted.org/packages/ef/85/f4c391c807f67c6483d02c02d28683e2fe229403728369c0cd33f61e4292/charset_normalizer-3.5.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3bfbe543d957213fc9a3db4979a8e171b7aa7504c1d737029defdb03a6095a38", size = 252120, upload-time = "2026-08-12T14:31:56.227Z" }, + { url = "https://files.pythonhosted.org/packages/4e/cb/dcf5aa14e24270613fafa2f02b3979820c244610410e5508696ca96bd0d2/charset_normalizer-3.5.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:3587d94b5c9f05c2dc4c3f3d47aba6375ff141a21adae3051d8d4d53e8a937c0", size = 241622, upload-time = "2026-08-12T14:31:57.54Z" }, + { url = "https://files.pythonhosted.org/packages/83/a9/decd1c1cc01ccbfce66845096e3945397e4ede354f31cc5cb28fc6ca601b/charset_normalizer-3.5.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:a7cb4cd266bd85613367fb85a30cfbf6fe6349919e87e18ca8dba584951bfb8a", size = 280745, upload-time = "2026-08-12T14:31:58.91Z" }, + { url = "https://files.pythonhosted.org/packages/8b/47/420ddefc04f089e4497b3bcbadea37586477713300c13204fb4a7c736071/charset_normalizer-3.5.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:ffdd7ac514301d0a67f7c23b9f2b431ef909a3c3dd6c3766668d0a6f5900c94e", size = 258669, upload-time = "2026-08-12T14:32:00.069Z" }, + { url = "https://files.pythonhosted.org/packages/58/73/01d5173097a5f0a13417e77db9ba3aea24de54421344c8e0c4973bf8cf21/charset_normalizer-3.5.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:3684ebbdffd51329ac44245d1d227d90b965797aa1a8abd026568a1f6ae88811", size = 277344, upload-time = "2026-08-12T14:32:01.211Z" }, + { url = "https://files.pythonhosted.org/packages/41/4a/300ef2598da520744aca7c49370e48732cab1f04de5f784f0e4f0e9e1d11/charset_normalizer-3.5.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8b8788f114845c01f2b520e0b91ea58d143276cfc0483aa943e815f7b9555c15", size = 263440, upload-time = "2026-08-12T14:32:02.421Z" }, + { url = "https://files.pythonhosted.org/packages/be/5e/78dd366df9ae4810039c0f799ec47d325a5cb76e92bb707ca9039b7c2306/charset_normalizer-3.5.0-cp310-cp310-win32.whl", hash = "sha256:9a1d9b13e5e394e13e3c316f0d910d100b17681ff59797f30da1dba032061296", size = 181680, upload-time = "2026-08-12T14:32:03.932Z" }, + { url = "https://files.pythonhosted.org/packages/67/d6/455982837da317ce47cafe35260f446f218f5843090b77a59ee69aa0ad94/charset_normalizer-3.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:5a54587f93f2e289f8faf25b35c997d4cc75cf677485ac6f50c985715989f99c", size = 205665, upload-time = "2026-08-12T14:32:05.045Z" }, + { url = "https://files.pythonhosted.org/packages/e5/e5/5b285d50d4fc82111c18ea4fff8b5e1916a257b98dcd5cd0abf1c165473b/charset_normalizer-3.5.0-cp310-cp310-win_arm64.whl", hash = "sha256:38a395079f229a631dece74e24c69c1f612536dd51f345a7d6a98abe2d3e047a", size = 184409, upload-time = "2026-08-12T14:32:06.503Z" }, + { url = "https://files.pythonhosted.org/packages/50/42/71e4e3bfe59202feef062c68487f54c6adf501cfbe087ecd93e3cd597fea/charset_normalizer-3.5.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e46a37ea7fcf9ae01d71b2e5ece19f1565987f3e308394b829197cbefc061f92", size = 349110, upload-time = "2026-08-12T14:32:07.832Z" }, + { url = "https://files.pythonhosted.org/packages/0f/dd/fd3386d0fbd358d3b5c7a2fa5bf312afe6159b04fafeb67d39fa971d7448/charset_normalizer-3.5.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1cdfed4d7a59333c8220c67dd3be4e7a6c887b67453a64394022dcc919570add", size = 250773, upload-time = "2026-08-12T14:32:09.113Z" }, + { url = "https://files.pythonhosted.org/packages/17/ad/4901a66d6d3b17f1096725d7e50266132c16555aa6a70047fe1cf262b4b2/charset_normalizer-3.5.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9491f594859b68052edebd69e05fb045055a713b57a67974e6c1553b4e503c39", size = 240229, upload-time = "2026-08-12T14:32:10.43Z" }, + { url = "https://files.pythonhosted.org/packages/43/b7/1d790e0425e0f4c99e9b89a3956a94a6d2d0c6f01b2a5eca93d8f082d5ac/charset_normalizer-3.5.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:420b19411959eec115063229536788e6b32d0a7fa907d6b940317919120d702d", size = 280757, upload-time = "2026-08-12T14:32:11.628Z" }, + { url = "https://files.pythonhosted.org/packages/44/bb/4b8c8086c67636e52d6354ad17697f54a00b40041ca53dc765737e21709b/charset_normalizer-3.5.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a565303d118ea3b94a4b6c076bf568069726be414e43b06d58f7070b076ce11d", size = 276174, upload-time = "2026-08-12T14:32:12.808Z" }, + { url = "https://files.pythonhosted.org/packages/25/fa/690a11924c40c766d258d2b74d817cc5efe7bbcfceeedc5c0f35256d7524/charset_normalizer-3.5.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:815f143a91983ba3041bba066e492ae3c42de523fb1c699685a1abf3313b7d1b", size = 261808, upload-time = "2026-08-12T14:32:14.138Z" }, + { url = "https://files.pythonhosted.org/packages/53/2d/4a6945eff0c8f684e3f5b7b978644ab18ba9198da060dbaa1d9206bc6cc9/charset_normalizer-3.5.0-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c5e981a5ac8641381efe6f0029467500661616a530d27bc6eedfe45f840599f8", size = 259922, upload-time = "2026-08-12T14:32:15.485Z" }, + { url = "https://files.pythonhosted.org/packages/60/4d/10ac7e07bbf7ea569effeb9524e32f345f7e643800b20d538fb4706eab4e/charset_normalizer-3.5.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1a573e1e428f93908e79e04b349717f400e720f2f82285f0aaaf3ee0ff7f4c79", size = 252315, upload-time = "2026-08-12T14:32:16.764Z" }, + { url = "https://files.pythonhosted.org/packages/13/bf/1ddacf7aa7da12097f229a6a4e71a70200937a621b3617f6dc819fb99a66/charset_normalizer-3.5.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:32e6d56dd825205f81e5c45bcebb4df6a11fb2bbf4969a01ef156d6ced90c224", size = 240600, upload-time = "2026-08-12T14:32:17.956Z" }, + { url = "https://files.pythonhosted.org/packages/c2/88/293444d48c8d86fe51552262117134a9fc666d68cbbbc9b8c1b2b35a29be/charset_normalizer-3.5.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:30ae26a1adcd943690dcbbc47f28be762bae9e08ad7442b78c86b1c0dd5a626c", size = 280788, upload-time = "2026-08-12T14:32:19.1Z" }, + { url = "https://files.pythonhosted.org/packages/12/ed/0e34e40584f51eda38d4a5daf25fd8586366347efd4b2470dbf64710e778/charset_normalizer-3.5.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:5f51a19dc52197a20218b05ec5336d0c6b3b09935f838724722032c8d45dc91a", size = 258425, upload-time = "2026-08-12T14:32:20.207Z" }, + { url = "https://files.pythonhosted.org/packages/72/b2/c1b1c27f6f0ef35b21a8bdb592854bbf7f219629db3477f74c0b1380e0ed/charset_normalizer-3.5.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:6e44bc2780516b3df986d6fe33103c7080cd9dcd5576fe3cb4b0f64309c8f22b", size = 277437, upload-time = "2026-08-12T14:32:21.345Z" }, + { url = "https://files.pythonhosted.org/packages/b2/bd/a1b7d959a37847675adb2f5978f81703306dd78df4fefb82ee5a1cc5e37f/charset_normalizer-3.5.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7faa47b56070b3dd6f4898ed28528843ab130d53266cb9948d9b1f3bb1a5c5e8", size = 262947, upload-time = "2026-08-12T14:32:22.613Z" }, + { url = "https://files.pythonhosted.org/packages/c1/fd/a76a2d7e639bfc6a9c869371e34f28231eaca7d7126ec19895aa38eedb51/charset_normalizer-3.5.0-cp311-cp311-win32.whl", hash = "sha256:830c04a49998b5ed58c8b642c65b7b26419397f52392a64121ba9fd0e95e7f9f", size = 181313, upload-time = "2026-08-12T14:32:23.736Z" }, + { url = "https://files.pythonhosted.org/packages/97/84/6fc03e802578df41a2ab9b6a1f26657fb92e32285a603ad5852a4a4f68c1/charset_normalizer-3.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:8cb9b6892b53bd6d11fa4cde3dbee020b1f0b6656be1fbaa1ec0d4324a7839db", size = 206197, upload-time = "2026-08-12T14:32:24.938Z" }, + { url = "https://files.pythonhosted.org/packages/0a/27/7208360ff1901607359869fcc45ca0989d597f3e30777ba30c7254170587/charset_normalizer-3.5.0-cp311-cp311-win_arm64.whl", hash = "sha256:2403b489c103e9a18c835863fc6dd54361355c8291d4cafdb37492b683440b9b", size = 184925, upload-time = "2026-08-12T14:32:26.123Z" }, + { url = "https://files.pythonhosted.org/packages/6d/3c/045ea64ea5a550870dd8ab60b2242870328d53f17d2be593b4f9f3121474/charset_normalizer-3.5.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:98820e1ceb25c6df7a80c4fd8efa59cb121f99bc7c4c1693ad94a2caff5b311d", size = 343861, upload-time = "2026-08-12T14:32:27.254Z" }, + { url = "https://files.pythonhosted.org/packages/fc/1b/7502be709db899d5b4801509829188b3a5a10969411da9c846115a5f1b70/charset_normalizer-3.5.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:608553f476fca509537e804c4a71f5eb166ce63b75141f89c2c686ce1aa36956", size = 237550, upload-time = "2026-08-12T14:32:28.385Z" }, + { url = "https://files.pythonhosted.org/packages/ca/ce/66392661375148d9455c17bee25509a54e28c39969e34befa48ec8777936/charset_normalizer-3.5.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6753de11eef42f1c321b26d682957d92c7f7bbce6530f34bbe0f9291dd37cc6f", size = 229673, upload-time = "2026-08-12T14:32:29.668Z" }, + { url = "https://files.pythonhosted.org/packages/6a/64/f58c32a8d4ecf55b82ee61ee9aa6a664d4afcd36c72feb4c926fd6fe9af8/charset_normalizer-3.5.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0f76dc0a47f94cb9b69d86f01e477f4b0371ca70208b9ccea7e063c41eed9046", size = 260768, upload-time = "2026-08-12T14:32:30.891Z" }, + { url = "https://files.pythonhosted.org/packages/b1/ea/36c90e59a96386174377e855479ec154221ef001e96637e0b23be92489c4/charset_normalizer-3.5.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c387c6bf91b4774e359a48a179e2872b8e8bf741e4fde06ba8d1665eb9a4760a", size = 257880, upload-time = "2026-08-12T14:32:32.175Z" }, + { url = "https://files.pythonhosted.org/packages/23/35/5b85772eb82528ef22ba29487ad544a7049dfd27f35b1a5a55dbc0843048/charset_normalizer-3.5.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:14f6904a3cf870abf044df3a8c4924ac6c8ef77e9896586fd37e73ae96cff2af", size = 247547, upload-time = "2026-08-12T14:32:33.495Z" }, + { url = "https://files.pythonhosted.org/packages/b6/14/ba11a99c2a22ab04c2d5383a700b378cb463a78ab15f36444cabc10cd671/charset_normalizer-3.5.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0cce46dd29d73e135e8087b96eb62a4aca6d69391b7f97808c6588ebed3178f3", size = 243326, upload-time = "2026-08-12T14:32:34.794Z" }, + { url = "https://files.pythonhosted.org/packages/4c/4a/cadba3f2400b45aa1d62a4ae0298bf58a3b30b1158baf15c338c7ce5b601/charset_normalizer-3.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b476cdb63df22da2b91837593380be3ddbe406f36c506c1c91d80e7196b66288", size = 238820, upload-time = "2026-08-12T14:32:35.984Z" }, + { url = "https://files.pythonhosted.org/packages/47/41/d5188b9342d75b72c2b05d3ee373f01a691397e770f001ee05e3b37925f5/charset_normalizer-3.5.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:1f56ce84b317ef2a59d7d3461891c7597c79247d2192bb8114c68a1a1debfcc0", size = 231661, upload-time = "2026-08-12T14:32:37.191Z" }, + { url = "https://files.pythonhosted.org/packages/13/5f/df38fa972c4e945c3d8cee2bc4e610613af522fd359c7dc7a74c419f0278/charset_normalizer-3.5.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:9ce0f885239357379d92fd9a5fddbe20f0e30e0527c29ba69f8e99eeb1304a76", size = 261459, upload-time = "2026-08-12T14:32:38.369Z" }, + { url = "https://files.pythonhosted.org/packages/a5/d7/043ff7720067a3beee05523465ac9c1c846c68b7884930dd483f72ee5ab6/charset_normalizer-3.5.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:96ae7ab5d8155fde927aa0864fbc8ba3cc4fde6d41ab0c7cea9d6012b4978603", size = 242300, upload-time = "2026-08-12T14:32:39.505Z" }, + { url = "https://files.pythonhosted.org/packages/19/f6/33980b7b802a048e546a6d9ad2ea783a6cf6b10a86aaccd10db462d8b913/charset_normalizer-3.5.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:bf91921009025e96ce57a03ced6d14604fc3baf0530351638e9504a55da6fa3b", size = 259101, upload-time = "2026-08-12T14:32:41.02Z" }, + { url = "https://files.pythonhosted.org/packages/a6/b7/0d19bde844bff9165377c1da9ef3c4792a4c24bd49b5b7094d9e6f6ab58b/charset_normalizer-3.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0b2e44e6d42d1a4ff78ccc219a93c5449105d10b16198d1aea581080df8073f9", size = 249246, upload-time = "2026-08-12T14:32:42.47Z" }, + { url = "https://files.pythonhosted.org/packages/1c/cc/2c34fdfaacdf0e96e880ef562cbf80a9b5f8ea97e0dd9e57ba348a9c65cf/charset_normalizer-3.5.0-cp312-cp312-win32.whl", hash = "sha256:deb99535e9bf0bea8e274c6413eb939a21be35a3f492678dba4d5b1f4d70f142", size = 178025, upload-time = "2026-08-12T14:32:43.909Z" }, + { url = "https://files.pythonhosted.org/packages/76/d0/c34dbd1df23bcbdc1b5d2f48256340d72fa747f1eb03924a9d2fa35ed85b/charset_normalizer-3.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:e54dd1a66fa4bce0ccaf0db9dde336e49b3eec646dc4c1c0991279369d373a14", size = 200143, upload-time = "2026-08-12T14:32:45.254Z" }, + { url = "https://files.pythonhosted.org/packages/c0/ea/4e6bf1465d60c3d8f488d5bde140d0cb91cd23ccab0dc2895cc6c6982047/charset_normalizer-3.5.0-cp312-cp312-win_arm64.whl", hash = "sha256:b8ea208b304587d47931b36481342d20336e0d338ab052f8b4305926482598d6", size = 180046, upload-time = "2026-08-12T14:32:46.545Z" }, + { url = "https://files.pythonhosted.org/packages/1d/be/cc7b7b6fc41984902c0d31b06f5d9297e67705c1dae9352608e5540fad09/charset_normalizer-3.5.0-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:5c23fa4f6eccdd601949cb00f3988c01d64e671d8faba356397971077022e144", size = 211050, upload-time = "2026-08-12T14:32:47.81Z" }, + { url = "https://files.pythonhosted.org/packages/d3/ae/e3ec8f17313609f43f7b323012fdb1ee37b83432277ca4eceba83e00366c/charset_normalizer-3.5.0-cp313-cp313-android_24_x86_64.whl", hash = "sha256:07f6f42b5a6325df35b458004fb5f9f29bf502d89287a33c7cdef3590e31de0f", size = 222768, upload-time = "2026-08-12T14:32:49.027Z" }, + { url = "https://files.pythonhosted.org/packages/c5/50/9f9c0d7ccc1512d49e27a0e7c12c58ec71dfe91698fa4326f058c33e1f1b/charset_normalizer-3.5.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:8efc3f1563ed431882dd0dc0411b5f8ace1b1b89074981deaf6bd8af77dbe1bc", size = 193907, upload-time = "2026-08-12T14:32:50.414Z" }, + { url = "https://files.pythonhosted.org/packages/fd/1d/cfe7b745ef7f4c3b7214581955b5a0869ba2ac551a58fc11036281ae167c/charset_normalizer-3.5.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:368eb2fc9482158b3a3386e8f01fa61f479c968e9a19ceab8f0188b86b312991", size = 197135, upload-time = "2026-08-12T14:32:51.605Z" }, + { url = "https://files.pythonhosted.org/packages/28/55/30fafdcfca9ba616bc394240545e4cd52f4f66dea43ded81b7d2d5274fde/charset_normalizer-3.5.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:826a295a039178479a325be1ae60eded1f0b10f7dda749df59e2440de8f61d64", size = 339892, upload-time = "2026-08-12T14:32:52.82Z" }, + { url = "https://files.pythonhosted.org/packages/f4/08/bdca5fc2bdc36ee443673dc7d12b23885a5a7b282bef85a1a4c3b325b40e/charset_normalizer-3.5.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70ff1c16eb0eb5ee6bb12739292347f981a5ba764cc4df1bc2e69b0405d4ac3b", size = 239439, upload-time = "2026-08-12T14:32:54.058Z" }, + { url = "https://files.pythonhosted.org/packages/d1/9e/506c8d7a7722bba7c8cdd78c1b5ef23bda92bfbe0b3e28ea84673d519a0f/charset_normalizer-3.5.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3cfdab178a4add5483e26a9bb1c16d8018ccf39b4be7a3aea6c3979e6828f2ee", size = 227896, upload-time = "2026-08-12T14:32:55.326Z" }, + { url = "https://files.pythonhosted.org/packages/0d/1a/dd828f2b1d6f4bf10821b9a74d866be05ffcdbfcddfc501d6fe6428762a7/charset_normalizer-3.5.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6083d10a846218502d664375b9448508d9fa580bd834567423156c6abfbe899d", size = 262548, upload-time = "2026-08-12T14:32:56.484Z" }, + { url = "https://files.pythonhosted.org/packages/be/81/196d26f6bd78b93e0d451b69082a71027ceeddd4b0be9170b81bb038f824/charset_normalizer-3.5.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0f211c21aa316cb6e2662e54a1194633a79d98a50a876addacfce7ba5b34b09f", size = 259986, upload-time = "2026-08-12T14:32:57.661Z" }, + { url = "https://files.pythonhosted.org/packages/3a/6a/5b964a1eb0f9075ecd45083eeb21aaec215334f98bac3d400302ea73875d/charset_normalizer-3.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b08ebf9488c7ff5eff038e48e6ea938178dfd9dcc8598b5ca941e4ae27b20be", size = 249853, upload-time = "2026-08-12T14:32:59.123Z" }, + { url = "https://files.pythonhosted.org/packages/c8/b4/aee3a9d82edd0e931091ef3e9f03e46491ae3590e96e998d0975dadbe17c/charset_normalizer-3.5.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6c95450fce59f00c6d08eff6572ec2e736e5054c9450253afd5748f8416f2eb9", size = 244217, upload-time = "2026-08-12T14:33:00.341Z" }, + { url = "https://files.pythonhosted.org/packages/22/3e/33f72ca11c1b619b220fd9f35905ebd171cbd0e0470f2357e467b9e861ee/charset_normalizer-3.5.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5780a29823e1d2bec69b7a104ead4195a43f3e97782efaedbf1f79a0157af715", size = 241307, upload-time = "2026-08-12T14:33:01.589Z" }, + { url = "https://files.pythonhosted.org/packages/78/27/6029dccba958621c7f3a65136f87c5512d712aef9e890f09512cc171bd03/charset_normalizer-3.5.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:054420b5db984971d886e5e4e2c37c760ae6682aedbd066687ff0949d9ed5f08", size = 233305, upload-time = "2026-08-12T14:33:02.866Z" }, + { url = "https://files.pythonhosted.org/packages/18/d7/691c967be459153fe9faf49bf78bc95639ef8bf6dd008f38cc6389a349eb/charset_normalizer-3.5.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:d016dc857136c726958102c3b8a3986acdc65ace6fbf12cfdc09cc4bfa2935b2", size = 263465, upload-time = "2026-08-12T14:33:04.166Z" }, + { url = "https://files.pythonhosted.org/packages/7c/2d/9202221be5c90b2a835924191e362690ed8dc8c7d6606100c2bd03fe0f8c/charset_normalizer-3.5.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:f2ce3d39fb4a9d674e6639dd5d3146b2e273475d2260f10163228d66fc04433d", size = 245060, upload-time = "2026-08-12T14:33:05.325Z" }, + { url = "https://files.pythonhosted.org/packages/b3/9a/298772fd0a0cbccadf36451a1cd7eef4b66a11e99b4a7f6fafc47cc62c75/charset_normalizer-3.5.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:a5613a3a82c974227bde18f03409e30c467f8065cb56d822e3eb83708a5f223d", size = 261091, upload-time = "2026-08-12T14:33:06.475Z" }, + { url = "https://files.pythonhosted.org/packages/82/3b/1a11fe66e555dbe2f5714ade6ba74fa29edc9155d9cf1001d4d6ed096aa7/charset_normalizer-3.5.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fded2e82ff082e5d8e017e2ddcc1411bd8cb83b8585097fc401ef574f756b888", size = 251857, upload-time = "2026-08-12T14:33:07.784Z" }, + { url = "https://files.pythonhosted.org/packages/17/fc/73b817e8af3f1d25ec5cf458d405abba5a144cf9812238a61530f5eac186/charset_normalizer-3.5.0-cp313-cp313-pyemscripten_2025_0_wasm32.whl", hash = "sha256:8f006866047c6ec4b627ec144b1e0bbc7427cb31fd7c08d19897d0ac9032af3d", size = 139745, upload-time = "2026-08-12T14:33:09.123Z" }, + { url = "https://files.pythonhosted.org/packages/b3/fb/ddb66303c86f7dc5043a457dad9fa82b4d6d0cb97094f9bcdde21693fd58/charset_normalizer-3.5.0-cp313-cp313-win32.whl", hash = "sha256:196e270c4e80827b5072eed7d6aa661d133afada94fe366669f9609e718d305e", size = 177217, upload-time = "2026-08-12T14:33:10.305Z" }, + { url = "https://files.pythonhosted.org/packages/fb/88/6018cc8d76ea2b7cb02918f37e23e86c261d1a102713d7e88d2cfb8b211c/charset_normalizer-3.5.0-cp313-cp313-win_amd64.whl", hash = "sha256:72982d9958a42f8132bf2d6b90214ed66477295ef1188731f98ae3511c6eeb5a", size = 198896, upload-time = "2026-08-12T14:33:11.51Z" }, + { url = "https://files.pythonhosted.org/packages/20/2e/04c0bbfc8d9abf91959f7a3d207d45cbf63a8116984caae2381890019bb5/charset_normalizer-3.5.0-cp313-cp313-win_arm64.whl", hash = "sha256:0b373bab0b867b68b8eb249da9478cab9181a42993437cd2f5dba5fb0b4fbd1b", size = 179193, upload-time = "2026-08-12T14:33:12.726Z" }, + { url = "https://files.pythonhosted.org/packages/43/14/d098868dac5ff27e0258f548b1c74c6484be528384965d8fcf8fc6a4011d/charset_normalizer-3.5.0-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:d95244906ed69d0f79f190893c65e336c15959003e21449256dc05c001b52ea2", size = 211664, upload-time = "2026-08-12T14:33:14.153Z" }, + { url = "https://files.pythonhosted.org/packages/e7/da/a944b32a46601ae5a4c3499e8d64ecd14fe82313f00da74dcdf00273a0b4/charset_normalizer-3.5.0-cp314-cp314-android_24_x86_64.whl", hash = "sha256:d788e2ded0c4c47efa4d73cfe59eaf975ee32f425219873d2cb3e3fbaa00f636", size = 224375, upload-time = "2026-08-12T14:33:15.472Z" }, + { url = "https://files.pythonhosted.org/packages/f7/db/eabb5996be2f529744755e7b2fc9396eff4a64961f034e7fd49d54b9afb2/charset_normalizer-3.5.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:f9f91d3e8382900f3a68fa0ce94294479de9cd2de6bc0c70acd0f0dfd511836b", size = 194364, upload-time = "2026-08-12T14:33:16.607Z" }, + { url = "https://files.pythonhosted.org/packages/78/65/4ad3c5be108930310d8003f5602861d5b89f728293b9f09c3a4837f7ba10/charset_normalizer-3.5.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:d54625cbf4e6b60bf0639728cb8b4cb541e340f6d7cafae5806051a40ddf4c45", size = 197643, upload-time = "2026-08-12T14:33:17.88Z" }, + { url = "https://files.pythonhosted.org/packages/3d/39/8fee3201b98d52289be60a775797d69be05a04fb6cfb48c1587dad33e649/charset_normalizer-3.5.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:1f99a8c3a1da5d955edbad18208b3d627bdd54c48a6e739fa877bdca98c686d6", size = 341384, upload-time = "2026-08-12T14:33:19.239Z" }, + { url = "https://files.pythonhosted.org/packages/a7/dd/9e757101d1f76c35c0643684ba499ac3a181fb2b264c68174bf727d627e8/charset_normalizer-3.5.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bf1e75dc07a3850b53d1e5f75e04d3ae12afe56284be7821771eaa2466350c73", size = 241637, upload-time = "2026-08-12T14:33:20.619Z" }, + { url = "https://files.pythonhosted.org/packages/eb/e4/7857023015400bc4aa0a82fbcca29fa2dc7ec25f971a130764cb2dc7a589/charset_normalizer-3.5.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:ac5a9cc079c67d75f4ddf343276031879eadbb333d1bb231cce297b8d7b9aae8", size = 226170, upload-time = "2026-08-12T14:33:21.773Z" }, + { url = "https://files.pythonhosted.org/packages/7d/ae/8b52935b304f7b6bbf33151ed2b75266b09aa4b6f8f04230d948885b2577/charset_normalizer-3.5.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0dfe83c1b4d00abbf433998117a14f56a5c2bc68226c0d331709eed0d1ce539b", size = 265093, upload-time = "2026-08-12T14:33:22.999Z" }, + { url = "https://files.pythonhosted.org/packages/dc/78/6e838f6bb059f2c0afc60a4e7f294252f043c254656ad4114c50302cae4d/charset_normalizer-3.5.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e4e8fa586df2208ef040684751345f10f503834a757c9a74ecd19c1a2f9b1ccd", size = 262789, upload-time = "2026-08-12T14:33:24.214Z" }, + { url = "https://files.pythonhosted.org/packages/c2/08/189b27e51fddc9d6b3695331da0e31792c1d88b953ad854e57f06e9b2cc8/charset_normalizer-3.5.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:82cc5835997ec78afe293a192e385099355770a7db94b2fb1239d36b32796f1c", size = 250580, upload-time = "2026-08-12T14:33:25.707Z" }, + { url = "https://files.pythonhosted.org/packages/ac/55/64854e99b25841f83e8e37d9df2f3d1f96f693439f80e5fabd542a7e47ab/charset_normalizer-3.5.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:19e52bda45086df8a4be4bb5910af6f5d9d3b538c78712c8ae09ef10b85bf458", size = 245008, upload-time = "2026-08-12T14:33:26.971Z" }, + { url = "https://files.pythonhosted.org/packages/4f/01/7720c904fa635d4260b4dced6029cf3d298c57b26741365d5a8d28c54043/charset_normalizer-3.5.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:3418edd0ecb72a0a3861cf72f31be0ad9b7fe338ce2b58fb5cc80b9aeb792700", size = 243892, upload-time = "2026-08-12T14:33:28.237Z" }, + { url = "https://files.pythonhosted.org/packages/70/50/7bfcb327631d4870c720872b548745f6ec8baa044d51c21b5d1d32ac4e3a/charset_normalizer-3.5.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:125ee619611019471b177c70bc3e9d4cda9fad7e01d93523501d3b188df0193a", size = 230996, upload-time = "2026-08-12T14:33:29.511Z" }, + { url = "https://files.pythonhosted.org/packages/24/51/40c45d6d940c04005ed721aa54bdebf1ebb2930f8a2ae537e8d60484fb27/charset_normalizer-3.5.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:a3ad0e3da22852533858663848608f3f24c0d35e5cde415a4903476f2b4c88ec", size = 265834, upload-time = "2026-08-12T14:33:30.689Z" }, + { url = "https://files.pythonhosted.org/packages/eb/d4/ef7a227ef89d215b47f9df79c3966610b17faa13bb2f236989207a631622/charset_normalizer-3.5.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:4ebebb410bc517e1d284c52a123e82704b21e4e7e26a21ebecf7439d0647b8a3", size = 245544, upload-time = "2026-08-12T14:33:31.859Z" }, + { url = "https://files.pythonhosted.org/packages/37/a9/a4ca9156964ded61c7718eba410ce11be2fd2b263fda4bcf08367b6578cd/charset_normalizer-3.5.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:91f9f7c151e772acebe489eaec96e96a2877202d7dd144e3f96b8676881715a0", size = 264110, upload-time = "2026-08-12T14:33:33.13Z" }, + { url = "https://files.pythonhosted.org/packages/38/6a/838364bb8702229c6e5f8b23f80ff0f052a12dfaf3113a12fd6acbe92a44/charset_normalizer-3.5.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:401ea6e7af9e7852ed818f64714b579c1935482049670847ca3bd7ba45dc63fb", size = 252303, upload-time = "2026-08-12T14:33:34.98Z" }, + { url = "https://files.pythonhosted.org/packages/9c/5f/d88032edce951f499a2321cf7ae0d35a043c74be12bc22d81084cc7afbcc/charset_normalizer-3.5.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl", hash = "sha256:f7496aed56b06325a1ad419c5bf23c6dd042558e874f71dd1b958f3e255f3053", size = 139964, upload-time = "2026-08-12T14:33:36.195Z" }, + { url = "https://files.pythonhosted.org/packages/37/ae/1c4a46b6b00d1c34d2ee355ef99ad6173674166800d1af0f05f85028d513/charset_normalizer-3.5.0-cp314-cp314-win32.whl", hash = "sha256:606a86c1c3196f3738de39a67a7490bbd61cb31c0e0436070bd0c6a48170b38e", size = 179790, upload-time = "2026-08-12T14:33:37.356Z" }, + { url = "https://files.pythonhosted.org/packages/01/51/f94dcf34fa8eba48c1fb89b6490a5f1426e19488fe5f38aac6c648c99057/charset_normalizer-3.5.0-cp314-cp314-win_amd64.whl", hash = "sha256:ec6c464cf45867f66a2273e2214d9199a8fbad5cb95ca0fd45f6a2fe1d9d2cf4", size = 203723, upload-time = "2026-08-12T14:33:38.639Z" }, + { url = "https://files.pythonhosted.org/packages/9f/ba/91d386870b5d9e4b0d8c4034f63877cc2e47b99c81ef05f3e6d42bf9a53f/charset_normalizer-3.5.0-cp314-cp314-win_arm64.whl", hash = "sha256:dc28949de1bb5f7f30a46f15d74ce7ac5aaa63e03c5de04d68f571c7423af834", size = 183423, upload-time = "2026-08-12T14:33:39.899Z" }, + { url = "https://files.pythonhosted.org/packages/f1/c9/534ecb17b7fb95f9052c4a44cf316316a27d4a8f73e8475ff55e778dcdd7/charset_normalizer-3.5.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:68b7e84ae8239a94f8d2c8f3f3a3a81bcde54805ec8f42a34de927d155688ec6", size = 368967, upload-time = "2026-08-12T14:33:41.093Z" }, + { url = "https://files.pythonhosted.org/packages/3c/b2/ad7c3242d7fe55cd55126c22c65cb1b49779782cdf8932fd01d12232d86a/charset_normalizer-3.5.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:58ca5dc0a0ef99f2801ec0574214c978e9574055bc783830bbb6e7433218609f", size = 239478, upload-time = "2026-08-12T14:33:42.428Z" }, + { url = "https://files.pythonhosted.org/packages/7e/62/77f0b850048e430fc350ec58876b0c020f5c8d0d3956fd1a4d6ae2fa292f/charset_normalizer-3.5.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6c57af4084c10cb3286688d65e4c654190ff5edcbc2411d08cdca0a8a44c59a1", size = 227036, upload-time = "2026-08-12T14:33:43.635Z" }, + { url = "https://files.pythonhosted.org/packages/f0/ba/47d951e1a51dddbaad0a1410baf49fb1d897ceb00281568f1183b79bce9a/charset_normalizer-3.5.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1619a3cc174a7e3963dd34348e6fceb6e50db0ddeb0031bd7c73a58286454fa", size = 260772, upload-time = "2026-08-12T14:33:44.96Z" }, + { url = "https://files.pythonhosted.org/packages/b0/61/8c7ff4c81b2a88271126acf4b83ab3e31f6d63868b0f01d331eaa0f9cb67/charset_normalizer-3.5.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1328cc57dd4372be1265f68232cee890e087416e3e6e93e6ffb32c2bad4d36a4", size = 259273, upload-time = "2026-08-12T14:33:46.185Z" }, + { url = "https://files.pythonhosted.org/packages/e1/fd/36129689be08dc287b951306946657ff70d76e287dd57018861f86d0e474/charset_normalizer-3.5.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:06f4fb62a9139bef056b8b2da6773c94c2f259f90e4b8e53b166f3d0372d7cf6", size = 248086, upload-time = "2026-08-12T14:33:47.54Z" }, + { url = "https://files.pythonhosted.org/packages/cf/f8/bcae67f994c8fd31dda445e5ebf84045823c31443fe46f0e9ee6aca99aa0/charset_normalizer-3.5.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:478650a70a750d75d5add401606c77f77069c32e4ba2c9131dc6cee566962ca0", size = 242671, upload-time = "2026-08-12T14:33:48.746Z" }, + { url = "https://files.pythonhosted.org/packages/61/92/0472cdad1061c2f0e4d3aee29973eb6e81bb8fe256ff2860cf115b15f1c9/charset_normalizer-3.5.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:48920bf6fe83eb2226756ac623fa54940487154eb18f80889d5735cf234965c0", size = 241311, upload-time = "2026-08-12T14:33:50.152Z" }, + { url = "https://files.pythonhosted.org/packages/f2/89/04a03de5d27c77c624d9fcf6287073754bd438df1b58cb7d030c57c2824d/charset_normalizer-3.5.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:168a0cb536b5123a77bc42ecf5e0bf6f923d0d9ae43c42a14eb0677c19ac6c19", size = 229898, upload-time = "2026-08-12T14:33:51.523Z" }, + { url = "https://files.pythonhosted.org/packages/42/a2/639c4278adcb7ed1f4db608dd9ac19b6774fa2285a96b1c0bdb9c124ccbd/charset_normalizer-3.5.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:f278e131afa96a3622cef9211c406ea2ad1b68eb06f8837cd443684a40e0ae50", size = 262852, upload-time = "2026-08-12T14:33:52.924Z" }, + { url = "https://files.pythonhosted.org/packages/9d/95/02e34c97bedfd0c5574efb9179c850591acc7f967ba039ed8dd29d332b73/charset_normalizer-3.5.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:d6100f877d2ed95f0856a3fde25334153add94bf2224c43f45f88e7039262aaa", size = 242913, upload-time = "2026-08-12T14:33:54.18Z" }, + { url = "https://files.pythonhosted.org/packages/a3/64/0946aeab6462dad9f160a50dfb4704d3f58a5ee708f085abc2105fbbff0c/charset_normalizer-3.5.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:4c440122e1ea68b1f8b44a631ebf49c39180f6869b1da22d76e8a724208ec6e9", size = 257938, upload-time = "2026-08-12T14:33:55.802Z" }, + { url = "https://files.pythonhosted.org/packages/79/77/36787d41ead124746506a4425c729f4f17c68280af8a6a5baa0a598cae86/charset_normalizer-3.5.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e5f834965c2fe589837bac1002e07e25734ff70381903ccd95b3d649e22bfa40", size = 249467, upload-time = "2026-08-12T14:33:57.081Z" }, + { url = "https://files.pythonhosted.org/packages/65/10/d9f6c5589cd24198d4ce6cd2948191c18e657272f433e5a00d258d9f5c22/charset_normalizer-3.5.0-cp314-cp314t-win32.whl", hash = "sha256:076cf9d3f3c7e410295c09d96355cf3b1bcae74990034d80e4371e20fe1ba4c6", size = 190624, upload-time = "2026-08-12T14:33:58.449Z" }, + { url = "https://files.pythonhosted.org/packages/6c/81/43e0584a802051a22c725795ebe1df78263abc7de858eef6cdc9b36637e9/charset_normalizer-3.5.0-cp314-cp314t-win_amd64.whl", hash = "sha256:3288a560dc3114d5d2ebe309b1ef43f8af355eafe25856832415c2a8196c9db3", size = 215902, upload-time = "2026-08-12T14:33:59.753Z" }, + { url = "https://files.pythonhosted.org/packages/30/f3/af6a1160fef0eac4510d035241e11eccf78e5350e4cd4de79e79fe02a5e5/charset_normalizer-3.5.0-cp314-cp314t-win_arm64.whl", hash = "sha256:a284c36b9c6616bf0a8aa4aabba668a0c75ba65ccf40a79868aeaa69ad996897", size = 193452, upload-time = "2026-08-12T14:34:01.017Z" }, + { url = "https://files.pythonhosted.org/packages/42/a4/dee470afb7a55c4f78b6fef37306c51fed17ebf94dbe530798c91d394350/charset_normalizer-3.5.0-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:c38d1e9bc2073b0984d2099ea647fd7f6c0d8f83a1e14e0cd32926f16e4c44ce", size = 341595, upload-time = "2026-08-12T14:34:02.4Z" }, + { url = "https://files.pythonhosted.org/packages/6a/32/9c3126dc429c6d9d7f79c52681a7c4453ed20a26267c9a8275d7ab620aba/charset_normalizer-3.5.0-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c9f45186390aee4d1f26f723c615b67df346766c3b16df000d84d6e374f06757", size = 242177, upload-time = "2026-08-12T14:34:03.741Z" }, + { url = "https://files.pythonhosted.org/packages/4b/9d/5b616a887301ff4cc0916b39ba44257390d3da80deeed6e8b6f2f26b14a8/charset_normalizer-3.5.0-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:f0fde5e5100c735b2274ab898f0742a5dcde492796296cfbe7e0ad6a4cd1a396", size = 236730, upload-time = "2026-08-12T14:34:04.991Z" }, + { url = "https://files.pythonhosted.org/packages/be/b4/d6d3e70be93ebe5fabef65e4c7ac113e1d1705cbaeb5fb72467e713aca17/charset_normalizer-3.5.0-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3d00e18e7bbf47e332ab63903d18bae31efc701b1d8cca0382b97784a621fc44", size = 265158, upload-time = "2026-08-12T14:34:06.235Z" }, + { url = "https://files.pythonhosted.org/packages/30/e7/3f1fafa87e2643257474f9c4eec609f2193a61d907dce7dd4f3f2390ebd5/charset_normalizer-3.5.0-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5b81980668800dd1c69faad8aea6e85a8cee0e13bcd3bba7671695ff16260293", size = 262931, upload-time = "2026-08-12T14:34:07.511Z" }, + { url = "https://files.pythonhosted.org/packages/0a/df/ebeb224a949d91829e5e114c6b64372a3c792b00762a9e951ce416f3a32d/charset_normalizer-3.5.0-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9bb3e0d1345b9c0fe73673ea656375f38a78ec679c2edeae0c24800f04798a85", size = 251388, upload-time = "2026-08-12T14:34:08.949Z" }, + { url = "https://files.pythonhosted.org/packages/a0/64/9a6ce2e7acc5cf1b4636f78f82e89ff581e06a0216a40678b28bd4d832c4/charset_normalizer-3.5.0-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:2401f7671242e921e604f609d429f6b282ea4ca787a6ffd22ed7372011ddb9d1", size = 251821, upload-time = "2026-08-12T14:34:10.138Z" }, + { url = "https://files.pythonhosted.org/packages/f1/b1/6e69b8056f615e5ccff6b91ca16db2d47922251f016821a300c115267fef/charset_normalizer-3.5.0-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:96720f2aeed3434bc48f4d52fbad64ecc820cfed88915d664780ed9ba09ede78", size = 244507, upload-time = "2026-08-12T14:34:11.488Z" }, + { url = "https://files.pythonhosted.org/packages/0f/34/02c15d6a0aa6b934dcdc136b111da63ae857b9fd51cf5505b0736337c2eb/charset_normalizer-3.5.0-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:c455829625df983f716cbaecbba77f2d1dc2e0e0ed1638c059cece15a279344b", size = 240951, upload-time = "2026-08-12T14:34:12.991Z" }, + { url = "https://files.pythonhosted.org/packages/ae/15/0fe893d3e1c7d111280bd6c4bd4c1e431487a1124a1bcbce78dfeda3a3a8/charset_normalizer-3.5.0-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:c41b067eddcfa5ee6b1169c287605be7fb6b0ea22bba6474c5bb978a668def4f", size = 266162, upload-time = "2026-08-12T14:34:14.232Z" }, + { url = "https://files.pythonhosted.org/packages/55/ea/eca03527307670f5d102c295671a800c404ca958cf94fefd10fc963a72f0/charset_normalizer-3.5.0-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:e31786a947b136329bfdc458c82c06d4ec539b4a4436b7da4df4aafc9902ee80", size = 251835, upload-time = "2026-08-12T14:34:15.48Z" }, + { url = "https://files.pythonhosted.org/packages/03/a8/fee5633081e595fe9e191df6f215106c791ad596eddf5e41e39b8ea0f2e2/charset_normalizer-3.5.0-cp315-cp315-musllinux_1_2_s390x.whl", hash = "sha256:c5c6d47a865147e0ae3322ce92e7fb52ba3169d94b447deda56897ea2aa6fac9", size = 264314, upload-time = "2026-08-12T14:34:16.679Z" }, + { url = "https://files.pythonhosted.org/packages/cf/fb/17f47ae6ca35b562fb6e6f4b05f7aec6034217353eb4a23aaa3566dc7340/charset_normalizer-3.5.0-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:c75191e3c8052045179646cb40e280800a4e0bdfda34d9c949c2f268d44e80e4", size = 253194, upload-time = "2026-08-12T14:34:17.975Z" }, + { url = "https://files.pythonhosted.org/packages/59/88/f2b0f7ebb92493e925889ff29239b3b0073ffafd91230dbfc69e5cf9389c/charset_normalizer-3.5.0-cp315-cp315-win32.whl", hash = "sha256:83b62410bd36bb1178a7d563e2ee0cf21eb1c980c912ab99c2c78f06227f1731", size = 179800, upload-time = "2026-08-12T14:34:19.409Z" }, + { url = "https://files.pythonhosted.org/packages/e2/f0/afb5bfdea52fd943b1960403847a276b8e900c6e4cd6a38752321b4eda64/charset_normalizer-3.5.0-cp315-cp315-win_amd64.whl", hash = "sha256:e3b9eaa99a6d8c9ace4cd303915947ef55088d4cd87c6676874f98c5c03aa040", size = 203726, upload-time = "2026-08-12T14:34:20.656Z" }, + { url = "https://files.pythonhosted.org/packages/fc/71/219783eb691aa2ec879c0e521afdfe2b826f9678eed51b9c039d03e0db2b/charset_normalizer-3.5.0-cp315-cp315-win_arm64.whl", hash = "sha256:fec352b793cdc183cc9e7e0b6c10fd7bff38ec54ba44cc43599b9b56f7f3db2e", size = 183428, upload-time = "2026-08-12T14:34:21.975Z" }, + { url = "https://files.pythonhosted.org/packages/d1/d0/14aef3b9f80f2593c039d897e89034635b9eb0eb44b6ce5173bbd79ff338/charset_normalizer-3.5.0-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:c9bde7a960720c8b8e1b5ef7afaa0c9a2f3b55c44abd635b2b29dd066b298e3a", size = 368728, upload-time = "2026-08-12T14:34:23.221Z" }, + { url = "https://files.pythonhosted.org/packages/10/fc/b249466ddbbeffa448b6597631e9091d1f01b5132ff8e7a0e21a6eb72b63/charset_normalizer-3.5.0-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f8cd1283a9fe6c2065c807e9d5da81afe5e1e004caef39adc0d8ae86dd883698", size = 240925, upload-time = "2026-08-12T14:34:24.504Z" }, + { url = "https://files.pythonhosted.org/packages/2b/b9/c17e72aaa1b3e1ca6c184e8025cf138ed492d01a54f85286ff7d31253a4b/charset_normalizer-3.5.0-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:1c010dd86d3f4c4433c9634d33ce8147393b270dfa54f217f965540b8ae8e075", size = 234932, upload-time = "2026-08-12T14:34:25.822Z" }, + { url = "https://files.pythonhosted.org/packages/18/d7/f84ef0966bbe216f71029e34e7fa425a16b1682e2a40265e679dedf2b655/charset_normalizer-3.5.0-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5e68229977b2dea28e7061c0c0630a23f2f9f6e9c6fb38d77d3d6dbfe3768b74", size = 261733, upload-time = "2026-08-12T14:34:27.112Z" }, + { url = "https://files.pythonhosted.org/packages/3b/73/3e887fa0781a395339355ed934ab6561ceb5bb52574160f070224039c630/charset_normalizer-3.5.0-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a60773eb5fda796e6e6f76b9c152d270fe59f9788a51a6ff8ba44082d8548ae4", size = 258460, upload-time = "2026-08-12T14:34:28.431Z" }, + { url = "https://files.pythonhosted.org/packages/b3/81/52ebd9849bf9e35d0b21fff115cb6543162a8e1f2f564e8f87121a336b8c/charset_normalizer-3.5.0-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d9419f44e568f7fafcdc0b3b5c766a2364e705a9b34fb8a56b431e0d1f3f4258", size = 249894, upload-time = "2026-08-12T14:34:29.698Z" }, + { url = "https://files.pythonhosted.org/packages/85/f3/9366492b8a5fe0187de282e001d61345740cf79eb4a5f20181d769be02b5/charset_normalizer-3.5.0-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:75e243abbb528c1a774390ed71e3f868a9f37b1373442e4bbadd401cfc505ff4", size = 249540, upload-time = "2026-08-12T14:34:30.96Z" }, + { url = "https://files.pythonhosted.org/packages/0b/af/28bb5e5dbd3e67cb9196a62781ac2b6d79492f4fc7a069b6ca7d6d6c8d58/charset_normalizer-3.5.0-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:54c963ce6404e52255b737e8a06d356fc762d59096ae566203a67cf2b7d050f2", size = 242734, upload-time = "2026-08-12T14:34:32.481Z" }, + { url = "https://files.pythonhosted.org/packages/26/d6/7ccfa62b53b40fc06b2d3504825aa400764740bd10cf248fdc4272441b93/charset_normalizer-3.5.0-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:63ea0cc840c66670183578c2630d138c0e944aeadfc33f25173ee240f5db780d", size = 239580, upload-time = "2026-08-12T14:34:33.916Z" }, + { url = "https://files.pythonhosted.org/packages/0b/82/71c0c9b046697b8da66b3acefa8d5f92d00a9ef433ad7c3522b971d0369a/charset_normalizer-3.5.0-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:6c06875a1d4a7537bef70f659b55c6b55b9a47ec3ba8f2db610350c2d9915e6e", size = 263281, upload-time = "2026-08-12T14:34:35.333Z" }, + { url = "https://files.pythonhosted.org/packages/d6/01/d027583c869f40ba980c1c76994adbd522c360a6327e72beb44d7c267385/charset_normalizer-3.5.0-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:4253da1b4456b633651a8d59eb1dc7a8a8fa38241014dd7c217b353e547ae394", size = 250027, upload-time = "2026-08-12T14:34:36.991Z" }, + { url = "https://files.pythonhosted.org/packages/2a/e9/6475d739e0ec8bb1236e06263dc3affaffdf947d8114ad27024932f325da/charset_normalizer-3.5.0-cp315-cp315t-musllinux_1_2_s390x.whl", hash = "sha256:f044cb1cf44012184715f46584658993b5fee9344d71c4b0c455a17a299730c0", size = 257547, upload-time = "2026-08-12T14:34:38.277Z" }, + { url = "https://files.pythonhosted.org/packages/a5/60/d1f502fcaa048a2aca3ab80bfef8407659c131e4f1792fa805fec14b4960/charset_normalizer-3.5.0-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:a17864853f7c518ae7d4b368af98f427f9396805476af40af8698560f09d7d97", size = 251718, upload-time = "2026-08-12T14:34:39.562Z" }, + { url = "https://files.pythonhosted.org/packages/c3/69/76343dcf4381a698807ff8a20d89f66bbdd9f6222b0b17740f77ab764335/charset_normalizer-3.5.0-cp315-cp315t-win32.whl", hash = "sha256:9e726478d7a213847860219d74665a6892a643ac93b8f76580f6cf9ed39996b7", size = 190757, upload-time = "2026-08-12T14:34:41.053Z" }, + { url = "https://files.pythonhosted.org/packages/e1/ea/d18147626a1667cc773c42104ab155a4ca5d6d4d174b7a35e01062213ea5/charset_normalizer-3.5.0-cp315-cp315t-win_amd64.whl", hash = "sha256:d7229a99120c6c2792d96f4857c2648ce5530e93667a2c2388c5ef69a6b84775", size = 215431, upload-time = "2026-08-12T14:34:42.501Z" }, + { url = "https://files.pythonhosted.org/packages/47/21/4869598aae0872d94faa5933918a4fe37ab2c5af9d095786e241f9506fed/charset_normalizer-3.5.0-cp315-cp315t-win_arm64.whl", hash = "sha256:527e28a5e751d9e11369b9c5f9ab35c748eb9c109101920c7deb40d6eadf8d03", size = 193205, upload-time = "2026-08-12T14:34:43.781Z" }, + { url = "https://files.pythonhosted.org/packages/5b/f3/7b523d807cb5e73562ef8acf21d39cdb9d704955327362c781bc3478a73d/charset_normalizer-3.5.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:5a4ee37248dfac25107c758bda99d545ce73e60b44d2dd39e4a2bb9f2831e9f5", size = 330840, upload-time = "2026-08-12T14:34:45.06Z" }, + { url = "https://files.pythonhosted.org/packages/f0/de/fc68978fe78ca97063c96d764e41ff92ca639948f319271e0ff450e577a2/charset_normalizer-3.5.0-cp37-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:a864bdcacd8bff58bb4845304e031f821a3ec64b2b7259f2d409cd49c9e59ca3", size = 251862, upload-time = "2026-08-12T14:34:46.58Z" }, + { url = "https://files.pythonhosted.org/packages/a9/cb/82b41a0ab7fb1a88065f1d78ad32696ad88ea3fe8e25b8189d08833938de/charset_normalizer-3.5.0-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:84b736e3b391601bc47b86da381c749c0f894e9191aaca9f31f30c2632206df3", size = 239484, upload-time = "2026-08-12T14:34:47.869Z" }, + { url = "https://files.pythonhosted.org/packages/e8/0c/19608b631f4538f908098d4a2d56a8f79a665e27cc58e9d90479761a9227/charset_normalizer-3.5.0-cp37-abi3-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6abb1f356fb865baeb6ebc3fadd843e9a96fbf49b9adcca55037f3cceccb7438", size = 230602, upload-time = "2026-08-12T14:34:49.265Z" }, + { url = "https://files.pythonhosted.org/packages/29/db/f648eb30e14eba301aed61e11672156f137905c1bdbb530151abe8065943/charset_normalizer-3.5.0-cp37-abi3-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1d366548d2ee28a8cfdcc4296363978cc644a728333be9824d2de4652e83df0a", size = 259208, upload-time = "2026-08-12T14:34:50.632Z" }, + { url = "https://files.pythonhosted.org/packages/d3/e0/ed2c8bdbac484d69614d6993143aeb6cb0f4dd1561c883402517b623c8ef/charset_normalizer-3.5.0-cp37-abi3-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d672f329ae504ee240eb39b6effb3318aa8e7e8924c0ce8eee5760b3fad98539", size = 253659, upload-time = "2026-08-12T14:34:52.11Z" }, + { url = "https://files.pythonhosted.org/packages/32/08/b4907cb9ec5b521d9d024ced13611240b86ef065c2eb15b3ad2334dc9940/charset_normalizer-3.5.0-cp37-abi3-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c54036a518748b6c02e666f6d46c3817561998fb904c3be25b56fb4fe3dc5706", size = 248821, upload-time = "2026-08-12T14:34:53.399Z" }, + { url = "https://files.pythonhosted.org/packages/12/b2/e2d1abcfbc05822f0030869efb4e9f8a3658e13b4821796d4b62da917327/charset_normalizer-3.5.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:22a1889f1c9b752c63c36758a0c2145458e3cadb20fced7a0790002e9dd12b26", size = 240271, upload-time = "2026-08-12T14:34:55.09Z" }, + { url = "https://files.pythonhosted.org/packages/dc/f9/4ba127ad610542fa3eabfa41c45bf12d357860a815b3566374ec0188e213/charset_normalizer-3.5.0-cp37-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:b7eb3eab5c646d3de7dcb14a7c9caebace5249c5767da39e1761cb1576e521a3", size = 232155, upload-time = "2026-08-12T14:34:56.543Z" }, + { url = "https://files.pythonhosted.org/packages/01/68/40613182366d00bd6dbd5f6c84a926cbd120960e038a8269e9ae7d782762/charset_normalizer-3.5.0-cp37-abi3-musllinux_1_2_ppc64le.whl", hash = "sha256:2080aa129a28267984cdc902898993d788c995c384e285d0d19199f56760d52e", size = 259674, upload-time = "2026-08-12T14:34:57.815Z" }, + { url = "https://files.pythonhosted.org/packages/0a/53/4574a14fa4c9de4a6c9f31725354bfa40b67f653e6d594ce1654f9a41b32/charset_normalizer-3.5.0-cp37-abi3-musllinux_1_2_riscv64.whl", hash = "sha256:fd68c825548a611158230e2f9222e210ceb2e3391995c0aa5865cbdf3ab4bd49", size = 246122, upload-time = "2026-08-12T14:34:59.337Z" }, + { url = "https://files.pythonhosted.org/packages/5a/02/bd8030d13d92c058ca7b2b9615bbb3169569e144db64d65c149cd45abf5e/charset_normalizer-3.5.0-cp37-abi3-musllinux_1_2_s390x.whl", hash = "sha256:d8a9316f4da85e937242642b537c6d55d7e9287dd38e5634732f8233932aff45", size = 255221, upload-time = "2026-08-12T14:35:00.71Z" }, + { url = "https://files.pythonhosted.org/packages/77/9d/10ecd3bcbe2666b3d4d4026c97b48f73990682815db516052a1e8f4a31c5/charset_normalizer-3.5.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d90254c8f609338c53ec180fcd4c4f9c16502e238e3fc88ca7fd4c2f38d445b8", size = 253450, upload-time = "2026-08-12T14:35:02.217Z" }, + { url = "https://files.pythonhosted.org/packages/e4/0f/d044c4872c0938a84f87b5027a698c0e61bacfc5c3551a4e749ca9b7bc5c/charset_normalizer-3.5.0-cp37-abi3-win32.whl", hash = "sha256:8b3e9e29b8b07cc461b9ce7768db7693a93979d0dadf22046f6f3555ded2f516", size = 173594, upload-time = "2026-08-12T14:35:03.845Z" }, + { url = "https://files.pythonhosted.org/packages/10/6b/6046773901f1944b9a89436351529811ee958afc7b774563be9d74a6f0c3/charset_normalizer-3.5.0-cp37-abi3-win_amd64.whl", hash = "sha256:0c8953d9d1617794cfc40d81179571c9ba3805dd029623a15c93f1fb70e60a74", size = 198959, upload-time = "2026-08-12T14:35:05.187Z" }, + { url = "https://files.pythonhosted.org/packages/ab/a6/b57708ac92aefc8e8389d51d5178129b81f03196da61ee2c23e687b8178a/charset_normalizer-3.5.0-cp37-abi3-win_arm64.whl", hash = "sha256:562d24ca7797c1af8852994950c2e623a907b201fc4b0ed29e92af173d3828ca", size = 267055, upload-time = "2026-08-12T14:35:06.533Z" }, + { url = "https://files.pythonhosted.org/packages/22/c7/754d09943a616937df61e4ba367c409ded2a987e872972098d51a6fcf73b/charset_normalizer-3.5.0-py3-none-any.whl", hash = "sha256:993dfcbe75a85a3784abb5084f2c41b915767c90546fcc92803cffa28611baea", size = 67943, upload-time = "2026-08-12T14:35:30.363Z" }, +] + +[[package]] +name = "click" +version = "8.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/76/d4/81420972a676e8ffea40450d8c8c92943e7218a78fe9b64359836cc9876b/click-8.4.2.tar.gz", hash = "sha256:9a6cea6e60b17ebe0a44c5cc636d94f09bd66142c1cd7d8b4cd731c4917a15f6", size = 338000, upload-time = "2026-06-24T17:45:15.148Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/e2/79c688af8b210d232694e31e59da9f6ec747bae31c3f5946e4e9b98860d5/click-8.4.2-py3-none-any.whl", hash = "sha256:e6f9f66136c816745b9d65817da91d61d957fb16e02e4dcd0552553c5a197b76", size = 119243, upload-time = "2026-06-24T17:45:13.73Z" }, +] + +[[package]] +name = "codameter" +source = { editable = "." } +dependencies = [ + { name = "matplotlib", version = "3.10.9", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "matplotlib", version = "3.11.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "numpy", version = "2.5.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "pandas", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "pandas", version = "3.0.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "pyarrow" }, + { name = "pyyaml" }, + { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "scipy", version = "1.18.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "xarray", version = "2025.6.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "xarray", version = "2026.7.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, +] + +[package.optional-dependencies] +all = [ + { name = "disba" }, + { name = "emcee" }, +] +aws = [ + { name = "boto3" }, +] +dev = [ + { name = "black" }, + { name = "disba" }, + { name = "emcee" }, + { name = "hypothesis" }, + { name = "mkdocs" }, + { name = "mkdocs-material" }, + { name = "mkdocstrings", extra = ["python"] }, + { name = "mypy" }, + { name = "pre-commit" }, + { name = "pytest" }, + { name = "pytest-cov" }, + { name = "ruff" }, +] +docs = [ + { name = "mkdocs" }, + { name = "mkdocs-material" }, + { name = "mkdocstrings", extra = ["python"] }, +] +kernels = [ + { name = "disba" }, +] +mcmc = [ + { name = "emcee" }, +] +test = [ + { name = "hypothesis" }, + { name = "pytest" }, + { name = "pytest-cov" }, +] + +[package.metadata] +requires-dist = [ + { name = "black", marker = "extra == 'dev'", specifier = ">=23.10" }, + { name = "boto3", marker = "extra == 'aws'", specifier = ">=1.28" }, + { name = "disba", marker = "extra == 'all'", specifier = ">=0.7,<0.8" }, + { name = "disba", marker = "extra == 'dev'", specifier = ">=0.7,<0.8" }, + { name = "disba", marker = "extra == 'kernels'", specifier = ">=0.7,<0.8" }, + { name = "emcee", marker = "extra == 'all'", specifier = ">=3.1" }, + { name = "emcee", marker = "extra == 'dev'", specifier = ">=3.1" }, + { name = "emcee", marker = "extra == 'mcmc'", specifier = ">=3.1" }, + { name = "hypothesis", marker = "extra == 'dev'", specifier = ">=6.80" }, + { name = "hypothesis", marker = "extra == 'test'", specifier = ">=6.80" }, + { name = "matplotlib", specifier = ">=3.7" }, + { name = "mkdocs", marker = "extra == 'dev'", specifier = ">=1.5" }, + { name = "mkdocs", marker = "extra == 'docs'", specifier = ">=1.5" }, + { name = "mkdocs-material", marker = "extra == 'dev'", specifier = ">=9.4" }, + { name = "mkdocs-material", marker = "extra == 'docs'", specifier = ">=9.4" }, + { name = "mkdocstrings", extras = ["python"], marker = "extra == 'dev'", specifier = ">=0.24" }, + { name = "mkdocstrings", extras = ["python"], marker = "extra == 'docs'", specifier = ">=0.24" }, + { name = "mypy", marker = "extra == 'dev'", specifier = ">=1.6" }, + { name = "numpy", specifier = ">=1.24" }, + { name = "pandas", specifier = ">=2.0" }, + { name = "pre-commit", marker = "extra == 'dev'", specifier = ">=3.5" }, + { name = "pyarrow", specifier = ">=12.0" }, + { name = "pytest", marker = "extra == 'dev'", specifier = ">=7.4" }, + { name = "pytest", marker = "extra == 'test'", specifier = ">=7.4" }, + { name = "pytest-cov", marker = "extra == 'dev'", specifier = ">=4.1" }, + { name = "pytest-cov", marker = "extra == 'test'", specifier = ">=4.1" }, + { name = "pyyaml", specifier = ">=6.0" }, + { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.1" }, + { name = "scipy", specifier = ">=1.10" }, + { name = "xarray", specifier = ">=2023.6" }, +] +provides-extras = ["all", "aws", "dev", "docs", "kernels", "mcmc", "test"] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "contourpy" +version = "1.3.2" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.11'", +] +dependencies = [ + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/54/eb9bfc647b19f2009dd5c7f5ec51c4e6ca831725f1aea7a993034f483147/contourpy-1.3.2.tar.gz", hash = "sha256:b6945942715a034c671b7fc54f9588126b0b8bf23db2696e3ca8328f3ff0ab54", size = 13466130, upload-time = "2025-04-15T17:47:53.79Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/a3/da4153ec8fe25d263aa48c1a4cbde7f49b59af86f0b6f7862788c60da737/contourpy-1.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ba38e3f9f330af820c4b27ceb4b9c7feee5fe0493ea53a8720f4792667465934", size = 268551, upload-time = "2025-04-15T17:34:46.581Z" }, + { url = "https://files.pythonhosted.org/packages/2f/6c/330de89ae1087eb622bfca0177d32a7ece50c3ef07b28002de4757d9d875/contourpy-1.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dc41ba0714aa2968d1f8674ec97504a8f7e334f48eeacebcaa6256213acb0989", size = 253399, upload-time = "2025-04-15T17:34:51.427Z" }, + { url = "https://files.pythonhosted.org/packages/c1/bd/20c6726b1b7f81a8bee5271bed5c165f0a8e1f572578a9d27e2ccb763cb2/contourpy-1.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9be002b31c558d1ddf1b9b415b162c603405414bacd6932d031c5b5a8b757f0d", size = 312061, upload-time = "2025-04-15T17:34:55.961Z" }, + { url = "https://files.pythonhosted.org/packages/22/fc/a9665c88f8a2473f823cf1ec601de9e5375050f1958cbb356cdf06ef1ab6/contourpy-1.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8d2e74acbcba3bfdb6d9d8384cdc4f9260cae86ed9beee8bd5f54fee49a430b9", size = 351956, upload-time = "2025-04-15T17:35:00.992Z" }, + { url = "https://files.pythonhosted.org/packages/25/eb/9f0a0238f305ad8fb7ef42481020d6e20cf15e46be99a1fcf939546a177e/contourpy-1.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e259bced5549ac64410162adc973c5e2fb77f04df4a439d00b478e57a0e65512", size = 320872, upload-time = "2025-04-15T17:35:06.177Z" }, + { url = "https://files.pythonhosted.org/packages/32/5c/1ee32d1c7956923202f00cf8d2a14a62ed7517bdc0ee1e55301227fc273c/contourpy-1.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad687a04bc802cbe8b9c399c07162a3c35e227e2daccf1668eb1f278cb698631", size = 325027, upload-time = "2025-04-15T17:35:11.244Z" }, + { url = "https://files.pythonhosted.org/packages/83/bf/9baed89785ba743ef329c2b07fd0611d12bfecbedbdd3eeecf929d8d3b52/contourpy-1.3.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cdd22595308f53ef2f891040ab2b93d79192513ffccbd7fe19be7aa773a5e09f", size = 1306641, upload-time = "2025-04-15T17:35:26.701Z" }, + { url = "https://files.pythonhosted.org/packages/d4/cc/74e5e83d1e35de2d28bd97033426b450bc4fd96e092a1f7a63dc7369b55d/contourpy-1.3.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b4f54d6a2defe9f257327b0f243612dd051cc43825587520b1bf74a31e2f6ef2", size = 1374075, upload-time = "2025-04-15T17:35:43.204Z" }, + { url = "https://files.pythonhosted.org/packages/0c/42/17f3b798fd5e033b46a16f8d9fcb39f1aba051307f5ebf441bad1ecf78f8/contourpy-1.3.2-cp310-cp310-win32.whl", hash = "sha256:f939a054192ddc596e031e50bb13b657ce318cf13d264f095ce9db7dc6ae81c0", size = 177534, upload-time = "2025-04-15T17:35:46.554Z" }, + { url = "https://files.pythonhosted.org/packages/54/ec/5162b8582f2c994721018d0c9ece9dc6ff769d298a8ac6b6a652c307e7df/contourpy-1.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:c440093bbc8fc21c637c03bafcbef95ccd963bc6e0514ad887932c18ca2a759a", size = 221188, upload-time = "2025-04-15T17:35:50.064Z" }, + { url = "https://files.pythonhosted.org/packages/b3/b9/ede788a0b56fc5b071639d06c33cb893f68b1178938f3425debebe2dab78/contourpy-1.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6a37a2fb93d4df3fc4c0e363ea4d16f83195fc09c891bc8ce072b9d084853445", size = 269636, upload-time = "2025-04-15T17:35:54.473Z" }, + { url = "https://files.pythonhosted.org/packages/e6/75/3469f011d64b8bbfa04f709bfc23e1dd71be54d05b1b083be9f5b22750d1/contourpy-1.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b7cd50c38f500bbcc9b6a46643a40e0913673f869315d8e70de0438817cb7773", size = 254636, upload-time = "2025-04-15T17:35:58.283Z" }, + { url = "https://files.pythonhosted.org/packages/8d/2f/95adb8dae08ce0ebca4fd8e7ad653159565d9739128b2d5977806656fcd2/contourpy-1.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6658ccc7251a4433eebd89ed2672c2ed96fba367fd25ca9512aa92a4b46c4f1", size = 313053, upload-time = "2025-04-15T17:36:03.235Z" }, + { url = "https://files.pythonhosted.org/packages/c3/a6/8ccf97a50f31adfa36917707fe39c9a0cbc24b3bbb58185577f119736cc9/contourpy-1.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:70771a461aaeb335df14deb6c97439973d253ae70660ca085eec25241137ef43", size = 352985, upload-time = "2025-04-15T17:36:08.275Z" }, + { url = "https://files.pythonhosted.org/packages/1d/b6/7925ab9b77386143f39d9c3243fdd101621b4532eb126743201160ffa7e6/contourpy-1.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65a887a6e8c4cd0897507d814b14c54a8c2e2aa4ac9f7686292f9769fcf9a6ab", size = 323750, upload-time = "2025-04-15T17:36:13.29Z" }, + { url = "https://files.pythonhosted.org/packages/c2/f3/20c5d1ef4f4748e52d60771b8560cf00b69d5c6368b5c2e9311bcfa2a08b/contourpy-1.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3859783aefa2b8355697f16642695a5b9792e7a46ab86da1118a4a23a51a33d7", size = 326246, upload-time = "2025-04-15T17:36:18.329Z" }, + { url = "https://files.pythonhosted.org/packages/8c/e5/9dae809e7e0b2d9d70c52b3d24cba134dd3dad979eb3e5e71f5df22ed1f5/contourpy-1.3.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:eab0f6db315fa4d70f1d8ab514e527f0366ec021ff853d7ed6a2d33605cf4b83", size = 1308728, upload-time = "2025-04-15T17:36:33.878Z" }, + { url = "https://files.pythonhosted.org/packages/e2/4a/0058ba34aeea35c0b442ae61a4f4d4ca84d6df8f91309bc2d43bb8dd248f/contourpy-1.3.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d91a3ccc7fea94ca0acab82ceb77f396d50a1f67412efe4c526f5d20264e6ecd", size = 1375762, upload-time = "2025-04-15T17:36:51.295Z" }, + { url = "https://files.pythonhosted.org/packages/09/33/7174bdfc8b7767ef2c08ed81244762d93d5c579336fc0b51ca57b33d1b80/contourpy-1.3.2-cp311-cp311-win32.whl", hash = "sha256:1c48188778d4d2f3d48e4643fb15d8608b1d01e4b4d6b0548d9b336c28fc9b6f", size = 178196, upload-time = "2025-04-15T17:36:55.002Z" }, + { url = "https://files.pythonhosted.org/packages/5e/fe/4029038b4e1c4485cef18e480b0e2cd2d755448bb071eb9977caac80b77b/contourpy-1.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:5ebac872ba09cb8f2131c46b8739a7ff71de28a24c869bcad554477eb089a878", size = 222017, upload-time = "2025-04-15T17:36:58.576Z" }, + { url = "https://files.pythonhosted.org/packages/34/f7/44785876384eff370c251d58fd65f6ad7f39adce4a093c934d4a67a7c6b6/contourpy-1.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4caf2bcd2969402bf77edc4cb6034c7dd7c0803213b3523f111eb7460a51b8d2", size = 271580, upload-time = "2025-04-15T17:37:03.105Z" }, + { url = "https://files.pythonhosted.org/packages/93/3b/0004767622a9826ea3d95f0e9d98cd8729015768075d61f9fea8eeca42a8/contourpy-1.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:82199cb78276249796419fe36b7386bd8d2cc3f28b3bc19fe2454fe2e26c4c15", size = 255530, upload-time = "2025-04-15T17:37:07.026Z" }, + { url = "https://files.pythonhosted.org/packages/e7/bb/7bd49e1f4fa805772d9fd130e0d375554ebc771ed7172f48dfcd4ca61549/contourpy-1.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:106fab697af11456fcba3e352ad50effe493a90f893fca6c2ca5c033820cea92", size = 307688, upload-time = "2025-04-15T17:37:11.481Z" }, + { url = "https://files.pythonhosted.org/packages/fc/97/e1d5dbbfa170725ef78357a9a0edc996b09ae4af170927ba8ce977e60a5f/contourpy-1.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d14f12932a8d620e307f715857107b1d1845cc44fdb5da2bc8e850f5ceba9f87", size = 347331, upload-time = "2025-04-15T17:37:18.212Z" }, + { url = "https://files.pythonhosted.org/packages/6f/66/e69e6e904f5ecf6901be3dd16e7e54d41b6ec6ae3405a535286d4418ffb4/contourpy-1.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:532fd26e715560721bb0d5fc7610fce279b3699b018600ab999d1be895b09415", size = 318963, upload-time = "2025-04-15T17:37:22.76Z" }, + { url = "https://files.pythonhosted.org/packages/a8/32/b8a1c8965e4f72482ff2d1ac2cd670ce0b542f203c8e1d34e7c3e6925da7/contourpy-1.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f26b383144cf2d2c29f01a1e8170f50dacf0eac02d64139dcd709a8ac4eb3cfe", size = 323681, upload-time = "2025-04-15T17:37:33.001Z" }, + { url = "https://files.pythonhosted.org/packages/30/c6/12a7e6811d08757c7162a541ca4c5c6a34c0f4e98ef2b338791093518e40/contourpy-1.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c49f73e61f1f774650a55d221803b101d966ca0c5a2d6d5e4320ec3997489441", size = 1308674, upload-time = "2025-04-15T17:37:48.64Z" }, + { url = "https://files.pythonhosted.org/packages/2a/8a/bebe5a3f68b484d3a2b8ffaf84704b3e343ef1addea528132ef148e22b3b/contourpy-1.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3d80b2c0300583228ac98d0a927a1ba6a2ba6b8a742463c564f1d419ee5b211e", size = 1380480, upload-time = "2025-04-15T17:38:06.7Z" }, + { url = "https://files.pythonhosted.org/packages/34/db/fcd325f19b5978fb509a7d55e06d99f5f856294c1991097534360b307cf1/contourpy-1.3.2-cp312-cp312-win32.whl", hash = "sha256:90df94c89a91b7362e1142cbee7568f86514412ab8a2c0d0fca72d7e91b62912", size = 178489, upload-time = "2025-04-15T17:38:10.338Z" }, + { url = "https://files.pythonhosted.org/packages/01/c8/fadd0b92ffa7b5eb5949bf340a63a4a496a6930a6c37a7ba0f12acb076d6/contourpy-1.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:8c942a01d9163e2e5cfb05cb66110121b8d07ad438a17f9e766317bcb62abf73", size = 223042, upload-time = "2025-04-15T17:38:14.239Z" }, + { url = "https://files.pythonhosted.org/packages/2e/61/5673f7e364b31e4e7ef6f61a4b5121c5f170f941895912f773d95270f3a2/contourpy-1.3.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:de39db2604ae755316cb5967728f4bea92685884b1e767b7c24e983ef5f771cb", size = 271630, upload-time = "2025-04-15T17:38:19.142Z" }, + { url = "https://files.pythonhosted.org/packages/ff/66/a40badddd1223822c95798c55292844b7e871e50f6bfd9f158cb25e0bd39/contourpy-1.3.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3f9e896f447c5c8618f1edb2bafa9a4030f22a575ec418ad70611450720b5b08", size = 255670, upload-time = "2025-04-15T17:38:23.688Z" }, + { url = "https://files.pythonhosted.org/packages/1e/c7/cf9fdee8200805c9bc3b148f49cb9482a4e3ea2719e772602a425c9b09f8/contourpy-1.3.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71e2bd4a1c4188f5c2b8d274da78faab884b59df20df63c34f74aa1813c4427c", size = 306694, upload-time = "2025-04-15T17:38:28.238Z" }, + { url = "https://files.pythonhosted.org/packages/dd/e7/ccb9bec80e1ba121efbffad7f38021021cda5be87532ec16fd96533bb2e0/contourpy-1.3.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de425af81b6cea33101ae95ece1f696af39446db9682a0b56daaa48cfc29f38f", size = 345986, upload-time = "2025-04-15T17:38:33.502Z" }, + { url = "https://files.pythonhosted.org/packages/dc/49/ca13bb2da90391fa4219fdb23b078d6065ada886658ac7818e5441448b78/contourpy-1.3.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:977e98a0e0480d3fe292246417239d2d45435904afd6d7332d8455981c408b85", size = 318060, upload-time = "2025-04-15T17:38:38.672Z" }, + { url = "https://files.pythonhosted.org/packages/c8/65/5245ce8c548a8422236c13ffcdcdada6a2a812c361e9e0c70548bb40b661/contourpy-1.3.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:434f0adf84911c924519d2b08fc10491dd282b20bdd3fa8f60fd816ea0b48841", size = 322747, upload-time = "2025-04-15T17:38:43.712Z" }, + { url = "https://files.pythonhosted.org/packages/72/30/669b8eb48e0a01c660ead3752a25b44fdb2e5ebc13a55782f639170772f9/contourpy-1.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c66c4906cdbc50e9cba65978823e6e00b45682eb09adbb78c9775b74eb222422", size = 1308895, upload-time = "2025-04-15T17:39:00.224Z" }, + { url = "https://files.pythonhosted.org/packages/05/5a/b569f4250decee6e8d54498be7bdf29021a4c256e77fe8138c8319ef8eb3/contourpy-1.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8b7fc0cd78ba2f4695fd0a6ad81a19e7e3ab825c31b577f384aa9d7817dc3bef", size = 1379098, upload-time = "2025-04-15T17:43:29.649Z" }, + { url = "https://files.pythonhosted.org/packages/19/ba/b227c3886d120e60e41b28740ac3617b2f2b971b9f601c835661194579f1/contourpy-1.3.2-cp313-cp313-win32.whl", hash = "sha256:15ce6ab60957ca74cff444fe66d9045c1fd3e92c8936894ebd1f3eef2fff075f", size = 178535, upload-time = "2025-04-15T17:44:44.532Z" }, + { url = "https://files.pythonhosted.org/packages/12/6e/2fed56cd47ca739b43e892707ae9a13790a486a3173be063681ca67d2262/contourpy-1.3.2-cp313-cp313-win_amd64.whl", hash = "sha256:e1578f7eafce927b168752ed7e22646dad6cd9bca673c60bff55889fa236ebf9", size = 223096, upload-time = "2025-04-15T17:44:48.194Z" }, + { url = "https://files.pythonhosted.org/packages/54/4c/e76fe2a03014a7c767d79ea35c86a747e9325537a8b7627e0e5b3ba266b4/contourpy-1.3.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0475b1f6604896bc7c53bb070e355e9321e1bc0d381735421a2d2068ec56531f", size = 285090, upload-time = "2025-04-15T17:43:34.084Z" }, + { url = "https://files.pythonhosted.org/packages/7b/e2/5aba47debd55d668e00baf9651b721e7733975dc9fc27264a62b0dd26eb8/contourpy-1.3.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c85bb486e9be652314bb5b9e2e3b0d1b2e643d5eec4992c0fbe8ac71775da739", size = 268643, upload-time = "2025-04-15T17:43:38.626Z" }, + { url = "https://files.pythonhosted.org/packages/a1/37/cd45f1f051fe6230f751cc5cdd2728bb3a203f5619510ef11e732109593c/contourpy-1.3.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:745b57db7758f3ffc05a10254edd3182a2a83402a89c00957a8e8a22f5582823", size = 310443, upload-time = "2025-04-15T17:43:44.522Z" }, + { url = "https://files.pythonhosted.org/packages/8b/a2/36ea6140c306c9ff6dd38e3bcec80b3b018474ef4d17eb68ceecd26675f4/contourpy-1.3.2-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:970e9173dbd7eba9b4e01aab19215a48ee5dd3f43cef736eebde064a171f89a5", size = 349865, upload-time = "2025-04-15T17:43:49.545Z" }, + { url = "https://files.pythonhosted.org/packages/95/b7/2fc76bc539693180488f7b6cc518da7acbbb9e3b931fd9280504128bf956/contourpy-1.3.2-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6c4639a9c22230276b7bffb6a850dfc8258a2521305e1faefe804d006b2e532", size = 321162, upload-time = "2025-04-15T17:43:54.203Z" }, + { url = "https://files.pythonhosted.org/packages/f4/10/76d4f778458b0aa83f96e59d65ece72a060bacb20cfbee46cf6cd5ceba41/contourpy-1.3.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc829960f34ba36aad4302e78eabf3ef16a3a100863f0d4eeddf30e8a485a03b", size = 327355, upload-time = "2025-04-15T17:44:01.025Z" }, + { url = "https://files.pythonhosted.org/packages/43/a3/10cf483ea683f9f8ab096c24bad3cce20e0d1dd9a4baa0e2093c1c962d9d/contourpy-1.3.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:d32530b534e986374fc19eaa77fcb87e8a99e5431499949b828312bdcd20ac52", size = 1307935, upload-time = "2025-04-15T17:44:17.322Z" }, + { url = "https://files.pythonhosted.org/packages/78/73/69dd9a024444489e22d86108e7b913f3528f56cfc312b5c5727a44188471/contourpy-1.3.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e298e7e70cf4eb179cc1077be1c725b5fd131ebc81181bf0c03525c8abc297fd", size = 1372168, upload-time = "2025-04-15T17:44:33.43Z" }, + { url = "https://files.pythonhosted.org/packages/0f/1b/96d586ccf1b1a9d2004dd519b25fbf104a11589abfd05484ff12199cca21/contourpy-1.3.2-cp313-cp313t-win32.whl", hash = "sha256:d0e589ae0d55204991450bb5c23f571c64fe43adaa53f93fc902a84c96f52fe1", size = 189550, upload-time = "2025-04-15T17:44:37.092Z" }, + { url = "https://files.pythonhosted.org/packages/b0/e6/6000d0094e8a5e32ad62591c8609e269febb6e4db83a1c75ff8868b42731/contourpy-1.3.2-cp313-cp313t-win_amd64.whl", hash = "sha256:78e9253c3de756b3f6a5174d024c4835acd59eb3f8e2ca13e775dbffe1558f69", size = 238214, upload-time = "2025-04-15T17:44:40.827Z" }, + { url = "https://files.pythonhosted.org/packages/33/05/b26e3c6ecc05f349ee0013f0bb850a761016d89cec528a98193a48c34033/contourpy-1.3.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:fd93cc7f3139b6dd7aab2f26a90dde0aa9fc264dbf70f6740d498a70b860b82c", size = 265681, upload-time = "2025-04-15T17:44:59.314Z" }, + { url = "https://files.pythonhosted.org/packages/2b/25/ac07d6ad12affa7d1ffed11b77417d0a6308170f44ff20fa1d5aa6333f03/contourpy-1.3.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:107ba8a6a7eec58bb475329e6d3b95deba9440667c4d62b9b6063942b61d7f16", size = 315101, upload-time = "2025-04-15T17:45:04.165Z" }, + { url = "https://files.pythonhosted.org/packages/8f/4d/5bb3192bbe9d3f27e3061a6a8e7733c9120e203cb8515767d30973f71030/contourpy-1.3.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ded1706ed0c1049224531b81128efbd5084598f18d8a2d9efae833edbd2b40ad", size = 220599, upload-time = "2025-04-15T17:45:08.456Z" }, + { url = "https://files.pythonhosted.org/packages/ff/c0/91f1215d0d9f9f343e4773ba6c9b89e8c0cc7a64a6263f21139da639d848/contourpy-1.3.2-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5f5964cdad279256c084b69c3f412b7801e15356b16efa9d78aa974041903da0", size = 266807, upload-time = "2025-04-15T17:45:15.535Z" }, + { url = "https://files.pythonhosted.org/packages/d4/79/6be7e90c955c0487e7712660d6cead01fa17bff98e0ea275737cc2bc8e71/contourpy-1.3.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49b65a95d642d4efa8f64ba12558fcb83407e58a2dfba9d796d77b63ccfcaff5", size = 318729, upload-time = "2025-04-15T17:45:20.166Z" }, + { url = "https://files.pythonhosted.org/packages/87/68/7f46fb537958e87427d98a4074bcde4b67a70b04900cfc5ce29bc2f556c1/contourpy-1.3.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:8c5acb8dddb0752bf252e01a3035b21443158910ac16a3b0d20e7fed7d534ce5", size = 221791, upload-time = "2025-04-15T17:45:24.794Z" }, +] + +[[package]] +name = "contourpy" +version = "1.3.3" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.15' and sys_platform == 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'win32'", + "python_full_version >= '3.15' and sys_platform == 'emscripten'", + "python_full_version == '3.14.*' and sys_platform == 'emscripten'", + "python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'emscripten'", + "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] +dependencies = [ + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "numpy", version = "2.5.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/58/01/1253e6698a07380cd31a736d248a3f2a50a7c88779a1813da27503cadc2a/contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880", size = 13466174, upload-time = "2025-07-26T12:03:12.549Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/91/2e/c4390a31919d8a78b90e8ecf87cd4b4c4f05a5b48d05ec17db8e5404c6f4/contourpy-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:709a48ef9a690e1343202916450bc48b9e51c049b089c7f79a267b46cffcdaa1", size = 288773, upload-time = "2025-07-26T12:01:02.277Z" }, + { url = "https://files.pythonhosted.org/packages/0d/44/c4b0b6095fef4dc9c420e041799591e3b63e9619e3044f7f4f6c21c0ab24/contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:23416f38bfd74d5d28ab8429cc4d63fa67d5068bd711a85edb1c3fb0c3e2f381", size = 270149, upload-time = "2025-07-26T12:01:04.072Z" }, + { url = "https://files.pythonhosted.org/packages/30/2e/dd4ced42fefac8470661d7cb7e264808425e6c5d56d175291e93890cce09/contourpy-1.3.3-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:929ddf8c4c7f348e4c0a5a3a714b5c8542ffaa8c22954862a46ca1813b667ee7", size = 329222, upload-time = "2025-07-26T12:01:05.688Z" }, + { url = "https://files.pythonhosted.org/packages/f2/74/cc6ec2548e3d276c71389ea4802a774b7aa3558223b7bade3f25787fafc2/contourpy-1.3.3-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9e999574eddae35f1312c2b4b717b7885d4edd6cb46700e04f7f02db454e67c1", size = 377234, upload-time = "2025-07-26T12:01:07.054Z" }, + { url = "https://files.pythonhosted.org/packages/03/b3/64ef723029f917410f75c09da54254c5f9ea90ef89b143ccadb09df14c15/contourpy-1.3.3-cp311-cp311-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0bf67e0e3f482cb69779dd3061b534eb35ac9b17f163d851e2a547d56dba0a3a", size = 380555, upload-time = "2025-07-26T12:01:08.801Z" }, + { url = "https://files.pythonhosted.org/packages/5f/4b/6157f24ca425b89fe2eb7e7be642375711ab671135be21e6faa100f7448c/contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:51e79c1f7470158e838808d4a996fa9bac72c498e93d8ebe5119bc1e6becb0db", size = 355238, upload-time = "2025-07-26T12:01:10.319Z" }, + { url = "https://files.pythonhosted.org/packages/98/56/f914f0dd678480708a04cfd2206e7c382533249bc5001eb9f58aa693e200/contourpy-1.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:598c3aaece21c503615fd59c92a3598b428b2f01bfb4b8ca9c4edeecc2438620", size = 1326218, upload-time = "2025-07-26T12:01:12.659Z" }, + { url = "https://files.pythonhosted.org/packages/fb/d7/4a972334a0c971acd5172389671113ae82aa7527073980c38d5868ff1161/contourpy-1.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:322ab1c99b008dad206d406bb61d014cf0174df491ae9d9d0fac6a6fda4f977f", size = 1392867, upload-time = "2025-07-26T12:01:15.533Z" }, + { url = "https://files.pythonhosted.org/packages/75/3e/f2cc6cd56dc8cff46b1a56232eabc6feea52720083ea71ab15523daab796/contourpy-1.3.3-cp311-cp311-win32.whl", hash = "sha256:fd907ae12cd483cd83e414b12941c632a969171bf90fc937d0c9f268a31cafff", size = 183677, upload-time = "2025-07-26T12:01:17.088Z" }, + { url = "https://files.pythonhosted.org/packages/98/4b/9bd370b004b5c9d8045c6c33cf65bae018b27aca550a3f657cdc99acdbd8/contourpy-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42", size = 225234, upload-time = "2025-07-26T12:01:18.256Z" }, + { url = "https://files.pythonhosted.org/packages/d9/b6/71771e02c2e004450c12b1120a5f488cad2e4d5b590b1af8bad060360fe4/contourpy-1.3.3-cp311-cp311-win_arm64.whl", hash = "sha256:15ff10bfada4bf92ec8b31c62bf7c1834c244019b4a33095a68000d7075df470", size = 193123, upload-time = "2025-07-26T12:01:19.848Z" }, + { url = "https://files.pythonhosted.org/packages/be/45/adfee365d9ea3d853550b2e735f9d66366701c65db7855cd07621732ccfc/contourpy-1.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b08a32ea2f8e42cf1d4be3169a98dd4be32bafe4f22b6c4cb4ba810fa9e5d2cb", size = 293419, upload-time = "2025-07-26T12:01:21.16Z" }, + { url = "https://files.pythonhosted.org/packages/53/3e/405b59cfa13021a56bba395a6b3aca8cec012b45bf177b0eaf7a202cde2c/contourpy-1.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:556dba8fb6f5d8742f2923fe9457dbdd51e1049c4a43fd3986a0b14a1d815fc6", size = 273979, upload-time = "2025-07-26T12:01:22.448Z" }, + { url = "https://files.pythonhosted.org/packages/d4/1c/a12359b9b2ca3a845e8f7f9ac08bdf776114eb931392fcad91743e2ea17b/contourpy-1.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92d9abc807cf7d0e047b95ca5d957cf4792fcd04e920ca70d48add15c1a90ea7", size = 332653, upload-time = "2025-07-26T12:01:24.155Z" }, + { url = "https://files.pythonhosted.org/packages/63/12/897aeebfb475b7748ea67b61e045accdfcf0d971f8a588b67108ed7f5512/contourpy-1.3.3-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b2e8faa0ed68cb29af51edd8e24798bb661eac3bd9f65420c1887b6ca89987c8", size = 379536, upload-time = "2025-07-26T12:01:25.91Z" }, + { url = "https://files.pythonhosted.org/packages/43/8a/a8c584b82deb248930ce069e71576fc09bd7174bbd35183b7943fb1064fd/contourpy-1.3.3-cp312-cp312-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:626d60935cf668e70a5ce6ff184fd713e9683fb458898e4249b63be9e28286ea", size = 384397, upload-time = "2025-07-26T12:01:27.152Z" }, + { url = "https://files.pythonhosted.org/packages/cc/8f/ec6289987824b29529d0dfda0d74a07cec60e54b9c92f3c9da4c0ac732de/contourpy-1.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4d00e655fcef08aba35ec9610536bfe90267d7ab5ba944f7032549c55a146da1", size = 362601, upload-time = "2025-07-26T12:01:28.808Z" }, + { url = "https://files.pythonhosted.org/packages/05/0a/a3fe3be3ee2dceb3e615ebb4df97ae6f3828aa915d3e10549ce016302bd1/contourpy-1.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:451e71b5a7d597379ef572de31eeb909a87246974d960049a9848c3bc6c41bf7", size = 1331288, upload-time = "2025-07-26T12:01:31.198Z" }, + { url = "https://files.pythonhosted.org/packages/33/1d/acad9bd4e97f13f3e2b18a3977fe1b4a37ecf3d38d815333980c6c72e963/contourpy-1.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:459c1f020cd59fcfe6650180678a9993932d80d44ccde1fa1868977438f0b411", size = 1403386, upload-time = "2025-07-26T12:01:33.947Z" }, + { url = "https://files.pythonhosted.org/packages/cf/8f/5847f44a7fddf859704217a99a23a4f6417b10e5ab1256a179264561540e/contourpy-1.3.3-cp312-cp312-win32.whl", hash = "sha256:023b44101dfe49d7d53932be418477dba359649246075c996866106da069af69", size = 185018, upload-time = "2025-07-26T12:01:35.64Z" }, + { url = "https://files.pythonhosted.org/packages/19/e8/6026ed58a64563186a9ee3f29f41261fd1828f527dd93d33b60feca63352/contourpy-1.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:8153b8bfc11e1e4d75bcb0bff1db232f9e10b274e0929de9d608027e0d34ff8b", size = 226567, upload-time = "2025-07-26T12:01:36.804Z" }, + { url = "https://files.pythonhosted.org/packages/d1/e2/f05240d2c39a1ed228d8328a78b6f44cd695f7ef47beb3e684cf93604f86/contourpy-1.3.3-cp312-cp312-win_arm64.whl", hash = "sha256:07ce5ed73ecdc4a03ffe3e1b3e3c1166db35ae7584be76f65dbbe28a7791b0cc", size = 193655, upload-time = "2025-07-26T12:01:37.999Z" }, + { url = "https://files.pythonhosted.org/packages/68/35/0167aad910bbdb9599272bd96d01a9ec6852f36b9455cf2ca67bd4cc2d23/contourpy-1.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:177fb367556747a686509d6fef71d221a4b198a3905fe824430e5ea0fda54eb5", size = 293257, upload-time = "2025-07-26T12:01:39.367Z" }, + { url = "https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1", size = 274034, upload-time = "2025-07-26T12:01:40.645Z" }, + { url = "https://files.pythonhosted.org/packages/73/23/90e31ceeed1de63058a02cb04b12f2de4b40e3bef5e082a7c18d9c8ae281/contourpy-1.3.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:348ac1f5d4f1d66d3322420f01d42e43122f43616e0f194fc1c9f5d830c5b286", size = 334672, upload-time = "2025-07-26T12:01:41.942Z" }, + { url = "https://files.pythonhosted.org/packages/ed/93/b43d8acbe67392e659e1d984700e79eb67e2acb2bd7f62012b583a7f1b55/contourpy-1.3.3-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:655456777ff65c2c548b7c454af9c6f33f16c8884f11083244b5819cc214f1b5", size = 381234, upload-time = "2025-07-26T12:01:43.499Z" }, + { url = "https://files.pythonhosted.org/packages/46/3b/bec82a3ea06f66711520f75a40c8fc0b113b2a75edb36aa633eb11c4f50f/contourpy-1.3.3-cp313-cp313-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:644a6853d15b2512d67881586bd03f462c7ab755db95f16f14d7e238f2852c67", size = 385169, upload-time = "2025-07-26T12:01:45.219Z" }, + { url = "https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9", size = 362859, upload-time = "2025-07-26T12:01:46.519Z" }, + { url = "https://files.pythonhosted.org/packages/33/71/e2a7945b7de4e58af42d708a219f3b2f4cff7386e6b6ab0a0fa0033c49a9/contourpy-1.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a15459b0f4615b00bbd1e91f1b9e19b7e63aea7483d03d804186f278c0af2659", size = 1332062, upload-time = "2025-07-26T12:01:48.964Z" }, + { url = "https://files.pythonhosted.org/packages/12/fc/4e87ac754220ccc0e807284f88e943d6d43b43843614f0a8afa469801db0/contourpy-1.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca0fdcd73925568ca027e0b17ab07aad764be4706d0a925b89227e447d9737b7", size = 1403932, upload-time = "2025-07-26T12:01:51.979Z" }, + { url = "https://files.pythonhosted.org/packages/a6/2e/adc197a37443f934594112222ac1aa7dc9a98faf9c3842884df9a9d8751d/contourpy-1.3.3-cp313-cp313-win32.whl", hash = "sha256:b20c7c9a3bf701366556e1b1984ed2d0cedf999903c51311417cf5f591d8c78d", size = 185024, upload-time = "2025-07-26T12:01:53.245Z" }, + { url = "https://files.pythonhosted.org/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263", size = 226578, upload-time = "2025-07-26T12:01:54.422Z" }, + { url = "https://files.pythonhosted.org/packages/8a/9a/2f6024a0c5995243cd63afdeb3651c984f0d2bc727fd98066d40e141ad73/contourpy-1.3.3-cp313-cp313-win_arm64.whl", hash = "sha256:fd914713266421b7536de2bfa8181aa8c699432b6763a0ea64195ebe28bff6a9", size = 193524, upload-time = "2025-07-26T12:01:55.73Z" }, + { url = "https://files.pythonhosted.org/packages/c0/b3/f8a1a86bd3298513f500e5b1f5fd92b69896449f6cab6a146a5d52715479/contourpy-1.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:88df9880d507169449d434c293467418b9f6cbe82edd19284aa0409e7fdb933d", size = 306730, upload-time = "2025-07-26T12:01:57.051Z" }, + { url = "https://files.pythonhosted.org/packages/3f/11/4780db94ae62fc0c2053909b65dc3246bd7cecfc4f8a20d957ad43aa4ad8/contourpy-1.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d06bb1f751ba5d417047db62bca3c8fde202b8c11fb50742ab3ab962c81e8216", size = 287897, upload-time = "2025-07-26T12:01:58.663Z" }, + { url = "https://files.pythonhosted.org/packages/ae/15/e59f5f3ffdd6f3d4daa3e47114c53daabcb18574a26c21f03dc9e4e42ff0/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e4e6b05a45525357e382909a4c1600444e2a45b4795163d3b22669285591c1ae", size = 326751, upload-time = "2025-07-26T12:02:00.343Z" }, + { url = "https://files.pythonhosted.org/packages/0f/81/03b45cfad088e4770b1dcf72ea78d3802d04200009fb364d18a493857210/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ab3074b48c4e2cf1a960e6bbeb7f04566bf36b1861d5c9d4d8ac04b82e38ba20", size = 375486, upload-time = "2025-07-26T12:02:02.128Z" }, + { url = "https://files.pythonhosted.org/packages/0c/ba/49923366492ffbdd4486e970d421b289a670ae8cf539c1ea9a09822b371a/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c3d53c796f8647d6deb1abe867daeb66dcc8a97e8455efa729516b997b8ed99", size = 388106, upload-time = "2025-07-26T12:02:03.615Z" }, + { url = "https://files.pythonhosted.org/packages/9f/52/5b00ea89525f8f143651f9f03a0df371d3cbd2fccd21ca9b768c7a6500c2/contourpy-1.3.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50ed930df7289ff2a8d7afeb9603f8289e5704755c7e5c3bbd929c90c817164b", size = 352548, upload-time = "2025-07-26T12:02:05.165Z" }, + { url = "https://files.pythonhosted.org/packages/32/1d/a209ec1a3a3452d490f6b14dd92e72280c99ae3d1e73da74f8277d4ee08f/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4feffb6537d64b84877da813a5c30f1422ea5739566abf0bd18065ac040e120a", size = 1322297, upload-time = "2025-07-26T12:02:07.379Z" }, + { url = "https://files.pythonhosted.org/packages/bc/9e/46f0e8ebdd884ca0e8877e46a3f4e633f6c9c8c4f3f6e72be3fe075994aa/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2b7e9480ffe2b0cd2e787e4df64270e3a0440d9db8dc823312e2c940c167df7e", size = 1391023, upload-time = "2025-07-26T12:02:10.171Z" }, + { url = "https://files.pythonhosted.org/packages/b9/70/f308384a3ae9cd2209e0849f33c913f658d3326900d0ff5d378d6a1422d2/contourpy-1.3.3-cp313-cp313t-win32.whl", hash = "sha256:283edd842a01e3dcd435b1c5116798d661378d83d36d337b8dde1d16a5fc9ba3", size = 196157, upload-time = "2025-07-26T12:02:11.488Z" }, + { url = "https://files.pythonhosted.org/packages/b2/dd/880f890a6663b84d9e34a6f88cded89d78f0091e0045a284427cb6b18521/contourpy-1.3.3-cp313-cp313t-win_amd64.whl", hash = "sha256:87acf5963fc2b34825e5b6b048f40e3635dd547f590b04d2ab317c2619ef7ae8", size = 240570, upload-time = "2025-07-26T12:02:12.754Z" }, + { url = "https://files.pythonhosted.org/packages/80/99/2adc7d8ffead633234817ef8e9a87115c8a11927a94478f6bb3d3f4d4f7d/contourpy-1.3.3-cp313-cp313t-win_arm64.whl", hash = "sha256:3c30273eb2a55024ff31ba7d052dde990d7d8e5450f4bbb6e913558b3d6c2301", size = 199713, upload-time = "2025-07-26T12:02:14.4Z" }, + { url = "https://files.pythonhosted.org/packages/72/8b/4546f3ab60f78c514ffb7d01a0bd743f90de36f0019d1be84d0a708a580a/contourpy-1.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fde6c716d51c04b1c25d0b90364d0be954624a0ee9d60e23e850e8d48353d07a", size = 292189, upload-time = "2025-07-26T12:02:16.095Z" }, + { url = "https://files.pythonhosted.org/packages/fd/e1/3542a9cb596cadd76fcef413f19c79216e002623158befe6daa03dbfa88c/contourpy-1.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:cbedb772ed74ff5be440fa8eee9bd49f64f6e3fc09436d9c7d8f1c287b121d77", size = 273251, upload-time = "2025-07-26T12:02:17.524Z" }, + { url = "https://files.pythonhosted.org/packages/b1/71/f93e1e9471d189f79d0ce2497007731c1e6bf9ef6d1d61b911430c3db4e5/contourpy-1.3.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22e9b1bd7a9b1d652cd77388465dc358dafcd2e217d35552424aa4f996f524f5", size = 335810, upload-time = "2025-07-26T12:02:18.9Z" }, + { url = "https://files.pythonhosted.org/packages/91/f9/e35f4c1c93f9275d4e38681a80506b5510e9327350c51f8d4a5a724d178c/contourpy-1.3.3-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a22738912262aa3e254e4f3cb079a95a67132fc5a063890e224393596902f5a4", size = 382871, upload-time = "2025-07-26T12:02:20.418Z" }, + { url = "https://files.pythonhosted.org/packages/b5/71/47b512f936f66a0a900d81c396a7e60d73419868fba959c61efed7a8ab46/contourpy-1.3.3-cp314-cp314-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:afe5a512f31ee6bd7d0dda52ec9864c984ca3d66664444f2d72e0dc4eb832e36", size = 386264, upload-time = "2025-07-26T12:02:21.916Z" }, + { url = "https://files.pythonhosted.org/packages/04/5f/9ff93450ba96b09c7c2b3f81c94de31c89f92292f1380261bd7195bea4ea/contourpy-1.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f64836de09927cba6f79dcd00fdd7d5329f3fccc633468507079c829ca4db4e3", size = 363819, upload-time = "2025-07-26T12:02:23.759Z" }, + { url = "https://files.pythonhosted.org/packages/3e/a6/0b185d4cc480ee494945cde102cb0149ae830b5fa17bf855b95f2e70ad13/contourpy-1.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1fd43c3be4c8e5fd6e4f2baeae35ae18176cf2e5cced681cca908addf1cdd53b", size = 1333650, upload-time = "2025-07-26T12:02:26.181Z" }, + { url = "https://files.pythonhosted.org/packages/43/d7/afdc95580ca56f30fbcd3060250f66cedbde69b4547028863abd8aa3b47e/contourpy-1.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6afc576f7b33cf00996e5c1102dc2a8f7cc89e39c0b55df93a0b78c1bd992b36", size = 1404833, upload-time = "2025-07-26T12:02:28.782Z" }, + { url = "https://files.pythonhosted.org/packages/e2/e2/366af18a6d386f41132a48f033cbd2102e9b0cf6345d35ff0826cd984566/contourpy-1.3.3-cp314-cp314-win32.whl", hash = "sha256:66c8a43a4f7b8df8b71ee1840e4211a3c8d93b214b213f590e18a1beca458f7d", size = 189692, upload-time = "2025-07-26T12:02:30.128Z" }, + { url = "https://files.pythonhosted.org/packages/7d/c2/57f54b03d0f22d4044b8afb9ca0e184f8b1afd57b4f735c2fa70883dc601/contourpy-1.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:cf9022ef053f2694e31d630feaacb21ea24224be1c3ad0520b13d844274614fd", size = 232424, upload-time = "2025-07-26T12:02:31.395Z" }, + { url = "https://files.pythonhosted.org/packages/18/79/a9416650df9b525737ab521aa181ccc42d56016d2123ddcb7b58e926a42c/contourpy-1.3.3-cp314-cp314-win_arm64.whl", hash = "sha256:95b181891b4c71de4bb404c6621e7e2390745f887f2a026b2d99e92c17892339", size = 198300, upload-time = "2025-07-26T12:02:32.956Z" }, + { url = "https://files.pythonhosted.org/packages/1f/42/38c159a7d0f2b7b9c04c64ab317042bb6952b713ba875c1681529a2932fe/contourpy-1.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:33c82d0138c0a062380332c861387650c82e4cf1747aaa6938b9b6516762e772", size = 306769, upload-time = "2025-07-26T12:02:34.2Z" }, + { url = "https://files.pythonhosted.org/packages/c3/6c/26a8205f24bca10974e77460de68d3d7c63e282e23782f1239f226fcae6f/contourpy-1.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ea37e7b45949df430fe649e5de8351c423430046a2af20b1c1961cae3afcda77", size = 287892, upload-time = "2025-07-26T12:02:35.807Z" }, + { url = "https://files.pythonhosted.org/packages/66/06/8a475c8ab718ebfd7925661747dbb3c3ee9c82ac834ccb3570be49d129f4/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d304906ecc71672e9c89e87c4675dc5c2645e1f4269a5063b99b0bb29f232d13", size = 326748, upload-time = "2025-07-26T12:02:37.193Z" }, + { url = "https://files.pythonhosted.org/packages/b4/a3/c5ca9f010a44c223f098fccd8b158bb1cb287378a31ac141f04730dc49be/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca658cd1a680a5c9ea96dc61cdbae1e85c8f25849843aa799dfd3cb370ad4fbe", size = 375554, upload-time = "2025-07-26T12:02:38.894Z" }, + { url = "https://files.pythonhosted.org/packages/80/5b/68bd33ae63fac658a4145088c1e894405e07584a316738710b636c6d0333/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ab2fd90904c503739a75b7c8c5c01160130ba67944a7b77bbf36ef8054576e7f", size = 388118, upload-time = "2025-07-26T12:02:40.642Z" }, + { url = "https://files.pythonhosted.org/packages/40/52/4c285a6435940ae25d7410a6c36bda5145839bc3f0beb20c707cda18b9d2/contourpy-1.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7301b89040075c30e5768810bc96a8e8d78085b47d8be6e4c3f5a0b4ed478a0", size = 352555, upload-time = "2025-07-26T12:02:42.25Z" }, + { url = "https://files.pythonhosted.org/packages/24/ee/3e81e1dd174f5c7fefe50e85d0892de05ca4e26ef1c9a59c2a57e43b865a/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2a2a8b627d5cc6b7c41a4beff6c5ad5eb848c88255fda4a8745f7e901b32d8e4", size = 1322295, upload-time = "2025-07-26T12:02:44.668Z" }, + { url = "https://files.pythonhosted.org/packages/3c/b2/6d913d4d04e14379de429057cd169e5e00f6c2af3bb13e1710bcbdb5da12/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:fd6ec6be509c787f1caf6b247f0b1ca598bef13f4ddeaa126b7658215529ba0f", size = 1391027, upload-time = "2025-07-26T12:02:47.09Z" }, + { url = "https://files.pythonhosted.org/packages/93/8a/68a4ec5c55a2971213d29a9374913f7e9f18581945a7a31d1a39b5d2dfe5/contourpy-1.3.3-cp314-cp314t-win32.whl", hash = "sha256:e74a9a0f5e3fff48fb5a7f2fd2b9b70a3fe014a67522f79b7cca4c0c7e43c9ae", size = 202428, upload-time = "2025-07-26T12:02:48.691Z" }, + { url = "https://files.pythonhosted.org/packages/fa/96/fd9f641ffedc4fa3ace923af73b9d07e869496c9cc7a459103e6e978992f/contourpy-1.3.3-cp314-cp314t-win_amd64.whl", hash = "sha256:13b68d6a62db8eafaebb8039218921399baf6e47bf85006fd8529f2a08ef33fc", size = 250331, upload-time = "2025-07-26T12:02:50.137Z" }, + { url = "https://files.pythonhosted.org/packages/ae/8c/469afb6465b853afff216f9528ffda78a915ff880ed58813ba4faf4ba0b6/contourpy-1.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b", size = 203831, upload-time = "2025-07-26T12:02:51.449Z" }, + { url = "https://files.pythonhosted.org/packages/a5/29/8dcfe16f0107943fa92388c23f6e05cff0ba58058c4c95b00280d4c75a14/contourpy-1.3.3-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:cd5dfcaeb10f7b7f9dc8941717c6c2ade08f587be2226222c12b25f0483ed497", size = 278809, upload-time = "2025-07-26T12:02:52.74Z" }, + { url = "https://files.pythonhosted.org/packages/85/a9/8b37ef4f7dafeb335daee3c8254645ef5725be4d9c6aa70b50ec46ef2f7e/contourpy-1.3.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:0c1fc238306b35f246d61a1d416a627348b5cf0648648a031e14bb8705fcdfe8", size = 261593, upload-time = "2025-07-26T12:02:54.037Z" }, + { url = "https://files.pythonhosted.org/packages/0a/59/ebfb8c677c75605cc27f7122c90313fd2f375ff3c8d19a1694bda74aaa63/contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70f9aad7de812d6541d29d2bbf8feb22ff7e1c299523db288004e3157ff4674e", size = 302202, upload-time = "2025-07-26T12:02:55.947Z" }, + { url = "https://files.pythonhosted.org/packages/3c/37/21972a15834d90bfbfb009b9d004779bd5a07a0ec0234e5ba8f64d5736f4/contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ed3657edf08512fc3fe81b510e35c2012fbd3081d2e26160f27ca28affec989", size = 329207, upload-time = "2025-07-26T12:02:57.468Z" }, + { url = "https://files.pythonhosted.org/packages/0c/58/bd257695f39d05594ca4ad60df5bcb7e32247f9951fd09a9b8edb82d1daa/contourpy-1.3.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:3d1a3799d62d45c18bafd41c5fa05120b96a28079f2393af559b843d1a966a77", size = 225315, upload-time = "2025-07-26T12:02:58.801Z" }, +] + +[[package]] +name = "coverage" +version = "7.15.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/be/c3/4f2195f512fb172aa425a8803a874b2baa9ba7f80ff7b6080998761fc701/coverage-7.15.4.tar.gz", hash = "sha256:0548198fff07ccf4faf469520bce1c2eceb1ce3e62891921138dec10907f9d00", size = 936952, upload-time = "2026-08-06T13:50:24.442Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/30/70/b052a519a584663a7bd052841a2debe11c8309ec49a7786340003f9c0a02/coverage-7.15.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d0be6daac4cce6b8c8dc65886bae1b082ddbca4da8e5cbb5e15166acf253e264", size = 222245, upload-time = "2026-08-06T13:46:55.253Z" }, + { url = "https://files.pythonhosted.org/packages/67/39/892fa511aba3d1c3c8f49509a0ff5c71eab9f9f88d08e1a38da395821660/coverage-7.15.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b24e078eabcd6a9caa8b0713f9bc1eeb310bcc960a29d45a3b4fcd4b16d5b11d", size = 222762, upload-time = "2026-08-06T13:46:57.848Z" }, + { url = "https://files.pythonhosted.org/packages/9f/95/b2c724ce1e64bc23cb5b1d7eeffa9548dc3d811f7a6297b2d01607f4e062/coverage-7.15.4-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cfe20cc8cf8821d4fe54f89106cbf06aa27f37b5bbe3535568065a81539b4150", size = 249498, upload-time = "2026-08-06T13:46:59.012Z" }, + { url = "https://files.pythonhosted.org/packages/0b/4f/b1973f67a1382af65b572a31ed692f8e490a6ad707191eab59148376832a/coverage-7.15.4-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:83cf06cdd687677742caff1a9134833b7a8b75f111519d2cb0e0ba1b9a851e15", size = 251328, upload-time = "2026-08-06T13:47:00.764Z" }, + { url = "https://files.pythonhosted.org/packages/a2/09/03efa6722a132abcac91b32a60b64b240dd707c189c64eee697e48992c96/coverage-7.15.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8fa4de68e2a752468ff14b4e15db7def689a71be759e826a31ccecbef69c5fd0", size = 253194, upload-time = "2026-08-06T13:47:01.976Z" }, + { url = "https://files.pythonhosted.org/packages/45/63/8299201d9c80fb65551ce99c966cab83d706ec4066ac999bef08201346de/coverage-7.15.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4dff9daa47d83120c3ec38ce921214242944a832aa04e903e50b5b7ebac8972d", size = 255106, upload-time = "2026-08-06T13:47:03.281Z" }, + { url = "https://files.pythonhosted.org/packages/ee/16/26fd8a691eb8d9a230128685f6d23309d7402cb030aa553001788c8c50fc/coverage-7.15.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a093fd37229918976f602aa07aa59e0973cde82186f220c8e197f721f5be0ce4", size = 250177, upload-time = "2026-08-06T13:47:04.713Z" }, + { url = "https://files.pythonhosted.org/packages/ad/ef/3c7556f33783a0a566e01443ca62bd8eb2cdfe22d271efdc02e08beb5654/coverage-7.15.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:317db01a2cb02552fd67e2b1cca77a4b528a2a277176c5e0bf2cecbb639d3f54", size = 251234, upload-time = "2026-08-06T13:47:06.104Z" }, + { url = "https://files.pythonhosted.org/packages/29/49/640a34043edac950738f36a3567832db5731d4cb2ed84b59cdb89c6bccbf/coverage-7.15.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:8ee3838dcb656602c3b51e16aed9bfb0822f8d8d6d1c5966d32ec8c104be8e20", size = 249237, upload-time = "2026-08-06T13:47:07.467Z" }, + { url = "https://files.pythonhosted.org/packages/48/f5/e80f212669dd1be954ff844f883ef11a437ef4fd0089c6e0effc7b66b15d/coverage-7.15.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:425920379052ff1fe465268f3361d35804a241bbdd5a1b592c8cb60df4c52325", size = 253050, upload-time = "2026-08-06T13:47:08.748Z" }, + { url = "https://files.pythonhosted.org/packages/c7/e9/e5da0fe39f7fde1bca9edc09c60921bb5fdba4cec7db5bbad41ddfd8c230/coverage-7.15.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:69bb2400abef928e365ea7d4d9925169ada78ed2295546780002d4b65de3df88", size = 249508, upload-time = "2026-08-06T13:47:10.072Z" }, + { url = "https://files.pythonhosted.org/packages/7d/38/41bf25774a0c8bba6b467f917cb1c9a0a2605e02dc93aad489fc7050ed59/coverage-7.15.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:81661f82d302484e3119e7c80c519c02fa9bcc2a6b339baf67d67bc89c580f04", size = 250110, upload-time = "2026-08-06T13:47:11.35Z" }, + { url = "https://files.pythonhosted.org/packages/89/6e/26f2e54b79acc29d179ee4272922625aedb69198c4eb61f7ff4f098f3c78/coverage-7.15.4-cp310-cp310-win32.whl", hash = "sha256:cb476b2e828ecb71cb6b6a928d23fd20a7ddb501188022dae1c37499149cc338", size = 224294, upload-time = "2026-08-06T13:47:12.753Z" }, + { url = "https://files.pythonhosted.org/packages/7b/06/9a318fc3ae040d4d6cb2d86101c6aa963fab20899a5c58666adf52cde0ca/coverage-7.15.4-cp310-cp310-win_amd64.whl", hash = "sha256:3fc2130bf37df31852a8384f12601563a45a0024bccc6624f38355cba7a8d360", size = 224919, upload-time = "2026-08-06T13:47:14.17Z" }, + { url = "https://files.pythonhosted.org/packages/2a/66/edcec7d7a0b524aa8923e22925fde6fe50ce005a113dca13ae1581455c4c/coverage-7.15.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bbac5abad70df71019988f83f26ac7092ff2642975def4429e98dc7585ef3490", size = 222367, upload-time = "2026-08-06T13:47:15.578Z" }, + { url = "https://files.pythonhosted.org/packages/e6/c6/ab8de429e2e8548faf58ec7e1674a4ce00414b4113942d3fe87109cf0f68/coverage-7.15.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:357a173465c7ce028d07a95cc2b63b5bf59f50ecdd5ad75c5cbb78ada984048e", size = 222874, upload-time = "2026-08-06T13:47:16.961Z" }, + { url = "https://files.pythonhosted.org/packages/be/c4/3b7b49587e8a6b9af79b3eb468d443d6042b6d65b47aa26586846a0d6566/coverage-7.15.4-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:21b803935e2efc3acebe9697197a294fccf5dc4e5382bd6369542ff7a7d2a1d7", size = 253287, upload-time = "2026-08-06T13:47:18.291Z" }, + { url = "https://files.pythonhosted.org/packages/fb/65/ec03b743a2a229c72cc1eff3e57be9d3564e9c6b4d5aba2d70744a3fc0d8/coverage-7.15.4-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7a2b580774a4786c1053157c0165e04476e03ff293993d7c148eee784a94bae6", size = 255199, upload-time = "2026-08-06T13:47:19.765Z" }, + { url = "https://files.pythonhosted.org/packages/41/4b/5163729e4b6582d61975cfd3ccab45b4ec53e21cf156d9941cb025188468/coverage-7.15.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a9464451c4efffe8d47ace5a540b10b0dc10e879066290f8600872b7f54a419d", size = 257308, upload-time = "2026-08-06T13:47:21.206Z" }, + { url = "https://files.pythonhosted.org/packages/86/08/2167a0f08fb87d702fa423a48578a32865464b7c9e1db3911ad7812ab414/coverage-7.15.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:de602f34123c2f4af1c1869c6dbbbd60da6d5983bf01937367295d135cccbfce", size = 259268, upload-time = "2026-08-06T13:47:22.503Z" }, + { url = "https://files.pythonhosted.org/packages/1e/e5/68eebae3053dbd48508edea559c21b23fbdf3460784f91370c83a86a6acd/coverage-7.15.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6879ded16a27f3eeca19b900c147e81616e7054db451471a611b2755ee5249f7", size = 253392, upload-time = "2026-08-06T13:47:23.88Z" }, + { url = "https://files.pythonhosted.org/packages/1a/46/fd4ced40a2b691c774e515c9b69500bfa64c7960b67fcee4b2f6fad97fc3/coverage-7.15.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:986be58c3ab54aae8d3496a6225eea74f760fdbe739b38bd442c7e8d133aa53b", size = 255001, upload-time = "2026-08-06T13:47:25.469Z" }, + { url = "https://files.pythonhosted.org/packages/53/25/ae2e5fa710bb6957a9aadeb9e3598d3b3e4af6587ce857ad42e8639a3f30/coverage-7.15.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:c6103639613fe6c1e989082948419bc77a2d26b6c825c99d7fad25f7d3d87afc", size = 253061, upload-time = "2026-08-06T13:47:26.845Z" }, + { url = "https://files.pythonhosted.org/packages/d7/31/67ddc0365db2c6e93ac8580bc4bbc50f65273262f973f63ebcdbc15c0495/coverage-7.15.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d3af93dddb5659276c63bc16ac6466ac2033a70ca816097bbc06345b8ccdf571", size = 256831, upload-time = "2026-08-06T13:47:28.217Z" }, + { url = "https://files.pythonhosted.org/packages/f6/78/82b8fd18f57fb13f12d98fe874995bb2c4f9f17be8aff762c426323fdb96/coverage-7.15.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:b10075e5421d04265766a6d1dac809bbeb8a946fbb23c8f82c227409b2190719", size = 252781, upload-time = "2026-08-06T13:47:29.712Z" }, + { url = "https://files.pythonhosted.org/packages/0a/eb/6c74ef4dd12b252e573c49bdef9e2ac265bf3dbb79b8d7feb3266e084e9e/coverage-7.15.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a67a9f78b2942d87ba8ce3059c642164d2aedd65337377fb52fe9803656bc5c7", size = 253692, upload-time = "2026-08-06T13:47:31.192Z" }, + { url = "https://files.pythonhosted.org/packages/5a/66/eb9aed1c3fd2d36ee00eb173f434b14fa607fc056739c9a89ff4244010ea/coverage-7.15.4-cp311-cp311-win32.whl", hash = "sha256:69484d1aca26e322e1c3ce03f09341e84524ababad2d7202161738d83cc9f82e", size = 224461, upload-time = "2026-08-06T13:47:32.572Z" }, + { url = "https://files.pythonhosted.org/packages/e2/6d/81fa4161dfb3ed9d74e40d58647eff83a56b7612e78352581280fce2f477/coverage-7.15.4-cp311-cp311-win_amd64.whl", hash = "sha256:63fd6fcd1dd6e158f7eb78606e72933b3f6d01e7b747f99c6c12d764307a0fdc", size = 224937, upload-time = "2026-08-06T13:47:34.205Z" }, + { url = "https://files.pythonhosted.org/packages/5b/c1/d8dacf683c6cad3cf85ce68fd3774a6774ec402128822fdfaed920f11e6a/coverage-7.15.4-cp311-cp311-win_arm64.whl", hash = "sha256:ea82116c9893fa89e929b7f197ee5a1950a76e91cc5c85ba503fc02379d04890", size = 224479, upload-time = "2026-08-06T13:47:36.118Z" }, + { url = "https://files.pythonhosted.org/packages/1d/48/bc8d4ba7b37551a767bd863f15b3f80182b271c2f55975356f5f7dbe94c2/coverage-7.15.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d4fedd1f7f428f9fe83b1ead5e7cc87a43427be31aadafbac3ac0636dc7abb22", size = 222543, upload-time = "2026-08-06T13:47:37.562Z" }, + { url = "https://files.pythonhosted.org/packages/20/dd/88d6f83f1fffc974a3691a34a97951c5b12df7512a6782c5963883cbc058/coverage-7.15.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:37e2f0cdf58e2e1fed4e4d5a8f8786ae2f7eb80b478016876667dc4a01d60a97", size = 222905, upload-time = "2026-08-06T13:47:38.927Z" }, + { url = "https://files.pythonhosted.org/packages/bd/5c/54ee0d4748585bb0acab9891cd8d92f2d3593165b4e59fc9de113bfb3140/coverage-7.15.4-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:fb55d0e70bb15f2e81477613627286581414693d74ac7963c93a790dd453ca9d", size = 254407, upload-time = "2026-08-06T13:47:40.488Z" }, + { url = "https://files.pythonhosted.org/packages/8c/3f/f0642a372f494bd0d7dad3b497083b910194a5f1c88be2c94fef707c3b59/coverage-7.15.4-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:899b9da30f3c6c336566e3707495bb23e8302d39d862f01fa78c48b99b9437e2", size = 257145, upload-time = "2026-08-06T13:47:41.931Z" }, + { url = "https://files.pythonhosted.org/packages/71/17/8b46d0ed68251016002ec972c8fc0119961a765d0984cafb8bf317c43758/coverage-7.15.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d15715e8c46552827e5e4f30a35575a2dbcad14454cf3284c54483946bd16931", size = 258257, upload-time = "2026-08-06T13:47:43.527Z" }, + { url = "https://files.pythonhosted.org/packages/30/b8/8498a0e72d0adbe15477dd07463d2b3bb2c9f6a4815e8589e50939e2c3ae/coverage-7.15.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:002a438859f7b430bc99afeaf01a6d187dad1d0dc907b64cdeffc632a5db8fd8", size = 260517, upload-time = "2026-08-06T13:47:45.121Z" }, + { url = "https://files.pythonhosted.org/packages/41/e1/7dce19c3bdb1e3dd63e769508216500edad81bd5f69a26d724e32aceaf78/coverage-7.15.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e4193a04b518f7968f3099755f5509ee7cccc6dc2b92a6b14841934d22e222c9", size = 254785, upload-time = "2026-08-06T13:47:46.541Z" }, + { url = "https://files.pythonhosted.org/packages/dd/b1/e1494703c675a2561723cd9b89f45c9168782c31280c611b1f767851e57c/coverage-7.15.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e98dcc55d572b38e69d117da7e8e8efb8500f1f5eaf81ecd460a63220790b839", size = 256176, upload-time = "2026-08-06T13:47:48.155Z" }, + { url = "https://files.pythonhosted.org/packages/73/76/a5629d270fb638a43a4b10466f51e2f49d532c1aa4da2913cbbb150bbe0a/coverage-7.15.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:af6c538498ce66c10d3fd541c2a8d5b03da5850355add34e6cba564210cb9e72", size = 254321, upload-time = "2026-08-06T13:47:49.757Z" }, + { url = "https://files.pythonhosted.org/packages/ff/4f/9c44447218435d5766b911534f9d798144a5560f85e9a54ebe5f3f5d19f9/coverage-7.15.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1d10025d96ea89fc2f73714dbc4cbd433fe012c1ac9e23f895d7728b238b6e52", size = 258390, upload-time = "2026-08-06T13:47:51.248Z" }, + { url = "https://files.pythonhosted.org/packages/de/36/c1e127616fb3fa18a9ff71e76c417f2fd7424332a4870015ac224ef4c039/coverage-7.15.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d802e1947603162ded419bff83ac7489820355d2b856dfb09206574e3a37ac0c", size = 253894, upload-time = "2026-08-06T13:47:52.816Z" }, + { url = "https://files.pythonhosted.org/packages/e9/b9/fdb92c8ae7a8bb9b850cc253b7b3b9c8526f68130002048b5671cd510d09/coverage-7.15.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c2de40895718f91951b86712b4c5b694acaf9a0a49be13874896f599a1eed3f4", size = 255763, upload-time = "2026-08-06T13:47:54.296Z" }, + { url = "https://files.pythonhosted.org/packages/6f/c0/a7d51b2587c7bdb76e71b0896d2565bf7d60436b5122fc83e511adb1f7cd/coverage-7.15.4-cp312-cp312-win32.whl", hash = "sha256:5c3431b2161279b7db5c2a1aa58ae02e5cb8c3c42d93a5094be3f5537bd5b11b", size = 224597, upload-time = "2026-08-06T13:47:56.074Z" }, + { url = "https://files.pythonhosted.org/packages/49/b9/5c5f80cc55f5acaaca6dee677626bfcec8c87204a7809b438b08e84f4571/coverage-7.15.4-cp312-cp312-win_amd64.whl", hash = "sha256:6befeab5fb2b51c958ca4ac6c5d141a1e8240f4f76e46350f1911963deda49cd", size = 225135, upload-time = "2026-08-06T13:47:57.52Z" }, + { url = "https://files.pythonhosted.org/packages/47/e4/2a4561f89ff6bf7c925c287d0f2cce8bdf139c3a33735c87e3203401cf94/coverage-7.15.4-cp312-cp312-win_arm64.whl", hash = "sha256:67bc345491ab55b837277d76f5775d057e8c7f1ac44d890d8c2c82adde258c6f", size = 224515, upload-time = "2026-08-06T13:47:58.977Z" }, + { url = "https://files.pythonhosted.org/packages/f1/84/651a9310859673aaa3b3203f1aa1641ca60fcf2494683e1c9474c7172780/coverage-7.15.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c705b28feb2775dc82a25f1d473a370bc37ff93f5177f4e29ce2425f560f6921", size = 222565, upload-time = "2026-08-06T13:48:00.796Z" }, + { url = "https://files.pythonhosted.org/packages/82/f9/4dcf700137e8af550670f4d74d1b63828ce93e1e2b05e5f10710eb2ea987/coverage-7.15.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3ff205ab5e3ecc670f6a4dd19d9cbf12ede53dd41cfc1e15716ec961ea6d314e", size = 222936, upload-time = "2026-08-06T13:48:02.391Z" }, + { url = "https://files.pythonhosted.org/packages/07/4a/612ff1e780b3fbfd637486f542f84adc5503873d8b5d279dec1ffeef9414/coverage-7.15.4-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5172326e861a38b48b48befca15e0f477a26b283337a33a739c8fed229934e36", size = 253926, upload-time = "2026-08-06T13:48:04.382Z" }, + { url = "https://files.pythonhosted.org/packages/b0/04/d1cff1c2ead4708a6a79c01d3736b6a25bd38a36678398f72a8dd33dfad9/coverage-7.15.4-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:12b59c90084e3234fb11184886bf4a40f4f16a8c8f867be2e087b81f8e8868d4", size = 256523, upload-time = "2026-08-06T13:48:05.996Z" }, + { url = "https://files.pythonhosted.org/packages/b9/80/d34e13fb4b293cbdb9665838cf5522077b8ad14ef947550631a4bced36a5/coverage-7.15.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:349062d66f00b40fa2c1c222438bad25fabf755631b5d82937fe985c8008615c", size = 257759, upload-time = "2026-08-06T13:48:08.036Z" }, + { url = "https://files.pythonhosted.org/packages/0f/e7/2c5fe7636fdb0732fe0f09f308a5b066864078b7fc61f6678e8478554f2e/coverage-7.15.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4256ced708e598e05209bc1a8ab4074e04a51dba4c62fb45926a229af675ace7", size = 259890, upload-time = "2026-08-06T13:48:09.834Z" }, + { url = "https://files.pythonhosted.org/packages/92/28/9689f0858dfff59c2ea688938ab9fa2925631235df67126a42b6c5c70ae1/coverage-7.15.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d80f974b20782d9612c8b4c9beeca867074c7cf4079d1419843fa25a26428b25", size = 254121, upload-time = "2026-08-06T13:48:11.459Z" }, + { url = "https://files.pythonhosted.org/packages/f9/e2/785077c230c157243eb5aa9a26c3be260ecd02001bead54a3cada3df8e03/coverage-7.15.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2e179f19bfe1d31f8eeeaa12990194d761c4f62f0759661000bca6cd8729f40b", size = 255891, upload-time = "2026-08-06T13:48:13.209Z" }, + { url = "https://files.pythonhosted.org/packages/d4/90/e20371b17b40f912f21305c2db2f30efa3de306f7320fc916804872c85a4/coverage-7.15.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8bc16bb47b7679670eceff71d78bfb7d6e5b143f6c2cd117487ec7c75e0d4b78", size = 253859, upload-time = "2026-08-06T13:48:14.736Z" }, + { url = "https://files.pythonhosted.org/packages/05/49/25371987ee459a5f67c0427fb75c74f9358e65f2c71fe75bf41c1b6c5fcb/coverage-7.15.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:1cd685005cd2c4200adfc14cf39a603b9320efab3f18a8f7f156d20c9cc3345f", size = 258011, upload-time = "2026-08-06T13:48:16.464Z" }, + { url = "https://files.pythonhosted.org/packages/30/6e/32e67467f6154bf4f1c4f63b05acc5097cba4237d45bbeeea446b52e8ac1/coverage-7.15.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:337399ad2c93b3acd2a937627dae8b3e86b66707cd3d3e856347999aadf1ef8d", size = 253676, upload-time = "2026-08-06T13:48:18.493Z" }, + { url = "https://files.pythonhosted.org/packages/03/c1/8b24192e89286399765155251f99ee9f070a9d637109018ac23d99b99f6f/coverage-7.15.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:96e257121228ec5cd2bb919276e94ac11074471bc37d68dbae0e8308cce15fff", size = 255453, upload-time = "2026-08-06T13:48:20.057Z" }, + { url = "https://files.pythonhosted.org/packages/16/6f/8b41ebdf67c87854e17c035336a90f1cfbad0c14c2a584301be6ff148718/coverage-7.15.4-cp313-cp313-win32.whl", hash = "sha256:c65a9e0dfc6143491879da4e13b5e30f8be192055de508d737fb14601edbd22c", size = 224605, upload-time = "2026-08-06T13:48:21.655Z" }, + { url = "https://files.pythonhosted.org/packages/e0/e2/2946c7f0b42b152ecb21ff1bdad72e3d301e790c0c487e4a86e8c9f69347/coverage-7.15.4-cp313-cp313-win_amd64.whl", hash = "sha256:2ff8f5e9b8f7a94f0c11c45631eee103dbcb7d63274edd12c56efe1be690b3b4", size = 225148, upload-time = "2026-08-06T13:48:23.376Z" }, + { url = "https://files.pythonhosted.org/packages/9e/83/3f4a69957f48ae7a0aba76c34743f88963d607b19e03f3f8e66f91cae0f9/coverage-7.15.4-cp313-cp313-win_arm64.whl", hash = "sha256:6e0a8a5083b096487d6cfced94cdd514d8f5db6f113610fb36c0620edb1028cf", size = 224536, upload-time = "2026-08-06T13:48:25.117Z" }, + { url = "https://files.pythonhosted.org/packages/ea/ac/748cf29eeb2d6be34a3176ce26a4f49e38085ee08e8935f05f6f26ed7e0f/coverage-7.15.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:770e9325ab5ea6d56f77e59b29ecfe0ac20b57a82a601876f90494a4dda0386f", size = 222608, upload-time = "2026-08-06T13:48:26.806Z" }, + { url = "https://files.pythonhosted.org/packages/0b/02/1abbf5c984677b0aa439cdacaccbf38d248939d8ef8fe1cc7a50d73edb77/coverage-7.15.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d12b33a3a50a1676b7784dc8d00a0c6d66a9f2add4b85a041c19b6a7e53ef23c", size = 222940, upload-time = "2026-08-06T13:48:28.432Z" }, + { url = "https://files.pythonhosted.org/packages/eb/e1/ff8f9f53d9fcf586125b55d0b1f04ec1c14955fee41e83d5814bee141bb5/coverage-7.15.4-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5669c8378ebde86f5def7a25d29586631b58acc27ffde04399f678f3dfc6e082", size = 253985, upload-time = "2026-08-06T13:48:29.995Z" }, + { url = "https://files.pythonhosted.org/packages/a1/26/595759762e514e81be1d7d01ed03444303bcd152226a6529998d253f9201/coverage-7.15.4-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:ff97a14362eef486483ed44042ca2027ea257df6ff768e62358ee0c9776925ac", size = 256492, upload-time = "2026-08-06T13:48:31.634Z" }, + { url = "https://files.pythonhosted.org/packages/24/68/b79aabac54d482be23b5fcdd4f4662bff24a78edc4ee29201726929936d5/coverage-7.15.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5a325e815318638aed1655d9c06e6d7c2d3d46c09231ce988070428a8762d734", size = 257837, upload-time = "2026-08-06T13:48:33.186Z" }, + { url = "https://files.pythonhosted.org/packages/09/0f/bf7f297885a5bf6fd71e5782404e0ff059ca09e8711ceb3a08544abde45a/coverage-7.15.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:474223409d88eb20d2d6a0d37ea60e8647a65a90cc008dc1f0410af5f64f1e0d", size = 260152, upload-time = "2026-08-06T13:48:34.75Z" }, + { url = "https://files.pythonhosted.org/packages/fd/f1/296744e854ff8368542343457414380465e9ceefb9192342feb9d3bc461d/coverage-7.15.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7f2f62ae3cd189dd2e13aece758c57b3eecbd27be070dbd4cbd10936049e5dbf", size = 253978, upload-time = "2026-08-06T13:48:36.434Z" }, + { url = "https://files.pythonhosted.org/packages/55/b0/bbdb2e9057493e66220a2e149ca2d301ba0e3a58a83bd6b90de9826d16f3/coverage-7.15.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:39ece820e29e0a2ba34b3ecb3be83c27e997eed8926f2ba6fe7ce7a0bda5843b", size = 255846, upload-time = "2026-08-06T13:48:38.317Z" }, + { url = "https://files.pythonhosted.org/packages/96/e4/38015b2b6d21258713bd17e76b59d033b191efb5703589cffd037dfbca20/coverage-7.15.4-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:f21b56dcace11dfe013014201f577dcd592b2a9b72182d930361b47cf6f73f25", size = 253808, upload-time = "2026-08-06T13:48:39.993Z" }, + { url = "https://files.pythonhosted.org/packages/0b/64/0d515c1e60ee6fbfd1a0e79c07cd87d388a233b7adc37758735677203808/coverage-7.15.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:93a3a0b662abcc10c73a47cbc72cd60f63618d6989fb2d1286e50eacd974f303", size = 258081, upload-time = "2026-08-06T13:48:41.971Z" }, + { url = "https://files.pythonhosted.org/packages/91/71/04d9e7a3642146c6351338aef4ef85ab11dbbb54744c13245caba1aad1c0/coverage-7.15.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:141fae2cabf5569b782c10afc4c850ce10f618c13f8db54765cba99cc839da1f", size = 253624, upload-time = "2026-08-06T13:48:43.731Z" }, + { url = "https://files.pythonhosted.org/packages/b4/a7/6c28b74c81ebff66987b0e2522ba5cffa3e90b0c33cb6a2eb264d4ee8cf1/coverage-7.15.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:81294c7e6ab30c5f74c0353b11b2fd6320e72d9bee6ac73b357caa8b916323a5", size = 255280, upload-time = "2026-08-06T13:48:45.58Z" }, + { url = "https://files.pythonhosted.org/packages/52/af/bc19996a7014b98d7bbb0f0939453c67074af65784a3aa16a789a07381fa/coverage-7.15.4-cp314-cp314-win32.whl", hash = "sha256:7bbd7d6418e0dab31a206af5203bd43ae36edb8e7fba1940b055d3e9249290d7", size = 224768, upload-time = "2026-08-06T13:48:47.525Z" }, + { url = "https://files.pythonhosted.org/packages/ee/90/219484e476d6e101ba0a444852579e05f5b75c37c611a42ed1190f73ef62/coverage-7.15.4-cp314-cp314-win_amd64.whl", hash = "sha256:f0204ed122758782970526057093f448051a39db9d810d4e344bb87a3546f425", size = 225259, upload-time = "2026-08-06T13:48:49.513Z" }, + { url = "https://files.pythonhosted.org/packages/b7/66/fa77daf4e383e5f776dac62c2409b6af81910ae6fe326bd5170dba74cc63/coverage-7.15.4-cp314-cp314-win_arm64.whl", hash = "sha256:9e71e7bc71c686a123347ae47a0de33a175e797a85bb57b791492adf4eec8ed8", size = 224684, upload-time = "2026-08-06T13:48:51.235Z" }, + { url = "https://files.pythonhosted.org/packages/58/5b/f03bf0ce362bbf3f785fa5219620d00778d4ac6fc9e407734828e9c672f6/coverage-7.15.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7c922735321eef3f87c280a3d39afff6b646723a2880b862cda4ac7a093b8aa8", size = 223338, upload-time = "2026-08-06T13:48:52.896Z" }, + { url = "https://files.pythonhosted.org/packages/0f/76/e77d0ae22501831cc9f92193e8a957a5caa1dd177f90a6d1d9b106242d92/coverage-7.15.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f41c17c4668a655ce96d090d8d5ffdc24ef64b5a02f9753884d08483e8a4a41a", size = 223609, upload-time = "2026-08-06T13:48:54.688Z" }, + { url = "https://files.pythonhosted.org/packages/82/1a/b1f089da8d38ac612fa2dd6dc7f4a1a7657d12f3e261d2996edd3a838d0b/coverage-7.15.4-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:46822e9b6ff1c6a72b518c162c44a8f45a61a1d609c51084bf5b16c023c5037b", size = 264970, upload-time = "2026-08-06T13:48:56.403Z" }, + { url = "https://files.pythonhosted.org/packages/bf/31/e66d98d6e9c7fcc88470f1e234eaf6b1950dc0dfbf797f7282c1c861da24/coverage-7.15.4-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:3d6f4955b73b5445271379a59e3792b0d978f42d4a01e0cf7a67d9c33a3bb0a5", size = 267088, upload-time = "2026-08-06T13:48:58.41Z" }, + { url = "https://files.pythonhosted.org/packages/59/a1/ae94eb2c541add426378408379f233591e069040b1e2cdb33df9498a0682/coverage-7.15.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3fc9e047706fb4a9abb54f719d3aa643e80e5bb3818182c40aee01ac0f0247ba", size = 269508, upload-time = "2026-08-06T13:49:00.42Z" }, + { url = "https://files.pythonhosted.org/packages/9c/c7/88a10694a1c6a213569766aba9f25847b28155d4ac731b13226db216356d/coverage-7.15.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:05e491d4f3165d62d4f5c8fd48dfeabf2ae8f42cbbd484319af33ea851b78982", size = 270629, upload-time = "2026-08-06T13:49:02.234Z" }, + { url = "https://files.pythonhosted.org/packages/b3/34/d8b8232e5e55169933b59aabcef2fedfa4b9d8897361bb80fcbda146505f/coverage-7.15.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:226c66e80ec0598d3b9b4874123df167ccca342aca8714f77cac6829688ee09c", size = 264043, upload-time = "2026-08-06T13:49:04.102Z" }, + { url = "https://files.pythonhosted.org/packages/7e/35/58b009dbf8c471c7224716478b9fed4a7e1af15320e1ed41660978504663/coverage-7.15.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ac41cc14bebda0dbfb0628036b7f75706935c95bcc07fefe9a0f93614aa60a57", size = 266963, upload-time = "2026-08-06T13:49:05.821Z" }, + { url = "https://files.pythonhosted.org/packages/62/aa/57fbda1b42c892968273c56b6ee9dc0f1310850859230a507bc7873b1f65/coverage-7.15.4-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:8af623e5cd92080acddd02b38f2f406a2c3a0893c38950b211890361448fbf26", size = 264569, upload-time = "2026-08-06T13:49:07.706Z" }, + { url = "https://files.pythonhosted.org/packages/98/8a/360e6e7f24d477b7e889703af0afa878d15b6d4d8d2a822b2835c169a879/coverage-7.15.4-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:07545711d4f0f32852a18f18ad11f76f0109909d09e78b9008b4cfc67e829429", size = 268299, upload-time = "2026-08-06T13:49:09.587Z" }, + { url = "https://files.pythonhosted.org/packages/4e/89/6f701261aee21b6b5fa8f7872229406dc917e125069448292223bf213606/coverage-7.15.4-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:a0865421cfdc53654b342d515e5a233187590882d20b95752150e53f65460017", size = 263413, upload-time = "2026-08-06T13:49:11.604Z" }, + { url = "https://files.pythonhosted.org/packages/3f/0f/6f04036edc260ed425af83e834f627fad48941ce97b50bfe6edd8b6fa623/coverage-7.15.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:460115e32ee40566476db5048f9bec1e842c127ad8e6f8be745aad3ac9cbc839", size = 265725, upload-time = "2026-08-06T13:49:13.38Z" }, + { url = "https://files.pythonhosted.org/packages/c4/ce/d19b5d4d5c49a7bfb925fd74310fee7d28bc99520ac3367ccbc54e662518/coverage-7.15.4-cp314-cp314t-win32.whl", hash = "sha256:cbde877ef9dd7baf272b9bfef2b8a25edd45d9170fc326951dd20eb480335e85", size = 225079, upload-time = "2026-08-06T13:49:15.265Z" }, + { url = "https://files.pythonhosted.org/packages/26/bb/7aa1b3b173faee0679037ca950bbbe1247273656697994d8d13f80f8d4b4/coverage-7.15.4-cp314-cp314t-win_amd64.whl", hash = "sha256:3da9e92d1c551fd7563833e9ade686efb0c4b7363ab7681a94283958c950bf5e", size = 225911, upload-time = "2026-08-06T13:49:17.279Z" }, + { url = "https://files.pythonhosted.org/packages/81/1c/4ea9e47426d80038d9222db3c4534cb6021a74b237d3ff97ffd33b6600dd/coverage-7.15.4-cp314-cp314t-win_arm64.whl", hash = "sha256:3a54f5a0d85050c73a38f6793090ee83974531e67fe5e57a1da9bee11398aa5e", size = 225219, upload-time = "2026-08-06T13:49:19.293Z" }, + { url = "https://files.pythonhosted.org/packages/2b/c4/dc5d2ac8f9142e7ec7de66e7bf0591db29d78955a040bd915870d9c0e657/coverage-7.15.4-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:2c9872e4d9dc5d3cf616bf4b382f5a00359305a5be666a3dd0b5cdb4e49597f9", size = 222604, upload-time = "2026-08-06T13:49:21.279Z" }, + { url = "https://files.pythonhosted.org/packages/70/39/33e63df81fe2ee100897451841c821467635923e58e37c6bd4b46dd8106c/coverage-7.15.4-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:e101dbb4b9b72f0cddd8cdc8c9c5b47f456766f5e0ac82dbfb75e5c55409b78a", size = 222944, upload-time = "2026-08-06T13:49:23.187Z" }, + { url = "https://files.pythonhosted.org/packages/99/1f/ef3ffb5557febc75a0d97aa459d0266d7d741110265121cc6d8539343d44/coverage-7.15.4-cp315-cp315-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7d1abebdb047729e852b9c77a00497dfbeb11eb3a117e037d7dbc3ac8e5f5c54", size = 254050, upload-time = "2026-08-06T13:49:25.008Z" }, + { url = "https://files.pythonhosted.org/packages/6f/f5/1f0f6f77698c3601ca0ae7431e34b24c62ca2f06fecb23b73ed1f651d2be/coverage-7.15.4-cp315-cp315-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d28a4a899354d0ea6214cc59b4fa19eefbce1b9ff1688ab579acf49e894bd3fb", size = 256967, upload-time = "2026-08-06T13:49:26.896Z" }, + { url = "https://files.pythonhosted.org/packages/03/7a/2ed9bed79925f4367c83c77f66a89e5ca7229c288d2d19ad5f36d1ca0070/coverage-7.15.4-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ffb3c2aacea411cc7e1d27712490c11108e2de1d39019ae32915493a59a8b9ed", size = 258587, upload-time = "2026-08-06T13:49:28.692Z" }, + { url = "https://files.pythonhosted.org/packages/45/8c/fa34044f71b7cc4ecb6da9c2408770959b0591fa9b5fb6fb6bca38f94298/coverage-7.15.4-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a9447978a92f405d301123cfd39ff49895490efb769a758fe2734c7f631bf8ce", size = 260785, upload-time = "2026-08-06T13:49:30.472Z" }, + { url = "https://files.pythonhosted.org/packages/4f/54/d5727ce36b4524a7394ab9f5f1df378e1f23affcdab01037dc8655185cc7/coverage-7.15.4-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:050467a7983b8e2fe7dd41a78bb30c3e7f8c0b8cafda14b1c46f8b5e3cf2dd3c", size = 254545, upload-time = "2026-08-06T13:49:32.271Z" }, + { url = "https://files.pythonhosted.org/packages/dc/e6/6e3783e576719590194bdffb6dd6d85490801785b7c331e35a245d8cb8b5/coverage-7.15.4-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:d003b7a5708ddad5c206c79607a6b92abb6fc13c57d99d8a4468cc03a2941ced", size = 256682, upload-time = "2026-08-06T13:49:34.089Z" }, + { url = "https://files.pythonhosted.org/packages/dc/f2/bacdbde18b69ed2de424fcf64d9fb0a4913753d4f0eca8bae9daad69f4bd/coverage-7.15.4-cp315-cp315-musllinux_1_2_i686.whl", hash = "sha256:c38efe30fd74e5c19e9433f11fb1f5dc9c6522770971b7c6145bbaa413dc8800", size = 254560, upload-time = "2026-08-06T13:49:36.052Z" }, + { url = "https://files.pythonhosted.org/packages/6c/a3/1fb927196e3477c1b48831169ab58ba08f451ba87ae311ff1de68b26a616/coverage-7.15.4-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:1f4f826d70f772ab8b0c052329580d7fe8b8abd191e4ce0c8f81aec6614665d3", size = 258792, upload-time = "2026-08-06T13:49:38.01Z" }, + { url = "https://files.pythonhosted.org/packages/41/58/30d4c149c69053de0edfe325614c1d28d508f62b1783e0e4a234d2e49136/coverage-7.15.4-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:4a4bf917c9953f57c957be31c1cd504e3bd2f34d4a352b9d391a3025336f6768", size = 253968, upload-time = "2026-08-06T13:49:39.934Z" }, + { url = "https://files.pythonhosted.org/packages/89/e4/77f639371b918aad30dda4051f95404b43578f7f2e2f87ba73e02ed1ff37/coverage-7.15.4-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:1c9bf40ebef178a45192c75c4964760bb261b0e6ad725da5fc4c93f674f19753", size = 255893, upload-time = "2026-08-06T13:49:41.825Z" }, + { url = "https://files.pythonhosted.org/packages/5c/62/13be29b3ddab35f14c87967a4820a05106d2a3eccb4fa4ff550bf30b75e0/coverage-7.15.4-cp315-cp315-win32.whl", hash = "sha256:43619d04c3671792d2c4706ae8bf45e265dc87bbd4078189ef8b847ea1e74be2", size = 224768, upload-time = "2026-08-06T13:49:44.08Z" }, + { url = "https://files.pythonhosted.org/packages/a1/70/af0c6be0f964af6954f6b74bc109b0dbca02824696d2520fb17fe1ab06e3/coverage-7.15.4-cp315-cp315-win_amd64.whl", hash = "sha256:be619439dbcd31a2eab10b32de9fff62c26ed4bab69dc32b8363fdaaa0882809", size = 225242, upload-time = "2026-08-06T13:49:45.899Z" }, + { url = "https://files.pythonhosted.org/packages/4f/2d/f3bd3aab899fc9efc18b53133ee68f5f98574ef480649b23e12962226387/coverage-7.15.4-cp315-cp315-win_arm64.whl", hash = "sha256:def597967dafc2e8d97c9097ea453c464e0bb8ed38f193a43070f10dc623bb6d", size = 224674, upload-time = "2026-08-06T13:49:48.322Z" }, + { url = "https://files.pythonhosted.org/packages/f5/ca/f69251cd63eabc6438321aea22148754cce758a26bde07dd490e3fe7cfc5/coverage-7.15.4-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:c7dbc748ac8a1e3e59a2b28bea47675e6e778081dbbf081bde0d75def2fcbe1d", size = 223333, upload-time = "2026-08-06T13:49:50.293Z" }, + { url = "https://files.pythonhosted.org/packages/a7/a7/037b53b2885b0d8447064432491a4d5a1014cd9f97a594d53acd0c04541a/coverage-7.15.4-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:2413074a5ecbb61a01a7888fc72db0ca324d13588c5b38bc0dd8564cdcdfea26", size = 223630, upload-time = "2026-08-06T13:49:52.637Z" }, + { url = "https://files.pythonhosted.org/packages/80/4f/152b8a4779ae90da11bb24f7467df8a59f0be48a5c52acb856325ca48289/coverage-7.15.4-cp315-cp315t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:4e6f6f632b7b2f714bf7a1346e8f97b650ee71f3c298aaad42a2ab60f0f07645", size = 264489, upload-time = "2026-08-06T13:49:54.52Z" }, + { url = "https://files.pythonhosted.org/packages/10/2d/84b4b9e0e1dd6528a51920ff7031f35b789382e467a28ec6a5a578cb8812/coverage-7.15.4-cp315-cp315t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8df457da2249d3c75ca2e5e835d59c725abfe92d27fdff6cd99eed85b51d5e9a", size = 267567, upload-time = "2026-08-06T13:49:56.721Z" }, + { url = "https://files.pythonhosted.org/packages/53/fc/ba01cc25299f9f8a2c8b02d3b28c53f3543d9fbfbe4e74fa2760b48f163e/coverage-7.15.4-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:050f66a08805acb5b8a23c6d4a517b1ecf82c08e81ed0e4bd727df065e5c6624", size = 270123, upload-time = "2026-08-06T13:49:58.736Z" }, + { url = "https://files.pythonhosted.org/packages/cf/d0/db2647cbf40b14f8c308f94ff7bf89c06d564e59f396906edf50086ec788/coverage-7.15.4-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1587fb771d1ccceef708fdde1e5af8c7ed24b486b61d13a321acb7d8145390aa", size = 271107, upload-time = "2026-08-06T13:50:00.811Z" }, + { url = "https://files.pythonhosted.org/packages/70/ff/4d2d17924552c458bb4f77dd631f0e3bc92fbbdf2d2d916cd4b33bbfd5b1/coverage-7.15.4-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8b4f1c3a69ca580f3fbd6b2046915f536d7f586874f25c1bb23add2a3c88d50f", size = 264955, upload-time = "2026-08-06T13:50:03.023Z" }, + { url = "https://files.pythonhosted.org/packages/ee/de/dc010c7a3691f396d93bbc26bfcafa1c2a3a351cd520470f15faf5795bd5/coverage-7.15.4-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:ffb58d7eff5b7f6ecc6fa21d6288ab7f968a212cb67d682c269c09b9eba3b66f", size = 267949, upload-time = "2026-08-06T13:50:05.557Z" }, + { url = "https://files.pythonhosted.org/packages/78/ea/dc96a11375e83c045c2f7c61fb6918277cfe9401db7c0f7b1d111a84b2e5/coverage-7.15.4-cp315-cp315t-musllinux_1_2_i686.whl", hash = "sha256:d9df165544774574ee004b953023d1bebada1894a80b1052a43d798b0f676e67", size = 264421, upload-time = "2026-08-06T13:50:07.612Z" }, + { url = "https://files.pythonhosted.org/packages/c8/86/b77131a0f9503ce461cd577076147d7a9040f0c5dda772686f729e2cc9cb/coverage-7.15.4-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:f9de0a24a4079b53e523b5c5e2c5945ec251ab486652659955187cf255a259bc", size = 269121, upload-time = "2026-08-06T13:50:09.58Z" }, + { url = "https://files.pythonhosted.org/packages/24/24/944bc35007862955e7ebf05754e645419dcf5d7526c52735cfa2715e8ebf/coverage-7.15.4-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:150089274bdc9f940628552cb92844e0223c987f1902ab8efe9f45a2ec758d88", size = 264565, upload-time = "2026-08-06T13:50:11.722Z" }, + { url = "https://files.pythonhosted.org/packages/c7/cc/a3bb9f93e7e740659163e2ea584f8196ddcd2c456a5dbe15f6c50105fec1/coverage-7.15.4-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:a58a94fed5da6997d258e8f7668c1e195fbd04a691d781b7558f1e468f9e68bc", size = 266522, upload-time = "2026-08-06T13:50:13.786Z" }, + { url = "https://files.pythonhosted.org/packages/49/dd/e0e40f3560d878d888c580698ff5ad1179f5e1c3ac949684ef66b41a3817/coverage-7.15.4-cp315-cp315t-win32.whl", hash = "sha256:ebd5a6d8466ff30836572f3ba2cae8a5e8f85029b1c6d5e2ed338dc472a5166a", size = 225068, upload-time = "2026-08-06T13:50:15.825Z" }, + { url = "https://files.pythonhosted.org/packages/c6/7e/37732ea80eebc30e976e4cdab15c190bc42d96959a42e38ddf6f8c60468f/coverage-7.15.4-cp315-cp315t-win_amd64.whl", hash = "sha256:288bde2a2d7ab6b6c2d7252fcde8b524387f2d970bdba9658fc6f8bbcaef0f9b", size = 225895, upload-time = "2026-08-06T13:50:17.928Z" }, + { url = "https://files.pythonhosted.org/packages/c6/08/1e00f7923eaaba45fb3d51dd794125fc766304b1df264f3a9c6557bfb30e/coverage-7.15.4-cp315-cp315t-win_arm64.whl", hash = "sha256:68be5e1de60ff13c9095bbec0e5a7fa45b33b101752215b91345ea1f61c4a278", size = 225213, upload-time = "2026-08-06T13:50:19.981Z" }, + { url = "https://files.pythonhosted.org/packages/b4/d9/e70c286c979378f061d8266e279b686ab0b0b688e1fe0af864684f23a77d/coverage-7.15.4-py3-none-any.whl", hash = "sha256:964730a1e9de9c0cf11be6a1a3c79ce419c34882842abd256086ba4698705e84", size = 214332, upload-time = "2026-08-06T13:50:22.192Z" }, +] + +[package.optional-dependencies] +toml = [ + { name = "tomli", marker = "python_full_version <= '3.11'" }, +] + +[[package]] +name = "cycler" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/95/a3dbbb5028f35eafb79008e7522a75244477d2838f38cbb722248dabc2a8/cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c", size = 7615, upload-time = "2023-10-07T05:32:18.335Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321, upload-time = "2023-10-07T05:32:16.783Z" }, +] + +[[package]] +name = "disba" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "importlib-metadata" }, + { name = "matplotlib", version = "3.10.9", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "matplotlib", version = "3.11.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numba" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "numpy", version = "2.5.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3d/c1/2e2fd15b910cb7a916a6a560ad9daf7376247aa25516849056ba68bdfd00/disba-0.7.0.tar.gz", hash = "sha256:06f925d6f08dc917d992257ae089c8a5fba229f12839d91b0ce152fbd5faeb1c", size = 25405, upload-time = "2024-12-19T19:24:21.137Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/66/cd/493c94249b86e92389acec94078d782607cc5e0f81d060ea3b7b66305ccd/disba-0.7.0-py3-none-any.whl", hash = "sha256:17d09ab4ad5eabf55a5d55ee6feb15b74cffa238a29bb0ee1346f7605863f91d", size = 28029, upload-time = "2024-12-19T19:24:18.529Z" }, +] + +[[package]] +name = "distlib" +version = "0.4.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c9/02/bd72be9134d25ed783ecbbc38a539ffaefbf90c78418c7fb7229600dbac7/distlib-0.4.3.tar.gz", hash = "sha256:f152097224a0ae24be5a0f6bae1b9359af82133bce63f98a95f86cae1aede9ed", size = 615141, upload-time = "2026-06-12T08:04:52.847Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/08/9c41fb51ab5b43eb21674aff13df270e8ba6c4b29c8624e328dc7a9482af/distlib-0.4.3-py2.py3-none-any.whl", hash = "sha256:4b0ce306c966eb73bc3a7b6abad017c556dadd92c44701562cd528ac7fde4d5b", size = 470628, upload-time = "2026-06-12T08:04:50.506Z" }, +] + +[[package]] +name = "emcee" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "numpy", version = "2.5.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cb/53/1045ee878cb24281387079f8ee4f0ade1622c6aae1ed1fd91a53e4fa5b19/emcee-3.1.6.tar.gz", hash = "sha256:11af4daf6ab8f9ca69681e3c29054665db7bbd87fd4eb8e437d2c3a1248c637d", size = 2871117, upload-time = "2024-04-19T10:03:19.555Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/ef/2196b9bf88ffa1bde45853c72df021fbd07a8fa91a0f59a22d14a050dc04/emcee-3.1.6-py2.py3-none-any.whl", hash = "sha256:f2d63752023bdccf744461450e512a5b417ae7d28f18e12acd76a33de87580cb", size = 47351, upload-time = "2024-04-19T10:03:17.522Z" }, +] + +[[package]] +name = "exceptiongroup" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, +] + +[[package]] +name = "filelock" +version = "3.32.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/64/a02e6765de08964ed371eca577870593245afc9dfac16d037de7c10d18e6/filelock-3.32.3.tar.gz", hash = "sha256:0ffa185a3540854c95caa7fa76b76cb219d907415e2c5dc9af25fd970563487f", size = 218135, upload-time = "2026-08-13T16:00:05.577Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/8e/50f46a9c0ce8d2861a394c1347caae037ea0431d2f67d7feb151cbc4649a/filelock-3.32.3-py3-none-any.whl", hash = "sha256:7f0ca4bcc0e181c60dbbd8aa9ab5b120ebb99e4e064e83636340056f833a1f09", size = 98901, upload-time = "2026-08-13T16:00:03.974Z" }, +] + +[[package]] +name = "fonttools" +version = "4.63.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/84/69/c97f2c18e0db87d2c7b15da1974dace76ae938f1cfa22e2727a648b7ed43/fonttools-4.63.0.tar.gz", hash = "sha256:caeb583deeb5168e694b65cda8b4ee62abedfa66cf88488734466f2366b9c4e0", size = 3597189, upload-time = "2026-05-14T12:04:30.958Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f2/c9/4141c90a90db20f807c7e10bfd689fe53eb8f7f4caff58ee4d4dfe46919f/fonttools-4.63.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e3297a6a4059b4acc3a1e9a8b04741f240a80044eef08ebd32e8b5bcdddce75b", size = 2884632, upload-time = "2026-05-14T12:02:38.56Z" }, + { url = "https://files.pythonhosted.org/packages/b8/46/ad12b5c10eae602d7ef814b02afa08aacbf89da917fed5b071282b7eadc2/fonttools-4.63.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b1cd75a03ad8cb5bc40c90bfde68c0c47de423aa19e5c0f362b43520645eea94", size = 2429441, upload-time = "2026-05-14T12:02:41.162Z" }, + { url = "https://files.pythonhosted.org/packages/90/8f/bdca24a84c81d56fffed052229cdcff368f6e05882e526f4558891481f65/fonttools-4.63.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c0425b277a59cff3d80ca42162a8de360f318438a2ac83570842a678d826d579", size = 4946346, upload-time = "2026-05-14T12:02:43.41Z" }, + { url = "https://files.pythonhosted.org/packages/04/59/a639c0e136441ee91a65b56fdf89e5d075927e7a09c559d1b0f5276577db/fonttools-4.63.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d7e5c9973aa04c95650c96e5f5ad865fbf42d62079163ecfab1e01cbc2504c22", size = 4903184, upload-time = "2026-05-14T12:02:45.742Z" }, + { url = "https://files.pythonhosted.org/packages/e6/53/91b7e0cb45b536f3da1b29ba8cbab89f27e8b986809e0b1982303a3f4eca/fonttools-4.63.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cb014d58140a38135f16064c74c652ed57aa0b75cbf8bb59cac821f7edb5334e", size = 4922967, upload-time = "2026-05-14T12:02:48.386Z" }, + { url = "https://files.pythonhosted.org/packages/c7/b7/87439bf44e6b97c5538cd29d0b7e366a5b8ce2cc132a4134fb67fa3f2fa2/fonttools-4.63.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:032038247a96c1690f9f31e377c389383c902531b085aa4e4dabd6f57f870e69", size = 5042799, upload-time = "2026-05-14T12:02:50.424Z" }, + { url = "https://files.pythonhosted.org/packages/ad/7c/8b96c3263b89ef99cded544c0f0636686f85dbd3c211c4dceef0231fca23/fonttools-4.63.0-cp310-cp310-win32.whl", hash = "sha256:a8b33a82979e0a6a34ff435cc81317be1f95ec1ebb7a3a2d1c8a6a54f02ae44e", size = 1519704, upload-time = "2026-05-14T12:02:52.523Z" }, + { url = "https://files.pythonhosted.org/packages/e5/4d/2c2f0069970b6907de8fb5b05c5c0193cc22f717df151d1c7aef1c738f58/fonttools-4.63.0-cp310-cp310-win_amd64.whl", hash = "sha256:0c18358a155d75034911c5ee397a5b44cd19dd325dbb8b35fb60bf421d6a72ac", size = 1568666, upload-time = "2026-05-14T12:02:54.917Z" }, + { url = "https://files.pythonhosted.org/packages/75/2b/a7f1545bdf5da69c4bda0cea2a5781f0ad2a6623e0277267672db43c5fe6/fonttools-4.63.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2b8ae05d9eacf6081414d759c0a352769ac28ce31280d6bb8e77b03f9e3c449f", size = 2881793, upload-time = "2026-05-14T12:02:56.645Z" }, + { url = "https://files.pythonhosted.org/packages/49/50/965308c703f085f225db2886813b27e015b8b3438c350b22dd65b52c2a2c/fonttools-4.63.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:79cdc9f567aec74a72918fd060283911406750cbc9fd28c1316023deb6ce31a9", size = 2428130, upload-time = "2026-05-14T12:02:58.891Z" }, + { url = "https://files.pythonhosted.org/packages/d8/38/6937fbd7f2dc3a6b48725851bc2c15ec949b9af14d9bbcb5fe83cdf9bdf9/fonttools-4.63.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2c14b4fd138c4bafcca294765c547914e1aa431ae1ca94ab99d8db08c958bd3b", size = 5111952, upload-time = "2026-05-14T12:03:01.263Z" }, + { url = "https://files.pythonhosted.org/packages/0b/43/a81f20050a3115b57d62c8e781446949512eac36690dc384ccea65ff4cc1/fonttools-4.63.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d76ac49f929aecaf82d83250b8347e099d7aecba0f4726c1d9b6df3b8bb5fe18", size = 5082308, upload-time = "2026-05-14T12:03:03.211Z" }, + { url = "https://files.pythonhosted.org/packages/67/00/cdd9d4944ca6ae280d01e69cc37bde3bf663630b837a6fc6d2cd65d80e0e/fonttools-4.63.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:dcf076a4474fe0d7367e5bbf5b052c7284fa1feca729c04176ce513521afd8a0", size = 5087932, upload-time = "2026-05-14T12:03:05.147Z" }, + { url = "https://files.pythonhosted.org/packages/f5/f1/0aa0dbea778c75adbef223c42019fd47d22262b905974d62d829545d485f/fonttools-4.63.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7dd683fef0663e9f0f45cf541d788d24caa3ec9db50796b588e1757d8b3bc007", size = 5213271, upload-time = "2026-05-14T12:03:07.238Z" }, + { url = "https://files.pythonhosted.org/packages/a8/99/253e4056e1f0e67b9390125a154b73b5eb73ad521bece95c004858fdeec2/fonttools-4.63.0-cp311-cp311-win32.whl", hash = "sha256:afefc1ed0a59785a7fb06ea7e1678e849c193e1e387db783579bc7b3056fcfcb", size = 2304473, upload-time = "2026-05-14T12:03:09.271Z" }, + { url = "https://files.pythonhosted.org/packages/08/60/defa5e69641db890a63be281f41345f4c33b157824eaf0b9fad3e08b0dcb/fonttools-4.63.0-cp311-cp311-win_amd64.whl", hash = "sha256:063e08bd17bd5a90127a14123de0d6a952dbc847695fd98b63c043d58057f90c", size = 2356389, upload-time = "2026-05-14T12:03:11.53Z" }, + { url = "https://files.pythonhosted.org/packages/08/ef/b3c6b9b5be2f82416d73fe2ed2e96e2793cd80e7510bd6a17ca79cdd88ec/fonttools-4.63.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:37dd23e621e3b0aef1baa70a303b80aaf38449632cfc8fd2a55fb285bbccfc02", size = 2881131, upload-time = "2026-05-14T12:03:13.386Z" }, + { url = "https://files.pythonhosted.org/packages/44/a0/c815bea63117fa63e4e1c01f8a1110d2112fa003f838e6467094ec2432ce/fonttools-4.63.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a9faff9e0c1f76f9fd55899d2ce785832efebab37eb8ae13995853aef178bef0", size = 2426704, upload-time = "2026-05-14T12:03:15.801Z" }, + { url = "https://files.pythonhosted.org/packages/44/04/0b91d8e916e92ad1fac9e4624760baf0fd5ff2ead614c2f68fb21373f03f/fonttools-4.63.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ef3048ef05dbb552b89817713d9cac912e00d0fde4a3105c00d29e52e10c89af", size = 5044298, upload-time = "2026-05-14T12:03:18.085Z" }, + { url = "https://files.pythonhosted.org/packages/77/c7/2342da9830e3e9d4870305ca5d2091d2a83284f2953079b7bdd3b5e029d8/fonttools-4.63.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:58dc6bb86a78d782f00f9190ca02c119cf5bbe2807536e361e18d42019f877d8", size = 4999800, upload-time = "2026-05-14T12:03:20.161Z" }, + { url = "https://files.pythonhosted.org/packages/e6/6d/67fe16c48d7ce050979b33f47e0d28a318f02da030602e944c34f7a16ef3/fonttools-4.63.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ee08ebfa58f6e1aeff5697ab9582105bb620008c1caafb681e4c557e7483027b", size = 4982666, upload-time = "2026-05-14T12:03:22.87Z" }, + { url = "https://files.pythonhosted.org/packages/f2/00/3bbab338c07c71fa56269953845e92c951a61457bbbb0f1022551ea266d9/fonttools-4.63.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:27fdc65af8da6f88b9c6121c47a464cbe359fcfff7ff6fc2d37a1f395d755b78", size = 5133598, upload-time = "2026-05-14T12:03:25.168Z" }, + { url = "https://files.pythonhosted.org/packages/62/f2/aa27c7f98db5b064883dadcc5283947e81e034de42e22a33675878d98b54/fonttools-4.63.0-cp312-cp312-win32.whl", hash = "sha256:af2fd1664d00a397d75f806985ddb36282091c2131a73a6485c23b4a34722263", size = 2292575, upload-time = "2026-05-14T12:03:27.496Z" }, + { url = "https://files.pythonhosted.org/packages/87/36/cccb9bc2a6ab63d1b2980374f0dca72ce95ae267c9b4cfe77455bb70d0d4/fonttools-4.63.0-cp312-cp312-win_amd64.whl", hash = "sha256:59ac449f8cca9b4ffa08d2e7bbadad87ce710d69d1eda5c3c1ce579baa987272", size = 2343211, upload-time = "2026-05-14T12:03:30.057Z" }, + { url = "https://files.pythonhosted.org/packages/0f/8d/d8fec3dcde2963f8c908fb315e5ff2cd0ac34f82394bbbf73a2aa5145ce3/fonttools-4.63.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:cd7e9857e5e63738b9d9fd707bc1f59c8b09e5177726d23664db393c59bb08bd", size = 2876062, upload-time = "2026-05-14T12:03:32.554Z" }, + { url = "https://files.pythonhosted.org/packages/ef/71/d935dc54e4ff121bfdd11e08702db63a7e6f25af21d8a3d7b7212df53641/fonttools-4.63.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c2a2a42198b696a6f48fad91709afb55176e66a5e566131219dba372fb7f8c59", size = 2424594, upload-time = "2026-05-14T12:03:34.86Z" }, + { url = "https://files.pythonhosted.org/packages/8e/40/e76320afa1df918e146155ef239b1719ee266092e96f5423bfd075affba1/fonttools-4.63.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e874792a8212b44583ea02189d9e693906b2f78b261f372f95d6c563210ac1d", size = 5024840, upload-time = "2026-05-14T12:03:36.745Z" }, + { url = "https://files.pythonhosted.org/packages/ce/36/0b805d8c485f872f65a509cbe3b58a5d0d17bee855333b54a150c79d3061/fonttools-4.63.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:22135da48a348785c5e2d5d2d9d6bec5ed44adacbaeb9db12d9493bf6c6bfa68", size = 4975801, upload-time = "2026-05-14T12:03:38.833Z" }, + { url = "https://files.pythonhosted.org/packages/c8/26/2cee03d0aa083ab022da5c07aff9ed3f689da1defb81ad6917c9627896da/fonttools-4.63.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ccf41f2efdf56994d22d73bef4ced1052161958169428d06ba9724ea9e9a64be", size = 4965009, upload-time = "2026-05-14T12:03:41.494Z" }, + { url = "https://files.pythonhosted.org/packages/7e/48/cc4b66d9058c0d0982c833fad10127c4b0e9324606aafa41382295ca4102/fonttools-4.63.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9ced0bd02ac751dd6319b0da88aaef24414e3b0dbc32bb4f24944821a3741a27", size = 5105892, upload-time = "2026-05-14T12:03:43.525Z" }, + { url = "https://files.pythonhosted.org/packages/d8/1f/a98a30a814b9ddef3a2e706025f90b9e0bc94890e6cb15254bc86547d11a/fonttools-4.63.0-cp313-cp313-win32.whl", hash = "sha256:85be818f5506e8a7753153def2c9550178f0ecae6a47b5e0e8dbb23f7cc90380", size = 2291313, upload-time = "2026-05-14T12:03:45.594Z" }, + { url = "https://files.pythonhosted.org/packages/92/46/5177b01f3b4abfdd4409f31cca4ab279c9343a26efbe9ec78c97fc612e02/fonttools-4.63.0-cp313-cp313-win_amd64.whl", hash = "sha256:ba04cb5891d4c0c21b6da95eda8d7b090021508a294fff33464fc7d241e0856b", size = 2342299, upload-time = "2026-05-14T12:03:47.414Z" }, + { url = "https://files.pythonhosted.org/packages/27/d2/23d25e3f247b328be58d04a4c9f894178a0d1eda7d42867cfb388adaf416/fonttools-4.63.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:fd1e3094f42d806d3d7c79162fc59e5910fcbe3a7360c385b8da969bc4493745", size = 2875338, upload-time = "2026-05-14T12:03:50.052Z" }, + { url = "https://files.pythonhosted.org/packages/cd/58/7dfa0c761cb3b2964e2a84c4dc986c926a87de0cb9fb60d5b28ded3f2914/fonttools-4.63.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:6e528da43bc3791085f8cb6141b1d13e459226790240340fcbb4625649238b03", size = 2422661, upload-time = "2026-05-14T12:03:52.154Z" }, + { url = "https://files.pythonhosted.org/packages/dd/87/64cfa18a7a1621d17b7f4502b2b0ed8a135a90c3db51ea590ee99043e76b/fonttools-4.63.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b2248c5decb223562f7902ff6325077a073f608ee8e33e88ad88db734eb9f49", size = 5010526, upload-time = "2026-05-14T12:03:54.647Z" }, + { url = "https://files.pythonhosted.org/packages/36/e1/a8933a72c45a87177fbde2696e0d0755c8c9062f8c077a961c6215fa27b1/fonttools-4.63.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:308f957cdeaf8abe4e5f2f124902ef405448af92c90f80e302a3b771c2e6116b", size = 4923946, upload-time = "2026-05-14T12:03:56.984Z" }, + { url = "https://files.pythonhosted.org/packages/27/60/872e6e233b8c5e8b41413796ff18b7fe479661bd40147e071b450dfad7a1/fonttools-4.63.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:bf00f21eb5fb721dbaf73d1e9da6d02a1af7768f2ebcf9798be98beab8ba90f6", size = 4962489, upload-time = "2026-05-14T12:03:59.443Z" }, + { url = "https://files.pythonhosted.org/packages/30/c4/83c24f2ec38b90cfda84bf4b1a1f49df80e84a1db4e7ac6e0d41bf23bc39/fonttools-4.63.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c1aaa4b9c75798400ac043ce04d74e7830376c85095a5a6ed7cba2f17a266bf4", size = 5071870, upload-time = "2026-05-14T12:04:02.122Z" }, + { url = "https://files.pythonhosted.org/packages/de/40/3ae22b60ff1d41ce0bd044b31238cdc72cef99f28b976f1e128ebd618c9b/fonttools-4.63.0-cp314-cp314-win32.whl", hash = "sha256:22693918177bd9ceabec4736d338045f357769416fc6b0b2508eefef75b08616", size = 2295026, upload-time = "2026-05-14T12:04:04.47Z" }, + { url = "https://files.pythonhosted.org/packages/c3/d4/98078064ccc76b45cb0f6c002452011e93c4bd26f6850344f0951cc1fe89/fonttools-4.63.0-cp314-cp314-win_amd64.whl", hash = "sha256:7d782fac32985914c351556f68ac0855391572bcd87de50e05970d3cd4c96fc5", size = 2347454, upload-time = "2026-05-14T12:04:06.752Z" }, + { url = "https://files.pythonhosted.org/packages/49/4e/652d1580c5f4e39f7d103b0c793e4773129ad633dce4addd0cf4dfebde02/fonttools-4.63.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:6db5140a60a5d731d21ec076745b40a310607731b0a565b50776393188649001", size = 2958152, upload-time = "2026-05-14T12:04:08.706Z" }, + { url = "https://files.pythonhosted.org/packages/0e/55/ad864c9a9b219f552eb46b32cd7906c466e5a578ba0c3abfcc0fe7413eb6/fonttools-4.63.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7d76edbff9014094dbf03bd2d074709dfa6ec7aba13d838c937a2b33d2d6a86e", size = 2460809, upload-time = "2026-05-14T12:04:10.783Z" }, + { url = "https://files.pythonhosted.org/packages/ea/2b/0aa8db70f18cf52e49b4ed5ecec68547f981160bf5ded3b5aed6faa0a6f9/fonttools-4.63.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0eac00b9118c3c2f87d272e45341871c5b3066baa3c86897fa634a7c3fb59096", size = 5148649, upload-time = "2026-05-14T12:04:12.747Z" }, + { url = "https://files.pythonhosted.org/packages/7f/63/18e4369c25043096f1048e0c9915951adc4f842bd81c6b18155824d6fa99/fonttools-4.63.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:51394295f1a51de8b5f30bdb1e1b9a4231536c7064ef5c6e211eec19fa36036f", size = 4932147, upload-time = "2026-05-14T12:04:14.806Z" }, + { url = "https://files.pythonhosted.org/packages/a1/3f/67f3eac2ffd8a98446c5022f8ed3864eac878a5ff7af8df4c8286dba16cc/fonttools-4.63.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:9e12f105d2b6342c559c298afb674006bb2893afc7102dcf8a1b55b0486b4e40", size = 5027237, upload-time = "2026-05-14T12:04:17.675Z" }, + { url = "https://files.pythonhosted.org/packages/1a/ba/4e6214cb38a7b04779e97bb7636de9a5c7f20af7018d03dee0b64c08510a/fonttools-4.63.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:796f27556dbe094c4824f75ca85267e4df776c79036c8441469a4df37038c196", size = 5053933, upload-time = "2026-05-14T12:04:20.818Z" }, + { url = "https://files.pythonhosted.org/packages/34/3b/214dcc19ee31d3d38fb5ad2755c11ef0514e5dc300bbaf41c0b69f393799/fonttools-4.63.0-cp314-cp314t-win32.whl", hash = "sha256:948428a275741f0b64b113c955425a953314f4b9ab9997f73a72c83e68e569c8", size = 2359326, upload-time = "2026-05-14T12:04:24.22Z" }, + { url = "https://files.pythonhosted.org/packages/dd/1e/3ff1a9b523058c2eeb6a9d50f5574e2a738200d0d94107d5bc4105e8da3f/fonttools-4.63.0-cp314-cp314t-win_amd64.whl", hash = "sha256:6d4741eb179121cab9eea4cb2393d24492373a260d7945006358c08cfbf45419", size = 2425829, upload-time = "2026-05-14T12:04:26.829Z" }, + { url = "https://files.pythonhosted.org/packages/2c/47/c99d5268f354002ce80f8d029cd9d7d872969da1de8b93d32de4dc56d6f4/fonttools-4.63.0-py3-none-any.whl", hash = "sha256:445af2eab030a16b9171ea8bdda7ebf7d96bda2df88ee182a464252f6e05e20d", size = 1164562, upload-time = "2026-05-14T12:04:29.092Z" }, +] + +[[package]] +name = "ghp-import" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "python-dateutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d9/29/d40217cbe2f6b1359e00c6c307bb3fc876ba74068cbab3dde77f03ca0dc4/ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343", size = 10943, upload-time = "2022-05-02T15:47:16.11Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619", size = 11034, upload-time = "2022-05-02T15:47:14.552Z" }, +] + +[[package]] +name = "griffelib" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/33/e4/8d187ea29c2e30b3a09505c567513077d6117861bde1fbd997a167f262ec/griffelib-2.1.0.tar.gz", hash = "sha256:762a186d2c6fd6794d4ea20d428d597ffb857cb56b66421651cbba15bdd5e813", size = 216234, upload-time = "2026-06-19T12:05:42.278Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e4/d3/5268aeabf2ad82658c4e2ff3a060648d0f02f3926cb53247c0e4d0dab49e/griffelib-2.1.0-py3-none-any.whl", hash = "sha256:cc7b3d2d2865ad0b909fcc38086e3f554b5ea7acbaa7bbb7ecaa3f5dfb7d9f00", size = 142560, upload-time = "2026-06-19T12:05:38.742Z" }, +] + +[[package]] +name = "hypothesis" +version = "6.165.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "sortedcontainers" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/65/43/401c4208471374e6fa2d3abc77a595abd7e6518ebae83383f4556b4ae33b/hypothesis-6.165.7.tar.gz", hash = "sha256:7145e6f61aaa68721f5ad2009db85a2c694d7ae81cf3a6ed46c065ac34560a52", size = 503331, upload-time = "2026-08-14T05:57:11.691Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ac/ab/09bcf090991f953b657052dc2390b0a8ee612c57d74dfd22685f9f7d2f9c/hypothesis-6.165.7-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:05639812b66f353ed46b0f6fb1dbd6a022fb448636cf08ac460ea76aa6449783", size = 782842, upload-time = "2026-08-14T05:57:04.341Z" }, + { url = "https://files.pythonhosted.org/packages/5d/32/e283d3101473b0211e1587bac1b347f694c810d862608abd0b25ef8e85db/hypothesis-6.165.7-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:dfe2d72373dbf684be3fd77a5316b2948978f7d9c35870104f4a5094111d740d", size = 778398, upload-time = "2026-08-14T05:55:58.893Z" }, + { url = "https://files.pythonhosted.org/packages/e5/b6/407bce9773679ca08ef42c1a686bca46da03aeae69180c3870307b0070e4/hypothesis-6.165.7-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d99825c13df96e730c587d09c64b8e28602e4d255c82602b0c730b389d1da0af", size = 1107621, upload-time = "2026-08-14T05:56:38.918Z" }, + { url = "https://files.pythonhosted.org/packages/1c/40/0ff4e07fde5ca5e1762b0ef9177766dd5ae664698cea902bb14a25c87b64/hypothesis-6.165.7-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c43d30d6a764109797f8cd00ada9099204a83e4c7fdbfb7e769757be586e45f0", size = 1136230, upload-time = "2026-08-14T05:56:10.274Z" }, + { url = "https://files.pythonhosted.org/packages/92/c6/7f5f66b87f50abcdc3f511e2997121d808d4137cbf344b5269fda3ce35c4/hypothesis-6.165.7-cp310-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f3760432b5a208581b387afebad424270f87cebb610fa6cc9de56a78a20603bb", size = 1134841, upload-time = "2026-08-14T05:55:44.418Z" }, + { url = "https://files.pythonhosted.org/packages/3f/8b/1c77c7d9ff349078c14de659ceb5236c6b77fa85d727a577404b16ef00ff/hypothesis-6.165.7-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da023cc350040e835237e9b4a30b09453dc6cc9fbf63e54c06827ca5dae1deff", size = 1157128, upload-time = "2026-08-14T05:56:43.256Z" }, + { url = "https://files.pythonhosted.org/packages/24/4b/baa3f9c168f736f7b82dfdf52b9d009fe70bb6981097b8de151fc185ec90/hypothesis-6.165.7-cp310-abi3-manylinux_2_31_riscv64.whl", hash = "sha256:13562eced596160d318c392de82ea60b2c5f94632bac3b6417b2a521ebb3597d", size = 1112486, upload-time = "2026-08-14T05:56:16.705Z" }, + { url = "https://files.pythonhosted.org/packages/c5/d0/9aa42cbea4bf4790fa84e5763643af561412de52aa3a671ae536a4c51bf6/hypothesis-6.165.7-cp310-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c7106554e5683eb9b18ee71e4a69e2cb19a45437b62f5f6be9b90a556a742d2f", size = 1149212, upload-time = "2026-08-14T05:56:12.908Z" }, + { url = "https://files.pythonhosted.org/packages/63/56/647b411a8913ed0883b13b0f82e1de66c545b2cc11f7f3fddaca88a2ffef/hypothesis-6.165.7-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:b75a7a09cadd4eb4046b65b7ba34ea15c9f44ca5fb2b790071bb6257ec6d7c72", size = 1282996, upload-time = "2026-08-14T05:55:51.874Z" }, + { url = "https://files.pythonhosted.org/packages/b6/1b/56075bd8a33c55e38c9200f2b5a060d2445b63337e7693e35a0deae59d78/hypothesis-6.165.7-cp310-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:f3b926e12d2314ac225c7ad04d4dfab6ae6b62a4c0a41566cbce4d20c152eb6a", size = 1409545, upload-time = "2026-08-14T05:55:53.286Z" }, + { url = "https://files.pythonhosted.org/packages/23/c4/aa8951270f661997fc4b204dbb0ea2afe3c97aa312f814f1fad01ab63be1/hypothesis-6.165.7-cp310-abi3-musllinux_1_2_ppc64le.whl", hash = "sha256:9c4865980cec71d97f5283b6a3fcee6372176b41b10472b5ae90533d9d374378", size = 1264591, upload-time = "2026-08-14T05:56:03.028Z" }, + { url = "https://files.pythonhosted.org/packages/6d/5d/74c6f203aab52d4d011367c650978eef089a78e215f72c375265d2fa7437/hypothesis-6.165.7-cp310-abi3-musllinux_1_2_riscv64.whl", hash = "sha256:dd1a4e2a2f81448050208819577995648a0c1b272369918cdb82382d969f0cd2", size = 1282338, upload-time = "2026-08-14T05:56:28.712Z" }, + { url = "https://files.pythonhosted.org/packages/6b/62/bf42e3dc0835b97769af8a8f971964dc471067b9d6eb0234dd9f3c003e84/hypothesis-6.165.7-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:056f34f7709596f9dec38132996427f8b33d3f8c543945d5dfb8f7ce5507ab7e", size = 1324395, upload-time = "2026-08-14T05:56:18.256Z" }, + { url = "https://files.pythonhosted.org/packages/59/fb/2d5cf2b98d03b04d54c4b6d29957e9c9a1e7a1c39df18d4e4c09e4ace73d/hypothesis-6.165.7-cp310-abi3-win32.whl", hash = "sha256:87cd7c545fac14cb418c9a80026f24ef44bd39e4cb1b30c88c1d70041b0bad7a", size = 668623, upload-time = "2026-08-14T05:57:05.908Z" }, + { url = "https://files.pythonhosted.org/packages/b6/c6/174ca11ee966dd3c7e7312ff6b85f4a915db76928dddd672fc7609e387c0/hypothesis-6.165.7-cp310-abi3-win_amd64.whl", hash = "sha256:c9b5e76c15716e687c5903b716f3909b9f8a745c918031d508e0c27485cda195", size = 674806, upload-time = "2026-08-14T05:56:25.24Z" }, + { url = "https://files.pythonhosted.org/packages/54/2a/ad3195a4831b0e5202a602f61c7bd54c0935d675fc0bddbde8556c94d22b/hypothesis-6.165.7-cp310-abi3-win_arm64.whl", hash = "sha256:45e278dad2995461caaf5f08ea5a0c1832138764ea3d2baabc8800953b5220fc", size = 673115, upload-time = "2026-08-14T05:55:40.73Z" }, + { url = "https://files.pythonhosted.org/packages/4e/aa/e6e670f3c4d758f06dd74415233218aabeca00c76cda989d779fffe303ab/hypothesis-6.165.7-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:9c586a300f267c3ca0bca3bb6f5af45303e6c8861c1fed3bd2fd56ae6cb51c21", size = 783545, upload-time = "2026-08-14T05:56:14.229Z" }, + { url = "https://files.pythonhosted.org/packages/99/67/abec18f8b44254fdfcbebda07dbda6545833d3df7c2bd08b6a502cc1ab94/hypothesis-6.165.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:66e8e303d91c61924b63d9b410e2cbc74f49508ee7dfe06401700a878c6e844e", size = 779274, upload-time = "2026-08-14T05:56:04.349Z" }, + { url = "https://files.pythonhosted.org/packages/70/4b/852bae5af2b576d6153491204271471c2e1eb401017d11d6016c254e3500/hypothesis-6.165.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a9f8c27c34a9de29573998e9d26aa15ee164dc79100112332c106d51af3a571", size = 1108114, upload-time = "2026-08-14T05:56:58.472Z" }, + { url = "https://files.pythonhosted.org/packages/b4/f1/a9cb8d38fe47d66b4233b30b086a79a51a9cd0f5c250f1c9ecc61943f456/hypothesis-6.165.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38e6ba38738ad5b97b716e81913214c5b80c565811864e63f5cb1e0913634fba", size = 1157714, upload-time = "2026-08-14T05:56:45.102Z" }, + { url = "https://files.pythonhosted.org/packages/a8/ad/7c370e098daaa2d6cff8c27ac0be901a52c8a65abbeb0509a006cd9f9a41/hypothesis-6.165.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f2839ba7c30356af3c1570afb09fca1ee75fa351b402e70e186150e2c7314608", size = 1283737, upload-time = "2026-08-14T05:56:19.717Z" }, + { url = "https://files.pythonhosted.org/packages/93/e9/51450401aa331f53cf817d92655072c73b074ff712762040e1cd91453216/hypothesis-6.165.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f7aa3e09e5976d2a4b0c7fa295debe4f4ccb221ba93f09d58a755c1aec863d7e", size = 1324709, upload-time = "2026-08-14T05:55:43.212Z" }, + { url = "https://files.pythonhosted.org/packages/d3/b4/8ad2530f3070d4c9176a4b3068a7a6f559639a58e97189cca7657736b803/hypothesis-6.165.7-cp310-cp310-win_amd64.whl", hash = "sha256:0a44240d57d5117009360317756eb8ef3eb7e99c7d59cf52671b3e2c8224c403", size = 674671, upload-time = "2026-08-14T05:56:34.587Z" }, + { url = "https://files.pythonhosted.org/packages/c5/ae/2e6cb48b1be81fcddbe5b6fa2dc9f1d23999cf402fc0c191f25dbc083a66/hypothesis-6.165.7-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:c959f87798115a5ff4b160d9fde7c45c4f51ee136dbcf2f6f881c76795b95c30", size = 783310, upload-time = "2026-08-14T05:56:27.047Z" }, + { url = "https://files.pythonhosted.org/packages/e1/3c/a22df8a371b0642f6b33daa26c1f09b93cf26aff356f9e27e2ced21002c5/hypothesis-6.165.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4d53d1d5e3617f04664fa75d8b0fb75789b395aca03f60a878ca810bf35b352d", size = 779088, upload-time = "2026-08-14T05:56:48.875Z" }, + { url = "https://files.pythonhosted.org/packages/4a/fd/65a5050794c84afc661681176000ace177477244d84e6ba35b385e447c6d/hypothesis-6.165.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d68ba072108072db4849491830b540206821f02d9805cbcce6d5045c8bfe9a02", size = 1107977, upload-time = "2026-08-14T05:56:52.313Z" }, + { url = "https://files.pythonhosted.org/packages/70/5b/85f931749402e658c2740de69dc7899e55af4a7297b42dc527c71761894c/hypothesis-6.165.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03d16a55357918f144e049aad8462cd8143f19482310752611afff1c3944cded", size = 1157449, upload-time = "2026-08-14T05:56:05.498Z" }, + { url = "https://files.pythonhosted.org/packages/52/a1/5d7ec87ad85c52174c0f71fd68994642848f5db7884f99599a7c1ea59d73/hypothesis-6.165.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a4c1f574b3ee4d77232408fdcf5d0431521068c7ae83952e7b0788b41640567a", size = 1283318, upload-time = "2026-08-14T05:56:57.044Z" }, + { url = "https://files.pythonhosted.org/packages/7c/67/7c1fa720a56ff81849b5c669026fd02393348fe890ed1af734b82d6372ae/hypothesis-6.165.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:8bf896b9c1f0dda906d8d68a9ecd1c921fbbb3278d2cdfff43e66c5d9fcf0771", size = 1324652, upload-time = "2026-08-14T05:55:47.979Z" }, + { url = "https://files.pythonhosted.org/packages/c6/86/d71e7e2c9250a7e25af554a3091143ac1a2ae00d0ae5dfaac8c8bf447feb/hypothesis-6.165.7-cp311-cp311-win_amd64.whl", hash = "sha256:b505d188b6a0e10b0cd71391864b4e48120fc6e6f56fd4ced468d6fa5ccff47b", size = 674513, upload-time = "2026-08-14T05:56:32.951Z" }, + { url = "https://files.pythonhosted.org/packages/23/48/34d0520707dd4257e43109f0ee6e014c8a82a1638b608acb2e36f4a58388/hypothesis-6.165.7-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:deda016ecb384238a633aea1211eace838fbb511bbc9b45d72cfc100c3099c27", size = 784426, upload-time = "2026-08-14T05:57:02.595Z" }, + { url = "https://files.pythonhosted.org/packages/a2/fd/d031f0484aae5b66c1efe5e6b7c6d7b45d665997abf4d16a452b3ed7aadb/hypothesis-6.165.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4d75e61487624c8ed1a6b4a152f7246f822adf5dc08b04ca8cbdef9d0513ac17", size = 775984, upload-time = "2026-08-14T05:56:50.507Z" }, + { url = "https://files.pythonhosted.org/packages/c6/78/bbe4f69f520c49b856a7e57d45edbe3eb29e8683ab6bd9c30e28b833f27c/hypothesis-6.165.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33bc7000fb8600f490861ba520498f3dcdba21323e30b9c984e1844163a18f09", size = 1106403, upload-time = "2026-08-14T05:55:56.354Z" }, + { url = "https://files.pythonhosted.org/packages/33/46/dae1892594f4393cfcb54d861e90457bf265d480549ed7380e3b0e4659ee/hypothesis-6.165.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aba0c419d0bab7a020148aa676c6d95a2caf1fd562b4448c5d765ebe800fe7cd", size = 1156510, upload-time = "2026-08-14T05:56:08.634Z" }, + { url = "https://files.pythonhosted.org/packages/ee/c9/0e585192260b93097edb7a79875c3c52858fb9f19064bf9c675f2c9d94c1/hypothesis-6.165.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f28f60ad62b22cf781e31db6c29b5db9593c271cbe9433674ecba1f9e5d684ac", size = 1280394, upload-time = "2026-08-14T05:56:01.761Z" }, + { url = "https://files.pythonhosted.org/packages/0a/65/ee27554a6c174e9afcf315a61a8d4877410a0448630de0cf728fc93f14ea/hypothesis-6.165.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7a91f9a0b081ec2dc09c7321e73510eb8182ad14993dd9b4b2d5232373c9b9ed", size = 1323736, upload-time = "2026-08-14T05:55:49.186Z" }, + { url = "https://files.pythonhosted.org/packages/20/00/ec50544eb9b299817548170ab458680ebfb7f80ccb802a3bab99b858bd32/hypothesis-6.165.7-cp312-cp312-win_amd64.whl", hash = "sha256:abb6c19b3f44f03c74f970f7977d73bf62657a2bd785ed7095e859bff15e3ef0", size = 671928, upload-time = "2026-08-14T05:56:23.892Z" }, + { url = "https://files.pythonhosted.org/packages/87/ab/6afbe5702c3ee6d671b7582e904b8826765eb34839a1648000dada0daeda/hypothesis-6.165.7-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:920e9c2683605fd9f679cefc3dadec5b02ef6cca0b703471694b52bbc2ac4662", size = 784317, upload-time = "2026-08-14T05:56:41.856Z" }, + { url = "https://files.pythonhosted.org/packages/7d/d1/5335d4419a165e8143637999a94b0286631c70ef14b7be5d3857ba8f6ff3/hypothesis-6.165.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4d3ef6419119179e419979f91cdbdcd1837ad89ae07749075cb6681a5a392aae", size = 775947, upload-time = "2026-08-14T05:56:15.459Z" }, + { url = "https://files.pythonhosted.org/packages/98/86/98a0f79fe09b5af7ec947145068004900877455796c3e1ed17671b4a81da/hypothesis-6.165.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f0116b20965a679b162fe581279a86f579ba121c33243a4a0c1c795b01a8c00", size = 1106315, upload-time = "2026-08-14T05:55:37.583Z" }, + { url = "https://files.pythonhosted.org/packages/55/2d/78badb82d103fa372e309e7a7e06ddfdde7895d35c09ad08432f44b833f0/hypothesis-6.165.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:146ef6ea75f4be8c3c6efecfda04e3125598904e5c60a4e4fc40272f16322f36", size = 1156340, upload-time = "2026-08-14T05:55:45.834Z" }, + { url = "https://files.pythonhosted.org/packages/28/27/aa6fc3c1886e38d396fcd29eef851840ff0c800b400a151a38d816fad379/hypothesis-6.165.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:236583a200fd5b499e64a519c52cd38ff061a97c1a7c7e7dbec6a6d8c721c2d1", size = 1280379, upload-time = "2026-08-14T05:55:54.91Z" }, + { url = "https://files.pythonhosted.org/packages/3a/dc/39ed61ce537d2cf559674e224ccdf1a367cd2d79fb4bba49b8851a4e00d9/hypothesis-6.165.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d08febaa6b74dfb24b0f269101076fb7506183e6a60cc693b52dc6c79e7b5dae", size = 1323499, upload-time = "2026-08-14T05:55:41.938Z" }, + { url = "https://files.pythonhosted.org/packages/eb/ce/7cfd46644e28c44c2a1fb6f489e606e99b4bcaf094858b27f9b059e57c9c/hypothesis-6.165.7-cp313-cp313-win_amd64.whl", hash = "sha256:1c4a671640466b66d4fa139d87c38f9a9fd2a6698838a53d7c94b4ef8194f99a", size = 671937, upload-time = "2026-08-14T05:56:47.057Z" }, + { url = "https://files.pythonhosted.org/packages/a4/d6/68666ba55fd5b6b2910306a9bec58c245d5fb30fae6d20f77bed94386bb6/hypothesis-6.165.7-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:48d99baf86bee75b8b01f4b145bcac8d9b8aaa9e90c8e7bbb4fd5c855fcd536e", size = 784417, upload-time = "2026-08-14T05:55:57.713Z" }, + { url = "https://files.pythonhosted.org/packages/f2/e3/0894e616e18fc947fa22eeead5cc68dc62fd04206900f1757d8034a61e74/hypothesis-6.165.7-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a7cd0884b06a6fc0cec0664428c064cba2fc12b60cd08d8f3350e68f0e40122a", size = 776089, upload-time = "2026-08-14T05:55:38.915Z" }, + { url = "https://files.pythonhosted.org/packages/3b/7c/16381076313d0dbad72cae42647736494bf7f76cb82ac775c2d50be7744c/hypothesis-6.165.7-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4648d7a0db16e5b42036df621656c10626010e2fb81aaef20f10425aae3b3425", size = 1106860, upload-time = "2026-08-14T05:56:07.242Z" }, + { url = "https://files.pythonhosted.org/packages/a5/30/1a7e6870d1796d0dd36a4d0a84633537c933aba58c9c5c4843f8ebd39271/hypothesis-6.165.7-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e1952892b29ef0c4833dc95ba7ac038100e97253eb050097fa87ebc04ae079b", size = 1156523, upload-time = "2026-08-14T05:56:30.253Z" }, + { url = "https://files.pythonhosted.org/packages/8a/49/d7df70b65082ae47acea3c1d80ad3e0cd47b25fa8fdf5f83db6841d1222d/hypothesis-6.165.7-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:52e17d84282a47ea34056ad0f20ea6086196c058e7ee7479a6f4cb14eb45efc6", size = 1280741, upload-time = "2026-08-14T05:57:07.505Z" }, + { url = "https://files.pythonhosted.org/packages/5a/0b/38dd337508400889f0b7379f59fa11de51aecdedebd568c4a6f646530a0f/hypothesis-6.165.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b5cc1c0a4aff6307486964ae0e2edfc66154284a0f0f5d243bd1ee543bb3ceba", size = 1323827, upload-time = "2026-08-14T05:56:22.553Z" }, + { url = "https://files.pythonhosted.org/packages/63/52/c95ca46bb516cdf8dad77018dc7e3f5fff27762133804e0c852d67a11b6d/hypothesis-6.165.7-cp314-cp314-pyemscripten_2026_0_wasm32.whl", hash = "sha256:65b6d71f7311b0da65846a941d97db89d8c86be42b44e8f8f3c92f05f947d180", size = 615984, upload-time = "2026-08-14T05:56:40.362Z" }, + { url = "https://files.pythonhosted.org/packages/3e/29/019affba6c280292304df7ef2f1e74d8e18ae7c6c6d10dfa45e118573c1e/hypothesis-6.165.7-cp314-cp314-win_amd64.whl", hash = "sha256:2d4920d44286356eb9b951857855edf546ccbfe3e5ec9ff9dde8d892e3b94006", size = 671738, upload-time = "2026-08-14T05:56:36.064Z" }, + { url = "https://files.pythonhosted.org/packages/e0/38/79db43ec2b43058dbdea754b4ca00f67639d26328dc0341d84ee68e8fe04/hypothesis-6.165.7-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:4bfac98cea1c8607b727c91365d5f67fb94b1d132dd17d8e8c1dcc6299436e1b", size = 782877, upload-time = "2026-08-14T05:56:55.544Z" }, + { url = "https://files.pythonhosted.org/packages/f3/14/606021e740adc51aa5c24a0e7d1657dd53b3b01ffc9bba2f8eef6a398ae9/hypothesis-6.165.7-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7d32d2e8de8c1e4a05fd26d2a63565edd6c57958f519f5c157c0dbab522990d8", size = 774508, upload-time = "2026-08-14T05:56:21.316Z" }, + { url = "https://files.pythonhosted.org/packages/fb/da/d8f07d7de2b2860b198deb1ddcd93381aefa21fac4256431fd0570971042/hypothesis-6.165.7-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81dccd2854ad314261258ac1c4a589821cc201eda12481577f3a02d96189cae3", size = 1105037, upload-time = "2026-08-14T05:56:31.577Z" }, + { url = "https://files.pythonhosted.org/packages/5c/05/bebc7fa30212b7273f62007e53132a09aab3c494b132b887c7387dbbadf0/hypothesis-6.165.7-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de498adb1e468890fb92c0e28aa8a804beb5f7a3b86fc12cc52234e96422d869", size = 1155181, upload-time = "2026-08-14T05:56:00.334Z" }, + { url = "https://files.pythonhosted.org/packages/c0/37/a7caaf1c23318a7ee5040aa57d2c1dca6e47a032a0bf2d15f4813d7d64d3/hypothesis-6.165.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:3de56b506f23625e7e3d69a782020c86ddf0d55f5a96263da08bce3fe77969c1", size = 1278765, upload-time = "2026-08-14T05:55:50.654Z" }, + { url = "https://files.pythonhosted.org/packages/fc/f0/25b8f2dd3df22cfc78b00d4ae96188aa0b0a2a50f8718087cd581c52ab1c/hypothesis-6.165.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:fe32ce174c50ceb034ba9ed02cea889bc5d8d8d4fbb31aea65b5ff3cebcee72a", size = 1322457, upload-time = "2026-08-14T05:55:35.527Z" }, + { url = "https://files.pythonhosted.org/packages/f6/d7/0b6dd3be856e6e500e300393302f0e3c5d5ad8c0a5fe4bd4c18cbf1a12e7/hypothesis-6.165.7-cp314-cp314t-win_amd64.whl", hash = "sha256:419def31dde1afee05f95122b34f134ad86625eaf38a8f89a90448c95541d6e8", size = 671737, upload-time = "2026-08-14T05:55:46.902Z" }, + { url = "https://files.pythonhosted.org/packages/b3/bc/c8b40749c091013c58c24259eac0e0bb4d33d789c6c4d5d86342fa520282/hypothesis-6.165.7-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:d3515860fd9511ea288469387dd60be4015082fc4570aadfaa81aeae625f60da", size = 784232, upload-time = "2026-08-14T05:57:09.752Z" }, + { url = "https://files.pythonhosted.org/packages/0d/4d/ea2ac212e5f7372a320019970a7b19568f2d6a219df97f29fb6e6e821ad9/hypothesis-6.165.7-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:2d548516e3e3c8bc3a978b170d9277845eae6211c2626e974871a3f38c88835a", size = 780077, upload-time = "2026-08-14T05:56:37.494Z" }, + { url = "https://files.pythonhosted.org/packages/27/71/3cd533e7e7fa3f8dbb9de803f3448ebb61b745487a4e8a21d355271c5587/hypothesis-6.165.7-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79f2e5e163e0c326fbc5e50db14a692e35b72dd26c0ba8cc20dcc58873a772ee", size = 1108956, upload-time = "2026-08-14T05:56:54.028Z" }, + { url = "https://files.pythonhosted.org/packages/d2/57/69125a71ac2cdf58d0e3f9145307487e1ddf0192fdb8c9f3f63e25073aae/hypothesis-6.165.7-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b94f1fe479be8a71b85821d0eee36dad3320dd1502edcacc50c1590b7c329afd", size = 1158724, upload-time = "2026-08-14T05:57:00.63Z" }, + { url = "https://files.pythonhosted.org/packages/cc/87/bf55333a9eaaa98cbb74f4d9f7225df0ac170c264f81cf14fdec2f899d72/hypothesis-6.165.7-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:566ca258edc99ebd3fa1e41e74e86bcc217186f94962954d47f2cb5006e473af", size = 675628, upload-time = "2026-08-14T05:56:11.599Z" }, +] + +[[package]] +name = "identify" +version = "2.6.19" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/52/63/51723b5f116cc04b061cb6f5a561790abf249d25931d515cd375e063e0f4/identify-2.6.19.tar.gz", hash = "sha256:6be5020c38fcb07da56c53733538a3081ea5aa70d36a156f83044bfbf9173842", size = 99567, upload-time = "2026-04-17T18:39:50.265Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl", hash = "sha256:20e6a87f786f768c092a721ad107fc9df0eb89347be9396cadf3f4abbd1fb78a", size = 99397, upload-time = "2026-04-17T18:39:49.221Z" }, +] + +[[package]] +name = "idna" +version = "3.18" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cd/63/9496c57188a2ee585e0f1db071d75089a11e98aa86eb99d9d7618fc1edce/idna-3.18.tar.gz", hash = "sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848", size = 196711, upload-time = "2026-06-02T14:34:07.794Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl", hash = "sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2", size = 65455, upload-time = "2026-06-02T14:34:06.319Z" }, +] + +[[package]] +name = "importlib-metadata" +version = "9.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "zipp" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a9/01/15bb152d77b21318514a96f43af312635eb2500c96b55398d020c93d86ea/importlib_metadata-9.0.0.tar.gz", hash = "sha256:a4f57ab599e6a2e3016d7595cfd72eb4661a5106e787a95bcc90c7105b831efc", size = 56405, upload-time = "2026-03-20T06:42:56.999Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/3d/2d244233ac4f76e38533cfcb2991c9eb4c7bf688ae0a036d30725b8faafe/importlib_metadata-9.0.0-py3-none-any.whl", hash = "sha256:2d21d1cc5a017bd0559e36150c21c830ab1dc304dedd1b7ea85d20f45ef3edd7", size = 27789, upload-time = "2026-03-20T06:42:55.665Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, +] + +[[package]] +name = "jmespath" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d3/59/322338183ecda247fb5d1763a6cbe46eff7222eaeebafd9fa65d4bf5cb11/jmespath-1.1.0.tar.gz", hash = "sha256:472c87d80f36026ae83c6ddd0f1d05d4e510134ed462851fd5f754c8c3cbb88d", size = 27377, upload-time = "2026-01-22T16:35:26.279Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/14/2f/967ba146e6d58cf6a652da73885f52fc68001525b4197effc174321d70b4/jmespath-1.1.0-py3-none-any.whl", hash = "sha256:a5663118de4908c91729bea0acadca56526eb2698e83de10cd116ae0f4e97c64", size = 20419, upload-time = "2026-01-22T16:35:24.919Z" }, +] + +[[package]] +name = "kiwisolver" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/67/9c61eccb13f0bdca9307614e782fec49ffdde0f7a2314935d489fa93cd9c/kiwisolver-1.5.0.tar.gz", hash = "sha256:d4193f3d9dc3f6f79aaed0e5637f45d98850ebf01f7ca20e69457f3e8946b66a", size = 103482, upload-time = "2026-03-09T13:15:53.382Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ac/f8/06549565caa026e540b7e7bab5c5a90eb7ca986015f4c48dace243cd24d9/kiwisolver-1.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:32cc0a5365239a6ea0c6ed461e8838d053b57e397443c0ca894dcc8e388d4374", size = 122802, upload-time = "2026-03-09T13:12:37.515Z" }, + { url = "https://files.pythonhosted.org/packages/84/eb/8476a0818850c563ff343ea7c9c05dcdcbd689a38e01aa31657df01f91fa/kiwisolver-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cc0b66c1eec9021353a4b4483afb12dfd50e3669ffbb9152d6842eb34c7e29fd", size = 66216, upload-time = "2026-03-09T13:12:38.812Z" }, + { url = "https://files.pythonhosted.org/packages/f3/c4/f9c8a6b4c21aed4198566e45923512986d6cef530e7263b3a5f823546561/kiwisolver-1.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:86e0287879f75621ae85197b0877ed2f8b7aa57b511c7331dce2eb6f4de7d476", size = 63917, upload-time = "2026-03-09T13:12:40.053Z" }, + { url = "https://files.pythonhosted.org/packages/f1/0e/ba4ae25d03722f64de8b2c13e80d82ab537a06b30fc7065183c6439357e3/kiwisolver-1.5.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:62f59da443c4f4849f73a51a193b1d9d258dcad0c41bc4d1b8fb2bcc04bfeb22", size = 1628776, upload-time = "2026-03-09T13:12:41.976Z" }, + { url = "https://files.pythonhosted.org/packages/8a/e4/3f43a011bc8a0860d1c96f84d32fa87439d3feedf66e672fef03bf5e8bac/kiwisolver-1.5.0-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9190426b7aa26c5229501fa297b8d0653cfd3f5a36f7990c264e157cbf886b3b", size = 1228164, upload-time = "2026-03-09T13:12:44.002Z" }, + { url = "https://files.pythonhosted.org/packages/4b/34/3a901559a1e0c218404f9a61a93be82d45cb8f44453ba43088644980f033/kiwisolver-1.5.0-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c8277104ded0a51e699c8c3aff63ce2c56d4ed5519a5f73e0fd7057f959a2b9e", size = 1246656, upload-time = "2026-03-09T13:12:45.557Z" }, + { url = "https://files.pythonhosted.org/packages/87/9e/f78c466ea20527822b95ad38f141f2de1dcd7f23fb8716b002b0d91bbe59/kiwisolver-1.5.0-cp310-cp310-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8f9baf6f0a6e7571c45c8863010b45e837c3ee1c2c77fcd6ef423be91b21fedb", size = 1295562, upload-time = "2026-03-09T13:12:47.562Z" }, + { url = "https://files.pythonhosted.org/packages/0a/66/fd0e4a612e3a286c24e6d6f3a5428d11258ed1909bc530ba3b59807fd980/kiwisolver-1.5.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cff8e5383db4989311f99e814feeb90c4723eb4edca425b9d5d9c3fefcdd9537", size = 2178473, upload-time = "2026-03-09T13:12:50.254Z" }, + { url = "https://files.pythonhosted.org/packages/dc/8e/6cac929e0049539e5ee25c1ee937556f379ba5204840d03008363ced662d/kiwisolver-1.5.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ebae99ed6764f2b5771c522477b311be313e8841d2e0376db2b10922daebbba4", size = 2274035, upload-time = "2026-03-09T13:12:51.785Z" }, + { url = "https://files.pythonhosted.org/packages/ca/d3/9d0c18f1b52ea8074b792452cf17f1f5a56bd0302a85191f405cfbf9da16/kiwisolver-1.5.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:d5cd5189fc2b6a538b75ae45433140c4823463918f7b1617c31e68b085c0022c", size = 2443217, upload-time = "2026-03-09T13:12:53.329Z" }, + { url = "https://files.pythonhosted.org/packages/45/2a/6e19368803a038b2a90857bf4ee9e3c7b667216d045866bf22d3439fd75e/kiwisolver-1.5.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f42c23db5d1521218a3276bb08666dcb662896a0be7347cba864eca45ff64ede", size = 2249196, upload-time = "2026-03-09T13:12:55.057Z" }, + { url = "https://files.pythonhosted.org/packages/75/2b/3f641dfcbe72e222175d626bacf2f72c3b34312afec949dd1c50afa400f5/kiwisolver-1.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:94eff26096eb5395136634622515b234ecb6c9979824c1f5004c6e3c3c85ccd2", size = 73389, upload-time = "2026-03-09T13:12:56.496Z" }, + { url = "https://files.pythonhosted.org/packages/da/88/299b137b9e0025d8982e03d2d52c123b0a2b159e84b0ef1501ef446339cf/kiwisolver-1.5.0-cp310-cp310-win_arm64.whl", hash = "sha256:dd952e03bfbb096cfe2dd35cd9e00f269969b67536cb4370994afc20ff2d0875", size = 64782, upload-time = "2026-03-09T13:12:57.609Z" }, + { url = "https://files.pythonhosted.org/packages/12/dd/a495a9c104be1c476f0386e714252caf2b7eca883915422a64c50b88c6f5/kiwisolver-1.5.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9eed0f7edbb274413b6ee781cca50541c8c0facd3d6fd289779e494340a2b85c", size = 122798, upload-time = "2026-03-09T13:12:58.963Z" }, + { url = "https://files.pythonhosted.org/packages/11/60/37b4047a2af0cf5ef6d8b4b26e91829ae6fc6a2d1f74524bcb0e7cd28a32/kiwisolver-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c4923e404d6bcd91b6779c009542e5647fef32e4a5d75e115e3bbac6f2335eb", size = 66216, upload-time = "2026-03-09T13:13:00.155Z" }, + { url = "https://files.pythonhosted.org/packages/0a/aa/510dc933d87767584abfe03efa445889996c70c2990f6f87c3ebaa0a18c5/kiwisolver-1.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0df54df7e686afa55e6f21fb86195224a6d9beb71d637e8d7920c95cf0f89aac", size = 63911, upload-time = "2026-03-09T13:13:01.671Z" }, + { url = "https://files.pythonhosted.org/packages/80/46/bddc13df6c2a40741e0cc7865bb1c9ed4796b6760bd04ce5fae3928ef917/kiwisolver-1.5.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2517e24d7315eb51c10664cdb865195df38ab74456c677df67bb47f12d088a27", size = 1438209, upload-time = "2026-03-09T13:13:03.385Z" }, + { url = "https://files.pythonhosted.org/packages/fd/d6/76621246f5165e5372f02f5e6f3f48ea336a8f9e96e43997d45b240ed8cd/kiwisolver-1.5.0-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff710414307fefa903e0d9bdf300972f892c23477829f49504e59834f4195398", size = 1248888, upload-time = "2026-03-09T13:13:05.231Z" }, + { url = "https://files.pythonhosted.org/packages/b2/c1/31559ec6fb39a5b48035ce29bb63ade628f321785f38c384dee3e2c08bc1/kiwisolver-1.5.0-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6176c1811d9d5a04fa391c490cc44f451e240697a16977f11c6f722efb9041db", size = 1266304, upload-time = "2026-03-09T13:13:06.743Z" }, + { url = "https://files.pythonhosted.org/packages/5e/ef/1cb8276f2d29cc6a41e0a042f27946ca347d3a4a75acf85d0a16aa6dcc82/kiwisolver-1.5.0-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:50847dca5d197fcbd389c805aa1a1cf32f25d2e7273dc47ab181a517666b68cc", size = 1319650, upload-time = "2026-03-09T13:13:08.607Z" }, + { url = "https://files.pythonhosted.org/packages/4c/e4/5ba3cecd7ce6236ae4a80f67e5d5531287337d0e1f076ca87a5abe4cd5d0/kiwisolver-1.5.0-cp311-cp311-manylinux_2_39_riscv64.whl", hash = "sha256:01808c6d15f4c3e8559595d6d1fe6411c68e4a3822b4b9972b44473b24f4e679", size = 970949, upload-time = "2026-03-09T13:13:10.299Z" }, + { url = "https://files.pythonhosted.org/packages/5a/69/dc61f7ae9a2f071f26004ced87f078235b5507ab6e5acd78f40365655034/kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f1f9f4121ec58628c96baa3de1a55a4e3a333c5102c8e94b64e23bf7b2083309", size = 2199125, upload-time = "2026-03-09T13:13:11.841Z" }, + { url = "https://files.pythonhosted.org/packages/e5/7b/abbe0f1b5afa85f8d084b73e90e5f801c0939eba16ac2e49af7c61a6c28d/kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b7d335370ae48a780c6e6a6bbfa97342f563744c39c35562f3f367665f5c1de2", size = 2293783, upload-time = "2026-03-09T13:13:14.399Z" }, + { url = "https://files.pythonhosted.org/packages/8a/80/5908ae149d96d81580d604c7f8aefd0e98f4fd728cf172f477e9f2a81744/kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:800ee55980c18545af444d93fdd60c56b580db5cc54867d8cbf8a1dc0829938c", size = 1960726, upload-time = "2026-03-09T13:13:16.047Z" }, + { url = "https://files.pythonhosted.org/packages/84/08/a78cb776f8c085b7143142ce479859cfec086bd09ee638a317040b6ef420/kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c438f6ca858697c9ab67eb28246c92508af972e114cac34e57a6d4ba17a3ac08", size = 2464738, upload-time = "2026-03-09T13:13:17.897Z" }, + { url = "https://files.pythonhosted.org/packages/b1/e1/65584da5356ed6cb12c63791a10b208860ac40a83de165cb6a6751a686e3/kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:8c63c91f95173f9c2a67c7c526b2cea976828a0e7fced9cdcead2802dc10f8a4", size = 2270718, upload-time = "2026-03-09T13:13:19.421Z" }, + { url = "https://files.pythonhosted.org/packages/be/6c/28f17390b62b8f2f520e2915095b3c94d88681ecf0041e75389d9667f202/kiwisolver-1.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:beb7f344487cdcb9e1efe4b7a29681b74d34c08f0043a327a74da852a6749e7b", size = 73480, upload-time = "2026-03-09T13:13:20.818Z" }, + { url = "https://files.pythonhosted.org/packages/d8/0e/2ee5debc4f77a625778fec5501ff3e8036fe361b7ee28ae402a485bb9694/kiwisolver-1.5.0-cp311-cp311-win_arm64.whl", hash = "sha256:ad4ae4ffd1ee9cd11357b4c66b612da9888f4f4daf2f36995eda64bd45370cac", size = 64930, upload-time = "2026-03-09T13:13:21.997Z" }, + { url = "https://files.pythonhosted.org/packages/4d/b2/818b74ebea34dabe6d0c51cb1c572e046730e64844da6ed646d5298c40ce/kiwisolver-1.5.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:4e9750bc21b886308024f8a54ccb9a2cc38ac9fa813bf4348434e3d54f337ff9", size = 123158, upload-time = "2026-03-09T13:13:23.127Z" }, + { url = "https://files.pythonhosted.org/packages/bf/d9/405320f8077e8e1c5c4bd6adc45e1e6edf6d727b6da7f2e2533cf58bff71/kiwisolver-1.5.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:72ec46b7eba5b395e0a7b63025490d3214c11013f4aacb4f5e8d6c3041829588", size = 66388, upload-time = "2026-03-09T13:13:24.765Z" }, + { url = "https://files.pythonhosted.org/packages/99/9f/795fedf35634f746151ca8839d05681ceb6287fbed6cc1c9bf235f7887c2/kiwisolver-1.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ed3a984b31da7481b103f68776f7128a89ef26ed40f4dc41a2223cda7fb24819", size = 64068, upload-time = "2026-03-09T13:13:25.878Z" }, + { url = "https://files.pythonhosted.org/packages/c4/13/680c54afe3e65767bed7ec1a15571e1a2f1257128733851ade24abcefbcc/kiwisolver-1.5.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bb5136fb5352d3f422df33f0c879a1b0c204004324150cc3b5e3c4f310c9049f", size = 1477934, upload-time = "2026-03-09T13:13:27.166Z" }, + { url = "https://files.pythonhosted.org/packages/c8/2f/cebfcdb60fd6a9b0f6b47a9337198bcbad6fbe15e68189b7011fd914911f/kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b2af221f268f5af85e776a73d62b0845fc8baf8ef0abfae79d29c77d0e776aaf", size = 1278537, upload-time = "2026-03-09T13:13:28.707Z" }, + { url = "https://files.pythonhosted.org/packages/f2/0d/9b782923aada3fafb1d6b84e13121954515c669b18af0c26e7d21f579855/kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b0f172dc8ffaccb8522d7c5d899de00133f2f1ca7b0a49b7da98e901de87bf2d", size = 1296685, upload-time = "2026-03-09T13:13:30.528Z" }, + { url = "https://files.pythonhosted.org/packages/27/70/83241b6634b04fe44e892688d5208332bde130f38e610c0418f9ede47ded/kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6ab8ba9152203feec73758dad83af9a0bbe05001eb4639e547207c40cfb52083", size = 1346024, upload-time = "2026-03-09T13:13:32.818Z" }, + { url = "https://files.pythonhosted.org/packages/e4/db/30ed226fb271ae1a6431fc0fe0edffb2efe23cadb01e798caeb9f2ceae8f/kiwisolver-1.5.0-cp312-cp312-manylinux_2_39_riscv64.whl", hash = "sha256:cdee07c4d7f6d72008d3f73b9bf027f4e11550224c7c50d8df1ae4a37c1402a6", size = 987241, upload-time = "2026-03-09T13:13:34.435Z" }, + { url = "https://files.pythonhosted.org/packages/ec/bd/c314595208e4c9587652d50959ead9e461995389664e490f4dce7ff0f782/kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7c60d3c9b06fb23bd9c6139281ccbdc384297579ae037f08ae90c69f6845c0b1", size = 2227742, upload-time = "2026-03-09T13:13:36.4Z" }, + { url = "https://files.pythonhosted.org/packages/c1/43/0499cec932d935229b5543d073c2b87c9c22846aab48881e9d8d6e742a2d/kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e315e5ec90d88e140f57696ff85b484ff68bb311e36f2c414aa4286293e6dee0", size = 2323966, upload-time = "2026-03-09T13:13:38.204Z" }, + { url = "https://files.pythonhosted.org/packages/3d/6f/79b0d760907965acfd9d61826a3d41f8f093c538f55cd2633d3f0db269f6/kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:1465387ac63576c3e125e5337a6892b9e99e0627d52317f3ca79e6930d889d15", size = 1977417, upload-time = "2026-03-09T13:13:39.966Z" }, + { url = "https://files.pythonhosted.org/packages/ab/31/01d0537c41cb75a551a438c3c7a80d0c60d60b81f694dac83dd436aec0d0/kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:530a3fd64c87cffa844d4b6b9768774763d9caa299e9b75d8eca6a4423b31314", size = 2491238, upload-time = "2026-03-09T13:13:41.698Z" }, + { url = "https://files.pythonhosted.org/packages/e4/34/8aefdd0be9cfd00a44509251ba864f5caf2991e36772e61c408007e7f417/kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1d9daea4ea6b9be74fe2f01f7fbade8d6ffab263e781274cffca0dba9be9eec9", size = 2294947, upload-time = "2026-03-09T13:13:43.343Z" }, + { url = "https://files.pythonhosted.org/packages/ad/cf/0348374369ca588f8fe9c338fae49fa4e16eeb10ffb3d012f23a54578a9e/kiwisolver-1.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:f18c2d9782259a6dc132fdc7a63c168cbc74b35284b6d75c673958982a378384", size = 73569, upload-time = "2026-03-09T13:13:45.792Z" }, + { url = "https://files.pythonhosted.org/packages/28/26/192b26196e2316e2bd29deef67e37cdf9870d9af8e085e521afff0fed526/kiwisolver-1.5.0-cp312-cp312-win_arm64.whl", hash = "sha256:f7c7553b13f69c1b29a5bde08ddc6d9d0c8bfb84f9ed01c30db25944aeb852a7", size = 64997, upload-time = "2026-03-09T13:13:46.878Z" }, + { url = "https://files.pythonhosted.org/packages/9d/69/024d6711d5ba575aa65d5538042e99964104e97fa153a9f10bc369182bc2/kiwisolver-1.5.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:fd40bb9cd0891c4c3cb1ddf83f8bbfa15731a248fdc8162669405451e2724b09", size = 123166, upload-time = "2026-03-09T13:13:48.032Z" }, + { url = "https://files.pythonhosted.org/packages/ce/48/adbb40df306f587054a348831220812b9b1d787aff714cfbc8556e38fccd/kiwisolver-1.5.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c0e1403fd7c26d77c1f03e096dc58a5c726503fa0db0456678b8668f76f521e3", size = 66395, upload-time = "2026-03-09T13:13:49.365Z" }, + { url = "https://files.pythonhosted.org/packages/a8/3a/d0a972b34e1c63e2409413104216cd1caa02c5a37cb668d1687d466c1c45/kiwisolver-1.5.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dda366d548e89a90d88a86c692377d18d8bd64b39c1fb2b92cb31370e2896bbd", size = 64065, upload-time = "2026-03-09T13:13:50.562Z" }, + { url = "https://files.pythonhosted.org/packages/2b/0a/7b98e1e119878a27ba8618ca1e18b14f992ff1eda40f47bccccf4de44121/kiwisolver-1.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:332b4f0145c30b5f5ad9374881133e5aa64320428a57c2c2b61e9d891a51c2f3", size = 1477903, upload-time = "2026-03-09T13:13:52.084Z" }, + { url = "https://files.pythonhosted.org/packages/18/d8/55638d89ffd27799d5cc3d8aa28e12f4ce7a64d67b285114dbedc8ea4136/kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c50b89ffd3e1a911c69a1dd3de7173c0cd10b130f56222e57898683841e4f96", size = 1278751, upload-time = "2026-03-09T13:13:54.673Z" }, + { url = "https://files.pythonhosted.org/packages/b8/97/b4c8d0d18421ecceba20ad8701358453b88e32414e6f6950b5a4bad54e65/kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4db576bb8c3ef9365f8b40fe0f671644de6736ae2c27a2c62d7d8a1b4329f099", size = 1296793, upload-time = "2026-03-09T13:13:56.287Z" }, + { url = "https://files.pythonhosted.org/packages/c4/10/f862f94b6389d8957448ec9df59450b81bec4abb318805375c401a1e6892/kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0b85aad90cea8ac6797a53b5d5f2e967334fa4d1149f031c4537569972596cb8", size = 1346041, upload-time = "2026-03-09T13:13:58.269Z" }, + { url = "https://files.pythonhosted.org/packages/a3/6a/f1650af35821eaf09de398ec0bc2aefc8f211f0cda50204c9f1673741ba9/kiwisolver-1.5.0-cp313-cp313-manylinux_2_39_riscv64.whl", hash = "sha256:d36ca54cb4c6c4686f7cbb7b817f66f5911c12ddb519450bbe86707155028f87", size = 987292, upload-time = "2026-03-09T13:13:59.871Z" }, + { url = "https://files.pythonhosted.org/packages/de/19/d7fb82984b9238115fe629c915007be608ebd23dc8629703d917dbfaffd4/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:38f4a703656f493b0ad185211ccfca7f0386120f022066b018eb5296d8613e23", size = 2227865, upload-time = "2026-03-09T13:14:01.401Z" }, + { url = "https://files.pythonhosted.org/packages/7f/b9/46b7f386589fd222dac9e9de9c956ce5bcefe2ee73b4e79891381dda8654/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3ac2360e93cb41be81121755c6462cff3beaa9967188c866e5fce5cf13170859", size = 2324369, upload-time = "2026-03-09T13:14:02.972Z" }, + { url = "https://files.pythonhosted.org/packages/92/8b/95e237cf3d9c642960153c769ddcbe278f182c8affb20cecc1cc983e7cc5/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c95cab08d1965db3d84a121f1c7ce7479bdd4072c9b3dafd8fecce48a2e6b902", size = 1977989, upload-time = "2026-03-09T13:14:04.503Z" }, + { url = "https://files.pythonhosted.org/packages/1b/95/980c9df53501892784997820136c01f62bc1865e31b82b9560f980c0e649/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fc20894c3d21194d8041a28b65622d5b86db786da6e3cfe73f0c762951a61167", size = 2491645, upload-time = "2026-03-09T13:14:06.106Z" }, + { url = "https://files.pythonhosted.org/packages/cb/32/900647fd0840abebe1561792c6b31e6a7c0e278fc3973d30572a965ca14c/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7a32f72973f0f950c1920475d5c5ea3d971b81b6f0ec53b8d0a956cc965f22e0", size = 2295237, upload-time = "2026-03-09T13:14:08.891Z" }, + { url = "https://files.pythonhosted.org/packages/be/8a/be60e3bbcf513cc5a50f4a3e88e1dcecebb79c1ad607a7222877becaa101/kiwisolver-1.5.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bf3acf1419fa93064a4c2189ac0b58e3be7872bf6ee6177b0d4c63dc4cea276", size = 73573, upload-time = "2026-03-09T13:14:12.327Z" }, + { url = "https://files.pythonhosted.org/packages/4d/d2/64be2e429eb4fca7f7e1c52a91b12663aeaf25de3895e5cca0f47ef2a8d0/kiwisolver-1.5.0-cp313-cp313-win_arm64.whl", hash = "sha256:fa8eb9ecdb7efb0b226acec134e0d709e87a909fa4971a54c0c4f6e88635484c", size = 64998, upload-time = "2026-03-09T13:14:13.469Z" }, + { url = "https://files.pythonhosted.org/packages/b0/69/ce68dd0c85755ae2de490bf015b62f2cea5f6b14ff00a463f9d0774449ff/kiwisolver-1.5.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:db485b3847d182b908b483b2ed133c66d88d49cacf98fd278fadafe11b4478d1", size = 125700, upload-time = "2026-03-09T13:14:14.636Z" }, + { url = "https://files.pythonhosted.org/packages/74/aa/937aac021cf9d4349990d47eb319309a51355ed1dbdc9c077cdc9224cb11/kiwisolver-1.5.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:be12f931839a3bdfe28b584db0e640a65a8bcbc24560ae3fdb025a449b3d754e", size = 67537, upload-time = "2026-03-09T13:14:15.808Z" }, + { url = "https://files.pythonhosted.org/packages/ee/20/3a87fbece2c40ad0f6f0aefa93542559159c5f99831d596050e8afae7a9f/kiwisolver-1.5.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:16b85d37c2cbb3253226d26e64663f755d88a03439a9c47df6246b35defbdfb7", size = 65514, upload-time = "2026-03-09T13:14:18.035Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7f/f943879cda9007c45e1f7dba216d705c3a18d6b35830e488b6c6a4e7cdf0/kiwisolver-1.5.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4432b835675f0ea7414aab3d37d119f7226d24869b7a829caeab49ebda407b0c", size = 1584848, upload-time = "2026-03-09T13:14:19.745Z" }, + { url = "https://files.pythonhosted.org/packages/37/f8/4d4f85cc1870c127c88d950913370dd76138482161cd07eabbc450deff01/kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b0feb50971481a2cc44d94e88bdb02cdd497618252ae226b8eb1201b957e368", size = 1391542, upload-time = "2026-03-09T13:14:21.54Z" }, + { url = "https://files.pythonhosted.org/packages/04/0b/65dd2916c84d252b244bd405303220f729e7c17c9d7d33dca6feeff9ffc4/kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:56fa888f10d0f367155e76ce849fa1166fc9730d13bd2d65a2aa13b6f5424489", size = 1404447, upload-time = "2026-03-09T13:14:23.205Z" }, + { url = "https://files.pythonhosted.org/packages/39/5c/2606a373247babce9b1d056c03a04b65f3cf5290a8eac5d7bdead0a17e21/kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:940dda65d5e764406b9fb92761cbf462e4e63f712ab60ed98f70552e496f3bf1", size = 1455918, upload-time = "2026-03-09T13:14:24.74Z" }, + { url = "https://files.pythonhosted.org/packages/d5/d1/c6078b5756670658e9192a2ef11e939c92918833d2745f85cd14a6004bdf/kiwisolver-1.5.0-cp313-cp313t-manylinux_2_39_riscv64.whl", hash = "sha256:89fc958c702ee9a745e4700378f5d23fddbc46ff89e8fdbf5395c24d5c1452a3", size = 1072856, upload-time = "2026-03-09T13:14:26.597Z" }, + { url = "https://files.pythonhosted.org/packages/cb/c8/7def6ddf16eb2b3741d8b172bdaa9af882b03c78e9b0772975408801fa63/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9027d773c4ff81487181a925945743413f6069634d0b122d0b37684ccf4f1e18", size = 2333580, upload-time = "2026-03-09T13:14:28.237Z" }, + { url = "https://files.pythonhosted.org/packages/9e/87/2ac1fce0eb1e616fcd3c35caa23e665e9b1948bb984f4764790924594128/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:5b233ea3e165e43e35dba1d2b8ecc21cf070b45b65ae17dd2747d2713d942021", size = 2423018, upload-time = "2026-03-09T13:14:30.018Z" }, + { url = "https://files.pythonhosted.org/packages/67/13/c6700ccc6cc218716bfcda4935e4b2997039869b4ad8a94f364c5a3b8e63/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:ce9bf03dad3b46408c08649c6fbd6ca28a9fce0eb32fdfffa6775a13103b5310", size = 2062804, upload-time = "2026-03-09T13:14:32.888Z" }, + { url = "https://files.pythonhosted.org/packages/1b/bd/877056304626943ff0f1f44c08f584300c199b887cb3176cd7e34f1515f1/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:fc4d3f1fb9ca0ae9f97b095963bc6326f1dbfd3779d6679a1e016b9baaa153d3", size = 2597482, upload-time = "2026-03-09T13:14:34.971Z" }, + { url = "https://files.pythonhosted.org/packages/75/19/c60626c47bf0f8ac5dcf72c6c98e266d714f2fbbfd50cf6dab5ede3aaa50/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f443b4825c50a51ee68585522ab4a1d1257fac65896f282b4c6763337ac9f5d2", size = 2394328, upload-time = "2026-03-09T13:14:36.816Z" }, + { url = "https://files.pythonhosted.org/packages/47/84/6a6d5e5bb8273756c27b7d810d47f7ef2f1f9b9fd23c9ee9a3f8c75c9cef/kiwisolver-1.5.0-cp313-cp313t-win_arm64.whl", hash = "sha256:893ff3a711d1b515ba9da14ee090519bad4610ed1962fbe298a434e8c5f8db53", size = 68410, upload-time = "2026-03-09T13:14:38.695Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d7/060f45052f2a01ad5762c8fdecd6d7a752b43400dc29ff75cd47225a40fd/kiwisolver-1.5.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:8df31fe574b8b3993cc61764f40941111b25c2d9fea13d3ce24a49907cd2d615", size = 123231, upload-time = "2026-03-09T13:14:41.323Z" }, + { url = "https://files.pythonhosted.org/packages/c2/a7/78da680eadd06ff35edef6ef68a1ad273bad3e2a0936c9a885103230aece/kiwisolver-1.5.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:1d49a49ac4cbfb7c1375301cd1ec90169dfeae55ff84710d782260ce77a75a02", size = 66489, upload-time = "2026-03-09T13:14:42.534Z" }, + { url = "https://files.pythonhosted.org/packages/49/b2/97980f3ad4fae37dd7fe31626e2bf75fbf8bdf5d303950ec1fab39a12da8/kiwisolver-1.5.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0cbe94b69b819209a62cb27bdfa5dc2a8977d8de2f89dfd97ba4f53ed3af754e", size = 64063, upload-time = "2026-03-09T13:14:44.759Z" }, + { url = "https://files.pythonhosted.org/packages/e7/f9/b06c934a6aa8bc91f566bd2a214fd04c30506c2d9e2b6b171953216a65b6/kiwisolver-1.5.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:80aa065ffd378ff784822a6d7c3212f2d5f5e9c3589614b5c228b311fd3063ac", size = 1475913, upload-time = "2026-03-09T13:14:46.247Z" }, + { url = "https://files.pythonhosted.org/packages/6b/f0/f768ae564a710135630672981231320bc403cf9152b5596ec5289de0f106/kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e7f886f47ab881692f278ae901039a234e4025a68e6dfab514263a0b1c4ae05", size = 1282782, upload-time = "2026-03-09T13:14:48.458Z" }, + { url = "https://files.pythonhosted.org/packages/e2/9f/1de7aad00697325f05238a5f2eafbd487fb637cc27a558b5367a5f37fb7f/kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5060731cc3ed12ca3a8b57acd4aeca5bbc2f49216dd0bec1650a1acd89486bcd", size = 1300815, upload-time = "2026-03-09T13:14:50.721Z" }, + { url = "https://files.pythonhosted.org/packages/5a/c2/297f25141d2e468e0ce7f7a7b92e0cf8918143a0cbd3422c1ad627e85a06/kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7a4aa69609f40fce3cbc3f87b2061f042eee32f94b8f11db707b66a26461591a", size = 1347925, upload-time = "2026-03-09T13:14:52.304Z" }, + { url = "https://files.pythonhosted.org/packages/b9/d3/f4c73a02eb41520c47610207b21afa8cdd18fdbf64ffd94674ae21c4812d/kiwisolver-1.5.0-cp314-cp314-manylinux_2_39_riscv64.whl", hash = "sha256:d168fda2dbff7b9b5f38e693182d792a938c31db4dac3a80a4888de603c99554", size = 991322, upload-time = "2026-03-09T13:14:54.637Z" }, + { url = "https://files.pythonhosted.org/packages/7b/46/d3f2efef7732fcda98d22bf4ad5d3d71d545167a852ca710a494f4c15343/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:413b820229730d358efd838ecbab79902fe97094565fdc80ddb6b0a18c18a581", size = 2232857, upload-time = "2026-03-09T13:14:56.471Z" }, + { url = "https://files.pythonhosted.org/packages/3f/ec/2d9756bf2b6d26ae4349b8d3662fb3993f16d80c1f971c179ce862b9dbae/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:5124d1ea754509b09e53738ec185584cc609aae4a3b510aaf4ed6aa047ef9303", size = 2329376, upload-time = "2026-03-09T13:14:58.072Z" }, + { url = "https://files.pythonhosted.org/packages/8f/9f/876a0a0f2260f1bde92e002b3019a5fabc35e0939c7d945e0fa66185eb20/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e4415a8db000bf49a6dd1c478bf70062eaacff0f462b92b0ba68791a905861f9", size = 1982549, upload-time = "2026-03-09T13:14:59.668Z" }, + { url = "https://files.pythonhosted.org/packages/6c/4f/ba3624dfac23a64d54ac4179832860cb537c1b0af06024936e82ca4154a0/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d618fd27420381a4f6044faa71f46d8bfd911bd077c555f7138ed88729bfbe79", size = 2494680, upload-time = "2026-03-09T13:15:01.364Z" }, + { url = "https://files.pythonhosted.org/packages/39/b7/97716b190ab98911b20d10bf92eca469121ec483b8ce0edd314f51bc85af/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5092eb5b1172947f57d6ea7d89b2f29650414e4293c47707eb499ec07a0ac796", size = 2297905, upload-time = "2026-03-09T13:15:03.925Z" }, + { url = "https://files.pythonhosted.org/packages/a3/36/4e551e8aa55c9188bca9abb5096805edbf7431072b76e2298e34fd3a3008/kiwisolver-1.5.0-cp314-cp314-win_amd64.whl", hash = "sha256:d76e2d8c75051d58177e762164d2e9ab92886534e3a12e795f103524f221dd8e", size = 75086, upload-time = "2026-03-09T13:15:07.775Z" }, + { url = "https://files.pythonhosted.org/packages/70/15/9b90f7df0e31a003c71649cf66ef61c3c1b862f48c81007fa2383c8bd8d7/kiwisolver-1.5.0-cp314-cp314-win_arm64.whl", hash = "sha256:fa6248cd194edff41d7ea9425ced8ca3a6f838bfb295f6f1d6e6bb694a8518df", size = 66577, upload-time = "2026-03-09T13:15:09.139Z" }, + { url = "https://files.pythonhosted.org/packages/17/01/7dc8c5443ff42b38e72731643ed7cf1ed9bf01691ae5cdca98501999ed83/kiwisolver-1.5.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:d1ffeb80b5676463d7a7d56acbe8e37a20ce725570e09549fe738e02ca6b7e1e", size = 125794, upload-time = "2026-03-09T13:15:10.525Z" }, + { url = "https://files.pythonhosted.org/packages/46/8a/b4ebe46ebaac6a303417fab10c2e165c557ddaff558f9699d302b256bc53/kiwisolver-1.5.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:bc4d8e252f532ab46a1de9349e2d27b91fce46736a9eedaa37beaca66f574ed4", size = 67646, upload-time = "2026-03-09T13:15:12.016Z" }, + { url = "https://files.pythonhosted.org/packages/60/35/10a844afc5f19d6f567359bf4789e26661755a2f36200d5d1ed8ad0126e5/kiwisolver-1.5.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6783e069732715ad0c3ce96dbf21dbc2235ab0593f2baf6338101f70371f4028", size = 65511, upload-time = "2026-03-09T13:15:13.311Z" }, + { url = "https://files.pythonhosted.org/packages/f8/8a/685b297052dd041dcebce8e8787b58923b6e78acc6115a0dc9189011c44b/kiwisolver-1.5.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e7c4c09a490dc4d4a7f8cbee56c606a320f9dc28cf92a7157a39d1ce7676a657", size = 1584858, upload-time = "2026-03-09T13:15:15.103Z" }, + { url = "https://files.pythonhosted.org/packages/9e/80/04865e3d4638ac5bddec28908916df4a3075b8c6cc101786a96803188b96/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2a075bd7bd19c70cf67c8badfa36cf7c5d8de3c9ddb8420c51e10d9c50e94920", size = 1392539, upload-time = "2026-03-09T13:15:16.661Z" }, + { url = "https://files.pythonhosted.org/packages/ba/01/77a19cacc0893fa13fafa46d1bba06fb4dc2360b3292baf4b56d8e067b24/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bdd3e53429ff02aa319ba59dfe4ceeec345bf46cf180ec2cf6fd5b942e7975e9", size = 1405310, upload-time = "2026-03-09T13:15:18.229Z" }, + { url = "https://files.pythonhosted.org/packages/53/39/bcaf5d0cca50e604cfa9b4e3ae1d64b50ca1ae5b754122396084599ef903/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cdcb35dc9d807259c981a85531048ede628eabcffb3239adf3d17463518992d", size = 1456244, upload-time = "2026-03-09T13:15:20.444Z" }, + { url = "https://files.pythonhosted.org/packages/d0/7a/72c187abc6975f6978c3e39b7cf67aeb8b3c0a8f9790aa7fd412855e9e1f/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_39_riscv64.whl", hash = "sha256:70d593af6a6ca332d1df73d519fddb5148edb15cd90d5f0155e3746a6d4fcc65", size = 1073154, upload-time = "2026-03-09T13:15:22.039Z" }, + { url = "https://files.pythonhosted.org/packages/c7/ca/cf5b25783ebbd59143b4371ed0c8428a278abe68d6d0104b01865b1bbd0f/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:377815a8616074cabbf3f53354e1d040c35815a134e01d7614b7692e4bf8acfa", size = 2334377, upload-time = "2026-03-09T13:15:23.741Z" }, + { url = "https://files.pythonhosted.org/packages/4a/e5/b1f492adc516796e88751282276745340e2a72dcd0d36cf7173e0daf3210/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0255a027391d52944eae1dbb5d4cc5903f57092f3674e8e544cdd2622826b3f0", size = 2425288, upload-time = "2026-03-09T13:15:25.789Z" }, + { url = "https://files.pythonhosted.org/packages/e6/e5/9b21fbe91a61b8f409d74a26498706e97a48008bfcd1864373d32a6ba31c/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:012b1eb16e28718fa782b5e61dc6f2da1f0792ca73bd05d54de6cb9561665fc9", size = 2063158, upload-time = "2026-03-09T13:15:27.63Z" }, + { url = "https://files.pythonhosted.org/packages/b1/02/83f47986138310f95ea95531f851b2a62227c11cbc3e690ae1374fe49f0f/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:0e3aafb33aed7479377e5e9a82e9d4bf87063741fc99fc7ae48b0f16e32bdd6f", size = 2597260, upload-time = "2026-03-09T13:15:29.421Z" }, + { url = "https://files.pythonhosted.org/packages/07/18/43a5f24608d8c313dd189cf838c8e68d75b115567c6279de7796197cfb6a/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e7a116ae737f0000343218c4edf5bd45893bfeaff0993c0b215d7124c9f77646", size = 2394403, upload-time = "2026-03-09T13:15:31.517Z" }, + { url = "https://files.pythonhosted.org/packages/3b/b5/98222136d839b8afabcaa943b09bd05888c2d36355b7e448550211d1fca4/kiwisolver-1.5.0-cp314-cp314t-win_amd64.whl", hash = "sha256:1dd9b0b119a350976a6d781e7278ec7aca0b201e1a9e2d23d9804afecb6ca681", size = 79687, upload-time = "2026-03-09T13:15:33.204Z" }, + { url = "https://files.pythonhosted.org/packages/99/a2/ca7dc962848040befed12732dff6acae7fb3c4f6fc4272b3f6c9a30b8713/kiwisolver-1.5.0-cp314-cp314t-win_arm64.whl", hash = "sha256:58f812017cd2985c21fbffb4864d59174d4903dd66fa23815e74bbc7a0e2dd57", size = 70032, upload-time = "2026-03-09T13:15:34.411Z" }, + { url = "https://files.pythonhosted.org/packages/1c/fa/2910df836372d8761bb6eff7d8bdcb1613b5c2e03f260efe7abe34d388a7/kiwisolver-1.5.0-graalpy312-graalpy250_312_native-macosx_10_13_x86_64.whl", hash = "sha256:5ae8e62c147495b01a0f4765c878e9bfdf843412446a247e28df59936e99e797", size = 130262, upload-time = "2026-03-09T13:15:35.629Z" }, + { url = "https://files.pythonhosted.org/packages/0f/41/c5f71f9f00aabcc71fee8b7475e3f64747282580c2fe748961ba29b18385/kiwisolver-1.5.0-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:f6764a4ccab3078db14a632420930f6186058750df066b8ea2a7106df91d3203", size = 138036, upload-time = "2026-03-09T13:15:36.894Z" }, + { url = "https://files.pythonhosted.org/packages/fa/06/7399a607f434119c6e1fdc8ec89a8d51ccccadf3341dee4ead6bd14caaf5/kiwisolver-1.5.0-graalpy312-graalpy250_312_native-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c31c13da98624f957b0fb1b5bae5383b2333c2c3f6793d9825dd5ce79b525cb7", size = 194295, upload-time = "2026-03-09T13:15:38.22Z" }, + { url = "https://files.pythonhosted.org/packages/b5/91/53255615acd2a1eaca307ede3c90eb550bae9c94581f8c00081b6b1c8f44/kiwisolver-1.5.0-graalpy312-graalpy250_312_native-win_amd64.whl", hash = "sha256:1f1489f769582498610e015a8ef2d36f28f505ab3096d0e16b4858a9ec214f57", size = 75987, upload-time = "2026-03-09T13:15:39.65Z" }, + { url = "https://files.pythonhosted.org/packages/17/6f/6fd4f690a40c2582fa34b97d2678f718acf3706b91d270c65ecb455d0a06/kiwisolver-1.5.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:295d9ffe712caa9f8a3081de8d32fc60191b4b51c76f02f951fd8407253528f4", size = 59606, upload-time = "2026-03-09T13:15:40.81Z" }, + { url = "https://files.pythonhosted.org/packages/82/a0/2355d5e3b338f13ce63f361abb181e3b6ea5fffdb73f739b3e80efa76159/kiwisolver-1.5.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:51e8c4084897de9f05898c2c2a39af6318044ae969d46ff7a34ed3f96274adca", size = 57537, upload-time = "2026-03-09T13:15:42.071Z" }, + { url = "https://files.pythonhosted.org/packages/c8/b9/1d50e610ecadebe205b71d6728fd224ce0e0ca6aba7b9cbe1da049203ac5/kiwisolver-1.5.0-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b83af57bdddef03c01a9138034c6ff03181a3028d9a1003b301eb1a55e161a3f", size = 79888, upload-time = "2026-03-09T13:15:43.317Z" }, + { url = "https://files.pythonhosted.org/packages/cd/ee/b85ffcd75afed0357d74f0e6fc02a4507da441165de1ca4760b9f496390d/kiwisolver-1.5.0-pp310-pypy310_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bf4679a3d71012a7c2bf360e5cd878fbd5e4fcac0896b56393dec239d81529ed", size = 77584, upload-time = "2026-03-09T13:15:44.605Z" }, + { url = "https://files.pythonhosted.org/packages/6b/dd/644d0dde6010a8583b4cd66dd41c5f83f5325464d15c4f490b3340ab73b4/kiwisolver-1.5.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:41024ed50e44ab1a60d3fe0a9d15a4ccc9f5f2b1d814ff283c8d01134d5b81bc", size = 73390, upload-time = "2026-03-09T13:15:45.832Z" }, + { url = "https://files.pythonhosted.org/packages/e9/eb/5fcbbbf9a0e2c3a35effb88831a483345326bbc3a030a3b5b69aee647f84/kiwisolver-1.5.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ec4c85dc4b687c7f7f15f553ff26a98bfe8c58f5f7f0ac8905f0ba4c7be60232", size = 59532, upload-time = "2026-03-09T13:15:47.047Z" }, + { url = "https://files.pythonhosted.org/packages/c3/9b/e17104555bb4db148fd52327feea1e96be4b88e8e008b029002c281a21ab/kiwisolver-1.5.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:12e91c215a96e39f57989c8912ae761286ac5a9584d04030ceb3368a357f017a", size = 57420, upload-time = "2026-03-09T13:15:48.199Z" }, + { url = "https://files.pythonhosted.org/packages/48/44/2b5b95b7aa39fb2d8d9d956e0f3d5d45aef2ae1d942d4c3ffac2f9cfed1a/kiwisolver-1.5.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:be4a51a55833dc29ab5d7503e7bcb3b3af3402d266018137127450005cdfe737", size = 79892, upload-time = "2026-03-09T13:15:49.694Z" }, + { url = "https://files.pythonhosted.org/packages/52/7d/7157f9bba6b455cfb4632ed411e199fc8b8977642c2b12082e1bd9e6d173/kiwisolver-1.5.0-pp311-pypy311_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:daae526907e262de627d8f70058a0f64acc9e2641c164c99c8f594b34a799a16", size = 77603, upload-time = "2026-03-09T13:15:50.945Z" }, + { url = "https://files.pythonhosted.org/packages/0a/dd/8050c947d435c8d4bc94e3252f4d8bb8a76cfb424f043a8680be637a57f1/kiwisolver-1.5.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:59cd8683f575d96df5bb48f6add94afc055012c29e28124fcae2b63661b9efb1", size = 73558, upload-time = "2026-03-09T13:15:52.112Z" }, +] + +[[package]] +name = "librt" +version = "0.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/36/9b/356320fbae2ac8467e21c5e73e1389c80468e4998c62cc7d3536cc51b614/librt-0.15.0.tar.gz", hash = "sha256:4e66cbe84437497d951b799d3e1551291b6fb3d643820a7014b3655d57a59162", size = 214338, upload-time = "2026-08-07T10:49:42.663Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/12/e2e9ca532cf5a0e08c9489826c4a35c6958c92ba0313fda70e8c6c3912be/librt-0.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e1a49adf16a7c9d9646816c2946135527197b6fcf4347c7b8b761cf1bfbf4489", size = 148673, upload-time = "2026-08-07T10:46:22.569Z" }, + { url = "https://files.pythonhosted.org/packages/6d/7c/02005e23478bd5950618d9712e0fd2b4c511657857f3efd8ba6a5feabcdd/librt-0.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:81a398f45b45a59200e13cd5ad1ae1d3f44334de98b148331afe2cdfee701c52", size = 153547, upload-time = "2026-08-07T10:46:23.931Z" }, + { url = "https://files.pythonhosted.org/packages/a0/90/d8848a735f5642077fc4b3b4bebcdb08edf10178e3add45597f5201a368f/librt-0.15.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4eafbaff06b9563f8b1c850621ce51605de05208e09d4d71ce490bc972b7b9e8", size = 494355, upload-time = "2026-08-07T10:46:25.122Z" }, + { url = "https://files.pythonhosted.org/packages/e1/0b/8604f41ea02feace490e9e405a338a15f9905369f55b239a9ce31c946f24/librt-0.15.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:b0411b4066db926b80258c60dcb0e6db4c9cee312eab45b7e8866b17ddf9ada1", size = 485459, upload-time = "2026-08-07T10:46:26.447Z" }, + { url = "https://files.pythonhosted.org/packages/a0/ac/84153bda1ce0da609182527ab92b40d961809e544eefdc5a1c2422971416/librt-0.15.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:febb1ce6cac545a54e6b769982824e955a700fdd9fbf3a08a3d82c990968b57d", size = 498398, upload-time = "2026-08-07T10:46:27.701Z" }, + { url = "https://files.pythonhosted.org/packages/2c/3a/5ca6cd282b2c244bec8ec84102e09773264e9c02891d56ab3a8f0e4d7083/librt-0.15.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b230acc1c3bfe2d6f2627ba2b95dc92e58aa494600e9722d0e6ccbc931e59702", size = 515474, upload-time = "2026-08-07T10:46:28.9Z" }, + { url = "https://files.pythonhosted.org/packages/73/d3/bd34110234779eb843c6ed66aba7c9b2091d3dd85989f1fb9922f564cb7a/librt-0.15.0-cp310-cp310-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6da110e5f314c19ab8478464d02ae18808ae73d522c15260fa4918acdcd64da9", size = 509484, upload-time = "2026-08-07T10:46:30.124Z" }, + { url = "https://files.pythonhosted.org/packages/1b/6c/43c3f7f071d71631a7daa3b835ef2168ea39f20692d81464d4e47fbaa6d6/librt-0.15.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:eab9208b00ca55bf75983ec99f7bf13acc746a36102e98953addaad7f7ea1e1b", size = 532534, upload-time = "2026-08-07T10:46:31.511Z" }, + { url = "https://files.pythonhosted.org/packages/c5/1c/b854adf036ea817c40408873a5b794d65a91d9f0f39826f2ad2a2d5d7f48/librt-0.15.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:6c013cd3a1721e69e14380ada97eaa4b7b0cdf1c6b96fa765d4ea47c875088db", size = 537087, upload-time = "2026-08-07T10:46:32.734Z" }, + { url = "https://files.pythonhosted.org/packages/25/5c/c9a890e244e7dd725d3bd8b560e41f0aec787eaf343b46956a290ab7b841/librt-0.15.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:567b1c430f8bd560e689421468278ac5941bab4a05303b5d95b6ae10db03f451", size = 536575, upload-time = "2026-08-07T10:46:33.965Z" }, + { url = "https://files.pythonhosted.org/packages/5f/c5/c8e70b60b704299555f55db468eb46b1c81bfc60201ffbfe20407d89870c/librt-0.15.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:29c4cab9df457b19672c39be7f384ebb2bc925c4e2684b8780c222b43eb36389", size = 517142, upload-time = "2026-08-07T10:46:35.577Z" }, + { url = "https://files.pythonhosted.org/packages/56/d1/767a90c41f5d381b3195bc88ac0ec4afda35777c9c781e1f9848fedd965e/librt-0.15.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bccbd8e5b0bffb7106cf18eb1baa3d7194b1cebb3b4b1cdbd4bdb19382a6ee6c", size = 558714, upload-time = "2026-08-07T10:46:36.829Z" }, + { url = "https://files.pythonhosted.org/packages/f9/b4/3c0624b8dc8301ab808f2b3a910995bcabe28df070fb9a0e5505ae997dae/librt-0.15.0-cp310-cp310-win32.whl", hash = "sha256:8ae493ed5f659a7761c43d42f183db514536073ded9bcf671d2d1df47e29a07e", size = 104426, upload-time = "2026-08-07T10:46:38.594Z" }, + { url = "https://files.pythonhosted.org/packages/31/98/e91c0382304bedb2db9c6801897319a9dcb68daac5e975819b562362f20d/librt-0.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:bc25fb356d0c7810bb49ff3df908ad1fda6995d660ab099ded69244ed7ab6053", size = 125057, upload-time = "2026-08-07T10:46:40.052Z" }, + { url = "https://files.pythonhosted.org/packages/59/52/06790ced2ac7117f890c21bda43c39c958ec82aa665c0718e821d33ff939/librt-0.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:823b92cf3c18ecd08afc70c42473888b41b6e8ef5046f3b82c05c154a2fa3d22", size = 148039, upload-time = "2026-08-07T10:46:41.165Z" }, + { url = "https://files.pythonhosted.org/packages/e7/1d/8e150b7fc449a1f33c8a760965cc1f43b14fc1577d9d0b50ab2701420e74/librt-0.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c70bc1b602cf59917e8f0c7a2cbc8bcc6fbc14d5486136b00707a79619121d63", size = 153067, upload-time = "2026-08-07T10:46:42.418Z" }, + { url = "https://files.pythonhosted.org/packages/51/87/a162bc5a66a35599dc619ecb215145f4de7d68e886b479b6d12593139f7c/librt-0.15.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:814ff83a25b5fce8b9c80c4dd803153fb5c5599fc74db9e022466938368957ef", size = 493087, upload-time = "2026-08-07T10:46:43.657Z" }, + { url = "https://files.pythonhosted.org/packages/e5/3a/aeea1fc620cf48060d3065b37614edbf97043c099d0f50782bc8ca61d897/librt-0.15.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:57f5eeb6ad4c180de583b1038e61fe5fbd9796bb69a8a1c1a0c7ddbec4c8c60f", size = 485608, upload-time = "2026-08-07T10:46:45.038Z" }, + { url = "https://files.pythonhosted.org/packages/52/ff/fe571ad416f0856fd0d5578ffc2e6dc531891e586e36b647bcf50569cab8/librt-0.15.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:82909c8f7eb9952656b65d3147afde4cf8e6d5a991eebc86418b5e65843b0ab8", size = 498723, upload-time = "2026-08-07T10:46:46.35Z" }, + { url = "https://files.pythonhosted.org/packages/0f/e1/7a65eb5dedb1f00aebd948cdd8e17add48bf066cab3514e9daf84ab45a6c/librt-0.15.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f779070399f991400fc451719e0ea388eb7de313388bada2c127a35de05f798a", size = 516002, upload-time = "2026-08-07T10:46:47.599Z" }, + { url = "https://files.pythonhosted.org/packages/5f/45/59832b0ebfbd08c2742e6ece372ceb53f18bf1faef5d33c8daf3abebf749/librt-0.15.0-cp311-cp311-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bac89069bc496ebdf4f79ebb57bbd10d0b214c8454225deb672d91002bd17e18", size = 508607, upload-time = "2026-08-07T10:46:48.873Z" }, + { url = "https://files.pythonhosted.org/packages/ea/0d/37fa73f3b43ebd8259f91ae9102a15e5a54e65d581e48dea72df3e81d7a4/librt-0.15.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e0d00c708fb2f5822b152429b1ac80a58dbbbc3f6c232c4d13a3f7fcf2ea5b4c", size = 530422, upload-time = "2026-08-07T10:46:50.45Z" }, + { url = "https://files.pythonhosted.org/packages/26/02/e046c6fe7a5881ac34623242192f484426ba8a75595fd18f22c53a3f530f/librt-0.15.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:6c6624fe268625869485553dd7cc1daf30d22558215bb2a4ff16f67a9801a31a", size = 534303, upload-time = "2026-08-07T10:46:51.693Z" }, + { url = "https://files.pythonhosted.org/packages/95/32/d5e6d861ab0366f3edf74f887ab0c9eb9f535aaf01d32b80b4f734daa179/librt-0.15.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f56b397858a23dacf35ede366ed2212fdc03a6a57a1ad36468ad6e9dc5fac091", size = 536084, upload-time = "2026-08-07T10:46:52.951Z" }, + { url = "https://files.pythonhosted.org/packages/2a/de/d69d725513fe53fc90c6d7a1f86e4428939bad2fb905b17fe4c18d413dde/librt-0.15.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:4388184646efe2054911c5b00a1077d6d1ee86a95b7e8ba96dc7850a809f3f40", size = 514307, upload-time = "2026-08-07T10:46:54.194Z" }, + { url = "https://files.pythonhosted.org/packages/36/93/f8aded0d6682b4f25820fa86e0690f87f01df9fd7bd09ddb04d9167ad021/librt-0.15.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:97335f59082f9fe2ce6c2a9cc6433a0114bbb6cd4d5c09dd76c95c68b9f9a8b0", size = 557686, upload-time = "2026-08-07T10:46:55.443Z" }, + { url = "https://files.pythonhosted.org/packages/74/09/ffeb6bdeb6cd862b4272fddc8ad05f938dd25d020ed517e631813917d80a/librt-0.15.0-cp311-cp311-win32.whl", hash = "sha256:83380ffde38062a2e9bb55d83e74474f6614665528b98a6928720fc006dfffbb", size = 104917, upload-time = "2026-08-07T10:46:56.605Z" }, + { url = "https://files.pythonhosted.org/packages/96/28/7e2313a3ffbf0b4de7ba3da58a09e488507b4bd1ea2b5e69378354a23415/librt-0.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:f75720477ee05d509a310e856cacc8d909adc182f7b91193c207bcc26d7ee6db", size = 125886, upload-time = "2026-08-07T10:46:57.729Z" }, + { url = "https://files.pythonhosted.org/packages/39/9e/04b8c3cde014ef255ee785730425268354543acc38902093a40afa0dc164/librt-0.15.0-cp311-cp311-win_arm64.whl", hash = "sha256:256237037a3ab001ae8d9803b2d43562a4c3aa38739843694349e4d5ebb0fd56", size = 111885, upload-time = "2026-08-07T10:46:58.787Z" }, + { url = "https://files.pythonhosted.org/packages/ba/39/99c25030e782bdfb7a21be8c05254806a2e4bbb05c8d50c2a2130acbfa05/librt-0.15.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e87bc679f86a99aa3b26e3c78eeb821a247c9a28eae48eaafcc32c3bf4c3bb9e", size = 151021, upload-time = "2026-08-07T10:47:00.057Z" }, + { url = "https://files.pythonhosted.org/packages/14/43/f4b1bd1b2888798a1409808889a25ea1ba49eaabce7d681ed27734c2df9d/librt-0.15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:71599e011ac880e8e45d46047d714871894c7d4ab6f25626f8d4f89da21f368d", size = 155267, upload-time = "2026-08-07T10:47:01.311Z" }, + { url = "https://files.pythonhosted.org/packages/0c/db/3ad9c965c72f1e1d6beeec44ec10a54e17be8ae042fbb4baade16cbadced/librt-0.15.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c802434092b769b1d613ed2e13fac15fbfce1934a74bd10283b03c0fae231cd1", size = 503136, upload-time = "2026-08-07T10:47:02.45Z" }, + { url = "https://files.pythonhosted.org/packages/4b/07/5888a6d76acd62ebce66c61b74d94e9370b9c32929f111e487bb6546f8ed/librt-0.15.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:5500eeae393a184d14e1f35645962c27129d20c81afa4069e6ef826ebc2b3aaa", size = 496670, upload-time = "2026-08-07T10:47:03.675Z" }, + { url = "https://files.pythonhosted.org/packages/29/39/ab57cc2f5b276156da02bb7f5a8921bada1cb1993ffec99acf811c602c23/librt-0.15.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6ecfc32dfb46fb7b565bcd6abf9412acf978775a998273d22888a6d7953730dd", size = 513688, upload-time = "2026-08-07T10:47:04.981Z" }, + { url = "https://files.pythonhosted.org/packages/a7/b9/bdbb0b648b5c2befb031f4c6f3b1dd857415e8fb492a25a3c764a6681e6c/librt-0.15.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:89cc46cfd15022e35084355478c9ac809d90b1152222706ac9a7655ec21df6fa", size = 531904, upload-time = "2026-08-07T10:47:06.211Z" }, + { url = "https://files.pythonhosted.org/packages/93/26/473c2e4b6c104e9e58e27ce95fc8005c8bd4fc36cae4f254371125a92db8/librt-0.15.0-cp312-cp312-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d5f51401d102c885b9ca509e62c79b1dbff286e1b9b047fde6f763780789356d", size = 524427, upload-time = "2026-08-07T10:47:07.592Z" }, + { url = "https://files.pythonhosted.org/packages/26/60/03b3abb82b41714671b907bf6989b228e31e6a8af52dec82b5b0728dc250/librt-0.15.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:cc30523e3f1a23fb7511cc659834a0d01a1042bb9de359bc1c131cc4ec6c9656", size = 543155, upload-time = "2026-08-07T10:47:08.866Z" }, + { url = "https://files.pythonhosted.org/packages/f2/0e/9bb1f0a4affbd0a1888f4f79dc03ed2a299d9a2c26c59ab2a97dcbf11903/librt-0.15.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:59fe030d8ae4a57e3fb7756bf35a858de74e04066fc8555c53d0af979132af81", size = 546890, upload-time = "2026-08-07T10:47:10.327Z" }, + { url = "https://files.pythonhosted.org/packages/dc/84/6937a280d461f7de6e031ffb02edc2b7c3c90d49d630565ce8ff27cbc5f2/librt-0.15.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5a6526a2a956bbb1e4ae3568c82e650fc99119c66bb011ea60715744955a2b4d", size = 555163, upload-time = "2026-08-07T10:47:11.798Z" }, + { url = "https://files.pythonhosted.org/packages/bc/95/2a2853c1ee014bf102116e7f897a04beeaeb2461b45b79af98bdfb95f1ef/librt-0.15.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:85ea21ec6730194d67156b0e0b5430ccb1d61f8b8b907e39b37f9812b74a13f0", size = 535812, upload-time = "2026-08-07T10:47:13.279Z" }, + { url = "https://files.pythonhosted.org/packages/c9/4c/cf9601c1b4c5f09280acd5d83abdb2e68527a2be8257136eb42304218622/librt-0.15.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1e47b8ba865d7ede071a91a7163073bbaeb72541f1ef8a07d512c45c7b5007f2", size = 573688, upload-time = "2026-08-07T10:47:14.727Z" }, + { url = "https://files.pythonhosted.org/packages/47/6d/9ac7cbec46189a7625af4b5acbd25f10d827f4141b2002181848c8418923/librt-0.15.0-cp312-cp312-win32.whl", hash = "sha256:a5207ec414d1c4a2a7231b2086970dc036f94293cdf338190984958a013a42f1", size = 106138, upload-time = "2026-08-07T10:47:15.973Z" }, + { url = "https://files.pythonhosted.org/packages/38/d0/2ae99c83be86ce23f925ac1aeeedc777e97f427c4a8d190c70d0a16e9a87/librt-0.15.0-cp312-cp312-win_amd64.whl", hash = "sha256:73b30cfa976659b3917c8f6153bdb0591c6a9ec6583599fd24a689b690622022", size = 126974, upload-time = "2026-08-07T10:47:17.049Z" }, + { url = "https://files.pythonhosted.org/packages/5d/ef/dd24f9635c730b86b87587967dda7516b1845e8b17684603d31607fed598/librt-0.15.0-cp312-cp312-win_arm64.whl", hash = "sha256:a54cf9e0ef47b96af580849db5471142200568ce1e02cbf416addab551369570", size = 112292, upload-time = "2026-08-07T10:47:18.222Z" }, + { url = "https://files.pythonhosted.org/packages/e7/42/467b53a601b406ccd7b97c1fd54b59cb34f9185ad5ce7e9d5c3c4e8961c8/librt-0.15.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:db13ca398005abcbe538deda87b686d9bd08b7001cf40c4c06b444960ae10a26", size = 151029, upload-time = "2026-08-07T10:47:19.312Z" }, + { url = "https://files.pythonhosted.org/packages/3e/e6/36c2299b7a94b84fdd01220d8a777a71be5be0925bb0dbdf71c0a06a34d9/librt-0.15.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:aa1f1995789dca3698bc550aaceb09a51bd5df0a057ff84ff15296cd1975b801", size = 155194, upload-time = "2026-08-07T10:47:20.398Z" }, + { url = "https://files.pythonhosted.org/packages/c9/b6/ed5071f9325845e670bd36012757419767fbf56af77ed483077b9e4db541/librt-0.15.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:55456ea87d8df21808446d03817be2f65e20391c1c615d9187440dff28cd08dc", size = 502568, upload-time = "2026-08-07T10:47:21.652Z" }, + { url = "https://files.pythonhosted.org/packages/7f/81/6450c67c3615d87704bcbc21323fafc69c799b06a044c447529f725d4b01/librt-0.15.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:5a86a5a08c2235316bdb359d5dbb6ce0abfca7fac06363103e2c5af571d92f95", size = 496153, upload-time = "2026-08-07T10:47:22.925Z" }, + { url = "https://files.pythonhosted.org/packages/e1/d6/5f52b722bc75076954b3bfd49be15ea362df4d580c6fb315d0f617100d30/librt-0.15.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e56b6a368529bed262da40ce13f8fef590db0479819cca84f16a1f01ac356d0b", size = 513336, upload-time = "2026-08-07T10:47:24.213Z" }, + { url = "https://files.pythonhosted.org/packages/8d/e2/c08fd1d36ce63ea5a12b85c5d37f4550b5f86a692167e41e5a74222607ae/librt-0.15.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:234d8d394721fa0d786af15ebf1f3fb7f3ed82fd1cd0cde45c2f247b5d4281d2", size = 531661, upload-time = "2026-08-07T10:47:25.507Z" }, + { url = "https://files.pythonhosted.org/packages/3f/d8/d9482fcbeb177b9eb87bb3899eeb3b42be690313c652f9e146b1d0681fb2/librt-0.15.0-cp313-cp313-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d8363d7accb0286ac3a0e633f396e93800dafb8150494505daf9515bbda591f3", size = 524487, upload-time = "2026-08-07T10:47:26.79Z" }, + { url = "https://files.pythonhosted.org/packages/10/cc/075171517b41f861753034fbb151b42cfc83bcc853849f24f5e66fd60ccf/librt-0.15.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0f0ee3644d951f31055ad07d77d92520e84505dd7a432cc4cd501dd70ee06785", size = 543201, upload-time = "2026-08-07T10:47:27.999Z" }, + { url = "https://files.pythonhosted.org/packages/b0/03/42c2330f37eeb475b6affeedd06518f60035f323af3a839335e3fc9fef2d/librt-0.15.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2cfd1a81a648806e6a7717be4cc4d1bb392fa229752bf8444ba365e381e984d6", size = 546467, upload-time = "2026-08-07T10:47:29.396Z" }, + { url = "https://files.pythonhosted.org/packages/57/1e/1ad4c5638f7e64d8560328bd25c54b409a661bdb6ff254b38ff90744288d/librt-0.15.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a6cd22c9da0d866558e46a041f1cc0c2bbb26b61b137b2347fa834c332e1d101", size = 555139, upload-time = "2026-08-07T10:47:30.815Z" }, + { url = "https://files.pythonhosted.org/packages/49/41/39fa7d15db1204cd1cbe6514680fbdc243adf754a0885061308f43afc013/librt-0.15.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:6d5225ef8801e4ea5e482fa9b5dfb891dd9ef6f6d870f1f25d449ca2c70ac218", size = 536050, upload-time = "2026-08-07T10:47:32.222Z" }, + { url = "https://files.pythonhosted.org/packages/1e/88/c6dcf0dd8e26dc0c9a499a2abab8646c86dcaf9ecea9524cb46d3686331a/librt-0.15.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d28a05796b99f749bf8794f17ba9ba1612d0076b802e9cfc62c554634e9ce3b", size = 573700, upload-time = "2026-08-07T10:47:33.527Z" }, + { url = "https://files.pythonhosted.org/packages/1b/9b/ab54c71a7918a7c34fa5327fb61390a77446a07a146fbfb1165250a61035/librt-0.15.0-cp313-cp313-pyemscripten_2025_0_wasm32.whl", hash = "sha256:2067ff438048cead9d223ca5675bae2a25e520a7c3e6c1498bf9c6892d22caab", size = 82194, upload-time = "2026-08-07T10:47:34.835Z" }, + { url = "https://files.pythonhosted.org/packages/8d/b2/4f9a243bb892395f3becb80789ade13771701091f9f07ab8230247953ba8/librt-0.15.0-cp313-cp313-win32.whl", hash = "sha256:1cd3b721f24c206398b9e26da3c3a9c011e6e89d06f318ba8ebefc30f1003890", size = 106231, upload-time = "2026-08-07T10:47:36.251Z" }, + { url = "https://files.pythonhosted.org/packages/bf/af/64aff4885a40b93132382f2c314647d722574605416504379184ef3045ea/librt-0.15.0-cp313-cp313-win_amd64.whl", hash = "sha256:f395a4a9a03ac062dbe9a9f82e0c720502e590a38feee6a757bc82e9c63afbd8", size = 126996, upload-time = "2026-08-07T10:47:37.453Z" }, + { url = "https://files.pythonhosted.org/packages/27/83/335bccf6c7cb9028cb0b54aead27d9ece3f01f83bc6baa2abace5da655c1/librt-0.15.0-cp313-cp313-win_arm64.whl", hash = "sha256:0a15cb554761247d84a3ec0cbdf4078d70725384f0e4662c0fa3b26266eb60ad", size = 112188, upload-time = "2026-08-07T10:47:38.729Z" }, + { url = "https://files.pythonhosted.org/packages/a8/93/949053fb462eecc4a9a5ee770a81f4b40be7b79538b245545d4aebc6b58b/librt-0.15.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:f5de7feedc56337a088eb15cd9fafa9938367362221d8cc62c642b7f94821993", size = 149833, upload-time = "2026-08-07T10:47:39.86Z" }, + { url = "https://files.pythonhosted.org/packages/61/ca/8281aa6cd560a3420e4497729f6b704b53be3eeaaef82d5aeadddaf7441f/librt-0.15.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:6c0eb900c0e91f4aebe680845242e614f1864edfd44106380d0752ac29522bf8", size = 154088, upload-time = "2026-08-07T10:47:41.065Z" }, + { url = "https://files.pythonhosted.org/packages/dd/02/1a1662dceaba6a086360891448d5ce9a7d3555976cae59a31a39d744b9c7/librt-0.15.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e8c9a650a188e38bac005048cbe6342e81407782944d01934540ab75e417df21", size = 494215, upload-time = "2026-08-07T10:47:42.388Z" }, + { url = "https://files.pythonhosted.org/packages/69/84/99211619dc656370a3740c33d2b0b6d5a3fb1e73689314f6ed477a397dc4/librt-0.15.0-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:92bfed8deec93df30286b9fe9e3b1dd17329cc076a192b4ee5ec223841d54953", size = 491173, upload-time = "2026-08-07T10:47:43.683Z" }, + { url = "https://files.pythonhosted.org/packages/d4/aa/5448d0b05f4579b635d3899176817ebf561af0e57bacd425b5b1887264c1/librt-0.15.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ec4b19788f835711a2072f9dbe6b03b3bf32ed1f0fb30cf399bdd59d9f0c33fa", size = 505512, upload-time = "2026-08-07T10:47:45.314Z" }, + { url = "https://files.pythonhosted.org/packages/95/82/01940e40b83c43a546c4a3c896cf34ca272a9690899d55914e4827b3dcce/librt-0.15.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d4c7bacb70930f3d0a56f4ecf1be474a1f0d941b01dd73b756f3c256d42cb879", size = 523073, upload-time = "2026-08-07T10:47:46.66Z" }, + { url = "https://files.pythonhosted.org/packages/88/fa/759c0030f3ee371439eb26de34fc745807caf0abb878af7af4b8b7c3dd3d/librt-0.15.0-cp314-cp314-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3e79f05e4a08b4d880342673312bbc895b56df7765605796f15902eb5367d3ae", size = 515080, upload-time = "2026-08-07T10:47:48.319Z" }, + { url = "https://files.pythonhosted.org/packages/0b/27/894e072228fcb159703c655da69f8cd10dbed489c36e3df7dd032a2483be/librt-0.15.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a417149c0cba4d50b61e992e5a15e69eaf96746609b461cc4ed168aeef6b79dd", size = 534164, upload-time = "2026-08-07T10:47:49.875Z" }, + { url = "https://files.pythonhosted.org/packages/98/a3/0078e91c1f36f8815db17827de15650b9a3fe56c55fbf998c854b34e40d3/librt-0.15.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:da7a94d6a3411f579d72aa3e3bc5fbca7ed4549f3dbd7e5de3aa567333374285", size = 540616, upload-time = "2026-08-07T10:47:51.408Z" }, + { url = "https://files.pythonhosted.org/packages/86/33/81a29b796dd52a45e9ef7974c7732926e8f10f15b8d2be505665979f896d/librt-0.15.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:856f743ae607f2c1380eccb566c0038a9fb3eabf0fc2be2704d76d9f73557239", size = 545890, upload-time = "2026-08-07T10:47:52.818Z" }, + { url = "https://files.pythonhosted.org/packages/05/82/8be1baa1350e5d30cfd70ae79d0a6f4dc5862ef47f7bb2808aabc9bb86e5/librt-0.15.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:779a6e7c894737e5983e7790a9c78c4000c30e23c9aada08081bdbea53b0fa60", size = 523287, upload-time = "2026-08-07T10:47:54.165Z" }, + { url = "https://files.pythonhosted.org/packages/c6/4f/d1be6a01a35c20ef734e0e44113f87d4af756a9354a89dcfbe3b4f8af5e1/librt-0.15.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:96bb17dbe8bab3c0954fbebfc69ed395599de75b6bbc35e3270a878e15d4dd65", size = 565868, upload-time = "2026-08-07T10:47:55.566Z" }, + { url = "https://files.pythonhosted.org/packages/67/88/649cfa33f5825927b160610f670bdab012a64d627eddb94fa795ea4292fd/librt-0.15.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl", hash = "sha256:7220697efaa6e5348fc3d18ee7f8563d4bfecd9872b37ffb915bfc1d08840622", size = 81619, upload-time = "2026-08-07T10:47:56.886Z" }, + { url = "https://files.pythonhosted.org/packages/22/31/8e88a8d5e48fc8d1a817787fb6811dfff6499acd6c8683dd83934aa6ede0/librt-0.15.0-cp314-cp314-win32.whl", hash = "sha256:f54598964d357b1c5ab77cf5d92f21e598fe0e23cdbe9618480807f81b4eba15", size = 100138, upload-time = "2026-08-07T10:47:58.093Z" }, + { url = "https://files.pythonhosted.org/packages/80/92/20fd6c4b6a1b1a564b076d55cd3d427d8428217d7638dc25a654cc4791d4/librt-0.15.0-cp314-cp314-win_amd64.whl", hash = "sha256:3ff5893a2c23d886aa9ce786de5ac6ddc74aeeaf90743682b74d920e117d2e28", size = 121258, upload-time = "2026-08-07T10:47:59.564Z" }, + { url = "https://files.pythonhosted.org/packages/fc/28/6af430b44d9ebb897b865a3c363b6dcace51357be2347cc0f8f869656a86/librt-0.15.0-cp314-cp314-win_arm64.whl", hash = "sha256:3722a099730704c9a3d70c879fc0f51daec25fe5f1555672d97bc595abeafb95", size = 106467, upload-time = "2026-08-07T10:48:01.097Z" }, + { url = "https://files.pythonhosted.org/packages/7e/aa/b42bb798942ced219f6d63b27e07f91237887a8d0bd0921666db79a13790/librt-0.15.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:38c0c7d4b6fc06c3324b3f9162c8391bfc4fd9dde53afe1033ce7edb48d5a714", size = 159523, upload-time = "2026-08-07T10:48:02.442Z" }, + { url = "https://files.pythonhosted.org/packages/75/03/1b53cd4ef904e73b1d828a5f90143bf94a2967d7cfff0b9ccf93e12aa9b4/librt-0.15.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:8b2fdd7ead3c995c37940a790690660d0ca006c302db26cc51933f6766866fc3", size = 161638, upload-time = "2026-08-07T10:48:03.725Z" }, + { url = "https://files.pythonhosted.org/packages/ac/c4/9f9c9fba097d49e9e694c2b4dc331df31884645ecbc58a93b4b5fc69d2c5/librt-0.15.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2fde98cf1fc4bac144ce23c2c4c017b924ba714509ea9334977b0b27050c837d", size = 701795, upload-time = "2026-08-07T10:48:05.135Z" }, + { url = "https://files.pythonhosted.org/packages/4c/05/0966840bda0380c8ae167b9043c6230202941cc90ea29c48e096964c765e/librt-0.15.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:e3b461183c5fa7681b48560f91515f53a953122fb30c71e07abc67d7ddf58c38", size = 682147, upload-time = "2026-08-07T10:48:06.555Z" }, + { url = "https://files.pythonhosted.org/packages/18/af/1c47ca573c30ea47d195aec26133af522fea1104afaace028d7b32247ea8/librt-0.15.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4bbcc257e3babea20a91715c361b24554ec4e8f51aa578568afc230799fe1a19", size = 696397, upload-time = "2026-08-07T10:48:08.03Z" }, + { url = "https://files.pythonhosted.org/packages/2e/0f/1aed6223d4f9f9d1171a8596ff100ea4c3f7699fea7a4ba657c3e60daa6c/librt-0.15.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b845b8d48088fad0cadc84be4b8fda63203be7e9237b71015b3925443c1f35ab", size = 722542, upload-time = "2026-08-07T10:48:09.569Z" }, + { url = "https://files.pythonhosted.org/packages/c6/22/9e3a929aea456c97d69e6ef3884efea56d4807f97399471cc946baebd8af/librt-0.15.0-cp314-cp314t-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b30e600e8f337b9bd7f39b86d9fdfedc73cc46e3d0f745931a23a234220bb7e2", size = 729709, upload-time = "2026-08-07T10:48:11.129Z" }, + { url = "https://files.pythonhosted.org/packages/e9/1b/c327ef6018e3a9ca0b8e7c5eddeeb331ba8f9b76c24e126d37d0f6d62faf/librt-0.15.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:64b0c8c35aa4c4ed79896359f3e0b285cbe4e610042106500da4811c322cc108", size = 752891, upload-time = "2026-08-07T10:48:12.558Z" }, + { url = "https://files.pythonhosted.org/packages/d7/d1/d5f1ea02c56930087009e39db9b70660a663e76c730b27b925d786718457/librt-0.15.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:0da0d94cb802f32a0524653e7201f2cef72d5f700a5407678f5290483d4fcd08", size = 745301, upload-time = "2026-08-07T10:48:14.55Z" }, + { url = "https://files.pythonhosted.org/packages/d9/3c/5f7c585d15ebb2250c73e7c0ee4e9e47be72c65d520c07ddbcdc62037674/librt-0.15.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:4a6369168d371207339b1e50d4532b06a7121586141f82599505a3f315751d47", size = 747921, upload-time = "2026-08-07T10:48:16.453Z" }, + { url = "https://files.pythonhosted.org/packages/7f/52/1443a446486eba966bcbca1696b472e4f210320ec42f490a47f48fbf0fdc/librt-0.15.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:c434e072557ade9cbc642d052c89d031efe47d5c9614523619d0d74a02378e81", size = 727561, upload-time = "2026-08-07T10:48:18.089Z" }, + { url = "https://files.pythonhosted.org/packages/79/91/2270a9380f11725cf83ce1925a5e32dd1dde2be9bba597f25c10a38644e7/librt-0.15.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c7eec6a42018bc1d45763b1c162d3d2bf7c3b9a1b0ed30d3e91dcba390efefcc", size = 774417, upload-time = "2026-08-07T10:48:19.611Z" }, + { url = "https://files.pythonhosted.org/packages/9e/3b/f4b1548d4f5b99186737fe27aec238e9823e8d5d23bf4df007c030689dc5/librt-0.15.0-cp314-cp314t-win32.whl", hash = "sha256:6912fa5e635d74529ac7cdb1bdf6ca3af4453da8d1edbe0110ee1cb4ad407ebf", size = 104381, upload-time = "2026-08-07T10:48:21.048Z" }, + { url = "https://files.pythonhosted.org/packages/80/b6/134afad262def1de04c0843c376d02135f1168af43f22e09a52bd8394727/librt-0.15.0-cp314-cp314t-win_amd64.whl", hash = "sha256:8e11699ed745931c395acd3621b07062e0f840efa6935aad87a64ed0995f0915", size = 127034, upload-time = "2026-08-07T10:48:22.561Z" }, + { url = "https://files.pythonhosted.org/packages/99/5f/1b6846b20572bd699c9e9ec321a5f781845bee477df2aa2a43b28bc40119/librt-0.15.0-cp314-cp314t-win_arm64.whl", hash = "sha256:5d2a91724463bfed4f573cd7a9fdc856d2e230d0c0e5a61416a93481dccd8605", size = 110827, upload-time = "2026-08-07T10:48:23.804Z" }, + { url = "https://files.pythonhosted.org/packages/c6/44/4de9f4ddadb009a55c7758eb5736d62534a7daaf27bd71bc50e64b606b06/librt-0.15.0-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:8443e38dcfcfdbcf5add5118c623efd788d65ac2e25756d6251a54a06a4d0aca", size = 149843, upload-time = "2026-08-07T10:48:25.148Z" }, + { url = "https://files.pythonhosted.org/packages/1f/eb/5d9ab71e30119c44094e0275f38b47dd327aea0f843a080396677029d508/librt-0.15.0-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:6d15a29033c57490cfe2069097c6fc4049e4e65ffbb749be7dc453b7c4c68965", size = 154510, upload-time = "2026-08-07T10:48:26.485Z" }, + { url = "https://files.pythonhosted.org/packages/d0/9c/8505d1b8f5e8c19587bd03f7429993b3e9ce5c06819d856bfb11d919374c/librt-0.15.0-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d2c05c729b589e734c09578bf5964be48a911765484840d017bbc84f49d4c4ad", size = 497543, upload-time = "2026-08-07T10:48:28.045Z" }, + { url = "https://files.pythonhosted.org/packages/1d/9a/3a8390775cb095765aded027ac9c63e7c8ea74e731498607544c6505de0e/librt-0.15.0-cp315-cp315-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:fa60887537e1d0cd2d9982269d33a709bf54b195cd2b9364fc0a758022af5bd9", size = 480452, upload-time = "2026-08-07T10:48:29.531Z" }, + { url = "https://files.pythonhosted.org/packages/e7/40/258a4a7117ee915d66de5cd9b8ade65a440993161107ce3a686f1859955c/librt-0.15.0-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d8bc24219b24c0af375718942ab75e3544b2763085f40f965be4326734ae8328", size = 507768, upload-time = "2026-08-07T10:48:31.007Z" }, + { url = "https://files.pythonhosted.org/packages/6b/c6/2f4dd296c97a0b85b98894519b279408ec9dd602d4f692b1ea0e25dee670/librt-0.15.0-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:86a21a7bd3fe3a419512ef424cc1c020f6771d0b29cfddff36d1635a855e63f0", size = 525122, upload-time = "2026-08-07T10:48:32.7Z" }, + { url = "https://files.pythonhosted.org/packages/49/dd/29eab42be13b2bf0ea8cb227135a45d44693e30a7e8b92871981ff56b82b/librt-0.15.0-cp315-cp315-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:dbab647e88d90b3167b91efe7091e248653688ed4337e4f90907a722c7361bb9", size = 520371, upload-time = "2026-08-07T10:48:34.294Z" }, + { url = "https://files.pythonhosted.org/packages/91/ed/4bad71adeca8fe208b775c2a35417fa5a2584c8f4791daaf89a89450fea1/librt-0.15.0-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:d8edcf6f550e918dca779c069b9e156385c60b406f99fc7641f32c52f7193659", size = 537258, upload-time = "2026-08-07T10:48:35.88Z" }, + { url = "https://files.pythonhosted.org/packages/4c/63/59dba6143fdcc7240c54458b629f3250000a61b8945890fc9efd451b19c5/librt-0.15.0-cp315-cp315-musllinux_1_2_i686.whl", hash = "sha256:8b62076030baa2d8b1501a46bf0e19c27a489aa90671c55665bff7887f7660b0", size = 527432, upload-time = "2026-08-07T10:48:37.466Z" }, + { url = "https://files.pythonhosted.org/packages/ec/21/21a24c6a2327d8362580efebe77286bf47b0f4062ec5ea41766e609d3c7d/librt-0.15.0-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:d00d20d1818e82a07a0ee0aa89a98b17ed7916b92441090b683719cb20a59b6d", size = 548108, upload-time = "2026-08-07T10:48:39.384Z" }, + { url = "https://files.pythonhosted.org/packages/5a/6d/fc68c89a7971418b41f9a873623ff935cb864097544c6a2f8ce491c8ef5d/librt-0.15.0-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:4e6ee93fc3cf848dcbf0cce2eca73d8e7dcd0cc2b6df3a529d57750b30a4c55c", size = 529681, upload-time = "2026-08-07T10:48:41.392Z" }, + { url = "https://files.pythonhosted.org/packages/65/7e/c2d98766124400d722063a630b0fde38a9fc768705d37eecca15c47dc192/librt-0.15.0-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:32896a0af72508ea979e0acb4e4c04cbeeae04938167950d535c83c45597167d", size = 567736, upload-time = "2026-08-07T10:48:43.124Z" }, + { url = "https://files.pythonhosted.org/packages/55/6c/f8c34a95e3a515c6e1c192b89511e7253c89a7760c6b500d57ffdb8d2dc8/librt-0.15.0-cp315-cp315-pyemscripten_2026_5_wasm32.whl", hash = "sha256:ec3ba415afaf951f6951b1dd16d3c8e4f540065fc382d7e70b823a79567ca374", size = 81673, upload-time = "2026-08-07T10:48:44.645Z" }, + { url = "https://files.pythonhosted.org/packages/c9/9e/e23fa8e78679ec45728188650b39e8ff476c83b691c96f749217df3b1b7c/librt-0.15.0-cp315-cp315-win32.whl", hash = "sha256:d2813ba2503764f0450680c533d13df7cff9b49df1411062eded5f67db4195b9", size = 100081, upload-time = "2026-08-07T10:48:46.171Z" }, + { url = "https://files.pythonhosted.org/packages/e1/dc/3eb4c5e297343f0620a55532cd7c8d764d3001fa2159212dadf480464827/librt-0.15.0-cp315-cp315-win_amd64.whl", hash = "sha256:b87d67e33afaf265262f2a66db578284b88ee2e6fcd224579cb5c15518677ad8", size = 121228, upload-time = "2026-08-07T10:48:47.631Z" }, + { url = "https://files.pythonhosted.org/packages/97/70/43abce19f04e49762f8ec834c8fafee13cc40fd6b94a72a24e534febfcd0/librt-0.15.0-cp315-cp315-win_arm64.whl", hash = "sha256:713bd7df21170b982e729e46870f31d6b437bd1a9b4648cffb529bd3c2ec5c4b", size = 106487, upload-time = "2026-08-07T10:48:49.095Z" }, + { url = "https://files.pythonhosted.org/packages/de/15/83f2deddb9368b8951ec8c9477269b5b9b8bd9bbf15e57402d0f38817dca/librt-0.15.0-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:3de789c82752730f94782a5ee518baf9c05edf85733aeaf73bb6e518755cdf54", size = 159448, upload-time = "2026-08-07T10:48:50.649Z" }, + { url = "https://files.pythonhosted.org/packages/06/bf/043097353f9b3c73b583d07f6b8e552795463f4bfc8caf85e42eee50c26a/librt-0.15.0-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:e0b5deec9a8664eb722c797241970fd4aa1894d25fda36a1ddac0f7407606bd6", size = 161686, upload-time = "2026-08-07T10:48:52.174Z" }, + { url = "https://files.pythonhosted.org/packages/f4/2a/8ae77f9719d42ce71cd708560a3557b38ac3c17a0383e57f87084de45bbe/librt-0.15.0-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5563302a8359bc2295bb7084d1a8ed1519df96afb30eb2aa4e0bff7b54228988", size = 710668, upload-time = "2026-08-07T10:48:53.782Z" }, + { url = "https://files.pythonhosted.org/packages/61/34/c0436ea134deb9a0d6da80a396a2739a81cb31e0418f7227239e23140898/librt-0.15.0-cp315-cp315t-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:22d6263b9d39d7bbb286fa791945646e3218f1be2d693e36fb630f1d0e59cd13", size = 679396, upload-time = "2026-08-07T10:48:55.645Z" }, + { url = "https://files.pythonhosted.org/packages/4a/9f/001e0d99aa9250d5cd5715a9081291a20656083459f9019cda15255329e1/librt-0.15.0-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:39ffd14646190c454f0d86e0d256b33f00a87a26ab410e619773b841d0e41416", size = 704313, upload-time = "2026-08-07T10:48:57.46Z" }, + { url = "https://files.pythonhosted.org/packages/2d/53/b34fa9d0ff00f136f4d58ebb4c411ff634baed1eb412bb602a2bc8dcafcb/librt-0.15.0-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c47318cd3a61401452de11282242937e3e057c4fd3dbaf601e269d0928a06c0a", size = 729847, upload-time = "2026-08-07T10:48:59.231Z" }, + { url = "https://files.pythonhosted.org/packages/86/ac/fa4d7a424665040e95baf480a6d523446057684b6758624c85338e8a23b2/librt-0.15.0-cp315-cp315t-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a56a1d4f859a82ca5b99fc4b82c9b027b15e3c455c5cd99e7d0719f27bb20b6c", size = 742736, upload-time = "2026-08-07T10:49:01.151Z" }, + { url = "https://files.pythonhosted.org/packages/8a/f1/e17a9bb5de6fb8c3186ed1a7d68d21618b027ac2d3633e03d3b6109c67ae/librt-0.15.0-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:077471b3182db4e17c36ae91555f36a4d2c00080b267f749bcad34a478a9a302", size = 763454, upload-time = "2026-08-07T10:49:03.039Z" }, + { url = "https://files.pythonhosted.org/packages/1d/ec/ecd02cd30935b931b9cdbfed6ab5a099c51b280b4e7baa274da80978ed27/librt-0.15.0-cp315-cp315t-musllinux_1_2_i686.whl", hash = "sha256:411ca4d1b905b860ceba7570dd6717a71dedaddcc4b0f77ece710aa41ee11f8d", size = 743296, upload-time = "2026-08-07T10:49:04.941Z" }, + { url = "https://files.pythonhosted.org/packages/e6/b5/b3c2b8353ce820a4854f78d19321344242f89fa71c975b71132ba9bf242a/librt-0.15.0-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:1256589e0b0adb31751d685a68bce29d73407ddf4ef05d4188f49d5dcf9566d9", size = 756217, upload-time = "2026-08-07T10:49:06.825Z" }, + { url = "https://files.pythonhosted.org/packages/3c/52/6cc22542ba59146b05cca2a656f9ff8bb67e38e63d12c3b0cc183d837bf1/librt-0.15.0-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:f42b74a53e5f26a0ba0007411a7455b66c67ce4022a39cc1f56fc4efd65bcbab", size = 741934, upload-time = "2026-08-07T10:49:08.839Z" }, + { url = "https://files.pythonhosted.org/packages/40/32/a04b72b1aa86e3be23b2ecff8c1aad2dcc955bd3956d6d26e7e34267e57a/librt-0.15.0-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:291bf73caf78b9e88d6fae9bfd693207ff7d832e2fdbe2cf8e746bc13f5f892b", size = 783763, upload-time = "2026-08-07T10:49:10.661Z" }, + { url = "https://files.pythonhosted.org/packages/6c/f0/89eb11dffbe9279ff37144dec786927314502ae0b114f1449dc78c458aab/librt-0.15.0-cp315-cp315t-win32.whl", hash = "sha256:c16d15ee371643ab48dc8248a3e680ebbeca573a13af2c3dd0c985b142d77162", size = 104313, upload-time = "2026-08-07T10:49:12.305Z" }, + { url = "https://files.pythonhosted.org/packages/6d/4a/1f1978c200f563beda63c36adff2d65bbecb81e365e8e69e572f5f70fbc6/librt-0.15.0-cp315-cp315t-win_amd64.whl", hash = "sha256:dbd605739f228912dc49027cb764456b9757750bdc2b6b7773164db7096c6fd1", size = 126889, upload-time = "2026-08-07T10:49:13.881Z" }, + { url = "https://files.pythonhosted.org/packages/38/a6/800800bfed7b1fb10fc3f3d557785c3854e80d3f7a9800d784b176a1fc2d/librt-0.15.0-cp315-cp315t-win_arm64.whl", hash = "sha256:84d244b00604d17df3fc7736c327892d6bba66181254aa4087be807b6c342bdc", size = 110700, upload-time = "2026-08-07T10:49:15.499Z" }, +] + +[[package]] +name = "llvmlite" +version = "0.49.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/27/72ae94ea5c8f7349ec1c229d4cd058feb799cbd0833ad6d1b47c919b37b7/llvmlite-0.49.0.tar.gz", hash = "sha256:00f16db782f4a13c78c5804aedc434e46794a77e89999a168f9401106270e50a", size = 194467, upload-time = "2026-08-11T16:26:00.489Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/0d/daceb212c44cad1115b2d05dd55beafe23ff06627344adb4ded0c661bb1a/llvmlite-0.49.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:ee81e96c15a6f870918f1eb60c913551c16aa23defb4f5f1acfa660d6a0aaac2", size = 40479229, upload-time = "2026-08-11T16:22:56.104Z" }, + { url = "https://files.pythonhosted.org/packages/72/2c/eb42378b4f3afc71f9fe172d01f30135dc1d54c7fd95cf76d5445d6f7809/llvmlite-0.49.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:854941c2267fd4fc5b2ce02b8af8ecdffa79fb7784591d3a89370322039ea09f", size = 59890659, upload-time = "2026-08-11T16:23:03.359Z" }, + { url = "https://files.pythonhosted.org/packages/4f/dc/fe880ac1eb93c09b6c9a0539ad18c98778386978a0e20a13a55788044ad2/llvmlite-0.49.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:da7b64474ac15ca595efa2644d5c6836638ccf70709fad3aba3fc56a55966928", size = 58344482, upload-time = "2026-08-11T16:23:12.122Z" }, + { url = "https://files.pythonhosted.org/packages/59/f6/5c18be29145cfca1d9e859e55a3c586a8c5a821825017b04c7999cd166c9/llvmlite-0.49.0-cp310-cp310-win_amd64.whl", hash = "sha256:b352c14353330c879e339b8f8d7491d565fe94242697714a24e80bd757202384", size = 41865252, upload-time = "2026-08-11T16:23:20.532Z" }, + { url = "https://files.pythonhosted.org/packages/9f/d0/ab52de2328e97ca96cdf0331a5f774796bddc420a51768f4501193f80cbb/llvmlite-0.49.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:4b0e710880b7cc910392bd6b9f1bbf468fed99b182e4420d51598f36114b3dce", size = 40479230, upload-time = "2026-08-11T16:23:28.744Z" }, + { url = "https://files.pythonhosted.org/packages/1f/80/0989432d12b7c86a6f5f380eb92eca7de779af9b34dedbd311b694d7da8d/llvmlite-0.49.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a8c0fc9d624bdc30a3d2db11eb2fb98f80fb209d20b37604eda516cd9b699cf4", size = 59890659, upload-time = "2026-08-11T16:23:37.346Z" }, + { url = "https://files.pythonhosted.org/packages/58/e9/76859ca36aaa460b6ae0508e01637f0e9bdb9b59faaa4637ade3b94bbcca/llvmlite-0.49.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:20496a5c9fdb8179fb9300e7d19f6782555d98aeeb4a322264aa7fd99f980618", size = 58344482, upload-time = "2026-08-11T16:23:44.199Z" }, + { url = "https://files.pythonhosted.org/packages/7d/49/47cd23e05d52d117b6119871ec299adedc9d8d332a2296964d9b2adc06d9/llvmlite-0.49.0-cp311-cp311-win_amd64.whl", hash = "sha256:6a5b06c1b5fc4ae4c9b169b065f42b719448ef1f873687ef224ef69969b75ec3", size = 41865253, upload-time = "2026-08-11T16:23:50.198Z" }, + { url = "https://files.pythonhosted.org/packages/6b/ae/3f699ebe3590e15e023a6372dd147526fd8ec398aacf9ceb844e854964a8/llvmlite-0.49.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:b541c8fac3450db7574d1f53cf9dff83f285bfed9d69bf81fe71fc2a7d4f97fe", size = 40479231, upload-time = "2026-08-11T16:23:56.773Z" }, + { url = "https://files.pythonhosted.org/packages/be/3c/e97f69c62a2d972066d9a2612ce1f3de313035ac897a5b9f787cad8b55f7/llvmlite-0.49.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6acba646d88abbc87d5c113a3d62c1fbf8b8fee11c6493f516803e30f21ae870", size = 59890658, upload-time = "2026-08-11T16:24:05.451Z" }, + { url = "https://files.pythonhosted.org/packages/69/e6/e942ee08605fc0526ff3854260c384d8315a5830e16c4c2a5aebc14dc9bf/llvmlite-0.49.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4ec8ad805e7515cb8440a690eb3cef4d34acb29eef80b705ec4e1c1ad3c43c68", size = 58344481, upload-time = "2026-08-11T16:24:13.503Z" }, + { url = "https://files.pythonhosted.org/packages/84/49/2a44871cac6b5a2fd4aabd68cfdaf6de9a5c7edb36dee5d47b77bda4b50f/llvmlite-0.49.0-cp312-cp312-win_amd64.whl", hash = "sha256:3a9c9e3af4e214acfefa4f73ebe7bc3fb35854a62b654edb3953f5ae33c08ba3", size = 41865543, upload-time = "2026-08-11T16:24:20.41Z" }, + { url = "https://files.pythonhosted.org/packages/7d/85/0b536a3c59f2636d9dd51dda832b6c1d0ffec37608429dedf128664918f1/llvmlite-0.49.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:039fa4054a06f537fb39248d4472284ca96be311a142ec09e69f95630ab469cc", size = 40479230, upload-time = "2026-08-11T16:24:27.295Z" }, + { url = "https://files.pythonhosted.org/packages/8e/1c/ca8ba47b057b793099784475499771780ec46839f2782f753a7079d23520/llvmlite-0.49.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ddc7aecd4f56397ed6e8f120ec5dcd5a1a8f0e6032ca4af413462792d4dca2e3", size = 59890659, upload-time = "2026-08-11T16:24:35.595Z" }, + { url = "https://files.pythonhosted.org/packages/de/af/9526dfdd33a923f33e29a18b8f9801ee7ee4b7397e88d28192c1024c4a75/llvmlite-0.49.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d3dee64784201b64c13a8df62c48a4f4218858faaa65889866bb29bdc243c038", size = 58344482, upload-time = "2026-08-11T16:24:45.79Z" }, + { url = "https://files.pythonhosted.org/packages/96/7f/9f5afcf6476b228d6b170408f377a0c4f91477fc1fc91f8141088b45bf46/llvmlite-0.49.0-cp313-cp313-win_amd64.whl", hash = "sha256:a1b414dc6b164738ec39dd8987cea73829057b7dd92fc6d91b52838385fc1dd2", size = 41865544, upload-time = "2026-08-11T16:24:53.962Z" }, + { url = "https://files.pythonhosted.org/packages/25/d1/16599b8c9f21802448059482eab48a9e74086dc56b901a677ba355565e64/llvmlite-0.49.0-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:80a84683d04516bb51da1bbeebddaf2c2f558809c93078a8f91807909ae331f8", size = 40479230, upload-time = "2026-08-11T16:25:01.513Z" }, + { url = "https://files.pythonhosted.org/packages/3a/61/0b23849141a4c4e7091fcd158ebb45195896974bebca3e58fee7cad4b4f4/llvmlite-0.49.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4281a0171d66d2098adce4ba706b8c550b1b10718650f682d64cde16e84e4de5", size = 59890659, upload-time = "2026-08-11T16:25:08.733Z" }, + { url = "https://files.pythonhosted.org/packages/c4/92/628692b74b31e27af9ba7e8ba651941ee4956959d5478123c453f59aad4a/llvmlite-0.49.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b095f15fb12c4d90495df5b1a3772b4732cc408398b204a787dbedd370e09c69", size = 58344479, upload-time = "2026-08-11T16:25:15.731Z" }, + { url = "https://files.pythonhosted.org/packages/96/8a/412fc273521b02cbfe0b5f8ad56cc696385f6eaeecdb9e9ae6a90111d98d/llvmlite-0.49.0-cp314-cp314-win_amd64.whl", hash = "sha256:294e2f0b70aef8f92d0ae7b203e2609f08beb39437eee73de59a21669331aae9", size = 42986588, upload-time = "2026-08-11T16:25:22.534Z" }, + { url = "https://files.pythonhosted.org/packages/fc/15/f47cf45c00c8b165ac3d268502dcb21d900e86f27fd338268a66ce922ab0/llvmlite-0.49.0-cp314-cp314-win_arm64.whl", hash = "sha256:95d1071023ed858b79f6971954fd7cc1f5dbcbab987718a4ccbe1411e47d0b81", size = 37441881, upload-time = "2026-08-11T16:25:28.324Z" }, + { url = "https://files.pythonhosted.org/packages/e8/2e/eafd488766d1c02413cba24f7b22acb9b3ccdfd8407e98d30eb16bac4e2a/llvmlite-0.49.0-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:f3f2ff0aeb17d34fcce9f79b99baac441cfd3efa41b83e233ca4530a72381f72", size = 40479230, upload-time = "2026-08-11T16:25:35.125Z" }, + { url = "https://files.pythonhosted.org/packages/98/07/a2c4f04e2111ccc274b4d5e3331398a9dcf6d6e5e55d6444b1ad9d6381cf/llvmlite-0.49.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d5555ea1d63928481cbf7fcb1d67452b216c7e5b393a4eb7aa1401e67f2a4fc4", size = 59890658, upload-time = "2026-08-11T16:25:43.294Z" }, + { url = "https://files.pythonhosted.org/packages/80/f9/7b7b50f80b4585bcd78675ff3110c256877b11df32a8cde284f851762f57/llvmlite-0.49.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e32adb84fdaae28aeb86fdb6253084ee707ee157289a2e98fe3caf48a62bee82", size = 58344482, upload-time = "2026-08-11T16:25:51.527Z" }, + { url = "https://files.pythonhosted.org/packages/d8/c6/32d68bfbf1d0c36888530ef6fd72864861af23dc546302b41033471a8c3a/llvmlite-0.49.0-cp314-cp314t-win_amd64.whl", hash = "sha256:be637e465010bc9c50f070468f7f1cf5385e92fee364d192dd5e6cea790ecba9", size = 42986602, upload-time = "2026-08-11T16:25:57.69Z" }, +] + +[[package]] +name = "markdown" +version = "3.10.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/29/6f/da4c6aea59b3001f2e8c0ec7497475aadaf3b021c10cab5b2858f0f32b26/markdown-3.10.3.tar.gz", hash = "sha256:3589362618f743188b4d955b874402bc814f4f83f544dc207719f4baa7d9c45f", size = 372596, upload-time = "2026-07-30T19:05:29.005Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/69/4a5af2bc115a9a33fefe51709749de8262be3f9ba063d1753a837cdbc49c/markdown-3.10.3-py3-none-any.whl", hash = "sha256:fa6c92a00a4a3c98b22728c64a935ae1928250ae65058a6ded814d2cc29a4cea", size = 110757, upload-time = "2026-07-30T19:05:27.883Z" }, +] + +[[package]] +name = "markupsafe" +version = "3.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e8/4b/3541d44f3937ba468b75da9eebcae497dcf67adb65caa16760b0a6807ebb/markupsafe-3.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2f981d352f04553a7171b8e44369f2af4055f888dfb147d55e42d29e29e74559", size = 11631, upload-time = "2025-09-27T18:36:05.558Z" }, + { url = "https://files.pythonhosted.org/packages/98/1b/fbd8eed11021cabd9226c37342fa6ca4e8a98d8188a8d9b66740494960e4/markupsafe-3.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e1c1493fb6e50ab01d20a22826e57520f1284df32f2d8601fdd90b6304601419", size = 12057, upload-time = "2025-09-27T18:36:07.165Z" }, + { url = "https://files.pythonhosted.org/packages/40/01/e560d658dc0bb8ab762670ece35281dec7b6c1b33f5fbc09ebb57a185519/markupsafe-3.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ba88449deb3de88bd40044603fafffb7bc2b055d626a330323a9ed736661695", size = 22050, upload-time = "2025-09-27T18:36:08.005Z" }, + { url = "https://files.pythonhosted.org/packages/af/cd/ce6e848bbf2c32314c9b237839119c5a564a59725b53157c856e90937b7a/markupsafe-3.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f42d0984e947b8adf7dd6dde396e720934d12c506ce84eea8476409563607591", size = 20681, upload-time = "2025-09-27T18:36:08.881Z" }, + { url = "https://files.pythonhosted.org/packages/c9/2a/b5c12c809f1c3045c4d580b035a743d12fcde53cf685dbc44660826308da/markupsafe-3.0.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c0c0b3ade1c0b13b936d7970b1d37a57acde9199dc2aecc4c336773e1d86049c", size = 20705, upload-time = "2025-09-27T18:36:10.131Z" }, + { url = "https://files.pythonhosted.org/packages/cf/e3/9427a68c82728d0a88c50f890d0fc072a1484de2f3ac1ad0bfc1a7214fd5/markupsafe-3.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f", size = 21524, upload-time = "2025-09-27T18:36:11.324Z" }, + { url = "https://files.pythonhosted.org/packages/bc/36/23578f29e9e582a4d0278e009b38081dbe363c5e7165113fad546918a232/markupsafe-3.0.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:d2ee202e79d8ed691ceebae8e0486bd9a2cd4794cec4824e1c99b6f5009502f6", size = 20282, upload-time = "2025-09-27T18:36:12.573Z" }, + { url = "https://files.pythonhosted.org/packages/56/21/dca11354e756ebd03e036bd8ad58d6d7168c80ce1fe5e75218e4945cbab7/markupsafe-3.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:177b5253b2834fe3678cb4a5f0059808258584c559193998be2601324fdeafb1", size = 20745, upload-time = "2025-09-27T18:36:13.504Z" }, + { url = "https://files.pythonhosted.org/packages/87/99/faba9369a7ad6e4d10b6a5fbf71fa2a188fe4a593b15f0963b73859a1bbd/markupsafe-3.0.3-cp310-cp310-win32.whl", hash = "sha256:2a15a08b17dd94c53a1da0438822d70ebcd13f8c3a95abe3a9ef9f11a94830aa", size = 14571, upload-time = "2025-09-27T18:36:14.779Z" }, + { url = "https://files.pythonhosted.org/packages/d6/25/55dc3ab959917602c96985cb1253efaa4ff42f71194bddeb61eb7278b8be/markupsafe-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:c4ffb7ebf07cfe8931028e3e4c85f0357459a3f9f9490886198848f4fa002ec8", size = 15056, upload-time = "2025-09-27T18:36:16.125Z" }, + { url = "https://files.pythonhosted.org/packages/d0/9e/0a02226640c255d1da0b8d12e24ac2aa6734da68bff14c05dd53b94a0fc3/markupsafe-3.0.3-cp310-cp310-win_arm64.whl", hash = "sha256:e2103a929dfa2fcaf9bb4e7c091983a49c9ac3b19c9061b6d5427dd7d14d81a1", size = 13932, upload-time = "2025-09-27T18:36:17.311Z" }, + { url = "https://files.pythonhosted.org/packages/08/db/fefacb2136439fc8dd20e797950e749aa1f4997ed584c62cfb8ef7c2be0e/markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad", size = 11631, upload-time = "2025-09-27T18:36:18.185Z" }, + { url = "https://files.pythonhosted.org/packages/e1/2e/5898933336b61975ce9dc04decbc0a7f2fee78c30353c5efba7f2d6ff27a/markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a", size = 12058, upload-time = "2025-09-27T18:36:19.444Z" }, + { url = "https://files.pythonhosted.org/packages/1d/09/adf2df3699d87d1d8184038df46a9c80d78c0148492323f4693df54e17bb/markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50", size = 24287, upload-time = "2025-09-27T18:36:20.768Z" }, + { url = "https://files.pythonhosted.org/packages/30/ac/0273f6fcb5f42e314c6d8cd99effae6a5354604d461b8d392b5ec9530a54/markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf", size = 22940, upload-time = "2025-09-27T18:36:22.249Z" }, + { url = "https://files.pythonhosted.org/packages/19/ae/31c1be199ef767124c042c6c3e904da327a2f7f0cd63a0337e1eca2967a8/markupsafe-3.0.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f", size = 21887, upload-time = "2025-09-27T18:36:23.535Z" }, + { url = "https://files.pythonhosted.org/packages/b2/76/7edcab99d5349a4532a459e1fe64f0b0467a3365056ae550d3bcf3f79e1e/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a", size = 23692, upload-time = "2025-09-27T18:36:24.823Z" }, + { url = "https://files.pythonhosted.org/packages/a4/28/6e74cdd26d7514849143d69f0bf2399f929c37dc2b31e6829fd2045b2765/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115", size = 21471, upload-time = "2025-09-27T18:36:25.95Z" }, + { url = "https://files.pythonhosted.org/packages/62/7e/a145f36a5c2945673e590850a6f8014318d5577ed7e5920a4b3448e0865d/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a", size = 22923, upload-time = "2025-09-27T18:36:27.109Z" }, + { url = "https://files.pythonhosted.org/packages/0f/62/d9c46a7f5c9adbeeeda52f5b8d802e1094e9717705a645efc71b0913a0a8/markupsafe-3.0.3-cp311-cp311-win32.whl", hash = "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19", size = 14572, upload-time = "2025-09-27T18:36:28.045Z" }, + { url = "https://files.pythonhosted.org/packages/83/8a/4414c03d3f891739326e1783338e48fb49781cc915b2e0ee052aa490d586/markupsafe-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01", size = 15077, upload-time = "2025-09-27T18:36:29.025Z" }, + { url = "https://files.pythonhosted.org/packages/35/73/893072b42e6862f319b5207adc9ae06070f095b358655f077f69a35601f0/markupsafe-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c", size = 13876, upload-time = "2025-09-27T18:36:29.954Z" }, + { url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615, upload-time = "2025-09-27T18:36:30.854Z" }, + { url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020, upload-time = "2025-09-27T18:36:31.971Z" }, + { url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332, upload-time = "2025-09-27T18:36:32.813Z" }, + { url = "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d", size = 22947, upload-time = "2025-09-27T18:36:33.86Z" }, + { url = "https://files.pythonhosted.org/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a", size = 21962, upload-time = "2025-09-27T18:36:35.099Z" }, + { url = "https://files.pythonhosted.org/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b", size = 23760, upload-time = "2025-09-27T18:36:36.001Z" }, + { url = "https://files.pythonhosted.org/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f", size = 21529, upload-time = "2025-09-27T18:36:36.906Z" }, + { url = "https://files.pythonhosted.org/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b", size = 23015, upload-time = "2025-09-27T18:36:37.868Z" }, + { url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540, upload-time = "2025-09-27T18:36:38.761Z" }, + { url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105, upload-time = "2025-09-27T18:36:39.701Z" }, + { url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906, upload-time = "2025-09-27T18:36:40.689Z" }, + { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, + { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, + { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, + { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, + { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, + { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, + { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, + { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, + { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, + { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, + { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, + { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, + { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, + { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, + { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, + { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, + { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, + { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, + { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, + { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, + { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, + { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, + { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, + { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, + { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, + { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, + { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, + { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, + { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, + { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, + { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, + { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, + { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, + { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, + { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, + { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, + { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, + { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, +] + +[[package]] +name = "matplotlib" +version = "3.10.9" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.11'", +] +dependencies = [ + { name = "contourpy", version = "1.3.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "cycler", marker = "python_full_version < '3.11'" }, + { name = "fonttools", marker = "python_full_version < '3.11'" }, + { name = "kiwisolver", marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "packaging", marker = "python_full_version < '3.11'" }, + { name = "pillow", marker = "python_full_version < '3.11'" }, + { name = "pyparsing", marker = "python_full_version < '3.11'" }, + { name = "python-dateutil", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/63/1b/4be5be87d43d327a0cf4de1a56e86f7f84c89312452406cf122efe2839e6/matplotlib-3.10.9.tar.gz", hash = "sha256:fd66508e8c6877d98e586654b608a0456db8d7e8a546eb1e2600efd957302358", size = 34811233, upload-time = "2026-04-24T00:14:13.539Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/6f/340b04986e67aac6f66c5145ce68bf72c64bed30f92c8913499a6e6b8f99/matplotlib-3.10.9-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:77210dce9cb8153dffc967efaae990543392563d5a376d4dd8539bebcb0ed217", size = 8296625, upload-time = "2026-04-24T00:11:43.376Z" }, + { url = "https://files.pythonhosted.org/packages/bb/2f/127081eb83162053ebb9678ceac64220b93a663e0167432566e9c7c82aab/matplotlib-3.10.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1e7698ac9868428e84d2c967424803b2472ff7167d9d6590d4204ed775343c3b", size = 8188790, upload-time = "2026-04-24T00:11:46.556Z" }, + { url = "https://files.pythonhosted.org/packages/fc/b7/d8bcec2626c35f96972bff656299fef4578113ea6193c8fdad324710410c/matplotlib-3.10.9-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1aa972116abb4c9d201bf245620b433726cb6856f3bef6a78f776a00f5c92d37", size = 8769389, upload-time = "2026-04-24T00:11:48.959Z" }, + { url = "https://files.pythonhosted.org/packages/12/49/b78e214a527ea732033b7f4d37f7afb504d74ba9d134bd47938230dfb8b1/matplotlib-3.10.9-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ae2f11957b27ce53497dd4d7b235c4d4f1faf383dfb39d0c5beb833bff883294", size = 9589657, upload-time = "2026-04-24T00:11:51.915Z" }, + { url = "https://files.pythonhosted.org/packages/5f/15/5246f7b43beae19c74dfee651d58d6cc8112e06f77adb4e88cc04f2e3a23/matplotlib-3.10.9-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b049278ddce116aaa1c1377ebf58adea909132dfce0281cf7e3a1ea9fc2e2c65", size = 9651983, upload-time = "2026-04-24T00:11:54.766Z" }, + { url = "https://files.pythonhosted.org/packages/75/77/5acecfe672ba0fa1b8c0454f69ce155d1e6fc5852fa7206bf9afaf767121/matplotlib-3.10.9-cp310-cp310-win_amd64.whl", hash = "sha256:82834c3c292d24d3a8aae77cd2d20019de69d692a34a970e4fdb8d33e2ea3dda", size = 8199701, upload-time = "2026-04-24T00:11:58.389Z" }, + { url = "https://files.pythonhosted.org/packages/4c/8c/290f021104741fea63769c31494f5324c0cd249bf536a65a4350767b1f22/matplotlib-3.10.9-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:68cfdcede415f7c8f5577b03303dd94526cdb6d11036cecdc205e08733b2d2bb", size = 8306860, upload-time = "2026-04-24T00:12:01.207Z" }, + { url = "https://files.pythonhosted.org/packages/51/18/325cd32ece1120d1da51cc4e4294c6580190699490183fc2fe8cb6d61ec5/matplotlib-3.10.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfca0129678bd56379db26c52b5d77ed7de314c047492fbdc763aa7501710cfb", size = 8199254, upload-time = "2026-04-24T00:12:04.239Z" }, + { url = "https://files.pythonhosted.org/packages/79/db/e28c1b83e3680740aa78925f5fb2ae4d16207207419ad75ea9fe604f8676/matplotlib-3.10.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8e436d155fa8a3399dc62683f8f5d0e2e50d25d0144a73edd73f82eec8f4abfb", size = 8777092, upload-time = "2026-04-24T00:12:06.793Z" }, + { url = "https://files.pythonhosted.org/packages/55/fa/3ce7adfe9ba101748f465211660d9c6374c876b671bdb8c2bb6d347e8b94/matplotlib-3.10.9-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:56fc0bd271b00025c6edfdc7c2dcd247372c8e1544971d62e1dc7c17367e8bf9", size = 9595691, upload-time = "2026-04-24T00:12:09.706Z" }, + { url = "https://files.pythonhosted.org/packages/36/c4/6960a76686ed668f2c60f84e9799ba4c0d56abdb36b1577b60c1d061d1ec/matplotlib-3.10.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a5a6104ed666402ba5106d7f36e0e0cdca4e8d7fa4d39708ca88019e2835a2eb", size = 9659771, upload-time = "2026-04-24T00:12:12.766Z" }, + { url = "https://files.pythonhosted.org/packages/7e/0d/271aace3342157c64700c9ff4c59c7b392f3dbab393692e8db6fbe7ab96c/matplotlib-3.10.9-cp311-cp311-win_amd64.whl", hash = "sha256:d730e984eddf56974c3e72b6129c7ca462ac38dc624338f4b0b23eb23ecba00f", size = 8205112, upload-time = "2026-04-24T00:12:15.773Z" }, + { url = "https://files.pythonhosted.org/packages/e2/ee/cb57ad4754f3e7b9174ce6ce66d9205fb827067e48a9f58ac09d7e7d6b77/matplotlib-3.10.9-cp311-cp311-win_arm64.whl", hash = "sha256:51bf0ddbdc598e060d46c16b5590708f81a1624cefbaaf62f6a81bf9285b8c80", size = 8132310, upload-time = "2026-04-24T00:12:18.645Z" }, + { url = "https://files.pythonhosted.org/packages/35/c6/5581e26c72233ebb2a2a6fed2d24fb7c66b4700120b813f51b0555acf0b6/matplotlib-3.10.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f0c3c28d9fbcc1fe7a03be236d73430cf6409c41fb2383a7ac52fe932b072cb1", size = 8319908, upload-time = "2026-04-24T00:12:21.323Z" }, + { url = "https://files.pythonhosted.org/packages/b7/18/4880dd762e40cd360c1bf06e890c5a97b997e91cb324602b1a19950ad5ce/matplotlib-3.10.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:41cb28c2bd769aa3e98322c6ab09854cbcc52ab69d2759d681bba3e327b2b320", size = 8216016, upload-time = "2026-04-24T00:12:23.4Z" }, + { url = "https://files.pythonhosted.org/packages/32/91/d024616abdba99e83120e07a20658976f6a343646710760c4a51df126029/matplotlib-3.10.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ae20801130378b82d647ff5047c07316295b68dc054ca6b3c13519d0ea624285", size = 8789336, upload-time = "2026-04-24T00:12:26.096Z" }, + { url = "https://files.pythonhosted.org/packages/5c/04/030a2f61ef2158f5e4c259487a92ac877732499fb33d871585d89e03c42d/matplotlib-3.10.9-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6c63ebcd8b4b169eb2f5c200552ae6b8be8999a005b6b507ed76fb8d7d674fe2", size = 9604602, upload-time = "2026-04-24T00:12:29.052Z" }, + { url = "https://files.pythonhosted.org/packages/fc/c2/541e4d09d87bb6b5830fc28b4c887a9a8cf4e1c6cee698a8c05552ae2003/matplotlib-3.10.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d75d11c949914165976c621b2324f9ef162af7ebf4b057ddf95dd1dba7e5edcf", size = 9670966, upload-time = "2026-04-24T00:12:32.131Z" }, + { url = "https://files.pythonhosted.org/packages/04/a1/4571fc46e7702de8d0c2dc54ad1b2f8e29328dea3ee90831181f7353d93c/matplotlib-3.10.9-cp312-cp312-win_amd64.whl", hash = "sha256:d091f9d758b34aaaaa6331d13574bf01891d903b3dec59bfff458ef7551de5d6", size = 8217462, upload-time = "2026-04-24T00:12:35.226Z" }, + { url = "https://files.pythonhosted.org/packages/4b/d0/2269edb12aa30c13c8bcc9382892e39943ce1d28aab4ec296e0381798e81/matplotlib-3.10.9-cp312-cp312-win_arm64.whl", hash = "sha256:10cc5ce06d10231c36f40e875f3c7e8050362a4ee8f0ee5d29a6b3277d57bb42", size = 8136688, upload-time = "2026-04-24T00:12:37.442Z" }, + { url = "https://files.pythonhosted.org/packages/aa/d3/8d4f6afbecb49fc04e060a57c0fce39ea51cc163a6bd87303ccd698e4fa6/matplotlib-3.10.9-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b580440f1ff81a0e34122051a3dfabb7e4b7f9e380629929bde0eff9af72165f", size = 8320331, upload-time = "2026-04-24T00:12:39.688Z" }, + { url = "https://files.pythonhosted.org/packages/63/d9/9e14bc7564bf92d5ffa801ae5fac819ce74b925dfb55e3ebde61a3bbad3e/matplotlib-3.10.9-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b1b745c489cd1a77a0dc1120a05dc87af9798faebc913601feb8c73d89bf2d1e", size = 8216461, upload-time = "2026-04-24T00:12:42.494Z" }, + { url = "https://files.pythonhosted.org/packages/8a/17/4402d0d14ccf1dfc70932600b68097fbbf9c898a4871d2cbbe79c7801a32/matplotlib-3.10.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8f3bcac1ca5ed000a6f4337d47ba67dfddf37ed6a46c15fd7f014997f7bf865f", size = 8790091, upload-time = "2026-04-24T00:12:44.789Z" }, + { url = "https://files.pythonhosted.org/packages/3e/0b/322aeec06dd9b91411f92028b37d447342770a24392aa4813e317064dad5/matplotlib-3.10.9-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7a8d66a55def891c33147ba3ba9bfcabf0b526a43764c818acbb4525e5ed0838", size = 9605027, upload-time = "2026-04-24T00:12:47.583Z" }, + { url = "https://files.pythonhosted.org/packages/74/88/5f13482f55e7b00bcfc09838b093c2456e1379978d2a146844aae05350ad/matplotlib-3.10.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d843374407c4017a6403b59c6c81606773d136f3259d5b6da3131bc814542cc2", size = 9671269, upload-time = "2026-04-24T00:12:50.878Z" }, + { url = "https://files.pythonhosted.org/packages/c5/e0/0840fd2f93da988ec660b8ad1984abe9f25d2aed22a5e394ff1c68c88307/matplotlib-3.10.9-cp313-cp313-win_amd64.whl", hash = "sha256:f4399f64b3e94cd500195490972ae1ee81170df1636fa15364d157d5bdd7b921", size = 8217588, upload-time = "2026-04-24T00:12:53.784Z" }, + { url = "https://files.pythonhosted.org/packages/47/b9/d706d06dd605c49b9f83a2aed8c13e3e5db70697d7a80b7e3d7915de6b17/matplotlib-3.10.9-cp313-cp313-win_arm64.whl", hash = "sha256:ba7b3b8ef09eab7df0e86e9ae086faa433efbfbdb46afcb3aa16aabf779469a8", size = 8136913, upload-time = "2026-04-24T00:12:56.501Z" }, + { url = "https://files.pythonhosted.org/packages/9b/45/6e32d96978264c8ca8c4b1010adb955a1a49cfaf314e212bbc8908f04a61/matplotlib-3.10.9-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:09218df8a93712bd6ea133e83a153c755448cf7868316c531cffcc43f69d1cc9", size = 8368019, upload-time = "2026-04-24T00:12:58.896Z" }, + { url = "https://files.pythonhosted.org/packages/86/0a/c8e3d3bba245f0f7fc424937f8ff7ef77291a36af3edb97ccd78aa93d84f/matplotlib-3.10.9-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:82368699727bfb7b0182e1aa13082e3c08e092fa1a25d3e1fd92405bff96f6d4", size = 8264645, upload-time = "2026-04-24T00:13:01.406Z" }, + { url = "https://files.pythonhosted.org/packages/3d/aa/5bf5a14fe4fed73a4209a155606f8096ff797aad89c6c35179026571133e/matplotlib-3.10.9-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3225f4e1edcb8c86c884ddf79ebe20ecd0a67d30188f279897554ccd8fded4dc", size = 8802194, upload-time = "2026-04-24T00:13:03.702Z" }, + { url = "https://files.pythonhosted.org/packages/dd/5e/b4be852d6bba6fd15893fadf91ff26ae49cb91aac789e95dde9d342e664f/matplotlib-3.10.9-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:de2445a0c6690d21b7eb6ce071cebad6d40a2e9bdf10d039074a96ba19797b99", size = 9622684, upload-time = "2026-04-24T00:13:06.647Z" }, + { url = "https://files.pythonhosted.org/packages/4c/3d/ed428c971139112ef730f62770654d609467346d09d4b62617e1afd68a5a/matplotlib-3.10.9-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:b2b9516251cb89ff618d757daec0e2ed1bf21248013844a853d87ef85ab3081d", size = 9680790, upload-time = "2026-04-24T00:13:10.009Z" }, + { url = "https://files.pythonhosted.org/packages/e7/09/052e884aaf2b985c63cb79f715f1d5b6a3eaa7de78f6a52b9dbc077d5b53/matplotlib-3.10.9-cp313-cp313t-win_amd64.whl", hash = "sha256:e9fae004b941b23ff2edcf1567a857ed77bafc8086ffa258190462328434faf8", size = 8287571, upload-time = "2026-04-24T00:13:13.087Z" }, + { url = "https://files.pythonhosted.org/packages/f4/38/ae27288e788c35a4250491422f3db7750366fc8c97d6f36fbdecfc1f5518/matplotlib-3.10.9-cp313-cp313t-win_arm64.whl", hash = "sha256:6b63d9c7c769b88ab81e10dc86e4e0607cf56817b9f9e6cf24b2a5f1693b8e38", size = 8188292, upload-time = "2026-04-24T00:13:15.546Z" }, + { url = "https://files.pythonhosted.org/packages/d6/e6/3bd8afd04949f02eabc1c17115ea5255e19cacd4d06fc5abdde4eeb0052c/matplotlib-3.10.9-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:172db52c9e683f5d12eaf57f0f54834190e12581fe1cc2a19595a8f5acb4e77d", size = 8321276, upload-time = "2026-04-24T00:13:18.318Z" }, + { url = "https://files.pythonhosted.org/packages/41/86/86231232fff41c9f8e4a1a7d7a597d349a02527109c3af7d618366122139/matplotlib-3.10.9-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:97e35e8d39ccc85859095e01a53847432ba9a53ddf7986f7a54a11b73d0e143f", size = 8218218, upload-time = "2026-04-24T00:13:20.974Z" }, + { url = "https://files.pythonhosted.org/packages/85/8f/becc9722cafc64f5d2eb0b7c1bf5f585271c618a45dbd8fabeb021f898b6/matplotlib-3.10.9-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aba1615dabe83188e19d4f75a253c6a08423e04c1425e64039f800050a69de6b", size = 9608145, upload-time = "2026-04-24T00:13:23.228Z" }, + { url = "https://files.pythonhosted.org/packages/32/5d/f7e914f7d9325abff4057cee62c0fa70263683189f774473cbfb534cd13b/matplotlib-3.10.9-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:34cf8167e023ad956c15f36302911d5406bd99a9862c1a8499ea6f7c0e015dc2", size = 9885085, upload-time = "2026-04-24T00:13:25.849Z" }, + { url = "https://files.pythonhosted.org/packages/a5/fd/fa69f2221534e80cc5772ac2b7d222011a2acafc2ec7216d5dd174c864ae/matplotlib-3.10.9-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:59476c6d29d612b8e9bb6ce8c5b631be6ba8f9e3a2421f22a02b192c7dd28716", size = 9672358, upload-time = "2026-04-24T00:13:28.906Z" }, + { url = "https://files.pythonhosted.org/packages/ab/1a/5a4f747a8b271cbb024946d2dd3c913ab5032ba430626f8c3528ada96b4b/matplotlib-3.10.9-cp314-cp314-win_amd64.whl", hash = "sha256:336b9acc64d309063126edcdaca00db9373af3c476bb94388fe9c5a53ad13e6f", size = 8349970, upload-time = "2026-04-24T00:13:31.904Z" }, + { url = "https://files.pythonhosted.org/packages/64/dc/95d60ecaefe30680a154b52ea96ab4b0dab547f1fd6aa12f5fb655e89cae/matplotlib-3.10.9-cp314-cp314-win_arm64.whl", hash = "sha256:2dc9477819ffd78ad12a20df1d9d6a6bd4fec6aaa9072681465fddca052f1456", size = 8272785, upload-time = "2026-04-24T00:13:34.511Z" }, + { url = "https://files.pythonhosted.org/packages/70/a0/005d68bc8b8418300ce6591f18586910a8526806e2ab663933d9f20a41e9/matplotlib-3.10.9-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:da4e09638420548f31c354032a6250e473c68e5a4e96899b4844cf39ddea23fe", size = 8367999, upload-time = "2026-04-24T00:13:36.962Z" }, + { url = "https://files.pythonhosted.org/packages/22/05/1236cc9290be70b2498af20ca348add76e3fffe7f67b477db5133a84f3ea/matplotlib-3.10.9-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:345f6f68ecc8da0ca56fad2ea08fde1a115eda530079eca185d50a7bc3e146c6", size = 8264543, upload-time = "2026-04-24T00:13:39.851Z" }, + { url = "https://files.pythonhosted.org/packages/cd/c2/071f5a5ff6c5bd63aaaf2f45c811d9bf2ced94bde188d9e1a519e21d0cba/matplotlib-3.10.9-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4edcfbd8565339aa62f1cd4012f7180926fdbe71850f7b0d3c379c175cd6b66c", size = 9622800, upload-time = "2026-04-24T00:13:42.296Z" }, + { url = "https://files.pythonhosted.org/packages/95/57/da7d1f10a85624b9e7db68e069dd94e58dc41dbf9463c5921632ecbe3661/matplotlib-3.10.9-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6be157fe17fc37cb95ac1d7374cf717ce9259616edec911a78d9d26dae8522d4", size = 9888561, upload-time = "2026-04-24T00:13:45.026Z" }, + { url = "https://files.pythonhosted.org/packages/67/b2/ef8d6bb59b0edb6c16c968b70f548aa13b54348972def5aa6ac85df67145/matplotlib-3.10.9-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:4e42042d54db34fda4e95a7bd3e5789c2a995d2dad3eb8850232ee534092fbbf", size = 9680884, upload-time = "2026-04-24T00:13:48.066Z" }, + { url = "https://files.pythonhosted.org/packages/61/1c/d21bfeb9931881ebe96bcfcff27c7ae4b160ae0ec291a714c42641a56d75/matplotlib-3.10.9-cp314-cp314t-win_amd64.whl", hash = "sha256:c27df8b3848f32a83d1767566595e43cfaa4460380974da06f4279a7ec143c39", size = 8432333, upload-time = "2026-04-24T00:13:51.008Z" }, + { url = "https://files.pythonhosted.org/packages/78/23/92493c3e6e1b635ccfff146f7b99e674808787915420373ac399283764c2/matplotlib-3.10.9-cp314-cp314t-win_arm64.whl", hash = "sha256:a49f1eadc84ca85fd72fa4e89e70e61bf86452df6f971af04b12c60761a0772c", size = 8324785, upload-time = "2026-04-24T00:13:53.633Z" }, + { url = "https://files.pythonhosted.org/packages/2c/2b/0e92ad0ac446633f928a1563db4aa8add407e1924faf0ded5b95b35afb27/matplotlib-3.10.9-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:1872fb212a05b729e649754a72d5da61d03e0554d76e80303b6f83d1d2c0552b", size = 8293058, upload-time = "2026-04-24T00:13:56.339Z" }, + { url = "https://files.pythonhosted.org/packages/4b/23/74682fd369f5299ceda438fea2a0662e6383b85c9383fb9cdfcf04713e07/matplotlib-3.10.9-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:985f2238880e2e69093f588f5fe2e46771747febf0649f3cf7f7b7480875317f", size = 8186627, upload-time = "2026-04-24T00:13:58.623Z" }, + { url = "https://files.pythonhosted.org/packages/ca/e8/368aab88f3c4cd8992800f31abfe0670c3e47540ba20a97e9fdbcde594b3/matplotlib-3.10.9-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6640f75af2c6148293caa0a2b39dd806a492dd66c8a8b04035813e33d0fd2585", size = 8764117, upload-time = "2026-04-24T00:14:01.684Z" }, + { url = "https://files.pythonhosted.org/packages/63/e2/9f66ca6a651a52abfe0d4964ce01439ed34f3f1e119de10ff3a07f403043/matplotlib-3.10.9-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:42fb814efabe95c06c1994d8ab5a8385f43a249e23badd3ba931d4308e5bca20", size = 8304420, upload-time = "2026-04-24T00:14:04.57Z" }, + { url = "https://files.pythonhosted.org/packages/e8/e8/467c03568218792906aa87b5e7bb379b605e056ed0c74fe00c051786d925/matplotlib-3.10.9-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:f76e640a5268850bfda54b5131b1b1941cc685e42c5fa98ed9f2d64038308cba", size = 8197981, upload-time = "2026-04-24T00:14:07.233Z" }, + { url = "https://files.pythonhosted.org/packages/6f/87/afead29192170917537934c6aff4b008c805fff7b1ccea0c79120d96beda/matplotlib-3.10.9-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3fc0364dfbe1d07f6d15c5ebd0c5bf89e126916e5a8667dd4a7a6e84c36653d4", size = 8774002, upload-time = "2026-04-24T00:14:09.816Z" }, +] + +[[package]] +name = "matplotlib" +version = "3.11.1" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.15' and sys_platform == 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'win32'", + "python_full_version >= '3.15' and sys_platform == 'emscripten'", + "python_full_version == '3.14.*' and sys_platform == 'emscripten'", + "python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'emscripten'", + "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] +dependencies = [ + { name = "contourpy", version = "1.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "cycler", marker = "python_full_version >= '3.11'" }, + { name = "fonttools", marker = "python_full_version >= '3.11'" }, + { name = "kiwisolver", marker = "python_full_version >= '3.11'" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "numpy", version = "2.5.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "packaging", marker = "python_full_version >= '3.11'" }, + { name = "pillow", marker = "python_full_version >= '3.11'" }, + { name = "pyparsing", marker = "python_full_version >= '3.11'" }, + { name = "python-dateutil", marker = "python_full_version >= '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/49/64/f9a391af28f518b11ad45a8a712353c94a0aefce09d3703200e5c54b610a/matplotlib-3.11.1.tar.gz", hash = "sha256:69647db5746941c793d6e445a4cd349323ffb87d9cc958c2ad84a659b4832d30", size = 32612045, upload-time = "2026-07-18T03:39:46.63Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6e/d0/791aa183dd88491555cf7d4be0b52b0bcf6c3c2a2c22c815a2e819bf53e2/matplotlib-3.11.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:b7cf158e7add54a8d51ac9b5a84abd6d4e13ed4951b4f25f1c5139f41c2addb2", size = 9440302, upload-time = "2026-07-18T03:38:03.844Z" }, + { url = "https://files.pythonhosted.org/packages/35/74/82bbdf683a301f4478384c8aaba6903631a2ca18294b2d7655c9a542bffb/matplotlib-3.11.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d2ace7273b9a5061a3b420918a16fae1f2dc5dfee1abcc13aba71b5d94b1820c", size = 9268549, upload-time = "2026-07-18T03:38:06.144Z" }, + { url = "https://files.pythonhosted.org/packages/f0/f0/9b4298911303f74e6d83e64a81d996c0616405ec95046fac7f17e4258b9e/matplotlib-3.11.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aee55e9041211bf84302ab55ec3965df18dd90ae19f8b58332a7feaf208bfe83", size = 10024922, upload-time = "2026-07-18T03:38:08.236Z" }, + { url = "https://files.pythonhosted.org/packages/84/6f/0bc3c3d05b021db44c14bc379a7c0df7d57302aa15380c16fd4e63fd6a9b/matplotlib-3.11.1-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96f4bdeea33a8d15a071dbfe6d119451b1d719c733ac666d65357082901a9099", size = 10832170, upload-time = "2026-07-18T03:38:10.276Z" }, + { url = "https://files.pythonhosted.org/packages/db/4d/e375f39acdb2af5a9342730618608e39790ec842e6f1b392863028781459/matplotlib-3.11.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b4c78ceb2f11bcac7389d305cda17aeb1f4586a857854ab5780bd3dd8dbfc407", size = 10916701, upload-time = "2026-07-18T03:38:12.512Z" }, + { url = "https://files.pythonhosted.org/packages/bc/be/fa26ed085b41298f64a8f9b7592c671bbf1acc8b0df124c1c5de96b859f8/matplotlib-3.11.1-cp311-cp311-win_amd64.whl", hash = "sha256:7f33a781e12b1e53b278deb2f5373c2e55ec4f10727be3440c0cfb5cda9f944f", size = 9315331, upload-time = "2026-07-18T03:38:14.949Z" }, + { url = "https://files.pythonhosted.org/packages/b6/f3/eb5bdf3b6e191b200db298b08bbc1638b7f3c82cdc8680f9d88bf72559ae/matplotlib-3.11.1-cp311-cp311-win_arm64.whl", hash = "sha256:67e4c3cd578c65ebd81bdc09a1b6592ceafee6dfafe116dc85dfcb647b5bbb18", size = 9003475, upload-time = "2026-07-18T03:38:17.205Z" }, + { url = "https://files.pythonhosted.org/packages/f2/6c/7ef7ebcb2bd9739b2b66b18b076e077f44bb46fdbe28ca0506edb3c62c79/matplotlib-3.11.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e15ef41507f3d525f46154ac9e3ae785dacde9f20e593a25de8986267892ef74", size = 9453849, upload-time = "2026-07-18T03:38:19.593Z" }, + { url = "https://files.pythonhosted.org/packages/eb/f8/6d0c312c8d9738e7d9677f09fe5c986b3239e651a7b73a2deb38b65e4a71/matplotlib-3.11.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:21a67b961a6d597bca54fae826cd20695ba4a6e4d05424a08da6e13e3176fd6b", size = 9283113, upload-time = "2026-07-18T03:38:21.95Z" }, + { url = "https://files.pythonhosted.org/packages/c9/cf/b4ad2cc81b6672ea29ea04e64e350a9f9b493b0908ccd884c67eeff8f7b2/matplotlib-3.11.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ba8f811b8ddfac493734d6af0b2dff96919d0c28ca0d641858dab4262777c6ea", size = 10035615, upload-time = "2026-07-18T03:38:24.315Z" }, + { url = "https://files.pythonhosted.org/packages/88/90/4e10e033d9b66589d8ed98b84c95cdbb57033d57c1f41339d7393dbd2f2e/matplotlib-3.11.1-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c52f7ad20ef476806ed212380b1d54d20310c8b86bdc2c9a68b51f0024a44472", size = 10842559, upload-time = "2026-07-18T03:38:26.285Z" }, + { url = "https://files.pythonhosted.org/packages/88/eb/799612d0f8cd3e816a10fec59329fca52cd2353264df80378dfc541ae855/matplotlib-3.11.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8b14eb22961fe865efb0e4ff167e333e428908b00115a8d800ccb65ee108e481", size = 10927532, upload-time = "2026-07-18T03:38:28.532Z" }, + { url = "https://files.pythonhosted.org/packages/88/89/56649bbaa2fd12e20f3be03dbcc135b0c8676d88bac17977599e3eb442a0/matplotlib-3.11.1-cp312-cp312-win_amd64.whl", hash = "sha256:88a2a27dd9691ae448dfae4b26f59036be90c3c28757edd3553a29559d00859f", size = 9333886, upload-time = "2026-07-18T03:38:30.477Z" }, + { url = "https://files.pythonhosted.org/packages/c1/11/4d124efbbad677b7b7552f6f85a3bd432d4232f95400cea98fcd2ae36ef3/matplotlib-3.11.1-cp312-cp312-win_arm64.whl", hash = "sha256:480194afceca4df2f137c2721227d3cba67121fbf4397b69cee7f83714b0a58a", size = 9007545, upload-time = "2026-07-18T03:38:32.833Z" }, + { url = "https://files.pythonhosted.org/packages/04/6c/4798363b7fb5644e309fe1fac30216e9146c9f70859d80d588c18caf5317/matplotlib-3.11.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6771b0cd7838c6a857a7209814158c0ad09bfef878db3033dd82d70ad101f191", size = 9454341, upload-time = "2026-07-18T03:38:35.001Z" }, + { url = "https://files.pythonhosted.org/packages/59/98/6acadbe7f98df19d274bc107ac58bb439fa75df82c33dc110d71a4a8501f/matplotlib-3.11.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2abdee5ffa2fe11b2d19f7a5c63b785fb7c28cc46c7bc1814156341d9d1a33e1", size = 9283627, upload-time = "2026-07-18T03:38:37.061Z" }, + { url = "https://files.pythonhosted.org/packages/24/ea/65cec46fe241390ccea1b1754207ee28eb71c5ab866bd5f22fe47e538fa4/matplotlib-3.11.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b0a19dcf73406d3746d25a5ed42d713604c9a3e024d129b102852b0d941cb9f3", size = 10035860, upload-time = "2026-07-18T03:38:39.663Z" }, + { url = "https://files.pythonhosted.org/packages/c7/10/63fdccccbabe002fb0960876baabc5e3f24d9c1bb4cfb25651457f74b3a0/matplotlib-3.11.1-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7389b77ed2ab0552f46d9a90b81b7b8e6dfcdc42adc36c37a0865799843e0e3e", size = 10843594, upload-time = "2026-07-18T03:38:42.144Z" }, + { url = "https://files.pythonhosted.org/packages/98/51/a1155945bff7b91381875022ac1522c5dfdac0d006be8e7df389b3134eae/matplotlib-3.11.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c90be0b73568da4f662afac580956a76e308437e641b4a45aa08925eeb67d95f", size = 10927962, upload-time = "2026-07-18T03:38:44.302Z" }, + { url = "https://files.pythonhosted.org/packages/0d/3a/3d5e1f42dc761bf53401a62a83ff93389b37de9d2c093b2a3aa49ac34f1b/matplotlib-3.11.1-cp313-cp313-win_amd64.whl", hash = "sha256:68408341f2312836fbbdf6b3c78047f65b2d8752f5fd221c3e72d348f5b34f8b", size = 9334074, upload-time = "2026-07-18T03:38:46.616Z" }, + { url = "https://files.pythonhosted.org/packages/e2/db/3f5ea5a5b64060ef5e1ff60a19170423e41ce21b8497a6fe15a36e0b43e3/matplotlib-3.11.1-cp313-cp313-win_arm64.whl", hash = "sha256:0c1f44890d435c1b4ef52f701ad5828cb450ea97bcc83918fda6be74965d6cd2", size = 9007662, upload-time = "2026-07-18T03:38:49.112Z" }, + { url = "https://files.pythonhosted.org/packages/98/6e/c7ae5e0531425b69c0826b00ebbc264c85cab853f1cd6e096c9983c2cdc1/matplotlib-3.11.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:5e510088c27a89d53580a752f959146893563e63c330e161d159b0fee652af6f", size = 9503790, upload-time = "2026-07-18T03:38:51.527Z" }, + { url = "https://files.pythonhosted.org/packages/92/79/15be162e0a2ed546939674e2e97d0e33ec2447d86d4d4e611fa295bb178c/matplotlib-3.11.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:1524e2bdd48a93557aa47ddcfe9c225dfdd57d5a01a5c49128c20f0632980ee1", size = 9336148, upload-time = "2026-07-18T03:38:53.564Z" }, + { url = "https://files.pythonhosted.org/packages/6a/7f/36ffe144fc4aacfe0e3ed2318f72b6755d1e73b041d619b4d393e60f5a66/matplotlib-3.11.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:11664c551345553db92e61cae6cf1376f138f8c47cafdf13b64b18f3e3e9e464", size = 10049244, upload-time = "2026-07-18T03:38:55.911Z" }, + { url = "https://files.pythonhosted.org/packages/ab/5f/55812d68c0a840d3a463638f48c00ab1fe338518ec49a640cb6473b444af/matplotlib-3.11.1-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5e1f8922ba31959cf6a9dfb51be64b7f7bc582801a3957dc0c2f3afcd3537adf", size = 10860798, upload-time = "2026-07-18T03:38:58.282Z" }, + { url = "https://files.pythonhosted.org/packages/7a/64/cca444b4eb5e6c768c44fc5e1f0b5211f20ca2b282778051996e996a2bdf/matplotlib-3.11.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:83235693abde86e5e0129998f80ee39fc7f58e6d56a88fafb28a9278833e9d5f", size = 10943282, upload-time = "2026-07-18T03:39:00.465Z" }, + { url = "https://files.pythonhosted.org/packages/e5/0f/a49c329d394f2e9ef38506982107e8b04ecf94dd41a9d8423ff82cc737c7/matplotlib-3.11.1-cp313-cp313t-win_amd64.whl", hash = "sha256:9a076f4fc5cdc43fdf510f5981418d25c2db4973418d9f22d8bb3dc8045ada78", size = 9383532, upload-time = "2026-07-18T03:39:02.468Z" }, + { url = "https://files.pythonhosted.org/packages/e4/50/103e86afb806d8f64d04ede14e4cfc09dbfc25f512421ff85fdd6ebd59cf/matplotlib-3.11.1-cp313-cp313t-win_arm64.whl", hash = "sha256:216fbb93a74add02ddb4cb38ef5348f59ac00b3e84567eaf16598772d40e150a", size = 9059665, upload-time = "2026-07-18T03:39:04.607Z" }, + { url = "https://files.pythonhosted.org/packages/35/04/3079499fa8cb661ea66d13d6439d5a3ae6710a7afd5c7f72e08914f275f8/matplotlib-3.11.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:30c492d4ba9448595b6fd8708c6725963f8148e25c0d8842948da5b05f0ee8d3", size = 9456022, upload-time = "2026-07-18T03:39:07.041Z" }, + { url = "https://files.pythonhosted.org/packages/53/a2/69acfe84ec1f32930e801a5782a07fc5c79c8c6599a507b806d859d5da8e/matplotlib-3.11.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ac104be2768ffdd8655db9e71b768cbb45f2b9aa7b450cf1595e8f65d3822319", size = 9285475, upload-time = "2026-07-18T03:39:09.562Z" }, + { url = "https://files.pythonhosted.org/packages/d3/b3/31b15a2ca56d4ddd6aaa1c884c2f51cf9a61cfaf5ca6f6fbd6343d38e6df/matplotlib-3.11.1-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6be943cb68bc6660ead58c55b3aa6366cba2ef7feb06460fbcce32360376f19f", size = 10847102, upload-time = "2026-07-18T03:39:11.532Z" }, + { url = "https://files.pythonhosted.org/packages/64/0d/a17e966e620545c1548125af0b29ac812dd17b197a18a7462ac12fa859ee/matplotlib-3.11.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5af0dcda57d471440a7b5b623e70e0a61003518443d9098f211a96ecfbbc25be", size = 11131087, upload-time = "2026-07-18T03:39:13.764Z" }, + { url = "https://files.pythonhosted.org/packages/97/c5/5e100efdd67abb7de20befaa333612ef9bfc63417fb71398f904f25d083c/matplotlib-3.11.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3d3fd84082b1afbd9398466c81309e20045be20d48fe0fb18c43504d164cbbb2", size = 10929036, upload-time = "2026-07-18T03:39:16.888Z" }, + { url = "https://files.pythonhosted.org/packages/ce/04/d719a0a36930ecc8dfc801ff340f9dcfc4223f8ca5d39d06b4020032fff8/matplotlib-3.11.1-cp314-cp314-win_amd64.whl", hash = "sha256:9601a1e90be21e4884c53b4f3dc3ee0544654946f9975258d691f1c2e2f119c6", size = 9489571, upload-time = "2026-07-18T03:39:19.449Z" }, + { url = "https://files.pythonhosted.org/packages/48/65/facabdc2f1f6caba7e856db64dfedddca25f7608df07d96a1c8fd114fd3b/matplotlib-3.11.1-cp314-cp314-win_arm64.whl", hash = "sha256:ae30c6109848ac0f9fa36c5d6270938487614c47ba31860bd5361266dabc5685", size = 9164486, upload-time = "2026-07-18T03:39:21.424Z" }, + { url = "https://files.pythonhosted.org/packages/88/dd/18da6cd01cf96354534f98c468a25380c68ce582a2c9dd0cae12b04af4f2/matplotlib-3.11.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:dadfe80797174e2984aae3be0b77594a3c72d2c0a40fbd4a0de48d2728caf3ae", size = 9504876, upload-time = "2026-07-18T03:39:23.633Z" }, + { url = "https://files.pythonhosted.org/packages/79/b0/f0b63555a18b79d038c81fd6126f35fc4dfce0eaff48d96103348c7cf935/matplotlib-3.11.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:89b193b255f4f6f7948dbcee3691f4f341ab05d9a8874a67b45ddb4182922eda", size = 9336120, upload-time = "2026-07-18T03:39:25.797Z" }, + { url = "https://files.pythonhosted.org/packages/c6/dd/f210ec7c4a6f198d5567237048a93d0811fb5a1f1691f13320e592f95b41/matplotlib-3.11.1-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:191163532cdefcb1571ca38a6d7e6474baccde64495783e6ba47aa07ec4b9bbb", size = 10858033, upload-time = "2026-07-18T03:39:27.999Z" }, + { url = "https://files.pythonhosted.org/packages/ec/d2/d6d5324507c5fbb316db48e258c09c2807f3de03d9af47017e120070926f/matplotlib-3.11.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9fdf1c818ab05d0e74002091ddaf414478a3a449ec9d51c8976d45be7e3a01e2", size = 11141827, upload-time = "2026-07-18T03:39:30.092Z" }, + { url = "https://files.pythonhosted.org/packages/0f/68/3c22e9320bdce2c4d2f1320643ef706db7a24cb7420eea28b97a2d67f5a8/matplotlib-3.11.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b937b9dba5f5f6c1e31c47abe2186c865c0914fd18f2ce0dfc39c9adcef5951d", size = 10943061, upload-time = "2026-07-18T03:39:32.356Z" }, + { url = "https://files.pythonhosted.org/packages/f6/4a/907ed190ee81a9df581e0ed5456134fc0f7cb55ffcfda2f9e54ca900761c/matplotlib-3.11.1-cp314-cp314t-win_amd64.whl", hash = "sha256:f2912f647f3fbe1ccf085f91e213936f9101bead81a5e670565b1f1b3712f4fb", size = 9540074, upload-time = "2026-07-18T03:39:34.789Z" }, + { url = "https://files.pythonhosted.org/packages/23/d4/97c19b77e0a6e3b48581185bb65088f431cd20186076cc0f650a1757ea46/matplotlib-3.11.1-cp314-cp314t-win_arm64.whl", hash = "sha256:54d47b8ae8b579633a3902ca5b4ad6c1e132a5626d64447b2e22a66394e79987", size = 9213472, upload-time = "2026-07-18T03:39:37.141Z" }, + { url = "https://files.pythonhosted.org/packages/ee/38/ceb1d637c4db6d06141f3739e93af3321e7caaabe69b57ae48ffe3ee95b1/matplotlib-3.11.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:427258425f9a3fc4ed79a91f9e9b9aaf5a82cb6571e85dc14063cc6fbb993741", size = 9438045, upload-time = "2026-07-18T03:39:39.491Z" }, + { url = "https://files.pythonhosted.org/packages/89/25/72ad8b58602d3a6ef1dfc4b65ecd01634ab65a2bdf494c9fe0e966dbf081/matplotlib-3.11.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:1ac697e591c11b6ad04679a73c2d2f9980fe9d9f0311fb414a2e329706343dfb", size = 9266127, upload-time = "2026-07-18T03:39:41.597Z" }, + { url = "https://files.pythonhosted.org/packages/8a/6d/69552382fcc8e93d1f2763ef2665980a900a48b7f3a4c57ed290726d1cbc/matplotlib-3.11.1-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e4b9ac2f1f607ecda2af90a5232beee2af7582fce1cc30c4b6a1b012dc21ee99", size = 10019439, upload-time = "2026-07-18T03:39:43.78Z" }, +] + +[[package]] +name = "mergedeep" +version = "1.3.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3a/41/580bb4006e3ed0361b8151a01d324fb03f420815446c7def45d02f74c270/mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8", size = 4661, upload-time = "2021-02-05T18:55:30.623Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307", size = 6354, upload-time = "2021-02-05T18:55:29.583Z" }, +] + +[[package]] +name = "mkdocs" +version = "1.6.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "ghp-import" }, + { name = "jinja2" }, + { name = "markdown" }, + { name = "markupsafe" }, + { name = "mergedeep" }, + { name = "mkdocs-get-deps" }, + { name = "packaging" }, + { name = "pathspec" }, + { name = "pyyaml" }, + { name = "pyyaml-env-tag" }, + { name = "watchdog" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bc/c6/bbd4f061bd16b378247f12953ffcb04786a618ce5e904b8c5a01a0309061/mkdocs-1.6.1.tar.gz", hash = "sha256:7b432f01d928c084353ab39c57282f29f92136665bdd6abf7c1ec8d822ef86f2", size = 3889159, upload-time = "2024-08-30T12:24:06.899Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl", hash = "sha256:db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e", size = 3864451, upload-time = "2024-08-30T12:24:05.054Z" }, +] + +[[package]] +name = "mkdocs-autorefs" +version = "1.4.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown" }, + { name = "markupsafe" }, + { name = "mkdocs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/52/c0/f641843de3f612a6b48253f39244165acff36657a91cc903633d456ae1ac/mkdocs_autorefs-1.4.4.tar.gz", hash = "sha256:d54a284f27a7346b9c38f1f852177940c222da508e66edc816a0fa55fc6da197", size = 56588, upload-time = "2026-02-10T15:23:55.105Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl", hash = "sha256:834ef5408d827071ad1bc69e0f39704fa34c7fc05bc8e1c72b227dfdc5c76089", size = 25530, upload-time = "2026-02-10T15:23:53.817Z" }, +] + +[[package]] +name = "mkdocs-get-deps" +version = "0.2.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mergedeep" }, + { name = "platformdirs" }, + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ce/25/b3cccb187655b9393572bde9b09261d267c3bf2f2cdabe347673be5976a6/mkdocs_get_deps-0.2.2.tar.gz", hash = "sha256:8ee8d5f316cdbbb2834bc1df6e69c08fe769a83e040060de26d3c19fad3599a1", size = 11047, upload-time = "2026-03-10T02:46:33.632Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl", hash = "sha256:e7878cbeac04860b8b5e0ca31d3abad3df9411a75a32cde82f8e44b6c16ff650", size = 9555, upload-time = "2026-03-10T02:46:32.256Z" }, +] + +[[package]] +name = "mkdocs-material" +version = "9.7.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "babel" }, + { name = "backrefs" }, + { name = "colorama" }, + { name = "jinja2" }, + { name = "markdown" }, + { name = "mkdocs" }, + { name = "mkdocs-material-extensions" }, + { name = "paginate" }, + { name = "pygments" }, + { name = "pymdown-extensions" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f1/cd/c05d3a530ba7934f144fb45f7203cd236adc25c7bdcc34673d202f4b0278/mkdocs_material-9.7.7.tar.gz", hash = "sha256:c0649c065b1b0512d60aad8c10f947f8e455284475239b364b610f2deb4d0855", size = 4097923, upload-time = "2026-07-17T16:21:33.156Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ad/21/17c1bc9e6f47c972ad66fb2ac2568f99f90f1207eeb6fc3b34d094dba7b5/mkdocs_material-9.7.7-py3-none-any.whl", hash = "sha256:8ea9bb1737a5b524a5f9dcf2e1b4ebda8274ae3008aa7845720a97083bef708f", size = 9305438, upload-time = "2026-07-17T16:21:30.017Z" }, +] + +[[package]] +name = "mkdocs-material-extensions" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/79/9b/9b4c96d6593b2a541e1cb8b34899a6d021d208bb357042823d4d2cabdbe7/mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443", size = 11847, upload-time = "2023-11-22T19:09:45.208Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31", size = 8728, upload-time = "2023-11-22T19:09:43.465Z" }, +] + +[[package]] +name = "mkdocstrings" +version = "1.0.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jinja2" }, + { name = "markdown" }, + { name = "markupsafe" }, + { name = "mkdocs" }, + { name = "mkdocs-autorefs" }, + { name = "pymdown-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/53/71/f85bdf13355073ae15a7375f09879375a830553552e58c1c4b7e0bbc5c8b/mkdocstrings-1.0.6.tar.gz", hash = "sha256:a0b8c2bdd29a6416c80d717aa369bbf7831946bd9f23c2a66db1b1dbe7693dbd", size = 100649, upload-time = "2026-07-11T19:38:05.732Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/5b/4c1902e8bdd5c4db63284e9d101dece4038d4025d6d88850ffe0a1578980/mkdocstrings-1.0.6-py3-none-any.whl", hash = "sha256:2703708697487d1b6d6d7b412e176fa436edf120c1bf81dc9e126b12d00893c7", size = 35787, upload-time = "2026-07-11T19:38:04.417Z" }, +] + +[package.optional-dependencies] +python = [ + { name = "mkdocstrings-python" }, +] + +[[package]] +name = "mkdocstrings-python" +version = "2.0.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "griffelib" }, + { name = "mkdocs-autorefs" }, + { name = "mkdocstrings" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/b6/e858701499d57eee8b3fd8e78168083956c6683ddbe727b46758b19e1119/mkdocstrings_python-2.0.5.tar.gz", hash = "sha256:3a4d92556ad39637e88af94a5374213af9a8e3040c3824ceaed04b486c017594", size = 199578, upload-time = "2026-06-19T10:41:08.868Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/fc/10ab7e80650a9c9e8f4f1105f8c8e73567f88ed0c06ada589ab81d38687c/mkdocstrings_python-2.0.5-py3-none-any.whl", hash = "sha256:30c837bbff016549f659fcba6539ac351303f0fd7e713c89a040611072236e9d", size = 104951, upload-time = "2026-06-19T10:41:07.378Z" }, +] + +[[package]] +name = "mypy" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ast-serialize" }, + { name = "librt", marker = "platform_python_implementation != 'PyPy'" }, + { name = "mypy-extensions" }, + { name = "pathspec" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/12/af/4e516a05d3ca2eb9283e9ec45b2c02225c1514dd6da49fd3c9eaa6639370/mypy-2.3.0.tar.gz", hash = "sha256:465965d41cd9a2726694e983e8ce7113259327bec798115d1e1dfa2a52fb666e", size = 3988104, upload-time = "2026-07-13T11:34:53.387Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a9/09/f2f5f45dae0c9a0891e4751a73312730e009395102e5d72a22a976cca41f/mypy-2.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1fa8d916ac3b705af733c4c1e6c9ebe38fd0d52beb15b105c3e8355b55e6ecdc", size = 14927774, upload-time = "2026-07-13T11:28:38.224Z" }, + { url = "https://files.pythonhosted.org/packages/56/b9/345367effd3a6877275a94d481614bfca983f45e028c6290e2cc54603811/mypy-2.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:28e1e2af8cd8fff551fd30f2fe4b03fb76764ac8b1ba6c6a1bd00ad32b412db3", size = 14000127, upload-time = "2026-07-13T11:30:19.57Z" }, + { url = "https://files.pythonhosted.org/packages/99/6c/a10b7a7b9f0a755fb94e27ae834d4cea9ad6c5221f9325eef8f182641feb/mypy-2.3.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3e77244df3843048c3f927182916730e40c124cbaa43905c1fb86cb382aa0805", size = 14229437, upload-time = "2026-07-13T11:28:17.765Z" }, + { url = "https://files.pythonhosted.org/packages/d9/bd/a26a602acb1bbf849fa4bdac4bc657ee2f11c0c2a764a2cc87a5304e865c/mypy-2.3.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9559ab18a9c9957dfa3004ab57cd4bac5f26a724329a9584e583367f0c2e1117", size = 15171457, upload-time = "2026-07-13T11:29:01.834Z" }, + { url = "https://files.pythonhosted.org/packages/7f/14/124f462bef69bcbc90b9358088460b6091954a3e004852fcd9948db617a5/mypy-2.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:09abd66d8685e73f8f7d17b847c3e104d9a7b164a8706ea87d6c96a3d45816d5", size = 15478281, upload-time = "2026-07-13T11:32:23.413Z" }, + { url = "https://files.pythonhosted.org/packages/db/a4/8bdca6a8ac8d856d82ed049144af2721245a135c2e8001d3890c93975852/mypy-2.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:5e91adad1ca81742ac7ef9893959911df867752206b37135185e88dfb3c89494", size = 11148008, upload-time = "2026-07-13T11:34:17.332Z" }, + { url = "https://files.pythonhosted.org/packages/83/41/490eea348e60ba50decec20bc750605444149a5d7a8cc560042f90ba2c75/mypy-2.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:6f99ec626e3c3a2f7c0b22c5b90ddb5dabb1c18729c971e9bdaca1f1766d2cee", size = 10142329, upload-time = "2026-07-13T11:32:52.116Z" }, + { url = "https://files.pythonhosted.org/packages/e6/b9/d75b3082b05f1b3028828aeb18e74ae5ab0a0936051bbf1f32f59f654747/mypy-2.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3419d00717afbc5265b50dd14b1278f29ea4884dd398ab67873489ac093fd329", size = 14838725, upload-time = "2026-07-13T11:32:44.655Z" }, + { url = "https://files.pythonhosted.org/packages/a9/50/79a65c6ea6e115bc73296038a4543b2d5c91f07912b918a2c616a2514bba/mypy-2.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cfca8ee88544090f86b6dcce05ec55d66eb48a762412ac2507810ba4bd793b6f", size = 13911128, upload-time = "2026-07-13T11:32:02.021Z" }, + { url = "https://files.pythonhosted.org/packages/90/48/e11ed7716c26953ca321f726e452e374dbf81a6f2b8b212ec02af29b6b8f/mypy-2.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:75cbb4b9ef04a0c84a957f07abc4504fbf64b8dcc145675101f2d3a78a4b1d6a", size = 14146742, upload-time = "2026-07-13T11:33:03.313Z" }, + { url = "https://files.pythonhosted.org/packages/06/72/6807565b1c4861ef66f7fdd98b51c61556356eab80235717b46c53bb8627/mypy-2.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:982e3d53dd23d0a4cef67dd66791fdbede0cf38f9eb617bf47663554c51e1e36", size = 15081418, upload-time = "2026-07-13T11:31:13.899Z" }, + { url = "https://files.pythonhosted.org/packages/00/80/1ea14c5d80e589e415973db3e47c78c2219a305b808b2b506395342c1d79/mypy-2.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:85c5385b93012ffa3b31479ab579aef5415f4f3a32c6cf1ae07a984d2a0ff461", size = 15328164, upload-time = "2026-07-13T11:31:35.723Z" }, + { url = "https://files.pythonhosted.org/packages/37/28/8223157404a3d51920078459c37f80fbdc590e1d8ea049dc5ce48643022a/mypy-2.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:13b1b16e2fa39f3b2e33fb1c468abc7a69369fa2e886b4b87b5afc81472325cd", size = 11136472, upload-time = "2026-07-13T11:27:37.018Z" }, + { url = "https://files.pythonhosted.org/packages/6f/cc/ea27e5959c5f258585a756b252031f3b313583d81b5064b2bebc41d3706b/mypy-2.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:b5cd2f027a972a4a5f2278a11fac9747f5f81a53a30b714d74950b6807e55568", size = 10135800, upload-time = "2026-07-13T11:30:08.92Z" }, + { url = "https://files.pythonhosted.org/packages/dc/94/0e7e592619e2133596a47cdd642534b0456545c218430bd3b9d8fefdd1b1/mypy-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2d53fc67b9d28a43c6199077f49fea0f05839e36cf6158500331c9549225e5a5", size = 15026523, upload-time = "2026-07-13T11:34:49.206Z" }, + { url = "https://files.pythonhosted.org/packages/f6/d2/1e1731df090a857df2807177a4626863e5ac0f0256513c35780efe53986f/mypy-2.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fbc00cee7bdbb9291979ddc9d08034a29dfcda4932628c9bbc28c1edd589df0c", size = 14032189, upload-time = "2026-07-13T11:33:57.168Z" }, + { url = "https://files.pythonhosted.org/packages/44/95/cab921f4a806e171f34113e6181dd23c55358ccf6a80741269ef594a410e/mypy-2.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:04e617030eca5221909c8b7d8d7fd1c637948199aa2100b2ad9813feb07e1491", size = 14198696, upload-time = "2026-07-13T11:32:12.767Z" }, + { url = "https://files.pythonhosted.org/packages/66/80/e6d008bb19fe446e3662d85e0e2717bf9f2d611a2164fb29d6e067dbf46c/mypy-2.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:56c184d2c20ca6b6378d58d1960270a767f41f5e44acbbd27f05effef4f4e1d7", size = 15286904, upload-time = "2026-07-13T11:34:27.594Z" }, + { url = "https://files.pythonhosted.org/packages/db/83/94397c9293608a364aa03e8084fb34ede4ae976a260384b9b52929308135/mypy-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3961a4a34b05f7c74b0f05aa51fbfe99a2d1e126038df40318d15c8f558b7ef3", size = 15528342, upload-time = "2026-07-13T11:34:07.819Z" }, + { url = "https://files.pythonhosted.org/packages/cf/96/d8b37d819adec6cfccfb1fd3afc1735d94717ddeafb45536db9c6943e09b/mypy-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:b1942b9314d4c784b8ea1dbab4972603290e5dd5630f06675f13aec97526bc4c", size = 11218346, upload-time = "2026-07-13T11:28:27.745Z" }, + { url = "https://files.pythonhosted.org/packages/2b/cd/cd9f725b19b19e5b530a154cf9bcf9e94279c5d55b3c34fb42b3aa48ea1b/mypy-2.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:be51653d7669d7d7955d613b8d0bb57d5b652eaf71a873ddf65ac87254dd2595", size = 10204525, upload-time = "2026-07-13T11:31:02.552Z" }, + { url = "https://files.pythonhosted.org/packages/6e/ae/f7d056eb0294586a572d0d0d89580ec633c064db520f11d37d5a2fb833bd/mypy-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:91ad22a52ae2c7e621c2f67c94d5a17f66b3209a4cff5cf8a573579835c69e97", size = 14947298, upload-time = "2026-07-13T11:27:47.734Z" }, + { url = "https://files.pythonhosted.org/packages/32/d5/db3e7af01e7844d21662c6ddc1f7825ec7cb4053f0391ac02faf3638396f/mypy-2.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:99ac767cc5d3b64c8d0ae226ead10c96694f94e4e7da1668642225dcd4e75aac", size = 13950768, upload-time = "2026-07-13T11:27:57.726Z" }, + { url = "https://files.pythonhosted.org/packages/d9/fb/43c031f0190513d1ec248ed037eceb742ddd2a4d74bbf406658a28173837/mypy-2.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:de6d2c484742a4d7b0ed6d07b143375624d3b899c5749c7b3c947f56261f48a6", size = 14151586, upload-time = "2026-07-13T11:29:18.615Z" }, + { url = "https://files.pythonhosted.org/packages/ec/c3/f8b2ffc60883084da91be51af58e88a7ffd4ff9795acb7d902ff88d31eb1/mypy-2.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7da939dd335cfd2ad788bdfd081c9f4e47634ab995e5a45eb15fd1e5bc052f8b", size = 15227411, upload-time = "2026-07-13T11:30:29.904Z" }, + { url = "https://files.pythonhosted.org/packages/83/2e/16b917fc7adcf03f1aadddfc93aab804ffb234b1ab09c0ffd6d92a5d34a2/mypy-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7247eb2824f996722a949530183394921ca71deb9680052a338cf53cff7925c2", size = 15478790, upload-time = "2026-07-13T11:33:14.686Z" }, + { url = "https://files.pythonhosted.org/packages/c0/88/aaa65a93c73d0cdae7e42f8adb302bf6885bb281302084f99d0290a35347/mypy-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:75b0984bb3cbd76bb5c9291a8671f7ae66ca3b51c7584c358fc2e923259f0757", size = 11234919, upload-time = "2026-07-13T11:33:39.28Z" }, + { url = "https://files.pythonhosted.org/packages/35/19/b40de63f1a80e63bc2d40f0679a6a8dbd34e95176c8122119bdf406aa552/mypy-2.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:d78fcf900b59cb7e82cb7e3a235e31b462d9333d92285bd1e4952d355b8ffba1", size = 10201510, upload-time = "2026-07-13T11:31:52.619Z" }, + { url = "https://files.pythonhosted.org/packages/a4/58/fa0ae047da911f540284009b4f44b96fe09d83c076d7c103e9d645f46303/mypy-2.3.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ea317b060ce83e26050f8f9e4d7d6bf44ed7597c8ff9990bccffbb9d1d8522db", size = 14941909, upload-time = "2026-07-13T11:32:34.332Z" }, + { url = "https://files.pythonhosted.org/packages/15/14/2ba1d61452d7c2a7fe12741e8d374e52b183476b07aa7f9e2a0d02b0720a/mypy-2.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:094af99f92638aa92852326188b85a89e50f4a472f44827c03362228482f0762", size = 13967581, upload-time = "2026-07-13T11:30:00.587Z" }, + { url = "https://files.pythonhosted.org/packages/ed/5a/483fb9e5ffbbb1a28dccc7b0a13d141b17ac769b6c9f488c0a0c63698962/mypy-2.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:de121747278144fc9ae7caa2e978cf5df12aebc82933182f5b3b86081a30baef", size = 14168807, upload-time = "2026-07-13T11:28:48.6Z" }, + { url = "https://files.pythonhosted.org/packages/ae/77/70d7a10732063beb74ad713682cf871e88f5c5fa39bfc8beff8a524bf9cb/mypy-2.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:37fa4de896a84e2dc9200d91e614c22563b43d1a266789d4bbac7b22ebe6192b", size = 15200144, upload-time = "2026-07-13T11:31:25.283Z" }, + { url = "https://files.pythonhosted.org/packages/56/72/766218ac783be4fdfcd699b90037b63017348a3e86fb2c1fbfb18302637d/mypy-2.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f1b3a98dfd21058bc759bb3337d5d1f61d0fdf9f3cf9c00f4291790fb5427bff", size = 15460389, upload-time = "2026-07-13T11:29:29.077Z" }, + { url = "https://files.pythonhosted.org/packages/38/4e/8a9db7411ecb8ec0cb1fd05dba432f28bafffcd38b4e887714a4a0506689/mypy-2.3.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl", hash = "sha256:944c665d984157cb96a679dfb7a4a81dd1d36b24b9c284b699514e6e626b82d4", size = 7753664, upload-time = "2026-07-13T11:29:08.147Z" }, + { url = "https://files.pythonhosted.org/packages/65/4c/c3f8bfd6ed0e5e38b5a244403b27f821d433443df5a15a278417c10a3a3c/mypy-2.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:4359424140d985192c778c1ce2c114a10c1ca58a381ed79cfa70d37df94b299f", size = 11417237, upload-time = "2026-07-13T11:33:47.467Z" }, + { url = "https://files.pythonhosted.org/packages/3c/00/89a32eaf5ccf174bc4f90db0eaea5d70636c01b8d49f384bdab2e8834390/mypy-2.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:3dd0bed92c4bdec57c42505b96416fb9e6a5aa7be84d2809bcd5f2ecec2860d7", size = 10389252, upload-time = "2026-07-13T11:31:43.81Z" }, + { url = "https://files.pythonhosted.org/packages/31/56/104f93d69aa9f339b6b9d3b0a7faa699b8b466c942cf3ae86cc2a2ec0915/mypy-2.3.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:691fdc37132b1ae628d834f672e74de83462d9fb4aff621835767fb43a8dd373", size = 16385495, upload-time = "2026-07-13T11:29:49.818Z" }, + { url = "https://files.pythonhosted.org/packages/d2/03/f1d2123313f55efafdd27706960f43a771c62f1b68426c76043f3ab9ebf3/mypy-2.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:aec15d465d477558fd842757b487849007311cf3897849cdda0e3162ac0ac556", size = 15098155, upload-time = "2026-07-13T11:30:40.301Z" }, + { url = "https://files.pythonhosted.org/packages/e5/5d/d5f9200399b445e81726c4f23becee33f233aee81c72680b1ef3a258b641/mypy-2.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b352b7e49f5e6576009e8df730e1ff4f915cb565b851b396d2ffe2f5a6f5da88", size = 15514155, upload-time = "2026-07-13T11:34:38.569Z" }, + { url = "https://files.pythonhosted.org/packages/cd/ce/69977c555f08faa3190cfde44189b89dbd56861b1ab97aa18fc5f3a2e4a3/mypy-2.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c6c6bf687b17f90dbfcad95b960d32eaa0154c00da45f03ab50bf8952e047fe", size = 16766351, upload-time = "2026-07-13T11:33:29.195Z" }, + { url = "https://files.pythonhosted.org/packages/bc/92/6648b6caa3ab9e00f9ac0c2a78307805f873dd48139b24a6f6f7c3667bbf/mypy-2.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f4ed18f111bfe2d599bca7468e7f9251042c1c2118f762c8de2766a56d773c60", size = 17043490, upload-time = "2026-07-13T11:30:53.927Z" }, + { url = "https://files.pythonhosted.org/packages/7c/ab/0dc91d80f3f016634c68d451f294a97320fe903a9b6f90b9e57b3f7f1717/mypy-2.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:0b025a93cffb9781d231f232be07a17912f35f10a313c24f301c81e842870654", size = 12146869, upload-time = "2026-07-13T11:29:38.874Z" }, + { url = "https://files.pythonhosted.org/packages/85/b5/4c964d02634ba81f4d1c84838e5c5b18ab06d13ed568960f5d6318495ccc/mypy-2.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:adebc76aab4f3495a88b41d48aa4aff0c03f2822501da76625afcca5975f19e5", size = 10965113, upload-time = "2026-07-13T11:28:07.056Z" }, + { url = "https://files.pythonhosted.org/packages/2c/fa/fdc54fe583ba3cafbcedfb70eeeaf03849f75b1827a07096c7bd996f582d/mypy-2.3.0-py3-none-any.whl", hash = "sha256:6b1cdb579446b60432432b2b2403a6201b4b475a004d7f488511c9ba177c9e88", size = 2753292, upload-time = "2026-07-13T11:33:18.48Z" }, +] + +[[package]] +name = "mypy-extensions" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343, upload-time = "2025-04-22T14:54:24.164Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, +] + +[[package]] +name = "nodeenv" +version = "1.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/24/bf/d1bda4f6168e0b2e9e5958945e01910052158313224ada5ce1fb2e1113b8/nodeenv-1.10.0.tar.gz", hash = "sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb", size = 55611, upload-time = "2025-12-20T14:08:54.006Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl", hash = "sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827", size = 23438, upload-time = "2025-12-20T14:08:52.782Z" }, +] + +[[package]] +name = "numba" +version = "0.67.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "llvmlite" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "numpy", version = "2.5.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7a/90/2544f4e3a61e501d6c9a5418fd4b905323222693d54a02cab0106a0af865/numba-0.67.0.tar.gz", hash = "sha256:cd75aa535b33fa05d9d930b1ae8af9f97a2881e96d72dfb38ec9b78284d9f851", size = 2836515, upload-time = "2026-08-11T23:04:00.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/2e/6e72b3edbb7c7d6b44b2ca9e1b62e91997415d181541ef47fc6957c59bf2/numba-0.67.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:8c0e88acd4341ddf40779db3c0228b9188aca7fcab5f5f3ce9949a1fc71e9a02", size = 2745135, upload-time = "2026-08-11T23:03:08.321Z" }, + { url = "https://files.pythonhosted.org/packages/e5/17/5358f24235ef1a5a80b7e28f3e1baa886c0bcf07dc68557009284e6ba698/numba-0.67.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d6c8e9ba3f9602471e8c6f563ffcce8db8046741f0bafb782a052e41dc6b6861", size = 3821881, upload-time = "2026-08-11T23:03:11.172Z" }, + { url = "https://files.pythonhosted.org/packages/0e/18/2f00694248e32c53812baf3d36a7c656dbdd667c6993087b3da068f74b02/numba-0.67.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:694c81c6560b2b47e5fc1dc39c29175b907adf862d9af0af801453400a022a61", size = 3528397, upload-time = "2026-08-11T23:03:13.107Z" }, + { url = "https://files.pythonhosted.org/packages/7f/39/4175b074929938011bd4b564beb4e0fcffd46252e01f60602b57ffb02b06/numba-0.67.0-cp310-cp310-win_amd64.whl", hash = "sha256:ed333e0af4386294e7f03e550e01411856b6935e717d859225e0a7338c6b6795", size = 2815861, upload-time = "2026-08-11T23:03:15.072Z" }, + { url = "https://files.pythonhosted.org/packages/8c/ed/55ba4e54ee878396de6b18e6533cc4a92fa519e8c82d55cf40f98c0a6831/numba-0.67.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:3fa3d1b27f96f2c0d54513d953d7197886aa1eaa7d2439a0eedc44d993fb181a", size = 2744821, upload-time = "2026-08-11T23:03:17.321Z" }, + { url = "https://files.pythonhosted.org/packages/be/78/3f3c45dbaec3cf02bbb1825731beca50f591227e95143d6bd7a64897641c/numba-0.67.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8c80c847301dc33dc8f84a97a952004023d9a05578ae4512b087176264cc1960", size = 3827182, upload-time = "2026-08-11T23:03:19.684Z" }, + { url = "https://files.pythonhosted.org/packages/a5/24/4e70cb86534283d859c3aea2302da523e41539b98dd6c3c4d0a42af95cda/numba-0.67.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e7a7b0121466f1e9a8a074b0545fe90e16389623abf979b5d7c299dca1294d7e", size = 3532817, upload-time = "2026-08-11T23:03:22.06Z" }, + { url = "https://files.pythonhosted.org/packages/26/4d/23dab7f4233be0fc34f54a169ed85238467cd24d8adf2498e5c12ea19dc7/numba-0.67.0-cp311-cp311-win_amd64.whl", hash = "sha256:cfba1ac34f0363fb1a250a10e97240780d11e05227892f7286b26fbfd0ad58ce", size = 2815700, upload-time = "2026-08-11T23:03:23.812Z" }, + { url = "https://files.pythonhosted.org/packages/0d/58/915cddba90010348ed0444451132fdde9b000bcbaff1582029b5bf115d11/numba-0.67.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:6004d8d5f28d4028687fb2d972d629295b13685943bd2ed5cd8810c3b848e219", size = 2745050, upload-time = "2026-08-11T23:03:25.607Z" }, + { url = "https://files.pythonhosted.org/packages/bb/38/926757caaac18a66f057d7544a63620bf360a07d281c9f7ecadd2aa83963/numba-0.67.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f63d43db06b4756424d6d2484737c902e0ae944a0eec3e8b0b4de2c695b15caa", size = 3884596, upload-time = "2026-08-11T23:03:27.688Z" }, + { url = "https://files.pythonhosted.org/packages/4d/6d/58291dc58da39d98b32db7f044729f6d8d4920cd9622fbab3179b54ff4c4/numba-0.67.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:76d3335aaeffb9dc88309420890e73497a00be08a7530441bc2b58ffe025bfa5", size = 3585290, upload-time = "2026-08-11T23:03:29.684Z" }, + { url = "https://files.pythonhosted.org/packages/6e/63/ab21828b4056afed71f9ecb40f4de26c2c19de731cc001961aca74b79464/numba-0.67.0-cp312-cp312-win_amd64.whl", hash = "sha256:50e2b72406c18cda5dd7431b0082cb85ea94e06c64c33607248fc8bef92cfb81", size = 2815645, upload-time = "2026-08-11T23:03:31.732Z" }, + { url = "https://files.pythonhosted.org/packages/49/dd/bd9fe772f6c84597b76cac229b3f2890f01a2c64fd70e48ceaae10dd65cb/numba-0.67.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:77e1c7173fee57a0d84e006c7e70346689d6cb3e7db503489bae58646b4eff7b", size = 2744872, upload-time = "2026-08-11T23:03:33.649Z" }, + { url = "https://files.pythonhosted.org/packages/a1/1c/c05609739cc41116d36e30cb2b41fb00f126bb52e1b0bac907051ad8a35d/numba-0.67.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9c4953387c77864b596d8296e2cfbdef82b0eea4166ab4864b05d226c51143e0", size = 3892004, upload-time = "2026-08-11T23:03:35.797Z" }, + { url = "https://files.pythonhosted.org/packages/4a/77/a5276ad4178250403e0e2251f3e1f8ac18feac779b0474a8bcb08558490d/numba-0.67.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:88f6e0f5cb6c545e158b6ef0496c01b6d6958a7ccc6634a1576a94bbbab29ff2", size = 3591878, upload-time = "2026-08-11T23:03:37.845Z" }, + { url = "https://files.pythonhosted.org/packages/0f/80/d48f0ba7442516ceb5a1585f0c81d3aa531bc96bfcabcd9f8f925768c426/numba-0.67.0-cp313-cp313-win_amd64.whl", hash = "sha256:b68ad5125fe245339cc8dcc036081fc1ea482c5063387b9612a76ccd83dc91cd", size = 2815504, upload-time = "2026-08-11T23:03:39.736Z" }, + { url = "https://files.pythonhosted.org/packages/d7/16/345b1e4774a08247aafcfdb93d4e8d24a3646366cbe72de33053fc0de1b5/numba-0.67.0-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:f99f880ff25f418a67f9a1d00d0ddfbc63430f627b523e515085a592a7567f4b", size = 2745088, upload-time = "2026-08-11T23:03:41.864Z" }, + { url = "https://files.pythonhosted.org/packages/1b/36/e614ba2bc0f005ed0f37a6413f08fe705210297ddb9a37a475a8b9fdab61/numba-0.67.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5269245a675abdd3e2c35ec6bb2f250355effa9032514d8f2354f0d2d10854bd", size = 3861040, upload-time = "2026-08-11T23:03:43.842Z" }, + { url = "https://files.pythonhosted.org/packages/40/90/30c42a1dbc4176cf355e8e8be61803732c55597b1332925fe233912a43d9/numba-0.67.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f074a8e23db78490f11a3930c940be758316c10ac5985be83d2f298dc080acf7", size = 3561811, upload-time = "2026-08-11T23:03:46.037Z" }, + { url = "https://files.pythonhosted.org/packages/18/6d/21bd16f770476e394c5e5f504935817967442a71251d6b86c244a2767980/numba-0.67.0-cp314-cp314-win_amd64.whl", hash = "sha256:4d576e62bf2c9370f61312b51573c4bb1f3fe96798bbab56730847a368a316c4", size = 2817421, upload-time = "2026-08-11T23:03:47.922Z" }, + { url = "https://files.pythonhosted.org/packages/95/06/bb41b0e59b9ff52c94a2f01db24f6437df058caebb377b5f372fc343a6a2/numba-0.67.0-cp314-cp314-win_arm64.whl", hash = "sha256:7930748ce8355d2a5a28602abab056a61fdc676d17377f27d17993905428171f", size = 2788885, upload-time = "2026-08-11T23:03:49.967Z" }, + { url = "https://files.pythonhosted.org/packages/10/7c/aa07151fbd0f4283f78de437cc196f9084789be89a2b4de3fdc2f6a4b414/numba-0.67.0-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:4a2ed006635bbd0fe45681ed49f3b4f4bad1abf0c233bcc5842c9e3a34cabd61", size = 2748150, upload-time = "2026-08-11T23:03:51.755Z" }, + { url = "https://files.pythonhosted.org/packages/74/62/b8174ca95a4cc1a7ba1520767734e016991545590b8fbde521b681701a9f/numba-0.67.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aa5f002f665bec321b950dacaa26ee009e1d720f6ac9d9856eed5efe1caa03a6", size = 3896986, upload-time = "2026-08-11T23:03:53.752Z" }, + { url = "https://files.pythonhosted.org/packages/8c/f9/3a7b6dbf81e01a48958b45ad2239edbc64707522ab17f11f9f18c44bf6d1/numba-0.67.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:83ab968b0e0fa744eba03351282dd8000796e6ec8e4518f47bd3ed86c0a20c7b", size = 3614644, upload-time = "2026-08-11T23:03:55.794Z" }, + { url = "https://files.pythonhosted.org/packages/d9/5b/248f5681c121ca853a9f4e39d342a3e01b8a0261b0275853eb3d0d56aa20/numba-0.67.0-cp314-cp314t-win_amd64.whl", hash = "sha256:00c964a5b94d3ae82d83ac162cd610755875b98dadb779fdde06e6bfcdbca47e", size = 2822870, upload-time = "2026-08-11T23:03:58.097Z" }, +] + +[[package]] +name = "numpy" +version = "2.2.6" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.11'", +] +sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb", size = 21165245, upload-time = "2025-05-17T21:27:58.555Z" }, + { url = "https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90", size = 14360048, upload-time = "2025-05-17T21:28:21.406Z" }, + { url = "https://files.pythonhosted.org/packages/fd/77/dc2fcfc66943c6410e2bf598062f5959372735ffda175b39906d54f02349/numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163", size = 5340542, upload-time = "2025-05-17T21:28:30.931Z" }, + { url = "https://files.pythonhosted.org/packages/7a/4f/1cb5fdc353a5f5cc7feb692db9b8ec2c3d6405453f982435efc52561df58/numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf", size = 6878301, upload-time = "2025-05-17T21:28:41.613Z" }, + { url = "https://files.pythonhosted.org/packages/eb/17/96a3acd228cec142fcb8723bd3cc39c2a474f7dcf0a5d16731980bcafa95/numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83", size = 14297320, upload-time = "2025-05-17T21:29:02.78Z" }, + { url = "https://files.pythonhosted.org/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915", size = 16801050, upload-time = "2025-05-17T21:29:27.675Z" }, + { url = "https://files.pythonhosted.org/packages/07/b6/89d837eddef52b3d0cec5c6ba0456c1bf1b9ef6a6672fc2b7873c3ec4e2e/numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680", size = 15807034, upload-time = "2025-05-17T21:29:51.102Z" }, + { url = "https://files.pythonhosted.org/packages/01/c8/dc6ae86e3c61cfec1f178e5c9f7858584049b6093f843bca541f94120920/numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289", size = 18614185, upload-time = "2025-05-17T21:30:18.703Z" }, + { url = "https://files.pythonhosted.org/packages/5b/c5/0064b1b7e7c89137b471ccec1fd2282fceaae0ab3a9550f2568782d80357/numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d", size = 6527149, upload-time = "2025-05-17T21:30:29.788Z" }, + { url = "https://files.pythonhosted.org/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3", size = 12904620, upload-time = "2025-05-17T21:30:48.994Z" }, + { url = "https://files.pythonhosted.org/packages/da/a8/4f83e2aa666a9fbf56d6118faaaf5f1974d456b1823fda0a176eff722839/numpy-2.2.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f9f1adb22318e121c5c69a09142811a201ef17ab257a1e66ca3025065b7f53ae", size = 21176963, upload-time = "2025-05-17T21:31:19.36Z" }, + { url = "https://files.pythonhosted.org/packages/b3/2b/64e1affc7972decb74c9e29e5649fac940514910960ba25cd9af4488b66c/numpy-2.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c820a93b0255bc360f53eca31a0e676fd1101f673dda8da93454a12e23fc5f7a", size = 14406743, upload-time = "2025-05-17T21:31:41.087Z" }, + { url = "https://files.pythonhosted.org/packages/4a/9f/0121e375000b5e50ffdd8b25bf78d8e1a5aa4cca3f185d41265198c7b834/numpy-2.2.6-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3d70692235e759f260c3d837193090014aebdf026dfd167834bcba43e30c2a42", size = 5352616, upload-time = "2025-05-17T21:31:50.072Z" }, + { url = "https://files.pythonhosted.org/packages/31/0d/b48c405c91693635fbe2dcd7bc84a33a602add5f63286e024d3b6741411c/numpy-2.2.6-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:481b49095335f8eed42e39e8041327c05b0f6f4780488f61286ed3c01368d491", size = 6889579, upload-time = "2025-05-17T21:32:01.712Z" }, + { url = "https://files.pythonhosted.org/packages/52/b8/7f0554d49b565d0171eab6e99001846882000883998e7b7d9f0d98b1f934/numpy-2.2.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b64d8d4d17135e00c8e346e0a738deb17e754230d7e0810ac5012750bbd85a5a", size = 14312005, upload-time = "2025-05-17T21:32:23.332Z" }, + { url = "https://files.pythonhosted.org/packages/b3/dd/2238b898e51bd6d389b7389ffb20d7f4c10066d80351187ec8e303a5a475/numpy-2.2.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba10f8411898fc418a521833e014a77d3ca01c15b0c6cdcce6a0d2897e6dbbdf", size = 16821570, upload-time = "2025-05-17T21:32:47.991Z" }, + { url = "https://files.pythonhosted.org/packages/83/6c/44d0325722cf644f191042bf47eedad61c1e6df2432ed65cbe28509d404e/numpy-2.2.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bd48227a919f1bafbdda0583705e547892342c26fb127219d60a5c36882609d1", size = 15818548, upload-time = "2025-05-17T21:33:11.728Z" }, + { url = "https://files.pythonhosted.org/packages/ae/9d/81e8216030ce66be25279098789b665d49ff19eef08bfa8cb96d4957f422/numpy-2.2.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9551a499bf125c1d4f9e250377c1ee2eddd02e01eac6644c080162c0c51778ab", size = 18620521, upload-time = "2025-05-17T21:33:39.139Z" }, + { url = "https://files.pythonhosted.org/packages/6a/fd/e19617b9530b031db51b0926eed5345ce8ddc669bb3bc0044b23e275ebe8/numpy-2.2.6-cp311-cp311-win32.whl", hash = "sha256:0678000bb9ac1475cd454c6b8c799206af8107e310843532b04d49649c717a47", size = 6525866, upload-time = "2025-05-17T21:33:50.273Z" }, + { url = "https://files.pythonhosted.org/packages/31/0a/f354fb7176b81747d870f7991dc763e157a934c717b67b58456bc63da3df/numpy-2.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:e8213002e427c69c45a52bbd94163084025f533a55a59d6f9c5b820774ef3303", size = 12907455, upload-time = "2025-05-17T21:34:09.135Z" }, + { url = "https://files.pythonhosted.org/packages/82/5d/c00588b6cf18e1da539b45d3598d3557084990dcc4331960c15ee776ee41/numpy-2.2.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:41c5a21f4a04fa86436124d388f6ed60a9343a6f767fced1a8a71c3fbca038ff", size = 20875348, upload-time = "2025-05-17T21:34:39.648Z" }, + { url = "https://files.pythonhosted.org/packages/66/ee/560deadcdde6c2f90200450d5938f63a34b37e27ebff162810f716f6a230/numpy-2.2.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de749064336d37e340f640b05f24e9e3dd678c57318c7289d222a8a2f543e90c", size = 14119362, upload-time = "2025-05-17T21:35:01.241Z" }, + { url = "https://files.pythonhosted.org/packages/3c/65/4baa99f1c53b30adf0acd9a5519078871ddde8d2339dc5a7fde80d9d87da/numpy-2.2.6-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:894b3a42502226a1cac872f840030665f33326fc3dac8e57c607905773cdcde3", size = 5084103, upload-time = "2025-05-17T21:35:10.622Z" }, + { url = "https://files.pythonhosted.org/packages/cc/89/e5a34c071a0570cc40c9a54eb472d113eea6d002e9ae12bb3a8407fb912e/numpy-2.2.6-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:71594f7c51a18e728451bb50cc60a3ce4e6538822731b2933209a1f3614e9282", size = 6625382, upload-time = "2025-05-17T21:35:21.414Z" }, + { url = "https://files.pythonhosted.org/packages/f8/35/8c80729f1ff76b3921d5c9487c7ac3de9b2a103b1cd05e905b3090513510/numpy-2.2.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2618db89be1b4e05f7a1a847a9c1c0abd63e63a1607d892dd54668dd92faf87", size = 14018462, upload-time = "2025-05-17T21:35:42.174Z" }, + { url = "https://files.pythonhosted.org/packages/8c/3d/1e1db36cfd41f895d266b103df00ca5b3cbe965184df824dec5c08c6b803/numpy-2.2.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd83c01228a688733f1ded5201c678f0c53ecc1006ffbc404db9f7a899ac6249", size = 16527618, upload-time = "2025-05-17T21:36:06.711Z" }, + { url = "https://files.pythonhosted.org/packages/61/c6/03ed30992602c85aa3cd95b9070a514f8b3c33e31124694438d88809ae36/numpy-2.2.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:37c0ca431f82cd5fa716eca9506aefcabc247fb27ba69c5062a6d3ade8cf8f49", size = 15505511, upload-time = "2025-05-17T21:36:29.965Z" }, + { url = "https://files.pythonhosted.org/packages/b7/25/5761d832a81df431e260719ec45de696414266613c9ee268394dd5ad8236/numpy-2.2.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fe27749d33bb772c80dcd84ae7e8df2adc920ae8297400dabec45f0dedb3f6de", size = 18313783, upload-time = "2025-05-17T21:36:56.883Z" }, + { url = "https://files.pythonhosted.org/packages/57/0a/72d5a3527c5ebffcd47bde9162c39fae1f90138c961e5296491ce778e682/numpy-2.2.6-cp312-cp312-win32.whl", hash = "sha256:4eeaae00d789f66c7a25ac5f34b71a7035bb474e679f410e5e1a94deb24cf2d4", size = 6246506, upload-time = "2025-05-17T21:37:07.368Z" }, + { url = "https://files.pythonhosted.org/packages/36/fa/8c9210162ca1b88529ab76b41ba02d433fd54fecaf6feb70ef9f124683f1/numpy-2.2.6-cp312-cp312-win_amd64.whl", hash = "sha256:c1f9540be57940698ed329904db803cf7a402f3fc200bfe599334c9bd84a40b2", size = 12614190, upload-time = "2025-05-17T21:37:26.213Z" }, + { url = "https://files.pythonhosted.org/packages/f9/5c/6657823f4f594f72b5471f1db1ab12e26e890bb2e41897522d134d2a3e81/numpy-2.2.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0811bb762109d9708cca4d0b13c4f67146e3c3b7cf8d34018c722adb2d957c84", size = 20867828, upload-time = "2025-05-17T21:37:56.699Z" }, + { url = "https://files.pythonhosted.org/packages/dc/9e/14520dc3dadf3c803473bd07e9b2bd1b69bc583cb2497b47000fed2fa92f/numpy-2.2.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:287cc3162b6f01463ccd86be154f284d0893d2b3ed7292439ea97eafa8170e0b", size = 14143006, upload-time = "2025-05-17T21:38:18.291Z" }, + { url = "https://files.pythonhosted.org/packages/4f/06/7e96c57d90bebdce9918412087fc22ca9851cceaf5567a45c1f404480e9e/numpy-2.2.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:f1372f041402e37e5e633e586f62aa53de2eac8d98cbfb822806ce4bbefcb74d", size = 5076765, upload-time = "2025-05-17T21:38:27.319Z" }, + { url = "https://files.pythonhosted.org/packages/73/ed/63d920c23b4289fdac96ddbdd6132e9427790977d5457cd132f18e76eae0/numpy-2.2.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:55a4d33fa519660d69614a9fad433be87e5252f4b03850642f88993f7b2ca566", size = 6617736, upload-time = "2025-05-17T21:38:38.141Z" }, + { url = "https://files.pythonhosted.org/packages/85/c5/e19c8f99d83fd377ec8c7e0cf627a8049746da54afc24ef0a0cb73d5dfb5/numpy-2.2.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f92729c95468a2f4f15e9bb94c432a9229d0d50de67304399627a943201baa2f", size = 14010719, upload-time = "2025-05-17T21:38:58.433Z" }, + { url = "https://files.pythonhosted.org/packages/19/49/4df9123aafa7b539317bf6d342cb6d227e49f7a35b99c287a6109b13dd93/numpy-2.2.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bc23a79bfabc5d056d106f9befb8d50c31ced2fbc70eedb8155aec74a45798f", size = 16526072, upload-time = "2025-05-17T21:39:22.638Z" }, + { url = "https://files.pythonhosted.org/packages/b2/6c/04b5f47f4f32f7c2b0e7260442a8cbcf8168b0e1a41ff1495da42f42a14f/numpy-2.2.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e3143e4451880bed956e706a3220b4e5cf6172ef05fcc397f6f36a550b1dd868", size = 15503213, upload-time = "2025-05-17T21:39:45.865Z" }, + { url = "https://files.pythonhosted.org/packages/17/0a/5cd92e352c1307640d5b6fec1b2ffb06cd0dabe7d7b8227f97933d378422/numpy-2.2.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b4f13750ce79751586ae2eb824ba7e1e8dba64784086c98cdbbcc6a42112ce0d", size = 18316632, upload-time = "2025-05-17T21:40:13.331Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3b/5cba2b1d88760ef86596ad0f3d484b1cbff7c115ae2429678465057c5155/numpy-2.2.6-cp313-cp313-win32.whl", hash = "sha256:5beb72339d9d4fa36522fc63802f469b13cdbe4fdab4a288f0c441b74272ebfd", size = 6244532, upload-time = "2025-05-17T21:43:46.099Z" }, + { url = "https://files.pythonhosted.org/packages/cb/3b/d58c12eafcb298d4e6d0d40216866ab15f59e55d148a5658bb3132311fcf/numpy-2.2.6-cp313-cp313-win_amd64.whl", hash = "sha256:b0544343a702fa80c95ad5d3d608ea3599dd54d4632df855e4c8d24eb6ecfa1c", size = 12610885, upload-time = "2025-05-17T21:44:05.145Z" }, + { url = "https://files.pythonhosted.org/packages/6b/9e/4bf918b818e516322db999ac25d00c75788ddfd2d2ade4fa66f1f38097e1/numpy-2.2.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0bca768cd85ae743b2affdc762d617eddf3bcf8724435498a1e80132d04879e6", size = 20963467, upload-time = "2025-05-17T21:40:44Z" }, + { url = "https://files.pythonhosted.org/packages/61/66/d2de6b291507517ff2e438e13ff7b1e2cdbdb7cb40b3ed475377aece69f9/numpy-2.2.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:fc0c5673685c508a142ca65209b4e79ed6740a4ed6b2267dbba90f34b0b3cfda", size = 14225144, upload-time = "2025-05-17T21:41:05.695Z" }, + { url = "https://files.pythonhosted.org/packages/e4/25/480387655407ead912e28ba3a820bc69af9adf13bcbe40b299d454ec011f/numpy-2.2.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:5bd4fc3ac8926b3819797a7c0e2631eb889b4118a9898c84f585a54d475b7e40", size = 5200217, upload-time = "2025-05-17T21:41:15.903Z" }, + { url = "https://files.pythonhosted.org/packages/aa/4a/6e313b5108f53dcbf3aca0c0f3e9c92f4c10ce57a0a721851f9785872895/numpy-2.2.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:fee4236c876c4e8369388054d02d0e9bb84821feb1a64dd59e137e6511a551f8", size = 6712014, upload-time = "2025-05-17T21:41:27.321Z" }, + { url = "https://files.pythonhosted.org/packages/b7/30/172c2d5c4be71fdf476e9de553443cf8e25feddbe185e0bd88b096915bcc/numpy-2.2.6-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1dda9c7e08dc141e0247a5b8f49cf05984955246a327d4c48bda16821947b2f", size = 14077935, upload-time = "2025-05-17T21:41:49.738Z" }, + { url = "https://files.pythonhosted.org/packages/12/fb/9e743f8d4e4d3c710902cf87af3512082ae3d43b945d5d16563f26ec251d/numpy-2.2.6-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f447e6acb680fd307f40d3da4852208af94afdfab89cf850986c3ca00562f4fa", size = 16600122, upload-time = "2025-05-17T21:42:14.046Z" }, + { url = "https://files.pythonhosted.org/packages/12/75/ee20da0e58d3a66f204f38916757e01e33a9737d0b22373b3eb5a27358f9/numpy-2.2.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:389d771b1623ec92636b0786bc4ae56abafad4a4c513d36a55dce14bd9ce8571", size = 15586143, upload-time = "2025-05-17T21:42:37.464Z" }, + { url = "https://files.pythonhosted.org/packages/76/95/bef5b37f29fc5e739947e9ce5179ad402875633308504a52d188302319c8/numpy-2.2.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8e9ace4a37db23421249ed236fdcdd457d671e25146786dfc96835cd951aa7c1", size = 18385260, upload-time = "2025-05-17T21:43:05.189Z" }, + { url = "https://files.pythonhosted.org/packages/09/04/f2f83279d287407cf36a7a8053a5abe7be3622a4363337338f2585e4afda/numpy-2.2.6-cp313-cp313t-win32.whl", hash = "sha256:038613e9fb8c72b0a41f025a7e4c3f0b7a1b5d768ece4796b674c8f3fe13efff", size = 6377225, upload-time = "2025-05-17T21:43:16.254Z" }, + { url = "https://files.pythonhosted.org/packages/67/0e/35082d13c09c02c011cf21570543d202ad929d961c02a147493cb0c2bdf5/numpy-2.2.6-cp313-cp313t-win_amd64.whl", hash = "sha256:6031dd6dfecc0cf9f668681a37648373bddd6421fff6c66ec1624eed0180ee06", size = 12771374, upload-time = "2025-05-17T21:43:35.479Z" }, + { url = "https://files.pythonhosted.org/packages/9e/3b/d94a75f4dbf1ef5d321523ecac21ef23a3cd2ac8b78ae2aac40873590229/numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d", size = 21040391, upload-time = "2025-05-17T21:44:35.948Z" }, + { url = "https://files.pythonhosted.org/packages/17/f4/09b2fa1b58f0fb4f7c7963a1649c64c4d315752240377ed74d9cd878f7b5/numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db", size = 6786754, upload-time = "2025-05-17T21:44:47.446Z" }, + { url = "https://files.pythonhosted.org/packages/af/30/feba75f143bdc868a1cc3f44ccfa6c4b9ec522b36458e738cd00f67b573f/numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543", size = 16643476, upload-time = "2025-05-17T21:45:11.871Z" }, + { url = "https://files.pythonhosted.org/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666, upload-time = "2025-05-17T21:45:31.426Z" }, +] + +[[package]] +name = "numpy" +version = "2.4.6" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version == '3.11.*' and sys_platform == 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'emscripten'", + "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] +sdist = { url = "https://files.pythonhosted.org/packages/d0/ad/fed0499ce6a338d2a03ebae59cd15093910c8875328855781952abf6c2fe/numpy-2.4.6.tar.gz", hash = "sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda", size = 20735807, upload-time = "2026-05-18T23:37:14.07Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/49/ec46835a70be8fa6446c495126ac84fdb28cb2558e1620ffb87a10c8b64c/numpy-2.4.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0280e0356c0829a18d9de1cb7eee50ec22ca639878d7240307ca0943d73cd2c4", size = 16969194, upload-time = "2026-05-18T23:33:13.503Z" }, + { url = "https://files.pythonhosted.org/packages/0e/0d/f5957185c0ee2f3e12f78715aa9e3b353fd83633316c8532b38faa37e3f6/numpy-2.4.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:110f8b71aacb688ec69062bb7f6938a0f8acb01b7c1c4beb453c65b6d234584d", size = 14964111, upload-time = "2026-05-18T23:33:17.795Z" }, + { url = "https://files.pythonhosted.org/packages/ad/40/40a40ee0ddf7ceb782c49af278894b686e586d65d8c1889c8b5da01a3d7d/numpy-2.4.6-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:4cfe66903cc32a9921a6733d96b19bb6abf310397581bbad89c228f5abaf0ee8", size = 5469159, upload-time = "2026-05-18T23:33:20.654Z" }, + { url = "https://files.pythonhosted.org/packages/63/13/f9a8046535cb21deae82f8d03de9617e08882d274fad2539630761888228/numpy-2.4.6-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:8155154c7c691289fe18f510b5d4657c68c67989f293f0535a91360392ff6538", size = 6798936, upload-time = "2026-05-18T23:33:22.987Z" }, + { url = "https://files.pythonhosted.org/packages/33/a8/6fa8c1a345a8c85dbb21932c447bee07c30a2c2a3f31e369c0a84b300147/numpy-2.4.6-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ab0a9c4ffb1a6d95ef519fe4247dba8eb6b18ad93999f76b7f657039acabd47", size = 15966692, upload-time = "2026-05-18T23:33:26.62Z" }, + { url = "https://files.pythonhosted.org/packages/02/03/74fe2a4cb3817d94d86402f2506554130a2f01414e299b5a843e5a8a957f/numpy-2.4.6-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:89cd468399cfd2504718f0ba50e410dca55a170b61a02ad92bb18c8a65186e93", size = 16918164, upload-time = "2026-05-18T23:33:29.955Z" }, + { url = "https://files.pythonhosted.org/packages/c5/80/3615be3313f7e7696609bc194b9f0101da809df79e859bdb84e0cd043f46/numpy-2.4.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c2d37ab77531417474168eb79d6d80b14f821a966818505d03013d0833edb7a8", size = 17322877, upload-time = "2026-05-18T23:33:34.724Z" }, + { url = "https://files.pythonhosted.org/packages/ca/ac/a691e0fe2675e370d0e08ff905adc49a1c8830e8cae03efe4477e92cd55d/numpy-2.4.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f407cb6b8e9d6d8c626bc73c945db1706035af8fd632295547bf1c9e46d092d6", size = 18651487, upload-time = "2026-05-18T23:33:38.217Z" }, + { url = "https://files.pythonhosted.org/packages/15/a7/9bc1cd626d7bf6869bfedf27b91b6ab5dd607758bf8e959d6fa80c6a59cb/numpy-2.4.6-cp311-cp311-win32.whl", hash = "sha256:ddea102b48f9e339f3948bf22040944184627a30fdf7f858667673b9c5f033c8", size = 6233945, upload-time = "2026-05-18T23:33:41.331Z" }, + { url = "https://files.pythonhosted.org/packages/c5/31/7fc6239c12bce7e931463251cca4426c465e1876ba3cc785402ef4dd8f4e/numpy-2.4.6-cp311-cp311-win_amd64.whl", hash = "sha256:1e254a00cdf42b1e4d5b3d68d33af63268d41340d8885df2ab6470f2e1500147", size = 12608406, upload-time = "2026-05-18T23:33:44.131Z" }, + { url = "https://files.pythonhosted.org/packages/27/83/140f85a466595a16382996a1bf06b2b54bcd597488921b0c9daaeeda72af/numpy-2.4.6-cp311-cp311-win_arm64.whl", hash = "sha256:ed9749eef4cbd126da3dc1d6bcb3a57f5eb7ac6a6484146bdbf743f552dfc577", size = 10479528, upload-time = "2026-05-18T23:33:50.725Z" }, + { url = "https://files.pythonhosted.org/packages/95/2a/3d7b5ac8aac24feaf9ad7ed58f45b0bbc06d37e4338ae84c9f2298b570f9/numpy-2.4.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:001fbb8e08d942dd57599e781f2472269ee7f2755fae407b4f67b2f0b17da3f1", size = 16689119, upload-time = "2026-05-18T23:33:54.065Z" }, + { url = "https://files.pythonhosted.org/packages/ea/12/92c4c131527599e8288d6918e888d88726f84d805d784b771f32408aeaef/numpy-2.4.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ebfb099f8dcf083deef3ac1ca4c1503f387cf76296fcb3816b66f5ecb5f54fdb", size = 14699246, upload-time = "2026-05-18T23:33:57.621Z" }, + { url = "https://files.pythonhosted.org/packages/ad/fe/c0a6b7b2ca128a8fb228575147073b660656734b8ebe4d76c8fd748dcc79/numpy-2.4.6-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:3213d622a0283a39a93d188f3cf72b26862df52fbb4ca3697f51705016523d41", size = 5204410, upload-time = "2026-05-18T23:34:00.302Z" }, + { url = "https://files.pythonhosted.org/packages/f3/d4/9770d14ba719432bb90a421bfd443872ed0f70f7264b64bec12ea363d5fd/numpy-2.4.6-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:357cc07a6d7b0b182ff02249616a03742827ebb1277546b5c7cd7f7620a45698", size = 6551240, upload-time = "2026-05-18T23:34:02.852Z" }, + { url = "https://files.pythonhosted.org/packages/c9/c6/50a46a6205feba2343f1d6d17438107c5dc491ed1c736e6ea68689fd906b/numpy-2.4.6-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f9fb9157b4ce2971008323afe46053787b526ef624fea915b261468a8421a0f", size = 15671012, upload-time = "2026-05-18T23:34:05.485Z" }, + { url = "https://files.pythonhosted.org/packages/99/60/14115e6364fa676c5397c2ad3004e527e9aa487abf5d0706ec81bbd08529/numpy-2.4.6-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:90f9849678c75fe7afa2d348ac842c168b0a4d3d61919687216dfc547976d853", size = 16645538, upload-time = "2026-05-18T23:34:09.265Z" }, + { url = "https://files.pythonhosted.org/packages/ae/c5/693cbe59e57db94d2231fa519ca3978dc9e19da5a8f088588f5c6e947ff2/numpy-2.4.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c1a2af6c6ef86344a6b0db6b97834208bf598db514f2b155042439b62605601a", size = 17020706, upload-time = "2026-05-18T23:34:13.053Z" }, + { url = "https://files.pythonhosted.org/packages/ef/fc/85b7c4eff9b4966ade25c2273cf7e7012e92366c032058653934b37de044/numpy-2.4.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e5805d5a22fd19c8ccff10a9561f9df94436b0545619ea579db2d3c35294bce2", size = 18368541, upload-time = "2026-05-18T23:34:17.024Z" }, + { url = "https://files.pythonhosted.org/packages/f6/81/e1b27545deedce7f4a0b348618c6b62d74e36a4dc9ccd42f3eb2f85eee32/numpy-2.4.6-cp312-cp312-win32.whl", hash = "sha256:e3eeb0aabd6bd5ce64faae67e9935203a6991b4bc2a485a767fbafb2c5125f45", size = 5962825, upload-time = "2026-05-18T23:34:20.3Z" }, + { url = "https://files.pythonhosted.org/packages/ab/ca/feab00bd44aa5fe1ad2c18f08b4d3bb92e26484b0b1d1443897809ed528c/numpy-2.4.6-cp312-cp312-win_amd64.whl", hash = "sha256:d8e8286dd7cea7895157318d1b91cdacac64c479f3cbc8dce548331728484751", size = 12321687, upload-time = "2026-05-18T23:34:23.095Z" }, + { url = "https://files.pythonhosted.org/packages/63/cf/5a6d34850a39d1093558564f77ee8e8e0bee5061151b8f05a55711001ec7/numpy-2.4.6-cp312-cp312-win_arm64.whl", hash = "sha256:4081eb135ac24158bd51cdfbef16f1c64df7063b1143f24731387137c092bec8", size = 10221482, upload-time = "2026-05-18T23:34:25.876Z" }, + { url = "https://files.pythonhosted.org/packages/fb/82/bdab26d7438c6791ca31b7c024ca37c1eab8b726ba236129005cd4a06e45/numpy-2.4.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:511dbaf848decaaaf4b4ca48032619fb3138710c4bf7da7617765edad1ef96b0", size = 16684648, upload-time = "2026-05-18T23:34:29.41Z" }, + { url = "https://files.pythonhosted.org/packages/1b/30/a80189bcc7f5e4258b3fbc3968d909d1756f54d023299ecc39ad6fdb9ef8/numpy-2.4.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bf162abab1c1a736333192707cef898e735a5ca00f38f27eeedf44b39d9e85eb", size = 14693902, upload-time = "2026-05-18T23:34:33.013Z" }, + { url = "https://files.pythonhosted.org/packages/97/12/70b5d0d7c15e1ebb8a6a84a8caa1d19e181d84fb58bb6d70aca29099dec1/numpy-2.4.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:043191bfa8eab18c776647b62723ac9dddece59743b13f49b2016094129c2b3f", size = 5198992, upload-time = "2026-05-18T23:34:36.132Z" }, + { url = "https://files.pythonhosted.org/packages/ba/8c/ebd2a8f8a83541f8d38cc5667e8c2b69cecfd30da6e45693e8158857d44b/numpy-2.4.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:6180d8b35af935aed8ece3a85e0a43f87393ae0ac87c8d2c8bd2c993f7270ef3", size = 6546944, upload-time = "2026-05-18T23:34:38.484Z" }, + { url = "https://files.pythonhosted.org/packages/bb/c5/7b863a97a91671a0338f4253bd3b5a3d3852f0692dae91711c9f4a10e787/numpy-2.4.6-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:72fbe16c6fac95aedf5937fa873445cec2110be35d8a4e9433d7501fd98dae6b", size = 15669392, upload-time = "2026-05-18T23:34:41.257Z" }, + { url = "https://files.pythonhosted.org/packages/a5/9d/3584b9984ca4c047aea75214ce1a4c4c73d849bd71b604264b7f5653f8a8/numpy-2.4.6-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a7830bab239b79cda9c08c2da014761cafb48da6150e1da17ac06283f43b6089", size = 16633220, upload-time = "2026-05-18T23:34:45.075Z" }, + { url = "https://files.pythonhosted.org/packages/05/ae/7c67fba23bd98caec7c99261f3a16072ade14813486b0282cb29846de832/numpy-2.4.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ef4aea96ce4d3b074422cb4f2f64e216bf9e213004bb58ecfdf50ea02ea8eb9a", size = 17020800, upload-time = "2026-05-18T23:34:49.065Z" }, + { url = "https://files.pythonhosted.org/packages/d9/5d/3b6725cb31d983c5e66916f5d36f6d7e5521129e4c4404d64f918292a5b6/numpy-2.4.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:dfa20cc6ca228e6b155b11da03825975ce66aea520985dbbddf0f2a5a495c605", size = 18357600, upload-time = "2026-05-18T23:34:52.709Z" }, + { url = "https://files.pythonhosted.org/packages/f7/da/2ccc6c2fe8898dee01d90c75c5f5f914a23daf99e3e0f59516a08760c8b5/numpy-2.4.6-cp313-cp313-win32.whl", hash = "sha256:56b39e5e0622a09a25bf5baf62f4bcf0cb8a41ae6e2819cf49bbc5a74c083f91", size = 5961134, upload-time = "2026-05-18T23:34:55.618Z" }, + { url = "https://files.pythonhosted.org/packages/b5/cd/9cc4dc876fb065d5c220aae4d5e14826b2715331bb7618ce1fb07a679d99/numpy-2.4.6-cp313-cp313-win_amd64.whl", hash = "sha256:c4fc99836233ea196540b17ab0983aff60ed07941751930f5f4d05bc3b3b7359", size = 12318598, upload-time = "2026-05-18T23:34:58.928Z" }, + { url = "https://files.pythonhosted.org/packages/39/1e/c0bcba1f8694116485fe28fd1be698c278fcda4141c5b0e53a2aed8b12a8/numpy-2.4.6-cp313-cp313-win_arm64.whl", hash = "sha256:a7c711e21628b52034bb5ab8d1bce291f752fcc5e92accc615778acee1ff4778", size = 10222272, upload-time = "2026-05-18T23:35:02.167Z" }, + { url = "https://files.pythonhosted.org/packages/63/6d/cc5619247c8f4204e507f5883528372e4ac4bb189e579fb859a12e480b1f/numpy-2.4.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:112b06a867b235ef466ed3508ddf0238050df9c727cafb5301ac385b899189a1", size = 14821197, upload-time = "2026-05-18T23:35:05.468Z" }, + { url = "https://files.pythonhosted.org/packages/00/58/f1c39161c87d9e9bed660f1ed4bafc0e403d5ec9650b6dd77aead07d489b/numpy-2.4.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:eaf7fa2de5c0be8ae6ff8e9bea2ccd725e980541244521d8d4b5f3354a27babe", size = 5326287, upload-time = "2026-05-18T23:35:08.693Z" }, + { url = "https://files.pythonhosted.org/packages/af/57/3917ab0fd97f271a8694513581b8a36c655f111c446852c302f04ccdb6fc/numpy-2.4.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:7265a2f3d436e54ef9f2b52b5c937e6be778781bd97a590319d7348f1c1ca997", size = 6646763, upload-time = "2026-05-18T23:35:11.459Z" }, + { url = "https://files.pythonhosted.org/packages/eb/0f/037e64c494b67581ae18193d770adef354c41f3f2c8ebf865602d949bf8f/numpy-2.4.6-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20", size = 15728070, upload-time = "2026-05-18T23:35:14.79Z" }, + { url = "https://files.pythonhosted.org/packages/21/a6/5d2bae9c9542eb4df16dc9c46dc79c186e9bad53805dfa5399a6023c6db0/numpy-2.4.6-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ede83e07a75dd06bc501566c1eca2afc0d61677c1472ac9ad93fdee6e638a48d", size = 16681752, upload-time = "2026-05-18T23:35:18.836Z" }, + { url = "https://files.pythonhosted.org/packages/92/14/23d1dfb410ae362cd59ce53e936b1513d545eb40db3949ced632e19a459e/numpy-2.4.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:68bb27509ac1b9a3443094260f6326150663b06abe40b73a2f81160623da5b67", size = 17086024, upload-time = "2026-05-18T23:35:22.52Z" }, + { url = "https://files.pythonhosted.org/packages/4b/6e/23595a2c642cdf3bc567877064bdd7f91c8b0038a4453cf2daf7248eafe9/numpy-2.4.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:a0df0043bdb289bde1f62da130d20df23d58b45429f752bc7a8fc5325a225ecd", size = 18403398, upload-time = "2026-05-18T23:35:26.398Z" }, + { url = "https://files.pythonhosted.org/packages/8a/90/0ac3bc947217e66dec77e7cbc6a1979d1af70b6461b82f620d3bccd5e4c8/numpy-2.4.6-cp313-cp313t-win32.whl", hash = "sha256:29a287e0cf63ff528da061de6b9f64a4618da591ca1046aafc54062e40ca7eab", size = 6084971, upload-time = "2026-05-18T23:35:29.387Z" }, + { url = "https://files.pythonhosted.org/packages/77/71/5673e351671a1d2bd6063b91b44f70c0affea7d1516fa7a6572941ba4aa1/numpy-2.4.6-cp313-cp313t-win_amd64.whl", hash = "sha256:25c692919ac5a01f170a3bfcd62d745b24fd095c353d50812637d6fcab442e75", size = 12458532, upload-time = "2026-05-18T23:35:32.175Z" }, + { url = "https://files.pythonhosted.org/packages/3f/88/19d3503c5046e688f049274b27a3ef3d771152fa80d3ba3d01a3dff61abe/numpy-2.4.6-cp313-cp313t-win_arm64.whl", hash = "sha256:1e978ec1e8bd0e0e4de6bb75de9d30cbb74db6b6a2bb727618613703ca0167dd", size = 10291881, upload-time = "2026-05-18T23:35:35.465Z" }, + { url = "https://files.pythonhosted.org/packages/f8/91/3ab2044d05fd16d343c5ac2e69b127f1b2854040dd20b193257c78028bd3/numpy-2.4.6-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:06ca2f61ec4385a07a6977c55ba998a4466c123642b4a32694d3128fce18c079", size = 16683458, upload-time = "2026-05-18T23:35:38.353Z" }, + { url = "https://files.pythonhosted.org/packages/8e/62/764ce66fa4147ae6d73071a3abf804ffe606f174618697c571acdf26a7c9/numpy-2.4.6-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:38efbc8de75c7a0fc1ac190162d892787f3f47b57cc291231aafee36b80982b7", size = 14704559, upload-time = "2026-05-18T23:35:42.14Z" }, + { url = "https://files.pythonhosted.org/packages/60/61/23f27c172f022e04025b7dc2367f4d63c1a398120607ec896228649a6f48/numpy-2.4.6-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:d581b735e177fdcdce6fed8e7e8880a3fb6ee4e3653a3ac6af01c6f4c03effc5", size = 5209716, upload-time = "2026-05-18T23:35:45.377Z" }, + { url = "https://files.pythonhosted.org/packages/03/71/21cf70dc6ea3e3acb95fc53a265b2fc248b981f0194ceb5b475271b8809d/numpy-2.4.6-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:0a041d3d761dc3c35cc56ce0351506a02bcbc25f7b169f652435141a17db9096", size = 6543947, upload-time = "2026-05-18T23:35:47.926Z" }, + { url = "https://files.pythonhosted.org/packages/d5/91/64288395ee1799bd2e0b04a305dce9666da90c961e1f3fe982a05ee1c036/numpy-2.4.6-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:40fdc1ae7125e518ea98e53e69a4ebc27e1fd50510c47b7ea130cf21e5e1d42b", size = 15685197, upload-time = "2026-05-18T23:35:50.863Z" }, + { url = "https://files.pythonhosted.org/packages/f3/eb/ebffaa97dc55502df69584a8f0dcf07f69a3e0b3e2323670a2722db9aa39/numpy-2.4.6-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8", size = 16638245, upload-time = "2026-05-18T23:35:54.752Z" }, + { url = "https://files.pythonhosted.org/packages/b8/0b/54f9da33128d7e350fab89c7455902eeae70349ee52bddb448dc4a576f45/numpy-2.4.6-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:33111801a01c12a8a1e3721f0a9232f8cfc8ae2c6b7098167e6f623c6073f402", size = 17036587, upload-time = "2026-05-18T23:35:58.355Z" }, + { url = "https://files.pythonhosted.org/packages/b6/f0/fdebc1052db1cc37c64beb22072d67cd6d1c71adca1299f53dec2b5e20d3/numpy-2.4.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ae506e6902902557576a26ff33eda8695e7ecb3cb36c3b573a0765dee114ebdb", size = 18363226, upload-time = "2026-05-18T23:36:02.845Z" }, + { url = "https://files.pythonhosted.org/packages/aa/b4/298628d98c72b57e57f7165ae6a481a1deaf6f3c28262a6e4c739c275930/numpy-2.4.6-cp314-cp314-win32.whl", hash = "sha256:aaf159caa35993cb1f56fb9b8e4610d35758e7ca005412eb1daa856a78c9c4b1", size = 6010196, upload-time = "2026-05-18T23:36:05.92Z" }, + { url = "https://files.pythonhosted.org/packages/df/ac/46de6dda46478f7942f839e094970be2d4a861e005c4b3bf07c92e291a09/numpy-2.4.6-cp314-cp314-win_amd64.whl", hash = "sha256:b507f5c4c1d508876d1819b6bf9a49d365b96320b5d4993426b33a23ca4b8261", size = 12450334, upload-time = "2026-05-18T23:36:09.107Z" }, + { url = "https://files.pythonhosted.org/packages/78/92/b8b798ac784102c0da830d2257d59358e3d3d90d1e2b3f2575dad976c5cf/numpy-2.4.6-cp314-cp314-win_arm64.whl", hash = "sha256:6f41ae150c4e32db4f3310cdaf64b1593a03dbabe29eec77fc9b50fe64061df6", size = 10495678, upload-time = "2026-05-18T23:36:12.766Z" }, + { url = "https://files.pythonhosted.org/packages/30/34/ec28d1aa8115971537c01469ab2011ee96827930f0a124de1000cc2a7ed7/numpy-2.4.6-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ece3d2cfe132e7d51f44a832b303895e6f2d499c5e74dfbdb06ee246147a304a", size = 14823672, upload-time = "2026-05-18T23:36:16.473Z" }, + { url = "https://files.pythonhosted.org/packages/16/bd/f6d1fede4e54e8042a7ff97bb495510f3c220f94bcd9e8b228e87c92cc0d/numpy-2.4.6-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:e3e5193ef5a3dc73bceee50f7fdc2c90dbb76c42df8d8fae3d1067a583df579e", size = 5328731, upload-time = "2026-05-18T23:36:19.767Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f0/e105b9e2fd728a9910103884decd6951d9dd73896b914a98d9a231de02ee/numpy-2.4.6-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:17f9ade344e7d9b464a084d69bcf18fc691cb1db67c62ed80820bf4926d78f0e", size = 6649805, upload-time = "2026-05-18T23:36:22.266Z" }, + { url = "https://files.pythonhosted.org/packages/82/dd/1206a7ca6ab15e3f02069707ca96222e202af681bb73756da7527f3cb837/numpy-2.4.6-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43", size = 15730496, upload-time = "2026-05-18T23:36:25.713Z" }, + { url = "https://files.pythonhosted.org/packages/51/e7/38d3ea825dcab85a591734decb2f6c67caa7c8367d374df1a1c3842f9b07/numpy-2.4.6-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7d92c3819208a60205a12a245c91ad70cb0a85336659b19b834205573ac8456e", size = 16679616, upload-time = "2026-05-18T23:36:29.652Z" }, + { url = "https://files.pythonhosted.org/packages/93/b7/caabfdf53edf663e0b4eb74d7d405d83baef09eb5e83bcd32d601d72b93e/numpy-2.4.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e85b752a1e912b70eaad4fafbd4d1238007ab221de2009b9a2f5ae7461239895", size = 17085145, upload-time = "2026-05-18T23:36:33.449Z" }, + { url = "https://files.pythonhosted.org/packages/f9/45/68d7c33a6bcf3e5aa3bdbd57a367e6f615286dfd6482f97e8ffeb734306e/numpy-2.4.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:29cb7f67d10b479ff07c17d33e39f78c07f71c40ef30d63c153d340e96cd3fb4", size = 18403813, upload-time = "2026-05-18T23:36:37.369Z" }, + { url = "https://files.pythonhosted.org/packages/9c/50/0753655aa844c99cd9e018aacf76f130f1bd81d881bb74bc0aef5d73a8ba/numpy-2.4.6-cp314-cp314t-win32.whl", hash = "sha256:260a5d70215b61ab4fadf5c7baacd64821842975eea312125ed3c39a6391b063", size = 6156982, upload-time = "2026-05-18T23:36:40.817Z" }, + { url = "https://files.pythonhosted.org/packages/b2/d4/7c67becf668f973cb490cec3e98dfd799d866f9c989a54d355672cfa0db6/numpy-2.4.6-cp314-cp314t-win_amd64.whl", hash = "sha256:81a1cca95ed5bb92aa8b10dd2cdc9a0d3853a50fad926c28b5d7e8ea54389627", size = 12638908, upload-time = "2026-05-18T23:36:43.996Z" }, + { url = "https://files.pythonhosted.org/packages/43/bb/e1c71a4295b1b1d1393d50dbb4f2a36283c6859d9d3892e84f00ec5a91d5/numpy-2.4.6-cp314-cp314t-win_arm64.whl", hash = "sha256:0c9136e14ed34a9e343a31c533d78a9813a69a3148332bce5e9821cb2f996e66", size = 10565867, upload-time = "2026-05-18T23:36:47.114Z" }, + { url = "https://files.pythonhosted.org/packages/de/12/b422cc84439adc0d00de605bf4a308890ae5c26f2c71fbd73e5d08fbb0dd/numpy-2.4.6-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:55cced7c52e981362f708ad635198e97a752dfba412cc03c23bbf3bd8d5cd662", size = 16847511, upload-time = "2026-05-18T23:36:50.673Z" }, + { url = "https://files.pythonhosted.org/packages/44/53/f481bef68011740f8849418d82db07230e825013f31f4eef5ba5b805316a/numpy-2.4.6-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d6da64deb6b8ed903e7560180a92f2d804ee1ba5eeb849ac2748b8c1aba1f6d7", size = 14889064, upload-time = "2026-05-18T23:36:53.879Z" }, + { url = "https://files.pythonhosted.org/packages/7f/57/42ed575c10ced8af951d426bc4e1f8aff16fd851db33f067036215a7f860/numpy-2.4.6-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:68a5124b13fa6cc2086764a20005d30bc0548146f7f5322f02fce212ca14317f", size = 5394157, upload-time = "2026-05-18T23:36:57.194Z" }, + { url = "https://files.pythonhosted.org/packages/6a/ef/f66cc724fcc36c1e364c67f51ae9146090b8b584f27d58b97fdae3edd737/numpy-2.4.6-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:948424b06129ce883307e8cff868c31396d8dc7630a59c61d70d98dbe70f222c", size = 6708728, upload-time = "2026-05-18T23:36:59.575Z" }, + { url = "https://files.pythonhosted.org/packages/1a/9c/c531f2293b91265d8b48e9b329f54fdd7ffae73cb4134ea10cca4237e9cc/numpy-2.4.6-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5dbbdb29840ca3d91ee0fece42fc29278886d908280bfec0a5846c6f901a3eb0", size = 15798374, upload-time = "2026-05-18T23:37:02.674Z" }, + { url = "https://files.pythonhosted.org/packages/1a/b0/413077f6b1153ed3cba361401c6783bbad6114804a000cc22eb71c13e190/numpy-2.4.6-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8ad03c0965fb3c692200e74d458ca28c1dbb4ce96f9a479a8aa041ad5fabca02", size = 16747286, upload-time = "2026-05-18T23:37:06.327Z" }, + { url = "https://files.pythonhosted.org/packages/15/ce/e5ec180bc41812edcd8daeb8639d205622c0e8c02259d8ab25a0201b3c2a/numpy-2.4.6-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:2803abfebfc990042cd494d8ce2d5f82e9d847af6d35ec486923aa19dbad5e73", size = 12504263, upload-time = "2026-05-18T23:37:09.715Z" }, +] + +[[package]] +name = "numpy" +version = "2.5.2" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.15' and sys_platform == 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'win32'", + "python_full_version >= '3.15' and sys_platform == 'emscripten'", + "python_full_version == '3.14.*' and sys_platform == 'emscripten'", + "python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] +sdist = { url = "https://files.pythonhosted.org/packages/9a/80/db0b4559e57ec36362bedbb05530a87fafbcb6067708c946967a41d449e7/numpy-2.5.2.tar.gz", hash = "sha256:d482d171c406ae88c5b19cad3b6a1c4c5209f886ab74bc44c2c865c23f52d860", size = 20773161, upload-time = "2026-08-09T13:48:27.962Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/72/dccb0aaf40972777283303919f613964227266d0c13adebb79ac124f1c3e/numpy-2.5.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:14e373cfc6387177e8409dac3c7159be8eb05cd77096cd7c950268b86f62831c", size = 16891693, upload-time = "2026-08-09T13:44:51.702Z" }, + { url = "https://files.pythonhosted.org/packages/60/2e/b5aee50a1f74ac815cf8331812cb8251e29024025de462e0c047641c614c/numpy-2.5.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4bbd96c833ecc8cc069ce518078fc8c60cb9cbfb0fea5b7a803ad65035596d03", size = 11903109, upload-time = "2026-08-09T13:44:55.501Z" }, + { url = "https://files.pythonhosted.org/packages/f3/f4/29e78102a80601cf034d4e9767022cffeca2c3b4c926e1754572ca95593d/numpy-2.5.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:6e8172ddfcf5cf74b811d372b570b83c60bd2de87a6fbfbebdadb4a9bd9c6cbb", size = 5350202, upload-time = "2026-08-09T13:44:58.401Z" }, + { url = "https://files.pythonhosted.org/packages/11/4b/dcd3b7eadaf4035d2c7a4289d232523a6964f602598ef7674e4bd7291f93/numpy-2.5.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:65f188481f1669e26f62b701e8205d19e460fa4a9b52a1414ba382330e4a3414", size = 6687736, upload-time = "2026-08-09T13:45:00.813Z" }, + { url = "https://files.pythonhosted.org/packages/e5/21/4947e0e9d6c9fc2e2ff15b8949049ee44f63adb9cacc729ab8793f97e712/numpy-2.5.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8ee9c4eeb8454b3660a8b53493563c3e121c2fc94fbd72b848ef814ed7b676a9", size = 15612696, upload-time = "2026-08-09T13:45:04.151Z" }, + { url = "https://files.pythonhosted.org/packages/3a/5f/62d28cf019460c7f1394105b4d49d9911a9c444cb77ab0bd95a204c5a6de/numpy-2.5.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3cdec01fa790a186d430433fdd4d4ffb70eed6f0eeb4bf05c8dbe2dce0a9bcb8", size = 16722264, upload-time = "2026-08-09T13:45:07.714Z" }, + { url = "https://files.pythonhosted.org/packages/14/25/3f0be4c1b9fdf5dd5e708a6806978564d7c46a055c000496309ff2a2f8af/numpy-2.5.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7999d4ddb0c4025018373fd787510d46e04c769467af22869707b3c1cfd459ab", size = 16974396, upload-time = "2026-08-09T13:45:11.316Z" }, + { url = "https://files.pythonhosted.org/packages/22/72/6262cbdeeb45da9d971e40715f579d791603ba8ec0b5e2db1ac55454421d/numpy-2.5.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c1f017dc0875c9209d219f97feceb7d54c2661bb243deb4114478e1295808af7", size = 18476044, upload-time = "2026-08-09T13:45:14.869Z" }, + { url = "https://files.pythonhosted.org/packages/36/33/29208b8b075bde62d26a81d14b358c42b0f69b6cabd98d4ff97f37f22b05/numpy-2.5.2-cp312-cp312-win32.whl", hash = "sha256:d6a48072864e3324e194a8fbb3c657bcc5b5c869dbc64c9537b1d5c862572c0a", size = 6072817, upload-time = "2026-08-09T13:45:17.867Z" }, + { url = "https://files.pythonhosted.org/packages/7f/b9/87fea2769fe1c47c1b5b01d8310772c9d1a85d485de7cf386ef7a3332b02/numpy-2.5.2-cp312-cp312-win_amd64.whl", hash = "sha256:28ac63476ec7651484215ee7fa15a1f78b57c14621f01e392afe17b9a1390ce4", size = 12464674, upload-time = "2026-08-09T13:45:20.734Z" }, + { url = "https://files.pythonhosted.org/packages/14/52/032b97e00461ab0809bbe4c588b035620e5a14b8cdee47ecddefc7b17d33/numpy-2.5.2-cp312-cp312-win_arm64.whl", hash = "sha256:27650bb0e7140fa3d37b9923b4803645e0b125d190f326eecfd3f4dad8e8ade1", size = 10397131, upload-time = "2026-08-09T13:45:23.73Z" }, + { url = "https://files.pythonhosted.org/packages/f5/d2/6b24738a0ef4557d189b150046cd07823c50e4273e8aebd651222e24306f/numpy-2.5.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8e4cb9a754c8a0c62eaa88273a5fba3391f4a610d1dee893c0755da31c083f15", size = 16886595, upload-time = "2026-08-09T13:45:27.323Z" }, + { url = "https://files.pythonhosted.org/packages/65/60/f2d208d366f263f39c6e69ed309290717aab41078b6d04c9be2a84fa2a07/numpy-2.5.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:52c808f96484f5571a5cc863775ce50247c17dfb3b0361f8ed6b4b0456f80080", size = 11896845, upload-time = "2026-08-09T13:45:31.638Z" }, + { url = "https://files.pythonhosted.org/packages/3c/79/81e0bf24f4d020a2b1d5cd297a9f60c3f24eeb116f9bba5870443f7b6a4a/numpy-2.5.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:29d81e97f668489cba8ebfd796b9bdd453525d35dd9e162e2daec94bf3fc7740", size = 5343880, upload-time = "2026-08-09T13:45:34.373Z" }, + { url = "https://files.pythonhosted.org/packages/ba/cc/e3141cf06d1a8a2c7e107543fe1269c1d1af760d4d683c0794a4ee1127c2/numpy-2.5.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:afb3f0632d6b2e3ba04dbce8d1e48d321b369138b73830b5ca371a0e8d479d56", size = 6682264, upload-time = "2026-08-09T13:45:36.7Z" }, + { url = "https://files.pythonhosted.org/packages/29/f1/2a64a307d92c5d98f5255a4014eb43bb6103ee477087b61ecae44a3aa9b9/numpy-2.5.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0aadf13b60048d501e05fa699efaf7734e2494f3498a4c2a5521d822640324f3", size = 15609566, upload-time = "2026-08-09T13:45:39.518Z" }, + { url = "https://files.pythonhosted.org/packages/7b/44/59a1eb68e773c4098d107ef34a0dbdeca501d72ffcfbff9a7707343921ce/numpy-2.5.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:29b86ff8a6cc556b47ec6b64b194815cc80e6bf5eedcc6cddfd65318cb0b4eee", size = 16709995, upload-time = "2026-08-09T13:45:43.661Z" }, + { url = "https://files.pythonhosted.org/packages/8a/4c/3e54d4ddbc359a1295f8b633e8106bcd4d7d4a206e82df051bdfb3058755/numpy-2.5.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6950c4b7dd562453090548ba7f5da7e59f57f85663f15d5dcc60e249192f7e59", size = 16972511, upload-time = "2026-08-09T13:45:47.094Z" }, + { url = "https://files.pythonhosted.org/packages/f2/9f/02e371638ebf19b66d46231e4be52999e87f32d1961b113bc45656608b22/numpy-2.5.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b9727f472d2f3888053b8a75ab0cb94745a9de224bb5846dbadc0092101bc71d", size = 18465609, upload-time = "2026-08-09T13:45:50.808Z" }, + { url = "https://files.pythonhosted.org/packages/eb/ae/ad6645abc7a3510fe48e8ea1ab4598166f500057ef4ebf38bfad4f1577de/numpy-2.5.2-cp313-cp313-win32.whl", hash = "sha256:4f9744f9fbdcea0bc552e8f19e1f141f811a3f9bc2be2cc6e86d982cab23e3f4", size = 6070204, upload-time = "2026-08-09T13:45:54.111Z" }, + { url = "https://files.pythonhosted.org/packages/15/20/f3489f86d81ea460b2bcdceaed094142ca6579f6be0ec527b781d39afe68/numpy-2.5.2-cp313-cp313-win_amd64.whl", hash = "sha256:85aaccb24182c25df891ad0ec333585967e115269d5f1b17f2c9ae005bc96657", size = 12460532, upload-time = "2026-08-09T13:45:57.167Z" }, + { url = "https://files.pythonhosted.org/packages/d5/21/35b31dde1b283b79de828b80f876afd8c94e28fe1e9c375f89e261cc4c0d/numpy-2.5.2-cp313-cp313-win_arm64.whl", hash = "sha256:bd68ece1553d2023c09a4226d9e41c586ad2d20594d1a456186c33513d2cb3f2", size = 10396725, upload-time = "2026-08-09T13:46:00.478Z" }, + { url = "https://files.pythonhosted.org/packages/ac/f8/c3b222bf075b50afd8e949a07a15c4b312a4a84bd8102a332bcd953cbbb4/numpy-2.5.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d787cf769c3baeb5f6235e778edb52c08dfa923789b5958f28e6450f96107cb1", size = 16885180, upload-time = "2026-08-09T13:46:03.939Z" }, + { url = "https://files.pythonhosted.org/packages/17/e1/2c1d4b1987795a92b5bbf7c24fe249ab96aa2573ab0d7604802c189d7b86/numpy-2.5.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:24b9dc2e3d84aa58523798805194e23e736f3f6ce2d1a5b92583ae734e6dbda8", size = 11907878, upload-time = "2026-08-09T13:46:07.045Z" }, + { url = "https://files.pythonhosted.org/packages/b9/ee/d08226fc858044355983a6e5b94f08ff6f3969e0a2b160a4a89f0ddb3445/numpy-2.5.2-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:9e9413326d726c2545bfa65d2c0876871e8d8386e77f992c1d426e180bbd4323", size = 5354922, upload-time = "2026-08-09T13:46:10.04Z" }, + { url = "https://files.pythonhosted.org/packages/94/f0/6d3d933056440ebbc5e6bad92065fc6c26a48a84a36b1208580e94eea76c/numpy-2.5.2-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:60e902ac295855348a5ca2ea4c89108989a9f5fddfad3dfc0a8f36b10358567e", size = 6679168, upload-time = "2026-08-09T13:46:12.275Z" }, + { url = "https://files.pythonhosted.org/packages/c4/3b/ecd49dd90033cceb2704d88ca905d4d7d89b0e8c739608754ffd325fa820/numpy-2.5.2-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:50e500dc868e9313530ce12ba470fe50ff3afe3d62993ed6eff652dacd555b65", size = 15624501, upload-time = "2026-08-09T13:46:15.322Z" }, + { url = "https://files.pythonhosted.org/packages/c7/99/461bd36dbdfac6c1c53efa370bd55a83227542d0d118f1677dbf1a3dacd5/numpy-2.5.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:318b9a4c845dbea06708a29c84ee429cc3065048db34cdb799047643492050ee", size = 16713701, upload-time = "2026-08-09T13:46:18.949Z" }, + { url = "https://files.pythonhosted.org/packages/f9/9c/2b251df9e8a5d647b62b0cbc1b90a91850c1cf4859ecb532fd0b4eacff6c/numpy-2.5.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:34c319e2963be042673fb46570501b2f06c41924e17e3563d58646b4380dfb68", size = 16986065, upload-time = "2026-08-09T13:46:23.006Z" }, + { url = "https://files.pythonhosted.org/packages/8f/25/20de43f53ff1390534a124475055a19f01fe10c920a0fd11b8e18d6d6052/numpy-2.5.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f06571a052127dc1b4e8b83029b4d1b20daa2b64a31cdd181fc6bc774e9000eb", size = 18470031, upload-time = "2026-08-09T13:46:27.102Z" }, + { url = "https://files.pythonhosted.org/packages/56/5e/0c577ca308d6da5eb79b546ba10bbe5b60148192194e2da060913b1de4f1/numpy-2.5.2-cp314-cp314-win32.whl", hash = "sha256:2cc779226e476d1e1f08c74068c419e60f41a9e0e069c92f6671d31d5c985e98", size = 6121028, upload-time = "2026-08-09T13:46:30.046Z" }, + { url = "https://files.pythonhosted.org/packages/15/5c/7bcbd5b11f94199073320410cddcbb80cee62415bfeb540874b265c2d922/numpy-2.5.2-cp314-cp314-win_amd64.whl", hash = "sha256:7587f53dfbd5edc0f7b87c6217b4c6d2d1f2ef9c3da70bc1315e7db5f8d7ec9d", size = 12597627, upload-time = "2026-08-09T13:46:32.886Z" }, + { url = "https://files.pythonhosted.org/packages/87/bc/4d0b06fba0da90ccc75af62823cb9dcedb6c9ea0cffa058cb2c9ee773a77/numpy-2.5.2-cp314-cp314-win_arm64.whl", hash = "sha256:3e4c367352d3747784248a227fbec218e193b56f7e6692e3b64fc805478ecfdf", size = 10680414, upload-time = "2026-08-09T13:46:36.036Z" }, + { url = "https://files.pythonhosted.org/packages/cd/17/f429aac9dc08833a0d0f188eba38c532a751b1a1f2ca6018a37b455cb321/numpy-2.5.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b879fb674276e331513fb136b78dbc6bd3c848309e0d841cfd63be3896c4cfc1", size = 12026967, upload-time = "2026-08-09T13:46:39.084Z" }, + { url = "https://files.pythonhosted.org/packages/ca/9f/d0849de96a2a4ceaa16662f18ee13eaa9c0aa418269fdc8c4857c56b11da/numpy-2.5.2-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:fd0d703772bba096843785bd38371e31bb4a0c1151497ad5739d182114a73f7f", size = 5473874, upload-time = "2026-08-09T13:46:42.075Z" }, + { url = "https://files.pythonhosted.org/packages/89/3c/8df216d4a4a5422a3de045301cf7df8ea47286d76f5cb7160b0128ac26b7/numpy-2.5.2-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:3a2f061cebd9e3d23bdcfaaded5e2293a4c6a5b60fa42df85d410a725ce621bf", size = 6789276, upload-time = "2026-08-09T13:46:44.387Z" }, + { url = "https://files.pythonhosted.org/packages/e6/3a/20d7e9891c4ddfadd6ff8d95bf4b29f353d8e1770553de2099880551dfb9/numpy-2.5.2-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6df895598c0edcb41030126c89e0f353b07d93238116143b7405e937359736c4", size = 15659154, upload-time = "2026-08-09T13:46:47.538Z" }, + { url = "https://files.pythonhosted.org/packages/aa/d6/f3aa3d2688bf501b858835c6bd087ae9b51a56ae6fca8e2b0990abd177af/numpy-2.5.2-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1ab3d4a901f844ea836c3e80bf463c6a27d7f3c14e8e292fcf28d348b25b9bce", size = 16748909, upload-time = "2026-08-09T13:46:51.442Z" }, + { url = "https://files.pythonhosted.org/packages/7d/8f/1c5cae8d2baf86ab802ae97a00be55bc7e21ebc11b12bbc33376c5f05342/numpy-2.5.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:cebc2d6dbb605a7703d59751dea4bd6b0ab127a5a4338a6f432df1936fef8b26", size = 17027685, upload-time = "2026-08-09T13:46:55.095Z" }, + { url = "https://files.pythonhosted.org/packages/5c/27/71d3467404aedc1c24ce79610f91b52b0b0f466c43a701aa56fc75c145ab/numpy-2.5.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:eaca7ff36f0f52e2111ec71f169d8fd3e889e7ddc0d2592e0d703fd8d3ce8fac", size = 18501181, upload-time = "2026-08-09T13:46:59.09Z" }, + { url = "https://files.pythonhosted.org/packages/14/2f/42921d27c40aea7e077f4a423ae509fd9220b028cd787bafefd8ab2b3a5f/numpy-2.5.2-cp314-cp314t-win32.whl", hash = "sha256:ddf47472af2e4280d79bac82304f5e80150211f1b9e614b760061d5fdfbb6eba", size = 6271085, upload-time = "2026-08-09T13:47:01.903Z" }, + { url = "https://files.pythonhosted.org/packages/75/e6/bad5f5d56de9b1971bac959963dda276d35c40f1854475005434bbe08692/numpy-2.5.2-cp314-cp314t-win_amd64.whl", hash = "sha256:44ef9675d908e65f9953063837c3277730f3f4437615a4cdab67b366cabaf884", size = 12787971, upload-time = "2026-08-09T13:47:04.963Z" }, + { url = "https://files.pythonhosted.org/packages/df/05/f608795cb34391acd67e38d94a3c36abd8d8576293a3a80727d7595c372c/numpy-2.5.2-cp314-cp314t-win_arm64.whl", hash = "sha256:eaa088384c46f519dacb93b7ec483a6d6b19a4a2085ae4f25ab9b1c43d387d1e", size = 10750306, upload-time = "2026-08-09T13:47:07.976Z" }, + { url = "https://files.pythonhosted.org/packages/33/c6/28de0191c5f82b7d42a0a51390ba98587048aa93a39fafb05bdbe6e8d00c/numpy-2.5.2-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:078f9b027b478c9379b9677babbf0f8b8f1ecfada27636d7b9a93990c638739f", size = 16885274, upload-time = "2026-08-09T13:47:11.439Z" }, + { url = "https://files.pythonhosted.org/packages/dd/d1/973ca116000d244897e468ea1aff30b589e5022e3c8744b71706fe33bd57/numpy-2.5.2-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:50a68f4bacd8a2b33d8da3d2269d0d78500f86ea582e4786dc10f5ef2c2c6842", size = 11907846, upload-time = "2026-08-09T13:47:15.128Z" }, + { url = "https://files.pythonhosted.org/packages/78/d9/8c4b3937ef204cb2fd88d389ccd0f265a2ffb11f35a01d2064cf46714bd6/numpy-2.5.2-cp315-cp315-macosx_14_0_arm64.whl", hash = "sha256:e79aba74ffaf5f78a050d777c184cddf8fdffabab38acf5f3ef1fecbc17895d6", size = 5354892, upload-time = "2026-08-09T13:47:18.07Z" }, + { url = "https://files.pythonhosted.org/packages/74/9b/b6ee65ea2999fdb7023935e108e6fb776ee4082aa15f159acfa857e578c8/numpy-2.5.2-cp315-cp315-macosx_14_0_x86_64.whl", hash = "sha256:9a0731745a72a184490a582fb4af2533512bd071ace67785b5fdffc0ae58dce8", size = 6679309, upload-time = "2026-08-09T13:47:20.456Z" }, + { url = "https://files.pythonhosted.org/packages/43/f3/acb18d8b137a393c8e7803a8c994c9e64bde3930692a69d826993113a159/numpy-2.5.2-cp315-cp315-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4ec954036759bcee3aa484f8603bd9c14f3e776293b85578b8734c2d72777c69", size = 15625850, upload-time = "2026-08-09T13:47:24.365Z" }, + { url = "https://files.pythonhosted.org/packages/a9/bf/a8e9bb0db815a0e265b5744ebedd3af0bd5faad8604e5b50a1cd012f3c91/numpy-2.5.2-cp315-cp315-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dc649493697006bc90614a5f0bbc8cb3cb1866715c474e473694968d7e6b99ab", size = 16713664, upload-time = "2026-08-09T13:47:27.965Z" }, + { url = "https://files.pythonhosted.org/packages/0c/c3/6e913736b3dd6582344af32418b5fb9dab34282e8a8174ae1d54ceb0fc13/numpy-2.5.2-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:cf7de32f486e4ac9e2d93b810f9e9ac72a728dd46a32a0bb403222f27f653514", size = 16986749, upload-time = "2026-08-09T13:47:31.541Z" }, + { url = "https://files.pythonhosted.org/packages/80/09/7d3b23eff5c7428ef6c01e6f7052bb60d504c4d33e317b36b8959c24ad97/numpy-2.5.2-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:2ffa7bacab3e2ee1b19ed31766bb60bb380b68c23f051e199c5cc598afd68710", size = 18470495, upload-time = "2026-08-09T13:47:35.364Z" }, + { url = "https://files.pythonhosted.org/packages/a5/a4/68a321d825374f6eb677ffe8ef8c6b9a328304e6fd2e39d9530822776607/numpy-2.5.2-cp315-cp315-win32.whl", hash = "sha256:6b588cc8f902d6bff201c19fd00c43ab8545671e3554d014e12e14139e5e8617", size = 6120696, upload-time = "2026-08-09T13:47:38.561Z" }, + { url = "https://files.pythonhosted.org/packages/c8/23/deafbb1700f79fae9cd1e91220f133d124cc267de1b584da3fbf6db2f6cd/numpy-2.5.2-cp315-cp315-win_amd64.whl", hash = "sha256:07d4e89f3a9ab0a9ba24264ccdb642b3dd951b2281e8883a5481a4aa79cc31a7", size = 12597324, upload-time = "2026-08-09T13:47:41.401Z" }, + { url = "https://files.pythonhosted.org/packages/33/cd/3272ba105e3bbbdaeb11357eda31e7a6825ffe159e8171665660299a948f/numpy-2.5.2-cp315-cp315-win_arm64.whl", hash = "sha256:a610dc7e3c52edd39c2bc2375ff9c3fd59cb3ad00e4472d36f83bc1457145788", size = 10680466, upload-time = "2026-08-09T13:47:44.873Z" }, + { url = "https://files.pythonhosted.org/packages/0e/0e/58370637b1bb70a5c9ce2b43f4b521ccb224e36ccb76a6596b17ae4b447c/numpy-2.5.2-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:40f4d451aed46a8046a1aae41c4e55fb3612273df9c502480135e1501576a34b", size = 16993947, upload-time = "2026-08-09T13:47:48.97Z" }, + { url = "https://files.pythonhosted.org/packages/10/93/2abcb807712b289d6d60fe4cf30532f98974a8396d885650f3ba5a13026e/numpy-2.5.2-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:c081cbe16ba1ab53078e5ff29013621e33c509eedab055775d956427712c236e", size = 12025331, upload-time = "2026-08-09T13:47:52.646Z" }, + { url = "https://files.pythonhosted.org/packages/8b/3a/2898e003a5fbaf87e76c039b4ee1f5eb390471b4ffe74887c1f34c4e791e/numpy-2.5.2-cp315-cp315t-macosx_14_0_arm64.whl", hash = "sha256:0090ccdd57ec2703e9b49d0bf554767370581c1dd0a6b2bb2b2d9def317d042a", size = 5472336, upload-time = "2026-08-09T13:47:55.403Z" }, + { url = "https://files.pythonhosted.org/packages/61/a5/23f69d07c544597b29758b31b55c27dc9d541012a2c1496189fef702aec2/numpy-2.5.2-cp315-cp315t-macosx_14_0_x86_64.whl", hash = "sha256:6a9bb119fb8dd21ba30b3f0e555b7e2b081bd9883af21ec9c1c633d161cda3a8", size = 6788387, upload-time = "2026-08-09T13:47:58.192Z" }, + { url = "https://files.pythonhosted.org/packages/15/ea/c0dbdbcf22f43782510a3e492dd3da73c6112b69cac8929d16d127536fc4/numpy-2.5.2-cp315-cp315t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a839318485284a6fb31be4f8f2c91c8f2cb22f4543c4a8903f12b0671ffe07cc", size = 15667096, upload-time = "2026-08-09T13:48:01.562Z" }, + { url = "https://files.pythonhosted.org/packages/fc/5e/29c73c31748cdb0f7566642125ba17fd5b56780cddf891b085dab27e4466/numpy-2.5.2-cp315-cp315t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba0a474801b8dc67b66bf465548abc90e82b44d2611b5770f33008dcabffe8ec", size = 16751730, upload-time = "2026-08-09T13:48:05.706Z" }, + { url = "https://files.pythonhosted.org/packages/47/95/02501e8454796bb58dadf7a99d3181e0b464bf264e1003039572f9779fac/numpy-2.5.2-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:0a4035ae1129ff8777f08bfbd44f1e5d8e9c049ce0c2dd78fc0d92c13e7251c0", size = 17038686, upload-time = "2026-08-09T13:48:09.627Z" }, + { url = "https://files.pythonhosted.org/packages/0e/b5/53a681d91b5c82687067d8ea5035e02d917b5509d6f334cb06484a954714/numpy-2.5.2-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:77843ca236b777e67f8d6b3660ea116e499612703a0ecd7093f316201eb9d8e2", size = 18507727, upload-time = "2026-08-09T13:48:13.744Z" }, + { url = "https://files.pythonhosted.org/packages/42/06/6e11443f7b64ee376c860506091103bf68f92d2cab9e8d96d4501babf07c/numpy-2.5.2-cp315-cp315t-win32.whl", hash = "sha256:7354826bc6f8f69402e9b7fe28d15fcd34feebd74f856f111585c5b0c9fb0251", size = 6269775, upload-time = "2026-08-09T13:48:17.543Z" }, + { url = "https://files.pythonhosted.org/packages/f1/18/195d6b86cd72dbbc501edfa778005fa6b87afd34c153e46028cd3a0938f4/numpy-2.5.2-cp315-cp315t-win_amd64.whl", hash = "sha256:e5651f3f87add730ee6608d915009e19c911fba0cb000c7e3ea994b7d768eb12", size = 12782559, upload-time = "2026-08-09T13:48:21.023Z" }, + { url = "https://files.pythonhosted.org/packages/b4/07/458c344f0f0c178f4481dad5cca790626ffe4c34eabf9467069d06ee4999/numpy-2.5.2-cp315-cp315t-win_arm64.whl", hash = "sha256:5f8e00be2ec6f45f4e8a41a527f68d44a7d96fee92a650e4d8b1326f77f61e6e", size = 10748103, upload-time = "2026-08-09T13:48:24.21Z" }, +] + +[[package]] +name = "packaging" +version = "26.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/fa/3944b40b07da9ce895c0e6303a5ab7d53da063554f534556b134a54d6093/packaging-26.3.tar.gz", hash = "sha256:94edc256424af38762eb31306eed28beb9f0efc50a8837492c9d6fd6004aed79", size = 313412, upload-time = "2026-08-04T18:15:28.737Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/63/34/ba1c580383c9eada3711951fef0795c80b829a078d72188184bcab9dd527/packaging-26.3-py3-none-any.whl", hash = "sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c", size = 129956, upload-time = "2026-08-04T18:15:27.159Z" }, +] + +[[package]] +name = "paginate" +version = "0.5.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ec/46/68dde5b6bc00c1296ec6466ab27dddede6aec9af1b99090e1107091b3b84/paginate-0.5.7.tar.gz", hash = "sha256:22bd083ab41e1a8b4f3690544afb2c60c25e5c9a63a30fa2f483f6c60c8e5945", size = 19252, upload-time = "2024-08-25T14:17:24.139Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl", hash = "sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591", size = 13746, upload-time = "2024-08-25T14:17:22.55Z" }, +] + +[[package]] +name = "pandas" +version = "2.3.3" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.11'", +] +dependencies = [ + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "python-dateutil", marker = "python_full_version < '3.11'" }, + { name = "pytz", marker = "python_full_version < '3.11'" }, + { name = "tzdata", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223, upload-time = "2025-09-29T23:34:51.853Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3d/f7/f425a00df4fcc22b292c6895c6831c0c8ae1d9fac1e024d16f98a9ce8749/pandas-2.3.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:376c6446ae31770764215a6c937f72d917f214b43560603cd60da6408f183b6c", size = 11555763, upload-time = "2025-09-29T23:16:53.287Z" }, + { url = "https://files.pythonhosted.org/packages/13/4f/66d99628ff8ce7857aca52fed8f0066ce209f96be2fede6cef9f84e8d04f/pandas-2.3.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e19d192383eab2f4ceb30b412b22ea30690c9e618f78870357ae1d682912015a", size = 10801217, upload-time = "2025-09-29T23:17:04.522Z" }, + { url = "https://files.pythonhosted.org/packages/1d/03/3fc4a529a7710f890a239cc496fc6d50ad4a0995657dccc1d64695adb9f4/pandas-2.3.3-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5caf26f64126b6c7aec964f74266f435afef1c1b13da3b0636c7518a1fa3e2b1", size = 12148791, upload-time = "2025-09-29T23:17:18.444Z" }, + { url = "https://files.pythonhosted.org/packages/40/a8/4dac1f8f8235e5d25b9955d02ff6f29396191d4e665d71122c3722ca83c5/pandas-2.3.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dd7478f1463441ae4ca7308a70e90b33470fa593429f9d4c578dd00d1fa78838", size = 12769373, upload-time = "2025-09-29T23:17:35.846Z" }, + { url = "https://files.pythonhosted.org/packages/df/91/82cc5169b6b25440a7fc0ef3a694582418d875c8e3ebf796a6d6470aa578/pandas-2.3.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4793891684806ae50d1288c9bae9330293ab4e083ccd1c5e383c34549c6e4250", size = 13200444, upload-time = "2025-09-29T23:17:49.341Z" }, + { url = "https://files.pythonhosted.org/packages/10/ae/89b3283800ab58f7af2952704078555fa60c807fff764395bb57ea0b0dbd/pandas-2.3.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:28083c648d9a99a5dd035ec125d42439c6c1c525098c58af0fc38dd1a7a1b3d4", size = 13858459, upload-time = "2025-09-29T23:18:03.722Z" }, + { url = "https://files.pythonhosted.org/packages/85/72/530900610650f54a35a19476eca5104f38555afccda1aa11a92ee14cb21d/pandas-2.3.3-cp310-cp310-win_amd64.whl", hash = "sha256:503cf027cf9940d2ceaa1a93cfb5f8c8c7e6e90720a2850378f0b3f3b1e06826", size = 11346086, upload-time = "2025-09-29T23:18:18.505Z" }, + { url = "https://files.pythonhosted.org/packages/c1/fa/7ac648108144a095b4fb6aa3de1954689f7af60a14cf25583f4960ecb878/pandas-2.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:602b8615ebcc4a0c1751e71840428ddebeb142ec02c786e8ad6b1ce3c8dec523", size = 11578790, upload-time = "2025-09-29T23:18:30.065Z" }, + { url = "https://files.pythonhosted.org/packages/9b/35/74442388c6cf008882d4d4bdfc4109be87e9b8b7ccd097ad1e7f006e2e95/pandas-2.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8fe25fc7b623b0ef6b5009149627e34d2a4657e880948ec3c840e9402e5c1b45", size = 10833831, upload-time = "2025-09-29T23:38:56.071Z" }, + { url = "https://files.pythonhosted.org/packages/fe/e4/de154cbfeee13383ad58d23017da99390b91d73f8c11856f2095e813201b/pandas-2.3.3-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b468d3dad6ff947df92dcb32ede5b7bd41a9b3cceef0a30ed925f6d01fb8fa66", size = 12199267, upload-time = "2025-09-29T23:18:41.627Z" }, + { url = "https://files.pythonhosted.org/packages/bf/c9/63f8d545568d9ab91476b1818b4741f521646cbdd151c6efebf40d6de6f7/pandas-2.3.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b98560e98cb334799c0b07ca7967ac361a47326e9b4e5a7dfb5ab2b1c9d35a1b", size = 12789281, upload-time = "2025-09-29T23:18:56.834Z" }, + { url = "https://files.pythonhosted.org/packages/f2/00/a5ac8c7a0e67fd1a6059e40aa08fa1c52cc00709077d2300e210c3ce0322/pandas-2.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37b5848ba49824e5c30bedb9c830ab9b7751fd049bc7914533e01c65f79791", size = 13240453, upload-time = "2025-09-29T23:19:09.247Z" }, + { url = "https://files.pythonhosted.org/packages/27/4d/5c23a5bc7bd209231618dd9e606ce076272c9bc4f12023a70e03a86b4067/pandas-2.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:db4301b2d1f926ae677a751eb2bd0e8c5f5319c9cb3f88b0becbbb0b07b34151", size = 13890361, upload-time = "2025-09-29T23:19:25.342Z" }, + { url = "https://files.pythonhosted.org/packages/8e/59/712db1d7040520de7a4965df15b774348980e6df45c129b8c64d0dbe74ef/pandas-2.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:f086f6fe114e19d92014a1966f43a3e62285109afe874f067f5abbdcbb10e59c", size = 11348702, upload-time = "2025-09-29T23:19:38.296Z" }, + { url = "https://files.pythonhosted.org/packages/9c/fb/231d89e8637c808b997d172b18e9d4a4bc7bf31296196c260526055d1ea0/pandas-2.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d21f6d74eb1725c2efaa71a2bfc661a0689579b58e9c0ca58a739ff0b002b53", size = 11597846, upload-time = "2025-09-29T23:19:48.856Z" }, + { url = "https://files.pythonhosted.org/packages/5c/bd/bf8064d9cfa214294356c2d6702b716d3cf3bb24be59287a6a21e24cae6b/pandas-2.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3fd2f887589c7aa868e02632612ba39acb0b8948faf5cc58f0850e165bd46f35", size = 10729618, upload-time = "2025-09-29T23:39:08.659Z" }, + { url = "https://files.pythonhosted.org/packages/57/56/cf2dbe1a3f5271370669475ead12ce77c61726ffd19a35546e31aa8edf4e/pandas-2.3.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ecaf1e12bdc03c86ad4a7ea848d66c685cb6851d807a26aa245ca3d2017a1908", size = 11737212, upload-time = "2025-09-29T23:19:59.765Z" }, + { url = "https://files.pythonhosted.org/packages/e5/63/cd7d615331b328e287d8233ba9fdf191a9c2d11b6af0c7a59cfcec23de68/pandas-2.3.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b3d11d2fda7eb164ef27ffc14b4fcab16a80e1ce67e9f57e19ec0afaf715ba89", size = 12362693, upload-time = "2025-09-29T23:20:14.098Z" }, + { url = "https://files.pythonhosted.org/packages/a6/de/8b1895b107277d52f2b42d3a6806e69cfef0d5cf1d0ba343470b9d8e0a04/pandas-2.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a68e15f780eddf2b07d242e17a04aa187a7ee12b40b930bfdd78070556550e98", size = 12771002, upload-time = "2025-09-29T23:20:26.76Z" }, + { url = "https://files.pythonhosted.org/packages/87/21/84072af3187a677c5893b170ba2c8fbe450a6ff911234916da889b698220/pandas-2.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:371a4ab48e950033bcf52b6527eccb564f52dc826c02afd9a1bc0ab731bba084", size = 13450971, upload-time = "2025-09-29T23:20:41.344Z" }, + { url = "https://files.pythonhosted.org/packages/86/41/585a168330ff063014880a80d744219dbf1dd7a1c706e75ab3425a987384/pandas-2.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:a16dcec078a01eeef8ee61bf64074b4e524a2a3f4b3be9326420cabe59c4778b", size = 10992722, upload-time = "2025-09-29T23:20:54.139Z" }, + { url = "https://files.pythonhosted.org/packages/cd/4b/18b035ee18f97c1040d94debd8f2e737000ad70ccc8f5513f4eefad75f4b/pandas-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:56851a737e3470de7fa88e6131f41281ed440d29a9268dcbf0002da5ac366713", size = 11544671, upload-time = "2025-09-29T23:21:05.024Z" }, + { url = "https://files.pythonhosted.org/packages/31/94/72fac03573102779920099bcac1c3b05975c2cb5f01eac609faf34bed1ca/pandas-2.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdcd9d1167f4885211e401b3036c0c8d9e274eee67ea8d0758a256d60704cfe8", size = 10680807, upload-time = "2025-09-29T23:21:15.979Z" }, + { url = "https://files.pythonhosted.org/packages/16/87/9472cf4a487d848476865321de18cc8c920b8cab98453ab79dbbc98db63a/pandas-2.3.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e32e7cc9af0f1cc15548288a51a3b681cc2a219faa838e995f7dc53dbab1062d", size = 11709872, upload-time = "2025-09-29T23:21:27.165Z" }, + { url = "https://files.pythonhosted.org/packages/15/07/284f757f63f8a8d69ed4472bfd85122bd086e637bf4ed09de572d575a693/pandas-2.3.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac", size = 12306371, upload-time = "2025-09-29T23:21:40.532Z" }, + { url = "https://files.pythonhosted.org/packages/33/81/a3afc88fca4aa925804a27d2676d22dcd2031c2ebe08aabd0ae55b9ff282/pandas-2.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e0a175408804d566144e170d0476b15d78458795bb18f1304fb94160cabf40c", size = 12765333, upload-time = "2025-09-29T23:21:55.77Z" }, + { url = "https://files.pythonhosted.org/packages/8d/0f/b4d4ae743a83742f1153464cf1a8ecfafc3ac59722a0b5c8602310cb7158/pandas-2.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93c2d9ab0fc11822b5eece72ec9587e172f63cff87c00b062f6e37448ced4493", size = 13418120, upload-time = "2025-09-29T23:22:10.109Z" }, + { url = "https://files.pythonhosted.org/packages/4f/c7/e54682c96a895d0c808453269e0b5928a07a127a15704fedb643e9b0a4c8/pandas-2.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:f8bfc0e12dc78f777f323f55c58649591b2cd0c43534e8355c51d3fede5f4dee", size = 10993991, upload-time = "2025-09-29T23:25:04.889Z" }, + { url = "https://files.pythonhosted.org/packages/f9/ca/3f8d4f49740799189e1395812f3bf23b5e8fc7c190827d55a610da72ce55/pandas-2.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:75ea25f9529fdec2d2e93a42c523962261e567d250b0013b16210e1d40d7c2e5", size = 12048227, upload-time = "2025-09-29T23:22:24.343Z" }, + { url = "https://files.pythonhosted.org/packages/0e/5a/f43efec3e8c0cc92c4663ccad372dbdff72b60bdb56b2749f04aa1d07d7e/pandas-2.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74ecdf1d301e812db96a465a525952f4dde225fdb6d8e5a521d47e1f42041e21", size = 11411056, upload-time = "2025-09-29T23:22:37.762Z" }, + { url = "https://files.pythonhosted.org/packages/46/b1/85331edfc591208c9d1a63a06baa67b21d332e63b7a591a5ba42a10bb507/pandas-2.3.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6435cb949cb34ec11cc9860246ccb2fdc9ecd742c12d3304989017d53f039a78", size = 11645189, upload-time = "2025-09-29T23:22:51.688Z" }, + { url = "https://files.pythonhosted.org/packages/44/23/78d645adc35d94d1ac4f2a3c4112ab6f5b8999f4898b8cdf01252f8df4a9/pandas-2.3.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:900f47d8f20860de523a1ac881c4c36d65efcb2eb850e6948140fa781736e110", size = 12121912, upload-time = "2025-09-29T23:23:05.042Z" }, + { url = "https://files.pythonhosted.org/packages/53/da/d10013df5e6aaef6b425aa0c32e1fc1f3e431e4bcabd420517dceadce354/pandas-2.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a45c765238e2ed7d7c608fc5bc4a6f88b642f2f01e70c0c23d2224dd21829d86", size = 12712160, upload-time = "2025-09-29T23:23:28.57Z" }, + { url = "https://files.pythonhosted.org/packages/bd/17/e756653095a083d8a37cbd816cb87148debcfcd920129b25f99dd8d04271/pandas-2.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4fc4c21971a1a9f4bdb4c73978c7f7256caa3e62b323f70d6cb80db583350bc", size = 13199233, upload-time = "2025-09-29T23:24:24.876Z" }, + { url = "https://files.pythonhosted.org/packages/04/fd/74903979833db8390b73b3a8a7d30d146d710bd32703724dd9083950386f/pandas-2.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ee15f284898e7b246df8087fc82b87b01686f98ee67d85a17b7ab44143a3a9a0", size = 11540635, upload-time = "2025-09-29T23:25:52.486Z" }, + { url = "https://files.pythonhosted.org/packages/21/00/266d6b357ad5e6d3ad55093a7e8efc7dd245f5a842b584db9f30b0f0a287/pandas-2.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1611aedd912e1ff81ff41c745822980c49ce4a7907537be8692c8dbc31924593", size = 10759079, upload-time = "2025-09-29T23:26:33.204Z" }, + { url = "https://files.pythonhosted.org/packages/ca/05/d01ef80a7a3a12b2f8bbf16daba1e17c98a2f039cbc8e2f77a2c5a63d382/pandas-2.3.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d2cefc361461662ac48810cb14365a365ce864afe85ef1f447ff5a1e99ea81c", size = 11814049, upload-time = "2025-09-29T23:27:15.384Z" }, + { url = "https://files.pythonhosted.org/packages/15/b2/0e62f78c0c5ba7e3d2c5945a82456f4fac76c480940f805e0b97fcbc2f65/pandas-2.3.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ee67acbbf05014ea6c763beb097e03cd629961c8a632075eeb34247120abcb4b", size = 12332638, upload-time = "2025-09-29T23:27:51.625Z" }, + { url = "https://files.pythonhosted.org/packages/c5/33/dd70400631b62b9b29c3c93d2feee1d0964dc2bae2e5ad7a6c73a7f25325/pandas-2.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c46467899aaa4da076d5abc11084634e2d197e9460643dd455ac3db5856b24d6", size = 12886834, upload-time = "2025-09-29T23:28:21.289Z" }, + { url = "https://files.pythonhosted.org/packages/d3/18/b5d48f55821228d0d2692b34fd5034bb185e854bdb592e9c640f6290e012/pandas-2.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6253c72c6a1d990a410bc7de641d34053364ef8bcd3126f7e7450125887dffe3", size = 13409925, upload-time = "2025-09-29T23:28:58.261Z" }, + { url = "https://files.pythonhosted.org/packages/a6/3d/124ac75fcd0ecc09b8fdccb0246ef65e35b012030defb0e0eba2cbbbe948/pandas-2.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:1b07204a219b3b7350abaae088f451860223a52cfb8a6c53358e7948735158e5", size = 11109071, upload-time = "2025-09-29T23:32:27.484Z" }, + { url = "https://files.pythonhosted.org/packages/89/9c/0e21c895c38a157e0faa1fb64587a9226d6dd46452cac4532d80c3c4a244/pandas-2.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2462b1a365b6109d275250baaae7b760fd25c726aaca0054649286bcfbb3e8ec", size = 12048504, upload-time = "2025-09-29T23:29:31.47Z" }, + { url = "https://files.pythonhosted.org/packages/d7/82/b69a1c95df796858777b68fbe6a81d37443a33319761d7c652ce77797475/pandas-2.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0242fe9a49aa8b4d78a4fa03acb397a58833ef6199e9aa40a95f027bb3a1b6e7", size = 11410702, upload-time = "2025-09-29T23:29:54.591Z" }, + { url = "https://files.pythonhosted.org/packages/f9/88/702bde3ba0a94b8c73a0181e05144b10f13f29ebfc2150c3a79062a8195d/pandas-2.3.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a21d830e78df0a515db2b3d2f5570610f5e6bd2e27749770e8bb7b524b89b450", size = 11634535, upload-time = "2025-09-29T23:30:21.003Z" }, + { url = "https://files.pythonhosted.org/packages/a4/1e/1bac1a839d12e6a82ec6cb40cda2edde64a2013a66963293696bbf31fbbb/pandas-2.3.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e3ebdb170b5ef78f19bfb71b0dc5dc58775032361fa188e814959b74d726dd5", size = 12121582, upload-time = "2025-09-29T23:30:43.391Z" }, + { url = "https://files.pythonhosted.org/packages/44/91/483de934193e12a3b1d6ae7c8645d083ff88dec75f46e827562f1e4b4da6/pandas-2.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d051c0e065b94b7a3cea50eb1ec32e912cd96dba41647eb24104b6c6c14c5788", size = 12699963, upload-time = "2025-09-29T23:31:10.009Z" }, + { url = "https://files.pythonhosted.org/packages/70/44/5191d2e4026f86a2a109053e194d3ba7a31a2d10a9c2348368c63ed4e85a/pandas-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87", size = 13202175, upload-time = "2025-09-29T23:31:59.173Z" }, +] + +[[package]] +name = "pandas" +version = "3.0.5" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.15' and sys_platform == 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'win32'", + "python_full_version >= '3.15' and sys_platform == 'emscripten'", + "python_full_version == '3.14.*' and sys_platform == 'emscripten'", + "python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'emscripten'", + "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] +dependencies = [ + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "numpy", version = "2.5.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "python-dateutil", marker = "python_full_version >= '3.11'" }, + { name = "tzdata", marker = "(python_full_version >= '3.11' and sys_platform == 'emscripten') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/be/4f/5f3422a2afec5ffc46308b79e53291365a93748b498ac2e58bead0197916/pandas-3.0.5.tar.gz", hash = "sha256:dca3734d6ab7c906e6730f0788b0a1dbb9f2467731f9711f77995c8e9d62d712", size = 4658219, upload-time = "2026-07-22T22:19:28.819Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/ef/f1fd7431d635bf20015489bf0bd69c17fff1018de773540f651455a3916b/pandas-3.0.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2946e77e4a53cd248cbde631a12f0e51c8324ce354c3eba4d20147c1ad6f4282", size = 10397178, upload-time = "2026-07-22T22:17:48.274Z" }, + { url = "https://files.pythonhosted.org/packages/31/b4/0eafac990a431561187694126de01f9b12559549b4d86360c0c4bd870fde/pandas-3.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:71ecc8fb7ed1a7aa4392316b5309a6347e8e7f832f38fd897846b3a1457a9298", size = 9990736, upload-time = "2026-07-22T22:17:52.388Z" }, + { url = "https://files.pythonhosted.org/packages/de/21/359880af3ea9b7cb23bea5b51e8e70ef3866c03be09da9a2787e18e330a8/pandas-3.0.5-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b173f5951ff6b8b0ec7675e20dff3c97b7e7a57dfcce387c2d7c5afe87cb7899", size = 10814438, upload-time = "2026-07-22T22:17:54.708Z" }, + { url = "https://files.pythonhosted.org/packages/d1/50/d6cc4d7e508bbccf5d6027314a8312bc7ac73d0ec7f195f53838daafab40/pandas-3.0.5-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2c0cf1dd9b55a22d105fc46c1b489af3bd42264fcba7c66297bf47a9a1d9c78a", size = 11323634, upload-time = "2026-07-22T22:17:56.858Z" }, + { url = "https://files.pythonhosted.org/packages/70/2b/d5f0a8c90dd0ae04e64ba53b871afb796ec026b615086d382ddc2ade729b/pandas-3.0.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0fac0010c75e4efb6b99e249c183a8993ce0dc95c240f9b120a5e67c727b7928", size = 11850860, upload-time = "2026-07-22T22:17:59.1Z" }, + { url = "https://files.pythonhosted.org/packages/5c/30/183aec2e19adf778a98d29b5729a0a68f4cc4ebf9b9c3b70d0297355bcb1/pandas-3.0.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:08d24fe11a17dc33bd6e937dc9c665f9cba08fbdc9f657f405713515febe300d", size = 12411100, upload-time = "2026-07-22T22:18:01.485Z" }, + { url = "https://files.pythonhosted.org/packages/fa/9a/31f4983f191af51ab2a8f2d0c7b33dff3a84da26533f982fff02c2f9e28b/pandas-3.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:b1261758dfb6cf12c3cff8300e21cefad30e7ec709abb4c24ac7318e6a52462a", size = 9968804, upload-time = "2026-07-22T22:18:03.903Z" }, + { url = "https://files.pythonhosted.org/packages/49/97/7886c89a39045c69ad82cbceaf3343810480c8ef49a216319ce8183860a6/pandas-3.0.5-cp311-cp311-win_arm64.whl", hash = "sha256:679f4e85b30ddb1515458ab1e788d3e260eae369b1f78da7a3aa4cac8ebf4a2a", size = 9205447, upload-time = "2026-07-22T22:18:06.134Z" }, + { url = "https://files.pythonhosted.org/packages/1c/54/1dc810ea558d1320b597aa140a514f2fdf1d2ea09c38cf556f13ea712ec9/pandas-3.0.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fa290c16964d4963fbfbc358928239cf3bd755b20e988ce944877def2f44471d", size = 10411717, upload-time = "2026-07-22T22:18:08.307Z" }, + { url = "https://files.pythonhosted.org/packages/68/56/fbe81c09195924d8b7b8d4461a20458fe80a6a5ed6b24f0314da684277e1/pandas-3.0.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c2e26bb46934b8a2ca0c3de1d3d606fc5f6746584791b2db264d58cf370e08dc", size = 9957095, upload-time = "2026-07-22T22:18:10.6Z" }, + { url = "https://files.pythonhosted.org/packages/e0/51/fac252f4a913ed5eabf3c11b880a9e8d5a6c10f0b2129d0462212d238b4d/pandas-3.0.5-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:73fa87b08a7ef706f8aafda39ddaccf2a99047bea62d8c88a0361bcafb2237bc", size = 10485458, upload-time = "2026-07-22T22:18:12.834Z" }, + { url = "https://files.pythonhosted.org/packages/12/98/e976540c1addf70442be7842a18cf70884a964abbf69442504f4d2939989/pandas-3.0.5-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d373ce03ffd84010ed9839fa73672a9c8256990532e158440c0085db7d914b34", size = 10998091, upload-time = "2026-07-22T22:18:15.209Z" }, + { url = "https://files.pythonhosted.org/packages/a4/8c/1f29b5be8d3fc47dd7567eb167fabba2085879b31e0287ce7cba6d3d2ff4/pandas-3.0.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2a29c53d85ea98c5e792c59ef82ee9fbe6ca902c0d0adb6b23f45ef894cd7bf6", size = 11499501, upload-time = "2026-07-22T22:18:17.689Z" }, + { url = "https://files.pythonhosted.org/packages/9d/e2/bd9c98ad2df7b38bde002adde4cdf353519da51881634323b126c55997f9/pandas-3.0.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a5ad3b02ed6bc7d7ae9b70804b2c6aa31827489d150f8e623ce82491b82085d7", size = 12060559, upload-time = "2026-07-22T22:18:20.147Z" }, + { url = "https://files.pythonhosted.org/packages/f3/9a/ffbd852d58bd74a617fe2f8ee6a58a96982271ce41cf981eab22190b4a4b/pandas-3.0.5-cp312-cp312-pyemscripten_2024_0_wasm32.whl", hash = "sha256:b2acb4650527eec6822c3dadb2b771277b65e7dae7a267d4bccf65fd1bb3fbce", size = 7197652, upload-time = "2026-07-22T22:18:22.502Z" }, + { url = "https://files.pythonhosted.org/packages/70/b5/d2d3e9ae73362ba4229651b0ee1455cf78073a1ce585f6ff693782ce263e/pandas-3.0.5-cp312-cp312-win_amd64.whl", hash = "sha256:80a611068e8a3ac23f7398c6c14eb46dc974e5cc9997f653e2dcfd1da74edd41", size = 9831691, upload-time = "2026-07-22T22:18:24.534Z" }, + { url = "https://files.pythonhosted.org/packages/52/51/dea1e89d6a6796b9c43f85a09b484ee03edb8a4c4842e73e200a8c11301c/pandas-3.0.5-cp312-cp312-win_arm64.whl", hash = "sha256:25ff585b972a18ef1fe9ffa3ac6544d9950508aa76832e5147640b6022821e49", size = 9105796, upload-time = "2026-07-22T22:18:27.064Z" }, + { url = "https://files.pythonhosted.org/packages/bf/09/7b95c4a0025227d6f118c4039b423412ac6a982db02864166185d812fbc7/pandas-3.0.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c1c05a767fe8e5b4fe9e1c29806829c582052eaedb9120a3da83ba3f69e24a5b", size = 10385742, upload-time = "2026-07-22T22:18:29.346Z" }, + { url = "https://files.pythonhosted.org/packages/8d/0c/dc78fd8c4da477b4b5e8ad37295af352190d21ef63a9ee1bc071753074cc/pandas-3.0.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b86765f268b56f7e665b93bce9d5df69dee7f99e595cf8fb839483ab315942a3", size = 9932067, upload-time = "2026-07-22T22:18:31.833Z" }, + { url = "https://files.pythonhosted.org/packages/3e/71/3592c055cf44df9808550f9368ceda80ff2b224d355ef73fe251dcda1802/pandas-3.0.5-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c597ecf5616b5c420372c1d4d4c00dbbfba7398bea857dcc984347e1ea48417b", size = 10466756, upload-time = "2026-07-22T22:18:34.195Z" }, + { url = "https://files.pythonhosted.org/packages/e3/70/4363150359f95b4cb4bcbb34ca23572bb5495749a621a8f3d5a1ddfd293c/pandas-3.0.5-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4b11c36e218331d0387cbe3a0a5f75162357a1d92d57b2b08a336ff94b19b2be", size = 10938525, upload-time = "2026-07-22T22:18:36.81Z" }, + { url = "https://files.pythonhosted.org/packages/f7/d0/317e7a0c67c0e69fa905a0161409397a7dc2d46ff611f6ca4803352c042b/pandas-3.0.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cf52e1f61d229496da17dc7ab54acdee627357e7008fd4fecba3d0ba2937fa58", size = 11489303, upload-time = "2026-07-22T22:18:39.287Z" }, + { url = "https://files.pythonhosted.org/packages/f1/8d/36dade89b49e4f9d5cbdbe863772581f98c0c6d78fc39ad4c557f6f2e17e/pandas-3.0.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:db172144bb56422bd157812f3b021eacc255451470b31e2c633c349490a1cfee", size = 11989004, upload-time = "2026-07-22T22:18:42.208Z" }, + { url = "https://files.pythonhosted.org/packages/9c/ba/18c4ec8a746e177da05a9e7a7963781d8ea195780724f854601b6ebd6b78/pandas-3.0.5-cp313-cp313-win_amd64.whl", hash = "sha256:0d298e951f23016ce4699951d044ae6418dbc91bf68cefca0f77666fcbb4e5c6", size = 9826896, upload-time = "2026-07-22T22:18:44.539Z" }, + { url = "https://files.pythonhosted.org/packages/de/ec/28a57266b753799a87b8bc79e7887ac6fd981b8c6d2978a0b7e7b6bd708c/pandas-3.0.5-cp313-cp313-win_arm64.whl", hash = "sha256:66266d3442a5e8b3c90274c2b8b230bee42dd1c286bc822cc2f9f2c7e12b883e", size = 9094790, upload-time = "2026-07-22T22:18:47.468Z" }, + { url = "https://files.pythonhosted.org/packages/51/2f/cf6aae281264f4463f0875bcbb15fd2bb6d291cc535187dad1732475e4a9/pandas-3.0.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2f264fc46911cc8131a7322a16199bbf8e353d27c10bb211f5bd0c814324dc36", size = 10390034, upload-time = "2026-07-22T22:18:49.818Z" }, + { url = "https://files.pythonhosted.org/packages/06/ec/5189518c7a7659c4bdcc6b1eb32c46c6f3c86b0661ffd84143d1112c7732/pandas-3.0.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:53730687fcd161883b24e10411c06d6a4c0f2275d2faf3bb2bc25deb4ba8007c", size = 9980065, upload-time = "2026-07-22T22:18:52.249Z" }, + { url = "https://files.pythonhosted.org/packages/ea/f1/598503ce8d7e3c35601e0747ba288c7864baae66380725bc12f13f884dfe/pandas-3.0.5-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:960d3ebcf249f75206899fcd2c6de53f736b7265759ced0d3e559df0b8b709b0", size = 10545532, upload-time = "2026-07-22T22:18:54.813Z" }, + { url = "https://files.pythonhosted.org/packages/fa/de/ceae2adf7034e07e9910299fe412e1819c4f0dd520700a888bcb03625448/pandas-3.0.5-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e94c2c5ca43bd3ca32bf64d32308887b65e5f9bfd8023ea52755107a999f93b", size = 10963120, upload-time = "2026-07-22T22:18:57.42Z" }, + { url = "https://files.pythonhosted.org/packages/66/25/86e0f4451874eb79e688deeebe3c451fec4557f8952005818d800ee8ac7e/pandas-3.0.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e819dd5f62966b481a8cb649d3299ebd886a1ea91ed5a99bf7ce77c98d18ab94", size = 11563178, upload-time = "2026-07-22T22:18:59.729Z" }, + { url = "https://files.pythonhosted.org/packages/f3/45/8643daa3b4147e433adfcccefdd0380d3aad79d86b15d8999730fe1944d5/pandas-3.0.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3c5ed2e7c06e91d340dfd091d7934f9bc82e4a36b95f647f090b9d1c9ac649da", size = 12028708, upload-time = "2026-07-22T22:19:02.164Z" }, + { url = "https://files.pythonhosted.org/packages/96/58/ad979ae617615576e8aafd569c9d4b62f1191d896e38f51d66ba06f3b89a/pandas-3.0.5-cp314-cp314-win_amd64.whl", hash = "sha256:cd8f7c6dc98527058ee6264219343f5392240a6f1bfa654fc5d79023020d0c92", size = 9951806, upload-time = "2026-07-22T22:19:04.596Z" }, + { url = "https://files.pythonhosted.org/packages/69/32/7ac03886b304049a9d2625ee88f59af760d8a93bd30ed9239bce7b9869a8/pandas-3.0.5-cp314-cp314-win_arm64.whl", hash = "sha256:5183427f5a8156d480f30333777bc978be93650a49a7c01db26adffe95b31e85", size = 9238297, upload-time = "2026-07-22T22:19:06.836Z" }, + { url = "https://files.pythonhosted.org/packages/be/ed/1d1f2ee5547d5167face2376d11c8b2a4c7bfff5a416ee7a9046891fab1e/pandas-3.0.5-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:303da736987d481074ca720ada325f8bd80c64ebc2d45ed79b29df3aaa4a26ca", size = 10849690, upload-time = "2026-07-22T22:19:09.391Z" }, + { url = "https://files.pythonhosted.org/packages/57/55/17e17152e98fbb0c4b1e562bc65387a2f20a80db0f4a86bf8d3a0e4248d4/pandas-3.0.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3b2801bbb049d0136f6c213eae02b5fca969384fc2064dd728d8620552aa49da", size = 10509945, upload-time = "2026-07-22T22:19:11.773Z" }, + { url = "https://files.pythonhosted.org/packages/88/90/817d44dbf83facf9556f33576d9af0a241981e7bb5c00606c0bcb5df8dda/pandas-3.0.5-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cce3a9d11d2b1f82c69a27ec1f4948a170e2c403c4bbfa8cca62e3fdebe2ef3a", size = 10392197, upload-time = "2026-07-22T22:19:14.024Z" }, + { url = "https://files.pythonhosted.org/packages/f1/da/889f00c0a6f5aa1545add70abbf01502dff87ab577adb855bd631c54d2f2/pandas-3.0.5-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ef01af4d8dc6cd2c8d6c7736f149574ef93fe043811eeb5e445f2647154b5040", size = 10862726, upload-time = "2026-07-22T22:19:16.351Z" }, + { url = "https://files.pythonhosted.org/packages/bc/98/f1e934fb3c98fce859c6147c6785816c7b5b9ab7821115c5d8c4de9842b9/pandas-3.0.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e2759e890db96dfcffdbd9b86c3c2cb6afaf58def482820317e06163ec1066cd", size = 11414864, upload-time = "2026-07-22T22:19:18.981Z" }, + { url = "https://files.pythonhosted.org/packages/fe/be/d448af7d657d82e1888dd8551f79c6d6fb161080b5b9752d84d910ec2319/pandas-3.0.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b58b1b39d46a5862e3fb18f50d1a201398619d16a0f9f73f57eea5583cf0e63c", size = 11925105, upload-time = "2026-07-22T22:19:21.515Z" }, + { url = "https://files.pythonhosted.org/packages/29/c1/ccb4238212c8c4f496c584f3044d94e0c030ed8e1d68999db46c91c2242f/pandas-3.0.5-cp314-cp314t-win_amd64.whl", hash = "sha256:1c10461f6eeb35d8f05b6184c65c8b9991663b66c46b1d559b682cb34ae7c6ea", size = 10387612, upload-time = "2026-07-22T22:19:24.257Z" }, + { url = "https://files.pythonhosted.org/packages/d2/cf/6a51b2c38980e04c279fd2fa908a1b0982064e860444acfca4ec2e2c8359/pandas-3.0.5-cp314-cp314t-win_arm64.whl", hash = "sha256:3c5015fd1730fbf883647e88068176c839c102cea883ba1769a6f4593bfc1f8c", size = 9509776, upload-time = "2026-07-22T22:19:26.694Z" }, +] + +[[package]] +name = "pathspec" +version = "1.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5a/82/42f767fc1c1143d6fd36efb827202a2d997a375e160a71eb2888a925aac1/pathspec-1.1.1.tar.gz", hash = "sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a", size = 135180, upload-time = "2026-04-27T01:46:08.907Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f1/d9/7fb5aa316bc299258e68c73ba3bddbc499654a07f151cba08f6153988714/pathspec-1.1.1-py3-none-any.whl", hash = "sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189", size = 57328, upload-time = "2026-04-27T01:46:07.06Z" }, +] + +[[package]] +name = "pillow" +version = "12.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1c/3d/bb7fca845737cf9d7dbde16ed1843984665ff2e0a518f5db43e77ec540b9/pillow-12.3.0.tar.gz", hash = "sha256:3b8182a766685eaa002637e28b4ec8d6b18819a0c71f579bf0dbaa5830297cce", size = 47025035, upload-time = "2026-07-01T11:56:38.965Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/25/c2/669d88644cddb1485bd9534e63e8cf476c8e51cb3c3a1297677023505c0e/pillow-12.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:6c0016e7b354317c4e9e525b937ac8596c38d2d232b419529b9cd7a1cd46e39a", size = 5392418, upload-time = "2026-07-01T11:53:27.808Z" }, + { url = "https://files.pythonhosted.org/packages/6b/ba/3762f376a2948e3036488d773a146e0ae6ecc2ca03ac20e2615bd0b2ba02/pillow-12.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bcc33feacfaefce60c12fd500a277533bdc02b10a19f7f6d348763d8140bbba7", size = 4785287, upload-time = "2026-07-01T11:53:29.761Z" }, + { url = "https://files.pythonhosted.org/packages/07/50/b5d688cc9c52d4482f3d5bcab6ce20bc2a74a85d2343841c907444a3be2c/pillow-12.3.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5594fc43d548a7ed94949d139aa1341b270f1863f11cfd37f5a6c8b778a6b67f", size = 6253754, upload-time = "2026-07-01T11:53:32.298Z" }, + { url = "https://files.pythonhosted.org/packages/4e/89/36f4cd76cf4baf05c50ababb976249153f18c959171c7f6ba09a6f217260/pillow-12.3.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f0606c8bf2cdefea14a43530f7657cbbb7ecf1c4222512492ef4a4434a9501ec", size = 6925605, upload-time = "2026-07-01T11:53:34.487Z" }, + { url = "https://files.pythonhosted.org/packages/eb/c0/4de58cf6633b9e3a6061ef4be6fb91fc3c90b812ece886f531e3c523d777/pillow-12.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:85f998ea1848bc6757289e739cfbdda3a04adfd58b02fc018ce54d754a5ce468", size = 6327788, upload-time = "2026-07-01T11:53:36.433Z" }, + { url = "https://files.pythonhosted.org/packages/87/3c/14d53682a19550dbbaf3b598f807d5457646c510805a44c7d7891cd1cd1a/pillow-12.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:25b9b82bb22e6e2b3cd07b39c68b7b862001226cb3dff7130d1cb914121b39ed", size = 7036288, upload-time = "2026-07-01T11:53:38.712Z" }, + { url = "https://files.pythonhosted.org/packages/38/1d/36279e3c77efe034e4cc2b0393ee74ffdb5a62391dacbf9b916154f5f0b8/pillow-12.3.0-cp310-cp310-win32.whl", hash = "sha256:37dc8f7bbb66efe481bb60defacef820c950c24713fb44962ed6aa2a50966de1", size = 6472396, upload-time = "2026-07-01T11:53:40.781Z" }, + { url = "https://files.pythonhosted.org/packages/48/7c/8fa0039574c476d7c6fa57dd7c32a130436877c6ec1e5ce1cc8ec44878c1/pillow-12.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:300557495eb45ebb8aec96c2da9c4be642fbf7cd937278b4013ba894ea8eb0eb", size = 7226887, upload-time = "2026-07-01T11:53:42.764Z" }, + { url = "https://files.pythonhosted.org/packages/fa/17/e324be141d173c1c919428066c3259f21c1b8982e564e01a4a81e96dbdcf/pillow-12.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:514435a37670e3e5e08f3945b68718b6ed329bb84367777e16f9f4dfe1e61a0f", size = 2568039, upload-time = "2026-07-01T11:53:45.372Z" }, + { url = "https://files.pythonhosted.org/packages/fb/c8/0a78b0e02d7ac54bc03e5321c9220da52f0c2ea83b21f7c40e7f3169c502/pillow-12.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:00808c5e14ef63ac5161091d242999076604ff74b883423a11e5d7bbb38bf756", size = 5392415, upload-time = "2026-07-01T11:53:47.162Z" }, + { url = "https://files.pythonhosted.org/packages/b2/5b/a02d30018abd97ced9f5a6c63d28597694a00d066516b9c1c6de45859fc9/pillow-12.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:37d6d0a00072fd2948eb22bce7e1475f34569d90c87c59f7a2ec59541b77f7a6", size = 4785266, upload-time = "2026-07-01T11:53:49.079Z" }, + { url = "https://files.pythonhosted.org/packages/c8/98/766667a4be768150a202836acd9fad19c06824ca86c4286d3cf6b274964e/pillow-12.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bcb46e2f9feff8d06323983bd83ed00c201fdcab3d74973e7072a889b3979fcd", size = 6263814, upload-time = "2026-07-01T11:53:51.32Z" }, + { url = "https://files.pythonhosted.org/packages/3b/2d/ede717bc1144f63886c21fd349bb95860b0d1a21149ff16f2bb362b612b6/pillow-12.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23d27a3e0307ec2244cc51e7287b919aa68d097504ebe19df4e76a98a3eea5bd", size = 6934408, upload-time = "2026-07-01T11:53:53.487Z" }, + { url = "https://files.pythonhosted.org/packages/a3/48/9c58b685e69d49c31af6c8eb9012055fab7e665785165c84796e2c73ce72/pillow-12.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4f883547d4b7f0495ebe7056b0cc2aea76094e7a4abc8e933540f3271df27d9c", size = 6337160, upload-time = "2026-07-01T11:53:55.457Z" }, + { url = "https://files.pythonhosted.org/packages/ff/fa/dc2a5c0ba6df93f67c31d34b808b7ce440b40cdbf96f0b81cde1d1e6fa93/pillow-12.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:236ff70b9312fb68943c703aa842ca6a758abfa45ac187a5e7c1452e96ef72b5", size = 7045172, upload-time = "2026-07-01T11:53:57.736Z" }, + { url = "https://files.pythonhosted.org/packages/86/a5/444817a4d4c4c2417df00513086ca196f388d8f9ef40c2e4ccd1ad1af54b/pillow-12.3.0-cp311-cp311-win32.whl", hash = "sha256:10e41f0fbf1eec8cfd234b8fe17a4caac7c9d0db4c204d3c173a8f9f6ef3232b", size = 6472232, upload-time = "2026-07-01T11:53:59.767Z" }, + { url = "https://files.pythonhosted.org/packages/63/c6/4bad1b18d132a50b27e1365e1ab163616f7a5bb56d330f66f9d1d9d4f9d4/pillow-12.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:8e95e1385e4998ae9694eeaa4730ba5457ff61185b3a55e2e7bea0880aef452a", size = 7233653, upload-time = "2026-07-01T11:54:02.066Z" }, + { url = "https://files.pythonhosted.org/packages/fd/16/00f91ab7760dc842f5aad55217e80fc4a7067a0604535249bc8a2d6d9870/pillow-12.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:ebaea975e03d3141d9d3a507df75c9b3ec90fa9d2ffd07567b3a978d9d790b26", size = 2568195, upload-time = "2026-07-01T11:54:04.622Z" }, + { url = "https://files.pythonhosted.org/packages/37/bf/fb3ebff8ddcb76aac5a01389251bbbb9519922a9b520d8247c1ca864a25d/pillow-12.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ba09209fbe443b4acccebe845d8a138b89a8f4fbaeedd44953490b5315d5e965", size = 5345969, upload-time = "2026-07-01T11:54:06.397Z" }, + { url = "https://files.pythonhosted.org/packages/d8/66/9a386a92561f402389a4fc70c18838bf6d35eb5eb5c6850b4b2dc64f5048/pillow-12.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ffd0c5368496f41b0944be820fcb7a838aa6e623d250b01acf2643939c3f99d7", size = 4780323, upload-time = "2026-07-01T11:54:09.351Z" }, + { url = "https://files.pythonhosted.org/packages/25/27/ac8f99618ffd3dde21db0f4d4b1d2ab00c0880595bfd17df103f7f39fd0c/pillow-12.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9c7f76c0673154f044e9d78c8655fb4213f6ca31a836df48b40fe5d187717b9", size = 6266838, upload-time = "2026-07-01T11:54:11.71Z" }, + { url = "https://files.pythonhosted.org/packages/84/21/a35af28dcc61f37ed850a2d64c65c701321dfbf25085e469d5559360cbbf/pillow-12.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:78cb2c6865a35ab8ff8b75fd122f6033b92a62c82801110e48ddd6c936a45d91", size = 6940830, upload-time = "2026-07-01T11:54:13.732Z" }, + { url = "https://files.pythonhosted.org/packages/eb/51/8b08617af3ad95e33ce6d7dd2c99ed6c8298f7fb131636303956be022e25/pillow-12.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e491916b378fba47242221bb9ead245211b70d504f495d105d17b14a24b4907c", size = 6344383, upload-time = "2026-07-01T11:54:15.756Z" }, + { url = "https://files.pythonhosted.org/packages/1d/72/cf78ac9780bb93c28328f408973845a309d4d145041665f734572ced1b52/pillow-12.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0dd2064cbc55aaec028ef5fbb60fa47bb6c3e7918e07ff17935284b227a9d2df", size = 7052934, upload-time = "2026-07-01T11:54:17.721Z" }, + { url = "https://files.pythonhosted.org/packages/20/20/25e0f4dc178a6bc0696793720055519a0de89e7661dae886992decbd2f81/pillow-12.3.0-cp312-cp312-win32.whl", hash = "sha256:dbce0b29841537a2fa4a214c2bbf14de3587c9680caa9b4e217568472490b28f", size = 6472684, upload-time = "2026-07-01T11:54:19.839Z" }, + { url = "https://files.pythonhosted.org/packages/45/89/da2f7971a317f83d807fdd4065c0af40208e59e692cc43d315a71a0e96d1/pillow-12.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a2b55dd6b2a4c4b7d87ffa56bdb33fdc5fdb9a462173861a7bc097f17d91cb09", size = 7227137, upload-time = "2026-07-01T11:54:22.025Z" }, + { url = "https://files.pythonhosted.org/packages/de/47/4845a0a6c0dbf1db8456bd9fc791f13c5ced7ced20606d08a0aacfd25b49/pillow-12.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:331b624368d4f1d069149002f25f44bc61c8919ce8ddb3c45bdad8f6e2d89510", size = 2568267, upload-time = "2026-07-01T11:54:24.051Z" }, + { url = "https://files.pythonhosted.org/packages/9d/ac/31fb64e1e7efb5a4b50cd3d92049ba89ac6e4d8d3bb6a74e15048ca3353e/pillow-12.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:21900ce7ba264168cd50defae43cd75d25c833ad4ad6e73ffc5596d12e25ac89", size = 4161684, upload-time = "2026-07-01T11:54:25.934Z" }, + { url = "https://files.pythonhosted.org/packages/87/b4/9805e23d2b4d77842b468513841fda254ee42f0289d25088340e4ff46e2d/pillow-12.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:4e8c2a84d977f50b9daed6eeaf3baef67d00d5d74d932288f02cb94518ee3ace", size = 4255487, upload-time = "2026-07-01T11:54:27.935Z" }, + { url = "https://files.pythonhosted.org/packages/df/39/ecf519435a200c693fe053a6ee4d835b41cf963a4dfc2551c4e637cb2a71/pillow-12.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:ae26d61dfa7a47befdc7572b521024e8745f3d809bd95ca9505a7bba9ef849ec", size = 3696433, upload-time = "2026-07-01T11:54:29.813Z" }, + { url = "https://files.pythonhosted.org/packages/42/92/2fc3ffad878ae8dd5469ec1bc8eb83b71f48e13efdf68f02709003982a32/pillow-12.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7a743ff716f746fc19a9557f60dab1600d4613255f8a7aeb3cdde4db7eb15a66", size = 5345889, upload-time = "2026-07-01T11:54:31.97Z" }, + { url = "https://files.pythonhosted.org/packages/10/76/8803c13605b763d33d156c4678fc77f8443389c0c51c8aef707bb02015f4/pillow-12.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d69141514cc30b774ceea5e3ed3a6635c8d8a96edf664689b890f4089111fb35", size = 4780109, upload-time = "2026-07-01T11:54:34.026Z" }, + { url = "https://files.pythonhosted.org/packages/1f/01/e18aff37cb0b4aac47ac90f016d347a49aca667ef97f190b06ac2aabc928/pillow-12.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f7401aebd7f581d7f83a439d87d474999317ee099218e5ad25d125290990ba65", size = 6263736, upload-time = "2026-07-01T11:54:36.131Z" }, + { url = "https://files.pythonhosted.org/packages/f7/62/de5bdd77d935331f4f802edc11e4d82950f642caad6cb2f949837b8560e2/pillow-12.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0847a763afefb695bc912d7c131e7e0632d4edc1d8698f58ddabec8e46b8b6d3", size = 6937129, upload-time = "2026-07-01T11:54:38.216Z" }, + { url = "https://files.pythonhosted.org/packages/70/4d/105627a13300c5e0df1d174230b32fd1273062c96f7745fd552b945d1e1d/pillow-12.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:571b9fcb07b97ef3a492028fb3d2dc0993ca23a06138b0315286566d29ef718a", size = 6339562, upload-time = "2026-07-01T11:54:40.354Z" }, + { url = "https://files.pythonhosted.org/packages/6b/1d/f13de01a553988ab895ba1c722e06cf3144d4f57656fd5b81b6d881f1179/pillow-12.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:756c768d0c9c2955feb7a56c37ea24aea2e369f8d36a88da270b6a9f19e62b5e", size = 7049439, upload-time = "2026-07-01T11:54:42.489Z" }, + { url = "https://files.pythonhosted.org/packages/c9/f9/066794cca041b969964f779ee5fa66a9498bbf34248ac39c5d7954e4198f/pillow-12.3.0-cp313-cp313-win32.whl", hash = "sha256:a876864214e136f0eb367788dbd7df045f4806801518e2cfe9e13229cfe06d8f", size = 6473287, upload-time = "2026-07-01T11:54:44.9Z" }, + { url = "https://files.pythonhosted.org/packages/a6/9b/7a58e61d62be561da3a356fe2384d4059a6345fc130e23ef1c36a5b81d24/pillow-12.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:1cca606cd25738df4ed873d5ad46bbdb3d83b5cbca291f6b4ff13a4df6b0bbe8", size = 7239691, upload-time = "2026-07-01T11:54:47.141Z" }, + { url = "https://files.pythonhosted.org/packages/aa/b0/c4ed4f0ef8f8fa5ee8351537db6650bb8189f7e118842978dd6589065692/pillow-12.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:b629de27fda84b42cde7edef0d85f13b958b47f6e9bbcbba9b673c562a89bd8b", size = 2568185, upload-time = "2026-07-01T11:54:49.137Z" }, + { url = "https://files.pythonhosted.org/packages/dc/01/001f65b68192f0228cc1dbbc8d2530ab5d58b61037ba0587f946fea607cd/pillow-12.3.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:9cf95fe4d0f84c82d282745d9bb08ad9f926efa00be4697e767b814ce40d4330", size = 4161736, upload-time = "2026-07-01T11:54:51.156Z" }, + { url = "https://files.pythonhosted.org/packages/1a/d2/0219746d0fd16fc8a84498e79452375be3797d3ce4044596ce565164b84f/pillow-12.3.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:8728f216dcdb6e6d555cf971cb34076139ad74b31fc2c14da4fafc741c5f6217", size = 4255435, upload-time = "2026-07-01T11:54:53.414Z" }, + { url = "https://files.pythonhosted.org/packages/c8/02/8d0bc62ef0302318c46ff2a512822d2610e81c7aa46c9b3abe6cbaca5ad0/pillow-12.3.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:a45650e8ce7fafffd731db8550230db6b0d306d181a90b67d3e6bca2f1990930", size = 3696262, upload-time = "2026-07-01T11:54:55.739Z" }, + { url = "https://files.pythonhosted.org/packages/85/e2/73c77d218410b14f5f2d565e8a998d5317b7b9c75368d29985139f7a46f0/pillow-12.3.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ba54cfebe86920a559a7c4d6b9050791c20513650a1952ebe3368c7dc70306f8", size = 5350344, upload-time = "2026-07-01T11:54:57.657Z" }, + { url = "https://files.pythonhosted.org/packages/c7/da/32c752228ae345f489e3a42499d817b6c3996da7e8a3bc7a04fc806b243b/pillow-12.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:e158cb00350dc278f3b91551101aa7d12415a66ebf2c91d8d5ac14e56ddd3ad0", size = 4780131, upload-time = "2026-07-01T11:54:59.713Z" }, + { url = "https://files.pythonhosted.org/packages/b1/9d/8b2c807dbef61a5197c047afe99823787eb66f63daf9fb2432f91d6f0462/pillow-12.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e9aeb04d6aef139de265b29683e119b638208f88cf73cdd1658aa07221165321", size = 6263757, upload-time = "2026-07-01T11:55:01.778Z" }, + { url = "https://files.pythonhosted.org/packages/5c/44/c85361f65dbe00eea8576ee467c768d25129989efb76e94f205e9ca9bb46/pillow-12.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:251bf95b67017e27b13d82f5b326234ca62d70f9cf4c2b9032de2358a3b12c7b", size = 6936962, upload-time = "2026-07-01T11:55:03.93Z" }, + { url = "https://files.pythonhosted.org/packages/18/7e/e483414b35800b86b6f08dbbc7803fb5cd52c4d6f897f47d53ea2c7e6f65/pillow-12.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fe3cca2e4e8a592be0f269a1ca4835c25199d9f3ce815c8491048f785b0a0198", size = 6339171, upload-time = "2026-07-01T11:55:05.989Z" }, + { url = "https://files.pythonhosted.org/packages/f0/f4/68c491844841ede6bed70189546b3ee9731cf9f2cbad396faff5e1ccba45/pillow-12.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:23aceaa007d6172b02c277f0cd359c79492bbb14f7072b4ede9fbcaf20648130", size = 7048116, upload-time = "2026-07-01T11:55:08.131Z" }, + { url = "https://files.pythonhosted.org/packages/a3/34/77f3f793fed8efc7d243f21b33c5a3f0d1c97ee70346d3db855587e155ff/pillow-12.3.0-cp314-cp314-win32.whl", hash = "sha256:af8d94b0db561cf68b88a267c5c44b49e134f525d0dc2cb7ed413a66bc23559a", size = 6467209, upload-time = "2026-07-01T11:55:10.408Z" }, + { url = "https://files.pythonhosted.org/packages/f1/e0/492879f69d94f91f60fc8cd05ba03650e9520afebb2fb7aa12777d7c7f38/pillow-12.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:fdafc9cce40277e0f7a0feabce0ee50dd2fa1800f3b38015e51296b5e814048d", size = 7237707, upload-time = "2026-07-01T11:55:12.745Z" }, + { url = "https://files.pythonhosted.org/packages/c9/ac/6b11f2875f1c2ac040d84e1bbf9cf22a88038f901ca1037898b280b38365/pillow-12.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:e91206ee562682b51b98ef4b26a6ef48fd84e15fd4c4bc5ec768eb641d206838", size = 2565995, upload-time = "2026-07-01T11:55:14.736Z" }, + { url = "https://files.pythonhosted.org/packages/52/69/c2208e56af9bfc1913afb24020297a691eb1d4ef688474c8a04913f65e04/pillow-12.3.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:164b31cd1a0490ab6efae01aa5df49da7061be0af1b30e035b6e9a1bfe34ee6e", size = 5352503, upload-time = "2026-07-01T11:55:17.076Z" }, + { url = "https://files.pythonhosted.org/packages/07/70/e5686d753e898a45d778ff1718dba8516ead6ab6b95d85fc8c4b70650cf2/pillow-12.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5afb51d599ea772b8365ae807ae557f18bccfe46ab261fd1c2a9ed700fc6eb17", size = 4782956, upload-time = "2026-07-01T11:55:19.448Z" }, + { url = "https://files.pythonhosted.org/packages/d5/37/25c6692f06927ee973ff18c8d9ee98ad0b4d84ee67a09610c2dd1447958e/pillow-12.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3edce1d53195db527e0191f84b71d02022de0540bf43a16ed734ed7537b07385", size = 6322855, upload-time = "2026-07-01T11:55:21.613Z" }, + { url = "https://files.pythonhosted.org/packages/cc/91/420637fcb8f1bc11029e403b4538e6694744428d8246118e45719f944556/pillow-12.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bf16ba1b4d0b6b7c8e534936632270cf70eb00dbe09005bc345b2677b726855c", size = 6989642, upload-time = "2026-07-01T11:55:24.006Z" }, + { url = "https://files.pythonhosted.org/packages/10/08/b94d7811281ccf0d143a1cf768d1c49e1e54af63e7b708ab2ee3eb87face/pillow-12.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:24870b09b224f7ae3c39ed07d10e819d06f8720bc551847b1d623832b5b0e28d", size = 6391281, upload-time = "2026-07-01T11:55:26.252Z" }, + { url = "https://files.pythonhosted.org/packages/d2/87/24233f785f55474dc02ce3e739c5528a77e3a862e9333d1dd7a25cc31f70/pillow-12.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:30f2aa603c41533cc25c05acd0da21636e84a315768feb631c937177db558931", size = 7096716, upload-time = "2026-07-01T11:55:28.318Z" }, + { url = "https://files.pythonhosted.org/packages/23/26/fcb2f6e37175b04f53570b59937867e2b80ee1685e744023153028fc14f9/pillow-12.3.0-cp314-cp314t-win32.whl", hash = "sha256:4b0a7fe987b14c31ebda6083f74f22b561fd3739bc0ac51e019622e3d72668c7", size = 6474125, upload-time = "2026-07-01T11:55:30.956Z" }, + { url = "https://files.pythonhosted.org/packages/90/de/3634abee5f1c9e13c56787b7d5517b0ba8d6de51700b95578cf338349c9f/pillow-12.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:962864dc93511324d51ddbb5b9f8731bf71675b93ca612a07441896f4688fb8c", size = 7242939, upload-time = "2026-07-01T11:55:34.044Z" }, + { url = "https://files.pythonhosted.org/packages/ce/2a/fd13f8eb24de5714a6eb444a3d67e2842c6c576e159a43793adf23051351/pillow-12.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0740a512dc522224c77d9aa5a8d70d8b7d73fb91f2c21125d8d025d3b8990e45", size = 2567506, upload-time = "2026-07-01T11:55:35.988Z" }, + { url = "https://files.pythonhosted.org/packages/5d/dc/8fdce34ec725a33c81c6ba122b904d6b9024e50ea9ac7bede62fab54506c/pillow-12.3.0-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:0feb2e9d6ad6c9e3c06effe9d00f3f1e618a6643273576b016f591e9315a7139", size = 4162063, upload-time = "2026-07-01T11:55:37.941Z" }, + { url = "https://files.pythonhosted.org/packages/76/66/2044b9a63d3b84ff048228dfcb7cd9bf0df983e8470971bf7d4c57b693de/pillow-12.3.0-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:9e881fca225083806662a5c43d627d215f258ff43c890f831966c7d7ba9c7402", size = 4255549, upload-time = "2026-07-01T11:55:40.022Z" }, + { url = "https://files.pythonhosted.org/packages/52/7e/1f67e6f4ece6b582ee4b539decbcc9f848dc245a93ed8cd7338bafef72f1/pillow-12.3.0-cp315-cp315-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:4998562bf62a445225f22e07c896bb04b35b1b1f2eb6d760584c9c51d7a5f78c", size = 3696331, upload-time = "2026-07-01T11:55:41.98Z" }, + { url = "https://files.pythonhosted.org/packages/12/40/d306fc2c8e4d45d7f175c77edca7063be7b86fe7fe6e68f4353bf71d808c/pillow-12.3.0-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:dc624f6bc473dacdf7ef7eb8678d0d08edf15cd94fad6ae5c7d6cc67a4e4902f", size = 5350370, upload-time = "2026-07-01T11:55:44.028Z" }, + { url = "https://files.pythonhosted.org/packages/dd/44/668fb1437e8ce420f62d6106eb66e44a5971602a4d794615bdf79315d82d/pillow-12.3.0-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:71d6097b330eea8fd15097780c8e89cb1a8ce7838669f48c5bacd6f663dd4701", size = 4780147, upload-time = "2026-07-01T11:55:46.073Z" }, + { url = "https://files.pythonhosted.org/packages/0c/08/93fa2e70e30a2d81547e481b6ee2bb9522117221fb1e0ce4b5df70967677/pillow-12.3.0-cp315-cp315-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:28ce87c5ab450a9dd970b52e5aca5fe63ed432d18a2eaddd1979a00a1ba24ace", size = 6273659, upload-time = "2026-07-01T11:55:48.264Z" }, + { url = "https://files.pythonhosted.org/packages/f8/6d/043e96ff814fc31a33077e4cba86082167db520c93632afdf2042febbb0c/pillow-12.3.0-cp315-cp315-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6b02afb9b97f65fbca5f31db6a2a3ba21aa93030225f150fa3f249717e938fb4", size = 6947439, upload-time = "2026-07-01T11:55:50.503Z" }, + { url = "https://files.pythonhosted.org/packages/af/92/ba71d2ee2ac0edf3fa33bd9d5ee9ee080da70b1766f3ca3934f9938ddac9/pillow-12.3.0-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:1182d52bc2d5e5d7d0949503aa7e36d12f42205dc287e4883f407b1988820d39", size = 6353577, upload-time = "2026-07-01T11:55:52.697Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ce/e63064e2122923ff687c8ad792d0d736a7b3920a56a46982e81a7fdd25d6/pillow-12.3.0-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:e795b7eb908249c4e43c7c99fac7c2c75dab0c43566e37db472a355f63693d71", size = 7060394, upload-time = "2026-07-01T11:55:55.149Z" }, + { url = "https://files.pythonhosted.org/packages/54/76/a09cc3ccc8d773a7283d34c38bec1708f9e3cc932093cbc4c5e71ac4060b/pillow-12.3.0-cp315-cp315-win32.whl", hash = "sha256:57b3d78c95ba9059768b10e28b813002261d3f3dfc55cc48b0c988f625175827", size = 6467375, upload-time = "2026-07-01T11:55:57.769Z" }, + { url = "https://files.pythonhosted.org/packages/3e/03/1846c49ba3b1d5550392a4bbd06d6fb4578e1cd91a803198b5c90f5f7d53/pillow-12.3.0-cp315-cp315-win_amd64.whl", hash = "sha256:fa4ecea169a355be7a3ade2c783e2ed12f0e40d2c5621cda8b3297faf7fbb9f5", size = 7237048, upload-time = "2026-07-01T11:55:59.975Z" }, + { url = "https://files.pythonhosted.org/packages/fb/bb/89f35dcc79610423f9f195504d7def7f0d1416a711541b42867e25fe3412/pillow-12.3.0-cp315-cp315-win_arm64.whl", hash = "sha256:877c3f311ff35410f690861c4409e7ccbf0cd2f878e50628a28e5a0bb689e658", size = 2566006, upload-time = "2026-07-01T11:56:02.143Z" }, + { url = "https://files.pythonhosted.org/packages/30/88/707027ba09942dfa2c28759b5c222d769290a41c6d20ea60ec250801941f/pillow-12.3.0-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:e9871b1ffbfa9656b60aeee92ed5136a5742696006fa322b29ea3d8da0ecc9cf", size = 5352509, upload-time = "2026-07-01T11:56:04.2Z" }, + { url = "https://files.pythonhosted.org/packages/b0/6d/00352fa25332c2569cd387851f568cc5a4b75a9adbfb37ac4fbce4c02eec/pillow-12.3.0-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:53aa02d20d10c3d814d536aa4e5ac9b84ca0ff5a88377963b085ad6822f93e64", size = 4783167, upload-time = "2026-07-01T11:56:06.631Z" }, + { url = "https://files.pythonhosted.org/packages/13/4f/9e049dfa21af7c22427275720e2490267ba8138120add5c4c574deb69782/pillow-12.3.0-cp315-cp315t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:446c34dcc4324b084a53b705127dc15717b22c5e140ae0a3c38349d4efec071e", size = 6329237, upload-time = "2026-07-01T11:56:08.868Z" }, + { url = "https://files.pythonhosted.org/packages/36/16/cf6eeaae8d0fce8dd390a33437cf68c5d5bd73834a2bc6e2f14efda0ab45/pillow-12.3.0-cp315-cp315t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cf1845d02ad822a369a49f2bb9345b1614744267682e7a03527dc3bf6eea1777", size = 6997047, upload-time = "2026-07-01T11:56:11.379Z" }, + { url = "https://files.pythonhosted.org/packages/1e/69/dbf769bdd55f48bf5733cac28edc6364ffaa072ec9ba336266e4fe66be55/pillow-12.3.0-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:186941b6aef820ad110fb01fb06eb925374dc3a21b17e37ec9a53b250c6fe2d1", size = 6400440, upload-time = "2026-07-01T11:56:13.908Z" }, + { url = "https://files.pythonhosted.org/packages/a0/e1/ffc9cfc2eea0d178da8018e18e959301ad9d6bc9f3edb7181e748a474b97/pillow-12.3.0-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:f13c32a3abd6079a66d9526e18dad9b6d280384d49d7c54040cd57b6424041d9", size = 7105895, upload-time = "2026-07-01T11:56:16.575Z" }, + { url = "https://files.pythonhosted.org/packages/18/f0/a5595c1e8c3ae44b9828cb2f0fa8155e5095ef04d6327b8f61cf44a3df85/pillow-12.3.0-cp315-cp315t-win32.whl", hash = "sha256:1657923d2d45afb66526e5b933e5b3052e6bdea196c90d3abb2424e18c77dae8", size = 6474384, upload-time = "2026-07-01T11:56:18.855Z" }, + { url = "https://files.pythonhosted.org/packages/e4/04/62bcd9f844984c5938d3b05264a61d797a29d3e0812341a8204af70bbdee/pillow-12.3.0-cp315-cp315t-win_amd64.whl", hash = "sha256:8cd2f7bdda092d99c9fc2fb7391354f306d01443d22785d0cbfafa2e2c8bb418", size = 7243537, upload-time = "2026-07-01T11:56:21.214Z" }, + { url = "https://files.pythonhosted.org/packages/3d/68/1f3066acedf37673694a7141381d8f811ae97f30d34413d236abe7d489f1/pillow-12.3.0-cp315-cp315t-win_arm64.whl", hash = "sha256:06ff022112bc9cbf83b60f8e028d94ad87b60621706487e65f673de61610ab59", size = 2567491, upload-time = "2026-07-01T11:56:23.506Z" }, + { url = "https://files.pythonhosted.org/packages/75/18/2e8b40223153ccbc60df07f9e8928dc0c76202aa4e55ae9f53962b6510d6/pillow-12.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b3c777e849237620b022f7f297dd67705f9f5cf1685f09f02e46f93e92725468", size = 5302510, upload-time = "2026-07-01T11:56:25.736Z" }, + { url = "https://files.pythonhosted.org/packages/46/3e/51fabf59d5ab801ceab709453d3ab6b180083496579549de4c45ced6528a/pillow-12.3.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:b343699e8308bdc51978310e1c959c584e7869cc8c40780058c87da7781a1e94", size = 4736058, upload-time = "2026-07-01T11:56:28.041Z" }, + { url = "https://files.pythonhosted.org/packages/bf/20/22fe9384b7949e25fb1293bcfc84fb82590ff4ea6b37c95b24d26d793d86/pillow-12.3.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbd139c8447d25dd750ab79ee274cc5e1fe80fc56340ab10b18a195e1b6eca3e", size = 5237776, upload-time = "2026-07-01T11:56:30.263Z" }, + { url = "https://files.pythonhosted.org/packages/08/14/f6ba68107680ffa74b39985f3f30884e41318fbc4250caa423c79b4788bb/pillow-12.3.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e7e480451b9fa137494bccd3a7d69adbe8ac65a87d97be61e11f1b1050a5bac3", size = 5860358, upload-time = "2026-07-01T11:56:32.68Z" }, + { url = "https://files.pythonhosted.org/packages/36/54/0169bc772ec491108b62f644f8ecf1fe5d8ae5ebafde2ee2142210166903/pillow-12.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:04f01d28a6aaff387bf842a13be313df23ba0597a44f1a976c9feb3c6ff4711a", size = 7231786, upload-time = "2026-07-01T11:56:35.046Z" }, +] + +[[package]] +name = "platformdirs" +version = "4.11.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b8/d7/e7bfbc86e9f99ff7807e24de7703f032e9c9ba80bb355cf26e0e9bc5a75e/platformdirs-4.11.3.tar.gz", hash = "sha256:66a73d38a849810252df809a3d8bcbda8e26f6c189920e7535ad608a48dbb5ab", size = 33050, upload-time = "2026-08-13T22:43:27.52Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/19/a9/c34aebedd3a4c9afe5101b1b8713710b3fec18087c8a36c35d2f909861bd/platformdirs-4.11.3-py3-none-any.whl", hash = "sha256:5ed065d443751de711da036041a7a214122efc4a4de393b3f4137ba5576540e7", size = 23491, upload-time = "2026-08-13T22:43:26.121Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "pre-commit" +version = "4.6.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cfgv" }, + { name = "identify" }, + { name = "nodeenv" }, + { name = "pyyaml" }, + { name = "virtualenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/74/89/1f3e8e1fc3e97de0fa963495832f581f025f29471602a309e48808244292/pre_commit-4.6.2.tar.gz", hash = "sha256:8f5d7bfb021ecdbcd9d49d89847082dd24172ccde534390081a679ad046e2441", size = 198670, upload-time = "2026-08-10T22:07:18.421Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/45/e2/bbb7129c9e7999a6b8ee9cca3b66486c25c423ab5a75f34071798b74ce94/pre_commit-4.6.2-py2.py3-none-any.whl", hash = "sha256:e2dde9a75d3bce11bd3831c26d134df00a2803c1d818be6a0383c3dcda25dc4e", size = 226202, upload-time = "2026-08-10T22:07:16.942Z" }, +] + +[[package]] +name = "pyarrow" +version = "25.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3d/e3/27f57f80141379d60defe6703eb50a707325706f07fedfd1312c7a751995/pyarrow-25.0.1.tar.gz", hash = "sha256:9150a83248bfed9813ea3c3af74c3856c1984d444aa28e58bf7733b9750ddf6a", size = 1201653, upload-time = "2026-08-10T12:40:53.904Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0a/3e/5cd70becb51e1d044c54ba5e627424a6e87df5b98008cbd22cc6abd409ca/pyarrow-25.0.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:0b1edbb2f385a6a65e9711b62ba86ac54a7816a3f8d17bb3e8a5929d65fb2485", size = 35954271, upload-time = "2026-08-10T12:36:33.857Z" }, + { url = "https://files.pythonhosted.org/packages/64/be/17599e086df264ea7dc221d1101e3131e181e00da428a2f9bd0358f0d06b/pyarrow-25.0.1-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:a4dd8bf99a8fac133efc0ed6a92f5fddbe2adba0d0f6dd720e39ba9855cea85c", size = 37647543, upload-time = "2026-08-10T12:36:39.486Z" }, + { url = "https://files.pythonhosted.org/packages/42/34/e138b451fd3970a6eda4599f68ae3b2b32b661bc958de3239d54a0bf6575/pyarrow-25.0.1-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:bddd0c4f7630c2a3ddf6347c1bdaa79d97bcf6bd445f9e60c816b7d77c85a5ae", size = 46837120, upload-time = "2026-08-10T12:36:46.58Z" }, + { url = "https://files.pythonhosted.org/packages/57/5c/f8fc0eb2de03464a557d5a4d0c15e972d73362414696618833b771f7eddd/pyarrow-25.0.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a4d6d5e9a3d1879a97c08ded0c797579b7965eafd0f0c26c30b45ccc06db939b", size = 50066460, upload-time = "2026-08-10T12:36:53.702Z" }, + { url = "https://files.pythonhosted.org/packages/3f/d1/0dd64fd06de0333b808a02f60981635f067b71aad3a30698a9a104fae778/pyarrow-25.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:514ddb60285631af068875550c90eddc181db3e8e63a032b1559be189e82f056", size = 49937892, upload-time = "2026-08-10T12:37:00.349Z" }, + { url = "https://files.pythonhosted.org/packages/cb/3c/f89d1bd76d5f3284c2a44d7d7ebbd8204535e5ae2b41f4077069b4ff2ec6/pyarrow-25.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cab40b1edfef0262e0e5251aa2c58d75630f24d06dd7794480243acc001a1d7d", size = 53107240, upload-time = "2026-08-10T12:37:07.205Z" }, + { url = "https://files.pythonhosted.org/packages/67/67/b554a8e09f3f3decccf405eb8fbe86696321cbcb5b62d18b4a5057a4c113/pyarrow-25.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:60e89d8f13861a1f7f8d950fa54aebb8023b30734d0ac51ffa80beabe2df4bba", size = 27848683, upload-time = "2026-08-10T12:37:12.058Z" }, + { url = "https://files.pythonhosted.org/packages/ee/8b/0d23b47702fcfe8b3618d5292035099675c5a1c48258932350c08020f7b5/pyarrow-25.0.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:51093dd9e10325fbdb3c10a2ae7c4806e5c822d94e74ae4938b26524a3323fee", size = 35946180, upload-time = "2026-08-10T12:37:18.934Z" }, + { url = "https://files.pythonhosted.org/packages/d8/17/707d17a5476c55a9541fde0db8213ac30979a792864d72415f176ba50c45/pyarrow-25.0.1-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:eb6203482ff3746a5632303a7279ae0b5a304c46985b49ed1378cb350ea6728d", size = 37644787, upload-time = "2026-08-10T12:37:25.795Z" }, + { url = "https://files.pythonhosted.org/packages/c1/b2/cdc98ecf1a6408280bc3a6a07054cdd99a3f4670acc0545d383ce113e87d/pyarrow-25.0.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:880523be3d29efcf83d3998835d206118ccf35e3871dbd2fb60408cf6b007a80", size = 46834633, upload-time = "2026-08-10T12:37:33.604Z" }, + { url = "https://files.pythonhosted.org/packages/c8/6e/d3fafc41f378b2c65be43b827798c0fae42049a641c8526633ed3eb573e2/pyarrow-25.0.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:25f8720bf6387d5dc2ebd2622112de630760419e4b66134405dd24110d15f37e", size = 50065507, upload-time = "2026-08-10T12:37:40.565Z" }, + { url = "https://files.pythonhosted.org/packages/d5/12/8d0698954b8c3001844a898e0a6900bebe83d7ee40c11195174c5122f324/pyarrow-25.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4facd65742a024a4a366328a1d2292062d72d6e023c1b7dda8d4c37544933a25", size = 49955690, upload-time = "2026-08-10T12:37:46.644Z" }, + { url = "https://files.pythonhosted.org/packages/d3/0b/1ecb936ac6409e90a34d58eea1c7cec09a9ae6d2141b9e49ad01a2b1ea47/pyarrow-25.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:aa0559502e1cd6254d6814614085dd9c5a3dd0419362978a936a3f68a9e5c3df", size = 53128198, upload-time = "2026-08-10T12:37:52.531Z" }, + { url = "https://files.pythonhosted.org/packages/8e/1c/5236033550633c9b7377b2a53660b2bbb06cb06dc09c4356332d67643ca1/pyarrow-25.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:62cd0d785b8aa6675ee355f9fc02252a340f4441257c42674937826fd7594325", size = 27857263, upload-time = "2026-08-10T12:37:56.943Z" }, + { url = "https://files.pythonhosted.org/packages/a6/e2/9ab15b88cbfac28e16419ce5439ec29234c5172cb8259301b4ba639bdec0/pyarrow-25.0.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:df961f2e7ae9cf496459259d798652c70625f6c080650d6952f8c04053c58ee9", size = 35861559, upload-time = "2026-08-10T12:38:02.567Z" }, + { url = "https://files.pythonhosted.org/packages/58/79/a0036dbe1eabe1f73127427342f1d99982584c4a2cde2651d6c93499c6f6/pyarrow-25.0.1-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:cc4aa407fde9fc660be3939e49ea31f50f3e9fec17c0ec63159f7711edd3efc9", size = 37628383, upload-time = "2026-08-10T12:38:09.083Z" }, + { url = "https://files.pythonhosted.org/packages/13/49/d93a57d375f4bf0cf82913dd6bb54acafde83dd993be2282c81ac5616cad/pyarrow-25.0.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:4340f0ba6c1d2e13f21658de1d7c662ca2545018568d0030a1e9afca159d87e3", size = 46820190, upload-time = "2026-08-10T12:38:15.458Z" }, + { url = "https://files.pythonhosted.org/packages/60/c9/711ca85d79f1ec98f29a5eae2b051e25b4ecec5de3e3c0e2d5c5dcb15664/pyarrow-25.0.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:5389cdf79447ed1515c9e31620e6e1e2302249564d603f2ad727d4f6d313e4c3", size = 50102437, upload-time = "2026-08-10T12:38:22.487Z" }, + { url = "https://files.pythonhosted.org/packages/80/53/8fb8359ff17cfb6263a1cf3ebf7caec9fe197de118719e84fcb1d0618026/pyarrow-25.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d51592cb7561e87877c506113e7adbf1342ab579e6c21f0ef44b8ba41cb74c80", size = 49942424, upload-time = "2026-08-10T12:38:28.755Z" }, + { url = "https://files.pythonhosted.org/packages/e8/83/4e5ae02a9341571b18a6fca380ac7a58ce6ddae7ab3c060208c0a1e79f02/pyarrow-25.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6109c94d8b9f3b17a041daca16cacb2f651ad8f1ef70a4232c2c0f37a23da2a8", size = 53144206, upload-time = "2026-08-10T12:38:34.862Z" }, + { url = "https://files.pythonhosted.org/packages/65/ee/197cbf47e49f83e6ebeb946a5259a48a638dea27ac774db42fe78022179d/pyarrow-25.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:8858d7bfc22e3f51529aeaa4077225029724623e4595dc9eff8c793935c34140", size = 27953934, upload-time = "2026-08-10T12:38:39.808Z" }, + { url = "https://files.pythonhosted.org/packages/cc/8d/8f271a7a034c834910ec925d56fa4b29733b1380f5289419f5aaa3b02777/pyarrow-25.0.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:c7c534ec03c358a76ea3e505e74c1b6aef290af90c444dfd092dbfe23e755b85", size = 35855328, upload-time = "2026-08-10T12:38:45.489Z" }, + { url = "https://files.pythonhosted.org/packages/d2/cd/5bac242f4e841b9971d5eb94fdfe2577e2b70be983e27401e72055786037/pyarrow-25.0.1-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:dda9470024204d7bbf2042b47c6e8a0e47a3eeb8e34405882dfaea6577e0c153", size = 37622415, upload-time = "2026-08-10T12:38:51.107Z" }, + { url = "https://files.pythonhosted.org/packages/63/1f/96d03b4e1506524f7087adb0fd6b2f69f0c9c7aaff1ec36d8030082e15a5/pyarrow-25.0.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:44a9120ce5bd81936b8ab9a88076e3fd47c2c6838e0e43630fed83626aca81d9", size = 46813813, upload-time = "2026-08-10T12:38:57.773Z" }, + { url = "https://files.pythonhosted.org/packages/98/d6/33a411115b61dbfc16ad6ad73e71730f6fea654ee3667673bc53ab0e2fe7/pyarrow-25.0.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:0befcf816e45a1af33ac775a9970b749e4868a230c7372f0ae5e932bee27039f", size = 50104452, upload-time = "2026-08-10T12:39:04.579Z" }, + { url = "https://files.pythonhosted.org/packages/33/ae/b1b97c9ca87f9f9ddbb5230c798df94eccce61bd79b9b45458c69a478588/pyarrow-25.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3f89685964f46e4216103c75483aac0c0692a5f72212d7ca835adba5ede56ce3", size = 49951343, upload-time = "2026-08-10T12:39:11.8Z" }, + { url = "https://files.pythonhosted.org/packages/98/9e/a112df5cfd5a68cb1d9fc31cfe38c28d5aec9f10865ce37ecef2e4450873/pyarrow-25.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6943e2fe7954d29d84de45d29d34c8dc36ce96570e67d89aa9976e650a4a9138", size = 53144784, upload-time = "2026-08-10T12:39:20.503Z" }, + { url = "https://files.pythonhosted.org/packages/31/24/97e8bd98f1e3b07e2ba08bcdff690674fbe16d69a7d2712cc3884665e615/pyarrow-25.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:31e49a7888fcdf3a835da33ae777f6bb9a866334e5a789282fc26dcf426f7f15", size = 27870159, upload-time = "2026-08-10T12:39:26.161Z" }, + { url = "https://files.pythonhosted.org/packages/36/4c/b525824ad3094076919273cd97db61fb3d78252dee76fa3b8dc8f76774aa/pyarrow-25.0.1-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:bf0b672390cdcb640d7288f96b826d71ff4e9abb254a86c89890baf51a29cee6", size = 35885255, upload-time = "2026-08-10T12:39:32.366Z" }, + { url = "https://files.pythonhosted.org/packages/08/62/448bb0e940de41aec31d1a956e63ad9c54afdf122a103cc3ab20c2a3ce33/pyarrow-25.0.1-cp314-cp314-macosx_12_0_x86_64.whl", hash = "sha256:38a9a4b4b9613380e200641891495a56c3d5a98a092db4a870af9975e220471d", size = 37644461, upload-time = "2026-08-10T12:39:38.142Z" }, + { url = "https://files.pythonhosted.org/packages/6e/9a/13587e38bd4806fd218f50fd13b8903fab60588a699ff0c406372e5b4043/pyarrow-25.0.1-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:0b726ad7e7b669be982b0c71c07fe4b037d654354130da79a7902a669e93a66b", size = 46877146, upload-time = "2026-08-10T12:39:43.722Z" }, + { url = "https://files.pythonhosted.org/packages/8d/61/1c5d1229fa21da4cff5365e41e57177aaac57c563c727f35419b8513d1c1/pyarrow-25.0.1-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:9171748cdf796972d85a4b60157c279913e242992e350c90c7450182a9838b2a", size = 50131616, upload-time = "2026-08-10T12:39:49.304Z" }, + { url = "https://files.pythonhosted.org/packages/43/20/291e1d65cc0b09aa19f03cf25cf51a2f5fa94b5db315178f2d254ed5cad4/pyarrow-25.0.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b7a296aac7a71fa0886c08e155ddb6c636a50013f801f6178daafa0f9e726188", size = 50008879, upload-time = "2026-08-10T12:39:56.891Z" }, + { url = "https://files.pythonhosted.org/packages/8b/7c/1b7c9ec28e76576337e4f97b31141c9a181b89b6d1d6221e9d8205621a58/pyarrow-25.0.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:0fe7c8b6c03969b49c8c66182e4a18e3819ab92d07cfab5d8370c531b9369ef0", size = 53170864, upload-time = "2026-08-10T12:40:04.918Z" }, + { url = "https://files.pythonhosted.org/packages/b7/75/f3d789dc06011a765d14d86bda799cf72ac1d715b6a6edecaa0d73d95062/pyarrow-25.0.1-cp314-cp314-win_amd64.whl", hash = "sha256:f729cfdbd36fd99d543b67a914d2de044c84ebe45be8b34902b299b608c15c8f", size = 28620729, upload-time = "2026-08-10T12:40:51.41Z" }, + { url = "https://files.pythonhosted.org/packages/fc/05/647a8ee6f7c2662feb6921315617bc04dcd6034763fb61b1199720bf6162/pyarrow-25.0.1-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:59a2de54c0cbd954da861eee4d1d330f8e909c45b53455baef696380f2c55033", size = 36130288, upload-time = "2026-08-10T12:40:11.014Z" }, + { url = "https://files.pythonhosted.org/packages/93/f8/c9ee997554d7bea94520667dd1933f109ac1da3ee3556d2b49381e023484/pyarrow-25.0.1-cp314-cp314t-macosx_12_0_x86_64.whl", hash = "sha256:35935cd5de130aa5cf4dea052a63e6bf2e17006c35c3a468194242b9b2bf5956", size = 37762187, upload-time = "2026-08-10T12:40:16.592Z" }, + { url = "https://files.pythonhosted.org/packages/a2/08/a28c01c7fe9e96e8233ce2d13df1d402f4f999f848f51d2daacd6bb4c036/pyarrow-25.0.1-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:f3831aaa25c67a99f99dc8b05873cb9d64560390372e2aa197ce9dd4a3f06a44", size = 46888003, upload-time = "2026-08-10T12:40:23.242Z" }, + { url = "https://files.pythonhosted.org/packages/1b/b9/58612e977d28dc58c878448866838369ee8da2f1e7cc8ed2c84b952aafee/pyarrow-25.0.1-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:6a1fdfc6659b6b19022f2e50627fb5cf7156a66c46bf4299379955cbe742382a", size = 50079036, upload-time = "2026-08-10T12:40:29.169Z" }, + { url = "https://files.pythonhosted.org/packages/72/13/66e1402dcc860e1dc2760b1e0292c9a569b62b3bccab69def1b3e907d006/pyarrow-25.0.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:169d3429d5be7c752125890620f75a60776d38b0035eddae939651640822332e", size = 50040226, upload-time = "2026-08-10T12:40:35.186Z" }, + { url = "https://files.pythonhosted.org/packages/78/10/3f1a5497a7ef732ab0f03ecca3e66d89d9c0f57fdc61b4794c456b781f01/pyarrow-25.0.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:119297a6dc197e45d9c6d4415f7814a67ffa36c180d26f68c154c58067ae782d", size = 53149035, upload-time = "2026-08-10T12:40:41.454Z" }, + { url = "https://files.pythonhosted.org/packages/93/c0/37d4a7e8e2f7a6076283673d5298018ca26478b934c6ee369e10505ab32c/pyarrow-25.0.1-cp314-cp314t-win_amd64.whl", hash = "sha256:4288f27577352d608ca08553b0865e4a9b3aa14820c5d95b53337218d609835b", size = 28753071, upload-time = "2026-08-10T12:40:46.623Z" }, +] + +[[package]] +name = "pygments" +version = "2.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, +] + +[[package]] +name = "pymdown-extensions" +version = "11.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown" }, + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/21/a9/5f0c535ba3b08fe09270c16808e053a968868242ecbd5676d4e3a488bf28/pymdown_extensions-11.0.1.tar.gz", hash = "sha256:dd2905ae6fc5b75582fafb139a1266ffc754705efa902aa50067fa7ff4f94ec0", size = 857113, upload-time = "2026-07-02T17:59:22.955Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d6/54/da572c98c0b77626a91b5d3b89f0231d8bff5125c225420908632f8b342d/pymdown_extensions-11.0.1-py3-none-any.whl", hash = "sha256:db3943a62bab7e03af1364f0c4083e64b91fb097675a4b6cceccfbe9a77e5eb2", size = 269455, upload-time = "2026-07-02T17:59:21.271Z" }, +] + +[[package]] +name = "pyparsing" +version = "3.3.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/91/9c6ee907786a473bf81c5f53cf703ba0957b23ab84c264080fb5a450416f/pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc", size = 6851574, upload-time = "2026-01-21T03:57:59.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", size = 122781, upload-time = "2026-01-21T03:57:55.912Z" }, +] + +[[package]] +name = "pytest" +version = "9.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, +] + +[[package]] +name = "pytest-cov" +version = "7.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "coverage", extra = ["toml"] }, + { name = "pluggy" }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/51/a849f96e117386044471c8ec2bd6cfebacda285da9525c9106aeb28da671/pytest_cov-7.1.0.tar.gz", hash = "sha256:30674f2b5f6351aa09702a9c8c364f6a01c27aae0c1366ae8016160d1efc56b2", size = 55592, upload-time = "2026-03-21T20:11:16.284Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl", hash = "sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678", size = 22876, upload-time = "2026-03-21T20:11:14.438Z" }, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, +] + +[[package]] +name = "python-discovery" +version = "1.5.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "filelock" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/38/b7/ac44da2cf0e53ada0e419033c2d058219c95dc1403126f163304c9e814b1/python_discovery-1.5.2.tar.gz", hash = "sha256:45fd4f20a4e3f9b7bf2e0817870bc8e3b320a19658da177af800768c82dbf354", size = 82350, upload-time = "2026-08-12T14:05:26.419Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/45/689603d04b3bb8d7faa00f25c24acef993aab7813b3dbbfc472a459ab0b5/python_discovery-1.5.2-py3-none-any.whl", hash = "sha256:3e338c2d0f15dfaeea57493f4c2c6caebe0e998ea815c30ae8bf8ee21f1112d3", size = 38350, upload-time = "2026-08-12T14:05:25.113Z" }, +] + +[[package]] +name = "pytokens" +version = "0.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b6/34/b4e015b99031667a7b960f888889c5bd34ef585c85e1cb56a594b92836ac/pytokens-0.4.1.tar.gz", hash = "sha256:292052fe80923aae2260c073f822ceba21f3872ced9a68bb7953b348e561179a", size = 23015, upload-time = "2026-01-30T01:03:45.924Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/42/24/f206113e05cb8ef51b3850e7ef88f20da6f4bf932190ceb48bd3da103e10/pytokens-0.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a44ed93ea23415c54f3face3b65ef2b844d96aeb3455b8a69b3df6beab6acc5", size = 161522, upload-time = "2026-01-30T01:02:50.393Z" }, + { url = "https://files.pythonhosted.org/packages/d4/e9/06a6bf1b90c2ed81a9c7d2544232fe5d2891d1cd480e8a1809ca354a8eb2/pytokens-0.4.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:add8bf86b71a5d9fb5b89f023a80b791e04fba57960aa790cc6125f7f1d39dfe", size = 246945, upload-time = "2026-01-30T01:02:52.399Z" }, + { url = "https://files.pythonhosted.org/packages/69/66/f6fb1007a4c3d8b682d5d65b7c1fb33257587a5f782647091e3408abe0b8/pytokens-0.4.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:670d286910b531c7b7e3c0b453fd8156f250adb140146d234a82219459b9640c", size = 259525, upload-time = "2026-01-30T01:02:53.737Z" }, + { url = "https://files.pythonhosted.org/packages/04/92/086f89b4d622a18418bac74ab5db7f68cf0c21cf7cc92de6c7b919d76c88/pytokens-0.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4e691d7f5186bd2842c14813f79f8884bb03f5995f0575272009982c5ac6c0f7", size = 262693, upload-time = "2026-01-30T01:02:54.871Z" }, + { url = "https://files.pythonhosted.org/packages/b4/7b/8b31c347cf94a3f900bdde750b2e9131575a61fdb620d3d3c75832262137/pytokens-0.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:27b83ad28825978742beef057bfe406ad6ed524b2d28c252c5de7b4a6dd48fa2", size = 103567, upload-time = "2026-01-30T01:02:56.414Z" }, + { url = "https://files.pythonhosted.org/packages/3d/92/790ebe03f07b57e53b10884c329b9a1a308648fc083a6d4a39a10a28c8fc/pytokens-0.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d70e77c55ae8380c91c0c18dea05951482e263982911fc7410b1ffd1dadd3440", size = 160864, upload-time = "2026-01-30T01:02:57.882Z" }, + { url = "https://files.pythonhosted.org/packages/13/25/a4f555281d975bfdd1eba731450e2fe3a95870274da73fb12c40aeae7625/pytokens-0.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a58d057208cb9075c144950d789511220b07636dd2e4708d5645d24de666bdc", size = 248565, upload-time = "2026-01-30T01:02:59.912Z" }, + { url = "https://files.pythonhosted.org/packages/17/50/bc0394b4ad5b1601be22fa43652173d47e4c9efbf0044c62e9a59b747c56/pytokens-0.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b49750419d300e2b5a3813cf229d4e5a4c728dae470bcc89867a9ad6f25a722d", size = 260824, upload-time = "2026-01-30T01:03:01.471Z" }, + { url = "https://files.pythonhosted.org/packages/4e/54/3e04f9d92a4be4fc6c80016bc396b923d2a6933ae94b5f557c939c460ee0/pytokens-0.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d9907d61f15bf7261d7e775bd5d7ee4d2930e04424bab1972591918497623a16", size = 264075, upload-time = "2026-01-30T01:03:04.143Z" }, + { url = "https://files.pythonhosted.org/packages/d1/1b/44b0326cb5470a4375f37988aea5d61b5cc52407143303015ebee94abfd6/pytokens-0.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:ee44d0f85b803321710f9239f335aafe16553b39106384cef8e6de40cb4ef2f6", size = 103323, upload-time = "2026-01-30T01:03:05.412Z" }, + { url = "https://files.pythonhosted.org/packages/41/5d/e44573011401fb82e9d51e97f1290ceb377800fb4eed650b96f4753b499c/pytokens-0.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:140709331e846b728475786df8aeb27d24f48cbcf7bcd449f8de75cae7a45083", size = 160663, upload-time = "2026-01-30T01:03:06.473Z" }, + { url = "https://files.pythonhosted.org/packages/f0/e6/5bbc3019f8e6f21d09c41f8b8654536117e5e211a85d89212d59cbdab381/pytokens-0.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d6c4268598f762bc8e91f5dbf2ab2f61f7b95bdc07953b602db879b3c8c18e1", size = 255626, upload-time = "2026-01-30T01:03:08.177Z" }, + { url = "https://files.pythonhosted.org/packages/bf/3c/2d5297d82286f6f3d92770289fd439956b201c0a4fc7e72efb9b2293758e/pytokens-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:24afde1f53d95348b5a0eb19488661147285ca4dd7ed752bbc3e1c6242a304d1", size = 269779, upload-time = "2026-01-30T01:03:09.756Z" }, + { url = "https://files.pythonhosted.org/packages/20/01/7436e9ad693cebda0551203e0bf28f7669976c60ad07d6402098208476de/pytokens-0.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5ad948d085ed6c16413eb5fec6b3e02fa00dc29a2534f088d3302c47eb59adf9", size = 268076, upload-time = "2026-01-30T01:03:10.957Z" }, + { url = "https://files.pythonhosted.org/packages/2e/df/533c82a3c752ba13ae7ef238b7f8cdd272cf1475f03c63ac6cf3fcfb00b6/pytokens-0.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:3f901fe783e06e48e8cbdc82d631fca8f118333798193e026a50ce1b3757ea68", size = 103552, upload-time = "2026-01-30T01:03:12.066Z" }, + { url = "https://files.pythonhosted.org/packages/cb/dc/08b1a080372afda3cceb4f3c0a7ba2bde9d6a5241f1edb02a22a019ee147/pytokens-0.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8bdb9d0ce90cbf99c525e75a2fa415144fd570a1ba987380190e8b786bc6ef9b", size = 160720, upload-time = "2026-01-30T01:03:13.843Z" }, + { url = "https://files.pythonhosted.org/packages/64/0c/41ea22205da480837a700e395507e6a24425151dfb7ead73343d6e2d7ffe/pytokens-0.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5502408cab1cb18e128570f8d598981c68a50d0cbd7c61312a90507cd3a1276f", size = 254204, upload-time = "2026-01-30T01:03:14.886Z" }, + { url = "https://files.pythonhosted.org/packages/e0/d2/afe5c7f8607018beb99971489dbb846508f1b8f351fcefc225fcf4b2adc0/pytokens-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:29d1d8fb1030af4d231789959f21821ab6325e463f0503a61d204343c9b355d1", size = 268423, upload-time = "2026-01-30T01:03:15.936Z" }, + { url = "https://files.pythonhosted.org/packages/68/d4/00ffdbd370410c04e9591da9220a68dc1693ef7499173eb3e30d06e05ed1/pytokens-0.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:970b08dd6b86058b6dc07efe9e98414f5102974716232d10f32ff39701e841c4", size = 266859, upload-time = "2026-01-30T01:03:17.458Z" }, + { url = "https://files.pythonhosted.org/packages/a7/c9/c3161313b4ca0c601eeefabd3d3b576edaa9afdefd32da97210700e47652/pytokens-0.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:9bd7d7f544d362576be74f9d5901a22f317efc20046efe2034dced238cbbfe78", size = 103520, upload-time = "2026-01-30T01:03:18.652Z" }, + { url = "https://files.pythonhosted.org/packages/8f/a7/b470f672e6fc5fee0a01d9e75005a0e617e162381974213a945fcd274843/pytokens-0.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4a14d5f5fc78ce85e426aa159489e2d5961acf0e47575e08f35584009178e321", size = 160821, upload-time = "2026-01-30T01:03:19.684Z" }, + { url = "https://files.pythonhosted.org/packages/80/98/e83a36fe8d170c911f864bfded690d2542bfcfacb9c649d11a9e6eb9dc41/pytokens-0.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97f50fd18543be72da51dd505e2ed20d2228c74e0464e4262e4899797803d7fa", size = 254263, upload-time = "2026-01-30T01:03:20.834Z" }, + { url = "https://files.pythonhosted.org/packages/0f/95/70d7041273890f9f97a24234c00b746e8da86df462620194cef1d411ddeb/pytokens-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dc74c035f9bfca0255c1af77ddd2d6ae8419012805453e4b0e7513e17904545d", size = 268071, upload-time = "2026-01-30T01:03:21.888Z" }, + { url = "https://files.pythonhosted.org/packages/da/79/76e6d09ae19c99404656d7db9c35dfd20f2086f3eb6ecb496b5b31163bad/pytokens-0.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f66a6bbe741bd431f6d741e617e0f39ec7257ca1f89089593479347cc4d13324", size = 271716, upload-time = "2026-01-30T01:03:23.633Z" }, + { url = "https://files.pythonhosted.org/packages/79/37/482e55fa1602e0a7ff012661d8c946bafdc05e480ea5a32f4f7e336d4aa9/pytokens-0.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:b35d7e5ad269804f6697727702da3c517bb8a5228afa450ab0fa787732055fc9", size = 104539, upload-time = "2026-01-30T01:03:24.788Z" }, + { url = "https://files.pythonhosted.org/packages/30/e8/20e7db907c23f3d63b0be3b8a4fd1927f6da2395f5bcc7f72242bb963dfe/pytokens-0.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:8fcb9ba3709ff77e77f1c7022ff11d13553f3c30299a9fe246a166903e9091eb", size = 168474, upload-time = "2026-01-30T01:03:26.428Z" }, + { url = "https://files.pythonhosted.org/packages/d6/81/88a95ee9fafdd8f5f3452107748fd04c24930d500b9aba9738f3ade642cc/pytokens-0.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:79fc6b8699564e1f9b521582c35435f1bd32dd06822322ec44afdeba666d8cb3", size = 290473, upload-time = "2026-01-30T01:03:27.415Z" }, + { url = "https://files.pythonhosted.org/packages/cf/35/3aa899645e29b6375b4aed9f8d21df219e7c958c4c186b465e42ee0a06bf/pytokens-0.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d31b97b3de0f61571a124a00ffe9a81fb9939146c122c11060725bd5aea79975", size = 303485, upload-time = "2026-01-30T01:03:28.558Z" }, + { url = "https://files.pythonhosted.org/packages/52/a0/07907b6ff512674d9b201859f7d212298c44933633c946703a20c25e9d81/pytokens-0.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:967cf6e3fd4adf7de8fc73cd3043754ae79c36475c1c11d514fc72cf5490094a", size = 306698, upload-time = "2026-01-30T01:03:29.653Z" }, + { url = "https://files.pythonhosted.org/packages/39/2a/cbbf9250020a4a8dd53ba83a46c097b69e5eb49dd14e708f496f548c6612/pytokens-0.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:584c80c24b078eec1e227079d56dc22ff755e0ba8654d8383b2c549107528918", size = 116287, upload-time = "2026-01-30T01:03:30.912Z" }, + { url = "https://files.pythonhosted.org/packages/c6/78/397db326746f0a342855b81216ae1f0a32965deccfd7c830a2dbc66d2483/pytokens-0.4.1-py3-none-any.whl", hash = "sha256:26cef14744a8385f35d0e095dc8b3a7583f6c953c2e3d269c7f82484bf5ad2de", size = 13729, upload-time = "2026-01-30T01:03:45.029Z" }, +] + +[[package]] +name = "pytz" +version = "2026.3.post1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fb/48/fb042503b6ca6cd271261dc559fd6432f7d8c713153e9ec5c591af4dfc1c/pytz-2026.3.post1.tar.gz", hash = "sha256:2211d3fcf9a797d3405cac96ac7f61d80e6a644f72a3309607282fe8a2010c5d", size = 319745, upload-time = "2026-07-25T15:12:07.385Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/7b/39c34ca613b0b198cb866466651b26b045e2009864c5183c979a3b83f383/pytz-2026.3.post1-py2.py3-none-any.whl", hash = "sha256:dd95840dd199baea12d9cc096a1d452caa6596a1c1e4b5f3dbd1541855d5e815", size = 508283, upload-time = "2026-07-25T15:12:05.782Z" }, +] + +[[package]] +name = "pyyaml" +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/a0/39350dd17dd6d6c6507025c0e53aef67a9293a6d37d3511f23ea510d5800/pyyaml-6.0.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b", size = 184227, upload-time = "2025-09-25T21:31:46.04Z" }, + { url = "https://files.pythonhosted.org/packages/05/14/52d505b5c59ce73244f59c7a50ecf47093ce4765f116cdb98286a71eeca2/pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956", size = 174019, upload-time = "2025-09-25T21:31:47.706Z" }, + { url = "https://files.pythonhosted.org/packages/43/f7/0e6a5ae5599c838c696adb4e6330a59f463265bfa1e116cfd1fbb0abaaae/pyyaml-6.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8", size = 740646, upload-time = "2025-09-25T21:31:49.21Z" }, + { url = "https://files.pythonhosted.org/packages/2f/3a/61b9db1d28f00f8fd0ae760459a5c4bf1b941baf714e207b6eb0657d2578/pyyaml-6.0.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198", size = 840793, upload-time = "2025-09-25T21:31:50.735Z" }, + { url = "https://files.pythonhosted.org/packages/7a/1e/7acc4f0e74c4b3d9531e24739e0ab832a5edf40e64fbae1a9c01941cabd7/pyyaml-6.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b", size = 770293, upload-time = "2025-09-25T21:31:51.828Z" }, + { url = "https://files.pythonhosted.org/packages/8b/ef/abd085f06853af0cd59fa5f913d61a8eab65d7639ff2a658d18a25d6a89d/pyyaml-6.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0", size = 732872, upload-time = "2025-09-25T21:31:53.282Z" }, + { url = "https://files.pythonhosted.org/packages/1f/15/2bc9c8faf6450a8b3c9fc5448ed869c599c0a74ba2669772b1f3a0040180/pyyaml-6.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69", size = 758828, upload-time = "2025-09-25T21:31:54.807Z" }, + { url = "https://files.pythonhosted.org/packages/a3/00/531e92e88c00f4333ce359e50c19b8d1de9fe8d581b1534e35ccfbc5f393/pyyaml-6.0.3-cp310-cp310-win32.whl", hash = "sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e", size = 142415, upload-time = "2025-09-25T21:31:55.885Z" }, + { url = "https://files.pythonhosted.org/packages/2a/fa/926c003379b19fca39dd4634818b00dec6c62d87faf628d1394e137354d4/pyyaml-6.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c", size = 158561, upload-time = "2025-09-25T21:31:57.406Z" }, + { url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826, upload-time = "2025-09-25T21:31:58.655Z" }, + { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577, upload-time = "2025-09-25T21:32:00.088Z" }, + { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556, upload-time = "2025-09-25T21:32:01.31Z" }, + { url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", size = 882114, upload-time = "2025-09-25T21:32:03.376Z" }, + { url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", size = 806638, upload-time = "2025-09-25T21:32:04.553Z" }, + { url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", size = 767463, upload-time = "2025-09-25T21:32:06.152Z" }, + { url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", size = 794986, upload-time = "2025-09-25T21:32:07.367Z" }, + { url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543, upload-time = "2025-09-25T21:32:08.95Z" }, + { url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763, upload-time = "2025-09-25T21:32:09.96Z" }, + { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, + { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, + { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, + { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, + { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, + { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, + { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, + { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, +] + +[[package]] +name = "pyyaml-env-tag" +version = "1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/eb/2e/79c822141bfd05a853236b504869ebc6b70159afc570e1d5a20641782eaa/pyyaml_env_tag-1.1.tar.gz", hash = "sha256:2eb38b75a2d21ee0475d6d97ec19c63287a7e140231e4214969d0eac923cd7ff", size = 5737, upload-time = "2025-05-13T15:24:01.64Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl", hash = "sha256:17109e1a528561e32f026364712fee1264bc2ea6715120891174ed1b980d2e04", size = 4722, upload-time = "2025-05-13T15:23:59.629Z" }, +] + +[[package]] +name = "requests" +version = "2.34.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ac/c3/e2a2b89f2d3e2179abd6d00ebd70bff6273f37fb3e0cc209f48b39d00cbf/requests-2.34.2.tar.gz", hash = "sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed", size = 142856, upload-time = "2026-05-14T19:25:27.735Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl", hash = "sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0", size = 73075, upload-time = "2026-05-14T19:25:26.443Z" }, +] + +[[package]] +name = "ruff" +version = "0.16.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/61/b3/3213589383f8f1b3938781bd1278713f6d18621a14992b3e81fefb8a5ef9/ruff-0.16.3.tar.gz", hash = "sha256:e76d33a347661a84b5be6d043d0347fdc745dfdcf825a8f4fed64b5e26eebdf2", size = 4891904, upload-time = "2026-08-13T15:17:13.381Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bf/96/493770daebd68c0a67f1549fdf519f53be51fc435186c0585bcc272fd76c/ruff-0.16.3-py3-none-linux_armv6l.whl", hash = "sha256:0c5710e247a58a4521e66e124ba9a74655b414f61ba3a2e9e3811e11098f48f7", size = 10902799, upload-time = "2026-08-13T15:16:27.382Z" }, + { url = "https://files.pythonhosted.org/packages/5e/e6/2becf3942fddc29a29b8df47691d456fb1085391a694f74d84513251418c/ruff-0.16.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:fe155130631a2471fd2e14a7a664a4dfbd7194b8229c3d7b2a40b21178639081", size = 11135539, upload-time = "2026-08-13T15:16:30.87Z" }, + { url = "https://files.pythonhosted.org/packages/3e/1e/4b8b72f0d006dbf19326aa99f9ca0ee2ff374187c4d301cf529a51aa06fe/ruff-0.16.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e2ed719e14aa64d895c2ee922594a90a43c861a93f0575a95ff8c47cdbd13eb9", size = 10475095, upload-time = "2026-08-13T15:16:33.259Z" }, + { url = "https://files.pythonhosted.org/packages/92/32/2201fa49ba1f6c101ee321e83f051ac7a4b8d07b0ef6b4d3f2772b302275/ruff-0.16.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9e0b1da805eb043654645d74d5de1e5ce2edc686e40790d2b86f56d71cc06a84", size = 10668771, upload-time = "2026-08-13T15:16:35.65Z" }, + { url = "https://files.pythonhosted.org/packages/c3/66/4afc5c8363bd04d45effce1b7c8713ca037d7a6740b7451a2403a6e3a972/ruff-0.16.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a37bdea0bbe21780f590bf437d6412c8c4e1b6cd010f91a65c2c40c5e5f5f870", size = 10699568, upload-time = "2026-08-13T15:16:38.195Z" }, + { url = "https://files.pythonhosted.org/packages/53/fd/c67d246bf36bf1698551c56de39e95cd07f70e64433e0098e6267d77061b/ruff-0.16.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09571e6d1288ed9be475207a3ac04ada404f1cd898104be0f6ab8d7df438575b", size = 11499365, upload-time = "2026-08-13T15:16:40.623Z" }, + { url = "https://files.pythonhosted.org/packages/67/0b/00ecbceb99a263af7b12f6f05ac3c92bc47b905e91adc3f207a836e3bc01/ruff-0.16.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2c18c5a101eb540010638cc1ff3c84944d3adb3df62b8d98ca8f22ba484d3413", size = 12311728, upload-time = "2026-08-13T15:16:43.564Z" }, + { url = "https://files.pythonhosted.org/packages/54/b2/b7b3bb54f4d3f7db504e476ad4ab8de530dceebe2c061384b2757ee419e8/ruff-0.16.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8457c44f15033c85ddbb77b15d451df9e24e4bd03b628396dd3610cedc3b8f82", size = 11699896, upload-time = "2026-08-13T15:16:46.209Z" }, + { url = "https://files.pythonhosted.org/packages/c7/30/4c468429ac195addc5ee1b717b6ab1b66632786737ca3b2ed3443fb0c26a/ruff-0.16.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:294b95c4ae0cda9388525c2047778aa758d6b8d4bb876fd4e9eaa3ebc92343eb", size = 11058736, upload-time = "2026-08-13T15:16:48.823Z" }, + { url = "https://files.pythonhosted.org/packages/43/67/7a113cdaddf24b64d7f75b1242a99d04c82fcef4f6921fdbb832beaffb5f/ruff-0.16.3-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:3d0c7c40c87c2a820509c31ba007968da6e1306468c067b2d82fbfdbcd0e8474", size = 11586911, upload-time = "2026-08-13T15:16:51.913Z" }, + { url = "https://files.pythonhosted.org/packages/f1/c1/2e66f24c0f3ead25a5e660111778685e505e5da353c82802bf49f0cbe7b9/ruff-0.16.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:9f738c0fdfa8eed0b2ce7fb27ee7258208a92a68d7949e62aa15164bc7b389da", size = 10954265, upload-time = "2026-08-13T15:16:54.763Z" }, + { url = "https://files.pythonhosted.org/packages/c2/ba/4cee23bf52cba9a058d3726de623624daf50ef9638868edd86f4126157f6/ruff-0.16.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:fb785f0be25abe69d320415cd4f833b59e17ba7613d9ba6a958023b6bceb0a50", size = 10709886, upload-time = "2026-08-13T15:16:57.339Z" }, + { url = "https://files.pythonhosted.org/packages/82/df/7da7194fa5d9dc0a285f7e6fa5a4722e7c63faac0b45b614ded9314363a1/ruff-0.16.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c5536e3acfbf9563085aa2be7b13c629c3077e902afc5b941ac44024dbb9f506", size = 11210392, upload-time = "2026-08-13T15:17:00.171Z" }, + { url = "https://files.pythonhosted.org/packages/35/85/7795f6e817af050e7517bf3e7aa9b061cce70ef33d280aad902c956c1ecf/ruff-0.16.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:a2d85c02f9b8e165d85e6779184d38c4132de12603dab59c51c28e22584f9e4d", size = 11626910, upload-time = "2026-08-13T15:17:03.299Z" }, + { url = "https://files.pythonhosted.org/packages/78/9b/475b927cf27a5cbbda3c7bafb69ed6ff77e1d7923d5d85f17c2749d7ae32/ruff-0.16.3-py3-none-win32.whl", hash = "sha256:388cdf2166642bd9b13d52b5932d3170f34f8abed7e8d9a855f1d84b83645a0a", size = 10931415, upload-time = "2026-08-13T15:17:05.726Z" }, + { url = "https://files.pythonhosted.org/packages/b2/99/e2a2bfc4fbf0a1e8a916bc9ebe6fe6c58cc34c28e0ffc6ce281d572d1c2e/ruff-0.16.3-py3-none-win_amd64.whl", hash = "sha256:e80a7d69ca2a6d1c4d352ec91458cdca6e56c83cdbcabd93e4abe1e53591d948", size = 11445993, upload-time = "2026-08-13T15:17:08.353Z" }, + { url = "https://files.pythonhosted.org/packages/69/3e/4132e539aed78c148854d4997a2685b0ed4dc4e87110b59ce528564e184e/ruff-0.16.3-py3-none-win_arm64.whl", hash = "sha256:b8ca152da82c1acc1fa8d5874b15951935f0eef46f10e6954c83859011b6178a", size = 11399302, upload-time = "2026-08-13T15:17:10.908Z" }, +] + +[[package]] +name = "s3transfer" +version = "0.19.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "botocore" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/76/43/35e4d8aa320bffe8287fe8f65f578fa2d2db0a64212f0e710dce58267854/s3transfer-0.19.2.tar.gz", hash = "sha256:ba0309fd86be3c27dbf78cdd813c13c5e1df16e5874b99d2535ebbdfb9892993", size = 165592, upload-time = "2026-07-22T19:30:44.432Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bc/e7/5c595c75e9f41a44f30e526eda465ea0b4eec93470e074e4a111b253f13a/s3transfer-0.19.2-py3-none-any.whl", hash = "sha256:d8168eccca828cbb2cd573675333f3bddd254313a9c42494b84c76b539e8ba25", size = 90216, upload-time = "2026-07-22T19:30:43.251Z" }, +] + +[[package]] +name = "scipy" +version = "1.15.3" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.11'", +] +dependencies = [ + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0f/37/6964b830433e654ec7485e45a00fc9a27cf868d622838f6b6d9c5ec0d532/scipy-1.15.3.tar.gz", hash = "sha256:eae3cf522bc7df64b42cad3925c876e1b0b6c35c1337c93e12c0f366f55b0eaf", size = 59419214, upload-time = "2025-05-08T16:13:05.955Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/2f/4966032c5f8cc7e6a60f1b2e0ad686293b9474b65246b0c642e3ef3badd0/scipy-1.15.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:a345928c86d535060c9c2b25e71e87c39ab2f22fc96e9636bd74d1dbf9de448c", size = 38702770, upload-time = "2025-05-08T16:04:20.849Z" }, + { url = "https://files.pythonhosted.org/packages/a0/6e/0c3bf90fae0e910c274db43304ebe25a6b391327f3f10b5dcc638c090795/scipy-1.15.3-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:ad3432cb0f9ed87477a8d97f03b763fd1d57709f1bbde3c9369b1dff5503b253", size = 30094511, upload-time = "2025-05-08T16:04:27.103Z" }, + { url = "https://files.pythonhosted.org/packages/ea/b1/4deb37252311c1acff7f101f6453f0440794f51b6eacb1aad4459a134081/scipy-1.15.3-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:aef683a9ae6eb00728a542b796f52a5477b78252edede72b8327a886ab63293f", size = 22368151, upload-time = "2025-05-08T16:04:31.731Z" }, + { url = "https://files.pythonhosted.org/packages/38/7d/f457626e3cd3c29b3a49ca115a304cebb8cc6f31b04678f03b216899d3c6/scipy-1.15.3-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:1c832e1bd78dea67d5c16f786681b28dd695a8cb1fb90af2e27580d3d0967e92", size = 25121732, upload-time = "2025-05-08T16:04:36.596Z" }, + { url = "https://files.pythonhosted.org/packages/db/0a/92b1de4a7adc7a15dcf5bddc6e191f6f29ee663b30511ce20467ef9b82e4/scipy-1.15.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:263961f658ce2165bbd7b99fa5135195c3a12d9bef045345016b8b50c315cb82", size = 35547617, upload-time = "2025-05-08T16:04:43.546Z" }, + { url = "https://files.pythonhosted.org/packages/8e/6d/41991e503e51fc1134502694c5fa7a1671501a17ffa12716a4a9151af3df/scipy-1.15.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e2abc762b0811e09a0d3258abee2d98e0c703eee49464ce0069590846f31d40", size = 37662964, upload-time = "2025-05-08T16:04:49.431Z" }, + { url = "https://files.pythonhosted.org/packages/25/e1/3df8f83cb15f3500478c889be8fb18700813b95e9e087328230b98d547ff/scipy-1.15.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ed7284b21a7a0c8f1b6e5977ac05396c0d008b89e05498c8b7e8f4a1423bba0e", size = 37238749, upload-time = "2025-05-08T16:04:55.215Z" }, + { url = "https://files.pythonhosted.org/packages/93/3e/b3257cf446f2a3533ed7809757039016b74cd6f38271de91682aa844cfc5/scipy-1.15.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5380741e53df2c566f4d234b100a484b420af85deb39ea35a1cc1be84ff53a5c", size = 40022383, upload-time = "2025-05-08T16:05:01.914Z" }, + { url = "https://files.pythonhosted.org/packages/d1/84/55bc4881973d3f79b479a5a2e2df61c8c9a04fcb986a213ac9c02cfb659b/scipy-1.15.3-cp310-cp310-win_amd64.whl", hash = "sha256:9d61e97b186a57350f6d6fd72640f9e99d5a4a2b8fbf4b9ee9a841eab327dc13", size = 41259201, upload-time = "2025-05-08T16:05:08.166Z" }, + { url = "https://files.pythonhosted.org/packages/96/ab/5cc9f80f28f6a7dff646c5756e559823614a42b1939d86dd0ed550470210/scipy-1.15.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:993439ce220d25e3696d1b23b233dd010169b62f6456488567e830654ee37a6b", size = 38714255, upload-time = "2025-05-08T16:05:14.596Z" }, + { url = "https://files.pythonhosted.org/packages/4a/4a/66ba30abe5ad1a3ad15bfb0b59d22174012e8056ff448cb1644deccbfed2/scipy-1.15.3-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:34716e281f181a02341ddeaad584205bd2fd3c242063bd3423d61ac259ca7eba", size = 30111035, upload-time = "2025-05-08T16:05:20.152Z" }, + { url = "https://files.pythonhosted.org/packages/4b/fa/a7e5b95afd80d24313307f03624acc65801846fa75599034f8ceb9e2cbf6/scipy-1.15.3-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3b0334816afb8b91dab859281b1b9786934392aa3d527cd847e41bb6f45bee65", size = 22384499, upload-time = "2025-05-08T16:05:24.494Z" }, + { url = "https://files.pythonhosted.org/packages/17/99/f3aaddccf3588bb4aea70ba35328c204cadd89517a1612ecfda5b2dd9d7a/scipy-1.15.3-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:6db907c7368e3092e24919b5e31c76998b0ce1684d51a90943cb0ed1b4ffd6c1", size = 25152602, upload-time = "2025-05-08T16:05:29.313Z" }, + { url = "https://files.pythonhosted.org/packages/56/c5/1032cdb565f146109212153339f9cb8b993701e9fe56b1c97699eee12586/scipy-1.15.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:721d6b4ef5dc82ca8968c25b111e307083d7ca9091bc38163fb89243e85e3889", size = 35503415, upload-time = "2025-05-08T16:05:34.699Z" }, + { url = "https://files.pythonhosted.org/packages/bd/37/89f19c8c05505d0601ed5650156e50eb881ae3918786c8fd7262b4ee66d3/scipy-1.15.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39cb9c62e471b1bb3750066ecc3a3f3052b37751c7c3dfd0fd7e48900ed52982", size = 37652622, upload-time = "2025-05-08T16:05:40.762Z" }, + { url = "https://files.pythonhosted.org/packages/7e/31/be59513aa9695519b18e1851bb9e487de66f2d31f835201f1b42f5d4d475/scipy-1.15.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:795c46999bae845966368a3c013e0e00947932d68e235702b5c3f6ea799aa8c9", size = 37244796, upload-time = "2025-05-08T16:05:48.119Z" }, + { url = "https://files.pythonhosted.org/packages/10/c0/4f5f3eeccc235632aab79b27a74a9130c6c35df358129f7ac8b29f562ac7/scipy-1.15.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:18aaacb735ab38b38db42cb01f6b92a2d0d4b6aabefeb07f02849e47f8fb3594", size = 40047684, upload-time = "2025-05-08T16:05:54.22Z" }, + { url = "https://files.pythonhosted.org/packages/ab/a7/0ddaf514ce8a8714f6ed243a2b391b41dbb65251affe21ee3077ec45ea9a/scipy-1.15.3-cp311-cp311-win_amd64.whl", hash = "sha256:ae48a786a28412d744c62fd7816a4118ef97e5be0bee968ce8f0a2fba7acf3bb", size = 41246504, upload-time = "2025-05-08T16:06:00.437Z" }, + { url = "https://files.pythonhosted.org/packages/37/4b/683aa044c4162e10ed7a7ea30527f2cbd92e6999c10a8ed8edb253836e9c/scipy-1.15.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6ac6310fdbfb7aa6612408bd2f07295bcbd3fda00d2d702178434751fe48e019", size = 38766735, upload-time = "2025-05-08T16:06:06.471Z" }, + { url = "https://files.pythonhosted.org/packages/7b/7e/f30be3d03de07f25dc0ec926d1681fed5c732d759ac8f51079708c79e680/scipy-1.15.3-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:185cd3d6d05ca4b44a8f1595af87f9c372bb6acf9c808e99aa3e9aa03bd98cf6", size = 30173284, upload-time = "2025-05-08T16:06:11.686Z" }, + { url = "https://files.pythonhosted.org/packages/07/9c/0ddb0d0abdabe0d181c1793db51f02cd59e4901da6f9f7848e1f96759f0d/scipy-1.15.3-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:05dc6abcd105e1a29f95eada46d4a3f251743cfd7d3ae8ddb4088047f24ea477", size = 22446958, upload-time = "2025-05-08T16:06:15.97Z" }, + { url = "https://files.pythonhosted.org/packages/af/43/0bce905a965f36c58ff80d8bea33f1f9351b05fad4beaad4eae34699b7a1/scipy-1.15.3-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:06efcba926324df1696931a57a176c80848ccd67ce6ad020c810736bfd58eb1c", size = 25242454, upload-time = "2025-05-08T16:06:20.394Z" }, + { url = "https://files.pythonhosted.org/packages/56/30/a6f08f84ee5b7b28b4c597aca4cbe545535c39fe911845a96414700b64ba/scipy-1.15.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c05045d8b9bfd807ee1b9f38761993297b10b245f012b11b13b91ba8945f7e45", size = 35210199, upload-time = "2025-05-08T16:06:26.159Z" }, + { url = "https://files.pythonhosted.org/packages/0b/1f/03f52c282437a168ee2c7c14a1a0d0781a9a4a8962d84ac05c06b4c5b555/scipy-1.15.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:271e3713e645149ea5ea3e97b57fdab61ce61333f97cfae392c28ba786f9bb49", size = 37309455, upload-time = "2025-05-08T16:06:32.778Z" }, + { url = "https://files.pythonhosted.org/packages/89/b1/fbb53137f42c4bf630b1ffdfc2151a62d1d1b903b249f030d2b1c0280af8/scipy-1.15.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6cfd56fc1a8e53f6e89ba3a7a7251f7396412d655bca2aa5611c8ec9a6784a1e", size = 36885140, upload-time = "2025-05-08T16:06:39.249Z" }, + { url = "https://files.pythonhosted.org/packages/2e/2e/025e39e339f5090df1ff266d021892694dbb7e63568edcfe43f892fa381d/scipy-1.15.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0ff17c0bb1cb32952c09217d8d1eed9b53d1463e5f1dd6052c7857f83127d539", size = 39710549, upload-time = "2025-05-08T16:06:45.729Z" }, + { url = "https://files.pythonhosted.org/packages/e6/eb/3bf6ea8ab7f1503dca3a10df2e4b9c3f6b3316df07f6c0ded94b281c7101/scipy-1.15.3-cp312-cp312-win_amd64.whl", hash = "sha256:52092bc0472cfd17df49ff17e70624345efece4e1a12b23783a1ac59a1b728ed", size = 40966184, upload-time = "2025-05-08T16:06:52.623Z" }, + { url = "https://files.pythonhosted.org/packages/73/18/ec27848c9baae6e0d6573eda6e01a602e5649ee72c27c3a8aad673ebecfd/scipy-1.15.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2c620736bcc334782e24d173c0fdbb7590a0a436d2fdf39310a8902505008759", size = 38728256, upload-time = "2025-05-08T16:06:58.696Z" }, + { url = "https://files.pythonhosted.org/packages/74/cd/1aef2184948728b4b6e21267d53b3339762c285a46a274ebb7863c9e4742/scipy-1.15.3-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:7e11270a000969409d37ed399585ee530b9ef6aa99d50c019de4cb01e8e54e62", size = 30109540, upload-time = "2025-05-08T16:07:04.209Z" }, + { url = "https://files.pythonhosted.org/packages/5b/d8/59e452c0a255ec352bd0a833537a3bc1bfb679944c4938ab375b0a6b3a3e/scipy-1.15.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:8c9ed3ba2c8a2ce098163a9bdb26f891746d02136995df25227a20e71c396ebb", size = 22383115, upload-time = "2025-05-08T16:07:08.998Z" }, + { url = "https://files.pythonhosted.org/packages/08/f5/456f56bbbfccf696263b47095291040655e3cbaf05d063bdc7c7517f32ac/scipy-1.15.3-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:0bdd905264c0c9cfa74a4772cdb2070171790381a5c4d312c973382fc6eaf730", size = 25163884, upload-time = "2025-05-08T16:07:14.091Z" }, + { url = "https://files.pythonhosted.org/packages/a2/66/a9618b6a435a0f0c0b8a6d0a2efb32d4ec5a85f023c2b79d39512040355b/scipy-1.15.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79167bba085c31f38603e11a267d862957cbb3ce018d8b38f79ac043bc92d825", size = 35174018, upload-time = "2025-05-08T16:07:19.427Z" }, + { url = "https://files.pythonhosted.org/packages/b5/09/c5b6734a50ad4882432b6bb7c02baf757f5b2f256041da5df242e2d7e6b6/scipy-1.15.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9deabd6d547aee2c9a81dee6cc96c6d7e9a9b1953f74850c179f91fdc729cb7", size = 37269716, upload-time = "2025-05-08T16:07:25.712Z" }, + { url = "https://files.pythonhosted.org/packages/77/0a/eac00ff741f23bcabd352731ed9b8995a0a60ef57f5fd788d611d43d69a1/scipy-1.15.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:dde4fc32993071ac0c7dd2d82569e544f0bdaff66269cb475e0f369adad13f11", size = 36872342, upload-time = "2025-05-08T16:07:31.468Z" }, + { url = "https://files.pythonhosted.org/packages/fe/54/4379be86dd74b6ad81551689107360d9a3e18f24d20767a2d5b9253a3f0a/scipy-1.15.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f77f853d584e72e874d87357ad70f44b437331507d1c311457bed8ed2b956126", size = 39670869, upload-time = "2025-05-08T16:07:38.002Z" }, + { url = "https://files.pythonhosted.org/packages/87/2e/892ad2862ba54f084ffe8cc4a22667eaf9c2bcec6d2bff1d15713c6c0703/scipy-1.15.3-cp313-cp313-win_amd64.whl", hash = "sha256:b90ab29d0c37ec9bf55424c064312930ca5f4bde15ee8619ee44e69319aab163", size = 40988851, upload-time = "2025-05-08T16:08:33.671Z" }, + { url = "https://files.pythonhosted.org/packages/1b/e9/7a879c137f7e55b30d75d90ce3eb468197646bc7b443ac036ae3fe109055/scipy-1.15.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3ac07623267feb3ae308487c260ac684b32ea35fd81e12845039952f558047b8", size = 38863011, upload-time = "2025-05-08T16:07:44.039Z" }, + { url = "https://files.pythonhosted.org/packages/51/d1/226a806bbd69f62ce5ef5f3ffadc35286e9fbc802f606a07eb83bf2359de/scipy-1.15.3-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:6487aa99c2a3d509a5227d9a5e889ff05830a06b2ce08ec30df6d79db5fcd5c5", size = 30266407, upload-time = "2025-05-08T16:07:49.891Z" }, + { url = "https://files.pythonhosted.org/packages/e5/9b/f32d1d6093ab9eeabbd839b0f7619c62e46cc4b7b6dbf05b6e615bbd4400/scipy-1.15.3-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:50f9e62461c95d933d5c5ef4a1f2ebf9a2b4e83b0db374cb3f1de104d935922e", size = 22540030, upload-time = "2025-05-08T16:07:54.121Z" }, + { url = "https://files.pythonhosted.org/packages/e7/29/c278f699b095c1a884f29fda126340fcc201461ee8bfea5c8bdb1c7c958b/scipy-1.15.3-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:14ed70039d182f411ffc74789a16df3835e05dc469b898233a245cdfd7f162cb", size = 25218709, upload-time = "2025-05-08T16:07:58.506Z" }, + { url = "https://files.pythonhosted.org/packages/24/18/9e5374b617aba742a990581373cd6b68a2945d65cc588482749ef2e64467/scipy-1.15.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a769105537aa07a69468a0eefcd121be52006db61cdd8cac8a0e68980bbb723", size = 34809045, upload-time = "2025-05-08T16:08:03.929Z" }, + { url = "https://files.pythonhosted.org/packages/e1/fe/9c4361e7ba2927074360856db6135ef4904d505e9b3afbbcb073c4008328/scipy-1.15.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9db984639887e3dffb3928d118145ffe40eff2fa40cb241a306ec57c219ebbbb", size = 36703062, upload-time = "2025-05-08T16:08:09.558Z" }, + { url = "https://files.pythonhosted.org/packages/b7/8e/038ccfe29d272b30086b25a4960f757f97122cb2ec42e62b460d02fe98e9/scipy-1.15.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:40e54d5c7e7ebf1aa596c374c49fa3135f04648a0caabcb66c52884b943f02b4", size = 36393132, upload-time = "2025-05-08T16:08:15.34Z" }, + { url = "https://files.pythonhosted.org/packages/10/7e/5c12285452970be5bdbe8352c619250b97ebf7917d7a9a9e96b8a8140f17/scipy-1.15.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5e721fed53187e71d0ccf382b6bf977644c533e506c4d33c3fb24de89f5c3ed5", size = 38979503, upload-time = "2025-05-08T16:08:21.513Z" }, + { url = "https://files.pythonhosted.org/packages/81/06/0a5e5349474e1cbc5757975b21bd4fad0e72ebf138c5592f191646154e06/scipy-1.15.3-cp313-cp313t-win_amd64.whl", hash = "sha256:76ad1fb5f8752eabf0fa02e4cc0336b4e8f021e2d5f061ed37d6d264db35e3ca", size = 40308097, upload-time = "2025-05-08T16:08:27.627Z" }, +] + +[[package]] +name = "scipy" +version = "1.17.1" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version == '3.11.*' and sys_platform == 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'emscripten'", + "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] +dependencies = [ + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7a/97/5a3609c4f8d58b039179648e62dd220f89864f56f7357f5d4f45c29eb2cc/scipy-1.17.1.tar.gz", hash = "sha256:95d8e012d8cb8816c226aef832200b1d45109ed4464303e997c5b13122b297c0", size = 30573822, upload-time = "2026-02-23T00:26:24.851Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/75/b4ce781849931fef6fd529afa6b63711d5a733065722d0c3e2724af9e40a/scipy-1.17.1-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:1f95b894f13729334fb990162e911c9e5dc1ab390c58aa6cbecb389c5b5e28ec", size = 31613675, upload-time = "2026-02-23T00:16:00.13Z" }, + { url = "https://files.pythonhosted.org/packages/f7/58/bccc2861b305abdd1b8663d6130c0b3d7cc22e8d86663edbc8401bfd40d4/scipy-1.17.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:e18f12c6b0bc5a592ed23d3f7b891f68fd7f8241d69b7883769eb5d5dfb52696", size = 28162057, upload-time = "2026-02-23T00:16:09.456Z" }, + { url = "https://files.pythonhosted.org/packages/6d/ee/18146b7757ed4976276b9c9819108adbc73c5aad636e5353e20746b73069/scipy-1.17.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:a3472cfbca0a54177d0faa68f697d8ba4c80bbdc19908c3465556d9f7efce9ee", size = 20334032, upload-time = "2026-02-23T00:16:17.358Z" }, + { url = "https://files.pythonhosted.org/packages/ec/e6/cef1cf3557f0c54954198554a10016b6a03b2ec9e22a4e1df734936bd99c/scipy-1.17.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:766e0dc5a616d026a3a1cffa379af959671729083882f50307e18175797b3dfd", size = 22709533, upload-time = "2026-02-23T00:16:25.791Z" }, + { url = "https://files.pythonhosted.org/packages/4d/60/8804678875fc59362b0fb759ab3ecce1f09c10a735680318ac30da8cd76b/scipy-1.17.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:744b2bf3640d907b79f3fd7874efe432d1cf171ee721243e350f55234b4cec4c", size = 33062057, upload-time = "2026-02-23T00:16:36.931Z" }, + { url = "https://files.pythonhosted.org/packages/09/7d/af933f0f6e0767995b4e2d705a0665e454d1c19402aa7e895de3951ebb04/scipy-1.17.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:43af8d1f3bea642559019edfe64e9b11192a8978efbd1539d7bc2aaa23d92de4", size = 35349300, upload-time = "2026-02-23T00:16:49.108Z" }, + { url = "https://files.pythonhosted.org/packages/b4/3d/7ccbbdcbb54c8fdc20d3b6930137c782a163fa626f0aef920349873421ba/scipy-1.17.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cd96a1898c0a47be4520327e01f874acfd61fb48a9420f8aa9f6483412ffa444", size = 35127333, upload-time = "2026-02-23T00:17:01.293Z" }, + { url = "https://files.pythonhosted.org/packages/e8/19/f926cb11c42b15ba08e3a71e376d816ac08614f769b4f47e06c3580c836a/scipy-1.17.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4eb6c25dd62ee8d5edf68a8e1c171dd71c292fdae95d8aeb3dd7d7de4c364082", size = 37741314, upload-time = "2026-02-23T00:17:12.576Z" }, + { url = "https://files.pythonhosted.org/packages/95/da/0d1df507cf574b3f224ccc3d45244c9a1d732c81dcb26b1e8a766ae271a8/scipy-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:d30e57c72013c2a4fe441c2fcb8e77b14e152ad48b5464858e07e2ad9fbfceff", size = 36607512, upload-time = "2026-02-23T00:17:23.424Z" }, + { url = "https://files.pythonhosted.org/packages/68/7f/bdd79ceaad24b671543ffe0ef61ed8e659440eb683b66f033454dcee90eb/scipy-1.17.1-cp311-cp311-win_arm64.whl", hash = "sha256:9ecb4efb1cd6e8c4afea0daa91a87fbddbce1b99d2895d151596716c0b2e859d", size = 24599248, upload-time = "2026-02-23T00:17:34.561Z" }, + { url = "https://files.pythonhosted.org/packages/35/48/b992b488d6f299dbe3f11a20b24d3dda3d46f1a635ede1c46b5b17a7b163/scipy-1.17.1-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:35c3a56d2ef83efc372eaec584314bd0ef2e2f0d2adb21c55e6ad5b344c0dcb8", size = 31610954, upload-time = "2026-02-23T00:17:49.855Z" }, + { url = "https://files.pythonhosted.org/packages/b2/02/cf107b01494c19dc100f1d0b7ac3cc08666e96ba2d64db7626066cee895e/scipy-1.17.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:fcb310ddb270a06114bb64bbe53c94926b943f5b7f0842194d585c65eb4edd76", size = 28172662, upload-time = "2026-02-23T00:18:01.64Z" }, + { url = "https://files.pythonhosted.org/packages/cf/a9/599c28631bad314d219cf9ffd40e985b24d603fc8a2f4ccc5ae8419a535b/scipy-1.17.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:cc90d2e9c7e5c7f1a482c9875007c095c3194b1cfedca3c2f3291cdc2bc7c086", size = 20344366, upload-time = "2026-02-23T00:18:12.015Z" }, + { url = "https://files.pythonhosted.org/packages/35/f5/906eda513271c8deb5af284e5ef0206d17a96239af79f9fa0aebfe0e36b4/scipy-1.17.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:c80be5ede8f3f8eded4eff73cc99a25c388ce98e555b17d31da05287015ffa5b", size = 22704017, upload-time = "2026-02-23T00:18:21.502Z" }, + { url = "https://files.pythonhosted.org/packages/da/34/16f10e3042d2f1d6b66e0428308ab52224b6a23049cb2f5c1756f713815f/scipy-1.17.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e19ebea31758fac5893a2ac360fedd00116cbb7628e650842a6691ba7ca28a21", size = 32927842, upload-time = "2026-02-23T00:18:35.367Z" }, + { url = "https://files.pythonhosted.org/packages/01/8e/1e35281b8ab6d5d72ebe9911edcdffa3f36b04ed9d51dec6dd140396e220/scipy-1.17.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:02ae3b274fde71c5e92ac4d54bc06c42d80e399fec704383dcd99b301df37458", size = 35235890, upload-time = "2026-02-23T00:18:49.188Z" }, + { url = "https://files.pythonhosted.org/packages/c5/5c/9d7f4c88bea6e0d5a4f1bc0506a53a00e9fcb198de372bfe4d3652cef482/scipy-1.17.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8a604bae87c6195d8b1045eddece0514d041604b14f2727bbc2b3020172045eb", size = 35003557, upload-time = "2026-02-23T00:18:54.74Z" }, + { url = "https://files.pythonhosted.org/packages/65/94/7698add8f276dbab7a9de9fb6b0e02fc13ee61d51c7c3f85ac28b65e1239/scipy-1.17.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f590cd684941912d10becc07325a3eeb77886fe981415660d9265c4c418d0bea", size = 37625856, upload-time = "2026-02-23T00:19:00.307Z" }, + { url = "https://files.pythonhosted.org/packages/a2/84/dc08d77fbf3d87d3ee27f6a0c6dcce1de5829a64f2eae85a0ecc1f0daa73/scipy-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:41b71f4a3a4cab9d366cd9065b288efc4d4f3c0b37a91a8e0947fb5bd7f31d87", size = 36549682, upload-time = "2026-02-23T00:19:07.67Z" }, + { url = "https://files.pythonhosted.org/packages/bc/98/fe9ae9ffb3b54b62559f52dedaebe204b408db8109a8c66fdd04869e6424/scipy-1.17.1-cp312-cp312-win_arm64.whl", hash = "sha256:f4115102802df98b2b0db3cce5cb9b92572633a1197c77b7553e5203f284a5b3", size = 24547340, upload-time = "2026-02-23T00:19:12.024Z" }, + { url = "https://files.pythonhosted.org/packages/76/27/07ee1b57b65e92645f219b37148a7e7928b82e2b5dbeccecb4dff7c64f0b/scipy-1.17.1-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:5e3c5c011904115f88a39308379c17f91546f77c1667cea98739fe0fccea804c", size = 31590199, upload-time = "2026-02-23T00:19:17.192Z" }, + { url = "https://files.pythonhosted.org/packages/ec/ae/db19f8ab842e9b724bf5dbb7db29302a91f1e55bc4d04b1025d6d605a2c5/scipy-1.17.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:6fac755ca3d2c3edcb22f479fceaa241704111414831ddd3bc6056e18516892f", size = 28154001, upload-time = "2026-02-23T00:19:22.241Z" }, + { url = "https://files.pythonhosted.org/packages/5b/58/3ce96251560107b381cbd6e8413c483bbb1228a6b919fa8652b0d4090e7f/scipy-1.17.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:7ff200bf9d24f2e4d5dc6ee8c3ac64d739d3a89e2326ba68aaf6c4a2b838fd7d", size = 20325719, upload-time = "2026-02-23T00:19:26.329Z" }, + { url = "https://files.pythonhosted.org/packages/b2/83/15087d945e0e4d48ce2377498abf5ad171ae013232ae31d06f336e64c999/scipy-1.17.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:4b400bdc6f79fa02a4d86640310dde87a21fba0c979efff5248908c6f15fad1b", size = 22683595, upload-time = "2026-02-23T00:19:30.304Z" }, + { url = "https://files.pythonhosted.org/packages/b4/e0/e58fbde4a1a594c8be8114eb4aac1a55bcd6587047efc18a61eb1f5c0d30/scipy-1.17.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2b64ca7d4aee0102a97f3ba22124052b4bd2152522355073580bf4845e2550b6", size = 32896429, upload-time = "2026-02-23T00:19:35.536Z" }, + { url = "https://files.pythonhosted.org/packages/f5/5f/f17563f28ff03c7b6799c50d01d5d856a1d55f2676f537ca8d28c7f627cd/scipy-1.17.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:581b2264fc0aa555f3f435a5944da7504ea3a065d7029ad60e7c3d1ae09c5464", size = 35203952, upload-time = "2026-02-23T00:19:42.259Z" }, + { url = "https://files.pythonhosted.org/packages/8d/a5/9afd17de24f657fdfe4df9a3f1ea049b39aef7c06000c13db1530d81ccca/scipy-1.17.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:beeda3d4ae615106d7094f7e7cef6218392e4465cc95d25f900bebabfded0950", size = 34979063, upload-time = "2026-02-23T00:19:47.547Z" }, + { url = "https://files.pythonhosted.org/packages/8b/13/88b1d2384b424bf7c924f2038c1c409f8d88bb2a8d49d097861dd64a57b2/scipy-1.17.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6609bc224e9568f65064cfa72edc0f24ee6655b47575954ec6339534b2798369", size = 37598449, upload-time = "2026-02-23T00:19:53.238Z" }, + { url = "https://files.pythonhosted.org/packages/35/e5/d6d0e51fc888f692a35134336866341c08655d92614f492c6860dc45bb2c/scipy-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:37425bc9175607b0268f493d79a292c39f9d001a357bebb6b88fdfaff13f6448", size = 36510943, upload-time = "2026-02-23T00:20:50.89Z" }, + { url = "https://files.pythonhosted.org/packages/2a/fd/3be73c564e2a01e690e19cc618811540ba5354c67c8680dce3281123fb79/scipy-1.17.1-cp313-cp313-win_arm64.whl", hash = "sha256:5cf36e801231b6a2059bf354720274b7558746f3b1a4efb43fcf557ccd484a87", size = 24545621, upload-time = "2026-02-23T00:20:55.871Z" }, + { url = "https://files.pythonhosted.org/packages/6f/6b/17787db8b8114933a66f9dcc479a8272e4b4da75fe03b0c282f7b0ade8cd/scipy-1.17.1-cp313-cp313t-macosx_10_14_x86_64.whl", hash = "sha256:d59c30000a16d8edc7e64152e30220bfbd724c9bbb08368c054e24c651314f0a", size = 31936708, upload-time = "2026-02-23T00:19:58.694Z" }, + { url = "https://files.pythonhosted.org/packages/38/2e/524405c2b6392765ab1e2b722a41d5da33dc5c7b7278184a8ad29b6cb206/scipy-1.17.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:010f4333c96c9bb1a4516269e33cb5917b08ef2166d5556ca2fd9f082a9e6ea0", size = 28570135, upload-time = "2026-02-23T00:20:03.934Z" }, + { url = "https://files.pythonhosted.org/packages/fd/c3/5bd7199f4ea8556c0c8e39f04ccb014ac37d1468e6cfa6a95c6b3562b76e/scipy-1.17.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:2ceb2d3e01c5f1d83c4189737a42d9cb2fc38a6eeed225e7515eef71ad301dce", size = 20741977, upload-time = "2026-02-23T00:20:07.935Z" }, + { url = "https://files.pythonhosted.org/packages/d9/b8/8ccd9b766ad14c78386599708eb745f6b44f08400a5fd0ade7cf89b6fc93/scipy-1.17.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:844e165636711ef41f80b4103ed234181646b98a53c8f05da12ca5ca289134f6", size = 23029601, upload-time = "2026-02-23T00:20:12.161Z" }, + { url = "https://files.pythonhosted.org/packages/6d/a0/3cb6f4d2fb3e17428ad2880333cac878909ad1a89f678527b5328b93c1d4/scipy-1.17.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:158dd96d2207e21c966063e1635b1063cd7787b627b6f07305315dd73d9c679e", size = 33019667, upload-time = "2026-02-23T00:20:17.208Z" }, + { url = "https://files.pythonhosted.org/packages/f3/c3/2d834a5ac7bf3a0c806ad1508efc02dda3c8c61472a56132d7894c312dea/scipy-1.17.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:74cbb80d93260fe2ffa334efa24cb8f2f0f622a9b9febf8b483c0b865bfb3475", size = 35264159, upload-time = "2026-02-23T00:20:23.087Z" }, + { url = "https://files.pythonhosted.org/packages/4d/77/d3ed4becfdbd217c52062fafe35a72388d1bd82c2d0ba5ca19d6fcc93e11/scipy-1.17.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:dbc12c9f3d185f5c737d801da555fb74b3dcfa1a50b66a1a93e09190f41fab50", size = 35102771, upload-time = "2026-02-23T00:20:28.636Z" }, + { url = "https://files.pythonhosted.org/packages/bd/12/d19da97efde68ca1ee5538bb261d5d2c062f0c055575128f11a2730e3ac1/scipy-1.17.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:94055a11dfebe37c656e70317e1996dc197e1a15bbcc351bcdd4610e128fe1ca", size = 37665910, upload-time = "2026-02-23T00:20:34.743Z" }, + { url = "https://files.pythonhosted.org/packages/06/1c/1172a88d507a4baaf72c5a09bb6c018fe2ae0ab622e5830b703a46cc9e44/scipy-1.17.1-cp313-cp313t-win_amd64.whl", hash = "sha256:e30bdeaa5deed6bc27b4cc490823cd0347d7dae09119b8803ae576ea0ce52e4c", size = 36562980, upload-time = "2026-02-23T00:20:40.575Z" }, + { url = "https://files.pythonhosted.org/packages/70/b0/eb757336e5a76dfa7911f63252e3b7d1de00935d7705cf772db5b45ec238/scipy-1.17.1-cp313-cp313t-win_arm64.whl", hash = "sha256:a720477885a9d2411f94a93d16f9d89bad0f28ca23c3f8daa521e2dcc3f44d49", size = 24856543, upload-time = "2026-02-23T00:20:45.313Z" }, + { url = "https://files.pythonhosted.org/packages/cf/83/333afb452af6f0fd70414dc04f898647ee1423979ce02efa75c3b0f2c28e/scipy-1.17.1-cp314-cp314-macosx_10_14_x86_64.whl", hash = "sha256:a48a72c77a310327f6a3a920092fa2b8fd03d7deaa60f093038f22d98e096717", size = 31584510, upload-time = "2026-02-23T00:21:01.015Z" }, + { url = "https://files.pythonhosted.org/packages/ed/a6/d05a85fd51daeb2e4ea71d102f15b34fedca8e931af02594193ae4fd25f7/scipy-1.17.1-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:45abad819184f07240d8a696117a7aacd39787af9e0b719d00285549ed19a1e9", size = 28170131, upload-time = "2026-02-23T00:21:05.888Z" }, + { url = "https://files.pythonhosted.org/packages/db/7b/8624a203326675d7746a254083a187398090a179335b2e4a20e2ddc46e83/scipy-1.17.1-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:3fd1fcdab3ea951b610dc4cef356d416d5802991e7e32b5254828d342f7b7e0b", size = 20342032, upload-time = "2026-02-23T00:21:09.904Z" }, + { url = "https://files.pythonhosted.org/packages/c9/35/2c342897c00775d688d8ff3987aced3426858fd89d5a0e26e020b660b301/scipy-1.17.1-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:7bdf2da170b67fdf10bca777614b1c7d96ae3ca5794fd9587dce41eb2966e866", size = 22678766, upload-time = "2026-02-23T00:21:14.313Z" }, + { url = "https://files.pythonhosted.org/packages/ef/f2/7cdb8eb308a1a6ae1e19f945913c82c23c0c442a462a46480ce487fdc0ac/scipy-1.17.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:adb2642e060a6549c343603a3851ba76ef0b74cc8c079a9a58121c7ec9fe2350", size = 32957007, upload-time = "2026-02-23T00:21:19.663Z" }, + { url = "https://files.pythonhosted.org/packages/0b/2e/7eea398450457ecb54e18e9d10110993fa65561c4f3add5e8eccd2b9cd41/scipy-1.17.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eee2cfda04c00a857206a4330f0c5e3e56535494e30ca445eb19ec624ae75118", size = 35221333, upload-time = "2026-02-23T00:21:25.278Z" }, + { url = "https://files.pythonhosted.org/packages/d9/77/5b8509d03b77f093a0d52e606d3c4f79e8b06d1d38c441dacb1e26cacf46/scipy-1.17.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d2650c1fb97e184d12d8ba010493ee7b322864f7d3d00d3f9bb97d9c21de4068", size = 35042066, upload-time = "2026-02-23T00:21:31.358Z" }, + { url = "https://files.pythonhosted.org/packages/f9/df/18f80fb99df40b4070328d5ae5c596f2f00fffb50167e31439e932f29e7d/scipy-1.17.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:08b900519463543aa604a06bec02461558a6e1cef8fdbb8098f77a48a83c8118", size = 37612763, upload-time = "2026-02-23T00:21:37.247Z" }, + { url = "https://files.pythonhosted.org/packages/4b/39/f0e8ea762a764a9dc52aa7dabcfad51a354819de1f0d4652b6a1122424d6/scipy-1.17.1-cp314-cp314-win_amd64.whl", hash = "sha256:3877ac408e14da24a6196de0ddcace62092bfc12a83823e92e49e40747e52c19", size = 37290984, upload-time = "2026-02-23T00:22:35.023Z" }, + { url = "https://files.pythonhosted.org/packages/7c/56/fe201e3b0f93d1a8bcf75d3379affd228a63d7e2d80ab45467a74b494947/scipy-1.17.1-cp314-cp314-win_arm64.whl", hash = "sha256:f8885db0bc2bffa59d5c1b72fad7a6a92d3e80e7257f967dd81abb553a90d293", size = 25192877, upload-time = "2026-02-23T00:22:39.798Z" }, + { url = "https://files.pythonhosted.org/packages/96/ad/f8c414e121f82e02d76f310f16db9899c4fcde36710329502a6b2a3c0392/scipy-1.17.1-cp314-cp314t-macosx_10_14_x86_64.whl", hash = "sha256:1cc682cea2ae55524432f3cdff9e9a3be743d52a7443d0cba9017c23c87ae2f6", size = 31949750, upload-time = "2026-02-23T00:21:42.289Z" }, + { url = "https://files.pythonhosted.org/packages/7c/b0/c741e8865d61b67c81e255f4f0a832846c064e426636cd7de84e74d209be/scipy-1.17.1-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:2040ad4d1795a0ae89bfc7e8429677f365d45aa9fd5e4587cf1ea737f927b4a1", size = 28585858, upload-time = "2026-02-23T00:21:47.706Z" }, + { url = "https://files.pythonhosted.org/packages/ed/1b/3985219c6177866628fa7c2595bfd23f193ceebbe472c98a08824b9466ff/scipy-1.17.1-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:131f5aaea57602008f9822e2115029b55d4b5f7c070287699fe45c661d051e39", size = 20757723, upload-time = "2026-02-23T00:21:52.039Z" }, + { url = "https://files.pythonhosted.org/packages/c0/19/2a04aa25050d656d6f7b9e7b685cc83d6957fb101665bfd9369ca6534563/scipy-1.17.1-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:9cdc1a2fcfd5c52cfb3045feb399f7b3ce822abdde3a193a6b9a60b3cb5854ca", size = 23043098, upload-time = "2026-02-23T00:21:56.185Z" }, + { url = "https://files.pythonhosted.org/packages/86/f1/3383beb9b5d0dbddd030335bf8a8b32d4317185efe495374f134d8be6cce/scipy-1.17.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e3dcd57ab780c741fde8dc68619de988b966db759a3c3152e8e9142c26295ad", size = 33030397, upload-time = "2026-02-23T00:22:01.404Z" }, + { url = "https://files.pythonhosted.org/packages/41/68/8f21e8a65a5a03f25a79165ec9d2b28c00e66dc80546cf5eb803aeeff35b/scipy-1.17.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a9956e4d4f4a301ebf6cde39850333a6b6110799d470dbbb1e25326ac447f52a", size = 35281163, upload-time = "2026-02-23T00:22:07.024Z" }, + { url = "https://files.pythonhosted.org/packages/84/8d/c8a5e19479554007a5632ed7529e665c315ae7492b4f946b0deb39870e39/scipy-1.17.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:a4328d245944d09fd639771de275701ccadf5f781ba0ff092ad141e017eccda4", size = 35116291, upload-time = "2026-02-23T00:22:12.585Z" }, + { url = "https://files.pythonhosted.org/packages/52/52/e57eceff0e342a1f50e274264ed47497b59e6a4e3118808ee58ddda7b74a/scipy-1.17.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a77cbd07b940d326d39a1d1b37817e2ee4d79cb30e7338f3d0cddffae70fcaa2", size = 37682317, upload-time = "2026-02-23T00:22:18.513Z" }, + { url = "https://files.pythonhosted.org/packages/11/2f/b29eafe4a3fbc3d6de9662b36e028d5f039e72d345e05c250e121a230dd4/scipy-1.17.1-cp314-cp314t-win_amd64.whl", hash = "sha256:eb092099205ef62cd1782b006658db09e2fed75bffcae7cc0d44052d8aa0f484", size = 37345327, upload-time = "2026-02-23T00:22:24.442Z" }, + { url = "https://files.pythonhosted.org/packages/07/39/338d9219c4e87f3e708f18857ecd24d22a0c3094752393319553096b98af/scipy-1.17.1-cp314-cp314t-win_arm64.whl", hash = "sha256:200e1050faffacc162be6a486a984a0497866ec54149a01270adc8a59b7c7d21", size = 25489165, upload-time = "2026-02-23T00:22:29.563Z" }, +] + +[[package]] +name = "scipy" +version = "1.18.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.15' and sys_platform == 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'win32'", + "python_full_version >= '3.15' and sys_platform == 'emscripten'", + "python_full_version == '3.14.*' and sys_platform == 'emscripten'", + "python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] +dependencies = [ + { name = "numpy", version = "2.5.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a7/25/c2700dfaf6442b4effaa91af24ebce5dc9d31bb4a69706313aae70d72cd0/scipy-1.18.0.tar.gz", hash = "sha256:67b2ad2ad54c72ca6d04975a9b2df8c3638c34ddd5b28738e94fc2b57929d378", size = 30774447, upload-time = "2026-06-19T15:01:43.456Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/19/ca10ead60b0acc80b2b833c2c4a4f2ff753d0f58b811f70d911c7e94a25c/scipy-1.18.0-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:7bd21faaf5a1a3b2eff922d02db5f191b99a6518db9078a8fb23169f6d22259a", size = 31056519, upload-time = "2026-06-19T14:59:45.203Z" }, + { url = "https://files.pythonhosted.org/packages/96/72/1e6442a00cd2924d361aa1b642ab6373ec35c6fabf311a760be9f76e0f13/scipy-1.18.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:265915e79107de9f946b855e50d7470d5893ec3f54b342e1aa6201cbdcd8bb6b", size = 28681889, upload-time = "2026-06-19T14:59:48.103Z" }, + { url = "https://files.pythonhosted.org/packages/9b/2d/11dd93d21e147a73ba22bd75c0b9208d3a2e0ec76d53170ce7d9029b1015/scipy-1.18.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:9ab7b758be6940954a713ee466e2043e9f6e2ed965c1fce5c91039f4be3d90a9", size = 20423580, upload-time = "2026-06-19T14:59:50.665Z" }, + { url = "https://files.pythonhosted.org/packages/9c/01/93552f75e0d2a7dd115a45e59209c51e8d514daff02fc887d2623be06fe1/scipy-1.18.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:97b6cddaaee0a779ef6b5ca83c9604b27cc16b2b8fc22c142652df8793319fb8", size = 23054441, upload-time = "2026-06-19T14:59:53.564Z" }, + { url = "https://files.pythonhosted.org/packages/3c/23/21f5e703643d66f21faa6b4c73195bfcad70c55efcb4f1ab327cd7c4101a/scipy-1.18.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:52a96e21517c7292375c0e27dd796a811f03fcea5fd4d108fdfea8145dcf17ab", size = 33968720, upload-time = "2026-06-19T14:59:56.415Z" }, + { url = "https://files.pythonhosted.org/packages/dd/aa/1b939f6c67ed68635bb538e6752d3dacc02f66535182e939a89581a44e9c/scipy-1.18.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1f55797419e16e7f30cf88ffb3113ce0467f00cfe3f70d5c281730b21769bfc2", size = 35287115, upload-time = "2026-06-19T14:59:59.411Z" }, + { url = "https://files.pythonhosted.org/packages/b6/ff/eec46be7e9234208f801062b53e1983085eddebd693f6c9bfb03b459830d/scipy-1.18.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ad033410e2e0672ffdc1042110cef20e1c46f8fd0616cee1d44d8d58fad8fc11", size = 35577989, upload-time = "2026-06-19T15:00:02.235Z" }, + { url = "https://files.pythonhosted.org/packages/84/ca/210d4759c7210bb7d269437421959b39a33434e2776b60c5cb8a763bb30a/scipy-1.18.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4a55985d54c769c872e64b7f4c8a81cc30ef700cc04296abbbf3705439c126de", size = 37421717, upload-time = "2026-06-19T15:00:05.102Z" }, + { url = "https://files.pythonhosted.org/packages/2b/54/9a9edb45345bd6744da5ddfb6628e5d5185920494c6a67ec45b6381004cb/scipy-1.18.0-cp312-cp312-win_amd64.whl", hash = "sha256:71ccc8faa2dd16ac310233203474a8b5cb67f10dedd54a3116d34943f4b19132", size = 36597428, upload-time = "2026-06-19T15:00:08.112Z" }, + { url = "https://files.pythonhosted.org/packages/99/0e/33f32a2a58987e26aec0f7df252cbbad1e90ae77bdbc76f40dd4ed0cf0ea/scipy-1.18.0-cp312-cp312-win_arm64.whl", hash = "sha256:d88363fd9d8fbd3511bd273f1a49efb2a540773ddf92a91d57498ce7dd7f3e76", size = 24351481, upload-time = "2026-06-19T15:00:11.103Z" }, + { url = "https://files.pythonhosted.org/packages/05/52/9c0136c2de7ae0779b7b366447766cec6d9f0702c56bb8ffeb04c8fd3af4/scipy-1.18.0-cp313-cp313-macosx_10_15_x86_64.whl", hash = "sha256:09143f676d157d9f546d663504ef9c1becb819824f1afc018814176411942446", size = 31036107, upload-time = "2026-06-19T15:00:14.03Z" }, + { url = "https://files.pythonhosted.org/packages/02/73/0291a64843270f4efb86cdcf2ee0f2048631b65ec6b405398b2b4dbf11bf/scipy-1.18.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:5efe260f69417b97ddae455bfb5a95e8359f7f66ad7fa9522a60feb66f169520", size = 28663303, upload-time = "2026-06-19T15:00:16.819Z" }, + { url = "https://files.pythonhosted.org/packages/d3/0f/10ffa0b697a572f4e0d48b92a88895d366422f019f723e7e14a84c050dac/scipy-1.18.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:68363b7eaacd8b5dd426df56d782cc156468ac79a127a1b87ca597d6e2e82197", size = 20404960, upload-time = "2026-06-19T15:00:19.635Z" }, + { url = "https://files.pythonhosted.org/packages/7e/d2/e896cea21ba8edd6c81d4c55b1ffcc717e79698dcbebf9641b4cfb4c6622/scipy-1.18.0-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:c5557d8be5da8e41353fcd4d21491fdbab83b062fc579e94dc09a7c8ab4f669b", size = 23034074, upload-time = "2026-06-19T15:00:22.107Z" }, + { url = "https://files.pythonhosted.org/packages/ea/b2/e83ea34279a52c03374477c74006256ec78df65fc877baa4617d6de1d202/scipy-1.18.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0d13bca67c096d89fb95ced0d8921807300fce0275643aef9533cc63a0773468", size = 33942038, upload-time = "2026-06-19T15:00:24.964Z" }, + { url = "https://files.pythonhosted.org/packages/f6/af/e8fe5fb136f51e2b01678b92cb4106d10d8cd68ec147ead2e7cb0ac75398/scipy-1.18.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a46f9273dbd0eb1cefba61c9b8648b4dfe3cbc14a080176f9a73e44b8336dc7f", size = 35266390, upload-time = "2026-06-19T15:00:28.059Z" }, + { url = "https://files.pythonhosted.org/packages/3a/49/2c5cbb907b56695fc67517811d1db234dfd83381a84814ec220aded2794d/scipy-1.18.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5aba46108853ddfc77906b6557aac839d2b52e900c1d72a1180adaaab58d265f", size = 35551324, upload-time = "2026-06-19T15:00:31.014Z" }, + { url = "https://files.pythonhosted.org/packages/bb/73/eda39f7a2d306ff0ffc574afd13c0bbb6d10a603d9a413998ee269487a80/scipy-1.18.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b6f758e35f12757b5d95c00bc6de2438e229c2664b7a92e96f205959d9f2dfa4", size = 37404785, upload-time = "2026-06-19T15:00:34.072Z" }, + { url = "https://files.pythonhosted.org/packages/b7/d2/ae881ee28d014f38e0ccbfd974a06a919ba9af34f1f74bf42b5301891d63/scipy-1.18.0-cp313-cp313-win_amd64.whl", hash = "sha256:1afac4a847207c7ff8efd321734a50b06d0280b3b2a2c0fc2f413101747ad7c7", size = 36554943, upload-time = "2026-06-19T15:00:36.903Z" }, + { url = "https://files.pythonhosted.org/packages/70/3a/21154e2d54eb3639c6bf4dbae2e531c68356bfe95990daa30df33b30d556/scipy-1.18.0-cp313-cp313-win_arm64.whl", hash = "sha256:c5dbddf60e58c2312316d097271a8e73d40eaf2eabfa4d95ed7d3695bbf2ce7b", size = 24350911, upload-time = "2026-06-19T15:00:40.062Z" }, + { url = "https://files.pythonhosted.org/packages/78/b5/915a19b3de2f7430062b509653563db1633ddbb6f021b06731521115d4e2/scipy-1.18.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:4c256ee70c0d1a8a2ace807e199ccd4e3f57037433842abb3fb36bc17eaa9578", size = 31036253, upload-time = "2026-06-19T15:00:43.216Z" }, + { url = "https://files.pythonhosted.org/packages/d7/88/b72def7262e150d16be13fca37a96481138d624e700340bc3362a7588929/scipy-1.18.0-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:2ef3abc54a4ffc53765374b0d5728532dfdd2585ed23f6b11c206a1f0b1b9af8", size = 28673758, upload-time = "2026-06-19T15:00:46.663Z" }, + { url = "https://files.pythonhosted.org/packages/91/02/2e636a61a525632c373cf6a9c24442a3ffb79e364d38e98b32042964ac32/scipy-1.18.0-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:f2a6af57bd9e4a75d70e4117e78a1bbee84f79ae3fbb6d0111005d6ebcc4cb8d", size = 20415514, upload-time = "2026-06-19T15:00:49.399Z" }, + { url = "https://files.pythonhosted.org/packages/c9/b6/2135974442f6aba159d9d39d774a1c8cb19947016725d69fecc685df45bf/scipy-1.18.0-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:3f1ac564d3bf6c03d861d2cd87a1bea0da2887136f7fb1bf519c05a8971452d6", size = 23034398, upload-time = "2026-06-19T15:00:51.941Z" }, + { url = "https://files.pythonhosted.org/packages/f6/e6/ba89ec5abf6ee9257c0d1ec985573f3ae32742c24bc03e016388a40b1b15/scipy-1.18.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:40395a5fcd1abee49a5c7aaa98c29db393eedc835138560a588c47ec16156690", size = 33998032, upload-time = "2026-06-19T15:00:54.838Z" }, + { url = "https://files.pythonhosted.org/packages/7f/c4/bc41eb19b0fd0db868f4132920879019318d80cc522ad8f2bca4611af808/scipy-1.18.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8ca01e8ae69f1b18e9a58d91afead31be3cef0dd905a10249dac559ee15460a0", size = 35283333, upload-time = "2026-06-19T15:00:58.152Z" }, + { url = "https://files.pythonhosted.org/packages/53/a4/cbdeef6eb3830a8462a9d4ada814de5fc984345cc9ecf17cbec51a036f1e/scipy-1.18.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7a7f3b01647384dbc3a711e8c6778e0aabbe93959249fef5c7393396bcac0867", size = 35610216, upload-time = "2026-06-19T15:01:01.155Z" }, + { url = "https://files.pythonhosted.org/packages/80/4d/b2b82502b65f661d1b789c1665dcdf315d5f12194e06fc0b37946294ebae/scipy-1.18.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6aa94e78ec192a30063a5e72e561c28af769dc311190b24fe91774eff1969709", size = 37418960, upload-time = "2026-06-19T15:01:04.155Z" }, + { url = "https://files.pythonhosted.org/packages/93/3e/902d836831474b0ab5a37d16404f7bc5fafd9efba632890e271ba952635f/scipy-1.18.0-cp314-cp314-win_amd64.whl", hash = "sha256:2d8bbdc6c817f5b4006a54d799d4f5bab6f910193cbb9a1ff310833d4d270f61", size = 37288845, upload-time = "2026-06-19T15:01:07.822Z" }, + { url = "https://files.pythonhosted.org/packages/b6/43/8d73b337a3bdb14daa0314f0434210747c02d79d729ce1777574a817dcf6/scipy-1.18.0-cp314-cp314-win_arm64.whl", hash = "sha256:18e9575f1569b2c54174e6159d32942e03731177f63dce7975f0a0c88d102f5b", size = 24988971, upload-time = "2026-06-19T15:01:11.076Z" }, + { url = "https://files.pythonhosted.org/packages/b4/b4/f11918b0508a2787031a0499a03fbe3546f3bb5ca05d01038c45b278c09a/scipy-1.18.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:f351e0dd702687d12a402b867a1b4146a256923e1c38317cbc472f6372b94707", size = 31399325, upload-time = "2026-06-19T15:01:13.723Z" }, + { url = "https://files.pythonhosted.org/packages/7b/d1/1f287b57c0ff0ee5185dff3946d92c8017d39b0e431f0ae79a3ff1859512/scipy-1.18.0-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:7c7a51b33ce387193c97f228320cf8e87361daa1bba750638677729598b3e677", size = 29092110, upload-time = "2026-06-19T15:01:16.908Z" }, + { url = "https://files.pythonhosted.org/packages/ff/1a/7b74eb6c392fdcb27d414c0e7558a6d0231eb3b6d73571f479bb81ea8794/scipy-1.18.0-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:84031d7b052a54fae2f8632e0ec802073d385476eb9a63079bce6e23ef9283d4", size = 20833811, upload-time = "2026-06-19T15:01:20.488Z" }, + { url = "https://files.pythonhosted.org/packages/7c/ad/f3941716320a7b9cb4d68734a903b45fe16eff5fb7da7e16f2e619304979/scipy-1.18.0-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:56abf29a7c067dde59be8b9a22d606a4ea1b2f2a4b756d9d903c62818f5dacce", size = 23396644, upload-time = "2026-06-19T15:01:23.364Z" }, + { url = "https://files.pythonhosted.org/packages/22/22/1446b62ffe07f9719b7d9b1b6a4e05a772833ae8f441fe4c22c34c9b250f/scipy-1.18.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ad44305cfa24b1ba5803cbbebf033590ccbac1aa5d612d727b785325ab408b0", size = 34079318, upload-time = "2026-06-19T15:01:26.002Z" }, + { url = "https://files.pythonhosted.org/packages/56/3b/b87da667098bb470fa30c7011b0ba351ee976dd395c78798c66e941665a3/scipy-1.18.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:945c1761b93f38d7f99ae81ae80c63e621471608c7eeead563f6df025585cd58", size = 35324320, upload-time = "2026-06-19T15:01:28.881Z" }, + { url = "https://files.pythonhosted.org/packages/f8/a1/c7932f91909759b0267f75fdea34e91309f96b895757534b76a90b6b4344/scipy-1.18.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:1a4441f15d620578772a49e5ab48c0ee1f7a0220e387110283062729136b2553", size = 35699541, upload-time = "2026-06-19T15:01:31.968Z" }, + { url = "https://files.pythonhosted.org/packages/f7/86/5185061a1fcc41d18c5dc2463969b3a3964b31d9ac67b2fb05d4c7ff7670/scipy-1.18.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9aac6192fac56bf2ca534389d24623f07b39ff83317d58287285e7fbd622ff76", size = 37472480, upload-time = "2026-06-19T15:01:35.136Z" }, + { url = "https://files.pythonhosted.org/packages/31/8e/f04c68e39919a010d34f2ee1367fd705b0a25a02f609d755f0bfbc0a15fc/scipy-1.18.0-cp314-cp314t-win_amd64.whl", hash = "sha256:e40baea28ae7f5475c779741e2d90b1247c78531207b49c7030e698ff81cee3f", size = 37365390, upload-time = "2026-06-19T15:01:38.091Z" }, + { url = "https://files.pythonhosted.org/packages/d5/19/969dc072906c84dd0a3b05dcf57ea750936087d7873549e408b35cfc3f97/scipy-1.18.0-cp314-cp314t-win_arm64.whl", hash = "sha256:368e0a705903c466aa5f08eefb39e6b1b6b2d659e7352a31fd9e2438365be0f8", size = 25279661, upload-time = "2026-06-19T15:01:40.817Z" }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, +] + +[[package]] +name = "sortedcontainers" +version = "2.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e8/c4/ba2f8066cceb6f23394729afe52f3bf7adec04bf9ed2c820b39e19299111/sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88", size = 30594, upload-time = "2021-05-16T22:03:42.897Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0", size = 29575, upload-time = "2021-05-16T22:03:41.177Z" }, +] + +[[package]] +name = "tomli" +version = "2.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543, upload-time = "2026-03-25T20:22:03.828Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/11/db3d5885d8528263d8adc260bb2d28ebf1270b96e98f0e0268d32b8d9900/tomli-2.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30", size = 154704, upload-time = "2026-03-25T20:21:10.473Z" }, + { url = "https://files.pythonhosted.org/packages/6d/f7/675db52c7e46064a9aa928885a9b20f4124ecb9bc2e1ce74c9106648d202/tomli-2.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a", size = 149454, upload-time = "2026-03-25T20:21:12.036Z" }, + { url = "https://files.pythonhosted.org/packages/61/71/81c50943cf953efa35bce7646caab3cf457a7d8c030b27cfb40d7235f9ee/tomli-2.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076", size = 237561, upload-time = "2026-03-25T20:21:13.098Z" }, + { url = "https://files.pythonhosted.org/packages/48/c1/f41d9cb618acccca7df82aaf682f9b49013c9397212cb9f53219e3abac37/tomli-2.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9", size = 243824, upload-time = "2026-03-25T20:21:14.569Z" }, + { url = "https://files.pythonhosted.org/packages/22/e4/5a816ecdd1f8ca51fb756ef684b90f2780afc52fc67f987e3c61d800a46d/tomli-2.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c", size = 242227, upload-time = "2026-03-25T20:21:15.712Z" }, + { url = "https://files.pythonhosted.org/packages/6b/49/2b2a0ef529aa6eec245d25f0c703e020a73955ad7edf73e7f54ddc608aa5/tomli-2.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc", size = 247859, upload-time = "2026-03-25T20:21:17.001Z" }, + { url = "https://files.pythonhosted.org/packages/83/bd/6c1a630eaca337e1e78c5903104f831bda934c426f9231429396ce3c3467/tomli-2.4.1-cp311-cp311-win32.whl", hash = "sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049", size = 97204, upload-time = "2026-03-25T20:21:18.079Z" }, + { url = "https://files.pythonhosted.org/packages/42/59/71461df1a885647e10b6bb7802d0b8e66480c61f3f43079e0dcd315b3954/tomli-2.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e", size = 108084, upload-time = "2026-03-25T20:21:18.978Z" }, + { url = "https://files.pythonhosted.org/packages/b8/83/dceca96142499c069475b790e7913b1044c1a4337e700751f48ed723f883/tomli-2.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece", size = 95285, upload-time = "2026-03-25T20:21:20.309Z" }, + { url = "https://files.pythonhosted.org/packages/c1/ba/42f134a3fe2b370f555f44b1d72feebb94debcab01676bf918d0cb70e9aa/tomli-2.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a", size = 155924, upload-time = "2026-03-25T20:21:21.626Z" }, + { url = "https://files.pythonhosted.org/packages/dc/c7/62d7a17c26487ade21c5422b646110f2162f1fcc95980ef7f63e73c68f14/tomli-2.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085", size = 150018, upload-time = "2026-03-25T20:21:23.002Z" }, + { url = "https://files.pythonhosted.org/packages/5c/05/79d13d7c15f13bdef410bdd49a6485b1c37d28968314eabee452c22a7fda/tomli-2.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9", size = 244948, upload-time = "2026-03-25T20:21:24.04Z" }, + { url = "https://files.pythonhosted.org/packages/10/90/d62ce007a1c80d0b2c93e02cab211224756240884751b94ca72df8a875ca/tomli-2.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5", size = 253341, upload-time = "2026-03-25T20:21:25.177Z" }, + { url = "https://files.pythonhosted.org/packages/1a/7e/caf6496d60152ad4ed09282c1885cca4eea150bfd007da84aea07bcc0a3e/tomli-2.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585", size = 248159, upload-time = "2026-03-25T20:21:26.364Z" }, + { url = "https://files.pythonhosted.org/packages/99/e7/c6f69c3120de34bbd882c6fba7975f3d7a746e9218e56ab46a1bc4b42552/tomli-2.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1", size = 253290, upload-time = "2026-03-25T20:21:27.46Z" }, + { url = "https://files.pythonhosted.org/packages/d6/2f/4a3c322f22c5c66c4b836ec58211641a4067364f5dcdd7b974b4c5da300c/tomli-2.4.1-cp312-cp312-win32.whl", hash = "sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917", size = 98141, upload-time = "2026-03-25T20:21:28.492Z" }, + { url = "https://files.pythonhosted.org/packages/24/22/4daacd05391b92c55759d55eaee21e1dfaea86ce5c571f10083360adf534/tomli-2.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9", size = 108847, upload-time = "2026-03-25T20:21:29.386Z" }, + { url = "https://files.pythonhosted.org/packages/68/fd/70e768887666ddd9e9f5d85129e84910f2db2796f9096aa02b721a53098d/tomli-2.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257", size = 95088, upload-time = "2026-03-25T20:21:30.677Z" }, + { url = "https://files.pythonhosted.org/packages/07/06/b823a7e818c756d9a7123ba2cda7d07bc2dd32835648d1a7b7b7a05d848d/tomli-2.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54", size = 155866, upload-time = "2026-03-25T20:21:31.65Z" }, + { url = "https://files.pythonhosted.org/packages/14/6f/12645cf7f08e1a20c7eb8c297c6f11d31c1b50f316a7e7e1e1de6e2e7b7e/tomli-2.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a", size = 149887, upload-time = "2026-03-25T20:21:33.028Z" }, + { url = "https://files.pythonhosted.org/packages/5c/e0/90637574e5e7212c09099c67ad349b04ec4d6020324539297b634a0192b0/tomli-2.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897", size = 243704, upload-time = "2026-03-25T20:21:34.51Z" }, + { url = "https://files.pythonhosted.org/packages/10/8f/d3ddb16c5a4befdf31a23307f72828686ab2096f068eaf56631e136c1fdd/tomli-2.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f", size = 251628, upload-time = "2026-03-25T20:21:36.012Z" }, + { url = "https://files.pythonhosted.org/packages/e3/f1/dbeeb9116715abee2485bf0a12d07a8f31af94d71608c171c45f64c0469d/tomli-2.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d", size = 247180, upload-time = "2026-03-25T20:21:37.136Z" }, + { url = "https://files.pythonhosted.org/packages/d3/74/16336ffd19ed4da28a70959f92f506233bd7cfc2332b20bdb01591e8b1d1/tomli-2.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5", size = 251674, upload-time = "2026-03-25T20:21:38.298Z" }, + { url = "https://files.pythonhosted.org/packages/16/f9/229fa3434c590ddf6c0aa9af64d3af4b752540686cace29e6281e3458469/tomli-2.4.1-cp313-cp313-win32.whl", hash = "sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd", size = 97976, upload-time = "2026-03-25T20:21:39.316Z" }, + { url = "https://files.pythonhosted.org/packages/6a/1e/71dfd96bcc1c775420cb8befe7a9d35f2e5b1309798f009dca17b7708c1e/tomli-2.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36", size = 108755, upload-time = "2026-03-25T20:21:40.248Z" }, + { url = "https://files.pythonhosted.org/packages/83/7a/d34f422a021d62420b78f5c538e5b102f62bea616d1d75a13f0a88acb04a/tomli-2.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd", size = 95265, upload-time = "2026-03-25T20:21:41.219Z" }, + { url = "https://files.pythonhosted.org/packages/3c/fb/9a5c8d27dbab540869f7c1f8eb0abb3244189ce780ba9cd73f3770662072/tomli-2.4.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf", size = 155726, upload-time = "2026-03-25T20:21:42.23Z" }, + { url = "https://files.pythonhosted.org/packages/62/05/d2f816630cc771ad836af54f5001f47a6f611d2d39535364f148b6a92d6b/tomli-2.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac", size = 149859, upload-time = "2026-03-25T20:21:43.386Z" }, + { url = "https://files.pythonhosted.org/packages/ce/48/66341bdb858ad9bd0ceab5a86f90eddab127cf8b046418009f2125630ecb/tomli-2.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662", size = 244713, upload-time = "2026-03-25T20:21:44.474Z" }, + { url = "https://files.pythonhosted.org/packages/df/6d/c5fad00d82b3c7a3ab6189bd4b10e60466f22cfe8a08a9394185c8a8111c/tomli-2.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853", size = 252084, upload-time = "2026-03-25T20:21:45.62Z" }, + { url = "https://files.pythonhosted.org/packages/00/71/3a69e86f3eafe8c7a59d008d245888051005bd657760e96d5fbfb0b740c2/tomli-2.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15", size = 247973, upload-time = "2026-03-25T20:21:46.937Z" }, + { url = "https://files.pythonhosted.org/packages/67/50/361e986652847fec4bd5e4a0208752fbe64689c603c7ae5ea7cb16b1c0ca/tomli-2.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba", size = 256223, upload-time = "2026-03-25T20:21:48.467Z" }, + { url = "https://files.pythonhosted.org/packages/8c/9a/b4173689a9203472e5467217e0154b00e260621caa227b6fa01feab16998/tomli-2.4.1-cp314-cp314-win32.whl", hash = "sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6", size = 98973, upload-time = "2026-03-25T20:21:49.526Z" }, + { url = "https://files.pythonhosted.org/packages/14/58/640ac93bf230cd27d002462c9af0d837779f8773bc03dee06b5835208214/tomli-2.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7", size = 109082, upload-time = "2026-03-25T20:21:50.506Z" }, + { url = "https://files.pythonhosted.org/packages/d5/2f/702d5e05b227401c1068f0d386d79a589bb12bf64c3d2c72ce0631e3bc49/tomli-2.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232", size = 96490, upload-time = "2026-03-25T20:21:51.474Z" }, + { url = "https://files.pythonhosted.org/packages/45/4b/b877b05c8ba62927d9865dd980e34a755de541eb65fffba52b4cc495d4d2/tomli-2.4.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4", size = 164263, upload-time = "2026-03-25T20:21:52.543Z" }, + { url = "https://files.pythonhosted.org/packages/24/79/6ab420d37a270b89f7195dec5448f79400d9e9c1826df982f3f8e97b24fd/tomli-2.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c", size = 160736, upload-time = "2026-03-25T20:21:53.674Z" }, + { url = "https://files.pythonhosted.org/packages/02/e0/3630057d8eb170310785723ed5adcdfb7d50cb7e6455f85ba8a3deed642b/tomli-2.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d", size = 270717, upload-time = "2026-03-25T20:21:55.129Z" }, + { url = "https://files.pythonhosted.org/packages/7a/b4/1613716072e544d1a7891f548d8f9ec6ce2faf42ca65acae01d76ea06bb0/tomli-2.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41", size = 278461, upload-time = "2026-03-25T20:21:56.228Z" }, + { url = "https://files.pythonhosted.org/packages/05/38/30f541baf6a3f6df77b3df16b01ba319221389e2da59427e221ef417ac0c/tomli-2.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c", size = 274855, upload-time = "2026-03-25T20:21:57.653Z" }, + { url = "https://files.pythonhosted.org/packages/77/a3/ec9dd4fd2c38e98de34223b995a3b34813e6bdadf86c75314c928350ed14/tomli-2.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f", size = 283144, upload-time = "2026-03-25T20:21:59.089Z" }, + { url = "https://files.pythonhosted.org/packages/ef/be/605a6261cac79fba2ec0c9827e986e00323a1945700969b8ee0b30d85453/tomli-2.4.1-cp314-cp314t-win32.whl", hash = "sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8", size = 108683, upload-time = "2026-03-25T20:22:00.214Z" }, + { url = "https://files.pythonhosted.org/packages/12/64/da524626d3b9cc40c168a13da8335fe1c51be12c0a63685cc6db7308daae/tomli-2.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26", size = 121196, upload-time = "2026-03-25T20:22:01.169Z" }, + { url = "https://files.pythonhosted.org/packages/5a/cd/e80b62269fc78fc36c9af5a6b89c835baa8af28ff5ad28c7028d60860320/tomli-2.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396", size = 100393, upload-time = "2026-03-25T20:22:02.137Z" }, + { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583, upload-time = "2026-03-25T20:22:03.012Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, +] + +[[package]] +name = "tzdata" +version = "2026.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/92/ff/5a28bdfd8c3ebec42564ac7d0e54ca3db65044a9314a97f9564fa7a1e926/tzdata-2026.3.tar.gz", hash = "sha256:4a1518b8993086a7982523e071643f3c0e5f213e75b21318e78bcabfff9d1415", size = 198674, upload-time = "2026-07-10T08:50:37.887Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/6d/b53b99a9f2766d095985947a5782f1702cabb129a34f7a802d7197af832f/tzdata-2026.3-py2.py3-none-any.whl", hash = "sha256:dc096730c87af6cab1b171c9d532be840741ff5d459015e7f6947bd7d7e54931", size = 348168, upload-time = "2026-07-10T08:50:36.46Z" }, +] + +[[package]] +name = "urllib3" +version = "2.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/53/0c/06f8b233b8fd13b9e5ee11424ef85419ba0d8ba0b3138bf360be2ff56953/urllib3-2.7.0.tar.gz", hash = "sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c", size = 433602, upload-time = "2026-05-07T16:13:18.596Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897", size = 131087, upload-time = "2026-05-07T16:13:17.151Z" }, +] + +[[package]] +name = "virtualenv" +version = "21.7.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "distlib" }, + { name = "filelock" }, + { name = "platformdirs" }, + { name = "python-discovery" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2d/dc/a6eb1ddfa7f1e390fa599b078453c97edb3f6f846b34fb4eac3e8ea16401/virtualenv-21.7.4.tar.gz", hash = "sha256:c9d960c95fa458171e58222a5ccab7465298e4b6559977865e627c4719f1e825", size = 5345511, upload-time = "2026-08-10T22:54:33.316Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/4c/eb2f52aeeaf30dbd073d315a251a63ae2b8263171ec4428c135140cb0802/virtualenv-21.7.4-py3-none-any.whl", hash = "sha256:376ec93cd6aab3044fa395d7db226db38043b7b5748948044b2a87168525e843", size = 5324444, upload-time = "2026-08-10T22:54:31.515Z" }, +] + +[[package]] +name = "watchdog" +version = "6.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", size = 131220, upload-time = "2024-11-01T14:07:13.037Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/56/90994d789c61df619bfc5ce2ecdabd5eeff564e1eb47512bd01b5e019569/watchdog-6.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d1cdb490583ebd691c012b3d6dae011000fe42edb7a82ece80965b42abd61f26", size = 96390, upload-time = "2024-11-01T14:06:24.793Z" }, + { url = "https://files.pythonhosted.org/packages/55/46/9a67ee697342ddf3c6daa97e3a587a56d6c4052f881ed926a849fcf7371c/watchdog-6.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bc64ab3bdb6a04d69d4023b29422170b74681784ffb9463ed4870cf2f3e66112", size = 88389, upload-time = "2024-11-01T14:06:27.112Z" }, + { url = "https://files.pythonhosted.org/packages/44/65/91b0985747c52064d8701e1075eb96f8c40a79df889e59a399453adfb882/watchdog-6.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c897ac1b55c5a1461e16dae288d22bb2e412ba9807df8397a635d88f671d36c3", size = 89020, upload-time = "2024-11-01T14:06:29.876Z" }, + { url = "https://files.pythonhosted.org/packages/e0/24/d9be5cd6642a6aa68352ded4b4b10fb0d7889cb7f45814fb92cecd35f101/watchdog-6.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6eb11feb5a0d452ee41f824e271ca311a09e250441c262ca2fd7ebcf2461a06c", size = 96393, upload-time = "2024-11-01T14:06:31.756Z" }, + { url = "https://files.pythonhosted.org/packages/63/7a/6013b0d8dbc56adca7fdd4f0beed381c59f6752341b12fa0886fa7afc78b/watchdog-6.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2", size = 88392, upload-time = "2024-11-01T14:06:32.99Z" }, + { url = "https://files.pythonhosted.org/packages/d1/40/b75381494851556de56281e053700e46bff5b37bf4c7267e858640af5a7f/watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c", size = 89019, upload-time = "2024-11-01T14:06:34.963Z" }, + { url = "https://files.pythonhosted.org/packages/39/ea/3930d07dafc9e286ed356a679aa02d777c06e9bfd1164fa7c19c288a5483/watchdog-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948", size = 96471, upload-time = "2024-11-01T14:06:37.745Z" }, + { url = "https://files.pythonhosted.org/packages/12/87/48361531f70b1f87928b045df868a9fd4e253d9ae087fa4cf3f7113be363/watchdog-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860", size = 88449, upload-time = "2024-11-01T14:06:39.748Z" }, + { url = "https://files.pythonhosted.org/packages/5b/7e/8f322f5e600812e6f9a31b75d242631068ca8f4ef0582dd3ae6e72daecc8/watchdog-6.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0", size = 89054, upload-time = "2024-11-01T14:06:41.009Z" }, + { url = "https://files.pythonhosted.org/packages/68/98/b0345cabdce2041a01293ba483333582891a3bd5769b08eceb0d406056ef/watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", size = 96480, upload-time = "2024-11-01T14:06:42.952Z" }, + { url = "https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", size = 88451, upload-time = "2024-11-01T14:06:45.084Z" }, + { url = "https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", size = 89057, upload-time = "2024-11-01T14:06:47.324Z" }, + { url = "https://files.pythonhosted.org/packages/30/ad/d17b5d42e28a8b91f8ed01cb949da092827afb9995d4559fd448d0472763/watchdog-6.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c7ac31a19f4545dd92fc25d200694098f42c9a8e391bc00bdd362c5736dbf881", size = 87902, upload-time = "2024-11-01T14:06:53.119Z" }, + { url = "https://files.pythonhosted.org/packages/5c/ca/c3649991d140ff6ab67bfc85ab42b165ead119c9e12211e08089d763ece5/watchdog-6.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9513f27a1a582d9808cf21a07dae516f0fab1cf2d7683a742c498b93eedabb11", size = 88380, upload-time = "2024-11-01T14:06:55.19Z" }, + { url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079, upload-time = "2024-11-01T14:06:59.472Z" }, + { url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078, upload-time = "2024-11-01T14:07:01.431Z" }, + { url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076, upload-time = "2024-11-01T14:07:02.568Z" }, + { url = "https://files.pythonhosted.org/packages/ab/cc/da8422b300e13cb187d2203f20b9253e91058aaf7db65b74142013478e66/watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f", size = 79077, upload-time = "2024-11-01T14:07:03.893Z" }, + { url = "https://files.pythonhosted.org/packages/2c/3b/b8964e04ae1a025c44ba8e4291f86e97fac443bca31de8bd98d3263d2fcf/watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26", size = 79078, upload-time = "2024-11-01T14:07:05.189Z" }, + { url = "https://files.pythonhosted.org/packages/62/ae/a696eb424bedff7407801c257d4b1afda455fe40821a2be430e173660e81/watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c", size = 79077, upload-time = "2024-11-01T14:07:06.376Z" }, + { url = "https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2", size = 79078, upload-time = "2024-11-01T14:07:07.547Z" }, + { url = "https://files.pythonhosted.org/packages/07/f6/d0e5b343768e8bcb4cda79f0f2f55051bf26177ecd5651f84c07567461cf/watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a", size = 79065, upload-time = "2024-11-01T14:07:09.525Z" }, + { url = "https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680", size = 79070, upload-time = "2024-11-01T14:07:10.686Z" }, + { url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067, upload-time = "2024-11-01T14:07:11.845Z" }, +] + +[[package]] +name = "xarray" +version = "2025.6.1" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.11'", +] +dependencies = [ + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "packaging", marker = "python_full_version < '3.11'" }, + { name = "pandas", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/ec/e50d833518f10b0c24feb184b209bb6856f25b919ba8c1f89678b930b1cd/xarray-2025.6.1.tar.gz", hash = "sha256:a84f3f07544634a130d7dc615ae44175419f4c77957a7255161ed99c69c7c8b0", size = 3003185, upload-time = "2025-06-12T03:04:09.099Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/8a/6b50c1dd2260d407c1a499d47cf829f59f07007e0dcebafdabb24d1d26a5/xarray-2025.6.1-py3-none-any.whl", hash = "sha256:8b988b47f67a383bdc3b04c5db475cd165e580134c1f1943d52aee4a9c97651b", size = 1314739, upload-time = "2025-06-12T03:04:06.708Z" }, +] + +[[package]] +name = "xarray" +version = "2026.7.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.15' and sys_platform == 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'win32'", + "python_full_version >= '3.15' and sys_platform == 'emscripten'", + "python_full_version == '3.14.*' and sys_platform == 'emscripten'", + "python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'emscripten'", + "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] +dependencies = [ + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "numpy", version = "2.5.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "packaging", marker = "python_full_version >= '3.11'" }, + { name = "pandas", version = "3.0.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ea/96/3f7bdd00e505ec3698903415b30135024703e017b28c6b61f98da3193b0d/xarray-2026.7.0.tar.gz", hash = "sha256:361b495928fdbf5b58d0969bb6775339019da5e93ca74d61ddf4eb5edd6ce604", size = 3145348, upload-time = "2026-07-09T17:38:26.515Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/57/5b/28365212062939d213802e5e5fe855cdb231e1c2a93254ba1690066504e3/xarray-2026.7.0-py3-none-any.whl", hash = "sha256:bf9dd130b93806dc78e90c1b7ac24851b31557b888674c53622235691cf21824", size = 1426778, upload-time = "2026-07-09T17:38:24.224Z" }, +] + +[[package]] +name = "zipp" +version = "4.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b9/d8/eab98a517c14134c0b2eb4e2387bc5f457334293ec5d2dd3857ec2966802/zipp-4.1.0.tar.gz", hash = "sha256:4cb57381f544315db7688e976e922a2b18cdb513d21cc194eb42232ba2a3e602", size = 26214, upload-time = "2026-05-18T20:08:57.967Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/13/547360d81e6d88d58492968ffda9f9542854f11310ee556fef14260cc886/zipp-4.1.0-py3-none-any.whl", hash = "sha256:25ad4e16390cd314347dd8f1de67a2ac538ae658ed4ab9db16029c07c188e97f", size = 10238, upload-time = "2026-05-18T20:08:57.045Z" }, +]