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