def process(self, clipboard):
        """Reject outliers"""
        #         print "***** process ******"
        #         print "clipboard keys:"
        #         for key in clipboard.getKeys():
        #             print "*", key

        maskedImageList = self.getFromClipboard(clipboard, "maskedImageList")
        print "maskedImageList =", maskedImageList
        weightList = self.getFromClipboard(clipboard,
                                           "weightList",
                                           doRaise=False)
        outlierRejectionPolicy = self.policy.get("outlierRejectionPolicy")

        allowedMaskPlanes = outlierRejectionPolicy.get("allowedMaskPlanes")
        badPixelMask = coaddUtils.makeBitMask(allowedMaskPlanes.split(),
                                              doInvert=True)

        statsControl = afwMath.StatisticsControl()
        statsControl.setNumSigmaClip(outlierRejectionPolicy.get("numSigma"))
        statsControl.setNumIter(outlierRejectionPolicy.get("numIterations"))
        statsControl.setAndMask(badPixelMask)
        statsControl.setNanSafe(
            False)  # we're using masked images, so no need for NaN detection
        statsControl.setWeighted(True)

        if weightList != None:
            coadd = afwMath.statisticsStack(maskedImageList, afwMath.MEANCLIP,
                                            statsControl, weightList)
        else:
            coadd = afwMath.statisticsStack(maskedImageList, afwMath.MEANCLIP,
                                            statsControl)

        self.addToClipboard(clipboard, "coadd", coadd)
    def process(self, clipboard):
        """Reject outliers"""
#         print "***** process ******"
#         print "clipboard keys:"
#         for key in clipboard.getKeys():
#             print "*", key

        maskedImageList = self.getFromClipboard(clipboard, "maskedImageList")
        print "maskedImageList =", maskedImageList
        weightList = self.getFromClipboard(clipboard, "weightList", doRaise=False)
        outlierRejectionPolicy = self.policy.get("outlierRejectionPolicy")
        
        allowedMaskPlanes = outlierRejectionPolicy.get("allowedMaskPlanes")
        badPixelMask = coaddUtils.makeBitMask(allowedMaskPlanes.split(), doInvert=True)

        statsControl = afwMath.StatisticsControl()
        statsControl.setNumSigmaClip(outlierRejectionPolicy.get("numSigma"))
        statsControl.setNumIter(outlierRejectionPolicy.get("numIterations"))
        statsControl.setAndMask(badPixelMask)
        statsControl.setNanSafe(False) # we're using masked images, so no need for NaN detection
        statsControl.setWeighted(True)
        
        if weightList != None:
            coadd = afwMath.statisticsStack(maskedImageList, afwMath.MEANCLIP, statsControl, weightList)
        else:
            coadd = afwMath.statisticsStack(maskedImageList, afwMath.MEANCLIP, statsControl)

        self.addToClipboard(clipboard, "coadd", coadd)
예제 #3
0
파일: stacker.py 프로젝트: rbiswas4/afw
    def testRejectedMaskPropagation(self):
        """Test that we can propagate mask bits from rejected pixels, when the amount
        of rejection crosses a threshold."""
        rejectedBit = 1        # use this bit to determine whether to reject a pixel
        propagatedBit = 2  # propagate this bit if a pixel with it set is rejected
        statsCtrl = afwMath.StatisticsControl()
        statsCtrl.setMaskPropagationThreshold(propagatedBit, 0.3)
        statsCtrl.setAndMask(1 << rejectedBit)
        statsCtrl.setWeighted(True)
        maskedImageList = afwImage.vectorMaskedImageF()

        # start with 4 images with no mask bits set
        partialSum = numpy.zeros((1, 4), dtype=numpy.float32)
        finalImage = numpy.array([12.0, 12.0, 12.0, 12.0], dtype=numpy.float32)
        for i in range(4):
            mi = afwImage.MaskedImageF(4, 1)
            imArr, maskArr, varArr = mi.getArrays()
            imArr[:,:] = numpy.ones((1, 4), dtype=numpy.float32)
            maskedImageList.append(mi)
            partialSum += imArr
        # add one more image with all permutations of the first two bits set in different pixels
        mi = afwImage.MaskedImageF(4, 1)
        imArr, maskArr, varArr = mi.getArrays()
        imArr[0,:] = finalImage
        maskArr[0,1] |= (1 << rejectedBit)
        maskArr[0,2] |= (1 << propagatedBit)
        maskArr[0,3] |= (1 << rejectedBit)
        maskArr[0,3] |= (1 << propagatedBit)
        maskedImageList.append(mi)

        # these will always be rejected
        finalImage[1] = 0.0
        finalImage[3] = 0.0

        # Uniform weights: we should only see pixel 2 set with propagatedBit, because it's not rejected;
        # pixel 3 is rejected, but its weight (0.2) below the propagation threshold (0.3)
        stack1 = afwMath.statisticsStack(maskedImageList, afwMath.MEAN, statsCtrl, [1.0, 1.0, 1.0, 1.0, 1.0])
        self.assertEqual(stack1.get(0,0)[1], 0x0)
        self.assertEqual(stack1.get(1,0)[1], 0x0)
        self.assertEqual(stack1.get(2,0)[1], 1 << propagatedBit)
        self.assertEqual(stack1.get(3,0)[1], 0x0)
        self.assertClose(stack1.getImage().getArray(),
                         (partialSum + finalImage) / numpy.array([5.0, 4.0, 5.0, 4.0]),
                         rtol=1E-7)

        # Give the masked image more weight: we should see pixel 2 and pixel 3 set with propagatedBit,
        # pixel 2 because it's not rejected, and pixel 3 because the weight of the rejection (0.3333)
        # is above the threshold (0.3)
        # Note that rejectedBit is never propagated, because we didn't include it in statsCtrl (of course,
        # normally the bits we'd propagate and the bits we'd reject would be the same)
        stack2 = afwMath.statisticsStack(maskedImageList, afwMath.MEAN, statsCtrl, [1.0, 1.0, 1.0, 1.0, 2.0])
        self.assertEqual(stack2.get(0,0)[1], 0x0)
        self.assertEqual(stack2.get(1,0)[1], 0x0)
        self.assertEqual(stack2.get(2,0)[1], 1 << propagatedBit)
        self.assertEqual(stack2.get(3,0)[1], 1 << propagatedBit)
        self.assertClose(stack2.getImage().getArray(),
                         (partialSum + 2*finalImage) / numpy.array([6.0, 4.0, 6.0, 4.0]),
                         rtol=1E-7)
예제 #4
0
    def testRejectedMaskPropagation(self):
        """Test that we can propagate mask bits from rejected pixels, when the amount
        of rejection crosses a threshold."""
        rejectedBit = 1        # use this bit to determine whether to reject a pixel
        propagatedBit = 2  # propagate this bit if a pixel with it set is rejected
        statsCtrl = afwMath.StatisticsControl()
        statsCtrl.setMaskPropagationThreshold(propagatedBit, 0.3)
        statsCtrl.setAndMask(1 << rejectedBit)
        statsCtrl.setWeighted(True)
        maskedImageList = afwImage.vectorMaskedImageF()

        # start with 4 images with no mask bits set
        partialSum = numpy.zeros((1, 4), dtype=numpy.float32)
        finalImage = numpy.array([12.0, 12.0, 12.0, 12.0], dtype=numpy.float32)
        for i in range(4):
            mi = afwImage.MaskedImageF(4, 1)
            imArr, maskArr, varArr = mi.getArrays()
            imArr[:,:] = numpy.ones((1, 4), dtype=numpy.float32)
            maskedImageList.append(mi)
            partialSum += imArr
        # add one more image with all permutations of the first two bits set in different pixels
        mi = afwImage.MaskedImageF(4, 1)
        imArr, maskArr, varArr = mi.getArrays()
        imArr[0,:] = finalImage
        maskArr[0,1] |= (1 << rejectedBit)
        maskArr[0,2] |= (1 << propagatedBit)
        maskArr[0,3] |= (1 << rejectedBit)
        maskArr[0,3] |= (1 << propagatedBit)
        maskedImageList.append(mi)

        # these will always be rejected
        finalImage[1] = 0.0
        finalImage[3] = 0.0

        # Uniform weights: we should only see pixel 2 set with propagatedBit, because it's not rejected;
        # pixel 3 is rejected, but its weight (0.2) below the propagation threshold (0.3)
        stack1 = afwMath.statisticsStack(maskedImageList, afwMath.MEAN, statsCtrl, [1.0, 1.0, 1.0, 1.0, 1.0])
        self.assertEqual(stack1.get(0,0)[1], 0x0)
        self.assertEqual(stack1.get(1,0)[1], 0x0)
        self.assertEqual(stack1.get(2,0)[1], 1 << propagatedBit)
        self.assertEqual(stack1.get(3,0)[1], 0x0)
        self.assertClose(stack1.getImage().getArray(),
                         (partialSum + finalImage) / numpy.array([5.0, 4.0, 5.0, 4.0]),
                         rtol=1E-7)

        # Give the masked image more weight: we should see pixel 2 and pixel 3 set with propagatedBit,
        # pixel 2 because it's not rejected, and pixel 3 because the weight of the rejection (0.3333)
        # is above the threshold (0.3)
        # Note that rejectedBit is never propagated, because we didn't include it in statsCtrl (of course,
        # normally the bits we'd propagate and the bits we'd reject would be the same)
        stack2 = afwMath.statisticsStack(maskedImageList, afwMath.MEAN, statsCtrl, [1.0, 1.0, 1.0, 1.0, 2.0])
        self.assertEqual(stack2.get(0,0)[1], 0x0)
        self.assertEqual(stack2.get(1,0)[1], 0x0)
        self.assertEqual(stack2.get(2,0)[1], 1 << propagatedBit)
        self.assertEqual(stack2.get(3,0)[1], 1 << propagatedBit)
        self.assertClose(stack2.getImage().getArray(),
                         (partialSum + 2*finalImage) / numpy.array([6.0, 4.0, 6.0, 4.0]),
                         rtol=1E-7)
예제 #5
0
    def combine(self, target, imageList, stats):
        """!Combine multiple images

        @param target      Target image to receive the combined pixels
        @param imageList   List of input images
        @param stats       Statistics control
        """
        images = afwImage.vectorMaskedImageF([img for img in imageList if img is not None])
        afwMath.statisticsStack(target, images, self.config.combine, stats)
예제 #6
0
    def combine(self, target, imageList, stats):
        """!Combine multiple images

        @param target      Target image to receive the combined pixels
        @param imageList   List of input images
        @param stats       Statistics control
        """
        images = [img for img in imageList if img is not None]
        afwMath.statisticsStack(target, images,
                                afwMath.Property(self.config.combine), stats)
예제 #7
0
    def combineMIList(self, miList, method='MEANCLIP'):
        combinedFrame = miList[0].Factory()
        try:
            if method == 'MEANCLIP':
                combinedFrame = afwMath.statisticsStack(miList, afwMath.MEANCLIP, self.statsCtrl)
            elif method == 'MEDIAN':
                combinedFrame = afwMath.statisticsStack(miList, afwMath.MEDIAN, self.statsCtrl)
            else:
                raise ValueError("Method %s is not supported for combining frames" % (method))
        except Exception as e:
            self.log.warn("Could not combine the frames. %s", e)

        return combinedFrame
    def combineMIList(self, miList, method='MEANCLIP'):
        combinedFrame = miList[0].Factory()
        try:
            if method is 'MEANCLIP':
                combinedFrame = afwMath.statisticsStack(miList, afwMath.MEANCLIP, self.statsCtrl)
            elif method is 'MEDIAN':
                combinedFrame = afwMath.statisticsStack(miList, afwMath.MEDIAN, self.statsCtrl)
            else:
                raise ValueError("Method %s is not supported for combining frames" % (method))
        except Exception as e:
            self.log.warn("Could not combine the frames. %s", e)

        return combinedFrame
    def combine(self, target, imageList, stats):
        """!Combine multiple images

        @param target      Target image to receive the combined pixels
        @param imageList   List of input images
        @param stats       Statistics control
        """
        imageList = afwImage.vectorMaskedImageF([image for image in imageList if image is not None])
        if False:
            # In-place stacks are now supported on LSST's afw, but not yet on HSC
            afwMath.statisticsStack(target, imageList, self.config.combine, stats)
        else:
            stack = afwMath.statisticsStack(imageList, self.config.combine, stats)
            target <<= stack.getImage()
예제 #10
0
파일: stacker.py 프로젝트: rbiswas4/afw
    def testStatistics(self):
        """ Test the statisticsStack() function """
        
        imgList = afwImage.vectorImageF()
        for val in self.values:
            imgList.push_back(afwImage.ImageF(afwGeom.Extent2I(self.nX, self.nY), val))
            
        imgStack = afwMath.statisticsStack(imgList, afwMath.MEAN)
        mean = reduce(lambda x, y: x+y, self.values)/float(len(self.values))
        self.assertAlmostEqual(imgStack.get(self.nX//2, self.nY//2), mean)

        imgStack = afwMath.statisticsStack(imgList, afwMath.MEDIAN)
        median = sorted(self.values)[len(self.values)//2]
        self.assertEqual(imgStack.get(self.nX//2, self.nY//2), median)
예제 #11
0
    def testStatistics(self):
        """ Test the statisticsStack() function """
        
        imgList = afwImage.vectorImageF()
        for val in self.values:
            imgList.push_back(afwImage.ImageF(afwGeom.Extent2I(self.nX, self.nY), val))
            
        imgStack = afwMath.statisticsStack(imgList, afwMath.MEAN)
        mean = reduce(lambda x, y: x+y, self.values)/float(len(self.values))
        self.assertAlmostEqual(imgStack.get(self.nX/2, self.nY/2), mean)

        imgStack = afwMath.statisticsStack(imgList, afwMath.MEDIAN)
        median = sorted(self.values)[len(self.values)//2]
        self.assertEqual(imgStack.get(self.nX/2, self.nY/2), median)
예제 #12
0
    def testStatistics(self):
        """ Test the statisticsStack() function """

        imgList = []
        for val in self.values:
            imgList.append(afwImage.ImageF(
                lsst.geom.Extent2I(self.nX, self.nY), val))

        imgStack = afwMath.statisticsStack(imgList, afwMath.MEAN)
        mean = reduce(lambda x, y: x+y, self.values)/float(len(self.values))
        self.assertAlmostEqual(imgStack[self.nX//2, self.nY//2, afwImage.LOCAL], mean)

        imgStack = afwMath.statisticsStack(imgList, afwMath.MEDIAN)
        median = sorted(self.values)[len(self.values)//2]
        self.assertEqual(imgStack[self.nX//2, self.nY//2, afwImage.LOCAL], median)
예제 #13
0
    def combine(self, target, expList, stats):
        """Combine multiple images.

        Parameters
        ----------
        target : `lsst.afw.image.Exposure`
            Output exposure to construct.
        expList : `list` [`lsst.afw.image.Exposure`]
            Input exposures to combine.
        stats : `lsst.afw.math.StatisticsControl`
            Control explaining how to combine the input images.
        """
        images = [img.getMaskedImage() for img in expList if img is not None]
        afwMath.statisticsStack(target, images,
                                afwMath.Property(self.config.combine), stats)
예제 #14
0
    def testStatistics(self):
        """ Test the statisticsStack() function """

        imgList = []
        for val in self.values:
            imgList.append(afwImage.ImageF(
                lsst.geom.Extent2I(self.nX, self.nY), val))

        imgStack = afwMath.statisticsStack(imgList, afwMath.MEAN)
        mean = reduce(lambda x, y: x+y, self.values)/float(len(self.values))
        self.assertAlmostEqual(imgStack[self.nX//2, self.nY//2, afwImage.LOCAL], mean)

        imgStack = afwMath.statisticsStack(imgList, afwMath.MEDIAN)
        median = sorted(self.values)[len(self.values)//2]
        self.assertEqual(imgStack[self.nX//2, self.nY//2, afwImage.LOCAL], median)
예제 #15
0
    def run(self, bss_ref_list, region_name=None):
        """Read input bright star stamps and stack them together.

        The stacking is done iteratively over smaller areas of the final model
        image to allow for a great number of bright star stamps to be used.

        Parameters
        ----------
        bss_ref_list : `list` of
                `lsst.daf.butler._deferredDatasetHandle.DeferredDatasetHandle`
            List of available bright star stamps data references.
        region_name : `str`, optional
            Name of the focal plane region, if applicable. Only used for
            logging purposes, when running over multiple such regions
            (typically from `MeasureExtendedPsfTask`)
        """
        if region_name:
            region_message = f' for region "{region_name}".'
        else:
            region_message = ''
        self.log.info(
            'Building extended PSF from stamps extracted from %d detector images%s',
            len(bss_ref_list), region_message)
        # read in example set of full stamps
        example_bss = bss_ref_list[0].get(datasetType="brightStarStamps",
                                          immediate=True)
        example_stamp = example_bss[0].stamp_im
        # create model image
        ext_psf = afwImage.MaskedImageF(example_stamp.getBBox())
        # divide model image into smaller subregions
        subregion_size = Extent2I(*self.config.subregion_size)
        sub_bboxes = AssembleCoaddTask._subBBoxIter(ext_psf.getBBox(),
                                                    subregion_size)
        # compute approximate number of subregions
        n_subregions = int(ext_psf.getDimensions()[0] / subregion_size[0] +
                           1) * int(ext_psf.getDimensions()[1] /
                                    subregion_size[1] + 1)
        self.log.info(
            "Stacking will performed iteratively over approximately %d "
            "smaller areas of the final model image.", n_subregions)
        # set up stacking statistic
        stats_control, stats_flags = self._set_up_stacking(example_stamp)
        # perform stacking
        for jbbox, bbox in enumerate(sub_bboxes):
            all_stars = None
            for bss_ref in bss_ref_list:
                read_stars = bss_ref.get(datasetType="brightStarStamps",
                                         parameters={'bbox': bbox})
                if self.config.do_mag_cut:
                    read_stars = read_stars.selectByMag(
                        magMax=self.config.mag_limit)
                if all_stars:
                    all_stars.extend(read_stars)
                else:
                    all_stars = read_stars
            # TODO: DM-27371 add weights to bright stars for stacking
            coadd_sub_bbox = afwMath.statisticsStack(
                all_stars.getMaskedImages(), stats_flags, stats_control)
            ext_psf.assign(coadd_sub_bbox, bbox)
        return ext_psf
예제 #16
0
def superflat(files,
              bias_frame=None,
              outfile='superflat.fits',
              bitpix=-32,
              bias_subtract=True):
    """
    The superflat is created by bias-offset correcting the input files
    and median-ing them together.
    """
    # Get overscan region.
    overscan = makeAmplifierGeometry(files[0]).serial_overscan
    # Use the first file as a template for the fits output.
    output = fits.open(files[0])
    for amp in imutils.allAmps(files[0]):
        images = afwImage.vectorImageF()
        for infile in files:
            image = afwImage.ImageF(infile, imutils.dm_hdu(amp))
            if bias_subtract:
                if bias_frame:
                    bias_image = afwImage.ImageF(bias_frame,
                                                 imutils.dm_hdu(amp))
                    image = bias_subtracted_image(image, bias_image, overscan)
                else:
                    image -= imutils.bias_image(image,
                                                overscan,
                                                statistic=np.median)
            images.push_back(image)
        median_image = afwMath.statisticsStack(images, afwMath.MEDIAN)
        output[amp].data = median_image.getArray()
        if bitpix is not None:
            imutils.set_bitpix(output[amp], bitpix)
    fitsWriteto(output, outfile, clobber=True)
    return outfile
예제 #17
0
파일: stacker.py 프로젝트: rbiswas4/afw
    def testMean(self):
        """ Test the statisticsStack() function for a MEAN"""

        knownMean = 0.0
        imgList = afwImage.vectorImageF()
        for iImg in range(self.nImg):
            imgList.push_back(afwImage.ImageF(afwGeom.Extent2I(self.nX, self.nY), iImg))
            knownMean += iImg

        imgStack = afwMath.statisticsStack(imgList, afwMath.MEAN)
        knownMean /= self.nImg
        self.assertEqual(imgStack.get(self.nX//2, self.nY//2), knownMean)

        # Test in-place stacking
        afwMath.statisticsStack(imgStack, imgList, afwMath.MEAN)
        self.assertEqual(imgStack.get(self.nX//2, self.nY//2), knownMean)
예제 #18
0
파일: statBug1697.py 프로젝트: rnikutta/afw
    def testWeightedStats(self):
        """Test that bug from #1697 (weighted stats returning NaN) stays fixed."""
        
        rand = afwMath.Random()
        mu   = 10000

        edgeMask = afwImage.MaskU.getPlaneBitMask("EDGE")

        badPixelMask = afwImage.MaskU.getPlaneBitMask("EDGE")
        statsCtrl = afwMath.StatisticsControl()
        statsCtrl.setNumSigmaClip(3.0)
        statsCtrl.setNumIter(2)
        statsCtrl.setAndMask(badPixelMask)

        for weight in (300.0, 10.0, 1.0):
            print "Testing with weight=%0.1f" % (weight,)
            maskedImageList = afwImage.vectorMaskedImageF() # [] is rejected by afwMath.statisticsStack
            weightList = []

            nx, ny = 256, 256
            for i in range(3):
                print "Processing ", i
                maskedImage = afwImage.MaskedImageF(nx, ny)
                maskedImageList.append(maskedImage)

                afwMath.randomPoissonImage(maskedImage.getImage(), rand, mu)
                maskedImage.getVariance().set(mu)
                weightList.append(weight)
                    
            self.reportBadPixels(maskedImage, badPixelMask)

            print "Stack: ",
            coaddMaskedImage = afwMath.statisticsStack(
                maskedImageList, afwMath.MEANCLIP, statsCtrl, weightList)
            self.reportBadPixels(coaddMaskedImage, badPixelMask)
예제 #19
0
def superflat(files,
              bias_frame=None,
              outfile='superflat.fits',
              bitpix=None,
              bias_subtract=True,
              bias_method='row'):
    """
    The superflat is created by bias-offset correcting the input files
    and median-ing them together.
    """
    # Get overscan region.
    overscan = makeAmplifierGeometry(files[0]).serial_overscan
    output_images = dict()
    for amp in imutils.allAmps(files[0]):
        images = []
        for infile in files:
            image = afwImage.ImageF(infile, imutils.dm_hdu(amp))
            if bias_subtract:
                if bias_frame:
                    bias_image = afwImage.ImageF(bias_frame,
                                                 imutils.dm_hdu(amp))
                    image = bias_subtracted_image(image, bias_image, overscan,
                                                  bias_method)
                else:
                    image -= imutils.bias_image(im=image,
                                                overscan=overscan,
                                                bias_method=bias_method)
            images.append(image)
        if lsst.afw.__version__.startswith('12.0'):
            images = afwImage.vectorImageF(images)
        output_images[amp] = afwMath.statisticsStack(images, afwMath.MEDIAN)
    imutils.writeFits(output_images, outfile, files[0])
    return outfile
예제 #20
0
def stitchExposureStatisticsStack(destWcs, destBBox, expoList, warper):
    # Loosely based on pipe_tasks.assembleCoadd.
    # The weight of all images should be the same as they all come from the same skyMap.
    # Correct values for statsCtrl
    statsCtrl = afwMath.StatisticsControl()
    statsCtrl.setNumSigmaClip(3.0) # Believed to be ignored due to statsFlags = afw.Mean
    statsCtrl.setNumIter(2) # Believed to be ignored due to statsFlags = afw.Mean
    statsCtrl.setAndMask(afwImage.MaskU.getPlaneBitMask(["EDGE", "SAT"]))
    statsCtrl.setNanSafe(False) # Correct value is ???
    statsCtrl.setCalcErrorFromInputVariance(False) # Correct value is ???
    statsFlags = afwMath.MEAN
    #coaddMaskedImage = coaddExposure.getMaskedImage()
    #coaddView = afwImage.MaskedImageF(coaddMaskedImage, bbox, afwImage.PARENT, False)
    destExpo = afwImage.ExposureF(destBBox, destWcs)
    maskedImageList = afwImage.vectorMaskedImageF()
    weightList = []
    for j, expo in enumerate(expoList):
        warpedExposure = warper.warpExposure(
            destWcs = destExpo.getWcs(),
            srcExposure = expo,
            maxBBox = destExpo.getBBox())
        wn = "warpStatStack{}.fits".format(j)
        log.info(wn)
        #warpedExposure.writeFits(wn)
        j += 1
        maskedImage = warpedExposure.getMaskedImage()
        maskedImageList.append(maskedImage)
        weightList.append(1.0)

    coadd = afwMath.statisticsStack(maskedImageList, statsFlags, statsCtrl, weightList)
    #coadd.writeFits("coaddStatStack.fits")
    #coaddView <<= coadd
    destMaskedImage = destExpo.getMaskedImage()
    destMaskedImage <<= coadd
    return destExpo
예제 #21
0
파일: statBug1697.py 프로젝트: rbiswas4/afw
    def testWeightedStats(self):
        """Test that bug from #1697 (weighted stats returning NaN) stays fixed."""

        rand = afwMath.Random()
        mu = 10000

        edgeMask = afwImage.MaskU.getPlaneBitMask("EDGE")

        badPixelMask = afwImage.MaskU.getPlaneBitMask("EDGE")
        statsCtrl = afwMath.StatisticsControl()
        statsCtrl.setNumSigmaClip(3.0)
        statsCtrl.setNumIter(2)
        statsCtrl.setAndMask(badPixelMask)

        for weight in (300.0, 10.0, 1.0):
            print "Testing with weight=%0.1f" % (weight,)
            maskedImageList = afwImage.vectorMaskedImageF()  # [] is rejected by afwMath.statisticsStack
            weightList = []

            nx, ny = 256, 256
            for i in range(3):
                print "Processing ", i
                maskedImage = afwImage.MaskedImageF(nx, ny)
                maskedImageList.append(maskedImage)

                afwMath.randomPoissonImage(maskedImage.getImage(), rand, mu)
                maskedImage.getVariance().set(mu)
                weightList.append(weight)

            self.reportBadPixels(maskedImage, badPixelMask)

            print "Stack: ",
            coaddMaskedImage = afwMath.statisticsStack(maskedImageList, afwMath.MEANCLIP, statsCtrl, weightList)
            self.reportBadPixels(coaddMaskedImage, badPixelMask)
예제 #22
0
    def testMean(self):
        """ Test the statisticsStack() function for a MEAN"""

        knownMean = 0.0
        imgList = afwImage.vectorImageF()
        for iImg in range(self.nImg):
            imgList.push_back(afwImage.ImageF(afwGeom.Extent2I(self.nX, self.nY), iImg))
            knownMean += iImg

        imgStack = afwMath.statisticsStack(imgList, afwMath.MEAN)
        knownMean /= self.nImg
        self.assertEqual(imgStack.get(self.nX/2, self.nY/2), knownMean)

        # Test in-place stacking
        afwMath.statisticsStack(imgStack, imgList, afwMath.MEAN)
        self.assertEqual(imgStack.get(self.nX/2, self.nY/2), knownMean)
예제 #23
0
def fits_mean_file(files, outfile, overwrite=True, bitpix=32):
    output = fits.HDUList()
    output.append(fits.PrimaryHDU())
    all_amps = allAmps()
    for amp in all_amps:
        images = [afwImage.ImageF(item, dm_hdu(amp)) for item in files]
        if lsst.afw.__version__.startswith('12.0'):
            images = afwImage.vectorImageF(images)
        mean_image = afwMath.statisticsStack(images, afwMath.MEAN)
        if bitpix < 0:
            output.append(fits.ImageHDU(data=mean_image.getArray()))
        else:
            output.append(
                fits.CompImageHDU(data=mean_image.getArray(),
                                  compression_type='RICE_1'))
    with warnings.catch_warnings():
        warnings.filterwarnings('ignore', category=UserWarning, append=True)
        warnings.filterwarnings('ignore', category=AstropyWarning, append=True)
        warnings.filterwarnings('ignore',
                                category=AstropyUserWarning,
                                append=True)
        with fits.open(files[0]) as template:
            output[0].header.update(template[0].header)
            output[0].header['FILENAME'] = os.path.basename(outfile)
            for amp in all_amps:
                output[amp].header.update(template[amp].header)
                set_bitpix(output[amp], bitpix)
            for i in (-3, -2, -1):
                output.append(template[i])
            fitsWriteto(output, outfile, overwrite=overwrite)
예제 #24
0
    def testClipped(self):
        """Test that we set mask bits when pixels are clipped"""
        box = lsst.geom.Box2I(lsst.geom.Point2I(12345, 67890), lsst.geom.Extent2I(3, 3))
        num = 10
        maskVal = 0xAD
        value = 0.0

        images = [afwImage.MaskedImageF(box) for _ in range(num)]
        statsCtrl = afwMath.StatisticsControl()
        statsCtrl.setAndMask(maskVal)
        clipped = 1 << afwImage.Mask().addMaskPlane("CLIPPED")

        # No clipping: check that vanilla is working
        for img in images:
            img.getImage().set(value)
            img.getMask().set(0)
        stack = afwMath.statisticsStack(images, afwMath.MEANCLIP, clipped=clipped)
        self.assertFloatsAlmostEqual(stack.getImage().getArray(), 0.0, atol=0.0)
        self.assertFloatsAlmostEqual(stack.getMask().getArray(), 0, atol=0.0)  # Not floats, but that's OK

        # Clip a pixel; the CLIPPED bit should be set
        images[0].getImage()[1, 1, afwImage.LOCAL] = value + 1.0
        stack = afwMath.statisticsStack(images, afwMath.MEANCLIP, clipped=clipped)
        self.assertFloatsAlmostEqual(stack.getImage().getArray(), 0.0, atol=0.0)
        self.assertEqual(stack.mask[1, 1, afwImage.LOCAL], clipped)

        # Mask a pixel; the CLIPPED bit should be set
        images[0].getMask()[1, 1, afwImage.LOCAL] = maskVal
        stack = afwMath.statisticsStack(images, afwMath.MEAN, statsCtrl, clipped=clipped)
        self.assertFloatsAlmostEqual(stack.getImage().getArray(), 0.0, atol=0.0)
        self.assertEqual(stack.mask[1, 1, afwImage.LOCAL], clipped)

        # Excuse that mask; the CLIPPED bit should not be set
        stack = afwMath.statisticsStack(images, afwMath.MEAN, statsCtrl, clipped=clipped, excuse=maskVal)
        self.assertFloatsAlmostEqual(stack.getImage().getArray(), 0.0, atol=0.0)
        self.assertEqual(stack.mask[1, 1, afwImage.LOCAL], 0)

        # Map that mask value to a different one.
        rejected = 1 << afwImage.Mask().addMaskPlane("REJECTED")
        maskMap = [(maskVal, rejected)]
        images[0].mask[1, 1, afwImage.LOCAL] = 0        # only want to clip, not mask, this one
        images[1].mask[1, 2, afwImage.LOCAL] = maskVal  # only want to mask, not clip, this one
        stack = afwMath.statisticsStack(images, afwMath.MEANCLIP, statsCtrl, wvector=[], clipped=clipped,
                                        maskMap=maskMap)
        self.assertFloatsAlmostEqual(stack.getImage().getArray(), 0.0, atol=0.0)
        self.assertEqual(stack.mask[1, 1, afwImage.LOCAL], clipped)
        self.assertEqual(stack.mask[1, 2, afwImage.LOCAL], rejected)
예제 #25
0
    def testClipped(self):
        """Test that we set mask bits when pixels are clipped"""
        box = lsst.geom.Box2I(lsst.geom.Point2I(12345, 67890), lsst.geom.Extent2I(3, 3))
        num = 10
        maskVal = 0xAD
        value = 0.0

        images = [afwImage.MaskedImageF(box) for _ in range(num)]
        statsCtrl = afwMath.StatisticsControl()
        statsCtrl.setAndMask(maskVal)
        clipped = 1 << afwImage.Mask().addMaskPlane("CLIPPED")

        # No clipping: check that vanilla is working
        for img in images:
            img.getImage().set(value)
            img.getMask().set(0)
        stack = afwMath.statisticsStack(images, afwMath.MEANCLIP, clipped=clipped)
        self.assertFloatsAlmostEqual(stack.getImage().getArray(), 0.0, atol=0.0)
        self.assertFloatsAlmostEqual(stack.getMask().getArray(), 0, atol=0.0)  # Not floats, but that's OK

        # Clip a pixel; the CLIPPED bit should be set
        images[0].getImage()[1, 1, afwImage.LOCAL] = value + 1.0
        stack = afwMath.statisticsStack(images, afwMath.MEANCLIP, clipped=clipped)
        self.assertFloatsAlmostEqual(stack.getImage().getArray(), 0.0, atol=0.0)
        self.assertEqual(stack.mask[1, 1, afwImage.LOCAL], clipped)

        # Mask a pixel; the CLIPPED bit should be set
        images[0].getMask()[1, 1, afwImage.LOCAL] = maskVal
        stack = afwMath.statisticsStack(images, afwMath.MEAN, statsCtrl, clipped=clipped)
        self.assertFloatsAlmostEqual(stack.getImage().getArray(), 0.0, atol=0.0)
        self.assertEqual(stack.mask[1, 1, afwImage.LOCAL], clipped)

        # Excuse that mask; the CLIPPED bit should not be set
        stack = afwMath.statisticsStack(images, afwMath.MEAN, statsCtrl, clipped=clipped, excuse=maskVal)
        self.assertFloatsAlmostEqual(stack.getImage().getArray(), 0.0, atol=0.0)
        self.assertEqual(stack.mask[1, 1, afwImage.LOCAL], 0)

        # Map that mask value to a different one.
        rejected = 1 << afwImage.Mask().addMaskPlane("REJECTED")
        maskMap = [(maskVal, rejected)]
        images[0].mask[1, 1, afwImage.LOCAL] = 0        # only want to clip, not mask, this one
        images[1].mask[1, 2, afwImage.LOCAL] = maskVal  # only want to mask, not clip, this one
        stack = afwMath.statisticsStack(images, afwMath.MEANCLIP, statsCtrl, wvector=[], clipped=clipped,
                                        maskMap=maskMap)
        self.assertFloatsAlmostEqual(stack.getImage().getArray(), 0.0, atol=0.0)
        self.assertEqual(stack.mask[1, 1, afwImage.LOCAL], clipped)
        self.assertEqual(stack.mask[1, 2, afwImage.LOCAL], rejected)
예제 #26
0
    def testMean(self):
        """ Test the statisticsStack() function for a MEAN"""

        knownMean = 0.0
        imgList = []
        for iImg in range(self.nImg):
            imgList.append(afwImage.ImageF(
                lsst.geom.Extent2I(self.nX, self.nY), iImg))
            knownMean += iImg

        imgStack = afwMath.statisticsStack(imgList, afwMath.MEAN)
        knownMean /= self.nImg
        self.assertEqual(imgStack[self.nX//2, self.nY//2, afwImage.LOCAL], knownMean)

        # Test in-place stacking
        afwMath.statisticsStack(imgStack, imgList, afwMath.MEAN)
        self.assertEqual(imgStack[self.nX//2, self.nY//2, afwImage.LOCAL], knownMean)
예제 #27
0
    def testMean(self):
        """ Test the statisticsStack() function for a MEAN"""

        knownMean = 0.0
        imgList = []
        for iImg in range(self.nImg):
            imgList.append(afwImage.ImageF(
                lsst.geom.Extent2I(self.nX, self.nY), iImg))
            knownMean += iImg

        imgStack = afwMath.statisticsStack(imgList, afwMath.MEAN)
        knownMean /= self.nImg
        self.assertEqual(imgStack[self.nX//2, self.nY//2, afwImage.LOCAL], knownMean)

        # Test in-place stacking
        afwMath.statisticsStack(imgStack, imgList, afwMath.MEAN)
        self.assertEqual(imgStack[self.nX//2, self.nY//2, afwImage.LOCAL], knownMean)
예제 #28
0
def stack(ims, statistic=afwMath.MEDIAN):
    """Stacks a list of images based on a statistic."""
    images = []
    for image in ims:
        images.append(image)
    if lsst.afw.__version__.startswith('12.0'):
        images = afwImage.vectorImageF(images)
    summary = afwMath.statisticsStack(images, statistic)
    return summary
예제 #29
0
    def testWeightedStack(self):
        """ Test statisticsStack() function when weighting by a variance plane"""
        
        sctrl = afwMath.StatisticsControl()
        sctrl.setWeighted(True)
        mimgList = afwImage.vectorMaskedImageF()
        for val in self.values:
            mimg = afwImage.MaskedImageF(afwGeom.Extent2I(self.nX, self.nY))
            mimg.set(val, 0x0, val)
            mimgList.push_back(mimg)
        mimgStack = afwMath.statisticsStack(mimgList, afwMath.MEAN, sctrl)

        wvalues = [1.0/q for q in self.values]
        wmean = float(len(self.values)) / reduce(lambda x, y: x + y, wvalues)
        self.assertAlmostEqual(mimgStack.getImage().get(self.nX/2, self.nY/2), wmean)

        # Test in-place stacking
        afwMath.statisticsStack(mimgStack, mimgList, afwMath.MEAN, sctrl)
        self.assertAlmostEqual(mimgStack.getImage().get(self.nX/2, self.nY/2), wmean)
예제 #30
0
파일: stacker.py 프로젝트: rbiswas4/afw
    def testWeightedStack(self):
        """ Test statisticsStack() function when weighting by a variance plane"""
        
        sctrl = afwMath.StatisticsControl()
        sctrl.setWeighted(True)
        mimgList = afwImage.vectorMaskedImageF()
        for val in self.values:
            mimg = afwImage.MaskedImageF(afwGeom.Extent2I(self.nX, self.nY))
            mimg.set(val, 0x0, val)
            mimgList.push_back(mimg)
        mimgStack = afwMath.statisticsStack(mimgList, afwMath.MEAN, sctrl)

        wvalues = [1.0/q for q in self.values]
        wmean = float(len(self.values)) / reduce(lambda x, y: x + y, wvalues)
        self.assertAlmostEqual(mimgStack.getImage().get(self.nX//2, self.nY//2), wmean)

        # Test in-place stacking
        afwMath.statisticsStack(mimgStack, mimgList, afwMath.MEAN, sctrl)
        self.assertAlmostEqual(mimgStack.getImage().get(self.nX//2, self.nY//2), wmean)
예제 #31
0
def main():

    nImg = 10
    nX, nY = 64, 64

    imgList = afwImage.vectorImageF()
    for iImg in range(nImg):
        imgList.push_back(afwImage.ImageF(afwGeom.Extent2I(nX, nY), iImg))

    imgStack = afwMath.statisticsStack(imgList, afwMath.MEAN)

    print imgStack.get(nX / 2, nY / 2)
예제 #32
0
def main():

    nImg = 10
    nX, nY = 64, 64
    
    imgList = afwImage.vectorImageF()
    for iImg in range(nImg):
        imgList.push_back(afwImage.ImageF(afwGeom.Extent2I(nX, nY), iImg))

    imgStack = afwMath.statisticsStack(imgList, afwMath.MEAN)

    print imgStack.get(nX/2, nY/2)
예제 #33
0
    def setUp(self):

        # fill an image with a gradient
        self.n = 8
        self.img = afwImage.ImageF(afwGeom.Extent2I(self.n, self.n), 0)

        # these are the known answers for comparison
        def nVector(n, v):
            return [v for i in range(n)]

        self.column = nVector(self.n, 0.0)
        self.row = nVector(self.n, 0.0)
        self.colPlus = nVector(self.n, 0.0)
        self.colMinus = nVector(self.n, 0.0)
        self.colMult = nVector(self.n, 0.0)
        self.colDiv = nVector(self.n, 0.0)
        self.rowPlus = nVector(self.n, 0.0)
        self.rowMinus = nVector(self.n, 0.0)
        self.rowMult = nVector(self.n, 0.0)
        self.rowDiv = nVector(self.n, 0.0)

        # set the values in the image, and keep track of the stats to verify
        # things
        for y in range(self.n):
            for x in range(self.n):
                val = 1.0 * x + 2.0 * y
                self.img.set(x, y, val)
                self.column[y] += val
                self.row[x] += val

        for i in range(self.n):
            self.row[i] /= self.n
            self.column[i] /= self.n
            self.colPlus[i] = self.img.get(0, i) + self.column[i]

        # get stats on the columns and rows
        self.imgProjectCol = afwMath.statisticsStack(self.img, afwMath.MEAN,
                                                     'x')
        self.imgProjectRow = afwMath.statisticsStack(self.img, afwMath.MEAN,
                                                     'y')
예제 #34
0
    def test_online_coadd_input_variance_false(self):
        """Test online coaddition with calcErrorFromInputVariance=False."""
        exposures, weights = self.make_test_images_to_coadd()
        coadd_exposure = self.make_coadd_exposure(exposures[0])
        stats_ctrl = self.make_stats_ctrl()
        stats_ctrl.setCalcErrorFromInputVariance(False)
        mask_map = self.make_mask_map(stats_ctrl)

        stats_flags = afwMath.stringToStatisticsProperty("MEAN")
        clipped = afwImage.Mask.getPlaneBitMask("CLIPPED")

        masked_image_list = [exp.maskedImage for exp in exposures]

        afw_masked_image = afwMath.statisticsStack(masked_image_list,
                                                   stats_flags, stats_ctrl,
                                                   weights, clipped, mask_map)

        mask_threshold_dict = AccumulatorMeanStack.stats_ctrl_to_threshold_dict(
            stats_ctrl)

        # Make the stack with the online accumulator

        # By setting no_good_pixels=None we have the same behavior
        # as the default from stats_ctrl.getNoGoodPixelsMask(), but
        # covers the alternate code path.
        stacker = AccumulatorMeanStack(
            coadd_exposure.image.array.shape,
            stats_ctrl.getAndMask(),
            mask_threshold_dict=mask_threshold_dict,
            mask_map=mask_map,
            no_good_pixels_mask=None,
            calc_error_from_input_variance=stats_ctrl.
            getCalcErrorFromInputVariance(),
            compute_n_image=True)

        for exposure, weight in zip(exposures, weights):
            stacker.add_masked_image(exposure.maskedImage, weight=weight)

        stacker.fill_stacked_masked_image(coadd_exposure.maskedImage)

        online_masked_image = coadd_exposure.maskedImage

        # The coadds match at the <1e-5 level.
        testing.assert_array_almost_equal(online_masked_image.image.array,
                                          afw_masked_image.image.array,
                                          decimal=5)
        # The computed variances match at the <1e-4 level.
        testing.assert_array_almost_equal(online_masked_image.variance.array,
                                          afw_masked_image.variance.array,
                                          decimal=4)
        testing.assert_array_equal(online_masked_image.mask.array,
                                   afw_masked_image.mask.array)
예제 #35
0
    def testTicket1412(self):
        """Ticket 1412: ignored mask bits are propegated to output stack."""

        mimg1 = afwImage.MaskedImageF(afwGeom.Extent2I(1, 1))
        mimg1.set(0, 0, (1, 0x4, 1))  # set 0100
        mimg2 = afwImage.MaskedImageF(afwGeom.Extent2I(1, 1))
        mimg2.set(0, 0, (2, 0x3, 1))  # set 0010 and 0001

        imgList = afwImage.vectorMaskedImageF()
        imgList.push_back(mimg1)
        imgList.push_back(mimg2)

        sctrl = afwMath.StatisticsControl()
        sctrl.setAndMask(0x1)  # andmask only 0001

        # try first with no sctrl (no andmask set), should see 0x0111 for all output mask pixels
        imgStack = afwMath.statisticsStack(imgList, afwMath.MEAN)
        self.assertEqual(imgStack.get(0, 0)[1], 0x7)

        # now try with sctrl (andmask = 0x0001), should see 0x0100 for all output mask pixels
        imgStack = afwMath.statisticsStack(imgList, afwMath.MEAN, sctrl)
        self.assertEqual(imgStack.get(0, 0)[1], 0x4)
예제 #36
0
파일: stacker.py 프로젝트: rbiswas4/afw
    def testTicket1412(self):
        """Ticket 1412: ignored mask bits are propegated to output stack."""

        mimg1 = afwImage.MaskedImageF(afwGeom.Extent2I(1, 1))
        mimg1.set(0, 0, (1, 0x4, 1)) # set 0100
        mimg2 = afwImage.MaskedImageF(afwGeom.Extent2I(1, 1))
        mimg2.set(0, 0, (2, 0x3, 1)) # set 0010 and 0001
        
        imgList = afwImage.vectorMaskedImageF()
        imgList.push_back(mimg1)
        imgList.push_back(mimg2)
        
        sctrl = afwMath.StatisticsControl()
        sctrl.setAndMask(0x1) # andmask only 0001

        # try first with no sctrl (no andmask set), should see 0x0111 for all output mask pixels
        imgStack = afwMath.statisticsStack(imgList, afwMath.MEAN)
        self.assertEqual(imgStack.get(0, 0)[1], 0x7)

        # now try with sctrl (andmask = 0x0001), should see 0x0100 for all output mask pixels
        imgStack = afwMath.statisticsStack(imgList, afwMath.MEAN, sctrl)
        self.assertEqual(imgStack.get(0, 0)[1], 0x4)
예제 #37
0
    def setUp(self):

        # fill an image with a gradient
        self.n      = 8
        self.img    = afwImage.ImageF(afwGeom.Extent2I(self.n, self.n), 0)

        # these are the known answers for comparison
        def nVector(n, v):
            return [v for i in range(n)]
        self.column = nVector(self.n, 0.0)
        self.row    = nVector(self.n, 0.0)
        self.colPlus  = nVector(self.n, 0.0)
        self.colMinus = nVector(self.n, 0.0)
        self.colMult  = nVector(self.n, 0.0)
        self.colDiv   = nVector(self.n, 0.0)
        self.rowPlus  = nVector(self.n, 0.0)
        self.rowMinus = nVector(self.n, 0.0)
        self.rowMult  = nVector(self.n, 0.0)
        self.rowDiv   = nVector(self.n, 0.0)

        # set the values in the image, and keep track of the stats to verify things
        for y in range(self.n):
            for x in range(self.n):
                val = 1.0*x + 2.0*y
                self.img.set(x, y, val)
                self.column[y] += val
                self.row[x]    += val

        for i in range(self.n):
            self.row[i]    /= self.n
            self.column[i] /= self.n
            self.colPlus[i] = self.img.get(0, i) + self.column[i]
            
        # get stats on the columns and rows
        self.imgProjectCol = afwMath.statisticsStack(self.img, afwMath.MEAN, 'x')
        self.imgProjectRow = afwMath.statisticsStack(self.img, afwMath.MEAN, 'y')
예제 #38
0
파일: stacker.py 프로젝트: rbiswas4/afw
    def testConstantWeightedStack(self):
        """ Test statisticsStack() function when weighting by a vector of weights"""
        
        sctrl = afwMath.StatisticsControl()
        imgList = afwImage.vectorImageF()
        weights = afwMath.vectorF()
        for val in self.values:
            img = afwImage.ImageF(afwGeom.Extent2I(self.nX, self.nY), val)
            imgList.push_back(img)
            weights.push_back(val)
        imgStack = afwMath.statisticsStack(imgList, afwMath.MEAN, sctrl, weights)

        wsum = reduce(lambda x, y: x + y, self.values)
        wvalues = [x*x for x in self.values]
        wmean = reduce(lambda x, y: x + y, wvalues)/float(wsum)
        self.assertAlmostEqual(imgStack.get(self.nX//2, self.nY//2), wmean)
예제 #39
0
    def testConstantWeightedStack(self):
        """ Test statisticsStack() function when weighting by a vector of weights"""
        
        sctrl = afwMath.StatisticsControl()
        imgList = afwImage.vectorImageF()
        weights = afwMath.vectorF()
        for val in self.values:
            img = afwImage.ImageF(afwGeom.Extent2I(self.nX, self.nY), val)
            imgList.push_back(img)
            weights.push_back(val)
        imgStack = afwMath.statisticsStack(imgList, afwMath.MEAN, sctrl, weights)

        wsum = reduce(lambda x, y: x + y, self.values)
        wvalues = [x*x for x in self.values]
        wmean = reduce(lambda x, y: x + y, wvalues)/float(wsum)
        self.assertAlmostEqual(imgStack.get(self.nX/2, self.nY/2), wmean)
예제 #40
0
    def testConstantWeightedStack(self):
        """ Test statisticsStack() function when weighting by a vector of weights"""

        sctrl = afwMath.StatisticsControl()
        imgList = []
        weights = []
        for val in self.values:
            img = afwImage.ImageF(lsst.geom.Extent2I(self.nX, self.nY), val)
            imgList.append(img)
            weights.append(val)
        imgStack = afwMath.statisticsStack(
            imgList, afwMath.MEAN, sctrl, weights)

        wsum = reduce(lambda x, y: x + y, self.values)
        wvalues = [x*x for x in self.values]
        wmean = reduce(lambda x, y: x + y, wvalues)/float(wsum)
        self.assertAlmostEqual(imgStack[self.nX//2, self.nY//2, afwImage.LOCAL], wmean)
예제 #41
0
    def averageBackgrounds(self, bgList):
        """Average multiple background models

        The input background models should be a `BackgroundList` consisting
        of a single `BackgroundMI`.

        Parameters
        ----------
        bgList : `list` of `lsst.afw.math.BackgroundList`
            Background models to average.

        Returns
        -------
        bgExp : `lsst.afw.image.Exposure`
            Background model in Exposure format.
        """
        assert all(len(bg) == 1 for bg in
                   bgList), "Mixed bgList: %s" % ([len(bg) for bg in bgList], )
        images = [bg[0][0].getStatsImage() for bg in bgList]
        boxes = [bg[0][0].getImageBBox() for bg in bgList]
        assert len(set((box.getMinX(), box.getMinY(), box.getMaxX(), box.getMaxY()) for box in boxes)) == 1, \
            "Bounding boxes not all equal"
        bbox = boxes.pop(0)

        # Ensure bad pixels are masked
        maskVal = afwImage.Mask.getPlaneBitMask("BAD")
        for img in images:
            bad = numpy.isnan(img.getImage().getArray())
            img.getMask().getArray()[bad] = maskVal

        stats = afwMath.StatisticsControl()
        stats.setAndMask(maskVal)
        stats.setNanSafe(True)
        combined = afwMath.statisticsStack(images, afwMath.MEANCLIP, stats)

        # Set bad pixels to the median
        # Specifically NOT going to attempt to interpolate the bad values because we're only working on a
        # single CCD here and can't use the entire field-of-view to do the interpolation (which is what we
        # would need to avoid introducing problems at the edge of CCDs).
        array = combined.getImage().getArray()
        bad = numpy.isnan(array)
        median = numpy.median(array[~bad])
        array[bad] = median

        # Put it into an exposure, which is required for calibs
        return self.backgroundToExposure(combined, bbox)
예제 #42
0
    def assembleSubregion(self, coaddExposure, bbox, tempExpRefList, imageScalerList, weightList,
                          bgInfoList, altMaskList, statsFlags, statsCtrl):
        """Assemble the coadd for a sub-region

        @param coaddExposure: The target image for the coadd
        @param bbox: Sub-region to coadd
        @param tempExpRefList: List of data reference to tempExp
        @param imageScalerList: List of image scalers
        @param weightList: List of weights
        @param bgInfoList: List of background data from background matching
        @param altMaskList: List of alternate masks to use rather than those stored with tempExp, or None
        @param statsFlags: Statistic for coadd
        @param statsCtrl: Statistics control object for coadd
        """
        self.log.logdebug("Computing coadd over %s" % bbox)
        tempExpName = self.getTempExpDatasetName()
        coaddMaskedImage = coaddExposure.getMaskedImage()
        maskedImageList = afwImage.vectorMaskedImageF() # [] is rejected by afwMath.statisticsStack
        for tempExpRef, imageScaler, bgInfo, altMask in zip(tempExpRefList, imageScalerList, bgInfoList,
                                                            altMaskList):
            exposure = tempExpRef.get(tempExpName + "_sub", bbox=bbox)
            maskedImage = exposure.getMaskedImage()

            if altMask:
                altMaskSub = altMask.Factory(altMask, bbox, afwImage.PARENT)
                maskedImage.getMask().swap(altMaskSub)
            imageScaler.scaleMaskedImage(maskedImage)

            if self.config.doMatchBackgrounds and not bgInfo.isReference:
                backgroundModel = bgInfo.backgroundModel
                backgroundImage = backgroundModel.getImage() if \
                    self.matchBackgrounds.config.usePolynomial else \
                    backgroundModel.getImageF()
                backgroundImage.setXY0(coaddMaskedImage.getXY0())
                maskedImage += backgroundImage.Factory(backgroundImage, bbox, afwImage.PARENT, False)
                var = maskedImage.getVariance()
                var += (bgInfo.fitRMS)**2

            maskedImageList.append(maskedImage)

        with self.timer("stack"):
            coaddSubregion = afwMath.statisticsStack(
                maskedImageList, statsFlags, statsCtrl, weightList)

        coaddMaskedImage.assign(coaddSubregion, bbox)
예제 #43
0
    def test_online_coadd_image(self):
        """Test online coaddition with regular non-masked images."""
        exposures, weights = self.make_test_images_to_coadd()
        coadd_exposure = self.make_coadd_exposure(exposures[0])
        stats_ctrl = self.make_stats_ctrl()
        stats_ctrl.setAndMask(0)
        stats_ctrl.setCalcErrorFromInputVariance(True)
        mask_map = self.make_mask_map(stats_ctrl)

        stats_flags = afwMath.stringToStatisticsProperty("MEAN")
        clipped = afwImage.Mask.getPlaneBitMask("CLIPPED")

        masked_image_list = [exp.maskedImage for exp in exposures]

        afw_masked_image = afwMath.statisticsStack(masked_image_list,
                                                   stats_flags, stats_ctrl,
                                                   weights, clipped, mask_map)

        # Make the stack with the online accumulator
        stacker = AccumulatorMeanStack(
            coadd_exposure.image.array.shape,
            stats_ctrl.getAndMask(),
            mask_map=mask_map,
            no_good_pixels_mask=stats_ctrl.getNoGoodPixelsMask(),
            calc_error_from_input_variance=stats_ctrl.
            getCalcErrorFromInputVariance(),
            compute_n_image=True)

        for exposure, weight in zip(exposures, weights):
            stacker.add_image(exposure.image, weight=weight)

        stacker.fill_stacked_image(coadd_exposure.image)

        online_image = coadd_exposure.image

        # The unmasked coadd good pixels should match at the <1e-5 level
        # The masked pixels will not be correct for straight image stacking.
        good_pixels = np.where(afw_masked_image.mask.array == 0)

        testing.assert_array_almost_equal(
            online_image.array[good_pixels],
            afw_masked_image.image.array[good_pixels],
            decimal=5)
예제 #44
0
def fits_median(files, hdu=2, fix=True):
    """Compute the median image from a set of image FITS files."""
    ims = [afwImage.ImageF(f, hdu) for f in files]
    exptimes = [Metadata(f).get('EXPTIME') for f in files]

    if min(exptimes) != max(exptimes):
        raise RuntimeError("Error: unequal exposure times")

    if fix:
        medians = np.array([median(im) for im in ims])
        med = sum(medians) / len(medians)
        errs = medians - med
        for im, err in zip(ims, errs):
            im -= err

    if lsst.afw.__version__.startswith('12.0'):
        ims = afwImage.vectorImageF(ims)
    median_image = afwMath.statisticsStack(ims, afwMath.MEDIAN)

    return median_image
예제 #45
0
 def test2145(self):
     """The how-to-repeat from #2145"""
     Size = 5
     statsCtrl = afwMath.StatisticsControl()
     statsCtrl.setCalcErrorFromInputVariance(True)
     maskedImageList = afwImage.vectorMaskedImageF()
     weightList = []
     for i in range(3):
         mi = afwImage.MaskedImageF(Size, Size)
         imArr, maskArr, varArr = mi.getArrays()
         imArr[:] = numpy.random.normal(10, 0.1, (Size, Size))
         varArr[:] = numpy.random.normal(10, 0.1, (Size, Size))
         maskedImageList.append(mi)
         weightList.append(1.0)
         
     stack = afwMath.statisticsStack(maskedImageList, afwMath.MEAN, statsCtrl, weightList)
     if False:
         print "image=", stack.getImage().getArray()
         print "variance=", stack.getVariance().getArray()
     self.assertNotEqual(numpy.sum(stack.getVariance().getArray()), 0.0)
예제 #46
0
파일: stacker.py 프로젝트: rbiswas4/afw
 def test2145(self):
     """The how-to-repeat from #2145"""
     Size = 5
     statsCtrl = afwMath.StatisticsControl()
     statsCtrl.setCalcErrorFromInputVariance(True)
     maskedImageList = afwImage.vectorMaskedImageF()
     weightList = []
     for i in range(3):
         mi = afwImage.MaskedImageF(Size, Size)
         imArr, maskArr, varArr = mi.getArrays()
         imArr[:] = numpy.random.normal(10, 0.1, (Size, Size))
         varArr[:] = numpy.random.normal(10, 0.1, (Size, Size))
         maskedImageList.append(mi)
         weightList.append(1.0)
         
     stack = afwMath.statisticsStack(maskedImageList, afwMath.MEAN, statsCtrl, weightList)
     if False:
         print "image=", stack.getImage().getArray()
         print "variance=", stack.getVariance().getArray()
     self.assertNotEqual(numpy.sum(stack.getVariance().getArray()), 0.0)
예제 #47
0
    def testReturnInputs(self):
        """ Make sure that a single file put into the stacker is returned unscathed"""

        imgList = afwImage.vectorMaskedImageF()

        img = afwImage.MaskedImageF(afwGeom.Extent2I(10, 20))
        for y in range(img.getHeight()):
            simg = img.Factory(
                img, afwGeom.Box2I(afwGeom.Point2I(0, y), afwGeom.Extent2I(img.getWidth(), 1)), afwImage.LOCAL
            )
            simg.set(y)

        imgList.push_back(img)

        imgStack = afwMath.statisticsStack(imgList, afwMath.MEAN)

        if display:
            ds9.mtv(img, frame=1, title="input")
            ds9.mtv(imgStack, frame=2, title="stack")

        self.assertEqual(img.get(0, 0)[0], imgStack.get(0, 0)[0])
예제 #48
0
    def testReturnInputs(self):
        """ Make sure that a single file put into the stacker is returned unscathed"""

        imgList = afwImage.vectorMaskedImageF()
        
        img = afwImage.MaskedImageF(afwGeom.Extent2I(10, 20))
        for y in range(img.getHeight()):
            simg = img.Factory(
                img,
                afwGeom.Box2I(afwGeom.Point2I(0, y), afwGeom.Extent2I(img.getWidth(), 1)),
                afwImage.LOCAL)
            simg.set(y)

        imgList.push_back(img)

        imgStack = afwMath.statisticsStack(imgList, afwMath.MEAN)

        if display:
            ds9.mtv(img, frame=1, title="input")
            ds9.mtv(imgStack, frame=2, title="stack")

        self.assertEqual(img.get(0, 0)[0], imgStack.get(0, 0)[0])
예제 #49
0
    def testReturnInputs(self):
        """ Make sure that a single file put into the stacker is returned unscathed"""

        imgList = []

        img = afwImage.MaskedImageF(lsst.geom.Extent2I(10, 20))
        for y in range(img.getHeight()):
            simg = img.Factory(
                img,
                lsst.geom.Box2I(lsst.geom.Point2I(0, y),
                                lsst.geom.Extent2I(img.getWidth(), 1)),
                afwImage.LOCAL)
            simg.set(y)

        imgList.append(img)

        imgStack = afwMath.statisticsStack(imgList, afwMath.MEAN)

        if display:
            afwDisplay.Display(frame=1).mtv(img, title="input")
            afwDisplay.Display(frame=2).mtv(imgStack, title="stack")

        self.assertEqual(img[0, 0, afwImage.LOCAL][0], imgStack[0, 0, afwImage.LOCAL][0])
예제 #50
0
                    if self.config.doMatchBackgrounds and not backgroundInfoList[idx].isReference:
                        backgroundModel = backgroundInfoList[idx].backgroundModel
                        backgroundImage = backgroundModel.getImage() if \
                            self.matchBackgrounds.config.usePolynomial else \
                            backgroundModel.getImageF()
                        backgroundImage.setXY0(coaddMaskedImage.getXY0())
                        maskedImage += backgroundImage.Factory(backgroundImage, subBBox,
                                                               afwImage.PARENT, False)

                        var = maskedImage.getVariance()
                        var += (backgroundInfoList[idx].fitRMS)**2
                        
                    maskedImageList.append(maskedImage)

                with self.timer("stack"):
                    coaddSubregion = afwMath.statisticsStack(
                        maskedImageList, statsFlags, statsCtrl, weightList)

                coaddView <<= coaddSubregion
            except Exception, e:
                self.log.fatal("Cannot compute coadd %s: %s" % (subBBox, e,))

        if self.config.doMatchBackgrounds:
            self.log.info("Adding exposure information to metadata")
            metadata = coaddExposure.getMetadata()
            metadata.addString("CTExp_SDQA1_DESCRIPTION",
                               "Background matching: Ratio of matchedMSE / diffImVar")
            for ind, (tempExpRef, backgroundInfo) in enumerate(zip(tempExpRefList, backgroundInfoList)):
                tempExpStr = '&'.join('%s=%s' % (k,v) for k,v in tempExpRef.dataId.items())
                if backgroundInfo.isReference:
                    metadata.addString("ReferenceExp_ID", tempExpStr)
                else:
예제 #51
0
파일: stacker.py 프로젝트: rbiswas4/afw
 def tst():
     imgStackBad = afwMath.statisticsStack(imgList, afwMath.MEAN | afwMath.MEANCLIP, sctrl)
예제 #52
0
파일: stacker.py 프로젝트: rbiswas4/afw
    def testStackBadPixels(self):
        """Check that we properly ignore masked pixels, and set noGoodPixelsMask where there are
        no good pixels"""
        mimgVec = afwImage.vectorMaskedImageF()

        DETECTED = afwImage.MaskU_getPlaneBitMask("DETECTED")
        EDGE =  afwImage.MaskU_getPlaneBitMask("EDGE")
        INTRP = afwImage.MaskU_getPlaneBitMask("INTRP")
        SAT = afwImage.MaskU_getPlaneBitMask("SAT")

        sctrl = afwMath.StatisticsControl()
        sctrl.setNanSafe(False)
        sctrl.setAndMask(INTRP | SAT)
        sctrl.setNoGoodPixelsMask(EDGE)

        edgeBBox = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(20, 20)) # set these pixels to EDGE
        width, height = 512, 512
	dim=afwGeom.Extent2I(width, height)
        val, maskVal = 10, DETECTED
        for i in range(4):
            mimg = afwImage.MaskedImageF(dim)
            mimg.set(val, maskVal, 1)
            #
            # Set part of the image to NaN (with the INTRP bit set)
            #
            llc = afwGeom.Point2I(width//2*(i//2), height//2*(i%2))
            bbox = afwGeom.Box2I(llc, dim//2)

            smimg = mimg.Factory(mimg, bbox, afwImage.LOCAL)
            #smimg.set(numpy.nan, INTRP, numpy.nan)
            del smimg
            #
            # And the bottom corner to SAT
            #
            smask = mimg.getMask().Factory(mimg.getMask(), edgeBBox, afwImage.LOCAL)
            smask |= SAT
            del smask

            mimgVec.push_back(mimg)

            if display > 1:
                ds9.mtv(mimg, frame=i, title=str(i))

        mimgStack = afwMath.statisticsStack(mimgVec, afwMath.MEAN, sctrl)

        if display:
            i += 1
            ds9.mtv(mimgStack, frame=i, title="Stack")
            i += 1
            ds9.mtv(mimgStack.getVariance(), frame=i, title="var(Stack)")
        #
        # Check the output, ignoring EDGE pixels
        #
        sctrl = afwMath.StatisticsControl()
        sctrl.setAndMask(afwImage.MaskU_getPlaneBitMask("EDGE"))

        stats = afwMath.makeStatistics(mimgStack, afwMath.MIN | afwMath.MAX, sctrl)
        self.assertEqual(stats.getValue(afwMath.MIN), val)
        self.assertEqual(stats.getValue(afwMath.MAX), val)
        #
        # We have to clear EDGE in the known bad corner to check the mask
        #
        smask = mimgStack.getMask().Factory(mimgStack.getMask(), edgeBBox, afwImage.LOCAL)
        self.assertEqual(smask.get(edgeBBox.getMinX(), edgeBBox.getMinY()), EDGE)
        smask &= ~EDGE
        del smask

        self.assertEqual(afwMath.makeStatistics(mimgStack.getMask(), afwMath.SUM, sctrl).getValue(), maskVal)
예제 #53
0
    def run(self, exposure, sensorRef, templateIdList=None):
        """Retrieve and mosaic a template coadd that overlaps the exposure where
        the template spans multiple tracts.

        The resulting template image will be an average of all the input templates from
        the separate tracts.

        The PSF on the template is created by combining the CoaddPsf on each template image
        into a meta-CoaddPsf.

        Parameters
        ----------
        exposure: `lsst.afw.image.Exposure`
            an exposure for which to generate an overlapping template
        sensorRef : TYPE
            a Butler data reference that can be used to obtain coadd data
        templateIdList : TYPE, optional
            list of data ids (unused)
        Returns
        -------
        result : `struct`
            return a pipeBase.Struct:
            - ``exposure`` : a template coadd exposure assembled out of patches
            - ``sources`` :  None for this subtask
        """

        # Table for CoaddPSF
        tractsSchema = afwTable.ExposureTable.makeMinimalSchema()
        tractKey = tractsSchema.addField('tract',
                                         type=np.int32,
                                         doc='Which tract')
        patchKey = tractsSchema.addField('patch',
                                         type=np.int32,
                                         doc='Which patch')
        weightKey = tractsSchema.addField(
            'weight', type=float, doc='Weight for each tract, should be 1')
        tractsCatalog = afwTable.ExposureCatalog(tractsSchema)

        skyMap = sensorRef.get(datasetType=self.config.coaddName +
                               "Coadd_skyMap")
        expWcs = exposure.getWcs()
        expBoxD = geom.Box2D(exposure.getBBox())
        expBoxD.grow(self.config.templateBorderSize)
        ctrSkyPos = expWcs.pixelToSky(expBoxD.getCenter())

        centralTractInfo = skyMap.findTract(ctrSkyPos)
        if not centralTractInfo:
            raise RuntimeError("No suitable tract found for central point")

        self.log.info("Central skyMap tract %s" % (centralTractInfo.getId(), ))

        skyCorners = [
            expWcs.pixelToSky(pixPos) for pixPos in expBoxD.getCorners()
        ]
        tractPatchList = skyMap.findTractPatchList(skyCorners)
        if not tractPatchList:
            raise RuntimeError("No suitable tract found")

        self.log.info("All overlapping skyMap tracts %s" %
                      ([a[0].getId() for a in tractPatchList]))

        # Move central tract to front of the list and use as the reference
        tracts = [tract[0].getId() for tract in tractPatchList]
        centralIndex = tracts.index(centralTractInfo.getId())
        tracts.insert(0, tracts.pop(centralIndex))
        tractPatchList.insert(0, tractPatchList.pop(centralIndex))

        coaddPsf = None
        coaddFilter = None
        nPatchesFound = 0

        maskedImageList = []
        weightList = []

        for itract, tract in enumerate(tracts):
            tractInfo = tractPatchList[itract][0]

            coaddWcs = tractInfo.getWcs()
            coaddBBox = geom.Box2D()
            for skyPos in skyCorners:
                coaddBBox.include(coaddWcs.skyToPixel(skyPos))
            coaddBBox = geom.Box2I(coaddBBox)

            if itract == 0:
                # Define final wcs and bounding box from the reference tract
                finalWcs = coaddWcs
                finalBBox = coaddBBox

            patchList = tractPatchList[itract][1]
            for patchInfo in patchList:
                self.log.info('Adding patch %s from tract %s' %
                              (patchInfo.getIndex(), tract))

                # Local patch information
                patchSubBBox = geom.Box2I(patchInfo.getInnerBBox())
                patchSubBBox.clip(coaddBBox)
                patchInt = int(
                    f"{patchInfo.getIndex()[0]}{patchInfo.getIndex()[1]}")
                innerBBox = geom.Box2I(tractInfo._minimumBoundingBox(finalWcs))

                if itract == 0:
                    # clip to image and tract boundaries
                    patchSubBBox.clip(finalBBox)
                    patchSubBBox.clip(innerBBox)
                    if patchSubBBox.getArea() == 0:
                        self.log.debug("No ovlerap for patch %s" % patchInfo)
                        continue

                    patchArgDict = dict(
                        datasetType="deepCoadd_sub",
                        bbox=patchSubBBox,
                        tract=tractInfo.getId(),
                        patch="%s,%s" %
                        (patchInfo.getIndex()[0], patchInfo.getIndex()[1]),
                        filter=exposure.getFilter().getName())
                    coaddPatch = sensorRef.get(**patchArgDict)
                    if coaddFilter is None:
                        coaddFilter = coaddPatch.getFilter()

                    # create full image from final bounding box
                    exp = afwImage.ExposureF(finalBBox, finalWcs)
                    exp.maskedImage.set(
                        np.nan, afwImage.Mask.getPlaneBitMask("NO_DATA"),
                        np.nan)
                    exp.maskedImage.assign(coaddPatch.maskedImage,
                                           patchSubBBox)

                    maskedImageList.append(exp.maskedImage)
                    weightList.append(1)

                    record = tractsCatalog.addNew()
                    record.setPsf(coaddPatch.getPsf())
                    record.setWcs(coaddPatch.getWcs())
                    record.setPhotoCalib(coaddPatch.getPhotoCalib())
                    record.setBBox(patchSubBBox)
                    record.set(tractKey, tract)
                    record.set(patchKey, patchInt)
                    record.set(weightKey, 1.)
                    nPatchesFound += 1
                else:
                    # compute the exposure bounding box in a tract that is not the reference tract
                    localBox = geom.Box2I()
                    for skyPos in skyCorners:
                        localBox.include(
                            geom.Point2I(
                                tractInfo.getWcs().skyToPixel(skyPos)))

                    # clip to patch bounding box
                    localBox.clip(patchSubBBox)

                    # grow border to deal with warping at edges
                    localBox.grow(self.config.templateBorderSize)

                    # clip to tract inner bounding box
                    localInnerBBox = geom.Box2I(
                        tractInfo._minimumBoundingBox(tractInfo.getWcs()))
                    localBox.clip(localInnerBBox)

                    patchArgDict = dict(
                        datasetType="deepCoadd_sub",
                        bbox=localBox,
                        tract=tractInfo.getId(),
                        patch="%s,%s" %
                        (patchInfo.getIndex()[0], patchInfo.getIndex()[1]),
                        filter=exposure.getFilter().getName())
                    coaddPatch = sensorRef.get(**patchArgDict)

                    # warp to reference tract wcs
                    xyTransform = afwGeom.makeWcsPairTransform(
                        coaddPatch.getWcs(), finalWcs)
                    psfWarped = WarpedPsf(coaddPatch.getPsf(), xyTransform)
                    warped = self.warper.warpExposure(finalWcs,
                                                      coaddPatch,
                                                      maxBBox=finalBBox)

                    # check if warpped image is viable
                    if warped.getBBox().getArea() == 0:
                        self.log.info(
                            "No ovlerap for warped patch %s. Skipping" %
                            patchInfo)
                        continue

                    warped.setPsf(psfWarped)

                    exp = afwImage.ExposureF(finalBBox, finalWcs)
                    exp.maskedImage.set(
                        np.nan, afwImage.Mask.getPlaneBitMask("NO_DATA"),
                        np.nan)
                    exp.maskedImage.assign(warped.maskedImage,
                                           warped.getBBox())

                    maskedImageList.append(exp.maskedImage)
                    weightList.append(1)
                    record = tractsCatalog.addNew()
                    record.setPsf(psfWarped)
                    record.setWcs(finalWcs)
                    record.setPhotoCalib(coaddPatch.getPhotoCalib())
                    record.setBBox(warped.getBBox())
                    record.set(tractKey, tract)
                    record.set(patchKey, patchInt)
                    record.set(weightKey, 1.)
                    nPatchesFound += 1

        if nPatchesFound == 0:
            raise RuntimeError("No patches found!")

        # Combine images from individual patches together

        # Do not mask any values
        statsFlags = afwMath.stringToStatisticsProperty(self.config.statistic)
        maskMap = []
        statsCtrl = afwMath.StatisticsControl()
        statsCtrl.setNanSafe(True)
        statsCtrl.setWeighted(True)
        statsCtrl.setCalcErrorFromInputVariance(True)

        coaddExposure = afwImage.ExposureF(finalBBox, finalWcs)
        coaddExposure.maskedImage.set(np.nan,
                                      afwImage.Mask.getPlaneBitMask("NO_DATA"),
                                      np.nan)
        xy0 = coaddExposure.getXY0()
        coaddExposure.maskedImage = afwMath.statisticsStack(
            maskedImageList, statsFlags, statsCtrl, weightList, 0, maskMap)
        coaddExposure.maskedImage.setXY0(xy0)

        coaddPsf = CoaddPsf(tractsCatalog, finalWcs,
                            self.config.coaddPsf.makeControl())
        if coaddPsf is None:
            raise RuntimeError("No coadd Psf found!")

        coaddExposure.setPsf(coaddPsf)
        coaddExposure.setFilter(coaddFilter)
        return pipeBase.Struct(exposure=coaddExposure, sources=None)
예제 #54
0
 def tst():
     afwMath.statisticsStack(
         imgList,
         afwMath.Property(afwMath.MEAN | afwMath.MEANCLIP),
         sctrl)