Conversation
… marginalization Implements Thrane & Talbot (2019) Eq. 79: phase is marginalized first analytically via Bessel function, then distance is marginalized numerically. Inherits all distance grid setup from DistanceMarginalizedLikelihoodFD. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
📝 WalkthroughWalkthroughA new frequency-domain likelihood class Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Tip Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs). 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: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/jimgw/core/single_event/likelihood.py`:
- Line 537: The method _likelihood currently has an unused parameter named data
which triggers Ruff ARG002; rename the parameter to _data in the _likelihood
method signature and update any internal references (if any) to use _data so the
linter recognizes the parameter as intentionally unused — adjust the definition
of def _likelihood(self, params: dict[str, Float], data: dict) -> Float to use
_data instead and run tests/lint to confirm the warning is resolved.
- Around line 529-535: The evaluate method currently applies
self.fixed_parameters then unconditionally sets params["phase_c"] = 0.0 which
silently ignores any user-supplied phase_c; modify evaluate (method evaluate,
symbol fixed_parameters, and call to _likelihood) to detect if "phase_c" is
present in self.fixed_parameters and raise a clear ValueError (fail fast)
explaining that phase_c cannot be fixed when phase is marginalised, before
overwriting params["phase_c"]; keep the remaining assignments (d_L,
trigger_time, gmst) and then call self._likelihood(params, data).
| def evaluate(self, params: dict[str, Float], data: dict) -> Float: | ||
| params.update(self.fixed_parameters) | ||
| params["d_L"] = self.ref_dist | ||
| params["phase_c"] = 0.0 | ||
| params["trigger_time"] = self.trigger_time | ||
| params["gmst"] = self.gmst | ||
| return self._likelihood(params, data) |
There was a problem hiding this comment.
Reject fixed phase_c when phase is marginalised.
Line 530 applies fixed_parameters, but Line 532 always overrides phase_c = 0.0. If phase_c is supplied in fixed parameters, it is silently ignored. Please fail fast to avoid hidden misconfiguration.
🔧 Proposed fix
def evaluate(self, params: dict[str, Float], data: dict) -> Float:
+ if "phase_c" in self.fixed_parameters:
+ raise ValueError("Cannot have phase_c fixed while marginalising over phase_c")
params.update(self.fixed_parameters)
params["d_L"] = self.ref_dist
params["phase_c"] = 0.0
params["trigger_time"] = self.trigger_time
params["gmst"] = self.gmst
return self._likelihood(params, data)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| def evaluate(self, params: dict[str, Float], data: dict) -> Float: | |
| params.update(self.fixed_parameters) | |
| params["d_L"] = self.ref_dist | |
| params["phase_c"] = 0.0 | |
| params["trigger_time"] = self.trigger_time | |
| params["gmst"] = self.gmst | |
| return self._likelihood(params, data) | |
| def evaluate(self, params: dict[str, Float], data: dict) -> Float: | |
| if "phase_c" in self.fixed_parameters: | |
| raise ValueError("Cannot have phase_c fixed while marginalising over phase_c") | |
| params.update(self.fixed_parameters) | |
| params["d_L"] = self.ref_dist | |
| params["phase_c"] = 0.0 | |
| params["trigger_time"] = self.trigger_time | |
| params["gmst"] = self.gmst | |
| return self._likelihood(params, data) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/jimgw/core/single_event/likelihood.py` around lines 529 - 535, The
evaluate method currently applies self.fixed_parameters then unconditionally
sets params["phase_c"] = 0.0 which silently ignores any user-supplied phase_c;
modify evaluate (method evaluate, symbol fixed_parameters, and call to
_likelihood) to detect if "phase_c" is present in self.fixed_parameters and
raise a clear ValueError (fail fast) explaining that phase_c cannot be fixed
when phase is marginalised, before overwriting params["phase_c"]; keep the
remaining assignments (d_L, trigger_time, gmst) and then call
self._likelihood(params, data).
| params["gmst"] = self.gmst | ||
| return self._likelihood(params, data) | ||
|
|
||
| def _likelihood(self, params: dict[str, Float], data: dict) -> Float: |
There was a problem hiding this comment.
Address Ruff ARG002 for unused _likelihood argument.
data is unused in this override; rename it to _data to make intent explicit and clear the warning.
🧹 Proposed fix
- def _likelihood(self, params: dict[str, Float], data: dict) -> Float:
+ def _likelihood(self, params: dict[str, Float], _data: dict) -> Float:📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| def _likelihood(self, params: dict[str, Float], data: dict) -> Float: | |
| def _likelihood(self, params: dict[str, Float], _data: dict) -> Float: |
🧰 Tools
🪛 Ruff (0.15.2)
[warning] 537-537: Unused method argument: data
(ARG002)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/jimgw/core/single_event/likelihood.py` at line 537, The method
_likelihood currently has an unused parameter named data which triggers Ruff
ARG002; rename the parameter to _data in the _likelihood method signature and
update any internal references (if any) to use _data so the linter recognizes
the parameter as intentionally unused — adjust the definition of def
_likelihood(self, params: dict[str, Float], data: dict) -> Float to use _data
instead and run tests/lint to confirm the warning is resolved.
Summary
PhaseDistanceMarginalizedLikelihoodFDclass implementing combined phase + distance marginalization following Thrane & Talbot (2019), Section C.5 (Eq. 79)I_0, then distance is marginalized numerically over a pre-computed grid vialogsumexpDistanceMarginalizedLikelihoodFD(merged in PR Add distance-marginalized likelihood #84)phase_cnord_Lare sampling parameters — reduces dimensionality by 2Implementation
The integrand at each distance grid point i is:
where
kappa²_C_refis the complex matched-filter inner product at the reference distance (computed viacomplex_inner_product),s_i = D_0/D_iis the scaling factor, andlog_w_iare the normalized log prior weights.Verification
Tested against bilby's
GravitationalWaveTransientwithphase_marginalization=True, distance_marginalization=Trueusing shared 4s injection data (IMRPhenomD, M_c=35, q=0.9, 3-detector H1/L1/V1):The 0.0026 difference is due to bilby's 2D lookup table with bicubic spline interpolation vs Jim's direct quadrature (same as distance-only marginalization in PR #84).
Test plan
🤖 Generated with Claude Code
Summary by CodeRabbit