示例#1
0
    def testReadFitsConform(self):
        if not self.maskFile:
            print >> sys.stderr, "Warning: afwdata is not set up; not running the FITS I/O tests"
            return

        hdu = 3
        mask = afwImage.MaskU(self.maskFile, hdu, None, afwGeom.Box2I(),
                              afwImage.LOCAL, True)

        if False:
            import lsst.afw.display.ds9 as ds9
            ds9.mtv(mask)

        self.assertEqual(mask.get(32, 1), 0)
        self.assertEqual(mask.get(50, 50), 0)
        self.assertEqual(mask.get(0, 0), 1)
示例#2
0
    def testImageTypes(self):
        """Check that we can display a range of types of image"""
        with afwDisplay.getDisplay("dummy", "virtualDevice") as dummy:
            for imageType in [
                    afwImage.DecoratedImageF,
                    afwImage.ExposureF,
                    afwImage.ImageU,
                    afwImage.ImageI,
                    afwImage.ImageF,
                    afwImage.MaskedImageF,
            ]:
                im = imageType(self.fileName)
                dummy.mtv(im)

            im = afwImage.MaskU(self.fileName, 3)
            dummy.mtv(im)
示例#3
0
    def testMask(self):
        mask = afwImage.MaskU(afwGeom.Extent2I(10, 10))
        mask.set(0x0)

        mask.set(1, 1, 0x10)
        mask.set(3, 1, 0x08)
        mask.set(5, 4, 0x08)
        mask.set(4, 5, 0x02)

        stats = afwMath.makeStatistics(mask, afwMath.SUM | afwMath.NPOINT)
        self.assertEqual(mask.getWidth()*mask.getHeight(), stats.getValue(afwMath.NPOINT))
        self.assertEqual(0x1a, stats.getValue(afwMath.SUM))

        def tst():
            stats = afwMath.makeStatistics(mask, afwMath.MEAN)
        self.assertRaises(lsst.pex.exceptions.InvalidParameterError, tst)
示例#4
0
    def setUp(self):
        # Set a (non-standard) initial Mask plane definition
        #
        # Ideally we'd use the standard dictionary and a non-standard file, but
        # a standard file's what we have
        #
        mask = afwImage.MaskU()

        mask.clearMaskPlaneDict()
        for p in ("ZERO", "BAD", "SAT", "INTRP", "CR", "EDGE"):
            mask.addMaskPlane(p)

        if False:
            self.fileName = os.path.join(dataDir, "Small_MI.fits")
        else:
            self.fileName = os.path.join(dataDir, "CFHT", "D4", "cal-53535-i-797722_1.fits")
        self.mi = afwImage.MaskedImageF(self.fileName)
示例#5
0
class ProcessFileConfig(pexConfig.Config):
    """A container for the Configs that ProcessFile needs

Using such a container allows us to use the standard -c/-C/--show config options that pipe_base provides
"""
    variance = pexConfig.Field(
        dtype=float,
        default=np.nan,
        doc="Initial per-pixel variance (if <= 0, estimate from inputs)")
    badPixelValue = pexConfig.Field(dtype=float,
                                    default=np.nan,
                                    doc="Value indicating a bad pixel")
    interpPlanes = pexConfig.ListField(
        dtype=str,
        default=[
            "BAD",
        ],
        doc="Names of mask planes to interpolate over (e.g. ['BAD', 'SAT'])",
        itemCheck=lambda x: x in afwImage.MaskU().getMaskPlaneDict().keys())

    isr = MyIsrConfig()

    doCalibrate = pexConfig.Field(dtype=bool,
                                  default=True,
                                  doc="Calibrate input data?")
    charImage = pexConfig.ConfigField(
        dtype=CharacterizeImageTask.ConfigClass,
        doc=CharacterizeImageTask.ConfigClass.__doc__)

    detection = pexConfig.ConfigField(
        dtype=SourceDetectionTask.ConfigClass,
        doc=SourceDetectionTask.ConfigClass.__doc__)
    detection.returnOriginalFootprints = False

    measurement = pexConfig.ConfigField(
        dtype=SingleFrameMeasurementTask.ConfigClass,
        doc=SingleFrameMeasurementTask.ConfigClass.__doc__)

    doDeblend = pexConfig.Field(dtype=bool,
                                default=True,
                                doc="Deblend sources?")
    if SourceDeblendTask:
        deblend = pexConfig.ConfigField(
            dtype=SourceDeblendTask.ConfigClass,
            doc=SourceDeblendTask.ConfigClass.__doc__)
示例#6
0
    def testIntersectMask(self):
        bbox = afwGeom.BoxI(afwGeom.PointI(0,0), afwGeom.ExtentI(10))
        fp = afwDetect.Footprint(bbox)
        maskBBox = afwGeom.BoxI(bbox)
        maskBBox.grow(-2)
        mask = afwImage.MaskU(maskBBox)
        innerBBox = afwGeom.BoxI(maskBBox)
        innerBBox.grow(-2)
        subMask = mask.Factory(mask, innerBBox)
        subMask.set(1)

        fp.intersectMask(mask)
        fpBBox = fp.getBBox()
        self.assertEqual(fpBBox.getMinX(), maskBBox.getMinX())
        self.assertEqual(fpBBox.getMinY(), maskBBox.getMinY())
        self.assertEqual(fpBBox.getMaxX(), maskBBox.getMaxX())
        self.assertEqual(fpBBox.getMaxY(), maskBBox.getMaxY())

        self.assertEqual(fp.getArea(), maskBBox.getArea() - innerBBox.getArea())
示例#7
0
 def translate_dqmask(self, dqmask):
     # TODO: make a class member variable that knows the mappings
     # below instead of hard-coding them
     dqmArr = dqmask.getArray()
     mask = afwImage.MaskU(dqmask.getDimensions())
     mArr = mask.getArray()
     idxBad = np.where(dqmArr & 1)
     idxSat = np.where(dqmArr & 2)
     idxIntrp = np.where(dqmArr & 4)
     idxCr = np.where(dqmArr & 16)
     idxBleed = np.where(dqmArr & 64)
     idxEdge = np.where(dqmArr & 512)
     mArr[idxBad] |= mask.getPlaneBitMask("BAD")
     mArr[idxSat] |= mask.getPlaneBitMask("SAT")
     mArr[idxIntrp] |= mask.getPlaneBitMask("INTRP")
     mArr[idxCr] |= mask.getPlaneBitMask("CR")
     mArr[idxBleed] |= mask.getPlaneBitMask("SAT")
     mArr[idxEdge] |= mask.getPlaneBitMask("EDGE")
     return mask
示例#8
0
    def readFits(fileName, hdu=0, flags=0):
        """Read a our list of Backgrounds from a file
        @param fileName         FITS file to read
        @param hdu              First Header/Data Unit to attempt to read from
        @param flags            Flags to control details of reading; currently unused,
                                but present for consistency with
                                afw.table.BaseCatalog.readFits.

        See also getImage()
        """
        if not isinstance(fileName, MemFileManager) and not os.path.exists(fileName):
            raise RuntimeError("File not found: %s" % fileName)

        self = BackgroundList()

        while True:
            hdu += 1

            md = dafBase.PropertyList()
            try:
                img = afwImage.ImageF(fileName, hdu, md); hdu += 1
            except FitsError as e:
                break

            msk = afwImage.MaskU( fileName, hdu);     hdu += 1
            var = afwImage.ImageF(fileName, hdu)

            statsImage = afwImage.makeMaskedImage(img, msk, var)

            x0 = md.get("BKGD_X0")
            y0 = md.get("BKGD_Y0")
            width  = md.get("BKGD_WIDTH")
            height = md.get("BKGD_HEIGHT")
            imageBBox = afwGeom.BoxI(afwGeom.PointI(x0, y0), afwGeom.ExtentI(width, height))

            interpStyle =      md.get("INTERPSTYLE")
            undersampleStyle = md.get("UNDERSAMPLESTYLE")

            bkgd = afwMath.BackgroundMI(imageBBox, statsImage)
            self.append((bkgd, interpStyle, undersampleStyle,))

        return self
示例#9
0
    def testMaskedImageFromImage(self):
        w, h = 10, 20
        dims = afwGeom.Extent2I(w, h)
        im, mask, var = afwImage.ImageF(dims), afwImage.MaskU(
            dims), afwImage.ImageF(dims)
        im.set(666)

        maskedImage = afwImage.MaskedImageF(im, mask, var)

        maskedImage = afwImage.makeMaskedImage(im, mask, var)

        maskedImage = afwImage.MaskedImageF(im)
        self.assertEqual(im.getDimensions(),
                         maskedImage.getImage().getDimensions())
        self.assertEqual(im.getDimensions(),
                         maskedImage.getMask().getDimensions())
        self.assertEqual(im.getDimensions(),
                         maskedImage.getVariance().getDimensions())

        self.assertEqual(maskedImage.get(0, 0), (im.get(0, 0), 0x0, 0.0))
示例#10
0
    def makeExposure(self, im, mask=None, variance=None):
        """Method for constructing an exposure object from an image and the information contained in this
           class to construct the Detector and Calib objects.
           @param[in]  im        Image used to construct the exposure
           @param[in]  mask      Optional mask plane as a <askU
           @param[in]  variance  Optional variance plance as an image of the same type as im
           @param[out] Exposure object
        """
        if mask is None:
            mask = afwImage.MaskU(im.getDimensions())
        if variance is None:
            variance = im
        mi = afwImage.makeMaskedImage(im, mask, variance)
        detector = self.buildDetector()

        wcs = afwImage.makeWcs(self.detectorMetadata)
        calib = self.makeCalib()
        exp = afwImage.makeExposure(mi, wcs)
        exp.setCalib(calib)
        exp.setDetector(detector)
        return exp
示例#11
0
文件: mask.py 项目: ziggyman/afw_old
    def testImageSlices(self):
        """Test image slicing, which generate sub-images using Box2I under the covers"""
        im = afwImage.MaskU(10, 20)
        im[-3:, -2:] = 0x4
        im[4, 10] = 0x2
        sim = im[1:4, 6:10]
        sim[:] = 0x8
        im[0:4, 0:4] = im[2:6, 8:12]

        if display:
            ds9.mtv(im)

        self.assertEqual(im.get(0, 6), 0)
        self.assertEqual(im.get(6, 17), 0)
        self.assertEqual(im.get(7, 18), 0x4)
        self.assertEqual(im.get(9, 19), 0x4)
        self.assertEqual(im.get(1, 6), 0x8)
        self.assertEqual(im.get(3, 9), 0x8)
        self.assertEqual(im.get(4, 10), 0x2)
        self.assertEqual(im.get(4, 9), 0)
        self.assertEqual(im.get(2, 2), 0x2)
        self.assertEqual(im.get(0, 0), 0x8)
    def setUp(self):
        im = afwImage.ImageF(self.monetFile("small.fits"))
        self.mi = afwImage.MaskedImageF(im, afwImage.MaskU(im.getDimensions()),
                                        afwImage.ImageF(im.getDimensions()))
        self.ds = afwDetection.FootprintSet(self.mi,
                                            afwDetection.Threshold(100))

        if display:
            ds9.mtv(self.mi.getImage())
            ds9.erase()

        for foot in self.ds.getFootprints():
            bbox = foot.getBBox()
            x0, y0 = bbox.getMinX(), bbox.getMinY()
            x1, y1 = bbox.getMaxX(), bbox.getMaxY()
            xc = (x0 + x1) / 2.0
            yc = (y0 + y1) / 2.0

            if display:
                ds9.dot("+", xc, yc, ctype=ds9.BLUE)

                if False:
                    x0 -= 0.5
                    y0 -= 0.5
                    x1 += 0.5
                    y1 += 0.5

                    ds9.line([(x0, y0), (x1, y0), (x1, y1), (x0, y1),
                              (x0, y0)],
                             ctype=ds9.RED)

        self.control = algorithms.GaussianCentroidControl()
        schema = afwTable.SourceTable.makeMinimalSchema()
        self.centroider = algorithms.MeasureSourcesBuilder().addAlgorithm(
            self.control).build(schema)
        self.ssMeasured = afwTable.SourceCatalog(schema)
        self.ssMeasured.table.defineCentroid(self.control.name)
        self.ssTruth = afwTable.SourceCatalog(schema)
        self.readTruth(self.monetFile("positions.dat-original"))
basedir = os.path.join(rootdir, basename)
if not os.path.isdir(basedir):
    os.mkdir(basedir)

maskFormat = re.compile('^\[(\d+):(\d+),(\d+):(\d+)\]$')

ptr = pyfits.open(infile)
for i in range(1, 37):
    #raftdir  = os.path.join(basedir, str(i))
    #if not os.path.isdir(raftdir):
    #    os.mkdir(raftdir)

    ccdHeader = ptr[i].header
    nColMask = ccdHeader['NAXIS1']
    nRowMask = ccdHeader['NAXIS2']
    mask = afwImage.MaskU(nColMask, nRowMask)
    mask.set(0)

    bitmask = mask.getPlaneBitMask('BAD')
    for card in ccdHeader.ascardlist().keys():
        if card.startswith('MASK_'):
            datasec = ccdHeader[card]

            # Unfortunately, the format of the masks is wrong.  Its
            # x0,y0  x1,y1
            # e.g.
            # MASK_000= '[1:1,2112:1]'       / Bad pixels area definition
            #
            # Datasecs normally have
            # x0,x1  y0,y1
            # e.g.
    def getClumps(self, sigma=1.0, display=False):
        if self._num <= 0:
            raise RuntimeError("No candidate PSF sources")

        psfImage = self.getImage()
        #
        # Embed psfImage into a larger image so we can smooth when measuring it
        #
        width, height = psfImage.getWidth(), psfImage.getHeight()
        largeImg = psfImage.Factory(afwGeom.ExtentI(2 * width, 2 * height))
        largeImg.set(0)

        bbox = afwGeom.BoxI(afwGeom.PointI(width, height),
                            afwGeom.ExtentI(width, height))
        largeImg.assign(psfImage, bbox, afwImage.LOCAL)
        #
        # Now measure that image, looking for the highest peak.  Start by building an Exposure
        #
        msk = afwImage.MaskU(largeImg.getDimensions())
        msk.set(0)
        var = afwImage.ImageF(largeImg.getDimensions())
        var.set(1)
        mpsfImage = afwImage.MaskedImageF(largeImg, msk, var)
        mpsfImage.setXY0(afwGeom.PointI(-width, -height))
        del msk
        del var
        exposure = afwImage.makeExposure(mpsfImage)

        #
        # Next run an object detector
        #
        maxVal = afwMath.makeStatistics(psfImage, afwMath.MAX).getValue()
        threshold = maxVal - sigma * math.sqrt(maxVal)
        if threshold <= 0.0:
            threshold = maxVal

        threshold = afwDetection.Threshold(threshold)

        ds = afwDetection.FootprintSet(mpsfImage, threshold, "DETECTED")
        #
        # And measure it.  This policy isn't the one we use to measure
        # Sources, it's only used to characterize this PSF histogram
        #
        schema = SourceTable.makeMinimalSchema()
        psfImageConfig = SingleFrameMeasurementConfig()
        psfImageConfig.slots.centroid = "base_SdssCentroid"
        psfImageConfig.plugins["base_SdssCentroid"].doFootprintCheck = False
        psfImageConfig.slots.psfFlux = None  # "base_PsfFlux"
        psfImageConfig.slots.apFlux = "base_CircularApertureFlux_3_0"
        psfImageConfig.slots.modelFlux = None
        psfImageConfig.slots.instFlux = None
        psfImageConfig.slots.calibFlux = None
        psfImageConfig.slots.shape = "base_SdssShape"
        #   Formerly, this code had centroid.sdss, flux.psf, flux.naive,
        #   flags.pixel, and shape.sdss
        psfImageConfig.algorithms.names = [
            "base_SdssCentroid", "base_CircularApertureFlux", "base_SdssShape"
        ]
        psfImageConfig.algorithms["base_CircularApertureFlux"].radii = [3.0]
        psfImageConfig.validate()
        task = SingleFrameMeasurementTask(schema, config=psfImageConfig)

        sourceCat = SourceCatalog(schema)

        gaussianWidth = 1.5  # Gaussian sigma for detection convolution
        exposure.setPsf(algorithmsLib.DoubleGaussianPsf(11, 11, gaussianWidth))

        ds.makeSources(sourceCat)
        #
        # Show us the Histogram
        #
        if display:
            frame = 1
            dispImage = mpsfImage.Factory(
                mpsfImage,
                afwGeom.BoxI(afwGeom.PointI(width, height),
                             afwGeom.ExtentI(width, height)), afwImage.LOCAL)
            ds9.mtv(dispImage, title="PSF Selection Image", frame=frame)

        clumps = list()  # List of clumps, to return
        e = None  # thrown exception
        IzzMin = 1.0  # Minimum value for second moments
        IzzMax = (
            self._xSize /
            8.0)**2  # Max value ... clump radius should be < clumpImgSize/8
        apFluxes = []
        task.run(
            sourceCat,
            exposure)  # notes that this is backwards for the new framework
        for i, source in enumerate(sourceCat):
            if source.getCentroidFlag():
                continue
            x, y = source.getX(), source.getY()

            apFluxes.append(source.getApFlux())

            val = mpsfImage.getImage().get(int(x) + width, int(y) + height)

            psfClumpIxx = source.getIxx()
            psfClumpIxy = source.getIxy()
            psfClumpIyy = source.getIyy()

            if display:
                if i == 0:
                    ds9.pan(x, y, frame=frame)

                ds9.dot("+", x, y, ctype=ds9.YELLOW, frame=frame)
                ds9.dot("@:%g,%g,%g" % (psfClumpIxx, psfClumpIxy, psfClumpIyy),
                        x,
                        y,
                        ctype=ds9.YELLOW,
                        frame=frame)

            if psfClumpIxx < IzzMin or psfClumpIyy < IzzMin:
                psfClumpIxx = max(psfClumpIxx, IzzMin)
                psfClumpIyy = max(psfClumpIyy, IzzMin)
                if display:
                    ds9.dot("@:%g,%g,%g" %
                            (psfClumpIxx, psfClumpIxy, psfClumpIyy),
                            x,
                            y,
                            ctype=ds9.RED,
                            frame=frame)

            det = psfClumpIxx * psfClumpIyy - psfClumpIxy * psfClumpIxy
            try:
                a, b, c = psfClumpIyy / det, -psfClumpIxy / det, psfClumpIxx / det
            except ZeroDivisionError:
                a, b, c = 1e4, 0, 1e4

            clumps.append(
                Clump(peak=val,
                      x=x,
                      y=y,
                      a=a,
                      b=b,
                      c=c,
                      ixx=psfClumpIxx,
                      ixy=psfClumpIxy,
                      iyy=psfClumpIyy))

        if len(clumps) == 0:
            msg = "Failed to determine center of PSF clump"
            if e:
                msg += ": %s" % e
            raise RuntimeError(msg)

        # if it's all we got return it
        if len(clumps) == 1:
            return clumps

        # which clump is the best?
        # if we've undistorted the moments, stars should only have 1 clump
        # use the apFlux from the clump measurement, and take the highest
        # ... this clump has more psf star candidate neighbours than the others.

        # get rid of any that are huge, and thus poorly defined
        goodClumps = []
        for clump in clumps:
            if clump.ixx < IzzMax and clump.iyy < IzzMax:
                goodClumps.append(clump)

        # if culling > IzzMax cost us all clumps, we'll have to take what we have
        if len(goodClumps) == 0:
            goodClumps = clumps

        # use the 'brightest' clump
        iBestClump = numpy.argsort(apFluxes)[0]
        clumps = [clumps[iBestClump]]
        return clumps
示例#15
0
 def testMask(self):
     """Test that we can flip a Mask"""
     mask = afwImage.MaskU(10, 20)
     afwMath.flipImage(
         mask, True,
         False)  # for a while, swig couldn't handle the resulting Mask::Ptr
示例#16
0
class MaskedCCDTestCase(unittest.TestCase):
    gain = 1
    exptime = 1
    signal = 1
    xmin, xmax = 200, 250
    ymin, ymax = 1000, 1050
    mask_image = 'mask_image.fits'
    mpd = dict(afwImage.MaskU().getMaskPlaneDict().items())

    @classmethod
    def setUpClass(cls):
        ccd = sim_tools.CCD(exptime=cls.exptime, gain=cls.gain)
        for amp in ccd.segments:
            imarr = ccd.segments[amp].image.getArray()
            imarr[cls.ymin:cls.ymax, cls.xmin:cls.xmax] += cls.signal
        ccd.writeto(cls.mask_image)
        cls.mask_files = []
        for mask_plane, bit in cls.mpd.items():
            mask_file = 'mask_file_%s.fits' % mask_plane
            cls.mask_files.append(mask_file)
            masked_ccd = MaskedCCD(cls.mask_image)
            pixels, columns = {}, {}
            for amp in masked_ccd:
                bp = BrightPixels(masked_ccd,
                                  amp,
                                  cls.exptime,
                                  cls.gain,
                                  mask_plane=mask_plane,
                                  ethresh=cls.signal / 2.)
                pixels[amp], columns[amp] = bp.find()
            generate_mask(cls.mask_image,
                          mask_file,
                          mask_plane,
                          pixels=pixels,
                          columns=columns)
        cls.summed_mask_file = 'summed_mask_file.fits'
        add_mask_files(cls.mask_files, cls.summed_mask_file)

    @classmethod
    def tearDownClass(cls):
        os.remove(cls.mask_image)
        for mask_file in cls.mask_files:
            os.remove(mask_file)
        os.remove(cls.summed_mask_file)
#    @unittest.skip('skip test_add_masks')

    def test_add_masks(self):
        ccd = MaskedCCD(self.mask_image)
        ccd.add_masks(self.summed_mask_file)
        total_signal = (self.signal * (self.ymax - self.ymin) *
                        (self.xmax - self.xmin))
        ny, nx = ccd[ccd.keys()[0]].getImage().getArray().shape
        for amp in ccd:
            self.assertEqual(sum(ccd[amp].getImage().getArray().flat),
                             total_signal)
        stat_ctrl = ccd.setMask('BAD')
        for amp in ccd:
            stats = afwMath.makeStatistics(ccd[amp], afwMath.MEAN, stat_ctrl)
            self.assertEqual(0, stats.getValue(afwMath.MEAN))
        stat_ctrl = ccd.setMask(clear=True)
        for amp in ccd:
            stats = afwMath.makeStatistics(ccd[amp], afwMath.MEAN, stat_ctrl)
            self.assertAlmostEqual(float(total_signal) / (nx * ny),
                                   stats.getValue(afwMath.MEAN),
                                   places=10)


#    @unittest.skip('skip test_setMask')

    def test_setMask(self):
        ccd = MaskedCCD(self.mask_image)
        for mp, bit in self.mpd.items():
            sctrl = ccd.setMask(mask_name=mp, clear=True)
            self.assertEqual(sctrl.getAndMask(), 2**bit)
示例#17
0
    subim = afwImage.ImageF(im, box, afwImage.LOCAL)

try:
    subim += psf_im
except NotImplementedError:
    psf_im = psf_im.convertF()
    subim += psf_im

print(" subim = ", subim)

back_im = afwImage.ImageF(im.getBBox())
afwMath.randomPoissonImage(back_im, rand, 100)
im += back_im
display.mtv(im)
display.incrDefaultFrame()
mask = afwImage.MaskU(im.getBBox())
masked_im = afwImage.MaskedImageF(im, mask, im)

sys.exit()

threshold = afwDetect.createThreshold(5., 'stdev')
fs = afwDetect.FootprintSet(masked_im, threshold, 'DETECTED')
#display.mtv(masked_im)
#display.incrDefaultFrame()

bctrl = afwMath.BackgroundControl(11, 11)
bkgd = afwMath.makeBackground(masked_im, bctrl)
masked_im -= bkgd.getImageF()
masked_im.getMask().set(0)  # reset mask
fs = afwDetect.FootprintSet(masked_im, threshold, 'DETECTED')
#display.mtv(masked_im)
示例#18
0
class BackgroundConfig(pexConfig.Config):
    statisticsProperty = pexConfig.ChoiceField(
        doc="type of statistic to use for grid points",
        dtype=str,
        default="MEANCLIP",
        allowed={
            "MEANCLIP": "clipped mean",
            "MEAN": "unclipped mean",
            "MEDIAN": "median",
        })
    undersampleStyle = pexConfig.ChoiceField(
        doc=
        "behaviour if there are too few points in grid for requested interpolation style",
        dtype=str,
        default="REDUCE_INTERP_ORDER",
        allowed={
            "THROW_EXCEPTION":
            "throw an exception if there are too few points",
            "REDUCE_INTERP_ORDER":
            "use an interpolation style with a lower order.",
            "INCREASE_NXNYSAMPLE":
            "Increase the number of samples used to make the interpolation grid.",
        })
    binSize = pexConfig.RangeField(
        doc=
        "how large a region of the sky should be used for each background point",
        dtype=int,
        default=256,
        min=10)
    algorithm = pexConfig.ChoiceField(
        doc=
        "how to interpolate the background values. This maps to an enum; see afw::math::Background",
        dtype=str,
        default="NATURAL_SPLINE",
        optional=True,
        allowed={
            "CONSTANT": "Use a single constant value",
            "LINEAR": "Use linear interpolation",
            "NATURAL_SPLINE":
            "cubic spline with zero second derivative at endpoints",
            "AKIMA_SPLINE":
            "higher-level nonlinear spline that is more robust to outliers",
            "NONE": "No background estimation is to be attempted",
        })
    ignoredPixelMask = pexConfig.ListField(
        doc="Names of mask planes to ignore while estimating the background",
        dtype=str,
        default=["EDGE", "DETECTED", "DETECTED_NEGATIVE"],
        itemCheck=lambda x: x in afwImage.MaskU().getMaskPlaneDict().keys(),
    )
    isNanSafe = pexConfig.Field(
        doc="Ignore NaNs when estimating the background",
        dtype=bool,
        default=False,
    )

    def validate(self):
        pexConfig.Config.validate(self)
        # Allow None to be used as an equivalent for "NONE", even though C++ expects the latter.
        if self.algorithm is None:
            self.algorithm = "NONE"
示例#19
0
文件: mask.py 项目: ziggyman/afw_old
 def testInitializeMasks(self):
     val = 0x1234
     msk = afwImage.MaskU(afwGeom.ExtentI(10, 10), val)
     self.assertEqual(msk.get(0, 0), val)
示例#20
0
文件: background.py 项目: brianv0/afw
    def readFits(fileName, hdu=0, flags=0):
        """Read a our list of Backgrounds from a file
        @param fileName         FITS file to read
        @param hdu              First Header/Data Unit to attempt to read from
        @param flags            Flags to control details of reading; currently unused,
                                but present for consistency with
                                afw.table.BaseCatalog.readFits.

        See also getImage()
        """
        if not isinstance(fileName,
                          MemFileManager) and not os.path.exists(fileName):
            raise RuntimeError("File not found: %s" % fileName)

        self = BackgroundList()

        while True:
            hdu += 1

            md = dafBase.PropertyList()
            try:
                img = afwImage.ImageF(fileName, hdu, md)
                hdu += 1
            except FitsError:
                break

            msk = afwImage.MaskU(fileName, hdu)
            hdu += 1
            var = afwImage.ImageF(fileName, hdu)

            statsImage = afwImage.makeMaskedImage(img, msk, var)

            x0 = md.get("BKGD_X0")
            y0 = md.get("BKGD_Y0")
            width = md.get("BKGD_WIDTH")
            height = md.get("BKGD_HEIGHT")
            imageBBox = afwGeom.BoxI(afwGeom.PointI(x0, y0),
                                     afwGeom.ExtentI(width, height))

            interpStyle = md.get("INTERPSTYLE")
            undersampleStyle = md.get("UNDERSAMPLESTYLE")

            # Older outputs won't have APPROX* settings.  Provide alternative defaults.
            # Note: Currently X- and Y-orders must be equal due to a limitation in
            #       math::Chebyshev1Function2.  Setting approxOrderY = -1 is equivalent
            #       to saying approxOrderY = approxOrderX.
            approxStyle = md.get("APPROXSTYLE") if "APPROXSTYLE" in md.names() \
                          else afwMath.ApproximateControl.UNKNOWN
            approxOrderX = md.get(
                "APPROXORDERX") if "APPROXORDERX" in md.names() else 1
            approxOrderY = md.get(
                "APPROXORDERY") if "APPROXORDERY" in md.names() else -1
            approxWeighting = md.get(
                "APPROXWEIGHTING") if "APPROXWEIGHTING" in md.names() else True

            bkgd = afwMath.BackgroundMI(imageBBox, statsImage)
            bctrl = bkgd.getBackgroundControl()
            bctrl.setInterpStyle(interpStyle)
            bctrl.setUndersampleStyle(undersampleStyle)
            actrl = afwMath.ApproximateControl(approxStyle, approxOrderX,
                                               approxOrderY, approxWeighting)
            bctrl.setApproximateControl(actrl)
            bgInfo = (bkgd, interpStyle, undersampleStyle, approxStyle,
                      approxOrderX, approxOrderY, approxWeighting)
            self.append(bgInfo)

        return self
示例#21
0
def rolloff_mask(infile, outfile,
                 mask_plane='ROLLOFF_DEFECTS',
                 tmp_mask_image=None,
                 outer_edge_width=10,
                 bloom_stop_width=5,
                 signal=10,
                 cleanup=True):
    """
    This function creates a file containing masks for each segment to
    mask pixels affected the edge roll-off and midline blooming stop
    distortions.

    infile: Input file to mask.

    outfile: The name of the file to contain the masks.

    outer_edge_width: This is the width in pixels of the masked region
    along the sides closest to the sensor edges of the imaging region
    of each segment.

    bloom_stop_width: The width in pixels of the masked region of the
    imaging region of each segment, on either side of the central
    blooming stop implant.

    signal: This is the artificial signal written to the mask image so
    that the afwDetect code can generate the footprints used define
    the masks.  It basically just needs to be some positive (non-zero)
    number.
    """
    #
    # Create an empty set of frames to fill with an image of the mask
    # from which we will generate the masks.  The exposure time and
    # system gain need to be set to unity so that the BrightPixels.py
    # code can interpret DN directly as e- per second.
    #
    amp_geom = makeAmplifierGeometry(infile)
    gain = 1
    exptime = 1
    all_amps = imutils.allAmps(infile)
    ccd = CCD(exptime=exptime, gain=gain, geometry=amp_geom, amps=all_amps)
    #
    # Write the output file with a primary HDU so that the DMstack code
    # can append only image extensions (and not write to the PHDU).
    #
    warnings.filterwarnings('ignore', category=fits.verify.VerifyWarning, append=True)
    hdulist = fits.HDUList()
    hdulist.append(fits.PrimaryHDU())
    with fits.open(infile) as fd:
        hdulist[0].header.update(fd[0].header)
    # Use the mask_plane value ('ROLLOFF_DEFECTS') to distinguish
    # this file from other mask files.
    hdulist[0].header['MASKTYPE'] = mask_plane
    fitsWriteto(hdulist, outfile, overwrite=True)
    #
    # Amplifiers 1 (AMP10), 8 (AMP17), 9 (AMP07) and 16 (AMP00) are
    # along the perimeter, but have different edge rolloff pixels
    # depending on the vendor.
    #
    # These amps have edge roll-off adjacent to the prescan.
    amps = (8, 16) if amp_geom.vendor == 'E2V' else (8, 9)
    xmin = amp_geom.imaging.getMinX()
    xmax = xmin + outer_edge_width
    for amp in amps:
        if amp not in all_amps:
            continue
        imarr = ccd.segments[amp].image.getArray()
        imarr[:, xmin:xmax] += signal
    #
    # These amps have edge roll-off adjacent to the serial overscan:
    #
    amps = (1, 9) if amp_geom.vendor == 'E2V' else (1, 16)
    xmax = amp_geom.imaging.getMaxX() + 1
    xmin = xmax - outer_edge_width
    for amp in amps:
        if amp not in all_amps:
            continue
        imarr = ccd.segments[amp].image.getArray()
        imarr[:, xmin:xmax] += signal
    #
    # Loop over all amps, set signal in perimeter and around blooming
    # stop.
    #
    ymax = amp_geom.imaging.getMaxY() + 1
    ymin = ymax - bloom_stop_width
    for i, amp in enumerate(ccd.segments):
        image = ccd.segments[amp].image
        imarr = image.getArray()
        #
        # Set signal in row direction along perimeter.
        #
        xmin = amp_geom.imaging.getMinX()
        xmax = amp_geom.imaging.getMaxX()
        imarr[0:outer_edge_width, xmin:xmax] += signal

        if amp_geom.amp_loc == amp_loc['E2V']:
            #if True:
            #
            # Set signal around blooming stop
            #
            imarr[ymin:ymax, :] += signal
    #
    # Write the images of the mask regions to the FITS file.
    #
    if tmp_mask_image is None:
        tmp_mask_image = tempfile.mkstemp(suffix='.fits', dir='.')[-1]
    fitsWriteto(ccd, tmp_mask_image)
    #
    # Use BrightPixels code to detect the mask regions and write the mask file.
    #
    try:
        mask = afwImage.Mask(image.getDimensions())
    except AttributeError:
        mask = afwImage.MaskU(image.getDimensions())
    mask.addMaskPlane(mask_plane)
    maskedCCD = MaskedCCD(tmp_mask_image)
    pixels, columns = {}, {}
    for amp in maskedCCD:
        bright_pixels = BrightPixels(maskedCCD, amp, exptime, gain,
                                     ethresh=signal/2., mask_plane=mask_plane)
        pixels[amp], columns[amp] = bright_pixels.find()
    generate_mask(infile, outfile, mask_plane, pixels=pixels, columns=columns)
    if cleanup:
        os.remove(tmp_mask_image)
示例#22
0
class SubtractBackgroundConfig(pexConfig.Config):
    """!Config for SubtractBackgroundTask

    @note Many of these fields match fields in lsst.afw.math.BackgroundControl,
    the control class for lsst.afw.math.makeBackground
    """
    statisticsProperty = pexConfig.ChoiceField(
        doc="type of statistic to use for grid points",
        dtype=str,
        default="MEANCLIP",
        allowed={
            "MEANCLIP": "clipped mean",
            "MEAN": "unclipped mean",
            "MEDIAN": "median",
        })
    undersampleStyle = pexConfig.ChoiceField(
        doc=
        "behaviour if there are too few points in grid for requested interpolation style",
        dtype=str,
        default="REDUCE_INTERP_ORDER",
        allowed={
            "THROW_EXCEPTION":
            "throw an exception if there are too few points",
            "REDUCE_INTERP_ORDER":
            "use an interpolation style with a lower order.",
            "INCREASE_NXNYSAMPLE":
            "Increase the number of samples used to make the interpolation grid.",
        },
    )
    binSize = pexConfig.RangeField(
        doc=
        "how large a region of the sky should be used for each background point",
        dtype=int,
        default=256,
        min=1,
    )
    algorithm = pexConfig.ChoiceField(
        doc=
        "how to interpolate the background values. This maps to an enum; see afw::math::Background",
        dtype=str,
        default="NATURAL_SPLINE",
        optional=True,
        allowed={
            "CONSTANT": "Use a single constant value",
            "LINEAR": "Use linear interpolation",
            "NATURAL_SPLINE":
            "cubic spline with zero second derivative at endpoints",
            "AKIMA_SPLINE":
            "higher-level nonlinear spline that is more robust to outliers",
            "NONE": "No background estimation is to be attempted",
        },
    )
    ignoredPixelMask = pexConfig.ListField(
        doc="Names of mask planes to ignore while estimating the background",
        dtype=str,
        default=[
            "BAD",
            "EDGE",
            "DETECTED",
            "DETECTED_NEGATIVE",
            "NO_DATA",
        ],
        itemCheck=lambda x: x in afwImage.MaskU().getMaskPlaneDict().keys(),
    )
    isNanSafe = pexConfig.Field(
        doc="Ignore NaNs when estimating the background",
        dtype=bool,
        default=False,
    )

    useApprox = pexConfig.Field(
        doc="Use Approximate (Chebyshev) to model background.",
        dtype=bool,
        default=False,
    )
    approxOrderX = pexConfig.Field(
        doc=
        "Approximation order in X for background Chebyshev (valid only with useApprox=True)",
        dtype=int,
        default=6,
    )
    # Note: Currently X- and Y-orders must be equal due to a limitation in math::Chebyshev1Function2
    # The following is being added so that the weighting attribute can also be configurable for the
    # call to afwMath.ApproximateControl
    approxOrderY = pexConfig.Field(
        doc=
        "Approximation order in Y for background Chebyshev (valid only with useApprox=True)",
        dtype=int,
        default=-1,
    )
    weighting = pexConfig.Field(
        doc=
        "Use inverse variance weighting in calculation (valid only with useApprox=True)",
        dtype=bool,
        default=True,
    )
示例#23
0
class MatchBackgroundsConfig(pexConfig.Config):

    usePolynomial = pexConfig.Field(
        dtype = bool,
        doc = "Fit background difference with Chebychev polynomial interpolation " \
        "(using afw.math.Approximate)? If False, fit with spline interpolation using afw.math.Background",
        default = False
    )
    order = pexConfig.Field(
        dtype=int,
        doc=
        "Order of Chebyshev polynomial background model. Ignored if usePolynomial False",
        default=8)
    badMaskPlanes = pexConfig.ListField(
        doc="Names of mask planes to ignore while estimating the background",
        dtype=str,
        default=[
            "NO_DATA", "DETECTED", "DETECTED_NEGATIVE", "SAT", "BAD", "INTRP",
            "CR"
        ],
        itemCheck=lambda x: x in afwImage.MaskU().getMaskPlaneDict().keys(),
    )
    gridStatistic = pexConfig.ChoiceField(
        dtype=str,
        doc="Type of statistic to estimate pixel value for the grid points",
        default="MEAN",
        allowed={
            "MEAN": "mean",
            "MEDIAN": "median",
            "MEANCLIP": "clipped mean"
        })
    undersampleStyle = pexConfig.ChoiceField(
        doc = "Behaviour if there are too few points in grid for requested interpolation style. " \
        "Note: INCREASE_NXNYSAMPLE only allowed for usePolynomial=True.",
        dtype = str,
        default = "REDUCE_INTERP_ORDER",
        allowed = {
            "THROW_EXCEPTION": "throw an exception if there are too few points",
            "REDUCE_INTERP_ORDER": "use an interpolation style with a lower order.",
            "INCREASE_NXNYSAMPLE": "Increase the number of samples used to make the interpolation grid.",
            }
    )
    binSize = pexConfig.Field(
        doc=
        "Bin size for gridding the difference image and fitting a spatial model",
        dtype=int,
        default=256)
    interpStyle = pexConfig.ChoiceField(
        dtype = str,
        doc = "Algorithm to interpolate the background values; ignored if usePolynomial is True" \
              "Maps to an enum; see afw.math.Background",
        default = "AKIMA_SPLINE",
        allowed={
             "CONSTANT" : "Use a single constant value",
             "LINEAR" : "Use linear interpolation",
             "NATURAL_SPLINE" : "cubic spline with zero second derivative at endpoints",
             "AKIMA_SPLINE": "higher-level nonlinear spline that is more robust to outliers",
             "NONE": "No background estimation is to be attempted",
             }
    )
    numSigmaClip = pexConfig.Field(
        dtype=int,
        doc=
        "Sigma for outlier rejection; ignored if gridStatistic != 'MEANCLIP'.",
        default=3)
    numIter = pexConfig.Field(
        dtype=int,
        doc=
        "Number of iterations of outlier rejection; ignored if gridStatistic != 'MEANCLIP'.",
        default=2)
    bestRefWeightCoverage = pexConfig.RangeField(
        dtype = float,
        doc = "Weight given to coverage (number of pixels that overlap with patch), " \
        "when calculating best reference exposure. Higher weight prefers exposures with high coverage." \
        "Ignored when reference visit is supplied",
        default = 0.4,
        min = 0., max = 1.
    )
    bestRefWeightVariance = pexConfig.RangeField(
        dtype = float,
        doc = "Weight given to image variance when calculating best reference exposure. " \
        "Higher weight prefers exposures with low image variance. Ignored when reference visit is supplied",
        default = 0.4,
        min = 0., max = 1.
    )
    bestRefWeightLevel = pexConfig.RangeField(
        dtype = float,
        doc = "Weight given to mean background level when calculating best reference exposure. " \
        "Higher weight prefers exposures with low mean background level. " \
        "Ignored when reference visit is supplied.",
        default = 0.2,
        min = 0., max = 1.
    )
    approxWeighting = pexConfig.Field(
        dtype=bool,
        doc=
        ("Use inverse-variance weighting when approximating background offset model? "
         + "This will fail when the background offset is constant " +
         "(this is usually only the case in testing with artificial images)." +
         "(usePolynomial=True)"),
        default=True,
    )
    gridStdevEpsilon = pexConfig.RangeField(
        dtype = float,
        doc = "Tolerance on almost zero standard deviation in a background-offset grid bin. " \
        "If all bins have a standard deviation below this value, the background offset model " \
        "is approximated without inverse-variance weighting. (usePolynomial=True)",
        default = 1e-8,
        min = 0.
    )
示例#24
0
def main():

    date = datetime.datetime.now().strftime("%a %Y-%m-%d %H:%M:%S")

    ########################################################################
    # command line arguments and options
    ########################################################################

    parser = optparse.OptionParser(usage = __doc__)
    #parser.add_option("-a", "--aa", dest="aa", type=float,
    #                  default=1.0, help="default=%default")

    opts, args = parser.parse_args()

    if len(args) == 0:
        r1, r2, dr = 3.0, 3.0, 0.5
    elif len(args) == 3:
        r1, r2, dr = map(float, args)
    else:
        parser.print_help()
        sys.exit(1)


    # make a list of radii to compute the growthcurve points
    radius = []
    nR = int( (r2 - r1)/dr + 1 )
    for iR in range(nR):
        radius.append(r1 + iR*dr)


    # make an image big enough to hold the largest requested aperture
    xwidth = 2*(0 + 128)
    ywidth = xwidth

    # initializations
    sigmas = [1.5, 2.5]  # the Gaussian widths of the psfs we'll use
    nS = len(sigmas)
    a = 100.0
    aptaper = 2.0
    xcen = xwidth/2
    ycen = ywidth/2
    alg = measBase.PsfFluxAlgorithm
    schema = afwTable.SourceTable.makeMinimalSchema()
    schema.addField("centroid_x", type=float)
    schema.addField("centroid_y", type=float)
    plugin = alg(measBase.PsfFluxControl(), "test", schema)
    cat = afwTable.SourceCatalog(schema)
    cat.defineCentroid("centroid")
    print "# sig rad  Naive Sinc Psf"
    for iS in range(nS):
        sigma = sigmas[iS];

        # make a Gaussian star to measure
        gauss  = afwMath.GaussianFunction2D(sigma, sigma)
        kernel = afwMath.AnalyticKernel(xwidth, ywidth, gauss)
        kimg   = afwImage.ImageD(kernel.getDimensions())
        kernel.computeImage(kimg, False)
        kimg  *= 100.0
        mimg   = afwImage.MaskedImageF(kimg.convertFloat(),
                                       afwImage.MaskU(kimg.getDimensions(), 0x0),
                                       afwImage.ImageF(kimg.getDimensions(), 0.0))
        exposure = afwImage.ExposureF(mimg)

        # loop over all the radii in the growthcurve
        for iR in range(nR):

            psfH = int(2.0*(r2 + 2.0)) + 1
            psfW = int(2.0*(r2 + 2.0)) + 1

            # this test uses a single Gaussian instead of the original double gaussian
            psf = afwDet.GaussianPsf(psfW, psfH, sigma)

            # get the aperture fluxes for Naive and Sinc methods

            axes = afwGeom.ellipses.Axes(radius[iR], radius[iR], math.radians(0));
            center = afwGeom.Point2D(0,0)
            ellipse = afwGeom.ellipses.Ellipse(axes, center)
            resultSinc = measBase.ApertureFluxAlgorithm.computeSincFlux(mimg.getImage(), ellipse)
            resultNaive = measBase.ApertureFluxAlgorithm.computeNaiveFlux(mimg.getImage(), ellipse)
            source = cat.addNew()
            source["centroid_x"] = 0
            source["centroid_y"] = 0
            exposure.setPsf(psf)
            plugin.measure(source, exposure)
            fluxNaive = resultNaive.flux
            fluxSinc = resultSinc.flux
            fluxPsf   = source["test_flux"]

            # get the exact flux for the theoretical smooth PSF
            # rpsf = RGaussian(sigma, a, radius[iR], aptaper)
            # *** not sure how to integrate a python functor ***

            print "%.2f %.2f  %.3f %.3f %.3f" % (sigma, radius[iR], fluxNaive, fluxSinc, fluxPsf)
示例#25
0
文件: testMask.py 项目: brianv0/afw
    def testReadFitsConform(self):
        hdu = 3
        mask = afwImage.MaskU(self.maskFile, hdu, None, afwGeom.Box2I(),
                              afwImage.LOCAL, True)

        self.assertMasksEqual(mask, self.expect)
示例#26
0
def main(rerun, dataIds, fakes, root='/lustre/Subaru/SSP', rad=10):

    doCoadd = 'tract' in dataIds[0].keys()
    butler = dafPer.Butler(os.path.join(root, "rerun", rerun))

    #read in fits file, replace with txt file or anything else
    fits = pyfits.open(fakes)
    data = fits[1].data
    radecCat = loadRaDec(data)
    ndata = len(data)
    datamask = np.ones(ndata, dtype=bool)
    ids = data["ID"] if "ID" in data.names else range(len(data))
    idDict = dict(zip(ids, xrange(ndata)))

    for dataId in dataIds:
        print dataId
        try:
            sources = butler.get('deepCoadd_src' if doCoadd else 'src',
                                 dataId,
                                 immediate=True,
                                 flags=afwTable.SOURCE_IO_NO_FOOTPRINTS)
            cal_md = butler.get('deepCoadd_md' if doCoadd else 'calexp_md',
                                dataId,
                                immediate=True)
            calexp = butler.get('deepCoadd' if doCoadd else 'calexp',
                                dataId,
                                immediate=True)
        except:
            print "skipping", dataId
            continue

        if False:
            matches = afwTable.matchRaDec(sources, radecCat,
                                          3.3 * afwGeom.arcseconds)
            for (src, fake, d) in matches:
                datamask[idDict[fake.getId()]] = False

        msk = calexp.getMaskedImage().getMask()
        detected = msk.clone()
        detected &= msk.getPlaneBitMask("DETECTED")
        wcs = calexp.getWcs()
        count, good_count = 0, 0
        for i_d, datum in enumerate(radecCat):
            pixCoord = afwGeom.Point2I(wcs.skyToPixel(datum.getCoord()))
            pixBox = afwGeom.BoxI(pixCoord, afwGeom.Extent2I(1, 1))
            pixBox.grow(rad)
            pixBox.clip(calexp.getBBox(afwImage.PARENT))
            if pixBox.isEmpty():
                continue
            else:
                count += 1
                subMask = afwImage.MaskU(detected, pixBox, afwImage.PARENT)
                if sum(subMask.getArray().ravel()) != 0:
                    datamask[i_d] = False
                else:
                    good_count += 1
        print count, good_count

    newdata = data[datamask]
    print ndata, len(newdata)
    hdu = pyfits.BinTableHDU(newdata)
    hdu.writeto('blank_sources.fits', clobber=True)
示例#27
0
def plantSources(x0, y0, nx, ny, sky, nObj, wid, detector, useRandom=False):

    tanSys = detector.makeCameraSys(cameraGeom.TAN_PIXELS)
    pixToTanXYTransform = detector.getTransformMap()[tanSys]

    img0 = afwImage.ImageF(afwGeom.ExtentI(nx, ny))
    img = afwImage.ImageF(afwGeom.ExtentI(nx, ny))

    ixx0, iyy0, ixy0 = wid*wid, wid*wid, 0.0

    edgeBuffer = 40.0*wid

    flux = 1.0e4
    nkx, nky = int(10*wid) + 1, int(10*wid) + 1
    xhwid,yhwid = nkx/2, nky/2

    nRow = int(math.sqrt(nObj))
    xstep = (nx - 1 - 0.0*edgeBuffer)/(nRow+1)
    ystep = (ny - 1 - 0.0*edgeBuffer)/(nRow+1)

    if useRandom:
        nObj = nRow*nRow

    goodAdded0 = []
    goodAdded = []

    for i in range(nObj):

        # get our position
        if useRandom:
            xcen0, ycen0 = numpy.random.uniform(nx), numpy.random.uniform(ny)
        else:
            xcen0, ycen0 = xstep*((i%nRow) + 1), ystep*(int(i/nRow) + 1)
        ixcen0, iycen0 = int(xcen0), int(ycen0)

        # distort position and shape
        pTan = afwGeom.Point2D(xcen0, ycen0)
        linTransform = pixToTanXYTransform.linearizeReverseTransform(pTan).getLinear()
        m = geomEllip.Quadrupole(ixx0, iyy0, ixy0)
        m.transform(linTransform)

        p = pixToTanXYTransform.reverseTransform(pTan)
        xcen, ycen = xcen0, ycen0 #p.getX(), p.getY()
        if (xcen < 1.0*edgeBuffer or (nx - xcen) < 1.0*edgeBuffer or
            ycen < 1.0*edgeBuffer or (ny - ycen) < 1.0*edgeBuffer):
            continue
        ixcen, iycen = int(xcen), int(ycen)
        ixx, iyy, ixy = m.getIxx(), m.getIyy(), m.getIxy()

        # plant the object
        tmp = 0.25*(ixx-iyy)**2 + ixy**2
        a2 = 0.5*(ixx+iyy) + numpy.sqrt(tmp)
        b2 = 0.5*(ixx+iyy) - numpy.sqrt(tmp)
        #ellip = 1.0 - numpy.sqrt(b2/a2)
        theta = 0.5*numpy.arctan2(2.0*ixy, ixx-iyy)
        a = numpy.sqrt(a2)
        b = numpy.sqrt(b2)

        c, s = math.cos(theta), math.sin(theta)
        good0, good = True, True
        for y in range(nky):
            iy = iycen + y - yhwid
            iy0 = iycen0 + y - yhwid

            for x in range(nkx):
                ix = ixcen + x - xhwid
                ix0 = ixcen0 + x - xhwid

                if ix >= 0 and ix < nx and iy >= 0 and iy < ny:
                    dx, dy = ix - xcen, iy - ycen
                    u =  c*dx + s*dy
                    v = -s*dx + c*dy
                    I0 = flux/(2*math.pi*a*b)
                    val = I0*math.exp(-0.5*((u/a)**2 + (v/b)**2))
                    if val < 0:
                        val = 0
                    prevVal = img.get(ix, iy)
                    img.set(ix, iy, val+prevVal)
                else:
                    good = False

                if ix0 >=0 and ix0 < nx and iy0 >= 0 and iy0 < ny:
                    dx, dy = ix - xcen, iy - ycen
                    I0 = flux/(2*math.pi*wid*wid)
                    val = I0*math.exp(-0.5*((dx/wid)**2 + (dy/wid)**2))
                    if val < 0:
                        val = 0
                    prevVal = img0.get(ix0, iy0)
                    img0.set(ix0, iy0, val+prevVal)
                else:
                    good0 = False

        if good0:
            goodAdded0.append([xcen,ycen])
        if good:
            goodAdded.append([xcen,ycen])

    # add sky and noise
    img += sky
    img0 += sky
    noise = afwImage.ImageF(afwGeom.ExtentI(nx, ny))
    noise0 = afwImage.ImageF(afwGeom.ExtentI(nx, ny))
    for i in range(nx):
        for j in range(ny):
            noise.set(i, j, numpy.random.poisson(img.get(i,j) ))
            noise0.set(i, j, numpy.random.poisson(img0.get(i,j) ))


    edgeWidth = int(0.5*edgeBuffer)
    mask = afwImage.MaskU(afwGeom.ExtentI(nx, ny))
    left   = afwGeom.Box2I(afwGeom.Point2I(0,0), afwGeom.ExtentI(edgeWidth, ny))
    right  = afwGeom.Box2I(afwGeom.Point2I(nx - edgeWidth,0), afwGeom.ExtentI(edgeWidth, ny))
    top    = afwGeom.Box2I(afwGeom.Point2I(0,ny - edgeWidth), afwGeom.ExtentI(nx, edgeWidth))
    bottom = afwGeom.Box2I(afwGeom.Point2I(0,0), afwGeom.ExtentI(nx, edgeWidth))

    for pos in [left, right, top, bottom]:
        msk = afwImage.MaskU(mask, pos, False)
        msk.set(msk.getPlaneBitMask('EDGE'))

    expos = afwImage.makeExposure(afwImage.makeMaskedImage(noise, mask, afwImage.ImageF(noise, True)))
    expos0 = afwImage.makeExposure(afwImage.makeMaskedImage(noise0, mask, afwImage.ImageF(noise0, True)))

    im = expos.getMaskedImage().getImage()
    im0 = expos0.getMaskedImage().getImage()
    im -= sky
    im0 -= sky


    return expos, goodAdded, expos0, goodAdded0
示例#28
0
文件: shape.py 项目: mjuric/meas_base
    def do_testmeasureShape(self):
        """Test that we can instantiate and play with a measureShape"""

        im = afwImage.ImageF(afwGeom.ExtentI(100))
        msk = afwImage.MaskU(im.getDimensions())
        msk.set(0)
        var = afwImage.ImageF(im.getDimensions())
        var.set(10)
        mi = afwImage.MaskedImageF(im, msk, var)
        del im
        del msk
        del var
        exp = afwImage.makeExposure(mi)

        bkgd = 100.0
        control = measBase.SdssShapeControl()
        control.background = bkgd
        control.maxShift = 2
        plugin, cat = makePluginAndCat(measBase.SdssShapeAlgorithm,
                                       "test",
                                       control,
                                       centroid="centroid")

        #cat.defineCentroid("test")
        cat.defineShape("test")
        #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
        #
        # Add a Gaussian to the image
        #
        for a, b, phi, tol in [  # n.b. phi in degrees
            (2.5, 1.5, 90.0, 1e-3),
            (1.5, 2.5, 0.0, 1e-3),
            (1.5, 2.5, 45.0, 1e-3),
            (1.5, 2.5, 90.0, 1e-3),
            (3.0, 2.5, 0.0, 1e-3),
            (3.0, 12.5, 0.0, 1e-3),
            (3.0, 12.5, 0.0, 2e-4),
            (1.0, 1.0, 0.0, 4e-3),
            (1.0, 0.75, 0.0, 2e-2),
                #(0.75, 0.75, 0.0, 1e-1),
        ]:
            if b > a:
                a, b = b, a
                phi -= 90
            a, b, phi = float(a), float(b), math.radians(phi)

            im = mi.getImage()
            x, y = 30, 40  # centre of object
            im[:] = bkgd

            axes = afwGeom.ellipses.Axes(a, b, phi, True)
            quad = afwGeom.ellipses.Quadrupole(axes)
            if False:
                a0, b0 = a, b
                pixellatedAxes = axes.convolve(
                    afwGeom.ellipses.Quadrupole(1 / 6.0, 1 / 6.0))
                a, b = pixellatedAxes.getA(), pixellatedAxes.getB()
                print a, b, a0, b0
            sigma_xx, sigma_yy, sigma_xy = quad.getIxx(), quad.getIyy(
            ), quad.getIxy()

            ksize = 2 * int(4 * max(a, b)) + 1
            c, s = math.cos(phi), math.sin(phi)

            sum, sumxx, sumxy, sumyy = 4 * [0.0] if False else 4 * [None]
            for dx in range(-ksize / 2, ksize / 2 + 1):
                for dy in range(-ksize / 2, ksize / 2 + 1):
                    u, v = c * dx + s * dy, s * dx - c * dy
                    I = 1000 * math.exp(-0.5 * ((u / a)**2 + (v / b)**2))
                    im[x + dx, y + dy] += I

                    if sum is not None:
                        sum += I
                        sumxx += I * dx * dx
                        sumxy += I * dx * dy
                        sumyy += I * dy * dy

            if sum is not None:
                sumxx /= sum
                sumxy /= sum
                sumyy /= sum
                print "RHL %g %g %g" % (sumxx, sumyy, sumxy)

            if display:
                ds9.mtv(im)

            footprint = afwDetection.FootprintSet(
                im, afwDetection.Threshold(110)).getFootprints()[0]
            source = cat.addNew()
            source.setFootprint(footprint)
            source.set("centroid_x",
                       footprint.getPeaks()[0].getCentroid().getX())
            source.set("centroid_y",
                       footprint.getPeaks()[0].getCentroid().getY())
            plugin.measure(source, exp)

            if False:
                Ixx, Iyy, Ixy = source.getIxx(), source.getIyy(
                ), source.getIxy()
                A2 = 0.5 * (Ixx + Iyy) + math.sqrt((0.5 *
                                                    (Ixx - Iyy))**2 + Ixy**2)
                B2 = 0.5 * (Ixx + Iyy) - math.sqrt((0.5 *
                                                    (Ixx - Iyy))**2 + Ixy**2)

                print "I_xx:  %.5f %.5f" % (Ixx, sigma_xx)
                print "I_xy:  %.5f %.5f" % (Ixy, sigma_xy)
                print "I_yy:  %.5f %.5f" % (Iyy, sigma_yy)
                print "A2, B2 = %.5f, %.5f" % (A2, B2)

            print source.getX(), source.getY(), x, y
            print source.getIxx(), sigma_xx, source.getIyy(
            ), sigma_yy, source.getIxy(), sigma_xy
            self.assertTrue(
                abs(x - source.getX()) < 1e-4, "%g v. %g" % (x, source.getX()))
            self.assertTrue(
                abs(y - source.getY()) < 1e-4, "%g v. %g" % (y, source.getY()))
            self.assertTrue(
                abs(source.getIxx() - sigma_xx) < tol * (1 + sigma_xx),
                "%g v. %g" % (sigma_xx, source.getIxx()))
            self.assertTrue(
                abs(source.getIxy() - sigma_xy) < tol * (1 + abs(sigma_xy)),
                "%g v. %g" % (sigma_xy, source.getIxy()))
            self.assertTrue(
                abs(source.getIyy() - sigma_yy) < tol * (1 + sigma_yy),
                "%g v. %g" % (sigma_yy, source.getIyy()))
    def __call__(self, source, exposure):
        fp = source.getFootprint()
        peaks = fp.getPeaks()
        peaksF = [pk.getF() for pk in peaks]
        fbb = fp.getBBox()
        fmask = afwImage.MaskU(fbb)
        fmask.setXY0(fbb.getMinX(), fbb.getMinY())
        afwDetect.setMaskFromFootprint(fmask, fp, 1)

        psf = exposure.getPsf()
        psfSigPix = psf.computeShape().getDeterminantRadius()
        psfFwhmPix = psfSigPix * self.sigma2fwhm
        subimage = afwImage.ExposureF(exposure, fbb, True)
        cpsf = deblendBaseline.CachingPsf(psf)

        # if fewer than 2 peaks, just return a copy of the source
        if len(peaks) < 2:
            return source.getTable().copyRecord(source)

        # make sure you only deblend 2 peaks; take the brighest and faintest
        speaks = [(p.getPeakValue(), p) for p in peaks]
        speaks.sort()
        dpeaks = [speaks[0][1], speaks[-1][1]]

        # and only set these peaks in the footprint (peaks is mutable)
        peaks.clear()
        for peak in dpeaks:
            peaks.append(peak)

        if True:
            # Call top-level deblend task
            fpres = deblendBaseline.deblend(fp,
                                            exposure.getMaskedImage(),
                                            psf,
                                            psfFwhmPix,
                                            log=self.log,
                                            psfChisqCut1=self.psfChisqCut1,
                                            psfChisqCut2=self.psfChisqCut2,
                                            psfChisqCut2b=self.psfChisqCut2b)
        else:
            # Call lower-level _fit_psf task

            # Prepare results structure
            fpres = deblendBaseline.PerFootprint()
            fpres.peaks = []
            for pki, pk in enumerate(dpeaks):
                pkres = deblendBaseline.PerPeak()
                pkres.peak = pk
                pkres.pki = pki
                fpres.peaks.append(pkres)

            for pki, (pk, pkres,
                      pkF) in enumerate(zip(dpeaks, fpres.peaks, peaksF)):
                self.log.logdebug('Peak %i' % pki)
                deblendBaseline._fitPsf(
                    fp, fmask, pk, pkF, pkres, fbb, dpeaks, peaksF, self.log,
                    cpsf, psfFwhmPix,
                    subimage.getMaskedImage().getImage(),
                    subimage.getMaskedImage().getVariance(), self.psfChisqCut1,
                    self.psfChisqCut2, self.psfChisqCut2b)

        deblendedSource = source.getTable().copyRecord(source)
        deblendedSource.setParent(source.getId())
        peakList = deblendedSource.getFootprint().getPeaks()
        peakList.clear()

        for i, peak in enumerate(fpres.peaks):
            if peak.psfFitFlux > 0:
                suffix = "pos"
            else:
                suffix = "neg"
            c = peak.psfFitCenter
            self.log.info("deblended.centroid.dipole.psf.%s %f %f" %
                          (suffix, c[0], c[1]))
            self.log.info("deblended.chi2dof.dipole.%s %f" %
                          (suffix, peak.psfFitChisq / peak.psfFitDof))
            self.log.info("deblended.flux.dipole.psf.%s %f" %
                          (suffix, peak.psfFitFlux *
                           np.sum(peak.templateImage.getArray())))
            peakList.append(peak.peak)
        return deblendedSource
示例#30
0
def generate_mask(infile,
                  outfile,
                  mask_plane,
                  pixels=None,
                  columns=None,
                  temp_mask_image=None):
    """
    Generate a mask file for the specified pixels and columns.
    The amplifier geometry will be taken from infile.
    """
    # Insert artificial signal into specified pixels and columns for
    # each segment.
    exptime = 1
    gain = 1
    geometry = makeAmplifierGeometry(infile)
    amps = imutils.allAmps(infile)
    ccd = CCD(exptime=exptime, gain=gain, geometry=geometry, amps=amps)
    # Account for prescan in x-coordinate since we want to mask
    # columns the full segment.
    prescan = geometry.prescan.getWidth()

    signal = 10
    if pixels is None:
        pixels = {}
    for amp in pixels:
        imarr = ccd.segments[amp].image.getArray()
        for ix, iy in pixels[amp]:
            imarr[iy][ix + prescan] = signal

    if columns is None:
        columns = {}
    for amp in columns:
        imarr = ccd.segments[amp].image.getArray()
        for ix in columns[amp]:
            imarr[:, ix + prescan] = signal

    if temp_mask_image is None:
        temp_mask_image = tempfile.mkstemp(suffix='.fits', dir='.')[-1]
    fitsWriteto(ccd, temp_mask_image)

    # Use the afw code to create a mask file.
    try:
        afwImage.Mask.addMaskPlane(mask_plane)
    except AttributeError:
        afwImage.MaskU.addMaskPlane(mask_plane)

    # Loop over segments in the temporary file and add all pixels to
    # the mask with the inserted signal.
    with fits.open(infile) as hdus:
        hdus[0].header['MASKTYPE'] = mask_plane
        hdus[0].header['FILENAME'] = outfile
        maskedCCD = MaskedCCD(temp_mask_image)
        for amp in maskedCCD:
            threshold = afwDetect.Threshold(signal / 2. * exptime / gain)
            fp_set = afwDetect.FootprintSet(maskedCCD[amp], threshold)
            try:
                mask = afwImage.Mask(maskedCCD[amp].getDimensions())
            except AttributeError:
                mask = afwImage.MaskU(maskedCCD[amp].getDimensions())
            fp_set.setMask(mask, mask_plane)
            hdus[amp].data = mask.array
            # add mask plane keywords
            for key, value in mask.getMaskPlaneDict().items():
                hdus[amp].header['MP_' + key] = value
        hdus.writeto(outfile, overwrite=True)
    os.remove(temp_mask_image)