Source code for stixpy.product.sources.quicklook

import astropy.units as u
import numpy as np
from astropy.coordinates import SkyCoord
from astropy.time import Time
from astropy.units import Quantity
from numpy.typing import NDArray
from sunpy.time import TimeRange

from stixpy.coordinates.frames import STIXImaging
from stixpy.product.product import L1Product

THERMAL_INDEX_MAP = np.array(["None", "Minor", "Small", "Moderate", "Major"])
FLUX_INDEX_MAP = np.array(["None", "Weak", "Significant"])
LOCATION_INDEX_MAP = np.array(["None", "Previous", "New"])
TM_PROCESSING_STATUS = {
    0x01: "Imaging Started",
    0x02: "Imaging Ended",
    0x04: "Spectroscopy Started",
    0x08: "Spectroscopy Ended",
    0x10: "Publication Started",
    0x20: "Publication Ended",
    0x40: "Cancelled",
    0x80: "New Entry",
}

__all__ = ["QuickLookProduct", "QLLightCurve", "QLBackground", "QLVariance", "QLFlareFlag", "QLLightCurve"]


[docs] class QuickLookProduct(L1Product): """ Basic science data class """ @property def time(self) -> Time: return self.data["time"] @property def exposure_time(self) -> Quantity[u.s]: return self.data["timedel"].to(u.s) @property def time_range(self) -> TimeRange: """ A `sunpy.time.TimeRange` for the data. """ return TimeRange(self.time[0] - self.exposure_time[0] / 2, self.time[-1] + self.exposure_time[-1] / 2)
[docs] class QLLightCurve(QuickLookProduct): """ Quicklook Lightcurves nominal in 5 energy bins every 4s """
[docs] @classmethod def is_datasource_for(cls, *, meta, **kwargs): """Determines if meta data match""" service_subservice_ssid = tuple(meta[name] for name in ["STYPE", "SSTYPE", "SSID"]) level = meta["level"] if service_subservice_ssid == (21, 6, 30) and level == "L1": return True
def __repr__(self): return f"{self.__class__.__name__}\n {self.time_range}"
[docs] class QLBackground(QuickLookProduct): """ Quicklook Background nominal in 5 energy bins every 8s """
[docs] @classmethod def is_datasource_for(cls, *, meta, **kwargs): """Determines if meta data match""" service_subservice_ssid = tuple(meta[name] for name in ["STYPE", "SSTYPE", "SSID"]) level = meta["level"] if service_subservice_ssid == (21, 6, 31) and level == "L1": return True
def __repr__(self): return f"{self.__class__.__name__}\n {self.time_range}"
[docs] class QLVariance(QuickLookProduct): """ Quicklook variance nominally in 5 energy bins every 8s """
[docs] @classmethod def is_datasource_for(cls, *, meta, **kwargs): """Determines if meta data match""" service_subservice_ssid = tuple(meta[name] for name in ["STYPE", "SSTYPE", "SSID"]) level = meta["level"] if service_subservice_ssid == (21, 6, 33) and level == "L1": return True
def __repr__(self): return f"{self.__class__.__name__}\n {self.time_range}"
[docs] class QLFlareFlag(QuickLookProduct): """ Quicklook Flare flag and location """
[docs] @classmethod def is_datasource_for(cls, *, meta, **kwargs): """Determines if meta data match""" service_subservice_ssid = tuple(meta[name] for name in ["STYPE", "SSTYPE", "SSID"]) level = meta["level"] if service_subservice_ssid == (21, 6, 34) and level == "L1": return True
@property def thermal_index(self): r""" Flare thermal index - amount of thermal emission """ return THERMAL_INDEX_MAP[self.data["thermal_index"]] @property def flare_location(self) -> SkyCoord: r""" Flare location as` Notes ----- From STIX-TN-0109-FHNW_I3R3 `YLOS = -Ysc = -Yint` and `ZLOS = Zsc = Xint` """ return SkyCoord( self.data["loc_z"] * u.arcmin, -self.data["loc_y"] * u.arcmin, frame=STIXImaging(obstime=self.data["time"]) ) @property def non_thermal_index(self) -> NDArray[str]: r""" Flare non-thermal index - significant non-thermal emission """ return THERMAL_INDEX_MAP[self.data["non_thermal_index"]] @property def location_flag(self) -> NDArray[str]: r""" Flare location flag """ return THERMAL_INDEX_MAP[self.data["location_status"]] def __repr__(self): return f"{self.__class__.__name__}\n {self.time_range}"
class QLTMStatusFlareList(QuickLookProduct): """ Quicklook variance nominally in 5 energy bins every 8s """ @classmethod def is_datasource_for(cls, *, meta, **kwargs): """Determines if meta data match""" service_subservice_ssid = tuple(meta[name] for name in ["STYPE", "SSTYPE", "SSID"]) level = meta["level"] if service_subservice_ssid == (21, 6, 43) and level == "L1": return True @property def processing_status(self): r""" Processing status """ return [TM_PROCESSING_STATUS[status] for status in self.data["processing_mask"]] def __repr__(self): return f"{self.__class__.__name__}\n {self.time_range}"