LSSTApplications  17.0+124,17.0+14,17.0+73,18.0.0+37,18.0.0+80,18.0.0-4-g68ffd23+4,18.1.0-1-g0001055+12,18.1.0-1-g03d53ef+5,18.1.0-1-g1349e88+55,18.1.0-1-g2505f39+44,18.1.0-1-g5315e5e+4,18.1.0-1-g5e4b7ea+14,18.1.0-1-g7e8fceb+4,18.1.0-1-g85f8cd4+48,18.1.0-1-g8ff0b9f+4,18.1.0-1-ga2c679d+1,18.1.0-1-gd55f500+35,18.1.0-10-gb58edde+2,18.1.0-11-g0997b02+4,18.1.0-13-gfe4edf0b+12,18.1.0-14-g259bd21+21,18.1.0-19-gdb69f3f+2,18.1.0-2-g5f9922c+24,18.1.0-2-gd3b74e5+11,18.1.0-2-gfbf3545+32,18.1.0-26-g728bddb4+5,18.1.0-27-g6ff7ca9+2,18.1.0-3-g52aa583+25,18.1.0-3-g8ea57af+9,18.1.0-3-gb69f684+42,18.1.0-3-gfcaddf3+6,18.1.0-32-gd8786685a,18.1.0-4-gf3f9b77+6,18.1.0-5-g1dd662b+2,18.1.0-5-g6dbcb01+41,18.1.0-6-gae77429+3,18.1.0-7-g9d75d83+9,18.1.0-7-gae09a6d+30,18.1.0-9-gc381ef5+4,w.2019.45
LSSTDataManagementBasePackage
Classes | Functions | Variables
lsst.ip.isr.crosstalk Namespace Reference

Classes

class  CrosstalkConfig
 
class  CrosstalkTask
 
class  NullCrosstalkTask
 

Functions

def extractAmp (image, amp, corner, isTrimmed=False)
 
def calculateBackground (mi, badPixels=["BAD"])
 
def subtractCrosstalk (exposure, crosstalkCoeffs=None, badPixels=["BAD"], minPixelToMask=45000, crosstalkStr="CROSSTALK", isTrimmed=False, backgroundMethod="None")
 
def writeCrosstalkCoeffs (outputFileName, coeff, det=None, crosstalkName="Unknown", indent=2)
 

Variables

dictionary X_FLIP
 
dictionary Y_FLIP
 

Function Documentation

◆ calculateBackground()

def lsst.ip.isr.crosstalk.calculateBackground (   mi,
  badPixels = ["BAD"] 
)
Calculate median background in image

Getting a great background model isn't important for crosstalk correction,
since the crosstalk is at a low level. The median should be sufficient.

Parameters
----------
mi : `lsst.afw.image.MaskedImage`
    MaskedImage for which to measure background.
badPixels : `list` of `str`
    Mask planes to ignore.

Returns
-------
bg : `float`
    Median background level.

Definition at line 228 of file crosstalk.py.

228 def calculateBackground(mi, badPixels=["BAD"]):
229  """Calculate median background in image
230 
231  Getting a great background model isn't important for crosstalk correction,
232  since the crosstalk is at a low level. The median should be sufficient.
233 
234  Parameters
235  ----------
236  mi : `lsst.afw.image.MaskedImage`
237  MaskedImage for which to measure background.
238  badPixels : `list` of `str`
239  Mask planes to ignore.
240 
241  Returns
242  -------
243  bg : `float`
244  Median background level.
245  """
246  mask = mi.getMask()
248  stats.setAndMask(mask.getPlaneBitMask(badPixels))
249  return lsst.afw.math.makeStatistics(mi, lsst.afw.math.MEDIAN, stats).getValue()
250 
251 
Statistics makeStatistics(lsst::afw::math::MaskedVector< EntryT > const &mv, std::vector< WeightPixel > const &vweights, int const flags, StatisticsControl const &sctrl=StatisticsControl())
The makeStatistics() overload to handle lsst::afw::math::MaskedVector<>
Definition: Statistics.h:520
Pass parameters to a Statistics object.
Definition: Statistics.h:93
def calculateBackground(mi, badPixels=["BAD"])
Definition: crosstalk.py:228

◆ extractAmp()

def lsst.ip.isr.crosstalk.extractAmp (   image,
  amp,
  corner,
  isTrimmed = False 
)
Return an image of the amp

The returned image will have the amp's readout corner in the
nominated `corner`.

Parameters
----------
image : `lsst.afw.image.Image` or `lsst.afw.image.MaskedImage`
    Image containing the amplifier of interest.
amp : `lsst.afw.table.AmpInfoRecord`
    Amplifier information.
corner : `lsst.afw.table.ReadoutCorner` or `None`
    Corner in which to put the amp's readout corner, or `None` for
    no flipping.
isTrimmed : `bool`
    The image is already trimmed.
    This should no longer be needed once DM-15409 is resolved.

Returns
-------
output : `lsst.afw.image.Image`
    Image of the amplifier in the standard configuration.

Definition at line 196 of file crosstalk.py.

196 def extractAmp(image, amp, corner, isTrimmed=False):
197  """Return an image of the amp
198 
199  The returned image will have the amp's readout corner in the
200  nominated `corner`.
201 
202  Parameters
203  ----------
204  image : `lsst.afw.image.Image` or `lsst.afw.image.MaskedImage`
205  Image containing the amplifier of interest.
206  amp : `lsst.afw.table.AmpInfoRecord`
207  Amplifier information.
208  corner : `lsst.afw.table.ReadoutCorner` or `None`
209  Corner in which to put the amp's readout corner, or `None` for
210  no flipping.
211  isTrimmed : `bool`
212  The image is already trimmed.
213  This should no longer be needed once DM-15409 is resolved.
214 
215  Returns
216  -------
217  output : `lsst.afw.image.Image`
218  Image of the amplifier in the standard configuration.
219  """
220  output = image[amp.getBBox() if isTrimmed else amp.getRawDataBBox()]
221  ampCorner = amp.getReadoutCorner()
222  # Flipping is necessary only if the desired configuration doesn't match what we currently have
223  xFlip = X_FLIP[corner] ^ X_FLIP[ampCorner]
224  yFlip = Y_FLIP[corner] ^ Y_FLIP[ampCorner]
225  return lsst.afw.math.flipImage(output, xFlip, yFlip)
226 
227 
std::shared_ptr< ImageT > flipImage(ImageT const &inImage, bool flipLR, bool flipTB)
Flip an image left–right and/or top–bottom.
Definition: rotateImage.cc:92
def extractAmp(image, amp, corner, isTrimmed=False)
Definition: crosstalk.py:196

◆ subtractCrosstalk()

def lsst.ip.isr.crosstalk.subtractCrosstalk (   exposure,
  crosstalkCoeffs = None,
  badPixels = ["BAD"],
  minPixelToMask = 45000,
  crosstalkStr = "CROSSTALK",
  isTrimmed = False,
  backgroundMethod = "None" 
)
Subtract the intra-detector crosstalk from an exposure

We set the mask plane indicated by ``crosstalkStr`` in a target amplifier
for pixels in a source amplifier that exceed `minPixelToMask`. Note that
the correction is applied to all pixels in the amplifier, but only those
that have a substantial crosstalk are masked with ``crosstalkStr``.

The uncorrected image is used as a template for correction. This is good
enough if the crosstalk is small (e.g., coefficients < ~ 1e-3), but if it's
larger you may want to iterate.

This method needs unittests (DM-18876), but such testing requires
DM-18610 to allow the test detector to have the crosstalk
parameters set.

Parameters
----------
exposure : `lsst.afw.image.Exposure`
    Exposure for which to subtract crosstalk.
crosstalkCoeffs : `numpy.ndarray`
    Coefficients to use to correct crosstalk.
badPixels : `list` of `str`
    Mask planes to ignore.
minPixelToMask : `float`
    Minimum pixel value (relative to the background level) in
    source amplifier for which to set ``crosstalkStr`` mask plane
    in target amplifier.
crosstalkStr : `str`
    Mask plane name for pixels greatly modified by crosstalk.
isTrimmed : `bool`
    The image is already trimmed.
    This should no longer be needed once DM-15409 is resolved.
backgroundMethod : `str`
    Method used to subtract the background.  "AMP" uses
    amplifier-by-amplifier background levels, "DETECTOR" uses full
    exposure/maskedImage levels.  Any other value results in no
    background subtraction.

Definition at line 255 of file crosstalk.py.

255  backgroundMethod="None"):
256  """Subtract the intra-detector crosstalk from an exposure
257 
258  We set the mask plane indicated by ``crosstalkStr`` in a target amplifier
259  for pixels in a source amplifier that exceed `minPixelToMask`. Note that
260  the correction is applied to all pixels in the amplifier, but only those
261  that have a substantial crosstalk are masked with ``crosstalkStr``.
262 
263  The uncorrected image is used as a template for correction. This is good
264  enough if the crosstalk is small (e.g., coefficients < ~ 1e-3), but if it's
265  larger you may want to iterate.
266 
267  This method needs unittests (DM-18876), but such testing requires
268  DM-18610 to allow the test detector to have the crosstalk
269  parameters set.
270 
271  Parameters
272  ----------
273  exposure : `lsst.afw.image.Exposure`
274  Exposure for which to subtract crosstalk.
275  crosstalkCoeffs : `numpy.ndarray`
276  Coefficients to use to correct crosstalk.
277  badPixels : `list` of `str`
278  Mask planes to ignore.
279  minPixelToMask : `float`
280  Minimum pixel value (relative to the background level) in
281  source amplifier for which to set ``crosstalkStr`` mask plane
282  in target amplifier.
283  crosstalkStr : `str`
284  Mask plane name for pixels greatly modified by crosstalk.
285  isTrimmed : `bool`
286  The image is already trimmed.
287  This should no longer be needed once DM-15409 is resolved.
288  backgroundMethod : `str`
289  Method used to subtract the background. "AMP" uses
290  amplifier-by-amplifier background levels, "DETECTOR" uses full
291  exposure/maskedImage levels. Any other value results in no
292  background subtraction.
293  """
294  mi = exposure.getMaskedImage()
295  mask = mi.getMask()
296 
297  ccd = exposure.getDetector()
298  numAmps = len(ccd)
299  if crosstalkCoeffs is None:
300  coeffs = ccd.getCrosstalk()
301  else:
302  coeffs = crosstalkCoeffs
303  assert coeffs.shape == (numAmps, numAmps)
304 
305  # Set background level based on the requested method. The
306  # thresholdBackground holds the offset needed so that we only mask
307  # pixels high relative to the background, not in an absolute
308  # sense.
309  thresholdBackground = calculateBackground(mi, badPixels)
310 
311  backgrounds = [0.0 for amp in ccd]
312  if backgroundMethod is None:
313  pass
314  elif backgroundMethod == "AMP":
315  backgrounds = [calculateBackground(mi[amp.getBBox()], badPixels) for amp in ccd]
316  elif backgroundMethod == "DETECTOR":
317  backgrounds = [calculateBackground(mi, badPixels) for amp in ccd]
318 
319  # Set the crosstalkStr bit for the bright pixels (those which will have significant crosstalk correction)
320  crosstalkPlane = mask.addMaskPlane(crosstalkStr)
321  footprints = lsst.afw.detection.FootprintSet(mi, lsst.afw.detection.Threshold(minPixelToMask +
322  thresholdBackground))
323  footprints.setMask(mask, crosstalkStr)
324  crosstalk = mask.getPlaneBitMask(crosstalkStr)
325 
326  # Do pixel level crosstalk correction.
327  subtrahend = mi.Factory(mi.getBBox())
328  subtrahend.set((0, 0, 0))
329  for ii, iAmp in enumerate(ccd):
330  iImage = subtrahend[iAmp.getBBox() if isTrimmed else iAmp.getRawDataBBox()]
331  for jj, jAmp in enumerate(ccd):
332  if ii == jj:
333  assert coeffs[ii, jj] == 0.0
334  if coeffs[ii, jj] == 0.0:
335  continue
336 
337  jImage = extractAmp(mi, jAmp, iAmp.getReadoutCorner(), isTrimmed)
338  jImage.getMask().getArray()[:] &= crosstalk # Remove all other masks
339  jImage -= backgrounds[jj]
340 
341  iImage.scaledPlus(coeffs[ii, jj], jImage)
342 
343  # Set crosstalkStr bit only for those pixels that have been significantly modified (i.e., those
344  # masked as such in 'subtrahend'), not necessarily those that are bright originally.
345  mask.clearMaskPlane(crosstalkPlane)
346  mi -= subtrahend # also sets crosstalkStr bit for bright pixels
347 
348 
A Threshold is used to pass a threshold value to detection algorithms.
Definition: Threshold.h:43
def calculateBackground(mi, badPixels=["BAD"])
Definition: crosstalk.py:228
def extractAmp(image, amp, corner, isTrimmed=False)
Definition: crosstalk.py:196
A set of Footprints, associated with a MaskedImage.
Definition: FootprintSet.h:53

◆ writeCrosstalkCoeffs()

def lsst.ip.isr.crosstalk.writeCrosstalkCoeffs (   outputFileName,
  coeff,
  det = None,
  crosstalkName = "Unknown",
  indent = 2 
)
Write a yaml file containing the crosstalk coefficients

The coeff array is indexed by [i, j] where i and j are amplifiers
corresponding to the amplifiers in det

Parameters
----------
outputFileName : `str`
    Name of output yaml file
coeff : `numpy.array(namp, namp)`
    numpy array of coefficients
det : `lsst.afw.cameraGeom.Detector`
    Used to provide the list of amplifier names;
    if None use ['0', '1', ...]
ccdType : `str`
    Name of detector, used to index the yaml file
    If all detectors are identical could be the type (e.g. ITL)
indent : `int`
    Indent width to use when writing the yaml file

Definition at line 349 of file crosstalk.py.

349 def writeCrosstalkCoeffs(outputFileName, coeff, det=None, crosstalkName="Unknown", indent=2):
350  """Write a yaml file containing the crosstalk coefficients
351 
352  The coeff array is indexed by [i, j] where i and j are amplifiers
353  corresponding to the amplifiers in det
354 
355  Parameters
356  ----------
357  outputFileName : `str`
358  Name of output yaml file
359  coeff : `numpy.array(namp, namp)`
360  numpy array of coefficients
361  det : `lsst.afw.cameraGeom.Detector`
362  Used to provide the list of amplifier names;
363  if None use ['0', '1', ...]
364  ccdType : `str`
365  Name of detector, used to index the yaml file
366  If all detectors are identical could be the type (e.g. ITL)
367  indent : `int`
368  Indent width to use when writing the yaml file
369  """
370 
371  if det is None:
372  ampNames = [str(i) for i in range(coeff.shape[0])]
373  else:
374  ampNames = [a.getName() for a in det]
375 
376  assert coeff.shape == (len(ampNames), len(ampNames))
377 
378  dIndent = indent
379  indent = 0
380  with open(outputFileName, "w") as fd:
381  print(indent*" " + "crosstalk :", file=fd)
382  indent += dIndent
383  print(indent*" " + "%s :" % crosstalkName, file=fd)
384  indent += dIndent
385 
386  for i, ampNameI in enumerate(ampNames):
387  print(indent*" " + "%s : {" % ampNameI, file=fd)
388  indent += dIndent
389  print(indent*" ", file=fd, end='')
390 
391  for j, ampNameJ in enumerate(ampNames):
392  print("%s : %11.4e, " % (ampNameJ, coeff[i, j]), file=fd,
393  end='\n' + indent*" " if j%4 == 3 else '')
394  print("}", file=fd)
395 
396  indent -= dIndent
397 
def writeCrosstalkCoeffs(outputFileName, coeff, det=None, crosstalkName="Unknown", indent=2)
Definition: crosstalk.py:349

Variable Documentation

◆ X_FLIP

dictionary lsst.ip.isr.crosstalk.X_FLIP
Initial value:
1 = {lsst.afw.cameraGeom.ReadoutCorner.LL: False, lsst.afw.cameraGeom.ReadoutCorner.LR: True,
2  lsst.afw.cameraGeom.ReadoutCorner.UL: False, lsst.afw.cameraGeom.ReadoutCorner.UR: True}

Definition at line 185 of file crosstalk.py.

◆ Y_FLIP

dictionary lsst.ip.isr.crosstalk.Y_FLIP
Initial value:
1 = {lsst.afw.cameraGeom.ReadoutCorner.LL: False, lsst.afw.cameraGeom.ReadoutCorner.LR: False,
2  lsst.afw.cameraGeom.ReadoutCorner.UL: True, lsst.afw.cameraGeom.ReadoutCorner.UR: True}

Definition at line 187 of file crosstalk.py.