From 2a22ba0b8b5bd1cc33e8c795acac7629b0498b91 Mon Sep 17 00:00:00 2001 From: Roy Smart Date: Mon, 29 Jan 2024 21:55:15 -0700 Subject: [PATCH] Added tests and documentation to `iris.planning.num_repeats()` --- .github/workflows/tests.yml | 45 +++++++++++++++++++++++++++++++ iris/_tests/__init__.py | 0 iris/_tests/test_planning.py | 46 ++++++++++++++++++++++++++++++++ iris/planning.py | 51 +++++++++++++++++++++++++++++++----- 4 files changed, 135 insertions(+), 7 deletions(-) create mode 100644 .github/workflows/tests.yml create mode 100644 iris/_tests/__init__.py create mode 100644 iris/_tests/test_planning.py diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..45b9828 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,45 @@ + +name: tests + +on: + push: + branches: + - main + pull_request: + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ + ubuntu-latest, + windows-latest, + macOS-latest, + ] + python-version: ["3.11",] + name: ${{ matrix.os }}, Python ${{ matrix.python-version }} tests + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install package + run: | + python -m pip install --upgrade pip + pip install setuptools wheel + pip install -e .[test] + - name: Test with pytest + run: | + pip install pytest pytest-cov + pytest --cov=. --cov-report=html + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v3 + with: + token: ${{ secrets.CODECOV_TOKEN }} + file: coverage.xml + flags: unittests + env_vars: OS,PYTHON + name: codecov-umbrella diff --git a/iris/_tests/__init__.py b/iris/_tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/iris/_tests/test_planning.py b/iris/_tests/test_planning.py new file mode 100644 index 0000000..11495fa --- /dev/null +++ b/iris/_tests/test_planning.py @@ -0,0 +1,46 @@ +from __future__ import annotations +import pytest +import astropy.units as u +import astropy.time +import iris + + +@pytest.mark.parametrize( + argnames="time_start", + argvalues=[ + "2024-01-29T00:00:00", + ], +) +@pytest.mark.parametrize( + argnames="time_stop", + argvalues=[ + "2024-01-29T04:00:00", + + ], +) +@pytest.mark.parametrize( + argnames="timedelta_raster", + argvalues=[ + 1 * u.hr, + ], +) +@pytest.mark.parametrize( + argnames="timedelta_slew", + argvalues=[ + 20 * u.min, + ], +) +def test_num_repeats( + time_start: str | astropy.time.Time, + time_stop: str | astropy.time.Time, + timedelta_raster: u.Quantity, + timedelta_slew: u.Quantity, +): + result = iris.planning.num_repeats( + time_start=time_start, + time_stop=time_stop, + timedelta_raster=timedelta_raster, + timedelta_slew=timedelta_slew, + ) + assert isinstance(result, float) + assert result > 0 diff --git a/iris/planning.py b/iris/planning.py index 9185b91..1856e9a 100644 --- a/iris/planning.py +++ b/iris/planning.py @@ -1,3 +1,9 @@ +""" +Utilities for planning IRIS observations +""" + +from __future__ import annotations +import numpy as np import astropy.units as u import astropy.time @@ -7,17 +13,48 @@ def num_repeats( - time_start, - time_stop, - time_raster, - time_slew=10 * u.min, -): + time_start: str | astropy.time.Time, + time_stop: str | astropy.time.Time, + timedelta_raster: u.Quantity, + timedelta_slew: u.Quantity = 10 * u.min, +) -> np.ndarray: + """ + Calculate the number of times we can repeat a raster given the start and stop + times and the length of the raster. + + Parameters + ---------- + time_start + The starting time of the observation + time_stop + The stop time of the observation + timedelta_raster + The amount of time needed to complete one raster + timedelta_slew + The amount of time needed to slew before the observation begins + + Examples + -------- + Determine how many times we can repeat a 1-hour raster from 00:00 to 04:00 + + .. jupyter-execute:: + + import astropy.units as u + import iris + + iris.planning.num_repeats( + time_start="2024-01-01T00:00", + time_stop="2024-01-01T04:00", + timedelta_raster=1 * u.hr, + ) + """ if not isinstance(time_start, astropy.time.Time): time_start = astropy.time.Time(time_start) if not isinstance(time_stop, astropy.time.Time): time_stop = astropy.time.Time(time_stop) - result = (time_stop - time_start - time_slew) / time_raster - result = result.to(u.dimensionless_unscaled) + timedelta_full = time_stop - time_start + result = (timedelta_full - timedelta_slew) / timedelta_raster + result = result.to(u.dimensionless_unscaled).value return result