def sourceTableToCandidateList(sourceTable, templateExposure, scienceExposure, kConfig, dConfig, log, basisList, doBuild=False): """Convert a list of Sources into KernelCandidates. The KernelCandidates are used for fitting the Psf-matching kernel. Parameters ---------- sourceTable : TODO: DM-17458 TODO: DM-17458 templateExposure : TODO: DM-17458 TODO: DM-17458 scienceExposure : TODO: DM-17458 TODO: DM-17458 kConfig : TODO: DM-17458 TODO: DM-17458 dConfig : TODO: DM-17458 TODO: DM-17458 log : TODO: DM-17458 TODO: DM-17458 basisList : TODO: DM-17458 TODO: DM-17458 doBuild : `bool`, optional TODO: DM-17458 Returns ------- TODO: DM-17458 TODO: DM-17458 """ kernelSize = basisList[0].getWidth() footprintList = sourceToFootprintList(list(sourceTable), templateExposure, scienceExposure, kernelSize, dConfig, log) candList = [] if doBuild and not basisList: doBuild = False else: ps = pexConfig.makePropertySet(kConfig) visitor = diffimLib.BuildSingleKernelVisitorF(basisList, ps) ps = pexConfig.makePropertySet(kConfig) for cand in footprintList: bbox = cand['footprint'].getBBox() tmi = afwImage.MaskedImageF(templateExposure.getMaskedImage(), bbox) smi = afwImage.MaskedImageF(scienceExposure.getMaskedImage(), bbox) kCand = diffimLib.makeKernelCandidate(cand['source'], tmi, smi, ps) if doBuild: visitor.processCandidate(kCand) kCand.setStatus(afwMath.SpatialCellCandidate.UNKNOWN) candList.append(kCand) return candList
def testConvertPropertySet(self): ps = pexConfig.makePropertySet(self.simple) self.assertFalse(ps.exists("i")) self.assertEqual(ps.getScalar("f"), self.simple.f) self.assertEqual(ps.getScalar("b"), self.simple.b) self.assertEqual(ps.getScalar("c"), self.simple.c) self.assertEqual(list(ps.getArray("ll")), list(self.simple.ll)) ps = pexConfig.makePropertySet(self.comp) self.assertEqual(ps.getScalar("c.f"), self.comp.c.f)
def setUp(self): self.configAL = ipDiffim.ImagePsfMatchTask.ConfigClass() self.configAL.kernel.name = "AL" self.subconfigAL = self.configAL.kernel.active self.configDF = ipDiffim.ImagePsfMatchTask.ConfigClass() self.configDF.kernel.name = "DF" self.subconfigDF = self.configDF.kernel.active self.psAL = pexConfig.makePropertySet(self.subconfigAL) self.psDF = pexConfig.makePropertySet(self.subconfigDF) self.kSize = self.psAL["kernelSize"]
def __init__(self, *args, **kwargs): """Create the psf-matching Task Parameters ---------- *args Arguments to be passed to ``lsst.pipe.base.task.Task.__init__`` **kwargs Keyword arguments to be passed to ``lsst.pipe.base.task.Task.__init__`` Notes ----- The initialization sets the Psf-matching kernel configuration using the value of self.config.kernel.active. If the kernel is requested with regularization to moderate the bias/variance tradeoff, currently only used when a delta function kernel basis is provided, it creates a regularization matrix stored as member variable self.hMat. """ pipeBase.Task.__init__(self, *args, **kwargs) self.kConfig = self.config.kernel.active if 'useRegularization' in self.kConfig: self.useRegularization = self.kConfig.useRegularization else: self.useRegularization = False if self.useRegularization: self.hMat = diffimLib.makeRegularizationMatrix(pexConfig.makePropertySet(self.kConfig))
def setUp(self): self.config = ipDiffim.ImagePsfMatchTask.ConfigClass() self.config.kernel.name = "AL" self.subconfig = self.config.kernel.active self.ps = pexConfig.makePropertySet(self.subconfig) self.size = 51
def setUp(self): self.config = ipDiffim.ImagePsfMatchTask.ConfigClass() self.config.kernel.name = "DF" self.subconfig = self.config.kernel.active self.ps = pexConfig.makePropertySet(self.subconfig) self.kList = ipDiffim.makeKernelBasisList(self.subconfig)
def stats(self, cid, diffim, core=5): ps = pexConfig.makePropertySet(self.config) dStats = ipDiffim.ImageStatisticsF(ps) dStats.apply(diffim) logger.debug("Candidate %d : Residuals all (%d px): %.3f +/- %.3f", cid, dStats.getNpix(), dStats.getMean(), dStats.getRms()) dStats.apply(diffim, core) logger.debug("Candidate %d : Residuals core (%d px): %.3f +/- %.3f", cid, dStats.getNpix(), dStats.getMean(), dStats.getRms())
def setUp(self): schema = afwTable.SourceTable.makeMinimalSchema() afwTable.Point2DKey.addFields(schema, "Centroid", "input centroid", "pixel") schema.addField("PsfFlux_instFlux", type=float) schema.addField("PsfFlux_instFluxErr", type=float) schema.addField("PsfFlux_flag", type="Flag") self.table = afwTable.SourceTable.make(schema) self.table.definePsfFlux("PsfFlux") self.table.defineCentroid("Centroid") self.ss = afwTable.SourceCatalog(self.table) self.config = ipDiffim.ImagePsfMatchTask.ConfigClass() self.config.kernel.name = "DF" self.subconfig = self.config.kernel.active self.ps = pexConfig.makePropertySet(self.subconfig) self.ps[ 'fitForBackground'] = True # we are testing known background recovery here self.ps['checkConditionNumber'] = False # just in case self.ps["useRegularization"] = False if defDataDir: 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") scienceExposure = afwImage.ExposureF(defSciencePath) templateExposure = afwImage.ExposureF(defTemplatePath) # set XY0 = 0 scienceExposure.setXY0(geom.Point2I(0, 0)) templateExposure.setXY0(geom.Point2I(0, 0)) # do the warping first so we don't have any masked pixels in the postage stamps warper = afwMath.Warper.fromConfig(self.subconfig.warpingConfig) templateExposure = warper.warpExposure( scienceExposure.getWcs(), templateExposure, destBBox=scienceExposure.getBBox()) # Change xy0 # Nice star at position 276, 717 # And should be at index 40, 40 # No masked pixels in this one self.x02 = 276 self.y02 = 717 size = 40 bbox2 = geom.Box2I(geom.Point2I(self.x02 - size, self.y02 - size), geom.Point2I(self.x02 + size, self.y02 + size)) self.scienceImage2 = afwImage.ExposureF(scienceExposure, bbox2, origin=afwImage.LOCAL) self.templateExposure2 = afwImage.ExposureF(templateExposure, bbox2, origin=afwImage.LOCAL)
def testConvert(self): pol = pexConfig.makePolicy(self.simple) self.assertEqual(pol.exists("i"), False) self.assertEqual(pol.get("f"), self.simple.f) self.assertEqual(pol.get("b"), self.simple.b) self.assertEqual(pol.get("c"), self.simple.c) self.assertEqual(pol.getArray("ll"), list(self.simple.ll)) ps = pexConfig.makePropertySet(self.simple) self.assertEqual(ps.exists("i"), False) self.assertEqual(ps.getScalar("f"), self.simple.f) self.assertEqual(ps.getScalar("b"), self.simple.b) self.assertEqual(ps.getScalar("c"), self.simple.c) self.assertEqual(list(ps.getArray("ll")), list(self.simple.ll)) pol = pexConfig.makePolicy(self.comp) self.assertEqual(pol.get("c.f"), self.comp.c.f) ps = pexConfig.makePropertySet(self.comp) self.assertEqual(ps.getScalar("c.f"), self.comp.c.f)
def testConvert(self): pol = pexConfig.makePolicy(self.simple) self.assertEqual(pol.exists("i"), False) self.assertEqual(pol.get("f"), self.simple.f) self.assertEqual(pol.get("b"), self.simple.b) self.assertEqual(pol.get("c"), self.simple.c) self.assertEqual(pol.getArray("ll"), list(self.simple.ll)) ps = pexConfig.makePropertySet(self.simple) self.assertEqual(ps.exists("i"), False) self.assertEqual(ps.get("f"), self.simple.f) self.assertEqual(ps.get("b"), self.simple.b) self.assertEqual(ps.get("c"), self.simple.c) self.assertEqual(list(ps.get("ll")), list(self.simple.ll)) pol = pexConfig.makePolicy(self.comp) self.assertEqual(pol.get("c.f"), self.comp.c.f) ps = pexConfig.makePropertySet(self.comp) self.assertEqual(ps.get("c.f"), self.comp.c.f)
def testGetCollection(self): # NOTE - you need to subtract off background from the image # you run detection on. Here it is the template. bgConfig = self.subconfig.afwBackgroundConfig diffimTools.backgroundSubtract(bgConfig, [ self.templateImage, ]) detConfig = self.subconfig.detectionConfig maskPlane = detConfig.badMaskPlanes[0] maskVal = afwImage.Mask.getPlaneBitMask(maskPlane) kcDetect = ipDiffim.KernelCandidateDetectionF( pexConfig.makePropertySet(detConfig)) kcDetect.apply(self.templateImage, self.scienceImage) fpList1 = kcDetect.getFootprints() self.assertNotEqual(len(fpList1), 0) for fp in fpList1: bbox = fp.getBBox() tmi = afwImage.MaskedImageF(self.templateImage, bbox, origin=afwImage.LOCAL) smi = afwImage.MaskedImageF(self.scienceImage, bbox, origin=afwImage.LOCAL) tmask = tmi.getMask() smask = smi.getMask() for j in range(tmask.getHeight()): for i in range(tmask.getWidth()): # No masked pixels in either image self.assertEqual(tmask[i, j, afwImage.LOCAL], 0) self.assertEqual(smask[i, j, afwImage.LOCAL], 0) # add a masked pixel to the template image and make sure you don't get it tp = geom.Point2I(tmask.getWidth() // 2, tmask.getHeight() // 2) self.templateImage.mask[fpList1[0].getBBox(), afwImage.LOCAL][tp, afwImage.LOCAL] = maskVal kcDetect.apply(self.templateImage, self.scienceImage) fpList2 = kcDetect.getFootprints() self.assertEqual(len(fpList2), (len(fpList1) - 1)) # add a masked pixel to the science image and make sure you don't get it sp = geom.Point2I(smask.getWidth() // 2, smask.getHeight() // 2) self.scienceImage.mask[fpList1[1].getBBox(), afwImage.LOCAL][sp, afwImage.LOCAL] = maskVal self.scienceImage.mask[fpList1[2].getBBox(), afwImage.LOCAL][sp, afwImage.LOCAL] = maskVal kcDetect.apply(self.templateImage, self.scienceImage) fpList3 = kcDetect.getFootprints() self.assertEqual(len(fpList3), (len(fpList1) - 3))
def __call__(self, kernelCellSet, log): d1, d2, d3 = self.psfMatchConfig.alardDegGauss bicArray = {} for d1i in range(1, d1 + 1): for d2i in range(1, d2 + 1): for d3i in range(1, d3 + 1): dList = [d1i, d2i, d3i] bicConfig = type(self.psfMatchConfig)(self.psfMatchConfig, alardDegGauss=dList) kList = makeKernelBasisList(bicConfig, self.psfFwhmPixTc, self.psfFwhmPixTnc) k = len(kList) visitor = diffimLib.BuildSingleKernelVisitorF( kList, pexConfig.makePropertySet(bicConfig)) visitor.setSkipBuilt(False) kernelCellSet.visitCandidates(visitor, bicConfig.nStarPerCell) for cell in kernelCellSet.getCellList(): for cand in cell.begin( False): # False = include bad candidates if cand.getStatus( ) != afwMath.SpatialCellCandidate.GOOD: continue diffIm = cand.getDifferenceImage( diffimLib.KernelCandidateF.RECENT) bbox = cand.getKernel( diffimLib.KernelCandidateF.RECENT).shrinkBBox( diffIm.getBBox(afwImage.LOCAL)) diffIm = type(diffIm)(diffIm, bbox, True) chi2 = diffIm.getImage().getArray( )**2 / diffIm.getVariance().getArray() n = chi2.shape[0] * chi2.shape[1] bic = np.sum(chi2) + k * np.log(n) if cand.getId() not in bicArray: bicArray[cand.getId()] = {} bicArray[cand.getId()][(d1i, d2i, d3i)] = bic bestConfigs = [] for candId in bicArray: cconfig, cvals = list(bicArray[candId].keys()), list( bicArray[candId].values()) idx = np.argsort(cvals) bestConfig = cconfig[idx[0]] bestConfigs.append(bestConfig) counter = Counter(bestConfigs).most_common(3) log.info( "B.I.C. prefers basis complexity %s %d times; %s %d times; %s %d times", counter[0][0], counter[0][1], counter[1][0], counter[1][1], counter[2][0], counter[2][1]) return counter[0][0], counter[1][0], counter[2][0]
def _buildCellSet(self, templateMaskedImage, scienceMaskedImage, candidateList): """Build a SpatialCellSet for use with the solve method. Parameters ---------- templateMaskedImage : `lsst.afw.image.MaskedImage` MaskedImage to PSF-matched to scienceMaskedImage scienceMaskedImage : `lsst.afw.image.MaskedImage` Reference MaskedImage candidateList : `list` A list of footprints/maskedImages for kernel candidates; - Currently supported: list of Footprints or measAlg.PsfCandidateF Returns ------- kernelCellSet : `lsst.afw.math.SpatialCellSet` a SpatialCellSet for use with self._solve """ if not candidateList: raise RuntimeError( "Candidate list must be populated by makeCandidateList") sizeCellX, sizeCellY = self._adaptCellSize(candidateList) # Object to store the KernelCandidates for spatial modeling kernelCellSet = afwMath.SpatialCellSet(templateMaskedImage.getBBox(), sizeCellX, sizeCellY) ps = pexConfig.makePropertySet(self.kConfig) # Place candidates within the spatial grid for cand in candidateList: if isinstance(cand, afwDetect.Footprint): bbox = cand.getBBox() else: bbox = cand['footprint'].getBBox() tmi = afwImage.MaskedImageF(templateMaskedImage, bbox) smi = afwImage.MaskedImageF(scienceMaskedImage, bbox) if not isinstance(cand, afwDetect.Footprint): if 'source' in cand: cand = cand['source'] xPos = cand.getCentroid()[0] yPos = cand.getCentroid()[1] cand = diffimLib.makeKernelCandidate(xPos, yPos, tmi, smi, ps) self.log.debug("Candidate %d at %f, %f", cand.getId(), cand.getXCenter(), cand.getYCenter()) kernelCellSet.insertCandidate(cand) return kernelCellSet
def setUp(self): self.config = ipDiffim.ImagePsfMatchTask.ConfigClass() self.config.kernel.name = "DF" self.subconfig = self.config.kernel.active self.ps = pexConfig.makePropertySet(self.subconfig) self.ps["useRegularization"] = False self.ps[ "checkConditionNumber"] = False # I am making shady kernels by hand self.ps["useCoreStats"] = False # I am making off-center resids self.kList = ipDiffim.makeKernelBasisList(self.subconfig) self.size = 51
def jackknifeResample(self, psfmatch, results): kernel = results.psfMatchingKernel bg = results.backgroundModel cellSet = results.kernelCellSet goodList = [] for cell in cellSet.getCellList(): print() for cand in cell.begin(False): if cand.getStatus() == afwMath.SpatialCellCandidate.GOOD: goodList.append(cand.getId()) else: # This is so that UNKNOWNs are not processed cand.setStatus(afwMath.SpatialCellCandidate.BAD) nStarPerCell = self.config.nStarPerCell ps = pexConfig.makePropertySet(self.config) for idx in range(len(goodList)): cid = goodList[idx] print() # clear the screen logger.debug("Removing candidate %d", cid) cand = self.setStatus(cellSet, cid, afwMath.SpatialCellCandidate.BAD) # From _solve regionBBox = cellSet.getBBox() spatialkv = ipDiffim.BuildSpatialKernelVisitorF( kernel.getKernelList(), regionBBox, ps) cellSet.visitCandidates(spatialkv, nStarPerCell) spatialkv.solveLinearEquation() jkKernel, jkBg = spatialkv.getSolutionPair() # jkResults = psfmatch._solve(cellSet, kernel.getKernelList()) # jkKernel = jkResults[1] # jkBg = jkResults[2] # lots of windows # self.assess(cand, kernel, bg, jkKernel, jkBg, 6*idx+1) # only 6 windows self.assess(cand, kernel, bg, jkKernel, jkBg, 1) self.setStatus(cellSet, cid, afwMath.SpatialCellCandidate.GOOD)
def setUp(self): self.config = ipDiffim.ImagePsfMatchTask.ConfigClass() self.subconfig = self.config.kernel.active self.ps = pexConfig.makePropertySet(self.subconfig) self.kSize = self.ps['kernelSize'] # gaussian reference kernel self.gSize = self.kSize self.gaussFunction = afwMath.GaussianFunction2D(2, 3) self.gaussKernel = afwMath.AnalyticKernel(self.gSize, self.gSize, self.gaussFunction) if defDataDir: defImagePath = os.path.join(defDataDir, "DC3a-Sim", "sci", "v5-e0", "v5-e0-c011-a00.sci.fits") self.templateImage = afwImage.MaskedImageF(defImagePath) self.scienceImage = self.templateImage.Factory( self.templateImage.getDimensions()) afwMath.convolve(self.scienceImage, self.templateImage, self.gaussKernel, False)
def testDetection(self): """Test object detection""" # # Fix defects # # Mask known bad pixels # badPixels = testUtils.makeDefectList() algorithms.interpolateOverDefects(self.mi, self.psf, badPixels) # # Subtract background # bgGridSize = 64 # was 256 ... but that gives only one region and the spline breaks bctrl = afwMath.BackgroundControl(afwMath.Interpolate.NATURAL_SPLINE) bctrl.setNxSample(int(self.mi.getWidth() / bgGridSize) + 1) bctrl.setNySample(int(self.mi.getHeight() / bgGridSize) + 1) backobj = afwMath.makeBackground(self.mi.getImage(), bctrl) self.mi.getImage()[:] -= backobj.getImageF() # # Remove CRs # crConfig = algorithms.FindCosmicRaysConfig() algorithms.findCosmicRays(self.mi, self.psf, 0, pexConfig.makePropertySet(crConfig)) # # We do a pretty good job of interpolating, so don't propagagate the convolved CR/INTRP bits # (we'll keep them for the original CR/INTRP pixels) # savedMask = self.mi.getMask().Factory(self.mi.getMask(), True) saveBits = savedMask.getPlaneBitMask("CR") | \ savedMask.getPlaneBitMask("BAD") | \ savedMask.getPlaneBitMask("INTRP") # Bits to not convolve savedMask &= saveBits msk = self.mi.getMask() msk &= ~saveBits # Clear the saved bits del msk # # Smooth image # psf = algorithms.DoubleGaussianPsf( 15, 15, self.FWHM / (2 * math.sqrt(2 * math.log(2)))) cnvImage = self.mi.Factory(self.mi.getBBox()) kernel = psf.getKernel() afwMath.convolve(cnvImage, self.mi, kernel, afwMath.ConvolutionControl()) msk = cnvImage.getMask() msk |= savedMask # restore the saved bits del msk threshold = afwDetection.Threshold(3, afwDetection.Threshold.STDEV) # # Only search the part of the frame that was PSF-smoothed # llc = lsst.geom.PointI(psf.getKernel().getWidth() // 2, psf.getKernel().getHeight() // 2) urc = lsst.geom.PointI(cnvImage.getWidth() - llc[0] - 1, cnvImage.getHeight() - llc[1] - 1) middle = cnvImage.Factory(cnvImage, lsst.geom.BoxI(llc, urc), afwImage.LOCAL) ds = afwDetection.FootprintSet(middle, threshold, "DETECTED") del middle # # Reinstate the saved (e.g. BAD) (and also the DETECTED | EDGE) bits in the unsmoothed image # savedMask[:] = cnvImage.getMask() msk = self.mi.getMask() msk |= savedMask del msk del savedMask if display: disp = afwDisplay.Display(frame=2) disp.mtv(self.mi, title=self._testMethodName + ": image") afwDisplay.Display(frame=3).mtv(cnvImage, title=self._testMethodName + ": cnvImage") # # Time to actually measure # schema = afwTable.SourceTable.makeMinimalSchema() sfm_config = measBase.SingleFrameMeasurementConfig() sfm_config.plugins = [ "base_SdssCentroid", "base_CircularApertureFlux", "base_PsfFlux", "base_SdssShape", "base_GaussianFlux", "base_PixelFlags" ] sfm_config.slots.centroid = "base_SdssCentroid" sfm_config.slots.shape = "base_SdssShape" sfm_config.slots.psfFlux = "base_PsfFlux" sfm_config.slots.gaussianFlux = None sfm_config.slots.apFlux = "base_CircularApertureFlux_3_0" sfm_config.slots.modelFlux = "base_GaussianFlux" sfm_config.slots.calibFlux = None sfm_config.plugins["base_SdssShape"].maxShift = 10.0 sfm_config.plugins["base_CircularApertureFlux"].radii = [3.0] task = measBase.SingleFrameMeasurementTask(schema, config=sfm_config) measCat = afwTable.SourceCatalog(schema) # detect the sources and run with the measurement task ds.makeSources(measCat) self.exposure.setPsf(self.psf) task.run(measCat, self.exposure) self.assertGreater(len(measCat), 0) for source in measCat: if source.get("base_PixelFlags_flag_edge"): continue if display: disp.dot("+", source.getX(), source.getY())
def setUp(self, CFHT=True): lambdaValue = 1.0 self.config1 = ipDiffim.ImagePsfMatchTask.ConfigClass() self.config1.kernel.name = "DF" self.subconfig1 = self.config1.kernel.active self.config2 = ipDiffim.ImagePsfMatchTask.ConfigClass() self.config2.kernel.name = "DF" self.subconfig2 = self.config2.kernel.active self.config3 = ipDiffim.ImagePsfMatchTask.ConfigClass() self.config3.kernel.name = "DF" self.subconfig3 = self.config3.kernel.active self.config4 = ipDiffim.ImagePsfMatchTask.ConfigClass() self.config4.kernel.name = "DF" self.subconfig4 = self.config4.kernel.active self.subconfig1.useRegularization = False self.subconfig2.useRegularization = True self.subconfig2.lambdaType = "absolute" self.subconfig2.lambdaValue = lambdaValue self.subconfig2.regularizationType = "centralDifference" self.subconfig2.centralRegularizationStencil = 5 self.subconfig3.useRegularization = True self.subconfig3.lambdaType = "absolute" self.subconfig3.lambdaValue = lambdaValue self.subconfig3.regularizationType = "centralDifference" self.subconfig3.centralRegularizationStencil = 9 self.subconfig4.useRegularization = True self.subconfig4.lambdaType = "absolute" self.subconfig4.lambdaValue = lambdaValue self.subconfig4.regularizationType = "forwardDifference" self.subconfig4.forwardRegularizationOrders = [1, 2] self.kList1 = ipDiffim.makeKernelBasisList(self.subconfig1) self.bskv1 = ipDiffim.BuildSingleKernelVisitorF( self.kList1, pexConfig.makePropertySet(self.subconfig1)) self.kList2 = ipDiffim.makeKernelBasisList(self.subconfig2) self.hMat2 = ipDiffim.makeRegularizationMatrix( pexConfig.makePropertySet(self.subconfig2)) self.bskv2 = ipDiffim.BuildSingleKernelVisitorF( self.kList2, pexConfig.makePropertySet(self.subconfig2), self.hMat2) self.kList3 = ipDiffim.makeKernelBasisList(self.subconfig3) self.hMat3 = ipDiffim.makeRegularizationMatrix( pexConfig.makePropertySet(self.subconfig3)) self.bskv3 = ipDiffim.BuildSingleKernelVisitorF( self.kList3, pexConfig.makePropertySet(self.subconfig3), self.hMat3) self.kList4 = ipDiffim.makeKernelBasisList(self.subconfig4) self.hMat4 = ipDiffim.makeRegularizationMatrix( pexConfig.makePropertySet(self.subconfig4)) self.bskv4 = ipDiffim.BuildSingleKernelVisitorF( self.kList4, pexConfig.makePropertySet(self.subconfig4), self.hMat4) # known input images defDataDir = lsst.utils.getPackageDir('afwdata') if CFHT: defSciencePath = os.path.join(defDataDir, 'CFHT', 'D4', CFHTTORUN + '.fits') defTemplatePath = os.path.join(defDataDir, 'CFHT', 'D4', CFHTTORUN + '_tmpl.fits') # no need to remap self.scienceExposure = afwImage.ExposureF(defSciencePath) self.templateExposure = afwImage.ExposureF(defTemplatePath) else: defSciencePath = os.path.join(defDataDir, "DC3a-Sim", "sci", "v26-e0", "v26-e0-c011-a00.sci") defTemplatePath = os.path.join(defDataDir, "DC3a-Sim", "sci", "v5-e0", "v5-e0-c011-a00.sci") self.scienceExposure = afwImage.ExposureF(defSciencePath) self.templateExposure = afwImage.ExposureF(defTemplatePath) warper = afwMath.Warper.fromConfig(self.subconfig1.warpingConfig) self.templateExposure = warper.warpExposure( self.scienceExposure.getWcs(), self.templateExposure, destBBox=self.scienceExposure.getBBox()) diffimTools.backgroundSubtract(self.subconfig1.afwBackgroundConfig, [ self.scienceExposure.getMaskedImage(), self.templateExposure.getMaskedImage() ]) # tmi = self.templateExposure.getMaskedImage() smi = self.scienceExposure.getMaskedImage() detConfig = self.subconfig1.detectionConfig detps = pexConfig.makePropertySet(detConfig) detps["detThreshold"] = 50. detps["detOnTemplate"] = False kcDetect = ipDiffim.KernelCandidateDetectionF(detps) kcDetect.apply(tmi, smi) self.footprints = kcDetect.getFootprints()
def applyVisitor(self, invert=False, xloc=397, yloc=580): print('# %.2f %.2f' % (xloc, yloc)) imsize = int(3 * self.subconfig1.kernelSize) # chop out a region around a known object bbox = afwGeom.Box2I( afwGeom.Point2I(xloc - imsize // 2, yloc - imsize // 2), afwGeom.Point2I(xloc + imsize // 2, yloc + imsize // 2)) # sometimes the box goes off the image; no big deal... try: if invert: tmi = afwImage.MaskedImageF( self.scienceExposure.getMaskedImage(), bbox, origin=afwImage.LOCAL) smi = afwImage.MaskedImageF( self.templateExposure.getMaskedImage(), bbox, origin=afwImage.LOCAL) else: smi = afwImage.MaskedImageF( self.scienceExposure.getMaskedImage(), bbox, origin=afwImage.LOCAL) tmi = afwImage.MaskedImageF( self.templateExposure.getMaskedImage(), bbox, origin=afwImage.LOCAL) except Exception: return None # delta function kernel logger.debug('DF run') results1 = self.apply(pexConfig.makePropertySet(self.subconfig1), self.bskv1, xloc, yloc, tmi, smi) kSum1, bg1, dmean1, dstd1, vmean1, kImageOut1, diffIm1, kc1, dStats1 = results1 res = 'DF residuals : %.3f +/- %.3f; %.2f, %.2f; %.2f %.2f, %.2f' % ( dStats1.getMean(), dStats1.getRms(), kSum1, bg1, dmean1, dstd1, vmean1) logger.debug(res) if display: afwDisplay.Display(frame=1).mtv( tmi, title="Template image") # ds9 switches frame 0 and 1 afwDisplay.Display(frame=0).mtv(smi, title="Sciencte image") afwDisplay.Display(frame=2).mtv(kImageOut1, title="Kernal image: 1") afwDisplay.Display(frame=3).mtv(diffIm1, title="Difference image: 1") if writefits: tmi.writeFits('t.fits') smi.writeFits('s.fits') kImageOut1.writeFits('k1.fits') diffIm1.writeFits('d1.fits') # regularized delta function kernel logger.debug('DFrC5 run') results2 = self.apply(pexConfig.makePropertySet(self.subconfig2), self.bskv2, xloc, yloc, tmi, smi) kSum2, bg2, dmean2, dstd2, vmean2, kImageOut2, diffIm2, kc2, dStats2 = results2 res = 'DFrC5 residuals : %.3f +/- %.3f; %.2f, %.2f; %.2f %.2f, %.2f' % ( dStats2.getMean(), dStats2.getRms(), kSum2, bg2, dmean2, dstd2, vmean2) logger.debug(res) if display: afwDisplay.Display(frame=4).mtv(tmi, title="Template image") afwDisplay.Display(frame=5).mtv(smi, title="Science image") afwDisplay.Display(frame=6).mtv(kImageOut2, title="Kernal image: 2") afwDisplay.Display(frame=7).mtv(diffIm2, title="Difference image: 2") if writefits: kImageOut2.writeFits('k2.fits') diffIm2.writeFits('d2') # regularized delta function kernel logger.debug('DFrC9 run') results3 = self.apply(pexConfig.makePropertySet(self.subconfig3), self.bskv3, xloc, yloc, tmi, smi) kSum3, bg3, dmean3, dstd3, vmean3, kImageOut3, diffIm3, kc3, dStats3 = results3 res = 'DFrC9 residuals : %.3f +/- %.3f; %.2f, %.2f; %.2f %.2f, %.2f' % ( dStats3.getMean(), dStats3.getRms(), kSum3, bg3, dmean3, dstd3, vmean3) logger.debug(res) if display: afwDisplay.Display(frame=8).mtv(tmi) afwDisplay.Display(frame=9).mtv(smi) afwDisplay.Display(frame=10).mtv(kImageOut3) afwDisplay.Display(frame=11).mtv(diffIm3) if writefits: kImageOut2.writeFits('k3.fits') diffIm2.writeFits('d3') # regularized delta function kernel logger.debug('DFrF12 run') results4 = self.apply(pexConfig.makePropertySet(self.subconfig4), self.bskv4, xloc, yloc, tmi, smi) kSum4, bg4, dmean4, dstd4, vmean4, kImageOut4, diffIm4, kc4, dStats4 = results4 res = 'DFrF12 residuals : %.3f +/- %.3f; %.2f, %.2f; %.2f %.2f, %.2f' % ( dStats4.getMean(), dStats4.getRms(), kSum4, bg4, dmean4, dstd4, vmean4) logger.debug(res) if display: afwDisplay.Display(frame=12).mtv(tmi) afwDisplay.Display(frame=13).mtv(smi) afwDisplay.Display(frame=14).mtv(kImageOut4) afwDisplay.Display(frame=15).mtv(diffIm4) if writefits: kImageOut2.writeFits('k4.fits') diffIm2.writeFits('d4') input('Next: ')
def cosmicRay(self, exposure, keepCRs=None): """Mask cosmic rays @param[in,out] exposure Exposure to process @param[in] keepCRs Don't interpolate over the CR pixels (defer to pex_config if None) """ import lsstDebug display = lsstDebug.Info(__name__).display displayCR = lsstDebug.Info(__name__).displayCR assert exposure, "No exposure provided" psf = exposure.getPsf() assert psf, "No psf provided" # Blow away old mask try: mask = exposure.getMaskedImage().getMask() crBit = mask.getMaskPlane("CR") mask.clearMaskPlane(crBit) except Exception: pass exposure0 = exposure # initial value of exposure binSize = self.config.cosmicray.background.binSize nx, ny = exposure.getWidth()/binSize, exposure.getHeight()/binSize # Treat constant background as a special case to avoid the extra complexity in calling # measAlg.SubtractBackgroundTask(). if nx*ny <= 1: medianBg = afwMath.makeStatistics(exposure.getMaskedImage(), afwMath.MEDIAN).getValue() modelBg = None else: # make a deep copy of the exposure before subtracting its background, # because this routine is only allowed to modify the exposure by setting mask planes # and interpolating over defects, not changing the background level exposure = exposure.Factory(exposure, True) subtractBackgroundTask = measAlg.SubtractBackgroundTask(config=self.config.cosmicray.background) modelBg = subtractBackgroundTask.run(exposure).background medianBg = 0.0 if keepCRs is None: keepCRs = self.config.cosmicray.keepCRs try: crs = measAlg.findCosmicRays(exposure.getMaskedImage(), psf, medianBg, pexConfig.makePropertySet(self.config.cosmicray), keepCRs) if modelBg: # Add back background image img = exposure.getMaskedImage() img += modelBg.getImageF() del img # Replace original image with CR subtracted image exposure0.setMaskedImage(exposure.getMaskedImage()) except Exception: if display: afwDisplay.Display().mtv(exposure0, title="Failed CR") raise num = 0 if crs is not None: mask = exposure0.getMaskedImage().getMask() crBit = mask.getPlaneBitMask("CR") afwDet.setMaskFromFootprintList(mask, crs, crBit) num = len(crs) if display and displayCR: disp = afwDisplay.Display() disp.incrDefaultFrame() disp.mtv(exposure0, title="Post-CR") with disp.Buffering(): for cr in crs: afwDisplay.utils.drawBBox(cr.getBBox(), borderWidth=0.55) self.log.info("Identified %s cosmic rays.", num)
def setUp(self): self.config = ipDiffim.ImagePsfMatchTask.ConfigClass() self.config.kernel.name = "AL" self.subconfig = self.config.kernel.active # Test was put together before the min size went to 21 self.subconfig.kernelSize = 19 self.subconfig.scaleByFwhm = False self.subconfig.fitForBackground = True self.subconfig.spatialModelType = "polynomial" self.ps = pexConfig.makePropertySet(self.subconfig) self.smi = afwImage.MaskedImageF( 'tests/compareToHotpants/scienceMI.fits') self.tmi = afwImage.MaskedImageF( 'tests/compareToHotpants/templateMI.fits') self.smi.setXY0(0, 0) self.tmi.setXY0(0, 0) # Run detection # detConfig = self.subconfig.detectionConfig # Note here regarding detConfig: # # If I set detThresholdType = "pixel_stdev", I get slightly # different centroids than if I use "stdev". These different # centroids screw up the testing since hotpants was hardcoded to # use the "stdev" centroids. For completeness these are: # # 32 32 # 96 32 # 160 32 # 96 95 # 31 96 # 160 96 # 96 160 # 160 160 # 32 160 # As of Winter2013, KernelCandidateDetectionF does not return # these exact centroids anymore, so I need to hardcode them # in. self.footprints = [] for xc, yc in [(32, 32), (96, 32), (160, 32), (96, 95), (31, 96), (160, 96), (96, 160), (160, 160), (32, 160)]: self.footprints.append( afwDet.Footprint( afwGeom.SpanSet( geom.Box2I(geom.Point2I(xc, yc), geom.Extent2I(1, 1))))) # Make a basis list that hotpants has been run with nGauss = 1 sGauss = [3.] dGauss = [3] self.subconfig.alardNGauss = nGauss self.subconfig.alardSigGauss = sGauss self.subconfig.alardDegGauss = dGauss basisList0 = ipDiffim.makeKernelBasisList(self.subconfig) # HP does things in a different order, and with different normalization, so reorder list order = [0, 2, 5, 9, 1, 4, 8, 3, 7, 6] scaling = [ 1.000000e+00, 8.866037e-02, 1.218095e+01, 5.099318e-03, 8.866037e-02, 4.179772e-02, 1.138120e-02, 1.218095e+01, 1.138120e-02, 5.099318e-03 ] self.basisList = [] for i in range(len(order)): im = afwImage.ImageD(basisList0[order[i]].getDimensions()) basisList0[order[i]].computeImage(im, False) im /= scaling[i] # im.writeFits('k%d.fits' % (i)) k = afwMath.FixedKernel(im) self.basisList.append(k) # And a place to put candidates self.kernelCellSet = afwMath.SpatialCellSet( geom.Box2I( geom.Point2I(0, 0), geom.Extent2I(self.smi.getWidth(), self.smi.getHeight())), self.ps["sizeCellX"], self.ps["sizeCellY"]) # There are some -1 factors that come from differences in how # convolution is done. Some resulting convovled images end up # being a factor of -1 different, therefore the coefficients # need to be a factor of -1 different as well. self.parity = [1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1]
def testDetection(self): """Test CR detection.""" # # Subtract background # bctrl = afwMath.BackgroundControl(afwMath.Interpolate.NATURAL_SPLINE) bctrl.setNxSample(int(self.mi.getWidth() / 256) + 1) bctrl.setNySample(int(self.mi.getHeight() / 256) + 1) bctrl.getStatisticsControl().setNumSigmaClip(3.0) bctrl.getStatisticsControl().setNumIter(2) im = self.mi.getImage() try: backobj = afwMath.makeBackground(im, bctrl) except Exception as e: print(e, file=sys.stderr) bctrl.setInterpStyle(afwMath.Interpolate.CONSTANT) backobj = afwMath.makeBackground(im, bctrl) im -= backobj.getImageF() if display: frame = 0 disp = afwDisplay.Display(frame=frame) disp.mtv(self.mi, title=self._testMethodName + ": Raw") # raw frame if self.mi.getWidth() > 256: disp.pan(944 - self.mi.getX0(), 260 - self.mi.getY0()) # # Mask known bad pixels # measAlgorithmsDir = lsst.utils.getPackageDir('meas_algorithms') badPixels = algorithms.Defects.readText( os.path.join(measAlgorithmsDir, "policy", "BadPixels.ecsv")) # did someone lie about the origin of the maskedImage? If so, adjust bad pixel list if self.XY0.getX() != self.mi.getX0() or self.XY0.getY( ) != self.mi.getY0(): dx = self.XY0.getX() - self.mi.getX0() dy = self.XY0.getY() - self.mi.getY0() for bp in badPixels: bp.shift(-dx, -dy) algorithms.interpolateOverDefects(self.mi, self.psf, badPixels) stats = afwMath.makeStatistics(self.mi.getImage(), afwMath.MEANCLIP | afwMath.STDEVCLIP) background = stats.getValue(afwMath.MEANCLIP) crConfig = algorithms.FindCosmicRaysConfig() crs = algorithms.findCosmicRays(self.mi, self.psf, background, pexConfig.makePropertySet(crConfig)) # Run again using makePolicy and check for warning with self.assertWarns(FutureWarning): algorithms.findCosmicRays(self.mi, self.psf, background, pexConfig.makePolicy(crConfig)) if display: frame += 1 disp = afwDisplay.Display(frame=frame) disp.mtv(self.mi, title=self._testMethodName + ": CRs removed") if self.mi.getWidth() > 256: disp.pan(944 - self.mi.getX0(), 260 - self.mi.getY0()) print("Detected %d CRs" % len(crs)) if display and False: for cr in crs: bbox = cr.getBBox() bbox.shift( lsst.geom.ExtentI(-self.mi.getX0(), -self.mi.getY0())) disp.line([(bbox.getMinX() - 0.5, bbox.getMinY() - 0.5), (bbox.getMaxX() + 0.5, bbox.getMinY() - 0.5), (bbox.getMaxX() + 0.5, bbox.getMaxY() + 0.5), (bbox.getMinX() - 0.5, bbox.getMaxY() + 0.5), (bbox.getMinX() - 0.5, bbox.getMinY() - 0.5)]) if self.nCR is not None: self.assertEqual(len(crs), self.nCR)
for switch in ['A', 'B', 'C']: if switch == 'A': # Default Alard Lupton config = subconfigAL elif switch == 'B': # Add more AL bases (typically 4 3 2) config = subconfigAL config.alardDegGauss = (8, 6, 4) elif switch == 'C': # Delta function config = subconfigDF config.useRegularization = False kList = ipDiffim.makeKernelBasisList(config) ps = pexConfig.makePropertySet(config) bskv = ipDiffim.BuildSingleKernelVisitorF(kList, ps) # TEST 1 tmi, smi = makeTest1(doAddNoise) kc = ipDiffim.makeKernelCandidate(0.0, 0.0, tmi, smi, ps) bskv.processCandidate(kc) kernel = kc.getKernel(ipDiffim.KernelCandidateF.ORIG) kimage = afwImage.ImageD(kernel.getDimensions()) kernel.computeImage(kimage, False) diffim = kc.getDifferenceImage(ipDiffim.KernelCandidateF.ORIG) afwDisplay.Display(frame=fnum).mtv(tmi, title="Template image") fnum += 1 afwDisplay.Display(frame=fnum).mtv(smi, title="Science image")
def makeFakeKernelSet(sizeCell=128, nCell=3, deltaFunctionCounts=1.e4, tGaussianWidth=1.0, addNoise=True, bgValue=100., display=False): """Generate test template and science images with sources. Parameters ---------- sizeCell : `int`, optional Size of the square spatial cells in pixels. nCell : `int`, optional Number of adjacent spatial cells in both direction in both images. deltaFunctionCounts : `float`, optional Flux value for the template image sources. tGaussianWidth : `float`, optional Sigma of the generated Gaussian PSF sources in the template image. addNoise : `bool`, optional If `True`, Poisson noise is added to both the generated template and science images. bgValue : `float`, optional Background level to be added to the generated science image. display : `bool`, optional If `True` displays the generated template and science images by `lsst.afw.display.Display`. Notes ----- - The generated images consist of adjacent ``nCell x nCell`` cells, each of pixel size ``sizeCell x sizeCell``. - The sources in the science image are generated by convolving the template by ``sKernel``. ``sKernel`` is a spatial `LinearCombinationKernel` of hard wired kernel bases functions. The linear combination has first order polynomial spatial dependence with polynomial parameters from ``fakeCoeffs()``. - The template image sources are generated in the center of each spatial cell from one pixel, set to `deltaFunctionCounts` counts, then convolved by a 2D Gaussian with sigma of `tGaussianWidth` along each axis. - The sources are also returned in ``kernelCellSet`` each source is "detected" exactly at the center of a cell. Returns ------- tMi : `lsst.afw.image.MaskedImage` Generated template image. sMi : `lsst.afw.image.MaskedImage` Generated science image. sKernel : `lsst.afw.math.LinearCombinationKernel` The spatial kernel used to generate the sources in the science image. kernelCellSet : `lsst.afw.math.SpatialCellSet` Cell grid of `lsst.afw.math.SpatialCell` instances, containing `lsst.ip.diffim.KernelCandidate` instances around all the generated sources in the science image. configFake : `lsst.ip.diffim.ImagePsfMatchConfig` Config instance used in the image generation. """ from . import imagePsfMatch configFake = imagePsfMatch.ImagePsfMatchConfig() configFake.kernel.name = "AL" subconfigFake = configFake.kernel.active subconfigFake.alardNGauss = 1 subconfigFake.alardSigGauss = [ 2.5, ] subconfigFake.alardDegGauss = [ 2, ] subconfigFake.sizeCellX = sizeCell subconfigFake.sizeCellY = sizeCell subconfigFake.spatialKernelOrder = 1 subconfigFake.spatialModelType = "polynomial" subconfigFake.singleKernelClipping = False # variance is a hack subconfigFake.spatialKernelClipping = False # variance is a hack if bgValue > 0.0: subconfigFake.fitForBackground = True psFake = pexConfig.makePropertySet(subconfigFake) basisList = makeKernelBasisList(subconfigFake) kSize = subconfigFake.kernelSize # This sets the final extent of each convolved delta function gaussKernelWidth = sizeCell // 2 # This sets the scale over which pixels are correlated in the # spatial convolution; should be at least as big as the kernel you # are trying to fit for spatialKernelWidth = kSize # Number of bad pixels due to convolutions border = (gaussKernelWidth + spatialKernelWidth) // 2 # Make a fake image with a matrix of delta functions totalSize = nCell * sizeCell + 2 * border tim = afwImage.ImageF(geom.Extent2I(totalSize, totalSize)) for x in range(nCell): for y in range(nCell): tim[x * sizeCell + sizeCell // 2 + border - 1, y * sizeCell + sizeCell // 2 + border - 1, afwImage.LOCAL] = deltaFunctionCounts # Turn this into stars with a narrow width; conserve counts gaussFunction = afwMath.GaussianFunction2D(tGaussianWidth, tGaussianWidth) gaussKernel = afwMath.AnalyticKernel(gaussKernelWidth, gaussKernelWidth, gaussFunction) cim = afwImage.ImageF(tim.getDimensions()) afwMath.convolve(cim, tim, gaussKernel, True) tim = cim # Trim off border pixels bbox = gaussKernel.shrinkBBox(tim.getBBox(afwImage.LOCAL)) tim = afwImage.ImageF(tim, bbox, afwImage.LOCAL) # Now make a science image which is this convolved with some # spatial function. Use input basis list. polyFunc = afwMath.PolynomialFunction2D(1) kCoeffs = fakeCoeffs() nToUse = min(len(kCoeffs), len(basisList)) # Make the full convolved science image sKernel = afwMath.LinearCombinationKernel(basisList[:nToUse], polyFunc) sKernel.setSpatialParameters(kCoeffs[:nToUse]) sim = afwImage.ImageF(tim.getDimensions()) afwMath.convolve(sim, tim, sKernel, True) # Get the good subregion bbox = sKernel.shrinkBBox(sim.getBBox(afwImage.LOCAL)) # Add background sim += bgValue # Watch out for negative values tim += 2 * np.abs(np.min(tim.getArray())) # Add noise? if addNoise: sim = makePoissonNoiseImage(sim) tim = makePoissonNoiseImage(tim) # And turn into MaskedImages sim = afwImage.ImageF(sim, bbox, afwImage.LOCAL) svar = afwImage.ImageF(sim, True) smask = afwImage.Mask(sim.getDimensions()) smask.set(0x0) sMi = afwImage.MaskedImageF(sim, smask, svar) tim = afwImage.ImageF(tim, bbox, afwImage.LOCAL) tvar = afwImage.ImageF(tim, True) tmask = afwImage.Mask(tim.getDimensions()) tmask.set(0x0) tMi = afwImage.MaskedImageF(tim, tmask, tvar) if display: import lsst.afw.display as afwDisplay afwDisplay.Display(frame=1).mtv(tMi) afwDisplay.Display(frame=2).mtv(sMi) # Finally, make a kernelSet from these 2 images kernelCellSet = afwMath.SpatialCellSet( geom.Box2I(geom.Point2I(0, 0), geom.Extent2I(sizeCell * nCell, sizeCell * nCell)), sizeCell, sizeCell) stampHalfWidth = 2 * kSize for x in range(nCell): for y in range(nCell): xCoord = x * sizeCell + sizeCell // 2 yCoord = y * sizeCell + sizeCell // 2 p0 = geom.Point2I(xCoord - stampHalfWidth, yCoord - stampHalfWidth) p1 = geom.Point2I(xCoord + stampHalfWidth, yCoord + stampHalfWidth) bbox = geom.Box2I(p0, p1) tsi = afwImage.MaskedImageF(tMi, bbox, origin=afwImage.LOCAL) ssi = afwImage.MaskedImageF(sMi, bbox, origin=afwImage.LOCAL) kc = diffimLib.makeKernelCandidate(xCoord, yCoord, tsi, ssi, psFake) kernelCellSet.insertCandidate(kc) tMi.setXY0(0, 0) sMi.setXY0(0, 0) return tMi, sMi, sKernel, kernelCellSet, configFake
configDFr = ipDiffim.ImagePsfMatchTask.ConfigClass() configDFr.kernel.name = "DF" subconfigDFr = configDFr.kernel.active subconfigDF.useRegularization = False 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)
def testDetection(self): """Test CR detection.""" # # Subtract background # bctrl = afwMath.BackgroundControl(afwMath.Interpolate.NATURAL_SPLINE) bctrl.setNxSample(int(self.mi.getWidth() / 256) + 1) bctrl.setNySample(int(self.mi.getHeight() / 256) + 1) bctrl.getStatisticsControl().setNumSigmaClip(3.0) bctrl.getStatisticsControl().setNumIter(2) im = self.mi.getImage() try: backobj = afwMath.makeBackground(im, bctrl) except Exception as e: print(e, file=sys.stderr) bctrl.setInterpStyle(afwMath.Interpolate.CONSTANT) backobj = afwMath.makeBackground(im, bctrl) im -= backobj.getImageF() if display: frame = 0 disp = afwDisplay.Display(frame=frame) disp.mtv(self.mi, title=self._testMethodName + ": Raw") # raw frame if self.mi.getWidth() > 256: disp.pan(944 - self.mi.getX0(), 260 - self.mi.getY0()) # # Mask known bad pixels # badPixels = testUtils.makeDefectList() algorithms.interpolateOverDefects(self.mi, self.psf, badPixels) stats = afwMath.makeStatistics(self.mi.getImage(), afwMath.MEANCLIP | afwMath.STDEVCLIP) background = stats.getValue(afwMath.MEANCLIP) crConfig = algorithms.FindCosmicRaysConfig() crs = algorithms.findCosmicRays(self.mi, self.psf, background, pexConfig.makePropertySet(crConfig)) if display: frame += 1 disp = afwDisplay.Display(frame=frame) disp.mtv(self.mi, title=self._testMethodName + ": CRs removed") if self.mi.getWidth() > 256: disp.pan(944 - self.mi.getX0(), 260 - self.mi.getY0()) print("Detected %d CRs" % len(crs)) if display and False: for cr in crs: bbox = cr.getBBox() bbox.shift( lsst.geom.ExtentI(-self.mi.getX0(), -self.mi.getY0())) disp.line([(bbox.getMinX() - 0.5, bbox.getMinY() - 0.5), (bbox.getMaxX() + 0.5, bbox.getMinY() - 0.5), (bbox.getMaxX() + 0.5, bbox.getMaxY() + 0.5), (bbox.getMinX() - 0.5, bbox.getMaxY() + 0.5), (bbox.getMinX() - 0.5, bbox.getMinY() - 0.5)]) if self.nCR is not None: self.assertEqual(len(crs), self.nCR)
def applyVisitor(self, invert=False, xloc=397, yloc=580): print('# %.2f %.2f' % (xloc, yloc)) imsize = int(3 * self.subconfigAL.kernelSize) # chop out a region around a known object bbox = afwGeom.Box2I( afwGeom.Point2I(xloc - imsize // 2, yloc - imsize // 2), afwGeom.Point2I(xloc + imsize // 2, yloc + imsize // 2)) # sometimes the box goes off the image; no big deal... try: if invert: tmi = afwImage.MaskedImageF( self.scienceExposure.getMaskedImage(), bbox, origin=afwImage.LOCAL) smi = afwImage.MaskedImageF( self.templateExposure.getMaskedImage(), bbox, orign=afwImage.LOCAL) else: smi = afwImage.MaskedImageF( self.scienceExposure.getMaskedImage(), bbox, origin=afwImage.LOCAL) tmi = afwImage.MaskedImageF( self.templateExposure.getMaskedImage(), bbox, origin=afwImage.LOCAL) except Exception: return None # ### # # delta function kernel resultsDF = self.apply(pexConfig.makePropertySet(self.subconfigDF), self.bskvDF, xloc, yloc, tmi, smi) kSumDF, bgDF, dmeanDF, dstdDF, vmeanDF, kImageOutDF, diffImDF, kcDF, dStats = resultsDF kcDF.getKernelSolution( ipDiffim.KernelCandidateF.RECENT).getConditionNumber( ipDiffim.KernelSolution.EIGENVALUE) kcDF.getKernelSolution( ipDiffim.KernelCandidateF.RECENT).getConditionNumber( ipDiffim.KernelSolution.SVD) print( 'DF Diffim residuals : %.2f +/- %.2f; %.2f, %.2f; %.2f %.2f, %.2f' % (dStats.getMean(), dStats.getRms(), kSumDF, bgDF, dmeanDF, dstdDF, vmeanDF)) if display: afwDisplay.Display(frame=1).mtv( tmi) # ds9 switches frame 0 and 1 for some reason afwDisplay.Display(frame=0).mtv(smi) afwDisplay.Display(frame=2).mtv(kImageOutDF) afwDisplay.Display(frame=3).mtv(diffImDF) if writefits: tmi.writeFits('t') smi.writeFits('s') kImageOutDF.writeFits('kDF.fits') diffImDF.writeFits('dDF') # ### # # regularized delta function kernel resultsDFr = self.apply(pexConfig.makePropertySet(self.subconfigDFr), self.bskvDFr, xloc, yloc, tmi, smi) kSumDFr, bgDFr, dmeanDFr, dstdDFr, vmeanDFr, kImageOutDFr, diffImDFr, kcDFr, dStats = resultsDFr kcDFr.getKernelSolution( ipDiffim.KernelCandidateF.RECENT).getConditionNumber( ipDiffim.KernelSolution.EIGENVALUE) kcDFr.getKernelSolution( ipDiffim.KernelCandidateF.RECENT).getConditionNumber( ipDiffim.KernelSolution.SVD) print( 'DFr Diffim residuals : %.2f +/- %.2f; %.2f, %.2f; %.2f %.2f, %.2f' % (dStats.getMean(), dStats.getRms(), kSumDFr, bgDFr, dmeanDFr, dstdDFr, vmeanDFr)) if display: afwDisplay.Display(frame=4).mtv(tmi) afwDisplay.Display(frame=5).mtv(smi) afwDisplay.Display(frame=6).mtv(kImageOutDFr) afwDisplay.Display(frame=7).mtv(diffImDFr) if writefits: kImageOutDFr.writeFits('kDFr.fits') diffImDFr.writeFits('dDFr') # ### # # alard-lupton kernel resultsAL = self.apply(pexConfig.makePropertySet(self.subconfigAL), self.bskvAL, xloc, yloc, tmi, smi) kSumAL, bgAL, dmeanAL, dstdAL, vmeanAL, kImageOutAL, diffImAL, kcAL, dStats = resultsAL kcAL.getKernelSolution( ipDiffim.KernelCandidateF.RECENT).getConditionNumber( ipDiffim.KernelSolution.EIGENVALUE) kcAL.getKernelSolution( ipDiffim.KernelCandidateF.RECENT).getConditionNumber( ipDiffim.KernelSolution.SVD) print( 'AL Diffim residuals : %.2f +/- %.2f; %.2f, %.2f; %.2f %.2f, %.2f' % (dStats.getMean(), dStats.getRms(), kSumAL, bgAL, dmeanAL, dstdAL, vmeanAL)) # outputs if display: afwDisplay.Display(frame=8).mtv(tmi) afwDisplay.Display(frame=9).mtv(smi) afwDisplay.Display(frame=10).mtv(kImageOutAL) afwDisplay.Display(frame=11).mtv(diffImAL) if writefits: kImageOutAL.writeFits('kAL.fits') diffImAL.writeFits('dAL') input('Next: ')
def testDetection(self): crConfig = algorithms.FindCosmicRaysConfig() crs = algorithms.findCosmicRays(self.mi, self.psf, 0.0, pexConfig.makePropertySet(crConfig)) self.assertEqual(len(crs), 0, "Found %d CRs in empty image" % len(crs))
def setUp(self): self.configAL = ipDiffim.ImagePsfMatchTask.ConfigClass() self.configAL.kernel.name = "AL" self.subconfigAL = self.configAL.kernel.active self.configDF = ipDiffim.ImagePsfMatchTask.ConfigClass() self.configDF.kernel.name = "DF" self.subconfigDF = self.configDF.kernel.active self.configDFr = ipDiffim.ImagePsfMatchTask.ConfigClass() self.configDFr.kernel.name = "DF" self.subconfigDFr = self.configDFr.kernel.active self.subconfigDF.useRegularization = False self.subconfigDFr.useRegularization = True self.subconfigDFr.lambdaValue = 1000.0 self.subconfigAL.fitForBackground = fitForBackground self.subconfigDF.fitForBackground = fitForBackground self.subconfigDFr.fitForBackground = fitForBackground self.subconfigAL.constantVarianceWeighting = constantVarianceWeighting self.subconfigDF.constantVarianceWeighting = constantVarianceWeighting self.subconfigDFr.constantVarianceWeighting = constantVarianceWeighting self.kListAL = ipDiffim.makeKernelBasisList(self.subconfigAL) self.kListDF = ipDiffim.makeKernelBasisList(self.subconfigDF) self.kListDFr = ipDiffim.makeKernelBasisList(self.subconfigDFr) self.hMatDFr = ipDiffim.makeRegularizationMatrix( pexConfig.makePropertySet(self.subconfigDFr)) self.bskvAL = ipDiffim.BuildSingleKernelVisitorF( self.kListAL, pexConfig.makePropertySet(self.subconfigAL)) self.bskvDF = ipDiffim.BuildSingleKernelVisitorF( self.kListDF, pexConfig.makePropertySet(self.subconfigDF)) self.bskvDFr = ipDiffim.BuildSingleKernelVisitorF( self.kListDFr, pexConfig.makePropertySet(self.subconfigDF), self.hMatDFr) defSciencePath = globals()['defSciencePath'] defTemplatePath = globals()['defTemplatePath'] if defSciencePath and defTemplatePath: self.scienceExposure = afwImage.ExposureF(defSciencePath) self.templateExposure = afwImage.ExposureF(defTemplatePath) else: defDataDir = lsst.utils.getPackageDir('afwdata') defSciencePath = os.path.join(defDataDir, "DC3a-Sim", "sci", "v26-e0", "v26-e0-c011-a00.sci.fits") defTemplatePath = os.path.join(defDataDir, "DC3a-Sim", "sci", "v5-e0", "v5-e0-c011-a00.sci.fits") self.scienceExposure = afwImage.ExposureF(defSciencePath) self.templateExposure = afwImage.ExposureF(defTemplatePath) warper = afwMath.Warper.fromConfig(self.subconfigAL.warpingConfig) self.templateExposure = warper.warpExposure( self.scienceExposure.getWcs(), self.templateExposure, destBBox=self.scienceExposure.getBBox()) # tmi = self.templateExposure.getMaskedImage() smi = self.scienceExposure.getMaskedImage() # Object detection detConfig = self.subconfigAL.detectionConfig detps = pexConfig.makePropertySet(detConfig) detps["detThreshold"] = 50. detps["detThresholdType"] = "stdev" detps["detOnTemplate"] = False kcDetect = ipDiffim.KernelCandidateDetectionF(detps) kcDetect.apply(tmi, smi) self.footprints = kcDetect.getFootprints()
def _buildCellSet(self, exposure, referencePsfModel): """Build a SpatialCellSet for use with the solve method Parameters ---------- exposure : `lsst.afw.image.Exposure` The science exposure that will be convolved; must contain a Psf referencePsfModel : `lsst.afw.detection.Psf` Psf model to match to Returns ------- result : `struct` - ``kernelCellSet`` : a SpatialCellSet to be used by self._solve - ``referencePsfModel`` : Validated and/or modified reference model used to populate the SpatialCellSet Notes ----- If the reference Psf model and science Psf model have different dimensions, adjust the referencePsfModel (the model to which the exposure PSF will be matched) to match that of the science Psf. If the science Psf dimensions vary across the image, as is common with a WarpedPsf, either pad or clip (depending on config.padPsf) the dimensions to be constant. """ sizeCellX = self.kConfig.sizeCellX sizeCellY = self.kConfig.sizeCellY scienceBBox = exposure.getBBox() # Extend for proper spatial matching kernel all the way to edge, especially for narrow strips scienceBBox.grow(geom.Extent2I(sizeCellX, sizeCellY)) sciencePsfModel = exposure.getPsf() dimenR = referencePsfModel.getLocalKernel(scienceBBox.getCenter()).getDimensions() regionSizeX, regionSizeY = scienceBBox.getDimensions() scienceX0, scienceY0 = scienceBBox.getMin() kernelCellSet = afwMath.SpatialCellSet(geom.Box2I(scienceBBox), sizeCellX, sizeCellY) nCellX = regionSizeX//sizeCellX nCellY = regionSizeY//sizeCellY if nCellX == 0 or nCellY == 0: raise ValueError("Exposure dimensions=%s and sizeCell=(%s, %s). Insufficient area to match" % (scienceBBox.getDimensions(), sizeCellX, sizeCellY)) # Survey the PSF dimensions of the Spatial Cell Set # to identify the minimum enclosed or maximum bounding square BBox. widthList = [] heightList = [] for row in range(nCellY): posY = sizeCellY*row + sizeCellY//2 + scienceY0 for col in range(nCellX): posX = sizeCellX*col + sizeCellX//2 + scienceX0 widthS, heightS = sciencePsfModel.computeBBox(geom.Point2D(posX, posY)).getDimensions() widthList.append(widthS) heightList.append(heightS) psfSize = max(max(heightList), max(widthList)) if self.config.doAutoPadPsf: minPsfSize = nextOddInteger(self.kConfig.kernelSize*self.config.autoPadPsfTo) paddingPix = max(0, minPsfSize - psfSize) else: if self.config.padPsfBy % 2 != 0: raise ValueError("Config padPsfBy (%i pixels) must be even number." % self.config.padPsfBy) paddingPix = self.config.padPsfBy if paddingPix > 0: self.log.debug("Padding Science PSF from (%d, %d) to (%d, %d) pixels", psfSize, psfSize, paddingPix + psfSize, paddingPix + psfSize) psfSize += paddingPix # Check that PSF is larger than the matching kernel maxKernelSize = psfSize - 1 if maxKernelSize % 2 == 0: maxKernelSize -= 1 if self.kConfig.kernelSize > maxKernelSize: message = """ Kernel size (%d) too big to match Psfs of size %d. Please reconfigure by setting one of the following: 1) kernel size to <= %d 2) doAutoPadPsf=True 3) padPsfBy to >= %s """ % (self.kConfig.kernelSize, psfSize, maxKernelSize, self.kConfig.kernelSize - maxKernelSize) raise ValueError(message) dimenS = geom.Extent2I(psfSize, psfSize) if (dimenR != dimenS): try: referencePsfModel = referencePsfModel.resized(psfSize, psfSize) self.log.info("Adjusted dimensions of reference PSF model from %s to %s", dimenR, dimenS) except Exception as e: self.log.warning("Zero padding or clipping the reference PSF model of type %s and dimensions" " %s to the science Psf dimensions %s because: %s", referencePsfModel.__class__.__name__, dimenR, dimenS, e) dimenR = dimenS ps = pexConfig.makePropertySet(self.kConfig) for row in range(nCellY): # place at center of cell posY = sizeCellY*row + sizeCellY//2 + scienceY0 for col in range(nCellX): # place at center of cell posX = sizeCellX*col + sizeCellX//2 + scienceX0 getTraceLogger(self.log, 4).debug("Creating Psf candidate at %.1f %.1f", posX, posY) # reference kernel image, at location of science subimage referenceMI = self._makePsfMaskedImage(referencePsfModel, posX, posY, dimensions=dimenR) # kernel image we are going to convolve scienceMI = self._makePsfMaskedImage(sciencePsfModel, posX, posY, dimensions=dimenR) # The image to convolve is the science image, to the reference Psf. kc = diffimLib.makeKernelCandidate(posX, posY, scienceMI, referenceMI, ps) kernelCellSet.insertCandidate(kc) import lsstDebug display = lsstDebug.Info(__name__).display displaySpatialCells = lsstDebug.Info(__name__).displaySpatialCells maskTransparency = lsstDebug.Info(__name__).maskTransparency if not maskTransparency: maskTransparency = 0 if display: afwDisplay.setDefaultMaskTransparency(maskTransparency) if display and displaySpatialCells: dituils.showKernelSpatialCells(exposure.getMaskedImage(), kernelCellSet, symb="o", ctype=afwDisplay.CYAN, ctypeUnused=afwDisplay.YELLOW, ctypeBad=afwDisplay.RED, size=4, frame=lsstDebug.frame, title="Image to be convolved") lsstDebug.frame += 1 return pipeBase.Struct(kernelCellSet=kernelCellSet, referencePsfModel=referencePsfModel, )
def setUp(self): self.config = ipDiffim.ImagePsfMatchTask.ConfigClass() self.subconfig = self.config.kernel["DF"] self.ps = pexConfig.makePropertySet(self.subconfig)