def testSubtractExposures(self): # Test all 3 options tMi, sMi, sK, kcs, confake = diffimTools.makeFakeKernelSet( bgValue=self.bgValue) tWcs = self.makeWcs(offset=0) sWcs = self.makeWcs(offset=1) tExp = afwImage.ExposureF(tMi, tWcs) sExp = afwImage.ExposureF(sMi, sWcs) sExp.setPsf(self.psf) tExp.setPsf(self.psf) psfMatchAL = ipDiffim.ImagePsfMatchTask(config=self.configAL) psfMatchDF = ipDiffim.ImagePsfMatchTask(config=self.configDF) psfMatchDFr = ipDiffim.ImagePsfMatchTask(config=self.configDFr) self.assertEqual(psfMatchAL.useRegularization, False) self.assertEqual(psfMatchDF.useRegularization, False) self.assertEqual(psfMatchDFr.useRegularization, True) resultsAL = psfMatchAL.subtractExposures(tExp, sExp, doWarping=True) psfMatchDF.subtractExposures(tExp, sExp, doWarping=True) psfMatchDFr.subtractExposures(tExp, sExp, doWarping=True) self.assertEqual(type(resultsAL.subtractedExposure), afwImage.ExposureF) self.assertEqual(type(resultsAL.psfMatchingKernel), afwMath.LinearCombinationKernel) self.assertEqual(type(resultsAL.backgroundModel), afwMath.Chebyshev1Function2D) self.assertEqual(type(resultsAL.kernelCellSet), afwMath.SpatialCellSet)
def testWarping(self): templateSubImage = afwImage.ExposureF(self.templateImage, self.bbox) scienceSubImage = afwImage.ExposureF(self.scienceImage, self.bbox) psfmatch = ipDiffim.ImagePsfMatchTask(config=self.config) try: psfmatch.subtractExposures(templateSubImage, scienceSubImage, doWarping=False) except Exception: pass else: self.fail()
def runTest(self, mode): logger.debug("Mode %s", mode) if mode == "DF": self.config = self.subconfigDF elif mode == "DFr": self.config = self.subconfigDFr elif mode == "AL": self.config = self.subconfigAL else: raise psfmatch = ipDiffim.ImagePsfMatchTask(self.config) results = psfmatch.run(self.templateMaskedImage, self.scienceMaskedImage, "subtractMaskedImages") self.jackknifeResample(psfmatch, results)
def testWarping(self): # Should fail since images are not aligned if not self.defDataDir: print >> sys.stderr, "Warning: afwdata is not set up" return templateSubImage = afwImage.ExposureF(self.templateImage, self.bbox) scienceSubImage = afwImage.ExposureF(self.scienceImage, self.bbox) psfmatch = ipDiffim.ImagePsfMatchTask(config=self.config) try: psfmatch.subtractExposures(templateSubImage, scienceSubImage, doWarping=False) except Exception: pass else: self.fail()
def runTest(self, mode): pexLog.Trace("lsst.ip.diffim.JackknifeResampleKernel", 1, "Mode %s" % (mode)) if mode == "DF": self.config = self.subconfigDF elif mode == "DFr": self.config = self.subconfigDFr elif mode == "AL": self.config = self.subconfigAL else: raise psfmatch = ipDiffim.ImagePsfMatchTask(self.config) results = psfmatch.run(self.templateMaskedImage, self.scienceMaskedImage, "subtractMaskedImages") self.jackknifeResample(psfmatch, results)
def testWarping(self): tMi, sMi, sK, kcs, confake = diffimTools.makeFakeKernelSet( bgValue=self.bgValue) tWcs = self.makeWcs(offset=0) sWcs = self.makeWcs(offset=1) tExp = afwImage.ExposureF(tMi, tWcs) sExp = afwImage.ExposureF(sMi, sWcs) # Should fail due to registration problem psfMatchAL = ipDiffim.ImagePsfMatchTask(config=self.configAL) try: psfMatchAL.subtractExposures(tExp, sExp, doWarping=True) except Exception as e: print("testWarning failed with %r" % (e, )) pass else: self.fail()
def runTest(self, mode): logger.debug("Mode %s", mode) if mode == "DF": self.config = self.configDF elif mode == "DFr": self.config = self.configDFr elif mode == "AL": self.config = self.configAL else: raise subconfig = self.config.kernel.active psfmatch = ipDiffim.ImagePsfMatchTask(self.config) candidateList = [] if self.scienceExposure.getPsf(): candidateList = psfmatch.makeCandidateList(self.templateExposure, self.scienceExposure, subconfig.kernelSize) results = psfmatch.subtractMaskedImages(self.templateMaskedImage, self.scienceMaskedImage, candidateList) self.jackknifeResample(psfmatch, results)
def subtractExposures(scienceExposure, templateExposure): import lsst.ip.diffim as ipDiffim # Some configuration (no clear idea of what it is) config = ipDiffim.ImagePsfMatchTask.ConfigClass() config.kernel.name = "AL" subconfig = config.kernel.active fwhmT = fwhmS = defFwhm = 7.5 if templateExposure.hasPsf(): fwhmT = calc_fwhm_from_exp(templateExposure) print('USING: FwhmT =', fwhmT) if scienceExposure.hasPsf(): fwhmS = calc_fwhm_from_exp(scienceExposure) print('USING: FwhmS =', fwhmS) # Some code from RHL to try the self-convolution approach # In principle, the resulting difference image preConvolve = False if preConvolve: smoothedScienceExposure = smoothExp(scienceExposure, fwhmS) fwhmS *= np.sqrt(2) smoothedTemplateExposure = smoothExp(templateExposure, fwhmT) fwhmT *= np.sqrt(2) scienceExposure = smoothedScienceExposure templateExposure = smoothedTemplateExposure if preConvolve or fwhmS > fwhmT: convolveTemplate = True else: convolveTemplate = False psfmatch = ipDiffim.ImagePsfMatchTask(config) results = psfmatch.subtractExposures(templateExposure, scienceExposure, templateFwhmPix=fwhmT, scienceFwhmPix=fwhmS, convolveTemplate=convolveTemplate) return results
def testMatchExposures(self): # Only test 1 option tMi, sMi, sK, kcs, confake = diffimTools.makeFakeKernelSet( bgValue=self.bgValue) tWcs = self.makeWcs(offset=0) sWcs = self.makeWcs(offset=1) tExp = afwImage.ExposureF(tMi, tWcs) sExp = afwImage.ExposureF(sMi, sWcs) sExp.setPsf(self.psf) psfMatchAL = ipDiffim.ImagePsfMatchTask(config=self.configAL) resultsAL = psfMatchAL.matchExposures(tExp, sExp, templateFwhmPix=2.0, scienceFwhmPix=3.0, doWarping=True) self.assertEqual(type(resultsAL.matchedExposure), afwImage.ExposureF) self.assertEqual(type(resultsAL.psfMatchingKernel), afwMath.LinearCombinationKernel) self.assertEqual(type(resultsAL.backgroundModel), afwMath.Function2D) self.assertEqual(type(resultsAL.kernelCellSet), afwMath.SpatialCellSet)
def testPca(self, nTerms=3): tMi, sMi, sK, kcs, confake = diffimTools.makeFakeKernelSet( bgValue=self.bgValue) tWcs = self.makeWcs(offset=0) sWcs = self.makeWcs(offset=0) tExp = afwImage.ExposureF(tMi, tWcs) sExp = afwImage.ExposureF(sMi, sWcs) sExp.setPsf(self.psf) self.subconfigDF.usePcaForSpatialKernel = True self.subconfigDF.numPrincipalComponents = nTerms psfMatchDF = ipDiffim.ImagePsfMatchTask(config=self.configDF) candList = psfMatchDF.makeCandidateList(tExp, sExp, self.ksize) resultsDF = psfMatchDF.subtractMaskedImages(tMi, sMi, candList) spatialKernel = resultsDF.psfMatchingKernel spatialKernelSolution = spatialKernel.getSpatialParameters() self.assertEqual(len(spatialKernelSolution), nTerms) # First basis has no spatial variation for i in range(1, nTerms): self.assertEqual(spatialKernelSolution[0][i], 0.) # All bases have correct number of terms sko = self.subconfigDF.spatialKernelOrder nSpatialTerms = int(0.5 * (sko + 1) * (sko + 2)) for i in range(len(spatialKernelSolution)): self.assertEqual(len(spatialKernelSolution[i]), nSpatialTerms) spatialBg = resultsDF.backgroundModel spatialBgSolution = spatialBg.getParameters() bgo = self.subconfigDF.spatialBgOrder nBgTerms = int(0.5 * (bgo + 1) * (bgo + 2)) self.assertEqual(len(spatialBgSolution), nBgTerms)
def testSubtractMaskedImages(self): # Lets do some additional testing here to make sure we recover # the known spatial model. No background, just the faked # alard-lupton basis set. The rest of matchMaskedImages() and # subtractMaskedImages() functionality is tested by the # Exposure-based methods. fakeCoeffs = diffimTools.fakeCoeffs() # Quick note; you shouldn't change confake here, since the # candidates in the KernelCellSet are initialized in # makeFakeKernelSet tMi, sMi, sK, kcs, confake = diffimTools.makeFakeKernelSet( bgValue=0.0, addNoise=False) svar = sMi.getVariance() svar.set(1.0) tvar = tMi.getVariance() tvar.set(1.0) basisList = ipDiffim.makeKernelBasisList(confake.kernel.active) psfMatchAL = ipDiffim.ImagePsfMatchTask(config=confake) spatialSolution, psfMatchingKernel, backgroundModel = psfMatchAL._solve( kcs, basisList) fitCoeffs = psfMatchingKernel.getSpatialParameters() for b in range(len(fakeCoeffs)): for s in range(len(fakeCoeffs[b])): if fakeCoeffs[b][s] == 0.0: self.assertAlmostEqual(fitCoeffs[b][s], 0.0) else: # OUTSTANDING ISSUE - WHY IS THIS ONE TERM OFF!?!? if b != 4 and s != 0: self.assertAlmostEqual( fitCoeffs[b][s] / fakeCoeffs[b][s], 1.0, 1)
# Do in AFW diffimTools.backgroundSubtract( subconfig.afwBackgroundConfig, [templateExposure.getMaskedImage(), scienceExposure.getMaskedImage()]) subconfig.fitForBackground = False else: # Do in IP_DIFFIM subconfig.fitForBackground = True frame = 0 ds9.mtv(templateExposure, frame=frame, title="Template") frame += 1 ds9.mtv(scienceExposure, frame=frame, title="Sci Im") psfmatch = ipDiffim.ImagePsfMatchTask(config=config) try: results = psfmatch.run(templateExposure.getMaskedImage(), scienceExposure.getMaskedImage(), "subtractMaskedImages") diffim = results.subtractedImage spatialKernel = results.psfMatchingKernel spatialBg = results.backgroundModel kernelCellSet = results.kernelCellSet except Exception as e: print('FAIL') sys.exit(1) if False: print(spatialKernel.getSpatialFunctionList()[0].toString()) print(spatialKernel.getKernelParameters())
def testAutoCorrelation(orderMake, orderFit, inMi=None, display=False): config = ipDiffim.ImagePsfMatchTask.ConfigClass() config.kernel.name = "AL" subconfig = config.kernel.active subconfig.fitForBackground = True stride = 100 if inMi == None: width = 512 height = 2048 inMi = afwImage.MaskedImageF(afwGeom.Extent2I(width, height)) for j in num.arange(stride // 2, height, stride): j = int(j) for i in num.arange(stride // 2, width, stride): i = int(i) inMi.set(i - 1, j - 1, (100., 0x0, 1.)) inMi.set(i - 1, j + 0, (100., 0x0, 1.)) inMi.set(i - 1, j + 1, (100., 0x0, 1.)) inMi.set(i + 0, j - 1, (100., 0x0, 1.)) inMi.set(i + 0, j + 0, (100., 0x0, 1.)) inMi.set(i + 0, j + 1, (100., 0x0, 1.)) inMi.set(i + 1, j - 1, (100., 0x0, 1.)) inMi.set(i + 1, j + 0, (100., 0x0, 1.)) inMi.set(i + 1, j + 1, (100., 0x0, 1.)) addNoise(inMi) kSize = subconfig.kernelSize basicGaussian1 = afwMath.GaussianFunction2D(2., 2., 0.) basicKernel1 = afwMath.AnalyticKernel(kSize, kSize, basicGaussian1) basicGaussian2 = afwMath.GaussianFunction2D(5., 3., 0.5 * num.pi) basicKernel2 = afwMath.AnalyticKernel(kSize, kSize, basicGaussian2) basisList = [] basisList.append(basicKernel1) basisList.append(basicKernel2) spatialKernelFunction = afwMath.PolynomialFunction2D(orderMake) spatialKernel = afwMath.LinearCombinationKernel(basisList, spatialKernelFunction) kCoeffs = [[ 1.0 for x in range(1, spatialKernelFunction.getNParameters() + 1) ], [ 0.01 * x for x in range(1, spatialKernelFunction.getNParameters() + 1) ]] spatialKernel.setSpatialParameters(kCoeffs) cMi = afwImage.MaskedImageF(inMi.getDimensions()) afwMath.convolve(cMi, inMi, spatialKernel, True) if display: ds9.mtv(inMi.getImage(), frame=1) ds9.mtv(inMi.getVariance(), frame=2) ds9.mtv(cMi.getImage(), frame=3) ds9.mtv(cMi.getVariance(), frame=4) subconfig.spatialKernelOrder = orderFit subconfig.sizeCellX = stride subconfig.sizeCellY = stride psfmatch = ipDiffim.ImagePsfMatchTask(config=config) result = psfmatch.run(inMi, cMi, "subtractMaskedImages") differenceMaskedImage = result.subtractedImage spatialKernel = result.psfMatchingKernel spatialBg = result.backgroundModel kernelCellSet = result.kernelCellSet makeAutoCorrelation(kernelCellSet, spatialKernel, makePlot=True)
def testAutoCorrelation(orderMake, orderFit, inMi=None, display=False): config = ipDiffim.ImagePsfMatchTask.ConfigClass() config.kernel.name = "AL" subconfig = config.kernel.active subconfig.fitForBackground = True stride = 100 if inMi is None: width = 512 height = 2048 inMi = afwImage.MaskedImageF(afwGeom.Extent2I(width, height)) for j in num.arange(stride // 2, height, stride): j = int(j) for i in num.arange(stride // 2, width, stride): i = int(i) inMi._set((i - 1, j - 1), (100., 0x0, 1.), afwImage.LOCAL) inMi._set((i - 1, j + 0), (100., 0x0, 1.), afwImage.LOCAL) inMi._set((i - 1, j + 1), (100., 0x0, 1.), afwImage.LOCAL) inMi._set((i + 0, j - 1), (100., 0x0, 1.), afwImage.LOCAL) inMi._set((i + 0, j + 0), (100., 0x0, 1.), afwImage.LOCAL) inMi._set((i + 0, j + 1), (100., 0x0, 1.), afwImage.LOCAL) inMi._set((i + 1, j - 1), (100., 0x0, 1.), afwImage.LOCAL) inMi._set((i + 1, j + 0), (100., 0x0, 1.), afwImage.LOCAL) inMi._set((i + 1, j + 1), (100., 0x0, 1.), afwImage.LOCAL) addNoise(inMi) kSize = subconfig.kernelSize basicGaussian1 = afwMath.GaussianFunction2D(2., 2., 0.) basicKernel1 = afwMath.AnalyticKernel(kSize, kSize, basicGaussian1) basicGaussian2 = afwMath.GaussianFunction2D(5., 3., 0.5 * num.pi) basicKernel2 = afwMath.AnalyticKernel(kSize, kSize, basicGaussian2) basisList = [] basisList.append(basicKernel1) basisList.append(basicKernel2) spatialKernelFunction = afwMath.PolynomialFunction2D(orderMake) spatialKernel = afwMath.LinearCombinationKernel(basisList, spatialKernelFunction) kCoeffs = [[ 1.0 for x in range(1, spatialKernelFunction.getNParameters() + 1) ], [ 0.01 * x for x in range(1, spatialKernelFunction.getNParameters() + 1) ]] spatialKernel.setSpatialParameters(kCoeffs) cMi = afwImage.MaskedImageF(inMi.getDimensions()) convolutionControl = afwMath.ConvolutionControl() convolutionControl.setDoNormalize(True) afwMath.convolve(cMi, inMi, spatialKernel, convolutionControl) if display: afwDisplay.Display(frame=1).mtv(inMi.getImage()) afwDisplay.Display(frame=2).mtv(inMi.getVariance()) afwDisplay.Display(frame=3).mtv(cMi.getImage()) afwDisplay.Display(frame=4).mtv(cMi.getVariance()) subconfig.spatialKernelOrder = orderFit subconfig.sizeCellX = stride subconfig.sizeCellY = stride psfmatch = ipDiffim.ImagePsfMatchTask(config=config) candList = psfmatch.makeCandidateList(afwImage.ExposureF(inMi), afwImage.ExposureF(cMi), kSize) result = psfmatch.subtractMaskedImages(inMi, cMi, candList) spatialKernel = result.psfMatchingKernel kernelCellSet = result.kernelCellSet makeAutoCorrelation(kernelCellSet, spatialKernel, makePlot=True)
def main(): defDataDir = lsst.utils.getPackageDir('afwdata') defSciencePath = os.path.join(defDataDir, "DC3a-Sim", "sci", "v26-e0", "v26-e0-c011-a10.sci.fits") defTemplatePath = os.path.join(defDataDir, "DC3a-Sim", "sci", "v5-e0", "v5-e0-c011-a10.sci.fits") defOutputPath = 'diffExposure.fits' defVerbosity = 0 defFwhm = 3.5 sigma2fwhm = 2. * np.sqrt(2. * np.log(2.)) usage = """usage: %%prog [options] [scienceExposure [templateExposure [outputExposure]]]] Notes: - image arguments are paths to Expoure fits files - image arguments must NOT include the final _img.fits - the result is science image - template image - the template exposure is convolved, the science exposure is not - default scienceExposure=%s - default templateExposure=%s - default outputExposure=%s """ % (defSciencePath, defTemplatePath, defOutputPath) parser = optparse.OptionParser(usage) parser.add_option('-v', '--verbosity', type=int, default=defVerbosity, help='verbosity of Trace messages') parser.add_option('-d', '--display', action='store_true', default=False, help='display the images') parser.add_option('-b', '--bg', action='store_true', default=False, help='subtract backgrounds using afw') parser.add_option('--fwhmS', type=float, help='Science Image Psf Fwhm (pixel)') parser.add_option('--fwhmT', type=float, help='Template Image Psf Fwhm (pixel)') (options, args) = parser.parse_args() def getArg(ind, defValue): if ind < len(args): return args[ind] return defValue sciencePath = getArg(0, defSciencePath) templatePath = getArg(1, defTemplatePath) outputPath = getArg(2, defOutputPath) if sciencePath is None or templatePath is None: parser.print_help() sys.exit(1) print('Science exposure: ', sciencePath) print('Template exposure:', templatePath) print('Output exposure: ', outputPath) templateExposure = afwImage.ExposureF(templatePath) scienceExposure = afwImage.ExposureF(sciencePath) config = ipDiffim.ImagePsfMatchTask.ConfigClass() config.kernel.name = "AL" subconfig = config.kernel.active fwhmS = defFwhm if options.fwhmS: if scienceExposure.hasPsf(): sciPsf = scienceExposure.getPsf() fwhm = sciPsf.computeShape(sciPsf.getAveragePosition() ).getDeterminantRadius() * sigma2fwhm print('NOTE: Embedded Psf has FwhmS =', fwhm) print('USING: FwhmS =', options.fwhmS) fwhmS = options.fwhmS fwhmT = defFwhm if options.fwhmT: if templateExposure.hasPsf(): templPsf = templateExposure.getPsf() fwhm = templPsf.computeShape(templPsf.getAveragePosition() ).getDeterminantRadius() * sigma2fwhm print('NOTE: Embedded Psf has FwhmT =', fwhm) print('USING: FwhmT =', options.fwhmT) fwhmT = options.fwhmT bgSub = False if options.bg: print('Background subtract =', options.bg) bgSub = True if options.verbosity > 0: print('Verbosity =', options.verbosity) logUtils.trace_set_at("lsst.ip.diffim", options.verbosity) #### if bgSub: diffimTools.backgroundSubtract(subconfig.afwBackgroundConfig, [ templateExposure.getMaskedImage(), scienceExposure.getMaskedImage() ]) else: if not subconfig.fitForBackground: print('NOTE: no background subtraction at all is requested') # ImagePsfMatchTask requires a candidateList or that the exposoure have a PSF for detection if not scienceExposure.hasPsf(): sigmaS = fwhmS / sigma2fwhm kSize = int(6 * sigmaS) # minimum kernel size for FWHM oddKSize = kSize + 1 if kSize % 2 == 0 else kSize scienceExposure.setPsf(SingleGaussianPsf(oddKSize, oddKSize, sigmaS)) psfmatch = ipDiffim.ImagePsfMatchTask(config) results = psfmatch.subtractExposures(templateExposure, scienceExposure, templateFwhmPix=fwhmT, scienceFwhmPix=fwhmS) differenceExposure = results.subtractedExposure differenceExposure.writeFits(outputPath) if False: psfMatchingKernel = results.psfMatchingKernel backgroundModel = results.backgroundModel kernelCellSet = results.kernelCellSet diffimTools.writeKernelCellSet(kernelCellSet, psfMatchingKernel, backgroundModel, re.sub('.fits', '', outputPath))
def main(): imageProcDir = lsst.utils.getPackageDir('ip_diffim') defSciencePath = None defTemplatePath = None defOutputPath = 'diffImage.fits' defVerbosity = 5 defFwhm = 3.5 usage = """usage: %%prog [options] [scienceImage [templateImage [outputImage]]]] Notes: - image arguments are paths to MaskedImage fits files - image arguments must NOT include the final _img.fits - the result is science image - template image - the template image is convolved, the science image is not - default scienceMaskedImage=%s - default templateMaskedImage=%s - default outputImage=%s """ % (defSciencePath, defTemplatePath, defOutputPath) parser = optparse.OptionParser(usage) parser.add_option('-v', '--verbosity', type=int, default=defVerbosity, help='verbosity of Trace messages') parser.add_option('-d', '--display', action='store_true', default=False, help='display the images') parser.add_option('-b', '--bg', action='store_true', default=False, help='subtract backgrounds') parser.add_option('--fwhmS', type=float, help='Science Image Psf Fwhm (pixel)') parser.add_option('--fwhmT', type=float, help='Template Image Psf Fwhm (pixel)') (options, args) = parser.parse_args() def getArg(ind, defValue): if ind < len(args): return args[ind] return defValue sciencePath = getArg(0, defSciencePath) templatePath = getArg(1, defTemplatePath) outputPath = getArg(2, defOutputPath) if sciencePath == None or templatePath == None: parser.print_help() sys.exit(1) print('Science image: ', sciencePath) print('Template image:', templatePath) print('Output image: ', outputPath) fwhmS = defFwhm if options.fwhmS: print('FwhmS =', options.fwhmS) fwhmS = options.fwhmS fwhmT = defFwhm if options.fwhmT: print('Fwhmt =', options.fwhmT) fwhmT = options.fwhmT display = False if options.display: print('Display =', options.display) display = True bgSub = False if options.bg: print('Background subtract =', options.bg) bgSub = True if options.verbosity > 0: print('Verbosity =', options.verbosity) logUtils.traceSetAt("ip.diffim", options.verbosity) #### templateMaskedImage = afwImage.MaskedImageF(templatePath) scienceMaskedImage = afwImage.MaskedImageF(sciencePath) config = ipDiffim.ImagePsfMatchTask.ConfigClass() config.kernel.name = "AL" subconfig = config.kernel.active if bgSub: diffimTools.backgroundSubtract( subconfig.afwBackgroundConfig, [templateMaskedImage, scienceMaskedImage]) else: if subconfig.fitForBackground == False: print('NOTE: no background subtraction at all is requested') psfmatch = ipDiffim.ImagePsfMatchTask(subconfig) results = psfmatch.run(templateMaskedImage, scienceMaskedImage, "subtractMaskedImages", templateFwhmPix=fwhmT, scienceFwhmPix=fwhmS) differenceMaskedImage = results.subtractedImage differenceMaskedImage.writeFits(outputPath) if False: spatialKernel = results.psfMatchingKernel print(spatialKernel.getSpatialParameters()) if display: ds9.mtv(differenceMaskedImage)
subconfigDFr.useRegularization = True for param in [["spatialKernelOrder", 0], ["spatialBgOrder", 0], ["usePcaForSpatialKernel", True], ["fitForBackground", True]]: exec("subconfigAL.%s = %s" % (param[0], param[1])) exec("subconfigDF.%s = %s" % (param[0], param[1])) exec("subconfigDFr.%s = %s" % (param[0], param[1])) detConfig = subconfigAL.detectionConfig kcDetect = ipDiffim.KernelCandidateDetectionF( pexConfig.makePropertySet(detConfig)) kcDetect.apply(templateMaskedImage, scienceMaskedImage) footprints = kcDetect.getFootprints() # delta function psfmatch1 = ipDiffim.ImagePsfMatchTask(config=configDF) results1 = psfmatch1.subtractMaskedImages(templateMaskedImage, scienceMaskedImage, candidateList=footprints) diffim1 = results1.subtractedMaskedImage spatialKernel1 = results1.psfMatchingKernel spatialBg1 = results1.backgroundModel kernelCellSet1 = results1.kernelCellSet # alard lupton psfmatch2 = ipDiffim.ImagePsfMatchTask(config=configAL) results2 = psfmatch2.subtractMaskedImages(templateMaskedImage, scienceMaskedImage, candidateList=footprints) diffim2 = results2.subtractedMaskedImage spatialKernel2 = results2.psfMatchingKernel
def runModelType(self, fitForBackground): if not self.defDataDir: print >> sys.stderr, "Warning: afwdata is not set up" return self.subconfig.fitForBackground = fitForBackground templateSubImage = afwImage.ExposureF(self.templateImage, self.bbox) scienceSubImage = afwImage.ExposureF(self.scienceImage, self.bbox) self.subconfig.spatialModelType = 'chebyshev1' psfmatch1 = ipDiffim.ImagePsfMatchTask(config=self.config) results1 = psfmatch1.subtractExposures(templateSubImage, scienceSubImage, doWarping=True) spatialKernel1 = results1.psfMatchingKernel backgroundModel1 = results1.backgroundModel self.subconfig.spatialModelType = 'polynomial' psfmatch2 = ipDiffim.ImagePsfMatchTask(config=self.config) results2 = psfmatch2.subtractExposures(templateSubImage, scienceSubImage, doWarping=True) spatialKernel2 = results2.psfMatchingKernel backgroundModel2 = results2.backgroundModel # Got the types right? self.assertTrue(spatialKernel1.getSpatialFunctionList() [0].toString().startswith('Chebyshev1Function2')) self.assertTrue(spatialKernel2.getSpatialFunctionList() [0].toString().startswith('PolynomialFunction2')) # First order term has zero spatial variation and sum = kernel sum kp1par0 = spatialKernel1.getSpatialFunctionList()[0].getParameters() kp2par0 = spatialKernel2.getSpatialFunctionList()[0].getParameters() self.assertAlmostEqual(kp1par0[0], kp2par0[0], delta=1e-5) for i in range(1, len(kp1par0)): self.assertAlmostEqual(kp1par0[i], 0.0, delta=1e-5) self.assertAlmostEqual(kp1par0[i], kp2par0[i], delta=1e-5) if fitForBackground: # Nterms (zeroth order model) self.assertEqual(backgroundModel1.getNParameters(), 1) self.assertEqual(backgroundModel2.getNParameters(), 1) # Same value of function coefficients (different to 0.001 level) self.assertAlmostEqual(backgroundModel1.getParameters()[0], backgroundModel2.getParameters()[0], delta=1e-3) # Functions evaluate to same value at origin (0.001 difference) self.assertAlmostEqual(backgroundModel1(0, 0), backgroundModel2(0, 0), delta=1e-3) # At at different location within image self.assertAlmostEqual(backgroundModel1(10, 10), backgroundModel2(10, 10), delta=1e-3) else: # More improtant is the kernel needs to be then same when realized at a coordinate kim1 = afwImage.ImageD(spatialKernel1.getDimensions()) kim2 = afwImage.ImageD(spatialKernel2.getDimensions()) ksum1 = spatialKernel1.computeImage(kim1, False, 0.0, 0.0) ksum2 = spatialKernel2.computeImage(kim2, False, 0.0, 0.0) self.assertAlmostEqual(ksum1, ksum2, delta=1e-5) for y in range(kim1.getHeight()): for x in range(kim1.getHeight()): self.assertAlmostEqual(kim1.get(x, y), kim2.get(x, y), delta=1e-1) # Nterms (zeroth order) self.assertEqual(backgroundModel1.getNParameters(), 1) self.assertEqual(backgroundModel2.getNParameters(), 1) # Zero value in function self.assertAlmostEqual(backgroundModel1.getParameters()[0], 0.0, delta=1e-7) self.assertAlmostEqual(backgroundModel2.getParameters()[0], 0.0, delta=1e-7) # Function evaluates to zero self.assertAlmostEqual(backgroundModel1(0, 0), 0.0, delta=1e-7) self.assertAlmostEqual(backgroundModel2(0, 0), 0.0, delta=1e-7) # Spatially... self.assertAlmostEqual(backgroundModel1(10, 10), 0.0, delta=1e-7) self.assertAlmostEqual(backgroundModel2(10, 10), 0.0, delta=1e-7)
def runXY0(self, poly, fitForBackground=False): if not self.defDataDir: print >> sys.stderr, "Warning: afwdata is not set up" return self.subconfig.spatialModelType = poly self.subconfig.fitForBackground = fitForBackground templateSubImage = afwImage.ExposureF(self.templateImage, self.bbox) scienceSubImage = afwImage.ExposureF(self.scienceImage, self.bbox) # Have an XY0 psfmatch = ipDiffim.ImagePsfMatchTask(config=self.config) results1 = psfmatch.subtractExposures(templateSubImage, scienceSubImage, doWarping=True) spatialKernel1 = results1.psfMatchingKernel backgroundModel1 = results1.backgroundModel kernelCellSet1 = results1.kernelCellSet # And then take away XY0 templateSubImage.setXY0(afwGeom.Point2I(0, 0)) scienceSubImage.setXY0(afwGeom.Point2I(0, 0)) results2 = psfmatch.subtractExposures(templateSubImage, scienceSubImage, doWarping=True) spatialKernel2 = results2.psfMatchingKernel backgroundModel2 = results2.backgroundModel kernelCellSet2 = results2.kernelCellSet # need to count up the candidates first, since its a running tally count = 0 for cell in kernelCellSet1.getCellList(): for cand1 in cell.begin(False): count += 1 for cell in kernelCellSet1.getCellList(): for cand1 in cell.begin(False): if cand1.getStatus() == afwMath.SpatialCellCandidate.UNKNOWN: continue if cand1.getStatus() == afwMath.SpatialCellCandidate.BAD: continue cand1 = ipDiffim.cast_KernelCandidateF(cand1) cand2 = ipDiffim.cast_KernelCandidateF( kernelCellSet2.getCandidateById(cand1.getId() + count)) # positions are nearly the same (different at the 0.01 pixel level) self.assertAlmostEqual(cand1.getXCenter(), cand2.getXCenter(), delta=1e-1) self.assertAlmostEqual(cand1.getYCenter(), cand2.getYCenter() + self.offset, delta=1e-1) # kernels are the same im1 = cand1.getKernelImage(ipDiffim.KernelCandidateF.RECENT) im2 = cand2.getKernelImage(ipDiffim.KernelCandidateF.RECENT) for y in range(im1.getHeight()): for x in range(im1.getWidth()): self.assertAlmostEqual(im1.get(x, y), im2.get(x, y), delta=1e-7) # Spatial fits are the same skp1 = spatialKernel1.getSpatialParameters() skp2 = spatialKernel2.getSpatialParameters() bgp1 = backgroundModel1.getParameters() bgp2 = backgroundModel2.getParameters() # first term = kernel sum, 0, 0 self.assertAlmostEqual(skp1[0][0], skp2[0][0], delta=1e-6) # On other terms, the spatial terms are the same, the zpt terms are different for nk in range(1, len(skp1)): # Zeropoint if poly == 'polynomial': self.assertNotEqual(skp1[nk][0], skp2[nk][0]) elif poly == 'chebyshev1': # Cheby remaps coords, so model should be the same! self.assertAlmostEqual(skp1[nk][0], skp2[nk][0], delta=1e-4) else: self.fail() # Spatial terms for np in range(1, len(skp1[nk])): self.assertAlmostEqual(skp1[nk][np], skp2[nk][np], delta=1e-4) for np in range(len(bgp1)): self.assertAlmostEqual(bgp1[np], bgp2[np], delta=1e-4)
def main(): defDataDir = lsst.utils.getPackageDir('afwdata') imageProcDir = lsst.utils.getPackageDir('ip_diffim') defSciencePath = os.path.join(defDataDir, "DC3a-Sim", "sci", "v26-e0", "v26-e0-c011-a10.sci") defTemplatePath = os.path.join(defDataDir, "DC3a-Sim", "sci", "v5-e0", "v5-e0-c011-a10.sci") defOutputPath = 'diffExposure.fits' defVerbosity = 5 defFwhm = 3.5 sigma2fwhm = 2. * num.sqrt(2. * num.log(2.)) usage = """usage: %%prog [options] [scienceExposure [templateExposure [outputExposure]]]] Notes: - image arguments are paths to Expoure fits files - image arguments must NOT include the final _img.fits - the result is science image - template image - the template exposure is convolved, the science exposure is not - default scienceExposure=%s - default templateExposure=%s - default outputExposure=%s """ % (defSciencePath, defTemplatePath, defOutputPath) parser = optparse.OptionParser(usage) parser.add_option('-v', '--verbosity', type=int, default=defVerbosity, help='verbosity of Trace messages') parser.add_option('-d', '--display', action='store_true', default=False, help='display the images') parser.add_option('-b', '--bg', action='store_true', default=False, help='subtract backgrounds using afw') parser.add_option('--fwhmS', type=float, help='Science Image Psf Fwhm (pixel)') parser.add_option('--fwhmT', type=float, help='Template Image Psf Fwhm (pixel)') (options, args) = parser.parse_args() def getArg(ind, defValue): if ind < len(args): return args[ind] return defValue sciencePath = getArg(0, defSciencePath) templatePath = getArg(1, defTemplatePath) outputPath = getArg(2, defOutputPath) if sciencePath == None or templatePath == None: parser.print_help() sys.exit(1) print 'Science exposure: ', sciencePath print 'Template exposure:', templatePath print 'Output exposure: ', outputPath templateExposure = afwImage.ExposureF(templatePath) scienceExposure = afwImage.ExposureF(sciencePath) config = ipDiffim.ImagePsfMatchTask.ConfigClass() config.kernel.name = "AL" subconfig = config.kernel.active fwhmS = defFwhm if options.fwhmS: if scienceExposure.hasPsf(): width, height = scienceExposure.getPsf().getKernel().getDimensions( ) psfAttr = measAlg.PsfAttributes(scienceExposure.getPsf(), width // 2, height // 2) s = psfAttr.computeGaussianWidth( psfAttr.ADAPTIVE_MOMENT) # gaussian sigma in pixels fwhm = s * sigma2fwhm print 'NOTE: Embedded Psf has FwhmS =', fwhm print 'USING: FwhmS =', options.fwhmS fwhmS = options.fwhmS fwhmT = defFwhm if options.fwhmT: if templateExposure.hasPsf(): width, height = templateExposure.getPsf().getKernel( ).getDimensions() psfAttr = measAlg.PsfAttributes(templateExposure.getPsf(), width // 2, height // 2) s = psfAttr.computeGaussianWidth( psfAttr.ADAPTIVE_MOMENT) # gaussian sigma in pixels fwhm = s * sigma2fwhm print 'NOTE: Embedded Psf has FwhmT =', fwhm print 'USING: FwhmT =', options.fwhmT fwhmT = options.fwhmT display = False if options.display: print 'Display =', options.display display = True bgSub = False if options.bg: print 'Background subtract =', options.bg bgSub = True if options.verbosity > 0: print 'Verbosity =', options.verbosity Trace.setVerbosity('lsst.ip.diffim', options.verbosity) #### if bgSub: diffimTools.backgroundSubtract(subconfig.afwBackgroundConfig, [ templateExposure.getMaskedImage(), scienceExposure.getMaskedImage() ]) else: if subconfig.fitForBackground == False: print 'NOTE: no background subtraction at all is requested' psfmatch = ipDiffim.ImagePsfMatchTask(config) results = psfmatch.run(templateExposure, scienceExposure, "subtractExposures", templateFwhmPix=fwhmT, scienceFwhmPix=fwhmS) differenceExposure = results.subtractedImage differenceExposure.writeFits(outputPath) if False: psfMatchingKernel = results.psfMatchingKernel backgroundModel = results.backgroundModel kernelCellSet = results.kernelCellSet diffimTools.writeKernelCellSet(kernelCellSet, psfMatchingKernel, backgroundModel, re.sub('.fits', '', outputPath))
def doAlInStack(im1, im2, doWarping=False, doDecorr=True, doPreConv=False, spatialBackgroundOrder=0, spatialKernelOrder=0): preConvKernel = None im2c = im2 if doPreConv: #doDecorr = False # Right now decorr with pre-conv doesn't work preConvKernel = im2.psf im2c, kern = doConvolve(im2, preConvKernel, use_scipy=False) config = ipDiffim.ImagePsfMatchTask.ConfigClass() config.kernel.name = "AL" config.selectDetection.thresholdValue = 5.0 # default is 10.0 but this is necessary for very dense fields subconfig = config.kernel.active subconfig.spatialKernelOrder = spatialKernelOrder # 1 subconfig.spatialBgOrder = spatialBackgroundOrder subconfig.alardMinSig = 0.55 # Default is 0.7 but 0.55 is better for my simulations ??? #config.kernel.active.alardGaussBeta = 2.0 # Default is 2.0 subconfig.afwBackgroundConfig.useApprox = False subconfig.constantVarianceWeighting = False subconfig.singleKernelClipping = False subconfig.spatialKernelClipping = False subconfig.fitForBackground = False task = ipDiffim.ImagePsfMatchTask(config=config) task.log.setLevel(log_level) result = task.subtractExposures(im1, im2c, doWarping=doWarping) result.task = task # for debugging (e.g. task.metadata.get("ALBasisNGauss") if doDecorr: sig1squared = computeVarianceMean(im1) sig2squared = computeVarianceMean(im2) result = doALdecorrelation(result, sig1squared=sig1squared, sig2squared=sig2squared, preConvKernel=preConvKernel) # kimg = alPsfMatchingKernelToArray(result.psfMatchingKernel, im1) # #return kimg # if preConvKernel is not None and kimg.shape[0] < preConvKernel.shape[0]: # # This is likely brittle and may only work if both kernels are odd-shaped. # #kimg[np.abs(kimg) < 1e-4] = np.sign(kimg)[np.abs(kimg) < 1e-4] * 1e-8 # #kimg -= kimg[0, 0] # padSize0 = preConvKernel.shape[0]//2 - kimg.shape[0]//2 # padSize1 = preConvKernel.shape[1]//2 - kimg.shape[1]//2 # kimg = np.pad(kimg, ((padSize0, padSize0), (padSize1, padSize1)), mode='constant', # constant_values=0) # #kimg /= kimg.sum() # #preConvKernel = preConvKernel[padSize0:-padSize0, padSize1:-padSize1] # #print kimg.shape, preConvKernel.shape # sig1squared = computeVarianceMean(im1) # sig2squared = computeVarianceMean(im2) # pck = computeDecorrelationKernel(kimg, sig1squared, sig2squared, # preConvKernel=preConvKernel, delta=0.) # #return kimg, preConvKernel, pck # diffim, _ = doConvolve(result.subtractedExposure, pck, use_scipy=False) # #diffim.getMaskedImage().getImage().getArray()[:, ] \ # # /= np.sqrt(im1.metaData['sky'] + im1.metaData['sky']) # #diffim.getMaskedImage().getVariance().getArray()[:, ] \ # # /= np.sqrt(im1.metaData['sky'] + im1.metaData['sky']) # # For some reason, border areas of img and variance planes can become infinite. Fix it. # img = diffim.getMaskedImage().getImage().getArray() # img[~np.isfinite(img)] = np.nan # img = diffim.getMaskedImage().getVariance().getArray() # img[~np.isfinite(img)] = np.nan # # TBD: also need to update the mask as it is not (apparently) set correctly. # psf = afwPsfToArray(result.subtractedExposure.getPsf(), result.subtractedExposure) # .computeImage().getArray() # # NOTE! Need to compute the updated PSF including preConvKernel !!! This doesn't do it: # psfc = computeCorrectedDiffimPsf(kimg, psf, tvar=sig1squared, svar=sig2squared) # psfcI = afwImage.ImageD(psfc.shape[0], psfc.shape[1]) # psfcI.getArray()[:, :] = psfc # psfcK = afwMath.FixedKernel(psfcI) # psfNew = measAlg.KernelPsf(psfcK) # diffim.setPsf(psfNew) # result.decorrelatedDiffim = diffim # result.preConvKernel = preConvKernel # result.decorrelationKernel = pck # result.kappaImg = kimg return result