lsst.ip.isr  20.0.0-4-ge987224+4
crosstalk.py
Go to the documentation of this file.
1 #
2 # LSST Data Management System
3 # Copyright 2008-2017 AURA/LSST.
4 #
5 # This product includes software developed by the
6 # LSST Project (http://www.lsst.org/).
7 #
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
12 #
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the LSST License Statement and
19 # the GNU General Public License along with this program. If not,
20 # see <https://www.lsstcorp.org/LegalNotices/>.
21 #
22 """
23 Apply intra-detector crosstalk corrections
24 """
25 import numpy as np
26 from astropy.table import Table
27 
28 import lsst.afw.math
29 import lsst.afw.detection
30 from lsst.pex.config import Config, Field, ChoiceField, ListField
31 from lsst.pipe.base import Task
32 
33 from lsst.ip.isr import IsrCalib
34 
35 
36 __all__ = ["CrosstalkCalib", "CrosstalkConfig", "CrosstalkTask",
37  "NullCrosstalkTask"]
38 
39 
41  """Calibration of amp-to-amp crosstalk coefficients.
42 
43  Parameters
44  ----------
45  detector : `lsst.afw.cameraGeom.Detector`, optional
46  Detector to use to pull coefficients from.
47  log : `lsst.log.Log`, optional
48  Log to write messages to.
49  **kwargs :
50  Parameters to pass to parent constructor.
51  """
52  _OBSTYPE = 'CROSSTALK'
53  _SCHEMA = 'Gen3 Crosstalk'
54  _VERSION = 1.0
55 
56  def __init__(self, detector=None, **kwargs):
57  self.hasCrosstalk = False
58  self.nAmp = 0
59  self.crosstalkShape = (self.nAmp, self.nAmp)
60 
61  self.coeffs = None
62  self.coeffErr = None
63  self.coeffNum = None
64  self.interChip = None
65 
66  super().__init__(**kwargs)
67  self.requiredAttributes.update(['hasCrosstalk', 'nAmp', 'coeffs',
68  'coeffErr', 'coeffNum', 'interChip'])
69  if detector:
70  self.fromDetector(detector)
71 
72  def updateMetadata(self, setDate=False, **kwargs):
73  """Update calibration metadata.
74 
75  This calls the base class's method after ensuring the required
76  calibration keywords will be saved.
77 
78  Parameters
79  ----------
80  setDate : `bool`, optional
81  Update the CALIBDATE fields in the metadata to the current
82  time. Defaults to False.
83  kwargs :
84  Other keyword parameters to set in the metadata.
85  """
86  kwargs['DETECTOR'] = self._detectorName
87  kwargs['DETECTOR_SERIAL'] = self._detectorSerial
88  kwargs['HAS_CROSSTALK'] = self.hasCrosstalk
89  kwargs['NAMP'] = self.nAmp
90  self.crosstalkShape = (self.nAmp, self.nAmp)
91  kwargs['CROSSTALK_SHAPE'] = self.crosstalkShape
92 
93  super().updateMetadata(setDate=setDate, **kwargs)
94 
95  def fromDetector(self, detector, coeffVector=None):
96  """Set calibration parameters from the detector.
97 
98  Parameters
99  ----------
100  detector : `lsst.afw.cameraGeom.Detector`
101  Detector to use to set parameters from.
102  coeffVector : `numpy.array`, optional
103  Use the detector geometry (bounding boxes and flip
104  information), but use ``coeffVector`` instead of the
105  output of ``detector.getCrosstalk()``.
106 
107  Returns
108  -------
109  calib : `lsst.ip.isr.CrosstalkCalib`
110  The calibration constructed from the detector.
111 
112  """
113  if detector.hasCrosstalk() or coeffVector:
114  self._detectorName = detector.getName()
115  self._detectorSerial = detector.getSerial()
116 
117  self.nAmp = len(detector)
118  self.crosstalkShape = (self.nAmp, self.nAmp)
119 
120  if coeffVector is not None:
121  crosstalkCoeffs = coeffVector
122  else:
123  crosstalkCoeffs = detector.getCrosstalk()
124  if len(crosstalkCoeffs) == 1 and crosstalkCoeffs[0] == 0.0:
125  return self
126  self.coeffs = np.array(crosstalkCoeffs).reshape(self.crosstalkShape)
127 
128  if self.coeffs.shape != self.crosstalkShape:
129  raise RuntimeError("Crosstalk coefficients do not match detector shape. "
130  f"{self.crosstalkShape} {self.nAmp}")
131 
132  self.interChip = {}
133  self.hasCrosstalk = True
134  self.updateMetadata()
135  return self
136 
137  @classmethod
138  def fromDict(cls, dictionary):
139  """Construct a calibration from a dictionary of properties.
140 
141  Must be implemented by the specific calibration subclasses.
142 
143  Parameters
144  ----------
145  dictionary : `dict`
146  Dictionary of properties.
147 
148  Returns
149  -------
150  calib : `lsst.ip.isr.CalibType`
151  Constructed calibration.
152 
153  Raises
154  ------
155  RuntimeError :
156  Raised if the supplied dictionary is for a different
157  calibration.
158  """
159  calib = cls()
160 
161  if calib._OBSTYPE != dictionary['metadata']['OBSTYPE']:
162  raise RuntimeError(f"Incorrect crosstalk supplied. Expected {calib._OBSTYPE}, "
163  f"found {dictionary['metadata']['OBSTYPE']}")
164 
165  calib.setMetadata(dictionary['metadata'])
166  calib._detectorName = dictionary['metadata']['DETECTOR']
167  calib._detectorSerial = dictionary['metadata']['DETECTOR_SERIAL']
168 
169  calib.hasCrosstalk = dictionary.get('hasCrosstalk',
170  dictionary['metadata'].get('HAS_CROSSTALK', False))
171  if calib.hasCrosstalk:
172  calib.nAmp = dictionary.get('nAmp', dictionary['metadata'].get('NAMP', 0))
173  calib.crosstalkShape = (calib.nAmp, calib.nAmp)
174  calib.coeffs = np.array(dictionary['coeffs']).reshape(calib.crosstalkShape)
175 
176  calib.interChip = dictionary.get('interChip', None)
177  if calib.interChip:
178  for detector in calib.interChip:
179  coeffVector = calib.interChip[detector]
180  calib.interChip[detector] = np.array(coeffVector).reshape(calib.crosstalkShape)
181 
182  calib.updateMetadata()
183  return calib
184 
185  def toDict(self):
186  """Return a dictionary containing the calibration properties.
187 
188  The dictionary should be able to be round-tripped through
189  `fromDict`.
190 
191  Returns
192  -------
193  dictionary : `dict`
194  Dictionary of properties.
195  """
196  self.updateMetadata()
197 
198  outDict = {}
199  metadata = self.getMetadata()
200  outDict['metadata'] = metadata
201 
202  outDict['hasCrosstalk'] = self.hasCrosstalk
203  outDict['nAmp'] = self.nAmp
204  outDict['crosstalkShape'] = self.crosstalkShape
205 
206  ctLength = self.nAmp*self.nAmp
207  outDict['coeffs'] = self.coeffs.reshape(ctLength).tolist()
208 
209  if self.coeffErr is not None:
210  outDict['coeffErr'] = self.coeffErr.reshape(ctLength).tolist()
211  if self.coeffNum is not None:
212  outDict['coeffNum'] = self.coeffNum.reshape(ctLength).tolist()
213 
214  if self.interChip:
215  outDict['interChip'] = dict()
216  for detector in self.interChip:
217  outDict['interChip'][detector] = self.interChip[detector].reshape(ctLength).tolist()
218 
219  return outDict
220 
221  @classmethod
222  def fromTable(cls, tableList):
223  """Construct calibration from a list of tables.
224 
225  This method uses the `fromDict` method to create the
226  calibration, after constructing an appropriate dictionary from
227  the input tables.
228 
229  Parameters
230  ----------
231  tableList : `list` [`lsst.afw.table.Table`]
232  List of tables to use to construct the crosstalk
233  calibration.
234 
235  Returns
236  -------
237  calib : `lsst.ip.isr.CrosstalkCalib`
238  The calibration defined in the tables.
239 
240  """
241  coeffTable = tableList[0]
242 
243  metadata = coeffTable.meta
244  inDict = dict()
245  inDict['metadata'] = metadata
246  inDict['hasCrosstalk'] = metadata['HAS_CROSSTALK']
247  inDict['nAmp'] = metadata['NAMP']
248 
249  inDict['coeffs'] = coeffTable['CT_COEFFS']
250  if len(tableList) > 1:
251  inDict['interChip'] = dict()
252  interChipTable = tableList[1]
253  for record in interChipTable:
254  inDict['interChip'][record['IC_SOURCE_DET']] = record['IC_COEFFS']
255 
256  return cls().fromDict(inDict)
257 
258  def toTable(self):
259  """Construct a list of tables containing the information in this calibration.
260 
261  The list of tables should create an identical calibration
262  after being passed to this class's fromTable method.
263 
264  Returns
265  -------
266  tableList : `list` [`lsst.afw.table.Table`]
267  List of tables containing the crosstalk calibration
268  information.
269 
270  """
271  tableList = []
272  self.updateMetadata()
273  catalog = Table([{'CT_COEFFS': self.coeffs.reshape(self.nAmp*self.nAmp)}])
274  catalog.meta = self.getMetadata().toDict()
275  tableList.append(catalog)
276 
277  if self.interChip:
278  interChipTable = Table([{'IC_SOURCE_DET': sourceDet,
279  'IC_COEFFS': self.interChip[sourceDet].reshape(self.nAmp*self.nAmp)}
280  for sourceDet in self.interChip.keys()])
281  tableList.append(interChipTable)
282  return tableList
283 
284  # Implementation methods.
285  def extractAmp(self, image, amp, ampTarget, isTrimmed=False):
286  """Extract the image data from an amp, flipped to match ampTarget.
287 
288  Parameters
289  ----------
290  image : `lsst.afw.image.Image` or `lsst.afw.image.MaskedImage`
291  Image containing the amplifier of interest.
292  amp : `lsst.afw.cameraGeom.Amplifier`
293  Amplifier on image to extract.
294  ampTarget : `lsst.afw.cameraGeom.Amplifier`
295  Target amplifier that the extracted image will be flipped
296  to match.
297  isTrimmed : `bool`
298  The image is already trimmed.
299  TODO : DM-15409 will resolve this.
300 
301  Returns
302  -------
303  output : `lsst.afw.image.Image`
304  Image of the amplifier in the desired configuration.
305  """
306  X_FLIP = {lsst.afw.cameraGeom.ReadoutCorner.LL: False,
307  lsst.afw.cameraGeom.ReadoutCorner.LR: True,
308  lsst.afw.cameraGeom.ReadoutCorner.UL: False,
309  lsst.afw.cameraGeom.ReadoutCorner.UR: True}
310  Y_FLIP = {lsst.afw.cameraGeom.ReadoutCorner.LL: False,
311  lsst.afw.cameraGeom.ReadoutCorner.LR: False,
312  lsst.afw.cameraGeom.ReadoutCorner.UL: True,
313  lsst.afw.cameraGeom.ReadoutCorner.UR: True}
314 
315  output = image[amp.getBBox() if isTrimmed else amp.getRawDataBBox()]
316  thisAmpCorner = amp.getReadoutCorner()
317  targetAmpCorner = ampTarget.getReadoutCorner()
318 
319  # Flipping is necessary only if the desired configuration doesn't match what we currently have
320  xFlip = X_FLIP[targetAmpCorner] ^ X_FLIP[thisAmpCorner]
321  yFlip = Y_FLIP[targetAmpCorner] ^ Y_FLIP[thisAmpCorner]
322  self.log.debug("Extract amp: %s %s %s %s",
323  amp.getName(), ampTarget.getName(), thisAmpCorner, targetAmpCorner)
324  return lsst.afw.math.flipImage(output, xFlip, yFlip)
325 
326  def calculateBackground(self, mi, badPixels=["BAD"]):
327  """Estimate median background in image.
328 
329  Getting a great background model isn't important for crosstalk correction,
330  since the crosstalk is at a low level. The median should be sufficient.
331 
332  Parameters
333  ----------
334  mi : `lsst.afw.image.MaskedImage`
335  MaskedImage for which to measure background.
336  badPixels : `list` of `str`
337  Mask planes to ignore.
338  Returns
339  -------
340  bg : `float`
341  Median background level.
342  """
343  mask = mi.getMask()
345  stats.setAndMask(mask.getPlaneBitMask(badPixels))
346  return lsst.afw.math.makeStatistics(mi, lsst.afw.math.MEDIAN, stats).getValue()
347 
348  def subtractCrosstalk(self, thisExposure, sourceExposure=None, crosstalkCoeffs=None,
349  badPixels=["BAD"], minPixelToMask=45000,
350  crosstalkStr="CROSSTALK", isTrimmed=False,
351  backgroundMethod="None"):
352  """Subtract the crosstalk from thisExposure, optionally using a different source.
353 
354  We set the mask plane indicated by ``crosstalkStr`` in a target amplifier
355  for pixels in a source amplifier that exceed ``minPixelToMask``. Note that
356  the correction is applied to all pixels in the amplifier, but only those
357  that have a substantial crosstalk are masked with ``crosstalkStr``.
358 
359  The uncorrected image is used as a template for correction. This is good
360  enough if the crosstalk is small (e.g., coefficients < ~ 1e-3), but if it's
361  larger you may want to iterate.
362 
363  Parameters
364  ----------
365  thisExposure : `lsst.afw.image.Exposure`
366  Exposure for which to subtract crosstalk.
367  sourceExposure : `lsst.afw.image.Exposure`, optional
368  Exposure to use as the source of the crosstalk. If not set,
369  thisExposure is used as the source (intra-detector crosstalk).
370  crosstalkCoeffs : `numpy.ndarray`, optional.
371  Coefficients to use to correct crosstalk.
372  badPixels : `list` of `str`
373  Mask planes to ignore.
374  minPixelToMask : `float`
375  Minimum pixel value (relative to the background level) in
376  source amplifier for which to set ``crosstalkStr`` mask plane
377  in target amplifier.
378  crosstalkStr : `str`
379  Mask plane name for pixels greatly modified by crosstalk
380  (above minPixelToMask).
381  isTrimmed : `bool`
382  The image is already trimmed.
383  This should no longer be needed once DM-15409 is resolved.
384  backgroundMethod : `str`
385  Method used to subtract the background. "AMP" uses
386  amplifier-by-amplifier background levels, "DETECTOR" uses full
387  exposure/maskedImage levels. Any other value results in no
388  background subtraction.
389  """
390  mi = thisExposure.getMaskedImage()
391  mask = mi.getMask()
392  detector = thisExposure.getDetector()
393  if self.hasCrosstalk is False:
394  self.fromDetector(detector, coeffVector=crosstalkCoeffs)
395 
396  numAmps = len(detector)
397  if numAmps != self.nAmp:
398  raise RuntimeError(f"Crosstalk built for {self.nAmp} in {self._detectorName}, received "
399  f"{numAmps} in {detector.getName()}")
400 
401  if sourceExposure:
402  source = sourceExposure.getMaskedImage()
403  sourceDetector = sourceExposure.getDetector()
404  else:
405  source = mi
406  sourceDetector = detector
407 
408  if crosstalkCoeffs is not None:
409  coeffs = crosstalkCoeffs
410  else:
411  coeffs = self.coeffs
412  self.log.debug("CT COEFF: %s", coeffs)
413  # Set background level based on the requested method. The
414  # thresholdBackground holds the offset needed so that we only mask
415  # pixels high relative to the background, not in an absolute
416  # sense.
417  thresholdBackground = self.calculateBackground(source, badPixels)
418 
419  backgrounds = [0.0 for amp in sourceDetector]
420  if backgroundMethod is None:
421  pass
422  elif backgroundMethod == "AMP":
423  backgrounds = [self.calculateBackground(source[amp.getBBox()], badPixels)
424  for amp in sourceDetector]
425  elif backgroundMethod == "DETECTOR":
426  backgrounds = [self.calculateBackground(source, badPixels) for amp in sourceDetector]
427 
428  # Set the crosstalkStr bit for the bright pixels (those which will have
429  # significant crosstalk correction)
430  crosstalkPlane = mask.addMaskPlane(crosstalkStr)
431  footprints = lsst.afw.detection.FootprintSet(source,
432  lsst.afw.detection.Threshold(minPixelToMask
433  + thresholdBackground))
434  footprints.setMask(mask, crosstalkStr)
435  crosstalk = mask.getPlaneBitMask(crosstalkStr)
436 
437  # Define a subtrahend image to contain all the scaled crosstalk signals
438  subtrahend = source.Factory(source.getBBox())
439  subtrahend.set((0, 0, 0))
440 
441  coeffs = coeffs.transpose()
442  for ii, iAmp in enumerate(sourceDetector):
443  iImage = subtrahend[iAmp.getBBox() if isTrimmed else iAmp.getRawDataBBox()]
444  for jj, jAmp in enumerate(detector):
445  if coeffs[ii, jj] == 0.0:
446  continue
447  jImage = self.extractAmp(mi, jAmp, iAmp, isTrimmed)
448  jImage.getMask().getArray()[:] &= crosstalk # Remove all other masks
449  jImage -= backgrounds[jj]
450  iImage.scaledPlus(coeffs[ii, jj], jImage)
451 
452  # Set crosstalkStr bit only for those pixels that have been significantly modified (i.e., those
453  # masked as such in 'subtrahend'), not necessarily those that are bright originally.
454  mask.clearMaskPlane(crosstalkPlane)
455  mi -= subtrahend # also sets crosstalkStr bit for bright pixels
456 
457 
458 class CrosstalkConfig(Config):
459  """Configuration for intra-detector crosstalk removal."""
460  minPixelToMask = Field(
461  dtype=float,
462  doc="Set crosstalk mask plane for pixels over this value.",
463  default=45000
464  )
465  crosstalkMaskPlane = Field(
466  dtype=str,
467  doc="Name for crosstalk mask plane.",
468  default="CROSSTALK"
469  )
470  crosstalkBackgroundMethod = ChoiceField(
471  dtype=str,
472  doc="Type of background subtraction to use when applying correction.",
473  default="None",
474  allowed={
475  "None": "Do no background subtraction.",
476  "AMP": "Subtract amplifier-by-amplifier background levels.",
477  "DETECTOR": "Subtract detector level background."
478  },
479  )
480  useConfigCoefficients = Field(
481  dtype=bool,
482  doc="Ignore the detector crosstalk information in favor of CrosstalkConfig values?",
483  default=False,
484  )
485  crosstalkValues = ListField(
486  dtype=float,
487  doc=("Amplifier-indexed crosstalk coefficients to use. This should be arranged as a 1 x nAmp**2 "
488  "list of coefficients, such that when reshaped by crosstalkShape, the result is nAmp x nAmp. "
489  "This matrix should be structured so CT * [amp0 amp1 amp2 ...]^T returns the column "
490  "vector [corr0 corr1 corr2 ...]^T."),
491  default=[0.0],
492  )
493  crosstalkShape = ListField(
494  dtype=int,
495  doc="Shape of the coefficient array. This should be equal to [nAmp, nAmp].",
496  default=[1],
497  )
498 
499  def getCrosstalk(self, detector=None):
500  """Return a 2-D numpy array of crosstalk coefficients in the proper shape.
501 
502  Parameters
503  ----------
504  detector : `lsst.afw.cameraGeom.detector`
505  Detector that is to be crosstalk corrected.
506 
507  Returns
508  -------
509  coeffs : `numpy.ndarray`
510  Crosstalk coefficients that can be used to correct the detector.
511 
512  Raises
513  ------
514  RuntimeError
515  Raised if no coefficients could be generated from this detector/configuration.
516  """
517  if self.useConfigCoefficients is True:
518  coeffs = np.array(self.crosstalkValues).reshape(self.crosstalkShape)
519  if detector is not None:
520  nAmp = len(detector)
521  if coeffs.shape != (nAmp, nAmp):
522  raise RuntimeError("Constructed crosstalk coeffients do not match detector shape. "
523  f"{coeffs.shape} {nAmp}")
524  return coeffs
525  elif detector is not None and detector.hasCrosstalk() is True:
526  # Assume the detector defines itself consistently.
527  return detector.getCrosstalk()
528  else:
529  raise RuntimeError("Attempted to correct crosstalk without crosstalk coefficients")
530 
531  def hasCrosstalk(self, detector=None):
532  """Return a boolean indicating if crosstalk coefficients exist.
533 
534  Parameters
535  ----------
536  detector : `lsst.afw.cameraGeom.detector`
537  Detector that is to be crosstalk corrected.
538 
539  Returns
540  -------
541  hasCrosstalk : `bool`
542  True if this detector/configuration has crosstalk coefficients defined.
543  """
544  if self.useConfigCoefficients is True and self.crosstalkValues is not None:
545  return True
546  elif detector is not None and detector.hasCrosstalk() is True:
547  return True
548  else:
549  return False
550 
551 
552 class CrosstalkTask(Task):
553  """Apply intra-detector crosstalk correction."""
554  ConfigClass = CrosstalkConfig
555  _DefaultName = 'isrCrosstalk'
556 
557  def prepCrosstalk(self, dataRef, crosstalk=None):
558  """Placeholder for crosstalk preparation method, e.g., for inter-detector crosstalk.
559 
560  Parameters
561  ----------
562  dataRef : `daf.persistence.butlerSubset.ButlerDataRef`
563  Butler reference of the detector data to be processed.
564  crosstalk : `~lsst.ip.isr.CrosstalkConfig`
565  Crosstalk calibration that will be used.
566 
567  See also
568  --------
569  lsst.obs.decam.crosstalk.DecamCrosstalkTask.prepCrosstalk
570  """
571  return
572 
573  def run(self, exposure, crosstalk=None,
574  crosstalkSources=None, isTrimmed=False):
575  """Apply intra-detector crosstalk correction
576 
577  Parameters
578  ----------
579  exposure : `lsst.afw.image.Exposure`
580  Exposure for which to remove crosstalk.
581  crosstalkCalib : `lsst.ip.isr.CrosstalkCalib`, optional
582  External crosstalk calibration to apply. Constructed from
583  detector if not found.
584  crosstalkSources : `defaultdict`, optional
585  Image data for other detectors that are sources of
586  crosstalk in exposure. The keys are expected to be names
587  of the other detectors, with the values containing
588  `lsst.afw.image.Exposure` at the same level of processing
589  as ``exposure``.
590  The default for intra-detector crosstalk here is None.
591  isTrimmed : `bool`
592  The image is already trimmed.
593  This should no longer be needed once DM-15409 is resolved.
594 
595  Raises
596  ------
597  RuntimeError
598  Raised if called for a detector that does not have a
599  crosstalk correction.
600  """
601  if not crosstalk:
602  crosstalk = CrosstalkCalib(log=self.log)
603  crosstalk = crosstalk.fromDetector(exposure.getDetector(),
604  coeffVector=self.config.crosstalkValues)
605  if not crosstalk.log:
606  crosstalk.log = self.log
607  if not crosstalk.hasCrosstalk:
608  raise RuntimeError("Attempted to correct crosstalk without crosstalk coefficients.")
609 
610  else:
611  self.log.info("Applying crosstalk correction.")
612  crosstalk.subtractCrosstalk(exposure, crosstalkCoeffs=crosstalk.coeffs,
613  minPixelToMask=self.config.minPixelToMask,
614  crosstalkStr=self.config.crosstalkMaskPlane, isTrimmed=isTrimmed,
615  backgroundMethod=self.config.crosstalkBackgroundMethod)
616 
617  if crosstalk.interChip:
618  if crosstalkSources:
619  for detName in crosstalk.interChip:
620  if isinstance(crosstalkSources[0], 'lsst.afw.image.Exposure'):
621  # Received afwImage.Exposure
622  sourceNames = [exp.getDetector().getName() for exp in crosstalkSources]
623  else:
624  # Received dafButler.DeferredDatasetHandle
625  sourceNames = [expRef.get(datasetType='isrOscanCorr').getDetector().getName()
626  for expRef in crosstalkSources]
627  if detName not in sourceNames:
628  self.log.warn("Crosstalk lists %s, not found in sources: %s",
629  detName, sourceNames)
630  continue
631  interChipCoeffs = crosstalk.interChip[detName]
632  sourceExposure = crosstalkSources[sourceNames.index(detName)]
633  crosstalk.subtractCrosstalk(exposure, sourceExposure=sourceExposure,
634  crosstalkCoeffs=interChipCoeffs,
635  minPixelToMask=self.config.minPixelToMask,
636  crosstalkStr=self.config.crosstalkMaskPlane,
637  isTrimmed=isTrimmed,
638  backgroundMethod=self.config.crosstalkBackgroundMethod)
639  else:
640  self.log.warn("Crosstalk contains interChip coefficients, but no sources found!")
641 
642 
644  def run(self, exposure, crosstalkSources=None):
645  self.log.info("Not performing any crosstalk correction")
lsst::ip::isr.calibType.IsrCalib.fromDetector
def fromDetector(self, detector)
Definition: calibType.py:297
lsst::ip::isr.crosstalk.CrosstalkCalib
Definition: crosstalk.py:40
lsst::ip::isr.crosstalk.CrosstalkTask
Definition: crosstalk.py:552
lsst::ip::isr.calibType.IsrCalib.updateMetadata
def updateMetadata(self, setDate=False, **kwargs)
Definition: calibType.py:138
lsst::afw::math::makeStatistics
Statistics makeStatistics(lsst::afw::math::MaskedVector< EntryT > const &mv, std::vector< WeightPixel > const &vweights, int const flags, StatisticsControl const &sctrl=StatisticsControl())
lsst::ip::isr.crosstalk.NullCrosstalkTask.run
def run(self, exposure, crosstalkSources=None)
Definition: crosstalk.py:644
lsst::ip::isr.crosstalk.CrosstalkConfig.crosstalkValues
crosstalkValues
Definition: crosstalk.py:485
lsst::ip::isr.crosstalk.CrosstalkCalib.fromDetector
def fromDetector(self, detector, coeffVector=None)
Definition: crosstalk.py:95
lsst::ip::isr.crosstalk.CrosstalkCalib.hasCrosstalk
hasCrosstalk
Definition: crosstalk.py:57
lsst::ip::isr.calibType.IsrCalib.log
log
Definition: calibType.py:76
lsst::ip::isr.crosstalk.CrosstalkCalib.subtractCrosstalk
def subtractCrosstalk(self, thisExposure, sourceExposure=None, crosstalkCoeffs=None, badPixels=["BAD"], minPixelToMask=45000, crosstalkStr="CROSSTALK", isTrimmed=False, backgroundMethod="None")
Definition: crosstalk.py:348
lsst::afw::detection::FootprintSet
lsst::ip::isr.calibType.IsrCalib._detectorSerial
_detectorSerial
Definition: calibType.py:69
lsst::ip::isr.calibType.IsrCalib.requiredAttributes
requiredAttributes
Definition: calibType.py:73
lsst::ip::isr.crosstalk.NullCrosstalkTask
Definition: crosstalk.py:643
lsst::afw::detection::Threshold
lsst::ip::isr.crosstalk.CrosstalkCalib.coeffNum
coeffNum
Definition: crosstalk.py:63
lsst::ip::isr.crosstalk.CrosstalkConfig.hasCrosstalk
def hasCrosstalk(self, detector=None)
Definition: crosstalk.py:531
lsst::ip::isr.crosstalk.CrosstalkCalib.coeffErr
coeffErr
Definition: crosstalk.py:62
lsst::ip::isr.crosstalk.CrosstalkCalib.fromDict
def fromDict(cls, dictionary)
Definition: crosstalk.py:138
lsst::ip::isr.calibType.IsrCalib.getMetadata
def getMetadata(self)
Definition: calibType.py:108
lsst::ip::isr.crosstalk.CrosstalkCalib.extractAmp
def extractAmp(self, image, amp, ampTarget, isTrimmed=False)
Definition: crosstalk.py:285
lsst::afw::detection
lsst::afw::math::StatisticsControl
lsst::ip::isr.crosstalk.CrosstalkConfig.getCrosstalk
def getCrosstalk(self, detector=None)
Definition: crosstalk.py:499
lsst::ip::isr.crosstalk.CrosstalkCalib.updateMetadata
def updateMetadata(self, setDate=False, **kwargs)
Definition: crosstalk.py:72
lsst::ip::isr.crosstalk.CrosstalkCalib.__init__
def __init__(self, detector=None, **kwargs)
Definition: crosstalk.py:56
lsst::ip::isr.crosstalk.CrosstalkCalib.toDict
def toDict(self)
Definition: crosstalk.py:185
lsst::ip::isr
Definition: applyLookupTable.h:34
lsst::afw::math
lsst::ip::isr.calibType.IsrCalib
Definition: calibType.py:37
lsst::ip::isr.crosstalk.CrosstalkCalib.toTable
def toTable(self)
Definition: crosstalk.py:258
lsst::ip::isr.crosstalk.CrosstalkConfig.useConfigCoefficients
useConfigCoefficients
Definition: crosstalk.py:480
lsst::ip::isr.calibType.IsrCalib._detectorName
_detectorName
Definition: calibType.py:68
lsst::pipe::base
lsst::ip::isr.crosstalk.CrosstalkCalib.coeffs
coeffs
Definition: crosstalk.py:61
lsst::ip::isr.crosstalk.CrosstalkTask.run
def run(self, exposure, crosstalk=None, crosstalkSources=None, isTrimmed=False)
Definition: crosstalk.py:573
lsst::ip::isr.crosstalk.CrosstalkTask.prepCrosstalk
def prepCrosstalk(self, dataRef, crosstalk=None)
Definition: crosstalk.py:557
lsst::ip::isr.crosstalk.CrosstalkCalib.interChip
interChip
Definition: crosstalk.py:64
lsst::ip::isr.crosstalk.CrosstalkCalib.crosstalkShape
crosstalkShape
Definition: crosstalk.py:59
lsst::ip::isr.crosstalk.CrosstalkConfig.crosstalkShape
crosstalkShape
Definition: crosstalk.py:493
lsst::ip::isr.crosstalk.CrosstalkCalib.calculateBackground
def calculateBackground(self, mi, badPixels=["BAD"])
Definition: crosstalk.py:326
lsst::ip::isr.crosstalk.CrosstalkConfig
Definition: crosstalk.py:458
lsst::afw::math::flipImage
std::shared_ptr< ImageT > flipImage(ImageT const &inImage, bool flipLR, bool flipTB)
lsst::ip::isr.crosstalk.CrosstalkCalib.fromTable
def fromTable(cls, tableList)
Definition: crosstalk.py:222
lsst::ip::isr.crosstalk.CrosstalkCalib.nAmp
nAmp
Definition: crosstalk.py:58