lsst.meas.algorithms  19.0.0-17-gde1f5b76+1
defects.py
Go to the documentation of this file.
1 #
2 # LSST Data Management System
3 #
4 # Copyright 2008-2017 AURA/LSST.
5 #
6 # This product includes software developed by the
7 # LSST Project (http://www.lsst.org/).
8 #
9 # This program is free software: you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation, either version 3 of the License, or
12 # (at your option) any later version.
13 #
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
18 #
19 # You should have received a copy of the LSST License Statement and
20 # the GNU General Public License along with this program. If not,
21 # see <https://www.lsstcorp.org/LegalNotices/>.
22 #
23 """Support for image defects"""
24 
25 __all__ = ("Defects",)
26 
27 import logging
28 import itertools
29 import collections.abc
30 import numpy as np
31 import copy
32 import datetime
33 import math
34 import numbers
35 import os.path
36 import warnings
37 import astropy.table
38 
39 import lsst.geom
40 import lsst.afw.table
41 import lsst.afw.detection
42 import lsst.afw.image
43 import lsst.afw.geom
44 from lsst.daf.base import PropertyList
45 
46 from . import Defect
47 
48 log = logging.getLogger(__name__)
49 
50 SCHEMA_NAME_KEY = "DEFECTS_SCHEMA"
51 SCHEMA_VERSION_KEY = "DEFECTS_SCHEMA_VERSION"
52 
53 
54 class Defects(collections.abc.MutableSequence):
55  """Collection of `lsst.meas.algorithms.Defect`.
56 
57  Parameters
58  ----------
59  defectList : iterable of `lsst.meas.algorithms.Defect`
60  or `lsst.geom.BoxI`, optional
61  Collections of defects to apply to the image.
62  """
63 
64  _OBSTYPE = "defects"
65  """The calibration type used for ingest."""
66 
67  def __init__(self, defectList=None, metadata=None):
68  self._defects = []
69 
70  if metadata is not None:
71  self._metadata = metadata
72  else:
73  self.setMetadata()
74 
75  if defectList is None:
76  return
77 
78  # Ensure that type checking
79  for d in defectList:
80  self.append(d)
81 
82  def _check_value(self, value):
83  """Check that the supplied value is a `~lsst.meas.algorithms.Defect`
84  or can be converted to one.
85 
86  Parameters
87  ----------
88  value : `object`
89  Value to check.
90 
91  Returns
92  -------
93  new : `~lsst.meas.algorithms.Defect`
94  Either the supplied value or a new object derived from it.
95 
96  Raises
97  ------
98  ValueError
99  Raised if the supplied value can not be converted to
100  `~lsst.meas.algorithms.Defect`
101  """
102  if isinstance(value, Defect):
103  pass
104  elif isinstance(value, lsst.geom.BoxI):
105  value = Defect(value)
106  elif isinstance(value, lsst.geom.PointI):
107  value = Defect(lsst.geom.Box2I(value, lsst.geom.Extent2I(1, 1)))
108  elif isinstance(value, lsst.afw.image.DefectBase):
109  value = Defect(value.getBBox())
110  else:
111  raise ValueError(f"Defects must be of type Defect, BoxI, or PointI, not '{value!r}'")
112  return value
113 
114  def __len__(self):
115  return len(self._defects)
116 
117  def __getitem__(self, index):
118  return self._defects[index]
119 
120  def __setitem__(self, index, value):
121  """Can be given a `~lsst.meas.algorithms.Defect` or a `lsst.geom.BoxI`
122  """
123  self._defects[index] = self._check_value(value)
124 
125  def __iter__(self):
126  return iter(self._defects)
127 
128  def __delitem__(self, index):
129  del self._defects[index]
130 
131  def __eq__(self, other):
132  """Compare if two `Defects` are equal.
133 
134  Two `Defects` are equal if their bounding boxes are equal and in
135  the same order. Metadata content is ignored.
136  """
137  if not isinstance(other, self.__class__):
138  return False
139 
140  # checking the bboxes with zip() only works if same length
141  if len(self) != len(other):
142  return False
143 
144  # Assume equal if bounding boxes are equal
145  for d1, d2 in zip(self, other):
146  if d1.getBBox() != d2.getBBox():
147  return False
148 
149  return True
150 
151  def __str__(self):
152  return "Defects(" + ",".join(str(d.getBBox()) for d in self) + ")"
153 
154  def insert(self, index, value):
155  self._defects.insert(index, self._check_value(value))
156 
157  def getMetadata(self):
158  """Retrieve metadata associated with these `Defects`.
159 
160  Returns
161  -------
162  meta : `lsst.daf.base.PropertyList`
163  Metadata. The returned `~lsst.daf.base.PropertyList` can be
164  modified by the caller and the changes will be written to
165  external files.
166  """
167  return self._metadata
168 
169  def setMetadata(self, metadata=None):
170  """Store a copy of the supplied metadata with the defects.
171 
172  Parameters
173  ----------
174  metadata : `lsst.daf.base.PropertyList`, optional
175  Metadata to associate with the defects. Will be copied and
176  overwrite existing metadata. If not supplied the existing
177  metadata will be reset.
178  """
179  if metadata is None:
180  self._metadata = PropertyList()
181  else:
182  self._metadata = copy.copy(metadata)
183 
184  # Ensure that we have the obs type required by calibration ingest
185  self._metadata["OBSTYPE"] = self._OBSTYPE
186 
187  def copy(self):
188  """Copy the defects to a new list, creating new defects from the
189  bounding boxes.
190 
191  Returns
192  -------
193  new : `Defects`
194  New list with new `Defect` entries.
195 
196  Notes
197  -----
198  This is not a shallow copy in that new `Defect` instances are
199  created from the original bounding boxes. It's also not a deep
200  copy since the bounding boxes are not recreated.
201  """
202  return self.__class__(d.getBBox() for d in self)
203 
204  def transpose(self):
205  """Make a transposed copy of this defect list.
206 
207  Returns
208  -------
209  retDefectList : `Defects`
210  Transposed list of defects.
211  """
212  retDefectList = self.__class__()
213  for defect in self:
214  bbox = defect.getBBox()
215  dimensions = bbox.getDimensions()
216  nbbox = lsst.geom.Box2I(lsst.geom.Point2I(bbox.getMinY(), bbox.getMinX()),
217  lsst.geom.Extent2I(dimensions[1], dimensions[0]))
218  retDefectList.append(nbbox)
219  return retDefectList
220 
221  def maskPixels(self, maskedImage, maskName="BAD"):
222  """Set mask plane based on these defects.
223 
224  Parameters
225  ----------
226  maskedImage : `lsst.afw.image.MaskedImage`
227  Image to process. Only the mask plane is updated.
228  maskName : str, optional
229  Mask plane name to use.
230  """
231  # mask bad pixels
232  mask = maskedImage.getMask()
233  bitmask = mask.getPlaneBitMask(maskName)
234  for defect in self:
235  bbox = defect.getBBox()
236  lsst.afw.geom.SpanSet(bbox).clippedTo(mask.getBBox()).setMask(mask, bitmask)
237 
238  def toFitsRegionTable(self):
239  """Convert defect list to `~lsst.afw.table.BaseCatalog` using the
240  FITS region standard.
241 
242  Returns
243  -------
244  table : `lsst.afw.table.BaseCatalog`
245  Defects in tabular form.
246 
247  Notes
248  -----
249  The table created uses the
250  `FITS regions <https://fits.gsfc.nasa.gov/registry/region.html>`_
251  definition tabular format. The ``X`` and ``Y`` coordinates are
252  converted to FITS Physical coordinates that have origin pixel (1, 1)
253  rather than the (0, 0) used in LSST software.
254  """
255 
256  nrows = len(self._defects)
257 
258  schema = lsst.afw.table.Schema()
259  x = schema.addField("X", type="D", units="pix", doc="X coordinate of center of shape")
260  y = schema.addField("Y", type="D", units="pix", doc="Y coordinate of center of shape")
261  shape = schema.addField("SHAPE", type="String", size=16, doc="Shape defined by these values")
262  r = schema.addField("R", type="ArrayD", size=2, units="pix", doc="Extents")
263  rotang = schema.addField("ROTANG", type="D", units="deg", doc="Rotation angle")
264  component = schema.addField("COMPONENT", type="I", doc="Index of this region")
265  table = lsst.afw.table.BaseCatalog(schema)
266  table.resize(nrows)
267 
268  if nrows:
269  # Adding entire columns is more efficient than adding
270  # each element separately
271  xCol = []
272  yCol = []
273  rCol = []
274 
275  for i, defect in enumerate(self._defects):
276  box = defect.getBBox()
277  center = box.getCenter()
278  # Correct for the FITS 1-based offset
279  xCol.append(center.getX() + 1.0)
280  yCol.append(center.getY() + 1.0)
281 
282  width = box.width
283  height = box.height
284 
285  if width == 1 and height == 1:
286  # Call this a point
287  shapeType = "POINT"
288  else:
289  shapeType = "BOX"
290 
291  # Strings have to be added per row
292  table[i][shape] = shapeType
293 
294  rCol.append(np.array([width, height], dtype=np.float64))
295 
296  # Assign the columns
297  table[x] = np.array(xCol, dtype=np.float64)
298  table[y] = np.array(yCol, dtype=np.float64)
299 
300  table[r] = np.array(rCol)
301  table[rotang] = np.zeros(nrows, dtype=np.float64)
302  table[component] = np.arange(nrows)
303 
304  # Set some metadata in the table (force OBSTYPE to exist)
305  metadata = copy.copy(self.getMetadata())
306  metadata["OBSTYPE"] = self._OBSTYPE
307  metadata[SCHEMA_NAME_KEY] = "FITS Region"
308  metadata[SCHEMA_VERSION_KEY] = 1
309  table.setMetadata(metadata)
310 
311  return table
312 
313  def writeFits(self, *args):
314  """Write defect list to FITS.
315 
316  Parameters
317  ----------
318  *args
319  Arguments to be forwarded to
320  `lsst.afw.table.BaseCatalog.writeFits`.
321  """
322  table = self.toFitsRegionTable()
323 
324  # Add some additional headers useful for tracking purposes
325  metadata = table.getMetadata()
326  now = datetime.datetime.utcnow()
327  metadata["DATE"] = now.isoformat()
328  metadata["CALIB_CREATION_DATE"] = now.strftime("%Y-%m-%d")
329  metadata["CALIB_CREATION_TIME"] = now.strftime("%T %Z").strip()
330 
331  table.writeFits(*args)
332 
333  def toSimpleTable(self):
334  """Convert defects to a simple table form that we use to write
335  to text files.
336 
337  Returns
338  -------
339  table : `lsst.afw.table.BaseCatalog`
340  Defects in simple tabular form.
341 
342  Notes
343  -----
344  These defect tables are used as the human readable definitions
345  of defects in calibration data definition repositories. The format
346  is to use four columns defined as follows:
347 
348  x0 : `int`
349  X coordinate of bottom left corner of box.
350  y0 : `int`
351  Y coordinate of bottom left corner of box.
352  width : `int`
353  X extent of the box.
354  height : `int`
355  Y extent of the box.
356  """
357  schema = lsst.afw.table.Schema()
358  x = schema.addField("x0", type="I", units="pix",
359  doc="X coordinate of bottom left corner of box")
360  y = schema.addField("y0", type="I", units="pix",
361  doc="Y coordinate of bottom left corner of box")
362  width = schema.addField("width", type="I", units="pix",
363  doc="X extent of box")
364  height = schema.addField("height", type="I", units="pix",
365  doc="Y extent of box")
366  table = lsst.afw.table.BaseCatalog(schema)
367 
368  nrows = len(self._defects)
369  table.resize(nrows)
370 
371  if nrows:
372 
373  xCol = []
374  yCol = []
375  widthCol = []
376  heightCol = []
377 
378  for defect in self._defects:
379  box = defect.getBBox()
380  xCol.append(box.getBeginX())
381  yCol.append(box.getBeginY())
382  widthCol.append(box.getWidth())
383  heightCol.append(box.getHeight())
384 
385  table[x] = np.array(xCol, dtype=np.int64)
386  table[y] = np.array(yCol, dtype=np.int64)
387  table[width] = np.array(widthCol, dtype=np.int64)
388  table[height] = np.array(heightCol, dtype=np.int64)
389 
390  # Set some metadata in the table (force OBSTYPE to exist)
391  metadata = copy.copy(self.getMetadata())
392  metadata["OBSTYPE"] = self._OBSTYPE
393  metadata[SCHEMA_NAME_KEY] = "Simple"
394  metadata[SCHEMA_VERSION_KEY] = 1
395  table.setMetadata(metadata)
396 
397  return table
398 
399  def writeText(self, filename):
400  """Write the defects out to a text file with the specified name.
401 
402  Parameters
403  ----------
404  filename : `str`
405  Name of the file to write. The file extension ".ecsv" will
406  always be used.
407 
408  Returns
409  -------
410  used : `str`
411  The name of the file used to write the data (which may be
412  different from the supplied name given the change to file
413  extension).
414 
415  Notes
416  -----
417  The file is written to ECSV format and will include any metadata
418  associated with the `Defects`.
419  """
420 
421  # Using astropy table is the easiest way to serialize to ecsv
422  afwTable = self.toSimpleTable()
423  table = afwTable.asAstropy()
424 
425  metadata = afwTable.getMetadata()
426  now = datetime.datetime.utcnow()
427  metadata["DATE"] = now.isoformat()
428  metadata["CALIB_CREATION_DATE"] = now.strftime("%Y-%m-%d")
429  metadata["CALIB_CREATION_TIME"] = now.strftime("%T %Z").strip()
430 
431  table.meta = metadata.toDict()
432 
433  # Force file extension to .ecsv
434  path, ext = os.path.splitext(filename)
435  filename = path + ".ecsv"
436  table.write(filename, format="ascii.ecsv")
437  return filename
438 
439  @staticmethod
440  def _get_values(values, n=1):
441  """Retrieve N values from the supplied values.
442 
443  Parameters
444  ----------
445  values : `numbers.Number` or `list` or `np.array`
446  Input values.
447  n : `int`
448  Number of values to retrieve.
449 
450  Returns
451  -------
452  vals : `list` or `np.array` or `numbers.Number`
453  Single value from supplied list if ``n`` is 1, or `list`
454  containing first ``n`` values from supplied values.
455 
456  Notes
457  -----
458  Some supplied tables have vectors in some columns that can also
459  be scalars. This method can be used to get the first number as
460  a scalar or the first N items from a vector as a vector.
461  """
462  if n == 1:
463  if isinstance(values, numbers.Number):
464  return values
465  else:
466  return values[0]
467 
468  return values[:n]
469 
470  @classmethod
471  def fromTable(cls, table):
472  """Construct a `Defects` from the contents of a
473  `~lsst.afw.table.BaseCatalog`.
474 
475  Parameters
476  ----------
477  table : `lsst.afw.table.BaseCatalog`
478  Table with one row per defect.
479 
480  Returns
481  -------
482  defects : `Defects`
483  A `Defects` list.
484 
485  Notes
486  -----
487  Two table formats are recognized. The first is the
488  `FITS regions <https://fits.gsfc.nasa.gov/registry/region.html>`_
489  definition tabular format written by `toFitsRegionTable` where the
490  pixel origin is corrected from FITS 1-based to a 0-based origin.
491  The second is the legacy defects format using columns ``x0``, ``y0``
492  (bottom left hand pixel of box in 0-based coordinates), ``width``
493  and ``height``.
494 
495  The FITS standard regions can only read BOX, POINT, or ROTBOX with
496  a zero degree rotation.
497  """
498 
499  defectList = []
500 
501  schema = table.getSchema()
502 
503  # Check schema to see which definitions we have
504  if "X" in schema and "Y" in schema and "R" in schema and "SHAPE" in schema:
505  # This is a FITS region style table
506  isFitsRegion = True
507 
508  # Preselect the keys
509  xKey = schema["X"].asKey()
510  yKey = schema["Y"].asKey()
511  shapeKey = schema["SHAPE"].asKey()
512  rKey = schema["R"].asKey()
513  rotangKey = schema["ROTANG"].asKey()
514 
515  elif "x0" in schema and "y0" in schema and "width" in schema and "height" in schema:
516  # This is a classic LSST-style defect table
517  isFitsRegion = False
518 
519  # Preselect the keys
520  xKey = schema["x0"].asKey()
521  yKey = schema["y0"].asKey()
522  widthKey = schema["width"].asKey()
523  heightKey = schema["height"].asKey()
524 
525  else:
526  raise ValueError("Unsupported schema for defects extraction")
527 
528  for record in table:
529 
530  if isFitsRegion:
531  # Coordinates can be arrays (some shapes in the standard
532  # require this)
533  # Correct for FITS 1-based origin
534  xcen = cls._get_values(record[xKey]) - 1.0
535  ycen = cls._get_values(record[yKey]) - 1.0
536  shape = record[shapeKey].upper()
537  if shape == "BOX":
539  lsst.geom.Extent2I(cls._get_values(record[rKey],
540  n=2)))
541  elif shape == "POINT":
542  # Handle the case where we have an externally created
543  # FITS file.
544  box = lsst.geom.Point2I(xcen, ycen)
545  elif shape == "ROTBOX":
546  # Astropy regions always writes ROTBOX
547  rotang = cls._get_values(record[rotangKey])
548  # We can support 0 or 90 deg
549  if math.isclose(rotang % 90.0, 0.0):
550  # Two values required
551  r = cls._get_values(record[rKey], n=2)
552  if math.isclose(rotang % 180.0, 0.0):
553  width = r[0]
554  height = r[1]
555  else:
556  width = r[1]
557  height = r[0]
559  lsst.geom.Extent2I(width, height))
560  else:
561  log.warning("Defect can not be defined using ROTBOX with non-aligned rotation angle")
562  continue
563  else:
564  log.warning("Defect lists can only be defined using BOX or POINT not %s", shape)
565  continue
566 
567  else:
568  # This is a classic LSST-style defect table
569  box = lsst.geom.Box2I(lsst.geom.Point2I(record[xKey], record[yKey]),
570  lsst.geom.Extent2I(record[widthKey], record[heightKey]))
571 
572  defectList.append(box)
573 
574  defects = cls(defectList)
575  defects.setMetadata(table.getMetadata())
576 
577  # Once read, the schema headers are irrelevant
578  metadata = defects.getMetadata()
579  for k in (SCHEMA_NAME_KEY, SCHEMA_VERSION_KEY):
580  if k in metadata:
581  del metadata[k]
582 
583  return defects
584 
585  @classmethod
586  def readFits(cls, *args):
587  """Read defect list from FITS table.
588 
589  Parameters
590  ----------
591  *args
592  Arguments to be forwarded to
593  `lsst.afw.table.BaseCatalog.writeFits`.
594 
595  Returns
596  -------
597  defects : `Defects`
598  Defects read from a FITS table.
599  """
600  table = lsst.afw.table.BaseCatalog.readFits(*args)
601  return cls.fromTable(table)
602 
603  @classmethod
604  def readText(cls, filename):
605  """Read defect list from standard format text table file.
606 
607  Parameters
608  ----------
609  filename : `str`
610  Name of the file containing the defects definitions.
611 
612  Returns
613  -------
614  defects : `Defects`
615  Defects read from a FITS table.
616  """
617  with warnings.catch_warnings():
618  # Squash warnings due to astropy failure to close files; we think
619  # this is a real problem, but the warnings are even worse.
620  # https://github.com/astropy/astropy/issues/8673
621  warnings.filterwarnings("ignore", category=ResourceWarning, module="astropy.io.ascii")
622  table = astropy.table.Table.read(filename)
623 
624  # Need to convert the Astropy table to afw table
625  schema = lsst.afw.table.Schema()
626  for colName in table.columns:
627  schema.addField(colName, units=str(table[colName].unit),
628  type=table[colName].dtype.type)
629 
630  # Create AFW table that is required by fromTable()
631  afwTable = lsst.afw.table.BaseCatalog(schema)
632 
633  afwTable.resize(len(table))
634  for colName in table.columns:
635  # String columns will fail -- currently we do not expect any
636  afwTable[colName] = table[colName]
637 
638  # Copy in the metadata from the astropy table
639  metadata = PropertyList()
640  for k, v in table.meta.items():
641  metadata[k] = v
642  afwTable.setMetadata(metadata)
643 
644  # Extract defect information from the table itself
645  return cls.fromTable(afwTable)
646 
647  @classmethod
648  def readLsstDefectsFile(cls, filename):
649  """Read defects information from a legacy LSST format text file.
650 
651  Parameters
652  ----------
653  filename : `str`
654  Name of text file containing the defect information.
655 
656  Returns
657  -------
658  defects : `Defects`
659  The defects.
660 
661  Notes
662  -----
663  These defect text files are used as the human readable definitions
664  of defects in calibration data definition repositories. The format
665  is to use four columns defined as follows:
666 
667  x0 : `int`
668  X coordinate of bottom left corner of box.
669  y0 : `int`
670  Y coordinate of bottom left corner of box.
671  width : `int`
672  X extent of the box.
673  height : `int`
674  Y extent of the box.
675 
676  Files of this format were used historically to represent defects
677  in simple text form. Use `Defects.readText` and `Defects.writeText`
678  to use the more modern format.
679  """
680  # Use loadtxt so that ValueError is thrown if the file contains a
681  # non-integer value. genfromtxt converts bad values to -1.
682  defect_array = np.loadtxt(filename,
683  dtype=[("x0", "int"), ("y0", "int"),
684  ("x_extent", "int"), ("y_extent", "int")])
685 
686  return cls(lsst.geom.Box2I(lsst.geom.Point2I(row["x0"], row["y0"]),
687  lsst.geom.Extent2I(row["x_extent"], row["y_extent"]))
688  for row in defect_array)
689 
690  @classmethod
691  def fromFootprintList(cls, fpList):
692  """Compute a defect list from a footprint list, optionally growing
693  the footprints.
694 
695  Parameters
696  ----------
697  fpList : `list` of `lsst.afw.detection.Footprint`
698  Footprint list to process.
699 
700  Returns
701  -------
702  defects : `Defects`
703  List of defects.
704  """
705  return cls(itertools.chain.from_iterable(lsst.afw.detection.footprintToBBoxList(fp)
706  for fp in fpList))
707 
708  @classmethod
709  def fromMask(cls, maskedImage, maskName):
710  """Compute a defect list from a specified mask plane.
711 
712  Parameters
713  ----------
714  maskedImage : `lsst.afw.image.MaskedImage`
715  Image to process.
716  maskName : `str` or `list`
717  Mask plane name, or list of names to convert.
718 
719  Returns
720  -------
721  defects : `Defects`
722  Defect list constructed from masked pixels.
723  """
724  mask = maskedImage.getMask()
725  thresh = lsst.afw.detection.Threshold(mask.getPlaneBitMask(maskName),
726  lsst.afw.detection.Threshold.BITMASK)
727  fpList = lsst.afw.detection.FootprintSet(mask, thresh).getFootprints()
728  return cls.fromFootprintList(fpList)
lsst::meas::algorithms.defects.Defects.__setitem__
def __setitem__(self, index, value)
Definition: defects.py:120
lsst::afw::image
lsst::meas::algorithms.defects.Defects._get_values
def _get_values(values, n=1)
Definition: defects.py:440
lsst::meas::algorithms.defects.Defects
Definition: defects.py:54
lsst::meas::algorithms.defects.Defects.__delitem__
def __delitem__(self, index)
Definition: defects.py:128
lsst::geom::Box2I::makeCenteredBox
static Box2I makeCenteredBox(Point2D const &center, Extent const &size)
lsst::meas::algorithms.defects.Defects._check_value
def _check_value(self, value)
Definition: defects.py:82
lsst::daf::base::PropertyList
lsst::meas::algorithms.defects.Defects.getMetadata
def getMetadata(self)
Definition: defects.py:157
lsst::afw::table::Schema
lsst::meas::algorithms.defects.Defects.__str__
def __str__(self)
Definition: defects.py:151
lsst::meas::algorithms.defects.Defects.fromFootprintList
def fromFootprintList(cls, fpList)
Definition: defects.py:691
lsst::meas::algorithms.defects.Defects._OBSTYPE
string _OBSTYPE
Definition: defects.py:64
lsst::meas::algorithms.defects.Defects.readText
def readText(cls, filename)
Definition: defects.py:604
lsst::meas::algorithms.defects.Defects.toSimpleTable
def toSimpleTable(self)
Definition: defects.py:333
lsst::afw::detection::FootprintSet
lsst::afw::image::DefectBase
lsst::meas::algorithms.defects.Defects.writeFits
def writeFits(self, *args)
Definition: defects.py:313
lsst::afw::geom::SpanSet
lsst::afw::detection::footprintToBBoxList
std::vector< lsst::geom::Box2I > footprintToBBoxList(Footprint const &footprint)
lsst::meas::algorithms.defects.Defects.__iter__
def __iter__(self)
Definition: defects.py:125
lsst::meas::algorithms.defects.Defects._defects
_defects
Definition: defects.py:68
lsst::afw::detection::Threshold
lsst::meas::algorithms.defects.Defects.__eq__
def __eq__(self, other)
Definition: defects.py:131
lsst::meas::algorithms.defects.Defects.fromTable
def fromTable(cls, table)
Definition: defects.py:471
lsst::meas::algorithms.defects.Defects.__init__
def __init__(self, defectList=None, metadata=None)
Definition: defects.py:67
lsst::afw::table
lsst::meas::algorithms.defects.Defects.setMetadata
def setMetadata(self, metadata=None)
Definition: defects.py:169
lsst::meas::algorithms.defects.Defects.fromMask
def fromMask(cls, maskedImage, maskName)
Definition: defects.py:709
lsst::afw::detection
lsst::meas::algorithms.defects.Defects.transpose
def transpose(self)
Definition: defects.py:204
lsst::geom
lsst::meas::algorithms.defects.Defects.__getitem__
def __getitem__(self, index)
Definition: defects.py:117
lsst::daf::base
lsst::meas::algorithms.defects.Defects.maskPixels
def maskPixels(self, maskedImage, maskName="BAD")
Definition: defects.py:221
lsst::meas::algorithms.defects.Defects.readLsstDefectsFile
def readLsstDefectsFile(cls, filename)
Definition: defects.py:648
Point< int, 2 >
lsst::meas::algorithms.defects.Defects.copy
def copy(self)
Definition: defects.py:187
lsst::geom::Box2I
lsst::meas::algorithms.defects.Defects.readFits
def readFits(cls, *args)
Definition: defects.py:586
lsst::meas::algorithms.defects.Defects._metadata
_metadata
Definition: defects.py:71
lsst::meas::algorithms.defects.Defects.__len__
def __len__(self)
Definition: defects.py:114
lsst::meas::algorithms.defects.Defects.toFitsRegionTable
def toFitsRegionTable(self)
Definition: defects.py:238
CatalogT< BaseRecord >
Extent< int, 2 >
lsst::meas::algorithms.defects.Defects.insert
def insert(self, index, value)
Definition: defects.py:154
lsst::meas::algorithms.defects.Defects.writeText
def writeText(self, filename)
Definition: defects.py:399
lsst::afw::geom