Fix and improve relative binning in HeterodynedTransientLikelihoodFD#116
Fix and improve relative binning in HeterodynedTransientLikelihoodFD#116thomasckng wants to merge 2 commits into
Conversation
Addresses #108 (check and improve relative binning) by correcting three bugs and aligning the implementation with Bilby's reference (arXiv:1806.08792). Changes ------- 1. Correct gamma set in _max_phase_diff Old code used gamma = arange(-5, 6)/3 (11 terms, including zero) with a f_star-based normalisation. Replaced with Bilby's 5 PN/IMR terms: gamma in {-5/3, -2/3, 1, 5/3, 7/3}, each normalised by d_alpha so that its contribution spans exactly chi*2pi rad across [f_low, f_high]. Dtype now follows gamma.dtype instead of float32 for x64 compatibility. 2. Correct r0/r1 estimators in _likelihood Old code used a (center, left) off-centre finite difference. Replaced with Bilby's edge-average: r0 = (r_low + r_high)/2, r1 = (r_high - r_low)/bin_width. Adds waveform_high_ref and bin_widths as stored instance attributes; removes waveform_center_ref. 3. Adaptive epsilon-based binning New epsilon parameter (max phase change per bin in rad) controls bin count via max(1, int(total_phase/epsilon)). epsilon=0.5 is the default when neither epsilon nor n_bins is given, matching Bilby's convention and giving ~60 bins for a typical CBC signal. n_bins and epsilon are mutually exclusive; passing both raises ValueError. Non-positive values also raise ValueError. 4. Fix NaN at waveform boundary Mask condition changed from freq_grid_center <= f_waveform_max to freq_grid_high <= f_waveform_max so that bins whose upper edge exceeds the waveform's valid range are excluded. Previously the reference waveform was zero at freq_grid_high, producing 0/0 = NaN. 5. Rename helper methods to private max_phase_diff, make_binning_scheme, compute_coefficients renamed to _max_phase_diff, _make_binning_scheme, _compute_coefficients. _make_binning_scheme no longer accepts epsilon; resolution to n_bins is done in __init__. 6. CLI and docs CLIHeterodynedConfig gains an epsilon field (both n_bins and epsilon default to None). build_likelihood passes epsilon and logs the actual likelihood.n_bins. docs/guides/cli.md updated to show the new epsilon-based TOML configuration. All docstrings updated.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
|
Warning Review limit reached
More reviews will be available in 45 minutes and 48 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe pull request refactors heterodyned relative binning from a fixed 1000-bin default to support configurable phase-based (epsilon) or fixed-count (n_bins) binning. CLI configuration and likelihood builder integrate the new epsilon parameter; core likelihood implementation rewrites binning scheme computation, reference waveform storage from centre to separate low/high edges, and likelihood evaluation accordingly. Tests validate the new scheme. ChangesHeterodyned Likelihood Binning Refactor
🎯 4 (Complex) | ⏱️ ~45 minutes Suggested labels
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
tests/cross_validation/test_likelihood.py (1)
679-699:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winPin bilby
epsilonexplicitly and fix the stale comment.
tests/cross_validation/test_likelihood.pysets Jim withepsilon=0.5in both cross-validation segments, but both bilbyRelativeBinningGravitationalWaveTransient(...)initialisations omitepsilon(relying on bilby’s default).- With this repo’s pinned
bilby==2.8.0, the defaultepsilonis already0.5(so today the two sides match), but passingepsilon=0.5prevents future drift if bilby’s default changes.- The nearby comments still describe “reading back the number of bins” / an
n_binsmatching flow, which the current code doesn’t appear to use.Proposed patch
- # Initialize bilby first with its default epsilon so we can read back - # the number of bins it chose, then initialize Jim with the same count - # for an apples-to-apples comparison. + # Use explicit epsilon on both sides to avoid default-driven drift + # across bilby versions. bilby_likelihood = ( bilby.gw.likelihood.RelativeBinningGravitationalWaveTransient( interferometers=setup["bilby_ifos"], waveform_generator=build_bilby_waveform_generator( setup["duration"], setup["sampling_frequency"] ), fiducial_parameters=bilby_ref_params, + epsilon=0.5, ) ) @@ - # Initialize bilby first with its default epsilon so we can read back - # the number of bins it chose, then initialize Jim with the same count - # for an apples-to-apples comparison. + # Use explicit epsilon on both sides to avoid default-driven drift + # across bilby versions. bilby_likelihood = ( bilby.gw.likelihood.RelativeBinningGravitationalWaveTransient( interferometers=setup["bilby_ifos"], waveform_generator=build_bilby_waveform_generator( setup["duration"], setup["sampling_frequency"] ), fiducial_parameters=bilby_ref_params, phase_marginalization=True, priors=priors, + epsilon=0.5, ) )🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/cross_validation/test_likelihood.py` around lines 679 - 699, The test currently relies on bilby's default epsilon and has a stale comment about reading back number of bins; explicitly pass epsilon=0.5 to the bilby RelativeBinningGravitationalWaveTransient construction (the same value used when creating HeterodynedTransientLikelihoodFD) to avoid future drift, and update the surrounding comment near bilby_likelihood / RelativeBinningGravitationalWaveTransient to remove or replace the "reading back the number of bins / n_bins matching" wording so it accurately reflects that epsilon is being pinned for parity.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/jimgw/core/single_event/likelihood.py`:
- Around line 567-568: Normalize all jaxtyping shape strings in forward
annotations in src/jimgw/core/single_event/likelihood.py: remove
leading/trailing spaces inside the quoted dimension names, replace empty-string
dims with meaningful identifiers, and convert any arithmetic or expression-like
strings into single valid identifiers (e.g. change " n_bin" → "n_bin", "" →
"n_bin" or "n_freq" as appropriate, "n_bins + 1" → "n_bins_plus_1", "n_bands+1
2" → "n_bands_plus_1"). Apply these fixes to the annotated variables and
signatures such as waveform_low_ref and waveform_high_ref and the other forward
annotations flagged (around the original comment locations) so that every
Float[Array, "..."] uses a parsable identifier-only dimension name.
---
Outside diff comments:
In `@tests/cross_validation/test_likelihood.py`:
- Around line 679-699: The test currently relies on bilby's default epsilon and
has a stale comment about reading back number of bins; explicitly pass
epsilon=0.5 to the bilby RelativeBinningGravitationalWaveTransient construction
(the same value used when creating HeterodynedTransientLikelihoodFD) to avoid
future drift, and update the surrounding comment near bilby_likelihood /
RelativeBinningGravitationalWaveTransient to remove or replace the "reading back
the number of bins / n_bins matching" wording so it accurately reflects that
epsilon is being pinned for parity.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 04f5ad8f-9fa8-46f0-922e-8202300a1be1
📒 Files selected for processing (6)
docs/guides/cli.mdsrc/jimgw/cli/_config.pysrc/jimgw/cli/_likelihood.pysrc/jimgw/core/single_event/likelihood.pytests/cross_validation/test_likelihood.pytests/unit/core/single_event/test_likelihood.py
…consistent bin count comparison
Closes #108.
Summary
This PR corrects three bugs in
HeterodynedTransientLikelihoodFDand aligns the implementation with Bilby's relative-binning reference (arXiv:1806.08792).Changes
1. Correct gamma set in
_max_phase_diffThe old implementation used
gamma = arange(-5, 6) / 3(11 terms, including zero) with af_star-based normalisation that is not equivalent to Bilby's. Replaced with Bilby's 5 physically-motivated PN/IMR terms:Each term is normalised by
d_alphaso that its contribution spans exactlychi * 2πrad across[f_low, f_high]. The array is offset so it starts at zero (cumulative phase fromf_low).2. Correct r0/r1 estimators in
_likelihoodThe old code estimated the ratio polynomial using a center–left off-centre finite difference:
Replaced with Bilby's bin-edge average:
This requires evaluating the reference and proposal waveforms at both bin edges.
waveform_high_ref(evaluated atfreq_grid_high) replaceswaveform_center_ref, andbin_widthsis stored as an instance attribute.3. Adaptive epsilon-based binning
Added an
epsilonparameter — the maximum allowed phase change per bin in radians — as the primary way to control bin count, matching Bilby's interface:epsilon=0.5(the new default when neither argument is given) yields ~60 bins for a typical CBC signal withf=[20, 512]Hz.n_binsis still accepted but is now mutually exclusive withepsilon; passing both raisesValueError.ValueError.CLIHeterodynedConfig) gains a correspondingepsilonfield; both default toNone.4. Fix NaN at waveform boundary
The masking condition used
freq_grid_center <= f_waveform_max, which could include bins whose upper edge (freq_grid_high) extended beyond the waveform's valid range. At those frequencies the reference waveform is zero, causingr_high = 0 / 0 = NaN. Fixed by usingfreq_grid_high <= f_waveform_maxas the upper-bound condition.5. Rename helper methods to private
max_phase_diff,make_binning_scheme, andcompute_coefficientsare internal helpers not intended as public API. Renamed to_max_phase_diff,_make_binning_scheme, and_compute_coefficients._make_binning_schemeno longer acceptsepsilon; the resolution from epsilon to integern_binsis done in__init__before calling it.6. CLI and docs
CLIHeterodynedConfiggainsepsilon: Optional[float] = Nonealongsiden_bins: Optional[int] = None.build_likelihoodpassesepsilonto the constructor and now logslikelihood.n_bins(the actual post-construction bin count) rather than the config value.docs/guides/cli.mdupdated to reflect the new epsilon-based TOML configuration.Tests
waveform_center_ref→waveform_high_ref;freq_grid_highattribute assertion added. All 13 tests pass.epsilon=0.5directly instead of matchingbilby_likelihood.number_of_bins.Summary by CodeRabbit
Release Notes
New Features
Changes
Documentation