742 exposure, crosstalk=None,
743 crosstalkSources=None, isTrimmed=False, camera=None, parallelOverscanRegion=False,
746 """Apply intra-detector crosstalk correction
750 exposure : `lsst.afw.image.Exposure`
751 Exposure for which to remove crosstalk.
752 crosstalkCalib : `lsst.ip.isr.CrosstalkCalib`, optional
753 External crosstalk calibration to apply. Constructed from
754 detector if not found.
755 crosstalkSources : `defaultdict`, optional
756 Image data for other detectors that are sources of
757 crosstalk in exposure. The keys are expected to be names
758 of the other detectors, with the values containing
759 `lsst.afw.image.Exposure` at the same level of processing
761 The default for intra-detector crosstalk here is None.
762 isTrimmed : `bool`, optional
763 The image is already trimmed.
764 This should no longer be needed once DM-15409 is resolved.
765 camera : `lsst.afw.cameraGeom.Camera`, optional
766 Camera associated with this exposure. Only used for
768 parallelOverscanRegion : `bool`, optional
769 Do subtraction in parallel overscan region (only)?
770 detectorConfig : `lsst.ip.isr.OverscanDetectorConfig`, optional
771 Per-amplifier configs used when parallelOverscanRegion=True.
776 Raised if called for a detector that does not have a
777 crosstalk correction. Also raised if the crosstalkSource
778 is not an expected type.
782 crosstalk = crosstalk.fromDetector(exposure.getDetector(),
783 coeffVector=self.config.crosstalkValues)
784 if not crosstalk.log:
785 crosstalk.log = self.log
786 if not crosstalk.hasCrosstalk:
787 raise RuntimeError(
"Attempted to correct crosstalk without crosstalk coefficients.")
788 elif parallelOverscanRegion:
789 self.log.info(
"Applying crosstalk correction to parallel overscan region.")
790 crosstalk.subtractCrosstalkParallelOverscanRegion(
792 crosstalkCoeffs=crosstalk.coeffs,
793 detectorConfig=detectorConfig,
796 self.log.info(
"Applying crosstalk correction.")
797 crosstalk.subtractCrosstalk(exposure, crosstalkCoeffs=crosstalk.coeffs,
798 minPixelToMask=self.config.minPixelToMask,
799 crosstalkStr=self.config.crosstalkMaskPlane, isTrimmed=isTrimmed,
800 backgroundMethod=self.config.crosstalkBackgroundMethod)
802 if crosstalk.interChip:
808 sourceNames = [exp.getDetector().getName()
for exp
in crosstalkSources]
809 elif isinstance(crosstalkSources[0], lsst.daf.butler.DeferredDatasetHandle):
811 detectorList = [source.dataId[
'detector']
for source
in crosstalkSources]
812 sourceNames = [camera[detector].getName()
for detector
in detectorList]
814 raise RuntimeError(
"Unknown object passed as crosstalk sources.",
815 type(crosstalkSources[0]))
817 for detName
in crosstalk.interChip:
818 if detName
not in sourceNames:
819 self.log.warning(
"Crosstalk lists %s, not found in sources: %s",
820 detName, sourceNames)
823 interChipCoeffs = crosstalk.interChip[detName]
825 sourceExposure = crosstalkSources[sourceNames.index(detName)]
826 if isinstance(sourceExposure, lsst.daf.butler.DeferredDatasetHandle):
828 sourceExposure = sourceExposure.get()
830 raise RuntimeError(
"Unknown object passed as crosstalk sources.",
831 type(sourceExposure))
833 self.log.info(
"Correcting detector %s with ctSource %s",
834 exposure.getDetector().getName(),
835 sourceExposure.getDetector().getName())
836 crosstalk.subtractCrosstalk(exposure, sourceExposure=sourceExposure,
837 crosstalkCoeffs=interChipCoeffs,
838 minPixelToMask=self.config.minPixelToMask,
839 crosstalkStr=self.config.crosstalkMaskPlane,
841 backgroundMethod=self.config.crosstalkBackgroundMethod)
843 self.log.warning(
"Crosstalk contains interChip coefficients, but no sources found!")