def testPca(self): """Test calculating PCA""" random.seed(0) width, height = 200, 100 numBases = 3 numInputs = 3 bases = [] for i in range(numBases): im = afwImage.ImageF(width, height) array = im.getArray() x, y = np.indices(array.shape) period = 5 * (i + 1) fx = np.sin(2 * math.pi / period * x + 2 * math.pi / numBases * i) fy = np.sin(2 * math.pi / period * y + 2 * math.pi / numBases * i) array[x, y] = fx + fy bases.append(im) if display: mos = displayUtils.Mosaic(background=-10) ds9.mtv(mos.makeMosaic(bases), title="Basis functions", frame=1) inputs = [] for i in range(numInputs): im = afwImage.ImageF(afwGeom.Extent2I(width, height)) im.set(0) for b in bases: im.scaledPlus(random.random(), b) inputs.append(im) self.ImageSet.addImage(im, 1.0) if display: mos = displayUtils.Mosaic(background=-10) ds9.mtv(mos.makeMosaic(inputs), title="Inputs", frame=2) self.ImageSet.analyze() eImages = [] for img in self.ImageSet.getEigenImages(): eImages.append(img) if display: mos = displayUtils.Mosaic(background=-10) ds9.mtv(mos.makeMosaic(eImages), title="Eigenimages", frame=3) self.assertEqual(len(eImages), numInputs) # Test for orthogonality for i1, i2 in itertools.combinations(range(len(eImages)), 2): inner = afwImage.innerProduct(eImages[i1], eImages[i2]) norm1 = eImages[i1].getArray().sum() norm2 = eImages[i2].getArray().sum() inner /= norm1 * norm2 self.assertAlmostEqual(inner, 0)
def setUp(self): np.random.seed(1) self.val = 10 self.image = afwImage.ImageF( afwGeom.Box2I(afwGeom.Point2I(1000, 500), afwGeom.Extent2I(100, 200))) self.image.set(self.val)
def testInnerProducts(self): """Test inner products""" width, height = 10, 20 im1 = afwImage.ImageF(afwGeom.Extent2I(width, height)) val1 = 10 im1.set(val1) im2 = im1.Factory(im1.getDimensions()) val2 = 20 im2.set(val2) self.assertEqual(afwImage.innerProduct(im1, im1), width * height * val1 * val1) self.assertEqual(afwImage.innerProduct(im1, im2), width * height * val1 * val2) im2.set(0, 0, 0) self.assertEqual(afwImage.innerProduct(im1, im2), (width * height - 1) * val1 * val2) im2.set(0, 0, val2) # reinstate value im2.set(width - 1, height - 1, 1) self.assertEqual(afwImage.innerProduct(im1, im2), (width * height - 1) * val1 * val2 + val1)
def _testBadValue(self, badVal): """Test that we can handle an instance of `badVal` in the data correctly""" x, y = 10, 10 for useImage in [True, False]: if useImage: self.image = afwImage.ImageF(100, 100) self.image.set(self.val) self.image.set(x, y, badVal) else: self.image = afwImage.MaskedImageF(100, 100) self.image.set(self.val, 0x0, 1.0) self.image.set(x, y, (badVal, 0x0, 1.0)) self.assertEqual( afwMath.makeStatistics(self.image, afwMath.MAX).getValue(), self.val) self.assertEqual( afwMath.makeStatistics(self.image, afwMath.MEAN).getValue(), self.val) sctrl = afwMath.StatisticsControl() sctrl.setNanSafe(False) self.assertFalse( np.isfinite( afwMath.makeStatistics(self.image, afwMath.MAX, sctrl).getValue())) self.assertFalse( np.isfinite( afwMath.makeStatistics(self.image, afwMath.MEAN, sctrl).getValue()))
def testErrorsFromVariance(self): """Test that we can estimate the errors from the incoming variances""" weight, mean, variance = 0.1, 1.0, 10.0 ctrl = afwMath.StatisticsControl() mi = afwImage.MaskedImageF(afwGeom.Extent2I(10, 10)) npix = 10 * 10 mi.getImage().set(mean) mi.getVariance().set(variance) weights = afwImage.ImageF(mi.getDimensions()) weights.set(weight) ctrl.setCalcErrorFromInputVariance(True) weighted = afwMath.makeStatistics( mi, weights, afwMath.MEAN | afwMath.MEANCLIP | afwMath.SUM | afwMath.ERRORS, ctrl) self.assertAlmostEqual( weighted.getValue(afwMath.SUM) / (npix * mean * weight), 1) self.assertAlmostEqual(weighted.getValue(afwMath.MEAN), mean) self.assertAlmostEqual( weighted.getError(afwMath.MEAN)**2, variance / npix) self.assertAlmostEqual( weighted.getError(afwMath.MEANCLIP)**2, variance / npix)
def testMaxWithNan(self): """Test that we can handle NaNs correctly""" x, y = 10, 10 for useImage in [True, False]: if useImage: self.image = afwImage.ImageF(100, 100) self.image.set(self.val) self.image.set(x, y, np.nan) else: self.image = afwImage.MaskedImageF(100, 100) self.image.set(self.val, 0x0, 1.0) self.image.set(x, y, (np.nan, 0x0, 1.0)) self.assertEqual( afwMath.makeStatistics(self.image, afwMath.MAX).getValue(), self.val) self.assertEqual( afwMath.makeStatistics(self.image, afwMath.MEAN).getValue(), self.val) sctrl = afwMath.StatisticsControl() sctrl.setNanSafe(False) self.assertFalse( np.isfinite( afwMath.makeStatistics(self.image, afwMath.MAX, sctrl).getValue())) self.assertFalse( np.isfinite( afwMath.makeStatistics(self.image, afwMath.MEAN, sctrl).getValue()))
def getParabolaImage(self, nx, ny, pars=(1.0e-4, 1.0e-4, 0.1, 0.2, 10.0)): parabimg = afwImage.ImageF(afwGeom.Extent2I(nx, ny)) d2zdx2, d2zdy2, dzdx, dzdy, z0 = pars # no cross-terms for x in range(nx): for y in range(ny): parabimg.set(x, y, d2zdx2*x*x + d2zdy2*y*y + dzdx*x + dzdy*y + z0) return parabimg
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 testUndersample(self): """Test how the program handles nx,ny being too small for requested interp style.""" nx = 64 ny = 64 img = afwImage.ImageF(afwGeom.Extent2I(nx, ny)) # make a background control object bctrl = afwMath.BackgroundControl(10, 10) bctrl.setInterpStyle(afwMath.Interpolate.CUBIC_SPLINE) bctrl.setNxSample(3) bctrl.setNySample(3) # put nx,ny back to 2 and see if it adjusts the interp style down to linear bctrl.setNxSample(2) bctrl.setNySample(2) bctrl.setUndersampleStyle("REDUCE_INTERP_ORDER") backobj = afwMath.makeBackground(img, bctrl) backobj.getImageF( ) # Need to interpolate background to discover what we actually needed self.assertEqual(backobj.getAsUsedInterpStyle(), afwMath.Interpolate.LINEAR) # put interp style back up to cspline and see if it throws an exception bctrl.setUndersampleStyle("THROW_EXCEPTION") def tst(img, bctrl): backobj = afwMath.makeBackground(img, bctrl) backobj.getImageF( "CUBIC_SPLINE" ) # only now do we see that we have too few points self.assertRaises(lsst.pex.exceptions.InvalidParameterError, tst, img, bctrl)
def testOddSize(self): """Test for ticket #1781 -- without it, in oddly-sized images there is a chunk of pixels on the right/bottom that do not go into the fit and are extrapolated. After this ticket, the subimage boundaries are spread more evenly so the last pixels get fit as well. This slightly strange test case checks that the interpolant is close to the function at the end. I could not think of an interpolant that would fit exactly, so this just puts a limit on the errors. """ W, H = 2, 99 image = afwImage.ImageF(afwGeom.Extent2I(W, H)) bgCtrl = afwMath.BackgroundControl(afwMath.Interpolate.LINEAR) bgCtrl.setNxSample(2) NY = 10 bgCtrl.setNySample(NY) for y in range(H): for x in range(W): B = 89 if y < B: image.set(x, y, y) else: image.set(x, y, B + (y - B) * -1.) bobj = afwMath.makeBackground(image, bgCtrl) back = bobj.getImageF() for iy, by in zip([image.get(0, y) for y in range(H)], [back.get(0, y) for y in range(H)]): self.assertLess(abs(iy - by), 5)
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 getParabolaImage(self, nx, ny, pars=(1.0e-4, 1.0e-4, 0.1, 0.2, 10.0)): """Make sure a quadratic map is *well* reproduced by the spline model""" parabimg = afwImage.ImageF(afwGeom.Extent2I(nx, ny)) d2zdx2, d2zdy2, dzdx, dzdy, z0 = pars # no cross-terms for x in range(nx): for y in range(ny): parabimg.set( x, y, d2zdx2 * x * x + d2zdy2 * y * y + dzdx * x + dzdy * y + z0) return parabimg
def testTicket1681OffByOne(self): if False: # doesn't seem to actually test anything, and writes b?im.fits im = afwImage.ImageF(40, 40); im.set(5, 6, 100); nx, ny = im.getWidth()//2, im.getHeight()//2 print nx, ny bctrl = afwMath.BackgroundControl("LINEAR", nx, ny) bctrl.setStatisticsProperty(afwMath.MEAN) bkd = afwMath.makeBackground(im, bctrl) bim = bkd.getImageF() im.writeFits("im.fits") bim.writeFits("bim.fits")
def testMeanClipSingleValue(self): """Verify that the 3-sigma clipped mean doesn't not return NaN for a single value.""" stats = afwMath.makeStatistics(self.image, afwMath.MEANCLIP) self.assertEqual(stats.getValue(afwMath.MEANCLIP), self.val) # this bug was caused by the iterative nature of the MEANCLIP. # With only one point, the sample variance returns NaN to avoid a divide by zero error # Thus, on the second iteration, the clip width (based on _variance) is NaN and corrupts # all further calculations. img = afwImage.ImageF(afwGeom.Extent2I(1, 1)) img.set(0) stats = afwMath.makeStatistics(img, afwMath.MEANCLIP) self.assertEqual(stats.getValue(), 0)
def testStatisticsRamp(self): """ Tests Statistics on a 'ramp' (image with constant gradient) """ nx = 101 ny = 64 img = afwImage.ImageF(afwGeom.Extent2I(nx, ny)) z0 = 10.0 dzdx = 1.0 mean = z0 + (nx // 2) * dzdx stdev = 0.0 for y in range(ny): for x in range(nx): z = z0 + dzdx * x img.set(x, y, z) stdev += (z - mean) * (z - mean) stdev = math.sqrt(stdev / (nx * ny - 1)) stats = afwMath.makeStatistics( img, afwMath.NPOINT | afwMath.STDEV | afwMath.MEAN) testmean = stats.getValue(afwMath.MEAN) teststdev = stats.getValue(afwMath.STDEV) self.assertEqual(stats.getValue(afwMath.NPOINT), nx * ny) self.assertEqual(testmean, mean) self.assertAlmostEqual(teststdev, stdev) stats = afwMath.makeStatistics( img, afwMath.STDEV | afwMath.MEAN | afwMath.ERRORS) mean, meanErr = stats.getResult(afwMath.MEAN) sd = stats.getValue(afwMath.STDEV) self.assertEqual(mean, img.get(nx // 2, ny // 2)) self.assertEqual(meanErr, sd / math.sqrt(img.getWidth() * img.getHeight())) # =============================================================================== # sjb code for percentiles and clipped stats stats = afwMath.makeStatistics(img, afwMath.MEDIAN) self.assertEqual(z0 + dzdx * (nx - 1) / 2.0, stats.getValue(afwMath.MEDIAN)) stats = afwMath.makeStatistics(img, afwMath.IQRANGE) self.assertEqual(dzdx * (nx - 1) / 2.0, stats.getValue(afwMath.IQRANGE)) stats = afwMath.makeStatistics(img, afwMath.MEANCLIP) self.assertEqual(z0 + dzdx * (nx - 1) / 2.0, stats.getValue(afwMath.MEANCLIP))
def testBackgroundListIO(self): """Test I/O for BackgroundLists""" bgCtrl = afwMath.BackgroundControl(10, 10) interpStyle = afwMath.Interpolate.AKIMA_SPLINE undersampleStyle = afwMath.REDUCE_INTERP_ORDER approxOrderX = 6 approxOrderY = 6 im = self.image.Factory(self.image, self.image.getBBox(afwImage.PARENT)) arr = im.getArray() arr += numpy.random.normal(size=(im.getHeight(), im.getWidth())) for astyle in afwMath.ApproximateControl.UNKNOWN, afwMath.ApproximateControl.CHEBYSHEV: actrl = afwMath.ApproximateControl(astyle, approxOrderX) bgCtrl.setApproximateControl(actrl) backgroundList = afwMath.BackgroundList() backImage = afwImage.ImageF(im.getDimensions()) for i in range(2): bkgd = afwMath.makeBackground(im, bgCtrl) if i == 0: # no need to call getImage backgroundList.append((bkgd, interpStyle, undersampleStyle, astyle, approxOrderX, approxOrderY)) else: backgroundList.append( bkgd) # Relies on having called getImage; deprecated backImage += bkgd.getImageF(interpStyle, undersampleStyle) fileName = "backgroundList.fits" try: backgroundList.writeFits(fileName) backgrounds = afwMath.BackgroundList.readFits(fileName) finally: if os.path.exists(fileName): os.unlink(fileName) img = backgrounds.getImage() # # Check that the read-back image is identical to that generated from the backgroundList # round-tripped to disk # backImage -= img self.assertEqual(np.min(backImage.getArray()), 0.0) self.assertEqual(np.max(backImage.getArray()), 0.0)
def testAdjustLevel(self): """Test that we can adjust a background level """ sky = 100 im = afwImage.ImageF(40, 40); im.set(sky); nx, ny = im.getWidth()//2, im.getHeight()//2 bctrl = afwMath.BackgroundControl("LINEAR", nx, ny) bkd = afwMath.makeBackground(im, bctrl) self.assertEqual(afwMath.makeStatistics(bkd.getImageF(), afwMath.MEAN).getValue(), sky) delta = 123 bkd += delta self.assertEqual(afwMath.makeStatistics(bkd.getImageF(), afwMath.MEAN).getValue(), sky + delta) bkd -= delta self.assertEqual(afwMath.makeStatistics(bkd.getImageF(), afwMath.MEAN).getValue(), sky)
def testOddSize(self): ''' Test for ticket #1781 -- without it, in oddly-sized images there is a chunk of pixels on the right/bottom that do not go into the fit and are extrapolated. After this ticket, the subimage boundaries are spread more evenly so the last pixels get fit as well. This slightly strange test case checks that the interpolant is close to the function at the end. I could not think of an interpolant that would fit exactly, so this just puts a limit on the errors. ''' W, H = 2, 99 image = afwImage.ImageF(afwGeom.Extent2I(W, H)) bgCtrl = afwMath.BackgroundControl(afwMath.Interpolate.LINEAR) bgCtrl.setNxSample(2) NY = 10 bgCtrl.setNySample(NY) for y in range(H): for x in range(W): B = 89 if y < B: image.set(x, y, y) else: image.set(x, y, B + (y - B) * -1.) #0.5) bobj = afwMath.makeBackground(image, bgCtrl) back = bobj.getImageD() for iy, by in zip([image.get(0, y) for y in range(H)], [back.get(0, y) for y in range(H)]): self.assertTrue(abs(iy - by) < 5) if False: import matplotlib matplotlib.use('Agg') import pylab as plt plt.clf() IY = [image.get(0, y) for y in range(H)] BY = [back.get(0, y) for y in range(H)] for iy, by in zip(IY, BY): print 'diff', iy - by b = np.linspace(0, H - 1, NY + 1) plt.plot(IY, 'b-', lw=3, alpha=0.5) plt.plot(BY, 'r-') for y in b: plt.axvline(y) plt.savefig('bg.png')
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 testAddImages(self): """Test adding images to a PCA set""" nImage = 3 for i in range(nImage): im = afwImage.ImageF(afwGeom.Extent2I(21, 21)) val = 1 im.set(val) self.ImageSet.addImage(im, 1.0) vec = self.ImageSet.getImageList() self.assertEqual(len(vec), nImage) self.assertEqual(vec[nImage - 1].get(0, 0), val) def tst(): """Try adding an image with no flux""" self.ImageSet.addImage(im, 0.0) self.assertRaises(pexExcept.OutOfRangeError, tst)
def testSubImage(self): """Test getImage on a subregion of the full background image Using real image data is a cheap way to get a variable background """ mi = self.getCfhtImage() bctrl = afwMath.BackgroundControl(mi.getWidth()//128, mi.getHeight()//128) backobj = afwMath.makeBackground(mi.getImage(), bctrl) subBBox = afwGeom.Box2I(afwGeom.Point2I(1000, 3000), afwGeom.Extent2I(100, 100)) bgFullImage = backobj.getImageF() self.assertEqual(bgFullImage.getBBox(), mi.getBBox()) subFullArr = afwImage.ImageF(bgFullImage, subBBox).getArray() bgSubImage = backobj.getImageF(subBBox, bctrl.getInterpStyle()) subArr = bgSubImage.getArray() # the pixels happen to be identical but it is safer not to rely on that; close is good enough self.assertTrue(np.allclose(subArr, subFullArr))
def testWeightedSum2(self): """Test using a weight image separate from the variance plane""" weight, mean = 0.1, 1.0 ctrl = afwMath.StatisticsControl() mi = afwImage.MaskedImageF(afwGeom.Extent2I(10, 10)) npix = 10 * 10 mi.getImage().set(mean) mi.getVariance().set(np.nan) weights = afwImage.ImageF(mi.getDimensions()) weights.set(weight) stats = afwMath.makeStatistics(mi, afwMath.SUM, ctrl) self.assertEqual(stats.getValue(afwMath.SUM), mean * npix) weighted = afwMath.makeStatistics(mi, weights, afwMath.SUM, ctrl) # precision at "4 places" as images are floats # ... variance = 0.1 is stored as 0.100000001 self.assertAlmostEqual(weighted.getValue(afwMath.SUM), mean * npix * weight, 4)
def testBackgroundList(self): """Test that a BackgroundLists behaves like a list""" bgCtrl = afwMath.BackgroundControl(10, 10) interpStyle = afwMath.Interpolate.AKIMA_SPLINE undersampleStyle = afwMath.REDUCE_INTERP_ORDER approxStyle = afwMath.ApproximateControl.UNKNOWN approxOrderX = 0 approxOrderY = 0 backgroundList = afwMath.BackgroundList() backImage = afwImage.ImageF(self.image.getDimensions()) for i in range(2): bkgd = afwMath.makeBackground(self.image, bgCtrl) if i == 0: # no need to call getImage backgroundList.append( (bkgd, interpStyle, undersampleStyle, approxStyle, approxOrderX, approxOrderY)) else: backgroundList.append( bkgd) # Relies on having called getImage; deprecated def assertBackgroundList(bgl): self.assertEqual(len(bgl), 2) # check that len() works for a in bgl: # check that we can iterate pass self.assertEqual(len(bgl[0]), 6) # check that we can index # check that we always have a tuple (bkgd, interp, under, approxStyle, orderX, orderY) self.assertEqual(len(bgl[1]), 6) assertBackgroundList(backgroundList) # Check pickling new = pickle.loads(pickle.dumps(backgroundList)) assertBackgroundList(new) self.assertEqual(len(new), len(backgroundList)) for i, j in zip(new, backgroundList): self.assertBackgroundEqual(i[0], j[0]) self.assertEqual(i[1:], j[1:])
def testMean(self): """Test calculating mean image""" width, height = 10, 20 values = (100, 200, 300) meanVal = 0 for val in values: im = afwImage.ImageF(afwGeom.Extent2I(width, height)) im.set(val) self.ImageSet.addImage(im, 1.0) meanVal += val meanVal = meanVal / len(values) mean = self.ImageSet.getMean() self.assertEqual(mean.getWidth(), width) self.assertEqual(mean.getHeight(), height) self.assertEqual(mean.get(0, 0), meanVal) self.assertEqual(mean.get(width - 1, height - 1), meanVal)
def testBackgroundListIO(self): """Test I/O for BackgroundLists""" bgCtrl = afwMath.BackgroundControl(10, 10) interpStyle = afwMath.Interpolate.AKIMA_SPLINE undersampleStyle = afwMath.REDUCE_INTERP_ORDER backgroundList = afwMath.BackgroundList() backImage = afwImage.ImageF(self.image.getDimensions()) for i in range(2): bkgd = afwMath.makeBackground(self.image, bgCtrl) if i == 0: backgroundList.append(( bkgd, interpStyle, undersampleStyle, )) # no need to call getImage else: backgroundList.append( bkgd) # Relies on having called getImage; deprecated backImage += bkgd.getImageF(interpStyle, undersampleStyle) with utilsTests.getTempFilePath(".fits") as fileName: backgroundList.writeFits(fileName) backgrounds = afwMath.BackgroundList.readFits(fileName) img = backgrounds.getImage() # # Check that the read-back image is identical to that generated from the backgroundList # round-tripped to disk # backImage -= img self.assertEqual(np.min(backImage.getArray()), 0.0) self.assertEqual(np.max(backImage.getArray()), 0.0)
def testPcaNaN(self): """Test calculating PCA when the images can contain NaNs""" width, height = 20, 10 values = (100, 200, 300) for i, val in enumerate(values): im = afwImage.ImageF(afwGeom.Extent2I(width, height)) im.set(val) if i == 1: im.set(width // 2, height // 2, np.nan) self.ImageSet.addImage(im, 1.0) self.ImageSet.analyze() eImages = [] for img in self.ImageSet.getEigenImages(): eImages.append(img) if display: mos = displayUtils.Mosaic(background=-10) ds9.mtv(mos.makeMosaic(eImages), frame=1)
def setUp(self): self.val = 10 self.image = afwImage.ImageF(afwGeom.Extent2I(100, 200)) self.image.set(self.val)
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)