sxs 2024.0.41__py3-none-any.whl → 2024.0.43__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__ = "2024.0.41"
1
+ __version__ = "2024.0.43"
sxs/handlers.py CHANGED
@@ -284,7 +284,10 @@ def load(location, download=None, cache=None, progress=None, truepath=None, **kw
284
284
  return Simulations.load(
285
285
  download=download,
286
286
  local=kwargs.get("local", False),
287
- annex_dir=kwargs.get("annex_dir", None)
287
+ annex_dir=kwargs.get("annex_dir", None),
288
+ output_file=kwargs.get("output_file", None),
289
+ compute_md5=kwargs.get("compute_md5", False),
290
+ show_progress=kwargs.get("show_progress", False)
288
291
  )
289
292
 
290
293
  elif location == "dataframe":
sxs/metadata/metric.py CHANGED
@@ -14,6 +14,9 @@ class MetadataMetric:
14
14
  metadata, rather than as a strict metric for clustering or
15
15
  classification.
16
16
 
17
+ Note that calling an object of this class with two metadata
18
+ collections will return the *squared* distance between them.
19
+
17
20
  Parameters
18
21
  ----------
19
22
  parameters : list of str, optional
@@ -60,13 +63,14 @@ class MetadataMetric:
60
63
  def __init__(
61
64
  self,
62
65
  parameters=[
63
- "reference_mass_ratio",
66
+ "reference_mass1",
67
+ "reference_mass2",
64
68
  "reference_dimensionless_spin1",
65
69
  "reference_dimensionless_spin2",
66
70
  "reference_eccentricity",
67
71
  "reference_mean_anomaly",
68
72
  ],
69
- metric=np.diag([1, 1, 1, 1, 1, 1, 1, 1, 1/np.pi**2]),
73
+ metric=np.diag([1, 1, 1, 1, 1, 1, 1, 1, 1, 1/np.pi**2]),
70
74
  allow_different_object_types=False,
71
75
  eccentricity_threshold1=1e-2,
72
76
  eccentricity_threshold2=1e-3,
@@ -113,7 +117,7 @@ class MetadataMetric:
113
117
  values1[i], values2[i] = np.unwrap([floater(values1[i]), floater(values2[i])])
114
118
 
115
119
  if "reference_eccentricity" in self.parameters:
116
- # Either way, we first make sure that the corresponding entries are floats.
120
+ # Either way, we first try to make sure that the corresponding entries are floats.
117
121
  i = self.parameters.index("reference_eccentricity")
118
122
  values1[i] = metadata1.get("reference_eccentricity_bound", floaterbound(values1[i]))
119
123
  values2[i] = metadata2.get("reference_eccentricity_bound", floaterbound(values2[i]))
sxs/simulations/local.py CHANGED
@@ -215,12 +215,13 @@ def write_local_simulations(annex_dir, output_file=None, compute_md5=False, show
215
215
  simulations = local_simulations(annex_dir, compute_md5=compute_md5, show_progress=show_progress)
216
216
 
217
217
  # Write the simulations to file
218
- if output_file is None:
219
- output_file = sxs_directory("cache") / "local_simulations.json"
220
- else:
221
- output_file = Path(output_file)
222
- output_file.parent.mkdir(parents=True, exist_ok=True)
223
- with output_file.open("w") as f:
224
- dump(simulations, f, indent=2, separators=(",", ": "), ensure_ascii=True)
218
+ if output_file is not False: # Test literal identity to allow `None`
219
+ if output_file is None:
220
+ output_file = sxs_directory("cache") / "local_simulations.json"
221
+ else:
222
+ output_file = Path(output_file)
223
+ output_file.parent.mkdir(parents=True, exist_ok=True)
224
+ with output_file.open("w") as f:
225
+ dump(simulations, f, indent=2, separators=(",", ": "), ensure_ascii=True)
225
226
 
226
227
  return simulations
@@ -59,13 +59,14 @@ def Simulation(location, *args, **kwargs):
59
59
  If `True`, completely bypass checking for deprecation or
60
60
  supersession. No warnings or errors will be issued. Default
61
61
  is `False`.
62
- auto_supersede : bool, optional
63
- If `True`, automatically load the superseding simulation, if
64
- there is only one. If there are multiple superseding
65
- simulations, an error will be raised, and you must explicitly
66
- choose one. If there is only one, a warning will still be
67
- issued, but the superseding simulation will be loaded. Note
68
- that this can also be set in the configuration file with
62
+ auto_supersede : bool or float, optional
63
+ If present, automatically load the closest undeprecated
64
+ simulation. If this is a float and the distance to the
65
+ closest undeprecated simulation (see the following argument)
66
+ is larger, a ValueError will be raised. Otherwise, a warning
67
+ will be issued with the ID of the new simulation and the
68
+ distance. Note that this can also be set in the configuration
69
+ file by calling, e.g.,
69
70
  `sxs.write_config(auto_supersede=True)`.
70
71
  metadata_metric : MetadataMetric, optional
71
72
  Metric to use for comparing simulations when automatically
@@ -147,8 +148,9 @@ def Simulation(location, *args, **kwargs):
147
148
  f"Simulation '{location}' is deprecated. You could\n"
148
149
  + " 1. pass `ignore_deprecation=True` to load the latest available version,\n"
149
150
  + " 2. manually choose a different simulation from the catalog,\n"
150
- + " 3. pass `auto_supersede=True` to load the closest match in the catalog, or\n"
151
- + f" 4. include the version number, as in '{sxs_id_stem}v2.0', to load a specific version.\n"
151
+ + " 3. pass `auto_supersede=0.01` to load a match closer than 0.01 in the catalog if one exists,\n"
152
+ + " 4. pass `auto_supersede=True` to load the closest match in the catalog, or\n"
153
+ + f" 5. include the version number, as in '{sxs_id_stem}v2.0', to load a specific version.\n"
152
154
  )
153
155
  else:
154
156
  message = ("\n"
@@ -170,11 +172,25 @@ def Simulation(location, *args, **kwargs):
170
172
  original_kwargs["ignore_deprecation"] = True
171
173
  original = Simulation(location, *args, **original_kwargs)
172
174
  metadata_metric = kwargs.pop("metadata_metric", MetadataMetric())
173
- superseding = original.closest_simulation(
175
+ superseding, distance = original.closest_simulation(
174
176
  dataframe=simulations.dataframe,
175
177
  metadata_metric=metadata_metric
176
178
  )
177
- message = f"\nSimulation '{sxs_id}' is being automatically superseded by '{superseding}'."
179
+ if isinstance(auto_supersede, str):
180
+ try:
181
+ auto_supersede = float(auto_supersede)
182
+ except:
183
+ pass
184
+ if isinstance(auto_supersede, float) and distance > auto_supersede:
185
+ raise ValueError(
186
+ f"Simulation '{sxs_id}' is deprecated, but the closest undeprecated\n"
187
+ f"simulation is more distant than allowed by `auto_supersede` argument:\n"
188
+ f"{distance:.3g} > {auto_supersede:.3g}.\n"
189
+ )
190
+ message = (
191
+ f"\nSimulation '{sxs_id}' is being automatically superseded by '{superseding}'."
192
+ f"\nThe distance between them in the given metadata metric is {distance:.3g}."
193
+ )
178
194
  warn(message)
179
195
  new_location = f"{superseding}{input_version}"
180
196
  if input_lev_number:
@@ -342,6 +358,7 @@ class SimulationBase:
342
358
  metadata
343
359
 
344
360
  """
361
+ from numpy import sqrt
345
362
  from ..metadata.metric import MetadataMetric
346
363
  from .. import load
347
364
  if dataframe is None:
@@ -350,11 +367,11 @@ class SimulationBase:
350
367
  if drop_deprecated:
351
368
  dataframe = dataframe[~dataframe.deprecated]
352
369
  return dataframe.apply(
353
- lambda m: metadata_metric(self.metadata, m),
370
+ lambda m: sqrt(metadata_metric(self.metadata, m)),
354
371
  axis=1
355
372
  )
356
373
 
357
- def closest_simulation(self, dataframe=None, metadata_metric=None):
374
+ def closest_simulation(self, dataframe=None, metadata_metric=None, warning_threshold=1e-2):
358
375
  """Return the closest undeprecated simulation to this one
359
376
 
360
377
  Note that any simulation in `dataframe` with zero distance
@@ -370,12 +387,17 @@ class SimulationBase:
370
387
  metadata_metric : MetadataMetric, optional
371
388
  Metric to use for comparing simulations. If not provided,
372
389
  the default metric will be used.
390
+ warning_threshold : float, optional
391
+ Threshold distance above which a warning will be issued
392
+ that the closest simulation is fairly distant. Default is
393
+ 1e-3.
373
394
 
374
395
  Returns
375
396
  -------
376
397
  closest_index : str
377
398
  Index of the closest undeprecated simulation in the
378
399
  `dataframe`.
400
+ distance : float
379
401
 
380
402
  """
381
403
  d = self.distances(
@@ -384,7 +406,9 @@ class SimulationBase:
384
406
  drop_deprecated=True
385
407
  )
386
408
  d = d[d > 0].sort_values()
387
- return d.index[0]
409
+ if d.iloc[0] > warning_threshold:
410
+ warn(f"\nClosest simulation ({d.index[0]}) is fairly distant: {d.iloc[0]:.3g}")
411
+ return d.index[0], d.iloc[0]
388
412
 
389
413
  @property
390
414
  def dataframe(self):
@@ -173,7 +173,7 @@ class Simulations(collections.OrderedDict):
173
173
  return remote_timestamp
174
174
 
175
175
  @classmethod
176
- def local(cls, directory=None, *, download=None):
176
+ def local(cls, directory=None, *, download=None, output_file=None, compute_md5=False, show_progress=False):
177
177
  """Load the local catalog of SXS simulations
178
178
 
179
179
  This function loads the standard public catalog, but also
@@ -192,30 +192,47 @@ class Simulations(collections.OrderedDict):
192
192
  download : {None, bool}, optional
193
193
  Passed to `Simulations.load` when loading the public set
194
194
  of simulations.
195
+ output_file : {None, str, Path}, optional
196
+ If `directory` is not None, this will be passed to
197
+ `sxs.write_local_simulations`.
198
+ compute_md5 : bool, optional
199
+ If `directory` is not None, this will be passed to
200
+ `sxs.local_simulations`.
201
+ show_progress : bool, optional
202
+ If `directory` is not None, this will be passed to
203
+ `sxs.local_simulations`.
195
204
 
196
205
  See Also
197
206
  --------
198
207
  sxs.local_simulations : Search for local simulations
199
- sxs.write_local_simulations : Write local simulations to a file
208
+ sxs.write_local_simulations : Write local simulations to a
209
+ file
200
210
 
201
211
  """
202
212
  import json
203
213
  from .local import write_local_simulations
204
214
  from .. import sxs_directory
205
215
 
206
- local_path = sxs_directory("cache") / "local_simulations.json"
207
216
  if directory is not None:
208
- write_local_simulations(directory)
209
- if not local_path.exists():
210
- if directory is not None:
211
- raise ValueError(f"Writing local simulations for {directory=} failed")
212
- else:
213
- raise ValueError(
214
- f"Local simulations file not found, but no `directory` was provided.\n"
215
- + "If called from `sxs.load`, just pass the name of the directory."
216
- )
217
- with local_path.open("r") as f:
218
- local_simulations = json.load(f)
217
+ local_path = output_file
218
+ local_simulations = write_local_simulations(
219
+ directory,
220
+ output_file=output_file,
221
+ compute_md5=compute_md5,
222
+ show_progress=show_progress
223
+ )
224
+ else:
225
+ local_path = sxs_directory("cache") / "local_simulations.json"
226
+ if not local_path.exists():
227
+ if directory is not None:
228
+ raise ValueError(f"Writing local simulations for {directory=} failed")
229
+ else:
230
+ raise ValueError(
231
+ f"Local simulations file not found, but no `directory` was provided.\n"
232
+ + "If called from `sxs.load`, just pass the name of the directory."
233
+ )
234
+ with local_path.open("r") as f:
235
+ local_simulations = json.load(f)
219
236
  simulations = cls.load(download)
220
237
  doi_versions = {
221
238
  k: v["DOI_versions"]
@@ -229,7 +246,7 @@ class Simulations(collections.OrderedDict):
229
246
  return simulations
230
247
 
231
248
  @classmethod
232
- def load(cls, download=None, *, local=False, annex_dir=None):
249
+ def load(cls, download=None, *, local=False, annex_dir=None, output_file=None, compute_md5=False, show_progress=False):
233
250
  """Load the catalog of SXS simulations
234
251
 
235
252
  Note that — unlike most SXS data files — the simulations file
@@ -263,6 +280,15 @@ class Simulations(collections.OrderedDict):
263
280
  If provided and `local=True`, this function will load
264
281
  local simulations from the given directory. This is
265
282
  equivalent to calling `Simulations.local(directory)`.
283
+ output_file : {None, str, Path}, optional
284
+ If `annex_dir` is not None, this will be passed to
285
+ `sxs.write_local_simulations`.
286
+ compute_md5 : bool, optional
287
+ If `annex_dir` is not None, this will be passed to
288
+ `sxs.simulations.local_simulations`.
289
+ show_progress : bool, optional
290
+ If `annex_dir` is not None, this will be passed to
291
+ `sxs.simulations.local_simulations`.
266
292
 
267
293
  See Also
268
294
  --------
@@ -280,7 +306,13 @@ class Simulations(collections.OrderedDict):
280
306
  return cls._simulations
281
307
 
282
308
  if local or annex_dir is not None:
283
- cls._simulations = cls.local(annex_dir, download=download)
309
+ cls._simulations = cls.local(
310
+ annex_dir,
311
+ download=download,
312
+ output_file=output_file,
313
+ compute_md5=compute_md5,
314
+ show_progress=show_progress
315
+ )
284
316
  return cls._simulations
285
317
 
286
318
  progress = read_config("download_progress", True)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sxs
3
- Version: 2024.0.41
3
+ Version: 2024.0.43
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,6 +1,6 @@
1
1
  sxs/__init__.py,sha256=hbydsXWR88sFiKExPJ1NHWGEvWRbbJBjSc1irSMYKgY,2623
2
- sxs/__version__.py,sha256=o95yq2nvQ6FsIUfCHrH8nIWlGM_edEB29js8ZcW9LWw,26
3
- sxs/handlers.py,sha256=Nc1_aDKm_wDHg2cITI_ljbqU4VRWpwQ7fdgy3c1XcE8,17531
2
+ sxs/__version__.py,sha256=2f1GnLIs4eYPdnrJrRDZeA5ovQX_2cfkuPAyFII9GGE,26
3
+ sxs/handlers.py,sha256=o7ihff0glg1DEP95reBZ75lH2h2mP-sZkwUL1_eoMwU,17720
4
4
  sxs/juliapkg.json,sha256=-baaa3Za_KBmmiGjlh2YYLWmvUvZl6GaKKXwNI4S7qU,178
5
5
  sxs/time_series.py,sha256=OKaLg8tFyrtKcef7900ri-a0C6A8wKxA68KovZXvH6I,41081
6
6
  sxs/caltechdata/__init__.py,sha256=pvyc2Djch4DA6t06op-0NSTegrMSywzNi7Z3W_91-Cg,14670
@@ -17,11 +17,11 @@ sxs/julia/GWFrames.py,sha256=47H9Ugff7ldGBujiUTcADT3b4MSxUtqmajvSApI91WA,2892
17
17
  sxs/julia/__init__.py,sha256=uSLP_xfU-GZG7IO5vs0TEkCR4LH8aBYMF-852wDY3kI,3490
18
18
  sxs/metadata/__init__.py,sha256=jz0A3sBYQoNVZ5sdHv6LgI6y4kP2051-esCR62xt6bM,184
19
19
  sxs/metadata/metadata.py,sha256=vqzNufg46BrbFAuvDF55JvrQc0ZIBxSG4eH2awv5PDs,28610
20
- sxs/metadata/metric.py,sha256=zWyM23SQUMXwpDvQNnp2USJrwxiC3SoobFXm0h_sMMs,6615
20
+ sxs/metadata/metric.py,sha256=W_PMNmsJ2qBjIeAll4TgUz79-SZkiBTswTfK4gKWrPU,6785
21
21
  sxs/simulations/__init__.py,sha256=GrZym0PHTULDg_hyFmISNzDfqVLz_hQo-djbgecZs54,134
22
- sxs/simulations/local.py,sha256=kyFvlw9CywlyBy0H2GiSgOp4M7Uq31Db5LIdd2do43M,8242
23
- sxs/simulations/simulation.py,sha256=HRm6vaVGjRziQZ1VPOG1ESxaITgLAJCp4lhGZ4fpez8,36232
24
- sxs/simulations/simulations.py,sha256=xP1ljseDSkfs6_u25-DnSNlFQtQexiP25Kwtm7nWdsE,23910
22
+ sxs/simulations/local.py,sha256=nfca2cG3LWNC8Jc-i79BZmKdwPfhPgPKja-wXg_qEKw,8344
23
+ sxs/simulations/simulation.py,sha256=lVA2aSRy4-V1-1bFE74zIN8Tpvf7QDtn9n7xmR7oqcU,37579
24
+ sxs/simulations/simulations.py,sha256=5OYQez3BXtg8zbCe85MlSqYtAKv4UqXt7iRfLiPAWxw,25367
25
25
  sxs/utilities/__init__.py,sha256=WSStlqljfgQheMxHGfuofSc5LdmASGvO3FNO3f_zaT0,4806
26
26
  sxs/utilities/bitwise.py,sha256=G9ZNYgwDQRhq5wbDf-p2HcUqkEP_IRDiQoXW4KyU17k,13205
27
27
  sxs/utilities/dicts.py,sha256=CCpm3upG_9SRj9gjawukSUfaJ5asF-XRG2ausEXhYyg,695
@@ -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-2024.0.41.dist-info/METADATA,sha256=IUvgoHcgUjDEQ3GRq__ZTr7Dn5n9kYi8EFtr-tOpRKM,9253
86
- sxs-2024.0.41.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
87
- sxs-2024.0.41.dist-info/licenses/LICENSE,sha256=ptVOd5m7LDM5ZF0x32cxb8c2Nd5NDmAhy6DX7xt_7VA,1080
88
- sxs-2024.0.41.dist-info/RECORD,,
85
+ sxs-2024.0.43.dist-info/METADATA,sha256=5rmhF6Twj0ZjJtLFM6_zmtlccn4mJ0dDK78wh5CJaNM,9253
86
+ sxs-2024.0.43.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
87
+ sxs-2024.0.43.dist-info/licenses/LICENSE,sha256=ptVOd5m7LDM5ZF0x32cxb8c2Nd5NDmAhy6DX7xt_7VA,1080
88
+ sxs-2024.0.43.dist-info/RECORD,,