Example #1
0
    def setUp(self):
        self.testDir = os.path.dirname(__file__)

        def computeLstHA(data):
            """Return LST, Hour Angle, computed from VisitInfoData."""
            localEra = data.era + data.observatory.getLongitude()
            hourAngle = localEra - data.boresightRaDec[0]
            return localEra, hourAngle

        fields = [
            'exposureId', 'exposureTime', 'darkTime', 'date', 'ut1', 'era',
            'boresightRaDec', 'boresightAzAlt', 'boresightAirmass',
            'boresightRotAngle', 'rotType', 'observatory', 'weather'
        ]
        VisitInfoData = collections.namedtuple("VisitInfoData", fields)
        data1 = VisitInfoData(
            exposureId=10313423,
            exposureTime=10.01,
            darkTime=11.02,
            date=DateTime(65321.1, DateTime.MJD, DateTime.TAI),
            ut1=12345.1,
            era=45.1 * degrees,
            boresightRaDec=SpherePoint(23.1 * degrees, 73.2 * degrees),
            boresightAzAlt=SpherePoint(134.5 * degrees, 33.3 * degrees),
            boresightAirmass=1.73,
            boresightRotAngle=73.2 * degrees,
            rotType=afwImage.RotType.SKY,
            observatory=Observatory(11.1 * degrees, 22.2 * degrees, 0.333),
            weather=Weather(1.1, 2.2, 34.5),
        )
        self.data1 = data1
        self.localEra1, self.hourAngle1 = computeLstHA(data1)
        data2 = VisitInfoData(
            exposureId=1,
            exposureTime=15.5,
            darkTime=17.8,
            date=DateTime(55321.2, DateTime.MJD, DateTime.TAI),
            ut1=312345.1,
            era=25.1 * degrees,
            boresightRaDec=SpherePoint(2.1 * degrees, 33.2 * degrees),
            boresightAzAlt=SpherePoint(13.5 * degrees, 83.3 * degrees),
            boresightAirmass=2.05,
            boresightRotAngle=-53.2 * degrees,
            rotType=afwImage.RotType.HORIZON,
            observatory=Observatory(22.2 * degrees, 33.3 * degrees, 0.444),
            weather=Weather(2.2, 3.3, 44.4),
        )
        self.data2 = data2
        self.localEra2, self.hourAngle2 = computeLstHA(data2)
Example #2
0
    def setArgDict(self, md, argDict):
        """Set an argument dict for VisitInfo and pop associated metadata

        @param[in,out] md  metadata, as an lsst.daf.base.PropertyList or PropertySet
        @param[in,out] argdict  a dict of arguments
        """
        MakeRawVisitInfo.setArgDict(self, md, argDict)
        argDict["darkTime"] = self.popFloat(md, "DARKTIME")
        argDict["boresightAzAlt"] = Coord(
            self.popAngle(md, "TELAZ"),
            self.popAngle(md, "TELALT"),
        )
        argDict["boresightRaDec"] = IcrsCoord(
            self.popAngle(
                md,
                "RA_DEG",
            ),
            self.popAngle(md, "DEC_DEG"),
        )
        argDict["boresightAirmass"] = self.popFloat(md, "AIRMASS")
        argDict["observatory"] = Observatory(
            self.popAngle(md, "LONGITUD"),
            self.popAngle(md, "LATITUDE"),
            4204,  # from Wikipedia
        )
        argDict["weather"] = Weather(
            self.popFloat(md, "TEMPERAT"),
            self.popFloat(md, "PRESSURE") * 100.0,  # 100 Pascal per millibar
            self.popFloat(md, "RELHUMID"),
        )
        # Using LST to compute ERA until we get UT1 (see: DM-8053)
        LST = self.popAngle(md, "LST-OBS", units=astropy.units.h)
        argDict['era'] = self.eraFromLstAndLongitude(
            LST, argDict["observatory"].getLongitude())
Example #3
0
class MakeGotoRawVisitInfo(MakeRawVisitInfo):
    """Make a VisitInfo from the FITS header of a GOTO image
    """
    observatory = Observatory(-17.882 * degrees, 28.761 * degrees,
                              2332)  # long, lat, elev

    def setArgDict(self, md, argDict):
        """Set an argument dict for makeVisitInfo and pop associated metadata

        @param[in,out] md  metadata, as an lsst.daf.base.PropertyList or PropertySet
        @param[in,out] argdict  a dict of arguments
        """
        argDict["exposureTime"] = self.popFloat(md, 'EXPTIME')

        startDate = self.popIsoDate(md, "DATE-OBS")
        argDict["date"] = self.offsetDate(startDate,
                                          0.5 * argDict["exposureTime"])

        argDict["boresightAzAlt"] = SpherePoint(
            self.popAngle(md, "AZ"),
            self.popAngle(md, "ALT"),
        )
        argDict["boresightAirmass"] = self.popFloat(md, "AIRMASS")

        argDict["observatory"] = self.observatory

        argDict['darkTime'] = argDict['exposureTime']
class MakeSuperbitRawVisitInfo(MakeRawVisitInfo):
    """Make a VisitInfo from the FITS header of a SuperBIT image
    """
    #Hmm - bit tricky for a floaty observatory; let's hope it's not important
    #Having said that, if you have a record of the telescopes position
    #at the time of observation, you may be able to use that.
    #
    # Put in coordinates of CSBF as a placeholder, with an elevation of 30,000 m
    # hopefully that doesn't make limit of elev fail? --JEM
    observatory = Observatory(31.779524 * degrees, 95.712369 * degrees,
                              30000)  # long, lat, elev

    def setArgDict(self, md, argDict):
        """Set an argument dict for makeVisitInfo and pop associated metadata
        @param[in,out] md  metadata, as an lsst.daf.base.PropertyList or PropertySet
        @param[in,out] argdict  a dict of arguments
        """
        #I believe the names in capitals come from the header. You'll need
        #to change these to reflect your header keywords.
        startDate = self.popIsoDate(md, "DATE_OBS")
        argDict["exposureTime"] = self.popFloat(md, 'EXPTIME')
        argDict['darkTime'] = argDict['exposureTime']

        argDict["date"] = self.offsetDate(startDate,
                                          0.5 * argDict["exposureTime"])
        argDict["boresightAzAlt"] = SpherePoint(
            self.popAngle(md, "AZ"),
            self.popAngle(md, "EL"),
        )
        #argDict["boresightAirmass"] = self.popFloat(md, "AIRMASS")
        argDict["observatory"] = self.observatory
    def setArgDict(self, md, argDict):
        """Set an argument dict for VisitInfo and pop associated metadata

        Parameters
        ----------
        md : `lsst.daf.base.PropertyList` or `lsst.daf.base.PropertySet`
            Metadata to extract from. Extracted values are removed.
        argdict : `dict`
            A dict of arguments to add to values to.
        """
        MakeRawVisitInfo.setArgDict(self, md, argDict)
        argDict["darkTime"] = self.popFloat(md, "DARKTIME")
        argDict["boresightAzAlt"] = SpherePoint(
            self.popAngle(md, "TELAZ"),
            self.popAngle(md, "TELALT"),
        )
        argDict["boresightRaDec"] = SpherePoint(
            self.popAngle(md, "RA_DEG",),
            self.popAngle(md, "DEC_DEG"),
        )
        argDict["boresightAirmass"] = self.popFloat(md, "AIRMASS")
        argDict["observatory"] = Observatory(
            self.popAngle(md, "LONGITUD"),
            self.popAngle(md, "LATITUDE"),
            4204,  # from Wikipedia
        )
        argDict["weather"] = Weather(
            self.popFloat(md, "TEMPERAT"),
            self.popFloat(md, "PRESSURE")*100.0,  # 100 Pascal per millibar
            self.popFloat(md, "RELHUMID"),
        )
        # Using LST to compute ERA until we get UT1 (see: DM-8053)
        LST = self.popAngle(md, "LST-OBS", units=astropy.units.h)
        argDict['era'] = self.eraFromLstAndLongitude(LST, argDict["observatory"].getLongitude())
    def setArgDict(self, md, argDict):
        """Set an argument dict for VisitInfo and pop associated metadata

        @param[in,out] md  metadata, as an lsst.daf.base.PropertyList or PropertySet
        @param[in,out] argdict  a dict of arguments
        """
        MakeRawVisitInfo.setArgDict(self, md, argDict)
        argDict["darkTime"] = self.popFloat(md, "DARKTIME")
        argDict["boresightAzAlt"] = Coord(
            self.popAngle(md, "AZ"),
            self.altitudeFromZenithDistance(self.popAngle(md, "ZD")),
        )
        argDict["boresightRaDec"] = IcrsCoord(
            self.popAngle(md, "TELRA", units=astropy.units.h),
            self.popAngle(md, "TELDEC"),
        )
        argDict["boresightAirmass"] = self.popFloat(md, "AIRMASS")
        argDict["observatory"] = Observatory(
            self.popAngle(md, "OBS-LONG"),
            self.popAngle(md, "OBS-LAT"),
            self.popFloat(md, "OBS-ELEV"),
        )
        argDict["weather"] = Weather(
            self.popFloat(md, "OUTTEMP"),
            self.pascalFromMmHg(self.popFloat(md, "PRESSURE")),
            self.popFloat(md, "HUMIDITY"))
        longitude = argDict["observatory"].getLongitude()
        argDict['era'] = self.decamGetEra(md, argDict["boresightRaDec"][0],
                                          longitude)
class MakeLsstSimRawVisitInfo(MakeRawVisitInfo):
    """Make a VisitInfo from the FITS header of a raw LSST simulated image

    The convention for ROTANG is as follows:
    at  0 degrees E = +Y CCD = -X Focal Plane, N = +X CCD = +Y Focal Plane:   0 boresightRotAng
    at 90 degrees E = -X CCD = -Y Focal Plane, N = +Y CCD = -X Focal Plane: 270 boresightRotAng

    So boresightRotAng = -ROTANG
    """
    observatory = Observatory(-70.749417*degrees, -30.244633*degrees, 2663)  # long, lat, elev

    def setArgDict(self, md, argDict):
        """Set an argument dict for VisitInfo and pop associated metadata

        @param[in,out] md  metadata, as an lsst.daf.base.PropertyList or PropertySet
        @param[in,out] argdict  a dict of arguments
        """
        MakeRawVisitInfo.setArgDict(self, md, argDict)
        argDict["darkTime"] = self.popFloat(md, "DARKTIME")
        argDict["boresightAzAlt"] = SpherePoint(
            self.popAngle(md, "AZIMUTH"),
            self.altitudeFromZenithDistance(self.popAngle(md, "ZENITH")),
        )
        argDict["boresightRaDec"] = SpherePoint(
            self.popAngle(md, "RA_DEG"),
            self.popAngle(md, "DEC_DEG"),
        )
        argDict["boresightAirmass"] = self.popFloat(md, "AIRMASS")
        argDict["boresightRotAngle"] = -self.popAngle(md, "ROTANG")
        argDict["rotType"] = RotType.SKY
        argDict["observatory"] = self.observatory
        weather = defaultWeather(self.observatory.getElevation())
        temperature = self.defaultMetadata(self.popFloat(md, "TEMPERA"), weather.getAirTemperature(),
                                           minimum=-10, maximum=40.)
        pressure = self.defaultMetadata(self.pascalFromMmHg(self.popFloat(md, "PRESS")),
                                        weather.getAirPressure(), minimum=50000., maximum=90000.)
        humidity = 40.  # Not currently supplied by phosim, so set to a typical value.
        argDict["weather"] = Weather(temperature, pressure, humidity)
        longitude = argDict["observatory"].getLongitude()
        RA = argDict["boresightRaDec"][0]
        # phosim doesn't supply LST, HA, or UT1, and the alt/az/ra/dec/time can be inconsistent.
        # We will leave ERA as NaN until a better answer is available.
        try:
            # Other simulation tools don't have the same problem, and need hour angle if it is available.
            HA = self.popAngle(md, "HA", units=astropy.units.h)
            argDict['era'] = HA + RA - longitude
        except Exception:
            self.log.warn("Hour angle missing from metadata, will be NAN")
        return VisitInfo(**argDict)

    def getDateAvg(self, md, exposureTime):
        """Return date at the middle of the exposure

        @param[in,out] md  FITS metadata; changed in place
        @param[in] exposureTime  exposure time in sec
        """
        startDate = self.popMjdDate(md, "TAI", timesys="TAI")
        return self.offsetDate(startDate, 0.5*exposureTime)
Example #8
0
 def createVisitInfo():
     return lsst.afw.image.VisitInfo(
         10313423, 10.01, 11.02,
         DateTime(65321.1, DateTime.MJD,
                  DateTime.TAI), 12345.1, 45.1 * degrees,
         SpherePoint(23.1 * degrees, 73.2 * degrees),
         SpherePoint(134.5 * degrees, 33.3 * degrees), 1.73, 73.2 * degrees,
         lsst.afw.image.RotType.SKY,
         Observatory(11.1 * degrees, 22.2 * degrees, 0.333),
         Weather(1.1, 2.2, 34.5), "testCam")
Example #9
0
class MakeHscRawVisitInfo(MakeRawVisitInfo):
    """Make a VisitInfo from the FITS header of a Subaru HSC image
    """
    observatory = Observatory(-155.476667 * degrees, 19.825556 * degrees,
                              4139)  # long, lat, elev

    def setArgDict(self, md, argDict):
        """Set an argument dict for VisitInfo and pop associated metadata

        @param[in,out] md  metadata, as an lsst.daf.base.PropertyList or PropertySet
        @param[in,out] argdict  a dict of arguments
        """
        MakeRawVisitInfo.setArgDict(self, md, argDict)
        #argDict["boresightRaDec"] = SpherePoint(
        #self.popAngle(md, "RA", units=astropy.units.h),
        #self.popAngle(md, "DEC"),
        #)
        #altitude = self.popAngle(md, "ALTITUDE")
        #altitude = self.popAngle(md, "EL")
        #if altitude > 90*degrees:  # Sometimes during day observations, when not tracking
        #   if self.log is not None:
        #       self.log.warn("Clipping altitude (%f) at 90 degrees", altitude)
        #  altitude = 90*degrees
        #argDict["boresightAzAlt"] = SpherePoint(
        # self.popAngle(md, "AZ"),
        #  altitude,
        #  )
        #argDict["boresightAirmass"] = self.popFloat(md, "AIRMASS")
        #argDict["observatory"] = self.observatory
        #argDict["weather"] = Weather(
        #    self.centigradeFromKelvin(self.popFloat(md, "OUT-TMP")),
        #    self.pascalFromMmHg(self.popFloat(md, "OUT-PRS")),
        #    self.popFloat(md, "OUT-HUM"),
        #)
        #LST = self.popAngle(md, "LST-STR", units=astropy.units.h)
        #argDict['era'] = self.eraFromLstAndLongitude(LST, self.observatory.getLongitude())
        argDict['darkTime'] = argDict['exposureTime']

        # Rotation angle formula determined empirically from visual inspection
        # of HSC images.  See DM-9111.
        #rotAngle = (270.0*degrees - self.popAngle(md, "INST-PA")).wrap()
        #argDict['boresightRotAngle'] = rotAngle
        #argDict['rotType'] = RotType.SKY

    def getDateAvg(self, md, exposureTime):
        """Return date at the middle of the exposure

        @param[in,out] md  FITS metadata; changed in place
        @param[in] exposureTime  exposure time in sec
        """
        startDate = self.popMjdDate(md, "MJD-STR")
        return self.offsetDate(startDate, 0.5 * exposureTime)
Example #10
0
    def setUp(self):
        """Define parameters used by every test."""
        lsstLat = -30.244639 * degrees
        lsstLon = -70.749417 * degrees
        lsstAlt = 2663.
        lsstTemperature = 20. * units.Celsius  # in degrees Celsius
        lsstHumidity = 10.  # in percent
        lsstPressure = 73892. * units.pascal  # 1 atmosphere.
        np.random.seed(5)

        self.weather = Weather(lsstTemperature / units.Celsius,
                               lsstPressure / units.pascal, lsstHumidity)
        self.observatory = Observatory(lsstLon, lsstLat, lsstAlt)
Example #11
0
class MakeLsstSimRawVisitInfo(MakeRawVisitInfo):
    """Make a VisitInfo from the FITS header of a raw LSST simulated image

    The convention for ROTANG is as follows:
    at  0 degrees E = +Y CCD = -X Focal Plane, N = +X CCD = +Y Focal Plane:   0 boresightRotAng
    at 90 degrees E = -X CCD = -Y Focal Plane, N = +Y CCD = -X Focal Plane: 270 boresightRotAng

    So boresightRotAng = -ROTANG
    """
    observatory = Observatory(-70.749417 * degrees, -30.244633 * degrees,
                              2663)  # long, lat, elev

    def setArgDict(self, md, argDict):
        """Set an argument dict for VisitInfo and pop associated metadata

        @param[in,out] md  metadata, as an lsst.daf.base.PropertyList or PropertySet
        @param[in,out] argdict  a dict of arguments
        """
        MakeRawVisitInfo.setArgDict(self, md, argDict)
        argDict["darkTime"] = self.popFloat(md, "DARKTIME")
        argDict["boresightAzAlt"] = Coord(
            self.popAngle(md, "AZIMUTH"),
            self.altitudeFromZenithDistance(self.popAngle(md, "ZENITH")),
        )
        argDict["boresightRaDec"] = IcrsCoord(
            self.popAngle(md, "RA_DEG"),
            self.popAngle(md, "DEC_DEG"),
        )
        argDict["boresightAirmass"] = self.popFloat(md, "AIRMASS")
        argDict["boresightRotAngle"] = -self.popAngle(md, "ROTANG")
        argDict["rotType"] = RotType.SKY
        argDict["observatory"] = self.observatory
        argDict["weather"] = Weather(
            self.popFloat(md, "TEMPERA"),
            self.pascalFromMmHg(self.popFloat(md, "PRESS")),
            float("nan"),
        )
        # phosim doesn't supply LST, HA, or UT1, and the alt/az/ra/dec/time can be inconsistent.
        # We will leave ERA as NaN until a better answer is available.
        return VisitInfo(**argDict)

    def getDateAvg(self, md, exposureTime):
        """Return date at the middle of the exposure

        @param[in,out] md  FITS metadata; changed in place
        @param[in] exposureTime  exposure time in sec
        """
        startDate = self.popMjdDate(md, "TAI", timesys="TAI")
        return self.offsetDate(startDate, 0.5 * exposureTime)
def makeVisitInfo():
    """Return a non-NaN visitInfo."""
    return afwImage.VisitInfo(exposureId=10313423,
                              exposureTime=10.01,
                              darkTime=11.02,
                              date=dafBase.DateTime(65321.1, dafBase.DateTime.MJD, dafBase.DateTime.TAI),
                              ut1=12345.1,
                              era=45.1*afwGeom.degrees,
                              boresightRaDec=afwGeom.SpherePoint(23.1, 73.2, afwGeom.degrees),
                              boresightAzAlt=afwGeom.SpherePoint(134.5, 33.3, afwGeom.degrees),
                              boresightAirmass=1.73,
                              boresightRotAngle=73.2*afwGeom.degrees,
                              rotType=afwImage.RotType.SKY,
                              observatory=Observatory(11.1*afwGeom.degrees, 22.2*afwGeom.degrees, 0.333),
                              weather=Weather(1.1, 2.2, 34.5),
                              )
 def makeVisitInfo():
     return lsst.afw.image.VisitInfo(
         10313423,
         10.01,
         11.02,
         DateTime(65321.1, DateTime.MJD, DateTime.TAI),
         12345.1,
         45.1*lsst.afw.geom.degrees,
         lsst.afw.geom.SpherePoint(23.1, 73.2, lsst.afw.geom.degrees),
         lsst.afw.geom.SpherePoint(134.5, 33.3, lsst.afw.geom.degrees),
         1.73,
         73.2*lsst.afw.geom.degrees,
         lsst.afw.image.RotType.SKY,
         Observatory(11.1*lsst.afw.geom.degrees, 22.2*lsst.afw.geom.degrees, 0.333),
         Weather(1.1, 2.2, 34.5),
     )
class MakeHscRawVisitInfo(MakeRawVisitInfo):
    """Make a VisitInfo from the FITS header of a Subaru HSC image
    """
    observatory = Observatory(-155.476667 * degrees, 19.825556 * degrees,
                              4139)  # long, lat, elev

    def setArgDict(self, md, argDict):
        """Set an argument dict for VisitInfo and pop associated metadata

        @param[in,out] md  metadata, as an lsst.daf.base.PropertyList or PropertySet
        @param[in,out] argdict  a dict of arguments
        """
        MakeRawVisitInfo.setArgDict(self, md, argDict)
        argDict["boresightRaDec"] = IcrsCoord(
            self.popAngle(md, "RA2000", units=astropy.units.h),
            self.popAngle(md, "DEC2000"),
        )
        argDict["boresightAzAlt"] = Coord(
            self.popAngle(md, "AZIMUTH"),
            self.popAngle(md, "ALTITUDE"),
        )
        argDict["boresightAirmass"] = self.popFloat(md, "AIRMASS")
        argDict["observatory"] = self.observatory
        argDict["weather"] = Weather(
            self.centigradeFromKelvin(self.popFloat(md, "OUT-TMP")),
            self.pascalFromMmHg(self.popFloat(md, "OUT-PRS")),
            self.popFloat(md, "OUT-HUM"),
        )
        LST = self.popAngle(md, "LST-STR", units=astropy.units.h)
        argDict['era'] = self.eraFromLstAndLongitude(
            LST, self.observatory.getLongitude())
        argDict['darkTime'] = argDict['exposureTime']

        # Rotation angle formula determined empirically from visual inspection
        # of HSC images.  See DM-9111.
        rotAngle = (270.0 * degrees - self.popAngle(md, "INST-PA")).wrap()
        argDict['boresightRotAngle'] = rotAngle
        argDict['rotType'] = RotType.SKY

    def getDateAvg(self, md, exposureTime):
        """Return date at the middle of the exposure

        @param[in,out] md  FITS metadata; changed in place
        @param[in] exposureTime  exposure time in sec
        """
        startDate = self.popMjdDate(md, "MJD-STR")
        return self.offsetDate(startDate, 0.5 * exposureTime)
class MakeTestRawVisitInfo(MakeRawVisitInfo):
    """Make a VisitInfo from the FITS header of a test image

    Since the test data is extracted from LSST Sim data,
    this is a copy of MakeLsstSimRawVisitInfo
    (using a copy avoids undesireable dependencies)
    """
    observatory = Observatory(-70.749417 * degrees, -30.244633 * degrees,
                              2663)  # long, lat, elev

    def setArgDict(self, md, argDict):
        """Set an argument dict for VisitInfo and pop associated metadata

        @param[in,out] md  metadata, as an lsst.daf.base.PropertyList or PropertySet
        @param[in,out] argdict  a dict of arguments
        """
        MakeRawVisitInfo.setArgDict(self, md, argDict)
        argDict["darkTime"] = self.popFloat(md, "DARKTIME")
        argDict["boresightAzAlt"] = SpherePoint(
            self.popAngle(md, "AZIMUTH"),
            self.altitudeFromZenithDistance(self.popAngle(md, "ZENITH")),
        )
        argDict["boresightRaDec"] = SpherePoint(
            self.popAngle(md, "RA_DEG"),
            self.popAngle(md, "DEC_DEG"),
        )
        argDict["boresightAirmass"] = self.popFloat(md, "AIRMASS")
        argDict["boresightRotAngle"] = -self.popAngle(md, "ROTANG")
        argDict["rotType"] = RotType.SKY
        argDict["observatory"] = self.observatory
        argDict["weather"] = Weather(
            self.popFloat(md, "TEMPERA"),
            self.pascalFromMmHg(self.popFloat(md, "PRESS")),
            float("nan"),
        )
        return VisitInfo(**argDict)

    def getDateAvg(self, md, exposureTime):
        """Return date at the middle of the exposure

        @param[in,out] md  FITS metadata; changed in place
        @param[in] exposureTime  exposure time in sec
        """
        startDate = self.popMjdDate(md, "TAI", timesys="TAI")
        return self.offsetDate(startDate, 0.5 * exposureTime)
Example #16
0
class MakeGotoRawVisitInfo(MakeRawVisitInfo):
    """Make a VisitInfo from the FITS header of a Subaru HSC image

    Boresight rotation angle could probably be set from one of:
    - INST-PT (but apparently only available for HSC, not suprimecam)
    - INR-TR, INR-END (but appears to not be SKY; so probably not interesting)
    """
    observatory = Observatory(-155.476667 * degrees, 19.825556 * degrees,
                              4139)  # long, lat, elev

    def setArgDict(self, md, argDict):
        """Set an argument dict for makeVisitInfo and pop associated metadata

        @param[in,out] md  metadata, as an lsst.daf.base.PropertyList or PropertySet
        @param[in,out] argdict  a dict of arguments
        """
        MakeRawVisitInfo.setArgDict(self, md, argDict)
        argDict["boresightRaDec"] = IcrsCoord(
            self.popAngle(md, "RA2000", units=astropy.units.h),
            self.popAngle(md, "DEC2000"),
        )
        #        argDict["boresightAzAlt"] = Coord(
        #            self.popAngle(md, "AZIMUTH"),
        #            self.popAngle(md, "ALTITUDE"),
        #        )
        argDict["boresightAirmass"] = self.popFloat(md, "AIRMASS")
        argDict["observatory"] = self.observatory
        argDict["weather"] = Weather(
            self.centigradeFromKelvin(self.popFloat(md, "OUT-TMP")),
            self.pascalFromMmHg(self.popFloat(md, "OUT-PRS")),
            self.popFloat(md, "OUT-HUM"),
        )
        LST = self.popAngle(md, "LST-STR", units=astropy.units.h)
        argDict['era'] = self.eraFromLstAndLongitude(
            LST, self.observatory.getLongitude())
        argDict['darkTime'] = argDict['exposureTime']

    def getDateAvg(self, md, exposureTime):
        """Return date at the middle of the exposure

        @param[in,out] md  FITS metadata; changed in place
        @param[in] exposureTime  exposure time in sec
        """
        startDate = self.popMjdDate(md, "MJD-STR")
        return self.offsetDate(startDate, 0.5 * exposureTime)
    def setArgDict(self, md, argDict):
        """Set an argument dict for VisitInfo and pop associated metadata

        @param[in,out] md  metadata, as an lsst.daf.base.PropertyList or PropertySet
        @param[in,out] argdict  a dict of arguments
        """
        MakeRawVisitInfo.setArgDict(self, md, argDict)
        argDict["darkTime"] = self.popFloat(md, "DARKTIME")
        argDict["boresightAzAlt"] = SpherePoint(
            self.popAngle(md, "AZ"),
            self.altitudeFromZenithDistance(self.popAngle(md, "ZD")),
        )
        argDict["boresightRaDec"] = SpherePoint(
            self.popAngle(md, "TELRA", units=astropy.units.h),
            self.popAngle(md, "TELDEC"),
        )
        argDict["boresightAirmass"] = self.popFloat(md, "AIRMASS")
        argDict["observatory"] = Observatory(
            self.popAngle(md, "OBS-LONG"),
            self.popAngle(md, "OBS-LAT"),
            self.popFloat(md, "OBS-ELEV"),
        )
        # Default weather is based on typical conditions at an altitude of 2215 meters.
        temperature = self.defaultMetadata(self.popFloat(md, "OUTTEMP"),
                                           10.,
                                           minimum=-10.,
                                           maximum=40.)
        pressure = self.defaultMetadata(self.pascalFromMmHg(
            self.popFloat(md, "PRESSURE")),
                                        77161.1,
                                        minimum=70000.,
                                        maximum=85000.)
        humidity = self.defaultMetadata(self.popFloat(md, "HUMIDITY"),
                                        40.,
                                        minimum=0.,
                                        maximum=100.)
        argDict["weather"] = Weather(temperature, pressure, humidity)
        longitude = argDict["observatory"].getLongitude()
        argDict['era'] = self.decamGetEra(md, argDict["boresightRaDec"][0],
                                          longitude)
Example #18
0
class MakeCtmoRawVisitInfo(MakeRawVisitInfo):
    "Make a VisitInfo from the FITS header of a CTMO image"

    # longitude, latitude, elevation
    observatory = Observatory(-97.568956 * degrees, 25.995789 * degrees, 12)

    def setArgDict(self, md, argDict):
        """Set an argument dict for makeVisitInfo and pop associated metadata
        @param[in,out] md metadata, as an lsst.daf.base.PropertyList or PropertySet
        @param[in,out] argdict a dict of arguments

        While a Make<>RawVisitInfo file is mandatory for processCcd.py to run,
        it isn't mandatory for it to actually do anything.
        Hence this one simply contains a pass statement.

        However, it's recommended that you at least include the exposure time
        from the image header and observatory information
        (for the latter, remember to edit and uncomment the "observatory"
        variable above.)
        """
        argDict["exposureTime"] = self.popFloat(md, "EXPTIME")
        argDict["observatory"] = self.observatory
Example #19
0
    def __call__(self, md, exposureId=None):
        """Construct a VisitInfo and strip associated data from the metadata.

        Parameters
        ----------
        md : `lsst.daf.base.PropertyList` or `lsst.daf.base.PropertySet`
            Metadata to pull from.
            Items that are used are stripped from the metadata.
        exposureId : `int`, optional
            Ignored.  Here for compatibility with `MakeRawVisitInfo`.

        Returns
        -------
        visitInfo : `lsst.afw.image.VisitInfo`
            `~lsst.afw.image.VisitInfo` derived from the header using
            a `~astro_metadata_translator.MetadataTranslator`.
        """
        argDict = dict()

        obsInfo = ObservationInfo(md, translator_class=self.metadataTranslator)

        # Strip all the cards out that were used
        for c in obsInfo.cards_used:
            del md[c]

        # Map the translated information into a form suitable for VisitInfo
        if obsInfo.exposure_time is not None:
            argDict["exposureTime"] = obsInfo.exposure_time.to_value("s")
        if obsInfo.dark_time is not None:
            argDict["darkTime"] = obsInfo.dark_time.to_value("s")
        argDict["exposureId"] = obsInfo.detector_exposure_id

        # VisitInfo uses the middle of the observation for the date
        if obsInfo.datetime_begin is not None and obsInfo.datetime_end is not None:
            tdelta = obsInfo.datetime_end - obsInfo.datetime_begin
            middle = obsInfo.datetime_begin + 0.5 * tdelta

            # DateTime uses nanosecond resolution, regardless of the resolution
            # of the original date
            middle.precision = 9
            # isot is ISO8601 format with "T" separating date and time and no
            # time zone
            argDict["date"] = DateTime(middle.tai.isot, DateTime.TAI)

            # Derive earth rotation angle from UT1 (being out by a second is not
            # a big deal given the uncertainty over exactly what part of the
            # observation we are needing it for).
            # ERFA needs a UT1 time split into two floats
            # We ignore any problems with DUT1 not being defined for now.
            try:
                ut1time = middle.ut1
            except iers.IERSRangeError:
                ut1time = middle

            era = erfa.era00(ut1time.jd1, ut1time.jd2)
            argDict["era"] = era * radians
        else:
            argDict["date"] = DateTime()

        # Coordinates
        if obsInfo.tracking_radec is not None:
            icrs = obsInfo.tracking_radec.transform_to("icrs")
            argDict["boresightRaDec"] = SpherePoint(icrs.ra.degree,
                                                    icrs.dec.degree,
                                                    units=degrees)

        altaz = obsInfo.altaz_begin
        if altaz is not None:
            argDict["boresightAzAlt"] = SpherePoint(altaz.az.degree,
                                                    altaz.alt.degree,
                                                    units=degrees)

        argDict["boresightAirmass"] = obsInfo.boresight_airmass

        if obsInfo.boresight_rotation_angle is not None:
            argDict[
                "boresightRotAngle"] = obsInfo.boresight_rotation_angle.degree * degrees

        if obsInfo.boresight_rotation_coord is not None:
            rotType = RotType.UNKNOWN
            if obsInfo.boresight_rotation_coord == "sky":
                rotType = RotType.SKY
            argDict["rotType"] = rotType

        # Weather and Observatory Location
        temperature = float("nan")
        if obsInfo.temperature is not None:
            temperature = obsInfo.temperature.to_value(
                "deg_C", astropy.units.temperature())
        pressure = float("nan")
        if obsInfo.pressure is not None:
            pressure = obsInfo.pressure.to_value("Pa")
        relative_humidity = float("nan")
        if obsInfo.relative_humidity is not None:
            relative_humidity = obsInfo.relative_humidity
        argDict["weather"] = Weather(temperature, pressure, relative_humidity)

        if obsInfo.location is not None:
            geolocation = obsInfo.location.to_geodetic()
            argDict["observatory"] = Observatory(
                geolocation.lon.degree * degrees,
                geolocation.lat.degree * degrees,
                geolocation.height.to_value("m"))

        for key in list(
                argDict.keys()):  # use a copy because we may delete items
            if argDict[key] is None:
                self.log.warn("argDict[{}] is None; stripping".format(
                    key, argDict[key]))
                del argDict[key]

        return VisitInfo(**argDict)
Example #20
0
    def observationInfo2visitInfo(obsInfo, log=None):
        """Construct a `~lsst.afw.image.VisitInfo` from an
        `~astro_metadata_translator.ObservationInfo`

        Parameters
        ----------
        obsInfo : `astro_metadata_translator.ObservationInfo`
            Information gathered from the observation metadata.
        log : `logging.Logger` or `lsst.log.Log`, optional
            Logger to use for logging informational messages.
            If `None` logging will be disabled.

        Returns
        -------
        visitInfo : `lsst.afw.image.VisitInfo`
            `~lsst.afw.image.VisitInfo` derived from the supplied
            `~astro_metadata_translator.ObservationInfo`.
        """
        argDict = dict()

        # Map the translated information into a form suitable for VisitInfo
        if obsInfo.exposure_time is not None:
            argDict["exposureTime"] = obsInfo.exposure_time.to_value("s")
        if obsInfo.dark_time is not None:
            argDict["darkTime"] = obsInfo.dark_time.to_value("s")
        argDict["exposureId"] = obsInfo.detector_exposure_id

        # VisitInfo uses the middle of the observation for the date
        if obsInfo.datetime_begin is not None and obsInfo.datetime_end is not None:
            tdelta = obsInfo.datetime_end - obsInfo.datetime_begin
            middle = obsInfo.datetime_begin + 0.5 * tdelta

            # DateTime uses nanosecond resolution, regardless of the resolution
            # of the original date
            middle.precision = 9
            # isot is ISO8601 format with "T" separating date and time and no
            # time zone
            argDict["date"] = DateTime(middle.tai.isot, DateTime.TAI)

            # Derive earth rotation angle from UT1 (being out by a second is
            # not a big deal given the uncertainty over exactly what part of
            # the observation we are needing it for).
            # ERFA needs a UT1 time split into two floats
            # We ignore any problems with DUT1 not being defined for now.
            try:
                # Catch any warnings about the time being in the future
                # since there is nothing we can do about that for simulated
                # data and it tells us nothing for data from the past.
                with warnings.catch_warnings():
                    # If we are using the real erfa it is not an AstropyWarning
                    # During transition period filter both
                    warnings.simplefilter(
                        "ignore",
                        category=astropy.utils.exceptions.AstropyWarning)
                    if ErfaWarning is not None:
                        warnings.simplefilter("ignore", category=ErfaWarning)
                    ut1time = middle.ut1
            except iers.IERSRangeError:
                ut1time = middle

            era = erfa.era00(ut1time.jd1, ut1time.jd2)
            argDict["era"] = era * radians
        else:
            argDict["date"] = DateTime()

        # Coordinates
        if obsInfo.tracking_radec is not None:
            icrs = obsInfo.tracking_radec.transform_to("icrs")
            argDict["boresightRaDec"] = SpherePoint(icrs.ra.degree,
                                                    icrs.dec.degree,
                                                    units=degrees)

        altaz = obsInfo.altaz_begin
        if altaz is not None:
            argDict["boresightAzAlt"] = SpherePoint(altaz.az.degree,
                                                    altaz.alt.degree,
                                                    units=degrees)

        argDict["boresightAirmass"] = obsInfo.boresight_airmass

        if obsInfo.boresight_rotation_angle is not None:
            argDict[
                "boresightRotAngle"] = obsInfo.boresight_rotation_angle.degree * degrees

        if obsInfo.boresight_rotation_coord is not None:
            rotType = RotType.UNKNOWN
            if obsInfo.boresight_rotation_coord == "sky":
                rotType = RotType.SKY
            argDict["rotType"] = rotType

        # Weather and Observatory Location
        temperature = float("nan")
        if obsInfo.temperature is not None:
            temperature = obsInfo.temperature.to_value(
                "deg_C", astropy.units.temperature())
        pressure = float("nan")
        if obsInfo.pressure is not None:
            pressure = obsInfo.pressure.to_value("Pa")
        relative_humidity = float("nan")
        if obsInfo.relative_humidity is not None:
            relative_humidity = obsInfo.relative_humidity
        argDict["weather"] = Weather(temperature, pressure, relative_humidity)

        if obsInfo.location is not None:
            geolocation = obsInfo.location.to_geodetic()
            argDict["observatory"] = Observatory(
                geolocation.lon.degree * degrees,
                geolocation.lat.degree * degrees,
                geolocation.height.to_value("m"))

        for key in list(
                argDict.keys()):  # use a copy because we may delete items
            if argDict[key] is None:
                if log is not None:
                    log.warn("argDict[%s] is None; stripping", key)
                del argDict[key]

        return VisitInfo(**argDict)
Example #21
0
def makeMockVisitSummary(visit,
                         ra_center=0.0,
                         dec_center=-45.0,
                         physical_filter='TEST-I',
                         band='i',
                         mjd=59234.7083333334,
                         psf_sigma=3.0,
                         zenith_distance=45.0,
                         zero_point=30.0,
                         sky_background=100.0,
                         sky_noise=10.0,
                         mean_var=100.0,
                         exposure_time=100.0,
                         detector_size=200,
                         pixel_scale=0.2):
    """Make a mock visit summary catalog.

    This will contain two square detectors with the same metadata,
    with a small (20 pixel) gap between the detectors.  There is no
    rotation, as each detector is simply offset in RA from the
    specified boresight.

    Parameters
    ----------
    visit : `int`
        Visit number.
    ra_center : `float`
        Right ascension of the center of the "camera" boresight (degrees).
    dec_center : `float`
        Declination of the center of the "camera" boresight (degrees).
    physical_filter : `str`
        Arbitrary name for the physical filter.
    band : `str`
        Name of the associated band.
    mjd : `float`
        Modified Julian Date.
    psf_sigma : `float`
        Sigma width of Gaussian psf.
    zenith_distance : `float`
        Distance from zenith of the visit (degrees).
    zero_point : `float`
        Constant zero point for the visit (magnitudes).
    sky_background : `float`
        Background level for the visit (counts).
    sky_noise : `float`
        Noise level for the background of the visit (counts).
    mean_var : `float`
        Mean of the variance plane of the visit (counts).
    exposure_time : `float`
        Exposure time of the visit (seconds).
    detector_size : `int`
        Size of each square detector in the visit (pixels).
    pixel_scale : `float`
        Size of the pixel in arcseconds per pixel.

    Returns
    -------
    visit_summary : `lsst.afw.table.ExposureCatalog`
    """
    # We are making a 2 detector "camera"
    n_detector = 2

    schema = ConsolidateVisitSummaryTask()._makeVisitSummarySchema()
    visit_summary = afwTable.ExposureCatalog(schema)
    visit_summary.resize(n_detector)

    bbox = geom.Box2I(x=geom.IntervalI(min=0, max=detector_size - 1),
                      y=geom.IntervalI(min=0, max=detector_size - 1))

    for detector_id in range(n_detector):
        row = visit_summary[detector_id]

        row['id'] = detector_id
        row.setBBox(bbox)
        row['visit'] = visit
        row['physical_filter'] = physical_filter
        row['band'] = band
        row['zenithDistance'] = zenith_distance
        row['zeroPoint'] = zero_point
        row['skyBg'] = sky_background
        row['skyNoise'] = sky_noise
        row['meanVar'] = mean_var

        # Generate a photocalib
        instFluxMag0 = 10.**(zero_point / 2.5)
        row.setPhotoCalib(
            afwImage.makePhotoCalibFromCalibZeroPoint(instFluxMag0))

        # Generate a WCS and set values accordingly
        crpix = geom.Point2D(detector_size / 2., detector_size / 2.)
        # Create a 20 pixel gap between the two detectors (each offset 10 pixels).
        if detector_id == 0:
            delta_ra = -1.0 * ((detector_size + 10) * pixel_scale /
                               3600.) / np.cos(np.deg2rad(dec_center))
            delta_dec = 0.0
        elif detector_id == 1:
            delta_ra = ((detector_size + 10) * pixel_scale / 3600.) / np.cos(
                np.deg2rad(dec_center))
            delta_dec = 0.0
        crval = geom.SpherePoint(ra_center + delta_ra, dec_center + delta_dec,
                                 geom.degrees)
        cd_matrix = afwGeom.makeCdMatrix(scale=pixel_scale * geom.arcseconds,
                                         orientation=0.0 * geom.degrees)
        wcs = afwGeom.makeSkyWcs(crpix=crpix, crval=crval, cdMatrix=cd_matrix)
        row.setWcs(wcs)

        sph_pts = wcs.pixelToSky(geom.Box2D(bbox).getCorners())
        row['raCorners'] = np.array(
            [float(sph.getRa().asDegrees()) for sph in sph_pts])
        row['decCorners'] = np.array(
            [float(sph.getDec().asDegrees()) for sph in sph_pts])
        sph_pt = wcs.pixelToSky(bbox.getCenter())
        row['ra'] = sph_pt.getRa().asDegrees()
        row['decl'] = sph_pt.getDec().asDegrees()

        # Generate a visitInfo.
        # This does not need to be consistent with the zenith angle in the table,
        # it just needs to be valid and have sufficient information to compute
        # exposure time and parallactic angle.
        date = DateTime(date=mjd, system=DateTime.DateSystem.MJD)
        visit_info = afwImage.VisitInfo(
            exposureId=visit,
            exposureTime=exposure_time,
            date=date,
            darkTime=0.0,
            boresightRaDec=geom.SpherePoint(ra_center, dec_center,
                                            geom.degrees),
            era=45.1 * geom.degrees,
            observatory=Observatory(11.1 * geom.degrees, 0.0 * geom.degrees,
                                    0.333),
            boresightRotAngle=0.0 * geom.degrees,
            rotType=afwImage.RotType.SKY)
        row.setVisitInfo(visit_info)

        # Generate a PSF and set values accordingly
        psf = GaussianPsf(15, 15, psf_sigma)
        row.setPsf(psf)
        psfAvgPos = psf.getAveragePosition()
        shape = psf.computeShape(psfAvgPos)
        row['psfSigma'] = psf.getSigma()
        row['psfIxx'] = shape.getIxx()
        row['psfIyy'] = shape.getIyy()
        row['psfIxy'] = shape.getIxy()
        row['psfArea'] = shape.getArea()

    return visit_summary
Example #22
0
def makeVisitInfo(
    exposureId=0,
    exposureTime=nanFloat,
    darkTime=nanFloat,
    date=DateTime(),
    ut1=nanFloat,
    era=nanAngle,
    boresightRaDec=IcrsCoord(nanAngle, nanAngle),
    boresightAzAlt=Coord(nanAngle, nanAngle),
    boresightAirmass=nanFloat,
    boresightRotAngle=nanAngle,
    rotType=RotType_UNKNOWN,
    observatory=Observatory(nanAngle, nanAngle, nanFloat),
    weather=Weather(nanFloat, nanFloat, nanFloat),
):
    """Make a VisitInfo from keyword arguments

    This function will be replaced by a VisitInfo constructor once we switch to pybind11
    (it is too much hassle with SWIG).

    @param[in] exposureId  exposure ID (int, defaults to 0)
    @param[in] exposureTime  exposure duration (shutter open time); (float, sec, defaults to NaN)
    @param[in] darkTime  time from CCD flush to readout, including shutter open time (despite the name);
                    (float, sec, defaults to NaN)
    @param[in] date  TAI (international atomic time) MJD date at middle of exposure
                    (lsst.daf.base.DateTime; defaults to date of unix epoch)
    @param[in] ut1  UT1 (universal time) MJD date at middle of exposure (float, defaults to Nan)
    @param[in] era  earth rotation angle at middle of exposure
                    (lsst.afw.geom.Angle, defaults to Angle(Nan))
    @param[in] boresightRaDec  ICRS RA/Dec of boresight at middle of exposure
                    (lsst.afw.coord.IcrsCoord; defaults to IcrsCoord(Nan, Nan));
                    other Coord types are accepted and converted to Icrs
    @param[in] boresightAzAlt  refracted apparent topocentric Az/Alt of boresight at middle of exposure;
                    (lsst.afw.coord.Coord; defaults to Coord(Nan, Nan))
    @param[in] boresightAirmass  airmass at the boresight, relative to zenith at sea level
                    (float, defaults to Nan)
    @param[in] boresightRotAngle  rotation angle at boresight at middle of exposure;
                    see getBoresightRotAngle for details
                    (lsst.afw.geom.Angle, defaults to Angle(Nan))
    @param[in] rotType  rotation type; one of the lsst.afw.image.RotType_ constants,
                    defaults to RotType_UNKNOWN
    @param[in] observatory  observatory longitude, latitude and altitude,
                    (lsst.afw.coord.Observatory, defaults to Observatory(Angle(Nan), Angle(Nan), Nan))
    @param[in] weather  basic weather information for computing air mass,
                    (lsst.afw.coord.Weather, defaults to Weather(NaN, NaN, NaN))
    """
    return VisitInfo(
        exposureId,
        exposureTime,
        darkTime,
        date,
        ut1,
        era,
        boresightRaDec.toIcrs(),
        boresightAzAlt,
        boresightAirmass,
        boresightRotAngle,
        rotType,
        observatory,
        weather,
    )
Example #23
0
    def testComputeExposureSummary(self):
        """Make a fake exposure and background and compute summary.
        """
        np.random.seed(12345)

        # Make an exposure with a noise image
        exposure = afwImage.ExposureF(100, 100)
        skySigma = 10.0
        exposure.getImage().getArray()[:, :] = np.random.normal(0.0,
                                                                skySigma,
                                                                size=(100,
                                                                      100))
        exposure.getVariance().getArray()[:, :] = skySigma**2.

        # Set the visitInfo
        date = DateTime(date=59234.7083333334, system=DateTime.DateSystem.MJD)
        observatory = Observatory(-70.7366 * lsst.geom.degrees,
                                  -30.2407 * lsst.geom.degrees, 2650.)
        visitInfo = afwImage.VisitInfo(exposureTime=10.0,
                                       date=date,
                                       observatory=observatory)
        exposure.getInfo().setVisitInfo(visitInfo)

        # Install a Gaussian PSF
        psfSize = 2.0
        psf = GaussianPsf(5, 5, psfSize)
        exposure.setPsf(psf)

        # Install a simple WCS
        scale = 0.2 * lsst.geom.arcseconds
        raCenter = 300.0 * lsst.geom.degrees
        decCenter = 0.0 * lsst.geom.degrees
        cdMatrix = makeCdMatrix(scale=scale)
        skyWcs = makeSkyWcs(crpix=exposure.getBBox().getCenter(),
                            crval=lsst.geom.SpherePoint(raCenter, decCenter),
                            cdMatrix=cdMatrix)
        exposure.setWcs(skyWcs)

        # Install a simple photoCalib
        photoCalib = afwImage.PhotoCalib(calibrationMean=0.3)
        zp = 2.5 * np.log10(photoCalib.getInstFluxAtZeroMagnitude())
        exposure.setPhotoCalib(photoCalib)

        # Compute the background image
        bgGridSize = 10
        bctrl = afwMath.BackgroundControl(afwMath.Interpolate.NATURAL_SPLINE)
        bctrl.setNxSample(
            int(exposure.getMaskedImage().getWidth() / bgGridSize) + 1)
        bctrl.setNySample(
            int(exposure.getMaskedImage().getHeight() / bgGridSize) + 1)
        backobj = afwMath.makeBackground(exposure.getMaskedImage().getImage(),
                                         bctrl)
        background = afwMath.BackgroundList()
        background.append(backobj)

        # Run the task
        expSummaryTask = ComputeExposureSummaryStatsTask()
        summary = expSummaryTask.run(exposure, None, background)

        # Test the outputs
        self.assertFloatsAlmostEqual(summary.psfSigma, psfSize)
        self.assertFloatsAlmostEqual(summary.psfIxx, psfSize**2.)
        self.assertFloatsAlmostEqual(summary.psfIyy, psfSize**2.)
        self.assertFloatsAlmostEqual(summary.psfIxy, 0.0)
        self.assertFloatsAlmostEqual(summary.psfArea, 23.088975164455444)

        delta = (scale * 50).asDegrees()
        for a, b in zip(summary.raCorners, [
                raCenter.asDegrees() + delta,
                raCenter.asDegrees() - delta,
                raCenter.asDegrees() - delta,
                raCenter.asDegrees() + delta
        ]):
            self.assertFloatsAlmostEqual(a, b, atol=1e-10)
        for a, b in zip(summary.decCorners, [
                decCenter.asDegrees() - delta,
                decCenter.asDegrees() - delta,
                decCenter.asDegrees() + delta,
                decCenter.asDegrees() + delta
        ]):
            self.assertFloatsAlmostEqual(a, b, atol=1e-10)

        self.assertFloatsAlmostEqual(summary.ra,
                                     raCenter.asDegrees(),
                                     atol=1e-10)
        self.assertFloatsAlmostEqual(summary.decl,
                                     decCenter.asDegrees(),
                                     atol=1e-10)

        self.assertFloatsAlmostEqual(summary.zeroPoint, zp)

        # Need to compare background level and noise
        # These are only approximately 0+/-10 because of the small image
        self.assertFloatsAlmostEqual(summary.skyBg, -0.079, atol=1e-3)

        self.assertFloatsAlmostEqual(summary.meanVar, skySigma**2.)

        self.assertFloatsAlmostEqual(summary.zenithDistance,
                                     30.57112,
                                     atol=1e-5)
Example #24
0
 def test_getObservatory(self):
     observatory = Observatory(afwGeom.Angle(-70.749417, afwGeom.degrees),
                               afwGeom.Angle(-30.244633, afwGeom.degrees),
                               2663)
     self.assertEqual(observatory, self.visit_info.getObservatory())
Example #25
0
class MakeTestRawVisitInfo(MakeRawVisitInfo):
    """Make a VisitInfo from the FITS header of a test image.

    Notes
    -----
    Since the test data is extracted from LSST Sim data,
    this is a copy of MakeLsstSimRawVisitInfo
    (using a copy avoids undesireable dependencies).
    """
    observatory = Observatory(-70.749417 * degrees, -30.244633 * degrees,
                              2663)  # long, lat, elev

    def setArgDict(self, md, argDict):
        """Set an argument dict for VisitInfo and pop associated metadata.

        Parameters
        ----------
        md : `lsst.daf.base.PropertySet`
            Image metadata.
        argDict : `dict`
            A dict of arguments for the `lsst.afw.image.VisitInfo`
            constructor. Updated by this call.

        Returns
        -------
        visitInfo : `lsst.afw.image.VisitInfo`
            Visit information.
        """
        MakeRawVisitInfo.setArgDict(self, md, argDict)
        argDict["darkTime"] = self.popFloat(md, "DARKTIME")
        argDict["boresightAzAlt"] = SpherePoint(
            self.popAngle(md, "AZIMUTH"),
            self.altitudeFromZenithDistance(self.popAngle(md, "ZENITH")),
        )
        argDict["boresightRaDec"] = SpherePoint(
            self.popAngle(md, "RA_DEG"),
            self.popAngle(md, "DEC_DEG"),
        )
        argDict["boresightAirmass"] = self.popFloat(md, "AIRMASS")
        argDict["boresightRotAngle"] = -self.popAngle(md, "ROTANG")
        argDict["rotType"] = RotType.SKY
        argDict["observatory"] = self.observatory
        argDict["weather"] = Weather(
            self.popFloat(md, "TEMPERA"),
            self.pascalFromMmHg(self.popFloat(md, "PRESS")),
            float("nan"),
        )
        return VisitInfo(**argDict)

    def getDateAvg(self, md, exposureTime):
        """Return date at the middle of the exposure.

        Parameters
        ----------
        md : `lsst.daf.base.PropertySet`
            Image metadata.
        exposureTime : `float`
            Exposure time, in sec

        Returns
        -------
        dateAvg : `lsst.daf.base.DateTime`
            Date at middle of the exposure, or `lsst.daf.base.DateTime()`
            if the metadata item ``TAI`` is not found.
        """
        startDate = self.popMjdDate(md, "TAI", timesys="TAI")
        return self.offsetDate(startDate, 0.5 * exposureTime)