LSST Applications  21.0.0+04719a4bac,21.0.0-1-ga51b5d4+f5e6047307,21.0.0-11-g2b59f77+a9c1acf22d,21.0.0-11-ga42c5b2+86977b0b17,21.0.0-12-gf4ce030+76814010d2,21.0.0-13-g1721dae+760e7a6536,21.0.0-13-g3a573fe+768d78a30a,21.0.0-15-g5a7caf0+f21cbc5713,21.0.0-16-g0fb55c1+b60e2d390c,21.0.0-19-g4cded4ca+71a93a33c0,21.0.0-2-g103fe59+bb20972958,21.0.0-2-g45278ab+04719a4bac,21.0.0-2-g5242d73+3ad5d60fb1,21.0.0-2-g7f82c8f+8babb168e8,21.0.0-2-g8f08a60+06509c8b61,21.0.0-2-g8faa9b5+616205b9df,21.0.0-2-ga326454+8babb168e8,21.0.0-2-gde069b7+5e4aea9c2f,21.0.0-2-gecfae73+1d3a86e577,21.0.0-2-gfc62afb+3ad5d60fb1,21.0.0-25-g1d57be3cd+e73869a214,21.0.0-3-g357aad2+ed88757d29,21.0.0-3-g4a4ce7f+3ad5d60fb1,21.0.0-3-g4be5c26+3ad5d60fb1,21.0.0-3-g65f322c+e0b24896a3,21.0.0-3-g7d9da8d+616205b9df,21.0.0-3-ge02ed75+a9c1acf22d,21.0.0-4-g591bb35+a9c1acf22d,21.0.0-4-g65b4814+b60e2d390c,21.0.0-4-gccdca77+0de219a2bc,21.0.0-4-ge8a399c+6c55c39e83,21.0.0-5-gd00fb1e+05fce91b99,21.0.0-6-gc675373+3ad5d60fb1,21.0.0-64-g1122c245+4fb2b8f86e,21.0.0-7-g04766d7+cd19d05db2,21.0.0-7-gdf92d54+04719a4bac,21.0.0-8-g5674e7b+d1bd76f71f,master-gac4afde19b+a9c1acf22d,w.2021.13
LSST Data Management Base Package
Public Member Functions | Public Attributes | List of all members
lsst.ip.isr.defects.Defects Class Reference
Inheritance diagram for lsst.ip.isr.defects.Defects:
lsst.ip.isr.calibType.IsrCalib

Public Member Functions

def __init__ (self, defectList=None, metadata=None, *normalize_on_init=True, **kwargs)
 
def __len__ (self)
 
def __getitem__ (self, index)
 
def __setitem__ (self, index, value)
 
def __iter__ (self)
 
def __delitem__ (self, index)
 
def __eq__ (self, other)
 
def __str__ (self)
 
def bulk_update (self)
 
def append (self, value)
 
def insert (self, index, value)
 
def copy (self)
 
def transpose (self)
 
def maskPixels (self, maskedImage, maskName="BAD")
 
def toFitsRegionTable (self)
 
def fromDict (cls, dictionary)
 
def toDict (self)
 
def toTable (self)
 
def fromTable (cls, tableList, normalize_on_init=True)
 
def readLsstDefectsFile (cls, filename, normalize_on_init=False)
 
def fromFootprintList (cls, fpList)
 
def fromMask (cls, maskedImage, maskName)
 
def requiredAttributes (self)
 
def requiredAttributes (self, value)
 
def getMetadata (self)
 
def setMetadata (self, metadata)
 
def updateMetadata (self, camera=None, detector=None, filterName=None, setCalibId=False, setCalibInfo=False, setDate=False, **kwargs)
 
def calibInfoFromDict (self, dictionary)
 
def readText (cls, filename, **kwargs)
 
def writeText (self, filename, format='auto')
 
def readFits (cls, filename, **kwargs)
 
def writeFits (self, filename)
 
def fromDetector (self, detector)
 
def fromDict (cls, dictionary, **kwargs)
 
def fromTable (cls, tableList, **kwargs)
 
def validate (self, other=None)
 
def apply (self, target)
 

Public Attributes

 requiredAttributes
 
 log
 

Detailed Description

Calibration handler for collections of `lsst.meas.algorithms.Defect`.

Parameters
----------
defectList : iterable of `lsst.meas.algorithms.Defect`
             or `lsst.geom.BoxI`, optional
    Collections of defects to apply to the image.
metadata : `lsst.daf.base.PropertyList`, optional
    Metadata to associate with the defects.  Will be copied and
    overwrite existing metadata, if any. If not supplied the existing
    metadata will be reset.
normalize_on_init : `bool`
    If True, normalization is applied to the defects in ``defectList`` to
    remove duplicates, eliminate overlaps, etc.

Notes
-----
Defects are stored within this collection in a "reduced" or "normalized"
form: rather than simply storing the bounding boxes which are added to the
collection, we eliminate overlaps and duplicates. This normalization
procedure may introduce overhead when adding many new defects; it may be
temporarily disabled using the `Defects.bulk_update` context manager if
necessary.

The attributes stored in this calibration are:

_defects : `list` [`lsst.meas.algorithms.Defect`]
    The collection of Defect objects.
The calibration type used for ingest.

Definition at line 47 of file defects.py.

Constructor & Destructor Documentation

◆ __init__()

def lsst.ip.isr.defects.Defects.__init__ (   self,
  defectList = None,
  metadata = None,
normalize_on_init = True,
**  kwargs 
)

Definition at line 83 of file defects.py.

83  def __init__(self, defectList=None, metadata=None, *, normalize_on_init=True, **kwargs):
84  self._defects = []
85 
86  if defectList is not None:
87  self._bulk_update = True
88  for d in defectList:
89  self.append(d)
90  self._bulk_update = False
91 
92  if normalize_on_init:
93  self._normalize()
94 
95  super().__init__(**kwargs)
96  self.requiredAttributes.update(['_defects'])
97 

Member Function Documentation

◆ __delitem__()

def lsst.ip.isr.defects.Defects.__delitem__ (   self,
  index 
)

Definition at line 145 of file defects.py.

145  def __delitem__(self, index):
146  del self._defects[index]
147 

◆ __eq__()

def lsst.ip.isr.defects.Defects.__eq__ (   self,
  other 
)
Compare if two `Defects` are equal.

Two `Defects` are equal if their bounding boxes are equal and in
the same order.  Metadata content is ignored.

Reimplemented from lsst.ip.isr.calibType.IsrCalib.

Definition at line 148 of file defects.py.

148  def __eq__(self, other):
149  """Compare if two `Defects` are equal.
150 
151  Two `Defects` are equal if their bounding boxes are equal and in
152  the same order. Metadata content is ignored.
153  """
154  super().__eq__(other)
155 
156  if not isinstance(other, self.__class__):
157  return False
158 
159  # checking the bboxes with zip() only works if same length
160  if len(self) != len(other):
161  return False
162 
163  # Assume equal if bounding boxes are equal
164  for d1, d2 in zip(self, other):
165  if d1.getBBox() != d2.getBBox():
166  return False
167 
168  return True
169 

◆ __getitem__()

def lsst.ip.isr.defects.Defects.__getitem__ (   self,
  index 
)

Definition at line 133 of file defects.py.

133  def __getitem__(self, index):
134  return self._defects[index]
135 

◆ __iter__()

def lsst.ip.isr.defects.Defects.__iter__ (   self)

Definition at line 142 of file defects.py.

142  def __iter__(self):
143  return iter(self._defects)
144 

◆ __len__()

def lsst.ip.isr.defects.Defects.__len__ (   self)

Definition at line 130 of file defects.py.

130  def __len__(self):
131  return len(self._defects)
132 

◆ __setitem__()

def lsst.ip.isr.defects.Defects.__setitem__ (   self,
  index,
  value 
)
Can be given a `~lsst.meas.algorithms.Defect` or a `lsst.geom.BoxI`

Definition at line 136 of file defects.py.

136  def __setitem__(self, index, value):
137  """Can be given a `~lsst.meas.algorithms.Defect` or a `lsst.geom.BoxI`
138  """
139  self._defects[index] = self._check_value(value)
140  self._normalize()
141 

◆ __str__()

def lsst.ip.isr.defects.Defects.__str__ (   self)

Reimplemented from lsst.ip.isr.calibType.IsrCalib.

Definition at line 170 of file defects.py.

170  def __str__(self):
171  baseStr = super().__str__(self)
172  return baseStr + ",".join(str(d.getBBox()) for d in self) + ")"
173 

◆ append()

def lsst.ip.isr.defects.Defects.append (   self,
  value 
)

Definition at line 215 of file defects.py.

215  def append(self, value):
216  self._defects.append(self._check_value(value))
217  self._normalize()
218 
std::shared_ptr< FrameSet > append(FrameSet const &first, FrameSet const &second)
Construct a FrameSet that performs two transformations in series.
Definition: functional.cc:33

◆ apply()

def lsst.ip.isr.calibType.IsrCalib.apply (   self,
  target 
)
inherited
Method to apply the calibration to the target object.

Parameters
----------
target : `object`
    Thing to validate against.

Returns
-------
valid : `bool`
    Returns true if the calibration was applied correctly.

Raises
------
NotImplementedError :
    Raised if not implemented.

Definition at line 549 of file calibType.py.

549  def apply(self, target):
550  """Method to apply the calibration to the target object.
551 
552  Parameters
553  ----------
554  target : `object`
555  Thing to validate against.
556 
557  Returns
558  -------
559  valid : `bool`
560  Returns true if the calibration was applied correctly.
561 
562  Raises
563  ------
564  NotImplementedError :
565  Raised if not implemented.
566  """
567  raise NotImplementedError("Must be implemented by subclass.")
568 
569 

◆ bulk_update()

def lsst.ip.isr.defects.Defects.bulk_update (   self)
Temporarily suspend normalization of the defect list.

Definition at line 205 of file defects.py.

205  def bulk_update(self):
206  """Temporarily suspend normalization of the defect list.
207  """
208  self._bulk_update = True
209  try:
210  yield
211  finally:
212  self._bulk_update = False
213  self._normalize()
214 

◆ calibInfoFromDict()

def lsst.ip.isr.calibType.IsrCalib.calibInfoFromDict (   self,
  dictionary 
)
inherited
Handle common keywords.

This isn't an ideal solution, but until all calibrations
expect to find everything in the metadata, they still need to
search through dictionaries.

Parameters
----------
dictionary : `dict` or `lsst.daf.base.PropertyList`
    Source for the common keywords.

Raises
------
RuntimeError :
    Raised if the dictionary does not match the expected OBSTYPE.

Definition at line 229 of file calibType.py.

229  def calibInfoFromDict(self, dictionary):
230  """Handle common keywords.
231 
232  This isn't an ideal solution, but until all calibrations
233  expect to find everything in the metadata, they still need to
234  search through dictionaries.
235 
236  Parameters
237  ----------
238  dictionary : `dict` or `lsst.daf.base.PropertyList`
239  Source for the common keywords.
240 
241  Raises
242  ------
243  RuntimeError :
244  Raised if the dictionary does not match the expected OBSTYPE.
245 
246  """
247 
248  def search(haystack, needles):
249  """Search dictionary 'haystack' for an entry in 'needles'
250  """
251  test = [haystack.get(x) for x in needles]
252  test = set([x for x in test if x is not None])
253  if len(test) == 0:
254  if 'metadata' in haystack:
255  return search(haystack['metadata'], needles)
256  else:
257  return None
258  elif len(test) == 1:
259  value = list(test)[0]
260  if value == '':
261  return None
262  else:
263  return value
264  else:
265  raise ValueError(f"Too many values found: {len(test)} {test} {needles}")
266 
267  if 'metadata' in dictionary:
268  metadata = dictionary['metadata']
269 
270  if self._OBSTYPE != metadata['OBSTYPE']:
271  raise RuntimeError(f"Incorrect calibration supplied. Expected {self._OBSTYPE}, "
272  f"found {metadata['OBSTYPE']}")
273 
274  self._instrument = search(dictionary, ['INSTRUME', 'instrument'])
275  self._raftName = search(dictionary, ['RAFTNAME'])
276  self._slotName = search(dictionary, ['SLOTNAME'])
277  self._detectorId = search(dictionary, ['DETECTOR', 'detectorId'])
278  self._detectorName = search(dictionary, ['DET_NAME', 'DETECTOR_NAME', 'detectorName'])
279  self._detectorSerial = search(dictionary, ['DET_SER', 'DETECTOR_SERIAL', 'detectorSerial'])
280  self._filter = search(dictionary, ['FILTER', 'filterName'])
281  self._calibId = search(dictionary, ['CALIB_ID'])
282 
daf::base::PropertyList * list
Definition: fits.cc:913
daf::base::PropertySet * set
Definition: fits.cc:912

◆ copy()

def lsst.ip.isr.defects.Defects.copy (   self)
Copy the defects to a new list, creating new defects from the
bounding boxes.

Returns
-------
new : `Defects`
    New list with new `Defect` entries.

Notes
-----
This is not a shallow copy in that new `Defect` instances are
created from the original bounding boxes.  It's also not a deep
copy since the bounding boxes are not recreated.

Definition at line 223 of file defects.py.

223  def copy(self):
224  """Copy the defects to a new list, creating new defects from the
225  bounding boxes.
226 
227  Returns
228  -------
229  new : `Defects`
230  New list with new `Defect` entries.
231 
232  Notes
233  -----
234  This is not a shallow copy in that new `Defect` instances are
235  created from the original bounding boxes. It's also not a deep
236  copy since the bounding boxes are not recreated.
237  """
238  return self.__class__(d.getBBox() for d in self)
239 

◆ fromDetector()

def lsst.ip.isr.calibType.IsrCalib.fromDetector (   self,
  detector 
)
inherited
Modify the calibration parameters to match the supplied detector.

Parameters
----------
detector : `lsst.afw.cameraGeom.Detector`
    Detector to use to set parameters from.

Raises
------
NotImplementedError
    This needs to be implemented by subclasses for each
    calibration type.

Reimplemented in lsst.ip.isr.linearize.Linearizer.

Definition at line 432 of file calibType.py.

432  def fromDetector(self, detector):
433  """Modify the calibration parameters to match the supplied detector.
434 
435  Parameters
436  ----------
437  detector : `lsst.afw.cameraGeom.Detector`
438  Detector to use to set parameters from.
439 
440  Raises
441  ------
442  NotImplementedError
443  This needs to be implemented by subclasses for each
444  calibration type.
445  """
446  raise NotImplementedError("Must be implemented by subclass.")
447 

◆ fromDict() [1/2]

def lsst.ip.isr.defects.Defects.fromDict (   cls,
  dictionary 
)
Construct a calibration from a dictionary of properties.

Must be implemented by the specific calibration subclasses.

Parameters
----------
dictionary : `dict`
    Dictionary of properties.

Returns
-------
calib : `lsst.ip.isr.CalibType`
    Constructed calibration.

Raises
------
RuntimeError :
    Raised if the supplied dictionary is for a different
    calibration.

Definition at line 329 of file defects.py.

329  def fromDict(cls, dictionary):
330  """Construct a calibration from a dictionary of properties.
331 
332  Must be implemented by the specific calibration subclasses.
333 
334  Parameters
335  ----------
336  dictionary : `dict`
337  Dictionary of properties.
338 
339  Returns
340  -------
341  calib : `lsst.ip.isr.CalibType`
342  Constructed calibration.
343 
344  Raises
345  ------
346  RuntimeError :
347  Raised if the supplied dictionary is for a different
348  calibration.
349  """
350  calib = cls()
351 
352  if calib._OBSTYPE != dictionary['metadata']['OBSTYPE']:
353  raise RuntimeError(f"Incorrect crosstalk supplied. Expected {calib._OBSTYPE}, "
354  f"found {dictionary['metadata']['OBSTYPE']}")
355 
356  calib.setMetadata(dictionary['metadata'])
357  calib.calibInfoFromDict(dictionary)
358 
359  xCol = dictionary['x0']
360  yCol = dictionary['y0']
361  widthCol = dictionary['width']
362  heightCol = dictionary['height']
363 
364  with calib.bulk_update:
365  for x0, y0, width, height in zip(xCol, yCol, widthCol, heightCol):
366  calib.append(lsst.geom.Box2I(lsst.geom.Point2I(x0, y0),
367  lsst.geom.Extent2I(width, height)))
368  return calib
369 
An integer coordinate rectangle.
Definition: Box.h:55

◆ fromDict() [2/2]

def lsst.ip.isr.calibType.IsrCalib.fromDict (   cls,
  dictionary,
**  kwargs 
)
inherited
Construct a calibration from a dictionary of properties.

Must be implemented by the specific calibration subclasses.

Parameters
----------
dictionary : `dict`
    Dictionary of properties.
kwargs : `dict` or collections.abc.Mapping`, optional
    Set of key=value options.

Returns
------
calib : `lsst.ip.isr.CalibType`
    Constructed calibration.

Raises
------
NotImplementedError :
    Raised if not implemented.

Definition at line 449 of file calibType.py.

449  def fromDict(cls, dictionary, **kwargs):
450  """Construct a calibration from a dictionary of properties.
451 
452  Must be implemented by the specific calibration subclasses.
453 
454  Parameters
455  ----------
456  dictionary : `dict`
457  Dictionary of properties.
458  kwargs : `dict` or collections.abc.Mapping`, optional
459  Set of key=value options.
460 
461  Returns
462  ------
463  calib : `lsst.ip.isr.CalibType`
464  Constructed calibration.
465 
466  Raises
467  ------
468  NotImplementedError :
469  Raised if not implemented.
470  """
471  raise NotImplementedError("Must be implemented by subclass.")
472 

◆ fromFootprintList()

def lsst.ip.isr.defects.Defects.fromFootprintList (   cls,
  fpList 
)
Compute a defect list from a footprint list, optionally growing
the footprints.

Parameters
----------
fpList : `list` of `lsst.afw.detection.Footprint`
    Footprint list to process.

Returns
-------
defects : `Defects`
    List of defects.

Definition at line 638 of file defects.py.

638  def fromFootprintList(cls, fpList):
639  """Compute a defect list from a footprint list, optionally growing
640  the footprints.
641 
642  Parameters
643  ----------
644  fpList : `list` of `lsst.afw.detection.Footprint`
645  Footprint list to process.
646 
647  Returns
648  -------
649  defects : `Defects`
650  List of defects.
651  """
652  # normalize_on_init is set to False to avoid recursively calling
653  # fromMask/fromFootprintList in Defects.__init__.
654  return cls(itertools.chain.from_iterable(lsst.afw.detection.footprintToBBoxList(fp)
655  for fp in fpList), normalize_on_init=False)
656 
std::vector< lsst::geom::Box2I > footprintToBBoxList(Footprint const &footprint)
Return a list of BBoxs, whose union contains exactly the pixels in the footprint, neither more nor le...
Definition: Footprint.cc:352

◆ fromMask()

def lsst.ip.isr.defects.Defects.fromMask (   cls,
  maskedImage,
  maskName 
)
Compute a defect list from a specified mask plane.

Parameters
----------
maskedImage : `lsst.afw.image.MaskedImage`
    Image to process.
maskName : `str` or `list`
    Mask plane name, or list of names to convert.

Returns
-------
defects : `Defects`
    Defect list constructed from masked pixels.

Definition at line 658 of file defects.py.

658  def fromMask(cls, maskedImage, maskName):
659  """Compute a defect list from a specified mask plane.
660 
661  Parameters
662  ----------
663  maskedImage : `lsst.afw.image.MaskedImage`
664  Image to process.
665  maskName : `str` or `list`
666  Mask plane name, or list of names to convert.
667 
668  Returns
669  -------
670  defects : `Defects`
671  Defect list constructed from masked pixels.
672  """
673  mask = maskedImage.getMask()
674  thresh = lsst.afw.detection.Threshold(mask.getPlaneBitMask(maskName),
675  lsst.afw.detection.Threshold.BITMASK)
676  fpList = lsst.afw.detection.FootprintSet(mask, thresh).getFootprints()
677  return cls.fromFootprintList(fpList)
A set of Footprints, associated with a MaskedImage.
Definition: FootprintSet.h:53
A Threshold is used to pass a threshold value to detection algorithms.
Definition: Threshold.h:43

◆ fromTable() [1/2]

def lsst.ip.isr.calibType.IsrCalib.fromTable (   cls,
  tableList,
**  kwargs 
)
inherited
Construct a calibration from a dictionary of properties.

Must be implemented by the specific calibration subclasses.

Parameters
----------
tableList : `list` [`lsst.afw.table.Table`]
    List of tables of properties.
kwargs : `dict` or collections.abc.Mapping`, optional
    Set of key=value options.

Returns
------
calib : `lsst.ip.isr.CalibType`
    Constructed calibration.

Raises
------
NotImplementedError :
    Raised if not implemented.

Definition at line 492 of file calibType.py.

492  def fromTable(cls, tableList, **kwargs):
493  """Construct a calibration from a dictionary of properties.
494 
495  Must be implemented by the specific calibration subclasses.
496 
497  Parameters
498  ----------
499  tableList : `list` [`lsst.afw.table.Table`]
500  List of tables of properties.
501  kwargs : `dict` or collections.abc.Mapping`, optional
502  Set of key=value options.
503 
504  Returns
505  ------
506  calib : `lsst.ip.isr.CalibType`
507  Constructed calibration.
508 
509  Raises
510  ------
511  NotImplementedError :
512  Raised if not implemented.
513  """
514  raise NotImplementedError("Must be implemented by subclass.")
515 

◆ fromTable() [2/2]

def lsst.ip.isr.defects.Defects.fromTable (   cls,
  tableList,
  normalize_on_init = True 
)
Construct a `Defects` from the contents of a
`~lsst.afw.table.BaseCatalog`.

Parameters
----------
table : `lsst.afw.table.BaseCatalog`
    Table with one row per defect.
normalize_on_init : `bool`, optional
    If `True`, normalization is applied to the defects listed in the
    table to remove duplicates, eliminate overlaps, etc. Otherwise
    the defects in the returned object exactly match those in the
    table.

Returns
-------
defects : `Defects`
    A `Defects` list.

Notes
-----
Two table formats are recognized.  The first is the
`FITS regions <https://fits.gsfc.nasa.gov/registry/region.html>`_
definition tabular format written by `toFitsRegionTable` where the
pixel origin is corrected from FITS 1-based to a 0-based origin.
The second is the legacy defects format using columns ``x0``, ``y0``
(bottom left hand pixel of box in 0-based coordinates), ``width``
and ``height``.

The FITS standard regions can only read BOX, POINT, or ROTBOX with
a zero degree rotation.

Definition at line 489 of file defects.py.

489  def fromTable(cls, tableList, normalize_on_init=True):
490  """Construct a `Defects` from the contents of a
491  `~lsst.afw.table.BaseCatalog`.
492 
493  Parameters
494  ----------
495  table : `lsst.afw.table.BaseCatalog`
496  Table with one row per defect.
497  normalize_on_init : `bool`, optional
498  If `True`, normalization is applied to the defects listed in the
499  table to remove duplicates, eliminate overlaps, etc. Otherwise
500  the defects in the returned object exactly match those in the
501  table.
502 
503  Returns
504  -------
505  defects : `Defects`
506  A `Defects` list.
507 
508  Notes
509  -----
510  Two table formats are recognized. The first is the
511  `FITS regions <https://fits.gsfc.nasa.gov/registry/region.html>`_
512  definition tabular format written by `toFitsRegionTable` where the
513  pixel origin is corrected from FITS 1-based to a 0-based origin.
514  The second is the legacy defects format using columns ``x0``, ``y0``
515  (bottom left hand pixel of box in 0-based coordinates), ``width``
516  and ``height``.
517 
518  The FITS standard regions can only read BOX, POINT, or ROTBOX with
519  a zero degree rotation.
520  """
521  table = tableList[0]
522  defectList = []
523 
524  schema = table.columns
525  # Check schema to see which definitions we have
526  if "X" in schema and "Y" in schema and "R" in schema and "SHAPE" in schema:
527  # This is a FITS region style table
528  isFitsRegion = True
529  elif "x0" in schema and "y0" in schema and "width" in schema and "height" in schema:
530  # This is a classic LSST-style defect table
531  isFitsRegion = False
532  else:
533  raise ValueError("Unsupported schema for defects extraction")
534 
535  for record in table:
536  if isFitsRegion:
537  # Coordinates can be arrays (some shapes in the standard
538  # require this)
539  # Correct for FITS 1-based origin
540  xcen = cls._get_values(record['X']) - 1.0
541  ycen = cls._get_values(record['Y']) - 1.0
542  shape = record['SHAPE'].upper().rstrip()
543  if shape == "BOX":
545  lsst.geom.Extent2I(cls._get_values(record['R'],
546  n=2)))
547  elif shape == "POINT":
548  # Handle the case where we have an externally created
549  # FITS file.
550  box = lsst.geom.Point2I(xcen, ycen)
551  elif shape == "ROTBOX":
552  # Astropy regions always writes ROTBOX
553  rotang = cls._get_values(record['ROTANG'])
554  # We can support 0 or 90 deg
555  if math.isclose(rotang % 90.0, 0.0):
556  # Two values required
557  r = cls._get_values(record['R'], n=2)
558  if math.isclose(rotang % 180.0, 0.0):
559  width = r[0]
560  height = r[1]
561  else:
562  width = r[1]
563  height = r[0]
565  lsst.geom.Extent2I(width, height))
566  else:
567  log.warning("Defect can not be defined using ROTBOX with non-aligned rotation angle")
568  continue
569  else:
570  log.warning("Defect lists can only be defined using BOX or POINT not %s", shape)
571  continue
572 
573  else:
574  # This is a classic LSST-style defect table
575  box = lsst.geom.Box2I(lsst.geom.Point2I(record['x0'], record['y0']),
576  lsst.geom.Extent2I(record['width'], record['height']))
577 
578  defectList.append(box)
579 
580  defects = cls(defectList, normalize_on_init=normalize_on_init)
581  newMeta = dict(table.meta)
582  defects.updateMetadata(setCalibInfo=True, **newMeta)
583 
584  return defects
585 
static Box2I makeCenteredBox(Point2D const &center, Extent const &size)
Create a box centered as closely as possible on a particular point.
Definition: Box.cc:97

◆ getMetadata()

def lsst.ip.isr.calibType.IsrCalib.getMetadata (   self)
inherited
Retrieve metadata associated with this calibration.

Returns
-------
meta : `lsst.daf.base.PropertyList`
    Metadata. The returned `~lsst.daf.base.PropertyList` can be
    modified by the caller and the changes will be written to
    external files.

Definition at line 114 of file calibType.py.

114  def getMetadata(self):
115  """Retrieve metadata associated with this calibration.
116 
117  Returns
118  -------
119  meta : `lsst.daf.base.PropertyList`
120  Metadata. The returned `~lsst.daf.base.PropertyList` can be
121  modified by the caller and the changes will be written to
122  external files.
123  """
124  return self._metadata
125 

◆ insert()

def lsst.ip.isr.defects.Defects.insert (   self,
  index,
  value 
)

Definition at line 219 of file defects.py.

219  def insert(self, index, value):
220  self._defects.insert(index, self._check_value(value))
221  self._normalize()
222 

◆ maskPixels()

def lsst.ip.isr.defects.Defects.maskPixels (   self,
  maskedImage,
  maskName = "BAD" 
)
Set mask plane based on these defects.

Parameters
----------
maskedImage : `lsst.afw.image.MaskedImage`
    Image to process.  Only the mask plane is updated.
maskName : str, optional
    Mask plane name to use.

Definition at line 257 of file defects.py.

257  def maskPixels(self, maskedImage, maskName="BAD"):
258  """Set mask plane based on these defects.
259 
260  Parameters
261  ----------
262  maskedImage : `lsst.afw.image.MaskedImage`
263  Image to process. Only the mask plane is updated.
264  maskName : str, optional
265  Mask plane name to use.
266  """
267  # mask bad pixels
268  mask = maskedImage.getMask()
269  bitmask = mask.getPlaneBitMask(maskName)
270  for defect in self:
271  bbox = defect.getBBox()
272  lsst.afw.geom.SpanSet(bbox).clippedTo(mask.getBBox()).setMask(mask, bitmask)
273 
A compact representation of a collection of pixels.
Definition: SpanSet.h:78

◆ readFits()

def lsst.ip.isr.calibType.IsrCalib.readFits (   cls,
  filename,
**  kwargs 
)
inherited
Read calibration data from a FITS file.

Parameters
----------
filename : `str`
    Filename to read data from.
kwargs : `dict` or collections.abc.Mapping`, optional
    Set of key=value pairs to pass to the ``fromTable``
    method.

Returns
-------
calib : `lsst.ip.isr.IsrCalib`
    Calibration contained within the file.

Definition at line 370 of file calibType.py.

370  def readFits(cls, filename, **kwargs):
371  """Read calibration data from a FITS file.
372 
373  Parameters
374  ----------
375  filename : `str`
376  Filename to read data from.
377  kwargs : `dict` or collections.abc.Mapping`, optional
378  Set of key=value pairs to pass to the ``fromTable``
379  method.
380 
381  Returns
382  -------
383  calib : `lsst.ip.isr.IsrCalib`
384  Calibration contained within the file.
385  """
386  tableList = []
387  tableList.append(Table.read(filename, hdu=1))
388  extNum = 2 # Fits indices start at 1, we've read one already.
389  keepTrying = True
390 
391  while keepTrying:
392  with warnings.catch_warnings():
393  warnings.simplefilter("error")
394  try:
395  newTable = Table.read(filename, hdu=extNum)
396  tableList.append(newTable)
397  extNum += 1
398  except Exception:
399  keepTrying = False
400 
401  for table in tableList:
402  for k, v in table.meta.items():
403  if isinstance(v, fits.card.Undefined):
404  table.meta[k] = None
405 
406  return cls.fromTable(tableList, **kwargs)
407 

◆ readLsstDefectsFile()

def lsst.ip.isr.defects.Defects.readLsstDefectsFile (   cls,
  filename,
  normalize_on_init = False 
)
Read defects information from a legacy LSST format text file.

Parameters
----------
filename : `str`
    Name of text file containing the defect information.

normalize_on_init : `bool`, optional
    If `True`, normalization is applied to the defects listed in the
    table to remove duplicates, eliminate overlaps, etc. Otherwise
    the defects in the returned object exactly match those in the
    table.

Returns
-------
defects : `Defects`
    The defects.

Notes
-----
These defect text files are used as the human readable definitions
of defects in calibration data definition repositories.  The format
is to use four columns defined as follows:

x0 : `int`
    X coordinate of bottom left corner of box.
y0 : `int`
    Y coordinate of bottom left corner of box.
width : `int`
    X extent of the box.
height : `int`
    Y extent of the box.

Files of this format were used historically to represent defects
in simple text form.  Use `Defects.readText` and `Defects.writeText`
to use the more modern format.

Definition at line 587 of file defects.py.

587  def readLsstDefectsFile(cls, filename, normalize_on_init=False):
588  """Read defects information from a legacy LSST format text file.
589 
590  Parameters
591  ----------
592  filename : `str`
593  Name of text file containing the defect information.
594 
595  normalize_on_init : `bool`, optional
596  If `True`, normalization is applied to the defects listed in the
597  table to remove duplicates, eliminate overlaps, etc. Otherwise
598  the defects in the returned object exactly match those in the
599  table.
600 
601  Returns
602  -------
603  defects : `Defects`
604  The defects.
605 
606  Notes
607  -----
608  These defect text files are used as the human readable definitions
609  of defects in calibration data definition repositories. The format
610  is to use four columns defined as follows:
611 
612  x0 : `int`
613  X coordinate of bottom left corner of box.
614  y0 : `int`
615  Y coordinate of bottom left corner of box.
616  width : `int`
617  X extent of the box.
618  height : `int`
619  Y extent of the box.
620 
621  Files of this format were used historically to represent defects
622  in simple text form. Use `Defects.readText` and `Defects.writeText`
623  to use the more modern format.
624  """
625  # Use loadtxt so that ValueError is thrown if the file contains a
626  # non-integer value. genfromtxt converts bad values to -1.
627  defect_array = np.loadtxt(filename,
628  dtype=[("x0", "int"), ("y0", "int"),
629  ("x_extent", "int"), ("y_extent", "int")])
630 
631  defects = (lsst.geom.Box2I(lsst.geom.Point2I(row["x0"], row["y0"]),
632  lsst.geom.Extent2I(row["x_extent"], row["y_extent"]))
633  for row in defect_array)
634 
635  return cls(defects, normalize_on_init=normalize_on_init)
636 

◆ readText()

def lsst.ip.isr.calibType.IsrCalib.readText (   cls,
  filename,
**  kwargs 
)
inherited
Read calibration representation from a yaml/ecsv file.

Parameters
----------
filename : `str`
    Name of the file containing the calibration definition.
kwargs : `dict` or collections.abc.Mapping`, optional
    Set of key=value pairs to pass to the ``fromDict`` or
    ``fromTable`` methods.

Returns
-------
calib : `~lsst.ip.isr.IsrCalibType`
    Calibration class.

Raises
------
RuntimeError :
    Raised if the filename does not end in ".ecsv" or ".yaml".

Definition at line 284 of file calibType.py.

284  def readText(cls, filename, **kwargs):
285  """Read calibration representation from a yaml/ecsv file.
286 
287  Parameters
288  ----------
289  filename : `str`
290  Name of the file containing the calibration definition.
291  kwargs : `dict` or collections.abc.Mapping`, optional
292  Set of key=value pairs to pass to the ``fromDict`` or
293  ``fromTable`` methods.
294 
295  Returns
296  -------
297  calib : `~lsst.ip.isr.IsrCalibType`
298  Calibration class.
299 
300  Raises
301  ------
302  RuntimeError :
303  Raised if the filename does not end in ".ecsv" or ".yaml".
304  """
305  if filename.endswith((".ecsv", ".ECSV")):
306  data = Table.read(filename, format='ascii.ecsv')
307  return cls.fromTable([data], **kwargs)
308 
309  elif filename.endswith((".yaml", ".YAML")):
310  with open(filename, 'r') as f:
311  data = yaml.load(f, Loader=yaml.CLoader)
312  return cls.fromDict(data, **kwargs)
313  else:
314  raise RuntimeError(f"Unknown filename extension: {filename}")
315 

◆ requiredAttributes() [1/2]

def lsst.ip.isr.calibType.IsrCalib.requiredAttributes (   self)
inherited

Definition at line 107 of file calibType.py.

107  def requiredAttributes(self):
108  return self._requiredAttributes
109 

◆ requiredAttributes() [2/2]

def lsst.ip.isr.calibType.IsrCalib.requiredAttributes (   self,
  value 
)
inherited

Definition at line 111 of file calibType.py.

111  def requiredAttributes(self, value):
112  self._requiredAttributes = value
113 

◆ setMetadata()

def lsst.ip.isr.calibType.IsrCalib.setMetadata (   self,
  metadata 
)
inherited
Store a copy of the supplied metadata with this calibration.

Parameters
----------
metadata : `lsst.daf.base.PropertyList`
    Metadata to associate with the calibration.  Will be copied and
    overwrite existing metadata.

Definition at line 126 of file calibType.py.

126  def setMetadata(self, metadata):
127  """Store a copy of the supplied metadata with this calibration.
128 
129  Parameters
130  ----------
131  metadata : `lsst.daf.base.PropertyList`
132  Metadata to associate with the calibration. Will be copied and
133  overwrite existing metadata.
134  """
135  if metadata is not None:
136  self._metadata.update(metadata)
137 
138  # Ensure that we have the obs type required by calibration ingest
139  self._metadata["OBSTYPE"] = self._OBSTYPE
140  self._metadata[self._OBSTYPE + "_SCHEMA"] = self._SCHEMA
141  self._metadata[self._OBSTYPE + "_VERSION"] = self._VERSION
142 
143  if isinstance(metadata, dict):
144  self.calibInfoFromDict(metadata)
145  elif isinstance(metadata, PropertyList):
146  self.calibInfoFromDict(metadata.toDict())
147 

◆ toDict()

def lsst.ip.isr.defects.Defects.toDict (   self)
Return a dictionary containing the calibration properties.

The dictionary should be able to be round-tripped through
`fromDict`.

Returns
-------
dictionary : `dict`
    Dictionary of properties.

Reimplemented from lsst.ip.isr.calibType.IsrCalib.

Definition at line 370 of file defects.py.

370  def toDict(self):
371  """Return a dictionary containing the calibration properties.
372 
373  The dictionary should be able to be round-tripped through
374  `fromDict`.
375 
376  Returns
377  -------
378  dictionary : `dict`
379  Dictionary of properties.
380  """
381  self.updateMetadata()
382 
383  outDict = {}
384  metadata = self.getMetadata()
385  outDict['metadata'] = metadata
386 
387  xCol = []
388  yCol = []
389  widthCol = []
390  heightCol = []
391 
392  nrows = len(self._defects)
393  if nrows:
394  for defect in self._defects:
395  box = defect.getBBox()
396  xCol.append(box.getBeginX())
397  yCol.append(box.getBeginY())
398  widthCol.append(box.getWidth())
399  heightCol.append(box.getHeight())
400 
401  outDict['x0'] = xCol
402  outDict['y0'] = yCol
403  outDict['width'] = widthCol
404  outDict['height'] = heightCol
405 
406  return outDict
407 

◆ toFitsRegionTable()

def lsst.ip.isr.defects.Defects.toFitsRegionTable (   self)
Convert defect list to `~lsst.afw.table.BaseCatalog` using the
FITS region standard.

Returns
-------
table : `lsst.afw.table.BaseCatalog`
    Defects in tabular form.

Notes
-----
The table created uses the
`FITS regions <https://fits.gsfc.nasa.gov/registry/region.html>`_
definition tabular format.  The ``X`` and ``Y`` coordinates are
converted to FITS Physical coordinates that have origin pixel (1, 1)
rather than the (0, 0) used in LSST software.

Definition at line 274 of file defects.py.

274  def toFitsRegionTable(self):
275  """Convert defect list to `~lsst.afw.table.BaseCatalog` using the
276  FITS region standard.
277 
278  Returns
279  -------
280  table : `lsst.afw.table.BaseCatalog`
281  Defects in tabular form.
282 
283  Notes
284  -----
285  The table created uses the
286  `FITS regions <https://fits.gsfc.nasa.gov/registry/region.html>`_
287  definition tabular format. The ``X`` and ``Y`` coordinates are
288  converted to FITS Physical coordinates that have origin pixel (1, 1)
289  rather than the (0, 0) used in LSST software.
290  """
291  self.updateMetadata()
292  nrows = len(self._defects)
293 
294  if nrows:
295  # Adding entire columns is more efficient than adding
296  # each element separately
297  xCol = []
298  yCol = []
299  rCol = []
300  shapes = []
301  for i, defect in enumerate(self._defects):
302  box = defect.getBBox()
303  center = box.getCenter()
304  # Correct for the FITS 1-based offset
305  xCol.append(center.getX() + 1.0)
306  yCol.append(center.getY() + 1.0)
307 
308  width = box.width
309  height = box.height
310 
311  if width == 1 and height == 1:
312  # Call this a point
313  shapeType = "POINT"
314  else:
315  shapeType = "BOX"
316 
317  # Strings have to be added per row
318  shapes.append(shapeType)
319 
320  rCol.append(np.array([width, height], dtype=np.float64))
321 
322  table = astropy.table.Table({'X': xCol, 'Y': yCol, 'SHAPE': shapes,
323  'R': rCol, 'ROTANG': np.zeros(nrows),
324  'COMPONENT': np.arange(nrows)})
325  table.meta = self.getMetadata().toDict()
326  return table
327 

◆ toTable()

def lsst.ip.isr.defects.Defects.toTable (   self)
Convert defects to a simple table form that we use to write
to text files.

Returns
-------
table : `lsst.afw.table.BaseCatalog`
    Defects in simple tabular form.

Notes
-----
These defect tables are used as the human readable definitions
of defects in calibration data definition repositories.  The format
is to use four columns defined as follows:

x0 : `int`
    X coordinate of bottom left corner of box.
y0 : `int`
    Y coordinate of bottom left corner of box.
width : `int`
    X extent of the box.
height : `int`
    Y extent of the box.

Reimplemented from lsst.ip.isr.calibType.IsrCalib.

Definition at line 408 of file defects.py.

408  def toTable(self):
409  """Convert defects to a simple table form that we use to write
410  to text files.
411 
412  Returns
413  -------
414  table : `lsst.afw.table.BaseCatalog`
415  Defects in simple tabular form.
416 
417  Notes
418  -----
419  These defect tables are used as the human readable definitions
420  of defects in calibration data definition repositories. The format
421  is to use four columns defined as follows:
422 
423  x0 : `int`
424  X coordinate of bottom left corner of box.
425  y0 : `int`
426  Y coordinate of bottom left corner of box.
427  width : `int`
428  X extent of the box.
429  height : `int`
430  Y extent of the box.
431  """
432  tableList = []
433  self.updateMetadata()
434 
435  xCol = []
436  yCol = []
437  widthCol = []
438  heightCol = []
439 
440  nrows = len(self._defects)
441  if nrows:
442  for defect in self._defects:
443  box = defect.getBBox()
444  xCol.append(box.getBeginX())
445  yCol.append(box.getBeginY())
446  widthCol.append(box.getWidth())
447  heightCol.append(box.getHeight())
448 
449  catalog = astropy.table.Table({'x0': xCol, 'y0': yCol, 'width': widthCol, 'height': heightCol})
450  inMeta = self.getMetadata().toDict()
451  outMeta = {k: v for k, v in inMeta.items() if v is not None}
452  catalog.meta = outMeta
453  tableList.append(catalog)
454 
455  return tableList
456 

◆ transpose()

def lsst.ip.isr.defects.Defects.transpose (   self)
Make a transposed copy of this defect list.

Returns
-------
retDefectList : `Defects`
    Transposed list of defects.

Definition at line 240 of file defects.py.

240  def transpose(self):
241  """Make a transposed copy of this defect list.
242 
243  Returns
244  -------
245  retDefectList : `Defects`
246  Transposed list of defects.
247  """
248  retDefectList = self.__class__()
249  for defect in self:
250  bbox = defect.getBBox()
251  dimensions = bbox.getDimensions()
252  nbbox = lsst.geom.Box2I(lsst.geom.Point2I(bbox.getMinY(), bbox.getMinX()),
253  lsst.geom.Extent2I(dimensions[1], dimensions[0]))
254  retDefectList.append(nbbox)
255  return retDefectList
256 

◆ updateMetadata()

def lsst.ip.isr.calibType.IsrCalib.updateMetadata (   self,
  camera = None,
  detector = None,
  filterName = None,
  setCalibId = False,
  setCalibInfo = False,
  setDate = False,
**  kwargs 
)
inherited
Update metadata keywords with new values.

Parameters
----------
camera : `lsst.afw.cameraGeom.Camera`, optional
    Reference camera to use to set _instrument field.
detector : `lsst.afw.cameraGeom.Detector`, optional
    Reference detector to use to set _detector* fields.
filterName : `str`, optional
    Filter name to assign to this calibration.
setCalibId : `bool`, optional
    Construct the _calibId field from other fields.
setCalibInfo : `bool`, optional
    Set calibration parameters from metadata.
setDate : `bool`, optional
    Ensure the metadata CALIBDATE fields are set to the current datetime.
kwargs : `dict` or `collections.abc.Mapping`, optional
    Set of key=value pairs to assign to the metadata.

Definition at line 148 of file calibType.py.

150  **kwargs):
151  """Update metadata keywords with new values.
152 
153  Parameters
154  ----------
155  camera : `lsst.afw.cameraGeom.Camera`, optional
156  Reference camera to use to set _instrument field.
157  detector : `lsst.afw.cameraGeom.Detector`, optional
158  Reference detector to use to set _detector* fields.
159  filterName : `str`, optional
160  Filter name to assign to this calibration.
161  setCalibId : `bool`, optional
162  Construct the _calibId field from other fields.
163  setCalibInfo : `bool`, optional
164  Set calibration parameters from metadata.
165  setDate : `bool`, optional
166  Ensure the metadata CALIBDATE fields are set to the current datetime.
167  kwargs : `dict` or `collections.abc.Mapping`, optional
168  Set of key=value pairs to assign to the metadata.
169  """
170  mdOriginal = self.getMetadata()
171  mdSupplemental = dict()
172 
173  for k, v in kwargs.items():
174  if isinstance(v, fits.card.Undefined):
175  kwargs[k] = None
176 
177  if setCalibInfo:
178  self.calibInfoFromDict(kwargs)
179 
180  if camera:
181  self._instrument = camera.getName()
182 
183  if detector:
184  self._detectorName = detector.getName()
185  self._detectorSerial = detector.getSerial()
186  self._detectorId = detector.getId()
187  if "_" in self._detectorName:
188  (self._raftName, self._slotName) = self._detectorName.split("_")
189 
190  if filterName:
191  # TOD0 DM-28093: I think this whole comment can go away, if we
192  # always use physicalLabel everywhere in ip_isr.
193  # If set via:
194  # exposure.getInfo().getFilter().getName()
195  # then this will hold the abstract filter.
196  self._filter = filterName
197 
198  if setDate:
199  date = datetime.datetime.now()
200  mdSupplemental['CALIBDATE'] = date.isoformat()
201  mdSupplemental['CALIB_CREATION_DATE'] = date.date().isoformat()
202  mdSupplemental['CALIB_CREATION_TIME'] = date.time().isoformat()
203 
204  if setCalibId:
205  values = []
206  values.append(f"instrument={self._instrument}") if self._instrument else None
207  values.append(f"raftName={self._raftName}") if self._raftName else None
208  values.append(f"detectorName={self._detectorName}") if self._detectorName else None
209  values.append(f"detector={self._detectorId}") if self._detectorId else None
210  values.append(f"filter={self._filter}") if self._filter else None
211 
212  calibDate = mdOriginal.get('CALIBDATE', mdSupplemental.get('CALIBDATE', None))
213  values.append(f"calibDate={calibDate}") if calibDate else None
214 
215  self._calibId = " ".join(values)
216 
217  self._metadata["INSTRUME"] = self._instrument if self._instrument else None
218  self._metadata["RAFTNAME"] = self._raftName if self._raftName else None
219  self._metadata["SLOTNAME"] = self._slotName if self._slotName else None
220  self._metadata["DETECTOR"] = self._detectorId
221  self._metadata["DET_NAME"] = self._detectorName if self._detectorName else None
222  self._metadata["DET_SER"] = self._detectorSerial if self._detectorSerial else None
223  self._metadata["FILTER"] = self._filter if self._filter else None
224  self._metadata["CALIB_ID"] = self._calibId if self._calibId else None
225 
226  mdSupplemental.update(kwargs)
227  mdOriginal.update(mdSupplemental)
228 

◆ validate()

def lsst.ip.isr.calibType.IsrCalib.validate (   self,
  other = None 
)
inherited
Validate that this calibration is defined and can be used.

Parameters
----------
other : `object`, optional
    Thing to validate against.

Returns
-------
valid : `bool`
    Returns true if the calibration is valid and appropriate.

Definition at line 534 of file calibType.py.

534  def validate(self, other=None):
535  """Validate that this calibration is defined and can be used.
536 
537  Parameters
538  ----------
539  other : `object`, optional
540  Thing to validate against.
541 
542  Returns
543  -------
544  valid : `bool`
545  Returns true if the calibration is valid and appropriate.
546  """
547  return False
548 

◆ writeFits()

def lsst.ip.isr.calibType.IsrCalib.writeFits (   self,
  filename 
)
inherited
Write calibration data to a FITS file.

Parameters
----------
filename : `str`
    Filename to write data to.

Returns
-------
used : `str`
    The name of the file used to write the data.

Definition at line 408 of file calibType.py.

408  def writeFits(self, filename):
409  """Write calibration data to a FITS file.
410 
411  Parameters
412  ----------
413  filename : `str`
414  Filename to write data to.
415 
416  Returns
417  -------
418  used : `str`
419  The name of the file used to write the data.
420 
421  """
422  tableList = self.toTable()
423  with warnings.catch_warnings():
424  warnings.filterwarnings("ignore", category=Warning, module="astropy.io")
425  astropyList = [fits.table_to_hdu(table) for table in tableList]
426  astropyList.insert(0, fits.PrimaryHDU())
427 
428  writer = fits.HDUList(astropyList)
429  writer.writeto(filename, overwrite=True)
430  return filename
431 
def writeFits(filename, stamp_ims, metadata, type_name, write_mask, write_variance)
Definition: stamps.py:40

◆ writeText()

def lsst.ip.isr.calibType.IsrCalib.writeText (   self,
  filename,
  format = 'auto' 
)
inherited
Write the calibration data to a text file.

Parameters
----------
filename : `str`
    Name of the file to write.
format : `str`
    Format to write the file as.  Supported values are:
        ``"auto"`` : Determine filetype from filename.
        ``"yaml"`` : Write as yaml.
        ``"ecsv"`` : Write as ecsv.
Returns
-------
used : `str`
    The name of the file used to write the data.  This may
    differ from the input if the format is explicitly chosen.

Raises
------
RuntimeError :
    Raised if filename does not end in a known extension, or
    if all information cannot be written.

Notes
-----
The file is written to YAML/ECSV format and will include any
associated metadata.

Definition at line 316 of file calibType.py.

316  def writeText(self, filename, format='auto'):
317  """Write the calibration data to a text file.
318 
319  Parameters
320  ----------
321  filename : `str`
322  Name of the file to write.
323  format : `str`
324  Format to write the file as. Supported values are:
325  ``"auto"`` : Determine filetype from filename.
326  ``"yaml"`` : Write as yaml.
327  ``"ecsv"`` : Write as ecsv.
328  Returns
329  -------
330  used : `str`
331  The name of the file used to write the data. This may
332  differ from the input if the format is explicitly chosen.
333 
334  Raises
335  ------
336  RuntimeError :
337  Raised if filename does not end in a known extension, or
338  if all information cannot be written.
339 
340  Notes
341  -----
342  The file is written to YAML/ECSV format and will include any
343  associated metadata.
344 
345  """
346  if format == 'yaml' or (format == 'auto' and filename.lower().endswith((".yaml", ".YAML"))):
347  outDict = self.toDict()
348  path, ext = os.path.splitext(filename)
349  filename = path + ".yaml"
350  with open(filename, 'w') as f:
351  yaml.dump(outDict, f)
352  elif format == 'ecsv' or (format == 'auto' and filename.lower().endswith((".ecsv", ".ECSV"))):
353  tableList = self.toTable()
354  if len(tableList) > 1:
355  # ECSV doesn't support multiple tables per file, so we
356  # can only write the first table.
357  raise RuntimeError(f"Unable to persist {len(tableList)}tables in ECSV format.")
358 
359  table = tableList[0]
360  path, ext = os.path.splitext(filename)
361  filename = path + ".ecsv"
362  table.write(filename, format="ascii.ecsv")
363  else:
364  raise RuntimeError(f"Attempt to write to a file {filename} "
365  "that does not end in '.yaml' or '.ecsv'")
366 
367  return filename
368 

Member Data Documentation

◆ log

lsst.ip.isr.calibType.IsrCalib.log
inherited

Definition at line 82 of file calibType.py.

◆ requiredAttributes

lsst.ip.isr.calibType.IsrCalib.requiredAttributes
inherited

Definition at line 77 of file calibType.py.


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