def testBadImage(self): """Test that an entirely bad image doesn't cause an absolute failure """ initialValue = 20 mi = afwImage.MaskedImageF(500, 200) # # Check that no good values don't crash (they return NaN), and that a single good value # is enough to redeem the entire image # for pix00 in [np.nan, initialValue]: mi.getImage()[:] = np.nan mi.getImage()[0, 0] = pix00 sctrl = afwMath.StatisticsControl() nx, ny = 17, 17 bctrl = afwMath.BackgroundControl(nx, ny, sctrl, afwMath.MEANCLIP) bkgd = afwMath.makeBackground(mi, bctrl) afwMath.cast_BackgroundMI(bkgd).getStatsImage() # the test is that this doesn't fail if the bug (#2297) is fixed bkgdImage = bkgd.getImageF(afwMath.Interpolate.NATURAL_SPLINE, afwMath.REDUCE_INTERP_ORDER) val = np.mean(bkgdImage[0:100, 0:100].getArray()) if np.isfinite(pix00): self.assertEqual(val, pix00) else: self.assertTrue(np.isnan(val))
def complexBackground(image): binsize = 128 nx = int(image.getWidth() / binsize) + 1 ny = int(image.getHeight() / binsize) + 1 sctrl = afwMath.StatisticsControl() sctrl.setNumSigmaClip(3) sctrl.setNumIter(4) sctrl.setAndMask(afwImage.MaskU.getPlaneBitMask(["INTRP", "EDGE"])) sctrl.setNoGoodPixelsMask(afwImage.MaskU.getPlaneBitMask("BAD")) sctrl.setNanSafe(True) if False: sctrl.setWeighted(True) sctrl.setCalcErrorFromInputVariance(True) bctrl = afwMath.BackgroundControl(nx, ny, sctrl, afwMath.MEANCLIP) bkgd = afwMath.makeBackground(image, bctrl) statsImage = afwMath.cast_BackgroundMI(bkgd).getStatsImage() ds9.mtv(statsImage.getVariance()) bkdgImages = dict(SPLINE=bkgd.getImageF( afwMath.Interpolate.NATURAL_SPLINE), LINEAR=bkgd.getImageF(afwMath.Interpolate.LINEAR)) return bkgd
def testCFHT(self): """Test background subtraction on some real CFHT data""" afwdataDir = eups.productDir("afwdata") if not afwdataDir: print >> sys.stderr, "Skipping testCFHT as afwdata is not setup" return mi = afwImage.MaskedImageF(os.path.join(afwdataDir, "CFHT", "D4", "cal-53535-i-797722_1")) mi = mi.Factory(mi, afwGeom.Box2I(afwGeom.Point2I(32, 2), afwGeom.Point2I(2079, 4609)), afwImage.LOCAL) bctrl = afwMath.BackgroundControl(mi.getWidth()//128, mi.getHeight()//128) bctrl.getStatisticsControl().setNumSigmaClip(3.0) bctrl.getStatisticsControl().setNumIter(2) backobj = afwMath.makeBackground(mi.getImage(), bctrl) if display: ds9.mtv(mi, frame = 0) im = mi.getImage() im -= backobj.getImageF("AKIMA_SPLINE") if display: ds9.mtv(mi, frame = 1) statsImage = afwMath.cast_BackgroundMI(backobj).getStatsImage() if display: ds9.mtv(backobj.getStatsImage(), frame=2) ds9.mtv(backobj.getStatsImage().getVariance(), frame=3)
def testRamp(self): # make a ramping image (spline should be exact for linear increasing image nx = 512 ny = 512 rampimg = afwImage.ImageD(afwGeom.Extent2I(nx, ny)) dzdx, dzdy, z0 = 0.1, 0.2, 10000.0 for x in range(nx): for y in range(ny): rampimg.set(x, y, dzdx*x + dzdy*y + z0) # check corner, edge, and center pixels bctrl = afwMath.BackgroundControl(10, 10) bctrl.setInterpStyle(afwMath.Interpolate.CUBIC_SPLINE) bctrl.setNxSample(6) bctrl.setNySample(6) bctrl.getStatisticsControl().setNumSigmaClip(20.0) # something large enough to avoid clipping entirely bctrl.getStatisticsControl().setNumIter(1) backobj = afwMath.makeBackground(rampimg, bctrl) xpixels = [0, nx/2, nx - 1] ypixels = [0, ny/2, ny - 1] for xpix in xpixels: for ypix in ypixels: testval = afwMath.cast_BackgroundMI(backobj).getPixel(xpix, ypix) self.assertAlmostEqual(testval/rampimg.get(xpix, ypix), 1, 6)
def testBadRows(self): """Test that a bad set of rows in an image doesn't cause a failure """ initialValue = 20 mi = afwImage.MaskedImageF(500, 200) mi.set((initialValue, 0x0, 1.0)) im = mi.getImage() im[:, 0:100] = np.nan del im msk = mi.getMask() badBits = msk.getPlaneBitMask(['EDGE', 'DETECTED', 'DETECTED_NEGATIVE']) msk[0:400, :] |= badBits del msk if display: ds9.mtv(mi, frame=0) sctrl = afwMath.StatisticsControl() sctrl.setAndMask(badBits) nx, ny = 17, 17 bctrl = afwMath.BackgroundControl(nx, ny, sctrl, afwMath.MEANCLIP) bkgd = afwMath.makeBackground(mi, bctrl) statsImage = afwMath.cast_BackgroundMI(bkgd).getStatsImage() if display: ds9.mtv(statsImage, frame=1) # the test is that this doesn't fail if the bug (#2297) is fixed bkgdImage = bkgd.getImageF(afwMath.Interpolate.NATURAL_SPLINE, afwMath.REDUCE_INTERP_ORDER) self.assertEqual(np.mean(bkgdImage[0:100, 0:100].getArray()), initialValue) if display: ds9.mtv(bkgdImage, frame=2)
def testParabola(self): # make an image which varies parabolicly (spline should be exact for 2rd order polynomial) nx = 512 ny = 512 parabimg = self.getParabolaImage(nx, ny) # check corner, edge, and center pixels bctrl = afwMath.BackgroundControl(afwMath.Interpolate.CUBIC_SPLINE) bctrl.setNxSample(24) bctrl.setNySample(24) bctrl.getStatisticsControl().setNumSigmaClip(10.0) bctrl.getStatisticsControl().setNumIter(1) backobj = afwMath.makeBackground(parabimg, bctrl) segmentCenter = int(0.5*nx/bctrl.getNxSample()) xpixels = [segmentCenter, nx//2, nx - segmentCenter] ypixels = [segmentCenter, ny//2, ny - segmentCenter] for xpix in xpixels: for ypix in ypixels: testval = afwMath.cast_BackgroundMI(backobj).getPixel(bctrl.getInterpStyle(), xpix, ypix) realval = parabimg.get(xpix, ypix) # quadratic terms skew the averages of the subimages and the clipped mean for # a subimage != value of center pixel. 1/20 counts on a 10000 count sky # is a fair (if arbitrary) test. self.assertTrue( abs(testval - realval) < 0.5 )
def testXY0(self): """Test fitting the background to an image with nonzero xy0 The statsImage and background image should not vary with xy0 """ bgImageList = [] # list of background images, one per xy0 statsImageList = [] # list of stats images, one per xy0 for xy0 in (afwGeom.Point2I(0, 0), afwGeom.Point2I(-100, -999), afwGeom.Point2I(1000, 500)): mi = self.getCfhtImage() mi.setXY0(xy0) bctrl = afwMath.BackgroundControl(mi.getWidth()//128, mi.getHeight()//128) backobj = afwMath.makeBackground(mi.getImage(), bctrl) bgImage = backobj.getImageF() self.assertEqual(bgImage.getBBox(), mi.getBBox()) bgImageList.append(bgImage) statsImage = afwMath.cast_BackgroundMI(backobj).getStatsImage() statsImageList.append(statsImage) # changing the bounding box should make no difference to the pixel values, # so compare pixels using exact equality for bgImage in bgImageList[1:]: self.assertTrue(np.all(bgImage.getArray() == bgImageList[0].getArray())) for statsImage in statsImageList[1:]: for i in range(3): self.assertTrue(np.all(statsImage.getArrays()[i] == statsImageList[0].getArrays()[i]))
def testOnlyOneGridCell(self): """Test how the program handles nxSample,nySample being 1x1. """ # try a ramping image ... has an easy analytic solution nx = 64 ny = 64 img = afwImage.ImageF(afwGeom.Extent2I(nx, ny), 10) dzdx, dzdy, z0 = 0.1, 0.2, 10000.0 mean = z0 + dzdx*(nx - 1)/2 + dzdy*(ny - 1)/2 # the analytic solution for x in range(nx): for y in range(ny): img.set(x, y, dzdx*x + dzdy*y + z0) # make a background control object bctrl = afwMath.BackgroundControl(10, 10) bctrl.setInterpStyle(afwMath.Interpolate.CONSTANT) bctrl.setNxSample(1) bctrl.setNySample(1) bctrl.setUndersampleStyle(afwMath.THROW_EXCEPTION) backobj = afwMath.makeBackground(img, bctrl) xpixels = [0, nx//2, nx - 1] ypixels = [0, ny//2, ny - 1] for xpix in xpixels: for ypix in ypixels: testval = afwMath.cast_BackgroundMI(backobj).getPixel(bctrl.getInterpStyle(), xpix, ypix) self.assertAlmostEqual(testval/mean, 1)
def complexBackground(image): binsize = 128 nx = int(image.getWidth()/binsize) + 1 ny = int(image.getHeight()/binsize) + 1 sctrl = afwMath.StatisticsControl() sctrl.setNumSigmaClip(3) sctrl.setNumIter(4) sctrl.setAndMask(afwImage.MaskU.getPlaneBitMask(["INTRP", "EDGE"])) sctrl.setNoGoodPixelsMask(afwImage.MaskU.getPlaneBitMask("BAD")) sctrl.setNanSafe(True) if False: sctrl.setWeighted(True) sctrl.setCalcErrorFromInputVariance(True) bctrl = afwMath.BackgroundControl(nx, ny, sctrl, afwMath.MEANCLIP) bkgd = afwMath.makeBackground(image, bctrl) statsImage = afwMath.cast_BackgroundMI(bkgd).getStatsImage() ds9.mtv(statsImage.getVariance()) bkdgImages = dict(SPLINE = bkgd.getImageF(afwMath.Interpolate.NATURAL_SPLINE), LINEAR = bkgd.getImageF(afwMath.Interpolate.LINEAR)) return bkgd
def testBackgroundTestImages(self): imginfolist = [] #imginfolist.append( ["v1_i1_g_m400_s20_f.fits", 400.05551471441612] ) # cooked to known value #imginfolist.append( ["v1_i1_g_m400_s20_f.fits", 400.00295902395123] ) # cooked to known value #imginfolist.append( ["v1_i1_g_m400_s20_f.fits", 400.08468385712251] ) # cooked to known value #imginfolist.append( ["v1_i1_g_m400_s20_f.fits", 400.00305806663295] ) # cooked to known value #imginfolist.append( ["v1_i1_g_m400_s20_f.fits", 400.0035102188698] ) # cooked to known value imginfolist.append( ["v1_i1_g_m400_s20_f.fits", 399.9912966583894] ) # cooked to known value #imgfiles.append("v1_i1_g_m400_s20_u16.fits") #imgfiles.append("v1_i2_g_m400_s20_f.fits" #imgfiles.append("v1_i2_g_m400_s20_u16.fits") #imgfiles.append("v2_i1_p_m9_f.fits") #imgfiles.append("v2_i1_p_m9_u16.fits") #imgfiles.append("v2_i2_p_m9_f.fits") #imgfiles.append("v2_i2_p_m9_u16.fits") afwdataDir = eups.productDir("afwdata") if not afwdataDir: print >> sys.stderr, "Skipping testBackgroundTestImages as afwdata is not setup" return for imginfo in imginfolist: imgfile, centerValue = imginfo imgPath = afwdataDir + "/Statistics/" + imgfile # get the image and header dimg = afwImage.DecoratedImageD(imgPath) img = dimg.getImage() fitsHdr = dimg.getMetadata() # the FITS header # get the True values of the mean and stdev reqMean = fitsHdr.getAsDouble("MEANREQ") reqStdev = fitsHdr.getAsDouble("SIGREQ") naxis1 = img.getWidth() naxis2 = img.getHeight() # create a background control object bctrl = afwMath.BackgroundControl(afwMath.Interpolate.AKIMA_SPLINE) bctrl.setNxSample(5) bctrl.setNySample(5) # run the background constructor and call the getPixel() and getImage() functions. backobj = afwMath.makeBackground(img, bctrl) pixPerSubimage = img.getWidth()*img.getHeight()/(bctrl.getNxSample()*bctrl.getNySample()) stdevInterp = reqStdev/math.sqrt(pixPerSubimage) # test getPixel() testval = afwMath.cast_BackgroundMI(backobj).getPixel(naxis1/2, naxis2/2) self.assertAlmostEqual(testval/centerValue, 1, places=7) self.assertTrue( abs(testval - reqMean) < 2*stdevInterp ) # test getImage() by checking the center pixel bimg = backobj.getImageD() testImgval = bimg.get(naxis1/2, naxis2/2) self.assertTrue( abs(testImgval - reqMean) < 2*stdevInterp )
def testBackgroundTestImages(self): imginfolist = [] #imginfolist.append( ["v1_i1_g_m400_s20_f.fits", 400.05551471441612] ) # cooked to known value #imginfolist.append( ["v1_i1_g_m400_s20_f.fits", 400.00295902395123] ) # cooked to known value #imginfolist.append( ["v1_i1_g_m400_s20_f.fits", 400.08468385712251] ) # cooked to known value #imginfolist.append( ["v1_i1_g_m400_s20_f.fits", 400.00305806663295] ) # cooked to known value #imginfolist.append( ["v1_i1_g_m400_s20_f.fits", 400.0035102188698] ) # cooked to known value imginfolist.append(["v1_i1_g_m400_s20_f.fits", 399.9912966583894]) # cooked to known value #imgfiles.append("v1_i1_g_m400_s20_u16.fits") #imgfiles.append("v1_i2_g_m400_s20_f.fits" #imgfiles.append("v1_i2_g_m400_s20_u16.fits") #imgfiles.append("v2_i1_p_m9_f.fits") #imgfiles.append("v2_i1_p_m9_u16.fits") #imgfiles.append("v2_i2_p_m9_f.fits") #imgfiles.append("v2_i2_p_m9_u16.fits") for imginfo in imginfolist: imgfile, centerValue = imginfo imgPath = os.path.join(AfwdataDir, "Statistics", imgfile) # get the image and header dimg = afwImage.DecoratedImageD(imgPath) img = dimg.getImage() fitsHdr = dimg.getMetadata() # the FITS header # get the True values of the mean and stdev reqMean = fitsHdr.getAsDouble("MEANREQ") reqStdev = fitsHdr.getAsDouble("SIGREQ") naxis1 = img.getWidth() naxis2 = img.getHeight() # create a background control object bctrl = afwMath.BackgroundControl(afwMath.Interpolate.AKIMA_SPLINE) bctrl.setNxSample(5) bctrl.setNySample(5) # run the background constructor and call the getPixel() and getImage() functions. backobj = afwMath.makeBackground(img, bctrl) pixPerSubimage = img.getWidth() * img.getHeight() / ( bctrl.getNxSample() * bctrl.getNySample()) stdevInterp = reqStdev / math.sqrt(pixPerSubimage) # test getPixel() testval = afwMath.cast_BackgroundMI(backobj).getPixel( naxis1 // 2, naxis2 // 2) self.assertAlmostEqual(testval / centerValue, 1, places=7) self.assertTrue(abs(testval - reqMean) < 2 * stdevInterp) # test getImage() by checking the center pixel bimg = backobj.getImageD() testImgval = bimg.get(naxis1 // 2, naxis2 // 2) self.assertTrue(abs(testImgval - reqMean) < 2 * stdevInterp)
def testRamp(self): # make a ramping image (spline should be exact for linear increasing image nx = 512 ny = 512 rampimg = afwImage.ImageD(afwGeom.Extent2I(nx, ny)) dzdx, dzdy, z0 = 0.1, 0.2, 10000.0 for x in range(nx): for y in range(ny): rampimg.set(x, y, dzdx * x + dzdy * y + z0) # check corner, edge, and center pixels bctrl = afwMath.BackgroundControl(10, 10) bctrl.setInterpStyle(afwMath.Interpolate.CUBIC_SPLINE) bctrl.setNxSample(6) bctrl.setNySample(6) bctrl.getStatisticsControl().setNumSigmaClip( 20.0) # something large enough to avoid clipping entirely bctrl.getStatisticsControl().setNumIter(1) backobj = afwMath.makeBackground(rampimg, bctrl) xpixels = [0, nx // 2, nx - 1] ypixels = [0, ny // 2, ny - 1] for xpix in xpixels: for ypix in ypixels: testval = afwMath.cast_BackgroundMI(backobj).getPixel( xpix, ypix) self.assertAlmostEqual(testval / rampimg.get(xpix, ypix), 1, 6) # Test pickle bg = afwMath.cast_BackgroundMI(backobj) new = pickle.loads(pickle.dumps(bg)) self.assertBackgroundEqual(bg, new) # Check creation of sub-image box = afwGeom.Box2I(afwGeom.Point2I(123, 45), afwGeom.Extent2I(45, 123)) bgImage = bg.getImageF("AKIMA_SPLINE") bgSubImage = afwImage.ImageF(bgImage, box) testImage = bg.getImageF(box, "AKIMA_SPLINE") self.assertEqual(testImage.getXY0(), bgSubImage.getXY0()) self.assertEqual(testImage.getDimensions(), bgSubImage.getDimensions()) self.assertTrue(np.all(testImage.getArray() == bgSubImage.getArray()))
def testRamp(self): # make a ramping image (spline should be exact for linear increasing image nx = 512 ny = 512 x0, y0 = 9876, 54321 box = afwGeom.Box2I(afwGeom.Point2I(x0, y0), afwGeom.Extent2I(nx, ny)) rampimg = afwImage.ImageF(box) dzdx, dzdy, z0 = 0.1, 0.2, 10000.0 for x in range(nx): for y in range(ny): rampimg.set(x, y, dzdx*x + dzdy*y + z0) # check corner, edge, and center pixels bctrl = afwMath.BackgroundControl(10, 10) bctrl.setInterpStyle(afwMath.Interpolate.CUBIC_SPLINE) bctrl.setNxSample(6) bctrl.setNySample(6) bctrl.getStatisticsControl().setNumSigmaClip(20.0) # something large enough to avoid clipping entirely bctrl.getStatisticsControl().setNumIter(1) backobj = afwMath.cast_BackgroundMI(afwMath.makeBackground(rampimg, bctrl)) print(rampimg.getArray()) frame = 1 for interp in ("CONSTANT", "LINEAR", "NATURAL_SPLINE", "AKIMA_SPLINE"): diff = backobj.getImageF(interp) if display: ds9.mtv(diff, frame=frame); frame += 1 diff -= rampimg print(interp, diff.getArray().mean(), diff.getArray().std()) if display: ds9.mtv(diff, frame=frame); frame += 1 if display: ds9.mtv(rampimg, frame=frame); frame += 1 ds9.mtv(backobj.getStatsImage(), frame=frame); frame += 1 xpixels = [0, nx//2, nx - 1] ypixels = [0, ny//2, ny - 1] for xpix in xpixels: for ypix in ypixels: testval = backobj.getPixel(xpix, ypix) self.assertAlmostEqual(testval/rampimg.get(xpix, ypix), 1, 6) # Test pickle new = pickle.loads(pickle.dumps(backobj)) self.assertBackgroundEqual(backobj, new) # Check creation of sub-image box = afwGeom.Box2I(afwGeom.Point2I(123, 45), afwGeom.Extent2I(45, 123)) box.shift(afwGeom.Extent2I(x0, y0)) bgImage = backobj.getImageF("AKIMA_SPLINE") bgSubImage = afwImage.ImageF(bgImage, box) testImage = backobj.getImageF(box, "AKIMA_SPLINE") self.assertEqual(testImage.getXY0(), bgSubImage.getXY0()) self.assertEqual(testImage.getDimensions(), bgSubImage.getDimensions()) self.assertTrue(np.all(testImage.getArray() == bgSubImage.getArray()))
def testRamp(self): # make a ramping image (spline should be exact for linear increasing image nx = 512 ny = 512 rampimg = afwImage.ImageF(afwGeom.Extent2I(nx, ny)) dzdx, dzdy, z0 = 0.1, 0.2, 10000.0 for x in range(nx): for y in range(ny): rampimg.set(x, y, dzdx*x + dzdy*y + z0) # check corner, edge, and center pixels bctrl = afwMath.BackgroundControl(10, 10) bctrl.setInterpStyle(afwMath.Interpolate.CUBIC_SPLINE) bctrl.setNxSample(6) bctrl.setNySample(6) bctrl.getStatisticsControl().setNumSigmaClip(20.0) # something large enough to avoid clipping entirely bctrl.getStatisticsControl().setNumIter(1) backobj = afwMath.makeBackground(rampimg, bctrl) xpixels = [0, nx/2, nx - 1] ypixels = [0, ny/2, ny - 1] for xpix in xpixels: for ypix in ypixels: testval = afwMath.cast_BackgroundMI(backobj).getPixel(xpix, ypix) self.assertAlmostEqual(testval/rampimg.get(xpix, ypix), 1, 6) # Test pickle bg = afwMath.cast_BackgroundMI(backobj) new = pickle.loads(pickle.dumps(bg)) self.assertBackgroundEqual(bg, new) # Check creation of sub-image box = afwGeom.Box2I(afwGeom.Point2I(123, 45), afwGeom.Extent2I(45, 123)) bgImage = bg.getImageF("AKIMA_SPLINE") bgSubImage = afwImage.ImageF(bgImage, box) testImage = bg.getImageF(box, "AKIMA_SPLINE") self.assertEqual(testImage.getXY0(), bgSubImage.getXY0()) self.assertEqual(testImage.getDimensions(), bgSubImage.getDimensions()) self.assertTrue(np.all(testImage.getArray() == bgSubImage.getArray()))
def testgetPixel(self): """Test the getPixel() function """ xcen, ycen = 50, 100 bgCtrl = afwMath.BackgroundControl(10, 10) bgCtrl.setNxSample(5) bgCtrl.setNySample(5) bgCtrl.getStatisticsControl().setNumIter(3) bgCtrl.getStatisticsControl().setNumSigmaClip(3) back = afwMath.makeBackground(self.image, bgCtrl) self.assertEqual(afwMath.cast_BackgroundMI(back).getPixel(xcen, ycen), self.val)
def simpleBackground(image): binsize = 128 nx = int(image.getWidth() / binsize) + 1 ny = int(image.getHeight() / binsize) + 1 bctrl = afwMath.BackgroundControl(nx, ny) bkgd = afwMath.makeBackground(image, bctrl) statsImage = afwMath.cast_BackgroundMI(bkgd).getStatsImage() image -= bkgd.getImageF(afwMath.Interpolate.NATURAL_SPLINE) return bkgd
def simpleBackground(image): binsize = 128 nx = int(image.getWidth()/binsize) + 1 ny = int(image.getHeight()/binsize) + 1 bctrl = afwMath.BackgroundControl(nx, ny) bkgd = afwMath.makeBackground(image, bctrl) statsImage = afwMath.cast_BackgroundMI(bkgd).getStatsImage() image -= bkgd.getImageF(afwMath.Interpolate.NATURAL_SPLINE) return bkgd
def testBadPatch(self): """Test that a large bad patch of an image doesn't cause an absolute failure""" initialValue = 20 mi = afwImage.MaskedImageF(500, 200) mi.set((initialValue, 0x0, 1.0)) im = mi.getImage() im[0:200, :] = np.nan del im msk = mi.getMask() badBits = msk.getPlaneBitMask( ['EDGE', 'DETECTED', 'DETECTED_NEGATIVE']) msk[0:400, :] |= badBits del msk if display: ds9.mtv(mi, frame=0) sctrl = afwMath.StatisticsControl() sctrl.setAndMask(badBits) nx, ny = 17, 17 bctrl = afwMath.BackgroundControl(nx, ny, sctrl, afwMath.MEANCLIP) bkgd = afwMath.makeBackground(mi, bctrl) statsImage = afwMath.cast_BackgroundMI(bkgd).getStatsImage() if display: ds9.mtv(statsImage, frame=1) # the test is that this doesn't fail if the bug (#2297) is fixed bkgdImage = bkgd.getImageF(afwMath.Interpolate.NATURAL_SPLINE, afwMath.REDUCE_INTERP_ORDER) self.assertEqual(np.mean(bkgdImage[0:100, 0:100].getArray()), initialValue) if display: ds9.mtv(bkgdImage, frame=2) # # Check that we can fix the NaNs in the statsImage # sim = statsImage.getImage().getArray() sim[np.isnan(sim)] = initialValue # replace NaN by initialValue bkgdImage = bkgd.getImageF(afwMath.Interpolate.NATURAL_SPLINE, afwMath.REDUCE_INTERP_ORDER) self.assertAlmostEqual( np.mean(bkgdImage[0:100, 0:100].getArray(), dtype=np.float64), initialValue)
def testBadAreaFailsSpline(self): """Check that a NaN in the stats image doesn't cause spline interpolation to fail (#2734)""" image = afwImage.ImageF(15, 9) for y in range(image.getHeight()): for x in range(image.getWidth()): image.set( x, y, 1 + 2 * y ) # n.b. linear, which is what the interpolation will fall back to # Set the right corner to NaN. This will mean that we have too few points for a spline interpolator binSize = 3 image[-binSize:, -binSize:] = np.nan nx = image.getWidth() // binSize ny = image.getHeight() // binSize sctrl = afwMath.StatisticsControl() bctrl = afwMath.BackgroundControl(nx, ny, sctrl, afwMath.MEANCLIP) bkgd = afwMath.makeBackground(image, bctrl) if display: ds9.mtv(image) ds9.mtv(afwMath.cast_BackgroundMI(bkgd).getStatsImage(), frame=1) # # Should throw if we don't permit REDUCE_INTERP_ORDER # utilsTests.assertRaisesLsstCpp(self, lsst.pex.exceptions.OutOfRangeException, bkgd.getImageF, afwMath.Interpolate.NATURAL_SPLINE) # # The interpolation should fall back to linear for the right part of the image # where the NaNs don't permit spline interpolation (n.b. this happens to be exact) # bkgdImage = bkgd.getImageF(afwMath.Interpolate.NATURAL_SPLINE, afwMath.REDUCE_INTERP_ORDER) if display: ds9.mtv(bkgdImage, frame=2) image -= bkgdImage self.assertEqual( afwMath.makeStatistics(image, afwMath.MEAN).getValue(), 0.0)
def testBackgroundTestImages(self): """Tests Laher's afwdata/Statistics/*.fits images (doubles)""" imginfolist = [] imginfolist.append(["v1_i1_g_m400_s20_f.fits", 399.9912966583894]) # cooked to known value for imginfo in imginfolist: imgfile, centerValue = imginfo imgPath = os.path.join(AfwdataDir, "Statistics", imgfile) # get the image and header dimg = afwImage.DecoratedImageF(imgPath) img = dimg.getImage() fitsHdr = dimg.getMetadata() # the FITS header # get the True values of the mean and stdev reqMean = fitsHdr.getAsDouble("MEANREQ") reqStdev = fitsHdr.getAsDouble("SIGREQ") naxis1 = img.getWidth() naxis2 = img.getHeight() # create a background control object bctrl = afwMath.BackgroundControl(afwMath.Interpolate.AKIMA_SPLINE) bctrl.setNxSample(5) bctrl.setNySample(5) # run the background constructor and call the getPixel() and getImage() functions. backobj = afwMath.makeBackground(img, bctrl) pixPerSubimage = img.getWidth() * img.getHeight() / ( bctrl.getNxSample() * bctrl.getNySample()) stdevInterp = reqStdev / math.sqrt(pixPerSubimage) # test getPixel() testval = afwMath.cast_BackgroundMI(backobj).getPixel( naxis1 // 2, naxis2 // 2) self.assertAlmostEqual(testval / centerValue, 1, places=7) self.assertLess(abs(testval - reqMean), 2 * stdevInterp) # test getImage() by checking the center pixel bimg = backobj.getImageF() testImgval = bimg.get(naxis1 // 2, naxis2 // 2) self.assertLess(abs(testImgval - reqMean), 2 * stdevInterp)
def testBackgroundFromStatsImage(self): """Check that we can rebuild a Background from a BackgroundMI.getStatsImage() """ bgCtrl = afwMath.BackgroundControl(10, 10) bkgd = afwMath.cast_BackgroundMI(afwMath.makeBackground(self.image, bgCtrl)) interpStyle = afwMath.Interpolate.AKIMA_SPLINE undersampleStyle = afwMath.REDUCE_INTERP_ORDER bkgdImage = bkgd.getImageF(interpStyle, undersampleStyle) self.assertEqual(np.mean(bkgdImage.getArray()), self.val) self.assertEqual(interpStyle, bkgd.getAsUsedInterpStyle()) self.assertEqual(undersampleStyle, bkgd.getAsUsedUndersampleStyle()) # # OK, we have our background. Make a copy # bkgd2 = afwMath.BackgroundMI(self.image.getBBox(), bkgd.getStatsImage()) del bkgd # we should be handling the memory correctly, but let's check bkgdImage2 = bkgd2.getImageF(interpStyle) self.assertEqual(np.mean(bkgdImage2.getArray()), self.val)
def testBadPatch(self): """Test that a large bad patch of an image doesn't cause an absolute failure""" initialValue = 20 mi = afwImage.MaskedImageF(500, 200) mi.set((initialValue, 0x0, 1.0)) im = mi.getImage() im[0:200, :] = np.nan del im msk = mi.getMask() badBits = msk.getPlaneBitMask(['EDGE', 'DETECTED', 'DETECTED_NEGATIVE']) msk[0:400, :] |= badBits del msk if display: ds9.mtv(mi, frame=0) sctrl = afwMath.StatisticsControl() sctrl.setAndMask(badBits) nx, ny = 17, 17 bctrl = afwMath.BackgroundControl(nx, ny, sctrl, afwMath.MEANCLIP) bkgd = afwMath.makeBackground(mi, bctrl) statsImage = afwMath.cast_BackgroundMI(bkgd).getStatsImage() if display: ds9.mtv(statsImage, frame=1) # the test is that this doesn't fail if the bug (#2297) is fixed bkgdImage = bkgd.getImageF(afwMath.Interpolate.NATURAL_SPLINE, afwMath.REDUCE_INTERP_ORDER) self.assertEqual(np.mean(bkgdImage[0:100, 0:100].getArray()), initialValue) if display: ds9.mtv(bkgdImage, frame=2) # # Check that we can fix the NaNs in the statsImage # defaultValue = 10 sim = statsImage.getImage().getArray() sim[np.isnan(sim)] = defaultValue # replace NaN by defaultValue bkgdImage = bkgd.getImageF(afwMath.Interpolate.NATURAL_SPLINE, afwMath.REDUCE_INTERP_ORDER) self.assertEqual(np.mean(bkgdImage[0:100, 0:100].getArray()), defaultValue)
def main(): image = getImage() if display: ds9.mtv(image, frame=0) bkgd = simpleBackground(image) image = getImage() bkgd = complexBackground(image) if display: ds9.mtv(image, frame=1) ds9.mtv(afwMath.cast_BackgroundMI(bkgd).getStatsImage(), frame=2) order = 2 actrl = afwMath.ApproximateControl(afwMath.ApproximateControl.CHEBYSHEV, order, order) approx = bkgd.getApproximate(actrl) approx.getImage() approx.getMaskedImage() approx.getImage(order - 1)
def testBadAreaFailsSpline(self): """Check that a NaN in the stats image doesn't cause spline interpolation to fail (#2734) """ image = afwImage.ImageF(15, 9) for y in range(image.getHeight()): for x in range(image.getWidth()): image.set(x, y, 1 + 2*y) # n.b. linear, which is what the interpolation will fall back to # Set the right corner to NaN. This will mean that we have too few points for a spline interpolator binSize = 3 image[-binSize:, -binSize:] = np.nan nx = image.getWidth()//binSize ny = image.getHeight()//binSize sctrl = afwMath.StatisticsControl() bctrl = afwMath.BackgroundControl(nx, ny, sctrl, afwMath.MEANCLIP) bkgd = afwMath.makeBackground(image, bctrl) if display: ds9.mtv(image) ds9.mtv(afwMath.cast_BackgroundMI(bkgd).getStatsImage(), frame=1) # # Should throw if we don't permit REDUCE_INTERP_ORDER # self.assertRaises(lsst.pex.exceptions.OutOfRangeError, bkgd.getImageF, afwMath.Interpolate.NATURAL_SPLINE) # # The interpolation should fall back to linear for the right part of the image # where the NaNs don't permit spline interpolation (n.b. this happens to be exact) # bkgdImage = bkgd.getImageF(afwMath.Interpolate.NATURAL_SPLINE, afwMath.REDUCE_INTERP_ORDER) if display: ds9.mtv(bkgdImage, frame=2) image -= bkgdImage self.assertEqual(afwMath.makeStatistics(image, afwMath.MEAN).getValue(), 0.0)
def testCFHT(self): """Test background subtraction on some real CFHT data""" mi = self.getCfhtImage() bctrl = afwMath.BackgroundControl(mi.getWidth()//128, mi.getHeight()//128) bctrl.getStatisticsControl().setNumSigmaClip(3.0) bctrl.getStatisticsControl().setNumIter(2) backobj = afwMath.makeBackground(mi.getImage(), bctrl) if display: ds9.mtv(mi, frame = 0) im = mi.getImage() im -= backobj.getImageF("AKIMA_SPLINE") if display: ds9.mtv(mi, frame = 1) statsImage = afwMath.cast_BackgroundMI(backobj).getStatsImage() if display: ds9.mtv(statsImage, frame=2) ds9.mtv(statsImage.getVariance(), frame=3)
def result(fits): cat = pysex.run(fits, params=['X_IMAGE', 'Y_IMAGE', 'FLUX_APER'], conf_args={'PHOT_APERTURES':5}) print cat['FLUX_APER'] image = afwImage.MaskedImageF(fits) binsize = 128 nx = int(image.getWidth()/binsize) + 1 ny = int(image.getHeight()/binsize) + 1 bctrl = afwMath.BackgroundControl(nx, ny) bkgd = afwMath.makeBackground(image, bctrl) statsImage = afwMath.cast_BackgroundMI(bkgd).getStatsImage() image -= bkgd.getImageF(afwMath.Interpolate.NATURAL_SPLINE) return bkgd return
def testCFHT(self): """Test background subtraction on some real CFHT data""" afwdataDir = eups.productDir("afwdata") if not afwdataDir: print >> sys.stderr, "Skipping testCFHT as afwdata is not setup" return mi = afwImage.MaskedImageF( os.path.join(afwdataDir, "CFHT", "D4", "cal-53535-i-797722_1.fits")) mi = mi.Factory( mi, afwGeom.Box2I(afwGeom.Point2I(32, 2), afwGeom.Point2I(2079, 4609)), afwImage.LOCAL) bctrl = afwMath.BackgroundControl(mi.getWidth() // 128, mi.getHeight() // 128) bctrl.getStatisticsControl().setNumSigmaClip(3.0) bctrl.getStatisticsControl().setNumIter(2) backobj = afwMath.makeBackground(mi.getImage(), bctrl) if display: ds9.mtv(mi, frame=0) im = mi.getImage() im -= backobj.getImageF("AKIMA_SPLINE") if display: ds9.mtv(mi, frame=1) statsImage = afwMath.cast_BackgroundMI(backobj).getStatsImage() if display: ds9.mtv(backobj.getStatsImage(), frame=2) ds9.mtv(backobj.getStatsImage().getVariance(), frame=3)
def testCFHT(self): """Test background subtraction on some real CFHT data """ mi = self.getCfhtImage() bctrl = afwMath.BackgroundControl(mi.getWidth()//128, mi.getHeight()//128) bctrl.getStatisticsControl().setNumSigmaClip(3.0) bctrl.getStatisticsControl().setNumIter(2) backobj = afwMath.makeBackground(mi.getImage(), bctrl) if display: ds9.mtv(mi, frame = 0) im = mi.getImage() im -= backobj.getImageF("AKIMA_SPLINE") if display: ds9.mtv(mi, frame = 1) statsImage = afwMath.cast_BackgroundMI(backobj).getStatsImage() if display: ds9.mtv(statsImage, frame=2) ds9.mtv(statsImage.getVariance(), frame=3)
def testRamp(self): """tests Laher's afwdata/Statistics/*.fits images (doubles)""" # make a ramping image (spline should be exact for linear increasing image nx = 512 ny = 512 x0, y0 = 9876, 54321 box = afwGeom.Box2I(afwGeom.Point2I(x0, y0), afwGeom.Extent2I(nx, ny)) rampimg = afwImage.ImageF(box) dzdx, dzdy, z0 = 0.1, 0.2, 10000.0 for x in range(nx): for y in range(ny): rampimg.set(x, y, dzdx * x + dzdy * y + z0) # check corner, edge, and center pixels bctrl = afwMath.BackgroundControl(10, 10) bctrl.setInterpStyle(afwMath.Interpolate.CUBIC_SPLINE) bctrl.setNxSample(6) bctrl.setNySample(6) bctrl.getStatisticsControl().setNumSigmaClip( 20.0) # large enough to entirely avoid clipping bctrl.getStatisticsControl().setNumIter(1) backobj = afwMath.cast_BackgroundMI( afwMath.makeBackground(rampimg, bctrl)) if debugMode: print(rampimg.getArray()) frame = 1 for interp in ("CONSTANT", "LINEAR", "NATURAL_SPLINE", "AKIMA_SPLINE"): diff = backobj.getImageF(interp) if debugMode: ds9.mtv(diff, frame=frame) frame += 1 diff -= rampimg if debugMode: print(interp, diff.getArray().mean(), diff.getArray().std()) if debugMode: ds9.mtv(diff, frame=frame) frame += 1 if debugMode: ds9.mtv(rampimg, frame=frame) frame += 1 ds9.mtv(backobj.getStatsImage(), frame=frame) frame += 1 xpixels = [0, nx // 2, nx - 1] ypixels = [0, ny // 2, ny - 1] for xpix in xpixels: for ypix in ypixels: testval = backobj.getPixel(xpix, ypix) self.assertAlmostEqual(testval / rampimg.get(xpix, ypix), 1, 6) # Test pickle new = pickle.loads(pickle.dumps(backobj)) self.assertBackgroundEqual(backobj, new) # Check creation of sub-image box = afwGeom.Box2I(afwGeom.Point2I(123, 45), afwGeom.Extent2I(45, 123)) box.shift(afwGeom.Extent2I(x0, y0)) bgImage = backobj.getImageF("AKIMA_SPLINE") bgSubImage = afwImage.ImageF(bgImage, box) testImage = backobj.getImageF(box, "AKIMA_SPLINE") self.assertEqual(testImage.getXY0(), bgSubImage.getXY0()) self.assertEqual(testImage.getDimensions(), bgSubImage.getDimensions()) self.assertImagesEqual(testImage, bgSubImage)