LSSTApplications  19.0.0-14-gb0260a2+463b159a14,20.0.0+0f5db2c0a9,20.0.0+aad4e2d4eb,20.0.0+bddc4f4cbe,20.0.0+f04b2999c2,20.0.0+f47236d43c,20.0.0-1-g253301a+f47236d43c,20.0.0-1-g2b7511a+821cb29515,20.0.0-1-g5b95a8c+b1532f98d2,20.0.0-1-gedffbd8+e71ed47741,20.0.0-11-gd9dafd18+74fdb5a06a,20.0.0-16-gfab17e72e+e13f79ae9f,20.0.0-19-gb3c8180+37ae35d132,20.0.0-2-g4dae9ad+9ccd17b1a3,20.0.0-2-g61b8584+5d3db074ba,20.0.0-2-gb780d76+d529cf1a41,20.0.0-2-ged6426c+928601e9b9,20.0.0-2-gf072044+f47236d43c,20.0.0-2-gf1f7952+9ccd17b1a3,20.0.0-22-gdf434b7+9ccd17b1a3,20.0.0-23-g10eeb28+96244339af,20.0.0-25-g3dcad98+1dc6abc28c,20.0.0-3-g1653f94+5d3db074ba,20.0.0-3-g4cc78c6+e0676b0dc8,20.0.0-3-g8f21e14+1c0155d006,20.0.0-3-gbd60e8c+187b78b4b8,20.0.0-3-gbecbe05+5dad399003,20.0.0-36-g96d5af2b+2d45f6b8a5,20.0.0-4-g97dc21a+1dc6abc28c,20.0.0-4-gb4befbc+925a411f2f,20.0.0-5-gdfe0fee+60390a8ce6,20.0.0-5-gfbfe500+d529cf1a41,20.0.0-6-g64f541c+d529cf1a41,20.0.0-6-g9a5b7a1+a87ba7c33a,20.0.0-67-g32d6278+9ea4af2944,20.0.0-9-g4aef684+0219fac3b9,w.2020.45
LSSTDataManagementBasePackage
Public Member Functions | List of all members
lsst.meas.algorithms.defects.Defects Class Reference
Inheritance diagram for lsst.meas.algorithms.defects.Defects:

Public Member Functions

def __init__ (self, defectList=None, metadata=None, *normalize_on_init=True)
 
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 insert (self, index, value)
 
def getMetadata (self)
 
def setMetadata (self, metadata=None)
 
def copy (self)
 
def transpose (self)
 
def maskPixels (self, maskedImage, maskName="BAD")
 
def toFitsRegionTable (self)
 
def writeFits (self, *args)
 
def toSimpleTable (self)
 
def writeText (self, filename)
 
def fromTable (cls, table, normalize_on_init=True)
 
def readFits (cls, *args, normalize_on_init=False)
 
def readText (cls, filename, normalize_on_init=False)
 
def readLsstDefectsFile (cls, filename, normalize_on_init=False)
 
def fromFootprintList (cls, fpList)
 
def fromMask (cls, maskedImage, maskName)
 

Detailed Description

Collection 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.

Definition at line 56 of file defects.py.

Constructor & Destructor Documentation

◆ __init__()

def lsst.meas.algorithms.defects.Defects.__init__ (   self,
  defectList = None,
  metadata = None,
normalize_on_init = True 
)

Definition at line 86 of file defects.py.

86  def __init__(self, defectList=None, metadata=None, *, normalize_on_init=True):
87  self._defects = []
88 
89  if defectList is not None:
90  self._bulk_update = True
91  for d in defectList:
92  self.append(d)
93  self._bulk_update = False
94 
95  if normalize_on_init:
96  self._normalize()
97 
98  if metadata is not None:
99  self._metadata = metadata
100  else:
101  self.setMetadata()
102 

Member Function Documentation

◆ __delitem__()

def lsst.meas.algorithms.defects.Defects.__delitem__ (   self,
  index 
)

Definition at line 150 of file defects.py.

150  def __delitem__(self, index):
151  del self._defects[index]
152 

◆ __eq__()

def lsst.meas.algorithms.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.

Definition at line 153 of file defects.py.

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

◆ __getitem__()

def lsst.meas.algorithms.defects.Defects.__getitem__ (   self,
  index 
)

Definition at line 138 of file defects.py.

138  def __getitem__(self, index):
139  return self._defects[index]
140 

◆ __iter__()

def lsst.meas.algorithms.defects.Defects.__iter__ (   self)

Definition at line 147 of file defects.py.

147  def __iter__(self):
148  return iter(self._defects)
149 

◆ __len__()

def lsst.meas.algorithms.defects.Defects.__len__ (   self)

Definition at line 135 of file defects.py.

135  def __len__(self):
136  return len(self._defects)
137 

◆ __setitem__()

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

Definition at line 141 of file defects.py.

141  def __setitem__(self, index, value):
142  """Can be given a `~lsst.meas.algorithms.Defect` or a `lsst.geom.BoxI`
143  """
144  self._defects[index] = self._check_value(value)
145  self._normalize()
146 

◆ __str__()

def lsst.meas.algorithms.defects.Defects.__str__ (   self)

Definition at line 173 of file defects.py.

173  def __str__(self):
174  return "Defects(" + ",".join(str(d.getBBox()) for d in self) + ")"
175 

◆ bulk_update()

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

Definition at line 207 of file defects.py.

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

◆ copy()

def lsst.meas.algorithms.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 251 of file defects.py.

251  def copy(self):
252  """Copy the defects to a new list, creating new defects from the
253  bounding boxes.
254 
255  Returns
256  -------
257  new : `Defects`
258  New list with new `Defect` entries.
259 
260  Notes
261  -----
262  This is not a shallow copy in that new `Defect` instances are
263  created from the original bounding boxes. It's also not a deep
264  copy since the bounding boxes are not recreated.
265  """
266  return self.__class__(d.getBBox() for d in self)
267 

◆ fromFootprintList()

def lsst.meas.algorithms.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 777 of file defects.py.

777  def fromFootprintList(cls, fpList):
778  """Compute a defect list from a footprint list, optionally growing
779  the footprints.
780 
781  Parameters
782  ----------
783  fpList : `list` of `lsst.afw.detection.Footprint`
784  Footprint list to process.
785 
786  Returns
787  -------
788  defects : `Defects`
789  List of defects.
790  """
791  # normalize_on_init is set to False to avoid recursively calling
792  # fromMask/fromFootprintList in Defects.__init__.
793  return cls(itertools.chain.from_iterable(lsst.afw.detection.footprintToBBoxList(fp)
794  for fp in fpList), normalize_on_init=False)
795 

◆ fromMask()

def lsst.meas.algorithms.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 797 of file defects.py.

797  def fromMask(cls, maskedImage, maskName):
798  """Compute a defect list from a specified mask plane.
799 
800  Parameters
801  ----------
802  maskedImage : `lsst.afw.image.MaskedImage`
803  Image to process.
804  maskName : `str` or `list`
805  Mask plane name, or list of names to convert.
806 
807  Returns
808  -------
809  defects : `Defects`
810  Defect list constructed from masked pixels.
811  """
812  mask = maskedImage.getMask()
813  thresh = lsst.afw.detection.Threshold(mask.getPlaneBitMask(maskName),
814  lsst.afw.detection.Threshold.BITMASK)
815  fpList = lsst.afw.detection.FootprintSet(mask, thresh).getFootprints()
816  return cls.fromFootprintList(fpList)

◆ fromTable()

def lsst.meas.algorithms.defects.Defects.fromTable (   cls,
  table,
  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 535 of file defects.py.

535  def fromTable(cls, table, normalize_on_init=True):
536  """Construct a `Defects` from the contents of a
537  `~lsst.afw.table.BaseCatalog`.
538 
539  Parameters
540  ----------
541  table : `lsst.afw.table.BaseCatalog`
542  Table with one row per defect.
543  normalize_on_init : `bool`, optional
544  If `True`, normalization is applied to the defects listed in the
545  table to remove duplicates, eliminate overlaps, etc. Otherwise
546  the defects in the returned object exactly match those in the
547  table.
548 
549  Returns
550  -------
551  defects : `Defects`
552  A `Defects` list.
553 
554  Notes
555  -----
556  Two table formats are recognized. The first is the
557  `FITS regions <https://fits.gsfc.nasa.gov/registry/region.html>`_
558  definition tabular format written by `toFitsRegionTable` where the
559  pixel origin is corrected from FITS 1-based to a 0-based origin.
560  The second is the legacy defects format using columns ``x0``, ``y0``
561  (bottom left hand pixel of box in 0-based coordinates), ``width``
562  and ``height``.
563 
564  The FITS standard regions can only read BOX, POINT, or ROTBOX with
565  a zero degree rotation.
566  """
567 
568  defectList = []
569 
570  schema = table.getSchema()
571 
572  # Check schema to see which definitions we have
573  if "X" in schema and "Y" in schema and "R" in schema and "SHAPE" in schema:
574  # This is a FITS region style table
575  isFitsRegion = True
576 
577  # Preselect the keys
578  xKey = schema["X"].asKey()
579  yKey = schema["Y"].asKey()
580  shapeKey = schema["SHAPE"].asKey()
581  rKey = schema["R"].asKey()
582  rotangKey = schema["ROTANG"].asKey()
583 
584  elif "x0" in schema and "y0" in schema and "width" in schema and "height" in schema:
585  # This is a classic LSST-style defect table
586  isFitsRegion = False
587 
588  # Preselect the keys
589  xKey = schema["x0"].asKey()
590  yKey = schema["y0"].asKey()
591  widthKey = schema["width"].asKey()
592  heightKey = schema["height"].asKey()
593 
594  else:
595  raise ValueError("Unsupported schema for defects extraction")
596 
597  for record in table:
598 
599  if isFitsRegion:
600  # Coordinates can be arrays (some shapes in the standard
601  # require this)
602  # Correct for FITS 1-based origin
603  xcen = cls._get_values(record[xKey]) - 1.0
604  ycen = cls._get_values(record[yKey]) - 1.0
605  shape = record[shapeKey].upper()
606  if shape == "BOX":
608  lsst.geom.Extent2I(cls._get_values(record[rKey],
609  n=2)))
610  elif shape == "POINT":
611  # Handle the case where we have an externally created
612  # FITS file.
613  box = lsst.geom.Point2I(xcen, ycen)
614  elif shape == "ROTBOX":
615  # Astropy regions always writes ROTBOX
616  rotang = cls._get_values(record[rotangKey])
617  # We can support 0 or 90 deg
618  if math.isclose(rotang % 90.0, 0.0):
619  # Two values required
620  r = cls._get_values(record[rKey], n=2)
621  if math.isclose(rotang % 180.0, 0.0):
622  width = r[0]
623  height = r[1]
624  else:
625  width = r[1]
626  height = r[0]
628  lsst.geom.Extent2I(width, height))
629  else:
630  log.warning("Defect can not be defined using ROTBOX with non-aligned rotation angle")
631  continue
632  else:
633  log.warning("Defect lists can only be defined using BOX or POINT not %s", shape)
634  continue
635 
636  else:
637  # This is a classic LSST-style defect table
638  box = lsst.geom.Box2I(lsst.geom.Point2I(record[xKey], record[yKey]),
639  lsst.geom.Extent2I(record[widthKey], record[heightKey]))
640 
641  defectList.append(box)
642 
643  defects = cls(defectList, normalize_on_init=normalize_on_init)
644  defects.setMetadata(table.getMetadata())
645 
646  # Once read, the schema headers are irrelevant
647  metadata = defects.getMetadata()
648  for k in (SCHEMA_NAME_KEY, SCHEMA_VERSION_KEY):
649  if k in metadata:
650  del metadata[k]
651 
652  return defects
653 

◆ getMetadata()

def lsst.meas.algorithms.defects.Defects.getMetadata (   self)
Retrieve metadata associated with these `Defects`.

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 221 of file defects.py.

221  def getMetadata(self):
222  """Retrieve metadata associated with these `Defects`.
223 
224  Returns
225  -------
226  meta : `lsst.daf.base.PropertyList`
227  Metadata. The returned `~lsst.daf.base.PropertyList` can be
228  modified by the caller and the changes will be written to
229  external files.
230  """
231  return self._metadata
232 

◆ insert()

def lsst.meas.algorithms.defects.Defects.insert (   self,
  index,
  value 
)

Definition at line 217 of file defects.py.

217  def insert(self, index, value):
218  self._defects.insert(index, self._check_value(value))
219  self._normalize()
220 

◆ maskPixels()

def lsst.meas.algorithms.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 285 of file defects.py.

285  def maskPixels(self, maskedImage, maskName="BAD"):
286  """Set mask plane based on these defects.
287 
288  Parameters
289  ----------
290  maskedImage : `lsst.afw.image.MaskedImage`
291  Image to process. Only the mask plane is updated.
292  maskName : str, optional
293  Mask plane name to use.
294  """
295  # mask bad pixels
296  mask = maskedImage.getMask()
297  bitmask = mask.getPlaneBitMask(maskName)
298  for defect in self:
299  bbox = defect.getBBox()
300  lsst.afw.geom.SpanSet(bbox).clippedTo(mask.getBBox()).setMask(mask, bitmask)
301 

◆ readFits()

def lsst.meas.algorithms.defects.Defects.readFits (   cls,
args,
  normalize_on_init = False 
)
Read defect list from FITS table.

Parameters
----------
*args
    Arguments to be forwarded to
    `lsst.afw.table.BaseCatalog.readFits`.
normalize_on_init : `bool`, optional
    If `True`, normalization is applied to the defects read fom the
    file to remove duplicates, eliminate overlaps, etc. Otherwise
    the defects in the returned object exactly match those in the
    file.

Returns
-------
defects : `Defects`
    Defects read from a FITS table.

Definition at line 655 of file defects.py.

655  def readFits(cls, *args, normalize_on_init=False):
656  """Read defect list from FITS table.
657 
658  Parameters
659  ----------
660  *args
661  Arguments to be forwarded to
662  `lsst.afw.table.BaseCatalog.readFits`.
663  normalize_on_init : `bool`, optional
664  If `True`, normalization is applied to the defects read fom the
665  file to remove duplicates, eliminate overlaps, etc. Otherwise
666  the defects in the returned object exactly match those in the
667  file.
668 
669  Returns
670  -------
671  defects : `Defects`
672  Defects read from a FITS table.
673  """
674  table = lsst.afw.table.BaseCatalog.readFits(*args)
675  return cls.fromTable(table, normalize_on_init=normalize_on_init)
676 

◆ readLsstDefectsFile()

def lsst.meas.algorithms.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 read fom the
    file to remove duplicates, eliminate overlaps, etc. Otherwise
    the defects in the returned object exactly match those in the
    file.

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 727 of file defects.py.

727  def readLsstDefectsFile(cls, filename, normalize_on_init=False):
728  """Read defects information from a legacy LSST format text file.
729 
730  Parameters
731  ----------
732  filename : `str`
733  Name of text file containing the defect information.
734  normalize_on_init : `bool`, optional
735  If `True`, normalization is applied to the defects read fom the
736  file to remove duplicates, eliminate overlaps, etc. Otherwise
737  the defects in the returned object exactly match those in the
738  file.
739 
740  Returns
741  -------
742  defects : `Defects`
743  The defects.
744 
745  Notes
746  -----
747  These defect text files are used as the human readable definitions
748  of defects in calibration data definition repositories. The format
749  is to use four columns defined as follows:
750 
751  x0 : `int`
752  X coordinate of bottom left corner of box.
753  y0 : `int`
754  Y coordinate of bottom left corner of box.
755  width : `int`
756  X extent of the box.
757  height : `int`
758  Y extent of the box.
759 
760  Files of this format were used historically to represent defects
761  in simple text form. Use `Defects.readText` and `Defects.writeText`
762  to use the more modern format.
763  """
764  # Use loadtxt so that ValueError is thrown if the file contains a
765  # non-integer value. genfromtxt converts bad values to -1.
766  defect_array = np.loadtxt(filename,
767  dtype=[("x0", "int"), ("y0", "int"),
768  ("x_extent", "int"), ("y_extent", "int")])
769 
770  defects = (lsst.geom.Box2I(lsst.geom.Point2I(row["x0"], row["y0"]),
771  lsst.geom.Extent2I(row["x_extent"], row["y_extent"]))
772  for row in defect_array)
773 
774  return cls(defects, normalize_on_init=normalize_on_init)
775 

◆ readText()

def lsst.meas.algorithms.defects.Defects.readText (   cls,
  filename,
  normalize_on_init = False 
)
Read defect list from standard format text table file.

Parameters
----------
filename : `str`
    Name of the file containing the defects definitions.
normalize_on_init : `bool`, optional
    If `True`, normalization is applied to the defects read fom the
    file to remove duplicates, eliminate overlaps, etc. Otherwise
    the defects in the returned object exactly match those in the
    file.

Returns
-------
defects : `Defects`
    Defects read from a FITS table.

Definition at line 678 of file defects.py.

678  def readText(cls, filename, normalize_on_init=False):
679  """Read defect list from standard format text table file.
680 
681  Parameters
682  ----------
683  filename : `str`
684  Name of the file containing the defects definitions.
685  normalize_on_init : `bool`, optional
686  If `True`, normalization is applied to the defects read fom the
687  file to remove duplicates, eliminate overlaps, etc. Otherwise
688  the defects in the returned object exactly match those in the
689  file.
690 
691  Returns
692  -------
693  defects : `Defects`
694  Defects read from a FITS table.
695  """
696  with warnings.catch_warnings():
697  # Squash warnings due to astropy failure to close files; we think
698  # this is a real problem, but the warnings are even worse.
699  # https://github.com/astropy/astropy/issues/8673
700  warnings.filterwarnings("ignore", category=ResourceWarning, module="astropy.io.ascii")
701  table = astropy.table.Table.read(filename)
702 
703  # Need to convert the Astropy table to afw table
704  schema = lsst.afw.table.Schema()
705  for colName in table.columns:
706  schema.addField(colName, units=str(table[colName].unit),
707  type=table[colName].dtype.type)
708 
709  # Create AFW table that is required by fromTable()
710  afwTable = lsst.afw.table.BaseCatalog(schema)
711 
712  afwTable.resize(len(table))
713  for colName in table.columns:
714  # String columns will fail -- currently we do not expect any
715  afwTable[colName] = table[colName]
716 
717  # Copy in the metadata from the astropy table
718  metadata = PropertyList()
719  for k, v in table.meta.items():
720  metadata[k] = v
721  afwTable.setMetadata(metadata)
722 
723  # Extract defect information from the table itself
724  return cls.fromTable(afwTable, normalize_on_init=normalize_on_init)
725 

◆ setMetadata()

def lsst.meas.algorithms.defects.Defects.setMetadata (   self,
  metadata = None 
)
Store a copy of the supplied metadata with the defects.

Parameters
----------
metadata : `lsst.daf.base.PropertyList`, optional
    Metadata to associate with the defects.  Will be copied and
    overwrite existing metadata.  If not supplied the existing
    metadata will be reset.

Definition at line 233 of file defects.py.

233  def setMetadata(self, metadata=None):
234  """Store a copy of the supplied metadata with the defects.
235 
236  Parameters
237  ----------
238  metadata : `lsst.daf.base.PropertyList`, optional
239  Metadata to associate with the defects. Will be copied and
240  overwrite existing metadata. If not supplied the existing
241  metadata will be reset.
242  """
243  if metadata is None:
244  self._metadata = PropertyList()
245  else:
246  self._metadata = copy.copy(metadata)
247 
248  # Ensure that we have the obs type required by calibration ingest
249  self._metadata["OBSTYPE"] = self._OBSTYPE
250 

◆ toFitsRegionTable()

def lsst.meas.algorithms.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 302 of file defects.py.

302  def toFitsRegionTable(self):
303  """Convert defect list to `~lsst.afw.table.BaseCatalog` using the
304  FITS region standard.
305 
306  Returns
307  -------
308  table : `lsst.afw.table.BaseCatalog`
309  Defects in tabular form.
310 
311  Notes
312  -----
313  The table created uses the
314  `FITS regions <https://fits.gsfc.nasa.gov/registry/region.html>`_
315  definition tabular format. The ``X`` and ``Y`` coordinates are
316  converted to FITS Physical coordinates that have origin pixel (1, 1)
317  rather than the (0, 0) used in LSST software.
318  """
319 
320  nrows = len(self._defects)
321 
322  schema = lsst.afw.table.Schema()
323  x = schema.addField("X", type="D", units="pix", doc="X coordinate of center of shape")
324  y = schema.addField("Y", type="D", units="pix", doc="Y coordinate of center of shape")
325  shape = schema.addField("SHAPE", type="String", size=16, doc="Shape defined by these values")
326  r = schema.addField("R", type="ArrayD", size=2, units="pix", doc="Extents")
327  rotang = schema.addField("ROTANG", type="D", units="deg", doc="Rotation angle")
328  component = schema.addField("COMPONENT", type="I", doc="Index of this region")
329  table = lsst.afw.table.BaseCatalog(schema)
330  table.resize(nrows)
331 
332  if nrows:
333  # Adding entire columns is more efficient than adding
334  # each element separately
335  xCol = []
336  yCol = []
337  rCol = []
338 
339  for i, defect in enumerate(self._defects):
340  box = defect.getBBox()
341  center = box.getCenter()
342  # Correct for the FITS 1-based offset
343  xCol.append(center.getX() + 1.0)
344  yCol.append(center.getY() + 1.0)
345 
346  width = box.width
347  height = box.height
348 
349  if width == 1 and height == 1:
350  # Call this a point
351  shapeType = "POINT"
352  else:
353  shapeType = "BOX"
354 
355  # Strings have to be added per row
356  table[i][shape] = shapeType
357 
358  rCol.append(np.array([width, height], dtype=np.float64))
359 
360  # Assign the columns
361  table[x] = np.array(xCol, dtype=np.float64)
362  table[y] = np.array(yCol, dtype=np.float64)
363 
364  table[r] = np.array(rCol)
365  table[rotang] = np.zeros(nrows, dtype=np.float64)
366  table[component] = np.arange(nrows)
367 
368  # Set some metadata in the table (force OBSTYPE to exist)
369  metadata = copy.copy(self.getMetadata())
370  metadata["OBSTYPE"] = self._OBSTYPE
371  metadata[SCHEMA_NAME_KEY] = "FITS Region"
372  metadata[SCHEMA_VERSION_KEY] = 1
373  table.setMetadata(metadata)
374 
375  return table
376 

◆ toSimpleTable()

def lsst.meas.algorithms.defects.Defects.toSimpleTable (   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.

Definition at line 397 of file defects.py.

397  def toSimpleTable(self):
398  """Convert defects to a simple table form that we use to write
399  to text files.
400 
401  Returns
402  -------
403  table : `lsst.afw.table.BaseCatalog`
404  Defects in simple tabular form.
405 
406  Notes
407  -----
408  These defect tables are used as the human readable definitions
409  of defects in calibration data definition repositories. The format
410  is to use four columns defined as follows:
411 
412  x0 : `int`
413  X coordinate of bottom left corner of box.
414  y0 : `int`
415  Y coordinate of bottom left corner of box.
416  width : `int`
417  X extent of the box.
418  height : `int`
419  Y extent of the box.
420  """
421  schema = lsst.afw.table.Schema()
422  x = schema.addField("x0", type="I", units="pix",
423  doc="X coordinate of bottom left corner of box")
424  y = schema.addField("y0", type="I", units="pix",
425  doc="Y coordinate of bottom left corner of box")
426  width = schema.addField("width", type="I", units="pix",
427  doc="X extent of box")
428  height = schema.addField("height", type="I", units="pix",
429  doc="Y extent of box")
430  table = lsst.afw.table.BaseCatalog(schema)
431 
432  nrows = len(self._defects)
433  table.resize(nrows)
434 
435  if nrows:
436 
437  xCol = []
438  yCol = []
439  widthCol = []
440  heightCol = []
441 
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  table[x] = np.array(xCol, dtype=np.int64)
450  table[y] = np.array(yCol, dtype=np.int64)
451  table[width] = np.array(widthCol, dtype=np.int64)
452  table[height] = np.array(heightCol, dtype=np.int64)
453 
454  # Set some metadata in the table (force OBSTYPE to exist)
455  metadata = copy.copy(self.getMetadata())
456  metadata["OBSTYPE"] = self._OBSTYPE
457  metadata[SCHEMA_NAME_KEY] = "Simple"
458  metadata[SCHEMA_VERSION_KEY] = 1
459  table.setMetadata(metadata)
460 
461  return table
462 

◆ transpose()

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

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

Definition at line 268 of file defects.py.

268  def transpose(self):
269  """Make a transposed copy of this defect list.
270 
271  Returns
272  -------
273  retDefectList : `Defects`
274  Transposed list of defects.
275  """
276  retDefectList = self.__class__()
277  for defect in self:
278  bbox = defect.getBBox()
279  dimensions = bbox.getDimensions()
280  nbbox = lsst.geom.Box2I(lsst.geom.Point2I(bbox.getMinY(), bbox.getMinX()),
281  lsst.geom.Extent2I(dimensions[1], dimensions[0]))
282  retDefectList.append(nbbox)
283  return retDefectList
284 

◆ writeFits()

def lsst.meas.algorithms.defects.Defects.writeFits (   self,
args 
)
Write defect list to FITS.

Parameters
----------
*args
    Arguments to be forwarded to
    `lsst.afw.table.BaseCatalog.writeFits`.

Definition at line 377 of file defects.py.

377  def writeFits(self, *args):
378  """Write defect list to FITS.
379 
380  Parameters
381  ----------
382  *args
383  Arguments to be forwarded to
384  `lsst.afw.table.BaseCatalog.writeFits`.
385  """
386  table = self.toFitsRegionTable()
387 
388  # Add some additional headers useful for tracking purposes
389  metadata = table.getMetadata()
390  now = datetime.datetime.utcnow()
391  metadata["DATE"] = now.isoformat()
392  metadata["CALIB_CREATION_DATE"] = now.strftime("%Y-%m-%d")
393  metadata["CALIB_CREATION_TIME"] = now.strftime("%T %Z").strip()
394 
395  table.writeFits(*args)
396 

◆ writeText()

def lsst.meas.algorithms.defects.Defects.writeText (   self,
  filename 
)
Write the defects out to a text file with the specified name.

Parameters
----------
filename : `str`
    Name of the file to write.  The file extension ".ecsv" will
    always be used.

Returns
-------
used : `str`
    The name of the file used to write the data (which may be
    different from the supplied name given the change to file
    extension).

Notes
-----
The file is written to ECSV format and will include any metadata
associated with the `Defects`.

Definition at line 463 of file defects.py.

463  def writeText(self, filename):
464  """Write the defects out to a text file with the specified name.
465 
466  Parameters
467  ----------
468  filename : `str`
469  Name of the file to write. The file extension ".ecsv" will
470  always be used.
471 
472  Returns
473  -------
474  used : `str`
475  The name of the file used to write the data (which may be
476  different from the supplied name given the change to file
477  extension).
478 
479  Notes
480  -----
481  The file is written to ECSV format and will include any metadata
482  associated with the `Defects`.
483  """
484 
485  # Using astropy table is the easiest way to serialize to ecsv
486  afwTable = self.toSimpleTable()
487  table = afwTable.asAstropy()
488 
489  metadata = afwTable.getMetadata()
490  now = datetime.datetime.utcnow()
491  metadata["DATE"] = now.isoformat()
492  metadata["CALIB_CREATION_DATE"] = now.strftime("%Y-%m-%d")
493  metadata["CALIB_CREATION_TIME"] = now.strftime("%T %Z").strip()
494 
495  table.meta = metadata.toDict()
496 
497  # Force file extension to .ecsv
498  path, ext = os.path.splitext(filename)
499  filename = path + ".ecsv"
500  table.write(filename, format="ascii.ecsv")
501  return filename
502 

The documentation for this class was generated from the following file:
lsst::geom::Box2I::makeCenteredBox
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
lsst::afw::table::Schema
Defines the fields and offsets for a table.
Definition: Schema.h:50
strip
bool strip
Definition: fits.cc:911
lsst::afw::geom.transform.transformContinued.cls
cls
Definition: transformContinued.py:33
lsst::afw::detection::FootprintSet
A set of Footprints, associated with a MaskedImage.
Definition: FootprintSet.h:53
lsst::afw::geom::SpanSet
A compact representation of a collection of pixels.
Definition: SpanSet.h:78
lsst::afw::detection::footprintToBBoxList
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
lsst::afw::detection::Threshold
A Threshold is used to pass a threshold value to detection algorithms.
Definition: Threshold.h:43
lsst::geom::Point< double, 2 >
lsst::geom::Box2I
An integer coordinate rectangle.
Definition: Box.h:55
lsst::afw::table::CatalogT< BaseRecord >
lsst::geom::Extent< int, 2 >
astshim.fitsChanContinued.iter
def iter(self)
Definition: fitsChanContinued.py:88