811 spatiallyVarying=True, preConvKernel=None, templateMatched=True, preConvMode=False):
812 """Perform decorrelation of an image difference exposure.
813
814 Decorrelates the diffim due to the convolution of the
815 templateExposure with the A&L psfMatchingKernel. If
816 `spatiallyVarying` is True, it utilizes the spatially varying
817 matching kernel via the `imageMapReduce` framework to perform
818 spatially-varying decorrelation on a grid of subExposures.
819
820 Parameters
821 ----------
822 scienceExposure : `lsst.afw.image.Exposure`
823 the science Exposure used for PSF matching
824 templateExposure : `lsst.afw.image.Exposure`
825 the template Exposure used for PSF matching
826 subtractedExposure : `lsst.afw.image.Exposure`
827 the subtracted Exposure produced by `ip_diffim.ImagePsfMatchTask.subtractExposures()`
828 psfMatchingKernel : an (optionally spatially-varying) PSF matching kernel produced
829 by `ip_diffim.ImagePsfMatchTask.subtractExposures()`
830 spatiallyVarying : `bool`
831 if True, perform the spatially-varying operation
832 preConvKernel : `lsst.meas.algorithms.Psf`
833 if not none, the scienceExposure has been pre-filtered with this kernel. (Currently
834 this option is experimental.)
835 templateMatched : `bool`, optional
836 If True, the template exposure was matched (convolved) to the science exposure.
837 preConvMode : `bool`, optional
838 If True, ``subtractedExposure`` is assumed to be a likelihood difference image
839 and will be noise corrected as a likelihood image.
840
841 Returns
842 -------
843 results : `lsst.pipe.base.Struct`
844 a structure containing:
845 - ``correctedExposure`` : the decorrelated diffim
846 """
847 self.log.info('Running A&L decorrelation: spatiallyVarying=%r', spatiallyVarying)
848
849 svar = self.computeVarianceMean(scienceExposure)
850 tvar = self.computeVarianceMean(templateExposure)
851 if np.isnan(svar) or np.isnan(tvar):
852
853 if (np.all(np.isnan(scienceExposure.image.array))
854 or np.all(np.isnan(templateExposure.image.array))):
855 self.log.warning('Template or science image is entirely NaNs: skipping decorrelation.')
856 if np.isnan(svar):
857 svar = 1e-9
858 if np.isnan(tvar):
859 tvar = 1e-9
860
861 var = self.computeVarianceMean(subtractedExposure)
862
863 if spatiallyVarying:
864 self.log.info("Variance (science, template): (%f, %f)", svar, tvar)
865 self.log.info("Variance (uncorrected diffim): %f", var)
866 config = self.config.decorrelateMapReduceConfig
867 task = ImageMapReduceTask(config=config)
868 results = task.run(subtractedExposure, science=scienceExposure,
869 template=templateExposure, psfMatchingKernel=psfMatchingKernel,
870 preConvKernel=preConvKernel, forceEvenSized=True,
871 templateMatched=templateMatched, preConvMode=preConvMode)
872 results.correctedExposure = results.exposure
873
874
875 def gm(exp):
876 return exp.mask
877 gm(results.correctedExposure)[:, :] = gm(subtractedExposure)
878
879 var = self.computeVarianceMean(results.correctedExposure)
880 self.log.info("Variance (corrected diffim): %f", var)
881
882 else:
883 config = self.config.decorrelateConfig
884 task = DecorrelateALKernelTask(config=config)
885 results = task.run(scienceExposure, templateExposure,
886 subtractedExposure, psfMatchingKernel, preConvKernel=preConvKernel,
887 templateMatched=templateMatched, preConvMode=preConvMode)
888
889 return results