def testDefectsFromMaskedImage(self): """Test creation of a DefectList from a MaskedImage.""" mim = afwImage.MaskedImageF(10, 10) # Nothing masked -> no defects. defectList = ipIsr.getDefectListFromMask(mim, "BAD") self.assertEqual(len(defectList), 0) # Mask a single pixel. mask = mim.getMask() mask[5, 5, afwImage.LOCAL] = mask.getPlaneBitMask("BAD") defectList = ipIsr.getDefectListFromMask(mim, "BAD") self.assertEqual(len(defectList), 1) self.assertEqual(defectList[0].getX0(), 5) self.assertEqual(defectList[0].getY0(), 5) # Setting a different plane does not register as a defect. mask[1, 1, afwImage.LOCAL] = mask.getPlaneBitMask("SUSPECT") defectList = ipIsr.getDefectListFromMask(mim, "SUSPECT") self.assertEqual(len(defectList), 1) # But adding another BAD pixel does. mask[9, 9, afwImage.LOCAL] = mask.getPlaneBitMask("BAD") defectList = ipIsr.getDefectListFromMask(mim, "BAD") self.assertEqual(len(defectList), 2)
def testDefectsFromMaskedImage(self): """Test creation of a DefectList from a MaskedImage.""" mim = afwImage.MaskedImageF(10, 10) # Nothing masked -> no defects. defectList = ipIsr.getDefectListFromMask(mim, "BAD", growFootprints=0) self.assertEqual(len(defectList), 0) # Mask a single pixel. mask = mim.getMask() mask.set(5, 5, mask.getPlaneBitMask("BAD")) defectList = ipIsr.getDefectListFromMask(mim, "BAD", growFootprints=0) self.assertEqual(len(defectList), 1) self.assertEqual(defectList[0].getX0(), 5) self.assertEqual(defectList[0].getY0(), 5) # Setting a different plane does not register as a defect. mask.set(1, 1, mask.getPlaneBitMask("SUSPECT")) defectList = ipIsr.getDefectListFromMask(mim, "SUSPECT", growFootprints=0) self.assertEqual(len(defectList), 1) # But adding another BAD pixel does. mask.set(9, 9, mask.getPlaneBitMask("BAD")) defectList = ipIsr.getDefectListFromMask(mim, "BAD", growFootprints=0) self.assertEqual(len(defectList), 2)
def run(self, maskedImage, planeName, psf, fallbackValue=None): """Interpolate in place over the pixels in a maskedImage which are marked bad by a mask plane Note that the interpolation code in meas_algorithms currently doesn't use the input PSF (though it's a required argument), so it's not important to set the input PSF parameters exactly. @param[in,out] maskedImage: MaskedImage over which to interpolate over edge pixels @param[in] planeName: mask plane over which to interpolate @param[in] PSF to use to detect NaNs (if a float, interpreted as PSF's Gaussian FWHM in pixels) @param[in] fallbackValue Pixel value to use when all else fails (if None, use median) """ self.log.info("Interpolate over %s pixels" % (planeName,)) if isinstance(psf, float): fwhmPixels = psf kernelSize = int(round(fwhmPixels * self.config.interpKernelSizeFactor)) kernelDim = afwGeom.Point2I(kernelSize, kernelSize) coreSigma = fwhmPixels / FwhmPerSigma psf = measAlg.DoubleGaussianPsf(kernelDim[0], kernelDim[1], coreSigma, coreSigma*2.5, 0.1) if fallbackValue is None: fallbackValue = max(afwMath.makeStatistics(maskedImage, afwMath.MEDIAN).getValue(), 0.0) elif fallbackValue < 0: self.log.warn("Negative interpolation fallback value provided: %f" % fallbackValue) nanDefectList = ipIsr.getDefectListFromMask(maskedImage, planeName, growFootprints=0) measAlg.interpolateOverDefects(maskedImage, psf, nanDefectList, fallbackValue, self.config.useFallbackValueAtEdge)
def bypass_defects(self, datasetType, pythonType, butlerLocation, dataId): """Return a defect list based on butlerLocation returned by map_defects. Use all nonzero pixels in the Community Pipeline Bad Pixel Masks. @param[in] butlerLocation: Butler Location with path to defects FITS @param[in] dataId: data identifier @return meas.algorithms.DefectListT """ bpmFitsPath = butlerLocation.getLocationsWithRoot()[0] bpmImg = afwImage.ImageU(bpmFitsPath) idxBad = np.nonzero(bpmImg.getArray()) mim = afwImage.MaskedImageU(bpmImg.getDimensions()) mim.getMask().getArray()[idxBad] |= mim.getMask().getPlaneBitMask("BAD") return isr.getDefectListFromMask(mim, "BAD", growFootprints=0)
def interpolateOnePlane(self, maskedImage, planeName, fwhmPixels): """Interpolate over one mask plane, in place @param[in,out] maskedImage: MaskedImage over which to interpolate over edge pixels @param[in] fwhmPixels: FWHM of double Gaussian model to use for interpolation (pixels) @param[in] planeName: mask plane over which to interpolate @param[in] PSF to use to detect NaNs """ self.log.info("Interpolate over %s pixels" % (planeName,)) kernelSize = int(round(fwhmPixels * self.config.interpKernelSizeFactor)) kernelDim = afwGeom.Point2I(kernelSize, kernelSize) coreSigma = fwhmPixels / FwhmPerSigma psfModel = afwDetection.createPsf("DoubleGaussian", kernelDim[0], kernelDim[1], coreSigma, coreSigma * 2.5, 0.1) nanDefectList = ipIsr.getDefectListFromMask(maskedImage, planeName, growFootprints=0) measAlg.interpolateOverDefects(maskedImage, psfModel, nanDefectList, 0.0)
def run(self, image, planeName=None, fwhmPixels=None, defects=None): """!Interpolate in place over pixels in a maskedImage marked as bad Pixels to be interpolated are set by either a mask planeName provided by the caller OR a defects list of type measAlg.DefectListT. If both are provided an exception is raised. Note that the interpolation code in meas_algorithms currently doesn't use the input PSF (though it's a required argument), so it's not important to set the input PSF parameters exactly. This PSF is set here as the psf attached to the "image" (i.e if the image passed in is an Exposure). Otherwise, a psf model is created using measAlg.GaussianPsfFactory with the value of fwhmPixels (the value passed in by the caller, or the default defaultFwhm set in measAlg.GaussianPsfFactory if None). \param[in,out] image MaskedImage OR Exposure to be interpolated \param[in] planeName name of mask plane over which to interpolate If None, must provide a defects list. \param[in] fwhmPixels FWHM of core star (pixels) If None the default is used, where the default is set to the exposure psf if available \param[in] defects List of defects of type measAlg.DefectListT over which to interpolate. """ try: maskedImage = image.getMaskedImage() except AttributeError: maskedImage = image # set defectList from defects OR mask planeName provided if planeName is None: if defects is None: raise ValueError("No defects or plane name provided") else: defectList = defects planeName = "defects" else: if defects is not None: raise ValueError("Provide EITHER a planeName OR a list of defects, not both") if not maskedImage.getMask().getMaskPlaneDict().has_key(planeName): raise ValueError("maskedImage does not contain mask plane %s" % planeName) defectList = ipIsr.getDefectListFromMask(maskedImage, planeName, growFootprints=0) # set psf from exposure if provided OR using modelPsf with fwhmPixels provided try: psf = image.getPsf() self.log.info("Setting psf for interpolation from image") except AttributeError: self.log.info( "Creating psf model for interpolation from fwhm(pixels) = %s" % ( str(fwhmPixels) if fwhmPixels is not None else (str(self.config.modelPsf.defaultFwhm)) + " [default]" ) ) psf = self.config.modelPsf.apply(fwhm=fwhmPixels) fallbackValue = 0.0 # interpolateOverDefects needs this to be a float, regardless if it is used if self.config.useFallbackValueAtEdge: fallbackValue = self._setFallbackValue(maskedImage) measAlg.interpolateOverDefects(maskedImage, psf, defectList, fallbackValue, self.config.useFallbackValueAtEdge) self.log.info("Interpolated over %d %s pixels." % (len(defectList), planeName))
col1 = pyfits.Column(name='x0', format='I', array=numpy.array(x0)) col2 = pyfits.Column(name='y0', format='I', array=numpy.array(y0)) col3 = pyfits.Column(name='height', format='I', array=numpy.array(height)) col4 = pyfits.Column(name='width', format='I', array=numpy.array(width)) cols = pyfits.ColDefs([col1, col2, col3, col4]) tbhdu = pyfits.new_table(cols, header = head) hdu = pyfits.PrimaryHDU() thdulist = pyfits.HDUList([hdu, tbhdu]) thdulist.writeto(DefectsPath) if __name__ == "__main__": parser = argparse.ArgumentParser( description="""Construct a defects file from the mask plane of a test camera bias frame. To use this command you must setup ip_isr and pyfits. Output is written to the current directory as file %r, which must not already exist. """ % (DefectsPath,) ) parser.add_argument("bias", help="path to bias image for the test camera") args = parser.parse_args() biasMI = afwImage.MaskedImageF(args.bias) defectList = getDefectListFromMask(biasMI, "BAD", growFootprints=0) bboxList = [defect.getBBox() for defect in defectList] writeDefectsFile(bboxList, DefectsPath, detectorSerial, detectorName) print("wrote defects file %r" % (DefectsPath,)) test2BBoxList = getBBoxList(DefectsPath, detectorName) assert len(bboxList) == len(test2BBoxList) for boxA, boxB in itertools.izip(bboxList, test2BBoxList): assert boxA == boxB print("verified that defects file %r round trips correctly" % (DefectsPath,))
def testEdge(self): """Test that we can interpolate to the edge""" mi = afwImage.MaskedImageF(80, 30) ima = mi.getImage().getArray() # # We'll set the BAD bit in pixels we wish to interpolate over # pixelPlane = "BAD" badBit = afwImage.MaskU.getPlaneBitMask(pixelPlane) # # Set bad columns near left and right sides of image # nBadCol = 10 mi.set((0, 0x0, 0)) np.random.seed(666) ima[:] = np.random.uniform(-1, 1, ima.shape) mi[0:nBadCol, :] = (10, badBit, 0) # Bad left edge mi[-nBadCol:, :] = (10, badBit, 0) # With another bad set of columns next to bad left edge mi[nBadCol+1:nBadCol+4, 0:10] = (100, badBit, 0) # Bad right edge mi[-nBadCol-4:-nBadCol-1, 0:10] = (100, badBit, 0) # more bad of columns next to bad right edge defectList = ipIsr.getDefectListFromMask(mi, pixelPlane, growFootprints=0) if display: ds9.mtv(mi, frame=0) def validateInterp(miInterp, useFallbackValueAtEdge, fallbackValue): imaInterp = miInterp.getImage().getArray() if display: ds9.mtv(miInterp, frame=1) self.assertGreater(np.min(imaInterp), min(-2, 2*fallbackValue)) self.assertGreater(max(2, 2*fallbackValue), np.max(imaInterp)) val0 = np.mean(miInterp.getImage()[1, :].getArray(), dtype=float) if useFallbackValueAtEdge: self.assertAlmostEqual(val0, fallbackValue, 6) else: self.assertNotEqual(val0, 0) for useFallbackValueAtEdge in (False, True): miInterp = mi.clone() config = InterpImageTask.ConfigClass() config.useFallbackValueAtEdge = useFallbackValueAtEdge interpTask = InterpImageTask(config) if useFallbackValueAtEdge: config.fallbackUserValue = -1.0 # choiceField fallbackValueType cannot be None if useFallbackValueAtEdge is True config.fallbackValueType = None self.assertRaises(NotImplementedError, interpTask._setFallbackValue, miInterp) # make sure an invalid fallbackValueType raises a pexConfig.FieldValidationError with self.assertRaises(pexConfig.FieldValidationError): config.fallbackValueType = "NOTUSED" # make sure ValueError is raised if both a planeName and defects list are provided self.assertRaises(ValueError, interpTask.run, miInterp, defects=defectList, planeName=pixelPlane, fwhmPixels=self.FWHM) for fallbackValueType in ("USER", "MEAN", "MEDIAN", "MEANCLIP"): for negativeFallbackAllowed in (True, False): config.negativeFallbackAllowed = negativeFallbackAllowed config.fallbackValueType = fallbackValueType # Should raise if negative not allowed, but USER supplied negative value if not negativeFallbackAllowed and fallbackValueType == "USER": self.assertRaises(ValueError, config.validate) interpTask = InterpImageTask(config) fallbackValue = interpTask._setFallbackValue(mi) # # Time to interpolate # miInterp = mi.clone() interpTask.run(miInterp, planeName=pixelPlane, fwhmPixels=self.FWHM) validateInterp(miInterp, useFallbackValueAtEdge, fallbackValue) miInterp = mi.clone() interpTask.run(miInterp, defects=defectList) validateInterp(miInterp, useFallbackValueAtEdge, fallbackValue) else: # # Time to interpolate # miInterp = mi.clone() interpTask.run(miInterp, planeName=pixelPlane, fwhmPixels=self.FWHM) validateInterp(miInterp, useFallbackValueAtEdge, 0)
def testEdge(self): """Test that we can interpolate to the edge""" mi = afwImage.MaskedImageF(80, 30) ima = mi.getImage().getArray() # # We'll set the BAD bit in pixels we wish to interpolate over # pixelPlane = "BAD" badBit = afwImage.Mask.getPlaneBitMask(pixelPlane) # # Set bad columns near left and right sides of image # nBadCol = 10 mi.set((0, 0x0, 0)) np.random.seed(666) ima[:] = np.random.uniform(-1, 1, ima.shape) mi[0:nBadCol, :] = (10, badBit, 0) # Bad left edge mi[-nBadCol:, :] = ( 10, badBit, 0 ) # With another bad set of columns next to bad left edge mi[nBadCol + 1:nBadCol + 4, 0:10] = (100, badBit, 0) # Bad right edge mi[-nBadCol - 4:-nBadCol - 1, 0:10] = (100, badBit, 0 ) # more bad of columns next to bad right edge defectList = ipIsr.getDefectListFromMask(mi, pixelPlane, growFootprints=0) if display: ds9.mtv(mi, frame=0) def validateInterp(miInterp, useFallbackValueAtEdge, fallbackValue): imaInterp = miInterp.getImage().getArray() if display: ds9.mtv(miInterp, frame=1) self.assertGreater(np.min(imaInterp), min(-2, 2 * fallbackValue)) self.assertGreater(max(2, 2 * fallbackValue), np.max(imaInterp)) val0 = np.mean(miInterp.getImage()[1, :].getArray(), dtype=float) if useFallbackValueAtEdge: self.assertAlmostEqual(val0, fallbackValue, 6) else: self.assertNotEqual(val0, 0) for useFallbackValueAtEdge in (False, True): miInterp = mi.clone() config = InterpImageTask.ConfigClass() config.useFallbackValueAtEdge = useFallbackValueAtEdge interpTask = InterpImageTask(config) if useFallbackValueAtEdge: config.fallbackUserValue = -1.0 # choiceField fallbackValueType cannot be None if useFallbackValueAtEdge is True config.fallbackValueType = None self.assertRaises(NotImplementedError, interpTask._setFallbackValue, miInterp) # make sure an invalid fallbackValueType raises a pexConfig.FieldValidationError with self.assertRaises(pexConfig.FieldValidationError): config.fallbackValueType = "NOTUSED" # make sure ValueError is raised if both a planeName and defects list are provided self.assertRaises(ValueError, interpTask.run, miInterp, defects=defectList, planeName=pixelPlane, fwhmPixels=self.FWHM) for fallbackValueType in ("USER", "MEAN", "MEDIAN", "MEANCLIP"): for negativeFallbackAllowed in (True, False): config.negativeFallbackAllowed = negativeFallbackAllowed config.fallbackValueType = fallbackValueType # Should raise if negative not allowed, but USER supplied negative value if not negativeFallbackAllowed and fallbackValueType == "USER": self.assertRaises(ValueError, config.validate) interpTask = InterpImageTask(config) fallbackValue = interpTask._setFallbackValue(mi) # # Time to interpolate # miInterp = mi.clone() interpTask.run(miInterp, planeName=pixelPlane, fwhmPixels=self.FWHM) validateInterp(miInterp, useFallbackValueAtEdge, fallbackValue) miInterp = mi.clone() interpTask.run(miInterp, defects=defectList) validateInterp(miInterp, useFallbackValueAtEdge, fallbackValue) else: # # Time to interpolate # miInterp = mi.clone() interpTask.run(miInterp, planeName=pixelPlane, fwhmPixels=self.FWHM) validateInterp(miInterp, useFallbackValueAtEdge, 0)
def run(self, image, planeName=None, fwhmPixels=None, defects=None): """!Interpolate in place over pixels in a maskedImage marked as bad Pixels to be interpolated are set by either a mask planeName provided by the caller OR a defects list of type measAlg.DefectListT. If both are provided an exception is raised. Note that the interpolation code in meas_algorithms currently doesn't use the input PSF (though it's a required argument), so it's not important to set the input PSF parameters exactly. This PSF is set here as the psf attached to the "image" (i.e if the image passed in is an Exposure). Otherwise, a psf model is created using measAlg.GaussianPsfFactory with the value of fwhmPixels (the value passed in by the caller, or the default defaultFwhm set in measAlg.GaussianPsfFactory if None). @param[in,out] image MaskedImage OR Exposure to be interpolated @param[in] planeName name of mask plane over which to interpolate If None, must provide a defects list. @param[in] fwhmPixels FWHM of core star (pixels) If None the default is used, where the default is set to the exposure psf if available @param[in] defects List of defects of type measAlg.DefectListT over which to interpolate. """ try: maskedImage = image.getMaskedImage() except AttributeError: maskedImage = image # set defectList from defects OR mask planeName provided if planeName is None: if defects is None: raise ValueError("No defects or plane name provided") else: defectList = defects planeName = "defects" else: if defects is not None: raise ValueError( "Provide EITHER a planeName OR a list of defects, not both" ) if planeName not in maskedImage.getMask().getMaskPlaneDict(): raise ValueError("maskedImage does not contain mask plane %s" % planeName) defectList = ipIsr.getDefectListFromMask(maskedImage, planeName) # set psf from exposure if provided OR using modelPsf with fwhmPixels provided try: psf = image.getPsf() self.log.info("Setting psf for interpolation from image") except AttributeError: self.log.info( "Creating psf model for interpolation from fwhm(pixels) = %s" % (str(fwhmPixels) if fwhmPixels is not None else (str(self.config.modelPsf.defaultFwhm)) + " [default]")) psf = self.config.modelPsf.apply(fwhm=fwhmPixels) fallbackValue = 0.0 # interpolateOverDefects needs this to be a float, regardless if it is used if self.config.useFallbackValueAtEdge: fallbackValue = self._setFallbackValue(maskedImage) measAlg.interpolateOverDefects(maskedImage, psf, defectList, fallbackValue, self.config.useFallbackValueAtEdge) self.log.info("Interpolated over %d %s pixels." % (len(defectList), planeName))
col4 = pyfits.Column(name='width', format='I', array=numpy.array(width)) cols = pyfits.ColDefs([col1, col2, col3, col4]) tbhdu = pyfits.new_table(cols, header=head) hdu = pyfits.PrimaryHDU() thdulist = pyfits.HDUList([hdu, tbhdu]) thdulist.writeto(DefectsPath) if __name__ == "__main__": parser = argparse.ArgumentParser( description= """Construct a defects file from the mask plane of a test camera bias frame. To use this command you must setup ip_isr and pyfits. Output is written to the current directory as file %r, which must not already exist. """ % (DefectsPath, )) parser.add_argument("bias", help="path to bias image for the test camera") args = parser.parse_args() biasMI = afwImage.MaskedImageF(args.bias) defectList = getDefectListFromMask(biasMI, "BAD") bboxList = [defect.getBBox() for defect in defectList] writeDefectsFile(bboxList, DefectsPath, detectorSerial, detectorName) print("wrote defects file %r" % (DefectsPath, )) test2BBoxList = getBBoxList(DefectsPath, detectorName) assert len(bboxList) == len(test2BBoxList) for boxA, boxB in zip(bboxList, test2BBoxList): assert boxA == boxB print("verified that defects file %r round trips correctly" % (DefectsPath, ))
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(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
col3 = fits.Column(name='height', format='I', array=numpy.array(height)) col4 = fits.Column(name='width', format='I', array=numpy.array(width)) cols = fits.ColDefs([col1, col2, col3, col4]) tbhdu = fits.new_table(cols, header=head) hdu = fits.PrimaryHDU() thdulist = fits.HDUList([hdu, tbhdu]) thdulist.writeto(DefectsPath) if __name__ == "__main__": parser = argparse.ArgumentParser( description="""Construct a defects file from the mask plane of a test camera bias frame. To use this command you must setup ip_isr and astropy. Output is written to the current directory as file %r, which must not already exist. """ % (DefectsPath,) ) parser.add_argument("bias", help="path to bias image for the test camera") args = parser.parse_args() biasMI = afwImage.MaskedImageF(args.bias) defectList = getDefectListFromMask(biasMI, "BAD") bboxList = [defect.getBBox() for defect in defectList] writeDefectsFile(bboxList, DefectsPath, detectorSerial, detectorName) print("wrote defects file %r" % (DefectsPath,)) test2BBoxList = getBBoxList(DefectsPath, detectorName) assert len(bboxList) == len(test2BBoxList) for boxA, boxB in zip(bboxList, test2BBoxList): assert boxA == boxB print("verified that defects file %r round trips correctly" % (DefectsPath,))