Ejemplo n.º 1
0
 def testRemoveMaskPlane(self):
     mMask = self.mMask1
     # Add mask plane FOO and make sure it got added properly
     mMask.addMaskPlane("FOO")
     self.assertIn("FOO", mMask.getMaskPlaneDict())
     self.assertIn("FOO", Mask().getMaskPlaneDict())
     # Remove plane FOO, noting that removeMaskPlane removes it from the
     # default, but each instance remembers the version of the mask
     # dictionary that was current when it was created, so it will still
     # be in the mMask dict.
     mMask.removeMaskPlane("FOO")
     self.assertIn("FOO", mMask.getMaskPlaneDict())
     self.assertNotIn("FOO", Mask().getMaskPlaneDict())
Ejemplo n.º 2
0
 def __init__(self, *args, **kwargs):
     pipeBase.Task.__init__(self, *args, **kwargs)
     self._badPixelMask = Mask.getPlaneBitMask(self.config.badMaskPlanes)
     self._statsControl = afwMath.StatisticsControl()
     self._statsControl.setNumSigmaClip(self.config.numSigmaClip)
     self._statsControl.setNumIter(self.config.numIter)
     self._statsControl.setAndMask(self._badPixelMask)
Ejemplo n.º 3
0
 def testMaskFitsReader(self):
     maskIn = Mask(self.bbox, dtype=MaskPixel)
     maskIn.array[:, :] = np.random.randint(low=1, high=5, size=maskIn.array.shape)
     with lsst.utils.tests.getTempFilePath(".fits") as fileName:
         maskIn.writeFits(fileName)
         reader = MaskFitsReader(fileName)
         self.assertEqual(reader.readBBox(), self.bbox)
         self.assertEqual(reader.readDType(), MaskPixel)
         self.assertEqual(reader.fileName, fileName)
         for args in self.args:
             with self.subTest(args=args):
                 array = reader.readArray(*args)
                 mask = reader.read(*args)
                 subIn = maskIn.subset(*args) if args else maskIn
                 self.assertEqual(MaskPixel, array.dtype)
                 self.assertTrue(np.all(subIn.array == array))
                 self.assertEqual(subIn.getXY0(), reader.readXY0(*args))
                 self.assertImagesEqual(subIn, mask)
Ejemplo n.º 4
0
def getSpanSetFromImages(images, thresh=0, xy0=None):
    """Create a Footprint from a set of Images

    Parameters
    ----------
    images: `MultibandImage` or list of `Image`, array
        Images to extract the footprint from
    thresh: `float`
        All pixels above `thresh` will be included in the footprint
    xy0: `Point2I`
        Location of the minimum value of the images bounding box
        (if images is an array, otherwise the image bounding box is used).

    Returns
    -------
    spans: `SpanSet`
        Union of all spans in the images above the threshold
    imageBBox: `Box2I`
        Bounding box for the input images.
    """
    # Set the threshold for each band
    if not hasattr(thresh, "__len__"):
        thresh = [thresh] * len(images)

    # If images is a list of `afw Image` objects then
    # merge the SpanSet in each band into a single Footprint
    if isinstance(images, MultibandBase) or isinstance(images[0], Image):
        spans = SpanSet()
        for n, image in enumerate(images):
            mask = image.array > thresh[n]
            mask = Mask(mask.astype(np.int32), xy0=image.getBBox().getMin())
            spans = spans.union(SpanSet.fromMask(mask))
        imageBBox = images[0].getBBox()
    else:
        # Use thresh to detect the pixels above the threshold in each band
        thresh = np.array(thresh)
        if xy0 is None:
            xy0 = Point2I(0, 0)
        mask = np.any(images > thresh[:, None, None], axis=0)
        mask = Mask(mask.astype(np.int32), xy0=xy0)
        spans = SpanSet.fromMask(mask)
        imageBBox = mask.getBBox()
    return spans, imageBBox
Ejemplo n.º 5
0
 def testRemoveAndClearMaskPlane(self):
     mMask = self.mMask1
     # Add mask plane FOO and test clearing it without removing plane from
     # default dict
     mMask.addMaskPlane("FOO")
     mMask.removeAndClearMaskPlane("FOO")
     self.assertNotIn("FOO", mMask.getMaskPlaneDict())
     self.assertIn("FOO", Mask().getMaskPlaneDict())
     # Now also remove it from default dict
     mMask.addMaskPlane("FOO")
     mMask.removeAndClearMaskPlane("FOO", removeFromDefault=True)
     self.assertNotIn("FOO", mMask.getMaskPlaneDict())
     self.assertNotIn("FOO", Mask().getMaskPlaneDict())
     # Now remove and clear the EDGE mask plane and make sure all of the planes
     # in the MultibandMask (i.e. the "singles") got updated accordingly
     mMask.removeAndClearMaskPlane("EDGE", removeFromDefault=True)
     self.assertNotIn("EDGE", mMask.getMaskPlaneDict())
     self.assertNotIn("EDGE", Mask().getMaskPlaneDict())
     # Assert that all mask planes were updated (i.e. having EDGE removed)
     self.assertTrue(
         np.all([
             s.array == self.values1[n] & ~self.EDGE
             for n, s in enumerate(mMask.singles)
         ]))
Ejemplo n.º 6
0
def getSpanSetFromImages(images, thresh=0, xy0=None):
    """Create a Footprint from a set of Images

    Parameters
    ----------
    images: `MultibandImage` or list of `Image`, array
        Images to extract the footprint from
    thresh: `float`
        All pixels above `thresh` will be included in the footprint
    xy0: `Point2I`
        Location of the minimum value of the images bounding box
        (if images is an array, otherwise the image bounding box is used).

    Returns
    -------
    spans: `SpanSet`
        Union of all spans in the images above the threshold
    imageBBox: `Box2I`
        Bounding box for the input images.
    """
    # Set the threshold for each band
    if not hasattr(thresh, "__len__"):
        thresh = [thresh] * len(images)

    # If images is a list of `afw Image` objects then
    # merge the SpanSet in each band into a single Footprint
    if isinstance(images, MultibandBase) or isinstance(images[0], Image):
        spans = SpanSet()
        for n, image in enumerate(images):
            mask = image.array > thresh[n]
            mask = Mask(mask.astype(np.int32), xy0=image.getBBox().getMin())
            spans = spans.union(SpanSet.fromMask(mask))
        imageBBox = images[0].getBBox()
    else:
        # Use thresh to detect the pixels above the threshold in each band
        thresh = np.array(thresh)
        if xy0 is None:
            xy0 = Point2I(0, 0)
        mask = np.any(images > thresh[:, None, None], axis=0)
        mask = Mask(mask.astype(np.int32), xy0=xy0)
        spans = SpanSet.fromMask(mask)
        imageBBox = mask.getBBox()
    return spans, imageBBox
Ejemplo n.º 7
0
 def testMaskFitsReader(self):
     maskIn = Mask(self.bbox, dtype=MaskPixel)
     maskIn.array[:, :] = np.random.randint(low=1,
                                            high=5,
                                            size=maskIn.array.shape)
     with lsst.utils.tests.getTempFilePath(".fits") as fileName:
         maskIn.writeFits(fileName)
         reader = MaskFitsReader(fileName)
         self.assertEqual(reader.readBBox(), self.bbox)
         self.assertEqual(reader.readDType(), MaskPixel)
         self.assertEqual(reader.fileName, fileName)
         for args in self.args:
             with self.subTest(args=args):
                 array = reader.readArray(*args)
                 mask = reader.read(*args)
                 subIn = maskIn.subset(*args) if args else maskIn
                 self.assertEqual(MaskPixel, array.dtype)
                 self.assertTrue(np.all(subIn.array == array))
                 self.assertEqual(subIn.getXY0(), reader.readXY0(*args))
                 self.assertImagesEqual(subIn, mask)
Ejemplo n.º 8
0
def modelToHeavy(source, mExposure, blend, xy0=Point2I(), dtype=np.float32):
    """Convert a scarlet model to a `MultibandFootprint`.

    Parameters
    ----------
    source : `scarlet.Component`
        The source to convert to a `HeavyFootprint`.
    mExposure : `lsst.image.MultibandExposure`
        The multiband exposure containing the image,
        mask, and variance data.
    blend : `scarlet.Blend`
        The `Blend` object that contains information about
        the observation, PSF, etc, used to convolve the
        scarlet model to the observed seeing in each band.
    xy0 : `lsst.geom.Point2I`
        `(x,y)` coordinates of the lower-left pixel of the
        entire blend.
    dtype : `numpy.dtype`
        The data type for the returned `HeavyFootprint`.

    Returns
    -------
    mHeavy : `lsst.detection.MultibandFootprint`
        The multi-band footprint containing the model for the source.
    """
    # We want to convolve the model with the observed PSF,
    # which means we need to grow the model box by the PSF to
    # account for all of the flux after convolution.
    # FYI: The `scarlet.Box` class implements the `&` operator
    # to take the intersection of two boxes.

    # Get the PSF size and radii to grow the box
    py, px = blend.observations[0].psf.get_model().shape[1:]
    dh = py // 2
    dw = px // 2
    shape = (source.bbox.shape[0], source.bbox.shape[1] + py,
             source.bbox.shape[2] + px)
    origin = (source.bbox.origin[0], source.bbox.origin[1] - dh,
              source.bbox.origin[2] - dw)
    # Create the larger box to fit the model + PSf
    bbox = Box(shape, origin=origin)
    # Only use the portion of the convolved model that fits in the image
    overlap = bbox & source.frame.bbox
    # Load the full multiband model in the larger box
    model = source.model_to_box(overlap)
    # Convolve the model with the PSF in each band
    # Always use a real space convolution to limit artifacts
    model = blend.observations[0].renderer.convolve(
        model, convolution_type="real").astype(dtype)
    # Update xy0 with the origin of the sources box
    xy0 = Point2I(overlap.origin[-1] + xy0.x, overlap.origin[-2] + xy0.y)
    # Create the spans for the footprint
    valid = np.max(np.array(model), axis=0) != 0
    valid = Mask(valid.astype(np.int32), xy0=xy0)
    spans = SpanSet.fromMask(valid)

    # Add the location of the source to the peak catalog
    peakCat = PeakCatalog(source.detectedPeak.table)
    peakCat.append(source.detectedPeak)
    # Create the MultibandHeavyFootprint
    foot = Footprint(spans)
    foot.setPeakCatalog(peakCat)
    model = MultibandImage(mExposure.filters, model, valid.getBBox())
    mHeavy = MultibandFootprint.fromImages(mExposure.filters,
                                           model,
                                           footprint=foot)
    return mHeavy