Ejemplo n.º 1
0
 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")
Ejemplo n.º 2
0
    def testApproximate(self):
        """Test I/O for BackgroundLists with Approximate"""
        # approx and interp should be very close, but not the same
        img = self.getParabolaImage(256, 256)

        # try regular interpolated image (the default)
        bgCtrl = afwMath.BackgroundControl(6, 6)
        bgCtrl.setInterpStyle(afwMath.Interpolate.AKIMA_SPLINE)
        bgCtrl.setUndersampleStyle(afwMath.REDUCE_INTERP_ORDER)
        bkgd = afwMath.makeBackground(img, bgCtrl)
        interpImage = bkgd.getImageF()

        with lsst.utils.tests.getTempFilePath("_bgi.fits") as bgiFile, \
                lsst.utils.tests.getTempFilePath("_bga.fits") as bgaFile:
            bglInterp = afwMath.BackgroundList()
            bglInterp.append(bkgd)
            bglInterp.writeFits(bgiFile)

            # try an approx background
            approxStyle = afwMath.ApproximateControl.CHEBYSHEV
            approxOrder = 2
            actrl = afwMath.ApproximateControl(approxStyle, approxOrder)
            bkgd.getBackgroundControl().setApproximateControl(actrl)
            approxImage = bkgd.getImageF()
            bglApprox = afwMath.BackgroundList()
            bglApprox.append(bkgd)
            bglApprox.writeFits(bgaFile)

            # take a difference and make sure the two are very similar
            interpNp = interpImage.getArray()
            diff = np.abs(interpNp - approxImage.getArray()) / interpNp

            # the image and interp/approx parameters are chosen so these limits
            # will be greater than machine precision for float.  The two methods
            # should be measurably different (so we know we're not just getting the
            # same thing from the getImage() method.  But they should be very close
            # since they're both doing the same sort of thing.
            tolSame = 1.0e-3  # should be the same to this order
            tolDiff = 1.0e-4  # should be different here
            self.assertLess(diff.max(), tolSame)
            self.assertGreater(diff.max(), tolDiff)

            # now see if we can reload them from files and get the same images we wrote
            interpImage2 = afwMath.BackgroundList().readFits(
                bgiFile).getImage()
            approxImage2 = afwMath.BackgroundList().readFits(
                bgaFile).getImage()

            idiff = interpImage.getArray() - interpImage2.getArray()
            adiff = approxImage.getArray() - approxImage2.getArray()

            self.assertEqual(idiff.max(), 0.0)
            self.assertEqual(adiff.max(), 0.0)
Ejemplo n.º 3
0
    def testgetPixel(self):
        """Tests basic functionality of getPixel() method (floats)"""
        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)
Ejemplo n.º 4
0
def flattenBackground(im, nx=2, ny=2, scale=False):
    """Fit and subtract an nx*ny background model"""

    bctrl = afwMath.BackgroundControl(nx, ny)
    bkgd = afwMath.makeBackground(im, bctrl).getImageF(afwMath.Interpolate.LINEAR)
    mean = np.mean(bkgd.getArray())

    im -= bkgd
    im += float(mean)

    if scale:
        im /= mean
Ejemplo n.º 5
0
def crossCorrelate(maskedimage1, maskedimage2, maxLag, sigma, binsize):
    """
    Calculate the correlation coefficients.
    """
    sctrl = afwMath.StatisticsControl()
    sctrl.setNumSigmaClip(sigma)

    # Diff the images.
    diff = maskedimage1.clone()
    diff -= maskedimage2.getImage()

    # Subtract background.
    nx = diff.getWidth()//binsize
    ny = diff.getHeight()//binsize
    bctrl = afwMath.BackgroundControl(nx, ny, sctrl, afwMath.MEANCLIP)
    bkgd = afwMath.makeBackground(diff, bctrl)
    bgImg = bkgd.getImageF(afwMath.Interpolate.CUBIC_SPLINE,
                           afwMath.REDUCE_INTERP_ORDER)

    diff -= bgImg

    # Measure the correlations
    x0, y0 = diff.getXY0()
    width, height = diff.getDimensions()
    bbox_extent = lsstGeom.Extent2I(width - maxLag, height - maxLag)

    bbox = lsstGeom.Box2I(lsstGeom.Point2I(x0, y0), bbox_extent)
    dim0 = diff[bbox].clone()
    dim0 -= afwMath.makeStatistics(dim0, afwMath.MEANCLIP, sctrl).getValue()

    xcorr = np.zeros((maxLag + 1, maxLag + 1), dtype=np.float64)
    xcorr_err = np.zeros((maxLag + 1, maxLag + 1), dtype=np.float64)

    for xlag in range(maxLag + 1):
        for ylag in range(maxLag + 1):
            bbox_lag = lsstGeom.Box2I(lsstGeom.Point2I(x0 + xlag, y0 + ylag),
                                      bbox_extent)
            dim_xy = diff[bbox_lag].clone()
            dim_xy -= afwMath.makeStatistics(dim_xy, afwMath.MEANCLIP,
                                             sctrl).getValue()
            dim_xy *= dim0
            xcorr[xlag, ylag] = afwMath.makeStatistics(
                dim_xy, afwMath.MEANCLIP, sctrl).getValue()
            dim_xy_array = dim_xy.getImage().getArray().flatten()/xcorr[0][0]
            N = len(dim_xy_array.flatten())
            if xlag != 0 and ylag != 0:
                f = (1+xcorr[xlag, ylag]/xcorr[0][0]) / \
                    (1-xcorr[xlag, ylag]/xcorr[0][0])
                xcorr_err[xlag, ylag] = (
                    np.std(dim_xy_array)/np.sqrt(N))*np.sqrt(f)
            else:
                xcorr_err[xlag, ylag] = 0
    return xcorr, xcorr_err
Ejemplo n.º 6
0
def get_fp_pixels(ccd, amp, nsig=4, bg_reg=(10, 10), npix_range=(5, 20)):
    """
    Return a numpy record array with rows of the 9 pixel values around
    the peaks of Fe55 clusters.  The footprint threshold is
    nsig*stdevclip + median, bg_reg is the NxM local background
    region, and the number of pixels per footprint is restricted to be
    within npix_range.
    """
    # Background subtraction using a background image based on the
    # local background levels.
    bg_ctrl = afwMath.BackgroundControl(bg_reg[0], bg_reg[1], ccd.stat_ctrl)
    image = ccd[amp]
    image -= afwMath.makeBackground(ccd[amp], bg_ctrl).getImageF()

    # Set the footprint threshold.
    stats = afwMath.makeStatistics(image, afwMath.MEDIAN | afwMath.STDEVCLIP,
                                   ccd.stat_ctrl)
    threshold = afwDetect.Threshold(nsig * stats.getValue(afwMath.STDEVCLIP) +
                                    stats.getValue(afwMath.MEDIAN))

    # Gather the data for the record array object.  This includes the
    # amplifier number, the coordinates of the peak pixel (x0, y0),
    # the 3x3 pixels centered on (x0, y0), and the sum of ADU values
    # over the footprint.
    imarr = image.getImage().getArray()
    data = []
    for fp in afwDetect.FootprintSet(image, threshold).getFootprints():
        if fp.getArea() < npix_range[0] or npix_range[1] < fp.getArea():
            continue
        # Get peak coordinates and p0-p8 values
        peaks = [pk for pk in fp.getPeaks()]
        if len(peaks) > 1:
            continue
        x0, y0 = peaks[0].getIx(), peaks[0].getIy()
        row = [amp, x0, y0] + list(imarr[y0 - 1:y0 + 2,
                                         x0 - 1:x0 + 2].flatten())
        if len(row) != 12:
            # Skip if there are too few p0-p8 values (e.g., cluster is
            # on the imaging section edge).
            continue
        # Sum over pixels in the footprint.
        dn_sum = 0
        spans = fp.getSpans()
        for span in spans:
            y = span.getY()
            for x in range(span.getX0(), span.getX1() + 1):
                dn_sum += imarr[y][x]
        row.append(dn_sum)
        data.append(row)
    names = 'amp x y'.split() + ['p%i' % i for i in range(9)] + ['DN_sum']

    return np.rec.array(data, names=names)
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
    def testTicket1781(self):
        """Test an unusual-sized image"""
        nx = 526
        ny = 154

        parabimg = self.getParabolaImage(nx, ny)

        bctrl = afwMath.BackgroundControl(afwMath.Interpolate.CUBIC_SPLINE)
        bctrl.setNxSample(16)
        bctrl.setNySample(4)
        bctrl.getStatisticsControl().setNumSigmaClip(10.0)
        bctrl.getStatisticsControl().setNumIter(1)
        afwMath.makeBackground(parabimg, bctrl)
Ejemplo n.º 9
0
    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.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.assertTrue( abs(testval - reqMean) < 2*stdevInterp )

            # test getImage() by checking the center pixel
            bimg = backobj.getImageF()
            testImgval = bimg.get(naxis1//2, naxis2//2)
            self.assertTrue( abs(testImgval - reqMean) < 2*stdevInterp )
Ejemplo n.º 10
0
def getBackground(image, backgroundConfig, nx=0, ny=0, algorithm=None):
    """
    Make a new Exposure which is exposure - background
    """
    backgroundConfig.validate()

    if not nx:
        nx = image.getWidth() // backgroundConfig.binSize + 1
    if not ny:
        ny = image.getHeight() // backgroundConfig.binSize + 1

    displayBackground = lsstDebug.Info(__name__).displayBackground
    if displayBackground:
        import itertools
        ds9.mtv(image, frame=1)
        xPosts = numpy.rint(
            numpy.linspace(0, image.getWidth() + 1, num=nx, endpoint=True))
        yPosts = numpy.rint(
            numpy.linspace(0, image.getHeight() + 1, num=ny, endpoint=True))
        with ds9.Buffering():
            for (xMin, xMax), (yMin, yMax) in itertools.product(
                    zip(xPosts[:-1], xPosts[1:]), zip(yPosts[:-1],
                                                      yPosts[1:])):
                ds9.line([(xMin, yMin), (xMin, yMax), (xMax, yMax),
                          (xMax, yMin), (xMin, yMin)],
                         frame=1)

    sctrl = afwMath.StatisticsControl()
    sctrl.setAndMask(
        reduce(lambda x, y: x | image.getMask().getPlaneBitMask(y),
               backgroundConfig.ignoredPixelMask, 0x0))
    sctrl.setNanSafe(backgroundConfig.isNanSafe)

    pl = pexLogging.Debug("meas.utils.sourceDetection.getBackground")
    pl.debug(
        3, "Ignoring mask planes: %s" %
        ", ".join(backgroundConfig.ignoredPixelMask))

    if not algorithm:
        algorithm = backgroundConfig.algorithm

    bctrl = afwMath.BackgroundControl(algorithm, nx, ny,
                                      backgroundConfig.undersampleStyle, sctrl,
                                      backgroundConfig.statisticsProperty)

    if backgroundConfig.useApprox:
        actrl = afwMath.ApproximateControl(
            afwMath.ApproximateControl.CHEBYSHEV, backgroundConfig.approxOrder)
        bctrl.setApproximateControl(actrl)

    return afwMath.makeBackground(image, bctrl)
Ejemplo n.º 11
0
    def testTicket987(self):
        """This code used to abort; so the test is that it doesn't"""
        imagePath = os.path.join(AfwdataDir, "DC3a-Sim", "sci", "v5-e0",
                                 "v5-e0-c011-a00.sci.fits")
        mimg = afwImage.MaskedImageF(imagePath)
        binsize = 512
        nx = int(mimg.getWidth() / binsize) + 1
        ny = int(mimg.getHeight() / binsize) + 1
        bctrl = afwMath.BackgroundControl(nx, ny)

        image = mimg.getImage()
        backobj = afwMath.makeBackground(image, bctrl)
        # note: by default undersampleStyle is THROW_EXCEPTION
        image -= backobj.getImageF("NATURAL_SPLINE", "REDUCE_INTERP_ORDER")
Ejemplo n.º 12
0
    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)
Ejemplo n.º 13
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)
Ejemplo n.º 14
0
    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)
Ejemplo n.º 15
0
    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')
Ejemplo n.º 16
0
    def testTicket1781(self):
        # make an unusual-sized image
        nx = 526
        ny = 154

        parabimg = self.getParabolaImage(nx, ny)

        bctrl = afwMath.BackgroundControl(afwMath.Interpolate.CUBIC_SPLINE)
        bctrl.setNxSample(16)
        bctrl.setNySample(4)
        bctrl.getStatisticsControl().setNumSigmaClip(10.0)
        bctrl.getStatisticsControl().setNumIter(1)
        backobj = afwMath.makeBackground(parabimg, bctrl)

        if False:
            parabimg.writeFits('in.fits')
            backobj.getImageF().writeFits('out.fits')
Ejemplo n.º 17
0
    def testUndersample(self):
        """Test how the program handles nx,ny being too small for requested interp style."""

        # make an image
        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)

        if False:  # INCREASE_NXNYSAMPLE is no longer supported post #2074
            bctrl.setNxSample(2)
            bctrl.setNySample(2)
            # see if it adjusts the nx,ny values up to 3x3
            bctrl.setUndersampleStyle(afwMath.INCREASE_NXNYSAMPLE)
            backobj = afwMath.makeBackground(img, bctrl)
            self.assertEqual(backobj.getBackgroundControl().getNxSample(), 3)
            self.assertEqual(backobj.getBackgroundControl().getNySample(), 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

        utilsTests.assertRaisesLsstCpp(
            self, lsst.pex.exceptions.InvalidParameterException, tst, img,
            bctrl)
Ejemplo n.º 18
0
    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
        approxWeighting = True

        im = self.image.Factory(self.image, self.image.getBBox())
        arr = im.getArray()
        arr += np.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, approxWeighting))
                else:
                    # Relies on having called getImage; deprecated
                    with self.assertWarns(FutureWarning):
                        backgroundList.append(bkgd)

                backImage += bkgd.getImageF(interpStyle, undersampleStyle)

            with lsst.utils.tests.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)
Ejemplo n.º 19
0
    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()):
                # n.b. linear, which is what the interpolation will fall back
                # to
                image[x, y, afwImage.LOCAL] = 1 + 2 * y

        # Set the right corner to NaN.  This will mean that we have too few
        # points for a spline interpolator
        binSize = 3
        image[-binSize:, -binSize:, afwImage.LOCAL] = 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 debugMode:
            afwDisplay.Display(frame=0).mtv(image,
                                            title=self._testMethodName +
                                            " image")
            afwDisplay.Display(frame=1).mtv(bkgd.getStatsImage(),
                                            title=self._testMethodName +
                                            " bkgd StatsImage")
        # 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 debugMode:
            afwDisplay.Display(frame=2).mtv(bkgdImage,
                                            title=self._testMethodName +
                                            " bkgdImage")

        image -= bkgdImage
        self.assertEqual(
            afwMath.makeStatistics(image, afwMath.MEAN).getValue(), 0.0)
Ejemplo n.º 20
0
def getProcessedImageArray(ccd, amp, nx=10, ny=10):
    """
    Subtract afwMath local background model from an de-biased and
    trimmed image segment and return the underlying ndarray.
    """
    # Define extent of local background region
    bg_ctrl = afwMath.BackgroundControl(nx, ny, ccd.stat_ctrl)
    image = ccd.unbiased_and_trimmed_image(amp)
    try:
        bg = afwMath.makeBackground(image, bg_ctrl)
        bg_image = bg.getImageF()
        image -= bg.getImageF()
    except pexExcept.OutOfRangeError, eObj:
        # Stack fails to derive a local background image so rely on
        # bias subtraction. This produces less reliable results on
        # real and simulated data.
        print "TrapFinder.getProcessedImageArray:", eObj
        print "Skipping local background subtraction for amp", amp
Ejemplo n.º 21
0
    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)
Ejemplo n.º 22
0
    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()))
Ejemplo n.º 23
0
    def testBackgroundFromStatsImage(self):
        """Check that we can rebuild a Background from a BackgroundMI.getStatsImage()"""
        bgCtrl = afwMath.BackgroundControl(10, 10)
        bkgd = 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)
Ejemplo n.º 24
0
    def testDetection(self):
        """Test CR detection"""
        #
        # Subtract background
        #
        bctrl = afwMath.BackgroundControl(afwMath.Interpolate.NATURAL_SPLINE)
        bctrl.setNxSample(int(self.mi.getWidth() / 256) + 1)
        bctrl.setNySample(int(self.mi.getHeight() / 256) + 1)
        bctrl.getStatisticsControl().setNumSigmaClip(3.0)
        bctrl.getStatisticsControl().setNumIter(2)

        im = self.mi.getImage()
        try:
            backobj = afwMath.makeBackground(im, bctrl)
        except Exception, e:
            print >> sys.stderr, e,

            bctrl.setInterpStyle(afwMath.Interpolate.CONSTANT)
            backobj = afwMath.makeBackground(im, bctrl)
def subtractBackground(maskedImage):
    """Subtract the background from a MaskedImage
    
    Note: at present the mask and variance are ignored, but they might used be someday.
    
    Returns the background object returned by afwMath.makeBackground.
    """
    bkgControl = afwMath.BackgroundControl(afwMath.Interpolate.NATURAL_SPLINE)
    bkgControl.setNxSample(
        int(maskedImage.getWidth() // BackgroundCellSize) + 1)
    bkgControl.setNySample(
        int(maskedImage.getHeight() // BackgroundCellSize) + 1)
    bkgControl.getStatisticsControl().setNumSigmaClip(3)
    bkgControl.getStatisticsControl().setNumIter(3)

    image = maskedImage.getImage()
    bkgObj = afwMath.makeBackground(image, bkgControl)
    image -= bkgObj.getImageF()
    return bkgObj
Ejemplo n.º 26
0
    def testBackgroundTestImages(self):
        """Tests Laher's afwdata/Statistics/*.fits images (doubles)"""
        imginfolist = []
        # cooked to known value
        imginfolist.append(["v1_i1_g_m400_s20_f.fits", 399.9912966583894])

        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 = 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[naxis1//2, naxis2//2, afwImage.LOCAL]
            self.assertLess(abs(testImgval - reqMean), 2*stdevInterp)
Ejemplo n.º 27
0
    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
        approxWeighting = False

        backgroundList = afwMath.BackgroundList()

        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, approxWeighting))
            else:
                # Relies on having called getImage; deprecated
                with self.assertWarns(FutureWarning):
                    backgroundList.append(bkgd)

        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]), 7)  # check that we can index
            # check that we always have a tuple (bkgd, interp, under,
            # approxStyle, orderX, orderY, weighting)
            self.assertEqual(len(bgl[1]), 7)

        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:])
Ejemplo n.º 28
0
    def measureBackground(self, image):
        """Measure a background model for image

        This doesn't use a full-featured background model (e.g., no Chebyshev
        approximation) because we just want the binning behaviour.  This will
        allow us to average the bins later (`averageBackgrounds`).

        The `BackgroundMI` is wrapped in a `BackgroundList` so it can be
        pickled and persisted.

        Parameters
        ----------
        image : `lsst.afw.image.MaskedImage`
            Image for which to measure background.

        Returns
        -------
        bgModel : `lsst.afw.math.BackgroundList`
            Background model.
        """
        stats = afwMath.StatisticsControl()
        stats.setAndMask(image.getMask().getPlaneBitMask(self.config.background.mask))
        stats.setNanSafe(True)
        ctrl = afwMath.BackgroundControl(
            self.config.background.algorithm,
            max(int(image.getWidth()/self.config.background.xBinSize + 0.5), 1),
            max(int(image.getHeight()/self.config.background.yBinSize + 0.5), 1),
            "REDUCE_INTERP_ORDER",
            stats,
            self.config.background.statistic
        )

        bg = afwMath.makeBackground(image, ctrl)

        return afwMath.BackgroundList((
            bg,
            afwMath.stringToInterpStyle(self.config.background.algorithm),
            afwMath.stringToUndersampleStyle("REDUCE_INTERP_ORDER"),
            afwMath.ApproximateControl.UNKNOWN,
            0, 0, False
        ))
Ejemplo n.º 29
0
    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))
        mi.image[:, 0:100] = np.nan
        badBits = mi.mask.getPlaneBitMask(
            ['EDGE', 'DETECTED', 'DETECTED_NEGATIVE'])
        mi.mask[0:400, :] |= badBits

        if debugMode:
            afwDisplay.Display(frame=0).mtv(mi,
                                            title=self._testMethodName +
                                            " image")

        sctrl = afwMath.StatisticsControl()
        sctrl.setAndMask(badBits)
        nx, ny = 17, 17
        bctrl = afwMath.BackgroundControl(nx, ny, sctrl, afwMath.MEANCLIP)

        bkgd = afwMath.makeBackground(mi, bctrl)
        statsImage = bkgd.getStatsImage()
        if debugMode:
            afwDisplay.Display(frame=1).mtv(statsImage,
                                            title=self._testMethodName +
                                            " bkgd StatsImage")

        # the test is that this doesn't fail if the bug (#2297) is fixed
        for frame, interpStyle in enumerate([
                afwMath.Interpolate.CONSTANT, afwMath.Interpolate.LINEAR,
                afwMath.Interpolate.NATURAL_SPLINE,
                afwMath.Interpolate.AKIMA_SPLINE
        ], 2):
            bkgdImage = bkgd.getImageF(interpStyle,
                                       afwMath.REDUCE_INTERP_ORDER)
            self.assertEqual(np.mean(bkgdImage[0:100, 0:100].array),
                             initialValue)
            if debugMode:
                afwDisplay.Display(frame=frame).mtv(
                    bkgdImage,
                    title=f"{self._testMethodName} bkgdImage: {interpStyle}")
Ejemplo n.º 30
0
    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))