def makeThresholdMask(maskedImage, threshold, growFootprints=1, maskName='SAT'): """Mask pixels based on threshold detection. Parameters ---------- maskedImage : `lsst.afw.image.MaskedImage` Image to process. Only the mask plane is updated. threshold : scalar Detection threshold. growFootprints : scalar, optional Number of pixels to grow footprints of detected regions. maskName : str, optional Mask plane name, or list of names to convert Returns ------- defectList : `lsst.meas.algorithms.Defects` Defect list constructed from pixels above the threshold. """ # find saturated regions thresh = afwDetection.Threshold(threshold) fs = afwDetection.FootprintSet(maskedImage, thresh) if growFootprints > 0: fs = afwDetection.FootprintSet(fs, rGrow=growFootprints, isotropic=False) fpList = fs.getFootprints() # set mask mask = maskedImage.getMask() bitmask = mask.getPlaneBitMask(maskName) afwDetection.setMaskFromFootprintList(mask, fpList, bitmask) return Defects.fromFootprintList(fpList)
def cosmicray(exp, config, display=False): bg = 0.0 # We background-subtracted, right? crList = measAlg.findCosmicRays(exp.getMaskedImage(), exp.getPsf(), bg, makePolicy(config), True) if crList is None: print "No CRs found" return mask = exp.getMaskedImage().getMask() crBit = mask.getPlaneBitMask("CR") afwDet.setMaskFromFootprintList(mask, crList, crBit) num = len(crList) print "Found %d CRs" % num if display: frame = 2 import lsst.afw.display.ds9 as ds9 import lsst.afw.display.utils as displayUtils ds9.mtv(exp, title="Exposure with CRs") with ds9.Buffering(): for cr in crList: displayUtils.drawBBox(cr.getBBox(), borderWidth=0.55)
def testMergeFootprints(self): # YYYY """Merge positive and negative Footprints""" x0, y0 = 5, 6 dwidth, dheight = 6, 7 def callback(): x, y, I = x0 + 10, y0 + 4, -20 self.im.getImage().set(x, y, I) peaks2.append((x, y, I)) for grow1, grow2 in [(1, 1), (3, 3), (6, 6), ]: peaks2 = [] self.doTestPeaks(threshold=10, callback=callback, grow=0, x0=x0, y0=y0, dwidth=dwidth, dheight=dheight) threshold = afwDetect.Threshold(10, afwDetect.Threshold.VALUE, False) fs2 = afwDetect.FootprintSet(self.im, threshold) msk = self.im.getMask() afwDetect.setMaskFromFootprintList(msk, fs2.getFootprints(), msk.getPlaneBitMask("DETECTED_NEGATIVE")) self.fs.merge(fs2, grow1, grow2) self.peaks[-2] += peaks2 if grow1 + grow2 > 2: # grow merged all peaks self.peaks[0] = sorted(sum(self.peaks, []), lambda x, y: cmpPeaks(self.im, x, y)) afwDetect.setMaskFromFootprintList(msk, self.fs.getFootprints(), msk.getPlaneBitMask("EDGE")) self.checkPeaks(frame=3)
def testGrowLRUD2(self): """Grow footprints in various directions using the FootprintSet/FootprintControl constructor Check that overlapping grown Footprints give the expected answers """ ngrow = 3 # How much to grow by for fctrl, xy in [ (afwDetect.FootprintControl(True, True, False, False), [(4, 5), (5, 6), (6, 5)]), (afwDetect.FootprintControl(False, False, True, True), [(5, 4), (6, 5), (5, 6)]), ]: im = afwImage.MaskedImageF(11, 11) for x, y in xy: im[x, y, afwImage.LOCAL] = (10, 0x0, 0.0) fs = afwDetect.FootprintSet(im, afwDetect.Threshold(10)) self.assertEqual(len(fs.getFootprints()), 1) grown = afwDetect.FootprintSet(fs, ngrow, fctrl) im.getMask().set(0) afwDetect.setMaskFromFootprintList(im.getMask(), grown.getFootprints(), 0x10) if display: ds9.mtv(im) self.assertEqual(len(grown.getFootprints()), 1) foot = grown.getFootprints()[0] npix = 1 + 2 * ngrow npix += 3 + 2 * ngrow # 3: distance between pair of set pixels 000X0X000 self.assertEqual(foot.getArea(), npix)
def testGrowCircular(self): """Grow footprints in all 4 directions using the FootprintSet/FootprintControl constructor """ im = afwImage.MaskedImageF(11, 11) im[5, 5, afwImage.LOCAL] = (10, 0x0, 0.0) fs = afwDetect.FootprintSet(im, afwDetect.Threshold(10)) self.assertEqual(len(fs.getFootprints()), 1) radius = 3 # How much to grow by for fctrl in ( afwDetect.FootprintControl(), afwDetect.FootprintControl(True), afwDetect.FootprintControl(True, True), ): grown = afwDetect.FootprintSet(fs, radius, fctrl) afwDetect.setMaskFromFootprintList(im.getMask(), grown.getFootprints(), 0x10) if display: ds9.mtv(im) foot = grown.getFootprints()[0] if not fctrl.isCircular()[0]: self.assertEqual(foot.getArea(), 1) elif fctrl.isCircular()[0]: assert radius == 3 if fctrl.isIsotropic()[1]: self.assertEqual(foot.getArea(), 29) else: self.assertEqual(foot.getArea(), 25)
def testGrowCircular(self): """Grow footprints in all 4 directions using the FootprintSet/FootprintControl constructor """ im = afwImage.MaskedImageF(11, 11) im[5, 5, afwImage.LOCAL] = (10, 0x0, 0.0) fs = afwDetect.FootprintSet(im, afwDetect.Threshold(10)) self.assertEqual(len(fs.getFootprints()), 1) radius = 3 # How much to grow by for fctrl in (afwDetect.FootprintControl(), afwDetect.FootprintControl(True), afwDetect.FootprintControl(True, True), ): grown = afwDetect.FootprintSet(fs, radius, fctrl) afwDetect.setMaskFromFootprintList( im.getMask(), grown.getFootprints(), 0x10) if display: afwDisplay.Display(frame=3).mtv(im, title=self._testMethodName + " image") foot = grown.getFootprints()[0] if not fctrl.isCircular()[0]: self.assertEqual(foot.getArea(), 1) elif fctrl.isCircular()[0]: assert radius == 3 if fctrl.isIsotropic()[1]: self.assertEqual(foot.getArea(), 29) else: self.assertEqual(foot.getArea(), 25)
def testGrowCircular(self): """Grow footprints in all 4 directions using the FootprintSet/FootprintControl constructor """ im = afwImage.MaskedImageF(11, 11) im.set(5, 5, (10,)) fs = afwDetect.FootprintSet(im, afwDetect.Threshold(10)) self.assertEqual(len(fs.getFootprints()), 1) radius = 3 # How much to grow by for fctrl in ( afwDetect.FootprintControl(), afwDetect.FootprintControl(True), afwDetect.FootprintControl(True, True), ): grown = afwDetect.FootprintSet(fs, radius, fctrl) afwDetect.setMaskFromFootprintList(im.getMask(), grown.getFootprints(), 0x10) if display: ds9.mtv(im) foot = grown.getFootprints()[0] if not fctrl.isCircular()[0]: self.assertEqual(foot.getNpix(), 1) elif fctrl.isCircular()[0]: assert radius == 3 if fctrl.isIsotropic()[1]: self.assertEqual(foot.getNpix(), 29) else: self.assertEqual(foot.getNpix(), 25)
def makeThresholdMask(maskedImage, threshold, growFootprints=1, maskName='SAT'): """Mask pixels based on threshold detection @param[in,out] maskedImage afw.image.MaskedImage to process; the mask is altered @param[in] threshold detection threshold @param[in] growFootprints amount by which to grow footprints of detected regions @param[in] maskName mask plane name @return a list of defects (meas.algrithms.Defect) of regions set in the mask. """ # find saturated regions thresh = afwDetection.Threshold(threshold) fs = afwDetection.FootprintSet(maskedImage, thresh) if growFootprints > 0: fs = afwDetection.FootprintSet(fs, growFootprints) fpList = fs.getFootprints() # set mask mask = maskedImage.getMask() bitmask = mask.getPlaneBitMask(maskName) afwDetection.setMaskFromFootprintList(mask, fpList, bitmask) return defectListFromFootprintList(fpList, growFootprints=0)
def cr(infn, crfn, maskfn): exposure = afwImage.ExposureF(infn) #'850994p-21.fits' print 'exposure', exposure print 'w,h', exposure.getWidth(), exposure.getHeight() W,H = exposure.getWidth(), exposure.getHeight() #var = exposure.getMaskedImage().getVariance() #print 'Variance', var.get(0,0) wcs = exposure.getWcs() print 'wcs', wcs pixscale = wcs.pixelScale().asArcseconds() psf = getFakePsf(pixscale) # CRs mask = exposure.getMaskedImage().getMask() crBit = mask.getMaskPlane("CR") mask.clearMaskPlane(crBit) mi = exposure.getMaskedImage() bg = afwMath.makeStatistics(mi, afwMath.MEDIAN).getValue() print 'bg', bg varval = afwMath.makeStatistics(mi, afwMath.VARIANCE).getValue() print 'variance', varval, 'std', math.sqrt(varval) varval = afwMath.makeStatistics(mi, afwMath.VARIANCECLIP).getValue() print 'clipped variance', varval, 'std', math.sqrt(varval) var = exposure.getMaskedImage().getVariance() var.set(varval) var = exposure.getMaskedImage().getVariance() print 'Variance:', var.get(0,0) keepCRs = False policy = pexPolicy.Policy() # policy.add('minSigma', 6.) # policy.add('min_DN', 150.) # policy.add('cond3_fac', 2.5) # policy.add('cond3_fac2', 0.6) # policy.add('niteration', 3) # policy.add('nCrPixelMax', 200000) policy.add('minSigma', 10.) policy.add('min_DN', 500.) policy.add('cond3_fac', 2.5) policy.add('cond3_fac2', 0.6) policy.add('niteration', 1) policy.add('nCrPixelMax', 100000) #psfimg = psf.computeImage(afwGeom.Point2D(W/2., H/2.)) #psfimg.writeFits('psf.fits') print 'Finding cosmics...' crs = measAlg.findCosmicRays(mi, psf, bg, policy, keepCRs) print 'got', len(crs), 'cosmic rays', mask = mi.getMask() crBit = mask.getPlaneBitMask("CR") afwDet.setMaskFromFootprintList(mask, crs, crBit) mask.writeFits(maskfn) exposure.writeFits(crfn)
def doTestPeaks(self, dwidth=0, dheight=0, x0=0, y0=0, threshold=10, callback=None, polarity=True, grow=0): """Worker routine for tests polarity: True if should search for +ve pixels""" self.doSetUp(dwidth, dheight, x0, y0) if not polarity: self.im *= -1 if callback: callback() def peakDescending(p): """Sort self.peaks in decreasing peak height to match Footprint.getPeaks()""" return p[2]*-1.0 for i, peaks in enumerate(self.peaks): self.peaks[i] = sorted([(x, y, self.im.getImage()[x, y, afwImage.LOCAL]) for x, y in peaks], key=peakDescending) threshold = afwDetect.Threshold( threshold, afwDetect.Threshold.VALUE, polarity) fs = afwDetect.FootprintSet(self.im, threshold, "BINNED1") if grow: fs = afwDetect.FootprintSet(fs, grow, True) msk = self.im.getMask() afwDetect.setMaskFromFootprintList( msk, fs.getFootprints(), msk.getPlaneBitMask("DETECTED")) del msk self.fs = fs self.checkPeaks(dwidth, dheight, frame=3)
def testMergeFootprints(self): """Merge positive and negative Footprints""" x0, y0 = 5, 6 dwidth, dheight = 6, 7 def callback(): x, y, I = x0 + 10, y0 + 4, -20 self.im.getImage().set(x, y, I) peaks2.append((x, y, I)) for grow1, grow2 in [(1, 1), (3, 3), (6, 6), ]: peaks2 = [] self.doTestPeaks(threshold=10, callback=callback, grow=0, x0=x0, y0=y0, dwidth=dwidth, dheight=dheight) threshold = afwDetect.Threshold(10, afwDetect.Threshold.VALUE, False) fs2 = afwDetect.makeFootprintSet(self.im, threshold) msk = self.im.getMask() afwDetect.setMaskFromFootprintList(msk, fs2.getFootprints(), msk.getPlaneBitMask("DETECTED_NEGATIVE")) self.fs.merge(fs2, grow1, grow2) self.peaks[-2] += peaks2 if grow1 + grow2 > 2: # grow merged all peaks self.peaks[0] = sorted(sum(self.peaks, []), lambda x, y: cmpPeaks(self.im, x, y)) afwDetect.setMaskFromFootprintList(msk, self.fs.getFootprints(), msk.getPlaneBitMask("EDGE")) self.checkPeaks(frame=3)
def testMergeFootprintsEngulf(self): """Merge two Footprints when growing one Footprint totally replaces the other""" def callback(): self.im.set(0) self.peaks, self.objects = [], [] for x, y, I in [[6, 4, 20], [6, 5, 10]]: self.im.getImage().set(x, y, I) self.peaks.append([[6, 4]]) x, y, I = 8, 4, -20 self.im.getImage().set(x, y, I) peaks2.append((x, y, I)) grow1, grow2 = 0, 3 peaks2 = [] self.doTestPeaks(threshold=10, callback=callback, grow=0) threshold = afwDetect.Threshold(10, afwDetect.Threshold.VALUE, False) fs2 = afwDetect.makeFootprintSet(self.im, threshold) msk = self.im.getMask() afwDetect.setMaskFromFootprintList(msk, fs2.getFootprints(), msk.getPlaneBitMask("DETECTED_NEGATIVE")) self.fs.merge(fs2, grow1, grow2) self.peaks[0] += peaks2 self.peaks[0] = sorted(sum(self.peaks, []), lambda x, y: cmpPeaks(self.im, x, y)) afwDetect.setMaskFromFootprintList(msk, self.fs.getFootprints(), msk.getPlaneBitMask("EDGE")) self.checkPeaks(frame=3)
def run(self, inputExp): """Preprocess input exposures prior to FRINGE combination. This task scales and renormalizes the input frame based on the image background, and then masks all pixels above the detection threshold. Parameters ---------- inputExp : `lsst.afw.image.Exposure` Pre-processed fringe frame data to combine. Returns ------- outputExp : `lsst.afw.image.Exposure` Fringe pre-processed frame. """ bg = self.stats.run(inputExp) self.subtractBackground.run(inputExp) mi = inputExp.getMaskedImage() mi /= bg fpSets = self.detection.detectFootprints(inputExp, sigma=self.config.detectSigma) mask = mi.getMask() detected = 1 << mask.addMaskPlane("DETECTED") for fpSet in (fpSets.positive, fpSets.negative): if fpSet is not None: afwDet.setMaskFromFootprintList(mask, fpSet.getFootprints(), detected) return pipeBase.Struct(outputExp=inputExp, )
def cr(infn, crfn, maskfn): exposure = afwImage.ExposureF(infn) #'850994p-21.fits' print 'exposure', exposure print 'w,h', exposure.getWidth(), exposure.getHeight() W, H = exposure.getWidth(), exposure.getHeight() #var = exposure.getMaskedImage().getVariance() #print 'Variance', var.get(0,0) wcs = exposure.getWcs() print 'wcs', wcs pixscale = wcs.pixelScale().asArcseconds() psf = getFakePsf(pixscale) # CRs mask = exposure.getMaskedImage().getMask() crBit = mask.getMaskPlane("CR") mask.clearMaskPlane(crBit) mi = exposure.getMaskedImage() bg = afwMath.makeStatistics(mi, afwMath.MEDIAN).getValue() print 'bg', bg varval = afwMath.makeStatistics(mi, afwMath.VARIANCE).getValue() print 'variance', varval, 'std', math.sqrt(varval) varval = afwMath.makeStatistics(mi, afwMath.VARIANCECLIP).getValue() print 'clipped variance', varval, 'std', math.sqrt(varval) var = exposure.getMaskedImage().getVariance() var.set(varval) var = exposure.getMaskedImage().getVariance() print 'Variance:', var.get(0, 0) keepCRs = False policy = pexPolicy.Policy() # policy.add('minSigma', 6.) # policy.add('min_DN', 150.) # policy.add('cond3_fac', 2.5) # policy.add('cond3_fac2', 0.6) # policy.add('niteration', 3) # policy.add('nCrPixelMax', 200000) policy.add('minSigma', 10.) policy.add('min_DN', 500.) policy.add('cond3_fac', 2.5) policy.add('cond3_fac2', 0.6) policy.add('niteration', 1) policy.add('nCrPixelMax', 100000) #psfimg = psf.computeImage(afwGeom.Point2D(W/2., H/2.)) #psfimg.writeFits('psf.fits') print 'Finding cosmics...' crs = measAlg.findCosmicRays(mi, psf, bg, policy, keepCRs) print 'got', len(crs), 'cosmic rays', mask = mi.getMask() crBit = mask.getPlaneBitMask("CR") afwDet.setMaskFromFootprintList(mask, crs, crBit) mask.writeFits(maskfn) exposure.writeFits(crfn)
def makeThresholdMask(maskedImage, threshold, growFootprints=1, maskName='SAT'): """Mask pixels based on threshold detection. Parameters ---------- maskedImage : `lsst.afw.image.MaskedImage` Image to process. Only the mask plane is updated. threshold : scalar Detection threshold. growFootprints : scalar, optional Number of pixels to grow footprints of detected regions. maskName : str, optional Mask plane name, or list of names to convert Returns ------- defectList : `lsst.meas.algorithms.Defects` Defect list constructed from pixels above the threshold. """ # find saturated regions thresh = afwDetection.Threshold(threshold) fs = afwDetection.FootprintSet(maskedImage, thresh) if growFootprints > 0: fs = afwDetection.FootprintSet(fs, rGrow=growFootprints, isotropic=False) fpList = fs.getFootprints() # set mask mask = maskedImage.getMask() bitmask = mask.getPlaneBitMask(maskName) afwDetection.setMaskFromFootprintList(mask, fpList, bitmask) return measAlg.Defects.fromFootprintList(fpList)
def testMergeFootprints(self): # YYYY """Merge positive and negative Footprints""" x0, y0 = 5, 6 dwidth, dheight = 6, 7 def callback(): x, y, value = x0 + 10, y0 + 4, -20 self.im.getImage()[x, y, afwImage.LOCAL] = value peaks2.append((x, y, value)) for grow1, grow2 in [(1, 1), (3, 3), (6, 6), ]: peaks2 = [] self.doTestPeaks(threshold=10, callback=callback, grow=0, x0=x0, y0=y0, dwidth=dwidth, dheight=dheight) threshold = afwDetect.Threshold( 10, afwDetect.Threshold.VALUE, False) fs2 = afwDetect.FootprintSet(self.im, threshold) msk = self.im.getMask() afwDetect.setMaskFromFootprintList( msk, fs2.getFootprints(), msk.getPlaneBitMask("DETECTED_NEGATIVE")) self.fs.merge(fs2, grow1, grow2) self.peaks[-2] += peaks2 if grow1 + grow2 > 2: # grow merged all peaks def peaksSortKey(p): return peakFromImage(self.im, p) self.peaks[0] = sorted(sum(self.peaks, []), key=peaksSortKey) afwDetect.setMaskFromFootprintList( msk, self.fs.getFootprints(), msk.getPlaneBitMask("EDGE")) self.checkPeaks(frame=3)
def doTestPeaks(self, dwidth=0, dheight=0, x0=0, y0=0, threshold=10, callback=None, polarity=True, grow=0): """Worker routine for tests polarity: True if should search for +ve pixels""" self.doSetUp(dwidth, dheight, x0, y0) if not polarity: self.im *= -1 if callback: callback() # # Sort self.peaks in decreasing peak height to match Footprint.getPeaks() # for i, peaks in enumerate(self.peaks): self.peaks[i] = sorted([(x, y, self.im.getImage().get(x, y)) for x, y in peaks], lambda x, y: cmpPeaks(self.im, x, y)) threshold = afwDetect.Threshold(threshold, afwDetect.Threshold.VALUE, polarity) fs = afwDetect.FootprintSet(self.im, threshold, "BINNED1") if grow: fs = afwDetect.FootprintSet(fs, grow, True) msk = self.im.getMask() afwDetect.setMaskFromFootprintList(msk, fs.getFootprints(), msk.getPlaneBitMask("DETECTED")) del msk self.fs = fs self.checkPeaks(dwidth, dheight, frame=3)
def testGrowLRUD2(self): """Grow footprints in various directions using the FootprintSet/FootprintControl constructor Check that overlapping grown Footprints give the expected answers """ ngrow = 3 # How much to grow by for fctrl, xy in [ (afwDetect.FootprintControl(True, True, False, False), [(4, 5), (5, 6), (6, 5)]), (afwDetect.FootprintControl(False, False, True, True), [(5, 4), (6, 5), (5, 6)]), ]: im = afwImage.MaskedImageF(11, 11) for x, y in xy: im[x, y, afwImage.LOCAL] = (10, 0x0, 0.0) fs = afwDetect.FootprintSet(im, afwDetect.Threshold(10)) self.assertEqual(len(fs.getFootprints()), 1) grown = afwDetect.FootprintSet(fs, ngrow, fctrl) im.getMask().set(0) afwDetect.setMaskFromFootprintList( im.getMask(), grown.getFootprints(), 0x10) if display: afwDisplay.Display(frame=1).mtv(im, title=self._testMethodName + " image") self.assertEqual(len(grown.getFootprints()), 1) foot = grown.getFootprints()[0] npix = 1 + 2*ngrow npix += 3 + 2*ngrow # 3: distance between pair of set pixels 000X0X000 self.assertEqual(foot.getArea(), npix)
def testMergeFootprintsEngulf(self): """Merge two Footprints when growing one Footprint totally replaces the other""" def callback(): self.im.set(0) self.peaks, self.objects = [], [] for x, y, I in [[6, 4, 20], [6, 5, 10]]: self.im.getImage().set(x, y, I) self.peaks.append([[6, 4]]) x, y, I = 8, 4, -20 self.im.getImage().set(x, y, I) peaks2.append((x, y, I)) grow1, grow2 = 0, 3 peaks2 = [] self.doTestPeaks(threshold=10, callback=callback, grow=0) threshold = afwDetect.Threshold(10, afwDetect.Threshold.VALUE, False) fs2 = afwDetect.FootprintSet(self.im, threshold) msk = self.im.getMask() afwDetect.setMaskFromFootprintList( msk, fs2.getFootprints(), msk.getPlaneBitMask("DETECTED_NEGATIVE")) self.fs.merge(fs2, grow1, grow2) self.peaks[0] += peaks2 self.peaks[0] = sorted(sum(self.peaks, []), lambda x, y: cmpPeaks(self.im, x, y)) afwDetect.setMaskFromFootprintList(msk, self.fs.getFootprints(), msk.getPlaneBitMask("EDGE")) self.checkPeaks(frame=3)
def testGrowFootprints3(self): """Test that we can grow footprints, correctly merging those that now totally overwritten""" self.im = afwImage.MaskedImageF(14, 11) self.im.getImage().set(0) self.peaks = [] value = 11 for x, y in [(4, 7), (5, 7), (6, 7), (7, 7), (8, 7), (4, 6), (8, 6), (4, 5), (8, 5), (4, 4), (8, 4), (4, 3), (8, 3), ]: self.im.getImage()[x, y, afwImage.LOCAL] = value value -= 1e-3 self.im.getImage()[4, 7, afwImage.LOCAL] = 15 self.peaks.append([(4, 7,), ]) self.im.getImage()[6, 5, afwImage.LOCAL] = 30 self.peaks[0].append((6, 5,)) self.fs = afwDetect.FootprintSet( self.im, afwDetect.Threshold(10), "BINNED1") # # The disappearing Footprint special case only shows up if the outer Footprint is grown # _after_ the inner one. So arrange the order properly feet = self.fs.getFootprints() feet[0], feet[1] = feet[1], feet[0] msk = self.im.getMask() grow = 2 self.fs = afwDetect.FootprintSet(self.fs, grow, False) afwDetect.setMaskFromFootprintList(msk, self.fs.getFootprints(), msk.getPlaneBitMask("DETECTED_NEGATIVE")) if display: frame = 0 disp = afwDisplay.Display(frame=frame) disp.mtv(self.im, title=self._testMethodName + " image") with disp.Buffering(): for i, foot in enumerate(self.fs.getFootprints()): for p in foot.getPeaks(): disp.dot("+", p.getIx(), p.getIy(), size=0.4) if i < len(self.peaks): for trueX, trueY in self.peaks[i]: disp.dot("x", trueX, trueY, size=0.4, ctype=afwDisplay.RED) self.assertEqual(len(self.fs.getFootprints()), 1) self.assertEqual(len(self.fs.getFootprints()[ 0].getPeaks()), len(self.peaks[0]))
def run(frame=6): im = afwImage.MaskedImageF(afwGeom.Extent2I(14, 10)) # # Populate the image with objects that we should detect # objects = [] objects.append([(4, 1, 10), (3, 2, 10), (4, 2, 20), (5, 2, 10), (4, 3, 10),]) objects.append([(9, 7, 30), (10, 7, 29), (12, 7, 28), (10, 8, 27), (11, 8, 26), (10, 4, -5)]) objects.append([(3, 8, 10), (4, 8, 10),]) for obj in objects: for x, y, I in obj: im.getImage().set(x, y, I) im.getVariance().set(1) im.getVariance().set(10, 4, 0.5**2) # # Detect the objects at 10 counts or above # level = 10 fs = afwDetect.FootprintSet(im, afwDetect.Threshold(level), "DETECTED") showPeaks(im, fs, frame=frame) # # Detect the objects at -10 counts or below. N.b. the peak's at -5, so it isn't detected # polarity = False # look for objects below background threshold = afwDetect.Threshold(level, afwDetect.Threshold.VALUE, polarity) fs2 = afwDetect.FootprintSet(im, threshold, "DETECTED_NEGATIVE") print("Detected %d objects below background" % len(fs2.getFootprints())) # # Search in S/N (n.b. the peak's -10sigma) # threshold = afwDetect.Threshold(level, afwDetect.Threshold.PIXEL_STDEV, polarity) fs2 = afwDetect.FootprintSet(im, threshold) # # Here's another way to set a mask plane (we chose not to do so in the FootprintSet call) # msk = im.getMask() afwDetect.setMaskFromFootprintList(msk, fs2.getFootprints(), msk.getPlaneBitMask("DETECTED_NEGATIVE")) if frame is not None: ds9.mtv(msk, isMask=True, frame=frame) # # Merge the positive and negative detections, growing both sets by 1 pixel # fs.merge(fs2, 1, 1) # # Set EDGE so we can see the grown Footprints # afwDetect.setMaskFromFootprintList(msk, fs.getFootprints(), msk.getPlaneBitMask("EDGE")) if frame is not None: ds9.mtv(msk, isMask=True, frame=frame) showPeaks(fs=fs, frame=frame)
def testSetFromFootprint(self): """Test setting mask/image pixels from a Footprint list""" mi = afwImage.MaskedImageF(lsst.geom.Extent2I(12, 8)) im = mi.getImage() # # Objects that we should detect # self.objects = [] self.objects += [Object(10, [(1, 4, 4), (2, 3, 5), (3, 4, 4)])] self.objects += [Object(20, [(5, 7, 8), (5, 10, 10), (6, 8, 9)])] self.objects += [Object(20, [(6, 3, 3)])] im.set(0) # clear image for obj in self.objects: obj.insert(im) if False and display: ds9.mtv(mi, frame=0) ds = afwDetect.FootprintSet(mi, afwDetect.Threshold(15)) objects = ds.getFootprints() afwDetect.setMaskFromFootprintList(mi.getMask(), objects, 0x1) self.assertEqual(mi.getMask()[4, 2, afwImage.LOCAL], 0x0) self.assertEqual(mi.getMask()[3, 6, afwImage.LOCAL], 0x1) self.assertEqual(mi.getImage()[3, 6, afwImage.LOCAL], 20) for ft in objects: ft.spans.setImage(mi.getImage(), 5.0) self.assertEqual(mi.getImage()[4, 2, afwImage.LOCAL], 10) self.assertEqual(mi.getImage()[3, 6, afwImage.LOCAL], 5) if display: ds9.mtv(mi, frame=1) # # Check Footprint.contains() while we are about it # self.assertTrue(objects[0].contains(lsst.geom.Point2I(7, 5))) self.assertFalse(objects[0].contains(lsst.geom.Point2I(10, 6))) self.assertFalse(objects[0].contains(lsst.geom.Point2I(7, 6))) self.assertFalse(objects[0].contains(lsst.geom.Point2I(4, 2))) self.assertTrue(objects[1].contains(lsst.geom.Point2I(3, 6))) # Verify the FootprintSet footprint list setter can accept inputs from # the footprint list getter # Create a copy of the ds' FootprintList dsFpList = ds.getFootprints() footprintListCopy = [afwDetect.Footprint().assign(f) for f in dsFpList] # Use the FootprintList setter with the output from the getter ds.setFootprints(ds.getFootprints()[:-1]) dsFpListNew = ds.getFootprints() self.assertTrue(len(dsFpListNew) == len(footprintListCopy)-1) for new, old in zip(dsFpListNew, footprintListCopy[:-1]): self.assertEqual(new, old)
def run(frame=6): im = afwImage.MaskedImageF(afwGeom.Extent2I(14, 10)) # # Populate the image with objects that we should detect # objects = [] objects.append([(4, 1, 10), (3, 2, 10), (4, 2, 20), (5, 2, 10), (4, 3, 10)]) objects.append([(9, 7, 30), (10, 7, 29), (12, 7, 28), (10, 8, 27), (11, 8, 26), (10, 4, -5)]) objects.append([(3, 8, 10), (4, 8, 10)]) for obj in objects: for x, y, I in obj: im.getImage().set(x, y, I) im.getVariance().set(1) im.getVariance().set(10, 4, 0.5 ** 2) # # Detect the objects at 10 counts or above # level = 10 fs = afwDetect.makeFootprintSet(im, afwDetect.Threshold(level), "DETECTED") showPeaks(im, fs, frame=frame) # # Detect the objects at -10 counts or below. N.b. the peak's at -5, so it isn't detected # polarity = False # look for objects below background threshold = afwDetect.Threshold(level, afwDetect.Threshold.VALUE, polarity) fs2 = afwDetect.makeFootprintSet(im, threshold, "DETECTED_NEGATIVE") print "Detected %d objects below background" % len(fs2.getFootprints()) # # Search in S/N (n.b. the peak's -10sigma) # threshold = afwDetect.Threshold(level, afwDetect.Threshold.PIXEL_STDEV, polarity) fs2 = afwDetect.makeFootprintSet(im, threshold) # # Here's another way to set a mask plane (we chose not to do so in the makeFootprintSet call) # msk = im.getMask() afwDetect.setMaskFromFootprintList(msk, fs2.getFootprints(), msk.getPlaneBitMask("DETECTED_NEGATIVE")) if frame is not None: ds9.mtv(msk, isMask=True, frame=frame) # # Merge the positive and negative detections, growing both sets by 1 pixel # fs.merge(fs2, 1, 1) # # Set EDGE so we can see the grown Footprints # afwDetect.setMaskFromFootprintList(msk, fs.getFootprints(), msk.getPlaneBitMask("EDGE")) if frame is not None: ds9.mtv(msk, isMask=True, frame=frame) showPeaks(fs=fs, frame=frame)
def cosmicRay(self, exposure, keepCRs=None): """Mask cosmic rays \param[in,out] exposure Exposure to process \param[in] keepCRs Don't interpolate over the CR pixels (defer to pex_config if None) """ import lsstDebug display = lsstDebug.Info(__name__).display displayCR = lsstDebug.Info(__name__).displayCR assert exposure, "No exposure provided" psf = exposure.getPsf() assert psf, "No psf provided" # Blow away old mask try: mask = exposure.getMaskedImage().getMask() crBit = mask.getMaskPlane("CR") mask.clearMaskPlane(crBit) except Exception: pass mi = exposure.getMaskedImage() bg = afwMath.makeStatistics(mi, afwMath.MEDIAN).getValue() if keepCRs is None: keepCRs = self.config.cosmicray.keepCRs try: crs = measAlg.findCosmicRays(mi, psf, bg, pexConfig.makePolicy(self.config.cosmicray), keepCRs) except Exception: if display: import lsst.afw.display.ds9 as ds9 ds9.mtv(exposure, title="Failed CR") raise num = 0 if crs is not None: mask = mi.getMask() crBit = mask.getPlaneBitMask("CR") afwDet.setMaskFromFootprintList(mask, crs, crBit) num = len(crs) if display and displayCR: import lsst.afw.display.ds9 as ds9 import lsst.afw.display.utils as displayUtils ds9.incrDefaultFrame() ds9.mtv(exposure, title="Post-CR") with ds9.Buffering(): for cr in crs: displayUtils.drawBBox(cr.getBBox(), borderWidth=0.55) self.log.info("Identified %s cosmic rays." % (num,))
def testGrowFootprints3(self): """Test that we can grow footprints, correctly merging those that now totally overwritten""" self.im = afwImage.MaskedImageF(14, 11) self.im.getImage().set(0) self.peaks = [] I = 11 for x, y in [(4, 7), (5, 7), (6, 7), (7, 7), (8, 7), (4, 6), (8, 6), (4, 5), (8, 5), (4, 4), (8, 4), (4, 3), (8, 3), ]: self.im.getImage().set(x, y, I) I -= 1e-3 self.im.getImage().set(4, 7, 15) self.peaks.append([(4, 7,),]) self.im.getImage().set(6, 5, 30) self.peaks[0].append((6, 5,)) self.fs = afwDetect.FootprintSet(self.im, afwDetect.Threshold(10), "BINNED1") # # The disappearing Footprint special case only shows up if the outer Footprint is grown # _after_ the inner one. So arrange the order properly feet = self.fs.getFootprints() feet[0], feet[1] = feet[1], feet[0] msk = self.im.getMask() grow = 2 self.fs = afwDetect.FootprintSet(self.fs, grow, False) afwDetect.setMaskFromFootprintList(msk, self.fs.getFootprints(), msk.getPlaneBitMask("DETECTED_NEGATIVE")) if display: frame = 0 ds9.mtv(self.im, frame=frame) with ds9.Buffering(): for i, foot in enumerate(self.fs.getFootprints()): for p in foot.getPeaks(): ds9.dot("+", p.getIx(), p.getIy(), size=0.4, frame=frame) if i < len(self.peaks): for trueX, trueY in self.peaks[i]: ds9.dot("x", trueX, trueY, size=0.4, ctype=ds9.RED, frame=frame) self.assertEqual(len(self.fs.getFootprints()), 1) self.assertEqual(len(self.fs.getFootprints()[0].getPeaks()), len(self.peaks[0]))
def assemble(self, skyInfo, tempExpRefList, imageScalerList, weightList, bgModelList, *args, **kwargs): """Assemble the coadd for a region Identify clipped regions by detecting objects on the difference between unclipped and clipped coadd and then flag these regions on the individual visits so they are ignored in the coaddition process. N.b. *args and **kwargs are passed but ignored in order to match the call signature expected by the parent task. @param skyInfo: Patch geometry information, from getSkyInfo @param tempExpRefList: List of data reference to tempExp @param imageScalerList: List of image scalers @param weightList: List of weights @param bgModelList: List of background models from background matching return coadd exposure """ exp = self.buildDifferenceImage(skyInfo, tempExpRefList, imageScalerList, weightList, bgModelList) mask = exp.getMaskedImage().getMask() mask.addMaskPlane("CLIPPED") result = self.detectClip(exp, tempExpRefList) self.log.info('Found %d clipped objects' % len(result.clipFootprints)) # Go to individual visits for big footprints maskClipValue = mask.getPlaneBitMask("CLIPPED") maskDetValue = mask.getPlaneBitMask("DETECTED") | mask.getPlaneBitMask("DETECTED_NEGATIVE") bigFootprints = self.detectClipBig(result.tempExpClipList, result.clipFootprints, result.clipIndices, maskClipValue, maskDetValue) # Create mask of the current clipped footprints maskClip = mask.Factory(mask.getBBox(afwImage.PARENT)) afwDet.setMaskFromFootprintList(maskClip, result.clipFootprints, maskClipValue) maskClipBig = maskClip.Factory(mask.getBBox(afwImage.PARENT)) afwDet.setMaskFromFootprintList(maskClipBig, bigFootprints, maskClipValue) maskClip |= maskClipBig # Assemble coadd from base class, but ignoring CLIPPED pixels (doClip is false) badMaskPlanes = self.config.badMaskPlanes[:] badMaskPlanes.append("CLIPPED") badPixelMask = afwImage.MaskU.getPlaneBitMask(badMaskPlanes) coaddExp = AssembleCoaddTask.assemble(self, skyInfo, tempExpRefList, imageScalerList, weightList, bgModelList, result.tempExpClipList, doClip=False, mask=badPixelMask) # Set the coadd CLIPPED mask from the footprints since currently pixels that are masked # do not get propagated maskExp = coaddExp.getMaskedImage().getMask() maskExp |= maskClip return coaddExp
def processSingle(self, sensorRef): """Subtract the background and normalise by the background level""" exposure = CalibTask.processSingle(self, sensorRef) bgLevel = self.stats.run(exposure) self.subtractBackground.run(exposure) mi = exposure.getMaskedImage() mi /= bgLevel footprintSets = self.detection.detectFootprints(exposure, sigma=self.config.detectSigma) mask = exposure.getMaskedImage().getMask() detected = 1 << mask.addMaskPlane("DETECTED") for fpSet in (footprintSets.positive, footprintSets.negative): if fpSet is not None: afwDet.setMaskFromFootprintList(mask, fpSet.getFootprints(), detected) return exposure
def cosmicray(self, exposure, psf): """Cosmic ray masking @param exposure Exposure to process @param psf PSF """ import lsstDebug display = lsstDebug.Info(__name__).display displayCR = lsstDebug.Info(__name__).displayCR assert exposure, "No exposure provided" assert psf, "No psf provided" # Blow away old mask try: mask = exposure.getMaskedImage().getMask() crBit = mask.getMaskPlane("CR") mask.clearMaskPlane(crBit) except: pass if display and displayCR: ds9.incrDefaultFrame() ds9.mtv(exposure, title="Pre-CR") policy = self.config['cosmicray'].getPolicy() mi = exposure.getMaskedImage() bg = afwMath.makeStatistics(mi, afwMath.MEDIAN).getValue() crs = measAlg.findCosmicRays(mi, psf, bg, policy, self._keepCRs) num = 0 if crs is not None: mask = mi.getMask() crBit = mask.getPlaneBitMask("CR") afwDet.setMaskFromFootprintList(mask, crs, crBit) num = len(crs) if display and displayCR: ds9.incrDefaultFrame() ds9.mtv(exposure, title="Post-CR") ds9.cmdBuffer.pushSize() for cr in crs: displayUtils.drawBBox(cr.getBBox(), borderWidth=0.55) ds9.cmdBuffer.popSize() self.log.log(self.log.INFO, "Identified %d cosmic rays." % num) return
def processSingle(self, sensorRef): """Subtract the background and normalise by the background level""" exposure = CalibTask.processSingle(self, sensorRef) bgLevel = self.stats.run(exposure) self.subtractBackground.run(exposure) mi = exposure.getMaskedImage() mi /= bgLevel footprintSets = self.detection.detectFootprints( exposure, sigma=self.config.detectSigma) mask = exposure.getMaskedImage().getMask() detected = 1 << mask.addMaskPlane("DETECTED") for fpSet in (footprintSets.positive, footprintSets.negative): if fpSet is not None: afwDet.setMaskFromFootprintList(mask, fpSet.getFootprints(), detected) return exposure
def cosmicray(exp, config, display=False): bg = 0.0 # We background-subtracted, right? crList = measAlg.findCosmicRays(exp.getMaskedImage(), exp.getPsf(), bg, makePolicy(config), True) if crList is None: print "No CRs found" return mask = exp.getMaskedImage().getMask() crBit = mask.getPlaneBitMask("CR") afwDet.setMaskFromFootprintList(mask, crList, crBit) num = len(crList) print "Found %d CRs" % num if display: frame = 2
def testSetFromFootprint(self): """Test setting mask/image pixels from a Footprint list""" mi = afwImage.MaskedImageF(afwGeom.Extent2I(12, 8)) im = mi.getImage() # # Objects that we should detect # self.objects = [] self.objects += [Object(10, [(1, 4, 4), (2, 3, 5), (3, 4, 4)])] self.objects += [Object(20, [(5, 7, 8), (5, 10, 10), (6, 8, 9)])] self.objects += [Object(20, [(6, 3, 3)])] im.set(0) # clear image for obj in self.objects: obj.insert(im) if False and display: ds9.mtv(mi, frame=0) ds = afwDetect.makeFootprintSet(mi, afwDetect.Threshold(15)) objects = ds.getFootprints() afwDetect.setMaskFromFootprintList(mi.getMask(), objects, 0x1) self.assertEqual(mi.getMask().get(4, 2), 0x0) self.assertEqual(mi.getMask().get(3, 6), 0x1) self.assertEqual(mi.getImage().get(3, 6), 20) afwDetect.setImageFromFootprintList(mi.getImage(), objects, 5.0) self.assertEqual(mi.getImage().get(4, 2), 10) self.assertEqual(mi.getImage().get(3, 6), 5) if False and display: ds9.mtv(mi, frame=1) # # Check Footprint.contains() while we are about it # self.assertTrue(objects[0].contains(afwGeom.Point2I(7, 5))) self.assertFalse(objects[0].contains(afwGeom.Point2I(10, 6))) self.assertFalse(objects[0].contains(afwGeom.Point2I(7, 6))) self.assertFalse(objects[0].contains(afwGeom.Point2I(4, 2))) self.assertTrue(objects[1].contains(afwGeom.Point2I(3, 6)))
def testSetFromFootprint(self): """Test setting mask/image pixels from a Footprint list""" mi = afwImage.MaskedImageF(afwGeom.Extent2I(12, 8)) im = mi.getImage() # # Objects that we should detect # self.objects = [] self.objects += [Object(10, [(1, 4, 4), (2, 3, 5), (3, 4, 4)])] self.objects += [Object(20, [(5, 7, 8), (5, 10, 10), (6, 8, 9)])] self.objects += [Object(20, [(6, 3, 3)])] im.set(0) # clear image for obj in self.objects: obj.insert(im) if False and display: ds9.mtv(mi, frame=0) ds = afwDetect.FootprintSet(mi, afwDetect.Threshold(15)) objects = ds.getFootprints() afwDetect.setMaskFromFootprintList(mi.getMask(), objects, 0x1) self.assertEqual(mi.getMask().get(4, 2), 0x0) self.assertEqual(mi.getMask().get(3, 6), 0x1) self.assertEqual(mi.getImage().get(3, 6), 20) afwDetect.setImageFromFootprintList(mi.getImage(), objects, 5.0) self.assertEqual(mi.getImage().get(4, 2), 10) self.assertEqual(mi.getImage().get(3, 6), 5) if display: ds9.mtv(mi, frame=1) # # Check Footprint.contains() while we are about it # self.assertTrue(objects[0].contains(afwGeom.Point2I(7, 5))) self.assertFalse(objects[0].contains(afwGeom.Point2I(10, 6))) self.assertFalse(objects[0].contains(afwGeom.Point2I(7, 6))) self.assertFalse(objects[0].contains(afwGeom.Point2I(4, 2))) self.assertTrue(objects[1].contains(afwGeom.Point2I(3, 6)))
def detectClipBig(self, tempExpClipList, clipFootprints, clipIndices, maskClipValue, maskDetValue): """Find footprints from individual tempExp footprints for large footprints @param tempExpClipList: List of tempExp masks with clipping information @param clipFootprints: List of clipped footprints @param clipIndices: List of which entries in tempExpClipList each footprint belongs to @param maskClipValue: Mask value of clipped pixels @param maskClipValue: Mask value of detected pixels @return list of big footprints """ bigFootprintsCoadd = [] ignoreMask = self.getBadPixelMask() for index, tmpExpMask in enumerate(tempExpClipList): # Create list of footprints from the DETECTED pixels maskVisitDet = tmpExpMask.Factory(tmpExpMask, tmpExpMask.getBBox(afwImage.PARENT), afwImage.PARENT, True) maskVisitDet &= maskDetValue visitFootprints = afwDet.FootprintSet(maskVisitDet, afwDet.Threshold(1)) # build a mask of clipped footprints that are in this visit clippedFootprintsVisit = [] for foot, clipIndex in zip(clipFootprints, clipIndices): if index not in clipIndex: continue clippedFootprintsVisit.append(foot) maskVisitClip = maskVisitDet.Factory(maskVisitDet.getBBox(afwImage.PARENT)) afwDet.setMaskFromFootprintList(maskVisitClip, clippedFootprintsVisit, maskClipValue) bigFootprintsVisit = [] for foot in visitFootprints.getFootprints(): if foot.getArea() < self.config.minBigOverlap: continue nCount = countMaskFromFootprint(maskVisitClip, foot, maskClipValue, ignoreMask) if nCount > self.config.minBigOverlap: bigFootprintsVisit.append(foot) bigFootprintsCoadd.append(foot) # Update single visit masks maskVisitClip.clearAllMaskPlanes() afwDet.setMaskFromFootprintList(maskVisitClip, bigFootprintsVisit, maskClipValue) tmpExpMask |= maskVisitClip return bigFootprintsCoadd
def testInf(self): """Test detection for images with Infs""" im = afwImage.MaskedImageF(lsst.geom.Extent2I(10, 20)) im.set(0) import numpy for x in range(im.getWidth()): im[x, -1, afwImage.LOCAL] = (numpy.Inf, 0x0, 0) ds = afwDetect.FootprintSet(im, afwDetect.createThreshold(100)) objects = ds.getFootprints() afwDetect.setMaskFromFootprintList(im.getMask(), objects, 0x10) if display: ds9.mtv(im) self.assertEqual(len(objects), 1)
def testInf(self): """Test detection for images with Infs""" im = afwImage.MaskedImageF(lsst.geom.Extent2I(10, 20)) im.set(0) import numpy for x in range(im.getWidth()): im[x, -1, afwImage.LOCAL] = (numpy.Inf, 0x0, 0) ds = afwDetect.FootprintSet(im, afwDetect.createThreshold(100)) objects = ds.getFootprints() afwDetect.setMaskFromFootprintList(im.getMask(), objects, 0x10) if display: afwDisplay.Display(frame=2).mtv(im, title=self._testMethodName + " image") self.assertEqual(len(objects), 1)
def testInf(self): """Test detection for images with Infs""" im = afwImage.MaskedImageF(afwGeom.Extent2I(10, 20)) im.set(0) import numpy for x in range(im.getWidth()): im.set(x, im.getHeight() - 1, (numpy.Inf, 0x0, 0)) ds = afwDetect.makeFootprintSet(im, afwDetect.createThreshold(100)) objects = ds.getFootprints() afwDetect.setMaskFromFootprintList(im.getMask(), objects, 0x10) if display: ds9.mtv(im) self.assertEqual(len(objects), 1)
def makeThresholdMask(maskedImage, threshold, growFootprints=1, maskName = 'SAT'): """Mask pixels based on threshold detection @param[in,out] maskedImage afw.image.MaskedImage to process; the mask is altered @param[in] threshold detection threshold @param[in] growFootprints amount by which to grow footprints of detected regions @param[in] maskName mask plane name @return meas.algorihtms.DefectListT of regions set in the mask. """ # find saturated regions thresh = afwDetection.Threshold(threshold) fs = afwDetection.FootprintSet(maskedImage, thresh) if growFootprints > 0: fs = afwDetection.FootprintSet(fs, growFootprints) fpList = fs.getFootprints() # set mask mask = maskedImage.getMask() bitmask = mask.getPlaneBitMask(maskName) afwDetection.setMaskFromFootprintList(mask, fpList, bitmask) return defectListFromFootprintList(fpList, growFootprints=0)
def testMergeFootprintsEngulf(self): """Merge two Footprints when growing one Footprint totally replaces the other""" def callback(): self.im.set(0) self.peaks, self.objects = [], [] for x, y, I in [[6, 4, 20], [6, 5, 10]]: self.im.getImage()[x, y, afwImage.LOCAL] = I self.peaks.append([[6, 4]]) x, y, value = 8, 4, -20 self.im.getImage()[x, y, afwImage.LOCAL] = value peaks2.append((x, y, value)) grow1, grow2 = 0, 3 peaks2 = [] self.doTestPeaks(threshold=10, callback=callback, grow=0) threshold = afwDetect.Threshold(10, afwDetect.Threshold.VALUE, False) fs2 = afwDetect.FootprintSet(self.im, threshold) msk = self.im.getMask() afwDetect.setMaskFromFootprintList( msk, fs2.getFootprints(), msk.getPlaneBitMask("DETECTED_NEGATIVE")) self.fs.merge(fs2, grow1, grow2) self.peaks[0] += peaks2 def peaksSortKey(p): return peakFromImage(self.im, p) self.peaks[0] = sorted(sum(self.peaks, []), key=peaksSortKey) afwDetect.setMaskFromFootprintList( msk, self.fs.getFootprints(), msk.getPlaneBitMask("EDGE")) self.checkPeaks(frame=3)
def testGrowLRUD(self): """Grow footprints in various directions using the FootprintSet/FootprintControl constructor """ im = afwImage.MaskedImageF(11, 11) x0, y0, ny = 5, 5, 3 for y in range(y0 - ny // 2, y0 + ny // 2 + 1): im[x0, y, afwImage.LOCAL] = (10, 0x0, 0.0) fs = afwDetect.FootprintSet(im, afwDetect.Threshold(10)) self.assertEqual(len(fs.getFootprints()), 1) ngrow = 2 # How much to grow by # # Test growing to the left and/or right # for fctrl in ( afwDetect.FootprintControl(False, True, False, False), afwDetect.FootprintControl(True, False, False, False), afwDetect.FootprintControl(True, True, False, False), ): fs = afwDetect.FootprintSet(im, afwDetect.Threshold(10)) grown = afwDetect.FootprintSet(fs, ngrow, fctrl) im.getMask().set(0) afwDetect.setMaskFromFootprintList(im.getMask(), grown.getFootprints(), 0x10) if display: ds9.mtv(im) foot = grown.getFootprints()[0] nextra = 0 if fctrl.isLeft()[1]: nextra += ngrow for y in range(y0 - ny // 2, y0 + ny // 2 + 1): self.assertNotEqual( im.getMask()[x0 - 1, y, afwImage.LOCAL], 0) if fctrl.isRight()[1]: nextra += ngrow for y in range(y0 - ny // 2, y0 + ny // 2 + 1): self.assertNotEqual( im.getMask()[x0 + 1, y, afwImage.LOCAL], 0) self.assertEqual(foot.getArea(), (1 + nextra) * ny) # # Test growing to up and/or down # for fctrl in ( afwDetect.FootprintControl(False, False, True, False), afwDetect.FootprintControl(False, False, False, True), afwDetect.FootprintControl(False, False, True, True), ): grown = afwDetect.FootprintSet(fs, ngrow, fctrl) im.getMask().set(0) afwDetect.setMaskFromFootprintList(im.getMask(), grown.getFootprints(), 0x10) if display: ds9.mtv(im) foot = grown.getFootprints()[0] nextra = 0 if fctrl.isUp()[1]: nextra += ngrow for y in range(y0 + ny // 2 + 1, y0 + ny // 2 + ngrow + 1): self.assertNotEqual(im.getMask()[x0, y, afwImage.LOCAL], 0) if fctrl.isDown()[1]: nextra += ngrow for y in range(y0 - ny // 2 - 1, y0 - ny // 2 - ngrow - 1): self.assertNotEqual(im.getMask()[x0, y, afwImage.LOCAL], 0) self.assertEqual(foot.getArea(), ny + nextra)
def cosmicRay(self, exposure, keepCRs=None): """Mask cosmic rays \param[in,out] exposure Exposure to process \param[in] keepCRs Don't interpolate over the CR pixels (defer to pex_config if None) """ import lsstDebug display = lsstDebug.Info(__name__).display displayCR = lsstDebug.Info(__name__).displayCR assert exposure, "No exposure provided" psf = exposure.getPsf() assert psf, "No psf provided" # Blow away old mask try: mask = exposure.getMaskedImage().getMask() crBit = mask.getMaskPlane("CR") mask.clearMaskPlane(crBit) except Exception: pass exposure0 = exposure # initial value of exposure binSize = self.config.cosmicray.background.binSize nx, ny = exposure.getWidth()/binSize, exposure.getHeight()/binSize # Treat constant background as a special case to avoid the extra complexity in calling # measAlg.SubtractBackgroundTask(). if nx*ny <= 1: medianBg = afwMath.makeStatistics(exposure.getMaskedImage(), afwMath.MEDIAN).getValue() modelBg = None else: # make a deep copy of the exposure before subtracting its background, # because this routine is only allowed to modify the exposure by setting mask planes # and interpolating over defects, not changing the background level exposure = exposure.Factory(exposure, True) subtractBackgroundTask = measAlg.SubtractBackgroundTask(config=self.config.cosmicray.background) modelBg = subtractBackgroundTask.run(exposure).background medianBg = 0.0 if keepCRs is None: keepCRs = self.config.cosmicray.keepCRs try: crs = measAlg.findCosmicRays(exposure.getMaskedImage(), psf, medianBg, pexConfig.makePolicy(self.config.cosmicray), keepCRs) if modelBg: # Add back background image img = exposure.getMaskedImage() img += modelBg.getImageF() del img # Replace original image with CR subtracted image exposure0.setMaskedImage(exposure.getMaskedImage()) except Exception: if display: import lsst.afw.display.ds9 as ds9 ds9.mtv(exposure0, title="Failed CR") raise num = 0 if crs is not None: mask = exposure0.getMaskedImage().getMask() crBit = mask.getPlaneBitMask("CR") afwDet.setMaskFromFootprintList(mask, crs, crBit) num = len(crs) if display and displayCR: import lsst.afw.display.ds9 as ds9 import lsst.afw.display.utils as displayUtils ds9.incrDefaultFrame() ds9.mtv(exposure0, title="Post-CR") with ds9.Buffering(): for cr in crs: displayUtils.drawBBox(cr.getBBox(), borderWidth=0.55) self.log.info("Identified %s cosmic rays." % (num,))
def processImage(thresh, fileNames, grades=range(8), searchThresh=None, split=None, calcType=ras.HistogramTable.P_9, outputHistFile=None, outputEventsFile=None, assembleCcd=False, plotByAmp=False, plot=True, subplots=False, xlim=[None, 650], ylim=[None, None], displayRejects=False, displayUnknown=False, displayGrades=True, display=False, emulateMedpict=None # not used ): if searchThresh is None: searchThresh = thresh nImage = 0 # number of images we've processed events = [] ampIds = set() for frameNum, fileName in enumerate(fileNames): # Read file hdu = 0 # one-less than the next HDU while True: # while there are valid HDUs hdu += 1 if assembleCcd: if hdu > 1: break ccd, image = cameraGeom.assembleCcd(fileName, trim=True, perRow=True) dataSec = image ampIds = set(_.getId().getSerial() for _ in ccd) else: ccd = None # we don't have an assembled Ccd md = dafBase.PropertyList() try: image = afwImage.ImageF(fileName, hdu, md) except lsst.pex.exceptions.LsstCppException: if hdu == 1: # an empty PDU continue break # Get the image's camera geometry (e.g. where is the datasec?) amp = cameraGeom.makeAmp(md) ampIds.add(amp.getId().getSerial()) # Subtract the bias, estimated as the median of the biassec bias = image.Factory(image, amp.getDiskBiasSec()) image -= afwMath.makeStatistics(bias, afwMath.MEDIAN).getValue() # Search the datasec for Fe55 events dataSec = image.Factory(image, amp.getDiskDataSec()) nImage += 1 fs = afwDetect.FootprintSet(dataSec, afwDetect.Threshold(searchThresh)) if display: mi = afwImage.makeMaskedImage(image) afwDetect.setMaskFromFootprintList(mi.getMask(), fs.getFootprints(), 0x4) ds9.mtv(mi, title="bkgd subtracted", frame=0) del mi # Convert all the peaks within the detections to Events for foot in fs.getFootprints(): for i, peak in enumerate(foot.getPeaks()): peakPos = afwGeom.PointI(peak.getIx(), peak.getIy()) if ccd: amp = ccd.findAmp(peakPos, True) try: events.append(ras.Event(image, peakPos, frameNum, amp.getId().getSerial())) except lsst.pex.exceptions.LsstCppException, e: pass
def processImage(thresh, fileNames, grades=range(8), searchThresh=None, split=None, calcType=ras.HistogramTable.P_9, emulateMedpict=False, outputHistFile=None, outputEventsFile=None, displayRejects=False, displayUnknown=False, displayGrades=True, display=False, plot=True, subplots=False, assembleCcd=None, # not implemented plotByAmp=None, # not implemented ): events = [] for fileName in fileNames: md = dafBase.PropertyList() image = afwImage.ImageF(fileName, 1, md) amp = makeAmp(md, emulateMedpict) bias = image.Factory(image, amp.getBiasSec()) if emulateMedpict: image -= afwMath.makeStatistics(image, afwMath.MEDIAN).getValue() bias.set(0) else: image -= afwMath.makeStatistics(bias, afwMath.MEDIAN).getValue() if searchThresh is None: searchThresh = thresh dataSec = image.Factory(image, amp.getDataSec()) fs = afwDetect.FootprintSet(dataSec, afwDetect.Threshold(searchThresh)) if display: if displayMask: mi = afwImage.makeMaskedImage(image) afwDetect.setMaskFromFootprintList(mi.getMask(), fs.getFootprints(), 0x4) else: mi = image ds9.mtv(mi, title="bkgd subtracted", frame=0) for foot in fs.getFootprints(): for i, peak in enumerate(foot.getPeaks()): x, y = peak.getIx(), peak.getIy() # # medpict fails to find some events with two identical adjacent peak values, # in particular it uses th peak criterion embodied in the following logic # # If you set emulateMedpict == False and run showMedpict(dmEvents) # you'll see the real events it missed # if emulateMedpict: v00 = image.get(x, y) try: if not (v00 > image.get(x - 1, y - 1) and v00 > image.get(x , y - 1) and v00 > image.get(x + 1, y - 1) and v00 > image.get(x - 1, y ) and v00 >= image.get(x + 1, y ) and v00 >= image.get(x - 1, y + 1) and v00 >= image.get(x , y + 1) and v00 >= image.get(x + 1, y + 1)): continue except lsst.pex.exceptions.LsstCppException, e: pass try: events.append(ras.Event(image, afwGeom.PointI(x, y))) except lsst.pex.exceptions.LsstCppException, e: pass
def cosmicRay(self, exposure, keepCRs=None): """Mask cosmic rays @param[in,out] exposure Exposure to process @param[in] keepCRs Don't interpolate over the CR pixels (defer to pex_config if None) """ import lsstDebug display = lsstDebug.Info(__name__).display displayCR = lsstDebug.Info(__name__).displayCR assert exposure, "No exposure provided" psf = exposure.getPsf() assert psf, "No psf provided" # Blow away old mask try: mask = exposure.getMaskedImage().getMask() crBit = mask.getMaskPlane("CR") mask.clearMaskPlane(crBit) except Exception: pass exposure0 = exposure # initial value of exposure binSize = self.config.cosmicray.background.binSize nx, ny = exposure.getWidth()/binSize, exposure.getHeight()/binSize # Treat constant background as a special case to avoid the extra complexity in calling # measAlg.SubtractBackgroundTask(). if nx*ny <= 1: medianBg = afwMath.makeStatistics(exposure.getMaskedImage(), afwMath.MEDIAN).getValue() modelBg = None else: # make a deep copy of the exposure before subtracting its background, # because this routine is only allowed to modify the exposure by setting mask planes # and interpolating over defects, not changing the background level exposure = exposure.Factory(exposure, True) subtractBackgroundTask = measAlg.SubtractBackgroundTask(config=self.config.cosmicray.background) modelBg = subtractBackgroundTask.run(exposure).background medianBg = 0.0 if keepCRs is None: keepCRs = self.config.cosmicray.keepCRs try: crs = measAlg.findCosmicRays(exposure.getMaskedImage(), psf, medianBg, pexConfig.makePropertySet(self.config.cosmicray), keepCRs) if modelBg: # Add back background image img = exposure.getMaskedImage() img += modelBg.getImageF() del img # Replace original image with CR subtracted image exposure0.setMaskedImage(exposure.getMaskedImage()) except Exception: if display: afwDisplay.Display().mtv(exposure0, title="Failed CR") raise num = 0 if crs is not None: mask = exposure0.getMaskedImage().getMask() crBit = mask.getPlaneBitMask("CR") afwDet.setMaskFromFootprintList(mask, crs, crBit) num = len(crs) if display and displayCR: disp = afwDisplay.Display() disp.incrDefaultFrame() disp.mtv(exposure0, title="Post-CR") with disp.Buffering(): for cr in crs: afwDisplay.utils.drawBBox(cr.getBBox(), borderWidth=0.55) self.log.info("Identified %s cosmic rays.", num)
def testGrowLRUD(self): """Grow footprints in various directions using the FootprintSet/FootprintControl constructor """ im = afwImage.MaskedImageF(11, 11) x0, y0, ny = 5, 5, 3 for y in range(y0 - ny//2, y0 + ny//2 + 1): im[x0, y, afwImage.LOCAL] = (10, 0x0, 0.0) fs = afwDetect.FootprintSet(im, afwDetect.Threshold(10)) self.assertEqual(len(fs.getFootprints()), 1) ngrow = 2 # How much to grow by # # Test growing to the left and/or right # for fctrl in ( afwDetect.FootprintControl(False, True, False, False), afwDetect.FootprintControl(True, False, False, False), afwDetect.FootprintControl(True, True, False, False), ): fs = afwDetect.FootprintSet(im, afwDetect.Threshold(10)) grown = afwDetect.FootprintSet(fs, ngrow, fctrl) im.getMask().set(0) afwDetect.setMaskFromFootprintList( im.getMask(), grown.getFootprints(), 0x10) if display: afwDisplay.Display(frame=3).mtv(im, title=self._testMethodName + " image") foot = grown.getFootprints()[0] nextra = 0 if fctrl.isLeft()[1]: nextra += ngrow for y in range(y0 - ny//2, y0 + ny//2 + 1): self.assertNotEqual(im.getMask()[x0 - 1, y, afwImage.LOCAL], 0) if fctrl.isRight()[1]: nextra += ngrow for y in range(y0 - ny//2, y0 + ny//2 + 1): self.assertNotEqual(im.getMask()[x0 + 1, y, afwImage.LOCAL], 0) self.assertEqual(foot.getArea(), (1 + nextra)*ny) # # Test growing to up and/or down # for fctrl in ( afwDetect.FootprintControl(False, False, True, False), afwDetect.FootprintControl(False, False, False, True), afwDetect.FootprintControl(False, False, True, True), ): grown = afwDetect.FootprintSet(fs, ngrow, fctrl) im.getMask().set(0) afwDetect.setMaskFromFootprintList( im.getMask(), grown.getFootprints(), 0x10) if display: afwDisplay.Display(frame=2).mtv(im, title=self._testMethodName + " image") foot = grown.getFootprints()[0] nextra = 0 if fctrl.isUp()[1]: nextra += ngrow for y in range(y0 + ny//2 + 1, y0 + ny//2 + ngrow + 1): self.assertNotEqual(im.getMask()[x0, y, afwImage.LOCAL], 0) if fctrl.isDown()[1]: nextra += ngrow for y in range(y0 - ny//2 - 1, y0 - ny//2 - ngrow - 1): self.assertNotEqual(im.getMask()[x0, y, afwImage.LOCAL], 0) self.assertEqual(foot.getArea(), ny + nextra)