sxs 2024.0.21__tar.gz → 2024.0.23__tar.gz

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.
Files changed (130) hide show
  1. {sxs-2024.0.21 → sxs-2024.0.23}/.github/workflows/build.yml +1 -1
  2. {sxs-2024.0.21 → sxs-2024.0.23}/CITATION.cff +2 -2
  3. {sxs-2024.0.21 → sxs-2024.0.23}/PKG-INFO +1 -2
  4. sxs-2024.0.23/sxs/__version__.py +1 -0
  5. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/simulations/simulation.py +4 -3
  6. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/simulations/simulations.py +9 -5
  7. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/waveforms/__init__.py +1 -0
  8. sxs-2024.0.23/sxs/waveforms/format_handlers/grathena.py +89 -0
  9. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/waveforms/format_handlers/lvc.py +1 -0
  10. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/waveforms/format_handlers/nrar.py +41 -28
  11. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/waveforms/waveform_modes.py +4 -0
  12. {sxs-2024.0.21 → sxs-2024.0.23}/tests/test_waveform_rotations.py +1 -0
  13. sxs-2024.0.21/sxs/__version__.py +0 -1
  14. {sxs-2024.0.21 → sxs-2024.0.23}/.codecov.yml +0 -0
  15. {sxs-2024.0.21 → sxs-2024.0.23}/.github/dependabot.yml +0 -0
  16. {sxs-2024.0.21 → sxs-2024.0.23}/.github/scripts/parse_bump_rule.py +0 -0
  17. {sxs-2024.0.21 → sxs-2024.0.23}/.github/workflows/pr_rtd_link.yml +0 -0
  18. {sxs-2024.0.21 → sxs-2024.0.23}/.gitignore +0 -0
  19. {sxs-2024.0.21 → sxs-2024.0.23}/.readthedocs.yaml +0 -0
  20. {sxs-2024.0.21 → sxs-2024.0.23}/LICENSE +0 -0
  21. {sxs-2024.0.21 → sxs-2024.0.23}/README.md +0 -0
  22. {sxs-2024.0.21 → sxs-2024.0.23}/docs/api/catalog.md +0 -0
  23. {sxs-2024.0.21 → sxs-2024.0.23}/docs/api/horizons.md +0 -0
  24. {sxs-2024.0.21 → sxs-2024.0.23}/docs/api/load.md +0 -0
  25. {sxs-2024.0.21 → sxs-2024.0.23}/docs/api/metadata.md +0 -0
  26. {sxs-2024.0.21 → sxs-2024.0.23}/docs/api/simulation.md +0 -0
  27. {sxs-2024.0.21 → sxs-2024.0.23}/docs/api/simulations.md +0 -0
  28. {sxs-2024.0.21 → sxs-2024.0.23}/docs/api/time_series.md +0 -0
  29. {sxs-2024.0.21 → sxs-2024.0.23}/docs/api/waveforms.md +0 -0
  30. {sxs-2024.0.21 → sxs-2024.0.23}/docs/html/main.html +0 -0
  31. {sxs-2024.0.21 → sxs-2024.0.23}/docs/images/favicon.ico +0 -0
  32. {sxs-2024.0.21 → sxs-2024.0.23}/docs/index.md +0 -0
  33. {sxs-2024.0.21 → sxs-2024.0.23}/docs/javascript/mathjax.js +0 -0
  34. {sxs-2024.0.21 → sxs-2024.0.23}/docs/julia.md +0 -0
  35. {sxs-2024.0.21 → sxs-2024.0.23}/docs/mathematica.md +0 -0
  36. {sxs-2024.0.21 → sxs-2024.0.23}/docs/stylesheets/extra.css +0 -0
  37. {sxs-2024.0.21 → sxs-2024.0.23}/docs/tutorials/00-Introduction.ipynb +0 -0
  38. {sxs-2024.0.21 → sxs-2024.0.23}/docs/tutorials/01-Simulations_and_Metadata.ipynb +0 -0
  39. {sxs-2024.0.21 → sxs-2024.0.23}/docs/tutorials/02-Simulation.ipynb +0 -0
  40. {sxs-2024.0.21 → sxs-2024.0.23}/docs/tutorials/03-Horizons.ipynb +0 -0
  41. {sxs-2024.0.21 → sxs-2024.0.23}/docs/tutorials/04-Waveforms.ipynb +0 -0
  42. {sxs-2024.0.21 → sxs-2024.0.23}/docs/tutorials/05-PreprocessingForFFTs.ipynb +0 -0
  43. {sxs-2024.0.21 → sxs-2024.0.23}/mkdocs.yml +0 -0
  44. {sxs-2024.0.21 → sxs-2024.0.23}/pyproject.toml +0 -0
  45. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/__init__.py +0 -0
  46. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/caltechdata/__init__.py +0 -0
  47. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/caltechdata/catalog.py +0 -0
  48. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/caltechdata/login.py +0 -0
  49. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/catalog/__init__.py +0 -0
  50. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/catalog/catalog.py +0 -0
  51. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/catalog/create.py +0 -0
  52. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/catalog/description.py +0 -0
  53. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/handlers.py +0 -0
  54. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/horizons/__init__.py +0 -0
  55. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/horizons/spec_horizons_h5.py +0 -0
  56. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/horizons/xor_multishuffle_bzip2.py +0 -0
  57. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/julia/GWFrames.py +0 -0
  58. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/julia/__init__.py +0 -0
  59. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/juliapkg.json +0 -0
  60. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/metadata/__init__.py +0 -0
  61. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/metadata/metadata.py +0 -0
  62. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/simulations/__init__.py +0 -0
  63. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/simulations/local.py +0 -0
  64. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/time_series.py +0 -0
  65. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/__init__.py +0 -0
  66. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/bitwise.py +0 -0
  67. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/decimation/__init__.py +0 -0
  68. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/decimation/greedy_spline.py +0 -0
  69. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/decimation/linear_bisection.py +0 -0
  70. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/decimation/peak_greed.py +0 -0
  71. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/decimation/suppression.py +0 -0
  72. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/dicts.py +0 -0
  73. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/downloads.py +0 -0
  74. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/files.py +0 -0
  75. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/formats.py +0 -0
  76. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/inspire.py +0 -0
  77. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/lvcnr/__init__.py +0 -0
  78. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/lvcnr/comparisons.py +0 -0
  79. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/lvcnr/conversion.py +0 -0
  80. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/lvcnr/dataset.py +0 -0
  81. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/lvcnr/horizons.py +0 -0
  82. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/lvcnr/metadata.py +0 -0
  83. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/lvcnr/waveform_amp_phase.py +0 -0
  84. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/lvcnr/waveforms.py +0 -0
  85. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/monotonicity.py +0 -0
  86. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/pretty_print.py +0 -0
  87. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/references/__init__.py +0 -0
  88. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/references/ads.py +0 -0
  89. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/references/arxiv.py +0 -0
  90. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/references/fairchild_report.py +0 -0
  91. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/references/inspire.py +0 -0
  92. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/references/journal_abbreviations.py +0 -0
  93. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/references/references.py +0 -0
  94. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/select.py +0 -0
  95. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/smooth_functions.py +0 -0
  96. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/sxs_directories.py +0 -0
  97. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/sxs_identifiers.py +0 -0
  98. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/utilities/url.py +0 -0
  99. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/waveforms/alignment.py +0 -0
  100. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/waveforms/format_handlers/__init__.py +0 -0
  101. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/waveforms/format_handlers/rotating_paired_diff_multishuffle_bzip2.py +0 -0
  102. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/waveforms/format_handlers/rotating_paired_xor_multishuffle_bzip2.py +0 -0
  103. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/waveforms/format_handlers/spectre_cce_v1.py +0 -0
  104. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/waveforms/memory.py +0 -0
  105. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/waveforms/mode_utilities.py +0 -0
  106. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/waveforms/transformations.py +0 -0
  107. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/waveforms/waveform_grid.py +0 -0
  108. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/waveforms/waveform_mixin.py +0 -0
  109. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/waveforms/waveform_signal.py +0 -0
  110. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/zenodo/__init__.py +0 -0
  111. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/zenodo/api/__init__.py +0 -0
  112. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/zenodo/api/deposit.py +0 -0
  113. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/zenodo/api/login.py +0 -0
  114. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/zenodo/api/records.py +0 -0
  115. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/zenodo/catalog.py +0 -0
  116. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/zenodo/creators.py +0 -0
  117. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/zenodo/simannex.py +0 -0
  118. {sxs-2024.0.21 → sxs-2024.0.23}/sxs/zenodo/surrogatemodeling.py +0 -0
  119. {sxs-2024.0.21 → sxs-2024.0.23}/tests/__init__.py +0 -0
  120. {sxs-2024.0.21 → sxs-2024.0.23}/tests/conftest.py +0 -0
  121. {sxs-2024.0.21 → sxs-2024.0.23}/tests/test_catalog.py +0 -0
  122. {sxs-2024.0.21 → sxs-2024.0.23}/tests/test_horizons.py +0 -0
  123. {sxs-2024.0.21 → sxs-2024.0.23}/tests/test_julia.py +0 -0
  124. {sxs-2024.0.21 → sxs-2024.0.23}/tests/test_loader.py +0 -0
  125. {sxs-2024.0.21 → sxs-2024.0.23}/tests/test_metadata.py +0 -0
  126. {sxs-2024.0.21 → sxs-2024.0.23}/tests/test_simulation.py +0 -0
  127. {sxs-2024.0.21 → sxs-2024.0.23}/tests/test_time_series.py +0 -0
  128. {sxs-2024.0.21 → sxs-2024.0.23}/tests/test_transformations.py +0 -0
  129. {sxs-2024.0.21 → sxs-2024.0.23}/tests/test_utilities.py +0 -0
  130. {sxs-2024.0.21 → sxs-2024.0.23}/tests/test_waveforms.py +0 -0
@@ -79,7 +79,7 @@ jobs:
79
79
 
80
80
  - name: Upload coverage
81
81
  if: "matrix.python-version == '3.12' && matrix.os == 'ubuntu-latest'"
82
- uses: codecov/codecov-action@v4
82
+ uses: codecov/codecov-action@v5
83
83
  with:
84
84
  token: ${{ secrets.CODECOV_TOKEN }}
85
85
 
@@ -10,5 +10,5 @@ authors:
10
10
  title: "The sxs package"
11
11
  license: MIT
12
12
  doi: 10.5281/zenodo.4034006
13
- version: 2024.0.21
14
- date-released: 2024-10-24
13
+ version: 2024.0.23
14
+ date-released: 2024-11-24
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: sxs
3
- Version: 2024.0.21
3
+ Version: 2024.0.23
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/
@@ -26,7 +26,6 @@ License: The MIT License (MIT)
26
26
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
27
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
28
  SOFTWARE.
29
- License-File: LICENSE
30
29
  Classifier: Development Status :: 5 - Production/Stable
31
30
  Classifier: Intended Audience :: Science/Research
32
31
  Classifier: License :: OSI Approved :: MIT License
@@ -0,0 +1 @@
1
+ __version__ = "2024.0.23"
@@ -593,7 +593,10 @@ class SimulationBase:
593
593
 
594
594
  """
595
595
  from ..waveforms.format_handlers.lvc import to_lvc_conventions
596
- strain = self.load_waveform(*self.strain_path, transform_to_inertial=False)
596
+ strain = self.load_waveform(
597
+ *self.strain_path,
598
+ transform_to_inertial=False,
599
+ )
597
600
  return to_lvc_conventions(strain, self.horizons, **kwargs)
598
601
 
599
602
 
@@ -683,8 +686,6 @@ class Simulation_v1(SimulationBase):
683
686
  transform_to_inertial=transform_to_inertial
684
687
  )
685
688
  w.metadata = self.metadata
686
- if not transform_to_inertial:
687
- w = w.to_corotating_frame()
688
689
  return w
689
690
 
690
691
 
@@ -57,13 +57,17 @@ class SimulationsDataFrame(pd.DataFrame):
57
57
 
58
58
  @property
59
59
  def IMR(self):
60
- """Restrict dataframe to just BBH systems with inspiral, merger, and ringdown
60
+ """Restrict dataframe to just BBH IMR systems
61
61
 
62
+ "IMR" stands for inspiral, merger, and ringdown. Systems that
63
+ will *not* be in this group include simulations that
64
+ correspond to physical IMR systems, but were not continued
65
+ through the merger.
66
+
62
67
  The criteria used here are just that the reference
63
- eccentricity and remnant mass are actual (finite)
64
- numbers. Currently, at least, the existence of a
65
- measured eccentricity means that the system is not
66
- hyperbolic or head-on.
68
+ eccentricity and remnant mass are actual (finite) numbers.
69
+ Currently, at least, the existence of a measured eccentricity
70
+ means that the system is not hyperbolic or head-on.
67
71
  """
68
72
  df = self.BBH
69
73
  return type(df)(df[
@@ -15,6 +15,7 @@ from .format_handlers import (
15
15
  rotating_paired_diff_multishuffle_bzip2,
16
16
  rotating_paired_xor_multishuffle_bzip2,
17
17
  spectre_cce_v1,
18
+ grathena,
18
19
  )
19
20
  from .format_handlers.lvc import to_lvc_conventions
20
21
  from . import memory, transformations, alignment
@@ -0,0 +1,89 @@
1
+ from ... import sxs_directory
2
+ from . import nrar
3
+
4
+ def load(file, **kwargs):
5
+ """Load a waveform from a GR-Athena++ `tar` file.
6
+
7
+ Parameters
8
+ ==========
9
+ file : str
10
+ The path to the `tar` file containing the waveform data.
11
+
12
+ Other Parameters
13
+ ================
14
+ subfile : str
15
+ The name of the subfile within the `tar` file to read.
16
+ Default is "rh_Asymptotic_GeometricUnits.h5". Other
17
+ potentially useful values replace "rh" with "rPsi4" and/or
18
+ "Asymptotic" with "CCE" or "FiniteRadii".
19
+ radius : str
20
+ The extraction radius to use. Default is "100.00".
21
+
22
+ Notes
23
+ =====
24
+ Waveforms from GR-Athena++ are distributed as `tar` files
25
+ containing a set of HDF5 files, containing CCE data,
26
+ "extrapolated" data (where "extrapolation" refers to the
27
+ single-radius PN-based correction method that Nakano introduced),
28
+ or finite-radius data, for either Psi4 or h. Each of those files
29
+ is NRAR-formatted exactly like the old SXS data. We could extract
30
+ the `tar` file, and then use the `nrar.load` function to read the
31
+ data. Alternatively — as is done here — we could just use the
32
+ `tar` file as a file-like object, and pass that to the `nrar.load`
33
+ function. This is a bit more efficient, and is preferred if we
34
+ intend to directly use the `tar` files.
35
+
36
+ The `tar` file is generally named with the resolution of the
37
+ simulation, which — for the initial catalog at least — may be any
38
+ of 128, 192, 256, 320, or 384.
39
+
40
+ Within the `tar` file, we have files like the following — though
41
+ "384" may be replaced by any resolution:
42
+
43
+ * "384/rPsi4_Asymptotic_GeometricUnits.h5"
44
+ * "384/rPsi4_CCE_GeometricUnits.h5"
45
+ * "384/rPsi4_FiniteRadii_GeometricUnits.h5"
46
+ * "384/rh_Asymptotic_GeometricUnits.h5"
47
+ * "384/rh_CCE_GeometricUnits.h5"
48
+ * "384/rh_FiniteRadii_GeometricUnits.h5"
49
+
50
+ And finally, within each of those h5 files, we have waveforms
51
+ corresponding to a series of extraction radii, which may include
52
+
53
+ * "50.00"
54
+ * "60.00"
55
+ * "70.00"
56
+ * "80.00"
57
+ * "90.00"
58
+ * "100.00"
59
+ * "120.00"
60
+ * "140.00"
61
+
62
+ Note the two 0s after the decimal point. The `FiniteRadii` and
63
+ `Asymptotic` data generally contain all of the above radii, while
64
+ the `CCE` data generally contains only the "50.00" and "100.00"
65
+ radius.
66
+
67
+ """
68
+
69
+ from pathlib import Path
70
+ import tarfile
71
+
72
+ resolution = Path(file).stem
73
+ subfile = kwargs.pop("subfile", "rh_Asymptotic_GeometricUnits.h5")
74
+ radius = kwargs.pop("radius", "100.00")
75
+
76
+ with tarfile.open(file, "r") as tf:
77
+ tf_names = [tfi.name for tfi in tf]
78
+ index = tf_names.index(f"{resolution}/{subfile}")
79
+ h5file = tf.extractfile(list(tf)[index])
80
+ w = nrar.load(
81
+ h5file,
82
+ h5_group=radius,
83
+ frame_type=nrar.Inertial,
84
+ data_type=nrar.h,
85
+ m_is_scaled_out=True,
86
+ r_is_scaled_out=True,
87
+ )
88
+
89
+ return w
@@ -202,6 +202,7 @@ def to_lvc_conventions(
202
202
  # If `phi_ref` and `inclination` are not None, return polarizations
203
203
  if phi_ref is not None:
204
204
  hp, hc = h.evaluate(inclination, π/2 - phi_ref).ndarray.view((float, 2)).T
205
+ hc *= -1 # Because h = hp - i hc
205
206
  return h.t, hp, hc, dynamics_dict
206
207
  else:
207
208
  # Could do `dict(WaveformModesDict(h))` to convert to a plain dict
@@ -148,6 +148,7 @@ def load(file, **kwargs):
148
148
 
149
149
  """
150
150
  import pathlib
151
+ import tarfile
151
152
  import re
152
153
  import h5py
153
154
  import quaternionic
@@ -161,41 +162,53 @@ def load(file, **kwargs):
161
162
  w_attributes = {}
162
163
 
163
164
  # Get an h5py handle to the desired part of the h5 file
164
- file_str = str(file)
165
- split = file_str.rsplit(".h5", 1) # Raises ValueError if ".h5" is not in the string
166
- if len(split) != 2:
167
- split = file_str.rsplit(".hdf5", 1)
168
- file_ending = ".hdf5"
169
- else:
170
- file_ending = ".h5"
171
- if len(split) != 2:
172
- raise ValueError(f"Could not find a valid HDF5 filename ending in '{file_str}'")
173
- file_str, root_group = split
174
- file_str = file_str + file_ending
175
- if not root_group:
165
+ if isinstance(file, tarfile.ExFileObject):
166
+ file_path = file
167
+ file_name = pathlib.Path(file.name).name
168
+ file_str = f"{file_name}"
169
+ file_dir = pathlib.Path(file.name).parent
176
170
  root_group = kwargs.pop("h5_group", "")
177
- if not root_group:
178
- extrapolation_order = kwargs.pop("extrapolation_order", None)
179
- if extrapolation_order is None:
180
- warning = "\nCould not find root group as `h5_group` or as `extrapolation_order`; returning all groups"
181
- warnings.warn(warning)
182
- elif extrapolation_order is Ellipsis:
183
- pass
184
- elif isinstance(extrapolation_order, str):
185
- root_group = extrapolation_order
186
- elif extrapolation_order == -1:
187
- root_group = "OutermostExtraction.dir"
171
+ else:
172
+ file_str = str(file)
173
+ split = file_str.rsplit(".h5", 1) # Raises ValueError if ".h5" is not in the string
174
+ if len(split) != 2:
175
+ split = file_str.rsplit(".hdf5", 1)
176
+ file_ending = ".hdf5"
188
177
  else:
189
- root_group = f"Extrapolated_N{extrapolation_order}.dir"
178
+ file_ending = ".h5"
179
+ if len(split) != 2:
180
+ raise ValueError(f"Could not find a valid HDF5 filename ending in '{file_str}'")
181
+ file_str, root_group = split
182
+ file_str = file_str + file_ending
183
+ if not root_group:
184
+ root_group = kwargs.pop("h5_group", "")
185
+ if not root_group:
186
+ extrapolation_order = kwargs.pop("extrapolation_order", None)
187
+ if extrapolation_order is None:
188
+ warning = "\nCould not find root group as `h5_group` or as `extrapolation_order`; returning all groups"
189
+ warnings.warn(warning)
190
+ elif extrapolation_order is Ellipsis:
191
+ pass
192
+ elif isinstance(extrapolation_order, str):
193
+ root_group = extrapolation_order
194
+ elif extrapolation_order == -1:
195
+ root_group = "OutermostExtraction.dir"
196
+ else:
197
+ root_group = f"Extrapolated_N{extrapolation_order}.dir"
190
198
 
191
- file_path = pathlib.Path(file_str).expanduser().resolve()
192
- file_name = file_path.name
193
- file_dir = file_path.parent
199
+ file_path = pathlib.Path(file_str).expanduser().resolve()
200
+ file_name = file_path.name
201
+ file_dir = file_path.parent
194
202
 
195
203
  with h5py.File(file_path, "r") as f_h5:
196
204
  if root_group:
197
205
  if root_group not in f_h5:
198
- raise ValueError(f"Input root group '{root_group}' was not found in '{file_path}'")
206
+ message = [
207
+ f"Input root group '{root_group}' was not found in '{file_path}'",
208
+ "Available groups are:",
209
+ ]
210
+ f_h5.visit(lambda s: message.append(f"\t{s}"))
211
+ raise ValueError("\n".join(message))
199
212
  f = f_h5[root_group]
200
213
  else:
201
214
  return KeyPassingDict(**{
@@ -3,6 +3,7 @@
3
3
  import re
4
4
  import numbers
5
5
  from collections.abc import MutableMapping
6
+ import warnings
6
7
  import numpy as np
7
8
  from scipy.interpolate import CubicSpline
8
9
  from scipy.optimize import minimize_scalar
@@ -1127,6 +1128,9 @@ class WaveformModes(WaveformMixin, TimeSeries):
1127
1128
  raised.
1128
1129
 
1129
1130
  """
1131
+ if self.frame_type == "corotating":
1132
+ warnings.warn("This waveform is already in a corotating frame; returning original.")
1133
+ return self
1130
1134
  frame, omega = self.corotating_frame(
1131
1135
  R0=R0,
1132
1136
  tolerance=tolerance,
@@ -164,6 +164,7 @@ def test_corotating_frame():
164
164
  R0 = quaternionic.array.random().normalized
165
165
  R_in = R0 * np.exp(quaternionic.array([0, 0, 0, omega / 2]) * w.t)
166
166
  w_rot = w.copy().rotate(R_in.conjugate())
167
+ w_rot._metadata["frame_type"] = "inertial"
167
168
  R_out = w_rot.corotating_frame(R0=R0, tolerance=1e-12)
168
169
  assert np.allclose(R_in.ndarray, R_out.ndarray, atol=1e-10, rtol=0.0), (
169
170
  f"\nR_in = {R_in}\n"
@@ -1 +0,0 @@
1
- __version__ = "2024.0.21"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes