示例#1
0
def exposureFromImage(image, dataId=None, mapper=None, logger=None, setVisitInfo=True):
    """Generate an Exposure from an image-like object
    If the image is a DecoratedImage then also set its WCS and metadata
    (Image and MaskedImage are missing the necessary metadata
    and Exposure already has those set)
    Parameters
    ----------
    image : Image-like object
        Can be one of lsst.afw.image.DecoratedImage, Image, MaskedImage or
        Exposure.
    Returns
    -------
    `lsst.afw.image.Exposure`
        Exposure containing input image.
    """
    metadata = None
    if isinstance(image, afwImage.MaskedImage):
        exposure = afwImage.makeExposure(image)
    elif isinstance(image, afwImage.DecoratedImage):
        exposure = afwImage.makeExposure(afwImage.makeMaskedImage(image.getImage()))
        metadata = image.getMetadata()
        try:
            wcs = afwGeom.makeSkyWcs(metadata, strip=True)
            exposure.setWcs(wcs)
        except pexExcept.TypeError as e:
            # raised on failure to create a wcs (and possibly others)
            if logger is None:
                logger = lsstLog.Log.getLogger("CameraMapper")
            logger.warn("wcs set to None; insufficient information found in metadata to create a valid wcs: "
                        "%s", e.args[0])

        exposure.setMetadata(metadata)
    elif isinstance(image, afwImage.Exposure):
        # Exposure
        exposure = image
        metadata = exposure.getMetadata()
    else:
        # Image
        exposure = afwImage.makeExposure(afwImage.makeMaskedImage(image))
    #
    # set VisitInfo if we can
    #
    if setVisitInfo and exposure.getInfo().getVisitInfo() is None:
        if metadata is not None:
            if mapper is None:
                if not logger:
                    logger = lsstLog.Log.getLogger("CameraMapper")
                logger.warn("I can only set the VisitInfo if you provide a mapper")
            else:
                exposureId = mapper._computeCcdExposureId(dataId)
                visitInfo = mapper.makeRawVisitInfo(md=metadata, exposureId=exposureId)

                exposure.getInfo().setVisitInfo(visitInfo)

    return exposure
def makeExposure(bbox, scale, psfFwhm, flux):
    """Make a fake exposure

    @param bbox: Bounding box for image (Box2I)
    @param scale: Pixel scale (Angle)
    @param psfFwhm: PSF FWHM (arcseconds)
    @param flux: PSF flux (ADU)
    @return Exposure, source center
    """
    image = afwImage.ImageF(bbox)
    image.set(0)
    center = afwGeom.Box2D(bbox).getCenter()
    psfSigma = psfFwhm/SIGMA_TO_FWHM/scale.asArcseconds()
    psfWidth = 2*int(4.0*psfSigma) + 1
    psf = afwDetection.GaussianPsf(psfWidth, psfWidth, psfSigma)
    psfImage = psf.computeImage(center).convertF()
    psfFlux = psfImage.getArray().sum()
    psfImage *= flux/psfFlux

    subImage = afwImage.ImageF(image, psfImage.getBBox(afwImage.PARENT), afwImage.PARENT)
    subImage += psfImage

    exp = afwImage.makeExposure(afwImage.makeMaskedImage(image))
    exp.setPsf(psf)
    exp.getMaskedImage().getVariance().set(1.0)
    exp.getMaskedImage().getMask().set(0)

    exp.setWcs(afwImage.makeWcs(afwCoord.Coord(0.0*afwGeom.degrees, 0.0*afwGeom.degrees),
                                center, scale.asDegrees(), 0.0, 0.0, scale.asDegrees()))
    return exp, center
示例#3
0
    def readFull(self, fileDescriptor, parameters=None):
        """Read the full Exposure object.

        Parameters
        ----------
        fileDescriptor : `FileDescriptor`
            Identifies the file to read and parameters to be used for reading.
        parameters : `dict`, optional
            If specified a dictionary of slicing parameters that overrides
            those in ``fileDescriptor`.

        Returns
        -------
        exposure : `~lsst.afw.image.Exposure`
            Complete in-memory exposure.
        """
        from lsst.afw.image import makeExposure, makeMaskedImage
        full = makeExposure(makeMaskedImage(self.readImage(fileDescriptor)))
        mask = self.readMask(fileDescriptor)
        if mask is not None:
            full.setMask(mask)
        variance = self.readVariance(fileDescriptor)
        if variance is not None:
            full.setVariance(variance)
        metadata = self.readMetadata(fileDescriptor)
        info = full.getInfo()
        info.setWcs(self.makeWcs(metadata))
        info.setFilter(self.makeFilter(metadata))
        info.setVisitInfo(self.makeVisitInfo(metadata))
        # We shouldn't have to call stripMetadata() here because that should
        # have been done by makeVisitInfo and makeWcs (or by subclasses that
        # strip metadata for other components when constructing them).
        full.setMetadata(metadata)
        return full
示例#4
0
 def std_raw(self, item, dataId):
     md = item.getMetadata()
     md.set("LSSTAMP", "%(raft)s %(sensor)s %(channel)s" % dataId)
     newItem = afwImage.makeExposure(
         afwImage.makeMaskedImage(item.getImage()))
     newItem.setMetadata(md)
     return newItem
示例#5
0
    def standardizeCalib(self, dataset, item, dataId):
        """Standardize a calibration image read in by the butler

        Some calibrations are stored on disk as Images instead of MaskedImages
        or Exposures.  Here, we convert it to an Exposure.

        @param dataset  Dataset type (e.g., "bias", "dark" or "flat")
        @param item  The item read by the butler
        @param dataId  The data identifier (unused, included for future flexibility)
        @return standardized Exposure
        """
        mapping = self.calibrations[dataset]
        if "MaskedImage" in mapping.python:
            exp = afwImage.makeExposure(item)
        elif "Image" in mapping.python:
            if hasattr(item, "getImage"): # For DecoratedImageX
                item = item.getImage()
            exp = afwImage.makeExposure(afwImage.makeMaskedImage(item))
        elif "Exposure" in mapping.python:
            exp = item
        else:
            raise RuntimeError("Unrecognised python type: %s" % mapping.python)

        parent = super(PfsMapper, self)
        if hasattr(parent, "std_" + dataset):
            return getattr(parent, "std_" + dataset)(exp, dataId)
        return self._standardizeExposure(mapping, exp, dataId)
示例#6
0
    def testMultiple(self, pedestal=0.0):
        """Test subtraction of multiple fringe frames

        Paramters
        ---------
        pedestal : `float`, optional
           Pedestal to add into fringe frame.
        """
        xFreqList = [0.1, 0.13, 0.06]
        xOffsetList = [0.0, 0.1, 0.2]
        yFreqList = [0.09, 0.12, 0.07]
        yOffsetList = [0.3, 0.2, 0.1]
        fringeList = [createFringe(self.size, self.size, xFreq, xOffset, yFreq, yOffset)
                      for xFreq, xOffset, yFreq, yOffset in
                      zip(xFreqList, xOffsetList, yFreqList, yOffsetList)]

        for fringe in fringeList:
            fMi = fringe.getMaskedImage()
            fMi += pedestal
        # Generate science frame
        scales = [0.33, 0.33, 0.33]
        image = afwImage.ImageF(self.size, self.size)
        image.set(0)
        for s, f in zip(scales, fringeList):
            image.scaledPlus(s, f.getMaskedImage().getImage())
        mi = afwImage.makeMaskedImage(image)
        exp = afwImage.makeExposure(mi)
        exp.setFilter(afwImage.Filter('FILTER'))

        task = FringeTask(name="multiFringe", config=self.config)
        self.checkFringe(task, exp, fringeList, stddevMax=1.0e-2)
示例#7
0
    def _standardizeMasterCal(self, datasetType, item, dataId, setFilter=False):
        """Standardize a MasterCal image obtained from NOAO archive into Exposure

        These MasterCal images are MEF files with one HDU for each detector.
        Some WCS header, eg CTYPE1, exists only in the zeroth extensionr,
        so info in the zeroth header need to be copied over to metadata.

        @param datasetType: Dataset type ("bias" or "flat")
        @param item: The image read by the butler
        @param dataId: Data identifier
        @param setFilter: Whether to set the filter in the Exposure
        @return (lsst.afw.image.Exposure) the standardized Exposure
        """
        mi = afwImage.makeMaskedImage(item.getImage())
        md = item.getMetadata()
        masterCalMap = getattr(self, "map_" + datasetType)
        masterCalPath = masterCalMap(dataId).getLocations()[0]
        headerPath = re.sub(r'[\[](\d+)[\]]$', "[0]", masterCalPath)
        md0 = afwImage.readMetadata(headerPath)
        for kw in ('CTYPE1', 'CTYPE2', 'CRVAL1', 'CRVAL2', 'CUNIT1', 'CUNIT2',
                   'CD1_1', 'CD1_2', 'CD2_1', 'CD2_2'):
            if kw in md0.paramNames() and kw not in md.paramNames():
                md.add(kw, md0.get(kw))
        wcs = afwImage.makeWcs(md, True)
        exp = afwImage.makeExposure(mi, wcs)
        exp.setMetadata(md)
        return self._standardizeExposure(self.calibrations[datasetType], exp, dataId, filter=setFilter)
示例#8
0
def createFringe(width, height, xFreq, xOffset, yFreq, yOffset):
    """Create a fringe frame.

    Parameters
    ----------
    width, height : `int`
       Size of image.
    xFreq, yFreq : `float`
       Frequency of sinusoids in x and y.
    xOffset, yOffset : `float`
       Phase of sinusoids in x and y.

    Returns
    -------
    exp : `lsst.afw.image.ExposureF`
       Fringe frame.
    """
    image = afwImage.ImageF(width, height)
    array = image.getArray()
    x, y = np.indices(array.shape)
    array[x, y] = np.sin(xFreq*x + xOffset) + np.sin(yFreq*y + yOffset)
    mi = afwImage.makeMaskedImage(image)
    exp = afwImage.makeExposure(mi)
    exp.setFilter(afwImage.Filter('FILTER'))
    return exp
示例#9
0
def makeTestImage(xsize=200, ysize=100, nCR=15):

    randArr = numpy.random.poisson(1000., xsize * ysize)
    randArr = numpy.array(randArr.reshape(ysize, xsize),
                          dtype=numpy.float32)  # force to ImageF
    factory = measAlg.GaussianPsfFactory()
    factory.addWing = False
    psf = factory.apply(4)  # FWHM in pixels

    img = afwImage.makeImageFromArray(randArr)
    var = afwImage.ImageF(img, True)  # copy constructor
    mask = afwImage.Mask(xsize, ysize)

    xind = numpy.random.randint(0, xsize, nCR)
    yind = numpy.random.randint(0, ysize, nCR)

    # set some CRs
    for xi, yi in zip(xind, yind):
        xi, yi = int(xi), int(yi)
        img.set(xi, yi, 1e6)

    mi = afwImage.makeMaskedImage(img, mask, var)
    exp = afwImage.makeExposure(mi)
    exp.setPsf(psf)
    return exp
示例#10
0
def makeExposure(bbox, scale, psfFwhm, flux):
    """Make a fake exposure

    @param bbox: Bounding box for image (Box2I)
    @param scale: Pixel scale (Angle)
    @param psfFwhm: PSF FWHM (arcseconds)
    @param flux: PSF flux (ADU)
    @return Exposure, source center
    """
    image = afwImage.ImageF(bbox)
    image.set(0)
    center = afwGeom.Box2D(bbox).getCenter()
    psfSigma = psfFwhm / SIGMA_TO_FWHM / scale.asArcseconds()
    psfWidth = 2 * int(4.0 * psfSigma) + 1
    psf = afwDetection.GaussianPsf(psfWidth, psfWidth, psfSigma)
    psfImage = psf.computeImage(center).convertF()
    psfFlux = psfImage.getArray().sum()
    psfImage *= flux / psfFlux

    subImage = afwImage.ImageF(image, psfImage.getBBox(afwImage.PARENT),
                               afwImage.PARENT)
    subImage += psfImage

    exp = afwImage.makeExposure(afwImage.makeMaskedImage(image))
    exp.setPsf(psf)
    exp.getMaskedImage().getVariance().set(1.0)
    exp.getMaskedImage().getMask().set(0)

    exp.setWcs(
        afwImage.makeWcs(
            afwCoord.Coord(0.0 * afwGeom.degrees, 0.0 * afwGeom.degrees),
            center, scale.asDegrees(), 0.0, 0.0, scale.asDegrees()))
    return exp, center
示例#11
0
    def _standardizeMasterCal(self,
                              datasetType,
                              item,
                              dataId,
                              setFilter=False):
        """Standardize a MasterCal image obtained from NOAO archive into Exposure

        These MasterCal images are MEF files with one HDU for each detector.
        Some WCS header, eg CTYPE1, exists only in the zeroth extensionr,
        so info in the zeroth header need to be copied over to metadata.

        @param datasetType: Dataset type ("bias" or "flat")
        @param item: The image read by the butler
        @param dataId: Data identifier
        @param setFilter: Whether to set the filter in the Exposure
        @return (lsst.afw.image.Exposure) the standardized Exposure
        """
        mi = afwImage.makeMaskedImage(item.getImage())
        md = item.getMetadata()
        masterCalMap = getattr(self, "map_" + datasetType)
        masterCalPath = masterCalMap(dataId).getLocations()[0]
        headerPath = re.sub(r'[\[](\d+)[\]]$', "[0]", masterCalPath)
        md0 = afwImage.readMetadata(headerPath)
        for kw in ('CTYPE1', 'CTYPE2', 'CRVAL1', 'CRVAL2', 'CUNIT1', 'CUNIT2',
                   'CD1_1', 'CD1_2', 'CD2_1', 'CD2_2'):
            if kw in md0.paramNames() and kw not in md.paramNames():
                md.add(kw, md0.get(kw))
        wcs = afwImage.makeWcs(md, True)
        exp = afwImage.makeExposure(mi, wcs)
        exp.setMetadata(md)
        return self._standardizeExposure(self.calibrations[datasetType],
                                         exp,
                                         dataId,
                                         filter=setFilter)
示例#12
0
def computeIntensity(imageR, imageG=None, imageB=None):
    """!Return a naive total intensity from the red, blue, and green intensities
    @param imageR intensity of image that'll be mapped to red; or intensity if imageG and imageB are None
    @param imageG intensity of image that'll be mapped to green; or None
    @param imageB intensity of image that'll be mapped to blue; or None

    Inputs may be MaskedImages, Images, or numpy arrays and the return is of the same type
    """
    if imageG is None or imageB is None:
        assert imageG is None and imageB is None, \
            "Please specify either a single image or red, green, and blue images"
        return imageR

    imageRGB = [imageR, imageG, imageB]

    for i, c in enumerate(imageRGB):
        if hasattr(c, "getImage"):
            c = imageRGB[i] = c.getImage()
        if hasattr(c, "getArray"):
            imageRGB[i] = c.getArray()

    intensity = (imageRGB[0] + imageRGB[1] + imageRGB[2]) / float(3)
    #
    # Repack into whatever type was passed to us
    #
    Image = afwImage.ImageU if intensity.dtype == 'uint16' else afwImage.ImageF

    if hasattr(imageR, "getImage"):  # a maskedImage
        intensity = afwImage.makeMaskedImage(Image(intensity))
    elif hasattr(imageR, "getArray"):
        intensity = Image(intensity)

    return intensity
示例#13
0
    def testMultiple(self, pedestal=0.0):
        """Test subtraction of multiple fringe frames

        Paramters
        ---------
        pedestal : `float`, optional
           Pedestal to add into fringe frame.
        """
        xFreqList = [0.1, 0.13, 0.06]
        xOffsetList = [0.0, 0.1, 0.2]
        yFreqList = [0.09, 0.12, 0.07]
        yOffsetList = [0.3, 0.2, 0.1]
        fringeList = [
            createFringe(self.size, self.size, xFreq, xOffset, yFreq,
                         yOffset) for xFreq, xOffset, yFreq, yOffset in zip(
                             xFreqList, xOffsetList, yFreqList, yOffsetList)
        ]

        for fringe in fringeList:
            fMi = fringe.getMaskedImage()
            fMi += pedestal
        # Generate science frame
        scales = [0.33, 0.33, 0.33]
        image = afwImage.ImageF(self.size, self.size)
        image.set(0)
        for s, f in zip(scales, fringeList):
            image.scaledPlus(s, f.getMaskedImage().getImage())
        mi = afwImage.makeMaskedImage(image)
        exp = afwImage.makeExposure(mi)
        exp.setFilter(afwImage.FilterLabel(physical='FILTER'))

        task = FringeTask(name="multiFringe", config=self.config)
        self.checkFringe(task, exp, fringeList, stddevMax=1.0e-2)
示例#14
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.

        Parameters
        ----------
        im : `lsst.afw.image.Image`
            Image used to construct the exposure.
        mask : `lsst.afw.image.MaskU`
            Optional mask plane.
        variance : `lsst.afw.image.Image`
            Optional variance plance as an image of the same type as im.

        Returns
        -------
        exposure : `lsst.afw.image.Exposure`
            Constructed exposure (specific type will match that of ``im``).
        """
        if mask is None:
            mask = afwImage.Mask(im.getDimensions())
        if variance is None:
            variance = im
        mi = afwImage.makeMaskedImage(im, mask, variance)
        detector = self.buildDetector()

        exp = afwImage.makeExposure(mi)
        exp.setDetector(detector)
        return exp
示例#15
0
def readRawFile(fileName, dataId={}, detector=None):
    """Read a raw file from fileName, assembling it nicely.

    Parameters
    ----------
    filename : `str`
        The fully-qualified filename.
    dataId : `lsst.daf.persistence.DataId`
        If provided, used to look up e.g. the filter.
    detector : `lsst.afw.cameraGeom.Detector`
        If provided, add this detector to the returned Exposure

    Returns
    -------
    exposure : `lsst.afw.image.Exposure`
        The assembled exposure from the supplied filename.
    """

    class Info():
        def __init__(self, obj):
            self.obj = obj

    amps = []
    for hdu in range(1, 16+1):
        exp = afwImage.makeExposure(afwImage.makeMaskedImage(afwImage.ImageF(fileName, hdu=hdu)))
        exp.setDetector(detector)
        amps.append(exp)

    component_info = {}
    component_info["raw_hdu"] = Info(afwImage.readMetadata(fileName, hdu=0))
    component_info["raw_amp"] = Info(amps)

    exp = assemble_raw(dataId, component_info, None)

    return exp
示例#16
0
def computeIntensity(imageR, imageG=None, imageB=None):
    """!Return a naive total intensity from the red, blue, and green intensities
    \param imageR intensity of image that'll be mapped to red; or intensity if imageG and imageB are None
    \param imageG intensity of image that'll be mapped to green; or None
    \param imageB intensity of image that'll be mapped to blue; or None

    Inputs may be MaskedImages, Images, or numpy arrays and the return is of the same type
    """
    if imageG is None or imageB is None:
        assert imageG is None and imageB is None, \
            "Please specify either a single image or red, green, and blue images"
        return imageR

    imageRGB = [imageR, imageG, imageB]

    for i, c in enumerate(imageRGB):
        if hasattr(c, "getImage"):
            c = imageRGB[i] = c.getImage()
        if hasattr(c, "getArray"):
            imageRGB[i] = c.getArray()

    intensity = (imageRGB[0] + imageRGB[1] + imageRGB[2])/float(3)
    #
    # Repack into whatever type was passed to us
    #
    Image = afwImage.ImageU if intensity.dtype == 'uint16' else afwImage.ImageF

    if hasattr(imageR, "getImage"): # a maskedImage
        intensity = afwImage.makeMaskedImage(Image(intensity))
    elif hasattr(imageR, "getArray"):
        intensity = Image(intensity)

    return intensity
示例#17
0
    def X_standardizeCalib(self, dataset, item, dataId):
        """Standardize a calibration image read in by the butler

        Some calibrations are stored on disk as Images instead of MaskedImages
        or Exposures.  Here, we convert it to an Exposure.

        @param dataset  Dataset type (e.g., "bias", "dark" or "flat")
        @param item  The item read by the butler
        @param dataId  The data identifier (unused, included for future flexibility)
        @return standardized Exposure
        """
        mapping = self.calibrations[dataset]
        if "MaskedImage" in mapping.python:
            exp = afwImage.makeExposure(item)
        elif "Image" in mapping.python:
            if hasattr(item, "getImage"):  # For DecoratedImageX
                item = item.getImage()
                exp = afwImage.makeExposure(afwImage.makeMaskedImage(item))
        elif "Exposure" in mapping.python:
            exp = item
        else:
            raise RuntimeError("Unrecognised python type: %s" % mapping.python)

        parent = super(CameraMapper, self)
        if hasattr(parent, "std_" + dataset):
            return getattr(parent, "std_" + dataset)(exp, dataId)
        return self._standardizeExposure(mapping, exp, dataId)
    def process(self):
        clipboard = self.inputQueue.getNextDataset()
        metadataPolicy = self._policy.getPolicy("metadata")
        datatypePolicy = self._policy.getPolicy("datatype")
        imageKeys = self._policy.getStringArray("calibImageKey")

        if self._policy.exists("suffix"):
            suffix = self._policy.get("suffix")
        else:
            suffix = "Keyword"

        for imageKey in imageKeys:
            exposureKey = re.sub(r'Image', 'Exposure', imageKey)
            dImage = clipboard.get(imageKey)
            mask = afwImage.MaskU(dImage.getDimensions())
            mask.set(0)
            var = afwImage.ImageF(dImage.getDimensions())
            var.set(0)
            maskedImage = afwImage.makeMaskedImage(dImage.getImage(), mask,
                                                   var)
            metadata = dImage.getMetadata()
            exposure = afwImage.makeExposure(maskedImage)
            exposure.setMetadata(metadata)
            clipboard.put(exposureKey, exposure)

        self.outputQueue.addDataset(clipboard)
示例#19
0
def createFringe(width, height, xFreq, xOffset, yFreq, yOffset):
    """Create a fringe frame.

    Parameters
    ----------
    width, height : `int`
       Size of image.
    xFreq, yFreq : `float`
       Frequency of sinusoids in x and y.
    xOffset, yOffset : `float`
       Phase of sinusoids in x and y.

    Returns
    -------
    exp : `lsst.afw.image.ExposureF`
       Fringe frame.
    """
    image = afwImage.ImageF(width, height)
    array = image.getArray()
    x, y = np.indices(array.shape)
    array[x, y] = np.sin(xFreq * x + xOffset) + np.sin(yFreq * y + yOffset)
    mi = afwImage.makeMaskedImage(image)
    exp = afwImage.makeExposure(mi)
    exp.setFilter(afwImage.FilterLabel(band='y', physical='FILTER'))
    return exp
示例#20
0
 def std_raw(self, item, dataId):
     md = item.getMetadata()
     md.set("LSSTAMP", "%(raft)s %(sensor)s %(channel)s" % dataId)
     newItem = afwImage.makeExposure(
             afwImage.makeMaskedImage(item.getImage()))
     newItem.setMetadata(md)
     return newItem
示例#21
0
    def test1295(self):
        """A test case for #1295 (failure to interpolate over groups of defects."""
        im = afwImage.ImageF(lsst.geom.ExtentI(100, 100))
        mi = afwImage.makeMaskedImage(im)
        mi.set(100)
        flat = afwImage.ImageF(im.getDimensions())
        flat.set(1)
        flat[50:51, :, afwImage.LOCAL] = 0.0
        flat[55:56, :, afwImage.LOCAL] = 0.0
        flat[58:59, :, afwImage.LOCAL] = 0.0
        flat[51:60, 51:, afwImage.LOCAL] = 0.0

        mi /= flat

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

        defectList = algorithms.Defects()
        bbox = lsst.geom.BoxI(lsst.geom.PointI(50, 0), lsst.geom.ExtentI(1, 100))
        defectList.append(algorithms.Defect(bbox))
        bbox = lsst.geom.BoxI(lsst.geom.PointI(55, 0), lsst.geom.ExtentI(1, 100))
        defectList.append(algorithms.Defect(bbox))
        bbox = lsst.geom.BoxI(lsst.geom.PointI(58, 0), lsst.geom.ExtentI(1, 100))
        defectList.append(algorithms.Defect(bbox))
        bbox = lsst.geom.BoxI(lsst.geom.PointI(51, 51), lsst.geom.ExtentI(9, 49))
        defectList.append(algorithms.Defect(bbox))

        psf = algorithms.DoubleGaussianPsf(15, 15, 1./(2*math.sqrt(2*math.log(2))))
        algorithms.interpolateOverDefects(mi, psf, defectList, 50.)

        if display:
            afwDisplay.Display(frame=1).mtv(mi, title=self._testMethodName + ": Interpolated")

        self.assertTrue(np.isfinite(mi.image[56, 51, afwImage.LOCAL]))
示例#22
0
    def readFull(self, parameters=None):
        """Read the full Exposure object.

        Parameters
        ----------
        parameters : `dict`, optional
            If specified, a dictionary of slicing parameters that overrides
            those in the `fileDescriptor` attribute.

        Returns
        -------
        exposure : `~lsst.afw.image.Exposure`
            Complete in-memory exposure.
        """
        from lsst.afw.image import makeExposure, makeMaskedImage
        full = makeExposure(makeMaskedImage(self.readImage()))
        mask = self.readMask()
        if mask is not None:
            full.setMask(mask)
        variance = self.readVariance()
        if variance is not None:
            full.setVariance(variance)
        full.setDetector(self.getDetector(self.observationInfo.detector_num))
        info = full.getInfo()
        info.setFilter(self.makeFilter())
        info.setVisitInfo(self.makeVisitInfo())
        info.setWcs(self.makeWcs(info.getVisitInfo(), info.getDetector()))
        # We don't need to call stripMetadata() here because it has already
        # been stripped during creation of the ObservationInfo, WCS, etc.
        full.setMetadata(self.metadata)
        return full
示例#23
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")

            # 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
示例#24
0
 def std_dark(self, item, dataId):
     exp = afwImage.makeExposure(afwImage.makeMaskedImage(item))
     rawPath = self.map_raw(dataId).getLocations()[0]
     headerPath = re.sub(r'[\[](\d+)[\]]$', "[0]", rawPath)
     md0 = afwImage.readMetadata(headerPath)
     visitInfo = self.makeRawVisitInfo(md0)
     exp.getInfo().setVisitInfo(visitInfo)
     return self._standardizeExposure(self.calibrations["dark"], exp, dataId, filter=False)
示例#25
0
def makeExpFromIm(im, detector):
    wcs = makeFakeWcs()
    var = afwImage.ImageF(im)
    mask = afwImage.MaskU(im.getDimensions())
    mi = afwImage.makeMaskedImage(im, mask, var)
    exp = afwImage.makeExposure(mi)
    exp.setDetector(detector)
    exp.setWcs(wcs)
    return exp
示例#26
0
def makeExpFromIm(im, detector):
    wcs = makeFakeWcs()
    var = afwImage.ImageF(im)
    mask = afwImage.MaskU(im.getDimensions())
    mi = afwImage.makeMaskedImage(im, mask, var)
    exp = afwImage.makeExposure(mi)
    exp.setDetector(detector)
    exp.setWcs(wcs)
    return exp
示例#27
0
    def getExposure(self):
        """Construct a test exposure.

        The test exposure has a simple WCS set, as well as a list of
        unlikely header keywords that can be removed during ISR
        processing to exercise that code.

        Returns
        -------
        exposure : `lsst.afw.exposure.Exposure`
            Construct exposure containing masked image of the
            appropriate size.
        """
        camera = self.getCamera()
        detector = camera[self.config.detectorIndex]
        image = afwUtils.makeImageFromCcd(detector,
                                          isTrimmed=self.config.isTrimmed,
                                          showAmpGain=False,
                                          rcMarkSize=0,
                                          binSize=1,
                                          imageFactory=afwImage.ImageF)

        var = afwImage.ImageF(image.getDimensions())
        mask = afwImage.Mask(image.getDimensions())
        image.assign(0.0)

        maskedImage = afwImage.makeMaskedImage(image, mask, var)
        exposure = afwImage.makeExposure(maskedImage)
        exposure.setDetector(detector)
        exposure.setWcs(self.getWcs())

        visitInfo = afwImage.VisitInfo(exposureTime=self.config.expTime, darkTime=self.config.darkTime)
        exposure.getInfo().setVisitInfo(visitInfo)

        metadata = exposure.getMetadata()
        metadata.add("SHEEP", 7.3, "number of sheep on farm")
        metadata.add("MONKEYS", 155, "monkeys per tree")
        metadata.add("VAMPIRES", 4, "How scary are vampires.")

        ccd = exposure.getDetector()
        newCcd = ccd.rebuild()
        newCcd.clear()
        for amp in ccd:
            newAmp = amp.rebuild()
            newAmp.setLinearityCoeffs((0., 1., 0., 0.))
            newAmp.setLinearityType("Polynomial")
            newAmp.setGain(self.config.gain)
            newAmp.setSuspectLevel(25000.0)
            newAmp.setSaturation(32000.0)
            newCcd.append(newAmp)
        exposure.setDetector(newCcd.finish())

        exposure.image.array[:] = np.zeros(exposure.getImage().getDimensions()).transpose()
        exposure.mask.array[:] = np.zeros(exposure.getMask().getDimensions()).transpose()
        exposure.variance.array[:] = np.zeros(exposure.getVariance().getDimensions()).transpose()

        return exposure
示例#28
0
    def standardizeCalib(self, dataset, item, dataId):

        mapping = self.calibrations[dataset]
        if "Image" in mapping.python:
            exp = afwImage.makeMaskedImage(item)
        exp = afwImage.makeExposure(exp)    
        exp = self._standardizeExposure(mapping, exp, \
                                        dataId, filter=False, trimmed=False)        
        return exp
示例#29
0
    def testMakeMaskedImageXY0(self):
        """Test that makeMaskedImage sets XY0 correctly"""
        im = afwImage.ImageF(200, 300)
        xy0 = afwGeom.PointI(10, 20)
        im.setXY0(*xy0)
        mi = afwImage.makeMaskedImage(im)

        self.assertEqual(mi.getImage().getXY0(),    xy0)
        self.assertEqual(mi.getMask().getXY0(),     xy0)
        self.assertEqual(mi.getVariance().getXY0(), xy0)
示例#30
0
    def testMakeMaskedImageXY0(self):
        """Test that makeMaskedImage sets XY0 correctly"""
        im = afwImage.ImageF(200, 300)
        xy0 = lsst.geom.PointI(10, 20)
        im.setXY0(*xy0)
        mi = afwImage.makeMaskedImage(im)

        self.assertEqual(mi.image.getXY0(), xy0)
        self.assertEqual(mi.mask.getXY0(), xy0)
        self.assertEqual(mi.variance.getXY0(), xy0)
示例#31
0
def saturate(image, satValue):
    """Simulate saturation on an image, so we can test 'replaceSaturatedPixels'

    Takes an Image, sets saturated pixels to NAN and masks them, returning
    a MaskedImage.
    """
    image = afwImage.makeMaskedImage(image)
    afwDetect.FootprintSet(image, afwDetect.Threshold(satValue), "SAT")
    arr = image.getImage().getArray()
    arr[np.where(arr >= satValue)] = np.nan
    return image
示例#32
0
    def testImagesOverlap(self):
        # make pairs of image, variance and mask planes
        # using the same dimensions for each so we can mix and match
        # while making masked images
        dim = lsst.geom.Extent2I(10, 8)
        # a set of bounding boxes, some of which overlap each other
        # and some of which do not, and include the full image bounding box
        bboxes = (
            lsst.geom.Box2I(lsst.geom.Point2I(0, 0), dim),
            lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(3, 3)),
            lsst.geom.Box2I(lsst.geom.Point2I(2, 2), lsst.geom.Extent2I(6, 4)),
            lsst.geom.Box2I(lsst.geom.Point2I(4, 4), lsst.geom.Extent2I(6, 4)),
        )
        masks = [afwImage.Mask(dim), afwImage.Mask(dim)]
        variances = [afwImage.ImageF(dim), afwImage.ImageF(dim)]
        imageClasses = (afwImage.ImageF, afwImage.ImageD, afwImage.ImageI, afwImage.ImageU)
        for ImageClass1, ImageClass2 in itertools.product(imageClasses, imageClasses):
            images = [ImageClass1(dim), ImageClass2(dim)]
            for image1, mask1, variance1, image2, mask2, variance2 in itertools.product(
                    images, masks, variances, images, masks, variances):
                with self.subTest(ImageClass1=ImageClass1, ImageClass2=ImageClass2,
                                  image1=image1, mask1=mask1, variance1=variance1,
                                  image2=image2, mask2=mask2, variance2=variance2):
                    shouldOverlap = (image1 is image2) or (mask1 is mask2) or (variance1 is variance2)

                    mi1 = afwImage.makeMaskedImage(image=image1, mask=mask1, variance=variance1)
                    mi2 = afwImage.makeMaskedImage(image=image2, mask=mask2, variance=variance2)
                    self.assertEqual(afwImage.imagesOverlap(mi1, mi2), shouldOverlap)
                    self.assertEqual(afwImage.imagesOverlap(mi2, mi1), shouldOverlap)

                    for bbox1, bbox2 in itertools.product(bboxes, bboxes):
                        with self.subTest(bbox1=bbox1, bbox2=bbox2):
                            subMi1 = afwImage.makeMaskedImage(image=type(image1)(image1, bbox1),
                                                              mask=afwImage.Mask(mask1, bbox1),
                                                              variance=afwImage.ImageF(variance1, bbox1))
                            subMi2 = afwImage.makeMaskedImage(image=type(image2)(image2, bbox2),
                                                              mask=afwImage.Mask(mask2, bbox2),
                                                              variance=afwImage.ImageF(variance2, bbox2))
                            subregionsShouldOverlap = shouldOverlap and bbox1.overlaps(bbox2)
                            self.assertEqual(afwImage.imagesOverlap(subMi1, subMi2), subregionsShouldOverlap)
                            self.assertEqual(afwImage.imagesOverlap(subMi2, subMi1), subregionsShouldOverlap)
示例#33
0
    def testImagesOverlap(self):
        # make pairs of image, variance and mask planes
        # using the same dimensions for each so we can mix and match
        # while making masked images
        dim = lsst.geom.Extent2I(10, 8)
        # a set of bounding boxes, some of which overlap each other
        # and some of which do not, and include the full image bounding box
        bboxes = (
            lsst.geom.Box2I(lsst.geom.Point2I(0, 0), dim),
            lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(3, 3)),
            lsst.geom.Box2I(lsst.geom.Point2I(2, 2), lsst.geom.Extent2I(6, 4)),
            lsst.geom.Box2I(lsst.geom.Point2I(4, 4), lsst.geom.Extent2I(6, 4)),
        )
        masks = [afwImage.Mask(dim), afwImage.Mask(dim)]
        variances = [afwImage.ImageF(dim), afwImage.ImageF(dim)]
        imageClasses = (afwImage.ImageF, afwImage.ImageD, afwImage.ImageI, afwImage.ImageU)
        for ImageClass1, ImageClass2 in itertools.product(imageClasses, imageClasses):
            images = [ImageClass1(dim), ImageClass2(dim)]
            for image1, mask1, variance1, image2, mask2, variance2 in itertools.product(
                    images, masks, variances, images, masks, variances):
                with self.subTest(ImageClass1=ImageClass1, ImageClass2=ImageClass2,
                                  image1=image1, mask1=mask1, variance1=variance1,
                                  image2=image2, mask2=mask2, variance2=variance2):
                    shouldOverlap = (image1 is image2) or (mask1 is mask2) or (variance1 is variance2)

                    mi1 = afwImage.makeMaskedImage(image=image1, mask=mask1, variance=variance1)
                    mi2 = afwImage.makeMaskedImage(image=image2, mask=mask2, variance=variance2)
                    self.assertEqual(afwImage.imagesOverlap(mi1, mi2), shouldOverlap)
                    self.assertEqual(afwImage.imagesOverlap(mi2, mi1), shouldOverlap)

                    for bbox1, bbox2 in itertools.product(bboxes, bboxes):
                        with self.subTest(bbox1=bbox1, bbox2=bbox2):
                            subMi1 = afwImage.makeMaskedImage(image=type(image1)(image1, bbox1),
                                                              mask=afwImage.Mask(mask1, bbox1),
                                                              variance=afwImage.ImageF(variance1, bbox1))
                            subMi2 = afwImage.makeMaskedImage(image=type(image2)(image2, bbox2),
                                                              mask=afwImage.Mask(mask2, bbox2),
                                                              variance=afwImage.ImageF(variance2, bbox2))
                            subregionsShouldOverlap = shouldOverlap and bbox1.overlaps(bbox2)
                            self.assertEqual(afwImage.imagesOverlap(subMi1, subMi2), subregionsShouldOverlap)
                            self.assertEqual(afwImage.imagesOverlap(subMi2, subMi1), subregionsShouldOverlap)
def makeGalaxy(width, height, flux, a, b, theta, dx=0.0, dy=0.0, xy0=None, xcen=None, ycen=None):
    """Make a fake galaxy image.
    """
    gal = afwImage.ImageF(width, height)
    if xcen is None:
        xcen = 0.5*width + dx
    if ycen is None:
        ycen = 0.5*height + dy
    I0 = flux/(2*math.pi*a*b)

    if xy0 is not None:
        gal.setXY0(xy0)

    c, s = math.cos(math.radians(theta)), math.sin(math.radians(theta))
    ii, iuu, ivv = 0.0, 0.0, 0.0
    for y in range(height):
        for x in range(width):
            dx, dy = x + gal.getX0() - xcen, y + gal.getY0() - ycen
            if math.hypot(dx, dy) < 10.5:
                nsample = 5
                subZ = np.linspace(-0.5*(1 - 1/nsample), 0.5*(1 - 1/nsample), nsample)
            else:
                nsample = 1
                subZ = [0.0]

            val = 0
            for sx in subZ:
                for sy in subZ:
                    u = c*(dx + sx) + s*(dy + sy)
                    v = -s*(dx + sx) + c*(dy + sy)
                    val += I0*math.exp(-0.5*((u/a)**2 + (v/b)**2))

            if val < 0:
                val = 0
            gal[afwGeom.Point2I(x, y), afwImage.LOCAL] = val/nsample**2

            ii += val
            iuu += val*u**2
            ivv += val*v**2

    iuu /= ii
    ivv /= ii

    exp = afwImage.makeExposure(afwImage.makeMaskedImage(gal))
    exp.getMaskedImage().getVariance().set(1.0)
    scale = 1.0e-4*afwGeom.degrees
    cdMatrix = afwGeom.makeCdMatrix(scale=scale, flipX=True)
    exp.setWcs(afwGeom.makeSkyWcs(crpix=afwGeom.Point2D(0.0, 0.0),
                                  crval=afwGeom.SpherePoint(0.0, 0.0, afwGeom.degrees),
                                  cdMatrix=cdMatrix))
    # add a dummy Psf.  The new SdssCentroid needs one
    exp.setPsf(afwDetection.GaussianPsf(11, 11, 0.01))
    return exp
示例#35
0
    def writeDefects(self, maskFile, ccd, format=None):
        """Given a Mask, find the defects for each amp in the specified CCD (0-indexed).
        If format is provided, it's expected to be used as "format % (ccd, amp)" to generate
        a .paf filename to write the defects too.  If it's "-", write to stdout"""

        # Metadata should have validity range keywords, but it doesn't.
        if False:
            metaData = afwImage.readMetadata(maskFile, 0)

        hdu = ccd + 2
        im = afwImage.ImageF(maskFile, hdu)
        im -= 1
        im *= -1
        mask = afwImage.MaskU(im.getBBox(afwImage.PARENT))
        mask.set(0x0)
        mask = afwImage.makeMaskedImage(im, mask)

        for amp in self.ampList():
            subMask = mask.Factory(mask, self.getTrimSecBBox(amp),
                                   afwImage.LOCAL)

            ds = afwDetection.makeFootprintSet(subMask,
                                               afwDetection.Threshold(0.5),
                                               "INTRP")

            if False:
                ds9.setDefaultFrame(amp)

                ds9.mtv(subMask)
                ds9.dot("Amp %d" % amp, 0, 0)

            if not format:
                return

            if format == "-":
                fd = sys.stdout
            else:
                fd = open(format % (ccd, amp), "w")

            print >> fd, """\
#<?cfg paf policy ?>
#
# Defects for CCD%03d amp %02d generated from %s, HDU %d
#
# Coordinates are trimmed and per-amp not per-CCD.  If you change this, the ISR will have to change
#
# Generated by $HeadURL$
#
""" % (ccd, amp, maskFile, hdu),

            for foot in ds.getFootprints():
                afwDetectionUtils.writeFootprintAsDefects(fd, foot)
示例#36
0
    def setUp(self):
        # We create an image that has a ramp (unique values for each pixel),
        # with a single high pixel that allows for centering
        self.width, self.height = 50, 50
        self.xcen, self.ycen = self.width // 2, self.height // 2
        self.image = afwImage.ImageF(afwGeom.ExtentI(self.width, self.height))
        for y in range(self.height):
            for x in range(self.width):
                self.image.set(x, y, self.width * y + x)
        self.image.set(self.xcen, self.ycen, 1234567.89)
        self.exp = afwImage.makeExposure(afwImage.makeMaskedImage(self.image))
        self.exp.getMaskedImage().getVariance().set(1.0)
        scale = 0.2 / 3600
        wcs = afwImage.makeWcs(
            afwCoord.Coord(0 * afwGeom.degrees, 0 * afwGeom.degrees),
            afwGeom.Point2D(self.xcen, self.ycen), scale, 0, 0, scale)
        self.exp.setWcs(wcs)

        if display:
            frame = 1
            ds9.mtv(self.exp, frame=frame, title="Single pixel")

        # We will use a GaussianCentroid to tweak the center (it should not, for forced measurement)
        # and a NaiveFlux to measure the single pixel.  We'll start offset from the high pixel,
        # so that a forced measurement should yield a flux of zero, while a measurement that was allowed to
        # center should yield a flux of unity.
        # Note that previous versions used NaiveCentroid, which was so nonrobust that it failed to get
        # right answer when the input value was round-tripped through Wcs and modified by ~1E-8.
        gaussianCentroid = measAlg.GaussianCentroidControl()
        naiveFlux = measAlg.NaiveFluxControl()
        naiveFlux.radius = 0.5
        self.x, self.y = self.xcen - 1, self.ycen - 1

        self.foot = afwDetection.Footprint(afwGeom.Point2I(self.x, self.y), 2)
        self.foot.addPeak(self.x, self.y, float("NaN"))

        schema = afwTable.SourceTable.makeMinimalSchema()
        msb = measAlg.MeasureSourcesBuilder()
        msb.addAlgorithm(naiveFlux)
        msb.setCentroider(gaussianCentroid)
        self.measurer = msb.build(schema)
        self.table = afwTable.SourceTable.make(schema)
        self.table.defineCentroid("centroid.gaussian")

        schemaF = afwTable.SourceTable.makeMinimalSchema()
        msbF = measAlg.MeasureSourcesBuilder("", True)
        msbF.addAlgorithm(naiveFlux)
        msbF.setCentroider(gaussianCentroid)
        self.measurerF = msbF.build(schemaF)
        self.tableF = afwTable.SourceTable.make(schemaF)
        self.tableF.defineCentroid("centroid.gaussian")
示例#37
0
    def toCcdBackground(self, detector, bbox):
        """Produce a background model for a CCD

        The superpixel background model is warped back to the
        CCD frame, for application to the individual CCD.

        Parameters
        ----------
        detector : `lsst.afw.cameraGeom.Detector`
            CCD for which to produce background model.
        bbox : `lsst.geom.Box2I`
            Bounding box of CCD exposure.

        Returns
        -------
        bg : `lsst.afw.math.BackgroundList`
            Background model for CCD.
        """
        transform = detector.getTransformMap().getTransform(
            detector.makeCameraSys(afwCameraGeom.PIXELS),
            detector.makeCameraSys(afwCameraGeom.FOCAL_PLANE))
        binTransform = (
            geom.AffineTransform.makeScaling(self.config.binning) *
            geom.AffineTransform.makeTranslation(geom.Extent2D(0.5, 0.5)))

        # Binned image on CCD --> unbinned image on CCD --> focal plane --> binned focal plane
        toSample = afwGeom.makeTransform(binTransform).then(transform).then(
            self.transform)

        focalPlane = self.getStatsImage()
        fpNorm = afwImage.ImageF(focalPlane.getBBox())
        fpNorm.set(1.0)

        image = afwImage.ImageF(bbox.getDimensions() // self.config.binning)
        norm = afwImage.ImageF(image.getBBox())
        ctrl = afwMath.WarpingControl("bilinear")
        afwMath.warpImage(image, focalPlane, toSample.inverted(), ctrl)
        afwMath.warpImage(norm, fpNorm, toSample.inverted(), ctrl)
        image /= norm

        mask = afwImage.Mask(image.getBBox())
        isBad = numpy.isnan(image.getArray())
        mask.getArray()[isBad] = mask.getPlaneBitMask("BAD")
        image.getArray()[isBad] = image.getArray()[~isBad].mean()

        return afwMath.BackgroundList(
            (afwMath.BackgroundMI(bbox, afwImage.makeMaskedImage(image, mask)),
             afwMath.stringToInterpStyle(self.config.interpolation),
             afwMath.stringToUndersampleStyle("REDUCE_INTERP_ORDER"),
             afwMath.ApproximateControl.UNKNOWN, 0, 0, False))
def makeGalaxy(width, height, flux, a, b, theta, dx=0.0, dy=0.0, xy0=None, xcen=None, ycen=None):
    """Make a fake galaxy image"""
    gal = afwImage.ImageF(width, height)
    if xcen is None:
        xcen = 0.5*width + dx
    if ycen is None:
        ycen = 0.5*height + dy
    I0 = flux/(2*math.pi*a*b)

    if xy0 is not None:
        gal.setXY0(xy0)

    c, s = math.cos(math.radians(theta)), math.sin(math.radians(theta))
    I, Iuu, Ivv = 0.0, 0.0, 0.0
    for y in range(height):
        for x in range(width):
            dx, dy = x + gal.getX0() - xcen, y + gal.getY0() - ycen
            if math.hypot(dx, dy) < 10.5:
                nsample = float(5)
                subZ = np.linspace(-0.5*(1 - 1/nsample), 0.5*(1 - 1/nsample), nsample)
            else:
                nsample = 1
                subZ = [0.0]

            val = 0
            for sx in subZ:
                for sy in subZ:
                    u =  c*(dx + sx) + s*(dy + sy)
                    v = -s*(dx + sx) + c*(dy + sy)
                    val += I0*math.exp(-0.5*((u/a)**2 + (v/b)**2))

            if val < 0:
                val = 0
            gal.set(x, y, val/nsample**2)

            I += val
            Iuu += val*u**2
            Ivv += val*v**2

    Iuu /= I; Ivv /= I

    exp = afwImage.makeExposure(afwImage.makeMaskedImage(gal))
    exp.getMaskedImage().getVariance().setXY0(exp.getXY0()) # workaround #2577
    exp.getMaskedImage().getVariance().set(1.0)
    exp.setWcs(afwImage.makeWcs(afwCoord.Coord(0.0*afwGeom.degrees, 0.0*afwGeom.degrees),
                                afwGeom.Point2D(0.0, 0.0), 1.0e-4, 0.0, 0.0, 1.0e-4))
    # add a dummy Psf.  The new SdssCentroid needs one
    exp.setPsf(afwDetection.GaussianPsf(11, 11, 0.01))
    return exp
示例#39
0
    def getExposure(self):
        r"""Construct a test exposure.

        The test exposure has a simple WCS set, as well as a list of
        unlikely header keywords that can be removed during ISR
        processing to exercise that code.

        Returns
        -------
        exposure : `lsst.afw.exposure.Exposure`
            Construct exposure containing masked image of the
            appropriate size.
        """
        camera = self.getCamera()
        detector = camera[self.config.detectorIndex]
        image = afwUtils.makeImageFromCcd(detector,
                                          isTrimmed=self.config.isTrimmed,
                                          showAmpGain=False,
                                          rcMarkSize=0,
                                          binSize=1,
                                          imageFactory=afwImage.ImageF)

        var = afwImage.ImageF(image.getDimensions())
        mask = afwImage.Mask(image.getDimensions())
        image.assign(0.0)

        maskedImage = afwImage.makeMaskedImage(image, mask, var)
        exposure = afwImage.makeExposure(maskedImage)
        exposure.setDetector(detector)
        exposure.setWcs(self.getWcs())

        visitInfo = afwImage.VisitInfo(exposureTime=self.config.expTime, darkTime=self.config.darkTime)
        exposure.getInfo().setVisitInfo(visitInfo)

        metadata = exposure.getMetadata()
        metadata.add("SHEEP", 7.3, "number of sheep on farm")
        metadata.add("MONKEYS", 155, "monkeys per tree")
        metadata.add("VAMPIRES", 4, "How scary are vampires.")

        for amp in exposure.getDetector():
            amp.setLinearityCoeffs((0., 1., 0., 0.))
            amp.setLinearityType("Polynomial")
            amp.setGain(self.config.gain)

        exposure.image.array[:] = np.zeros(exposure.getImage().getDimensions()).transpose()
        exposure.mask.array[:] = np.zeros(exposure.getMask().getDimensions()).transpose()
        exposure.variance.array[:] = np.zeros(exposure.getVariance().getDimensions()).transpose()

        return exposure
    def testBrighterFatterInterface(self):
        """Test brighter fatter correction interface using a delta function kernel on a flat image"""

        image = afwImage.ImageF(100, 100)
        image.set(100)
        ref_image = afwImage.ImageF(image, True)

        mi = afwImage.makeMaskedImage(image)
        exp = afwImage.makeExposure(mi)

        with open(self.filename, 'rb') as f:
            bfKernel = pickle.load(f)

        isrFunctions.brighterFatterCorrection(exp, bfKernel, 5, 100, False)
        self.assertImagesEqual(ref_image, image)
示例#41
0
    def testBrighterFatterInterface(self):
        """Test brighter fatter correction interface using a delta function kernel on a flat image"""

        image = afwImage.ImageF(100, 100)
        image.set(100)
        ref_image = afwImage.ImageF(image, True)

        mi = afwImage.makeMaskedImage(image)
        exp = afwImage.makeExposure(mi)

        with open(self.filename, 'rb') as f:
            bfKernel = pickle.load(f)

        isrFunctions.brighterFatterCorrection(exp, bfKernel, 5, 100, False)
        self.assertImagesEqual(ref_image, image)
示例#42
0
    def writeDefects(self, maskFile, ccd, format=None):
        """Given a Mask, find the defects for each amp in the specified CCD (0-indexed).
        If format is provided, it's expected to be used as "format % (ccd, amp)" to generate
        a .paf filename to write the defects too.  If it's "-", write to stdout"""

        # Metadata should have validity range keywords, but it doesn't.
        if False:
            metaData = afwImage.readMetadata(maskFile, 0)

        hdu = ccd + 2
        im = afwImage.ImageF(maskFile, hdu)
        im -= 1
        im *= -1
        mask = afwImage.MaskU(im.getBBox(afwImage.PARENT)); mask.set(0x0)
        mask = afwImage.makeMaskedImage(im, mask)

        for amp in self.ampList():
            subMask = mask.Factory(mask, self.getTrimSecBBox(amp), afwImage.LOCAL)

            ds = afwDetection.makeFootprintSet(subMask, afwDetection.Threshold(0.5), "INTRP")

            if False:
                ds9.setDefaultFrame(amp)
                
                ds9.mtv(subMask)
                ds9.dot("Amp %d" % amp, 0, 0)

            if not format:
                return

            if format == "-":
                fd = sys.stdout
            else:
                fd = open(format % (ccd, amp), "w")

            print >> fd, """\
#<?cfg paf policy ?>
#
# Defects for CCD%03d amp %02d generated from %s, HDU %d
#
# Coordinates are trimmed and per-amp not per-CCD.  If you change this, the ISR will have to change
#
# Generated by $HeadURL$
#
""" % (ccd, amp, maskFile, hdu),
                          
            for foot in ds.getFootprints():
                afwDetectionUtils.writeFootprintAsDefects(fd, foot)
示例#43
0
def makeExposure(bbox, scale, psfFwhm, flux):
    """Make a fake exposure

    Parameters
    ----------

    bbox : `lsst.afw.geom.Box2I`
        Bounding box for image.
    scale : `lsst.afw.geom.Angle`
        Pixel scale.
    psfFwhm : `float`
        PSF FWHM (arcseconds)
    flux : `float`
        PSF flux (ADU)

    Returns
    -------
    exposure : `lsst.afw.image.ExposureF`
        Fake exposure.
    center : `lsst.afw.geom.Point2D`
        Position of fake source.
    """
    image = afwImage.ImageF(bbox)
    image.set(0)
    center = afwGeom.Box2D(bbox).getCenter()
    psfSigma = psfFwhm / SIGMA_TO_FWHM / scale.asArcseconds()
    psfWidth = 2 * int(4.0 * psfSigma) + 1
    psf = afwDetection.GaussianPsf(psfWidth, psfWidth, psfSigma)
    psfImage = psf.computeImage(center).convertF()
    psfFlux = psfImage.getArray().sum()
    psfImage *= flux / psfFlux

    subImage = afwImage.ImageF(image, psfImage.getBBox(afwImage.PARENT),
                               afwImage.PARENT)
    subImage += psfImage

    exp = afwImage.makeExposure(afwImage.makeMaskedImage(image))
    exp.setPsf(psf)
    exp.getMaskedImage().getVariance().set(1.0)
    exp.getMaskedImage().getMask().set(0)

    cdMatrix = afwGeom.makeCdMatrix(scale=scale)
    exp.setWcs(
        afwGeom.makeSkyWcs(crpix=center,
                           crval=afwGeom.SpherePoint(0.0, 0.0,
                                                     afwGeom.degrees),
                           cdMatrix=cdMatrix))
    return exp, center
示例#44
0
def createFringe(width, height, xFreq, xOffset, yFreq, yOffset):
    """Create a fringe frame

    @param width, height    Size of image
    @param xFreq, yFreq     Frequency of sinusoids in x and y
    @param xOffset, yOffset Phase of sinusoids in x and y
    @return Fringe frame
    """
    image = afwImage.ImageF(width, height)
    array = image.getArray()
    x, y = numpy.indices(array.shape)
    array[x,y] = numpy.sin(xFreq*x + xOffset) + numpy.sin(yFreq*y + yOffset)
    mi = afwImage.makeMaskedImage(image)
    exp = afwImage.makeExposure(mi)
    exp.setFilter(afwImage.Filter('FILTER'))
    return exp
示例#45
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))
示例#46
0
    def test_BrighterFatterInterface(self):
        """Test brighter fatter correction interface using a delta function
        kernel on a flat image"""

        image = afwImage.ImageF(100, 100)
        image.set(100)
        ref_image = afwImage.ImageF(image, True)

        mi = afwImage.makeMaskedImage(image)
        exp = afwImage.makeExposure(mi)

        self.bfk.makeDetectorKernelFromAmpwiseKernels(self.detector.getName())
        kernelToUse = self.bfk.detKernels[self.detector.getName()]

        isrFunctions.brighterFatterCorrection(exp, kernelToUse, 5, 100, False)
        self.assertImagesEqual(ref_image, image)
示例#47
0
def createFringe(width, height, xFreq, xOffset, yFreq, yOffset):
    """Create a fringe frame

    @param width, height    Size of image
    @param xFreq, yFreq     Frequency of sinusoids in x and y
    @param xOffset, yOffset Phase of sinusoids in x and y
    @return Fringe frame
    """
    image = afwImage.ImageF(width, height)
    array = image.getArray()
    x, y = np.indices(array.shape)
    array[x, y] = np.sin(xFreq * x + xOffset) + np.sin(yFreq * y + yOffset)
    mi = afwImage.makeMaskedImage(image)
    exp = afwImage.makeExposure(mi)
    exp.setFilter(afwImage.Filter('FILTER'))
    return exp
    def testBrighterFatterInterface(self):
        """Test brighter fatter correction interface using a delta function kernel on a flat image"""

        image = afwImage.ImageF(100,100)
        image.set(100)
        ref_image = afwImage.ImageF(image, True)

        mi = afwImage.makeMaskedImage(image)
        exp = afwImage.makeExposure(mi)

        isrTask = ipIsr.IsrTask()
        with open(self.filename) as f:
                bfKernel = pickle.load(f)

        isrTask.brighterFatterCorrection(exp, bfKernel, 5, 100, False)
        self.assertTrue(numpy.all(ref_image.getArray() == image.getArray()))
示例#49
0
def makeGalaxy(width, height, flux, a, b, theta, dx=0.0, dy=0.0, xy0=None, xcen=None, ycen=None):
    """Make a fake galaxy image"""
    gal = afwImage.ImageF(width, height)
    if xcen is None:
        xcen = 0.5*width + dx
    if ycen is None:
        ycen = 0.5*height + dy
    I0 = flux/(2*math.pi*a*b)

    if xy0 is not None:
        gal.setXY0(xy0)

    c, s = math.cos(math.radians(theta)), math.sin(math.radians(theta))
    I, Iuu, Ivv = 0.0, 0.0, 0.0
    for y in range(height):
        for x in range(width):
            dx, dy = x + gal.getX0() - xcen, y + gal.getY0() - ycen
            if math.hypot(dx, dy) < 10.5:
                nsample = float(5)
                subZ = np.linspace(-0.5*(1 - 1/nsample), 0.5*(1 - 1/nsample), nsample)
            else:
                nsample = 1
                subZ = [0.0]

            val = 0
            for sx in subZ:
                for sy in subZ:
                    u =  c*(dx + sx) + s*(dy + sy)
                    v = -s*(dx + sx) + c*(dy + sy)
                    val += I0*math.exp(-0.5*((u/a)**2 + (v/b)**2))

            if val < 0:
                val = 0
            gal.set(x, y, val/nsample**2)

            I += val
            Iuu += val*u**2
            Ivv += val*v**2

    Iuu /= I; Ivv /= I

    exp = afwImage.makeExposure(afwImage.makeMaskedImage(gal))
    exp.getMaskedImage().getVariance().setXY0(exp.getXY0()) # workaround #2577
    exp.getMaskedImage().getVariance().set(1.0)
    exp.setWcs(afwImage.makeWcs(afwCoord.Coord(0.0*afwGeom.degrees, 0.0*afwGeom.degrees),
                                afwGeom.Point2D(0.0, 0.0), 1.0e-4, 0.0, 0.0, 1.0e-4))
    return exp
示例#50
0
    def transposeContext(self, maskedImage, defects):
        """Context manager to potentially transpose an image

        This applies the ``transpose`` configuration setting.

        Transposing the image allows us to interpolate along columns instead
        of rows, which is useful when the saturation trails are typically
        oriented along rows on the warped/coadded images, instead of along
        columns as they typically are in raw CCD images.

        Parameters
        ----------
        maskedImage : `lsst.afw.image.MaskedImage`
            Image on which to perform interpolation.
        defects : `lsst.meas.algorithms.Defects`
            List of defects to interpolate over.

        Yields
        ------
        useImage : `lsst.afw.image.MaskedImage`
            Image to use for interpolation; it may have been transposed.
        useDefects : `lsst.meas.algorithms.Defects`
            List of defects to use for interpolation; they may have been
            transposed.
        """
        def transposeImage(image):
            """Transpose an image"""
            transposed = image.array.T.copy(
            )  # Copy to force row-major; required for ndarray+pybind
            return image.Factory(transposed, False,
                                 lsst.geom.Point2I(*reversed(image.getXY0())))

        useImage = maskedImage
        useDefects = defects
        if self.config.transpose:
            useImage = afwImage.makeMaskedImage(
                transposeImage(maskedImage.image),
                transposeImage(maskedImage.mask),
                transposeImage(maskedImage.variance))
            useDefects = defects.transpose()
        yield useImage, useDefects
        if self.config.transpose:
            maskedImage.image.array = useImage.image.array.T
            maskedImage.mask.array = useImage.mask.array.T
            maskedImage.variance.array = useImage.variance.array.T
示例#51
0
    def std_raw(self, image, dataId):
        """Standardize a raw dataset by converting it to an Exposure instead of an Image"""
        if isinstance(image, afwImage.DecoratedImageU) or isinstance(image, afwImage.DecoratedImageI) or \
                isinstance(image, afwImage.DecoratedImageF) or isinstance(image, afwImage.DecoratedImageD):
            exposure = afwImage.makeExposure(afwImage.makeMaskedImage(image.getImage()))
        else:
            exposure = image
        md = image.getMetadata()

        if True:
            wcs = afwImage.makeWcs(md, True)

            # The CASU WCSes use ZPN; our stuff wants TAN
            # This won't work near the pole, but should be decent away from it.
            box = afwGeom.BoxD(image.getImage().getBBox())
            refPix = box.getCenter()
            refSky = wcs.pixelToSky(refPix)
            refSkyOffsetX = wcs.pixelToSky(refPix + afwGeom.Extent2D(1.0, 0.0))
            refSkyOffsetY = wcs.pixelToSky(refPix + afwGeom.Extent2D(0.0, 1.0))
            xPixelScale = refSky.angularSeparation(refSkyOffsetX).asDegrees()
            yPixelScale = refSky.angularSeparation(refSkyOffsetY).asDegrees()

            xPixelScale = yPixelScale = wcs.pixelScale().asDegrees()
        else:
            refPix = afwGeom.Point2D(md.get("CRPIX1"), md.get("CRPIX2"))
            refSky = afwCoord.IcrsCoord(md.get("CRVAL1")*afwGeom.degrees,
                                        md.get("CRVAL2")*afwGeom.degrees)
            xPixelScale = yPixelScale = (0.2*afwGeom.arcseconds).asDegrees()

#        import pdb;pdb.set_trace()

        exposure.setMetadata(md)
        #newWcs = afwImage.makeWcs(refSky, refPix, xPixelScale, 0.0, 0.0, yPixelScale)
        #wcs = afwImage.makeWcs(md, True)
        #exposure.setWcs(newWcs)
        exposure.setWcs(wcs)

        """ Set up exposure time """
        pathId = self._transformId(dataId)
        expTime = pathId['expTime']
        exposure.getCalib().setExptime(expTime)

        return self._standardizeExposure(self.exposures['raw'], exposure, dataId,
                                         trimmed=False)
示例#52
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
示例#53
0
    def transposeContext(self, maskedImage, defects):
        """Context manager to potentially transpose an image

        This applies the ``transpose`` configuration setting.

        Transposing the image allows us to interpolate along columns instead
        of rows, which is useful when the saturation trails are typically
        oriented along rows on the warped/coadded images, instead of along
        columns as they typically are in raw CCD images.

        Parameters
        ----------
        maskedImage : `lsst.afw.image.MaskedImage`
            Image on which to perform interpolation.
        defects : `lsst.meas.algorithms.Defects`
            List of defects to interpolate over.

        Yields
        ------
        useImage : `lsst.afw.image.MaskedImage`
            Image to use for interpolation; it may have been transposed.
        useDefects : `lsst.meas.algorithms.Defects`
            List of defects to use for interpolation; they may have been
            transposed.
        """
        def transposeImage(image):
            """Transpose an image"""
            transposed = image.array.T.copy()  # Copy to force row-major; required for ndarray+pybind
            return image.Factory(transposed, False, lsst.geom.Point2I(*reversed(image.getXY0())))

        useImage = maskedImage
        useDefects = defects
        if self.config.transpose:
            useImage = afwImage.makeMaskedImage(transposeImage(maskedImage.image),
                                                transposeImage(maskedImage.mask),
                                                transposeImage(maskedImage.variance))
            useDefects = defects.transpose()
        yield useImage, useDefects
        if self.config.transpose:
            maskedImage.image.array = useImage.image.array.T
            maskedImage.mask.array = useImage.mask.array.T
            maskedImage.variance.array = useImage.variance.array.T
def exposureFromImage(image):
    """Generate an exposure from a DecoratedImage or similar
    @param[in] image Image of interest
    @return (lsst.afw.image.Exposure) Exposure containing input image
    """
    if isinstance(image, afwImage.DecoratedImageU) or isinstance(image, afwImage.DecoratedImageI) or \
        isinstance(image, afwImage.DecoratedImageF) or isinstance(image, afwImage.DecoratedImageD):
        exposure = afwImage.makeExposure(afwImage.makeMaskedImage(image.getImage()))
    else:
        exposure = image
    md = image.getMetadata()
    exposure.setMetadata(md)
    wcs = afwImage.makeWcs(md)
    if wcs is not None:
        exposure.setWcs(wcs)
        wcsMetadata = wcs.getFitsMetadata()
        for kw in wcsMetadata.paramNames():
            md.remove(kw)

    return exposure
示例#55
0
def computeIntensity(imageR, imageG=None, imageB=None):
    """Return a naive total intensity from the red, blue, and green intensities

    Parameters
    ----------
    imageR : `lsst.afw.image.MaskedImage`, `lsst.afw.image.Image`, or `numpy.ndarray`, (Nx, Ny)
        intensity of image that'll be mapped to red; or intensity if imageG and imageB are None
    imageG : `lsst.afw.image.MaskedImage`, `lsst.afw.image.Image`, or `numpy.ndarray`, (Nx, Ny)
        intensity of image that'll be mapped to green; or None
    imageB : `lsst.afw.image.MaskedImage`, `lsst.afw.image.Image`, or `numpy.ndarray`, (Nx, Ny)
        intensity of image that'll be mapped to blue; or None

    Returns
    -------
    image : type of ``imageR``, ``imageG``, and `imageB``
    """
    if imageG is None or imageB is None:
        assert imageG is None and imageB is None, \
            "Please specify either a single image or red, green, and blue images"
        return imageR

    imageRGB = [imageR, imageG, imageB]

    for i, c in enumerate(imageRGB):
        if hasattr(c, "getImage"):
            c = imageRGB[i] = c.getImage()
        if hasattr(c, "getArray"):
            imageRGB[i] = c.getArray()

    intensity = (imageRGB[0] + imageRGB[1] + imageRGB[2])/float(3)
    #
    # Repack into whatever type was passed to us
    #
    Image = afwImage.ImageU if intensity.dtype == 'uint16' else afwImage.ImageF

    if hasattr(imageR, "getImage"):  # a maskedImage
        intensity = afwImage.makeMaskedImage(Image(intensity))
    elif hasattr(imageR, "getArray"):
        intensity = Image(intensity)

    return intensity
示例#56
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
示例#57
0
    def testMaskedImageFromImage(self):
        w, h = 10, 20
        dims = lsst.geom.Extent2I(w, h)
        im, mask, var = afwImage.ImageF(dims), \
            afwImage.Mask(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.image.getDimensions())
        self.assertEqual(im.getDimensions(),
                         maskedImage.mask.getDimensions())
        self.assertEqual(im.getDimensions(),
                         maskedImage.variance.getDimensions())

        self.assertEqual(maskedImage[0, 0, afwImage.LOCAL], (im[0, 0, afwImage.LOCAL], 0x0, 0.0))
示例#58
0
    def run(self, sensorRefList, *args, **kwargs):
        """Mask vignetted pixels after combining

        This returns an Exposure instead of an Image, but upstream shouldn't
        care, as it just dumps it out via the Butler.
        """
        combined = super(HscFlatCombineTask, self).run(sensorRefList, *args, **kwargs)
        mi = afwImage.makeMaskedImage(combined.getImage())
        mi.getMask().set(0)

        # Retrieve the detector
        # XXX It's unfortunate that we have to read an entire image to get the detector, but there's no
        # public API in the butler to get the same.
        image = sensorRefList[0].get("postISRCCD")
        detector = image.getDetector()
        del image

        self.maskVignetting(mi.getMask(), detector)
        self.maskBadAmps(mi.getMask(), detector)

        return afwImage.makeExposure(mi)
示例#59
0
    def test1295(self):
        """A test case for #1295 (failure to interpolate over groups of defects"""

        im = afwImage.ImageF(afwGeom.ExtentI(100, 100))
        mi = afwImage.makeMaskedImage(im)
        mi.set(100)
        flat = afwImage.ImageF(im.getDimensions())
        flat.set(1)
        for i in range(100):
            for j in range(100):
                if i == 50 or i == 55 or i == 58:
                    flat.set(i,j,0)
                if i < 60 and i > 50 and j > 50:
                    flat.set(i,j,0)

        mi /= flat

        if display:
            ds9.mtv(mi, frame=0, title="Raw")

        defectList = algorithms.DefectListT()
        bbox = afwGeom.BoxI(afwGeom.PointI(50,0), afwGeom.ExtentI(1,100))
        defectList.append(algorithms.Defect(bbox))
        bbox = afwGeom.BoxI(afwGeom.PointI(55,0), afwGeom.ExtentI(1,100))
        defectList.append(algorithms.Defect(bbox))
        bbox = afwGeom.BoxI(afwGeom.PointI(58,0), afwGeom.ExtentI(1,100))
        defectList.append(algorithms.Defect(bbox))
        bbox = afwGeom.BoxI(afwGeom.PointI(51,51), afwGeom.ExtentI(9,49))
        defectList.append(algorithms.Defect(bbox))

        psf = algorithms.DoubleGaussianPsf(15, 15, 1./(2*math.sqrt(2*math.log(2))))
        algorithms.interpolateOverDefects(mi, psf, defectList, 50.)

        if display:
            ds9.mtv(mi, frame=1, title="Interpolated")

        self.assertTrue(numpy.isfinite(mi.getImage().get(56, 51)))