lisaanalysistools 1.1.6__cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of lisaanalysistools might be problematic. Click here for more details.
- lisaanalysistools/git_version.py +7 -0
- lisaanalysistools-1.1.6.dist-info/METADATA +295 -0
- lisaanalysistools-1.1.6.dist-info/RECORD +42 -0
- lisaanalysistools-1.1.6.dist-info/WHEEL +6 -0
- lisaanalysistools-1.1.6.dist-info/licenses/LICENSE +201 -0
- lisatools/__init__.py +58 -0
- lisatools/_version.py +34 -0
- lisatools/analysiscontainer.py +474 -0
- lisatools/cutils/__init__.py +126 -0
- lisatools/datacontainer.py +312 -0
- lisatools/detector.py +704 -0
- lisatools/diagnostic.py +990 -0
- lisatools/git_version.py.in +7 -0
- lisatools/orbit_files/equalarmlength-orbits-best-fit-to-esa.h5 +0 -0
- lisatools/orbit_files/equalarmlength-orbits.h5 +0 -0
- lisatools/orbit_files/esa-trailing-orbits.h5 +0 -0
- lisatools/sampling/__init__.py +0 -0
- lisatools/sampling/likelihood.py +882 -0
- lisatools/sampling/moves/__init__.py +0 -0
- lisatools/sampling/moves/skymodehop.py +110 -0
- lisatools/sampling/prior.py +646 -0
- lisatools/sampling/stopping.py +320 -0
- lisatools/sampling/utility.py +411 -0
- lisatools/sensitivity.py +972 -0
- lisatools/sources/__init__.py +6 -0
- lisatools/sources/bbh/__init__.py +1 -0
- lisatools/sources/bbh/waveform.py +106 -0
- lisatools/sources/defaultresponse.py +36 -0
- lisatools/sources/emri/__init__.py +1 -0
- lisatools/sources/emri/waveform.py +79 -0
- lisatools/sources/gb/__init__.py +1 -0
- lisatools/sources/gb/waveform.py +69 -0
- lisatools/sources/utils.py +459 -0
- lisatools/sources/waveformbase.py +41 -0
- lisatools/stochastic.py +327 -0
- lisatools/utils/__init__.py +0 -0
- lisatools/utils/constants.py +54 -0
- lisatools/utils/exceptions.py +95 -0
- lisatools/utils/parallelbase.py +11 -0
- lisatools/utils/utility.py +245 -0
- lisatools_backend_cpu/git_version.py +7 -0
- lisatools_backend_cpu/pycppdetector.cpython-312-x86_64-linux-gnu.so +0 -0
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import Tuple
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
# from ..sensitivity import get_sensitivity
|
|
6
|
+
|
|
7
|
+
try:
|
|
8
|
+
import cupy as cp
|
|
9
|
+
|
|
10
|
+
except (ModuleNotFoundError, ImportError):
|
|
11
|
+
import numpy as cp
|
|
12
|
+
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def get_array_module(arr: np.ndarray | cp.ndarray) -> object:
|
|
17
|
+
"""Return array library of an array (np/cp).
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
arr: Numpy or Cupy array.
|
|
21
|
+
|
|
22
|
+
"""
|
|
23
|
+
if isinstance(arr, np.ndarray):
|
|
24
|
+
return np
|
|
25
|
+
elif isinstance(arr, cp.ndarray):
|
|
26
|
+
return cp
|
|
27
|
+
else:
|
|
28
|
+
raise ValueError("arr must be a numpy or cupy array.")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def generate_noise_fd(freqs, df, *sensitivity_args, func=None, **sensitivity_kwargs):
|
|
32
|
+
if func is None:
|
|
33
|
+
func = get_sensitivity
|
|
34
|
+
|
|
35
|
+
norm = 0.5 * (1.0 / df) ** 0.5
|
|
36
|
+
psd = func(freqs, *sensitivity_args, **sensitivity_kwargs)
|
|
37
|
+
noise_to_add = psd ** (1 / 2) * (
|
|
38
|
+
np.random.normal(0, norm, len(freqs))
|
|
39
|
+
+ 1j * np.random.normal(0, norm, len(freqs))
|
|
40
|
+
)
|
|
41
|
+
return noise_to_add
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def AET(
|
|
45
|
+
X: float | np.ndarray, Y: float | np.ndarray, Z: float | np.ndarray
|
|
46
|
+
) -> Tuple[float | np.ndarray, float | np.ndarray, float | np.ndarray]:
|
|
47
|
+
"""Transform to AET from XYZ
|
|
48
|
+
|
|
49
|
+
.. math::
|
|
50
|
+
|
|
51
|
+
A = (Z - X) / \\sqrt(2)
|
|
52
|
+
|
|
53
|
+
.. math::
|
|
54
|
+
|
|
55
|
+
E = (X - 2Y + Z) / \\sqrt(6)
|
|
56
|
+
|
|
57
|
+
.. math::
|
|
58
|
+
|
|
59
|
+
T = (X + Y + Z) / \\sqrt(3)
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
X: X-channel information.
|
|
63
|
+
Y: Y-channel information.
|
|
64
|
+
Z: Z-channel information.
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
A, E, T Channels.
|
|
68
|
+
|
|
69
|
+
"""
|
|
70
|
+
return (
|
|
71
|
+
(Z - X) / np.sqrt(2.0),
|
|
72
|
+
(X - 2.0 * Y + Z) / np.sqrt(6.0),
|
|
73
|
+
(X + Y + Z) / np.sqrt(3.0),
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def searchsorted2d_vec(a, b, xp=None, gpu=None, **kwargs):
|
|
78
|
+
if xp is None:
|
|
79
|
+
xp = np
|
|
80
|
+
else:
|
|
81
|
+
try:
|
|
82
|
+
xp.cuda.runtime.setDevice(gpu)
|
|
83
|
+
except AttributeError:
|
|
84
|
+
pass
|
|
85
|
+
|
|
86
|
+
m, n = a.shape
|
|
87
|
+
max_num = xp.maximum(a.max() - a.min(), b.max() - b.min()) + 1
|
|
88
|
+
r = max_num * xp.arange(a.shape[0])[:, None]
|
|
89
|
+
p = xp.searchsorted((a + r).ravel(), (b + r).ravel(), **kwargs).reshape(m, -1)
|
|
90
|
+
|
|
91
|
+
out = p - n * (xp.arange(m)[:, None])
|
|
92
|
+
try:
|
|
93
|
+
xp.cuda.runtime.deviceSynchronize()
|
|
94
|
+
except AttributeError:
|
|
95
|
+
pass
|
|
96
|
+
|
|
97
|
+
return out
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def get_groups_from_band_structure(
|
|
101
|
+
f0, band_edges, f0_2=None, xp=None, num_groups_base=3, fix_f_test=None, inds=None
|
|
102
|
+
):
|
|
103
|
+
if num_groups_base not in [2, 3, 4]:
|
|
104
|
+
raise ValueError("num_groups_base must be 2 or 3 or 4.")
|
|
105
|
+
if xp is None:
|
|
106
|
+
xp = np
|
|
107
|
+
|
|
108
|
+
else:
|
|
109
|
+
try:
|
|
110
|
+
xp.cuda.runtime.setDevice(xp.cuda.runtime.getDevice())
|
|
111
|
+
|
|
112
|
+
except AttributeError:
|
|
113
|
+
# it is numpy
|
|
114
|
+
pass
|
|
115
|
+
|
|
116
|
+
if not isinstance(f0, xp.ndarray) or not isinstance(band_edges, xp.ndarray):
|
|
117
|
+
raise TypeError(
|
|
118
|
+
"f0 and band_edges must be xp.ndarray with xp as numpy or cupy as given by the xp kwarg."
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
shape = f0.shape
|
|
122
|
+
|
|
123
|
+
# remove any above or below bands
|
|
124
|
+
bad = (f0 < band_edges.min()) | (f0 > band_edges.max())
|
|
125
|
+
|
|
126
|
+
band_indices = xp.searchsorted(band_edges, f0.flatten()).reshape(shape) - 1
|
|
127
|
+
|
|
128
|
+
# sort the bands in, but keep places with inds_band_indices
|
|
129
|
+
band_indices_sorted = xp.sort(band_indices, axis=-1)
|
|
130
|
+
inds_band_indices = xp.argsort(band_indices, axis=-1)
|
|
131
|
+
|
|
132
|
+
if f0_2 is not None:
|
|
133
|
+
assert f0_2.shape == f0.shape
|
|
134
|
+
band_indices_2 = xp.searchsorted(band_edges, f0_2.flatten()).reshape(shape) - 1
|
|
135
|
+
band_indices_2_sorted = xp.take_along_axis(
|
|
136
|
+
band_indices_2, inds_band_indices, axis=-1
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
# very important: ensures the proposed new point is not further than 1 band away.
|
|
140
|
+
diff = 1 if num_groups_base > 2 else 0
|
|
141
|
+
keep = (
|
|
142
|
+
np.abs(band_indices_2_sorted.flatten() - band_indices_sorted.flatten())
|
|
143
|
+
<= diff
|
|
144
|
+
)
|
|
145
|
+
if fix_f_test is not None:
|
|
146
|
+
keep[fix_f_test.flatten()] = False
|
|
147
|
+
remove = ~keep
|
|
148
|
+
|
|
149
|
+
else:
|
|
150
|
+
keep = np.ones(np.prod(band_indices_sorted.shape), dtype=bool)
|
|
151
|
+
|
|
152
|
+
# temperature index associated with each band
|
|
153
|
+
temp_inds = xp.repeat(
|
|
154
|
+
xp.arange(band_indices_sorted.shape[0]), np.prod(band_indices_sorted.shape[1:])
|
|
155
|
+
)[
|
|
156
|
+
keep
|
|
157
|
+
] # .reshape(shape)
|
|
158
|
+
|
|
159
|
+
# walker index associated with each band
|
|
160
|
+
walker_inds = (
|
|
161
|
+
xp.tile(
|
|
162
|
+
xp.arange(band_indices_sorted.shape[1]),
|
|
163
|
+
(band_indices_sorted.shape[0], band_indices_sorted.shape[2], 1),
|
|
164
|
+
)
|
|
165
|
+
.transpose((0, 2, 1))
|
|
166
|
+
.flatten()[keep]
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
if f0_2 is not None:
|
|
170
|
+
temp_inds_remove = xp.repeat(
|
|
171
|
+
xp.arange(band_indices_sorted.shape[0]),
|
|
172
|
+
np.prod(band_indices_sorted.shape[1:]),
|
|
173
|
+
)[
|
|
174
|
+
remove
|
|
175
|
+
] # .reshape(shape)
|
|
176
|
+
|
|
177
|
+
# walker index associated with each band
|
|
178
|
+
walker_inds_remove = (
|
|
179
|
+
xp.tile(
|
|
180
|
+
xp.arange(band_indices_sorted.shape[1]),
|
|
181
|
+
(band_indices_sorted.shape[0], band_indices_sorted.shape[2], 1),
|
|
182
|
+
)
|
|
183
|
+
.transpose((0, 2, 1))
|
|
184
|
+
.flatten()[remove]
|
|
185
|
+
)
|
|
186
|
+
inds_band_indices_remove = inds_band_indices.flatten()[remove]
|
|
187
|
+
|
|
188
|
+
# special indexing method
|
|
189
|
+
band_indices_sorted_special = (
|
|
190
|
+
band_indices_sorted.flatten()[keep]
|
|
191
|
+
+ int(1e12) * temp_inds
|
|
192
|
+
+ int(1e6) * walker_inds
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
# get the unique special indicators
|
|
196
|
+
(
|
|
197
|
+
unique_special,
|
|
198
|
+
unique_special_start_inds,
|
|
199
|
+
unique_special_reverse,
|
|
200
|
+
unique_special_counts,
|
|
201
|
+
) = np.unique(
|
|
202
|
+
band_indices_sorted_special,
|
|
203
|
+
return_index=True,
|
|
204
|
+
return_inverse=True,
|
|
205
|
+
return_counts=True,
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
# this basically makes mini arange setups for each band
|
|
209
|
+
# the added_contribution for the first unique band index is removed
|
|
210
|
+
added_contribution = xp.arange(band_indices_sorted_special.shape[0])
|
|
211
|
+
|
|
212
|
+
# gets the groups
|
|
213
|
+
combined = band_indices_sorted_special + added_contribution
|
|
214
|
+
groups = (
|
|
215
|
+
combined - (combined[unique_special_start_inds])[unique_special_reverse]
|
|
216
|
+
) # .reshape(shape)
|
|
217
|
+
|
|
218
|
+
groups_even_odd_tmp = xp.asarray(
|
|
219
|
+
[
|
|
220
|
+
(num_groups_base * groups + i)
|
|
221
|
+
* (band_indices_sorted.flatten()[keep] % num_groups_base == i)
|
|
222
|
+
for i in range(num_groups_base)
|
|
223
|
+
]
|
|
224
|
+
)
|
|
225
|
+
groups_even_odd = xp.sum(groups_even_odd_tmp, axis=0)
|
|
226
|
+
|
|
227
|
+
groups_out = -2 * xp.ones_like(f0, dtype=int)
|
|
228
|
+
groups_out[(temp_inds, walker_inds, inds_band_indices.flatten()[keep])] = (
|
|
229
|
+
groups_even_odd
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
groups_out[bad] = -1
|
|
233
|
+
|
|
234
|
+
"""if f0_2 is not None and not np.all(keep):
|
|
235
|
+
fix = (temp_inds_remove, walker_inds_remove, inds_band_indices_remove)
|
|
236
|
+
fix_2 = band_indices_2[fix]
|
|
237
|
+
fix_1 = band_indices[fix]"""
|
|
238
|
+
|
|
239
|
+
return groups_out
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
autodoc_type_aliases = {
|
|
243
|
+
"Iterable": "Iterable",
|
|
244
|
+
"ArrayLike": "ArrayLike",
|
|
245
|
+
}
|
|
Binary file
|