sxs 2025.0.7__py3-none-any.whl → 2025.0.9__py3-none-any.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.
- sxs/__version__.py +1 -1
- sxs/simulations/analyze.py +64 -37
- sxs/simulations/simulation.py +7 -4
- sxs/waveforms/alignment.py +4 -1
- sxs/waveforms/memory.py +1 -0
- {sxs-2025.0.7.dist-info → sxs-2025.0.9.dist-info}/METADATA +1 -1
- {sxs-2025.0.7.dist-info → sxs-2025.0.9.dist-info}/RECORD +9 -9
- {sxs-2025.0.7.dist-info → sxs-2025.0.9.dist-info}/WHEEL +0 -0
- {sxs-2025.0.7.dist-info → sxs-2025.0.9.dist-info}/licenses/LICENSE +0 -0
sxs/__version__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "2025.0.
|
|
1
|
+
__version__ = "2025.0.9"
|
sxs/simulations/analyze.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import json
|
|
1
3
|
import multiprocessing
|
|
2
4
|
|
|
3
5
|
from ..waveforms.norms import create_unified_waveforms, L2_difference, mismatch
|
|
@@ -7,7 +9,7 @@ from ..handlers import load
|
|
|
7
9
|
import numpy as np
|
|
8
10
|
|
|
9
11
|
|
|
10
|
-
def compute_error_summary(wa, wb, t1, t2, modes=None,
|
|
12
|
+
def compute_error_summary(wa, wb, t1, t2, modes=None, ASDs_and_total_masses=None):
|
|
11
13
|
"""
|
|
12
14
|
Compute various errors between two waveforms.
|
|
13
15
|
|
|
@@ -27,12 +29,13 @@ def compute_error_summary(wa, wb, t1, t2, modes=None, ASDs=None, total_masses=No
|
|
|
27
29
|
modes : list, optional
|
|
28
30
|
Modes (ell, m) to include in error calculations.
|
|
29
31
|
Default is all modes.
|
|
30
|
-
|
|
31
|
-
Dictionary of functions mapping frequencies to the ASD of a detector(s)
|
|
32
|
+
ASDs_and_total_masses : dict of funcs, optional
|
|
33
|
+
Dictionary of functions mapping frequencies to the ASD of a detector(s)
|
|
34
|
+
and total masses to use for mismatch calculations with those ASDs, e.g.,
|
|
35
|
+
{
|
|
36
|
+
'CE': [CE_ASD, total_masses]
|
|
37
|
+
}
|
|
32
38
|
Default is no frequency-domain mismatch is calculated.
|
|
33
|
-
total_masses : list of floats, optional
|
|
34
|
-
Total masses in solar masses to use for frequency-domain mismatches.
|
|
35
|
-
Default is 1.
|
|
36
39
|
|
|
37
40
|
Returns
|
|
38
41
|
-------
|
|
@@ -65,10 +68,8 @@ def compute_error_summary(wa, wb, t1, t2, modes=None, ASDs=None, total_masses=No
|
|
|
65
68
|
|
|
66
69
|
wa_tilde = wa.fourier_transform()
|
|
67
70
|
wb_tilde = wb.fourier_transform()
|
|
68
|
-
if
|
|
69
|
-
|
|
70
|
-
raise ValueError("Need to specify total masses if ASDs are provided.")
|
|
71
|
-
for ASD in ASDs:
|
|
71
|
+
if ASDs_and_total_masses is not None:
|
|
72
|
+
for ASD_name, (ASD_data, total_masses) in ASDs_and_total_masses.items():
|
|
72
73
|
for total_mass in total_masses:
|
|
73
74
|
# Note that we only need to make the frequency unitful, since the
|
|
74
75
|
# magnitude of the strain scales out in the mismatch.
|
|
@@ -82,8 +83,8 @@ def compute_error_summary(wa, wb, t1, t2, modes=None, ASDs=None, total_masses=No
|
|
|
82
83
|
wa_tilde_total_mass.t = wa_tilde_total_mass.t * frequency_factor
|
|
83
84
|
wb_tilde_total_mass.t = wb_tilde_total_mass.t * frequency_factor
|
|
84
85
|
|
|
85
|
-
errors[f"mismatch {
|
|
86
|
-
wa_tilde_total_mass, wb_tilde_total_mass, f1 * frequency_factor, modes=modes, ASD=
|
|
86
|
+
errors[f"mismatch {ASD_name} {total_mass}"] = mismatch(
|
|
87
|
+
wa_tilde_total_mass, wb_tilde_total_mass, f1 * frequency_factor, modes=modes, ASD=ASD_data
|
|
87
88
|
)
|
|
88
89
|
|
|
89
90
|
ell_min = max(wa.ell_min, wb.ell_min)
|
|
@@ -104,8 +105,8 @@ def analyze_simulation(
|
|
|
104
105
|
analyze_levs=True,
|
|
105
106
|
analyze_extrapolation=True,
|
|
106
107
|
analyze_psi4=True,
|
|
107
|
-
|
|
108
|
-
|
|
108
|
+
ASDs_and_total_masses=None,
|
|
109
|
+
path_to_analysis_cache=None,
|
|
109
110
|
nprocs=None,
|
|
110
111
|
):
|
|
111
112
|
"""
|
|
@@ -134,12 +135,13 @@ def analyze_simulation(
|
|
|
134
135
|
analyze_psi4 : bool, optional
|
|
135
136
|
Whether or not to analyze the psi4 constraint -h.ddot = psi4..
|
|
136
137
|
Default is True.
|
|
137
|
-
|
|
138
|
-
Dictionary of functions mapping frequencies to the ASD of a detector(s)
|
|
138
|
+
ASDs_and_total_masses : dict of funcs, optional
|
|
139
|
+
Dictionary of functions mapping frequencies to the ASD of a detector(s)
|
|
140
|
+
and total masses to use for mismatch calculations with those ASDs, e.g.,
|
|
141
|
+
{
|
|
142
|
+
'CE': [CE_ASD, total_masses]
|
|
143
|
+
}
|
|
139
144
|
Default is no frequency-domain mismatch is calculated.
|
|
140
|
-
total_masses : list of floats, optional
|
|
141
|
-
Total masses in solar masses to use for frequency-domain mismatches.
|
|
142
|
-
Default is 1.
|
|
143
145
|
nprocs : int, optional
|
|
144
146
|
Number of cpus to use. Default is maximum number. If -1 is provided,
|
|
145
147
|
then no multiprocessing is performed.
|
|
@@ -154,23 +156,23 @@ def analyze_simulation(
|
|
|
154
156
|
sim = load(sim_name)
|
|
155
157
|
|
|
156
158
|
# Lev analysis
|
|
157
|
-
if analyze_levs:
|
|
158
|
-
for i,
|
|
159
|
-
sim_low_lev = load(f"{sim_name}/Lev{
|
|
160
|
-
sim_high_lev = load(f"{sim_name}/Lev{
|
|
159
|
+
if analyze_levs and len(sim.lev_numbers) > 1:
|
|
160
|
+
for i, (low_lev, high_lev) in enumerate(zip(sim.lev_numbers[:-1][::-1], sim.lev_numbers[1:][::-1])):
|
|
161
|
+
sim_low_lev = load(f"{sim_name}/Lev{low_lev}")
|
|
162
|
+
sim_high_lev = load(f"{sim_name}/Lev{high_lev}")
|
|
161
163
|
|
|
162
164
|
w_high_lev = sim_high_lev.h
|
|
163
165
|
if i == 0:
|
|
164
166
|
w_low_lev_prime, transformation, L2_norm, t1, t2 = align_simulations(
|
|
165
167
|
sim_low_lev, sim_high_lev, alignment_method="4d", nprocs=nprocs
|
|
166
168
|
)
|
|
167
|
-
errors[f"(Lev{
|
|
168
|
-
errors[f"(Lev{
|
|
169
|
+
errors[f"(Lev{low_lev}, Lev{high_lev}) 4d"] = compute_error_summary(w_low_lev_prime, w_high_lev, t1, t2, ASDs_and_total_masses=ASDs_and_total_masses)
|
|
170
|
+
errors[f"(Lev{low_lev}, Lev{high_lev}) 4d transformation"] = transformation
|
|
169
171
|
|
|
170
172
|
w_low_lev_prime, transformation, _, t1, t2 = align_simulations(
|
|
171
173
|
sim_low_lev, sim_high_lev, alignment_method="independent alignment", nprocs=nprocs
|
|
172
174
|
)
|
|
173
|
-
errors[f"(Lev{
|
|
175
|
+
errors[f"(Lev{low_lev}, Lev{high_lev})"] = L2_difference(w_high_lev, w_low_lev_prime, t1, t2)
|
|
174
176
|
|
|
175
177
|
# Extrapolation order analysis
|
|
176
178
|
if analyze_extrapolation:
|
|
@@ -179,7 +181,7 @@ def analyze_simulation(
|
|
|
179
181
|
|
|
180
182
|
w_n2 = sim.h
|
|
181
183
|
w_other = other.h
|
|
182
|
-
|
|
184
|
+
|
|
183
185
|
t1 = sim.metadata.relaxation_time
|
|
184
186
|
|
|
185
187
|
w_other_prime, transformation, _, t1, t2 = align_waveforms(
|
|
@@ -202,6 +204,26 @@ def analyze_simulation(
|
|
|
202
204
|
|
|
203
205
|
errors[f"(-h.ddot, psi4)"] = L2_norm
|
|
204
206
|
|
|
207
|
+
if path_to_analysis_cache is not None:
|
|
208
|
+
if not os.path.exists(path_to_analysis_cache):
|
|
209
|
+
os.makedirs(path_to_analysis_cache)
|
|
210
|
+
|
|
211
|
+
def default(obj):
|
|
212
|
+
if isinstance(obj, np.ndarray):
|
|
213
|
+
return obj.tolist()
|
|
214
|
+
raise TypeError("Not serializable")
|
|
215
|
+
|
|
216
|
+
sim_name = sim_name.replace(':','_')
|
|
217
|
+
with open(f"{path_to_analysis_cache}/{sim_name}.json", "w") as output_file:
|
|
218
|
+
json.dump(
|
|
219
|
+
errors,
|
|
220
|
+
output_file,
|
|
221
|
+
indent=2,
|
|
222
|
+
separators=(",", ": "),
|
|
223
|
+
ensure_ascii=True,
|
|
224
|
+
default=default,
|
|
225
|
+
)
|
|
226
|
+
|
|
205
227
|
return errors
|
|
206
228
|
|
|
207
229
|
|
|
@@ -210,8 +232,8 @@ def analyze_simulations(
|
|
|
210
232
|
analyze_levs=True,
|
|
211
233
|
analyze_extrapolation=True,
|
|
212
234
|
analyze_psi4=True,
|
|
213
|
-
|
|
214
|
-
|
|
235
|
+
ASDs_and_total_masses=None,
|
|
236
|
+
path_to_analysis_cache=None,
|
|
215
237
|
nprocs=None,
|
|
216
238
|
):
|
|
217
239
|
"""
|
|
@@ -240,12 +262,17 @@ def analyze_simulations(
|
|
|
240
262
|
analyze_psi4 : bool, optional
|
|
241
263
|
Whether or not to analyze the psi4 constraint -h.ddot = psi4..
|
|
242
264
|
Default is True.
|
|
243
|
-
|
|
244
|
-
Dictionary of functions mapping frequencies to the ASD of a detector(s)
|
|
265
|
+
ASDs_and_total_masses : dict of funcs, optional
|
|
266
|
+
Dictionary of functions mapping frequencies to the ASD of a detector(s)
|
|
267
|
+
and total masses to use for mismatch calculations with those ASDs, e.g.,
|
|
268
|
+
{
|
|
269
|
+
'CE': [CE_ASD, total_masses]
|
|
270
|
+
}
|
|
245
271
|
Default is no frequency-domain mismatch is calculated.
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
272
|
+
path_to_analysis_cache : str, optional
|
|
273
|
+
Path to directory to cache indvidual simulation analyses.
|
|
274
|
+
If None, no caching is performed.
|
|
275
|
+
Default is no cashing is performed.
|
|
249
276
|
nprocs : int, optional
|
|
250
277
|
Number of cpus to use. Default is maximum number. If -1 is provided,
|
|
251
278
|
then no multiprocessing is performed.
|
|
@@ -254,14 +281,14 @@ def analyze_simulations(
|
|
|
254
281
|
-------
|
|
255
282
|
errors : dict
|
|
256
283
|
Dictionary of the errors described above.
|
|
257
|
-
"""
|
|
284
|
+
"""
|
|
258
285
|
errors = {}
|
|
259
286
|
if nprocs != -1:
|
|
260
287
|
with multiprocessing.Pool(processes=nprocs) as pool:
|
|
261
288
|
results = pool.starmap(
|
|
262
289
|
analyze_simulation,
|
|
263
290
|
[
|
|
264
|
-
(sim_name, analyze_levs, analyze_extrapolation, analyze_psi4,
|
|
291
|
+
(sim_name, analyze_levs, analyze_extrapolation, analyze_psi4, ASDs_and_total_masses, path_to_analysis_cache, -1)
|
|
265
292
|
for sim_name in sim_names
|
|
266
293
|
],
|
|
267
294
|
)
|
|
@@ -270,7 +297,7 @@ def analyze_simulations(
|
|
|
270
297
|
else:
|
|
271
298
|
for sim_name in sim_names:
|
|
272
299
|
errors[sim_name] = analyze_simulation(
|
|
273
|
-
sim_name, analyze_levs, analyze_extrapolation, analyze_psi4,
|
|
300
|
+
sim_name, analyze_levs, analyze_extrapolation, analyze_psi4, ASDs_and_total_masses, path_to_analysis_cache, -1
|
|
274
301
|
)
|
|
275
302
|
|
|
276
303
|
return errors
|
sxs/simulations/simulation.py
CHANGED
|
@@ -233,7 +233,7 @@ def Simulation(location, *args, **kwargs):
|
|
|
233
233
|
)
|
|
234
234
|
warn(message)
|
|
235
235
|
new_location = f"{superseding}{input_version}"
|
|
236
|
-
if input_lev_number:
|
|
236
|
+
if input_lev_number is not None:
|
|
237
237
|
new_location += f"/Lev{input_lev_number}"
|
|
238
238
|
return Simulation(new_location, *args, **kwargs)
|
|
239
239
|
|
|
@@ -250,7 +250,7 @@ def Simulation(location, *args, **kwargs):
|
|
|
250
250
|
# If Lev is given as part of `location`, use it; otherwise, use the highest available
|
|
251
251
|
lev_numbers = metadata.get(
|
|
252
252
|
"lev_numbers",
|
|
253
|
-
sorted({lev_num for f in metadata.get("files", []) if (lev_num:=lev_number(f))})
|
|
253
|
+
sorted({lev_num for f in metadata.get("files", []) if (lev_num:=lev_number(f)) is not None})
|
|
254
254
|
)
|
|
255
255
|
if not lev_numbers:
|
|
256
256
|
raise ValueError(f"Could not find Levs for {location}")
|
|
@@ -259,7 +259,10 @@ def Simulation(location, *args, **kwargs):
|
|
|
259
259
|
f"Lev number '{input_lev_number}' not found in simulation files for {sxs_id}"
|
|
260
260
|
)
|
|
261
261
|
max_lev_number = max(lev_numbers)
|
|
262
|
-
|
|
262
|
+
if input_lev_number is not None:
|
|
263
|
+
output_lev_number = input_lev_number
|
|
264
|
+
else:
|
|
265
|
+
output_lev_number = max_lev_number
|
|
263
266
|
if output_lev_number is None:
|
|
264
267
|
raise ValueError(
|
|
265
268
|
f"No Lev number found for {location}"
|
|
@@ -270,7 +273,7 @@ def Simulation(location, *args, **kwargs):
|
|
|
270
273
|
# or a less-than-maximal Lev
|
|
271
274
|
if (
|
|
272
275
|
version_is_not_default
|
|
273
|
-
or
|
|
276
|
+
or output_lev_number != max_lev_number
|
|
274
277
|
):
|
|
275
278
|
metadata = None
|
|
276
279
|
|
sxs/waveforms/alignment.py
CHANGED
|
@@ -838,7 +838,10 @@ def align_simulations(
|
|
|
838
838
|
|
|
839
839
|
if t1 is None:
|
|
840
840
|
# Default to reference time
|
|
841
|
-
t1 =
|
|
841
|
+
t1 = max(
|
|
842
|
+
sima.metadata.reference_time,
|
|
843
|
+
simb.metadata.reference_time
|
|
844
|
+
)
|
|
842
845
|
|
|
843
846
|
wa_prime, transformation, L2_norm, t1, t2 = align_waveforms(
|
|
844
847
|
sima.h,
|
sxs/waveforms/memory.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sxs
|
|
3
|
-
Version: 2025.0.
|
|
3
|
+
Version: 2025.0.9
|
|
4
4
|
Summary: Interface to data produced by the Simulating eXtreme Spacetimes collaboration
|
|
5
5
|
Project-URL: Homepage, https://github.com/sxs-collaboration/sxs
|
|
6
6
|
Project-URL: Documentation, https://sxs.readthedocs.io/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
sxs/__init__.py,sha256=8PntABL6yx7Ad70hP7WedNAVDTZiwm_2At5xIQGo4k8,2610
|
|
2
|
-
sxs/__version__.py,sha256=
|
|
2
|
+
sxs/__version__.py,sha256=bJ1sZ9oROn9G9ZDBWzG6wiJYNXAEycXq6KeuuangpJc,25
|
|
3
3
|
sxs/handlers.py,sha256=jVV-HK-omzoBx5N2wcpLHvyoWq86hUfWCjnGbPpD91I,18343
|
|
4
4
|
sxs/juliapkg.json,sha256=-baaa3Za_KBmmiGjlh2YYLWmvUvZl6GaKKXwNI4S7qU,178
|
|
5
5
|
sxs/time_series.py,sha256=OKaLg8tFyrtKcef7900ri-a0C6A8wKxA68KovZXvH6I,41081
|
|
@@ -16,9 +16,9 @@ sxs/metadata/__init__.py,sha256=vEb633hoKAnI9O7kBtejZXFFsWM6h_ShuTq2_Xl3hUs,72
|
|
|
16
16
|
sxs/metadata/metadata.py,sha256=8LBDWeUAtLOP-MTqbwf_m5eb6k8UKj0L_yKthidF7lA,98
|
|
17
17
|
sxs/metadata/metric.py,sha256=Tsig1Jm50OO8r89zfjCuQ4i3JAoiazSb4J9qYtPWKgM,41
|
|
18
18
|
sxs/simulations/__init__.py,sha256=eXkheYhRaYyKjul5J1IXpoJ7Wq4nr3Tgwr-HSS3BTek,156
|
|
19
|
-
sxs/simulations/analyze.py,sha256=
|
|
19
|
+
sxs/simulations/analyze.py,sha256=YwX0i_GRATRpvp7T8VheShkclvqYsraGDDKEkJQxJnw,11530
|
|
20
20
|
sxs/simulations/local.py,sha256=e77SeaWMl2PWX_EndQtShOXZxcFKhQsUDQ55R2Njcuc,43
|
|
21
|
-
sxs/simulations/simulation.py,sha256=
|
|
21
|
+
sxs/simulations/simulation.py,sha256=8PJOyvC901XYzY1adPqrP-zpfVHYm8AsuHWx-FoREWo,42435
|
|
22
22
|
sxs/simulations/simulations.py,sha256=sMle89VoD1CQni1N23Vjo3h2yj9LHHAtuaB_qfD3Wgg,109
|
|
23
23
|
sxs/utilities/__init__.py,sha256=WSStlqljfgQheMxHGfuofSc5LdmASGvO3FNO3f_zaT0,4806
|
|
24
24
|
sxs/utilities/bitwise.py,sha256=G9ZNYgwDQRhq5wbDf-p2HcUqkEP_IRDiQoXW4KyU17k,13205
|
|
@@ -56,8 +56,8 @@ sxs/utilities/references/inspire.py,sha256=kDjY-UFJT-VTS3yJOT8fT6LJG-pRrX9TK8nv3
|
|
|
56
56
|
sxs/utilities/references/journal_abbreviations.py,sha256=SuRXcr4rv9YPbXD4mzujSvE7M6KS1lwELimuyn7mfCE,31018
|
|
57
57
|
sxs/utilities/references/references.py,sha256=29rPUZKw3dztXQLRDEt1hGYjZaONFd0qX--xQxzOmUU,418
|
|
58
58
|
sxs/waveforms/__init__.py,sha256=yfPzExhZZqNrPOe784f8BC8mHUiwb85urKM_4_pzUFo,1157
|
|
59
|
-
sxs/waveforms/alignment.py,sha256=
|
|
60
|
-
sxs/waveforms/memory.py,sha256=
|
|
59
|
+
sxs/waveforms/alignment.py,sha256=vFa58ZgdMTFam-LFQ47xo0iBjfiiFaGIaN1kE5kpjSk,32718
|
|
60
|
+
sxs/waveforms/memory.py,sha256=UR2NLMyS0TLJ-2ntdKdzQ00Ot4OvBDrlX6lhFM_uPtI,7300
|
|
61
61
|
sxs/waveforms/mode_utilities.py,sha256=gxsW-hunCoIReBVv9IrkGLdshr0rmztbH-JRgD6D9z0,5253
|
|
62
62
|
sxs/waveforms/norms.py,sha256=zemgJsWNhng3QAi3ixHAZ8P5SSIUcHysSQIcqRGDeyI,8944
|
|
63
63
|
sxs/waveforms/transformations.py,sha256=S5C-xnCk2umZlVsYgciyp7VMGZA8NI6md7OZp72upJU,9124
|
|
@@ -82,7 +82,7 @@ sxs/zenodo/api/__init__.py,sha256=EM_eh4Q8R5E0vIfMhyIR1IYFfOBu6vA0UTasgX9gHys,21
|
|
|
82
82
|
sxs/zenodo/api/deposit.py,sha256=J4RGvGjh0cEOrN4bBZWEDcPAhNscqB2fzLlvRZ5HTHM,36948
|
|
83
83
|
sxs/zenodo/api/login.py,sha256=Yz0ytgi81_5BpDzhrS0WPMXlvU2qUaCK8yn8zxfEbko,18007
|
|
84
84
|
sxs/zenodo/api/records.py,sha256=nKkhoHZ95CTztHF9Zzaug5p7IiUCJG4Em1i-l-WqH6U,3689
|
|
85
|
-
sxs-2025.0.
|
|
86
|
-
sxs-2025.0.
|
|
87
|
-
sxs-2025.0.
|
|
88
|
-
sxs-2025.0.
|
|
85
|
+
sxs-2025.0.9.dist-info/METADATA,sha256=6x201xfU_VJBuOrRmF6zYuzpJHrh5iWn_hb5s_lPqAY,9311
|
|
86
|
+
sxs-2025.0.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
87
|
+
sxs-2025.0.9.dist-info/licenses/LICENSE,sha256=ptVOd5m7LDM5ZF0x32cxb8c2Nd5NDmAhy6DX7xt_7VA,1080
|
|
88
|
+
sxs-2025.0.9.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|