Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
179 commits
Select commit Hold shift + click to select a range
86c0be5
lalsimutils.frame_data_to_hoft: fix ET (E1/E2/E3) frame selection
oshaughnessy-junior Jul 10, 2026
4c5af5f
jax_ile: differentiable JAX ILE for slow-rotation (Path A/B) + finite…
oshaughnessy-junior Jul 11, 2026
01214fe
jax_ile: high-SNR NUTS demo for finite-size extrinsic sky posterior
oshaughnessy-junior Jul 11, 2026
08178c6
jax_ile samplers: dense mass matrix (+ max_tree_depth) for multistart…
oshaughnessy-junior Jul 12, 2026
10918a7
jax_ile: report posterior ESS (sampling quality) vs evidence neff in …
oshaughnessy-junior Jul 12, 2026
ceed0a8
jax_ile: phase-rotation reparam (mirror --internal-rotate-phase) for …
oshaughnessy-junior Jul 12, 2026
fc19cf0
jax_ile demo: per-dim ESS breakdown for high-SNR NUTS
oshaughnessy-junior Jul 12, 2026
ee7a232
jax_ile samplers: gradient MAP-polish of NUTS seeds (fixes SNR=1000 r…
oshaughnessy-junior Jul 13, 2026
bb50b5d
jax_ile demo: covariance-ellipse sky area to show compact high-SNR lo…
oshaughnessy-junior Jul 13, 2026
2b2bb7c
jax_ile: 3G paper figure-data generator (sky-area-vs-SNR + recovery s…
oshaughnessy-junior Jul 13, 2026
7513fc6
jax_ile samplers: evidence-weighted pooling (post_weight) for multist…
oshaughnessy-junior Jul 14, 2026
3360ce1
jax_ile: high-SNR fidelity fixes (cubic interp, exact-deltaT tvals, t…
oshaughnessy-junior Jul 15, 2026
daf5821
Merge pull request #23 from oshaughnessy-junior/jax_slowrot
oshaughnessy-junior Jul 16, 2026
21a6af4
benchmark: add quantitative integrator benchmark harness
oshaughnessy-junior Jul 18, 2026
c142e1c
AV: bootstrappable warm-start (samples / Fisher / mixture / saved state)
oshaughnessy-junior Jul 18, 2026
86d76b7
portfolio oracles: FisherGaussian oracle + fix stubs + fix portfolio …
oshaughnessy-junior Jul 18, 2026
c0fceeb
NF: fix GPU crash + save_intg, add flow storage/reuse framework
oshaughnessy-junior Jul 18, 2026
0d9d715
ILE: wire AV bootstrap + NF flow reuse into production driver
oshaughnessy-junior Jul 19, 2026
882499d
AV: feed the integrand its native backend (fix real GPU-ILE regression)
oshaughnessy-junior Jul 19, 2026
9096500
portfolio, NF: feed integrand device-first (round out the GPU-ILE fix)
oshaughnessy-junior Jul 19, 2026
9fd07f7
AV: coverage floor (cover_frac) for safe cross-problem warm-start reuse
oshaughnessy-junior Jul 19, 2026
ed765ef
ILE: L0 auto-rescue + L1 sequential warm-start (safe warm-start threa…
oshaughnessy-junior Jul 19, 2026
a9a028c
integrators: ProposalField scaffold for L3 iteration-to-iteration reuse
oshaughnessy-junior Jul 19, 2026
344946a
L3: iteration-to-iteration proposal-field warm-start + handoff safety…
oshaughnessy-junior Jul 19, 2026
aa39472
L3: cherry-picked-pilot workflow (disk- and fit-safe), not whole-grid…
oshaughnessy-junior Jul 19, 2026
8763c0e
portfolio: balance-heuristic (q_mix) estimator makes portfolio SAFE u…
oshaughnessy-junior Jul 19, 2026
7d531be
AV: clip bootstrap bin indices to [0,nbins-1] (fix V>1 on wide seeds)
oshaughnessy-junior Jul 19, 2026
8cb8a4d
AV: set warm-start grid resolution from the core, not the coverage floor
oshaughnessy-junior Jul 19, 2026
6895603
AV: vectorize sample_from_bins (unblocks concentrated warm starts)
oshaughnessy-junior Jul 19, 2026
f5296be
integrators: drop accidentally-committed __pycache__/*.pyc, add .giti…
oshaughnessy-junior Jul 20, 2026
7a79f3c
portfolio: make it warm-startable (forward seed to AV members); gener…
oshaughnessy-junior Jul 21, 2026
8c29876
GMM: add bootstrap_from_samples (warm-start proposal from a seed cloud)
oshaughnessy-junior Jul 21, 2026
2b76b09
AV: opt-in ANISOTROPIC per-axis bin allocation (--sampler-anisotropic…
oshaughnessy-junior Jul 21, 2026
992486c
ILE: --internal-reparam-dl-incl (effective-distance reparam of distan…
oshaughnessy-junior Jul 21, 2026
d44fe48
portfolio: set up MEMBER REALIZATIONS (fix cold AV/GMM member draw cr…
oshaughnessy-junior Jul 21, 2026
edf775c
AV: fix empty-selection crash in update_sampling_prior_selfish (cold …
oshaughnessy-junior Jul 21, 2026
f2d51de
portfolio: freeze protection (grace + revive) + NaN-weight guard
oshaughnessy-junior Jul 21, 2026
9e420f8
GMM: O(k^3) Hungarian component matching (was O(k!) permutations)
oshaughnessy-junior Jul 21, 2026
6d05855
GMM: flexible (data-driven) component allocation + warm-start survival
oshaughnessy-junior Jul 21, 2026
3c336cd
GMM flexible allocation: default defensive component OFF + design doc
oshaughnessy-junior Jul 21, 2026
402df1e
test: add data-free synthetic benchmark for flexible GMM allocation
oshaughnessy-junior Jul 21, 2026
49351a6
GMM adaptive: safety floor at hard-coded count + portfolio wiring
oshaughnessy-junior Jul 21, 2026
f0411d0
doc: portfolio status after d44fe486 (draw_simplified fixed; AV selfi…
oshaughnessy-junior Jul 21, 2026
c6f542c
doc: AV+GMM portfolio benchmark on S250114ax (measured; confounded by…
oshaughnessy-junior Jul 21, 2026
ccfb087
doc: AV+GMM portfolio isolation measured (adaptive GMM member ~6x har…
oshaughnessy-junior Jul 21, 2026
492cf8e
portfolio: VARAHA never-freeze default + freeze-policy CLI + containe…
oshaughnessy-junior Jul 21, 2026
bb1bb1d
portfolio: adaptive-probe draw allocation (track the winning member)
oshaughnessy-junior Jul 22, 2026
31e2664
portfolio: make adaptive allocation OPT-IN (it regresses AV-favorable…
oshaughnessy-junior Jul 22, 2026
55e9523
portfolio: global-impact quality signal (marginal pooled n_eff) for a…
oshaughnessy-junior Jul 22, 2026
8ae375d
AV warm-start: raise cross-problem cover_frac default 0.1 -> 0.5 (mea…
oshaughn Jul 22, 2026
e42753d
portfolio: opt-in weight clipping (truncated IS) with TRACKED clipped…
oshaughnessy-junior Jul 22, 2026
98c644d
test: expensive pre-merge posterior SHAPE-recovery gate for MC integr…
oshaughnessy-junior Jul 22, 2026
6467ac9
shape gate: STARVED verdict (non-blocking absolute, differential-only…
oshaughnessy-junior Jul 22, 2026
13c2bc5
Merge pull request #26 from oshaughnessy-junior/rift_O4d_adaptive_int…
oshaughnessy-junior Jul 22, 2026
1d73383
ILE: honour --srate-resample-time-marginalization instead of always d…
oshaughn Jul 22, 2026
281715f
Fix Virgo calibration correction convention
oshaughn Jul 15, 2026
71171a5
Merge pull request #30 from oshaughnessy-junior/rift_O4d_junior_srate…
oshaughnessy-junior Jul 22, 2026
f5fcd8d
Merge pull request #29 from oshaughnessy-junior/rift_O4d_junior_virgo…
oshaughnessy-junior Jul 22, 2026
6930905
Merge remote-tracking branch 'junior/rift_O4d' into rift_O4d_shape_re…
oshaughnessy-junior Jul 22, 2026
a199c41
breadcrumbs: integrator changes must pass the shape-recovery merge gate
oshaughnessy-junior Jul 22, 2026
6950de8
Merge pull request #31 from oshaughnessy-junior/rift_O4d_shape_recove…
oshaughnessy-junior Jul 22, 2026
a711103
integrators: probe for a CUDA device before selecting cupy; fail loud…
oshaughnessy-junior Jul 22, 2026
68ba1cb
Merge pull request #32 from oshaughnessy-junior/rift_O4d_gmm_cpu_devi…
oshaughnessy-junior Jul 22, 2026
95d741a
portfolio: weight clipping applies to the ADAPTATION stream only (unb…
oshaughnessy-junior Jul 23, 2026
e10414f
GMM/portfolio: never train-silently-never — default n_comp=1, warn on…
oshaughnessy-junior Jul 23, 2026
841bcfe
Merge pull request #27 from oshaughnessy-junior/rift_O4d_gmm_flexible…
oshaughnessy-junior Jul 23, 2026
e9ee348
portfolio: narrow weight clipping to the PROPOSAL-FIT input only (fix…
oshaughnessy-junior Jul 23, 2026
0b7a2de
portfolio: record proposal-fit clip typical-event safety validation
oshaughnessy-junior Jul 23, 2026
7c6589f
Merge remote-tracking branch 'junior/rift_O4d' into rift_O4d_portfoli…
oshaughnessy-junior Jul 23, 2026
4c331e5
AV: draw_simplified must subsample randomly, not head-slice a bin-ord…
oshaughnessy-junior Jul 23, 2026
e7e8bcc
Merge remote-tracking branch 'junior/rift_O4d' into rift_O4d_portfoli…
oshaughnessy-junior Jul 23, 2026
6f79600
portfolio doc: mark the S250114ax weight-outlier diagnosis SUPERSEDED…
oshaughnessy-junior Jul 23, 2026
8ca6368
portfolio: tolerate unavailable optional plugins at import; make regr…
oshaughnessy-junior Jul 23, 2026
4bac744
Merge pull request #33 from oshaughnessy-junior/rift_O4d_portfolio_gm…
oshaughnessy-junior Jul 23, 2026
2a3a197
Merge remote-tracking branch 'junior/rift_O4d' into rift_O4d_portfoli…
oshaughnessy-junior Jul 23, 2026
56cff23
portfolio: VARAHA draw floor (opt-in) + post-#33 re-measurement; opt-…
oshaughnessy-junior Jul 23, 2026
113f2b1
portfolio: q_mix-native MIS credit-assignment quality signal ('credit')
oshaughnessy-junior Jul 23, 2026
efb30e4
portfolio: proposal-fit clipping BEATS AV at the production n_eff tar…
oshaughnessy-junior Jul 23, 2026
223f999
portfolio: default the plateau-aware revive OFF (it halved portfolio …
oshaughnessy-junior Jul 23, 2026
2254dd8
portfolio: record shape-gate PASS + harden the opt-in probe's environ…
oshaughnessy-junior Jul 23, 2026
2732564
portfolio: record flag-ON opt-in probe results (0 regressions; both f…
oshaughnessy-junior Jul 23, 2026
9c40120
Merge pull request #28 from oshaughnessy-junior/rift_O4d_portfolio_fr…
oshaughnessy-junior Jul 23, 2026
b638c3e
bench_multi_event: add already-inside-container mode (NO_SINGULARITY=…
oshaughnessy-junior Jul 23, 2026
6e3a066
doc: multi-event post-#33 clip validation — the S250114ax clip win do…
oshaughnessy-junior Jul 24, 2026
8249317
bench_coverfrac: pin the reference point; measure warm-start coverage…
oshaughnessy-junior Jul 24, 2026
434fd7f
onsource: portfolio rescues the high-SNR BEST-FIT point where AV and …
oshaughnessy-junior Jul 25, 2026
fd88f5d
onsource: adaptive GMM coverage nearly quadruples the high-SNR rescue…
oshaughnessy-junior Jul 25, 2026
f195fbb
onsource: GMM coverage is non-monotonic — sweet spot at cap16/inflate…
oshaughnessy-junior Jul 25, 2026
57ef26f
add shape_extrinsic.py: weighted-sample SHAPE check on ILE --save-sam…
oshaughnessy-junior Jul 25, 2026
7bb66a0
doc: high-SNR rescue is FLAKY (seed ensemble) + --save-samples unusab…
oshaughnessy-junior Jul 25, 2026
367dcac
portfolio: fix --save-samples 0-row export (cumsum linear weights + -…
oshaughnessy-junior Jul 25, 2026
f283d6b
onsource: n_eff is a LOTTERY for every cap (10-draw) -> pooling manda…
oshaughnessy-junior Jul 25, 2026
3a532ca
onsource: low n_eff == extrinsic MODE COLLAPSE; landed copies agree; …
oshaughnessy-junior Jul 25, 2026
fc7000e
onsource: coords help landers not collapse-rate; collapse=AV peak-loc…
oshaughnessy-junior Jul 26, 2026
76e1ea4
fix L0 auto-rescue gate for portfolio: detect via opts.sampler_portfo…
oshaughnessy-junior Jul 26, 2026
7c475a2
onsource: L0 auto-rescue is the high-SNR fix -- landed fraction 4/9 -…
oshaughnessy-junior Jul 26, 2026
24d07be
driver: stop clobbering opts.sampler_method during portfolio setup
oshaughnessy-junior Jul 26, 2026
2c3f998
doc: evidence audit -- flag which conclusions are single draws (cap24…
oshaughnessy-junior Jul 26, 2026
56fa1c8
bench_onsource: enable cubic Q_lm time interpolation (--interpolate-t…
oshaughnessy-junior Jul 26, 2026
ebb0fd9
fix PRE-EXISTING cold-start crash in mcsamplerEnsemble; L0 rescue now…
oshaughnessy-junior Jul 26, 2026
c893f07
cold ensemble: n_eff does NOT certify correctness -- highest-n_eff co…
oshaughnessy-junior Jul 26, 2026
9caecf2
auto-collect: AV-backstop / mode-budget sweep raw results + gate outcome
oshaughnessy-junior Jul 26, 2026
f56cfd9
portfolio: BAND the VARAHA draw share (--portfolio-varaha-max-frac), …
oshaughnessy-junior Jul 26, 2026
89fb763
shape-gate probe: cover the VARAHA draw-share constraints and the GMM…
oshaughnessy-junior Jul 26, 2026
18823b4
band sweep: share constraint and mode budget only work TOGETHER (n=4,…
oshaughnessy-junior Jul 26, 2026
403d1c2
n=9 like-for-like: constraint helps ~40% but p~0.08 (not significant)…
oshaughnessy-junior Jul 28, 2026
9b3ef61
flag-ON probe PASSED (0 opt-in regressions); status summary across al…
oshaughnessy-junior Jul 28, 2026
bdc844e
ILE: recover the requested export rate EXACTLY, not an integer multiple
oshaughn Jul 28, 2026
eb964b5
RETRACT at n=20: share constraint does not reduce lnZ scatter (p=0.66…
oshaughnessy-junior Jul 28, 2026
1e601b9
add chunk-size stability study (synthetic SNR ladder, truth-known, CP…
oshaughnessy-junior Jul 28, 2026
6a278a5
Merge pull request #34 from oshaughnessy-junior/rift_O4d_portfolio_fr…
oshaughnessy-junior Jul 29, 2026
cbb67cc
Merge pull request #36 from oshaughnessy-junior/rift_O4d_junior_srate…
oshaughnessy-junior Jul 29, 2026
a782afa
integrators: stabilize the MC error estimate (tail diagnostic, replic…
oshaughnessy-junior Jul 29, 2026
493db7c
Merge pull request #38 from oshaughnessy-junior/rift_O4d_mc_error_v2
oshaughnessy-junior Jul 29, 2026
ce4e494
WIP (UNVERIFIED): per-member draw floor + multi-AV backstop invariants
oshaughnessy-junior Jul 29, 2026
e18908a
Merge remote-tracking branch 'junior/rift_O4d' into rift_O4d_portfoli…
oshaughnessy-junior Jul 29, 2026
83010de
add k-hat validation: does the Pareto tail diagnostic catch the confi…
oshaughnessy-junior Jul 29, 2026
062f67d
restricted-range AV ladder (n=20/case/SNR): fail-safe confirmed, and …
oshaughnessy-junior Jul 29, 2026
ac39de3
k-hat does NOT catch confidently-wrong runs from support mismatch (an…
oshaughnessy-junior Jul 30, 2026
be7f5fc
helper: SNR-scaled extrinsic chunk size (40k default, linear above SN…
oshaughnessy-junior Jul 30, 2026
1891057
portfolio: per-member range plumbing for INTERVAL NARROWING (restrict…
oshaughnessy-junior Jul 31, 2026
81299d1
helper: expose cubic Q_lm time interpolation (--internal-ile-interpol…
oshaughnessy-junior Jul 31, 2026
47f23ea
mcsamplerGPU: fix adaptive-proposal support truncation biasing lnZ low
oshaughnessy-junior Jul 29, 2026
f5c8a83
Merge pull request #39 from oshaughnessy-junior/codex/mcsampler-gpu-a…
oshaughnessy-junior Aug 1, 2026
3582841
docs: catalog RIFT demo workflows
Jul 4, 2026
00d066f
docs: add distance-grid workflow guide
oshaughn Jul 30, 2026
9778b71
docs: clarify Issue 34 distance-grid outputs
oshaughn Jul 30, 2026
c936247
docs: make distance-grid output discovery location-safe
oshaughn Jul 30, 2026
3c93f27
docs: state distance-grid DAG preconditions
oshaughn Jul 30, 2026
4b580bf
Add container survey warmup tooling
oshaughnessy-junior Jul 4, 2026
7675bde
docs: drop stale execution-plan artifact
oshaughnessy-junior Aug 1, 2026
9858262
test: cover container survey tooling
oshaughnessy-junior Aug 1, 2026
6737fa1
style: normalize survey tooling files
oshaughnessy-junior Aug 1, 2026
fef3e41
Merge pull request #40 from oshaughnessy-junior/codex/o4d-docs-distan…
oshaughnessy-junior Aug 1, 2026
420f079
Merge pull request #41 from oshaughnessy-junior/codex/o4d-container-s…
oshaughnessy-junior Aug 1, 2026
8bd0ff5
docs: add survey_scan executable reference
oshaughn Aug 2, 2026
ede76b1
docs: clarify survey scan job and result scope
oshaughn Aug 2, 2026
675782c
docs: fix survey scan reference title adornment
oshaughn Aug 2, 2026
6a3c547
Merge pull request #42 from oshaughnessy-junior/docs/issue33-survey-s…
oshaughnessy-junior Aug 2, 2026
0cc00b4
chunk memory: HOST memory flat across 16x chunk range -> no RequestMe…
oshaughnessy-junior Aug 4, 2026
6813fa6
results hygiene: keep summaries + structured JSON, drop raw sampler l…
oshaughnessy-junior Aug 5, 2026
d50e1f8
results: gzip the per-run JSON records, drop the remaining raw log
oshaughnessy-junior Aug 5, 2026
07b5b20
fix two warm-start defects raised on PR #161; route pseudo_pipe optio…
oshaughnessy-junior Aug 5, 2026
7d07646
RETRACT the L0 'doubles landed fraction' claim: most of it was the br…
oshaughnessy-junior Aug 5, 2026
238f2a9
portfolio: close three silent-failure holes found in PR #45 review
oshaughnessy-junior Aug 5, 2026
17f89ef
gate: add warm-start / sequential-reuse cases; reset portfolio state …
oshaughnessy-junior Aug 5, 2026
9e054c7
portfolio: replay member setup args on reset; reject widening restric…
oshaughnessy-junior Aug 6, 2026
3bbf261
portfolio: snapshot member setup args -- gmm_dict aliasing leaked the…
oshaughnessy-junior Aug 6, 2026
a5ea8d8
gate: run the sequential cases in production shape (gmm_dict) and ass…
oshaughnessy-junior Aug 6, 2026
69e77fe
portfolio: clone seeded GMM models; make the gate's clearing check no…
oshaughnessy-junior Aug 6, 2026
87d66b7
Merge pull request #45 from oshaughnessy-junior/rift_O4d_portfolio_fr…
oshaughnessy-junior Aug 6, 2026
7e3f803
warm start: keep the full-support backstop cold; make MC-error replic…
oshaughnessy-junior Aug 6, 2026
e459ec0
warm start: hold a member cold only when EVERY member has compact sup…
oshaughnessy-junior Aug 6, 2026
8b2c4af
portfolio: off-path warm-start support-mismatch diagnostic (escaped_m…
oshaughnessy-junior Aug 6, 2026
26dfcf9
portfolio: declare full-support explicitly; reset portfolio-level ada…
oshaughnessy-junior Aug 6, 2026
9a68748
gate: require confirm-on-fail before a blocking regression counts
oshaughnessy-junior Aug 6, 2026
34d3e77
GMM: install the defensive component on every fit path; verify it bef…
oshaughnessy-junior Aug 6, 2026
999e85a
GMM: make the defensive component opt-in, and let only the portfolio …
oshaughnessy-junior Aug 6, 2026
0b2e56c
Merge pull request #48 from oshaughnessy-junior/rift_O4d_escaped_mass…
oshaughnessy-junior Aug 7, 2026
0ea0729
gate: confirmation now shares the comparator's classifier, counts fai…
oshaughnessy-junior Aug 7, 2026
cbb91b9
gate: point the runner docs at the wired enforcement flags
oshaughnessy-junior Aug 7, 2026
089ed55
gate: a missing candidate record is a blocking regression
oshaughnessy-junior Aug 7, 2026
0134abf
GMM: keep the coverage guarantee through the sampler lifecycle, not j…
oshaughnessy-junior Aug 7, 2026
4c08a21
Merge rift_O4d (escaped-mass diagnostic, #48) into the PR #47 branch
oshaughnessy-junior Aug 7, 2026
ceb29ac
Merge pull request #49: gate: confirm blocking regressions at fresh s…
oshaughnessy-junior Aug 7, 2026
d4bf582
Merge pull request #47: warm-start coverage honesty, cold MC-error re…
oshaughnessy-junior Aug 7, 2026
1c712bf
test/waveforms: add U,V mode-cross-term symmetry checks
oshaughnessy-junior Aug 7, 2026
04f9401
Pool MC-error replicas for export; warn on L0 truncated support; make…
oshaughnessy-junior Aug 7, 2026
3b99efd
test/waveforms: address PR #50 review
oshaughnessy-junior Aug 7, 2026
d88a1d1
L0 rescue: reject the warm pass only on evidence; pool by reported Z_…
oshaughnessy-junior Aug 7, 2026
dd32da6
Merge pull request #50 from oshaughnessy-junior/waveform-symmetry-che…
oshaughnessy-junior Aug 7, 2026
08b8440
test/waveforms: parity (orbital-plane reflection) diagnostics
oshaughn Aug 7, 2026
d008bf5
Pooling: equal within-block weights for fairdraw replicas; restore th…
oshaughnessy-junior Aug 7, 2026
7376601
test/waveforms: fold in IMRPhenomXPHM/XPNR; document X-family caveats
oshaughn Aug 7, 2026
02e668e
lalsimutils: fix spurious (l,±m) asymmetry in hlmoft FD-mode conditio…
oshaughn Aug 7, 2026
84e5174
LISA/lalsimutils_compat: zero surviving -fNyq bin after FD-mode resize
oshaughn Aug 7, 2026
fe98880
Pooling: rebuild cached log_weights so the science exports use the co…
oshaughnessy-junior Aug 7, 2026
d4c1f76
Merge pull request #51 from oshaughnessy-junior/rift_O4d_pr161_export…
oshaughnessy-junior Aug 7, 2026
92a9950
Merge pull request #53 from oshaughnessy-junior/lisa-compat-fnyq-conj…
oshaughnessy-junior Aug 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ python MonteCarloMarginalizeCode/Code/test/test_likelihood.py
## Testing
Tests use pytest but have no standard runner. Run individual test files directly.

### Merge gate for integrator changes (IMPORTANT)
Any change under `MonteCarloMarginalizeCode/Code/RIFT/integrators/` must pass the
**posterior shape-recovery gate** in
`MonteCarloMarginalizeCode/Code/test/expensive_before_merging/integrators/`
before merging into a production line (run base + candidate with identical seeds,
then `compare_shape_results.py base.json pr.json`; exit 1 = merge-blocking).
The fast CI integral test is NOT sufficient — integrators have shipped confident,
integral-invisible shape failures and silent n_eff~1 degradations that only this
gate catches. See `RIFT/integrators/TESTING.md` for the recipe and caveats.

## Important CLI tools
- `integrate_likelihood_extrinsic_batchmode` - Main PE engine
- `create_event_parameter_pipeline_BasicIteration` - Full pipeline
Expand Down
17 changes: 13 additions & 4 deletions MonteCarloMarginalizeCode/Code/RIFT/LISA/lalsimutils_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,19 @@ def hlmoff_for_LISA(
)
hlmsdict = lalsimutils.SphHarmFrequencySeries_to_dict(hlms_struct, Lmax)
hlmsdict = _filter_modes(hlmsdict, modes)
return {
mode: lal.ResizeCOMPLEX16FrequencySeries(hlm, 0, TDlen)
for mode, hlm in hlmsdict.items()
}
# SimInspiralChooseFDModes returns an ascending two-sided grid
# [-fNyq, ..., 0, ..., +fNyq] of odd length TDlen+1. The resize below
# truncates the +fNyq bin but keeps its -fNyq partner (index 0); zero it
# so the truncation commutes with the conjugate-pair (f -> -f) reflection
# h_{l,-m}(f) = (-1)^l conj(h_{lm}(-f)) for models with support at Nyquist.
out = {}
for mode, hlm in hlmsdict.items():
truncated = hlm.data.length > TDlen
hlm = lal.ResizeCOMPLEX16FrequencySeries(hlm, 0, TDlen)
if truncated:
hlm.data.data[0] = 0
out[mode] = hlm
return out

if P.approx in {lalsimutils.lalNRHybSur3dq8, lalsimutils.lalIMRPhenomD}:
hlms_struct = lalsimutils.hlmoff(P, Lmax=Lmax)
Expand Down
26 changes: 26 additions & 0 deletions MonteCarloMarginalizeCode/Code/RIFT/calmarg/calibration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""Helpers for matching bilby-pipe calibration conventions."""


def correction_type_for_ifo(setting, ifo_name, parse_dict=None):
"""Resolve bilby-pipe's calibration correction type for one detector."""
if setting is None or setting == "None":
return "template" if ifo_name == "V1" else "data"

if isinstance(setting, str):
if setting in ("data", "template"):
return setting
if parse_dict is None:
raise ValueError("parse_dict is required for detector-specific settings")
setting = parse_dict(setting)

try:
correction_type = setting[ifo_name]
except (KeyError, TypeError) as exc:
raise ValueError(
f"No calibration correction type specified for {ifo_name}"
) from exc
if correction_type not in ("data", "template"):
raise ValueError(
f"Invalid calibration correction type for {ifo_name}: {correction_type}"
)
return correction_type
237 changes: 237 additions & 0 deletions MonteCarloMarginalizeCode/Code/RIFT/integrators/DESIGN_flexible_gmm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
# Flexible (data-driven) GMM component allocation for the extrinsic integrator

Status: prototype, benchmarked on S250114ax (SNR~82, real H1L1). See the
measured results and the honest tradeoffs at the bottom -- the headline is that
**this fixed the GMM's hard-coding and two warm-start bugs, but pure GMM
importance sampling is still not the right tool for this particular event**; the
flexible GMM belongs in the portfolio (with AV) or on milder problems.

## The problem being fixed

`bin/integrate_likelihood_extrinsic_batchmode` built the GMM (`mcsamplerEnsemble`)
proposal with a **hard-coded** per-group component layout:

```
gmm_dict = {(ra,dec):None, (distance,inclination):None, (psi,phi_orb):wide-frozen}
comp_dict = {(ra,dec):4, (distance,inclination):2, (psi,phi_orb):4}
```

That pairing (large sky ring = 4 components; a single distance-inclination lobe = 2;
a wide frozen phase-polarization component) targets **quadrupole-dominated,
poorly-localized** binaries. It does not adapt to the actual posterior, and a
product of per-group GMMs cannot represent cross-group correlations. `--internal-
gmm-correlate-all` switches to a single full-dim group but still with a **fixed**
component count. Choosing that count by hand is exactly the "horrible hacky
hard-coding" this work removes.

## What the extrinsic posterior actually looks like (S250114ax)

Not a 10^-11 needle -- a **broad, correlated/degenerate 6-D blob** (see
`BREADCRUMB_av_neff_reproduction.md`). Sky is tight; **distance and inclination
are broad and coupled** (the classic distance-inclination degeneracy -- a curved
arc); phase and polarization are similarly degenerate. The prior is huge (all-
sky/all-distance/all-inclination), so the peak is a tiny *fraction* of the prior
even though it is not narrow in absolute terms.

## Design

Three orthogonal knobs, prototyped in order of leverage:

### 1. Scalable component matching (enabling; committed separately)
`gmm._match_components` enumerated all **k! permutations** to align old->new
mixture components in `update()`. Fine for k<=6, impossible for k>=10 (12!~5e8,
16!~2e13). The objective is additive over matched pairs, so it is a linear
assignment problem: `scipy.optimize.linear_sum_assignment` gives the **same
optimum in O(k^3)**. Verified identical to the permutation optimum for k=2..6;
k=16 now matches in ~6 ms. Without this, "wrap the arc with many small Gaussians"
is not even runnable.

### 2. Warm-start survival (bug fix; high leverage)
`bootstrap_from_samples` fits proposal models and stores them on
`self.integrator`, but `MCSampler.integrate()` **rebuilt a fresh integrator** from
the passed `gmm_dict` (values `None`) and never looked at `self.integrator` -- so
the warm fit was **silently discarded** and a "warm" run started cold (measured:
first chunk n_eff=1.0 despite a `[GMM warm-start] fitted ...` log line).
`integrate()` now transfers any fitted model whose dim-group key matches into the
new integrator (key mismatch -> cold, never biases).

### 3. Data-driven component count (the flexible allocation)
`fit_gmm_adaptive(samples, bounds, log_weights, k_max, ...)`:
* fit k over a ladder `[1,2,3,4,6,8,...] <= k_max`,
* score each by a **weighted BIC** `-2*wLL + p*ln(N_eff)` (p = free params of
a k-component d-dim mixture, N_eff = Kish effective sample size of the fit
weights),
* keep the best k, then **prune** components whose weight < floor.

BIC allocates more components only where the importance-weighted cloud is
genuinely non-Gaussian, and stays at k=1 for a single blob; the ln(N_eff) penalty
makes it self-limiting, so it avoids the instability of a fixed over-allocated k.

**Init-only, then stable merge.** A group with `gmm_adaptive[group]=k_max` picks
its k by BIC at *initialization*, then hands off to the existing, proven-stable
merge adaptation (`model.update()`). A per-chunk BIC refit-fresh was tried and
**rejected**: it makes the proposal wander (n_eff peaks then collapses) because
each fit sees a different elite cloud; the incremental merge smooths that out.

**Defensive tail coverage (optional, `add_defensive_component`).** A broad box-
covering component with weight `defensive_frac` bounds the importance weights so a
tight fit to the elite cloud cannot blow up n_eff on the broad/degenerate
directions (the AV sampler gets the same guarantee from its cover-fraction floor).
Kept as an option; see the caveat below.

### Safety: opt-in, and a floor at the stress-tested layout
The flexible allocation is a **refinement layer, never a replacement**:
* It is **opt-in** (`--internal-gmm-adaptive-components`, default OFF). With
the flag off the driver builds the exact hard-coded `gmm_dict`/`comp_dict`/
`gmm_adapt` as before -- byte-identical behavior for the primary ILE use case.
* When on, BIC chooses k in **[k_min, k_max]** with `k_min` = the group's
stress-tested hard-coded count, and pruning never drops below `k_min`. So
adaptive can only ADD components where the data earns them; it can never
allocate fewer than the validated layout. This protects broad multi-modal
posteriors (e.g. a multi-modal sky keeps its default components even if the
*initial* elite cloud -- fit before the proposal has explored every mode --
looks single-peaked; the spare capacity lets the merge adaptation grow into
the other modes as they appear).

### Portfolio
`--internal-gmm-adaptive-components` also works with `--sampler-method portfolio`.
Invoke the members with the flag REPEATED (it is `append`, not comma-split):
`--sampler-portfolio AV --sampler-portfolio GMM` (NOT `"AV,GMM"`, which becomes
one bogus member). When `GMM` is a member the driver sets `sampler_method='GMM'`,
so the full GMM config section runs for the member: it gets the stress-tested
pairing `{sky:4, dist-incl:2, phase:frozen}` AND, with the flag on, the per-group
adaptive allocation on the ADAPTING groups only -- e.g. `gmm_adaptive={(4,5):8,
(3,2):8}` (sky, dist-incl), floored at 4/2, phase excluded. The GMM member honors
this in `update_sampling_prior` (the path the portfolio drives). Default OFF ->
the portfolio's stress-tested GMM member config is unchanged. This is the intended
way to use the flexible GMM: AV carries convergence, the GMM member contributes a
hands-free correlated proposal instead of a hand-tuned component layout.

**Status (2026-07-21).** After the AV/portfolio fixes on the base branch
(`d44fe486` member setup, `edf775c7` AV empty-selection, `f2d51de0` freeze grace +
revive + NaN-weight guard) the AV+GMM portfolio runs to completion on S250114ax and
the default-vs-adaptive comparison is measurable. Warm, GPU, 4 M cap,
`--sampler-portfolio AV --sampler-portfolio GMM`:

| warm portfolio, GMM member | peak n_eff (grace=25, default) | peak n_eff (freeze-exempt) |
|------------------------------|-------------------------------:|---------------------------:|
| default (hard-coded pairing) | 3.01 | 1.66 |
| **adaptive (BIC, cap 8)** | **18.2** | 4.16 |

**The flexible allocation clearly helps the portfolio: the adaptive GMM member
gives ~6x the peak n_eff of the hard-coded member (18.2 vs 3.01)** at the default
grace(25). This is the headline portfolio result -- a hands-free GMM member that
outperforms the hand-tuned layout inside the mix.

**AV is still not contributing, and freeze-exemption does NOT fix it (a separate
balance-heuristic issue, PR #26 territory).** AV's mixture weight stays pinned at
~0.0099 (= 1/101, a weight floor) for the ENTIRE run whether it is frozen or not --
so the earlier "freeze-out" was a symptom, not the cause: the balance heuristic
simply never assigns AV meaningful weight when a warm GMM member is present, so the
portfolio always rides the GMM member. Making AV freeze-exempt (grace spanning the
whole run) is actually *worse* (adaptive 4.16 vs 18.2): AV then keeps drawing its
~1% share unproductively (with `nan`s) and dilutes the estimate, instead of being
frozen out of the way. So the open question for the AV/portfolio side is why the
balance heuristic floors AV's weight at 1/101 here -- not the freezing per se. The
GMM-member allocation result above stands regardless.

### Driver flags
```
--internal-gmm-adaptive-components # enable BIC allocation (opt-in; OFF by default)
--internal-gmm-max-components N (def 8) # per-group cap (floor = the hard-coded count)
--internal-gmm-defensive-frac F (def 0) # opt-in defensive tail component
--internal-gmm-inflate X (def 1) # covariance (std) inflation
```

## Measured results

### Synthetic (data-free, moderate SNR -- where importance sampling is viable)
6-D target: a curved **banana ridge** in 2 dims (distance-inclination analogue),
a strongly-correlated Gaussian pair (phase-pol analogue), a tight blob (sky).
`test/integrators/synth`-style harness, n_eff vs N (cumulative samples):

| proposal | n_eff>=100 at N | final n_eff | lnI |
|------------------------------|-----------------|-------------|--------|
| correlate-all, fixed k=1 | 76 k | ~50 | 3.06 |
| correlate-all, fixed k=2 | **28 k** | **312** | 3.05 |
| correlate-all, fixed k=4 | 752 k | ~96 | 3.06 |
| **flexible (BIC, k<=8)** | 220 k | 135 | 3.03 |

Flexible is **robust and unbiased**: it beats k=1, avoids the k=4 over-allocation
collapse, and lands the same integral -- without any hand-tuning. It does not beat
the *oracle-best* fixed k=2, which is the expected price of a hands-free allocator.
Note fixed k=4 being far worse than k=2 is exactly the "a wrong hard-coded count
hurts" failure the flexible allocation exists to avoid.

### S250114ax (real, SNR~82) -- n_eff vs N, `--n-max 4e6 --n-eff 100`
Same worker, byte-identical data, only the proposal/config varies:

| sampler / config | warm | peak n_eff (<=4 M) |
|----------------------------------------------------|------|--------------------|
| **AV (VARAHA), warm (reference)** | yes | **~89 (->100 @~3.4 M)** |
| hard-coded pairing, cold | no | 1.29 |
| correlate-all k=2, warm (warm-start now survives) | yes | 5.7 |
| correlate-all k=8 / k=16, warm + --adapt-adapt | yes | ~1.0 |
| **flexible (BIC k<=8), warm + --adapt-adapt** | yes | 1.03 |
| flexible (BIC k<=8), cold + --adapt-adapt | no | 1.00 |
| (independent) prior pure-GMM logs gmm*/cold* | -- | 1.3 - 3.2 |

**Pure GMM importance sampling stalls at n_eff ~ 1-7 on this event, regardless of
component allocation (fixed k=2..16, BIC-adaptive), warm start, defensive coverage
(0.05), or covariance inflation (2x-5x).** This is corroborated by five pre-
existing pure-GMM logs in the pipeline (peak 1.3-3.2). The runs that reached ~100
in that directory are **AV / portfolio** runs, not pure GMM.

## Why GMM stalls here (and AV does not)

At SNR~82 the likelihood spans exp(~1210). The honest per-chunk effective sample
size `ESS(lnL + ln p - ln q)` is **exactly 1** every chunk: within any chunk of
proposal draws, the single sample nearest the sharp peak carries ~100+ nats more
log-weight than the rest, so it dominates. For n_eff to exceed 1, the proposal
would have to match `exp(lnL)*prior` to within O(1) *across* the peak -- i.e. be
almost the posterior already. A moving Gaussian-mixture importance proposal does
not get there from a broad start:
* the beta-tempered refit drives the exponent to ~0.005 (nearly flat) to keep
its own ESS up, so it barely uses the likelihood and never concentrates;
* the rank-elite (cross-entropy) refit fits the top-k by lnL, but those elites
are spread along the curved degeneracy ridge, so the fit is a broad Gaussian
over the ridge -- more components do not help because the ESS-1 domination is
set by the *narrow* constrained directions, not the ridge.
AV (VARAHA) is not importance sampling: it contracts an axis-aligned live volume
against a likelihood threshold with a coverage floor, which is the right structure
for a sharply-peaked target (at the cost of not wrapping the diagonal arc, hence
its own ~3e-5 efficiency ceiling).

## Recommendation / tradeoffs

* **Keep** the three fixes -- they are correct and independently valuable:
O(k^3) matching, warm-start survival, and BIC allocation remove the hard-coding
and make a warm GMM actually warm. The synthetic shows the allocation is robust
and unbiased.
* **Do not** expect pure GMM to beat AV on high-SNR, strongly-degenerate events.
Use the flexible GMM **inside the portfolio** (`--sampler-method portfolio`),
where the balance-heuristic mixture density keeps a weak member from biasing --
with a **hands-free** GMM member instead of a hand-tuned component layout. This
is now wired and MEASURED (see Portfolio Status): the adaptive GMM member gives
~6x the portfolio peak n_eff of the hard-coded member on S250114ax. The one
remaining item is on the AV/portfolio side (PR #26): the balance heuristic floors
the AV member's weight at ~1/101 on this event, so AV never contributes (and
freeze-exemption does not fix it) -- once AV pulls its weight, the portfolio
should combine AV's convergence with the flexible GMM's correlated proposal.
* **Future levers** for making GMM itself competitive here would be *coordinate*
changes that de-curve the arc (a distance-inclination reparametrization,
rotate-phase for phase<->pol) so a low-k axis-aligned mixture fits -- i.e.
attack the correlation in coordinates, then let BIC pick k. See the breadcrumb's
"real levers" section.

## Code map
* `RIFT/integrators/gaussian_mixture_model.py`: `_match_components` (Hungarian),
`fit_gmm_adaptive`, `gmm.prune_components`, `gmm.num_free_params`,
`add_defensive_component`, `_mixture_log_density_normalized`.
* `RIFT/integrators/MonteCarloEnsemble.py`: `integrator.gmm_adaptive/
gmm_defensive_frac/gmm_inflate`; BIC-at-init in `_train`.
* `RIFT/integrators/mcsamplerEnsemble.py`: warm-start transfer in `integrate()`;
`gmm_adaptive` threading in `integrate()`/`setup()`.
* `bin/integrate_likelihood_extrinsic_batchmode`: the four flags + `gmm_adaptive`
dict construction in the GMM section.
* `test/integrators/test_gmm_adaptive.py`: unit tests (5/5).
Loading
Loading