Source code for aiapy.util.util

"""
Miscellaneous utility functions.
"""
import drms
import numpy as np

import astropy.units as u
from astropy.coordinates import SkyCoord
from astropy.time import Time
from sunpy.time import parse_time

from aiapy.util.decorators import validate_channel

__all__ = ["sdo_location", "telescope_number"]


[docs] def sdo_location(time): """ Returns the location of SDO at the given time. Parameters ---------- time : `astropy.time.Time` The time can also be supplied in a format compatible with :func:`sunpy.time.parse_time`. Returns ------- `astropy.coordinates.SkyCoord` Notes ----- This function performs a linear interpolation between the nearest DRMS records on either side of the given time. """ t = parse_time(time) # Query for +/- 3 seconds around the given time keys = drms.Client().query( f"aia.lev1[{(t - 3*u.s).utc.isot}/6s]", key="T_OBS, HAEX_OBS, HAEY_OBS, HAEZ_OBS", ) if keys is None or len(keys) == 0: raise ValueError("No DRMS records near this time") # Linear interpolation between the nearest records within the returned set times = Time(list(keys["T_OBS"]), scale="utc") x = np.interp(t.mjd, times.mjd, keys["HAEX_OBS"]) y = np.interp(t.mjd, times.mjd, keys["HAEY_OBS"]) z = np.interp(t.mjd, times.mjd, keys["HAEZ_OBS"]) return SkyCoord( x=x, y=y, z=z, unit=u.m, representation_type="cartesian", frame="heliocentricmeanecliptic", obstime=t, )
[docs] @u.quantity_input @validate_channel("channel") def telescope_number(channel: u.angstrom): """ For a given channel wavelength, return the associated telescope number. Parameters ---------- channel : `~astropy.units.Quantity` Wavelength of AIA channel. Returns ------- telescope_number : `int` The telescope number of the filter designated by ``channel`` """ return { 94 * u.angstrom: 4, 131 * u.angstrom: 1, 171 * u.angstrom: 3, 193 * u.angstrom: 2, 211 * u.angstrom: 2, 304 * u.angstrom: 4, 335 * u.angstrom: 1, 1600 * u.angstrom: 3, 1700 * u.angstrom: 3, 4500 * u.angstrom: 3, }[channel]