Esempio n. 1
0
def run(frame=6):
    im = afwImage.MaskedImageF(afwGeom.Extent2I(14, 10))
    #
    # Populate the image with objects that we should detect
    #
    objects = []
    objects.append([(4, 1, 10), (3, 2, 10), (4, 2, 20), (5, 2, 10), (4, 3, 10),])
    objects.append([(9, 7, 30), (10, 7, 29), (12, 7, 28), (10, 8, 27), (11, 8, 26), (10, 4, -5)])
    objects.append([(3, 8, 10), (4, 8, 10),])

    for obj in objects:
        for x, y, I in obj:
            im.getImage().set(x, y, I)

    im.getVariance().set(1)
    im.getVariance().set(10, 4, 0.5**2)
    #
    # Detect the objects at 10 counts or above
    #
    level = 10
    fs = afwDetect.FootprintSet(im, afwDetect.Threshold(level), "DETECTED")

    showPeaks(im, fs, frame=frame)
    #
    # Detect the objects at -10 counts or below.  N.b. the peak's at -5, so it isn't detected
    #
    polarity = False                     # look for objects below background
    threshold = afwDetect.Threshold(level, afwDetect.Threshold.VALUE, polarity)
    fs2 = afwDetect.FootprintSet(im, threshold, "DETECTED_NEGATIVE")
    print("Detected %d objects below background" % len(fs2.getFootprints()))
    #
    # Search in S/N (n.b. the peak's -10sigma)
    #
    threshold = afwDetect.Threshold(level, afwDetect.Threshold.PIXEL_STDEV, polarity)
    fs2 = afwDetect.FootprintSet(im, threshold)
    #
    # Here's another way to set a mask plane (we chose not to do so in the FootprintSet call)
    #
    msk = im.getMask()
    afwDetect.setMaskFromFootprintList(msk, fs2.getFootprints(), msk.getPlaneBitMask("DETECTED_NEGATIVE"))

    if frame is not None:
        ds9.mtv(msk, isMask=True, frame=frame)
    #
    # Merge the positive and negative detections, growing both sets by 1 pixel
    #
    fs.merge(fs2, 1, 1)
    #
    # Set EDGE so we can see the grown Footprints
    #
    afwDetect.setMaskFromFootprintList(msk, fs.getFootprints(), msk.getPlaneBitMask("EDGE"))

    if frame is not None:
        ds9.mtv(msk, isMask=True, frame=frame)

    showPeaks(fs=fs, frame=frame)
Esempio n. 2
0
    def setUp(self):
        """Build up three different sets of objects that are to be merged"""
        pos1 = [(40, 40), (220, 35), (40, 48), (220, 50),
                (67, 67), (150, 50), (40, 90), (70, 160),
                (35, 255), (70, 180), (250, 200), (120, 120),
                (170, 180), (100, 210), (20, 210),
                ]
        pos2 = [(43, 45), (215, 31), (171, 258), (211, 117),
                (48, 99), (70, 160), (125, 45), (251, 33),
                (37, 170), (134, 191), (79, 223), (258, 182)
                ]
        pos3 = [(70, 170), (219, 41), (253, 173), (253, 192)]

        box = lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Point2I(300, 300))
        psfsig = 1.
        kernelSize = 41
        flux = 1000

        # Create a different sized psf for each image and insert them at the
        # desired positions
        im1 = afwImage.MaskedImageD(box)
        psf1 = afwDetect.GaussianPsf(kernelSize, kernelSize, psfsig)

        im2 = afwImage.MaskedImageD(box)
        psf2 = afwDetect.GaussianPsf(kernelSize, kernelSize, 2*psfsig)

        im3 = afwImage.MaskedImageD(box)
        psf3 = afwDetect.GaussianPsf(kernelSize, kernelSize, 1.3*psfsig)

        insertPsf(pos1, im1, psf1, kernelSize, flux)
        insertPsf(pos2, im2, psf2, kernelSize, flux)
        insertPsf(pos3, im3, psf3, kernelSize, flux)

        schema = afwTable.SourceTable.makeMinimalSchema()
        self.idFactory = afwTable.IdFactory.makeSimple()
        self.table = afwTable.SourceTable.make(schema, self.idFactory)

        # Create SourceCatalogs from these objects
        fp1 = afwDetect.FootprintSet(
            im1, afwDetect.Threshold(0.001), "DETECTED")
        self.catalog1 = afwTable.SourceCatalog(self.table)
        fp1.makeSources(self.catalog1)

        fp2 = afwDetect.FootprintSet(
            im2, afwDetect.Threshold(0.001), "DETECTED")
        self.catalog2 = afwTable.SourceCatalog(self.table)
        fp2.makeSources(self.catalog2)

        fp3 = afwDetect.FootprintSet(
            im3, afwDetect.Threshold(0.001), "DETECTED")
        self.catalog3 = afwTable.SourceCatalog(self.table)
        fp3.makeSources(self.catalog3)
Esempio n. 3
0
def clipImage(im, minClip, maxClip):
    """Clip an image to lie between minClip and maxclip (None to ignore)"""

    if re.search("::MaskedImage<", im.__repr__()):
        mi = im
    else:
        mi = afwImage.makeMaskedImage(im, afwImage.MaskU(im.getDimensions()))

    if minClip is not None:
        ds = afwDetect.FootprintSet(mi, afwDetect.Threshold(-minClip, afwDetect.Threshold.VALUE, False))
        afwDetect.setImageFromFootprintList(mi.getImage(), ds.getFootprints(), minClip)

    if maxClip is not None:
        ds = afwDetect.FootprintSet(mi, afwDetect.Threshold(maxClip))
        afwDetect.setImageFromFootprintList(mi.getImage(), ds.getFootprints(), maxClip)
Esempio n. 4
0
def detector_crosstalk(ccd, aggressor_amp, dnthresh=None, nsig=5,
                       signal_extractor=extract_mean_signal,
                       min_fp_size=50):
    """
    Compute detector crosstalk from a spot image in the aggressor
    amplifier. dnthresh is the threshold in DN for detecting the
    illuminated column in the aggressor amplifier; if set to None,
    then nsig*clipped_stdev above median is used for the threshold.
    """
    image = ccd.unbiased_and_trimmed_image(aggressor_amp)
    #
    # Extract footprint of spot image using nominal detection
    # threshold.
    #
    if dnthresh is None:
        median, stdev = get_stats(image, ccd.stat_ctrl)
#        dnthresh = median + nsig*stdev
        dnthresh = (np.max(image.getImage().getArray())
                    + median)/2.
#    print "dnthresh =", dnthresh
    threshold = afwDetect.Threshold(dnthresh)
    fp_set = afwDetect.FootprintSet(image, threshold)
    try:
        footprint, peak_value = get_footprint(fp_set, min_fp_size, dnthresh)
    except IndexError:
        raise RuntimeError('index error in get_footprint')

    agg_mean = signal_extractor(ccd, aggressor_amp, footprint)[0]
    ratios = dict([(amp, signal_extractor(ccd, amp, footprint)
                    / agg_mean) for amp in ccd])
#    for amp in ratios:
#        if ratios[amp][0] > 0.1:
#            ratios[amp] = (0, 0)
    return ratios
Esempio n. 5
0
    def testMergeFootprints(self):      # YYYY
        """Merge positive and negative Footprints"""
        x0, y0 = 5, 6
        dwidth, dheight = 6, 7
        def callback():
            x, y, I = x0 + 10, y0 + 4, -20
            self.im.getImage().set(x, y, I)
            peaks2.append((x, y, I))

        for grow1, grow2 in [(1, 1), (3, 3), (6, 6), ]:
            peaks2 = []
            self.doTestPeaks(threshold=10, callback=callback, grow=0, x0=x0, y0=y0, dwidth=dwidth, dheight=dheight)

            threshold = afwDetect.Threshold(10, afwDetect.Threshold.VALUE, False)
            fs2 = afwDetect.FootprintSet(self.im, threshold)
            
            msk = self.im.getMask()
            afwDetect.setMaskFromFootprintList(msk, fs2.getFootprints(), msk.getPlaneBitMask("DETECTED_NEGATIVE"))

            self.fs.merge(fs2, grow1, grow2)
            self.peaks[-2] += peaks2

            if grow1 + grow2 > 2:                                                         # grow merged all peaks
                self.peaks[0] = sorted(sum(self.peaks, []), lambda x, y: cmpPeaks(self.im, x, y))

            afwDetect.setMaskFromFootprintList(msk, self.fs.getFootprints(), msk.getPlaneBitMask("EDGE"))

            self.checkPeaks(frame=3)
Esempio n. 6
0
    def doTestPeaks(self, dwidth=0, dheight=0, x0=0, y0=0, threshold=10, callback=None, polarity=True, grow=0):
        """Worker routine for tests
        polarity:  True if should search for +ve pixels"""
        
        self.doSetUp(dwidth, dheight, x0, y0)
        if not polarity:
            self.im *= -1
            
        if callback:
            callback()
        #
        # Sort self.peaks in decreasing peak height to match Footprint.getPeaks()
        #
        for i, peaks in enumerate(self.peaks):
            self.peaks[i] = sorted([(x, y, self.im.getImage().get(x, y)) for x, y in peaks],
                                   lambda x, y: cmpPeaks(self.im, x, y))

        threshold = afwDetect.Threshold(threshold, afwDetect.Threshold.VALUE, polarity)
        fs = afwDetect.FootprintSet(self.im, threshold, "BINNED1")

        if grow:
            fs = afwDetect.FootprintSet(fs, grow, True)
            msk = self.im.getMask()
            afwDetect.setMaskFromFootprintList(msk, fs.getFootprints(), msk.getPlaneBitMask("DETECTED"))
            del msk

        self.fs = fs
        self.checkPeaks(dwidth, dheight, frame=3)
Esempio n. 7
0
def remove_small_sources_thresholding(exposure, min_radius_arcsec, 
                                      random_state=None):

    mi = exposure.getMaskedImage()
    mask = mi.getMask()
    noise_array = utils.make_noise_image(mi, random_state)

    threshold = afwDet.Threshold(mask.getPlaneBitMask(['DETECTED']))
    fp_det = afwDet.FootprintSet(mask, threshold, afwDet.Threshold.BITMASK)
    area_min = np.pi * (min_radius_arcsec / utils.pixscale)**2 

    fp_list = []
    for fp in fp_det.getFootprints():
        if fp.getArea() < area_min:
            fp_list.append(fp)     
    fp_small = afwDet.FootprintSet(mi.getBBox())
    fp_small.setFootprints(fp_list)
    mask.addMaskPlane('SMALL')
    fp_small.setMask(mask, 'SMALL')

    exp_clean = exposure.clone()
    mi_clean = exp_clean.getMaskedImage()
    replace = mask.getArray() & mask.getPlaneBitMask('SMALL') != 0
    mi_clean = exp_clean.getMaskedImage()
    mi_clean.getImage().getArray()[replace] = noise_array[replace]

    return exp_clean
Esempio n. 8
0
def clean_use_hsc_mask(exposure, ref_plane='THRESH_HIGH', rgrow=None, 
                       random_state=None, bright_object_mask=True):

    # generate array of gaussian noise
    mi = exposure.getMaskedImage()
    mask = mi.getMask()
    noise_array = utils.make_noise_image(mi, random_state)
    
    threshold = afwDet.Threshold(mask.getPlaneBitMask(['DETECTED']))
    fp_det = afwDet.FootprintSet(mask, threshold, afwDet.Threshold.BITMASK)

    fp_list = []
    for fp in fp_det.getFootprints():
        hfp = afwDet.HeavyFootprintF(fp, mi)
        pix = hfp.getMaskArray()
        check = (pix & mask.getPlaneBitMask(ref_plane)!=0).sum()
        if check > 0:
            fp_list.append(fp)     
    fpset_replace = afwDet.FootprintSet(mi.getBBox())
    fpset_replace.setFootprints(fp_list)
    if rgrow:
        fpset_replace = afwDet.FootprintSet(fpset_replace, rgrow, True)
    mask.addMaskPlane('CLEANED')
    fpset_replace.setMask(mask, 'CLEANED')

    exp_clean = exposure.clone()
    mi_clean = exp_clean.getMaskedImage()
    replace = mask.getArray() & mask.getPlaneBitMask('CLEANED') != 0
    if bright_object_mask:
        replace |= mask.getArray() & mask.getPlaneBitMask('BRIGHT_OBJECT') != 0
    mi_clean.getImage().getArray()[replace] = noise_array[replace]

    return exp_clean
Esempio n. 9
0
    def testFootprintPeaks(self):
        """Test that we can extract the peaks from a Footprint"""
        fs = afwDetect.FootprintSet(self.ms, afwDetect.Threshold(10), "OBJECT")

        foot = fs.getFootprints()[0]

        self.assertEqual(len(foot.getPeaks()), 5)
Esempio n. 10
0
    def processSingle(self, sensorRef):
        """Process a single CCD

        Besides the regular ISR, also masks cosmic-rays and divides each
        processed image by the dark time to generate images of the dark rate.
        The dark time is provided by the 'getDarkTime' method.
        """
        exposure = CalibTask.processSingle(self, sensorRef)

        if self.config.doRepair:
            psf = measAlg.DoubleGaussianPsf(
                self.config.psfSize, self.config.psfSize,
                self.config.psfFwhm / (2 * math.sqrt(2 * math.log(2))))
            exposure.setPsf(psf)
            self.repair.run(exposure, keepCRs=False)
            if self.config.crGrow > 0:
                mask = exposure.getMaskedImage().getMask().clone()
                mask &= mask.getPlaneBitMask("CR")
                fpSet = afwDet.FootprintSet(mask, afwDet.Threshold(0.5))
                fpSet = afwDet.FootprintSet(fpSet, self.config.crGrow, True)
                fpSet.setMask(exposure.getMaskedImage().getMask(), "CR")

        mi = exposure.getMaskedImage()
        mi /= self.getDarkTime(exposure)
        return exposure
Esempio n. 11
0
def find_channels_with_saturation(eimage, full_well):
    """
    Find all channels in an eimage that have pixel values above full
    well.

    Parameters
    ----------
    eimage: lsst.afw.image.ImageF
        The "eimage" containing the image data in units of electrons per
        pixel.  This is the image prior to electronic readout (i.e.,
        conversion to ADU, addition of bias, dark current, crosstalk, etc.).
        For LSST CCDs, the eimages have parallel transfer directions along
        the x-axis, hence channels correspond to rows in eimages.
    full_well: int
        The pixel full well/saturation value in electrons.

    Returns
    -------
    set of ints:  The y-indices of the channels with saturated pixels.
    """
    threshold = afw_detect.Threshold(full_well)
    fp_set = afw_detect.FootprintSet(eimage, threshold)
    channels = []
    for fp in fp_set.getFootprints():
        for span in fp.spans:
            channels.append(span.getY())
    return set(channels)
Esempio n. 12
0
    def testMakeHeavy(self):
        """Test that we can make a FootprintSet heavy"""
        fs = afwDetect.FootprintSet(self.mi, afwDetect.Threshold(1))

        ctrl = afwDetect.HeavyFootprintCtrl(afwDetect.HeavyFootprintCtrl.NONE)
        fs.makeHeavy(self.mi, ctrl)

        if display:
            ds9.mtv(self.mi, frame=0, title="input")
            #ds9.mtv(omi, frame=1, title="output")

        omi = self.mi.Factory(self.mi.getDimensions())

        for foot in fs.getFootprints():
            self.assertNotEqual(afwDetect.cast_HeavyFootprint(foot, self.mi),
                                None)
            afwDetect.cast_HeavyFootprint(foot, self.mi).insert(omi)

        for foot in fs.getFootprints():
            self.assertNotEqual(afwDetect.HeavyFootprintF.cast(foot), None)
            afwDetect.HeavyFootprintF.cast(foot).insert(omi)

        self.assertTrue(
            np.all(
                np.equal(self.mi.getImage().getArray(),
                         omi.getImage().getArray())))
Esempio n. 13
0
 def gain(self, amp, jmargin=None, max_npix=9, buff=1):
     if jmargin is None:
         jmargins = list(range(10))
     else:
         jmargins = (jmargin, )
     self._generate_stats(amp)
     values = []
     fp_sets = []
     for j in jmargins:
         margin = self.noise * (j + 3)
         threshold = afwDetect.Threshold(self.median + margin)
         fp_set = afwDetect.FootprintSet(self.ccd[amp], threshold)
         fp_sets.append(fp_set)
         signals = [
             self._footprint_signal(fp, buff)
             for fp in fp_set.getFootprints() if fp.getNpix() < max_npix
         ]
         try:
             stats = afwMath.makeStatistics(signals, afwMath.MEANCLIP)
             mean = stats.getValue()
             values.append(self.fe55_yield / mean)
         except:
             pass
     my_gain = np.median(values)
     return my_gain
Esempio n. 14
0
    def testGrowCircular(self):
        """Grow footprints in all 4 directions using the FootprintSet/FootprintControl constructor """
        im = afwImage.MaskedImageF(11, 11)
        im[5, 5, afwImage.LOCAL] = (10, 0x0, 0.0)
        fs = afwDetect.FootprintSet(im, afwDetect.Threshold(10))
        self.assertEqual(len(fs.getFootprints()), 1)

        radius = 3  # How much to grow by
        for fctrl in (
                afwDetect.FootprintControl(),
                afwDetect.FootprintControl(True),
                afwDetect.FootprintControl(True, True),
        ):
            grown = afwDetect.FootprintSet(fs, radius, fctrl)
            afwDetect.setMaskFromFootprintList(im.getMask(),
                                               grown.getFootprints(), 0x10)

            if display:
                ds9.mtv(im)

            foot = grown.getFootprints()[0]

            if not fctrl.isCircular()[0]:
                self.assertEqual(foot.getArea(), 1)
            elif fctrl.isCircular()[0]:
                assert radius == 3
                if fctrl.isIsotropic()[1]:
                    self.assertEqual(foot.getArea(), 29)
                else:
                    self.assertEqual(foot.getArea(), 25)
Esempio n. 15
0
    def setUp(self):
        config = SingleFrameMeasurementTask.ConfigClass()
        config.slots.apFlux = 'base_CircularApertureFlux_12_0'
        self.schema = afwTable.SourceTable.makeMinimalSchema()

        self.measureSources = SingleFrameMeasurementTask(self.schema,
                                                         config=config)

        bbox = afwGeom.BoxI(afwGeom.PointI(0, 0),
                            afwGeom.ExtentI(self.width, self.height))
        self.cellSet = afwMath.SpatialCellSet(bbox, 100)

        self.footprintSet = afwDetection.FootprintSet(
            self.mi, afwDetection.Threshold(self.detectThresh), "DETECTED")

        self.catalog = self.measure(self.footprintSet, self.exposure)

        for source in self.catalog:
            try:
                cand = measAlg.makePsfCandidate(source, self.exposure)
                self.cellSet.insertCandidate(cand)

            except Exception as e:
                print(e)
                continue
Esempio n. 16
0
def makeThresholdMask(maskedImage,
                      threshold,
                      growFootprints=1,
                      maskName='SAT'):
    """Mask pixels based on threshold detection

    @param[in,out] maskedImage  afw.image.MaskedImage to process; the mask is altered
    @param[in] threshold  detection threshold
    @param[in] growFootprints  amount by which to grow footprints of detected regions
    @param[in] maskName  mask plane name
    @return a list of defects (meas.algrithms.Defect) of regions set in the mask.
    """
    # find saturated regions
    thresh = afwDetection.Threshold(threshold)
    fs = afwDetection.FootprintSet(maskedImage, thresh)

    if growFootprints > 0:
        fs = afwDetection.FootprintSet(fs, growFootprints)

    fpList = fs.getFootprints()
    # set mask
    mask = maskedImage.getMask()
    bitmask = mask.getPlaneBitMask(maskName)
    afwDetection.setMaskFromFootprintList(mask, fpList, bitmask)

    return defectListFromFootprintList(fpList, growFootprints=0)
Esempio n. 17
0
    def testMergeFootprintsEngulf(self):
        """Merge two Footprints when growing one Footprint totally replaces the other"""
        def callback():
            self.im.set(0)
            self.peaks, self.objects = [], []

            for x, y, I in [[6, 4, 20], [6, 5, 10]]:
                self.im.getImage().set(x, y, I)
            self.peaks.append([[6, 4]])

            x, y, I = 8, 4, -20
            self.im.getImage().set(x, y, I)
            peaks2.append((x, y, I))

        grow1, grow2 = 0, 3
        peaks2 = []
        self.doTestPeaks(threshold=10, callback=callback, grow=0)

        threshold = afwDetect.Threshold(10, afwDetect.Threshold.VALUE, False)
        fs2 = afwDetect.FootprintSet(self.im, threshold)

        msk = self.im.getMask()
        afwDetect.setMaskFromFootprintList(
            msk, fs2.getFootprints(), msk.getPlaneBitMask("DETECTED_NEGATIVE"))

        self.fs.merge(fs2, grow1, grow2)
        self.peaks[0] += peaks2

        self.peaks[0] = sorted(sum(self.peaks, []),
                               lambda x, y: cmpPeaks(self.im, x, y))

        afwDetect.setMaskFromFootprintList(msk, self.fs.getFootprints(),
                                           msk.getPlaneBitMask("EDGE"))

        self.checkPeaks(frame=3)
Esempio n. 18
0
def detectObjectsInExp(exp, nSigma=10, nPixMin=10, grow=0):
    """Quick and dirty object detection for an expsure.

    Return the footPrintSet for the objects in a preferably-postISR exposure.

    Parameters
    ----------
    exp : `lsst.afw.image.Exposure`
        The exposure to detect objects in.
    nSigma : `float`
        The number of sigma for detection.
    nPixMin : `int`
        The minimum number of pixels in an object for detection.
    grow : `int`
        The number of pixels to grow the footprint by after detection.

    Returns
    -------
    footPrintSet : `lsst.afw.detection.FootprintSet`
        The set of footprints in the image.
    """
    median = np.nanmedian(exp.image.array)
    exp.image -= median

    threshold = afwDetect.Threshold(nSigma, afwDetect.Threshold.STDEV)
    footPrintSet = afwDetect.FootprintSet(exp.getMaskedImage(), threshold, "DETECTED", nPixMin)
    if grow > 0:
        isotropic = True
        footPrintSet = afwDetect.FootprintSet(footPrintSet, grow, isotropic)

    exp.image += median  # add back in to leave background unchanged
    return footPrintSet
Esempio n. 19
0
    def createCandidate(self, threshold=0.1):
        """Create a PSF candidate from self.exp

        @param threshold: Threshold for creating footprints on image
        """

        source = self.catalog.addNew()
        fpSet = afwDet.FootprintSet(self.exp.getMaskedImage(),
                                    afwDet.Threshold(threshold), "DETECTED")
        if display:
            ds9.mtv(self.exp, frame=1)
            for fp in fpSet.getFootprints():
                for peak in fp.getPeaks():
                    ds9.dot("x", peak.getIx(), peak.getIy(), frame=1)

        # There might be multiple footprints; only the one around self.x,self.y should go in the source
        found = False
        for fp in fpSet.getFootprints():
            if fp.contains(afwGeom.Point2I(self.x, self.y)):
                found = True
                break
        self.assertTrue(
            found, "Unable to find central peak in footprint: faulty test")

        source.setFootprint(fp)
        return measAlg.PsfCandidateF(source, self.exp, self.x, self.y)
Esempio n. 20
0
def interpolateFromMask(maskedImage, fwhm, growSaturatedFootprints=1,
                        maskNameList=['SAT'], fallbackValue=None):
    """Interpolate over defects identified by a particular set of mask planes.

    Parameters
    ----------
    maskedImage : `lsst.afw.image.MaskedImage`
        Image to process.
    fwhm : scalar
        FWHM of double Gaussian smoothing kernel.
    growSaturatedFootprints : scalar, optional
        Number of pixels to grow footprints for saturated pixels.
    maskNameList : `List` of `str`, optional
        Mask plane name.
    fallbackValue : scalar, optional
        Value of last resort for interpolation.
    """
    mask = maskedImage.getMask()

    if growSaturatedFootprints > 0 and "SAT" in maskNameList:
        # If we are interpolating over an area larger than the original masked region, we need
        # to expand the original mask bit to the full area to explain why we interpolated there.
        growMasks(mask, radius=growSaturatedFootprints, maskNameList=['SAT'], maskValue="SAT")

    thresh = afwDetection.Threshold(mask.getPlaneBitMask(maskNameList), afwDetection.Threshold.BITMASK)
    fpSet = afwDetection.FootprintSet(mask, thresh)
    defectList = Defects.fromFootprintList(fpSet.getFootprints())

    interpolateDefectList(maskedImage, defectList, fwhm, fallbackValue=fallbackValue)

    return maskedImage
Esempio n. 21
0
def makeThresholdMask(maskedImage, threshold, growFootprints=1, maskName='SAT'):
    """Mask pixels based on threshold detection.

    Parameters
    ----------
    maskedImage : `lsst.afw.image.MaskedImage`
        Image to process.  Only the mask plane is updated.
    threshold : scalar
        Detection threshold.
    growFootprints : scalar, optional
        Number of pixels to grow footprints of detected regions.
    maskName : str, optional
        Mask plane name, or list of names to convert

    Returns
    -------
    defectList : `lsst.meas.algorithms.Defects`
        Defect list constructed from pixels above the threshold.
    """
    # find saturated regions
    thresh = afwDetection.Threshold(threshold)
    fs = afwDetection.FootprintSet(maskedImage, thresh)

    if growFootprints > 0:
        fs = afwDetection.FootprintSet(fs, rGrow=growFootprints, isotropic=False)
    fpList = fs.getFootprints()

    # set mask
    mask = maskedImage.getMask()
    bitmask = mask.getPlaneBitMask(maskName)
    afwDetection.setMaskFromFootprintList(mask, fpList, bitmask)

    return Defects.fromFootprintList(fpList)
Esempio n. 22
0
    def detectObjectsInExp(exp, nSigma, nPixMin, grow=0):
        """Run a very basic but fast threshold-based object detection on an exposure
        Return the footPrintSet for the objects in a postISR exposure.

        Parameters
        ----------
        exp : `lsst.afw.image.Exposure`
            Image in which to detect objects.
        nSigma : `float`
            nSigma above image's stddev at which to set the detection threshold.
        nPixMin : `int`
            Minimum number of pixels for detection.
        grow : `int`
            Grow the detected footprint by this many pixels.

        Returns
        -------
        footPrintSet : `lsst.afw.detection.FootprintSet`
            FootprintSet containing the detections.
        """
        threshold = afwDetect.Threshold(nSigma, afwDetect.Threshold.STDEV)
        footPrintSet = afwDetect.FootprintSet(exp.getMaskedImage(), threshold,
                                              "DETECTED", nPixMin)
        if grow > 0:
            isotropic = True
            footPrintSet = afwDetect.FootprintSet(footPrintSet, grow,
                                                  isotropic)
        return footPrintSet
Esempio n. 23
0
    def testGrowLRUD2(self):
        """Grow footprints in various directions using the FootprintSet/FootprintControl constructor

        Check that overlapping grown Footprints give the expected answers
        """
        ngrow = 3  # How much to grow by
        for fctrl, xy in [
            (afwDetect.FootprintControl(True, True, False, False), [(4, 5),
                                                                    (5, 6),
                                                                    (6, 5)]),
            (afwDetect.FootprintControl(False, False, True, True), [(5, 4),
                                                                    (6, 5),
                                                                    (5, 6)]),
        ]:
            im = afwImage.MaskedImageF(11, 11)
            for x, y in xy:
                im[x, y, afwImage.LOCAL] = (10, 0x0, 0.0)
            fs = afwDetect.FootprintSet(im, afwDetect.Threshold(10))
            self.assertEqual(len(fs.getFootprints()), 1)

            grown = afwDetect.FootprintSet(fs, ngrow, fctrl)
            im.getMask().set(0)
            afwDetect.setMaskFromFootprintList(im.getMask(),
                                               grown.getFootprints(), 0x10)

            if display:
                ds9.mtv(im)

            self.assertEqual(len(grown.getFootprints()), 1)
            foot = grown.getFootprints()[0]

            npix = 1 + 2 * ngrow
            npix += 3 + 2 * ngrow  # 3: distance between pair of set pixels 000X0X000
            self.assertEqual(foot.getArea(), npix)
Esempio n. 24
0
def subtractXTalk(mi, coeffs, minPixelToMask=45000, crosstalkStr="CROSSTALK"):
    """Subtract the crosstalk from MaskedImage mi given a set of coefficients

The pixels affected by signal over minPixelToMask have the crosstalkStr bit set
    """
    sctrl = afwMath.StatisticsControl()
    sctrl.setAndMask(mi.getMask().getPlaneBitMask("DETECTED"))
    bkgd = afwMath.makeStatistics(mi, afwMath.MEDIAN, sctrl).getValue()
    #
    # These are the pixels that are bright enough to cause crosstalk (more precisely,
    # the ones that we label as causing crosstalk; in reality all pixels cause crosstalk)
    #
    tempStr = "TEMP"                    # mask plane used to record the bright pixels that we need to mask
    mi.getMask().addMaskPlane(tempStr)
    try:
        fs = afwDetect.FootprintSet(mi, afwDetect.Threshold(minPixelToMask), tempStr)

        mi.getMask().addMaskPlane(crosstalkStr)
        afwDisplay.getDisplay().setMaskPlaneColor(crosstalkStr, afwDisplay.MAGENTA)
        fs.setMask(mi.getMask(), crosstalkStr) # the crosstalkStr bit will now be set whenever
                                               # we subtract crosstalk
        crosstalk = mi.getMask().getPlaneBitMask(crosstalkStr)

        width, height = mi.getDimensions()
        for i in range(nAmp):
            bbox = afwGeom.BoxI(afwGeom.PointI(i*(width//nAmp), 0), afwGeom.ExtentI(width//nAmp, height))
            ampI = mi.Factory(mi, bbox)
            for j in range(nAmp):
                if i == j:
                    continue

                bbox = afwGeom.BoxI(afwGeom.PointI(j*(width//nAmp), 0), afwGeom.ExtentI(width//nAmp, height))
                if (i + j)%2 == 1:
                    ampJ = afwMath.flipImage(mi.Factory(mi, bbox), True, False) # no need for a deep copy
                else:
                    ampJ = mi.Factory(mi, bbox, afwImage.LOCAL, True)

                msk = ampJ.getMask()
                if np.all(msk.getArray() & msk.getPlaneBitMask("SAT")):
                    # Bad amplifier; ignore it completely --- its effect will come out in the bias
                    continue
                msk &= crosstalk

                ampJ -= bkgd
                ampJ *= coeffs[j][i]

                ampI -= ampJ
        #
        # Clear the crosstalkStr bit in the original bright pixels, where tempStr is set
        #
        msk = mi.getMask()
        temp = msk.getPlaneBitMask(tempStr)
        xtalk_temp = crosstalk | temp
        np_msk = msk.getArray()
        mask_indicies = np.where(np.bitwise_and(np_msk, xtalk_temp) == xtalk_temp)
        np_msk[mask_indicies] &= getattr(np, np_msk.dtype.name)(~crosstalk)

    finally:
        msk.removeAndClearMaskPlane(tempStr, True) # added in afw #1853
Esempio n. 25
0
def clipImage(im, minClip, maxClip):
    """Clip an image to lie between minClip and maxclip (None to ignore)"""
    if isinstance(im, MaskedImage):
        mi = im
    else:
        mi = makeMaskedImage(im, Mask(im.getDimensions()))

    if minClip is not None:
        ds = afwDetect.FootprintSet(
            mi, afwDetect.Threshold(-minClip, afwDetect.Threshold.VALUE, False))
        afwDetect.setImageFromFootprintList(
            mi.getImage(), ds.getFootprints(), minClip)

    if maxClip is not None:
        ds = afwDetect.FootprintSet(mi, afwDetect.Threshold(maxClip))
        afwDetect.setImageFromFootprintList(
            mi.getImage(), ds.getFootprints(), maxClip)
Esempio n. 26
0
def subtractCrosstalkYagi(mi, coeffs1List, coeffs2List, gainsPreampSig, minPixelToMask=45000,
                          crosstalkStr="CROSSTALK"):
    """Subtract the crosstalk from MaskedImage mi given a set of coefficients
       based on procedure presented in Yagi et al. 2012, PASP in publication; arXiv:1210.8212
       The pixels affected by signal over minPixelToMask have the crosstalkStr bit set
    """

    ####sctrl = afwMath.StatisticsControl()
    ####sctrl.setAndMask(mi.getMask().getPlaneBitMask("DETECTED"))
    ####bkgd = afwMath.makeStatistics(mi, afwMath.MEDIAN, sctrl).getValue()
    #
    # These are the pixels that are bright enough to cause crosstalk (more precisely,
    # the ones that we label as causing crosstalk; in reality all pixels cause crosstalk)
    #
    if True:
        tempStr = "TEMP"                    # mask plane used to record the bright pixels that we need to mask
        mi.getMask().addMaskPlane(tempStr)
        fs = afwDetect.FootprintSet(mi, afwDetect.Threshold(minPixelToMask), tempStr)

        mi.getMask().addMaskPlane(crosstalkStr)
        ds9.setMaskPlaneColor(crosstalkStr, ds9.MAGENTA)
        fs.setMask(mi.getMask(), crosstalkStr)  # the crosstalkStr bit will now be set
        # whenever we subtract crosstalk
        crosstalk = mi.getMask().getPlaneBitMask(crosstalkStr)

    if True:
        # This python implementation is fairly fast
        image = mi.getImage()
        xtalk = afwImage.ImageF(image.getDimensions())
        xtalk.set(0)
        for i in range(4):
            xAmp, xOff = getAmplifier(xtalk, i, i)
            for j in range(4):
                if i == j:
                    continue
                gainRatio = gainsPreampSig[j] / gainsPreampSig[i]
                jAmp, jOff = getAmplifier(image, j, i)
                xAmp.scaledPlus(gainRatio*coeffs1List[i][j], jAmp)
                xOff.scaledPlus(gainRatio*coeffs2List[i][j], jOff)

        image -= xtalk
    else:
        nAmp = 4
        subtractCrosstalk(mi, nAmp, coeffs1List, coeffs2List, gainsPreampSig)

    #
    # Clear the crosstalkStr bit in the original bright pixels, where tempStr is set
    #
    msk = mi.getMask()
    temp = msk.getPlaneBitMask(tempStr)
    xtalk_temp = crosstalk | temp
    np_msk = msk.getArray()
    np_msk[np.where(np.bitwise_and(np_msk, xtalk_temp) == xtalk_temp)] &= ~crosstalk

    try:
        msk.removeAndClearMaskPlane(tempStr, True) # added in afw #1853
    except AttributeError:
        ds9.setMaskPlaneVisibility(tempStr, False)
Esempio n. 27
0
def Clusterfind_max_timecode_one_file(filename,
                                      winow_xmin=0,
                                      winow_xmax=999,
                                      winow_ymin=0,
                                      winow_ymax=999,
                                      glitch_threshold=20000,
                                      checkerboard_phase=None,
                                      npix_min=1):
    if str(filename).find('.DS') != -1: return

    import lsst.afw.detection as afwDetect
    import string, os

    cluster_sizes = []
    timecodes = []
    files = []

    thresholdValue = 1
    npixMin = npix_min
    grow = 0
    isotropic = False

    image = TimepixToExposure(filename, winow_xmin, winow_xmax, winow_ymin,
                              winow_ymax)

    threshold = afwDetect.Threshold(thresholdValue)
    footPrintSet = afwDetect.FootprintSet(image, threshold, npixMin)
    footPrintSet = afwDetect.FootprintSet(footPrintSet, grow, isotropic)
    footPrints = footPrintSet.getFootprints()

    for footprintnum, footprint in enumerate(footPrints):
        npix = afwDetect.Footprint.getNpix(footprint)
        cluster_sizes.append(npix)

        #         if npix >= 4:
        box = footprint.getBBox()
        bbox_xmin = box.getMinX()
        bbox_xmax = box.getMaxX() + 1
        bbox_ymin = box.getMinY()
        bbox_ymax = box.getMaxY() + 1

        data = image.getArray()[bbox_ymin:bbox_ymax, bbox_xmin:bbox_xmax]
        #         x,y,t,chisq = CentroidTimepixCluster(data, fit_function = 'gaus')
        #         timecodes.append(t)

        ##         centroid_x, centroid_y = footprint.getCentroid()
        ##         x += bbox_xmin
        ##         y += bbox_ymin

        if checkerboard_phase is not None:
            print('WARNING - Not yet implemented')
            exit()
            if (bbox_xmin + bbox_ymin) % 2 == checkerboard_phase:
                timecode -= 1

        timecodes.append(GetMaxClusterTimecode(data))

    return timecodes
Esempio n. 28
0
    def testFootprints2(self):
        """Check that we found the correct number of objects using FootprintSet"""
        ds = afwDetect.FootprintSet(self.ms, afwDetect.Threshold(10))

        objects = ds.getFootprints()

        self.assertEqual(len(objects), len(self.objects))
        for i in range(len(objects)):
            self.assertEqual(objects[i], self.objects[i])
Esempio n. 29
0
    def testFootprintsImage(self):
        """Check that we can search Images as well as MaskedImages"""
        ds = afwDetect.FootprintSet(self.ms.getImage(), afwDetect.Threshold(10))

        objects = ds.getFootprints()

        self.assertEqual(len(objects), len(self.objects))
        for i in range(len(objects)):
            self.assertEqual(objects[i], self.objects[i])
Esempio n. 30
0
    def testSetFromFootprint(self):
        """Test setting mask/image pixels from a Footprint list"""
        mi = afwImage.MaskedImageF(lsst.geom.Extent2I(12, 8))
        im = mi.getImage()
        #
        # Objects that we should detect
        #
        self.objects = []
        self.objects += [Object(10, [(1, 4, 4), (2, 3, 5), (3, 4, 4)])]
        self.objects += [Object(20, [(5, 7, 8), (5, 10, 10), (6, 8, 9)])]
        self.objects += [Object(20, [(6, 3, 3)])]

        im.set(0)                       # clear image
        for obj in self.objects:
            obj.insert(im)

        if False and display:
            ds9.mtv(mi, frame=0)

        ds = afwDetect.FootprintSet(mi, afwDetect.Threshold(15))

        objects = ds.getFootprints()
        afwDetect.setMaskFromFootprintList(mi.getMask(), objects, 0x1)

        self.assertEqual(mi.getMask()[4, 2, afwImage.LOCAL], 0x0)
        self.assertEqual(mi.getMask()[3, 6, afwImage.LOCAL], 0x1)

        self.assertEqual(mi.getImage()[3, 6, afwImage.LOCAL], 20)
        for ft in objects:
            ft.spans.setImage(mi.getImage(), 5.0)
        self.assertEqual(mi.getImage()[4, 2, afwImage.LOCAL], 10)
        self.assertEqual(mi.getImage()[3, 6, afwImage.LOCAL], 5)

        if display:
            ds9.mtv(mi, frame=1)
        #
        # Check Footprint.contains() while we are about it
        #
        self.assertTrue(objects[0].contains(lsst.geom.Point2I(7, 5)))
        self.assertFalse(objects[0].contains(lsst.geom.Point2I(10, 6)))
        self.assertFalse(objects[0].contains(lsst.geom.Point2I(7, 6)))
        self.assertFalse(objects[0].contains(lsst.geom.Point2I(4, 2)))

        self.assertTrue(objects[1].contains(lsst.geom.Point2I(3, 6)))

        # Verify the FootprintSet footprint list setter can accept inputs from
        # the footprint list getter
        # Create a copy of the ds' FootprintList
        dsFpList = ds.getFootprints()
        footprintListCopy = [afwDetect.Footprint().assign(f) for f in dsFpList]
        # Use the FootprintList setter with the output from the getter
        ds.setFootprints(ds.getFootprints()[:-1])
        dsFpListNew = ds.getFootprints()
        self.assertTrue(len(dsFpListNew) == len(footprintListCopy)-1)
        for new, old in zip(dsFpListNew, footprintListCopy[:-1]):
            self.assertEqual(new, old)