Source code for kbmod.standardizers.fits_standardizers.multi_extension_fits

"""Standardizer for FITS files containing multiple extensions."""

from astropy.io.fits import CompImageHDU, PrimaryHDU, ImageHDU

from .fits_standardizer import FitsStandardizer, FitsStandardizerConfig


__all__ = [
    "MultiExtensionFits",
]


[docs]class MultiExtensionFits(FitsStandardizer): """Suppports processing of a single, multi-extension FITS file. Extensions for which it's possible to extract WCS, bounding boxes and masks are required to be places in the ``exts`` attribute. For single extension FITS files this is the primary header, as it contains the image data. Parameters ---------- location : `str` Location of the FITS file, can be an URI or local filesystem path. set_exts : `bool` When `True`, finds all HDUs that are image-like and sets them as elements of `exts` list. Note that using the default `_isImageLike` implementation is rather costly as it loads the whole data into memory. Attributes ---------- hdulist : `~astropy.io.fits.HDUList` All HDUs found in the FITS file primary : `~astropy.io.fits.PrimaryHDU` The primary HDU. exts : `list` All HDUs from `hdulist` marked as "image-like" for further processing with KBMOD. Does not include the primary HDU, when it doesn't contain any image data. Contains at least 1 entry. wcs : `list` WCSs associated with the processable image data. Will contain at least 1 WCS. bbox : `list` Bounding boxes associated with each WCS. """ # Standardizers we don't want to register themselves we leave nameless # Since FitsStd isn't usable by itself - we do not register it. # name = "MultiExtensionFitsStandardizer" # priority = 1 configClass = FitsStandardizerConfig @staticmethod def _isImageLikeHDU(hdu): """If the given HDU contains an image, returns `True`, otherwise `False`. HDU is determined to be an image if it's one of the primary, image or compressed image types in Astropy and its ``.data`` attribute is not empty, but a 2D array with dimensions less than 6000 rows and columns. This is a generic best-guess implementation and there are no guarantees that the retrieved extensions are science images, i.e. images containing the actual sky, and not a small table-like HDU, guider or focus chip images. Parameters ---------- hdu : `astropy.fits.HDU` Header unit to inspect. Returns ------- image_like : `bool` True if HDU is image-like, False otherwise. """ # This is already a pretty good basic test if not any((isinstance(hdu, CompImageHDU), isinstance(hdu, PrimaryHDU), isinstance(hdu, ImageHDU))): return False # The problem is that all kinds of things are stored as ImageHDUs, say # a 120k x 8000k table (I'm looking at you SDSS!). To avoid that we # need to check the data shape. The problem is that causes the data to # load from disk and that is very expensive if len(hdu.shape) != 2: return False if hdu.shape[0] > 6000 or hdu.shape[1] > 6000: return False if hdu.data is None: return False return True
[docs] @classmethod def resolveTarget(cls, tgt): parentCanStandardize, res = super().resolveTarget(tgt) if not parentCanStandardize: return False, {} canStandardize = parentCanStandardize and len(res["hdulist"]) > 1 return canStandardize, res
def __init__(self, location=None, hdulist=None, config=None, set_processable=False, **kwargs): super().__init__(location=location, hdulist=hdulist, config=config, **kwargs) # do not load images from disk unless requested if set_processable: for hdu in self.hdulist: if self._isImageLikeHDU(hdu): self.processable.append(hdu)