Ejemplo n.º 1
0
 def testConstruction(self):
     a1 = Angle(1.0)
     a2 = Angle.fromRadians(1.0)
     a3 = Angle.fromDegrees(57.29577951308232)
     self.assertEqual(a1, a2)
     self.assertEqual(a1.asRadians(), 1.0)
     self.assertEqual(a1, a3)
     self.assertEqual(a1.asDegrees(), 57.29577951308232)
Ejemplo n.º 2
0
 def testConstruction(self):
     a1 = Angle(1.0)
     a2 = Angle.fromRadians(1.0)
     a3 = Angle.fromDegrees(57.29577951308232)
     self.assertEqual(a1, a2)
     self.assertEqual(a1.asRadians(), 1.0)
     self.assertEqual(a1, a3)
     self.assertEqual(a1.asDegrees(), 57.29577951308232)
Ejemplo n.º 3
0
    def index(self, exposure_or_metadata, data_id, database):
        """Spatially index an |exposure| or |metadata| object.

        Parameters
        ----------

        exposure_or_metadata : lsst.afw.image.Exposure[DFILU] or lsst.daf.base.PropertySet
            An afw |exposure| or corresponding |metadata| object.

        data_id : object
            An object identifying a single exposure (e.g. as used by the
            butler). It must be possible to pickle `data_id`.

        database : sqlite3.Connection or str
            A connection to (or filename of) a SQLite 3 database.

        Returns
        -------

        ``None``, unless the |defer_writes| coniguration parameter is ``True``.
        In that case, an :class:`.ExposureInfo` object containing a pickled
        data-id and an |encoded| |polygon| is returned.
        """
        # Get a pixel index bounding box for the exposure.
        if isinstance(exposure_or_metadata, daf_base.PropertySet):
            md = exposure_or_metadata
            # Map (LTV1, LTV2) to LSST (x0, y0). LSST convention says that
            # (x0, y0) is the location of the sub-image origin (the bottom-left
            # corner) relative to the origin of the parent, whereas LTVi encode
            # the origin of the parent relative to the origin of the subimage.
            pixel_bbox = afw_image.bboxFromMetadata(md)
            wcs = afw_image.makeWcs(md, False)
        else:
            pixel_bbox = exposure_or_metadata.getBBox()
            wcs = exposure_or_metadata.getWcs()
        # Pad the box by a configurable amount and bail if the result is empty.
        pixel_bbox.grow(self.config.pad_pixels)
        if pixel_bbox.isEmpty():
            self.log.warn("skipping exposure indexing for dataId=%s: "
                          "empty bounding box", data_id)
            return
        corners = []
        for c in pixel_bbox.getCorners():
            # Convert the box corners from pixel indexes to pixel positions,
            # and then to sky coordinates.
            c = wcs.pixelToSky(afw_image.indexToPosition(c.getX()),
                               afw_image.indexToPosition(c.getY()))
            c = (c.getLongitude().asRadians(), c.getLatitude().asRadians())
            # Bail if any coordinate is not finite.
            if any(math.isinf(x) or math.isnan(x) for x in c):
                self.log.warn("skipping exposure indexing for dataId=%s: "
                              "NaN or Inf in bounding box sky coordinate(s)"
                              " - bad WCS?", data_id)
                return
            # Convert from sky coordinates to unit vectors.
            corners.append(UnitVector3d(Angle.fromRadians(c[0]),
                                        Angle.fromRadians(c[1])))
        # Create a convex polygon containing the exposure pixels. When sphgeom
        # gains support for non-convex polygons, this could be changed to map
        # exposure.getPolygon() to a spherical equivalent, or to subdivide box
        # edges in pixel space to account for non linear projections. This
        # would have higher accuracy than the current approach of connecting
        # corner sky coordinates with great circles.
        poly = ConvexPolygon(corners)
        # Finally, persist or return the exposure information.
        info = ExposureInfo(pickle.dumps(data_id), poly.encode())
        if self.config.defer_writes:
            return info
        store_exposure_info(database, self.config.allow_replace, info)