lisaanalysistools 1.1.20__cp39-cp39-macosx_15_0_arm64.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.
- lisaanalysistools/git_version.py +7 -0
- lisaanalysistools-1.1.20.dist-info/METADATA +281 -0
- lisaanalysistools-1.1.20.dist-info/RECORD +48 -0
- lisaanalysistools-1.1.20.dist-info/WHEEL +5 -0
- lisaanalysistools-1.1.20.dist-info/licenses/LICENSE +201 -0
- lisatools/.dylibs/libgcc_s.1.1.dylib +0 -0
- lisatools/.dylibs/libstdc++.6.dylib +0 -0
- lisatools/__init__.py +90 -0
- lisatools/_version.py +34 -0
- lisatools/analysiscontainer.py +474 -0
- lisatools/cutils/Detector.cu +307 -0
- lisatools/cutils/Detector.hpp +84 -0
- lisatools/cutils/__init__.py +129 -0
- lisatools/cutils/global.hpp +28 -0
- lisatools/cutils/pycppdetector.pyx +256 -0
- lisatools/datacontainer.py +312 -0
- lisatools/detector.py +867 -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 +1554 -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 +37 -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 +122 -0
- lisatools_backend_cpu/git_version.py +7 -0
- lisatools_backend_cpu/pycppdetector.cpython-39-darwin.so +0 -0
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
import time
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from eryn.utils.stopping import Stopping
|
|
6
|
+
from eryn.utils.utility import thermodynamic_integration_log_evidence
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class SNRStopping(Stopping):
|
|
10
|
+
def __init__(self, snr_limit=100.0, verbose=False):
|
|
11
|
+
self.snr_limit = snr_limit
|
|
12
|
+
self.verbose = verbose
|
|
13
|
+
|
|
14
|
+
def __call__(self, iter, sample, sampler):
|
|
15
|
+
|
|
16
|
+
ind = sampler.get_log_like().argmax()
|
|
17
|
+
|
|
18
|
+
log_best = sampler.get_log_like().max()
|
|
19
|
+
snr_best = sampler.get_blobs()[:, :, :, 0].flatten()[ind]
|
|
20
|
+
# d_h_best = sampler.get_blobs()[:, :, :, 1].flatten()[ind]
|
|
21
|
+
# h_h_best = sampler.get_blobs()[:, :, :, 2].flatten()[ind]
|
|
22
|
+
|
|
23
|
+
if self.verbose:
|
|
24
|
+
print(
|
|
25
|
+
"snr_best",
|
|
26
|
+
snr_best,
|
|
27
|
+
"limit:",
|
|
28
|
+
self.snr_limit,
|
|
29
|
+
"loglike:",
|
|
30
|
+
log_best,
|
|
31
|
+
# d_h_best,
|
|
32
|
+
# h_h_best,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
if snr_best > self.snr_limit:
|
|
36
|
+
return True
|
|
37
|
+
|
|
38
|
+
else:
|
|
39
|
+
return False
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class NLeavesSearchStopping:
|
|
43
|
+
def __init__(self, convergence_iter=5, verbose=False):
|
|
44
|
+
self.convergence_iter = convergence_iter
|
|
45
|
+
self.verbose = verbose
|
|
46
|
+
|
|
47
|
+
def __call__(self, current_info):
|
|
48
|
+
|
|
49
|
+
if not hasattr(self, "st"):
|
|
50
|
+
self.st = time.perf_counter()
|
|
51
|
+
|
|
52
|
+
current_iter = current_info.gb_info["reader"].iteration
|
|
53
|
+
|
|
54
|
+
if current_iter > self.convergence_iter:
|
|
55
|
+
|
|
56
|
+
nleaves_cc = curr.gb_info["reader"].get_nleaves()["gb"][:, 0]
|
|
57
|
+
|
|
58
|
+
# do not include most recent
|
|
59
|
+
nleaves_cc_max_old = nleaves_cc[:-self.convergence_iter].max()
|
|
60
|
+
nleaves_cc_max_new = nleaves_cc[-self.convergence_iter:].max()
|
|
61
|
+
|
|
62
|
+
if nleaves_cc_max_old > nleaves_cc_max_new:
|
|
63
|
+
stop = True
|
|
64
|
+
|
|
65
|
+
else:
|
|
66
|
+
stop = False
|
|
67
|
+
|
|
68
|
+
if self.verbose:
|
|
69
|
+
dur = (time.perf_counter() - self.st) / 3600.0 # hours
|
|
70
|
+
print(
|
|
71
|
+
"\nnleaves max old:\n",
|
|
72
|
+
nleaves_cc_max_old,
|
|
73
|
+
"\nnleaves max new:\n",
|
|
74
|
+
nleaves_cc_max_newf,
|
|
75
|
+
f"\nTIME TO NOW: {dur} hours"
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
return stop
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class SearchConvergeStopping(Stopping):
|
|
82
|
+
def __init__(self, n_iters=30, diff=1.0, verbose=False, start_iteration=0):
|
|
83
|
+
self.n_iters = n_iters
|
|
84
|
+
self.iters_consecutive = 0
|
|
85
|
+
self.past_like_best = -np.inf
|
|
86
|
+
self.diff = diff
|
|
87
|
+
self.verbose = verbose
|
|
88
|
+
self.start_iteration = start_iteration
|
|
89
|
+
|
|
90
|
+
def __call__(self, iter, sample, sampler):
|
|
91
|
+
|
|
92
|
+
like_best = sampler.get_log_like(discard=self.start_iteration).max()
|
|
93
|
+
|
|
94
|
+
if np.abs(like_best - self.past_like_best) < self.diff:
|
|
95
|
+
self.iters_consecutive += 1
|
|
96
|
+
|
|
97
|
+
else:
|
|
98
|
+
self.iters_consecutive = 0
|
|
99
|
+
self.past_like_best = like_best
|
|
100
|
+
|
|
101
|
+
if self.verbose:
|
|
102
|
+
print(
|
|
103
|
+
"\nITERS CONSECUTIVE:\n",
|
|
104
|
+
self.iters_consecutive,
|
|
105
|
+
self.past_like_best,
|
|
106
|
+
like_best,
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
if self.iters_consecutive >= self.n_iters:
|
|
110
|
+
self.iters_consecutive = 0
|
|
111
|
+
return True
|
|
112
|
+
|
|
113
|
+
else:
|
|
114
|
+
return False
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
class GBBandLogLConvergeStopping(Stopping):
|
|
119
|
+
|
|
120
|
+
def __init__(self, fd, band_edges, n_iters=30, diff=1.0, verbose=False, start_iteration=0):
|
|
121
|
+
self.band_edge_inds = np.searchsorted(fd, band_edges, side="right") - 1
|
|
122
|
+
self.num_bands = self.band_edge_inds.shape[0] - 1
|
|
123
|
+
self.converged = np.zeros(self.num_bands, dtype=bool)
|
|
124
|
+
self.iters_consecutive = np.zeros(self.num_bands, dtype=int)
|
|
125
|
+
self.past_like_best = np.full(self.num_bands, -np.inf)
|
|
126
|
+
self.n_iters = n_iters
|
|
127
|
+
self.diff = diff
|
|
128
|
+
self.verbose = verbose
|
|
129
|
+
self.start_iteration = start_iteration
|
|
130
|
+
|
|
131
|
+
def add_mgh(self, mgh):
|
|
132
|
+
self.mgh = mgh
|
|
133
|
+
|
|
134
|
+
def __call__(self, i, sample, sampler):
|
|
135
|
+
|
|
136
|
+
ll_per_band = self.mgh.get_ll(band_edge_inds=self.band_edge_inds).max(axis=0)
|
|
137
|
+
|
|
138
|
+
ll_movement = (ll_per_band - self.past_like_best) > self.diff
|
|
139
|
+
|
|
140
|
+
self.iters_consecutive[~ll_movement] += 1
|
|
141
|
+
self.iters_consecutive[ll_movement] = 0
|
|
142
|
+
|
|
143
|
+
self.converged = self.iters_consecutive >= self.n_iters
|
|
144
|
+
|
|
145
|
+
self.past_like_best[ll_movement] = ll_per_band[ll_movement]
|
|
146
|
+
|
|
147
|
+
# for move in sampler.all_moves:
|
|
148
|
+
# move.converged_sub_bands = self.converged.copy()
|
|
149
|
+
|
|
150
|
+
if self.verbose:
|
|
151
|
+
print("Num still going:", (~self.converged).sum(), "\nChanged here:", (ll_movement).sum())
|
|
152
|
+
|
|
153
|
+
if np.all(self.converged):
|
|
154
|
+
return True
|
|
155
|
+
else:
|
|
156
|
+
return False
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
class SearchConvergeStopping2(Stopping):
|
|
164
|
+
def __init__(self, n_iters=30, diff=0.1, verbose=False, start_iteration=0, iter_back_check=-1):
|
|
165
|
+
self.n_iters = n_iters
|
|
166
|
+
self.iters_consecutive = 0
|
|
167
|
+
self.past_like_best = -np.inf
|
|
168
|
+
self.diff = diff
|
|
169
|
+
self.verbose = verbose
|
|
170
|
+
self.start_iteration = start_iteration
|
|
171
|
+
self.iter_back_check = iter_back_check
|
|
172
|
+
self.time = 0
|
|
173
|
+
self.back_check = [None for _ in range(self.iter_back_check)]
|
|
174
|
+
self.last_sampler_iteration = self.start_iteration
|
|
175
|
+
self.back_check_ind = 0
|
|
176
|
+
self.stop_here = True
|
|
177
|
+
|
|
178
|
+
def __call__(self, iter, sample, sampler):
|
|
179
|
+
|
|
180
|
+
self.time += 1
|
|
181
|
+
|
|
182
|
+
if sampler.iteration <= self.start_iteration:
|
|
183
|
+
return False
|
|
184
|
+
|
|
185
|
+
lps = sampler.get_log_like(discard=self.start_iteration)[self.last_sampler_iteration - self.start_iteration:]
|
|
186
|
+
try:
|
|
187
|
+
like_best = lps.max()
|
|
188
|
+
except:
|
|
189
|
+
breakpoint()
|
|
190
|
+
self.last_sampler_iteration = sampler.iteration
|
|
191
|
+
|
|
192
|
+
if np.any(np.asarray(self.back_check) == None):
|
|
193
|
+
for i in range(len(self.back_check)):
|
|
194
|
+
if self.back_check[i] is None:
|
|
195
|
+
self.back_check[i] = like_best
|
|
196
|
+
return False
|
|
197
|
+
|
|
198
|
+
first_check = like_best - self.past_like_best > self.diff
|
|
199
|
+
second_check = np.all(like_best >= np.asarray(self.back_check))
|
|
200
|
+
|
|
201
|
+
# spread in stored values is below difference
|
|
202
|
+
third_check = np.asarray(self.back_check).max() - np.asarray(self.back_check).min() < self.diff
|
|
203
|
+
|
|
204
|
+
update = (
|
|
205
|
+
(first_check and second_check and self.past_like_best == -np.inf)
|
|
206
|
+
or (self.past_like_best == -np.inf and third_check)
|
|
207
|
+
or (self.past_like_best > -np.inf and first_check)
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
self.back_check[self.back_check_ind] = like_best
|
|
211
|
+
self.back_check_ind = (self.back_check_ind + 1) % len(self.back_check)
|
|
212
|
+
|
|
213
|
+
if update:
|
|
214
|
+
self.past_like_best = like_best
|
|
215
|
+
self.iters_consecutive = 0
|
|
216
|
+
|
|
217
|
+
elif self.past_like_best > -np.inf:
|
|
218
|
+
self.iters_consecutive += 1
|
|
219
|
+
|
|
220
|
+
if self.verbose:
|
|
221
|
+
print(
|
|
222
|
+
"\nITERS CONSECUTIVE:\n",
|
|
223
|
+
self.iters_consecutive,
|
|
224
|
+
f"previous best: {self.past_like_best}, overall best: {like_best},",
|
|
225
|
+
"first check:", first_check,
|
|
226
|
+
"second check:", second_check
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
if self.iters_consecutive >= self.n_iters:
|
|
230
|
+
self.iters_consecutive = 0
|
|
231
|
+
return True
|
|
232
|
+
|
|
233
|
+
else:
|
|
234
|
+
return False
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
class EvidenceStopping(Stopping):
|
|
239
|
+
def __init__(self, diff=0.5, verbose=False):
|
|
240
|
+
self.diff = diff
|
|
241
|
+
self.verbose = verbose
|
|
242
|
+
|
|
243
|
+
def __call__(self, iter, sample, sampler):
|
|
244
|
+
|
|
245
|
+
betas = sampler.get_betas()[-1]
|
|
246
|
+
logls = sampler.get_log_like().mean(axis=(0, 2))
|
|
247
|
+
|
|
248
|
+
logZ, dlogZ = thermodynamic_integration_log_evidence(betas, logls)
|
|
249
|
+
print(logZ, dlogZ)
|
|
250
|
+
return False
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
if self.verbose:
|
|
254
|
+
print(
|
|
255
|
+
"snr_best",
|
|
256
|
+
snr_best,
|
|
257
|
+
"limit:",
|
|
258
|
+
self.snr_limit,
|
|
259
|
+
"loglike:",
|
|
260
|
+
log_best,
|
|
261
|
+
# d_h_best,
|
|
262
|
+
# h_h_best,
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
if snr_best > self.snr_limit:
|
|
266
|
+
return True
|
|
267
|
+
|
|
268
|
+
else:
|
|
269
|
+
return False
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
class MPICommunicateStopping(Stopping):
|
|
273
|
+
|
|
274
|
+
def __init__(self, stopper_rank, other_ranks, stop_fn=None):
|
|
275
|
+
|
|
276
|
+
self.stopper_rank = stopper_rank
|
|
277
|
+
self.other_ranks = other_ranks
|
|
278
|
+
self.stop_fn = stop_fn
|
|
279
|
+
|
|
280
|
+
def add_comm(self, comm):
|
|
281
|
+
self.comm = comm
|
|
282
|
+
|
|
283
|
+
def __call__(self, *args, **kwargs):
|
|
284
|
+
|
|
285
|
+
if not hasattr(self, "comm"):
|
|
286
|
+
raise ValueError("Must add comm via add_comm method before __call__ is used.")
|
|
287
|
+
|
|
288
|
+
if not hasattr(self, "rank"):
|
|
289
|
+
self.rank = self.comm.Get_rank()
|
|
290
|
+
if not self.rank == self.stopper_rank and not self.rank in self.other_ranks:
|
|
291
|
+
raise ValueError("Rank is not available in other ranks list. Must be either stopper rank or in other ranks list.")
|
|
292
|
+
|
|
293
|
+
if self.stopper_rank == self.rank and self.stop_fn is None:
|
|
294
|
+
raise ValueError("Rank is equivalent to stopper rank but stop_fn is not provided. It must be provided.")
|
|
295
|
+
|
|
296
|
+
if self.rank == self.stopper_rank:
|
|
297
|
+
stop = self.stop_fn(*args, **kwargs)
|
|
298
|
+
|
|
299
|
+
if stop:
|
|
300
|
+
for rank in self.other_ranks:
|
|
301
|
+
tag = int(str(rank) + "1000")
|
|
302
|
+
self.comm.isend(True, dest=rank, tag=tag)
|
|
303
|
+
|
|
304
|
+
else:
|
|
305
|
+
tag = int(str(self.rank) + "1000")
|
|
306
|
+
check_stop = self.comm.irecv(source=self.stopper_rank, tag=tag)
|
|
307
|
+
|
|
308
|
+
if check_stop.get_status():
|
|
309
|
+
stop = check_stop.wait()
|
|
310
|
+
|
|
311
|
+
else:
|
|
312
|
+
check_stop.cancel()
|
|
313
|
+
stop = False
|
|
314
|
+
|
|
315
|
+
return stop
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
|