def testRejectBlends(self): """Test the PcaPsfDeterminer blend removal We give it a single blended source, asking it to remove blends, and check that it barfs in the expected way. """ factory = measAlg.psfDeterminerRegistry["pca"] config = factory.ConfigClass() config.doRejectBlends = True psfDeterminer = factory(config) schema = afwTable.SourceTable.makeMinimalSchema() # Use The single frame measurement task to populate the schema with standard keys sfm = measBase.SingleFrameMeasurementTask(schema) catalog = afwTable.SourceCatalog(schema) source = catalog.addNew() # Make the source blended, with necessary information to calculate pca foot = afwDetection.Footprint(afwGeom.Point2I(45, 123), 6, self.exposure.getBBox()) foot.addPeak(45, 123, 6) foot.addPeak(47, 126, 5) source.setFootprint(foot) centerKey = afwTable.Point2DKey(source.schema['slot_Centroid']) shapeKey = afwTable.QuadrupoleKey(schema['slot_Shape']) source.set(centerKey, afwTable.Point2D(46, 124)) source.set(shapeKey, afwTable.Quadrupole(1.1, 2.2, 1)) candidates = [measAlg.makePsfCandidate(source, self.exposure)] metadata = dafBase.PropertyList() with self.assertRaises(RuntimeError) as cm: psfDeterminer.determinePsf(self.exposure, candidates, metadata) self.assertEqual(cm.exception.message, "All PSF candidates removed as blends")
def setUp(self): config = SingleFrameMeasurementTask.ConfigClass() config.slots.apFlux = 'base_CircularApertureFlux_12_0' self.schema = afwTable.SourceTable.makeMinimalSchema() self.measureSources = SingleFrameMeasurementTask(self.schema, config=config) bbox = afwGeom.BoxI(afwGeom.PointI(0, 0), afwGeom.ExtentI(self.width, self.height)) self.cellSet = afwMath.SpatialCellSet(bbox, 100) self.footprintSet = afwDetection.FootprintSet( self.mi, afwDetection.Threshold(self.detectThresh), "DETECTED") self.catalog = self.measure(self.footprintSet, self.exposure) for source in self.catalog: try: cand = measAlg.makePsfCandidate(source, self.exposure) self.cellSet.insertCandidate(cand) except Exception as e: print(e) continue
def testRejectBlends(self): """Test the PcaPsfDeterminer blend removal We give it a single blended source, asking it to remove blends, and check that it barfs in the expected way. """ factory = measAlg.psfDeterminerRegistry["pca"] config = factory.ConfigClass() config.doRejectBlends = True psfDeterminer = factory(config) schema = afwTable.SourceTable.makeMinimalSchema() schema.addField("position", afwGeom.Point2D, doc="Position") schema.addField("flux.psf", float, doc="psf") schema.addField("flux.psf.flags", "Flag", doc="psf") catalog = afwTable.SourceCatalog(schema) catalog.defineCentroid("position") catalog.definePsfFlux("flux.psf") source = catalog.addNew() foot = afwDetection.Footprint(afwGeom.Point2I(123, 45), 6, self.exposure.getBBox()) foot.addPeak(123, 45, 6) foot.addPeak(126, 47, 5) source.setFootprint(foot) candidates = [measAlg.makePsfCandidate(source, self.exposure)] metadata = dafBase.PropertyList() with self.assertRaises(RuntimeError) as cm: psfDeterminer.determinePsf(self.exposure, candidates, metadata) self.assertEqual(cm.exception.message, "All PSF candidates removed as blends")
def selectPsfSources(exposure, matches, psfPolicy): """Get a list of suitable stars to construct a PSF.""" import lsstDebug display = lsstDebug.Info(__name__).display displayExposure = lsstDebug.Info(__name__).displayExposure # display the Exposure + spatialCells # # Unpack policy # kernelSize = psfPolicy.get("kernelSize") borderWidth = psfPolicy.get("borderWidth") sizePsfCellX = psfPolicy.get("sizeCellX") sizePsfCellY = psfPolicy.get("sizeCellY") # mi = exposure.getMaskedImage() if display and displayExposure: disp = afwDisplay.Display(frame=0) disp.mtv(mi, title="PSF candidates") psfCellSet = afwMath.SpatialCellSet(mi.getBBox(), sizePsfCellX, sizePsfCellY) psfStars = [] for val in matches: ref, source = val[0:2] if not (ref.getFlagForDetection() & measAlg.Flags.STAR) or \ (source.getFlagForDetection() & measAlg.Flags.BAD): continue try: cand = measAlg.makePsfCandidate(source, mi) # # The setXXX methods are class static, but it's convenient to call them on # an instance as we don't know Exposure's pixel type (and hence cand's exact type) if cand.getWidth() == 0: cand.setBorderWidth(borderWidth) cand.setWidth(kernelSize + 2*borderWidth) cand.setHeight(kernelSize + 2*borderWidth) im = cand.getMaskedImage().getImage() max = afwMath.makeStatistics(im, afwMath.MAX).getValue() if not np.isfinite(max): continue psfCellSet.insertCandidate(cand) if display and displayExposure: disp.dot("+", source.getXAstrom() - mi.getX0(), source.getYAstrom() - mi.getY0(), size=4, ctype=afwDisplay.CYAN) disp.dot("o", source.getXAstrom() - mi.getX0(), source.getYAstrom() - mi.getY0(), size=4, ctype=afwDisplay.CYAN) except Exception: continue source.setFlagForDetection(source.getFlagForDetection() | measAlg.Flags.STAR) psfStars += [source] return psfStars, psfCellSet
def setUp(self): width, height = 100, 300 self.mi = afwImage.MaskedImageF(afwGeom.ExtentI(width, height)) self.mi.set(0) self.mi.getVariance().set(10) self.mi.getMask().addMaskPlane("DETECTED") self.FWHM = 5 self.ksize = 25 # size of desired kernel self.exposure = afwImage.makeExposure(self.mi) psf = roundTripPsf(2, algorithms.DoubleGaussianPsf(self.ksize, self.ksize, self.FWHM/(2*sqrt(2*log(2))), 1, 0.1)) self.exposure.setPsf(psf) for x, y in [(20, 20), #(30, 35), (50, 50), (60, 20), (60, 210), (20, 210)]: flux = 10000 - 0*x - 10*y sigma = 3 + 0.01*(y - self.mi.getHeight()/2) psf = roundTripPsf(3, algorithms.DoubleGaussianPsf(self.ksize, self.ksize, sigma, 1, 0.1)) im = psf.computeImage().convertF() im *= flux smi = self.mi.getImage().Factory(self.mi.getImage(), afwGeom.BoxI(afwGeom.PointI(x - self.ksize/2, y - self.ksize/2), afwGeom.ExtentI(self.ksize)), afwImage.LOCAL) if False: # Test subtraction with non-centered psfs im = afwMath.offsetImage(im, 0.5, 0.5) smi += im del psf; del im; del smi psf = roundTripPsf(4, algorithms.DoubleGaussianPsf(self.ksize, self.ksize, self.FWHM/(2*sqrt(2*log(2))), 1, 0.1)) self.cellSet = afwMath.SpatialCellSet(afwGeom.BoxI(afwGeom.PointI(0, 0), afwGeom.ExtentI(width, height)), 100) ds = afwDetection.FootprintSet(self.mi, afwDetection.Threshold(10), "DETECTED") # # Prepare to measure # msConfig = algorithms.SourceMeasurementConfig() msConfig.load("tests/config/MeasureSources.py") schema = afwTable.SourceTable.makeMinimalSchema() measureSources = msConfig.makeMeasureSources(schema) catalog = afwTable.SourceCatalog(schema) msConfig.slots.calibFlux = None msConfig.slots.setupTable(catalog.table) ds.makeSources(catalog) for i, source in enumerate(catalog): measureSources.applyWithPeak(source, self.exposure) self.cellSet.insertCandidate(algorithms.makePsfCandidate(source, self.exposure))
def createCandidate(self, threshold=0.1): """Create a PSF candidate from self.exposure @param threshold: Threshold for creating footprints on image """ source = createFakeSource(self.x, self.y, self.catalog, self.exposure, threshold) return measAlg.makePsfCandidate(source, self.exposure)
def createCandidate(self, threshold=0.1): """Create a PSF candidate from self.exposure. Parameters ---------- threshold : `float`, optional Threshold for creating footprints on image. """ source = createFakeSource(self.x, self.y, self.catalog, self.exposure, threshold) return measAlg.makePsfCandidate(source, self.exposure)
def select(self, exposure, matches, psfPolicy): """Get a list of suitable stars to construct a PSF.""" import lsstDebug display = lsstDebug.Info(__name__).display displayExposure = lsstDebug.Info(__name__).displayExposure # display the Exposure + spatialCells # # Unpack policy # kernelSize = psfPolicy["kernelSizeMin"] borderWidth = psfPolicy["borderWidth"] # mi = exposure.getMaskedImage() if display and displayExposure: frame = 0 ds9.mtv(mi, frame=frame, title="PSF candidates") psfCandidates = [] for val in matches: ref, source = val[0:2] if not (ref.getFlagForDetection() & measAlg.Flags.STAR) or \ (source.getFlagForDetection() & measAlg.Flags.BAD): continue if source.getPsfFlux() <= 0.0: continue try: cand = measAlg.makePsfCandidate(source, mi) # # The setXXX methods are class static, but it's convenient to call them on # an instance as we don't know Exposure's pixel type (and hence cand's exact type) if cand.getWidth() == 0: cand.setBorderWidth(borderWidth) cand.setWidth(kernelSize + 2*borderWidth) cand.setHeight(kernelSize + 2*borderWidth) im = cand.getImage().getImage() max = afwMath.makeStatistics(im, afwMath.MAX).getValue() if not numpy.isfinite(max): continue if display and displayExposure: ds9.dot("+", source.getXAstrom() - mi.getX0(), source.getYAstrom() - mi.getY0(), size=4, frame=frame, ctype=ds9.CYAN) ds9.dot("o", source.getXAstrom() - mi.getX0(), source.getYAstrom() - mi.getY0(), size=4, frame=frame, ctype=ds9.CYAN) except Exception, e: continue source.setFlagForDetection(source.getFlagForDetection() | measAlg.Flags.STAR) psfCandidates.append(cand)
def setUp(self): config = SingleFrameMeasurementTask.ConfigClass() config.slots.apFlux = 'base_CircularApertureFlux_12_0' self.schema = afwTable.SourceTable.makeMinimalSchema() self.measureSources = SingleFrameMeasurementTask(self.schema, config=config) bbox = afwGeom.BoxI(afwGeom.PointI(0, 0), afwGeom.ExtentI(self.width, self.height)) self.cellSet = afwMath.SpatialCellSet(bbox, 100) self.footprintSet = afwDetection.FootprintSet(self.mi, afwDetection.Threshold(self.detectThresh), "DETECTED") self.catalog = self.measure(self.footprintSet, self.exposure) for source in self.catalog: try: cand = measAlg.makePsfCandidate(source, self.exposure) self.cellSet.insertCandidate(cand) except Exception as e: print(e) continue
def testRejectBlends(self): """Test the PcaPsfDeterminerTask blend removal.""" """ We give it a single blended source, asking it to remove blends, and check that it barfs in the expected way. """ psfDeterminerClass = measAlg.psfDeterminerRegistry["pca"] config = psfDeterminerClass.ConfigClass() config.doRejectBlends = True psfDeterminer = psfDeterminerClass(config=config) schema = afwTable.SourceTable.makeMinimalSchema() # Use The single frame measurement task to populate the schema with standard keys measBase.SingleFrameMeasurementTask(schema) catalog = afwTable.SourceCatalog(schema) source = catalog.addNew() # Make the source blended, with necessary information to calculate pca spanShift = afwGeom.Point2I(54, 123) spans = afwGeom.SpanSet.fromShape(6, offset=spanShift) foot = afwDetection.Footprint(spans, self.exposure.getBBox()) foot.addPeak(45, 123, 6) foot.addPeak(47, 126, 5) source.setFootprint(foot) centerKey = afwTable.Point2DKey(source.schema['slot_Centroid']) shapeKey = afwTable.QuadrupoleKey(schema['slot_Shape']) source.set(centerKey, afwGeom.Point2D(46, 124)) source.set(shapeKey, afwGeom.Quadrupole(1.1, 2.2, 1)) candidates = [measAlg.makePsfCandidate(source, self.exposure)] metadata = dafBase.PropertyList() with self.assertRaises(RuntimeError) as cm: psfDeterminer.determinePsf(self.exposure, candidates, metadata) self.assertEqual(str(cm.exception), "All PSF candidates removed as blends")
def selectStars(self, exposure, catalog, matches=None): """Return a list of PSF candidates that represent likely stars A list of PSF candidates may be used by a PSF fitter to construct a PSF. @param[in] exposure: the exposure containing the sources @param[in] catalog: a SourceCatalog containing sources that may be stars @param[in] matches: astrometric matches; ignored by this star selector @return psfCandidateList: a list of PSF candidates. """ import lsstDebug display = lsstDebug.Info(__name__).display displayExposure = display and \ lsstDebug.Info(__name__).displayExposure # display the Exposure + spatialCells plotFwhmHistogram = display and plt and \ lsstDebug.Info(__name__).plotFwhmHistogram # Plot histogram of FWHM plotFlags = display and plt and \ lsstDebug.Info(__name__).plotFlags # Plot the sources coloured by their flags plotRejection = display and plt and \ lsstDebug.Info(__name__).plotRejection # Plot why sources are rejected # create a log for my application logger = pexLogging.Log(pexLogging.getDefaultLog(), "meas.extensions.psfex.psfexStarSelector") #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- # fluxName = self.config.fluxName fluxErrName = self.config.fluxErrName minFwhm = self.config.minFwhm maxFwhm = self.config.maxFwhm maxFwhmVariability = self.config.maxFwhmVariability maxbad = self.config.maxbad maxbadflag = self.config.maxbadflag maxellip = self.config.maxellip minsn = self.config.minsn maxelong = (maxellip + 1.0)/(1.0 - maxellip) if maxellip < 1.0 else 100 # Unpack the catalogue shape = catalog.getShapeDefinition() ixx = catalog.get("%s.xx" % shape) iyy = catalog.get("%s.yy" % shape) fwhm = 2*np.sqrt(2*np.log(2))*np.sqrt(0.5*(ixx + iyy)) elong = 0.5*(ixx - iyy)/(ixx + iyy) flux = catalog.get(fluxName) fluxErr = catalog.get(fluxErrName) sn = flux/np.where(fluxErr > 0, fluxErr, 1) sn[fluxErr <= 0] = -psfex.psfex.cvar.BIG flags = 0x0 for i, f in enumerate(self.config.badFlags): flags = np.bitwise_or(flags, np.where(catalog.get(f), 1 << i, 0)) # # Estimate the acceptable range of source widths # good = np.logical_and(sn > minsn, np.logical_not(flags)) good = np.logical_and(good, elong < maxelong) good = np.logical_and(good, fwhm >= minFwhm) good = np.logical_and(good, fwhm < maxFwhm) fwhmMode, fwhmMin, fwhmMax = psfex.compute_fwhmrange(fwhm[good], maxFwhmVariability, minFwhm, maxFwhm, plot=dict(fwhmHistogram=plotFwhmHistogram)) #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- # # Here's select_candidates # #---- Apply some selection over flags, fluxes... bad = (flags != 0) #set.setBadFlags(int(sum(bad))) if plotRejection: selectionVectors = [] selectionVectors.append((bad, "flags %d" % sum(bad))) dbad = sn < minsn #set.setBadSN(int(sum(dbad))) bad = np.logical_or(bad, dbad) if plotRejection: selectionVectors.append((dbad, "S/N %d" % sum(dbad))) dbad = fwhm < fwhmMin #set.setBadFrmin(int(sum(dbad))) bad = np.logical_or(bad, dbad) if plotRejection: selectionVectors.append((dbad, "fwhmMin %d" % sum(dbad))) dbad = fwhm > fwhmMax #set.setBadFrmax(int(sum(dbad))) bad = np.logical_or(bad, dbad) if plotRejection: selectionVectors.append((dbad, "fwhmMax %d" % sum(dbad))) dbad = elong > maxelong #set.setBadElong(int(sum(dbad))) bad = np.logical_or(bad, dbad) if plotRejection: selectionVectors.append((dbad, "elong %d" % sum(dbad))) #-- ... and check the integrity of the sample if maxbadflag: nbad = np.array([(v <= -psfex.psfex.cvar.BIG).sum() for v in vignet]) dbad = nbad > maxbad #set.setBadPix(int(sum(dbad))) bad = np.logical_or(bad, dbad) if plotRejection: selectionVectors.append((dbad, "badpix %d" % sum(dbad))) good = np.logical_not(bad) # # We know enough to plot, if so requested # frame = 0 if displayExposure: mi = exposure.getMaskedImage() ds9.mtv(mi, frame=frame, title="PSF candidates") with ds9.Buffering(): for i, source in enumerate(catalog): if good[i]: ctype = ds9.GREEN # star candidate else: ctype = ds9.RED # not star ds9.dot("+", source.getX() - mi.getX0(), source.getY() - mi.getY0(), frame=frame, ctype=ctype) if plotFlags or plotRejection: imag = -2.5*np.log10(flux) plt.clf() alpha = 0.5 if plotFlags: isSet = np.where(flags == 0x0)[0] plt.plot(imag[isSet], fwhm[isSet], 'o', alpha=alpha, label="good") for i, f in enumerate(self.config.badFlags): mask = 1 << i isSet = np.where(np.bitwise_and(flags, mask))[0] if isSet.any(): if np.isfinite(imag[isSet] + fwhm[isSet]).any(): label = re.sub(r"\_flag", "", re.sub(r"^base\_", "", re.sub(r"^.*base\_PixelFlags\_flag\_", "", f))) plt.plot(imag[isSet], fwhm[isSet], 'o', alpha=alpha, label=label) else: for bad, label in selectionVectors: plt.plot(imag[bad], fwhm[bad], 'o', alpha=alpha, label=label) plt.plot(imag[good], fwhm[good], 'o', color="black", label="selected") [plt.axhline(_, color='red') for _ in [fwhmMin, fwhmMax]] plt.xlim(np.median(imag[good]) + 5*np.array([-1, 1])) plt.ylim(fwhm[np.where(np.isfinite(fwhm + imag))].min(), 2*fwhmMax) plt.legend(loc=2) plt.xlabel("Instrumental %s Magnitude" % fluxName.split(".")[-1].title()) plt.ylabel("fwhm") title = "PSFEX Star Selection" plt.title("%s %d selected" % (title, sum(good))) if displayExposure: global eventHandler eventHandler = EventHandler(plt.axes(), imag, fwhm, catalog.getX(), catalog.getY(), frames=[frame]) if plotFlags or plotRejection: while True: try: reply = raw_input("continue? [y[es] h(elp) p(db) q(uit)] ").strip() except EOFError: reply = "y" if not reply: reply = "y" if reply[0] == "h": print """\ At this prompt, you can continue with almost any key; 'p' enters pdb, 'q' returns to the shell, and 'h' prints this text """, if displayExposure: print """ If you put the cursor on a point in the matplotlib scatter plot and hit 'p' you'll see it in ds9.""" elif reply[0] == "p": import pdb; pdb.set_trace() elif reply[0] == 'q': sys.exit(1) else: break # # Time to use that stellar classification to generate psfCandidateList # with ds9.Buffering(): psfCandidateList = [] if True: catalog = [s for s,g in zip(catalog, good) if g] else: catalog = catalog[good] for source in catalog: try: psfCandidate = measAlg.makePsfCandidate(source, exposure) # The setXXX methods are class static, but it's convenient to call them on # an instance as we don't know Exposure's pixel type # (and hence psfCandidate's exact type) if psfCandidate.getWidth() == 0: psfCandidate.setBorderWidth(self.config.borderWidth) psfCandidate.setWidth(self.config.kernelSize + 2*self.config.borderWidth) psfCandidate.setHeight(self.config.kernelSize + 2*self.config.borderWidth) im = psfCandidate.getMaskedImage().getImage() vmax = afwMath.makeStatistics(im, afwMath.MAX).getValue() if not np.isfinite(vmax): continue psfCandidateList.append(psfCandidate) if display and displayExposure: ds9.dot("o", source.getX() - mi.getX0(), source.getY() - mi.getY0(), size=4, frame=frame, ctype=ds9.CYAN) except Exception as err: logger.logdebug("Failed to make a psfCandidate from source %d: %s" % (source.getId(), err)) return psfCandidateList
def setUp(self): config = SingleFrameMeasurementTask.ConfigClass() config.slots.apFlux = 'base_CircularApertureFlux_12_0' self.schema = afwTable.SourceTable.makeMinimalSchema() self.measureSources = SingleFrameMeasurementTask(self.schema, config=config) width, height = 110, 301 self.mi = afwImage.MaskedImageF(geom.ExtentI(width, height)) self.mi.set(0) sd = 3 # standard deviation of image self.mi.getVariance().set(sd * sd) self.mi.getMask().addMaskPlane("DETECTED") self.ksize = 31 # size of desired kernel sigma1 = 1.75 sigma2 = 2 * sigma1 self.exposure = afwImage.makeExposure(self.mi) self.exposure.setPsf( measAlg.DoubleGaussianPsf(self.ksize, self.ksize, 1.5 * sigma1, 1, 0.1)) cdMatrix = np.array([1.0, 0.0, 0.0, 1.0]) cdMatrix.shape = (2, 2) wcs = afwGeom.makeSkyWcs(crpix=geom.PointD(0, 0), crval=geom.SpherePoint( 0.0, 0.0, geom.degrees), cdMatrix=cdMatrix) self.exposure.setWcs(wcs) # # Make a kernel with the exactly correct basis functions. # Useful for debugging # basisKernelList = [] for sigma in (sigma1, sigma2): basisKernel = afwMath.AnalyticKernel( self.ksize, self.ksize, afwMath.GaussianFunction2D(sigma, sigma)) basisImage = afwImage.ImageD(basisKernel.getDimensions()) basisKernel.computeImage(basisImage, True) basisImage /= np.sum(basisImage.getArray()) if sigma == sigma1: basisImage0 = basisImage else: basisImage -= basisImage0 basisKernelList.append(afwMath.FixedKernel(basisImage)) order = 1 # 1 => up to linear spFunc = afwMath.PolynomialFunction2D(order) exactKernel = afwMath.LinearCombinationKernel(basisKernelList, spFunc) exactKernel.setSpatialParameters([[1.0, 0, 0], [0.0, 0.5 * 1e-2, 0.2e-2]]) rand = afwMath.Random() # make these tests repeatable by setting seed addNoise = True if addNoise: im = self.mi.getImage() afwMath.randomGaussianImage(im, rand) # N(0, 1) im *= sd # N(0, sd^2) del im xarr, yarr = [], [] for x, y in [ (20, 20), (60, 20), (30, 35), (50, 50), (20, 90), (70, 160), (25, 265), (75, 275), (85, 30), (50, 120), (70, 80), (60, 210), (20, 210), ]: xarr.append(x) yarr.append(y) for x, y in zip(xarr, yarr): dx = rand.uniform() - 0.5 # random (centered) offsets dy = rand.uniform() - 0.5 k = exactKernel.getSpatialFunction(1)( x, y) # functional variation of Kernel ... b = (k * sigma1**2 / ((1 - k) * sigma2**2) ) # ... converted double Gaussian's "b" # flux = 80000 - 20*x - 10*(y/float(height))**2 flux = 80000 * (1 + 0.1 * (rand.uniform() - 0.5)) I0 = flux * (1 + b) / (2 * np.pi * (sigma1**2 + b * sigma2**2)) for iy in range(y - self.ksize // 2, y + self.ksize // 2 + 1): if iy < 0 or iy >= self.mi.getHeight(): continue for ix in range(x - self.ksize // 2, x + self.ksize // 2 + 1): if ix < 0 or ix >= self.mi.getWidth(): continue II = I0 * psfVal(ix, iy, x + dx, y + dy, sigma1, sigma2, b) Isample = rand.poisson(II) if addNoise else II self.mi.image[ix, iy, afwImage.LOCAL] += Isample self.mi.variance[ix, iy, afwImage.LOCAL] += II bbox = geom.BoxI(geom.PointI(0, 0), geom.ExtentI(width, height)) self.cellSet = afwMath.SpatialCellSet(bbox, 100) self.footprintSet = afwDetection.FootprintSet( self.mi, afwDetection.Threshold(100), "DETECTED") self.catalog = self.measure(self.footprintSet, self.exposure) for source in self.catalog: try: cand = measAlg.makePsfCandidate(source, self.exposure) self.cellSet.insertCandidate(cand) except Exception as e: print(e) continue
def setUp(self): width, height = 100, 300 self.mi = afwImage.MaskedImageF(lsst.geom.ExtentI(width, height)) self.mi.set(0) self.mi.getVariance().set(10) self.mi.getMask().addMaskPlane("DETECTED") self.FWHM = 5 self.ksize = 25 # size of desired kernel self.exposure = afwImage.makeExposure(self.mi) psf = roundTripPsf(2, algorithms.DoubleGaussianPsf(self.ksize, self.ksize, self.FWHM/(2*math.sqrt(2*math.log(2))), 1, 0.1)) self.exposure.setPsf(psf) for x, y in [(20, 20), # (30, 35), (50, 50), (60, 20), (60, 210), (20, 210)]: flux = 10000 - 0*x - 10*y sigma = 3 + 0.01*(y - self.mi.getHeight()/2) psf = roundTripPsf(3, algorithms.DoubleGaussianPsf(self.ksize, self.ksize, sigma, 1, 0.1)) im = psf.computeImage().convertF() im *= flux x0y0 = lsst.geom.PointI(x - self.ksize//2, y - self.ksize//2) smi = self.mi.getImage().Factory(self.mi.getImage(), lsst.geom.BoxI(x0y0, lsst.geom.ExtentI(self.ksize)), afwImage.LOCAL) if False: # Test subtraction with non-centered psfs im = afwMath.offsetImage(im, 0.5, 0.5) smi += im del psf del im del smi roundTripPsf(4, algorithms.DoubleGaussianPsf(self.ksize, self.ksize, self.FWHM/(2*math.sqrt(2*math.log(2))), 1, 0.1)) self.cellSet = afwMath.SpatialCellSet(lsst.geom.BoxI(lsst.geom.PointI(0, 0), lsst.geom.ExtentI(width, height)), 100) ds = afwDetection.FootprintSet(self.mi, afwDetection.Threshold(10), "DETECTED") # # Prepare to 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) task.run(measCat, self.exposure) for source in measCat: self.cellSet.insertCandidate(algorithms.makePsfCandidate(source, self.exposure))
def setUp(self): width, height = 100, 300 self.mi = afwImage.MaskedImageF(afwGeom.ExtentI(width, height)) self.mi.set(0) self.mi.getVariance().set(10) self.mi.getMask().addMaskPlane("DETECTED") self.FWHM = 5 self.ksize = 25 # size of desired kernel self.exposure = afwImage.makeExposure(self.mi) psf = roundTripPsf( 2, algorithms.DoubleGaussianPsf( self.ksize, self.ksize, self.FWHM / (2 * math.sqrt(2 * math.log(2))), 1, 0.1)) self.exposure.setPsf(psf) for x, y in [ (20, 20), #(30, 35), (50, 50), (60, 20), (60, 210), (20, 210) ]: flux = 10000 - 0 * x - 10 * y sigma = 3 + 0.01 * (y - self.mi.getHeight() / 2) psf = roundTripPsf( 3, algorithms.DoubleGaussianPsf(self.ksize, self.ksize, sigma, 1, 0.1)) im = psf.computeImage().convertF() im *= flux x0y0 = afwGeom.PointI(x - self.ksize // 2, y - self.ksize // 2) smi = self.mi.getImage().Factory( self.mi.getImage(), afwGeom.BoxI(x0y0, afwGeom.ExtentI(self.ksize)), afwImage.LOCAL) if False: # Test subtraction with non-centered psfs im = afwMath.offsetImage(im, 0.5, 0.5) smi += im del psf del im del smi roundTripPsf( 4, algorithms.DoubleGaussianPsf( self.ksize, self.ksize, self.FWHM / (2 * math.sqrt(2 * math.log(2))), 1, 0.1)) self.cellSet = afwMath.SpatialCellSet( afwGeom.BoxI(afwGeom.PointI(0, 0), afwGeom.ExtentI(width, height)), 100) ds = afwDetection.FootprintSet(self.mi, afwDetection.Threshold(10), "DETECTED") # # Prepare to 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.instFlux = 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) task.run(measCat, self.exposure) for source in measCat: self.cellSet.insertCandidate( algorithms.makePsfCandidate(source, self.exposure))
def setUp(self): self.schema = afwTable.SourceTable.makeMinimalSchema() config = measBase.SingleFrameMeasurementConfig() config.algorithms.names = ["base_PixelFlags", "base_SdssCentroid", "base_GaussianFlux", "base_SdssShape", "base_CircularApertureFlux", "base_PsfFlux", ] config.algorithms["base_CircularApertureFlux"].radii = [3.0] config.slots.centroid = "base_SdssCentroid" config.slots.psfFlux = "base_PsfFlux" config.slots.apFlux = "base_CircularApertureFlux_3_0" config.slots.modelFlux = None config.slots.gaussianFlux = None config.slots.calibFlux = None config.slots.shape = "base_SdssShape" self.measureTask = measBase.SingleFrameMeasurementTask(self.schema, config=config) width, height = 110, 301 self.mi = afwImage.MaskedImageF(lsst.geom.ExtentI(width, height)) self.mi.set(0) sd = 3 # standard deviation of image self.mi.getVariance().set(sd*sd) self.mi.getMask().addMaskPlane("DETECTED") self.FWHM = 5 self.ksize = 31 # size of desired kernel sigma1 = 1.75 sigma2 = 2*sigma1 self.exposure = afwImage.makeExposure(self.mi) self.exposure.setPsf(measAlg.DoubleGaussianPsf(self.ksize, self.ksize, 1.5*sigma1, 1, 0.1)) self.exposure.setDetector(DetectorWrapper().detector) # # Make a kernel with the exactly correct basis functions. Useful for debugging # basisKernelList = [] for sigma in (sigma1, sigma2): basisKernel = afwMath.AnalyticKernel(self.ksize, self.ksize, afwMath.GaussianFunction2D(sigma, sigma)) basisImage = afwImage.ImageD(basisKernel.getDimensions()) basisKernel.computeImage(basisImage, True) basisImage /= np.sum(basisImage.getArray()) if sigma == sigma1: basisImage0 = basisImage else: basisImage -= basisImage0 basisKernelList.append(afwMath.FixedKernel(basisImage)) order = 1 # 1 => up to linear spFunc = afwMath.PolynomialFunction2D(order) exactKernel = afwMath.LinearCombinationKernel(basisKernelList, spFunc) exactKernel.setSpatialParameters([[1.0, 0, 0], [0.0, 0.5*1e-2, 0.2e-2]]) self.exactPsf = measAlg.PcaPsf(exactKernel) rand = afwMath.Random() # make these tests repeatable by setting seed addNoise = True if addNoise: im = self.mi.getImage() afwMath.randomGaussianImage(im, rand) # N(0, 1) im *= sd # N(0, sd^2) del im xarr, yarr = [], [] for x, y in [(20, 20), (60, 20), (30, 35), (50, 50), (20, 90), (70, 160), (25, 265), (75, 275), (85, 30), (50, 120), (70, 80), (60, 210), (20, 210), ]: xarr.append(x) yarr.append(y) for x, y in zip(xarr, yarr): dx = rand.uniform() - 0.5 # random (centered) offsets dy = rand.uniform() - 0.5 k = exactKernel.getSpatialFunction(1)(x, y) # functional variation of Kernel ... b = (k*sigma1**2/((1 - k)*sigma2**2)) # ... converted double Gaussian's "b" # flux = 80000 - 20*x - 10*(y/float(height))**2 flux = 80000*(1 + 0.1*(rand.uniform() - 0.5)) I0 = flux*(1 + b)/(2*np.pi*(sigma1**2 + b*sigma2**2)) for iy in range(y - self.ksize//2, y + self.ksize//2 + 1): if iy < 0 or iy >= self.mi.getHeight(): continue for ix in range(x - self.ksize//2, x + self.ksize//2 + 1): if ix < 0 or ix >= self.mi.getWidth(): continue intensity = I0*psfVal(ix, iy, x + dx, y + dy, sigma1, sigma2, b) Isample = rand.poisson(intensity) if addNoise else intensity self.mi.image[ix, iy, afwImage.LOCAL] += Isample self.mi.variance[ix, iy, afwImage.LOCAL] += intensity # bbox = lsst.geom.BoxI(lsst.geom.PointI(0, 0), lsst.geom.ExtentI(width, height)) self.cellSet = afwMath.SpatialCellSet(bbox, 100) self.footprintSet = afwDetection.FootprintSet(self.mi, afwDetection.Threshold(100), "DETECTED") self.catalog = self.measure(self.footprintSet, self.exposure) for source in self.catalog: try: cand = measAlg.makePsfCandidate(source, self.exposure) self.cellSet.insertCandidate(cand) except Exception as e: print(e) continue
def selectStars(self, exposure, sourceCat, matches=None): """!Return a list of PSF candidates that represent likely stars A list of PSF candidates may be used by a PSF fitter to construct a PSF. @param[in] exposure the exposure containing the sources @param[in] sourceCat catalog of sources that may be stars (an lsst.afw.table.SourceCatalog) @param[in] matches a match vector as produced by meas_astrom; required (defaults to None to match the StarSelector API and improve error handling) @return psfCandidateList: a list of PSF candidates. """ import lsstDebug display = lsstDebug.Info(__name__).display displayExposure = lsstDebug.Info(__name__).displayExposure # display the Exposure + spatialCells pauseAtEnd = lsstDebug.Info(__name__).pauseAtEnd # pause when done if matches is None: raise RuntimeError("CatalogStarSelector requires matches") mi = exposure.getMaskedImage() if display: frames = {} if displayExposure: frames["displayExposure"] = 1 ds9.mtv(mi, frame=frames["displayExposure"], title="PSF candidates") # # Read the reference catalogue # isGoodSource = CheckSource(sourceCat, self._fluxLim, self._fluxMax, self._badStarPixelFlags) # # Go through and find all the PSFs in the catalogue # # We'll split the image into a number of cells, each of which contributes only # one PSF candidate star # psfCandidateList = [] with ds9.Buffering(): for ref, source, d in matches: if not ref.get("resolved"): if not isGoodSource(source): symb, ctype = "+", ds9.RED else: try: psfCandidate = measAlg.makePsfCandidate(source, exposure) # The setXXX methods are class static, but it's convenient to call them on # an instance as we don't know Exposure's pixel type # (and hence psfCandidate's exact type) if psfCandidate.getWidth() == 0: psfCandidate.setBorderWidth(self._borderWidth) psfCandidate.setWidth(self._kernelSize + 2*self._borderWidth) psfCandidate.setHeight(self._kernelSize + 2*self._borderWidth) im = psfCandidate.getMaskedImage().getImage() max = afwMath.makeStatistics(im, afwMath.MAX).getValue() if not numpy.isfinite(max): continue psfCandidateList.append(psfCandidate) symb, ctype = "+", ds9.GREEN except Exception as err: symb, ctype = "o", ds9.RED print "RHL", err pass # FIXME: should log this! else: symb, ctype = "o", ds9.BLUE if display and displayExposure: ds9.dot(symb, source.getX() - mi.getX0(), source.getY() - mi.getY0(), size=4, frame=frames["displayExposure"], ctype=ctype) if display and pauseAtEnd: raw_input("Continue? y[es] p[db] ") return psfCandidateList
def setUp(self): self.schema = afwTable.SourceTable.makeMinimalSchema() config = measBase.SingleFrameMeasurementConfig() config.algorithms.names = [ "base_PixelFlags", "base_SdssCentroid", "base_GaussianFlux", "base_SdssShape", "base_CircularApertureFlux", "base_PsfFlux", ] config.algorithms["base_CircularApertureFlux"].radii = [3.0] config.slots.centroid = "base_SdssCentroid" config.slots.psfFlux = "base_PsfFlux" config.slots.apFlux = "base_CircularApertureFlux_3_0" config.slots.modelFlux = None config.slots.instFlux = None config.slots.calibFlux = None config.slots.shape = "base_SdssShape" self.measureTask = measBase.SingleFrameMeasurementTask(self.schema, config=config) width, height = 110, 301 self.mi = afwImage.MaskedImageF(afwGeom.ExtentI(width, height)) self.mi.set(0) sd = 3 # standard deviation of image self.mi.getVariance().set(sd * sd) self.mi.getMask().addMaskPlane("DETECTED") self.FWHM = 5 self.ksize = 31 # size of desired kernel sigma1 = 1.75 sigma2 = 2 * sigma1 self.exposure = afwImage.makeExposure(self.mi) self.exposure.setPsf( measAlg.DoubleGaussianPsf(self.ksize, self.ksize, 1.5 * sigma1, 1, 0.1)) self.exposure.setDetector(DetectorWrapper().detector) # # Make a kernel with the exactly correct basis functions. Useful for debugging # basisKernelList = [] for sigma in (sigma1, sigma2): basisKernel = afwMath.AnalyticKernel( self.ksize, self.ksize, afwMath.GaussianFunction2D(sigma, sigma)) basisImage = afwImage.ImageD(basisKernel.getDimensions()) basisKernel.computeImage(basisImage, True) basisImage /= np.sum(basisImage.getArray()) if sigma == sigma1: basisImage0 = basisImage else: basisImage -= basisImage0 basisKernelList.append(afwMath.FixedKernel(basisImage)) order = 1 # 1 => up to linear spFunc = afwMath.PolynomialFunction2D(order) exactKernel = afwMath.LinearCombinationKernel(basisKernelList, spFunc) exactKernel.setSpatialParameters([[1.0, 0, 0], [0.0, 0.5 * 1e-2, 0.2e-2]]) self.exactPsf = measAlg.PcaPsf(exactKernel) rand = afwMath.Random() # make these tests repeatable by setting seed addNoise = True if addNoise: im = self.mi.getImage() afwMath.randomGaussianImage(im, rand) # N(0, 1) im *= sd # N(0, sd^2) del im xarr, yarr = [], [] for x, y in [ (20, 20), (60, 20), (30, 35), (50, 50), (20, 90), (70, 160), (25, 265), (75, 275), (85, 30), (50, 120), (70, 80), (60, 210), (20, 210), ]: xarr.append(x) yarr.append(y) for x, y in zip(xarr, yarr): dx = rand.uniform() - 0.5 # random (centered) offsets dy = rand.uniform() - 0.5 k = exactKernel.getSpatialFunction(1)( x, y) # functional variation of Kernel ... b = (k * sigma1**2 / ((1 - k) * sigma2**2) ) # ... converted double Gaussian's "b" # flux = 80000 - 20*x - 10*(y/float(height))**2 flux = 80000 * (1 + 0.1 * (rand.uniform() - 0.5)) I0 = flux * (1 + b) / (2 * np.pi * (sigma1**2 + b * sigma2**2)) for iy in range(y - self.ksize // 2, y + self.ksize // 2 + 1): if iy < 0 or iy >= self.mi.getHeight(): continue for ix in range(x - self.ksize // 2, x + self.ksize // 2 + 1): if ix < 0 or ix >= self.mi.getWidth(): continue intensity = I0 * psfVal(ix, iy, x + dx, y + dy, sigma1, sigma2, b) Isample = rand.poisson( intensity) if addNoise else intensity self.mi.getImage().set( ix, iy, self.mi.getImage().get(ix, iy) + Isample) self.mi.getVariance().set( ix, iy, self.mi.getVariance().get(ix, iy) + intensity) # bbox = afwGeom.BoxI(afwGeom.PointI(0, 0), afwGeom.ExtentI(width, height)) self.cellSet = afwMath.SpatialCellSet(bbox, 100) self.footprintSet = afwDetection.FootprintSet( self.mi, afwDetection.Threshold(100), "DETECTED") self.catalog = self.measure(self.footprintSet, self.exposure) for source in self.catalog: try: cand = measAlg.makePsfCandidate(source, self.exposure) self.cellSet.insertCandidate(cand) except Exception as e: print(e) continue
def setUp(self): width, height = 110, 301 self.mi = afwImage.MaskedImageF(afwGeom.ExtentI(width, height)) self.mi.set(0) sd = 3 # standard deviation of image self.mi.getVariance().set(sd*sd) self.mi.getMask().addMaskPlane("DETECTED") self.FWHM = 5 self.ksize = 31 # size of desired kernel sigma1 = 1.75 sigma2 = 2*sigma1 self.exposure = afwImage.makeExposure(self.mi) self.exposure.setPsf(measAlg.DoubleGaussianPsf(self.ksize, self.ksize, 1.5*sigma1, 1, 0.1)) crval = afwCoord.makeCoord(afwCoord.ICRS, 0.0*afwGeom.degrees, 0.0*afwGeom.degrees) wcs = afwImage.makeWcs(crval, afwGeom.PointD(0, 0), 1.0, 0, 0, 1.0) self.exposure.setWcs(wcs) ccd = cameraGeom.Ccd(cameraGeom.Id(1)) ccd.addAmp(cameraGeom.Amp(cameraGeom.Id(0), afwGeom.BoxI(afwGeom.PointI(0,0), self.exposure.getDimensions()), afwGeom.BoxI(afwGeom.PointI(0,0), afwGeom.ExtentI(0,0)), afwGeom.BoxI(afwGeom.PointI(0,0), self.exposure.getDimensions()), cameraGeom.ElectronicParams(1.0, 100.0, 65535))) self.exposure.setDetector(ccd) self.exposure.getDetector().setDistortion(None) # # Make a kernel with the exactly correct basis functions. Useful for debugging # basisKernelList = afwMath.KernelList() for sigma in (sigma1, sigma2): basisKernel = afwMath.AnalyticKernel(self.ksize, self.ksize, afwMath.GaussianFunction2D(sigma, sigma)) basisImage = afwImage.ImageD(basisKernel.getDimensions()) basisKernel.computeImage(basisImage, True) basisImage /= np.sum(basisImage.getArray()) if sigma == sigma1: basisImage0 = basisImage else: basisImage -= basisImage0 basisKernelList.append(afwMath.FixedKernel(basisImage)) order = 1 # 1 => up to linear spFunc = afwMath.PolynomialFunction2D(order) exactKernel = afwMath.LinearCombinationKernel(basisKernelList, spFunc) exactKernel.setSpatialParameters([[1.0, 0, 0], [0.0, 0.5*1e-2, 0.2e-2]]) rand = afwMath.Random() # make these tests repeatable by setting seed addNoise = True if addNoise: im = self.mi.getImage() afwMath.randomGaussianImage(im, rand) # N(0, 1) im *= sd # N(0, sd^2) del im xarr, yarr = [], [] for x, y in [(20, 20), (60, 20), (30, 35), (50, 50), (20, 90), (70, 160), (25, 265), (75, 275), (85, 30), (50, 120), (70, 80), (60, 210), (20, 210), ]: xarr.append(x) yarr.append(y) for x, y in zip(xarr, yarr): dx = rand.uniform() - 0.5 # random (centered) offsets dy = rand.uniform() - 0.5 k = exactKernel.getSpatialFunction(1)(x, y) # functional variation of Kernel ... b = (k*sigma1**2/((1 - k)*sigma2**2)) # ... converted double Gaussian's "b" #flux = 80000 - 20*x - 10*(y/float(height))**2 flux = 80000*(1 + 0.1*(rand.uniform() - 0.5)) I0 = flux*(1 + b)/(2*np.pi*(sigma1**2 + b*sigma2**2)) for iy in range(y - self.ksize//2, y + self.ksize//2 + 1): if iy < 0 or iy >= self.mi.getHeight(): continue for ix in range(x - self.ksize//2, x + self.ksize//2 + 1): if ix < 0 or ix >= self.mi.getWidth(): continue I = I0*psfVal(ix, iy, x + dx, y + dy, sigma1, sigma2, b) Isample = rand.poisson(I) if addNoise else I self.mi.getImage().set(ix, iy, self.mi.getImage().get(ix, iy) + Isample) self.mi.getVariance().set(ix, iy, self.mi.getVariance().get(ix, iy) + I) # bbox = afwGeom.BoxI(afwGeom.PointI(0,0), afwGeom.ExtentI(width, height)) self.cellSet = afwMath.SpatialCellSet(bbox, 100) self.footprintSet = afwDetection.FootprintSet(self.mi, afwDetection.Threshold(100), "DETECTED") self.catalog = SpatialModelPsfTestCase.measure(self.footprintSet, self.exposure) for source in self.catalog: try: cand = measAlg.makePsfCandidate(source, self.exposure) self.cellSet.insertCandidate(cand) except Exception, e: print e continue
def setUp(self): width, height = 110, 301 self.mi = afwImage.MaskedImageF(afwGeom.ExtentI(width, height)) self.mi.set(0) sd = 3 # standard deviation of image self.mi.getVariance().set(sd*sd) self.mi.getMask().addMaskPlane("DETECTED") self.FWHM = 5 self.ksize = 31 # size of desired kernel sigma1 = 1.75 sigma2 = 2*sigma1 self.exposure = afwImage.makeExposure(self.mi) self.exposure.setPsf(measAlg.DoubleGaussianPsf(self.ksize, self.ksize, 1.5*sigma1, 1, 0.1)) crval = afwCoord.makeCoord(afwCoord.ICRS, 0.0*afwGeom.degrees, 0.0*afwGeom.degrees) wcs = afwImage.makeWcs(crval, afwGeom.PointD(0, 0), 1.0, 0, 0, 1.0) self.exposure.setWcs(wcs) # # Make a kernel with the exactly correct basis functions. Useful for debugging # basisKernelList = afwMath.KernelList() for sigma in (sigma1, sigma2): basisKernel = afwMath.AnalyticKernel(self.ksize, self.ksize, afwMath.GaussianFunction2D(sigma, sigma)) basisImage = afwImage.ImageD(basisKernel.getDimensions()) basisKernel.computeImage(basisImage, True) basisImage /= np.sum(basisImage.getArray()) if sigma == sigma1: basisImage0 = basisImage else: basisImage -= basisImage0 basisKernelList.append(afwMath.FixedKernel(basisImage)) order = 1 # 1 => up to linear spFunc = afwMath.PolynomialFunction2D(order) exactKernel = afwMath.LinearCombinationKernel(basisKernelList, spFunc) exactKernel.setSpatialParameters([[1.0, 0, 0], [0.0, 0.5*1e-2, 0.2e-2]]) rand = afwMath.Random() # make these tests repeatable by setting seed addNoise = True if addNoise: im = self.mi.getImage() afwMath.randomGaussianImage(im, rand) # N(0, 1) im *= sd # N(0, sd^2) del im xarr, yarr = [], [] for x, y in [(20, 20), (60, 20), (30, 35), (50, 50), (20, 90), (70, 160), (25, 265), (75, 275), (85, 30), (50, 120), (70, 80), (60, 210), (20, 210), ]: xarr.append(x) yarr.append(y) for x, y in zip(xarr, yarr): dx = rand.uniform() - 0.5 # random (centered) offsets dy = rand.uniform() - 0.5 k = exactKernel.getSpatialFunction(1)(x, y) # functional variation of Kernel ... b = (k*sigma1**2/((1 - k)*sigma2**2)) # ... converted double Gaussian's "b" #flux = 80000 - 20*x - 10*(y/float(height))**2 flux = 80000*(1 + 0.1*(rand.uniform() - 0.5)) I0 = flux*(1 + b)/(2*np.pi*(sigma1**2 + b*sigma2**2)) for iy in range(y - self.ksize//2, y + self.ksize//2 + 1): if iy < 0 or iy >= self.mi.getHeight(): continue for ix in range(x - self.ksize//2, x + self.ksize//2 + 1): if ix < 0 or ix >= self.mi.getWidth(): continue I = I0*psfVal(ix, iy, x + dx, y + dy, sigma1, sigma2, b) Isample = rand.poisson(I) if addNoise else I self.mi.getImage().set(ix, iy, self.mi.getImage().get(ix, iy) + Isample) self.mi.getVariance().set(ix, iy, self.mi.getVariance().get(ix, iy) + I) bbox = afwGeom.BoxI(afwGeom.PointI(0,0), afwGeom.ExtentI(width, height)) self.cellSet = afwMath.SpatialCellSet(bbox, 100) self.footprintSet = afwDetection.FootprintSet(self.mi, afwDetection.Threshold(100), "DETECTED") self.catalog = SpatialModelPsfTestCase.measure(self.footprintSet, self.exposure) for source in self.catalog: try: cand = measAlg.makePsfCandidate(source, self.exposure) self.cellSet.insertCandidate(cand) except Exception, e: print e continue
def setUp(self): width, height = 100, 300 self.mi = afwImage.MaskedImageF(afwGeom.ExtentI(width, height)) self.mi.set(0) self.mi.getVariance().set(10) self.mi.getMask().addMaskPlane("DETECTED") self.FWHM = 5 self.ksize = 25 # size of desired kernel self.exposure = afwImage.makeExposure(self.mi) psf = roundTripPsf( 2, algorithms.DoubleGaussianPsf(self.ksize, self.ksize, self.FWHM / (2 * sqrt(2 * log(2))), 1, 0.1)) self.exposure.setPsf(psf) for x, y in [ (20, 20), #(30, 35), (50, 50), (60, 20), (60, 210), (20, 210) ]: flux = 10000 - 0 * x - 10 * y sigma = 3 + 0.01 * (y - self.mi.getHeight() / 2) psf = roundTripPsf( 3, algorithms.DoubleGaussianPsf(self.ksize, self.ksize, sigma, 1, 0.1)) im = psf.computeImage().convertF() im *= flux smi = self.mi.getImage().Factory( self.mi.getImage(), afwGeom.BoxI( afwGeom.PointI(x - self.ksize / 2, y - self.ksize / 2), afwGeom.ExtentI(self.ksize)), afwImage.LOCAL) if False: # Test subtraction with non-centered psfs im = afwMath.offsetImage(im, 0.5, 0.5) smi += im del psf del im del smi psf = roundTripPsf( 4, algorithms.DoubleGaussianPsf(self.ksize, self.ksize, self.FWHM / (2 * sqrt(2 * log(2))), 1, 0.1)) self.cellSet = afwMath.SpatialCellSet( afwGeom.BoxI(afwGeom.PointI(0, 0), afwGeom.ExtentI(width, height)), 100) ds = afwDetection.FootprintSet(self.mi, afwDetection.Threshold(10), "DETECTED") # # Prepare to measure # msConfig = algorithms.SourceMeasurementConfig() msConfig.load("tests/config/MeasureSources.py") schema = afwTable.SourceTable.makeMinimalSchema() measureSources = msConfig.makeMeasureSources(schema) catalog = afwTable.SourceCatalog(schema) msConfig.slots.calibFlux = None msConfig.slots.setupTable(catalog.table) ds.makeSources(catalog) for i, source in enumerate(catalog): measureSources.applyWithPeak(source, self.exposure) self.cellSet.insertCandidate( algorithms.makePsfCandidate(source, self.exposure))