22 __all__ = (
"FitsRawFormatterBase",)
24 from abc
import ABCMeta, abstractmethod
26 from astro_metadata_translator
import ObservationInfo
31 from lsst.daf.butler
import FileDescriptor
32 from lsst.daf.butler.formatters.fitsExposureFormatter
import FitsExposureFormatter
40 """Abstract base class for reading and writing raw data to and from 49 def fromMetadata(cls, metadata, obsInfo=None, storageClass=None, location=None):
50 """Construct a possibly-limited formatter from known metadata. 54 metadata : `lsst.daf.base.PropertyList` 55 Raw header metadata, with any fixes (see 56 `astro_metadata_translator.fix_header`) applied but nothing 58 obsInfo : `astro_metadata_translator.ObservationInfo`, optional 59 Structured information already extracted from ``metadata``. 60 If not provided, will be read from ``metadata`` on first use. 61 storageClass : `lsst.daf.butler.StorageClass`, optional 62 StorageClass for this file. If not provided, the formatter will 63 only support `makeWcs`, `makeVisitInfo`, `makeFilter`, and other 64 operations that operate purely on metadata and not the actual file. 65 location : `lsst.daf.butler.Location`, optional. 66 Location of the file. If not provided, the formatter will only 67 support `makeWcs`, `makeVisitInfo`, `makeFilter`, and other 68 operations that operate purely on metadata and not the actual file. 72 formatter : `FitsRawFormatterBase` 73 An instance of ``cls``. 75 self = cls(FileDescriptor(location, storageClass))
83 """`~astro_metadata_translator.MetadataTranslator` to translate 84 metadata header to `~astro_metadata_translator.ObservationInfo`. 88 _observationInfo =
None 93 """`~lsst.obs.base.FilterDefinitions`, defining the filters for this 99 """Read just the image component of the Exposure. 103 image : `~lsst.afw.image.Image` 104 In-memory image component. 106 return lsst.afw.image.ImageU(self.fileDescriptor.location.path)
109 """Read just the mask component of the Exposure. 111 May return None (as the default implementation does) to indicate that 112 there is no mask information to be extracted (at least not trivially) 113 from the raw data. This will prohibit direct reading of just the mask, 114 and set the mask of the full Exposure to zeros. 118 mask : `~lsst.afw.image.Mask` 119 In-memory mask component. 124 """Read just the variance component of the Exposure. 126 May return None (as the default implementation does) to indicate that 127 there is no variance information to be extracted (at least not 128 trivially) from the raw data. This will prohibit direct reading of 129 just the variance, and set the variance of the full Exposure to zeros. 133 image : `~lsst.afw.image.Image` 134 In-memory variance component. 139 """Boolean to determine if the exposure is thought to be on the sky. 144 Returns `True` if the observation looks like it was taken on the 145 sky. Returns `False` if this observation looks like a calibration 150 If there is tracking RA/Dec information associated with the 151 observation it is assumed that the observation is on sky. 152 Currently the observation type is not checked. 159 """Remove metadata entries that are parsed into components. 168 """Construct a VisitInfo from metadata. 172 visitInfo : `~lsst.afw.image.VisitInfo` 173 Structured metadata about the observation. 175 return MakeRawVisitInfoViaObsInfo.observationInfo2visitInfo(self.
observationInfo)
179 """Return the detector that acquired this raw exposure. 184 The identifying number of the detector to get. 188 detector : `~lsst.afw.cameraGeom.Detector` 189 The detector associated with that ``id``. 191 raise NotImplementedError(
"Must be implemented by subclasses.")
194 """Create a SkyWcs from information about the exposure. 196 If VisitInfo is not None, use it and the detector to create a SkyWcs, 197 otherwise return the metadata-based SkyWcs (always created, so that 198 the relevant metadata keywords are stripped). 202 visitInfo : `~lsst.afw.image.VisitInfo` 203 The information about the telescope boresight and camera 204 orientation angle for this exposure. 205 detector : `~lsst.afw.cameraGeom.Detector` 206 The detector used to acquire this exposure. 210 skyWcs : `~lsst.afw.geom.SkyWcs` 211 Reversible mapping from pixel coordinates to sky coordinates. 216 Raised if there is an error generating the SkyWcs, chained from the 217 lower-level exception if available. 225 log = lsst.log.Log.getLogger(
"fitsRawFormatter")
226 if visitInfo
is None:
227 msg =
"No VisitInfo; cannot access boresight information. Defaulting to metadata-based SkyWcs." 231 "See warnings in log messages for details.")
237 def _createSkyWcsFromMetadata(self):
238 """Create a SkyWcs from the FITS header metadata in an Exposure. 242 skyWcs: `lsst.afw.geom.SkyWcs`, or None 243 The WCS that was created from ``self.metadata``, or None if that 244 creation fails due to invalid metadata. 251 return lsst.afw.geom.makeSkyWcs(self.metadata, strip=
True)
252 except TypeError
as e:
253 log = lsst.log.Log.getLogger(
"fitsRawFormatter")
254 log.warn(
"Cannot create a valid WCS from metadata: %s", e.args[0])
258 """Construct a Filter from metadata. 262 filter : `~lsst.afw.image.Filter` 263 Object that identifies the filter for this image. 268 Raised if the physical filter was not registered via 269 `~lsst.afw.image.utils.defineFilter`. 274 """Read the image, mask, or variance component of an Exposure. 278 component : `str`, optional 279 Component to read from the file. Always one of "image", 280 "variance", or "mask". 284 image : `~lsst.afw.image.Image` or `~lsst.afw.image.Mask` 285 In-memory image, variance, or mask component. 287 if component ==
"image":
289 elif component ==
"mask":
291 elif component ==
"variance":
295 """Read a component held by ExposureInfo. 297 The implementation provided by FitsRawFormatter provides only "wcs" 298 and "visitInfo". When adding support for other components, subclasses 299 should delegate to `super()` for those and update `readFull` with 304 component : `str`, optional 305 Component to read from the file. 309 obj : component-dependent 310 In-memory component object. 312 if component ==
"filter":
314 elif component ==
"visitInfo":
316 elif component ==
"wcs":
319 return self.
makeWcs(visitInfo, detector)
323 """Read the full Exposure object. 327 parameters : `dict`, optional 328 If specified, a dictionary of slicing parameters that overrides 329 those in the `fileDescriptor` attribute. 333 exposure : `~lsst.afw.image.Exposure` 334 Complete in-memory exposure. 336 from lsst.afw.image
import makeExposure, makeMaskedImage
337 full = makeExposure(makeMaskedImage(self.
readImage()))
342 if variance
is not None:
343 full.setVariance(variance)
345 info = full.getInfo()
348 info.setWcs(self.
makeWcs(info.getVisitInfo(), info.getDetector()))
351 full.setMetadata(self.metadata)
355 """Read the SkyWcs stored in the un-modified raw FITS WCS header keys. 357 return lsst.afw.geom.makeSkyWcs(lsst.afw.fits.readMetadata(self.fileDescriptor))
360 """Write a Python object to a file. 364 inMemoryDataset : `object` 365 The Python object to store. 370 The `URI` where the primary file is stored. 372 raise NotImplementedError(
"Raw data cannot be `put`.")
376 """The `~astro_metadata_translator.ObservationInfo` extracted from 377 this file's metadata (`~astro_metadata_translator.ObservationInfo`,
def createInitialSkyWcs(visitInfo, detector, flipX=False)