LSST Applications  21.0.0+75b29a8a7f,21.0.0+e70536a077,21.0.0-1-ga51b5d4+62c747d40b,21.0.0-10-gbfb87ad6+3307648ee3,21.0.0-15-gedb9d5423+47cba9fc36,21.0.0-2-g103fe59+fdf0863a2a,21.0.0-2-g1367e85+d38a93257c,21.0.0-2-g45278ab+e70536a077,21.0.0-2-g5242d73+d38a93257c,21.0.0-2-g7f82c8f+e682ffb718,21.0.0-2-g8dde007+d179fbfa6a,21.0.0-2-g8f08a60+9402881886,21.0.0-2-ga326454+e682ffb718,21.0.0-2-ga63a54e+08647d4b1b,21.0.0-2-gde069b7+26c92b3210,21.0.0-2-gecfae73+0445ed2f95,21.0.0-2-gfc62afb+d38a93257c,21.0.0-27-gbbd0d29+ae871e0f33,21.0.0-28-g5fc5e037+feb0e9397b,21.0.0-3-g21c7a62+f4b9c0ff5c,21.0.0-3-g357aad2+57b0bddf0b,21.0.0-3-g4be5c26+d38a93257c,21.0.0-3-g65f322c+3f454acf5d,21.0.0-3-g7d9da8d+75b29a8a7f,21.0.0-3-gaa929c8+9e4ef6332c,21.0.0-3-ge02ed75+4b120a55c4,21.0.0-4-g3300ddd+e70536a077,21.0.0-4-g591bb35+4b120a55c4,21.0.0-4-gc004bbf+4911b9cd27,21.0.0-4-gccdca77+f94adcd104,21.0.0-4-ge8fba5a+2b3a696ff9,21.0.0-5-gb155db7+2c5429117a,21.0.0-5-gdf36809+637e4641ee,21.0.0-6-g00874e7+c9fd7f7160,21.0.0-6-g4e60332+4b120a55c4,21.0.0-7-gc8ca178+40eb9cf840,21.0.0-8-gfbe0b4b+9e4ef6332c,21.0.0-9-g2fd488a+d83b7cd606,w.2021.05
LSST Data Management Base Package
Public Member Functions | Static Public Attributes | List of all members
lsst.obs.base.formatters.fitsExposure.FitsImageFormatter Class Reference
Inheritance diagram for lsst.obs.base.formatters.fitsExposure.FitsImageFormatter:
lsst.obs.base.formatters.fitsExposure.FitsExposureFormatter

Public Member Functions

def metadata (self)
 
def readMetadata (self)
 
def stripMetadata (self)
 
def readComponent (self, component, parameters=None)
 
def readFull (self, parameters=None)
 
def read (self, component=None)
 
def write (self, inMemoryDataset)
 
def getImageCompressionSettings (self, recipeName)
 
def validateWriteRecipes (cls, recipes)
 

Static Public Attributes

 supportedExtensions = frozenset({".fits", ".fits.gz", ".fits.fz", ".fz", ".fit"})
 
string extension = ".fits"
 
 supportedWriteParameters = frozenset({"recipe"})
 
dictionary unsupportedParameters = {}
 

Detailed Description

Specialisation for `~lsst.afw.image.Image` reading.

Definition at line 421 of file fitsExposure.py.

Member Function Documentation

◆ getImageCompressionSettings()

def lsst.obs.base.formatters.fitsExposure.FitsExposureFormatter.getImageCompressionSettings (   self,
  recipeName 
)
inherited
Retrieve the relevant compression settings for this recipe.

Parameters
----------
recipeName : `str`
    Label associated with the collection of compression parameters
    to select.

Returns
-------
settings : `dict`
    The selected settings.

Definition at line 304 of file fitsExposure.py.

304  def getImageCompressionSettings(self, recipeName):
305  """Retrieve the relevant compression settings for this recipe.
306 
307  Parameters
308  ----------
309  recipeName : `str`
310  Label associated with the collection of compression parameters
311  to select.
312 
313  Returns
314  -------
315  settings : `dict`
316  The selected settings.
317  """
318  # if no recipe has been provided and there is no default
319  # return immediately
320  if not recipeName:
321  if "default" not in self.writeRecipes:
322  return {}
323  recipeName = "default"
324 
325  if recipeName not in self.writeRecipes:
326  raise RuntimeError(f"Unrecognized recipe option given for compression: {recipeName}")
327 
328  recipe = self.writeRecipes[recipeName]
329 
330  # Set the seed based on dataId
331  seed = hash(tuple(self.dataId.items())) % 2**31
332  for plane in ("image", "mask", "variance"):
333  if plane in recipe and "scaling" in recipe[plane]:
334  scaling = recipe[plane]["scaling"]
335  if "seed" in scaling and scaling["seed"] == 0:
336  scaling["seed"] = seed
337 
338  return recipe
339 
std::vector< SchemaItem< Flag > > * items

◆ metadata()

def lsst.obs.base.formatters.fitsExposure.FitsExposureFormatter.metadata (   self)
inherited
The metadata read from this file. It will be stripped as
components are extracted from it
(`lsst.daf.base.PropertyList`).

Definition at line 95 of file fitsExposure.py.

95  def metadata(self):
96  """The metadata read from this file. It will be stripped as
97  components are extracted from it
98  (`lsst.daf.base.PropertyList`).
99  """
100  if self._metadata is None:
101  self._metadata = self.readMetadata()
102  return self._metadata
103 

◆ read()

def lsst.obs.base.formatters.fitsExposure.FitsExposureFormatter.read (   self,
  component = None 
)
inherited
Read data from a file.

Parameters
----------
component : `str`, optional
    Component to read from the file. Only used if the `StorageClass`
    for reading differed from the `StorageClass` used to write the
    file.

Returns
-------
inMemoryDataset : `object`
    The requested data as a Python object. The type of object
    is controlled by the specific formatter.

Raises
------
ValueError
    Component requested but this file does not seem to be a concrete
    composite.
KeyError
    Raised when parameters passed with fileDescriptor are not
    supported.

Definition at line 242 of file fitsExposure.py.

242  def read(self, component=None):
243  """Read data from a file.
244 
245  Parameters
246  ----------
247  component : `str`, optional
248  Component to read from the file. Only used if the `StorageClass`
249  for reading differed from the `StorageClass` used to write the
250  file.
251 
252  Returns
253  -------
254  inMemoryDataset : `object`
255  The requested data as a Python object. The type of object
256  is controlled by the specific formatter.
257 
258  Raises
259  ------
260  ValueError
261  Component requested but this file does not seem to be a concrete
262  composite.
263  KeyError
264  Raised when parameters passed with fileDescriptor are not
265  supported.
266  """
267  fileDescriptor = self.fileDescriptor
268  if fileDescriptor.readStorageClass != fileDescriptor.storageClass:
269  if component == "metadata":
270  self.stripMetadata()
271  return self.metadata
272  elif component is not None:
273  return self.readComponent(component)
274  else:
275  raise ValueError("Storage class inconsistency ({} vs {}) but no"
276  " component requested".format(fileDescriptor.readStorageClass.name,
277  fileDescriptor.storageClass.name))
278  return self.readFull()
279 
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
Definition: history.py:174

◆ readComponent()

def lsst.obs.base.formatters.fitsExposure.FitsExposureFormatter.readComponent (   self,
  component,
  parameters = None 
)
inherited
Read a component held by the Exposure.

Parameters
----------
component : `str`, optional
    Component to read from the file.
parameters : `dict`, optional
    If specified, a dictionary of slicing parameters that
    overrides those in ``fileDescriptor``.

Returns
-------
obj : component-dependent
    In-memory component object.

Raises
------
KeyError
    Raised if the requested component cannot be handled.

Reimplemented in lsst.obs.base._fitsRawFormatterBase.FitsRawFormatterBase.

Definition at line 145 of file fitsExposure.py.

145  def readComponent(self, component, parameters=None):
146  """Read a component held by the Exposure.
147 
148  Parameters
149  ----------
150  component : `str`, optional
151  Component to read from the file.
152  parameters : `dict`, optional
153  If specified, a dictionary of slicing parameters that
154  overrides those in ``fileDescriptor``.
155 
156  Returns
157  -------
158  obj : component-dependent
159  In-memory component object.
160 
161  Raises
162  ------
163  KeyError
164  Raised if the requested component cannot be handled.
165  """
166 
167  # Metadata is handled explicitly elsewhere
168  componentMap = {'wcs': ('readWcs', False, None),
169  'coaddInputs': ('readCoaddInputs', False, None),
170  'psf': ('readPsf', False, None),
171  'image': ('readImage', True, None),
172  'mask': ('readMask', True, None),
173  'variance': ('readVariance', True, None),
174  'photoCalib': ('readPhotoCalib', False, None),
175  'bbox': ('readBBox', True, None),
176  'dimensions': ('readBBox', True, None),
177  'xy0': ('readXY0', True, None),
178  # TODO: deprecate in DM-27170, remove in DM-27177
179  'filter': ('readFilter', False, None),
180  # TODO: deprecate in DM-27177, remove in DM-27811
181  'filterLabel': ('readFilterLabel', False, None),
182  'validPolygon': ('readValidPolygon', False, None),
183  'apCorrMap': ('readApCorrMap', False, None),
184  'visitInfo': ('readVisitInfo', False, None),
185  'transmissionCurve': ('readTransmissionCurve', False, None),
186  'detector': ('readDetector', False, None),
187  'exposureInfo': ('readExposureInfo', False, None),
188  'summaryStats': ('readComponent', False, ExposureInfo.KEY_SUMMARY_STATS),
189  }
190  method, hasParams, componentName = componentMap.get(component, (None, False, None))
191 
192  if method:
193  # This reader can read standalone Image/Mask files as well
194  # when dealing with components.
195  reader = self._readerClass(self.fileDescriptor.location.path)
196  caller = getattr(reader, method, None)
197 
198  if caller:
199  if parameters is None:
200  parameters = self.fileDescriptor.parameters
201  if parameters is None:
202  parameters = {}
203  self.fileDescriptor.storageClass.validateParameters(parameters)
204 
205  if componentName is None:
206  if hasParams and parameters:
207  thisComponent = caller(**parameters)
208  else:
209  thisComponent = caller()
210  else:
211  thisComponent = caller(componentName)
212 
213  if component == "dimensions" and thisComponent is not None:
214  thisComponent = thisComponent.getDimensions()
215  return thisComponent
216  else:
217  raise KeyError(f"Unknown component requested: {component}")
218 

◆ readFull()

def lsst.obs.base.formatters.fitsExposure.FitsExposureFormatter.readFull (   self,
  parameters = None 
)
inherited
Read the full Exposure object.

Parameters
----------
parameters : `dict`, optional
    If specified a dictionary of slicing parameters that overrides
    those in ``fileDescriptor``.

Returns
-------
exposure : `~lsst.afw.image.Exposure`
    Complete in-memory exposure.

Reimplemented in lsst.obs.base._fitsRawFormatterBase.FitsRawFormatterBase.

Definition at line 219 of file fitsExposure.py.

219  def readFull(self, parameters=None):
220  """Read the full Exposure object.
221 
222  Parameters
223  ----------
224  parameters : `dict`, optional
225  If specified a dictionary of slicing parameters that overrides
226  those in ``fileDescriptor``.
227 
228  Returns
229  -------
230  exposure : `~lsst.afw.image.Exposure`
231  Complete in-memory exposure.
232  """
233  fileDescriptor = self.fileDescriptor
234  if parameters is None:
235  parameters = fileDescriptor.parameters
236  if parameters is None:
237  parameters = {}
238  fileDescriptor.storageClass.validateParameters(parameters)
239  reader = self._readerClass(fileDescriptor.location.path)
240  return reader.read(**parameters)
241 

◆ readMetadata()

def lsst.obs.base.formatters.fitsExposure.FitsExposureFormatter.readMetadata (   self)
inherited
Read all header metadata directly into a PropertyList.

Returns
-------
metadata : `~lsst.daf.base.PropertyList`
    Header metadata.

Reimplemented in lsst.obs.decam.rawFormatter.DarkEnergyCameraRawFormatter.

Definition at line 104 of file fitsExposure.py.

104  def readMetadata(self):
105  """Read all header metadata directly into a PropertyList.
106 
107  Returns
108  -------
109  metadata : `~lsst.daf.base.PropertyList`
110  Header metadata.
111  """
112  md = readMetadata(self.fileDescriptor.location.path)
113  fix_header(md)
114  return md
115 
std::shared_ptr< daf::base::PropertyList > readMetadata(std::string const &fileName, int hdu=DEFAULT_HDU, bool strip=false)
Read FITS header.
Definition: fits.cc:1657

◆ stripMetadata()

def lsst.obs.base.formatters.fitsExposure.FitsExposureFormatter.stripMetadata (   self)
inherited
Remove metadata entries that are parsed into components.

This is only called when just the metadata is requested; stripping
entries there forces code that wants other components to ask for those
components directly rather than trying to extract them from the
metadata manually, which is fragile.  This behavior is an intentional
change from Gen2.

Parameters
----------
metadata : `~lsst.daf.base.PropertyList`
    Header metadata, to be modified in-place.

Reimplemented in lsst.obs.base._fitsRawFormatterBase.FitsRawFormatterBase.

Definition at line 116 of file fitsExposure.py.

116  def stripMetadata(self):
117  """Remove metadata entries that are parsed into components.
118 
119  This is only called when just the metadata is requested; stripping
120  entries there forces code that wants other components to ask for those
121  components directly rather than trying to extract them from the
122  metadata manually, which is fragile. This behavior is an intentional
123  change from Gen2.
124 
125  Parameters
126  ----------
127  metadata : `~lsst.daf.base.PropertyList`
128  Header metadata, to be modified in-place.
129  """
130  # TODO: make sure this covers everything, by delegating to something
131  # that doesn't yet exist in afw.image.ExposureInfo.
132  from lsst.afw.image import bboxFromMetadata
133  from lsst.afw.geom import makeSkyWcs
134 
135  # Protect against the metadata being missing
136  try:
137  bboxFromMetadata(self.metadata) # always strips
138  except LookupError:
139  pass
140  try:
141  makeSkyWcs(self.metadata, strip=True)
142  except Exception:
143  pass
144 
std::shared_ptr< SkyWcs > makeSkyWcs(daf::base::PropertySet &metadata, bool strip=false)
Construct a SkyWcs from FITS keywords.
Definition: SkyWcs.cc:526
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
lsst::geom::Box2I bboxFromMetadata(daf::base::PropertySet &metadata)
Determine the image bounding box from its metadata (FITS header)
Definition: Image.cc:688

◆ validateWriteRecipes()

def lsst.obs.base.formatters.fitsExposure.FitsExposureFormatter.validateWriteRecipes (   cls,
  recipes 
)
inherited
Validate supplied recipes for this formatter.

The recipes are supplemented with default values where appropriate.

TODO: replace this custom validation code with Cerberus (DM-11846)

Parameters
----------
recipes : `dict`
    Recipes to validate. Can be empty dict or `None`.

Returns
-------
validated : `dict`
    Validated recipes. Returns what was given if there are no
    recipes listed.

Raises
------
RuntimeError
    Raised if validation fails.

Definition at line 341 of file fitsExposure.py.

341  def validateWriteRecipes(cls, recipes):
342  """Validate supplied recipes for this formatter.
343 
344  The recipes are supplemented with default values where appropriate.
345 
346  TODO: replace this custom validation code with Cerberus (DM-11846)
347 
348  Parameters
349  ----------
350  recipes : `dict`
351  Recipes to validate. Can be empty dict or `None`.
352 
353  Returns
354  -------
355  validated : `dict`
356  Validated recipes. Returns what was given if there are no
357  recipes listed.
358 
359  Raises
360  ------
361  RuntimeError
362  Raised if validation fails.
363  """
364  # Schemas define what should be there, and the default values (and by
365  # the default value, the expected type).
366  compressionSchema = {
367  "algorithm": "NONE",
368  "rows": 1,
369  "columns": 0,
370  "quantizeLevel": 0.0,
371  }
372  scalingSchema = {
373  "algorithm": "NONE",
374  "bitpix": 0,
375  "maskPlanes": ["NO_DATA"],
376  "seed": 0,
377  "quantizeLevel": 4.0,
378  "quantizePad": 5.0,
379  "fuzz": True,
380  "bscale": 1.0,
381  "bzero": 0.0,
382  }
383 
384  if not recipes:
385  # We can not insist on recipes being specified
386  return recipes
387 
388  def checkUnrecognized(entry, allowed, description):
389  """Check to see if the entry contains unrecognised keywords"""
390  unrecognized = set(entry) - set(allowed)
391  if unrecognized:
392  raise RuntimeError(
393  f"Unrecognized entries when parsing image compression recipe {description}: "
394  f"{unrecognized}")
395 
396  validated = {}
397  for name in recipes:
398  checkUnrecognized(recipes[name], ["image", "mask", "variance"], name)
399  validated[name] = {}
400  for plane in ("image", "mask", "variance"):
401  checkUnrecognized(recipes[name][plane], ["compression", "scaling"],
402  f"{name}->{plane}")
403 
404  np = {}
405  validated[name][plane] = np
406  for settings, schema in (("compression", compressionSchema),
407  ("scaling", scalingSchema)):
408  np[settings] = {}
409  if settings not in recipes[name][plane]:
410  for key in schema:
411  np[settings][key] = schema[key]
412  continue
413  entry = recipes[name][plane][settings]
414  checkUnrecognized(entry, schema.keys(), f"{name}->{plane}->{settings}")
415  for key in schema:
416  value = type(schema[key])(entry[key]) if key in entry else schema[key]
417  np[settings][key] = value
418  return validated
419 
420 
table::Key< int > type
Definition: Detector.cc:163
daf::base::PropertySet * set
Definition: fits.cc:912

◆ write()

def lsst.obs.base.formatters.fitsExposure.FitsExposureFormatter.write (   self,
  inMemoryDataset 
)
inherited
Write a Python object to a file.

Parameters
----------
inMemoryDataset : `object`
    The Python object to store.

Reimplemented in lsst.obs.base._fitsRawFormatterBase.FitsRawFormatterBase.

Definition at line 280 of file fitsExposure.py.

280  def write(self, inMemoryDataset):
281  """Write a Python object to a file.
282 
283  Parameters
284  ----------
285  inMemoryDataset : `object`
286  The Python object to store.
287  """
288  # Update the location with the formatter-preferred file extension
289  self.fileDescriptor.location.updateExtension(self.extension)
290  outputPath = self.fileDescriptor.location.path
291 
292  # check to see if we have a recipe requested
293  recipeName = self.writeParameters.get("recipe")
294  recipe = self.getImageCompressionSettings(recipeName)
295  if recipe:
296  # Can not construct a PropertySet from a hierarchical
297  # dict but can update one.
298  ps = PropertySet()
299  ps.update(recipe)
300  inMemoryDataset.writeFitsWithOptions(outputPath, options=ps)
301  else:
302  inMemoryDataset.writeFits(outputPath)
303 
void write(OutputArchiveHandle &handle) const override

Member Data Documentation

◆ extension

string lsst.obs.base.formatters.fitsExposure.FitsExposureFormatter.extension = ".fits"
staticinherited

Definition at line 86 of file fitsExposure.py.

◆ supportedExtensions

lsst.obs.base.formatters.fitsExposure.FitsExposureFormatter.supportedExtensions = frozenset({".fits", ".fits.gz", ".fits.fz", ".fz", ".fit"})
staticinherited

Definition at line 85 of file fitsExposure.py.

◆ supportedWriteParameters

lsst.obs.base.formatters.fitsExposure.FitsExposureFormatter.supportedWriteParameters = frozenset({"recipe"})
staticinherited

Definition at line 88 of file fitsExposure.py.

◆ unsupportedParameters

dictionary lsst.obs.base.formatters.fitsExposure.FitsExposureFormatter.unsupportedParameters = {}
staticinherited

Definition at line 91 of file fitsExposure.py.


The documentation for this class was generated from the following file: