Skip to content

Commit

Permalink
Python versioning (#25)
Browse files Browse the repository at this point in the history
* Implemented checks on python version before scri related things so that users can use this with the most recent python as long as they don't use those features

* Update test actions

* update pyproject.toml for current version

* update citation version
  • Loading branch information
deborahferguson authored Apr 5, 2024
1 parent a969f5f commit 7285418
Show file tree
Hide file tree
Showing 15 changed files with 760 additions and 363 deletions.
15 changes: 14 additions & 1 deletion .github/workflows/test_suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
branches: [ main ]

jobs:
build:
python_3_10_job:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -15,5 +15,18 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Test with pytest
run: python -m unittest discover tests
python_3_12_job:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: '3.12'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Test with pytest
run: python -m unittest discover tests
4 changes: 2 additions & 2 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ authors:
- family-names: "Valorz"
given-names: "Finny"
title: "mayawaves"
version: v2023.10
date-released: 2023-10-23
version: v2024.4
date-released: 2024-04-05
url: "https://github.com/MayaWaves/mayawaves"
doi: 10.5281/zenodo.10035526
10 changes: 8 additions & 2 deletions docs/html/_sources/source/getting_started.rst.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,17 @@ at the top of your file. You can also import specific parts of mayawaves instead

Requirements
-------------------------------------
Due to its dependencies, this package requires 3.9 :math:`\leq` python :math:`\leq` 3.10.
For most usecases, this package requires 3.9 :math:`\leq` python.

It also relies upon the following python packages which are automatically installed from pip when you install mayawaves::

numpy, scipy, pandas, romspline, wget, matplotlib, mock, numba, scri
numpy, scipy, pandas, romspline, wget, matplotlib, mock


However, if you want to use the ability to switch to a center-of-mass frame for the gravitational radiation, that has
additional dependencies that require python :math:`\leq` 3.10 as well as the following dependencies::

numba, scri

This package has been tested with Einstein Toolkit Release Meitner (released on December 6th, 2023).
It supports output from the following thorns::
Expand Down
2 changes: 1 addition & 1 deletion docs/html/searchindex.js

Large diffs are not rendered by default.

9 changes: 7 additions & 2 deletions docs/html/source/getting_started.html
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,14 @@ <h2>How to install<a class="headerlink" href="#how-to-install" title="Link to th
</section>
<section id="requirements">
<h2>Requirements<a class="headerlink" href="#requirements" title="Link to this heading"></a></h2>
<p>Due to its dependencies, this package requires 3.9 <span class="math notranslate nohighlight">\(\leq\)</span> python <span class="math notranslate nohighlight">\(\leq\)</span> 3.10.</p>
<p>For most usecases, this package requires 3.9 <span class="math notranslate nohighlight">\(\leq\)</span> python.</p>
<p>It also relies upon the following python packages which are automatically installed from pip when you install mayawaves:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">numpy</span><span class="p">,</span> <span class="n">scipy</span><span class="p">,</span> <span class="n">pandas</span><span class="p">,</span> <span class="n">romspline</span><span class="p">,</span> <span class="n">wget</span><span class="p">,</span> <span class="n">matplotlib</span><span class="p">,</span> <span class="n">mock</span><span class="p">,</span> <span class="n">numba</span><span class="p">,</span> <span class="n">scri</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">numpy</span><span class="p">,</span> <span class="n">scipy</span><span class="p">,</span> <span class="n">pandas</span><span class="p">,</span> <span class="n">romspline</span><span class="p">,</span> <span class="n">wget</span><span class="p">,</span> <span class="n">matplotlib</span><span class="p">,</span> <span class="n">mock</span>
</pre></div>
</div>
<p>However, if you want to use the ability to switch to a center-of-mass frame for the gravitational radiation, that has
additional dependencies that require python <span class="math notranslate nohighlight">\(\leq\)</span> 3.10 as well as the following dependencies:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">numba</span><span class="p">,</span> <span class="n">scri</span>
</pre></div>
</div>
<p>This package has been tested with Einstein Toolkit Release Meitner (released on December 6th, 2023).
Expand Down
10 changes: 8 additions & 2 deletions docs/source/getting_started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,17 @@ at the top of your file. You can also import specific parts of mayawaves instead

Requirements
-------------------------------------
Due to its dependencies, this package requires 3.9 :math:`\leq` python :math:`\leq` 3.10.
For most usecases, this package requires 3.9 :math:`\leq` python.

It also relies upon the following python packages which are automatically installed from pip when you install mayawaves::

numpy, scipy, pandas, romspline, wget, matplotlib, mock, numba, scri
numpy, scipy, pandas, romspline, wget, matplotlib, mock


However, if you want to use the ability to switch to a center-of-mass frame for the gravitational radiation, that has
additional dependencies that require python :math:`\leq` 3.10 as well as the following dependencies::

numba, scri

This package has been tested with Einstein Toolkit Release Meitner (released on December 6th, 2023).
It supports output from the following thorns::
Expand Down
5 changes: 5 additions & 0 deletions mayawaves/coalescence.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,11 @@ def set_radiation_frame(self, center_of_mass_corrected: bool = False):
Args:
center_of_mass_corrected (:obj:`bool`, optional): Whether to correct for center of mass drift. Default False. If false, the frame is set back to the original, raw frame.
"""
import sys
if sys.version_info.major == 3 and sys.version_info.minor > 10:
warnings.warn('Python version too recent to be compatible with Scri package. Unable to change the radiation frame.')
raise ImportError('Unable to change the radiation frame. Python version too recent to be compatible with Scri package. If you would like the ability to move to center-of-mass corrected frame, use python <= 3.10.')

from mayawaves.radiation import Frame

if center_of_mass_corrected:
Expand Down
45 changes: 42 additions & 3 deletions mayawaves/radiation.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@
import h5py
import numpy as np
import scipy.integrate
import scri
from scipy.ndimage import uniform_filter1d
from scipy.signal import butter, filtfilt
from scipy.signal.windows import blackmanharris
import math
from spherical_functions import LM_index


class Frame(Enum):
Expand Down Expand Up @@ -76,6 +74,10 @@ def set_frame(self, new_frame: Frame, time: np.ndarray = None, center_of_mass: n
center_of_mass (:obj:`numpy.ndarray`, optional): Time series of center of mass. Only necessary if moving to center of mass corrected frame.
"""
import sys
if sys.version_info.major == 3 and sys.version_info.minor > 10:
raise ImportError('Unable to change the radiation frame. Python version too recent to be compatible with Scri package. If you would like the ability to move to center-of-mass corrected frame, use python <= 3.10.')

if type(new_frame) != Frame:
warnings.warn("You must provide the frame as a Frame enum value")
return
Expand Down Expand Up @@ -685,6 +687,11 @@ def set_frame(self, new_frame: Frame, time: np.ndarray = None, center_of_mass: n
alpha (:obj:`numpy.ndarray`, optional): Offset for center of mass correction. Only necessary if moving to center of mass corrected frame and not providing the center of mass timeseries.
beta (:obj:`numpy.ndarray`, optional): Boost for center of mass correction. Only necessary if moving to center of mass corrected frame and not providing the center of mass timeseries.
"""
import sys
if sys.version_info.major == 3 and sys.version_info.minor > 10:
raise ImportError(
'Unable to change the radiation frame. Python version too recent to be compatible with Scri package. If you would like the ability to move to center-of-mass corrected frame, use python <= 3.10.')

if type(new_frame) != Frame:
warnings.warn('You must provide the new frame as a Frame enum')
return
Expand All @@ -704,6 +711,11 @@ def modes(self) -> dict:
if self.frame == Frame.RAW:
return self.raw_modes
if self.frame == Frame.COM_CORRECTED:
import sys
if sys.version_info.major == 3 and sys.version_info.minor > 10:
raise ImportError(
'Unable to return modes in center-of-mass corrected frame. Python version too recent to be compatible with Scri package. If you would like the ability to move to center-of-mass corrected frame, use python <= 3.10.')

if self.__com_corrected_modes is None:
self.__frame = Frame.RAW
self._generate_com_corrected_modes()
Expand Down Expand Up @@ -736,6 +748,11 @@ def l_max(self) -> int:
def time(self) -> np.ndarray:
"""Time array associated with all timeseries provided by this RadiationSphere."""
if self.frame == Frame.COM_CORRECTED:
import sys
if sys.version_info.major == 3 and sys.version_info.minor > 10:
raise ImportError(
'Unable to return time in center-of-mass corrected frame. Python version too recent to be compatible with Scri package. If you would like the ability to move to center-of-mass corrected frame, use python <= 3.10.')

return self.__com_corrected_time
return self.__time

Expand Down Expand Up @@ -1239,18 +1256,28 @@ def get_extrapolated_sphere(self, order: int = 1):
extrapolated_sphere = RadiationSphere(mode_dict=temp_modes, time=np.array(self.__time), radius=self.radius,
extrapolated=True)
if self.frame != Frame.RAW:
import sys
if sys.version_info.major == 3 and sys.version_info.minor > 10:
raise ImportError(
'Unable to set center-of-mass corrected frame. Python version too recent to be compatible with Scri package. If you would like the ability to move to center-of-mass corrected frame, use python <= 3.10.')

extrapolated_sphere.set_frame(self.frame, alpha=self.__alpha, beta=self.__beta)

return extrapolated_sphere

def _scri_waveform_modes_object(self) -> scri.WaveformModes:
def _scri_waveform_modes_object(self):
"""Create and return a Scri WaveformModes object containing the data for this extraction sphere.
For more information on scri objects, refer to https://scri.readthedocs.io.
Returns: A Scri WaveformModes object
"""
import sys
if sys.version_info.major == 3 and sys.version_info.minor > 10:
raise ImportError(
'Unable to create scri waveform modes object. Python version too recent to be compatible with Scri package. If you would like the ability to move to center-of-mass corrected frame, use python <= 3.10.')

from scri import WaveformModes
from scri import h as scri_h
from scri import Inertial
Expand Down Expand Up @@ -1292,6 +1319,11 @@ def _set_alpha_beta_for_com_transformation(self, com_time, center_of_mass):
center_of_mass (np.ndarray): timeseries of center of mass
"""
import sys
if sys.version_info.major == 3 and sys.version_info.minor > 10:
raise ImportError(
'Unable to convert to center-of-mass corrected frame. Python version too recent to be compatible with Scri package. If you would like the ability to move to center-of-mass corrected frame, use python <= 3.10.')

com_time = com_time + self.radius
t_max = np.max(com_time)
ti = 0.1 * t_max
Expand All @@ -1316,6 +1348,13 @@ def _generate_com_corrected_modes(self):
Uses scri to perform the transformation. For more information on scri, refer to https://scri.readthedocs.io.
"""
import sys
if sys.version_info.major == 3 and sys.version_info.minor > 10:
raise ImportError(
'Unable to return modes in center-of-mass corrected frame. Python version too recent to be compatible with Scri package. If you would like the ability to move to center-of-mass corrected frame, use python <= 3.10.')

from spherical_functions import LM_index

scri_waveform_object = self._scri_waveform_modes_object()
if scri_waveform_object is None:
return
Expand Down
13 changes: 9 additions & 4 deletions mayawaves/utils/postprocessingutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2667,10 +2667,12 @@ def _put_data_in_lal_compatible_format(coalescence: Coalescence, lal_h5_file_nam
center_of_mass_correction (:obj:'bool', optional): whether to correct for center of mass drift. Default False.
"""
from mayawaves.radiation import Frame
if center_of_mass_correction:
coalescence.set_radiation_frame(center_of_mass_corrected=True)
else:
coalescence.set_radiation_frame()
if not coalescence.radiation_frame == Frame.RAW:
coalescence.set_radiation_frame()

initial_time_horizon = 75
if extraction_radius != 0:
Expand Down Expand Up @@ -2737,15 +2739,18 @@ def _put_data_in_lal_compatible_format(coalescence: Coalescence, lal_h5_file_nam
_store_compact_object_timeseries_data(coalescence, lal_h5_file, lvc_format, time_shift, initial_time_horizon)

lal_h5_file.close()
coalescence.set_radiation_frame()
if coalescence.radiation_frame != Frame.RAW:
coalescence.set_radiation_frame()

except Exception as e:
lal_h5_file.close()
coalescence.set_radiation_frame()
if coalescence.radiation_frame != Frame.RAW:
coalescence.set_radiation_frame()
raise e

if raise_mode_error:
coalescence.set_radiation_frame()
if coalescence.radiation_frame != Frame.RAW:
coalescence.set_radiation_frame()
raise IOError(f"Data is missing for one of the included modes")


Expand Down
8 changes: 4 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
name = "mayawaves"
version = "2023.10"
version = "2024.4"
authors = [
{ name="Deborah Ferguson", email="[email protected]" },
{ name="Surendra Anne" },
Expand All @@ -22,7 +22,7 @@ authors = [
description = "A python package for interacting with Einstein Toolkit simulations and the MAYA Catalog of NR Waveforms"
readme = "README.md"
license = { file="LICENSE" }
requires-python = ">=3.8,<3.11"
requires-python = ">=3.8"
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
Expand All @@ -35,8 +35,8 @@ dependencies = ["numpy",
"wget",
"matplotlib",
"mock",
"numba",
"scri"
"numba; python_version < '3.11'",
"scri; python_version < '3.11'"
]

[project.urls]
Expand Down
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ romspline
wget
matplotlib
mock
numba
scri
numba; python_version < '3.11'
scri; python_version < '3.11'
84 changes: 59 additions & 25 deletions tests/test_coalescence.py
Original file line number Diff line number Diff line change
Expand Up @@ -622,31 +622,65 @@ def test_set_radiation_frame(self):

# center of mass
# center of mass data is None
with patch.object(RadiationBundle, 'set_frame') as mock_set_frame:
with patch.object(Coalescence, 'center_of_mass', new_callable=PropertyMock,
return_value=(None, None)) as mock_center_of_mass:
TestCoalescence.coalescence.set_radiation_frame(center_of_mass_corrected=True)

mock_center_of_mass.assert_called_once()
mock_set_frame.assert_not_called()
# center of mass data is not None
with patch.object(RadiationBundle, 'set_frame') as mock_set_frame:
with patch.object(Coalescence, 'center_of_mass', new_callable=PropertyMock,
return_value=(
np.array([1, 2, 3]), np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]))) as mock_center_of_mass:
TestCoalescence.coalescence.set_radiation_frame(center_of_mass_corrected=True)

mock_center_of_mass.assert_called_once()
self.assertEqual(Frame.COM_CORRECTED, mock_set_frame.call_args[0][0])
self.assertEqual(2, len(mock_set_frame.call_args[1]))
self.assertTrue(np.all(np.array([1, 2, 3]) == mock_set_frame.call_args[1]['time']))
self.assertTrue(np.all(
np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) == mock_set_frame.call_args[1]['center_of_mass']))

# resetting to raw frame
with patch.object(RadiationBundle, 'set_frame') as mock_set_frame:
TestCoalescence.coalescence.set_radiation_frame()
mock_set_frame.assert_called_once_with(Frame.RAW)
import sys
if sys.version_info.major == 3 and sys.version_info.minor > 10:
with patch.object(RadiationBundle, 'set_frame') as mock_set_frame:
with patch.object(Coalescence, 'center_of_mass', new_callable=PropertyMock,
return_value=(None, None)) as mock_center_of_mass:
try:
TestCoalescence.coalescence.set_radiation_frame(center_of_mass_corrected=True)
self.fail()
except ImportError:
mock_center_of_mass.assert_not_called()
mock_set_frame.assert_not_called()

# center of mass data is not None
with patch.object(RadiationBundle, 'set_frame') as mock_set_frame:
with patch.object(Coalescence, 'center_of_mass', new_callable=PropertyMock,
return_value=(
np.array([1, 2, 3]), np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]))) as mock_center_of_mass:
try:
TestCoalescence.coalescence.set_radiation_frame(center_of_mass_corrected=True)
self.fail()
except ImportError:
mock_center_of_mass.assert_not_called()

# resetting to raw frame
with patch.object(RadiationBundle, 'set_frame') as mock_set_frame:
try:
TestCoalescence.coalescence.set_radiation_frame()
self.fail()
except ImportError:
mock_set_frame.assert_not_called()

else:
with patch.object(RadiationBundle, 'set_frame') as mock_set_frame:
with patch.object(Coalescence, 'center_of_mass', new_callable=PropertyMock,
return_value=(None, None)) as mock_center_of_mass:
TestCoalescence.coalescence.set_radiation_frame(center_of_mass_corrected=True)

mock_center_of_mass.assert_called_once()
mock_set_frame.assert_not_called()

# center of mass data is not None
with patch.object(RadiationBundle, 'set_frame') as mock_set_frame:
with patch.object(Coalescence, 'center_of_mass', new_callable=PropertyMock,
return_value=(
np.array([1, 2, 3]),
np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]))) as mock_center_of_mass:
TestCoalescence.coalescence.set_radiation_frame(center_of_mass_corrected=True)

mock_center_of_mass.assert_called_once()
self.assertEqual(Frame.COM_CORRECTED, mock_set_frame.call_args[0][0])
self.assertEqual(2, len(mock_set_frame.call_args[1]))
self.assertTrue(np.all(np.array([1, 2, 3]) == mock_set_frame.call_args[1]['time']))
self.assertTrue(np.all(
np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) == mock_set_frame.call_args[1]['center_of_mass']))

# resetting to raw frame
with patch.object(RadiationBundle, 'set_frame') as mock_set_frame:
TestCoalescence.coalescence.set_radiation_frame()
mock_set_frame.assert_called_once_with(Frame.RAW)

@mock.patch("mayawaves.compactobject.CompactObject.initial_horizon_mass", new_callable=PropertyMock)
@mock.patch("mayawaves.compactobject.CompactObject.horizon_mass", new_callable=PropertyMock)
Expand Down
Loading

0 comments on commit 7285418

Please sign in to comment.