sxs 2025.0.6__py3-none-any.whl → 2025.0.8__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 CHANGED
@@ -1 +1 @@
1
- __version__ = "2025.0.6"
1
+ __version__ = "2025.0.8"
@@ -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, ASDs=None, total_masses=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
- ASDs : dict of funcs, optional
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 ASDs is not None:
69
- if total_masses is None:
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 {ASD} {total_mass}"] = mismatch(
86
- wa_tilde_total_mass, wb_tilde_total_mass, f1 * frequency_factor, modes=modes, ASD=ASDs[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
- ASDs=None,
108
- total_masses=None,
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
- ASDs : dict of funcs, optional
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, lev in enumerate(sim.lev_numbers[1:][::-1]):
159
- sim_low_lev = load(f"{sim_name}/Lev{lev - 1}")
160
- sim_high_lev = load(f"{sim_name}/Lev{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{lev - 1}, Lev{lev}) 4d"] = compute_error_summary(w_low_lev_prime, w_high_lev, t1, t2)
168
- errors[f"(Lev{lev - 1}, Lev{lev}) 4d transformation"] = transformation
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{lev - 1}, Lev{lev})"] = L2_difference(w_high_lev, w_low_lev_prime, t1, t2)
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
- ASDs=None,
214
- total_masses=None,
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
- ASDs : dict of funcs, optional
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
- total_masses : list of floats, optional
247
- Total masses in solar masses to use for frequency-domain mismatches.
248
- Default is 1.
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, ASDs, total_masses, -1)
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, ASDs, total_masses, -1
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
@@ -7,6 +7,32 @@ from ..utilities import (
7
7
  )
8
8
 
9
9
 
10
+ def search_prefixes(file, lev, files, ending=""):
11
+ """Find the actual filename present in the list of files
12
+
13
+ Different versions of Zenodo and CaltechDATA place different
14
+ restrictions on filenames — and specifically, things I would
15
+ consider to be directories. If there are multiple Levs for a
16
+ simulation, we have to somehow specify the Lev in the filename.
17
+ The permitted strings for doing so have changed over the years, so
18
+ the directory separator was allowed to be a "/" for old systems,
19
+ but must be something else now; we settled on ":". However, if
20
+ there is just one Lev in a simulation, and we try to save the
21
+ files in a consistent way — including the Lev with the appropriate
22
+ separator, different versions of Zenodo and CaltechDATA will
23
+ either allow or silently remove that prefix. The simplest
24
+ approach is to just search over all possibilities, for which
25
+ filename is actually present in the data. That's what this
26
+ function does.
27
+
28
+ """
29
+ for prefix in [f"{lev}:", f"{lev}/", ""]:
30
+ fn = f"{prefix}{file}"
31
+ if f"{fn}{ending}" in files:
32
+ return fn
33
+ raise ValueError(f"{file}{ending} not found in any form in files")
34
+
35
+
10
36
  def Simulation(location, *args, **kwargs):
11
37
  """Construct a Simulation object from a location string
12
38
 
@@ -113,8 +139,8 @@ def Simulation(location, *args, **kwargs):
113
139
  # Extract the simulation ID, version, and Lev from the location string
114
140
  simulation_id, input_version = sxs_id_and_version(location)
115
141
  if not simulation_id:
116
- if location.split("/Lev")[0] in simulations:
117
- simulation_id = location.split("/Lev")[0]
142
+ if (sim_id := location.split("/Lev")[0]) in simulations:
143
+ simulation_id = sim_id
118
144
  input_version = latest_version
119
145
  else:
120
146
  raise ValueError(f"Invalid SXS ID in '{simulation_id}'")
@@ -129,7 +155,11 @@ def Simulation(location, *args, **kwargs):
129
155
  series = simulations.dataframe.loc[simulation_id]
130
156
 
131
157
  # If input_version is not the default, remove "files" from metadata
132
- if input_version and input_version != max(metadata.get("DOI_versions", []), default=""):
158
+ version_is_not_default = (
159
+ input_version
160
+ and input_version != max(metadata.get("DOI_versions", []), default="")
161
+ )
162
+ if version_is_not_default:
133
163
  metadata = type(metadata)({
134
164
  key: value for key, value in metadata.items() if key != "files"
135
165
  })
@@ -211,26 +241,35 @@ def Simulation(location, *args, **kwargs):
211
241
  kwargs["deprecated"] = deprecated
212
242
 
213
243
  # We want to do this *after* deprecation checking, to avoid possibly unnecessary web requests
214
- if 1 <= float(version[1:]) < 3.0 and "files" in metadata:
215
- # The simulation metadata is points to files with a different version
216
- del metadata["files"]
244
+ if version_is_not_default:
245
+ # The default metadata points to files with a different version, so delete this info
246
+ if "files" in metadata:
247
+ del metadata["files"]
217
248
  files = get_file_info(metadata, sxs_id, download=kwargs.get("download_file_info", None))
218
249
 
219
250
  # If Lev is given as part of `location`, use it; otherwise, use the highest available
220
- lev_numbers = sorted({lev for f in files if (lev:=lev_number(f))})
221
- if input_lev_number is not None and lev_numbers:
222
- if input_lev_number not in lev_numbers:
223
- raise ValueError(
224
- f"Lev number '{input_lev_number}' not found in simulation files for {sxs_id}"
225
- )
226
- max_lev_number = max(lev_numbers, default=np.nan)
251
+ lev_numbers = metadata.get(
252
+ "lev_numbers",
253
+ sorted({lev_num for f in metadata.get("files", []) if (lev_num:=lev_number(f))})
254
+ )
255
+ if not lev_numbers:
256
+ raise ValueError(f"Could not find Levs for {location}")
257
+ if input_lev_number is not None and input_lev_number not in lev_numbers:
258
+ raise ValueError(
259
+ f"Lev number '{input_lev_number}' not found in simulation files for {sxs_id}"
260
+ )
261
+ max_lev_number = max(lev_numbers)
227
262
  output_lev_number = input_lev_number or max_lev_number
263
+ if output_lev_number is None:
264
+ raise ValueError(
265
+ f"No Lev number found for {location}"
266
+ )
228
267
  location = f"{sxs_id_stem}{version}/Lev{output_lev_number}"
229
268
 
230
269
  # Keep the metadata around unless we're asking for an old version
231
270
  # or a less-than-maximal Lev
232
271
  if (
233
- version != latest_version
272
+ version_is_not_default
234
273
  or (lev_numbers and output_lev_number != max_lev_number)
235
274
  ):
236
275
  metadata = None
@@ -462,9 +501,9 @@ class SimulationBase:
462
501
  def metadata_path(self):
463
502
  for separator in [":", "/"]:
464
503
  for ending in [".json", ".txt"]:
465
- prefix = f"{self.lev}{separator}" if self.lev else ""
466
- if (fn := f"{prefix}metadata{ending}") in self.files:
467
- return fn
504
+ for prefix in ["", f"{self.lev}{separator}" if self.lev else ""]:
505
+ if (fn := f"{prefix}metadata{ending}") in self.files:
506
+ return fn
468
507
  raise ValueError(
469
508
  f"Metadata file not found in simulation files for {self.location}"
470
509
  )
@@ -758,50 +797,29 @@ class Simulation_v1(SimulationBase):
758
797
 
759
798
  @property
760
799
  def horizons_path(self):
761
- prefix = f"{self.lev}/" if self.lev else ""
762
- return f"{prefix}Horizons.h5"
763
-
764
- def load_horizons(self):
765
- from .. import load
766
- sxs_id_path = Path(self.sxs_id)
767
- horizons_path = self.horizons_path
768
- if horizons_path in self.files:
769
- horizons_location = self.files.get(horizons_path)["link"]
770
- else:
771
- # Some simulations used the SXS ID as a prefix in file paths
772
- # within the Zenodo upload in version 1.x of the catalog.
773
- if (extended_horizons_path := f"{self.sxs_id_stem}/{horizons_path}") in self.files:
774
- horizons_location = self.files.get(extended_horizons_path)["link"]
775
- else:
776
- raise ValueError(
777
- f"File '{horizons_path}' not found in simulation files for {self.location}"
778
- )
779
- horizons_truepath = Path(sxs_path_to_system_path(sxs_id_path / horizons_path))
780
- return load(horizons_location, truepath=horizons_truepath)
800
+ return search_prefixes("Horizons.h5", self.lev, self.files)
781
801
 
782
802
  @property
783
803
  def strain_path(self):
784
- prefix = f"{self.lev}/" if self.lev else ""
785
804
  extrapolation = (
786
805
  f"Extrapolated_{self.extrapolation}.dir"
787
806
  if self.extrapolation != "Outer"
788
807
  else "OutermostExtraction.dir"
789
808
  )
790
809
  return (
791
- f"{prefix}rhOverM_Asymptotic_GeometricUnits_CoM.h5",
810
+ search_prefixes("rhOverM_Asymptotic_GeometricUnits_CoM.h5", self.lev, self.files),
792
811
  extrapolation
793
812
  )
794
813
 
795
814
  @property
796
815
  def psi4_path(self):
797
- prefix = f"{self.lev}/" if self.lev else ""
798
816
  extrapolation = (
799
817
  f"Extrapolated_{self.extrapolation}.dir"
800
818
  if self.extrapolation != "Outer"
801
819
  else "OutermostExtraction.dir"
802
820
  )
803
821
  return (
804
- f"{prefix}rMPsi4_Asymptotic_GeometricUnits_CoM.h5",
822
+ search_prefixes("rMPsi4_Asymptotic_GeometricUnits_CoM.h5", self.lev, self.files),
805
823
  extrapolation
806
824
  )
807
825
 
@@ -848,14 +866,12 @@ class Simulation_v2(SimulationBase):
848
866
 
849
867
  @property
850
868
  def horizons_path(self):
851
- prefix = f"{self.lev}:" if self.lev else ""
852
- return f"{prefix}Horizons.h5"
869
+ return search_prefixes("Horizons.h5", self.lev, self.files)
853
870
 
854
871
  @property
855
872
  def strain_path(self):
856
- prefix = f"{self.lev}:" if self.lev else ""
857
873
  return (
858
- f"{prefix}Strain_{self.extrapolation}",
874
+ search_prefixes(f"Strain_{self.extrapolation}", self.lev, self.files, ".h5"),
859
875
  "/"
860
876
  )
861
877
 
@@ -866,9 +882,9 @@ class Simulation_v2(SimulationBase):
866
882
  if self.extrapolation != "Outer"
867
883
  else "OutermostExtraction.dir"
868
884
  )
869
- prefix = f"{self.lev}:" if self.lev else ""
885
+ prefix = f"{self.lev}:" if len(self.lev_numbers)>1 else ""
870
886
  return (
871
- f"{prefix}ExtraWaveforms",
887
+ search_prefixes(f"ExtraWaveforms", self.lev, self.files, ".h5"),
872
888
  f"/rMPsi4_Asymptotic_GeometricUnits_CoM_Mem/{extrapolation}"
873
889
  )
874
890
 
@@ -905,20 +921,18 @@ class Simulation_v3(Simulation_v2):
905
921
 
906
922
  @property
907
923
  def strain_path(self):
908
- prefix = f"{self.lev}:" if self.lev else ""
909
924
  return (
910
- f"{prefix}Strain_{self.extrapolation}",
925
+ search_prefixes(f"Strain_{self.extrapolation}", self.lev, self.files, ".h5"),
911
926
  "/"
912
927
  ) if self.extrapolation == self.default_extrapolation else (
913
- f"{prefix}ExtraWaveforms",
928
+ search_prefixes("ExtraWaveforms", self.lev, self.files, ".h5"),
914
929
  f"/Strain_{self.extrapolation}.dir"
915
930
  )
916
931
 
917
932
  @property
918
933
  def psi4_path(self):
919
- prefix = f"{self.lev}:" if self.lev else ""
920
934
  return (
921
- f"{prefix}ExtraWaveforms",
935
+ search_prefixes("ExtraWaveforms", self.lev, self.files, ".h5"),
922
936
  f"/Psi4_{self.extrapolation}.dir"
923
937
  )
924
938
 
@@ -838,7 +838,10 @@ def align_simulations(
838
838
 
839
839
  if t1 is None:
840
840
  # Default to reference time
841
- t1 = simb.metadata.reference_time
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
@@ -13,6 +13,7 @@ h_with_memory = sxs.waveforms.memory.add_memory(h, integration_start_time=1000.0
13
13
  """
14
14
 
15
15
  import numpy as np
16
+ from . import WaveformModes
16
17
  from . import waveform_mts
17
18
 
18
19
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sxs
3
- Version: 2025.0.6
3
+ Version: 2025.0.8
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/
@@ -47,7 +47,7 @@ Requires-Dist: quaternionic>=1.0.15
47
47
  Requires-Dist: requests>=2.24.0
48
48
  Requires-Dist: scipy>=1.13
49
49
  Requires-Dist: spherical>=1.0.15
50
- Requires-Dist: sxscatalog>=3.0.12
50
+ Requires-Dist: sxscatalog>=3.0.13
51
51
  Requires-Dist: tqdm>=4.63.1
52
52
  Requires-Dist: urllib3>=1.25.10
53
53
  Provides-Extra: docs
@@ -1,5 +1,5 @@
1
1
  sxs/__init__.py,sha256=8PntABL6yx7Ad70hP7WedNAVDTZiwm_2At5xIQGo4k8,2610
2
- sxs/__version__.py,sha256=yvdjudtPjiQebLjJ4Ne10nfyYPrzHlDRMvfyAxij7Mo,25
2
+ sxs/__version__.py,sha256=T6-wsPrw9CRtaYHLEWomkUB0ZeTyias2V5LZbbcYNIs,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=RaImREx3fWlXgJRCI-Wsq0-LjidL-Mb8SIN3-n-TMqM,10373
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=QtGdZDOXgt7C44CqqvdJCCQmEkcXjxPUL-yDrUR13Ps,41741
21
+ sxs/simulations/simulation.py,sha256=tzI1s15mU1CDdst7XZRD4UehtbkRvIao16ONTAA0zfI,42353
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=TYSsGq3dRQwoookyzkNkT02pGViPC0TqQ64RksX4OxU,32649
60
- sxs/waveforms/memory.py,sha256=zuph5JgeBog6xrCbcSYzXegPfUtoPUXnYmmY5KfYUj8,7272
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.6.dist-info/METADATA,sha256=HsKY1bopxuPt9Art9HXqOlYGrIy6l73GU6y5xotFisQ,9311
86
- sxs-2025.0.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
87
- sxs-2025.0.6.dist-info/licenses/LICENSE,sha256=ptVOd5m7LDM5ZF0x32cxb8c2Nd5NDmAhy6DX7xt_7VA,1080
88
- sxs-2025.0.6.dist-info/RECORD,,
85
+ sxs-2025.0.8.dist-info/METADATA,sha256=61LeHMJCrGehO9QH6lA0dTXDkCLE-raLMRjFjKE6hhc,9311
86
+ sxs-2025.0.8.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
87
+ sxs-2025.0.8.dist-info/licenses/LICENSE,sha256=ptVOd5m7LDM5ZF0x32cxb8c2Nd5NDmAhy6DX7xt_7VA,1080
88
+ sxs-2025.0.8.dist-info/RECORD,,
File without changes