def main(expName, config, display=False): exp = afwImage.ExposureF(expName) # Assume exposure is bias-subtracted, CCD-assembled, has variance and mask plane. # If not, put code here to fix what's lacking. bg, bgSubExp = estimateBackground(exp, config.background, subtract=True) detection = SourceDetectionTask(config=config.detection) detResults = detection.detectFootprints(bgSubExp, sigma=config.psfSigma) fpSet = detResults.positive print "Found %d positive footprints" % len(fpSet.getFootprints()) if display: print "Displaying results..." import lsst.afw.display.ds9 as ds9 frame = 1 ds9.mtv(bgSubExp, frame=frame, title="Background-subtracted exposure") with ds9.Buffering(): for fp in fpSet.getFootprints(): peakList = fp.getPeaks() for p in peakList: ds9.dot("x", p.getFx(), p.getFy(), frame=frame) # XXX Work with footprints here psf = measAlg.SingleGaussianPsf(config.psfSize, config.psfSize, config.psfSigma) exp.setPsf(psf) cosmicray(exp, config.cosmicray, display=display)
def maskAndInterpDefect(self, ccdExposure, defectBaseList): """Mask defects and edges, interpolate over defects in place Mask defect pixels using mask plane BAD and interpolate over them. Mask the potentially problematic glowing edges as SUSPECT. Parameters ---------- ccdExposure : `lsst.afw.image.Exposure` exposure to process defectBaseList : `list` a list of defects to mask and interpolate Returns ------- ccdExposure : `lsst.afw.image.Exposure` exposure corrected in place """ IsrTask.maskAndInterpDefect(self, ccdExposure, defectBaseList) maskedImage = ccdExposure.getMaskedImage() goodBBox = maskedImage.getBBox() # This makes a bbox numEdgeSuspect pixels smaller than the image on each side goodBBox.grow(-self.config.numEdgeSuspect) # Mask pixels outside goodBBox as SUSPECT SourceDetectionTask.setEdgeBits( maskedImage, goodBBox, maskedImage.getMask().getPlaneBitMask("SUSPECT"))
def run(display=False): exposure = loadData() schema = afwTable.SourceTable.makeMinimalSchema() # # Create the detection and measurement Tasks # config = SourceDetectionTask.ConfigClass() config.reEstimateBackground = False detectionTask = SourceDetectionTask(config=config, schema=schema) config = SingleFrameMeasurementTask.ConfigClass() # Use the minimum set of plugins required. config.plugins.names.clear() for plugin in [ "base_SdssCentroid", "base_SdssShape", "base_CircularApertureFlux", "base_PixelFlags" ]: config.plugins.names.add(plugin) config.plugins["base_CircularApertureFlux"].radii = [7.0] # Use of the PSF flux is hardcoded in secondMomentStarSelector config.slots.psfFlux = "base_CircularApertureFlux_7_0" measureTask = SingleFrameMeasurementTask(schema, config=config) # # Create the measurePsf task # config = MeasurePsfTask.ConfigClass() psfDeterminer = config.psfDeterminer.apply() psfDeterminer.config.sizeCellX = 128 psfDeterminer.config.sizeCellY = 128 psfDeterminer.config.spatialOrder = 1 psfDeterminer.config.nEigenComponents = 3 measurePsfTask = MeasurePsfTask(config=config, schema=schema) # # Create the output table # tab = afwTable.SourceTable.make(schema) # # Process the data # sources = detectionTask.run(tab, exposure, sigma=2).sources measureTask.measure(exposure, sources) result = measurePsfTask.run(exposure, sources) psf = result.psf cellSet = result.cellSet if display: # display on ds9 (see also --debug argparse option) frame = 1 ds9.mtv(exposure, frame=frame) with ds9.Buffering(): for s in sources: xy = s.getCentroid() ds9.dot('+', *xy, frame=frame) if s.get("calib.psf.candidate"): ds9.dot('x', *xy, ctype=ds9.YELLOW, frame=frame) if s.get("calib.psf.used"): ds9.dot('o', *xy, size=4, ctype=ds9.RED, frame=frame)
def flatCorrection(self, exposure, flatExposure): """Apply flat correction in place DECam flat products have been trimmed and are smaller than the raw exposure. The size of edge trim is computed based on the dimensions of the input data. Only process the inner part of the raw exposure, and mask the outer pixels as EDGE. @param[in,out] exposure: exposure to process @param[in] flatExposure: flatfield exposure """ nEdge = _computeEdgeSize(exposure, flatExposure) if nEdge > 0: rawMaskedImage = exposure.getMaskedImage()[nEdge:-nEdge, nEdge:-nEdge] else: rawMaskedImage = exposure.getMaskedImage() flatCorrection( rawMaskedImage, flatExposure.getMaskedImage(), self.config.flatScalingType, self.config.flatUserScale ) # Mask the unprocessed edge pixels as EDGE SourceDetectionTask.setEdgeBits( exposure.getMaskedImage(), rawMaskedImage.getBBox(), exposure.getMaskedImage().getMask().getPlaneBitMask("EDGE"), )
def run(display=False): exposure = loadData() schema = afwTable.SourceTable.makeMinimalSchema() # # Create the detection and measurement Tasks # config = SourceDetectionTask.ConfigClass() config.reEstimateBackground = False detectionTask = SourceDetectionTask(config=config, schema=schema) config = SingleFrameMeasurementTask.ConfigClass() # Use the minimum set of plugins required. config.plugins.names.clear() for plugin in ["base_SdssCentroid", "base_SdssShape", "base_CircularApertureFlux", "base_PixelFlags"]: config.plugins.names.add(plugin) config.plugins["base_CircularApertureFlux"].radii = [7.0] config.slots.psfFlux = "base_CircularApertureFlux_7_0" # Use of the PSF flux is hardcoded in secondMomentStarSelector measureTask = SingleFrameMeasurementTask(schema, config=config) # # Create the measurePsf task # config = MeasurePsfTask.ConfigClass() psfDeterminer = config.psfDeterminer.apply() psfDeterminer.config.sizeCellX = 128 psfDeterminer.config.sizeCellY = 128 psfDeterminer.config.spatialOrder = 1 psfDeterminer.config.nEigenComponents = 3 measurePsfTask = MeasurePsfTask(config=config, schema=schema) # # Create the output table # tab = afwTable.SourceTable.make(schema) # # Process the data # sources = detectionTask.run(tab, exposure, sigma=2).sources measureTask.measure(exposure, sources) result = measurePsfTask.run(exposure, sources) psf = result.psf cellSet = result.cellSet if display: # display on ds9 (see also --debug argparse option) frame = 1 ds9.mtv(exposure, frame=frame) with ds9.Buffering(): for s in sources: xy = s.getCentroid() ds9.dot('+', *xy, frame=frame) if s.get("calib.psf.candidate"): ds9.dot('x', *xy, ctype=ds9.YELLOW, frame=frame) if s.get("calib.psf.used"): ds9.dot('o', *xy, size=4, ctype=ds9.RED, frame=frame)
def run(display=False): exposure = loadData() schema = afwTable.SourceTable.makeMinimalSchema() # # Create the detection task # config = SourceDetectionTask.ConfigClass() config.thresholdPolarity = "both" config.background.isNanSafe = True config.thresholdValue = 3 detectionTask = SourceDetectionTask(config=config, schema=schema) # # And the measurement Task # config = SingleFrameMeasurementTask.ConfigClass() config.algorithms.names = ["base_SdssCentroid", "base_SdssShape", "base_CircularApertureFlux"] config.algorithms["base_CircularApertureFlux"].radii = [1, 2, 4, 8, 12, 16] # pixels config.slots.gaussianFlux = None config.slots.modelFlux = None config.slots.psfFlux = None algMetadata = dafBase.PropertyList() measureTask = SingleFrameMeasurementTask(schema, algMetadata=algMetadata, config=config) radii = algMetadata.getArray("base_CircularApertureFlux_radii") # # Create the output table # tab = afwTable.SourceTable.make(schema) # # Process the data # result = detectionTask.run(tab, exposure) sources = result.sources print("Found %d sources (%d +ve, %d -ve)" % (len(sources), result.fpSets.numPos, result.fpSets.numNeg)) measureTask.run(sources, exposure) if display: # display image (see also --debug argparse option) afwDisplay.setDefaultMaskTransparency(75) frame = 1 disp = afwDisplay.Display(frame=frame) disp.mtv(exposure) with disp.Buffering(): for s in sources: xy = s.getCentroid() disp.dot('+', *xy, ctype=afwDisplay.CYAN if s.get("flags_negative") else afwDisplay.GREEN) disp.dot(s.getShape(), *xy, ctype=afwDisplay.RED) for radius in radii: disp.dot('o', *xy, size=radius, ctype=afwDisplay.YELLOW)
def run(display=False): exposure = loadData() schema = afwTable.SourceTable.makeMinimalSchema() # # Create the detection task # config = SourceDetectionTask.ConfigClass() config.thresholdPolarity = "both" config.background.isNanSafe = True config.thresholdValue = 3 detectionTask = SourceDetectionTask(config=config, schema=schema) # # And the measurement Task # config = SingleFrameMeasurementTask.ConfigClass() config.plugins.names.clear() for plugin in ["base_SdssCentroid", "base_SdssShape", "base_CircularApertureFlux", "base_GaussianFlux"]: config.plugins.names.add(plugin) config.slots.psfFlux = None config.slots.apFlux = "base_CircularApertureFlux_3_0" measureTask = SingleFrameMeasurementTask(schema, config=config) # # Print the schema the configuration produced # print(schema) # # Create the output table # tab = afwTable.SourceTable.make(schema) # # Process the data # result = detectionTask.run(tab, exposure) sources = result.sources print("Found %d sources (%d +ve, %d -ve)" % (len(sources), result.fpSets.numPos, result.fpSets.numNeg)) measureTask.run(sources, exposure) if display: # display image (see also --debug argparse option) frame = 1 disp = afwDisplay.Display(frame=frame) disp.mtv(exposure) with disp.Buffering(): for s in sources: xy = s.getCentroid() disp.dot('+', *xy, ctype=afwDisplay.CYAN if s.get("flags_negative") else afwDisplay.GREEN) disp.dot(s.getShape(), *xy, ctype=afwDisplay.RED) disp.dot('o', *xy, size=config.plugins["base_CircularApertureFlux"].radii[0], ctype=afwDisplay.YELLOW)
def run(display=False): exposure = loadData() schema = afwTable.SourceTable.makeMinimalSchema() # # Create the detection task # config = SourceDetectionTask.ConfigClass() config.thresholdPolarity = "both" config.background.isNanSafe = True config.thresholdValue = 3 detectionTask = SourceDetectionTask(config=config, schema=schema) # # And the measurement Task # config = SingleFrameMeasurementTask.ConfigClass() config.algorithms.names = ["base_SdssCentroid", "base_SdssShape", "base_CircularApertureFlux"] config.algorithms["base_CircularApertureFlux"].radii = [1, 2, 4, 8, 16] # pixels config.slots.instFlux = None config.slots.modelFlux = None config.slots.psfFlux = None algMetadata = dafBase.PropertyList() measureTask = SingleFrameMeasurementTask(schema, algMetadata=algMetadata, config=config) radii = algMetadata.get("base_CircularApertureFlux_radii") # # Create the output table # tab = afwTable.SourceTable.make(schema) # # Process the data # result = detectionTask.run(tab, exposure) sources = result.sources print("Found %d sources (%d +ve, %d -ve)" % (len(sources), result.fpSets.numPos, result.fpSets.numNeg)) measureTask.run(sources, exposure) if display: # display on ds9 (see also --debug argparse option) frame = 1 ds9.mtv(exposure, frame=frame) with ds9.Buffering(): for s in sources: xy = s.getCentroid() ds9.dot('+', *xy, ctype=ds9.CYAN if s.get("flags.negative") else ds9.GREEN, frame=frame) ds9.dot(s.getShape(), *xy, ctype=ds9.RED, frame=frame) for i in range(s.get("flux.aperture.nProfile")): ds9.dot('o', *xy, size=radii[i], ctype=ds9.YELLOW, frame=frame)
def maskAndInterpDefect(self, ccdExposure, defectBaseList): """Mask defects and edges, interpolate over defects in place Mask defect pixels using mask plane BAD and interpolate over them. Mask the potentially problematic glowing edges as SUSPECT. @param[in,out] ccdExposure: exposure to process @param[in] defectBaseList: a list of defects to mask and interpolate """ IsrTask.maskAndInterpDefect(self, ccdExposure, defectBaseList) maskedImage = ccdExposure.getMaskedImage() goodBBox = maskedImage.getBBox() # This makes a bbox numEdgeSuspect pixels smaller than the image on each side goodBBox.grow(-self.config.numEdgeSuspect) # Mask pixels outside goodBBox as SUSPECT SourceDetectionTask.setEdgeBits(maskedImage, goodBBox, maskedImage.getMask().getPlaneBitMask("SUSPECT"))
def trimToMatchCalibBBox(rawMaskedImage, calibMaskedImage): """Compute number of edge trim pixels to match the calibration data. Use the dimension difference between the raw exposure and the calibration exposure to compute the edge trim pixels. This trim is applied symmetrically, with the same number of pixels masked on each side. Parameters ---------- rawMaskedImage : `lsst.afw.image.MaskedImage` Image to trim. calibMaskedImage : `lsst.afw.image.MaskedImage` Calibration image to draw new bounding box from. Returns ------- replacementMaskedImage : `lsst.afw.image.MaskedImage` ``rawMaskedImage`` trimmed to the appropriate size Raises ------ RuntimeError Rasied if ``rawMaskedImage`` cannot be symmetrically trimmed to match ``calibMaskedImage``. """ nx, ny = rawMaskedImage.getBBox().getDimensions( ) - calibMaskedImage.getBBox().getDimensions() if nx != ny: raise RuntimeError( "Raw and calib maskedImages are trimmed differently in X and Y.") if nx % 2 != 0: raise RuntimeError("Calibration maskedImage is trimmed unevenly in X.") if nx < 0: raise RuntimeError("Calibration maskedImage is larger than raw data.") nEdge = nx // 2 if nEdge > 0: replacementMaskedImage = rawMaskedImage[nEdge:-nEdge, nEdge:-nEdge, afwImage.LOCAL] SourceDetectionTask.setEdgeBits( rawMaskedImage, replacementMaskedImage.getBBox(), rawMaskedImage.getMask().getPlaneBitMask("EDGE")) else: replacementMaskedImage = rawMaskedImage return replacementMaskedImage
def run(args): exposure = loadData(args.image) if args.debug: ds9.mtv(exposure, frame=1) schema = afwTable.SourceTable.makeMinimalSchema() # Create the detection task config = SourceDetectionTask.ConfigClass() config.thresholdPolarity = "both" config.background.isNanSafe = True config.thresholdValue = 3 detectionTask = SourceDetectionTask(config=config, schema=schema) # And the measurement Task config = DipoleMeasurementTask.ConfigClass() config.plugins.names.remove('base_SkyCoord') algMetadata = dafBase.PropertyList() measureTask = DipoleMeasurementTask(schema, algMetadata, config=config) # Create the output table tab = afwTable.SourceTable.make(schema) # Process the data results = detectionTask.run(tab, exposure) # Merge the positve and negative sources fpSet = results.fpSets.positive growFootprint = 2 fpSet.merge(results.fpSets.negative, growFootprint, growFootprint, False) diaSources = afwTable.SourceCatalog(tab) fpSet.makeSources(diaSources) print("Merged %s Sources into %d diaSources (from %d +ve, %d -ve)" % (len(results.sources), len(diaSources), results.fpSets.numPos, results.fpSets.numNeg)) measureTask.run(diaSources, exposure) # Display dipoles if debug enabled if args.debug: dpa = DipoleAnalysis() dpa.displayDipoles(exposure, diaSources)
def trimToMatchCalibBBox(rawMaskedImage, calibMaskedImage): """Compute number of edge trim pixels to match the calibration data. Use the dimension difference between the raw exposure and the calibration exposure to compute the edge trim pixels. This trim is applied symmetrically, with the same number of pixels masked on each side. Parameters ---------- rawMaskedImage : `lsst.afw.image.MaskedImage` Image to trim. calibMaskedImage : `lsst.afw.image.MaskedImage` Calibration image to draw new bounding box from. Returns ------- replacementMaskedImage : `lsst.afw.image.MaskedImage` ``rawMaskedImage`` trimmed to the appropriate size Raises ------ RuntimeError Rasied if ``rawMaskedImage`` cannot be symmetrically trimmed to match ``calibMaskedImage``. """ nx, ny = rawMaskedImage.getBBox().getDimensions() - calibMaskedImage.getBBox().getDimensions() if nx != ny: raise RuntimeError("Raw and calib maskedImages are trimmed differently in X and Y.") if nx % 2 != 0: raise RuntimeError("Calibration maskedImage is trimmed unevenly in X.") if nx < 0: raise RuntimeError("Calibration maskedImage is larger than raw data.") nEdge = nx//2 if nEdge > 0: replacementMaskedImage = rawMaskedImage[nEdge:-nEdge, nEdge:-nEdge, afwImage.LOCAL] SourceDetectionTask.setEdgeBits( rawMaskedImage, replacementMaskedImage.getBBox(), rawMaskedImage.getMask().getPlaneBitMask("EDGE") ) else: replacementMaskedImage = rawMaskedImage return replacementMaskedImage
def testMismatchedSchema(self): schema = afwTable.SourceTable.makeMinimalSchema() # Create the detection task and process the data detectionTask = SourceDetectionTask(schema=schema) table = afwTable.SourceTable.make(schema) result = detectionTask.run(table, self.calexp) self.assertEqual(schema, result.sources.getSchema()) # SourceDeblendTask modifies the schema in-place at construction # and add extra keys to it deblendTask = SourceDeblendTask(schema) self.assertNotEqual(schema, result.sources.getSchema()) # As the deblendTask has a different schema than the original schema # of the detectionTask, the assert should fail and stop running with self.assertRaises(AssertionError): deblendTask.run(self.calexp, result.sources)
def testInclude(self): schema = afwTable.SourceTable.makeMinimalSchema() # Create the detection task config = SourceDetectionTask.ConfigClass() config.reEstimateBackground = False # Turn off so that background does not change from orig detectionTask = SourceDetectionTask(config=config, schema=schema) # Create the deblender Task debConfig = measDeb.SourceDeblendConfig() debTask = measDeb.SourceDeblendTask(schema, config=debConfig) # Create the measurement Task config = SingleFrameMeasurementTask.ConfigClass() measureTask = SingleFrameMeasurementTask(schema, config=config) # Create the output table tab = afwTable.SourceTable.make(schema) # Process the data result = detectionTask.run(tab, self.calexp) sources = result.sources # Run the deblender debTask.run(self.calexp, sources) # Run the measurement task: this where the replace-with-noise occurs measureTask.run(sources, self.calexp) plotOnFailure = False if display: plotOnFailure = True # The relative differences ranged from 0.02 to ~2. This rtol is somewhat # random, but will certainly catch the pathology if it occurs. self.assertFloatsAlmostEqual( self.calexpOrig.getMaskedImage().getImage().getArray(), self.calexp.getMaskedImage().getImage().getArray(), rtol=1E-3, printFailures=False, plotOnFailure=plotOnFailure)
def biasCorrection(self, exposure, biasExposure): """Apply bias correction in place DECam bias products have been trimmed and are smaller than the raw exposure. The size of edge trim is computed based on the dimensions of the input data. Only process the inner part of the raw exposure, and mask the outer pixels as EDGE. @param[in,out] exposure: exposure to process @param[in] biasExposure: bias exposure """ nEdge = _computeEdgeSize(exposure, biasExposure) if nEdge > 0: rawMaskedImage = exposure.getMaskedImage()[nEdge:-nEdge, nEdge:-nEdge] else: rawMaskedImage = exposure.getMaskedImage() biasCorrection(rawMaskedImage, biasExposure.getMaskedImage()) # Mask the unprocessed edge pixels as EDGE SourceDetectionTask.setEdgeBits( exposure.getMaskedImage(), rawMaskedImage.getBBox(), exposure.getMaskedImage().getMask().getPlaneBitMask("EDGE"))
def testInclude(self): schema = afwTable.SourceTable.makeMinimalSchema() # Create the detection task config = SourceDetectionTask.ConfigClass() config.reEstimateBackground = False # Turn off so that background does not change from orig detectionTask = SourceDetectionTask(config=config, schema=schema) # Create the deblender Task debConfig = measDeb.SourceDeblendConfig() debTask = measDeb.SourceDeblendTask(schema, config=debConfig) # Create the measurement Task config = SingleFrameMeasurementTask.ConfigClass() measureTask = SingleFrameMeasurementTask(schema, config=config) # Create the output table tab = afwTable.SourceTable.make(schema) # Process the data result = detectionTask.run(tab, self.calexp) sources = result.sources # Run the deblender debTask.run(self.calexp, sources) # Run the measurement task: this where the replace-with-noise occurs measureTask.run(sources, self.calexp) plotOnFailure = False if display: plotOnFailure = True # The relative differences ranged from 0.02 to ~2. This rtol is somewhat # random, but will certainly catch the pathology if it occurs. self.assertFloatsAlmostEqual(self.calexpOrig.getMaskedImage().getImage().getArray(), self.calexp.getMaskedImage().getImage().getArray(), rtol=1E-3, printFailures=False, plotOnFailure=plotOnFailure)
def flatCorrection(self, exposure, flatExposure): """Apply flat correction in place DECam flat products have been trimmed and are smaller than the raw exposure. The size of edge trim is computed based on the dimensions of the input data. Only process the inner part of the raw exposure, and mask the outer pixels as EDGE. @param[in,out] exposure: exposure to process @param[in] flatExposure: flatfield exposure """ nEdge = _computeEdgeSize(exposure, flatExposure) if nEdge > 0: rawMaskedImage = exposure.getMaskedImage()[nEdge:-nEdge, nEdge:-nEdge] else: rawMaskedImage = exposure.getMaskedImage() flatCorrection(rawMaskedImage, flatExposure.getMaskedImage(), self.config.flatScalingType, self.config.flatUserScale) # Mask the unprocessed edge pixels as EDGE SourceDetectionTask.setEdgeBits( exposure.getMaskedImage(), rawMaskedImage.getBBox(), exposure.getMaskedImage().getMask().getPlaneBitMask("EDGE"))
def biasCorrection(self, exposure, biasExposure): """Apply bias correction in place DECam bias products have been trimmed and are smaller than the raw exposure. The size of edge trim is computed based on the dimensions of the input data. Only process the inner part of the raw exposure, and mask the outer pixels as EDGE. @param[in,out] exposure: exposure to process @param[in] biasExposure: bias exposure """ nEdge = _computeEdgeSize(exposure, biasExposure) if nEdge > 0: rawMaskedImage = exposure.getMaskedImage()[nEdge:-nEdge, nEdge:-nEdge] else: rawMaskedImage = exposure.getMaskedImage() biasCorrection(rawMaskedImage, biasExposure.getMaskedImage()) # Mask the unprocessed edge pixels as EDGE SourceDetectionTask.setEdgeBits( exposure.getMaskedImage(), rawMaskedImage.getBBox(), exposure.getMaskedImage().getMask().getPlaneBitMask("EDGE"), )
def detectAndMeasureWithDM(display): ### what file are you going to look at? This should be in fits format. ### The test image included in this example contains stars and galaxies in the center only. imagefile = "test_image_stars.fits" ### open the file in the stack format exposure = afwImage.ExposureF(imagefile) im = exposure.getMaskedImage().getImage() if display: ### display the original image frame = 1 ds9.mtv(exposure, frame=frame, title="Original Image"); frame+=1 ### Set up the schema schema = afwTable.SourceTable.makeMinimalSchema() schema.setVersion(0) ### Create the detection task config = SourceDetectionTask.ConfigClass() config.reEstimateBackground = False detectionTask = SourceDetectionTask(config=config, schema=schema) ### create the measurement task config = SourceMeasurementTask.ConfigClass() ### algMetadata is used to return info on the active algorithms algMetadata = dafBase.PropertyList() ### Set up which algorithms you want to run config.algorithms.names.clear() for alg in ["shape.sdss", "flux.sinc", "flux.aperture", "flux.gaussian", "flux.psf"]: config.algorithms.names.add(alg) config.algorithms["flux.aperture"].radii = [1, 2, 4, 8, 16] # pixels ### Need to un-set some of the slots if we're not using them. ### If you include them in the alg list above, then you don't ###need to unset these quantities. #config.slots.instFlux = None # flux.gaussian #config.slots.modelFlux = None # flux.gaussian #config.slots.psfFlux = None # flux.psf measureTask = SourceMeasurementTask(schema, algMetadata, config=config) ### Create the output table tab = afwTable.SourceTable.make(schema) ### uncomments this to see what algorithms have gone into the schema #print schema ### Process the data print "*** running detection task..." sources = detectionTask.run(tab, exposure, sigma=5).sources print "*** running measure task..." measureTask.measure(exposure, sources) if display: ### Plot the results ds9.mtv(exposure, frame=frame, title="Measured Sources") with ds9.Buffering(): for s in sources: xy = s.getCentroid() ds9.dot('+', *xy, ctype=ds9.CYAN if s.get("flags.negative") else ds9.GREEN, frame=frame) ds9.dot(s.getShape(), *xy, ctype=ds9.RED, frame=frame) print sources[0] ### Look at some of the information measured. ### TODO: add more useful quantities to this. centroids = [] for i in range(len(sources)): record = sources[i] centroid = record.getCentroid() #Returns a Point object containing the measured x and y. centroidErr = record.getCentroid()#Returns the 2x2 symmetric covariance matrix, with rows and columns ordered (x, y) ### quantities from the SdssShape class, calculated because we specified shape.sdss ixx = record.getIxx() iyy = record.getIyy() ixy = record.getIxy() centroids.append(centroid) print "first centroid:", centroids[0]
def detectAndMeasureWithDM(): ### what file are you going to look at? This should be in fits format. ### The test image included in this example contains stars and galaxies in the center only. imagefile = "test_image_stars.fits" ### open the file in the stack format exposure = afwImage.ExposureF(imagefile) im = exposure.getMaskedImage().getImage() ### display the original image frame = 0 ds9.mtv(exposure, frame=frame, title="Original Image"); frame+=1 ### Subtract background. ### To do this, we'll set up a grid of 64x64 pixel areas across th eimage ### Fit the second moment of the pixels in each (which should be bg-dominated) and a fit a smooth function ### Subtract this function. print "** subtracting background" #back_size = 256 ## dunno what this is #back_ctrl = afwMath.BackgroundControl(im.getWidth()//back_size+1, im.getHeight()//back_size +1) #back_obj = afwMath.makeBackground(im, back_ctrl) #im -=back_obj.getImageF("LINEAR") im -= float(np.median(im.getArray())) ds9.mtv(exposure, frame=frame, title="Background removed"); frame+=1 ### Set up the schema schema = afwTable.SourceTable.makeMinimalSchema() schema.setVersion(0) ### Create the detection task config = SourceDetectionTask.ConfigClass() config.reEstimateBackground = False detectionTask = SourceDetectionTask(config=config, schema=schema) ### create the measurement task config = SourceMeasurementTask.ConfigClass() config.slots.psfFlux = "flux.sinc" # use of the psf flux is hardcoded in secondMomentStarSelector measureTask = SourceMeasurementTask(schema, config=config) ### Create the measurePsf task config = MeasurePsfTask.ConfigClass() starSelector = config.starSelector.apply() starSelector.name = "objectSize" #starSelector.config.badFlags = ["flags.pixel.edge", "flags.pixel.cr.center", # "flags.pixel.interpolated.center", "flags.pixel.saturated.center"] psfDeterminer = config.psfDeterminer.apply() psfDeterminer.config.sizeCellX = 128 psfDeterminer.config.sizeCellY = 128 psfDeterminer.config.nStarPerCell = 1 psfDeterminer.config.spatialOrder = 1 psfDeterminer.config.nEigenComponents = 3 measurePsfTask = MeasurePsfTask(config=config, schema=schema) ### Create the output table tab = afwTable.SourceTable.make(schema) lsstDebug.getInfo(MeasurePsfTask).display=True ### Process the data print "*** running detection task..." sources = detectionTask.run(tab, exposure, sigma=2).sources print "*** running measure task..." measureTask.measure(exposure, sources) print "*** running measurePsf task..." result = measurePsfTask.run(exposure, sources) psf = result.psf cellSet = result.cellSet ### Look at the psf psfIm = psf.computeImage() ds9.mtv(psfIm, frame=frame, title = "Psf Image"); frame+=1 ### render it on a grid import lsst.meas.algorithms.utils as measUtils cellSet = result.cellSet measUtils.showPsfMosaic(exposure, psf=psf, frame=frame); frame += 1 with ds9.Buffering(): for s in sources: xy = s.getCentroid() ds9.dot('+', *xy, ctype=ds9.GREEN, frame=frame) if s.get("calib.psf.candidate"): ds9.dot('x', *xy, ctype=ds9.YELLOW, frame=frame) if s.get("calib.psf.used"): ds9.dot('o', *xy, size=4, ctype=ds9.RED, frame=frame) """
def run(display=False): exposure = loadData() schema = afwTable.SourceTable.makeMinimalSchema() # # Create the detection task # config = SourceDetectionTask.ConfigClass() config.thresholdPolarity = "both" config.background.isNanSafe = True config.thresholdValue = 3 detectionTask = SourceDetectionTask(config=config, schema=schema) # # And the measurement Task # config = SingleFrameMeasurementTask.ConfigClass() config.algorithms.names = [ "base_SdssCentroid", "base_SdssShape", "base_CircularApertureFlux" ] config.algorithms["base_CircularApertureFlux"].radii = [ 1, 2, 4, 8, 12, 16 ] # pixels config.slots.gaussianFlux = None config.slots.modelFlux = None config.slots.psfFlux = None algMetadata = dafBase.PropertyList() measureTask = SingleFrameMeasurementTask(schema, algMetadata=algMetadata, config=config) radii = algMetadata.getArray("BASE_CIRCULARAPERTUREFLUX_RADII") # # Create the output table # tab = afwTable.SourceTable.make(schema) # # Process the data # result = detectionTask.run(tab, exposure) sources = result.sources print("Found %d sources (%d +ve, %d -ve)" % (len(sources), result.fpSets.numPos, result.fpSets.numNeg)) measureTask.run(sources, exposure) if display: # display image (see also --debug argparse option) afwDisplay.setDefaultMaskTransparency(75) frame = 1 disp = afwDisplay.Display(frame=frame) disp.mtv(exposure) with disp.Buffering(): for s in sources: xy = s.getCentroid() disp.dot('+', *xy, ctype=afwDisplay.CYAN if s.get("flags_negative") else afwDisplay.GREEN) disp.dot(s.getShape(), *xy, ctype=afwDisplay.RED) for radius in radii: disp.dot('o', *xy, size=radius, ctype=afwDisplay.YELLOW)
def run(config, inputFiles, weightFiles=None, varianceFiles=None, returnCalibSources=False, display=False, verbose=False): # # Create the tasks # schema = afwTable.SourceTable.makeMinimalSchema() algMetadata = dafBase.PropertyList() calibrateTask = CalibrateTask(config=config.calibrate) sourceDetectionTask = SourceDetectionTask(config=config.detection, schema=schema) if config.doDeblend: if SourceDeblendTask: sourceDeblendTask = SourceDeblendTask(config=config.deblend, schema=schema) else: print >> sys.stderr, "Failed to import lsst.meas.deblender; setting doDeblend = False" config.doDeblend = False sourceMeasurementTask = SingleFrameMeasurementTask(config=config.measurement, schema=schema, algMetadata=algMetadata) exposureDict = {}; calibSourcesDict = {}; sourcesDict = {} for inputFile, weightFile, varianceFile in zip(inputFiles, weightFiles, varianceFiles): # # Create the output table # tab = afwTable.SourceTable.make(schema) # # read the data # if verbose: print "Reading %s" % inputFile exposure = makeExposure(inputFile, weightFile, varianceFile, config.badPixelValue, config.variance, verbose) # # process the data # calibSources = None # sources used to calibrate the frame (photom, astrom, psf) if config.doCalibrate: result = calibrateTask.run(exposure) exposure, sources = result.exposure, result.sources if returnCalibSources: calibSources = sources else: if not exposure.getPsf(): calibrateTask.installInitialPsf(exposure) if config.edgeRolloff.applyModel: if verbose: print "Adding edge rolloff distortion to the exposure WCS" addEdgeRolloffDistortion(exposure, config.edgeRolloff) exposureDict[inputFile] = exposure calibSourcesDict[inputFile] = calibSources result = sourceDetectionTask.run(tab, exposure) sources = result.sources sourcesDict[inputFile] = sources if config.doDeblend: sourceDeblendTask.run(exposure, sources, exposure.getPsf()) sourceMeasurementTask.measure(exposure, sources) if verbose: print "Detected %d objects" % len(sources) if display: # display on ds9 (see also --debug argparse option) if algMetadata.exists("base_CircularApertureFlux_radii"): radii = algMetadata.get("base_CircularApertureFlux_radii") else: radii = None frame = 1 ds9.mtv(exposure, title=os.path.split(inputFile)[1], frame=frame) with ds9.Buffering(): for s in sources: xy = s.getCentroid() ds9.dot('+', *xy, ctype=ds9.CYAN if s.get("flags_negative") else ds9.GREEN, frame=frame) ds9.dot(s.getShape(), *xy, ctype=ds9.RED, frame=frame) if radii: for radius in radii: ds9.dot('o', *xy, size=radius, ctype=ds9.YELLOW, frame=frame) return exposureDict, calibSourcesDict, sourcesDict
def run(config, inputFiles, weightFiles=None, varianceFiles=None, returnCalibSources=False, displayResults=[], verbose=False): # # Create the tasks # schema = afwTable.SourceTable.makeMinimalSchema() algMetadata = dafBase.PropertyList() isrTask = IsrTask(config=config.isr) calibrateTask = CalibrateTask(config=config.calibrate) sourceDetectionTask = SourceDetectionTask(config=config.detection, schema=schema) if config.doDeblend: if SourceDeblendTask: sourceDeblendTask = SourceDeblendTask(config=config.deblend, schema=schema) else: print >> sys.stderr, "Failed to import lsst.meas.deblender; setting doDeblend = False" config.doDeblend = False sourceMeasurementTask = SingleFrameMeasurementTask(config=config.measurement, schema=schema, algMetadata=algMetadata) sourceMeasurementTask.config.doApplyApCorr = 'yes' # # Add fields needed to identify stars while calibrating # keysToCopy = [(schema.addField(afwTable.Field["Flag"]("calib_detected", "Source was detected by calibrate")), None)] for key in calibrateTask.getCalibKeys(): keysToCopy.append((schema.addField(calibrateTask.schema.find(key).field), key)) exposureDict = {}; calibSourcesDict = {}; sourcesDict = {} for inputFile, weightFile, varianceFile in zip(inputFiles, weightFiles, varianceFiles): # # Create the output table # tab = afwTable.SourceTable.make(schema) # # read the data # if verbose: print "Reading %s" % inputFile exposure = makeExposure(inputFile, weightFile, varianceFile, config.badPixelValue, config.variance) # if config.interpPlanes: import lsst.ip.isr as ipIsr defects = ipIsr.getDefectListFromMask(exposure.getMaskedImage(), config.interpPlanes, growFootprints=0) isrTask.run(exposure, defects=defects) # # process the data # if config.doCalibrate: result = calibrateTask.run(exposure) exposure, calibSources = result.exposure, result.sources else: calibSources = None if not exposure.getPsf(): calibrateTask.installInitialPsf(exposure) exposureDict[inputFile] = exposure calibSourcesDict[inputFile] = calibSources if returnCalibSources else None result = sourceDetectionTask.run(tab, exposure) sources = result.sources sourcesDict[inputFile] = sources if config.doDeblend: sourceDeblendTask.run(exposure, sources, exposure.getPsf()) sourceMeasurementTask.measure(exposure, sources) if verbose: print "Detected %d objects" % len(sources) propagateCalibFlags(keysToCopy, calibSources, sources) if displayResults: # display results of processing (see also --debug argparse option) showApertures = "showApertures".upper() in displayResults showShapes = "showShapes".upper() in displayResults display = afwDisplay.getDisplay(frame=1) if algMetadata.exists("base_CircularApertureFlux_radii"): radii = algMetadata.get("base_CircularApertureFlux_radii") else: radii = [] display.mtv(exposure, title=os.path.split(inputFile)[1]) with display.Buffering(): for s in sources: xy = s.getCentroid() display.dot('+', *xy, ctype=afwDisplay.CYAN if s.get("flags_negative") else afwDisplay.GREEN) if showShapes: display.dot(s.getShape(), *xy, ctype=afwDisplay.RED) if showApertures: for radius in radii: display.dot('o', *xy, size=radius, ctype=afwDisplay.YELLOW) return exposureDict, calibSourcesDict, sourcesDict
def run(config, inputFiles, weightFiles=None, varianceFiles=None, returnCalibSources=False, displayResults=[], verbose=False): # # Create the tasks # schema = afwTable.SourceTable.makeMinimalSchema() algMetadata = dafBase.PropertyList() isrTask = IsrTask(config=config.isr) charImageTask = CharacterizeImageTask(None, config=config.charImage) sourceDetectionTask = SourceDetectionTask(config=config.detection, schema=schema) if config.doDeblend: if SourceDeblendTask: sourceDeblendTask = SourceDeblendTask(config=config.deblend, schema=schema) else: print >> sys.stderr, "Failed to import lsst.meas.deblender; setting doDeblend = False" config.doDeblend = False sourceMeasurementTask = SingleFrameMeasurementTask( schema=schema, config=config.measurement, algMetadata=algMetadata) keysToCopy = [] for key in [ charImageTask.measurePsf.reservedKey, charImageTask.measurePsf.usedKey, ]: keysToCopy.append( (schema.addField(charImageTask.schema.find(key).field), key)) exposureDict = {} calibSourcesDict = {} sourcesDict = {} for inputFile, weightFile, varianceFile in zip(inputFiles, weightFiles, varianceFiles): # # Create the output table # tab = afwTable.SourceTable.make(schema) # # read the data # if verbose: print "Reading %s" % inputFile exposure = makeExposure(inputFile, weightFile, varianceFile, config.badPixelValue, config.variance) # if config.interpPlanes: import lsst.ip.isr as ipIsr defects = ipIsr.getDefectListFromMask(exposure.getMaskedImage(), config.interpPlanes, growFootprints=0) isrTask.run(exposure, defects=defects) # # process the data # if config.doCalibrate: result = charImageTask.characterize(exposure) exposure, calibSources = result.exposure, result.sourceCat else: calibSources = None if not exposure.getPsf(): charImageTask.installSimplePsf.run(exposure) exposureDict[inputFile] = exposure calibSourcesDict[ inputFile] = calibSources if returnCalibSources else None result = sourceDetectionTask.run(tab, exposure) sources = result.sources sourcesDict[inputFile] = sources if config.doDeblend: sourceDeblendTask.run(exposure, sources) sourceMeasurementTask.measure(exposure, sources) if verbose: print "Detected %d objects" % len(sources) propagatePsfFlags(keysToCopy, calibSources, sources) if displayResults: # display results of processing (see also --debug argparse option) showApertures = "showApertures".upper() in displayResults showPSFs = "showPSFs".upper() in displayResults showShapes = "showShapes".upper() in displayResults display = afwDisplay.getDisplay(frame=1) if algMetadata.exists("base_CircularApertureFlux_radii"): radii = algMetadata.get("base_CircularApertureFlux_radii") else: radii = [] display.mtv(exposure, title=os.path.split(inputFile)[1]) with display.Buffering(): for s in sources: xy = s.getCentroid() display.dot('+', *xy, ctype=afwDisplay.CYAN if s.get("flags_negative") else afwDisplay.GREEN) if showPSFs and (s.get("calib_psfUsed") or s.get("calib_psfReserved")): display.dot( 'o', *xy, size=10, ctype=afwDisplay.GREEN if s.get("calib_psfUsed") else afwDisplay.YELLOW) if showShapes: display.dot(s.getShape(), *xy, ctype=afwDisplay.RED) if showApertures: for radius in radii: display.dot('o', *xy, size=radius, ctype=afwDisplay.YELLOW) return exposureDict, calibSourcesDict, sourcesDict
def run(display=False): exposure = loadData() schema = afwTable.SourceTable.makeMinimalSchema() # # Create the detection task # config = SourceDetectionTask.ConfigClass() config.thresholdPolarity = "both" config.background.isNanSafe = True config.thresholdValue = 3 detectionTask = SourceDetectionTask(config=config, schema=schema) # # And the measurement Task # config = SingleFrameMeasurementTask.ConfigClass() config.plugins.names.clear() for plugin in [ "base_SdssCentroid", "base_SdssShape", "base_CircularApertureFlux", "base_GaussianFlux" ]: config.plugins.names.add(plugin) config.slots.psfFlux = None config.slots.apFlux = "base_CircularApertureFlux_3_0" measureTask = SingleFrameMeasurementTask(schema, config=config) # # Print the schema the configuration produced # print schema # # Create the output table # tab = afwTable.SourceTable.make(schema) # # Process the data # result = detectionTask.run(tab, exposure) sources = result.sources print "Found %d sources (%d +ve, %d -ve)" % ( len(sources), result.fpSets.numPos, result.fpSets.numNeg) measureTask.run(sources, exposure) if display: # display on ds9 (see also --debug argparse option) frame = 1 ds9.mtv(exposure, frame=frame) with ds9.Buffering(): for s in sources: xy = s.getCentroid() ds9.dot( '+', *xy, ctype=ds9.CYAN if s.get("flags_negative") else ds9.GREEN, frame=frame) ds9.dot(s.getShape(), *xy, ctype=ds9.RED, frame=frame) ds9.dot( 'o', *xy, size=config.plugins["base_CircularApertureFlux"].radii[0], ctype=ds9.YELLOW, frame=frame)