Skip to content

lalsimutils: phi12, chi_p_vec, vectorized in-plane spin coordinates (O4d port of #203) - #377

Merged
oshaughnessy-junior merged 5 commits into
rift_O4dfrom
claude/ring-coordinate-cip-o4d
Oct 1, 2026
Merged

oshaughnessy-junior merged 5 commits into
rift_O4dfrom
claude/ring-coordinate-cip-o4d

Conversation

@oshaughnessy-junior

@oshaughnessy-junior oshaughnessy-junior commented Sep 30, 2026 •

Copy link
Copy Markdown
Owner

rift_O4d port of oshaughn#203.

extract_param gains phi12 (listed in valid_params, never implemented) and chi_p_vec, the vector sum of the in-plane terms in chi_p. The spherical-spin branch of convert_waveform_coordinates builds chi1_perp, chi2_perp, phi12, SOverM2_perp, DeltaOverM2_perp and chi_p_vec vectorized, in the L frame only.

Review fixes, also applied to #203: the block accepts CIP's object arrays (the default sampler crashed), keeps the enforce_kerr rule, and returns phi12 = 0 at zero in-plane spin. chi_p_vec is not in valid_params, since grid readers assign every listed column.

No defaults change. The CIP width results (RIFT_roboto_paper analyses/transverse_convergence/RESULTS_ring_coordinate_2026-09-30.md) were measured on rc3, not O4d.

Tests (ldas-grid, IGWN python 3.11, numpy):

  • test_ring_coordinates.py: 7 passed
  • test-core-units.sh: PASS, 608 collected, 595 passed, 0 failed; floors 605/592
  • roster and vector-coordinate tests pass; existing coordinate sets bit-identical to base
  • CIP with the default sampler and the new coordinates: exit 0

🤖 Generated with Claude Code

…nates

rift_O4d port of oshaughn#203.  extract_param gains
phi12 (listed in valid_params but not implemented) and chi_p_vec, the
vector-sum analogue of chi_p (same A1, A2 weights).  The spherical branch
of convert_waveform_coordinates builds chi1_perp, chi2_perp, phi12,
SOverM2_perp, DeltaOverM2_perp and chi_p_vec vectorized, when
spin_convention is "L"; otherwise they fall through to extract_param as
before.  test_ring_coordinates.py joins the core-units gate; its floors
are re-measured at 600/587.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@oshaughnessy-junior
oshaughnessy-junior deployed to private-review-dispatch-rift September 30, 2026 21:02 — with GitHub Actions Active
for p in ring_names:
if p in coord_names_reduced:
x_out[:,coord_names.index(p)] = ring_vals[p]
coord_names_reduced.remove(p)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Preserve enforce_kerr when moving ring coordinates out of the fallback

At head 0f933e7a7a2a1f772eb4feba21e03303d29a80e1, removing these outputs from coord_names_reduced lets the existing early return bypass the only enforce_kerr check, which runs in the per-row fallback. This changes the behavior of existing SOverM2_perp/DeltaOverM2_perp outputs and can admit super-Kerr rows through CIP's --downselect-enforce-kerr coordinate transformation. Reproduced with L convention, low_level_coord_names=['mc','delta_mc','chi1','cos_theta1','phi1','chi2','cos_theta2','phi2'], x_in=np.array([[20.,.3,1.2,.2,1.,.5,.4,2.]]), coord_names=['SOverM2_perp'], and enforce_kerr=True: parent f0d90b21 returns [[-inf]], whereas PR head returns [[0.52919969]]. Adding chi_p to the requested head outputs returns [[-inf,-inf]] because it forces fallback, so row validity now depends on the output feature list. Apply the Kerr rejection mask before the vectorized early return (or retain fallback when enforcement is requested), and cover both super-Kerr and valid rows in a regression test.

@oshaughnessy-junior

Copy link
Copy Markdown
Owner Author

[P2] Use one phi12 convention at zero transverse spin in both conversion paths

Adversarial review of head 0f933e7a7a2a1f772eb4feba21e03303d29a80e1: the new vector path at lalsimutils.py:6161 subtracts the input azimuths even when a transverse spin is zero, whereas extract_param('phi12') at line 1396 derives its azimuth from the Cartesian spin. These give different finite fitting coordinates for the same physical configuration.

Concrete reproduction (NumPy backend):

LOW = ['mc','delta_mc','chi1','cos_theta1','phi1','chi2','cos_theta2','phi2']
x = np.array([[20., .3, 0., .2, 1., .5, .4, 2.]])
convert_waveform_coordinates(x, coord_names=['phi12'], low_level_coord_names=LOW)
# [[1.]]
# Build the equivalent Cartesian ChooseWaveformParams:
# spin 1 = (0,0,0), spin 2 azimuth = 2 radians
P.extract_param('phi12')
# 2.0

The same mismatch occurs with nonzero chi1 and cos_theta1=+1 or -1. All other ring coordinates agree for these cases. phi12 is physically undefined at a vanishing transverse spin, so a canonical policy must be selected; this is not an argument for a particular angle. The issue is that CIP assembles training fit coordinates using P.extract_param (util_ConstructIntrinsicPosterior_GenericCoordinates.py:2391) and obtains sampling fit coordinates through the vector converter. Exact aligned/zero-spin likelihood grid points can therefore be encoded differently from the sampling path, even with identical physical spins.

Please apply a common canonical policy in both paths and add zero-spin/aligned-pole cases to the agreement test. The two submitted tests pass, as do 1,000 additional random nondegenerate draws and individual-coordinate subsets; their continuous random draws never exercise these boundaries.

oshaughnessy-junior added a commit that referenced this pull request Sep 30, 2026
…arams

From review of the O4d port (#377), which applies here too:
- The vectorized in-plane block can end convert_waveform_coordinates before the
  per-row fallthrough, whose enforce_kerr rule then never ran. The block now
  applies the same rule (row set to -inf if chi1 or chi2 > 1). Sets that do not
  use the in-plane names are bit-identical to the base, with and without
  enforce_kerr.
- chi_p_vec is removed from valid_params: grid readers call assign_param on
  every listed column, and chi_p_vec is derived only. CIP does not need it there.
- phi12 cannot return exactly 2 pi.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rr, phi12)

From adversarial review of this PR and of the O4c version (#203 upstream):
- CIP's default sampler passes an object array of python floats; the ring
  block's ufuncs raised TypeError, so CIP exited 1 with these fit coordinates.
  The block now casts to float.
- The ring block can end convert_waveform_coordinates before the per-row
  fallthrough, whose enforce_kerr rule then never ran. The block applies it.
- phi12 is 0 in both paths when an in-plane spin vanishes (they disagreed),
  cannot return exactly 2 pi, and joins periodic_params.
- chi_p_vec leaves valid_params: grid readers assign_param every listed column.
- Tests: phi12 at pi/3 in both paths, object arrays, zero in-plane spin, Kerr,
  valid_params. Core-units floors re-measured: 605/592.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@oshaughnessy-junior
oshaughnessy-junior marked this pull request as ready for review September 30, 2026 22:59
@oshaughnessy-junior
oshaughnessy-junior deployed to private-review-dispatch-rift September 30, 2026 22:59 — with GitHub Actions Active
…ing-coordinate port

Conflict only in .travis/test-core-units.sh: both sides added a test file and
raised the floors.  Kept both files; floors re-measured on the merged tree
(ldas-grid, numpy backend): junit 616 collected / 603 passed / 13 skipped /
0 failed, 3 subtests, so 613/600.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@oshaughnessy-junior
oshaughnessy-junior deployed to private-review-dispatch-rift October 1, 2026 00:24 — with GitHub Actions Active

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent automated review completed at the recorded exact commit. Detailed findings were withheld from public output by the private-context egress policy and require private human declassification.

@oshaughnessy-junior
oshaughnessy-junior deployed to private-review-dispatch-rift October 1, 2026 00:33 — with GitHub Actions Active

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent automated review completed at the recorded exact commit. Detailed findings were withheld from public output by the private-context egress policy and require private human declassification.

54eadb1 lowered the floors to 607/594 on the premise that the merge
counted #375's tests twice.  CI on that very commit counted 616 collected
/ 603 passed / 13 skipped (3 subtests), i.e. 613/600, so 607/594 sat six
below the tree.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@oshaughnessy-junior
oshaughnessy-junior deployed to private-review-dispatch-rift October 1, 2026 20:56 — with GitHub Actions Active

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent automated review completed at the recorded exact commit. Detailed findings were withheld from public output by the private-context egress policy and require private human declassification.

@oshaughnessy-junior
oshaughnessy-junior merged commit c49dcb4 into rift_O4d Oct 1, 2026
35 checks passed
@oshaughnessy-junior
oshaughnessy-junior deployed to private-review-dispatch-rift October 1, 2026 23:28 — with GitHub Actions Active

This branch was successfully deployed

1 active deployment
private-review-dispatch-rift — aae57ce2 Deployed Oct 1, 2026 by oshaughnessy-junior via Dispatch exact RIFT PR generation #1462
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant