Пример #1
0
    def factory(cls, stamp_im, metadata, index):
        """This method is needed to service the FITS reader.
        We need a standard interface to construct objects like this.
        Parameters needed to construct this object are passed in via
        a metadata dictionary and then passed to the constructor of
        this class.  If lists of values are passed with the following
        keys, they will be passed to the constructor, otherwise dummy
        values will be passed: RA_DEG, DEC_DEG.  They should
        each point to lists of values.

        Parameters
        ----------
        stamp : `lsst.afw.image.MaskedImage`
            Pixel data to pass to the constructor
        metadata : `dict`
            Dictionary containing the information
            needed by the constructor.
        idx : `int`
            Index into the lists in ``metadata``

        Returns
        -------
        stamp : `Stamp`
            An instance of this class
        """
        if 'RA_DEG' in metadata and 'DEC_DEG' in metadata:
            return cls(stamp_im=stamp_im,
                       position=SpherePoint(
                           Angle(metadata.getArray('RA_DEG')[index], degrees),
                           Angle(metadata.getArray('DEC_DEG')[index],
                                 degrees)))
        else:
            return cls(stamp_im=stamp_im,
                       position=SpherePoint(Angle(numpy.nan),
                                            Angle(numpy.nan)))
Пример #2
0
class Stamp(AbstractStamp):
    """Single stamp

    Parameters
    ----------
    stamp_im : `lsst.afw.image.MaskedImageF`
        The actual pixel values for the postage stamp
    position : `lsst.geom.SpherePoint`, optional
        Position of the center of the stamp.  Note the user
        must keep track of the coordinate system
    """
    stamp_im: afwImage.maskedImage.MaskedImageF
    archive_element: Optional[afwTable.io.Persistable] = None
    position: Optional[SpherePoint] = SpherePoint(Angle(numpy.nan),
                                                  Angle(numpy.nan))

    @classmethod
    def factory(cls, stamp_im, metadata, index, archive_element=None):
        """This method is needed to service the FITS reader.
        We need a standard interface to construct objects like this.
        Parameters needed to construct this object are passed in via
        a metadata dictionary and then passed to the constructor of
        this class.  If lists of values are passed with the following
        keys, they will be passed to the constructor, otherwise dummy
        values will be passed: RA_DEG, DEC_DEG.  They should
        each point to lists of values.

        Parameters
        ----------
        stamp : `lsst.afw.image.MaskedImage`
            Pixel data to pass to the constructor
        metadata : `dict`
            Dictionary containing the information
            needed by the constructor.
        idx : `int`
            Index into the lists in ``metadata``
        archive_element : `afwTable.io.Persistable`, optional
            Archive element (e.g. Transform or WCS) associated with this stamp.

        Returns
        -------
        stamp : `Stamp`
            An instance of this class
        """
        if 'RA_DEG' in metadata and 'DEC_DEG' in metadata:
            return cls(stamp_im=stamp_im,
                       archive_element=archive_element,
                       position=SpherePoint(
                           Angle(metadata.getArray('RA_DEG')[index], degrees),
                           Angle(metadata.getArray('DEC_DEG')[index],
                                 degrees)))
        else:
            return cls(stamp_im=stamp_im,
                       archive_element=archive_element,
                       position=SpherePoint(Angle(numpy.nan),
                                            Angle(numpy.nan)))
Пример #3
0
 def test_repr(self):
     """Test that eval(repr(Angle)) round-trips for finite and non-finite
     values.
     """
     from lsst.geom import Angle, degrees  # need symbols in scope for eval
     d = 4.0 / 7.0
     self.assertEqual(eval(repr(Angle(d, degrees))), Angle(d, degrees))
     self.assertEqual(eval(repr(Angle(float("inf"), degrees))),
                      Angle(float("inf"), degrees))
     self.assertTrue(
         np.isnan(eval(repr(Angle(float("NaN"), degrees))).asDegrees()))
Пример #4
0
    def evaluate(self, angle_start: Angle, angle_end: Optional[Angle] = None):
        """Get y-band background image array for a range of angles.

        It is hypothesized that the instrument rotator rotates at a constant
        angular velocity. This is not strictly true, but should be a
        sufficient approximation for the relatively short exposure times
        typical for HSC.

        Parameters
        ----------
        angle_start : `float`
            Instrument rotation angle in degrees at the start of the exposure.
        angle_end : `float`, optional
            Instrument rotation angle in degrees at the end of the exposure.
            If not provided, the returned array will reflect a snapshot at
            `angle_start`.

        Returns
        -------
        ccd_img : `numpy.ndarray`
            Background data for this exposure.
        """
        hdulist = fits.open(self._filename)
        header = hdulist[0].header

        # full-size ccd height & channel width
        ccd_h, ch_w = header["F_NAXIS2"], header["F_NAXIS1"]
        # saved data is compressed to 1/2**scale_level of the original size
        image_scale_level = header["WTLEVEL2"], header["WTLEVEL1"]
        angle_scale_level = header["WTLEVEL3"]

        ccd_w = ch_w * len(hdulist)
        ccd_img = numpy.empty(shape=(ccd_h, ccd_w), dtype=numpy.float32)

        for ch, hdu in enumerate(hdulist):
            volume = _upscale_volume(hdu.data, angle_scale_level)

            if angle_end is None:
                img = volume(angle_start.asDegrees())
            else:
                img = (volume.integrate(angle_start.asDegrees(),
                                        angle_end.asDegrees()) *
                       (1.0 /
                        (angle_end.asDegrees() - angle_start.asDegrees())))

            ccd_img[:, ch_w * ch:ch_w * (ch + 1)] = _upscale_image(
                img, (ccd_h, ch_w), image_scale_level)

        # Some regions don't have useful values because the amplifier is dead
        # when the darks were taken
        #    is_bad = ccd_img > BAD_THRESHOLD
        #    ccd_img[is_bad] = numpy.median(ccd_img[~is_bad])

        return ccd_img
Пример #5
0
 def __init__(self, config=None):
     if config is None:
         config = self.ConfigClass()
     config.freeze()  # just to be sure, e.g. for pickling
     self.config = config
     self._tractInfoList = []
     self._wcsFactory = detail.WcsFactory(
         pixelScale=Angle(self.config.pixelScale, arcseconds),
         projection=self.config.projection,
         rotation=Angle(self.config.rotation, degrees),
     )
     self._sha1 = None
Пример #6
0
    def _horizonRotAngle(self):
        """!Compute rotation angle of camera with respect to horizontal
        coordinates from self.visitInfo.

        @returns horizon rotation angle.
        """
        observatory = self.visitInfo.getObservatory()
        lat = observatory.getLatitude()
        lon = observatory.getLongitude()
        radec = self.visitInfo.getBoresightRaDec()
        ra = radec.getRa()
        dec = radec.getDec()
        era = self.visitInfo.getEra()
        ha = (era + lon - ra).wrap()
        alt = self.visitInfo.getBoresightAzAlt().getLatitude()

        # parallactic angle
        sinParAng = (np.cos(lat.asRadians()) * np.sin(ha.asRadians()) /
                     np.cos(alt.asRadians()))
        cosParAng = np.sqrt(1 - sinParAng * sinParAng)
        if dec > lat:
            cosParAng = -cosParAng
        parAng = Angle(np.arctan2(sinParAng, cosParAng))

        bra = self.visitInfo.getBoresightRotAngle()
        return (bra - parAng).wrap()
Пример #7
0
    def __init__(self, config=None):
        """Construct a BaseSkyMap

        @param[in] config: an instance of self.ConfigClass; if None the default config is used
        """
        if config is None:
            config = self.ConfigClass()
        config.freeze()  # just to be sure, e.g. for pickling
        self.config = config
        self._tractInfoList = []
        self._wcsFactory = detail.WcsFactory(
            pixelScale=Angle(self.config.pixelScale, arcseconds),
            projection=self.config.projection,
            rotation=Angle(self.config.rotation, degrees),
        )
        self._sha1 = None
Пример #8
0
 def testParallacticAngleSouthMeridian(self):
     """An observation on the Meridian that is South of zenith has a parallactic angle of zero."""
     meridianBoresightRA = self.data1.era + self.data1.observatory.getLongitude()
     southBoresightDec = self.data1.observatory.getLatitude() - 10.*degrees
     visitInfo = afwImage.VisitInfo(era=self.data1.era,
                                    boresightRaDec=SpherePoint(meridianBoresightRA,
                                                               southBoresightDec),
                                    observatory=self.data1.observatory,
                                    )
     self.assertAnglesAlmostEqual(visitInfo.getBoresightParAngle(), Angle(0.))