Skip to content

Commit

Permalink
Merge pull request #383 from mkelley/optional-dependencies-2023.07
Browse files Browse the repository at this point in the history
Limit dependencies to strictly necessary packages.
  • Loading branch information
mkelley authored Jan 10, 2024
2 parents ca24266 + e342b89 commit 1315915
Show file tree
Hide file tree
Showing 59 changed files with 1,153 additions and 581 deletions.
54 changes: 27 additions & 27 deletions .github/workflows/ci_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ name: CI Tests
on:
push:
branches:
- main
- main
tags:
- '*'
- "*"
pull_request:
# branches: # only build on PRs against 'main' if you need to further limit when CI is run.
# - main
Expand All @@ -34,45 +34,45 @@ jobs:
ARCH_ON_CI: "normal"
IS_CRON: "false"
submodules: false
coverage: ''
coverage: ""
envs: |
- name: Code style checks
linux: codestyle
- name: Python 3.11 with minimal dependencies and full coverage
- name: Python 3.11 with minimal dependencies, measuring coverage
linux: py311-test-cov
coverage: codecov
- name: Python 3.10 with all optional dependencies
linux: py310-test-alldeps
- name: Python 3.10 with all optional dependencies, measuring coverage
linux: py310-test-alldeps-cov
coverage: codecov
- name: Python 3.8 with oldest supported versions
linux: py38-test-oldestdeps
coverage: codecov
macos-tests:
name: Python 3.10 with all optional dependencies (MacOS)
runs-on: macos-latest
env:
ARCH_ON_CI: "normal"
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up python
uses: actions/setup-python@v4
with:
python-version: "3.10"
- name: Set up gfortran on ${{ matrix.os }}
if: runner.os == 'macos'
run: |
echo `which gfortran-11`
sudo ln -sfn /usr/local/bin/gfortran-11 /usr/local/bin/gfortran
gfortran --version
- name: Install base dependencies
run: |
python -m pip install --upgrade pip
python -m pip install tox
- name: Test with tox
run: tox -e py310-test-alldeps
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up python
uses: actions/setup-python@v4
with:
python-version: "3.10"
- name: Set up gfortran on ${{ matrix.os }}
if: runner.os == 'macos'
run: |
echo `which gfortran-11`
sudo ln -sfn /usr/local/bin/gfortran-11 /usr/local/bin/gfortran
gfortran --version
- name: Install base dependencies
run: |
python -m pip install --upgrade pip
python -m pip install tox
- name: Test with tox
run: tox -e py310-test-alldeps
43 changes: 43 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,46 @@
0.5.0 (unreleased)
==================

- Revised required and optional packages:

- Only numpy and astropy are required; scipy, synphot, ads, and astroquery are
now optional dependences.

- Created an option to install a recommended list of packages, e.g., ``pip
install sbpy[recommended]``.


New Features
------------

sbpy.utils
^^^^^^^^^^

- New `required_packages` and `optional_packages` functions to test for the
presence of required and optional packages.

sbpy.utils.decorators
^^^^^^^^^^^^^^^^^^^^^

- New `requires` and `optionally_uses` function decorators to simplify testing
for required and optional packages.


API Changes
-----------

sbpy.sources
^^^^^^^^^^^^
* Deprecated ``SynphotRequired``. Use ``sbpy.execptions.RequiredPackageUnavailable``.


Bug Fixes
---------
* ``sbpy.sources.SpectralSource`` now correctly raises
``RequiredPackageUnavailable`` when ``synphot`` is not available, replacing a
locally defined ``SynphotRequired`` or the generic ``ImportError``.


0.4.0 (2023-06-30)
==================

Expand Down
9 changes: 6 additions & 3 deletions docs/development/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,12 @@ Technical requirements
* customized exceptions and warnings are encouraged, and should
ultimately be derived from the base classes in `sbpy.exceptions`
* if you use `~sbpy.data.DataClass` objects, extend the :ref:`field
name list` list where it makes sense
* a CHANGELOG entry is required as of v0.2; update the :doc:`/status`
where applicable
name list` list where it makes sense
* consider using the sbpy function and decorator helpers to test for the
presence of optional dependencies:
* `~sbpy.utils.required_packages` and `[email protected]` raise an exception if a package cannot be imported.
* `~sbpy.utils.optional_packages` and `[email protected]_uses` warn the user if a package cannot be imported.
* a CHANGELOG entry is required; also update the :doc:`/status` where applicable



Expand Down
18 changes: 12 additions & 6 deletions docs/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,26 @@ Requirements
care of with installation using pip:

* Python 3.8 or later
* `ads <https://github.com/andycasey/ads/>`__ 0.12 or later, to fetch citation details for bibliography tracking.
* `astropy <https://www.astropy.org/>`__ 4.3 or later.
* `astroquery <https://astroquery.readthedocs.io/en/latest/>`__ 0.4.5 or later, for retrieval of online data, e.g., ephemerides and orbits.
* `numpy <https://numpy.org/>`__ 1.18 or later.
* `scipy <https://scipy.org/>`__: 1.3 or later, for numerical integrations in `sbpy.activity.gas` and `sbpy.photometry`, among others.
* `synphot <https://github.com/spacetelescope/synphot_refactor>`__ 1.1.1 or later, for calibration with respect to the Sun and Vega, filtering spectra through bandpasses.

Optional dependencies
^^^^^^^^^^^^^^^^^^^^^

* `ads <https://github.com/andycasey/ads/>`__ 0.12 or later, to fetch citation details for bibliography tracking. **Recommended**
* `astroquery <https://astroquery.readthedocs.io/en/latest/>`__ 0.4.5 or later, for retrieval of online data, e.g., ephemerides and orbits. **Recommended**
* Python extensions for `oorb <https://github.com/oorb/oorb/>`__: For orbit
transformations (`~sbpy.data.Orbit.oo_transform`) and propagations
(`~sbpy.data.Orbit.oo_propagate`), as well as ephemerides calculations
(`~sbpy.data.Ephem.from_oo`).
* `pyradex <https://github.com/keflavich/pyradex>`__: For non-LTE production
rate calculations related to cometary activity (`~sbpy.activity.gas.NonLTE`).
* `ginga <https://ejeschke.github.io/ginga/>`__ and `photutils
<https://photutils.readthedocs.io/en/stable/>`__: To interactively enhance
* `scipy <https://scipy.org/>`__: 1.3 or later, for numerical integrations in `sbpy.activity.gas` and `sbpy.photometry`, among others. **Recommended**
* `synphot <https://github.com/spacetelescope/synphot_refactor>`__ 1.1.1 or later, for calibration with respect to the Sun and Vega, filtering spectra through bandpasses. **Recommended**
* `ginga <https://ejeschke.github.io/ginga/>`__ : To interactively enhance
images of comets with the `~sbpy.imageanalysis.CometaryEnhancement` Ginga
plugin.
* `photutils <https://photutils.readthedocs.io/en/stable/>`__: For centroiding within the Cometary Enhancements Ginga plugin.


Using pip
Expand All @@ -40,6 +40,12 @@ The latest stable version of `sbpy` can be installed with:
$ pip install sbpy
Recommended dependencies may be installed via:

.. code-block:: bash
$ pip install sbpy[recommended]
Most optional dependencies may be installed via:

.. code-block:: bash
Expand Down
6 changes: 6 additions & 0 deletions docs/sbpy/activity/dust.rst
Original file line number Diff line number Diff line change
Expand Up @@ -147,18 +147,24 @@ Phase angles and functions

Phase angle was not used in the previous section. In the *Afρ* formalism, "albedo" includes the scattering phase function, and is more precisely written *A(θ)*, where *θ* is the phase angle. The default behavior for `Afrho` is to compute *A(θ)fρ* as opposed to *A(0°)fρ*. Returning to the A'Hearn et al. data, we scale *Afρ* to 0° from 3.3° phase using the :func:`~sbpy.activity.Afrho.to_phase` method:

.. doctest-requires:: scipy

>>> afrho = Afrho(6029.9 * u.cm)
>>> print(afrho.to_phase(0 * u.deg, 3.3 * u.deg)) # doctest: +FLOAT_CMP
6886.825981017757 cm

The default phase function is the Halley-Marcus composite phase function (:func:`~sbpy.activity.phase_HalleyMarcus`). Any function or callable object that accepts an angle as a `~astropy.units.Quantity` and returns a scalar value may be used:

.. doctest-requires:: scipy

>>> Phi = lambda phase: 10**(-0.016 / u.deg * phase.to('deg'))
>>> print(afrho.to_phase(0 * u.deg, 3.3 * u.deg, Phi=Phi)) # doctest: +FLOAT_CMP
6809.419810008357 cm

To correct an observed flux density for the phase function, use the ``phasecor`` option of :func:`~sbpy.activity.Afrho.to_fluxd` and :func:`~sbpy.activity.Afrho.from_fluxd` methods:

.. doctest-requires:: scipy

>>> flam = 10**-13.99 * u.Unit('erg/(s cm2 AA)')
>>> aper = 27200 * u.km
>>> eph = Ephem.from_dict({
Expand Down
8 changes: 8 additions & 0 deletions docs/sbpy/activity/gas.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ Some sources provide values for the quiet and active Sun (Huebner et al. 1992):

With the :doc:`../bib`, the citation may be discovered:

.. doctest-requires:: ads

>>> from sbpy import bib
>>> bib.reset() # clear any old citations
>>> with bib.Tracking():
Expand Down Expand Up @@ -83,6 +85,8 @@ daughter species. It is included with some calculation enhancements based on
Newburn and Johnson (1978). With `~sbpy.activity.gas.Haser`, we may compute the
column density and total number of molecules within an aperture:

.. doctest-requires:: scipy

>>> Q = 1e28 / u.s # production rate
>>> v = 0.8 * u.km / u.s # expansion speed
>>> parent = gas.photo_lengthscale('H2O')
Expand All @@ -95,6 +99,8 @@ column density and total number of molecules within an aperture:

The gas coma models work with sbpy's apertures:

.. doctest-requires:: scipy

>>> from sbpy.activity import AnnularAperture
>>> ap = AnnularAperture((5000, 10000) * u.km)
>>> print(coma.total_number(ap)) # doctest: +FLOAT_CMP
Expand Down Expand Up @@ -126,6 +132,8 @@ number of molecules in an aperture. Parent and daughter data is provided via
| daughter | v_photo | m/s | photodissociation velocity (v_R) |
+------------------+-----------+------+-------------------------------------------------------+

.. doctest-requires:: scipy

>>> from sbpy.data import Phys
>>> water = Phys.from_dict({
... 'tau_T': gas.photo_timescale('H2O') * 0.8, # approximate
Expand Down
13 changes: 9 additions & 4 deletions docs/sbpy/calib.rst
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ The `~astropy.utils.state.ScienceState` objects `~sbpy.calib.solar_fluxd` and `~
>>> from sbpy.calib import Sun, solar_fluxd, vega_fluxd
>>> import sbpy.units as sbu

.. doctest-requires:: astropy>=5.3
.. doctest-requires:: astropy>=5.3

>>> from sbpy.calib import Sun, solar_fluxd, vega_fluxd
>>> import sbpy.units as sbu
Expand Down Expand Up @@ -184,13 +184,15 @@ When the requested spectral resolution is comparable to the spectral resolution

Compare interpolation and rebinning for the E490 low-resolution solar spectrum, using the stored wavelengths of the spectrum. Initialize a `~sbpy.calib.Sun` object with the low-resolution spectrum.

.. doctest-requires:: synphot

>>> import numpy as np
>>> from sbpy.calib import Sun
>>> sun = Sun.from_builtin('E490_2014LR')

Inspect a sub-set of the data for this example.

.. doctest-requires:: astropy>=5.3
.. doctest-requires:: astropy>=5.3, synphot

>>> wave = sun.wave[430:435]
>>> S = sun.fluxd[430:435]
Expand All @@ -202,23 +204,26 @@ Inspect a sub-set of the data for this example.
Interpolate with observe() and compare to the original values.

.. testsetup::
.. doctest-requires:: astropy<5.3
.. doctest-requires:: astropy<5.3, synphot

>>> wave = sun.wave[430:435]
>>> S = sun.fluxd[430:435]

>>> S_interp = sun.observe(wave, interpolate=True)
>>> np.allclose(S.value, S_interp.value)
True

Re-bin with observe using the same wavelengths as band centers.

.. doctest-requires:: synphot

>>> S_rebin = sun.observe(wave)
>>> np.allclose(S.value, S_rebin.value)
False

Inspect the differences.

.. doctest-requires:: synphot

>>> print((S_rebin - S) / (S_rebin + S) * 2) # doctest: +FLOAT_CMP
[-0.00429693 0.00281266 -0.00227604 0.00412338 -0.00132301]

Expand Down
14 changes: 12 additions & 2 deletions docs/sbpy/data/ephem.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ query for ephemerides of asteroid Ceres on a given date and for the position of
Mauna Kea Observatory (IAU observatory code 568) from the `JPL Horizons service
<https://ssd.jpl.nasa.gov/horizons/>`_:

.. .. doctest-requires:: astroquery
.. doctest-remote-data::

>>> from sbpy.data import Ephem
Expand All @@ -35,6 +36,7 @@ Mauna Kea Observatory (IAU observatory code 568) from the `JPL Horizons service
The full column name list in the data table can be retrieved with the
`~sbpy.data.DataClass.field_names` property:

.. .. doctest-requires:: astroquery
.. doctest-remote-data::

>>> eph.field_names
Expand All @@ -48,6 +50,7 @@ In the above example a specific epoch was specified, but multiple epochs may be
requested, or even a range of epochs. All time references are
`~astropy.time.Time` objects.

.. .. doctest-requires:: astroquery
.. doctest-remote-data::

>>> epochs = Time(['2022-06-04', '2023-06-04'])
Expand All @@ -67,6 +70,7 @@ than a few hundred to prevent corruption of the query (see

To specify a range of epochs:

.. .. doctest-requires:: astroquery
.. doctest-remote-data::

>>> import astropy.units as u
Expand Down Expand Up @@ -96,7 +100,8 @@ Mulitple targets
An additional feature of `~sbpy.data.Ephem.from_horizons` is that you can
automatically concatenate queries for a number of objects:

.. doctest-remote-data::
.. .. doctest-requires:: astroquery
.. doctest-remote-data::

>>> epoch1 = Time('2018-08-03 14:20')
>>> eph = Ephem.from_horizons(['Ceres', 'Pallas', 12893, '1983 SA'],
Expand Down Expand Up @@ -130,6 +135,7 @@ codes <https://www.minorplanetcenter.net/iau/lists/ObsCodesF.html>`__ as above,
or by using `~astropy.coordinates.EarthLocation` as shown in the following
example:

.. .. doctest-requires:: astroquery
.. doctest-remote-data::

>>> from astropy.coordinates import EarthLocation
Expand All @@ -155,6 +161,7 @@ to `~sbpy.data.Ephem.from_horizons` are directly passed on to
flexibility of the latter function. For example one may use the
``skip_daylight`` keyword argument:

.. .. doctest-requires:: astroquery
.. doctest-remote-data::

>>> epoch1 = Time('2018-08-03 14:20', scale='utc')
Expand All @@ -170,6 +177,7 @@ Or, a common option for periodic cometary targets is to limit orbit look-ups to
the apparition closest to the epochs being queried (requires
``id_type='designation'``):

.. .. doctest-requires:: astroquery
.. doctest-remote-data::

>>> eph = Ephem.from_horizons('2P') # doctest: +SKIP
Expand All @@ -196,12 +204,13 @@ Offering similar functionality, the `~sbpy.data.Ephem.from_mpc` method will
retrieve ephemerides from the `Minor Planet Center's Ephemeris Service
<https://minorplanetcenter.net/iau/MPEph/MPEph.html>`_:

.. .. doctest-requires:: astroquery
.. doctest-remote-data::

>>> eph = Ephem.from_mpc('2P', location='568',
... epochs={'start': Time('2018-10-22'),
... 'stop': Time('2018-10-26'),
... 'step': 1*u.day}) # doctest: +REMOTE_DATA
... 'step': 1*u.day})
>>> eph # doctest: +SKIP
<QTable length=5>
Targetname Date ... Moon distance Moon altitude
Expand All @@ -223,6 +232,7 @@ Finally, `~sbpy.data.Ephem.from_miriade` will retrieve ephemerides from the
`Institut de Mécanique Céleste et de Calcul des Éphémérides
<https://www.imcce.fr/>`_:

.. .. doctest-requires:: astroquery
.. doctest-remote-data::

>>> eph = Ephem.from_miriade('2P', objtype='comet', location='568',
Expand Down
Loading

0 comments on commit 1315915

Please sign in to comment.