def psf(self, exposure, sources): """Measure the PSF @param exposure Exposure to process @param sources Measured sources on exposure """ assert exposure, "No exposure provided" assert sources, "No sources provided" psfPolicy = self.config['psf'] selName = psfPolicy['selectName'] selPolicy = psfPolicy['select'].getPolicy() algName = psfPolicy['algorithmName'] algPolicy = psfPolicy['algorithm'].getPolicy() self.log.log(self.log.INFO, "Measuring PSF") # # Run an extra detection step to mask out faint stars # if False: print "RHL is cleaning faint sources" import lsst.afw.math as afwMath sigma = 1.0 gaussFunc = afwMath.GaussianFunction1D(sigma) gaussKernel = afwMath.SeparableKernel(15, 15, gaussFunc, gaussFunc) im = exposure.getMaskedImage().getImage() convolvedImage = im.Factory(im.getDimensions()) afwMath.convolve(convolvedImage, im, gaussKernel) del im fs = afwDet.makeFootprintSet(convolvedImage, afwDet.createThreshold(4, "stdev")) fs = afwDet.makeFootprintSet(fs, 3, True) fs.setMask(exposure.getMaskedImage().getMask(), "DETECTED") starSelector = measAlg.makeStarSelector(selName, selPolicy) psfCandidateList = starSelector.selectStars(exposure, sources) psfDeterminer = measAlg.makePsfDeterminer(algName, algPolicy) psf, cellSet = psfDeterminer.determinePsf(exposure, psfCandidateList) # The PSF candidates contain a copy of the source, and so we need to explicitly propagate new flags for cand in psfCandidateList: cand = measAlg.cast_PsfCandidateF(cand) src = cand.getSource() if src.getFlagForDetection() & measAlg.Flags.PSFSTAR: ident = src.getId() src = sources[ident] assert src.getId() == ident src.setFlagForDetection(src.getFlagForDetection() | measAlg.Flags.PSFSTAR) exposure.setPsf(psf) return psf, cellSet
def showPsfSpatialCells(exposure, cellSet, showBadCandidates, frame=1): maUtils.showPsfSpatialCells(exposure, cellSet, symb="o", ctype=ds9.CYAN, ctypeUnused=ds9.YELLOW, size=4, frame=frame) for cell in cellSet.getCellList(): for cand in cell.begin(not showBadCandidates): # maybe include bad candidates cand = measAlg.cast_PsfCandidateF(cand) status = cand.getStatus() ds9.dot('+', *cand.getSource().getCentroid(), frame=frame, ctype=ds9.GREEN if status == afwMath.SpatialCellCandidate.GOOD else ds9.YELLOW if status == afwMath.SpatialCellCandidate.UNKNOWN else ds9.RED)
def plotPsfCandidates(cellSet, showBadCandidates=False, frame=1): import lsst.afw.display.utils as displayUtils stamps = [] for cell in cellSet.getCellList(): for cand in cell.begin(not showBadCandidates): # maybe include bad candidates cand = measAlg.cast_PsfCandidateF(cand) try: im = cand.getMaskedImage() chi2 = cand.getChi2() if chi2 < 1e100: chi2 = "%.1f" % chi2 else: chi2 = numpy.nan stamps.append((im, "%d%s" % (maUtils.splitId(cand.getSource().getId(), True)["objId"], chi2), cand.getStatus())) except Exception, e: continue
def plotPsfCandidates(cellSet, showBadCandidates=False, frame=1): import lsst.afw.display.utils as displayUtils stamps = [] for cell in cellSet.getCellList(): for cand in cell.begin(not showBadCandidates): # maybe include bad candidates cand = measAlg.cast_PsfCandidateF(cand) try: im = cand.getMaskedImage() chi2 = cand.getChi2() if chi2 < 1e100: chi2 = "%.1f" % chi2 else: chi2 = float("nan") stamps.append((im, "%d%s" % (maUtils.splitId(cand.getSource().getId(), True)["objId"], chi2), cand.getStatus())) except Exception: continue mos = displayUtils.Mosaic() for im, label, status in stamps: im = type(im)(im, True) try: im /= afwMath.makeStatistics(im, afwMath.MAX).getValue() except NotImplementedError: pass mos.append(im, label, ds9.GREEN if status == afwMath.SpatialCellCandidate.GOOD else ds9.YELLOW if status == afwMath.SpatialCellCandidate.UNKNOWN else ds9.RED) if mos.images: mos.makeMosaic(frame=frame, title="Psf Candidates")
def testGetPcaKernel(self): """Convert our cellSet to a LinearCombinationKernel""" nEigenComponents = 2 spatialOrder = 1 kernelSize = 21 nStarPerCell = 2 nStarPerCellSpatialFit = 2 tolerance = 1e-5 if display: ds9.mtv(self.mi, frame=0) # # Show the candidates we're using # for cell in self.cellSet.getCellList(): i = 0 for cand in cell: i += 1 source = algorithms.cast_PsfCandidateF(cand).getSource() xc, yc = source.getXAstrom() - self.mi.getX0(), source.getYAstrom() - self.mi.getY0() if i <= nStarPerCell: ds9.dot("o", xc, yc, ctype=ds9.GREEN) else: ds9.dot("o", xc, yc, ctype=ds9.YELLOW) pair = algorithms.createKernelFromPsfCandidates(self.cellSet, self.exposure.getDimensions(), self.exposure.getXY0(), nEigenComponents, spatialOrder, kernelSize, nStarPerCell) kernel, eigenValues = pair[0], pair[1]; del pair print "lambda", " ".join(["%g" % l for l in eigenValues]) pair = algorithms.fitSpatialKernelFromPsfCandidates(kernel, self.cellSet, nStarPerCellSpatialFit, tolerance) status, chi2 = pair[0], pair[1]; del pair print "Spatial fit: %s chi^2 = %.2g" % (status, chi2) psf = algorithms.PcaPsf.swigConvert(roundTripPsf(5, algorithms.PcaPsf(kernel))) # Hurrah! self.assertTrue(afwMath.cast_AnalyticKernel(psf.getKernel()) is None) self.assertTrue(afwMath.cast_LinearCombinationKernel(psf.getKernel()) is not None) self.checkTablePersistence(psf) if display: #print psf.getKernel().toString() eImages = [] for k in afwMath.cast_LinearCombinationKernel(psf.getKernel()).getKernelList(): im = afwImage.ImageD(k.getDimensions()) k.computeImage(im, False) eImages.append(im) mos = displayUtils.Mosaic() frame = 3 ds9.mtv(mos.makeMosaic(eImages), frame=frame) ds9.dot("Eigen Images", 0, 0, frame=frame) # # Make a mosaic of PSF candidates # stamps = [] stampInfo = [] for cell in self.cellSet.getCellList(): for cand in cell: # # Swig doesn't know that we inherited from SpatialCellMaskedImageCandidate; all # it knows is that we have a SpatialCellCandidate, and SpatialCellCandidates # don't know about getMaskedImage; so cast the pointer to PsfCandidate # cand = algorithms.cast_PsfCandidateF(cand) s = cand.getSource() im = cand.getMaskedImage() stamps.append(im) stampInfo.append("[%d 0x%x]" % (s.getId(), s.getFlagForDetection())) mos = displayUtils.Mosaic() frame = 1 ds9.mtv(mos.makeMosaic(stamps), frame=frame, lowOrderBits=True) for i in range(len(stampInfo)): ds9.dot(stampInfo[i], mos.getBBox(i).getX0(), mos.getBBox(i).getY0(), frame=frame, ctype=ds9.RED) psfImages = [] labels = [] if False: nx, ny = 3, 4 for iy in range(ny): for ix in range(nx): x = int((ix + 0.5)*self.mi.getWidth()/nx) y = int((iy + 0.5)*self.mi.getHeight()/ny) im = psf.getImage(x, y) psfImages.append(im.Factory(im, True)) labels.append("PSF(%d,%d)" % (int(x), int(y))) if True: print x, y, "PSF parameters:", psf.getKernel().getKernelParameters() else: nx, ny = 2, 2 for x, y in [(20, 20), (60, 20), (60, 210), (20, 210)]: im = psf.computeImage(afwGeom.PointD(x, y)) psfImages.append(im.Factory(im, True)) labels.append("PSF(%d,%d)" % (int(x), int(y))) if True: print x, y, "PSF parameters:", psf.getKernel().getKernelParameters() frame = 2 mos.makeMosaic(psfImages, frame=frame, mode=nx) mos.drawLabels(labels, frame=frame) if display: ds9.mtv(self.mi, frame=0) psfImages = [] labels = [] if False: nx, ny = 3, 4 for iy in range(ny): for ix in range(nx): x = int((ix + 0.5)*self.mi.getWidth()/nx) y = int((iy + 0.5)*self.mi.getHeight()/ny) algorithms.subtractPsf(psf, self.mi, x, y) else: nx, ny = 2, 2 for x, y in [(20, 20), (60, 20), (60, 210), (20, 210)]: if False: # Test subtraction with non-centered psfs x += 0.5; y -= 0.5 #algorithms.subtractPsf(psf, self.mi, x, y) ds9.mtv(self.mi, frame=1)
def testGetPcaKernel(self): """Convert our cellSet to a LinearCombinationKernel""" nEigenComponents = 2 spatialOrder = 1 kernelSize = 21 nStarPerCell = 2 nStarPerCellSpatialFit = 2 tolerance = 1e-5 if display: ds9.mtv(self.mi, frame=0) # # Show the candidates we're using # for cell in self.cellSet.getCellList(): i = 0 for cand in cell: i += 1 source = algorithms.cast_PsfCandidateF(cand).getSource() xc, yc = source.getXAstrom() - self.mi.getX0( ), source.getYAstrom() - self.mi.getY0() if i <= nStarPerCell: ds9.dot("o", xc, yc, ctype=ds9.GREEN) else: ds9.dot("o", xc, yc, ctype=ds9.YELLOW) pair = algorithms.createKernelFromPsfCandidates( self.cellSet, self.exposure.getDimensions(), self.exposure.getXY0(), nEigenComponents, spatialOrder, kernelSize, nStarPerCell) kernel, eigenValues = pair[0], pair[1] del pair print "lambda", " ".join(["%g" % l for l in eigenValues]) pair = algorithms.fitSpatialKernelFromPsfCandidates( kernel, self.cellSet, nStarPerCellSpatialFit, tolerance) status, chi2 = pair[0], pair[1] del pair print "Spatial fit: %s chi^2 = %.2g" % (status, chi2) psf = algorithms.PcaPsf.swigConvert( roundTripPsf(5, algorithms.PcaPsf(kernel))) # Hurrah! self.assertTrue(afwMath.cast_AnalyticKernel(psf.getKernel()) is None) self.assertTrue( afwMath.cast_LinearCombinationKernel(psf.getKernel()) is not None) self.checkTablePersistence(psf) if display: #print psf.getKernel().toString() eImages = [] for k in afwMath.cast_LinearCombinationKernel( psf.getKernel()).getKernelList(): im = afwImage.ImageD(k.getDimensions()) k.computeImage(im, False) eImages.append(im) mos = displayUtils.Mosaic() frame = 3 ds9.mtv(mos.makeMosaic(eImages), frame=frame) ds9.dot("Eigen Images", 0, 0, frame=frame) # # Make a mosaic of PSF candidates # stamps = [] stampInfo = [] for cell in self.cellSet.getCellList(): for cand in cell: # # Swig doesn't know that we inherited from SpatialCellMaskedImageCandidate; all # it knows is that we have a SpatialCellCandidate, and SpatialCellCandidates # don't know about getMaskedImage; so cast the pointer to PsfCandidate # cand = algorithms.cast_PsfCandidateF(cand) s = cand.getSource() im = cand.getMaskedImage() stamps.append(im) stampInfo.append("[%d 0x%x]" % (s.getId(), s.getFlagForDetection())) mos = displayUtils.Mosaic() frame = 1 ds9.mtv(mos.makeMosaic(stamps), frame=frame, lowOrderBits=True) for i in range(len(stampInfo)): ds9.dot(stampInfo[i], mos.getBBox(i).getX0(), mos.getBBox(i).getY0(), frame=frame, ctype=ds9.RED) psfImages = [] labels = [] if False: nx, ny = 3, 4 for iy in range(ny): for ix in range(nx): x = int((ix + 0.5) * self.mi.getWidth() / nx) y = int((iy + 0.5) * self.mi.getHeight() / ny) im = psf.getImage(x, y) psfImages.append(im.Factory(im, True)) labels.append("PSF(%d,%d)" % (int(x), int(y))) if True: print x, y, "PSF parameters:", psf.getKernel( ).getKernelParameters() else: nx, ny = 2, 2 for x, y in [(20, 20), (60, 20), (60, 210), (20, 210)]: im = psf.computeImage(afwGeom.PointD(x, y)) psfImages.append(im.Factory(im, True)) labels.append("PSF(%d,%d)" % (int(x), int(y))) if True: print x, y, "PSF parameters:", psf.getKernel( ).getKernelParameters() frame = 2 mos.makeMosaic(psfImages, frame=frame, mode=nx) mos.drawLabels(labels, frame=frame) if display: ds9.mtv(self.mi, frame=0) psfImages = [] labels = [] if False: nx, ny = 3, 4 for iy in range(ny): for ix in range(nx): x = int((ix + 0.5) * self.mi.getWidth() / nx) y = int((iy + 0.5) * self.mi.getHeight() / ny) algorithms.subtractPsf(psf, self.mi, x, y) else: nx, ny = 2, 2 for x, y in [(20, 20), (60, 20), (60, 210), (20, 210)]: if False: # Test subtraction with non-centered psfs x += 0.5 y -= 0.5 #algorithms.subtractPsf(psf, self.mi, x, y) ds9.mtv(self.mi, frame=1)
algPolicy.add('kernelSizeMax', 45) algPolicy.add('spatialOrder', 2) algPolicy.add('nStarPerCell', 0) algPolicy.add('nStarPerCellSpatialFit', 10) algPolicy.add('tolerance', 1e-2) algPolicy.add('spatialReject', 3.) starSelector = measAlg.makeStarSelector(selName, selPolicy) psfCandidateList = starSelector.selectStars(exposure, sources) psfDeterminer = measAlg.makePsfDeterminer(algName, algPolicy) psf, cellSet = psfDeterminer.determinePsf(exposure, psfCandidateList) # The PSF candidates contain a copy of the source, and so we need to explicitly propagate new flags for cand in psfCandidateList: cand = measAlg.cast_PsfCandidateF(cand) src = cand.getSource() if src.getFlagForDetection() & measAlg.Flags.PSFSTAR: ident = src.getId() src = sources[ident] assert src.getId() == ident src.setFlagForDetection(src.getFlagForDetection() | measAlg.Flags.PSFSTAR) exposure.setPsf(psf) print 'Got PSF', psf # Target cluster #x,y = 726., 4355. psfimg = psf.computeImage(afwGeom.Point2D(x, y)) psfimg.writeFits(psffn)
algPolicy.add('kernelSizeMax', 45) algPolicy.add('spatialOrder', 2) algPolicy.add('nStarPerCell', 0) algPolicy.add('nStarPerCellSpatialFit', 10) algPolicy.add('tolerance', 1e-2) algPolicy.add('spatialReject', 3.) starSelector = measAlg.makeStarSelector(selName, selPolicy) psfCandidateList = starSelector.selectStars(exposure, sources) psfDeterminer = measAlg.makePsfDeterminer(algName, algPolicy) psf, cellSet = psfDeterminer.determinePsf(exposure, psfCandidateList) # The PSF candidates contain a copy of the source, and so we need to explicitly propagate new flags for cand in psfCandidateList: cand = measAlg.cast_PsfCandidateF(cand) src = cand.getSource() if src.getFlagForDetection() & measAlg.Flags.PSFSTAR: ident = src.getId() src = sources[ident] assert src.getId() == ident src.setFlagForDetection(src.getFlagForDetection() | measAlg.Flags.PSFSTAR) exposure.setPsf(psf) print 'Got PSF', psf # Target cluster #x,y = 726., 4355. psfimg = psf.computeImage(afwGeom.Point2D(x,y)) psfimg.writeFits(psffn)