Skip to content

Commit

Permalink
Documentation refactor + nitpicky + example review + chaos (#318)
Browse files Browse the repository at this point in the history
Aim to add more info about using aiapy and reduce any overlap with the
sunpy development documentation.

TODO:
- [ ] Work out what could be missing and fix it.

---------

Co-authored-by: Will Barnes <will.t.barnes@gmail.com>
  • Loading branch information
nabobalis and wtbarnes authored May 11, 2024
1 parent f92240a commit ae48fd4
Show file tree
Hide file tree
Showing 61 changed files with 1,115 additions and 850 deletions.
11 changes: 5 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
toxdeps: tox-pypi-filter
posargs: -n auto
envs: |
- linux: py311
- linux: py312
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

Expand All @@ -42,15 +42,15 @@ jobs:
posargs: -n auto
envs: |
- windows: py310
- macos: py39
- macos: py311
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

docs:
needs: [core]
uses: OpenAstronomy/github-actions-workflows/.github/workflows/tox.yml@main
with:
default_python: "3.9"
default_python: "3.12"
submodules: false
pytest: false
toxdeps: tox-pypi-filter
Expand All @@ -69,13 +69,12 @@ jobs:
needs: [docs]
uses: OpenAstronomy/github-actions-workflows/.github/workflows/tox.yml@main
with:
default_python: "3.9"
submodules: false
coverage: codecov
toxdeps: tox-pypi-filter
posargs: -n auto --dist loadgroup
envs: |
- linux: py39-online
- linux: py312-online
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

Expand All @@ -95,7 +94,7 @@ jobs:
needs: [test]
uses: OpenAstronomy/github-actions-workflows/.github/workflows/publish_pure_python.yml@main
with:
python-version: "3.10"
python-version: "3.12"
test_extras: "all,tests"
test_command: 'pytest -p no:warnings --doctest-rst -m "not mpl_image_compare" --pyargs sunpy'
submodules: false
Expand Down
35 changes: 18 additions & 17 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
exclude: ".*(.fits|.fts|.fit|.txt|.csv)$"
repos:
- repo: https://github.com/myint/docformatter
rev: v1.7.5
hooks:
- id: docformatter
args: [--in-place, --pre-summary-newline, --make-summary-multi]
args: ["--in-place", "--pre-summary-newline", "--make-summary-multi"]
- repo: https://github.com/myint/autoflake
rev: v2.2.1
rev: v2.3.1
hooks:
- id: autoflake
args:
Expand All @@ -17,29 +16,31 @@ repos:
]
exclude: ".*(.fits|.fts|.fit|.txt|tca.*|extern.*|.rst|.md|docs/conf.py)$"
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: "v0.1.8"
rev: "v0.4.4"
hooks:
- id: ruff
args: ["--fix", "--unsafe-fixes"]
- repo: https://github.com/psf/black
rev: 23.12.0
hooks:
- id: black
- repo: https://github.com/PyCQA/isort
rev: 5.13.2
hooks:
- id: isort
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v3.1.0
hooks:
- id: prettier
- id: ruff-format
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
rev: v4.6.0
hooks:
- id: check-ast
- id: check-case-conflict
- id: trailing-whitespace
exclude: ".*(.fits|.fts|.fit|.txt|.csv)$"
- id: mixed-line-ending
exclude: ".*(.fits|.fts|.fit|.txt|.csv)$"
- id: end-of-file-fixer
exclude: ".*(.fits|.fts|.fit|.txt|.csv)$"
- id: check-yaml
- id: debug-statements
- repo: https://github.com/codespell-project/codespell
rev: v2.2.6
hooks:
- id: codespell
additional_dependencies:
- tomli
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v4.0.0-alpha.8
hooks:
- id: prettier
4 changes: 2 additions & 2 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,8 @@ Features
- Added a function (``aiapy.calibrate.normalize_exposure``) to normalize an image by its exposure time. (`#78 <https://gitlab.com/LMSAL_HUB/aia_hub/aiapy/-/merge_requests/78>`__)
- :func:`aiapy.calibrate.degradation` can now accept `~astropy.time.Time` objects with length greater than 1.
This makes it easier to compute the channel degradation over long intervals. (`#80 <https://gitlab.com/LMSAL_HUB/aia_hub/aiapy/-/merge_requests/80>`__)
- Citation information for `aiapy` is now available from `aiapy.__citation__`. (`#82 <https://gitlab.com/LMSAL_HUB/aia_hub/aiapy/-/merge_requests/82>`__)
- The pointing table can now be passsed in as a keyword argument to :func:`aiapy.calibrate.update_pointing`.
- Citation information for `aiapy` is now available from ``aiapy.__citation__``. (`#82 <https://gitlab.com/LMSAL_HUB/aia_hub/aiapy/-/merge_requests/82>`__)
- The pointing table can now be passed in as a keyword argument to :func:`aiapy.calibrate.update_pointing`.
Added a :func:`aiapy.calibrate.util.get_pointing_table` to retrieve the 3-hour pointing table from JSOC over a given time interval. (`#84 <https://gitlab.com/LMSAL_HUB/aia_hub/aiapy/-/merge_requests/84>`__)

Bug Fixes
Expand Down
2 changes: 1 addition & 1 deletion aiapy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from pathlib import Path
from itertools import compress
from pathlib import Path

from .version import version as __version__

Expand Down
11 changes: 6 additions & 5 deletions aiapy/calibrate/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
"""
Subpackage for calibrating AIA imaging data.
"""
from .meta import * # NOQA
from .prep import * # NOQA
from .spikes import * # NOQA
from .transform import * # NOQA
from .uncertainty import * # NOQA

from .meta import * # NOQA: F403
from .prep import * # NOQA: F403
from .spikes import * # NOQA: F403
from .transform import * # NOQA: F403
from .uncertainty import * # NOQA: F403
71 changes: 46 additions & 25 deletions aiapy/calibrate/meta.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Functions for updating/fixing header keywords.
"""

import copy
import warnings

Expand All @@ -25,13 +26,20 @@ def fix_observer_location(smap):
keywords using the heliocentric aries ecliptic keywords, ``HAEX_OBS,
HAEY_OBS, HAEZ_OBS``.
.. note:: `~sunpy.map.sources.AIAMap` already accounts for the inaccurate
HGS keywords by using the HAE keywords to construct the
derived observer location.
.. note::
`~sunpy.map.sources.AIAMap` already accounts for the inaccurate
HGS keywords by using the HAE keywords to construct the
derived observer location.
Parameters
----------
smap : `~sunpy.map.source.sdo.AIAMap`
smap : `~sunpy.map.sources.AIAMap`
Input map.
Returns
-------
`~sunpy.map.sources.AIAMap`
"""
# Create observer coordinate from HAE coordinates
coord = SkyCoord(
Expand All @@ -48,48 +56,60 @@ def fix_observer_location(smap):
new_meta["hglt_obs"] = coord.lat.to(u.degree).value
new_meta["dsun_obs"] = coord.radius.to(u.m).value

return smap._new_instance(smap.data, new_meta, plot_settings=smap.plot_settings, mask=smap.mask)
return smap._new_instance(smap.data, new_meta, plot_settings=smap.plot_settings, mask=smap.mask) # NOQA: SLF001


def update_pointing(smap, *, pointing_table=None):
"""
Update pointing information in the `smap` header.
Update the pointing information in the input map header.
This function updates the pointing information in `smap` by
This function updates the pointing information in ``smap`` by
updating the ``CRPIX1, CRPIX2, CDELT1, CDELT2, CROTA2`` keywords
in the header using the information provided in `pointing_table`.
If `pointing_table` is not specified, the 3-hour pointing
in the header using the information provided in ``pointing_table``.
If ``pointing_table`` is not specified, the 3-hour pointing
information is queried from the `JSOC <http://jsoc.stanford.edu/>`_.
.. note:: The method removes any ``PCi_j`` matrix keys in the header and
updates the ``CROTA2`` keyword.
.. note::
The method removes any ``PCi_j`` matrix keys in the header and
updates the ``CROTA2`` keyword.
.. note::
If correcting pointing information for a large number of images,
it is strongly recommended to query the table once for the
appropriate interval and then pass this table in rather than
executing repeated queries.
.. warning::
.. note:: If correcting pointing information for a large number of images,
it is strongly recommended to query the table once for the
appropriate interval and then pass this table in rather than
executing repeated queries.
This function is only intended to be used for full-disk images
at the full resolution of 4096x4096 pixels. It will raise a
``ValueError`` if the input map does not meet these criteria.
Parameters
----------
smap : `~sunpy.map.sources.sdo.AIAMap`
smap : `~sunpy.map.sources.AIAMap`
Input map.
pointing_table : `~astropy.table.QTable`, optional
Table of pointing information. If not specified, the table
will be retrieved from JSOC.
Returns
-------
`~sunpy.map.sources.sdo.AIAMap`
`~sunpy.map.sources.AIAMap`
See Also
--------
aiapy.calibrate.util.get_pointing_table
`aiapy.calibrate.util.get_pointing_table`
"""
# This function can only be applied to full-resolution, full-frame images
if not contains_full_disk(smap):
raise ValueError("Input must be a full disk image.")
msg = "Input must be a full disk image."
raise ValueError(msg)
shape_full_frame = (4096, 4096)
if not all(d == (s * u.pixel) for d, s in zip(smap.dimensions, shape_full_frame)):
raise ValueError(f"Input must be at the full resolution of {shape_full_frame}")
if not all(d == (s * u.pixel) for d, s in zip(smap.dimensions, shape_full_frame, strict=True)):
msg = f"Input must be at the full resolution of {shape_full_frame}"
raise ValueError(msg)
if pointing_table is None:
# Make range wide enough to get closest 3-hour pointing
pointing_table = get_pointing_table(smap.date - 12 * u.h, smap.date + 12 * u.h)
Expand All @@ -116,11 +136,12 @@ def update_pointing(smap, *, pointing_table=None):
t_obs = astropy.time.Time(t_obs)
t_obs_in_interval = np.logical_and(t_obs >= pointing_table["T_START"], t_obs < pointing_table["T_STOP"])
if not t_obs_in_interval.any():
raise IndexError(
msg = (
f"No valid entries for {t_obs} in pointing table "
f'with first T_START date of {pointing_table[0]["T_START"]} '
f'and a last T_STOP date of {pointing_table[-1]["T_STOP"]}.',
f'and a last T_STOP date of {pointing_table[-1]["T_STOP"]}.'
)
raise IndexError(msg)
i_nearest = np.where(t_obs_in_interval)[0][0]
w_str = f"{smap.wavelength.to(u.angstrom).value:03.0f}"
new_meta = copy.deepcopy(smap.meta)
Expand Down Expand Up @@ -167,4 +188,4 @@ def update_pointing(smap, *, pointing_table=None):
new_meta.pop("PC1_2")
new_meta.pop("PC2_1")
new_meta.pop("PC2_2")
return smap._new_instance(smap.data, new_meta, plot_settings=smap.plot_settings, mask=smap.mask)
return smap._new_instance(smap.data, new_meta, plot_settings=smap.plot_settings, mask=smap.mask) # NOQA: SLF001
40 changes: 21 additions & 19 deletions aiapy/calibrate/prep.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Functions for calibrating AIA images.
"""

import warnings

import astropy.units as u
Expand All @@ -20,13 +21,13 @@
@add_common_docstring(rotation_function_names=_rotation_function_names)
def register(smap, *, missing=None, order=3, method="scipy"):
"""
Processes a full-disk level 1 `~sunpy.map.sources.sdo.AIAMap` into a level
1.5 `~sunpy.map.sources.sdo.AIAMap`.
Processes a full-disk level 1 `~sunpy.map.sources.AIAMap` into a level
1.5 `~sunpy.map.sources.AIAMap`.
Rotates, scales and translates the image so that solar North is aligned
with the y axis, each pixel is 0.6 arcsec across, and the center of the
Sun is at the center of the image. The actual transformation is done by
the `~sunpy.map.mapbase.GenericMap.rotate` method.
the `~sunpy.map.GenericMap.rotate` method.
.. warning::
Expand All @@ -48,7 +49,7 @@ def register(smap, *, missing=None, order=3, method="scipy"):
Parameters
----------
smap : `~sunpy.map.sources.sdo.AIAMap` or `~sunpy.map.sources.sdo.HMIMap`
smap : `~sunpy.map.sources.AIAMap` or `~sunpy.map.sources.sdo.HMIMap`
A `~sunpy.map.Map` containing a full-disk AIA image or HMI magnetogram
missing : `float`, optional
If there are missing values after the interpolation, they will be
Expand All @@ -61,17 +62,19 @@ def register(smap, *, missing=None, order=3, method="scipy"):
Returns
-------
`~sunpy.map.sources.sdo.AIAMap` or `~sunpy.map.sources.sdo.HMIMap`:
A level 1.5 copy of `~sunpy.map.sources.sdo.AIAMap` or
`~sunpy.map.sources.AIAMap` or `~sunpy.map.sources.sdo.HMIMap`:
A level 1.5 copy of `~sunpy.map.sources.AIAMap` or
`~sunpy.map.sources.sdo.HMIMap`.
"""
# This implementation is taken directly from the `aiaprep` method in
# sunpy.instr.aia.aiaprep under the terms of the BSD 2 Clause license.
# See licenses/SUNPY.rst.
if not isinstance(smap, (AIAMap, HMIMap)):
raise ValueError("Input must be an AIAMap or HMIMap.")
if not isinstance(smap, AIAMap | HMIMap):
msg = "Input must be an AIAMap or HMIMap."
raise TypeError(msg)
if not contains_full_disk(smap):
raise ValueError("Input must be a full disk image.")
msg = "Input must be a full disk image."
raise ValueError(msg)
if smap.processing_level is None or smap.processing_level > 1:
warnings.warn(
"Image registration should only be applied to level 1 data",
Expand Down Expand Up @@ -121,7 +124,7 @@ def correct_degradation(smap, *, correction_table=None, calibration_version=None
Parameters
----------
smap : `~sunpy.map.sources.sdo.AIAMap`
smap : `~sunpy.map.sources.AIAMap`
Map to be corrected.
correction_table : `~astropy.table.Table` or `str`, optional
Table of correction parameters or path to correction table file.
Expand All @@ -138,7 +141,7 @@ def correct_degradation(smap, *, correction_table=None, calibration_version=None
Returns
-------
`~sunpy.map.sources.sdo.AIAMap`
`~sunpy.map.sources.AIAMap`
See Also
--------
Expand Down Expand Up @@ -167,20 +170,20 @@ def degradation(
The correction factor to account for the time-varying degradation of
the telescopes is given by a normalization to the calibration epoch
closest to `obstime` and an interpolation within that epoch to
`obstime`,
closest to ``obstime`` and an interpolation within that epoch to
``obstime``,
.. math::
\frac{A_{eff}(t_{e})}{A_{eff}(t_0)}(1 + p_1\delta t + p_2\delta t^2 + p_3\delta t^3)
where :math:`A_{eff}(t_e)` is the effective area calculated at the
calibration epoch for `obstime`, :math:`A_{eff}(t_0)` is the effective
calibration epoch for ``obstime``, :math:`A_{eff}(t_0)` is the effective
area at the first calibration epoch (i.e. at launch),
:math:`p_1,p_2,p_3` are the interpolation coefficients for the
`obstime` epoch, and :math:`\delta t` is the difference between the
start time of the epoch and `obstime`.
All calibration terms are taken from the `aia.response` series in JSOC
``obstime`` epoch, and :math:`\delta t` is the difference between the
start time of the epoch and ``obstime``.
All calibration terms are taken from the ``aia.response`` series in JSOC
or read from the table input by the user.
.. note:: This function is adapted directly from the
Expand All @@ -206,8 +209,7 @@ def degradation(
See Also
--------
degradation
aiapy.calibrate.get_correction_table
aiapy.calibrate.util.get_correction_table
aiapy.response.Channel.wavelength_response
aiapy.response.Channel.eve_correction
"""
Expand Down
Loading

0 comments on commit ae48fd4

Please sign in to comment.