def setDefaults(self): SingleFrameMeasurementConfig.setDefaults(self) self.plugins = [ "base_CircularApertureFlux", "base_PixelFlags", "base_SkyCoord", "base_PsfFlux", "ip_diffim_NaiveDipoleCentroid", "ip_diffim_NaiveDipoleFlux", "ip_diffim_PsfDipoleFlux" ] self.slots.calibFlux = None self.slots.modelFlux = None self.slots.instFlux = None self.slots.shape = None self.slots.centroid = "ip_diffim_NaiveDipoleCentroid" self.doReplaceWithNoise = False
def setDefaults(self): SingleFrameMeasurementConfig.setDefaults(self) self.plugins = ["base_CircularApertureFlux", "base_PixelFlags", "base_SkyCoord", "base_PsfFlux", "ip_diffim_NaiveDipoleCentroid", "ip_diffim_NaiveDipoleFlux", "ip_diffim_PsfDipoleFlux"] self.slots.calibFlux = None self.slots.modelFlux = None self.slots.instFlux = None self.slots.shape = None self.slots.centroid = "ip_diffim_NaiveDipoleCentroid" self.doReplaceWithNoise = False
def test1(self): #exposure = afwImage.ExposureF('mini-v85408556-fr-R23-S11.fits') #exposure = afwImage.ExposureF('../afwdata/ImSim/calexp/v85408556-fr/R23/S11.fits') #bb = afwGeom.Box2I(afwGeom.Point2I(0,0), afwGeom.Point2I(511,511)) #exposure = afwImage.ExposureF('data/goodSeeingCoadd/r/3/113,0/coadd-r-3-113,0.fits', 0, bb) #exposure.writeFits('mini-r-3-113,0.fits') fn = os.path.join(os.path.dirname(__file__), 'data', 'mini-r-3-113,0.fits.gz') print 'Reading image', fn exposure = afwImage.ExposureF(fn) exposure.setPsf(afwDetection.GaussianPsf(15, 15, 3)) schema = afwTable.SourceTable.makeMinimalSchema() idFactory = afwTable.IdFactory.makeSimple() dconf = measAlg.SourceDetectionConfig() dconf.reEstimateBackground = False dconf.includeThresholdMultiplier = 5. mconf = SingleFrameMeasurementConfig() aconf = ANetAstrometryConfig() aconf.forceKnownWcs = True det = measAlg.SourceDetectionTask(schema=schema, config=dconf) meas = SingleFrameMeasurementTask(schema, config=mconf) astrom = ANetAstrometryTask(schema, config=aconf, name='astrom') astrom.log.setThreshold(pexLog.Log.DEBUG) inwcs = exposure.getWcs() print 'inwcs:', inwcs instr = inwcs.getFitsMetadata().toString() print 'inwcs:', instr table = afwTable.SourceTable.make(schema, idFactory) sources = det.makeSourceCatalog(table, exposure, sigma=1).sources meas.measure(exposure, sources) for dosip in [False, True]: aconf.solver.calculateSip = dosip ast = astrom.run(sourceCat=sources, exposure=exposure) outwcs = exposure.getWcs() outstr = outwcs.getFitsMetadata().toString() if dosip is False: self.assertEqual(inwcs, outwcs) self.assertEqual(instr, outstr) print 'inwcs:', instr print 'outwcs:', outstr print len(ast.matches), 'matches' self.assertTrue(len(ast.matches) > 10)
def test1(self): fn = os.path.join(os.path.dirname(__file__), 'data', 'mini-r-3-113,0.fits.gz') print('Reading image', fn) exposure = afwImage.ExposureF(fn) exposure.setPsf(afwDetection.GaussianPsf(15, 15, 3)) schema = afwTable.SourceTable.makeMinimalSchema() idFactory = afwTable.IdFactory.makeSimple() dconf = measAlg.SourceDetectionConfig() dconf.reEstimateBackground = False dconf.includeThresholdMultiplier = 5. mconf = SingleFrameMeasurementConfig() aconf = ANetAstrometryConfig() aconf.forceKnownWcs = True det = measAlg.SourceDetectionTask(schema=schema, config=dconf) meas = SingleFrameMeasurementTask(schema, config=mconf) astrom = ANetAstrometryTask(schema, config=aconf, name='astrom') astrom.log.setLevel(astrom.log.TRACE) inwcs = exposure.getWcs() print('inwcs:', inwcs) instr = inwcs.getFitsMetadata().toString() print('inwcs:', instr) table = afwTable.SourceTable.make(schema, idFactory) sources = det.makeSourceCatalog(table, exposure, sigma=1).sources meas.measure(sources, exposure) for dosip in [False, True]: aconf.solver.calculateSip = dosip ast = astrom.run(sourceCat=sources, exposure=exposure) outwcs = exposure.getWcs() outstr = outwcs.getFitsMetadata().toString() if not dosip: self.assertEqual(inwcs, outwcs) self.assertEqual(instr, outstr) print('inwcs:', instr) print('outwcs:', outstr) print(len(ast.matches), 'matches') self.assertGreater(len(ast.matches), 10)
def getClumps(self, sigma=1.0, display=False): if self._num <= 0: raise RuntimeError("No candidate PSF sources") psfImage = self.getImage() # # Embed psfImage into a larger image so we can smooth when measuring it # width, height = psfImage.getWidth(), psfImage.getHeight() largeImg = psfImage.Factory(afwGeom.ExtentI(2 * width, 2 * height)) largeImg.set(0) bbox = afwGeom.BoxI(afwGeom.PointI(width, height), afwGeom.ExtentI(width, height)) largeImg.assign(psfImage, bbox, afwImage.LOCAL) # # Now measure that image, looking for the highest peak. Start by building an Exposure # msk = afwImage.MaskU(largeImg.getDimensions()) msk.set(0) var = afwImage.ImageF(largeImg.getDimensions()) var.set(1) mpsfImage = afwImage.MaskedImageF(largeImg, msk, var) mpsfImage.setXY0(afwGeom.PointI(-width, -height)) del msk del var exposure = afwImage.makeExposure(mpsfImage) # # Next run an object detector # maxVal = afwMath.makeStatistics(psfImage, afwMath.MAX).getValue() threshold = maxVal - sigma * math.sqrt(maxVal) if threshold <= 0.0: threshold = maxVal threshold = afwDetection.Threshold(threshold) ds = afwDetection.FootprintSet(mpsfImage, threshold, "DETECTED") # # And measure it. This policy isn't the one we use to measure # Sources, it's only used to characterize this PSF histogram # schema = SourceTable.makeMinimalSchema() psfImageConfig = SingleFrameMeasurementConfig() psfImageConfig.slots.centroid = "base_SdssCentroid" psfImageConfig.plugins["base_SdssCentroid"].doFootprintCheck = False psfImageConfig.slots.psfFlux = None # "base_PsfFlux" psfImageConfig.slots.apFlux = "base_CircularApertureFlux_3_0" psfImageConfig.slots.modelFlux = None psfImageConfig.slots.instFlux = None psfImageConfig.slots.calibFlux = None psfImageConfig.slots.shape = "base_SdssShape" # Formerly, this code had centroid.sdss, flux.psf, flux.naive, # flags.pixel, and shape.sdss psfImageConfig.algorithms.names = [ "base_SdssCentroid", "base_CircularApertureFlux", "base_SdssShape" ] psfImageConfig.algorithms["base_CircularApertureFlux"].radii = [3.0] psfImageConfig.validate() task = SingleFrameMeasurementTask(schema, config=psfImageConfig) sourceCat = SourceCatalog(schema) gaussianWidth = 1.5 # Gaussian sigma for detection convolution exposure.setPsf(algorithmsLib.DoubleGaussianPsf(11, 11, gaussianWidth)) ds.makeSources(sourceCat) # # Show us the Histogram # if display: frame = 1 dispImage = mpsfImage.Factory( mpsfImage, afwGeom.BoxI(afwGeom.PointI(width, height), afwGeom.ExtentI(width, height)), afwImage.LOCAL) ds9.mtv(dispImage, title="PSF Selection Image", frame=frame) clumps = list() # List of clumps, to return e = None # thrown exception IzzMin = 1.0 # Minimum value for second moments IzzMax = ( self._xSize / 8.0)**2 # Max value ... clump radius should be < clumpImgSize/8 apFluxes = [] task.run( sourceCat, exposure) # notes that this is backwards for the new framework for i, source in enumerate(sourceCat): if source.getCentroidFlag(): continue x, y = source.getX(), source.getY() apFluxes.append(source.getApFlux()) val = mpsfImage.getImage().get(int(x) + width, int(y) + height) psfClumpIxx = source.getIxx() psfClumpIxy = source.getIxy() psfClumpIyy = source.getIyy() if display: if i == 0: ds9.pan(x, y, frame=frame) ds9.dot("+", x, y, ctype=ds9.YELLOW, frame=frame) ds9.dot("@:%g,%g,%g" % (psfClumpIxx, psfClumpIxy, psfClumpIyy), x, y, ctype=ds9.YELLOW, frame=frame) if psfClumpIxx < IzzMin or psfClumpIyy < IzzMin: psfClumpIxx = max(psfClumpIxx, IzzMin) psfClumpIyy = max(psfClumpIyy, IzzMin) if display: ds9.dot("@:%g,%g,%g" % (psfClumpIxx, psfClumpIxy, psfClumpIyy), x, y, ctype=ds9.RED, frame=frame) det = psfClumpIxx * psfClumpIyy - psfClumpIxy * psfClumpIxy try: a, b, c = psfClumpIyy / det, -psfClumpIxy / det, psfClumpIxx / det except ZeroDivisionError: a, b, c = 1e4, 0, 1e4 clumps.append( Clump(peak=val, x=x, y=y, a=a, b=b, c=c, ixx=psfClumpIxx, ixy=psfClumpIxy, iyy=psfClumpIyy)) if len(clumps) == 0: msg = "Failed to determine center of PSF clump" if e: msg += ": %s" % e raise RuntimeError(msg) # if it's all we got return it if len(clumps) == 1: return clumps # which clump is the best? # if we've undistorted the moments, stars should only have 1 clump # use the apFlux from the clump measurement, and take the highest # ... this clump has more psf star candidate neighbours than the others. # get rid of any that are huge, and thus poorly defined goodClumps = [] for clump in clumps: if clump.ixx < IzzMax and clump.iyy < IzzMax: goodClumps.append(clump) # if culling > IzzMax cost us all clumps, we'll have to take what we have if len(goodClumps) == 0: goodClumps = clumps # use the 'brightest' clump iBestClump = numpy.argsort(apFluxes)[0] clumps = [clumps[iBestClump]] return clumps
def getClumps(self, sigma=1.0, display=False): if self._num <= 0: raise RuntimeError("No candidate PSF sources") psfImage = self.getImage() # # Embed psfImage into a larger image so we can smooth when measuring it # width, height = psfImage.getWidth(), psfImage.getHeight() largeImg = psfImage.Factory(afwGeom.ExtentI(2*width, 2*height)) largeImg.set(0) bbox = afwGeom.BoxI(afwGeom.PointI(width, height), afwGeom.ExtentI(width, height)) largeImg.assign(psfImage, bbox, afwImage.LOCAL) # # Now measure that image, looking for the highest peak. Start by building an Exposure # msk = afwImage.MaskU(largeImg.getDimensions()) msk.set(0) var = afwImage.ImageF(largeImg.getDimensions()) var.set(1) mpsfImage = afwImage.MaskedImageF(largeImg, msk, var) mpsfImage.setXY0(afwGeom.PointI(-width, -height)) del msk del var exposure = afwImage.makeExposure(mpsfImage) # # Next run an object detector # maxVal = afwMath.makeStatistics(psfImage, afwMath.MAX).getValue() threshold = maxVal - sigma*math.sqrt(maxVal) if threshold <= 0.0: threshold = maxVal threshold = afwDetection.Threshold(threshold) ds = afwDetection.FootprintSet(mpsfImage, threshold, "DETECTED") # # And measure it. This policy isn't the one we use to measure # Sources, it's only used to characterize this PSF histogram # schema = SourceTable.makeMinimalSchema() psfImageConfig = SingleFrameMeasurementConfig() psfImageConfig.doApplyApCorr = "no" psfImageConfig.slots.centroid = "base_SdssCentroid" psfImageConfig.slots.psfFlux = None #"base_PsfFlux" psfImageConfig.slots.apFlux = "base_CircularApertureFlux_3_0" psfImageConfig.slots.modelFlux = None psfImageConfig.slots.instFlux = None psfImageConfig.slots.calibFlux = None psfImageConfig.slots.shape = "base_SdssShape" # Formerly, this code had centroid.sdss, flux.psf, flux.naive, # flags.pixel, and shape.sdss psfImageConfig.algorithms.names = ["base_SdssCentroid", "base_CircularApertureFlux", "base_SdssShape"] psfImageConfig.algorithms["base_CircularApertureFlux"].radii = [3.0] psfImageConfig.validate() task = SingleFrameMeasurementTask(schema, config=psfImageConfig) sourceCat = SourceCatalog(schema) gaussianWidth = 1.5 # Gaussian sigma for detection convolution exposure.setPsf(algorithmsLib.DoubleGaussianPsf(11, 11, gaussianWidth)) ds.makeSources(sourceCat) # # Show us the Histogram # if display: frame = 1 dispImage = mpsfImage.Factory(mpsfImage, afwGeom.BoxI(afwGeom.PointI(width, height), afwGeom.ExtentI(width, height)), afwImage.LOCAL) ds9.mtv(dispImage,title="PSF Selection Image", frame=frame) clumps = list() # List of clumps, to return e = None # thrown exception IzzMin = 1.0 # Minimum value for second moments IzzMax = (self._xSize/8.0)**2 # Max value ... clump r < clumpImgSize/8 # diameter should be < 1/4 clumpImgSize apFluxes = [] task.run(exposure, sourceCat) # notes that this is backwards for the new framework for i, source in enumerate(sourceCat): if source.getCentroidFlag(): continue x, y = source.getX(), source.getY() apFluxes.append(source.getApFlux()) val = mpsfImage.getImage().get(int(x) + width, int(y) + height) psfClumpIxx = source.getIxx() psfClumpIxy = source.getIxy() psfClumpIyy = source.getIyy() if display: if i == 0: ds9.pan(x, y, frame=frame) ds9.dot("+", x, y, ctype=ds9.YELLOW, frame=frame) ds9.dot("@:%g,%g,%g" % (psfClumpIxx, psfClumpIxy, psfClumpIyy), x, y, ctype=ds9.YELLOW, frame=frame) if psfClumpIxx < IzzMin or psfClumpIyy < IzzMin: psfClumpIxx = max(psfClumpIxx, IzzMin) psfClumpIyy = max(psfClumpIyy, IzzMin) if display: ds9.dot("@:%g,%g,%g" % (psfClumpIxx, psfClumpIxy, psfClumpIyy), x, y, ctype=ds9.RED, frame=frame) det = psfClumpIxx*psfClumpIyy - psfClumpIxy*psfClumpIxy try: a, b, c = psfClumpIyy/det, -psfClumpIxy/det, psfClumpIxx/det except ZeroDivisionError: a, b, c = 1e4, 0, 1e4 clumps.append(Clump(peak=val, x=x, y=y, a=a, b=b, c=c, ixx=psfClumpIxx, ixy=psfClumpIxy, iyy=psfClumpIyy)) if len(clumps) == 0: msg = "Failed to determine center of PSF clump" if e: msg += ": %s" % e raise RuntimeError(msg) # if it's all we got return it if len(clumps) == 1: return clumps # which clump is the best? # if we've undistorted the moments, stars should only have 1 clump # use the apFlux from the clump measurement, and take the highest # ... this clump has more psf star candidate neighbours than the others. # get rid of any that are huge, and thus poorly defined goodClumps = [] for clump in clumps: if clump.ixx < IzzMax and clump.iyy < IzzMax: goodClumps.append(clump) # if culling > IzzMax cost us all clumps, we'll have to take what we have if len(goodClumps) == 0: goodClumps = clumps # use the 'brightest' clump iBestClump = numpy.argsort(apFluxes)[0] clumps = [clumps[iBestClump]] return clumps
def detect_and_deblend(*, exp, log): log = lsst.log.Log.getLogger("LSSTMEDSifier") thresh = 5.0 loglevel = 'INFO' # This schema holds all the measurements that will be run within the # stack It needs to be constructed before running anything and passed # to algorithms that make additional measurents. schema = afw_table.SourceTable.makeMinimalSchema() # Setup algorithms to run meas_config = SingleFrameMeasurementConfig() meas_config.plugins.names = [ "base_SdssCentroid", "base_PsfFlux", "base_SkyCoord", # "modelfit_ShapeletPsfApprox", "modelfit_DoubleShapeletPsfApprox", "modelfit_CModel", # "base_SdssShape", # "base_LocalBackground", ] # set these slots to none because we aren't running these algorithms meas_config.slots.apFlux = None meas_config.slots.gaussianFlux = None meas_config.slots.calibFlux = None meas_config.slots.modelFlux = None # goes with SdssShape above meas_config.slots.shape = None # fix odd issue where it things things are near the edge meas_config.plugins['base_SdssCentroid'].binmax = 1 meas_task = SingleFrameMeasurementTask( config=meas_config, schema=schema, ) # setup detection config detection_config = SourceDetectionConfig() detection_config.reEstimateBackground = False detection_config.thresholdValue = thresh detection_task = SourceDetectionTask(config=detection_config) detection_task.log.setLevel(getattr(lsst.log, loglevel)) deblend_config = SourceDeblendConfig() deblend_task = SourceDeblendTask(config=deblend_config, schema=schema) deblend_task.log.setLevel(getattr(lsst.log, loglevel)) # Detect objects table = afw_table.SourceTable.make(schema) result = detection_task.run(table, exp) sources = result.sources # run the deblender deblend_task.run(exp, sources) # Run on deblended images noise_replacer_config = NoiseReplacerConfig() footprints = { record.getId(): (record.getParent(), record.getFootprint()) for record in result.sources } # This constructor will replace all detected pixels with noise in the # image replacer = NoiseReplacer( noise_replacer_config, exposure=exp, footprints=footprints, ) nbad = 0 ntry = 0 kept_sources = [] for record in result.sources: # Skip parent objects where all children are inserted if record.get('deblend_nChild') != 0: continue ntry += 1 # This will insert a single source into the image replacer.insertSource(record.getId()) # Get the peak as before # peak = record.getFootprint().getPeaks()[0] # The bounding box will be for the parent object # bbox = record.getFootprint().getBBox() meas_task.callMeasure(record, exp) # Remove object replacer.removeSource(record.getId()) if record.getCentroidFlag(): nbad += 1 kept_sources.append(record) # Insert all objects back into image replacer.end() if ntry > 0: log.debug('nbad center: %d frac: %d' % (nbad, nbad / ntry)) nkeep = len(kept_sources) ntot = len(result.sources) log.debug('kept %d/%d non parents' % (nkeep, ntot)) return kept_sources