Example #1
0
    def testMakeAlertDict(self):
        """Test stripping data from the various data products and into a
        dictionary "alert".
        """
        packageAlerts = PackageAlertsTask()
        alertId = 1234

        for srcIdx, diaSource in self.diaSources.iterrows():
            sphPoint = geom.SpherePoint(diaSource["ra"], diaSource["decl"],
                                        geom.degrees)
            cutout = self.exposure.getCutout(
                sphPoint, geom.Extent2I(self.cutoutSize, self.cutoutSize))
            ccdCutout = packageAlerts.createCcdDataCutout(
                cutout, sphPoint,
                geom.Extent2I(self.cutoutSize, self.cutoutSize),
                cutout.getPhotoCalib(), 1234)
            cutoutBytes = packageAlerts.streamCcdDataToBytes(ccdCutout)
            objSources = self.diaSourceHistory.loc[srcIdx[0]]
            objForcedSources = self.diaForcedSources.loc[srcIdx[0]]
            alert = packageAlerts.makeAlertDict(alertId, diaSource,
                                                self.diaObjects.loc[srcIdx[0]],
                                                objSources, objForcedSources,
                                                ccdCutout, ccdCutout)
            self.assertEqual(len(alert), 9)

            self.assertEqual(alert["alertId"], alertId)
            self.assertEqual(alert["diaSource"], diaSource.to_dict())
            self.assertEqual(alert["cutoutDifference"], cutoutBytes)
            self.assertEqual(alert["cutoutTemplate"], cutoutBytes)
    def testGaussianWithNoise(self):
        # Convolve a real image with a gaussian and try and recover
        # it.  Add noise and perform the same test.

        gsize = self.ps["kernelSize"]
        gaussFunction = afwMath.GaussianFunction2D(2, 3)
        gaussKernel = afwMath.AnalyticKernel(gsize, gsize, gaussFunction)
        kImageIn = afwImage.ImageD(geom.Extent2I(gsize, gsize))
        kSumIn = gaussKernel.computeImage(kImageIn, False)

        imX, imY = self.templateExposure2.getMaskedImage().getDimensions()
        smi = afwImage.MaskedImageF(geom.Extent2I(imX, imY))
        afwMath.convolve(smi, self.templateExposure2.getMaskedImage(), gaussKernel, False)

        bbox = gaussKernel.shrinkBBox(smi.getBBox(afwImage.LOCAL))

        tmi2 = afwImage.MaskedImageF(self.templateExposure2.getMaskedImage(), bbox, origin=afwImage.LOCAL)
        smi2 = afwImage.MaskedImageF(smi, bbox, origin=afwImage.LOCAL)

        kc = ipDiffim.KernelCandidateF(self.x02, self.y02, tmi2, smi2, self.ps)
        kList = ipDiffim.makeKernelBasisList(self.subconfig)
        kc.build(kList)
        self.assertEqual(kc.isInitialized(), True)
        kImageOut = kc.getImage()

        soln = kc.getKernelSolution(ipDiffim.KernelCandidateF.RECENT)
        self.assertAlmostEqual(soln.getKsum(), kSumIn)
        # 8.7499380640430563e-06 != 0.0 within 7 places
        self.assertAlmostEqual(soln.getBackground(), 0.0, 4)

        for j in range(kImageOut.getHeight()):
            for i in range(kImageOut.getWidth()):

                # in the outskirts of the kernel, the ratio can get screwed because of low S/N
                # e.g. 7.45817359824e-09 vs. 1.18062529402e-08
                # in the guts of the kernel it should look closer
                if kImageIn[i, j, afwImage.LOCAL] > 1e-4:
                    # sigh, too bad this sort of thing fails..
                    # 0.99941584433815966 != 1.0 within 3 places
                    self.assertAlmostEqual(kImageOut[i, j, afwImage.LOCAL]/kImageIn[i, j, afwImage.LOCAL],
                                           1.0, 2)

        # now repeat with noise added; decrease precision of comparison
        self.addNoise(smi2)
        kc = ipDiffim.KernelCandidateF(self.x02, self.y02, tmi2, smi2, self.ps)
        kList = ipDiffim.makeKernelBasisList(self.subconfig)
        kc.build(kList)
        self.assertEqual(kc.isInitialized(), True)
        kImageOut = kc.getImage()

        soln = kc.getKernelSolution(ipDiffim.KernelCandidateF.RECENT)
        self.assertAlmostEqual(soln.getKsum(), kSumIn, 3)
        if not self.ps.get("fitForBackground"):
            self.assertEqual(soln.getBackground(), 0.0)

        for j in range(kImageOut.getHeight()):
            for i in range(kImageOut.getWidth()):
                if kImageIn[i, j, afwImage.LOCAL] > 1e-2:
                    self.assertAlmostEqual(kImageOut[i, j, afwImage.LOCAL],
                                           kImageIn[i, j, afwImage.LOCAL], 2)
Example #3
0
 def testMutators(self):
     box = geom.Box2I(geom.Point2I(-2, -3), geom.Point2I(2, 1), True)
     box.grow(1)
     self.assertEqual(
         box, geom.Box2I(geom.Point2I(-3, -4), geom.Point2I(3, 2), True))
     box.grow(geom.Extent2I(2, 3))
     self.assertEqual(
         box, geom.Box2I(geom.Point2I(-5, -7), geom.Point2I(5, 5), True))
     box.shift(geom.Extent2I(3, 2))
     self.assertEqual(
         box, geom.Box2I(geom.Point2I(-2, -5), geom.Point2I(8, 7), True))
     box.include(geom.Point2I(-4, 2))
     self.assertEqual(
         box, geom.Box2I(geom.Point2I(-4, -5), geom.Point2I(8, 7), True))
     box.include(geom.Point2I(0, -6))
     self.assertEqual(
         box, geom.Box2I(geom.Point2I(-4, -6), geom.Point2I(8, 7), True))
     box.include(geom.Box2I(geom.Point2I(0, 0), geom.Point2I(10, 11), True))
     self.assertEqual(
         box, geom.Box2I(geom.Point2I(-4, -6), geom.Point2I(10, 11), True))
     box.clip(geom.Box2I(geom.Point2I(0, 0), geom.Point2I(11, 12), True))
     self.assertEqual(
         box, geom.Box2I(geom.Point2I(0, 0), geom.Point2I(10, 11), True))
     box.clip(geom.Box2I(geom.Point2I(-1, -2), geom.Point2I(5, 4), True))
     self.assertEqual(
         box, geom.Box2I(geom.Point2I(0, 0), geom.Point2I(5, 4), True))
Example #4
0
def getAmplifier(image, amp, ampReference=None, offset=2):
    """Extract an image of the amplifier from the CCD, along with an offset
    version

    The amplifier image will be flipped (if required) to match the
    orientation of a nominated reference amplifier.

    An additional image, with the nominated offset applied, is also produced.

    Parameters
    ----------
    image :
        Image of CCD
    amp :
        Index of amplifier
    ampReference :
        Index of reference amplifier
    offset :
        Offset to apply

    Returns
    -------
    amp_image :
        amplifier image, offset amplifier image
    """
    height = image.getHeight()
    ampBox = geom.Box2I(geom.Point2I(amp * 512, 0), geom.Extent2I(512, height))
    ampImage = image.Factory(image, ampBox, afwImage.LOCAL)
    if ampReference is not None and amp % 2 != ampReference % 2:
        ampImage = afwMath.flipImage(ampImage, True, False)
    offBox = geom.Box2I(geom.Point2I(offset if amp == ampReference else 0, 0),
                        geom.Extent2I(510, height))
    offsetImage = ampImage.Factory(ampImage, offBox, afwImage.LOCAL)
    return ampImage, offsetImage
Example #5
0
    def testMakeCenteredBox(self):
        dimensionsI = [
            geom.Extent2I(100, 50),
            geom.Extent2I(15, 15),
            geom.Extent2I(0, 10),
            geom.Extent2I(25, 30),
            geom.Extent2I(15, -5)
        ]
        dimensionsD = [geom.Extent2D(d) for d in dimensionsI] \
            + [geom.Extent2D(1.5, 2.1), geom.Extent2D(4, 3.7),
               geom.Extent2D(-0.1, -0.1), geom.Extent2D(5.5, 5.5),
               geom.Extent2D(-np.nan, 5.5), geom.Extent2D(4, np.inf)]
        locations = [
            geom.Point2D(0, 0),
            geom.Point2D(0.2, 0.7),
            geom.Point2D(1, 1.5),
            geom.Point2D(-0.5 + 1e-4, -0.5 + 1e-4),
            geom.Point2D(-0.5 - 1e-4, -0.5 - 1e-4),
            geom.Point2D(-np.nan, 0),
            geom.Point2D(1.0, np.inf),
        ]

        for center in locations:
            for size in dimensionsI:
                self._checkBoxConstruction(geom.Box2I, size, center,
                                           np.sqrt(0.5))
            for size in dimensionsD:
                self._checkBoxConstruction(geom.Box2D, size, center, 1e-10)
Example #6
0
 def testAssertions(self):
     """Test that addToCoadd requires coadd and weightMap to have the same dimensions and xy0"""
     maskedImage = afwImage.MaskedImageF(geom.Extent2I(10, 10))
     coadd = afwImage.MaskedImageF(geom.Extent2I(11, 11))
     coadd.setXY0(5, 6)
     for dw, dh in (1, 0), (0, 1), (-1, 0), (0, -1):
         weightMapBBox = geom.Box2I(
             coadd.getXY0(),
             coadd.getDimensions() + geom.Extent2I(dw, dh))
         weightMap = afwImage.ImageF(weightMapBBox)
         weightMap.setXY0(coadd.getXY0())
         try:
             coaddUtils.addToCoadd(coadd, weightMap, maskedImage, 0x0, 0.1)
             self.fail("should have raised exception")
         except pexExcept.Exception:
             pass
     for dx0, dy0 in (1, 0), (0, 1), (-1, 0), (0, -1):
         weightMapBBox = geom.Box2I(
             coadd.getXY0() + geom.Extent2I(dx0, dy0),
             coadd.getDimensions())
         weightMap = afwImage.ImageF(weightMapBBox)
         try:
             coaddUtils.addToCoadd(coadd, weightMap, maskedImage, 0x0, 0.1)
             self.fail("should have raised exception")
         except pexExcept.Exception:
             pass
Example #7
0
def addAmp(ampCatalog, i, eparams):
    """ Add an amplifier to an AmpInfoCatalog

    @param ampCatalog: An instance of an AmpInfoCatalog object to fill with amp properties
    @param i which amplifier? (i == 0 ? left : right)
    @param eparams: Electronic parameters.  This is a list of tuples with (i, params),
                    where params is a dictionary of electronic parameters.
    """
    #
    # Layout of active and overclock pixels in the as-readout data  The layout is:
    #     Amp0 || extended | overclock | data || data | overclock | extended || Amp1
    # for each row; all rows are identical in drift-scan data
    #
    height = 1361  # number of rows in a frame
    width = 1024  # number of data pixels read out through one amplifier
    nExtended = 8  # number of pixels in the extended register
    nOverclock = 32  # number of (horizontal) overclock pixels
    #
    # Construct the needed bounding boxes given that geometrical information.
    #
    # Note that all the offsets are relative to the origin of this amp, not to its eventual
    # position in the CCD
    #
    record = ampCatalog.addNew()
    xtot = width + nExtended + nOverclock
    allPixels = geom.BoxI(geom.PointI(0, 0), geom.ExtentI(xtot, height))
    biasSec = geom.BoxI(geom.PointI(nExtended if i == 0 else width, 0),
                        geom.ExtentI(nOverclock, height))
    dataSec = geom.BoxI(
        geom.PointI(nExtended + nOverclock if i == 0 else 0, 0),
        geom.ExtentI(width, height))
    emptyBox = geom.BoxI()
    bbox = geom.BoxI(geom.PointI(0, 0), geom.ExtentI(width, height))
    bbox.shift(geom.Extent2I(width * i, 0))

    shiftp = geom.Extent2I(xtot * i, 0)
    allPixels.shift(shiftp)
    biasSec.shift(shiftp)
    dataSec.shift(shiftp)

    record.setBBox(bbox)
    record.setRawXYOffset(geom.ExtentI(0, 0))
    record.setName('left' if i == 0 else 'right')
    record.setReadoutCorner(afwTable.LL if i == 0 else afwTable.LR)
    record.setGain(eparams['gain'])
    record.setReadNoise(eparams['readNoise'])
    record.setSaturation(eparams['fullWell'])
    record.setSuspectLevel(float("nan"))
    record.setLinearityType(NullLinearityType)
    record.setLinearityCoeffs([
        1.,
    ])
    record.setHasRawInfo(True)
    record.setRawFlipX(False)
    record.setRawFlipY(False)
    record.setRawBBox(allPixels)
    record.setRawDataBBox(dataSec)
    record.setRawHorizontalOverscanBBox(biasSec)
    record.setRawVerticalOverscanBBox(emptyBox)
    record.setRawPrescanBBox(emptyBox)
 def makeCandidate(self, kSum, x, y, size=51):
     mi1 = afwImage.MaskedImageF(geom.Extent2I(size, size))
     mi1.getVariance().set(1.0)  # avoid NaNs
     mi1[size // 2, size // 2, afwImage.LOCAL] = (1, 0x0, 1)
     mi2 = afwImage.MaskedImageF(geom.Extent2I(size, size))
     mi2.getVariance().set(1.0)  # avoid NaNs
     mi2[size // 2, size // 2, afwImage.LOCAL] = (kSum, 0x0, kSum)
     kc = ipDiffim.makeKernelCandidate(x, y, mi1, mi2, self.ps)
     return kc
    def runMeasurement(self, algorithmName, imageid, x, y, v):
        """Run the measurement algorithm on an image"""
        # load the test image
        imgFile = os.path.join(self.dataDir, "image.%d.fits" % imageid)
        img = afwImage.ImageF(imgFile)
        img -= self.bkgd
        nx, ny = img.getWidth(), img.getHeight()
        msk = afwImage.Mask(geom.Extent2I(nx, ny), 0x0)
        var = afwImage.ImageF(geom.Extent2I(nx, ny), v)
        mimg = afwImage.MaskedImageF(img, msk, var)
        msk.getArray()[:] = np.where(np.fabs(img.getArray()) < 1.0e-8, msk.getPlaneBitMask("BAD"), 0)

        # Put it in a bigger image, in case it matters
        big = afwImage.MaskedImageF(self.offset + mimg.getDimensions())
        big.getImage().set(0)
        big.getMask().set(0)
        big.getVariance().set(v)
        subBig = afwImage.MaskedImageF(big, geom.Box2I(big.getXY0() + self.offset, mimg.getDimensions()))
        subBig <<= mimg
        mimg = big
        mimg.setXY0(self.xy0)

        exposure = afwImage.makeExposure(mimg)
        cdMatrix = np.array([1.0/(2.53*3600.0), 0.0, 0.0, 1.0/(2.53*3600.0)])
        cdMatrix.shape = (2, 2)
        exposure.setWcs(afwGeom.makeSkyWcs(crpix=geom.Point2D(1.0, 1.0),
                                           crval=geom.SpherePoint(0, 0, geom.degrees),
                                           cdMatrix=cdMatrix))

        # load the corresponding test psf
        psfFile = os.path.join(self.dataDir, "psf.%d.fits" % imageid)
        psfImg = afwImage.ImageD(psfFile)
        psfImg -= self.bkgd

        kernel = afwMath.FixedKernel(psfImg)
        kernelPsf = algorithms.KernelPsf(kernel)
        exposure.setPsf(kernelPsf)

        # perform the shape measurement
        msConfig = base.SingleFrameMeasurementConfig()
        alg = base.SingleFramePlugin.registry[algorithmName].PluginClass.AlgClass
        control = base.SingleFramePlugin.registry[algorithmName].PluginClass.ConfigClass().makeControl()
        msConfig.algorithms.names = [algorithmName]
        # Note: It is essential to remove the floating point part of the position for the
        # Algorithm._apply.  Otherwise, when the PSF is realised it will have been warped
        # to account for the sub-pixel offset and we won't get *exactly* this PSF.
        plugin, table = makePluginAndCat(alg, algorithmName, control, centroid="centroid")
        center = geom.Point2D(int(x), int(y)) + geom.Extent2D(self.offset + geom.Extent2I(self.xy0))
        source = table.makeRecord()
        source.set("centroid_x", center.getX())
        source.set("centroid_y", center.getY())
        source.setFootprint(afwDetection.Footprint(afwGeom.SpanSet(exposure.getBBox(afwImage.PARENT))))
        plugin.measure(source, exposure)

        return source
    def testGaussian(self, imsize=50):
        # Convolve a delta function with a known gaussian; try to
        # recover using delta-function basis

        gsize = self.ps["kernelSize"]
        tsize = imsize + gsize

        gaussFunction = afwMath.GaussianFunction2D(2, 3)
        gaussKernel = afwMath.AnalyticKernel(gsize, gsize, gaussFunction)
        kImageIn = afwImage.ImageD(geom.Extent2I(gsize, gsize))
        gaussKernel.computeImage(kImageIn, False)

        # template image with a single hot pixel in the exact center
        tmi = afwImage.MaskedImageF(geom.Extent2I(tsize, tsize))
        tmi.set(0, 0x0, 1e-4)
        cpix = tsize // 2
        tmi[cpix, cpix, afwImage.LOCAL] = (1, 0x0, 1)

        # science image
        smi = afwImage.MaskedImageF(tmi.getDimensions())
        convolutionControl = afwMath.ConvolutionControl()
        convolutionControl.setDoNormalize(False)
        afwMath.convolve(smi, tmi, gaussKernel, convolutionControl)

        # get the actual kernel sum (since the image is not infinite)
        gscaling = afwMath.makeStatistics(smi,
                                          afwMath.SUM).getValue(afwMath.SUM)

        # grab only the non-masked subregion
        bbox = gaussKernel.shrinkBBox(smi.getBBox(afwImage.LOCAL))

        tmi2 = afwImage.MaskedImageF(tmi, bbox, origin=afwImage.LOCAL)
        smi2 = afwImage.MaskedImageF(smi, bbox, origin=afwImage.LOCAL)

        # make sure its a valid subregion!
        for j in range(tmi2.getHeight()):
            for i in range(tmi2.getWidth()):
                self.assertEqual(tmi2.mask[i, j, afwImage.LOCAL], 0)
                self.assertEqual(smi2.mask[i, j, afwImage.LOCAL], 0)

        kc = ipDiffim.KernelCandidateF(0.0, 0.0, tmi2, smi2, self.ps)
        kList = ipDiffim.makeKernelBasisList(self.subconfig)
        kc.build(kList)
        self.assertEqual(kc.isInitialized(), True)
        kImageOut = kc.getImage()

        soln = kc.getKernelSolution(ipDiffim.KernelCandidateF.RECENT)
        self.assertAlmostEqual(soln.getKsum(), gscaling)
        self.assertAlmostEqual(soln.getBackground(), 0.0)

        for j in range(kImageOut.getHeight()):
            for i in range(kImageOut.getWidth()):
                self.assertAlmostEqual(
                    kImageOut[i, j, afwImage.LOCAL] /
                    kImageIn[i, j, afwImage.LOCAL], 1.0, 5)
    def testRejection(self):
        # we need to construct a candidate whose shape does not
        # match the underlying basis
        #
        # so lets just make a kernel list with all the power in
        # the center, but the candidate requires some off center
        # power
        kc1 = self.makeCandidate(1, 0.0, 0.0)
        kc2 = self.makeCandidate(2, 0.0, 0.0)
        kc3 = self.makeCandidate(3, 0.0, 0.0)
        bskv1 = ipDiffim.BuildSingleKernelVisitorF(self.kList, self.ps)
        bskv1.processCandidate(kc1)
        bskv1.processCandidate(kc2)
        bskv1.processCandidate(kc3)

        imagePca = ipDiffim.KernelPcaD()
        kpv = ipDiffim.KernelPcaVisitorF(imagePca)
        kpv.processCandidate(kc1)
        kpv.processCandidate(kc2)
        kpv.processCandidate(kc3)
        kpv.subtractMean()
        imagePca.analyze()
        eigenKernels = []
        eigenKernels.append(kpv.getEigenKernels()[0])
        self.assertEqual(len(eigenKernels), 1)

        # bogus candidate
        mi1 = afwImage.MaskedImageF(geom.Extent2I(self.size, self.size))
        mi1.getVariance().set(0.1)
        mi1[self.size // 2, self.size // 2, afwImage.LOCAL] = (1, 0x0, 1)
        mi2 = afwImage.MaskedImageF(geom.Extent2I(self.size, self.size))
        mi2.getVariance().set(0.1)
        # make it high enough to make the mean resids large
        mi2[self.size // 3, self.size // 3,
            afwImage.LOCAL] = (self.size**2, 0x0, 1)
        kc4 = ipDiffim.makeKernelCandidate(0, 0, mi1, mi2, self.ps)
        self.assertEqual(kc4.getStatus(), afwMath.SpatialCellCandidate.UNKNOWN)

        # process with eigenKernels
        bskv2 = ipDiffim.BuildSingleKernelVisitorF(eigenKernels, self.ps)
        bskv2.setSkipBuilt(False)
        bskv2.processCandidate(kc1)
        bskv2.processCandidate(kc2)
        bskv2.processCandidate(kc3)
        bskv2.processCandidate(kc4)

        self.assertEqual(bskv2.getNProcessed(), 4)
        self.assertEqual(bskv2.getNRejected(), 1)

        self.assertEqual(kc1.getStatus(), afwMath.SpatialCellCandidate.GOOD)
        self.assertEqual(kc2.getStatus(), afwMath.SpatialCellCandidate.GOOD)
        self.assertEqual(kc3.getStatus(), afwMath.SpatialCellCandidate.GOOD)
        self.assertEqual(kc4.getStatus(), afwMath.SpatialCellCandidate.BAD)
Example #12
0
 def testWholeImageGrid(self):
     """Test that a 1-cell `grid` is actually the whole image"""
     config = ZogyConfig()
     task = ZogyTask(config=config)
     bb = geom.Box2I(geom.Point2I(5, 10), geom.Extent2I(200, 300))
     D = afwImage.ImageI(bb)
     grid = task.generateGrid(bb, geom.Extent2I(15, 15), bb.getDimensions())
     self.assertTrue(len(grid) == 1, "Grid length is not 1")
     x = grid[0]
     D[x.innerBox] += 1
     self.assertTrue(np.all(D.array == 1),
                     "Single cell does not cover the original image.")
Example #13
0
    def testConstructors(self):
        # test extent from extent 2-d
        e1 = geom.Extent2I(1, 2)
        e2 = geom.Extent2I(e1)
        self.assertAlmostEqual(tuple(e1), tuple(e2))

        e1 = geom.Extent2D(1.2, 3.4)
        e2 = geom.Extent2D(e1)
        self.assertAlmostEqual(tuple(e1), tuple(e2))

        e1 = geom.Extent2I(1, 2)
        e2 = geom.Extent2D(e1)
        self.assertAlmostEqual(tuple(e1), tuple(e2))

        # test extent from extent 3-d
        e1 = geom.Extent3I(1, 2, 3)
        e2 = geom.Extent3I(e1)
        self.assertAlmostEqual(tuple(e1), tuple(e2))

        e1 = geom.Extent3D(1.2, 3.4, 5.6)
        e2 = geom.Extent3D(e1)
        self.assertAlmostEqual(tuple(e1), tuple(e2))

        e1 = geom.Extent3I(1, 2, 3)
        e2 = geom.Extent3D(e1)
        self.assertAlmostEqual(tuple(e1), tuple(e2))

        # test extent from point 2-d
        e1 = geom.Point2I(1, 2)
        e2 = geom.Extent2I(e1)
        self.assertAlmostEqual(tuple(e1), tuple(e2))

        e1 = geom.Point2D(1.2, 3.4)
        e2 = geom.Extent2D(e1)
        self.assertAlmostEqual(tuple(e1), tuple(e2))

        e1 = geom.Point2I(1, 2)
        e2 = geom.Extent2D(e1)
        self.assertAlmostEqual(tuple(e1), tuple(e2))

        # test extent from point 3-d
        e1 = geom.Point3I(1, 2, 3)
        e2 = geom.Extent3I(e1)
        self.assertAlmostEqual(tuple(e1), tuple(e2))

        e1 = geom.Point3D(1.2, 3.4, 5.6)
        e2 = geom.Extent3D(e1)
        self.assertAlmostEqual(tuple(e1), tuple(e2))

        e1 = geom.Point3I(1, 2, 3)
        e2 = geom.Extent3D(e1)
        self.assertAlmostEqual(tuple(e1), tuple(e2))
Example #14
0
    def _testAddToCoaddImpl(self, useMask, uniformWeight=True):
        """Test coadd"""

        trueImageValue = 10.0
        imBBox = geom.Box2I(geom.Point2I(0, 0), geom.Extent2I(10, 20))
        if useMask:
            coadd = afwImage.MaskedImageF(imBBox)
            weightMap = coadd.getImage().Factory(coadd.getBBox())

            badBits = 0x1
            badPixel = (float("NaN"), badBits, 0)
            truth = (trueImageValue, 0x0, 0)
        else:
            coadd = afwImage.ImageF(imBBox)
            weightMap = coadd.Factory(coadd.getBBox())

            badPixel = float("NaN")
            truth = trueImageValue

        for i in range(0, 20, 3):
            image = coadd.Factory(coadd.getDimensions())
            image.set(badPixel)

            subBBox = geom.Box2I(geom.Point2I(0, i),
                                 image.getDimensions() - geom.Extent2I(0, i))
            subImage = image.Factory(image, subBBox, afwImage.LOCAL)
            subImage.set(truth)
            del subImage

            weight = 1.0 if uniformWeight else 1.0 + 0.1 * i
            if useMask:
                coaddUtils.addToCoadd(coadd, weightMap, image, badBits, weight)
            else:
                coaddUtils.addToCoadd(coadd, weightMap, image, weight)

            self.assertEqual(image[-1, -1, afwImage.LOCAL], truth)

        coadd /= weightMap

        if display:
            ds9.mtv(image, title="image", frame=1)
            ds9.mtv(coadd, title="coadd", frame=2)
            ds9.mtv(weightMap, title="weightMap", frame=3)

        stats = afwMath.makeStatistics(coadd, afwMath.MEAN | afwMath.STDEV)

        return [
            trueImageValue,
            stats.getValue(afwMath.MEAN), 0.0,
            stats.getValue(afwMath.STDEV)
        ]
 def testCreateBBox(self):
     """Test the bbox creation
     """
     packConfig = PackageAlertsConfig()
     # Just create a minimum less than the default cutout.
     packConfig.minCutoutSize = self.cutoutSize - 5
     packageAlerts = PackageAlertsTask(config=packConfig)
     bbox = packageAlerts.createDiaSourceBBox(packConfig.minCutoutSize - 5)
     self.assertTrue(bbox == geom.Extent2I(packConfig.minCutoutSize,
                                           packConfig.minCutoutSize))
     # Test that the cutout size is correct.
     bbox = packageAlerts.createDiaSourceBBox(self.cutoutSize)
     self.assertTrue(
         bbox == geom.Extent2I(self.cutoutSize, self.cutoutSize))
Example #16
0
    def __init__(self, config):
        super().__init__(config)

        self._cellInnerDimensions = geom.Extent2I(
            *(val for val in config.cellInnerDimensions))
        self._cellBorder = config.cellBorder
        self._numCellsPerPatchInner = config.numCellsPerPatchInner
        self._numCellsInPatchBorder = config.numCellsInPatchBorder
        self._patchInnerDimensions = geom.Extent2I(
            *(val * self._numCellsPerPatchInner
              for val in config.cellInnerDimensions))
        # The patch border is the number of cells in the border + the cell border
        self._patchBorder = config.numCellsInPatchBorder * config.cellInnerDimensions[
            0] + self._cellBorder
        self._initialized = False
Example #17
0
 def testCreateExtent(self):
     """Test the extent creation for the cutout bbox.
     """
     packConfig = PackageAlertsConfig()
     # Just create a minimum less than the default cutout.
     packConfig.minCutoutSize = self.cutoutSize - 5
     packageAlerts = PackageAlertsTask(config=packConfig)
     extent = packageAlerts.createDiaSourceExtent(packConfig.minCutoutSize -
                                                  5)
     self.assertTrue(extent == geom.Extent2I(packConfig.minCutoutSize,
                                             packConfig.minCutoutSize))
     # Test that the cutout size is correct.
     extent = packageAlerts.createDiaSourceExtent(self.cutoutSize)
     self.assertTrue(
         extent == geom.Extent2I(self.cutoutSize, self.cutoutSize))
    def setUp(self):

        nSources = 10
        # CFHT Filters from the camera mapper.
        afwImageUtils.resetFilters()
        afwImageUtils.defineFilter('u', lambdaEff=374, alias="u.MP9301")
        afwImageUtils.defineFilter('g', lambdaEff=487, alias="g.MP9401")
        afwImageUtils.defineFilter('r', lambdaEff=628, alias="r.MP9601")
        afwImageUtils.defineFilter('i', lambdaEff=778, alias="i.MP9701")
        afwImageUtils.defineFilter('z', lambdaEff=1170, alias="z.MP9801")

        self.bbox = geom.Box2I(geom.Point2I(0, 0), geom.Extent2I(1024, 1153))
        dataset = measTests.TestDataset(self.bbox)
        for srcIdx in range(nSources):
            dataset.addSource(100000.0, geom.Point2D(100, 100))
        self.inputCatalogNoFlags, _ = make_input_source_catalog(dataset, False)
        self.inputCatalog, self.exposure = \
            make_input_source_catalog(dataset, True)

        detector = DetectorWrapper(id=23,
                                   bbox=self.exposure.getBBox()).detector
        visit = afwImage.VisitInfo(exposureId=4321,
                                   exposureTime=200.,
                                   date=dafBase.DateTime(nsecs=1400000000 *
                                                         10**9))
        self.exposure.setDetector(detector)
        self.exposure.getInfo().setVisitInfo(visit)
        self.exposure.setFilter(afwImage.Filter('g.MP9401'))
        scale = 2
        scaleErr = 1
        self.photoCalib = afwImage.PhotoCalib(scale, scaleErr)
        self.exposure.setPhotoCalib(self.photoCalib)
    def testVisit(self, nCell=3):
        bskv = ipDiffim.BuildSingleKernelVisitorF(self.kList, self.ps)

        sizeCellX = self.ps["sizeCellX"]
        sizeCellY = self.ps["sizeCellY"]

        kernelCellSet = afwMath.SpatialCellSet(
            geom.Box2I(geom.Point2I(0, 0),
                       geom.Extent2I(sizeCellX * nCell, sizeCellY * nCell)),
            sizeCellX, sizeCellY)
        nTot = 0
        for candX in range(nCell):
            for candY in range(nCell):
                if candX == nCell // 2 and candY == nCell // 2:
                    kc = self.makeCandidate(100.0,
                                            candX * sizeCellX + sizeCellX // 2,
                                            candY * sizeCellY + sizeCellY // 2)
                else:
                    kc = self.makeCandidate(1.0,
                                            candX * sizeCellX + sizeCellX // 2,
                                            candY * sizeCellY + sizeCellY // 2)
                kernelCellSet.insertCandidate(kc)
                nTot += 1

        kernelCellSet.visitCandidates(bskv, 1)
        self.assertEqual(bskv.getNProcessed(), nTot)
        self.assertEqual(bskv.getNRejected(), 0)

        for cell in kernelCellSet.getCellList():
            for cand in cell.begin(False):
                self.assertEqual(cand.getStatus(),
                                 afwMath.SpatialCellCandidate.GOOD)
Example #20
0
    def fromCamera(cls, config, camera):
        """Construct from a camera object

        Parameters
        ----------
        config : `FocalPlaneBackgroundConfig`
            Configuration for measuring backgrounds.
        camera : `lsst.afw.cameraGeom.Camera`
            Camera for which to measure backgrounds.
        """
        cameraBox = geom.Box2D()
        for ccd in camera:
            for point in ccd.getCorners(afwCameraGeom.FOCAL_PLANE):
                cameraBox.include(point)

        width, height = cameraBox.getDimensions()
        # Offset so that we run from zero
        offset = geom.Extent2D(cameraBox.getMin()) * -1
        # Add an extra pixel buffer on either side
        dims = geom.Extent2I(
            int(numpy.ceil(width / config.xSize)) + 2,
            int(numpy.ceil(height / config.ySize)) + 2)
        # Transform takes us from focal plane coordinates --> sample coordinates
        transform = (
            geom.AffineTransform.makeTranslation(geom.Extent2D(1, 1)) *
            geom.AffineTransform.makeScaling(1.0 / config.xSize,
                                             1.0 / config.ySize) *
            geom.AffineTransform.makeTranslation(offset))

        return cls(config, dims, afwGeom.makeTransform(transform))
Example #21
0
    def _getCenterOfMass(exp, nominalCentroid, boxSize):
        """Get the centre of mass around a point in the image.

        Parameters
        ----------
        exp : `lsst.afw.image.Exposure`
            The exposure in question.
        nominalCentroid : `tuple` of `float`
            Nominal location of the centroid in pixel coordinates.
        boxSize : `int`
            The size of the box around the nominalCentroid in which to measure
            the centre of mass.

        Returns
        -------
        com : `tuple` of `float`
            The locaiton of the centre of mass of the brightest source in pixel
            coordinates.
        """
        centroidPoint = geom.Point2I(nominalCentroid)
        extent = geom.Extent2I(1, 1)
        bbox = geom.Box2I(centroidPoint, extent)
        bbox = bbox.dilatedBy(int(boxSize // 2))
        bbox = bbox.clippedTo(exp.getBBox())
        data = exp[bbox].image.array
        xy0 = exp[bbox].getXY0()

        peak = ndImage.center_of_mass(data)
        peak = (peak[1], peak[0])  # numpy coords returned
        com = geom.Point2D(xy0)
        com.shift(geom.Extent2D(*peak))
        return (com[0], com[1])
Example #22
0
    def vircamUpdateDetector(self, ccdExposure):
        """Update the detector bounding boxes to match the image

        VIRCAM CASU stacks are different sizes depending on 
 
        Parameters
        ----------
        ccdExposure : `lsst.afw.image.Exposure`
            The exposure to modify the bounding boxes for.

        """
        detector = ccdExposure.getDetector()
        #update BBox to image size
        BBox = geom.Box2I(
            geom.Point2I(0, 0),
            geom.Extent2I(ccdExposure.getImage().array.shape[1],
                          ccdExposure.getImage().array.shape[0]))
        self.log.info(
            "VISTA: Updating detector BBox to contain full stacked image [{},{}]."
            .format(ccdExposure.getImage().array.shape[1],
                    ccdExposure.getImage().array.shape[0]))
        detBuilder = detector.rebuild()
        detBuilder.setBBox(BBox)
        amplifier = detBuilder.getAmplifiers()[0]
        #ampBuilder=amplifier.rebuild()
        amplifier.setRawBBox(BBox)
        amplifier.setBBox(BBox)
        amplifier.setRawDataBBox(BBox)
        ccdExposure.setDetector(detBuilder.finish())
    def testSubMap(self):
        bbox = geom.BoxI(geom.Point2I(200, 100), geom.Extent2I(300, 400))
        mapper = MinMapper2(root=ROOT)
        loc = mapper.map("raw_sub", {"ccd": 13, "bbox": bbox}, write=True)
        self.assertEqual(loc.getPythonType(), "lsst.afw.image.ExposureU")
        self.assertEqual(loc.getCppType(), "ImageU")
        self.assertEqual(loc.getStorageName(), "FitsStorage")
        self.assertEqual(loc.getLocations(), ["foo-13.fits"])
        self.assertEqual(loc.getStorage().root, ROOT)
        self.assertEqual(loc.getAdditionalData().getScalar("ccd"), 13)
        self.assertEqual(loc.getAdditionalData().getScalar("width"), 300)
        self.assertEqual(loc.getAdditionalData().getScalar("height"), 400)
        self.assertEqual(loc.getAdditionalData().getScalar("llcX"), 200)
        self.assertEqual(loc.getAdditionalData().getScalar("llcY"), 100)
        checkCompression(self, loc.getAdditionalData())

        loc = mapper.map("raw_sub", {
            "ccd": 13,
            "bbox": bbox,
            "imageOrigin": "PARENT"
        },
                         write=True)
        self.assertEqual(loc.getPythonType(), "lsst.afw.image.ExposureU")
        self.assertEqual(loc.getCppType(), "ImageU")
        self.assertEqual(loc.getStorageName(), "FitsStorage")
        self.assertEqual(loc.getLocations(), ["foo-13.fits"])
        self.assertEqual(loc.getStorage().root, ROOT)
        self.assertEqual(loc.getAdditionalData().getScalar("ccd"), 13)
        self.assertEqual(loc.getAdditionalData().getScalar("width"), 300)
        self.assertEqual(loc.getAdditionalData().getScalar("height"), 400)
        self.assertEqual(loc.getAdditionalData().getScalar("llcX"), 200)
        self.assertEqual(loc.getAdditionalData().getScalar("llcY"), 100)
        self.assertEqual(loc.getAdditionalData().getScalar("imageOrigin"),
                         "PARENT")
        checkCompression(self, loc.getAdditionalData())
    def testVisit(self, nCell=3):
        ksv = ipDiffim.makeKernelSumVisitor(self.ps)

        sizeCellX = self.ps["sizeCellX"]
        sizeCellY = self.ps["sizeCellY"]

        kernelCellSet = afwMath.SpatialCellSet(
            geom.Box2I(geom.Point2I(0, 0),
                       geom.Extent2I(sizeCellX * nCell, sizeCellY * nCell)),
            sizeCellX, sizeCellY)

        for candX in range(nCell):
            for candY in range(nCell):
                if candX == nCell // 2 and candY == nCell // 2:
                    kc = self.makeCandidate(100.0,
                                            candX * sizeCellX + sizeCellX // 2,
                                            candY * sizeCellY + sizeCellY // 2)
                else:
                    kc = self.makeCandidate(1.0,
                                            candX * sizeCellX + sizeCellX // 2,
                                            candY * sizeCellY + sizeCellY // 2)
                kc.build(self.kList)
                kernelCellSet.insertCandidate(kc)

        ksv.setMode(ipDiffim.KernelSumVisitorF.AGGREGATE)
        kernelCellSet.visitCandidates(ksv, 1)
        ksv.processKsumDistribution()
        ksv.setMode(ipDiffim.KernelSumVisitorF.REJECT)
        kernelCellSet.visitCandidates(ksv, 1)

        self.assertEqual(ksv.getNRejected(), 1)
Example #25
0
    def makeExposure(imgArray, psfArray, imgVariance):
        """! Convert an image numpy.array and corresponding PSF numpy.array into an exposure.

        Add the (constant) variance plane equal to `imgVariance`.

        @param imgArray 2-d numpy.array containing the image
        @param psfArray 2-d numpy.array containing the PSF image
        @param imgVariance variance of input image
        @return a new exposure containing the image, PSF and desired variance plane
        """
        # All this code to convert the template image array/psf array into an exposure.
        bbox = geom.Box2I(
            geom.Point2I(0, 0),
            geom.Point2I(imgArray.shape[1] - 1, imgArray.shape[0] - 1))
        im1ex = afwImage.ExposureD(bbox)
        im1ex.getMaskedImage().getImage().getArray()[:, :] = imgArray
        im1ex.getMaskedImage().getVariance().getArray()[:, :] = imgVariance
        psfBox = geom.Box2I(geom.Point2I(-12, -12),
                            geom.Point2I(12, 12))  # a 25x25 pixel psf
        psf = afwImage.ImageD(psfBox)
        psfBox.shift(geom.Extent2I(size[0] // 2, size[1] // 2))
        im1_psf_sub = psfArray[psfBox.getMinX():psfBox.getMaxX() + 1,
                               psfBox.getMinY():psfBox.getMaxY() + 1]
        psf.getArray()[:, :] = im1_psf_sub
        psfK = afwMath.FixedKernel(psf)
        psfNew = measAlg.KernelPsf(psfK)
        im1ex.setPsf(psfNew)
        wcs = makeWcs()
        im1ex.setWcs(wcs)
        return im1ex
Example #26
0
    def testImageStatisticsMask2(self):
        # Mask value that does not get ignored
        maskPlanes = self.ps.getArray("badMaskPlanes")
        for maskPlane in ("BAD", "EDGE", "CR", "SAT", "INTRP"):
            if maskPlane not in maskPlanes:
                maskVal = afwImage.Mask.getPlaneBitMask(maskPlane)
                break
        self.assertGreater(maskVal, 0)

        numArray = num.ones((20, 20))
        mi = afwImage.MaskedImageF(geom.Extent2I(20, 20))
        for j in range(mi.getHeight()):
            for i in range(mi.getWidth()):
                val = i + 2.3 * j

                if i == 19:
                    mi[i, j, afwImage.LOCAL] = (val, maskVal, 1)
                    numArray[j][i] = val
                else:
                    mi[i, j, afwImage.LOCAL] = (val, 0x0, 1)
                    numArray[j][i] = val

        imstat = ipDiffim.ImageStatisticsF(self.ps)
        imstat.apply(mi)

        self.assertAlmostEqual(imstat.getMean(), numArray.mean())
        # note that these don't agree exactly...
        self.assertAlmostEqual(imstat.getRms(), numArray.std(), 1)
        self.assertEqual(imstat.getNpix(), 20 * 20)
    def testGood(self):
        ti = afwImage.MaskedImageF(geom.Extent2I(100, 100))
        ti.getVariance().set(0.1)
        ti[50, 50, afwImage.LOCAL] = (1., 0x0, 1.)
        sKernel = self.makeSpatialKernel(2)
        si = afwImage.MaskedImageF(ti.getDimensions())
        convolutionControl = afwMath.ConvolutionControl()
        convolutionControl.setDoNormalize(True)
        afwMath.convolve(si, ti, sKernel, convolutionControl)

        bbox = geom.Box2I(geom.Point2I(25, 25),
                          geom.Point2I(75, 75))
        si = afwImage.MaskedImageF(si, bbox, origin=afwImage.LOCAL)
        ti = afwImage.MaskedImageF(ti, bbox, origin=afwImage.LOCAL)
        kc = ipDiffim.KernelCandidateF(50., 50., ti, si, self.ps)

        sBg = afwMath.PolynomialFunction2D(1)
        bgCoeffs = [0., 0., 0.]
        sBg.setParameters(bgCoeffs)

        # must be initialized
        bskv = ipDiffim.BuildSingleKernelVisitorF(self.kList, self.ps)
        bskv.processCandidate(kc)
        self.assertEqual(kc.isInitialized(), True)

        askv = ipDiffim.AssessSpatialKernelVisitorF(sKernel, sBg, self.ps)
        askv.processCandidate(kc)

        self.assertEqual(askv.getNProcessed(), 1)
        self.assertEqual(askv.getNRejected(), 0)
        self.assertEqual(kc.getStatus(), afwMath.SpatialCellCandidate.GOOD)
Example #28
0
    def bypass_defects(self, datasetType, pythonType, butlerLocation, dataId):
        """Return a defect based on the butler location returned by map_defects

        Parameters
        ----------
        butlerLocation : `lsst.daf.persistence.ButlerLocation`
            locationList = path to defects FITS file
        dataId : `dict`
            Butler data ID; "ccd" must be set.

        Note: the name "bypass_XXX" means the butler makes no attempt to
        convert the ButlerLocation into an object, which is what we want for
        now, since that conversion is a bit tricky.
        """
        detectorName = self._extractDetectorName(dataId)
        defectsFitsPath = butlerLocation.locationList[0]

        with fits.open(defectsFitsPath) as hduList:
            for hdu in hduList[1:]:
                if hdu.header["name"] != detectorName:
                    continue

                defectList = Defects()
                for data in hdu.data:
                    bbox = geom.Box2I(
                        geom.Point2I(int(data['x0']), int(data['y0'])),
                        geom.Extent2I(int(data['width']), int(data['height'])),
                    )
                    defectList.append(bbox)
                return defectList

        raise RuntimeError("No defects for ccd %s in %s" % (detectorName, defectsFitsPath))
    def testInsert(self):
        mi = afwImage.MaskedImageF(geom.Extent2I(10, 10))
        kc = ipDiffim.makeKernelCandidate(0., 0., mi, mi, self.ps)
        kc.setStatus(afwMath.SpatialCellCandidate.GOOD)

        sizeCellX = self.ps["sizeCellX"]
        sizeCellY = self.ps["sizeCellY"]
        kernelCellSet = afwMath.SpatialCellSet(geom.Box2I(geom.Point2I(0, 0), geom.Extent2I(1, 1)),
                                               sizeCellX, sizeCellY)
        kernelCellSet.insertCandidate(kc)
        nSeen = 0
        for cell in kernelCellSet.getCellList():
            for cand in cell.begin(True):
                self.assertEqual(cand.getStatus(), afwMath.SpatialCellCandidate.GOOD)
                nSeen += 1
        self.assertEqual(nSeen, 1)
Example #30
0
    def _setupPatches(self, minBBox, wcs):
        """Setup for patches of a particular size.

        We grow the bounding box to hold an exact multiple of
        the desired size (patchInnerDimensions), while keeping
        the center roughly the same.  We return the final
        bounding box, and the number of patches in each dimension
        (as an Extent2I).

        Parameters
        ----------
        minBBox : `lsst.geom.Box2I`
            Minimum bounding box for tract
        wcs : `lsst.afw.geom.SkyWcs`
            Wcs object

        Returns
        -------
        bbox : `lsst.geom.Box2I
            final bounding box, number of patches
        numPatches : `int`
        """
        bbox = geom.Box2I(minBBox)
        bboxMin = bbox.getMin()
        bboxDim = bbox.getDimensions()
        numPatches = geom.Extent2I(0, 0)
        for i, innerDim in enumerate(self._patchInnerDimensions):
            num = (bboxDim[i] + innerDim - 1) // innerDim  # round up
            deltaDim = (innerDim * num) - bboxDim[i]
            if deltaDim > 0:
                bboxDim[i] = innerDim * num
                bboxMin[i] -= deltaDim // 2
            numPatches[i] = num
        bbox = geom.Box2I(bboxMin, bboxDim)
        return bbox, numPatches