Skip to content

Commit 1ed73af

Browse files
authored
BUG: fix ROQ likelihood incompatibility with numpy 2.4 (#1106)
* BUG: fix roq_params shape when using HDF5 format * TST: add tests for roq_params * ENH: improve roq_params validation * TST: add test for missing roq param fields
1 parent 1153adc commit 1ed73af

2 files changed

Lines changed: 57 additions & 7 deletions

File tree

bilby/gw/likelihood/roq.py

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,31 @@ class ROQGravitationalWaveTransient(GravitationalWaveTransient):
8484
- e.g., "H1": sample in the time of arrival at H1
8585
8686
"""
87+
@property
88+
def roq_params(self):
89+
return self._roq_params
90+
91+
@roq_params.setter
92+
def roq_params(self, roq_params):
93+
if roq_params is not None:
94+
if not isinstance(roq_params, np.ndarray) or roq_params.dtype.names is None:
95+
raise TypeError(
96+
"roq_params must be None or a scalar structured numpy array"
97+
)
98+
if roq_params.ndim != 0:
99+
raise ValueError(
100+
"roq_params must be a scalar structured array; "
101+
f"received shape {roq_params.shape}"
102+
)
103+
required_fields = {"flow", "fhigh", "seglen"}
104+
missing_fields = required_fields.difference(roq_params.dtype.names)
105+
if missing_fields:
106+
raise ValueError(
107+
"roq_params is missing required fields: "
108+
+ ", ".join(sorted(missing_fields))
109+
)
110+
self._roq_params = roq_params
111+
87112
def __init__(
88113
self, interferometers, waveform_generator, priors,
89114
weights=None, linear_matrix=None, quadratic_matrix=None,
@@ -96,6 +121,7 @@ def __init__(
96121

97122
):
98123
self._delta_tc = delta_tc
124+
self._roq_params = None
99125
super(ROQGravitationalWaveTransient, self).__init__(
100126
interferometers=interferometers,
101127
waveform_generator=waveform_generator, priors=priors,
@@ -130,17 +156,17 @@ def __init__(
130156
if self.roq_params is None:
131157
if is_hdf5_linear:
132158
self.roq_params = np.array(
133-
[(linear_matrix['minimum_frequency_hz'][()],
134-
linear_matrix['maximum_frequency_hz'][()],
135-
linear_matrix['duration_s'][()])],
159+
(linear_matrix['minimum_frequency_hz'][()],
160+
linear_matrix['maximum_frequency_hz'][()],
161+
linear_matrix['duration_s'][()]),
136162
dtype=[('flow', float), ('fhigh', float), ('seglen', float)]
137163
)
138164
if is_hdf5_quadratic:
139165
if self.roq_params is None:
140166
self.roq_params = np.array(
141-
[(quadratic_matrix['minimum_frequency_hz'][()],
142-
quadratic_matrix['maximum_frequency_hz'][()],
143-
quadratic_matrix['duration_s'][()])],
167+
(quadratic_matrix['minimum_frequency_hz'][()],
168+
quadratic_matrix['maximum_frequency_hz'][()],
169+
quadratic_matrix['duration_s'][()]),
144170
dtype=[('flow', float), ('fhigh', float), ('seglen', float)]
145171
)
146172
else:

test/gw/likelihood_test.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import tempfile
44
from functools import cached_property
55
from itertools import product
6+
from unittest import mock
67
from parameterized import parameterized
78
import pytest
89
from copy import deepcopy
@@ -1032,13 +1033,36 @@ def test_from_hdf5(self, basis_linear, basis_quadratic):
10321033
)
10331034
)
10341035

1035-
bilby.gw.likelihood.ROQGravitationalWaveTransient(
1036+
likelihood = bilby.gw.likelihood.ROQGravitationalWaveTransient(
10361037
interferometers=interferometers,
10371038
priors=priors,
10381039
waveform_generator=search_waveform_generator,
10391040
linear_matrix=f"{self.roq_dir}/{basis_linear}",
10401041
quadratic_matrix=f"{self.roq_dir}/{basis_quadratic}"
10411042
)
1043+
assert np.asarray(likelihood.roq_params).shape == ()
1044+
1045+
def test_roq_params_requires_scalar_structured_array(self):
1046+
likelihood = mock.Mock()
1047+
with self.assertRaisesRegex(ValueError, "scalar structured array"):
1048+
bilby.gw.likelihood.ROQGravitationalWaveTransient.roq_params.fset(
1049+
likelihood,
1050+
np.array(
1051+
[(20.0, 1024.0, 16.0)],
1052+
dtype=[("flow", float), ("fhigh", float), ("seglen", float)],
1053+
),
1054+
)
1055+
1056+
def test_roq_params_requires_expected_fields(self):
1057+
likelihood = mock.Mock()
1058+
with self.assertRaisesRegex(ValueError, "missing required fields: seglen"):
1059+
bilby.gw.likelihood.ROQGravitationalWaveTransient.roq_params.fset(
1060+
likelihood,
1061+
np.array(
1062+
(20.0, 1024.0),
1063+
dtype=[("flow", float), ("fhigh", float)],
1064+
),
1065+
)
10421066

10431067
@parameterized.expand([(False, ), (True, )])
10441068
def test_from_npy(self, from_array):

0 commit comments

Comments
 (0)