def finalize(self, idFactory):
        """Finalize construction of the catalog.

        Create a SourceCatalog from the MultiMatch object and compute the corresponding
        merged footprint.
        @param[in]  idFactory   Used to generate ids.

        @return    SourceCatalog of DIAObjects
        """
        if self.multi_matches is None:
            return None

        schema = afwTable.SourceTable.makeMinimalSchema()
        nobsKey = schema.addField("nobs",
                                  type=np.int32,
                                  doc='Number of times observed')
        fluxKey = schema.addField("flux", type=float, doc='Average flux')
        raKey = schema['coord_ra'].asKey()
        decKey = schema['coord_dec'].asKey()
        table = afwTable.SourceTable.make(schema, idFactory)
        cat = afwTable.SourceCatalog(table)

        results = self.multi_matches.finish(removeAmbiguous=False)
        allMatches = afwTable.GroupView.build(results)

        psfMagKey = allMatches.schema.find(self.config.fluxType).key
        raKey = allMatches.schema.find("coord_ra").key
        decKey = allMatches.schema.find("coord_dec").key

        ave_ra = allMatches.aggregate(np.mean, field=raKey)
        ave_dec = allMatches.aggregate(np.mean, field=decKey)
        ave_flux = allMatches.aggregate(np.mean, field=psfMagKey)

        # Merge the footprints from the same object together
        object_ids = np.unique(results['object'])
        footprints = []
        for id in object_ids:
            mask = results['object'] == id
            footprint = None
            for rec in results[mask]:
                if footprint is None:
                    footprint = rec.getFootprint()
                else:
                    footprint = afwDet.mergeFootprints(footprint,
                                                       rec.getFootprint())
            footprints.append(footprint)

        for i in range(len(ave_ra)):
            rec = cat.addNew()
            rec.setFootprint(footprints[i])
            rec.set(raKey, ave_ra[i] * geom.radians)
            rec.set(decKey, ave_dec[i] * geom.radians)
            rec.set(fluxKey, ave_flux[i])

        return cat
Beispiel #2
0
    def testMergeFootprints(self):
        f1 = self.foot
        f2 = afwDetect.Footprint()

        spanList1 = [(10, 10, 20), (10, 30, 40), (10, 50, 60), (11, 30, 50),
                     (12, 30, 50), (13, 10, 20), (13, 30, 40), (13, 50, 60),
                     (15, 10, 20), (15, 31, 40), (15, 51, 60)]
        spanSet1 = afwGeom.SpanSet([afwGeom.Span(*span) for span in spanList1])
        f1.spans = spanSet1

        spanList2 = [(8, 10, 20), (9, 20, 30), (10, 0, 9), (10, 35, 65),
                     (10, 70, 80), (13, 49, 54), (14, 10, 30), (15, 21, 30),
                     (15, 41, 50), (15, 61, 70)]
        spanSet2 = afwGeom.SpanSet([afwGeom.Span(*span) for span in spanList2])
        f2.spans = spanSet2

        fA = afwDetect.mergeFootprints(f1, f2)
        fB = afwDetect.mergeFootprints(f2, f1)

        ims = []
        for i, f in enumerate([f1, f2, fA, fB]):
            im1 = afwImage.ImageU(100, 100)
            im1.set(0)
            imbb = im1.getBBox()
            f.setRegion(imbb)
            f.spans.setImage(im1, 1)
            ims.append(im1)

        for i, merged in enumerate([ims[2], ims[3]]):
            m = merged.getArray()
            a1 = ims[0].getArray()
            a2 = ims[1].getArray()
            # Slightly looser tests to start...
            # Every pixel in f1 is in f[AB]
            self.assertTrue(np.all(m.flat[np.flatnonzero(a1)] == 1))
            # Every pixel in f2 is in f[AB]
            self.assertTrue(np.all(m.flat[np.flatnonzero(a2)] == 1))
            # merged == a1 | a2.
            self.assertTrue(np.all(m == np.maximum(a1, a2)))
Beispiel #3
0
    def _fig8Test(self, x1, y1, x2, y2):
        # Construct a "figure of 8" consisting of two circles touching at the
        # centre of an image, then demonstrate that it shrinks correctly.
        # (Helper method for tests below.)
        radius = 3
        imwidth, imheight = 100, 100
        nshrink = 1

        # These are the correct values for footprint sizes given the paramters
        # above.
        circle_npix = 29
        initial_npix = circle_npix * 2 - 1  # touch at one pixel
        shrunk_npix = 26

        box = lsst.geom.Box2I(lsst.geom.Point2I(0, 0),
                              lsst.geom.Extent2I(imwidth, imheight))

        e1 = afwGeom.Ellipse(afwGeomEllipses.Axes(radius, radius, 0),
                             lsst.geom.Point2D(x1, y1))
        spanSet1 = afwGeom.SpanSet.fromShape(e1)
        f1 = afwDetect.Footprint(spanSet1, box)
        self.assertEqual(f1.getArea(), circle_npix)

        e2 = afwGeom.Ellipse(afwGeomEllipses.Axes(radius, radius, 0),
                             lsst.geom.Point2D(x2, y2))
        spanSet2 = afwGeom.SpanSet.fromShape(e2)
        f2 = afwDetect.Footprint(spanSet2, box)
        self.assertEqual(f2.getArea(), circle_npix)

        initial = afwDetect.mergeFootprints(f1, f2)
        initial.setRegion(
            f2.getRegion())  # merge does not propagate the region
        self.assertEqual(initial_npix, initial.getArea())

        shrunk = afwDetect.Footprint().assign(initial)
        shrunk.erode(nshrink)
        self.assertEqual(shrunk_npix, shrunk.getArea())

        if display:
            idImage = afwImage.ImageU(imwidth, imheight)
            for i, foot in enumerate([initial, shrunk]):
                print(foot.getArea())
                foot.spans.setImage(idImage, i + 1)
            afwDisplay.Display(frame=1).mtv(idImage,
                                            title=self._testMethodName +
                                            " image")
Beispiel #4
0
    def _fig8Test(self, x1, y1, x2, y2):
        # Construct a "figure of 8" consisting of two circles touching at the
        # centre of an image, then demonstrate that it shrinks correctly.
        # (Helper method for tests below.)
        radius = 3
        imwidth, imheight = 100, 100
        nshrink = 1

        # These are the correct values for footprint sizes given the paramters
        # above.
        circle_npix = 29
        initial_npix = circle_npix * 2 - 1  # touch at one pixel
        shrunk_npix = 26

        box = afwGeom.Box2I(afwGeom.Point2I(0, 0),
                            afwGeom.Extent2I(imwidth, imheight))

        e1 = afwGeomEllipses.Ellipse(afwGeomEllipses.Axes(radius, radius, 0),
                                     afwGeom.Point2D(x1, y1))
        f1 = afwDetect.Footprint(e1, box)
        self.assertEqual(f1.getNpix(), circle_npix)

        e2 = afwGeomEllipses.Ellipse(afwGeomEllipses.Axes(radius, radius, 0),
                                     afwGeom.Point2D(x2, y2))
        f2 = afwDetect.Footprint(e2, box)
        self.assertEqual(f2.getNpix(), circle_npix)

        initial = afwDetect.mergeFootprints(f1, f2)
        initial.setRegion(
            f2.getRegion())  # merge does not propagate the region
        self.assertEqual(initial_npix, initial.getNpix())

        shrunk = afwDetect.shrinkFootprint(initial, nshrink, True)
        self.assertEqual(shrunk_npix, shrunk.getNpix())

        if display:
            idImage = afwImage.ImageU(imwidth, imheight)
            for i, foot in enumerate([initial, shrunk]):
                print(foot.getNpix())
                foot.insertIntoImage(idImage, i + 1)
            ds9.mtv(idImage)
Beispiel #5
0
    def _fig8Test(self, x1, y1, x2, y2):
        # Construct a "figure of 8" consisting of two circles touching at the
        # centre of an image, then demonstrate that it shrinks correctly.
        # (Helper method for tests below.)
        radius = 3
        imwidth, imheight = 100, 100
        nshrink = 1

        # These are the correct values for footprint sizes given the paramters
        # above.
        circle_npix = 29
        initial_npix = circle_npix * 2 - 1 # touch at one pixel
        shrunk_npix = 26

        box = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(imwidth, imheight))

        e1 = afwGeomEllipses.Ellipse(afwGeomEllipses.Axes(radius, radius, 0),
                                          afwGeom.Point2D(x1, y1))
        f1 = afwDetect.Footprint(e1,box)
        self.assertEqual(f1.getNpix(), circle_npix)

        e2 = afwGeomEllipses.Ellipse(afwGeomEllipses.Axes(radius, radius, 0),
                                          afwGeom.Point2D(x2, y2))
        f2 = afwDetect.Footprint(e2,box)
        self.assertEqual(f2.getNpix(), circle_npix)

        initial = afwDetect.mergeFootprints(f1, f2)
        initial.setRegion(f2.getRegion()) # merge does not propagate the region
        self.assertEqual(initial_npix, initial.getNpix())

        shrunk = afwDetect.shrinkFootprint(initial, nshrink, True)
        self.assertEqual(shrunk_npix, shrunk.getNpix())

        if display:
            idImage = afwImage.ImageU(imwidth, imheight)
            for i, foot in enumerate([initial, shrunk]):
                print foot.getNpix()
                foot.insertIntoImage(idImage, i+1);
            ds9.mtv(idImage)
Beispiel #6
0
    def testMergeFootprints(self):
        f1 = self.foot
        f2 = afwDetect.Footprint()

        f1.addSpan(10, 10, 20)
        f1.addSpan(10, 30, 40)
        f1.addSpan(10, 50, 60)

        f1.addSpan(11, 30, 50)
        f1.addSpan(12, 30, 50)

        f1.addSpan(13, 10, 20)
        f1.addSpan(13, 30, 40)
        f1.addSpan(13, 50, 60)

        f1.addSpan(15, 10, 20)
        f1.addSpan(15, 31, 40)
        f1.addSpan(15, 51, 60)

        f2.addSpan(8, 10, 20)
        f2.addSpan(9, 20, 30)
        f2.addSpan(10, 0, 9)
        f2.addSpan(10, 35, 65)
        f2.addSpan(10, 70, 80)

        f2.addSpan(13, 49, 54)
        f2.addSpan(14, 10, 30)

        f2.addSpan(15, 21, 30)
        f2.addSpan(15, 41, 50)
        f2.addSpan(15, 61, 70)

        f1.normalize()
        f2.normalize()

        fA = afwDetect.mergeFootprints(f1, f2)
        fB = afwDetect.mergeFootprints(f2, f1)

        ims = []
        for i, f in enumerate([f1, f2, fA, fB]):
            im1 = afwImage.ImageU(100, 100)
            im1.set(0)
            imbb = im1.getBBox()
            f.setRegion(imbb)
            f.insertIntoImage(im1, 1)
            ims.append(im1)

        for i, merged in enumerate([ims[2], ims[3]]):
            m = merged.getArray()
            a1 = ims[0].getArray()
            a2 = ims[1].getArray()
            # Slightly looser tests to start...
            # Every pixel in f1 is in f[AB]
            self.assertTrue(np.all(m.flat[np.flatnonzero(a1)] == 1))
            # Every pixel in f2 is in f[AB]
            self.assertTrue(np.all(m.flat[np.flatnonzero(a2)] == 1))
            # merged == a1 | a2.
            self.assertTrue(np.all(m == np.maximum(a1, a2)))

        if False:
            import matplotlib
            matplotlib.use('Agg')
            import pylab as plt
            plt.clf()
            for i, im1 in enumerate(ims):
                plt.subplot(4, 1, i + 1)
                plt.imshow(im1.getArray(),
                           interpolation='nearest',
                           origin='lower')
                plt.axis([0, 100, 0, 20])
            plt.savefig('merge2.png')
    def finalize(self, idFactory):
        """Finalize construction of the catalog.

        Create a SourceCatalog from the MultiMatch object and compute the corresponding
        merged footprint.
        @param[in]  idFactory   Used to generate ids.

        @return    SourceCatalog of DIAObjects
        """
        if self.multi_matches is None:
            return None

        schema = afwTable.SourceTable.makeMinimalSchema()
        nobsKey = schema.addField("nobs",
                                  type=np.int32,
                                  doc='Number of times observed')

        keys = {}
        for filter in self.config.filters:
            flux = self.config.fluxType
            keys[f'{flux}_Mean_{filter}'] = schema.addField(
                f"{flux}_Mean_{filter}",
                type=float,
                doc=f'Mean {flux} in filter {filter}')
            keys[f'{flux}_MeanErr_{filter}'] = schema.addField(
                f"{flux}_MeanErr_{filter}",
                type=float,
                doc=f'MeanErr {flux} in filter {filter}')
            keys[f'{flux}_Sigma_{filter}'] = schema.addField(
                f"{flux}_Sigma_{filter}",
                type=float,
                doc=f'Sigma {flux} in filter {filter}')
            keys[f'{flux}_Ndata_{filter}'] = schema.addField(
                f"{flux}_NData_{filter}",
                type=np.int32,
                doc=f'Number of observations in filter {filter}')
            keys[f'{flux}_Chi2_{filter}'] = schema.addField(
                f"{flux}_Chi2_{filter}",
                type=float,
                doc=f'Chi2 of {flux} for {filter}')
        raKey = schema['coord_ra'].asKey()
        decKey = schema['coord_dec'].asKey()
        table = afwTable.SourceTable.make(schema, idFactory)
        cat = afwTable.SourceCatalog(table)

        results = self.multi_matches.finish(removeAmbiguous=False)
        allMatches = afwTable.GroupView.build(results)

        raKey = allMatches.schema.find("coord_ra").key
        decKey = allMatches.schema.find("coord_dec").key

        ave_ra = allMatches.aggregate(np.mean, field=raKey)
        ave_dec = allMatches.aggregate(np.mean, field=decKey)

        # Merge the footprints from the same object together and accumulate
        # information
        object_ids = np.unique(results['object'])
        footprints = []
        all_fluxes = []
        all_flux_errs = []
        num_nobs = []
        self.diaSrcIds = []
        self.diaObjectIds = []

        for id in object_ids:
            mask = results['object'] == id
            num_nobs.append(np.sum(mask))

            footprint = None
            src_ids = []
            fluxes = defaultdict(list)
            flux_errs = defaultdict(list)
            for rec in results[mask]:
                if footprint is None:
                    footprint = rec.getFootprint()
                else:
                    footprint = afwDet.mergeFootprints(footprint,
                                                       rec.getFootprint())
                src_ids.append(rec.get('id'))

                flux = rec.get(self.config.fluxType)
                if np.isfinite(flux) is False:
                    continue

                filter = self.config.filters[rec.get('filter')]
                calib = self.calibDict[rec.get('visit')][rec.get('ccd')]
                flux_err = rec.get(self.config.fluxType + "Err")
                new_val, new_val_err = scaleFlux(flux, flux_err, calib,
                                                 self.calib)

                fluxes[filter].append(new_val)
                flux_errs[filter].append(new_val_err)

            self.diaSrcIds.append(src_ids)
            footprints.append(footprint)
            all_fluxes.append(fluxes)
            all_flux_errs.append(flux_errs)

        for i in range(len(ave_ra)):
            rec = cat.addNew()
            self.diaObjectIds.append(rec.get('id'))
            rec.setFootprint(footprints[i])
            rec.set(raKey, ave_ra[i] * geom.radians)
            rec.set(decKey, ave_dec[i] * geom.radians)
            rec.set(nobsKey, num_nobs[i])
            for filter in self.config.filters:
                fluxes = np.array(all_fluxes[i][filter])
                if len(fluxes) == 0:
                    continue

                flux_errs = np.array(all_flux_errs[i][filter])
                flux = self.config.fluxType
                rec.set(keys[f'{flux}_Mean_{filter}'], np.mean(fluxes))
                rec.set(keys[f'{flux}_Sigma_{filter}'], np.std(fluxes, ddof=1))
                rec.set(keys[f'{flux}_Ndata_{filter}'], len(fluxes))
                rec.set(
                    keys[f'{flux}_MeanErr_{filter}'],
                    rec.get(f'{flux}_Sigma_{filter}') / np.sqrt(len(fluxes)))
                residuals = fluxes - rec.get(keys[f'{flux}_Mean_{filter}'])
                rec.set(keys[f'{flux}_Chi2_{filter}'],
                        np.sum((residuals / flux_errs)**2))

        return cat
Beispiel #8
0
    def testMergeFootprints(self):
        f1 = self.foot
        f2 = afwDetect.Footprint()

        f1.addSpan(10, 10, 20)
        f1.addSpan(10, 30, 40)
        f1.addSpan(10, 50, 60)

        f1.addSpan(11, 30, 50)
        f1.addSpan(12, 30, 50)

        f1.addSpan(13, 10, 20)
        f1.addSpan(13, 30, 40)
        f1.addSpan(13, 50, 60)

        f1.addSpan(15, 10,20)
        f1.addSpan(15, 31,40)
        f1.addSpan(15, 51,60)

        f2.addSpan(8,  10, 20)
        f2.addSpan(9,  20, 30)
        f2.addSpan(10,  0,  9)
        f2.addSpan(10, 35, 65)
        f2.addSpan(10, 70, 80)

        f2.addSpan(13, 49, 54)
        f2.addSpan(14, 10, 30)

        f2.addSpan(15, 21,30)
        f2.addSpan(15, 41,50)
        f2.addSpan(15, 61,70)

        f1.normalize()
        f2.normalize()

        fA = afwDetect.mergeFootprints(f1, f2)
        fB = afwDetect.mergeFootprints(f2, f1)

        ims = []
        for i,f in enumerate([f1,f2,fA,fB]):
            im1 = afwImage.ImageU(100, 100)
            im1.set(0)
            imbb = im1.getBBox()
            f.setRegion(imbb)
            f.insertIntoImage(im1, 1)
            ims.append(im1)

        for i,merged in enumerate([ims[2],ims[3]]):
            m = merged.getArray()
            a1 = ims[0].getArray()
            a2 = ims[1].getArray()
            # Slightly looser tests to start...
            # Every pixel in f1 is in f[AB]
            self.assertTrue(numpy.all(m.flat[numpy.flatnonzero(a1)] == 1))
            # Every pixel in f2 is in f[AB]
            self.assertTrue(numpy.all(m.flat[numpy.flatnonzero(a2)] == 1))
            # merged == a1 | a2.
            self.assertTrue(numpy.all(m == numpy.maximum(a1, a2)))

        if False:
            import matplotlib
            matplotlib.use('Agg')
            import pylab as plt
            plt.clf()
            for i,im1 in enumerate(ims):
                plt.subplot(4,1, i+1)
                plt.imshow(im1.getArray(), interpolation='nearest', origin='lower')
                plt.axis([0, 100, 0, 20])
            plt.savefig('merge2.png')