def test1295(self): """A test case for #1295 (failure to interpolate over groups of defects.""" im = afwImage.ImageF(lsst.geom.ExtentI(100, 100)) mi = afwImage.makeMaskedImage(im) mi.set(100) flat = afwImage.ImageF(im.getDimensions()) flat.set(1) flat[50:51, :, afwImage.LOCAL] = 0.0 flat[55:56, :, afwImage.LOCAL] = 0.0 flat[58:59, :, afwImage.LOCAL] = 0.0 flat[51:60, 51:, afwImage.LOCAL] = 0.0 mi /= flat if display: afwDisplay.Display(frame=0).mtv(mi, title=self._testMethodName + ": Raw") defectList = algorithms.Defects() bbox = lsst.geom.BoxI(lsst.geom.PointI(50, 0), lsst.geom.ExtentI(1, 100)) defectList.append(algorithms.Defect(bbox)) bbox = lsst.geom.BoxI(lsst.geom.PointI(55, 0), lsst.geom.ExtentI(1, 100)) defectList.append(algorithms.Defect(bbox)) bbox = lsst.geom.BoxI(lsst.geom.PointI(58, 0), lsst.geom.ExtentI(1, 100)) defectList.append(algorithms.Defect(bbox)) bbox = lsst.geom.BoxI(lsst.geom.PointI(51, 51), lsst.geom.ExtentI(9, 49)) defectList.append(algorithms.Defect(bbox)) psf = algorithms.DoubleGaussianPsf(15, 15, 1./(2*math.sqrt(2*math.log(2)))) algorithms.interpolateOverDefects(mi, psf, defectList, 50.) if display: afwDisplay.Display(frame=1).mtv(mi, title=self._testMethodName + ": Interpolated") self.assertTrue(np.isfinite(mi.image[56, 51, afwImage.LOCAL]))
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 testDetection(self): """Test Interp algorithms.""" if display: frame = 0 ds9.mtv(self.mi, frame=frame, title="Original") algorithms.interpolateOverDefects(self.mi, self.psf, self.badPixels) if display: ds9.mtv(self.mi, frame=frame + 1, title="Interpolated") ds9.mtv(self.mi.getVariance(), frame=frame + 2, title="Variance")
def testDetection(self): """Test Interp algorithms""" if display: frame = 0 ds9.mtv(self.mi, frame=frame, title="Original") algorithms.interpolateOverDefects(self.mi, self.psf, self.badPixels) if display: ds9.mtv(self.mi, frame = frame + 1, title="Interpolated") ds9.mtv(self.mi.getVariance(), frame = frame + 2, title="Variance")
def interpolate(self, exposure, defects): """Interpolate over defects @param[in,out] exposure Exposure to process @param defects Defect list """ assert exposure, "No exposure provided" assert defects is not None, "No defects provided" psf = exposure.getPsf() assert psf, "No psf provided" mi = exposure.getMaskedImage() fallbackValue = afwMath.makeStatistics(mi, afwMath.MEANCLIP).getValue() measAlg.interpolateOverDefects(mi, psf, defects, fallbackValue) self.log.info("Interpolated over %d defects." % len(defects))
def testDetection(self): """Test Interp algorithms.""" if display: frame = 0 afwDisplay.Display(frame=frame).mtv(self.mi, title=self._testMethodName + ": Original") algorithms.interpolateOverDefects(self.mi, self.psf, self.badPixels) if display: frame += 1 afwDisplay.Display(frame=frame).mtv(self.mi, title=self._testMethodName + ": Interpolated") frame += 1 afwDisplay.Display(frame=frame).mtv(self.mi.getVariance(), title=self._testMethodName + ": Variance")
def interpolateDefectList(maskedImage, defectList, fwhm, fallbackValue=None): """Interpolate over defects specified in a defect list @param[in,out] maskedImage masked image to process @param[in] defectList defect list @param[in] fwhm FWHM of double Gaussian smoothing kernel @param[in] fallbackValue fallback value if an interpolated value cannot be determined; if None then use clipped mean image value """ psf = createPsf(fwhm) if fallbackValue is None: fallbackValue = afwMath.makeStatistics(maskedImage.getImage(), afwMath.MEANCLIP).getValue() if 'INTRP' not in maskedImage.getMask().getMaskPlaneDict().keys(): maskedImage.getMask.addMaskPlane('INTRP') measAlg.interpolateOverDefects(maskedImage, psf, defectList, fallbackValue, True)
def psf(self, exposure): psf, wcs = self._Calibrate.fakePsf(exposure) # Need to clobber NANs... # XXX Use a Pipette process for this exposure.getMaskedImage().getMask().addMaskPlane("UNMASKEDNAN") nanMasker = ipIsr.UnmaskedNanCounterF() nanMasker.apply(exposure.getMaskedImage()) nans = ipIsr.defectListFromMask(exposure, maskName='UNMASKEDNAN') measAlg.interpolateOverDefects(exposure.getMaskedImage(), psf, nans, 0.0) sources = self._Calibrate.phot(exposure, psf) psf, cellSet = self._Calibrate.psf(exposure, sources) apcorr = self._Calibrate.apCorr(exposure, cellSet) return psf, apcorr
def interpolate(self, exposure, psf, defects): """Interpolate over defects @param exposure Exposure to process @param psf PSF for interpolation @param defects Defect list """ assert exposure, "No exposure provided" assert defects is not None, "No defects provided" assert psf, "No psf provided" mi = exposure.getMaskedImage() fallbackValue = afwMath.makeStatistics(mi, afwMath.MEANCLIP).getValue() measAlg.interpolateOverDefects(mi, psf, defects, fallbackValue) self.log.log(self.log.INFO, "Interpolated over %d defects." % len(defects)) return
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 interpolateDefectList(maskedImage, defectList, fwhm, fallbackValue=None): """Interpolate over defects specified in a defect list @param[in,out] maskedImage masked image to process @param[in] defectList defect list @param[in] fwhm FWHM of double Gaussian smoothing kernel @param[in] fallbackValue fallback value if an interpolated value cannot be determined; if None then use clipped mean image value """ psf = createPsf(fwhm) if fallbackValue is None: fallbackValue = afwMath.makeStatistics(maskedImage.getImage(), afwMath.MEANCLIP).getValue() if 'INTRP' not in maskedImage.getMask().getMaskPlaneDict(): maskedImage.getMask.addMaskPlane('INTRP') measAlg.interpolateOverDefects(maskedImage, psf, defectList, fallbackValue, True)
def test818(self): """A test case for #818; the full test is in /lsst/DC3root/ticketFiles/818""" badPixels = [] defects = [((82, 663), 6, 8), ((83, 659), 9, 6), ((85, 660), 10, 11), ((87, 669), 3, 3), ] for xy0, width, height in defects: x0, y0 = xy0 bbox = lsst.geom.BoxI(lsst.geom.PointI(x0, y0), lsst.geom.ExtentI(width, height)) badPixels.append(algorithms.Defect(bbox)) mi = afwImage.MaskedImageF(517, 800) algorithms.interpolateOverDefects(mi, self.psf, badPixels)
def test818(self): """A test case for #818; the full test is in /lsst/DC3root/ticketFiles/818""" badPixels = [] defects = [((82, 663), 6, 8), ((83, 659), 9, 6), ((85, 660), 10, 11), ((87, 669), 3, 3), ] for xy0, width, height in defects: x0, y0 = xy0 bbox = afwGeom.BoxI(afwGeom.PointI(x0, y0), afwGeom.ExtentI(width, height)) badPixels.append(algorithms.Defect(bbox)) mi = afwImage.MaskedImageF(517, 800) algorithms.interpolateOverDefects(mi, self.psf, badPixels)
def XXXtest818(self): """A test case for #818; the full test is in /lsst/DC3root/ticketFiles/818""" badPixels = algorithms.DefectListT() defects = [((82, 663), 6, 8), ((83, 659), 9, 6), ((85, 660), 10, 11), ((87, 669), 3, 3), ] for xy0, width, height in defects: x0, y0 = xy0 bbox = afwImage.BBox(afwImage.PointI(x0, y0), width, height) badPixels.push_back(algorithms.Defect(bbox)) mi = afwImage.MaskedImageF(517, 800) algorithms.interpolateOverDefects(mi, self.psf, badPixels)
def interpolateImage(self, maskedImage, psf, defectList, fallbackValue): """Interpolate over defects in an image Parameters ---------- maskedImage : `lsst.afw.image.MaskedImage` Image on which to perform interpolation. psf : `lsst.afw.detection.Psf` Point-spread function; currently unused. defectList : `lsst.meas.algorithms.Defects` List of defects to interpolate over. fallbackValue : `float` Value to set when interpolation fails. """ if not defectList: return with self.transposeContext(maskedImage, defectList) as (image, defects): measAlg.interpolateOverDefects(image, psf, defects, fallbackValue, self.config.useFallbackValueAtEdge)
def test1295(self): """A test case for #1295 (failure to interpolate over groups of defects.""" im = afwImage.ImageF(lsst.geom.ExtentI(100, 100)) mi = afwImage.makeMaskedImage(im) mi.set(100) flat = afwImage.ImageF(im.getDimensions()) flat.set(1) flat[50:51, :, afwImage.LOCAL] = 0.0 flat[55:56, :, afwImage.LOCAL] = 0.0 flat[58:59, :, afwImage.LOCAL] = 0.0 flat[51:60, 51:, afwImage.LOCAL] = 0.0 mi /= flat if display: afwDisplay.Display(frame=0).mtv(mi, title=self._testMethodName + ": Raw") defectList = [] bbox = lsst.geom.BoxI(lsst.geom.PointI(50, 0), lsst.geom.ExtentI(1, 100)) defectList.append(algorithms.Defect(bbox)) bbox = lsst.geom.BoxI(lsst.geom.PointI(55, 0), lsst.geom.ExtentI(1, 100)) defectList.append(algorithms.Defect(bbox)) bbox = lsst.geom.BoxI(lsst.geom.PointI(58, 0), lsst.geom.ExtentI(1, 100)) defectList.append(algorithms.Defect(bbox)) bbox = lsst.geom.BoxI(lsst.geom.PointI(51, 51), lsst.geom.ExtentI(9, 49)) defectList.append(algorithms.Defect(bbox)) psf = algorithms.DoubleGaussianPsf( 15, 15, 1. / (2 * math.sqrt(2 * math.log(2)))) algorithms.interpolateOverDefects(mi, psf, defectList, 50.) if display: afwDisplay.Display(frame=1).mtv(mi, title=self._testMethodName + ": Interpolated") self.assertTrue(np.isfinite(mi.image[56, 51, afwImage.LOCAL]))
def interpolateDefectList(maskedImage, defectList, fwhm, fallbackValue=None): """Interpolate over defects specified in a defect list. Parameters ---------- maskedImage : `lsst.afw.image.MaskedImage` Image to process. defectList : `list` List of defects to interpolate over. fwhm : scalar FWHM of double Gaussian smoothing kernel. fallbackValue : scalar, optional Fallback value if an interpolated value cannot be determined. If None, then the clipped mean of the image is used. """ psf = createPsf(fwhm) if fallbackValue is None: fallbackValue = afwMath.makeStatistics(maskedImage.getImage(), afwMath.MEANCLIP).getValue() if 'INTRP' not in maskedImage.getMask().getMaskPlaneDict(): maskedImage.getMask.addMaskPlane('INTRP') measAlg.interpolateOverDefects(maskedImage, psf, defectList, fallbackValue, True)
def interpolateDefectList(maskedImage, defectList, fwhm, fallbackValue=None): """Interpolate over defects specified in a defect list. Parameters ---------- maskedImage : `lsst.afw.image.MaskedImage` Image to process. defectList : `lsst.meas.algorithms.Defects` List of defects to interpolate over. fwhm : scalar FWHM of double Gaussian smoothing kernel. fallbackValue : scalar, optional Fallback value if an interpolated value cannot be determined. If None, then the clipped mean of the image is used. """ psf = createPsf(fwhm) if fallbackValue is None: fallbackValue = afwMath.makeStatistics(maskedImage.getImage(), afwMath.MEANCLIP).getValue() if 'INTRP' not in maskedImage.getMask().getMaskPlaneDict(): maskedImage.getMask().addMaskPlane('INTRP') measAlg.interpolateOverDefects(maskedImage, psf, defectList, fallbackValue, True) return maskedImage
def test1295(self): """A test case for #1295 (failure to interpolate over groups of defects""" im = afwImage.ImageF(afwGeom.ExtentI(100, 100)) mi = afwImage.makeMaskedImage(im) mi.set(100) flat = afwImage.ImageF(im.getDimensions()) flat.set(1) for i in range(100): for j in range(100): if i == 50 or i == 55 or i == 58: flat.set(i, j, 0) if i < 60 and i > 50 and j > 50: flat.set(i, j, 0) mi /= flat if display: ds9.mtv(mi, frame=0, title="Raw") defectList = algorithms.DefectListT() bbox = afwGeom.BoxI(afwGeom.PointI(50, 0), afwGeom.ExtentI(1, 100)) defectList.append(algorithms.Defect(bbox)) bbox = afwGeom.BoxI(afwGeom.PointI(55, 0), afwGeom.ExtentI(1, 100)) defectList.append(algorithms.Defect(bbox)) bbox = afwGeom.BoxI(afwGeom.PointI(58, 0), afwGeom.ExtentI(1, 100)) defectList.append(algorithms.Defect(bbox)) bbox = afwGeom.BoxI(afwGeom.PointI(51, 51), afwGeom.ExtentI(9, 49)) defectList.append(algorithms.Defect(bbox)) psf = algorithms.DoubleGaussianPsf( 15, 15, 1. / (2 * math.sqrt(2 * math.log(2)))) algorithms.interpolateOverDefects(mi, psf, defectList, 50.) if display: ds9.mtv(mi, frame=1, title="Interpolated") self.assertTrue(numpy.isfinite(mi.getImage().get(56, 51)))
def ISR(self, fixCRs = True): """Run the ISR stage, removing CRs and patching bad columns""" mi = self.exposure.getMaskedImage() mi.getMask().set(0) # XXX # # Fix defects # # Mask known bad pixels # badPixels = measAlg.defects.policyToBadRegionList(os.path.join(eups.productDir("meas_algorithms"), "examples", "BadPixels.paf")) # did someone lie about the origin of the maskedImage? If so, adjust bad pixel list if self.XY0.getX() != mi.getX0() or self.XY0.getY() != mi.getY0(): dx = self.XY0.getX() - mi.getX0() dy = self.XY0.getY() - mi.getY0() for bp in badPixels: bp.shift(-dx, -dy) measAlg.interpolateOverDefects(mi, self.psf, badPixels) # # Subtract background # bctrl = afwMath.BackgroundControl("LINEAR"); bctrl.setNxSample(int(mi.getWidth()/256) + 1); bctrl.setNySample(int(mi.getHeight()/256) + 1); backobj = afwMath.makeBackground(mi.getImage(), bctrl) img = mi.getImage(); img -= backobj.getImageF(); del img # # Remove CRs # if fixCRs: crConfig = measAlg.FindCosmicRaysConfig() crs = measAlg.findCosmicRays(mi, self.psf, 0, pexConfig.makePolicy(crConfig)) if self.display: ds9.mtv(mi, frame = 0, lowOrderBits = True)
def test1295(self): """A test case for #1295 (failure to interpolate over groups of defects""" im = afwImage.ImageF(afwGeom.ExtentI(100, 100)) mi = afwImage.makeMaskedImage(im) mi.set(100) flat = afwImage.ImageF(im.getDimensions()) flat.set(1) for i in range(100): for j in range(100): if i == 50 or i == 55 or i == 58: flat.set(i,j,0) if i < 60 and i > 50 and j > 50: flat.set(i,j,0) mi /= flat if display: ds9.mtv(mi, frame=0, title="Raw") defectList = algorithms.DefectListT() bbox = afwGeom.BoxI(afwGeom.PointI(50,0), afwGeom.ExtentI(1,100)) defectList.append(algorithms.Defect(bbox)) bbox = afwGeom.BoxI(afwGeom.PointI(55,0), afwGeom.ExtentI(1,100)) defectList.append(algorithms.Defect(bbox)) bbox = afwGeom.BoxI(afwGeom.PointI(58,0), afwGeom.ExtentI(1,100)) defectList.append(algorithms.Defect(bbox)) bbox = afwGeom.BoxI(afwGeom.PointI(51,51), afwGeom.ExtentI(9,49)) defectList.append(algorithms.Defect(bbox)) psf = algorithms.DoubleGaussianPsf(15, 15, 1./(2*math.sqrt(2*math.log(2)))) algorithms.interpolateOverDefects(mi, psf, defectList, 50.) if display: ds9.mtv(mi, frame=1, title="Interpolated") self.assertTrue(numpy.isfinite(mi.getImage().get(56, 51)))
def testDetection(self): """Test CR detection.""" # # Subtract background # bctrl = afwMath.BackgroundControl(afwMath.Interpolate.NATURAL_SPLINE) bctrl.setNxSample(int(self.mi.getWidth() / 256) + 1) bctrl.setNySample(int(self.mi.getHeight() / 256) + 1) bctrl.getStatisticsControl().setNumSigmaClip(3.0) bctrl.getStatisticsControl().setNumIter(2) im = self.mi.getImage() try: backobj = afwMath.makeBackground(im, bctrl) except Exception as e: print(e, file=sys.stderr) bctrl.setInterpStyle(afwMath.Interpolate.CONSTANT) backobj = afwMath.makeBackground(im, bctrl) im -= backobj.getImageF() if display: frame = 0 disp = afwDisplay.Display(frame=frame) disp.mtv(self.mi, title=self._testMethodName + ": Raw") # raw frame if self.mi.getWidth() > 256: disp.pan(944 - self.mi.getX0(), 260 - self.mi.getY0()) # # Mask known bad pixels # badPixels = testUtils.makeDefectList() algorithms.interpolateOverDefects(self.mi, self.psf, badPixels) stats = afwMath.makeStatistics(self.mi.getImage(), afwMath.MEANCLIP | afwMath.STDEVCLIP) background = stats.getValue(afwMath.MEANCLIP) crConfig = algorithms.FindCosmicRaysConfig() crs = algorithms.findCosmicRays(self.mi, self.psf, background, pexConfig.makePropertySet(crConfig)) if display: frame += 1 disp = afwDisplay.Display(frame=frame) disp.mtv(self.mi, title=self._testMethodName + ": CRs removed") if self.mi.getWidth() > 256: disp.pan(944 - self.mi.getX0(), 260 - self.mi.getY0()) print("Detected %d CRs" % len(crs)) if display and False: for cr in crs: bbox = cr.getBBox() bbox.shift( lsst.geom.ExtentI(-self.mi.getX0(), -self.mi.getY0())) disp.line([(bbox.getMinX() - 0.5, bbox.getMinY() - 0.5), (bbox.getMaxX() + 0.5, bbox.getMinY() - 0.5), (bbox.getMaxX() + 0.5, bbox.getMaxY() + 0.5), (bbox.getMinX() - 0.5, bbox.getMaxY() + 0.5), (bbox.getMinX() - 0.5, bbox.getMinY() - 0.5)]) if self.nCR is not None: self.assertEqual(len(crs), self.nCR)
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))
def testDetection(self): """Test object detection""" # # Fix defects # # Mask known bad pixels # measAlgorithmsDir = lsst.utils.getPackageDir('meas_algorithms') badPixels = defects.policyToBadRegionList(os.path.join(measAlgorithmsDir, "policy/BadPixels.paf")) # did someone lie about the origin of the maskedImage? If so, adjust bad pixel list if self.XY0.getX() != self.mi.getX0() or self.XY0.getY() != self.mi.getY0(): dx = self.XY0.getX() - self.mi.getX0() dy = self.XY0.getY() - self.mi.getY0() for bp in badPixels: bp.shift(-dx, -dy) algorithms.interpolateOverDefects(self.mi, self.psf, badPixels) # # Subtract background # bgGridSize = 64 # was 256 ... but that gives only one region and the spline breaks bctrl = afwMath.BackgroundControl(afwMath.Interpolate.NATURAL_SPLINE) bctrl.setNxSample(int(self.mi.getWidth()/bgGridSize) + 1) bctrl.setNySample(int(self.mi.getHeight()/bgGridSize) + 1) backobj = afwMath.makeBackground(self.mi.getImage(), bctrl) self.mi.getImage()[:] -= backobj.getImageF() # # Remove CRs # crConfig = algorithms.FindCosmicRaysConfig() algorithms.findCosmicRays(self.mi, self.psf, 0, pexConfig.makePolicy(crConfig)) # # We do a pretty good job of interpolating, so don't propagagate the convolved CR/INTRP bits # (we'll keep them for the original CR/INTRP pixels) # savedMask = self.mi.getMask().Factory(self.mi.getMask(), True) saveBits = savedMask.getPlaneBitMask("CR") | \ savedMask.getPlaneBitMask("BAD") | \ savedMask.getPlaneBitMask("INTRP") # Bits to not convolve savedMask &= saveBits msk = self.mi.getMask() msk &= ~saveBits # Clear the saved bits del msk # # Smooth image # psf = algorithms.DoubleGaussianPsf(15, 15, self.FWHM/(2*math.sqrt(2*math.log(2)))) cnvImage = self.mi.Factory(self.mi.getBBox()) kernel = psf.getKernel() afwMath.convolve(cnvImage, self.mi, kernel, afwMath.ConvolutionControl()) msk = cnvImage.getMask() msk |= savedMask # restore the saved bits del msk threshold = afwDetection.Threshold(3, afwDetection.Threshold.STDEV) # # Only search the part of the frame that was PSF-smoothed # llc = lsst.geom.PointI(psf.getKernel().getWidth()//2, psf.getKernel().getHeight()//2) urc = lsst.geom.PointI(cnvImage.getWidth() - llc[0] - 1, cnvImage.getHeight() - llc[1] - 1) middle = cnvImage.Factory(cnvImage, lsst.geom.BoxI(llc, urc), afwImage.LOCAL) ds = afwDetection.FootprintSet(middle, threshold, "DETECTED") del middle # # Reinstate the saved (e.g. BAD) (and also the DETECTED | EDGE) bits in the unsmoothed image # savedMask[:] = cnvImage.getMask() msk = self.mi.getMask() msk |= savedMask del msk del savedMask if display: disp = afwDisplay.Display(frame=2) disp.mtv(self.mi, title=self._testMethodName + ": image") afwDisplay.Display(frame=3).mtv(cnvImage, title=self._testMethodName + ": cnvImage") # # Time to actually 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) self.exposure.setPsf(self.psf) task.run(measCat, self.exposure) self.assertGreater(len(measCat), 0) for source in measCat: if source.get("base_PixelFlags_flag_edge"): continue if display: disp.dot("+", source.getX(), source.getY())
class CosmicRayTestCase(unittest.TestCase): """A test case for Cosmic Ray detection""" def setUp(self): self.FWHM = 5 # pixels self.psf = algorithms.DoubleGaussianPsf( 29, 29, self.FWHM / (2 * sqrt(2 * log(2)))) self.mi = afwImage.MaskedImageF(imageFile) self.XY0 = afwGeom.PointI(0, 0) # origin of the subimage we use if imageFile == imageFile0: if True: # use full image, trimmed to data section self.XY0 = afwGeom.PointI(32, 2) self.mi = self.mi.Factory( self.mi, afwGeom.BoxI(self.XY0, afwGeom.PointI(2079, 4609)), afwImage.LOCAL) self.mi.setXY0(afwGeom.PointI(0, 0)) self.nCR = 1076 # number of CRs we should detect else: # use sub-image if True: self.XY0 = afwGeom.PointI(824, 140) self.nCR = 10 else: self.XY0 = afwGeom.PointI(280, 2750) self.nCR = 2 self.mi = self.mi.Factory( self.mi, afwGeom.BoxI(self.XY0, afwGeom.ExtentI(256, 256), afwImage.LOCAL)) self.mi.setXY0(afwGeom.PointI(0, 0)) else: self.nCR = None self.mi.getMask().addMaskPlane("DETECTED") def tearDown(self): del self.mi del self.psf def testDetection(self): """Test CR detection""" # # Subtract background # bctrl = afwMath.BackgroundControl(afwMath.Interpolate.NATURAL_SPLINE) bctrl.setNxSample(int(self.mi.getWidth() / 256) + 1) bctrl.setNySample(int(self.mi.getHeight() / 256) + 1) bctrl.getStatisticsControl().setNumSigmaClip(3.0) bctrl.getStatisticsControl().setNumIter(2) im = self.mi.getImage() try: backobj = afwMath.makeBackground(im, bctrl) except Exception, e: print >> sys.stderr, e, bctrl.setInterpStyle(afwMath.Interpolate.CONSTANT) backobj = afwMath.makeBackground(im, bctrl) im -= backobj.getImageF() if display: frame = 0 ds9.mtv(self.mi, frame=frame, title="Raw") # raw frame if self.mi.getWidth() > 256: ds9.pan(944 - self.mi.getX0(), 260 - self.mi.getY0()) # # Mask known bad pixels # badPixels = defects.policyToBadRegionList( os.path.join(os.environ["MEAS_ALGORITHMS_DIR"], "policy", "BadPixels.paf")) # did someone lie about the origin of the maskedImage? If so, adjust bad pixel list if self.XY0.getX() != self.mi.getX0() or self.XY0.getY( ) != self.mi.getY0(): dx = self.XY0.getX() - self.mi.getX0() dy = self.XY0.getY() - self.mi.getY0() for bp in badPixels: bp.shift(-dx, -dy) algorithms.interpolateOverDefects(self.mi, self.psf, badPixels) stats = afwMath.makeStatistics(self.mi.getImage(), afwMath.MEANCLIP | afwMath.STDEVCLIP) background = stats.getValue(afwMath.MEANCLIP) crConfig = algorithms.FindCosmicRaysConfig() crs = algorithms.findCosmicRays(self.mi, self.psf, background, pexConfig.makePolicy(crConfig)) if display: ds9.mtv(self.mi, frame=frame + 1, title="CRs removed") if self.mi.getWidth() > 256: ds9.pan(944 - self.mi.getX0(), 260 - self.mi.getY0()) print "Detected %d CRs" % len(crs) if display and False: for cr in crs: bbox = cr.getBBox() bbox.shift(afwGeom.ExtentI(-self.mi.getX0(), -self.mi.getY0())) ds9.line([(bbox.getMinX() - 0.5, bbox.getMinY() - 0.5), (bbox.getMaxX() + 0.5, bbox.getMinY() - 0.5), (bbox.getMaxX() + 0.5, bbox.getMaxY() + 0.5), (bbox.getMinX() - 0.5, bbox.getMaxY() + 0.5), (bbox.getMinX() - 0.5, bbox.getMinY() - 0.5)], frame=frame + 1) if self.nCR is not None: self.assertEqual(len(crs), self.nCR)
def testEdge(self): """Test that we can interpolate to the edge""" mi = afwImage.MaskedImageF(80, 30) ima = mi.getImage().getArray() # # Loop over number of bad columns at left or right edge of image # for nBadCol in range(0, 20): mi.set((0, 0x0, 0)) np.random.seed(666) ima[:] = np.random.uniform(-1, 1, ima.shape) defects = [] if nBadCol > 0: # # Bad left edge # ima[:, 0:nBadCol] = 10 defects.append(afwGeom.BoxI(afwGeom.PointI(0, 0), afwGeom.ExtentI(nBadCol, mi.getHeight()))) # # With another bad set of columns next to bad left edge # ima[:, -nBadCol:] = 10 defects.append(afwGeom.BoxI(afwGeom.PointI(mi.getWidth() - nBadCol, 0), afwGeom.ExtentI(nBadCol, mi.getHeight()))) # # Bad right edge # ima[0:10, nBadCol+1:nBadCol+4] = 100 defects.append(afwGeom.BoxI(afwGeom.PointI(nBadCol+1, 0), afwGeom.ExtentI(3, 10))) # # With another bad set of columns next to bad right edge # ima[0:10, -nBadCol-4:-nBadCol-1] = 100 defects.append((afwGeom.BoxI(afwGeom.PointI(mi.getWidth() - nBadCol - 4, 0), afwGeom.ExtentI(3, 10)))) # # Test cases that left and right bad patches nearly (or do) coalesce # ima[-3:, 0:mi.getWidth()//2-1] = 100 defects.append(afwGeom.BoxI(afwGeom.PointI(0, mi.getHeight() - 3), afwGeom.ExtentI(mi.getWidth()//2-1, 1))) ima[-3:, mi.getWidth()//2+1:] = 100 defects.append(afwGeom.BoxI(afwGeom.PointI(mi.getWidth()//2 + 1, mi.getHeight() - 3), afwGeom.ExtentI(mi.getWidth()//2 - 1, 1))) ima[-2:, 0:mi.getWidth()//2] = 100 defects.append(afwGeom.BoxI(afwGeom.PointI(0, mi.getHeight() - 2), afwGeom.ExtentI(mi.getWidth()//2, 1))) ima[-2:, mi.getWidth()//2+1:] = 100 defects.append(afwGeom.BoxI(afwGeom.PointI(mi.getWidth()//2 + 1, mi.getHeight() - 2), afwGeom.ExtentI(mi.getWidth()//2 - 1, 1))) ima[-1:, :] = 100 defects.append(afwGeom.BoxI(afwGeom.PointI(0, mi.getHeight() - 1), afwGeom.ExtentI(mi.getWidth(), 1))) # Test fix for HSC-978: long defect stops one pixel shy of the edge (when nBadCol == 0) ima[13, :-1] = 100 defects.append(afwGeom.BoxI(afwGeom.PointI(0, 13), afwGeom.ExtentI(mi.getWidth() - 1, 1))) ima[14, 1:] = 100 defects.append(afwGeom.BoxI(afwGeom.PointI(1, 14), afwGeom.ExtentI(mi.getWidth() - 1, 1))) # # Build list of defects to interpolate over # defectList = [] for bbox in defects: defectList.append(algorithms.Defect(bbox)) # # Guess a PSF and do the work # if display: ds9.mtv(mi, frame=0) psf = algorithms.DoubleGaussianPsf(15, 15, 1./(2*math.sqrt(2*math.log(2)))) algorithms.interpolateOverDefects(mi, psf, defectList, 0, True) if display: ds9.mtv(mi, frame=1) self.assertGreater(np.min(ima), -2) self.assertGreater(2, np.max(ima))
def testDetection(self): """Test CR detection.""" # # Subtract background # bctrl = afwMath.BackgroundControl(afwMath.Interpolate.NATURAL_SPLINE) bctrl.setNxSample(int(self.mi.getWidth()/256) + 1) bctrl.setNySample(int(self.mi.getHeight()/256) + 1) bctrl.getStatisticsControl().setNumSigmaClip(3.0) bctrl.getStatisticsControl().setNumIter(2) im = self.mi.getImage() try: backobj = afwMath.makeBackground(im, bctrl) except Exception as e: print(e, file=sys.stderr) bctrl.setInterpStyle(afwMath.Interpolate.CONSTANT) backobj = afwMath.makeBackground(im, bctrl) im -= backobj.getImageF() if display: frame = 0 disp = afwDisplay.Display(frame=frame) disp.mtv(self.mi, title=self._testMethodName + ": Raw") # raw frame if self.mi.getWidth() > 256: disp.pan(944 - self.mi.getX0(), 260 - self.mi.getY0()) # # Mask known bad pixels # measAlgorithmsDir = lsst.utils.getPackageDir('meas_algorithms') badPixels = defects.policyToBadRegionList(os.path.join(measAlgorithmsDir, "policy", "BadPixels.paf")) # did someone lie about the origin of the maskedImage? If so, adjust bad pixel list if self.XY0.getX() != self.mi.getX0() or self.XY0.getY() != self.mi.getY0(): dx = self.XY0.getX() - self.mi.getX0() dy = self.XY0.getY() - self.mi.getY0() for bp in badPixels: bp.shift(-dx, -dy) algorithms.interpolateOverDefects(self.mi, self.psf, badPixels) stats = afwMath.makeStatistics(self.mi.getImage(), afwMath.MEANCLIP | afwMath.STDEVCLIP) background = stats.getValue(afwMath.MEANCLIP) crConfig = algorithms.FindCosmicRaysConfig() crs = algorithms.findCosmicRays(self.mi, self.psf, background, pexConfig.makePolicy(crConfig)) if display: frame += 1 disp = afwDisplay.Display(frame=frame) disp.mtv(self.mi, title=self._testMethodName + ": CRs removed") if self.mi.getWidth() > 256: disp.pan(944 - self.mi.getX0(), 260 - self.mi.getY0()) print("Detected %d CRs" % len(crs)) if display and False: for cr in crs: bbox = cr.getBBox() bbox.shift(lsst.geom.ExtentI(-self.mi.getX0(), -self.mi.getY0())) disp.line([(bbox.getMinX() - 0.5, bbox.getMinY() - 0.5), (bbox.getMaxX() + 0.5, bbox.getMinY() - 0.5), (bbox.getMaxX() + 0.5, bbox.getMaxY() + 0.5), (bbox.getMinX() - 0.5, bbox.getMaxY() + 0.5), (bbox.getMinX() - 0.5, bbox.getMinY() - 0.5)]) if self.nCR is not None: self.assertEqual(len(crs), self.nCR)
def testDetection(self): """Test object detection""" # # Fix defects # # Mask known bad pixels # badPixels = defects.policyToBadRegionList(os.path.join(eups.productDir("meas_algorithms"), "policy/BadPixels.paf")) # did someone lie about the origin of the maskedImage? If so, adjust bad pixel list if self.XY0.getX() != self.mi.getX0() or self.XY0.getY() != self.mi.getY0(): dx = self.XY0.getX() - self.mi.getX0() dy = self.XY0.getY() - self.mi.getY0() for bp in badPixels: bp.shift(-dx, -dy) algorithms.interpolateOverDefects(self.mi, self.psf, badPixels) # # Subtract background # bgGridSize = 64 # was 256 ... but that gives only one region and the spline breaks bctrl = afwMath.BackgroundControl(afwMath.Interpolate.NATURAL_SPLINE); bctrl.setNxSample(int(self.mi.getWidth()/bgGridSize) + 1); bctrl.setNySample(int(self.mi.getHeight()/bgGridSize) + 1); backobj = afwMath.makeBackground(self.mi.getImage(), bctrl) img = self.mi.getImage(); img -= backobj.getImageF(); del img # # Remove CRs # crConfig = algorithms.FindCosmicRaysConfig() crs = algorithms.findCosmicRays(self.mi, self.psf, 0, pexConfig.makePolicy(crConfig)) # # We do a pretty good job of interpolating, so don't propagagate the convolved CR/INTRP bits # (we'll keep them for the original CR/INTRP pixels) # savedMask = self.mi.getMask().Factory(self.mi.getMask(), True) saveBits = savedMask.getPlaneBitMask("CR") | \ savedMask.getPlaneBitMask("BAD") | \ savedMask.getPlaneBitMask("INTRP") # Bits to not convolve savedMask &= saveBits msk = self.mi.getMask(); msk &= ~saveBits; del msk # Clear the saved bits # # Smooth image # FWHM = 5 psf = algorithms.DoubleGaussianPsf(15, 15, self.FWHM/(2*sqrt(2*log(2)))) cnvImage = self.mi.Factory(self.mi.getBBox(afwImage.PARENT)) kernel = psf.getKernel() afwMath.convolve(cnvImage, self.mi, kernel, afwMath.ConvolutionControl()) msk = cnvImage.getMask(); msk |= savedMask; del msk # restore the saved bits threshold = afwDetection.Threshold(3, afwDetection.Threshold.STDEV) # # Only search the part of the frame that was PSF-smoothed # llc = afwGeom.PointI(psf.getKernel().getWidth()/2, psf.getKernel().getHeight()/2) urc = afwGeom.PointI(cnvImage.getWidth() -llc[0] - 1, cnvImage.getHeight() - llc[1] - 1) middle = cnvImage.Factory(cnvImage, afwGeom.BoxI(llc, urc), afwImage.LOCAL) ds = afwDetection.FootprintSet(middle, threshold, "DETECTED") del middle # # Reinstate the saved (e.g. BAD) (and also the DETECTED | EDGE) bits in the unsmoothed image # savedMask <<= cnvImage.getMask() msk = self.mi.getMask(); msk |= savedMask; del msk del savedMask if display: ds9.mtv(self.mi, frame = 0) ds9.mtv(cnvImage, frame = 1) # # Time to actually measure # measureSourcesConfig = algorithms.SourceMeasurementConfig() measureSourcesConfig.load("tests/config/MeasureSources.py") schema = afwTable.SourceTable.makeMinimalSchema() ms = measureSourcesConfig.makeMeasureSources(schema) catalog = afwTable.SourceCatalog(schema) measureSourcesConfig.slots.calibFlux = None measureSourcesConfig.slots.setupTable(catalog.table) ds.makeSources(catalog) for source in catalog: # NOTE: this was effectively failing on master, because an exception was being squashed ms.applyWithPeak(source, self.exposure) if source.get("flags.pixel.edge"): continue if display: ds9.dot("+", source.getX() - self.mi.getX0(), source.getY() - self.mi.getY0())
def testEdge(self): """Test that we can interpolate to the edge""" mi = afwImage.MaskedImageF(80, 30) ima = mi.getImage().getArray() # # Loop over number of bad columns at left or right edge of image # for nBadCol in range(0, 20): mi.set((0, 0x0, 0)) np.random.seed(666) ima[:] = np.random.uniform(-1, 1, ima.shape) defects = [] if nBadCol > 0: # # Bad left edge # ima[:, 0:nBadCol] = 10 defects.append(lsst.geom.BoxI(lsst.geom.PointI(0, 0), lsst.geom.ExtentI(nBadCol, mi.getHeight()))) # # With another bad set of columns next to bad left edge # ima[:, -nBadCol:] = 10 defects.append(lsst.geom.BoxI(lsst.geom.PointI(mi.getWidth() - nBadCol, 0), lsst.geom.ExtentI(nBadCol, mi.getHeight()))) # # Bad right edge # ima[0:10, nBadCol+1:nBadCol+4] = 100 defects.append(lsst.geom.BoxI(lsst.geom.PointI(nBadCol+1, 0), lsst.geom.ExtentI(3, 10))) # # With another bad set of columns next to bad right edge # ima[0:10, -nBadCol-4:-nBadCol-1] = 100 defects.append((lsst.geom.BoxI(lsst.geom.PointI(mi.getWidth() - nBadCol - 4, 0), lsst.geom.ExtentI(3, 10)))) # # Test cases that left and right bad patches nearly (or do) coalesce # ima[-3:, 0:mi.getWidth()//2-1] = 100 defects.append(lsst.geom.BoxI(lsst.geom.PointI(0, mi.getHeight() - 3), lsst.geom.ExtentI(mi.getWidth()//2-1, 1))) ima[-3:, mi.getWidth()//2+1:] = 100 defects.append(lsst.geom.BoxI(lsst.geom.PointI(mi.getWidth()//2 + 1, mi.getHeight() - 3), lsst.geom.ExtentI(mi.getWidth()//2 - 1, 1))) ima[-2:, 0:mi.getWidth()//2] = 100 defects.append(lsst.geom.BoxI(lsst.geom.PointI(0, mi.getHeight() - 2), lsst.geom.ExtentI(mi.getWidth()//2, 1))) ima[-2:, mi.getWidth()//2+1:] = 100 defects.append(lsst.geom.BoxI(lsst.geom.PointI(mi.getWidth()//2 + 1, mi.getHeight() - 2), lsst.geom.ExtentI(mi.getWidth()//2 - 1, 1))) ima[-1:, :] = 100 defects.append(lsst.geom.BoxI(lsst.geom.PointI(0, mi.getHeight() - 1), lsst.geom.ExtentI(mi.getWidth(), 1))) # Test fix for HSC-978: long defect stops one pixel shy of the edge (when nBadCol == 0) ima[13, :-1] = 100 defects.append(lsst.geom.BoxI(lsst.geom.PointI(0, 13), lsst.geom.ExtentI(mi.getWidth() - 1, 1))) ima[14, 1:] = 100 defects.append(lsst.geom.BoxI(lsst.geom.PointI(1, 14), lsst.geom.ExtentI(mi.getWidth() - 1, 1))) # # Build list of defects to interpolate over # defectList = algorithms.Defects() for bbox in defects: defectList.append(algorithms.Defect(bbox)) # # Guess a PSF and do the work # if display: afwDisplay.Display(frame=2).mtv(mi, title=self._testMethodName + ": image") psf = algorithms.DoubleGaussianPsf(15, 15, 1./(2*math.sqrt(2*math.log(2)))) algorithms.interpolateOverDefects(mi, psf, defectList, 0, True) if display: afwDisplay.Display(frame=3).mtv(mi, title=self._testMethodName + ": image") self.assertGreater(np.min(ima), -2) self.assertGreater(2, np.max(ima))
def testDetection(self): """Test CR detection.""" # # Subtract background # bctrl = afwMath.BackgroundControl(afwMath.Interpolate.NATURAL_SPLINE) bctrl.setNxSample(int(self.mi.getWidth() / 256) + 1) bctrl.setNySample(int(self.mi.getHeight() / 256) + 1) bctrl.getStatisticsControl().setNumSigmaClip(3.0) bctrl.getStatisticsControl().setNumIter(2) im = self.mi.getImage() try: backobj = afwMath.makeBackground(im, bctrl) except Exception as e: print(e, file=sys.stderr) bctrl.setInterpStyle(afwMath.Interpolate.CONSTANT) backobj = afwMath.makeBackground(im, bctrl) im -= backobj.getImageF() if display: frame = 0 disp = afwDisplay.Display(frame=frame) disp.mtv(self.mi, title=self._testMethodName + ": Raw") # raw frame if self.mi.getWidth() > 256: disp.pan(944 - self.mi.getX0(), 260 - self.mi.getY0()) # # Mask known bad pixels # measAlgorithmsDir = lsst.utils.getPackageDir('meas_algorithms') badPixels = defects.policyToBadRegionList( os.path.join(measAlgorithmsDir, "policy", "BadPixels.paf")) # did someone lie about the origin of the maskedImage? If so, adjust bad pixel list if self.XY0.getX() != self.mi.getX0() or self.XY0.getY( ) != self.mi.getY0(): dx = self.XY0.getX() - self.mi.getX0() dy = self.XY0.getY() - self.mi.getY0() for bp in badPixels: bp.shift(-dx, -dy) algorithms.interpolateOverDefects(self.mi, self.psf, badPixels) stats = afwMath.makeStatistics(self.mi.getImage(), afwMath.MEANCLIP | afwMath.STDEVCLIP) background = stats.getValue(afwMath.MEANCLIP) crConfig = algorithms.FindCosmicRaysConfig() crs = algorithms.findCosmicRays(self.mi, self.psf, background, pexConfig.makePolicy(crConfig)) if display: frame += 1 disp = afwDisplay.Display(frame=frame) disp.mtv(self.mi, title=self._testMethodName + ": CRs removed") if self.mi.getWidth() > 256: disp.pan(944 - self.mi.getX0(), 260 - self.mi.getY0()) print("Detected %d CRs" % len(crs)) if display and False: for cr in crs: bbox = cr.getBBox() bbox.shift( lsst.geom.ExtentI(-self.mi.getX0(), -self.mi.getY0())) disp.line([(bbox.getMinX() - 0.5, bbox.getMinY() - 0.5), (bbox.getMaxX() + 0.5, bbox.getMinY() - 0.5), (bbox.getMaxX() + 0.5, bbox.getMaxY() + 0.5), (bbox.getMinX() - 0.5, bbox.getMaxY() + 0.5), (bbox.getMinX() - 0.5, bbox.getMinY() - 0.5)]) if self.nCR is not None: self.assertEqual(len(crs), self.nCR)
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))