gwBOB 1.0.0__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.
gwbob-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Anuj Kankani
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
gwbob-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,124 @@
1
+ Metadata-Version: 2.4
2
+ Name: gwBOB
3
+ Version: 1.0.0
4
+ Summary: A Backwards-One-Body Gravitational Waveform Package
5
+ Author-email: Anuj Kankani <anuj.kankani@mail.wvu.edu>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/AnujKankani/BackwardsOneBody
8
+ Project-URL: Documentation, https://backwardsonebody.readthedocs.io
9
+ Project-URL: Repository, https://github.com/AnujKankani/BackwardsOneBody
10
+ Requires-Python: >=3.12
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ Requires-Dist: sxs
14
+ Requires-Dist: kuibit
15
+ Requires-Dist: sympy
16
+ Requires-Dist: qnmfits
17
+ Requires-Dist: jax
18
+ Provides-Extra: docs
19
+ Requires-Dist: sphinx; extra == "docs"
20
+ Requires-Dist: sphinx-rtd-theme; extra == "docs"
21
+ Requires-Dist: myst-parser; extra == "docs"
22
+ Requires-Dist: sphinx-autodoc-typehints; extra == "docs"
23
+ Requires-Dist: sphinx-copybutton; extra == "docs"
24
+ Requires-Dist: sphinx-design; extra == "docs"
25
+ Provides-Extra: tests
26
+ Requires-Dist: pytest; extra == "tests"
27
+ Dynamic: license-file
28
+
29
+
30
+ <p align="center">
31
+ <img src="docs/source/images/BOB_logo_v2.png" alt="gwBOB Logo" width="300">
32
+ </p>
33
+
34
+ <h1 align="center">gwBOB</h1>
35
+ <h3 align="center">The Backwards-One-Body Gravitational Waveform Package</h3>
36
+
37
+ <p align="center">
38
+ <a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
39
+ <a href="https://github.com/AnujKankani/BackwardsOneBody/actions/workflows/pytest.yml">
40
+ <img src="https://github.com/AnujKankani/BackwardsOneBody/actions/workflows/pytest.yml/badge.svg" alt="Build Status">
41
+ </a>
42
+ <a href="https://backwardsonebody.readthedocs.io/en/latest/?badge=latest">
43
+ <img src="https://readthedocs.org/projects/backwardsonebody/badge/?version=latest" alt="Documentation Status">
44
+ </a>
45
+ <a href="https://www.python.org/downloads/release/python-3120/">
46
+ <img src="https://img.shields.io/badge/python-3.12+-blue.svg" alt="Python Version">
47
+ </a>
48
+ <a href="https://github.com/AnujKankani/BackwardsOneBody">
49
+ <img src="https://img.shields.io/badge/status-active-success.svg" alt="Project Status">
50
+ </a>
51
+ </p>
52
+
53
+ ## Getting Started
54
+ Please see more detailed documentation [here](https://backwardsonebody.readthedocs.io/en/latest/index.html)!\
55
+ And check out the tutorial notebooks in this repo!
56
+
57
+
58
+ ## What is the Backwards One Body Model?
59
+
60
+ The **Backwards One Body (BOB) model** is an analytical and physically motivated approach to modeling gravitational waveforms from black hole binary mergers, as described in [arXiv:1810.00040](https://arxiv.org/abs/1810.00040). The BOB model is based on the physical insight that, during the late stages of binary evolution, the spacetime dynamics of the binary system closely resemble a linear perturbation of the final, stationary black hole remnant.
61
+
62
+ ---
63
+
64
+ ## Features
65
+ - **Analytical accuracy:** Closed form expressions for the amplitude and frequency evolution.
66
+ - **Minimally Calibrated:** Requires minimal calibration to numerical relativity (NR)
67
+ - **Test all BOB flavors** Easily generate and switch between different "flavors" of BOB depending on your research problem.
68
+ - **Easy initialization** Easy initialization using SXS, CCE, or raw NR data.
69
+ - **Beyond Kerr waveforms** Compare NR data to BOB waveforms generated with custom QNMs.
70
+ - **Easy comparisons:** Easy comparisons to waveforms from the public SXS and CCE catalog, as well as raw NR data.
71
+ - **Well Documented and Actively Developed**
72
+
73
+ <p align="center">
74
+ <b>Generate plots like these with just a few lines of code!</b>
75
+ </p>
76
+ <p align="center">
77
+ <img src="docs/source/images/BOB_news_0305.png">
78
+ </p>
79
+
80
+
81
+ ## Requirements
82
+
83
+ - (Windows users should use [WSL](https://docs.microsoft.com/en-us/windows/wsl/))
84
+ - [`kuibit`](https://github.com/SRombetto/kuibit)
85
+ - [`sxs`](https://github.com/sxs-collaboration/sxs)
86
+ - [`qnmfits`](https://github.com/sxs-collaboration/qnmfits)
87
+ - [`scri`](https://github.com/moble/scri)
88
+ - `jax` (install the GPU compatible version if possible)
89
+ - `sympy`
90
+ - `numpy`
91
+ - `scipy`
92
+ - `matplotlib`
93
+
94
+
95
+ ## Install via pip
96
+
97
+ ```bash
98
+ pip install gwBOB
99
+ ```
100
+
101
+
102
+ ## Citing this Code
103
+
104
+ If you use this code please cite
105
+ ```text
106
+ @article{mcwilliams2019analytical,
107
+ title={Analytical black-hole binary merger waveforms},
108
+ author={McWilliams, Sean T},
109
+ journal={Physical review letters},
110
+ volume={122},
111
+ number={19},
112
+ pages={191102},
113
+ year={2019},
114
+ publisher={APS}
115
+ }
116
+ ```
117
+
118
+ BOB paper to be added.
119
+
120
+ JOSS paper to be added.
121
+
122
+ ## Contributing
123
+
124
+ Contributions are always welcome! If you find an issue, or have any questions on how to use the code, please raise an [issue](https://github.com/AnujKankani/BackwardsOneBody/issues) on this repo. If you want to contribute directly to the code, please fork the code and create a pull request!
gwbob-1.0.0/README.md ADDED
@@ -0,0 +1,96 @@
1
+
2
+ <p align="center">
3
+ <img src="docs/source/images/BOB_logo_v2.png" alt="gwBOB Logo" width="300">
4
+ </p>
5
+
6
+ <h1 align="center">gwBOB</h1>
7
+ <h3 align="center">The Backwards-One-Body Gravitational Waveform Package</h3>
8
+
9
+ <p align="center">
10
+ <a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
11
+ <a href="https://github.com/AnujKankani/BackwardsOneBody/actions/workflows/pytest.yml">
12
+ <img src="https://github.com/AnujKankani/BackwardsOneBody/actions/workflows/pytest.yml/badge.svg" alt="Build Status">
13
+ </a>
14
+ <a href="https://backwardsonebody.readthedocs.io/en/latest/?badge=latest">
15
+ <img src="https://readthedocs.org/projects/backwardsonebody/badge/?version=latest" alt="Documentation Status">
16
+ </a>
17
+ <a href="https://www.python.org/downloads/release/python-3120/">
18
+ <img src="https://img.shields.io/badge/python-3.12+-blue.svg" alt="Python Version">
19
+ </a>
20
+ <a href="https://github.com/AnujKankani/BackwardsOneBody">
21
+ <img src="https://img.shields.io/badge/status-active-success.svg" alt="Project Status">
22
+ </a>
23
+ </p>
24
+
25
+ ## Getting Started
26
+ Please see more detailed documentation [here](https://backwardsonebody.readthedocs.io/en/latest/index.html)!\
27
+ And check out the tutorial notebooks in this repo!
28
+
29
+
30
+ ## What is the Backwards One Body Model?
31
+
32
+ The **Backwards One Body (BOB) model** is an analytical and physically motivated approach to modeling gravitational waveforms from black hole binary mergers, as described in [arXiv:1810.00040](https://arxiv.org/abs/1810.00040). The BOB model is based on the physical insight that, during the late stages of binary evolution, the spacetime dynamics of the binary system closely resemble a linear perturbation of the final, stationary black hole remnant.
33
+
34
+ ---
35
+
36
+ ## Features
37
+ - **Analytical accuracy:** Closed form expressions for the amplitude and frequency evolution.
38
+ - **Minimally Calibrated:** Requires minimal calibration to numerical relativity (NR)
39
+ - **Test all BOB flavors** Easily generate and switch between different "flavors" of BOB depending on your research problem.
40
+ - **Easy initialization** Easy initialization using SXS, CCE, or raw NR data.
41
+ - **Beyond Kerr waveforms** Compare NR data to BOB waveforms generated with custom QNMs.
42
+ - **Easy comparisons:** Easy comparisons to waveforms from the public SXS and CCE catalog, as well as raw NR data.
43
+ - **Well Documented and Actively Developed**
44
+
45
+ <p align="center">
46
+ <b>Generate plots like these with just a few lines of code!</b>
47
+ </p>
48
+ <p align="center">
49
+ <img src="docs/source/images/BOB_news_0305.png">
50
+ </p>
51
+
52
+
53
+ ## Requirements
54
+
55
+ - (Windows users should use [WSL](https://docs.microsoft.com/en-us/windows/wsl/))
56
+ - [`kuibit`](https://github.com/SRombetto/kuibit)
57
+ - [`sxs`](https://github.com/sxs-collaboration/sxs)
58
+ - [`qnmfits`](https://github.com/sxs-collaboration/qnmfits)
59
+ - [`scri`](https://github.com/moble/scri)
60
+ - `jax` (install the GPU compatible version if possible)
61
+ - `sympy`
62
+ - `numpy`
63
+ - `scipy`
64
+ - `matplotlib`
65
+
66
+
67
+ ## Install via pip
68
+
69
+ ```bash
70
+ pip install gwBOB
71
+ ```
72
+
73
+
74
+ ## Citing this Code
75
+
76
+ If you use this code please cite
77
+ ```text
78
+ @article{mcwilliams2019analytical,
79
+ title={Analytical black-hole binary merger waveforms},
80
+ author={McWilliams, Sean T},
81
+ journal={Physical review letters},
82
+ volume={122},
83
+ number={19},
84
+ pages={191102},
85
+ year={2019},
86
+ publisher={APS}
87
+ }
88
+ ```
89
+
90
+ BOB paper to be added.
91
+
92
+ JOSS paper to be added.
93
+
94
+ ## Contributing
95
+
96
+ Contributions are always welcome! If you find an issue, or have any questions on how to use the code, please raise an [issue](https://github.com/AnujKankani/BackwardsOneBody/issues) on this repo. If you want to contribute directly to the code, please fork the code and create a pull request!
@@ -0,0 +1,124 @@
1
+ Metadata-Version: 2.4
2
+ Name: gwBOB
3
+ Version: 1.0.0
4
+ Summary: A Backwards-One-Body Gravitational Waveform Package
5
+ Author-email: Anuj Kankani <anuj.kankani@mail.wvu.edu>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/AnujKankani/BackwardsOneBody
8
+ Project-URL: Documentation, https://backwardsonebody.readthedocs.io
9
+ Project-URL: Repository, https://github.com/AnujKankani/BackwardsOneBody
10
+ Requires-Python: >=3.12
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ Requires-Dist: sxs
14
+ Requires-Dist: kuibit
15
+ Requires-Dist: sympy
16
+ Requires-Dist: qnmfits
17
+ Requires-Dist: jax
18
+ Provides-Extra: docs
19
+ Requires-Dist: sphinx; extra == "docs"
20
+ Requires-Dist: sphinx-rtd-theme; extra == "docs"
21
+ Requires-Dist: myst-parser; extra == "docs"
22
+ Requires-Dist: sphinx-autodoc-typehints; extra == "docs"
23
+ Requires-Dist: sphinx-copybutton; extra == "docs"
24
+ Requires-Dist: sphinx-design; extra == "docs"
25
+ Provides-Extra: tests
26
+ Requires-Dist: pytest; extra == "tests"
27
+ Dynamic: license-file
28
+
29
+
30
+ <p align="center">
31
+ <img src="docs/source/images/BOB_logo_v2.png" alt="gwBOB Logo" width="300">
32
+ </p>
33
+
34
+ <h1 align="center">gwBOB</h1>
35
+ <h3 align="center">The Backwards-One-Body Gravitational Waveform Package</h3>
36
+
37
+ <p align="center">
38
+ <a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
39
+ <a href="https://github.com/AnujKankani/BackwardsOneBody/actions/workflows/pytest.yml">
40
+ <img src="https://github.com/AnujKankani/BackwardsOneBody/actions/workflows/pytest.yml/badge.svg" alt="Build Status">
41
+ </a>
42
+ <a href="https://backwardsonebody.readthedocs.io/en/latest/?badge=latest">
43
+ <img src="https://readthedocs.org/projects/backwardsonebody/badge/?version=latest" alt="Documentation Status">
44
+ </a>
45
+ <a href="https://www.python.org/downloads/release/python-3120/">
46
+ <img src="https://img.shields.io/badge/python-3.12+-blue.svg" alt="Python Version">
47
+ </a>
48
+ <a href="https://github.com/AnujKankani/BackwardsOneBody">
49
+ <img src="https://img.shields.io/badge/status-active-success.svg" alt="Project Status">
50
+ </a>
51
+ </p>
52
+
53
+ ## Getting Started
54
+ Please see more detailed documentation [here](https://backwardsonebody.readthedocs.io/en/latest/index.html)!\
55
+ And check out the tutorial notebooks in this repo!
56
+
57
+
58
+ ## What is the Backwards One Body Model?
59
+
60
+ The **Backwards One Body (BOB) model** is an analytical and physically motivated approach to modeling gravitational waveforms from black hole binary mergers, as described in [arXiv:1810.00040](https://arxiv.org/abs/1810.00040). The BOB model is based on the physical insight that, during the late stages of binary evolution, the spacetime dynamics of the binary system closely resemble a linear perturbation of the final, stationary black hole remnant.
61
+
62
+ ---
63
+
64
+ ## Features
65
+ - **Analytical accuracy:** Closed form expressions for the amplitude and frequency evolution.
66
+ - **Minimally Calibrated:** Requires minimal calibration to numerical relativity (NR)
67
+ - **Test all BOB flavors** Easily generate and switch between different "flavors" of BOB depending on your research problem.
68
+ - **Easy initialization** Easy initialization using SXS, CCE, or raw NR data.
69
+ - **Beyond Kerr waveforms** Compare NR data to BOB waveforms generated with custom QNMs.
70
+ - **Easy comparisons:** Easy comparisons to waveforms from the public SXS and CCE catalog, as well as raw NR data.
71
+ - **Well Documented and Actively Developed**
72
+
73
+ <p align="center">
74
+ <b>Generate plots like these with just a few lines of code!</b>
75
+ </p>
76
+ <p align="center">
77
+ <img src="docs/source/images/BOB_news_0305.png">
78
+ </p>
79
+
80
+
81
+ ## Requirements
82
+
83
+ - (Windows users should use [WSL](https://docs.microsoft.com/en-us/windows/wsl/))
84
+ - [`kuibit`](https://github.com/SRombetto/kuibit)
85
+ - [`sxs`](https://github.com/sxs-collaboration/sxs)
86
+ - [`qnmfits`](https://github.com/sxs-collaboration/qnmfits)
87
+ - [`scri`](https://github.com/moble/scri)
88
+ - `jax` (install the GPU compatible version if possible)
89
+ - `sympy`
90
+ - `numpy`
91
+ - `scipy`
92
+ - `matplotlib`
93
+
94
+
95
+ ## Install via pip
96
+
97
+ ```bash
98
+ pip install gwBOB
99
+ ```
100
+
101
+
102
+ ## Citing this Code
103
+
104
+ If you use this code please cite
105
+ ```text
106
+ @article{mcwilliams2019analytical,
107
+ title={Analytical black-hole binary merger waveforms},
108
+ author={McWilliams, Sean T},
109
+ journal={Physical review letters},
110
+ volume={122},
111
+ number={19},
112
+ pages={191102},
113
+ year={2019},
114
+ publisher={APS}
115
+ }
116
+ ```
117
+
118
+ BOB paper to be added.
119
+
120
+ JOSS paper to be added.
121
+
122
+ ## Contributing
123
+
124
+ Contributions are always welcome! If you find an issue, or have any questions on how to use the code, please raise an [issue](https://github.com/AnujKankani/BackwardsOneBody/issues) on this repo. If you want to contribute directly to the code, please fork the code and create a pull request!
@@ -0,0 +1,10 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ requirements.txt
5
+ gwBOB/gwBOB.egg-info/PKG-INFO
6
+ gwBOB/gwBOB.egg-info/SOURCES.txt
7
+ gwBOB/gwBOB.egg-info/dependency_links.txt
8
+ gwBOB/gwBOB.egg-info/requires.txt
9
+ gwBOB/gwBOB.egg-info/top_level.txt
10
+ tests/test_BOB_utils.py
@@ -0,0 +1,16 @@
1
+ sxs
2
+ kuibit
3
+ sympy
4
+ qnmfits
5
+ jax
6
+
7
+ [docs]
8
+ sphinx
9
+ sphinx-rtd-theme
10
+ myst-parser
11
+ sphinx-autodoc-typehints
12
+ sphinx-copybutton
13
+ sphinx-design
14
+
15
+ [tests]
16
+ pytest
@@ -0,0 +1,44 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "gwBOB"
7
+ version = "1.0.0"
8
+ description = "A Backwards-One-Body Gravitational Waveform Package"
9
+ readme = { file = "README.md", content-type = "text/markdown" }
10
+ authors = [
11
+ { name = "Anuj Kankani", email = "anuj.kankani@mail.wvu.edu" }
12
+ ]
13
+ license = { text = "MIT" }
14
+ requires-python = ">=3.12"
15
+
16
+ dependencies = [
17
+ "sxs",
18
+ "kuibit",
19
+ "sympy",
20
+ "qnmfits",
21
+ "jax",
22
+ ]
23
+
24
+ [project.optional-dependencies]
25
+ docs = [
26
+ "sphinx",
27
+ "sphinx-rtd-theme",
28
+ "myst-parser",
29
+ "sphinx-autodoc-typehints",
30
+ "sphinx-copybutton",
31
+ "sphinx-design",
32
+ ]
33
+ tests = ["pytest"]
34
+
35
+ [project.urls]
36
+ Homepage = "https://github.com/AnujKankani/BackwardsOneBody"
37
+ Documentation = "https://backwardsonebody.readthedocs.io"
38
+ Repository = "https://github.com/AnujKankani/BackwardsOneBody"
39
+
40
+ [tool.setuptools.packages.find]
41
+ where = ["gwBOB"]
42
+ include = ["gwBOB*"]
43
+
44
+
@@ -0,0 +1,12 @@
1
+ sxs
2
+ kuibit
3
+ sympy
4
+ qnmfits
5
+ pytest
6
+ jax
7
+ sphinx
8
+ sphinx-rtd-theme
9
+ myst-parser
10
+ sphinx-autodoc-typehints
11
+ sphinx-copybutton
12
+ sphinx-design
gwbob-1.0.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,217 @@
1
+ from kuibit.timeseries import TimeSeries as kuibit_ts
2
+ import sys, os
3
+ sys.path.append(os.path.dirname(os.path.dirname(__file__)))
4
+ from gwBOB import gen_utils
5
+ import numpy as np
6
+ from gwBOB import BOB_utils
7
+ import sxs
8
+ import scri
9
+ import pytest
10
+
11
+ file_prefix = "./tests" #github
12
+ #file_prefix = "." #local
13
+ @pytest.fixture(scope="session")
14
+ def BOB_cce():
15
+ wf_paths = {}
16
+ wf_paths['h'] = f'{file_prefix}/sxs_cache/cce9/rhOverM_BondiCce_R0270.h5'
17
+ wf_paths['Psi4'] = f'{file_prefix}/sxs_cache/cce9/rMPsi4_BondiCce_R0270.h5'
18
+ wf_paths['Psi3'] = f'{file_prefix}/sxs_cache/cce9/r2Psi3_BondiCce_R0270.h5'
19
+ wf_paths['Psi2'] = f'{file_prefix}/sxs_cache/cce9/r3Psi2OverM_BondiCce_R0270.h5'
20
+ wf_paths['Psi1'] = f'{file_prefix}/sxs_cache/cce9/r4Psi1OverM2_BondiCce_R0270.h5'
21
+ wf_paths['Psi0'] = f'{file_prefix}/sxs_cache/cce9/r5Psi0OverM3_BondiCce_R0270.h5'
22
+
23
+ abd = scri.SpEC.create_abd_from_h5(file_format='RPDMB', **wf_paths)
24
+
25
+ BOB = BOB_utils.BOB()
26
+ BOB.initialize_with_cce_data(-1,provide_own_abd = abd,l=2,m=-2)
27
+
28
+ return BOB
29
+ def BOB_params(initialize , location = f'{file_prefix}/trusted_outputs/BOB_BBH_2325_optimize_psi4.npz'):
30
+ #Default to SXS BBH 2325 Params, Optimize Omega_0 = True if initialize and location are not given
31
+ if initialize == None:
32
+ data = np.load(location)
33
+ params = ([data["mf"], data["chif"], data["l"], data["m"], data["Ap"], data["tp"],
34
+ data["Omega_0"], data["Phi_0"], data["tau"], data["Omega_ISCO"]])
35
+ elif initialize == "SXS":
36
+ data = np.load(f'{file_prefix}/trusted_outputs/BOB_BBH_2325_optimize_psi4.npz')
37
+ params = ([data["mf"], data["chif"], data["l"], data["m"], data["Ap"], data["tp"],
38
+ data["Omega_0"], data["Phi_0"], data["tau"], data["Omega_ISCO"]])
39
+ elif initialize == "CCE":
40
+ data = np.load(f'{file_prefix}/trusted_outputs/BOB_BBH_CCE9_l2mm2_optimize_news.npz')
41
+ params = ([data["mf"], data["chif"], data["l"], data["m"], data["Ap"], data["tp"],
42
+ data["Omega_0"], data["Phi_0"], data["tau"], data["Omega_ISCO"]])
43
+ return params
44
+
45
+ def kuibit_ts_load(location):
46
+ data = np.load(location)
47
+ timeseries = {}
48
+ for key in data.files:
49
+ if key.endswith("_t"):
50
+ name = key[:-2]
51
+ t = data[f"{name}_t"]
52
+ y = data[f"{name}_y"]
53
+ timeseries[name] = kuibit_ts(t, y)
54
+ return timeseries
55
+
56
+ def test_initialize_with_sxs_data():
57
+ # Set path for cache locally
58
+ cache_path = f'{file_prefix}/sxs_cache'
59
+ sxs.write_config(cache_directory=cache_path)
60
+
61
+ expected_params = BOB_params("SXS")
62
+
63
+ BOB = BOB_utils.BOB()
64
+ BOB.initialize_with_sxs_data("SXS:BBH:2325",l=2,m=2,download=True)
65
+
66
+ BOB.what_should_BOB_create = "psi4"
67
+ BOB.optimize_Omega0 = True
68
+ t_bob_psi4, y_bob_psi4 = BOB.construct_BOB()
69
+ ts_psi4 = kuibit_ts(t_bob_psi4, y_bob_psi4)
70
+
71
+ result_params = ([BOB.mf, BOB.chif, BOB.l, BOB.m, BOB.Ap, BOB.tp,
72
+ BOB.Omega_0, BOB.Phi_0, BOB.tau, BOB.Omega_ISCO])
73
+
74
+ BOB.what_should_BOB_create = "news"
75
+ BOB.optimize_Omega0 = True
76
+ t_bob_news, y_bob_news = BOB.construct_BOB()
77
+ ts_news = kuibit_ts(t_bob_news, y_bob_news)
78
+
79
+
80
+ BOB.what_should_BOB_create = "strain"
81
+ BOB.optimize_Omega0 = True
82
+ t_bob_strain, y_bob_strain = BOB.construct_BOB()
83
+ ts_strain = kuibit_ts(t_bob_strain, y_bob_strain)
84
+
85
+
86
+ BOB_exp = kuibit_ts_load(f'{file_prefix}/trusted_outputs/BBH_2325_BOB_wf.npz')
87
+ psi4_exp = BOB_exp["psi4"]
88
+ news_exp = BOB_exp["news"]
89
+ strain_exp = BOB_exp["strain"]
90
+
91
+ mismatches = ([gen_utils.mismatch(ts_psi4, psi4_exp, t0 = 0, tf = 100),
92
+ gen_utils.mismatch(ts_news, news_exp, t0 = 0, tf = 100),
93
+ gen_utils.mismatch(ts_strain, strain_exp, t0 = 0, tf = 100)])
94
+ mismatches_exp = ([0.0,0.0,0.0])
95
+
96
+ for exp, res in zip(expected_params, result_params):
97
+ assert np.isclose(exp, res, rtol=1e-12)
98
+ for exp, res in zip(mismatches, mismatches_exp):
99
+ assert np.isclose(exp, res, rtol=1e-12)
100
+
101
+ def test_initialize_with_cce_data(BOB_cce):
102
+
103
+
104
+ expected_params = BOB_params(initialize = "CCE")
105
+
106
+ BOB_cce.what_should_BOB_create = "strain"
107
+ BOB_cce.optimize_Omega0 = True
108
+
109
+ t,y = BOB_cce.construct_BOB()
110
+ ts_strain = kuibit_ts(t,y)
111
+
112
+ BOB_cce.what_should_BOB_create = "news"
113
+ t,y = BOB_cce.construct_BOB()
114
+ ts_news = kuibit_ts(t,y)
115
+ result_params = ([BOB_cce.mf, BOB_cce.chif, BOB_cce.l, BOB_cce.m, BOB_cce.Ap, BOB_cce.tp,
116
+ BOB_cce.Omega_0, BOB_cce.Phi_0, BOB_cce.tau, BOB_cce.Omega_ISCO])
117
+
118
+ BOB_cce.what_should_BOB_create = "psi4"
119
+ t,y = BOB_cce.construct_BOB()
120
+ ts_psi4 = kuibit_ts(t,y)
121
+
122
+ BOB_exp = kuibit_ts_load(f'{file_prefix}/trusted_outputs/BBH_CCE9_l2mm2_BOB_wf.npz')
123
+ print(BOB_exp)
124
+ psi4_exp = BOB_exp["psi4"]
125
+ news_exp = BOB_exp["news"]
126
+ strain_exp = BOB_exp["strain"]
127
+
128
+ mismatches = ([gen_utils.mismatch(ts_psi4, psi4_exp, t0 = 0, tf = 100),
129
+ gen_utils.mismatch(ts_news, news_exp, t0 = 0, tf = 100),
130
+ gen_utils.mismatch(ts_strain, strain_exp, t0 = 0, tf = 100)])
131
+ mismatches_exp = ([0.0,0.0,0.0])
132
+
133
+ for exp, res in zip(expected_params, result_params):
134
+ assert np.isclose(exp, res, rtol=1e-12)
135
+ for exp, res in zip(mismatches, mismatches_exp):
136
+ assert np.isclose(exp, res, rtol=1e-12)
137
+ def test_kuibit_frequency_lm(BOB_cce):
138
+ BOB_cce.what_should_BOB_create = "psi4"
139
+ BOB_cce.optimize_Omega0 = True
140
+ t,y = BOB_cce.construct_BOB()
141
+ ts = kuibit_ts(t,y)
142
+ freq = gen_utils.get_frequency(ts)
143
+ # Load reference
144
+ ref = np.load(f'{file_prefix}/trusted_outputs/kuibit_cce9_rMPsi4_R0270_freq_l2_mm2.npz')
145
+ # Compare arrays
146
+ np.testing.assert_allclose(freq.t, ref["f_t"], rtol=1e-10, atol=1e-15)
147
+ np.testing.assert_allclose(freq.y, ref["f_y"], rtol=1e-10, atol=1e-15)
148
+
149
+ def test_get_phase(BOB_cce):
150
+ BOB_cce.what_should_BOB_create = "psi4"
151
+ BOB_cce.optimize_Omega0 = True
152
+ t,y = BOB_cce.construct_BOB()
153
+ ts = kuibit_ts(t,y)
154
+ phase = gen_utils.get_phase(ts)
155
+ # Load reference
156
+ ref = np.load(f'{file_prefix}/trusted_outputs/kuibit_cce9_rMPsi4_R0270_phase_l2_mm2.npz')
157
+ # Compare arrays
158
+ np.testing.assert_allclose(phase.t, ref["phase_t"], rtol=1e-10, atol=1e-15)
159
+ np.testing.assert_allclose(phase.y, ref["phase_y"], rtol=1e-10, atol=1e-15)
160
+
161
+
162
+ def test_get_r_isco_values():
163
+ # Small arrays of chi and M
164
+ chi_vals = np.array([0.0, 0.5, 0.9])
165
+ M_vals = np.array([1.0, 2.0, 5.0])
166
+
167
+ # Expected values computed manually or from reference
168
+ expected = [
169
+ 6.0, # (0, 1), Schwarzschild ISCO = 6M
170
+ 8.466005059061652, #(0.5, 2)
171
+ 11.604415208809435 # (0.9, 5.0)
172
+ ]
173
+
174
+ # Check that function returns correct shape and matches expected
175
+ for chi, M, exp in zip(chi_vals, M_vals, expected):
176
+ result = gen_utils.get_r_isco(chi, M)
177
+ assert np.isclose(result, exp, rtol=1e-11)
178
+ def test_get_Omega_isco_values():
179
+ chi_vals = np.array([0.0, 0.5, 0.9])
180
+ M_vals = np.array([1.0, 2.0, 5.0])
181
+
182
+ expected = [
183
+ 0.06804138174397717,
184
+ 0.05429417949013838,
185
+ 0.0450883417670616
186
+ ]
187
+
188
+ for chi, M, exp in zip(chi_vals, M_vals, expected):
189
+ result = gen_utils.get_Omega_isco(chi, M)
190
+ assert np.isclose(result, exp, rtol=1e-11)
191
+ def test_get_qnm():
192
+ chi_vals = np.array([0.0, 0.0, 0.0, 0.5, 0.5, 0.5])
193
+ M_vals = np.array([1.0, 1.0, 1.0, 1.0, 1.0, 2.0])
194
+ l_vals = np.array([2, 3, 2, 2, 2, 2])
195
+ m_vals = np.array([2, 2, 2, 2, 2, 2])
196
+ n_vals = np.array([0, 0, 1, 0, 0, 0])
197
+ sign_vals = np.array([1, 1, 1, -1, 1, 1])
198
+
199
+
200
+ expected_w_r_vals = np.array([0.37367168441804177, 0.5994432884374902, 0.34671099687916285, 0.32430731434882354, 0.46412302597593846, 0.23206151298796923])
201
+ expected_tau_vals = np.array([11.24071459084527, 10.787131838360468, 3.6507692360145394, 11.231973996651769, 11.676945396785948, 23.353890793571896])
202
+
203
+
204
+ for chi, M, l, m, n, sgn, exp_w, exp_tau in zip(chi_vals, M_vals, l_vals, m_vals, n_vals, sign_vals, expected_w_r_vals, expected_tau_vals):
205
+ result_w, result_tau = gen_utils.get_qnm(chi, M, l, m, n = n, sign = sgn)
206
+ assert np.isclose(result_w, exp_w, rtol=1e-11)
207
+ assert np.isclose(result_tau, exp_tau, rtol=1e-11)
208
+ def test_get_tp_Ap_from_spline(BOB_cce):
209
+ BOB_cce.what_should_BOB_create = "psi4"
210
+ BOB_cce.optimize_Omega0 = True
211
+ t,y = BOB_cce.construct_BOB()
212
+ ts = kuibit_ts(t,y)
213
+ amp = np.abs(ts)
214
+ expected_tp, expected_Ap = ([5148.657477586399, 0.046735948589431364])
215
+ result_tp, result_Ap = gen_utils.get_tp_Ap_from_spline(amp)
216
+ assert np.isclose(result_tp, expected_tp, rtol=1e-11)
217
+ assert np.isclose(result_Ap, expected_Ap, rtol=1e-11)