547 def run(self, exposure, ctiCalib, gains=None):
548 """Correct deferred charge/CTI issues.
549
550 Parameters
551 ----------
552 exposure : `lsst.afw.image.Exposure`
553 Exposure to correct the deferred charge on.
554 ctiCalib : `lsst.ip.isr.DeferredChargeCalib`
555 Calibration object containing the charge transfer
556 inefficiency model.
557 gains : `dict` [`str`, `float`]
558 A dictionary, keyed by amplifier name, of the gains to
559 use. If gains is None, the nominal gains in the amplifier
560 object are used.
561
562 Returns
563 -------
564 exposure : `lsst.afw.image.Exposure`
565 The corrected exposure.
566 """
567 image = exposure.getMaskedImage().image
568 detector = exposure.getDetector()
569
570
571
572
573
574 useGains = True
575 if "USEGAINS" in ctiCalib.getMetadata().keys():
576 useGains = ctiCalib.getMetadata()["USEGAINS"]
577 self.log.info(f"useGains = {useGains} from calibration metadata.")
578 else:
579 useGains = self.config.useGains
580 self.log.info(f"USEGAINS not found in calibration metadata. Using {useGains} from config.")
581
582 if useGains:
583 if gains is None:
584 gains = {amp.getName(): amp.getGain() for amp in detector.getAmplifiers()}
585
586 with gainContext(exposure, image, useGains, gains):
587 for amp in detector.getAmplifiers():
588 ampName = amp.getName()
589
590 ampImage = image[amp.getRawBBox()]
591 if self.config.zeroUnusedPixels:
592
593
594 ampImage[amp.getRawParallelOverscanBBox()].array[:, :] = 0.0
595 ampImage[amp.getRawSerialPrescanBBox()].array[:, :] = 0.0
596
597
598
599
600 ampData = self.flipData(ampImage.array, amp)
601
602 if ctiCalib.driftScale[ampName] > 0.0:
603 correctedAmpData = self.local_offset_inverse(ampData,
604 ctiCalib.driftScale[ampName],
605 ctiCalib.decayTime[ampName],
606 self.config.nPixelOffsetCorrection)
607 else:
608 correctedAmpData = ampData.copy()
609
610 correctedAmpData = self.local_trap_inverse(correctedAmpData,
611 ctiCalib.serialTraps[ampName],
612 ctiCalib.globalCti[ampName],
613 self.config.nPixelTrapCorrection)
614
615
616 correctedAmpData = self.flipData(correctedAmpData, amp)
617 image[amp.getRawBBox()].array[:, :] = correctedAmpData[:, :]
618
619 return exposure
620