예제 #1
0
    def testAppGeoFromICRS(self):
        mjd = 42350.0
        for pmRaList in [self.pm_raList, None]:
            for pmDecList in [self.pm_decList, None]:
                for pxList in [self.pxList, None]:
                    for vRadList in [self.v_radList, None]:
                        raRad, decRad = utils._appGeoFromICRS(
                            self.raList,
                            self.decList,
                            pmRaList,
                            pmDecList,
                            pxList,
                            vRadList,
                            mjd=ModifiedJulianDate(TAI=mjd))

                        raDeg, decDeg = utils.appGeoFromICRS(
                            np.degrees(self.raList),
                            np.degrees(self.decList),
                            utils.arcsecFromRadians(pmRaList),
                            utils.arcsecFromRadians(pmDecList),
                            utils.arcsecFromRadians(pxList),
                            vRadList,
                            mjd=ModifiedJulianDate(TAI=mjd))

                        dRa = utils.arcsecFromRadians(raRad -
                                                      np.radians(raDeg))
                        np.testing.assert_array_almost_equal(
                            dRa, np.zeros(self.nStars), 9)

                        dDec = utils.arcsecFromRadians(raRad -
                                                       np.radians(raDeg))
                        np.testing.assert_array_almost_equal(
                            dDec, np.zeros(self.nStars), 9)
예제 #2
0
    def ssoInCameraFov(self, ephems, obsData):
        """Determine which observations are within the actual camera footprint for a series of observations.
        Note that ephems and obsData must be the same length.

        Parameters
        ----------
        ephems : np.recarray
            Ephemerides for the objects.
        obsData : np.recarray
            Observation pointings.

        Returns
        -------
        np.ndarray
            Returns the indexes of the numpy array of the object observations which are inside the fov.
        """
        if not hasattr(self, 'camera'):
            self._setupCamera()
        epoch = 2000.0
        # See if the object is within 'rFov' of the center of the boresight.
        idxObsRough = self._ssoInCircleFov(ephems, obsData, rFov=2.1)
        # Then test for the camera footprint exactly.
        idxObs = []
        for idx in idxObsRough:
            mjd_date = obsData[idx][self.obsTimeCol]
            if self.obsTimeScale == 'TAI':
                mjd = ModifiedJulianDate(TAI=mjd_date)
            elif self.obsTimeScale == 'UTC':
                mjd = ModifiedJulianDate(UTC=mjd_date)
            else:
                warnings.warn(
                    'Expected timescale of TAI or UTC, but did not match. Using TAI.'
                )
                mjd = ModifiedJulianDate(TAI=mjd_date)
            if not self.obsDegrees:
                obs_metadata = ObservationMetaData(
                    pointingRA=np.degrees(obsData[idx][self.obsRA]),
                    pointingDec=np.degrees(obsData[idx][self.obsDec]),
                    rotSkyPos=np.degrees(obsData[idx][self.obsRotSkyPos]),
                    mjd=mjd)
            else:
                obs_metadata = ObservationMetaData(
                    pointingRA=obsData[idx][self.obsRA],
                    pointingDec=obsData[idx][self.obsDec],
                    rotSkyPos=obsData[idx][self.obsRotSkyPos],
                    mjd=mjd)
            # Catch the warnings from astropy about the time being in the future.
            with warnings.catch_warnings(record=False):
                warnings.simplefilter('ignore')
                chipName = chipNameFromRaDec(ra=ephems['ra'][idx],
                                             dec=ephems['dec'][idx],
                                             epoch=epoch,
                                             obs_metadata=obs_metadata,
                                             camera=self.camera)
            if chipName is not None:
                tt = self.ccd_type_dict[self.camera[chipName].getType()]
                if tt == 'science':
                    idxObs.append(idx)
        idxObs = np.array(idxObs, int)
        return idxObs
예제 #3
0
    def test_tai_from_utc(self):
        """
        Load a table of UTC vs. TAI (as JD) generated directly
        with ERFA.  Verify our ModifiedJulianDate wrapper against
        this data.  This is mostly so that we can catch any major
        API changes in astropy.
        """

        file_name = os.path.join(getPackageDir('sims_utils'), 'tests')
        file_name = os.path.join(file_name, 'testData', 'utc_tai_comparison_data.txt')

        dtype = np.dtype([('utc', np.float), ('tai', np.float)])
        data = np.genfromtxt(file_name, dtype=dtype)

        msg = "\n\nIt is possible you are using an out-of-date astropy.\n" + \
              "Try running 'conda update astropy' and restarting the build."

        for uu, tt in zip(data['utc']-2400000.5, data['tai']-2400000.5):
            mjd = ModifiedJulianDate(UTC=uu)
            dd_sec = np.abs(mjd.TAI-tt)*86400.0
            self.assertLess(dd_sec, 5.0e-5, msg=msg)
            self.assertAlmostEqual(mjd.UTC, uu, 15, msg=msg)
            mjd = ModifiedJulianDate(TAI=tt)
            dd_sec = np.abs(mjd.UTC-uu)*86400.0
            self.assertLess(dd_sec, 5.0e-5, msg=msg)
            self.assertAlmostEqual(mjd.TAI, tt, 15, msg=msg)
예제 #4
0
 def test_eq(self):
     mjd1 = ModifiedJulianDate(TAI=43000.0)
     mjd2 = ModifiedJulianDate(TAI=43000.0)
     self.assertEqual(mjd1, mjd2)
     self.assertTrue(mjd1 == mjd2)
     self.assertFalse(mjd1 != mjd2)
     mjd3 = ModifiedJulianDate(TAI=43000.01)
     self.assertNotEqual(mjd1, mjd3)
     self.assertFalse(mjd1 == mjd3)
     self.assertTrue(mjd1 != mjd3)
예제 #5
0
    def testApplyProperMotion(self):
        for mjd in self.mjdList:
            raRad, decRad = utils._applyProperMotion(
                self.raList,
                self.decList,
                self.pm_raList,
                self.pm_decList,
                self.pxList,
                self.v_radList,
                mjd=ModifiedJulianDate(TAI=mjd))

            raDeg, decDeg = utils.applyProperMotion(
                np.degrees(self.raList),
                np.degrees(self.decList),
                utils.arcsecFromRadians(self.pm_raList),
                utils.arcsecFromRadians(self.pm_decList),
                utils.arcsecFromRadians(self.pxList),
                self.v_radList,
                mjd=ModifiedJulianDate(TAI=mjd))

            dRa = utils.arcsecFromRadians(raRad - np.radians(raDeg))
            np.testing.assert_array_almost_equal(dRa, np.zeros(self.nStars), 9)

            dDec = utils.arcsecFromRadians(raRad - np.radians(raDeg))
            np.testing.assert_array_almost_equal(dDec, np.zeros(self.nStars),
                                                 9)

        for ra, dec, pm_ra, pm_dec, px, v_rad in \
            zip(self.raList, self.decList, self.pm_raList, self.pm_decList,
                self.pxList, self.v_radList):

            raRad, decRad = utils._applyProperMotion(
                ra,
                dec,
                pm_ra,
                pm_dec,
                px,
                v_rad,
                mjd=ModifiedJulianDate(TAI=self.mjdList[0]))

            raDeg, decDeg = utils.applyProperMotion(
                np.degrees(ra),
                np.degrees(dec),
                utils.arcsecFromRadians(pm_ra),
                utils.arcsecFromRadians(pm_dec),
                utils.arcsecFromRadians(px),
                v_rad,
                mjd=ModifiedJulianDate(TAI=self.mjdList[0]))

            self.assertAlmostEqual(
                utils.arcsecFromRadians(raRad - np.radians(raDeg)), 0.0, 9)
            self.assertAlmostEqual(
                utils.arcsecFromRadians(decRad - np.radians(decDeg)), 0.0, 9)
    def test_fast_agn_light_curves(self):
        raRange = (78.0, 85.0)
        decRange = (-69.0, -65.0)
        bandpass = ('g', 'r')

        slow_lc_gen = AgnLightCurveGenerator(self.agn_db, self.opsimDb)
        pointings = slow_lc_gen.get_pointings(raRange,
                                              decRange,
                                              bandpass=bandpass)
        for row in pointings:
            for obs in row:
                mjd = ModifiedJulianDate(TAI=obs.mjd.TAI - 49000.0 + 59580.0)
                obs.mjd = mjd

        slow_lc, slow_truth = slow_lc_gen.light_curves_from_pointings(
            pointings)

        self.assertGreater(len(slow_lc),
                           2)  # make sure we got some light curves

        fast_lc_gen = FastAgnLightCurveGenerator(self.agn_db, self.opsimDb)
        pointings = fast_lc_gen.get_pointings(raRange,
                                              decRange,
                                              bandpass=bandpass)
        for row in pointings:
            for obs in row:
                mjd = ModifiedJulianDate(TAI=obs.mjd.TAI - 49000.0 + 59580.0)
                obs.mjd = mjd

        fast_lc, fast_truth = fast_lc_gen.light_curves_from_pointings(
            pointings)

        self.assertEqual(len(slow_lc), len(fast_lc))
        self.assertEqual(len(slow_truth), len(fast_truth))

        for obj_id in slow_lc:
            self.assertEqual(len(fast_lc[obj_id]), len(slow_lc[obj_id]))
            for bp in fast_lc[obj_id]:
                self.assertEqual(len(fast_lc[obj_id][bp]),
                                 len(slow_lc[obj_id][bp]))
                for data_key in fast_lc[obj_id][bp]:
                    self.assertEqual(fast_lc[obj_id][bp][data_key].shape,
                                     slow_lc[obj_id][bp][data_key].shape)
                    self.assertLess(
                        np.abs(fast_lc[obj_id][bp][data_key] -
                               slow_lc[obj_id][bp][data_key]).max(),
                        2.0e-10,
                        msg='failed on %d, %s, %s' % (obj_id, bp, data_key))
예제 #7
0
    def test_dut1(self):
        """
        Test that UT1 is within 0.9 seconds of UTC and that dut1 is equal
        to UT1-UTC to within a microsecond.

        (Because calculating UT1-UTC requires loading a lookup
        table, we will just do this somewhat gross unit test to
        make sure that the astropy.time API doesn't change out
        from under us in some weird way... for instance, returning
        dut in units of days rather than seconds, etc.)
        """

        rng = np.random.RandomState(117)

        utc_list = rng.random_sample(1000) * 10000.0 + 43000.0
        for utc in utc_list:
            mjd = ModifiedJulianDate(UTC=utc)

            # first, test the self-consistency of ModifiedJulianData.dut1
            # and ModifiedJulianData.UT1-ModifiedJulianData.UTC
            #
            # this only works for days on which a leap second is not applied
            dt = (mjd.UT1-mjd.UTC) * 86400.0

            self.assertLess(np.abs(dt - mjd.dut1), 1.0e-5,
                            msg='failed on UTC: %.12f' % mjd.UTC)

            self.assertLess(np.abs(mjd.dut1), 0.9)
예제 #8
0
    def testApplyPrecession(self):
        for mjd in self.mjdList:
            raRad, decRad = utils._applyPrecession(
                self.raList, self.decList, mjd=ModifiedJulianDate(TAI=mjd))

            raDeg, decDeg = utils.applyPrecession(
                np.degrees(self.raList),
                np.degrees(self.decList),
                mjd=ModifiedJulianDate(TAI=mjd))

            dRa = utils.arcsecFromRadians(raRad - np.radians(raDeg))
            np.testing.assert_array_almost_equal(dRa, np.zeros(self.nStars), 9)

            dDec = utils.arcsecFromRadians(raRad - np.radians(raDeg))
            np.testing.assert_array_almost_equal(dDec, np.zeros(self.nStars),
                                                 9)
예제 #9
0
    def test_limited_agn_light_curves(self):
        """
        Test that we can select only a limited number of agn light curves
        per field of view
        """

        lc_limit = 2
        raRange = (78.0, 82.0)
        decRange = (-69.0, -65.0)
        bandpass = '******'

        lc_gen = AgnLightCurveGenerator(self.agn_db, self.opsimDb)
        pointings = lc_gen.get_pointings(raRange, decRange, bandpass=bandpass)
        for row in pointings:
            for obs in row:
                mjd = ModifiedJulianDate(TAI=obs.mjd.TAI - 49000.0 + 59580.0)
                obs.mjd = mjd
        self.assertEqual(len(pointings), 1)

        control_lc, truth = lc_gen.light_curves_from_pointings(pointings)
        self.assertGreater(len(control_lc), 2)
        test_lc, truth = lc_gen.light_curves_from_pointings(
            pointings, lc_per_field=lc_limit)
        self.assertGreater(len(control_lc), len(test_lc))
        self.assertEqual(len(test_lc), lc_limit)
    def __init__(self,
                 boundType=None,
                 boundLength=None,
                 mjd=None,
                 pointingRA=None,
                 pointingDec=None,
                 rotSkyPos=None,
                 bandpassName=None,
                 site=Site(name='LSST'),
                 m5=None,
                 skyBrightness=None,
                 seeing=None):

        self._bounds = None
        self._boundType = boundType
        self._bandpass = bandpassName
        self._skyBrightness = skyBrightness
        self._site = site
        self._OpsimMetaData = None

        if mjd is not None:
            if isinstance(mjd, numbers.Number):
                self._mjd = ModifiedJulianDate(TAI=mjd)
            elif isinstance(mjd, ModifiedJulianDate):
                self._mjd = mjd
            else:
                raise RuntimeError(
                    "You must pass either a float or a ModifiedJulianDate "
                    "as the kwarg mjd to ObservationMetaData")
        else:
            self._mjd = None

        if rotSkyPos is not None:
            self._rotSkyPos = np.radians(rotSkyPos)
        else:
            self._rotSkyPos = None

        if pointingRA is not None:
            self._pointingRA = np.radians(pointingRA)
        else:
            self._pointingRA = None

        if pointingDec is not None:
            self._pointingDec = np.radians(pointingDec)
        else:
            self._pointingDec = None

        if boundLength is not None:
            self._boundLength = np.radians(boundLength)
        else:
            self._boundLength = None

        self._m5 = self._assignDictKeyedToBandpass(m5, 'm5')

        self._seeing = self._assignDictKeyedToBandpass(seeing, 'seeing')

        if self._bounds is None:
            self._buildBounds()
예제 #11
0
    def testRaDecFromPupil(self):
        """
        Test conversion from pupil coordinates back to Ra, Dec
        """

        mjd = ModifiedJulianDate(TAI=52000.0)
        solarRA, solarDec = solarRaDec(mjd)

        # to make sure that we are more than 45 degrees from the Sun as required
        # for _icrsFromObserved to be at all accurate
        raCenter = solarRA + 100.0
        decCenter = solarDec - 30.0

        obs = ObservationMetaData(pointingRA=raCenter,
                                  pointingDec=decCenter,
                                  boundType='circle',
                                  boundLength=0.1,
                                  rotSkyPos=23.0,
                                  mjd=mjd)

        nSamples = 1000
        rng = np.random.RandomState(42)
        ra = (rng.random_sample(nSamples) * 0.1 - 0.2) + np.radians(raCenter)
        dec = (rng.random_sample(nSamples) * 0.1 - 0.2) + np.radians(decCenter)
        xp, yp = _pupilCoordsFromRaDec(ra, dec, obs_metadata=obs, epoch=2000.0)

        raTest, decTest = _raDecFromPupilCoords(xp,
                                                yp,
                                                obs_metadata=obs,
                                                epoch=2000.0)

        distance = arcsecFromRadians(haversine(ra, dec, raTest, decTest))

        dex = np.argmax(distance)

        worstSolarDistance = distanceToSun(np.degrees(ra[dex]),
                                           np.degrees(dec[dex]), mjd)

        msg = "_raDecFromPupilCoords off by %e arcsec at distance to Sun of %e degrees" % \
              (distance.max(), worstSolarDistance)

        self.assertLess(distance.max(), 1.0e-6, msg=msg)

        # now check that passing in the xp, yp values one at a time still gives
        # the right answer
        for ix in range(len(ra)):
            ra_f, dec_f = _raDecFromPupilCoords(xp[ix],
                                                yp[ix],
                                                obs_metadata=obs,
                                                epoch=2000.0)
            self.assertIsInstance(ra_f, np.float)
            self.assertIsInstance(dec_f, np.float)
            dist_f = arcsecFromRadians(
                haversine(ra_f, dec_f, raTest[ix], decTest[ix]))
            self.assertLess(dist_f, 1.0e-9)
 def mjd(self, value):
     """
     Either a float or a ModifiedJulianDate.  If a float, this setter
     assumes that you are passing in International Atomic Time
     """
     if isinstance(value, float):
         self._mjd = ModifiedJulianDate(TAI=value)
     elif isinstance(value, ModifiedJulianDate):
         self._mjd = value
     else:
         raise RuntimeError(
             "You can only set mjd to either a float or a ModifiedJulianDate"
         )
예제 #13
0
    def test_warnings(self):
        """
        Test that warnings raised when trying to interpolate UT1-UTC
        for UTC too far in the future are of the type UTCtoUT1Warning
        """
        with warnings.catch_warnings(record=True) as w_list:
            mjd = ModifiedJulianDate(1000000.0)
            # clear the warning registry, in case a previous test raised the warnings
            # we are looking for
            if '__warningregistry__' in mjd._warn_utc_out_of_bounds.__globals__:
                mjd._warn_utc_out_of_bounds.__globals__['__warningregistry__'].clear()
            warnings.simplefilter("always")
            # Trigger a warning.
            # Note that this may also trigger astropy warnings,
            # depending on the order in which tests are run.
            mjd.UT1
        expected_MJD_warnings = 1
        MJD_warnings = 0
        for w in w_list:
            # Count the number of warnings and test we can filter by category.
            if w.category == UTCtoUT1Warning:
                MJD_warnings += 1
                # Test that the string "ModifiedJulianDate.UT1" actually showed up in the message.
                # This indicates what method the warning occured from (UT1 vs dut).
                self.assertIn("ModifiedJulianDate.UT1", str(w.message))
        self.assertEqual(expected_MJD_warnings, MJD_warnings, msg="UT1 did not emit a UTCtoUT1Warning")

        expected_MJD_warnings = 1
        MJD_warnings = 0
        with warnings.catch_warnings(record=True) as w_list:
            warnings.simplefilter('always')
            mjd = ModifiedJulianDate(1000000.0)
            mjd.dut1
        for w in w_list:
            if w.category == UTCtoUT1Warning:
                MJD_warnings += 1
                self.assertIn("ModifiedJulianDate.dut1", str(w.message))
        self.assertEqual(expected_MJD_warnings, MJD_warnings, msg="dut1 did not emit a UTCtoUT1Warning")
예제 #14
0
    def inCameraFov(self,
                    ephems,
                    obsData,
                    epoch=2000.0,
                    timeCol='observationStartMJD'):
        """Determine which observations are within the actual camera footprint for a series of observations.

        Parameters
        ----------
        ephems : np.recarray
            Ephemerides for the objects, with RA and Dec as 'ra' and 'dec' columns (in degrees).
        obsData : np.recarray
            Observation pointings, with RA and Dec as 'ra' and 'dec' columns (in degrees).
            The telescope rotation angle should be in 'rotSkyPos' (in degrees), and the time of each
            pointing should be in the 'expMJD' column.
        epoch: float, opt
            The epoch of the ephemerides and pointing data. Default 2000.0.

        Returns
        -------
        np.ndarray
            Returns the indexes of the numpy array of the object observations which are inside the fov.
        """
        # See if the object is within 'rFov' of the center of the boresight.
        sep = angularSeparation(ephems['ra'], ephems['dec'], obsData['ra'],
                                obsData['dec'])
        idxObsRough = np.where(sep <= 2.1)[0]
        # Or go on and use the camera footprint.
        idxObs = []
        for idx in idxObsRough:
            mjd_date = obsData[idx][timeCol]
            mjd = ModifiedJulianDate(TAI=mjd_date)
            obs_metadata = ObservationMetaData(
                pointingRA=obsData[idx]['ra'],
                pointingDec=obsData[idx]['dec'],
                rotSkyPos=obsData[idx]['rotSkyPos'],
                mjd=mjd)
            # Catch the warnings from astropy about the time being in the future.
            with warnings.catch_warnings(record=False):
                warnings.simplefilter('ignore')
                chipName = chipNameFromRaDecLSST(ra=ephems['ra'][idx],
                                                 dec=ephems['dec'][idx],
                                                 epoch=epoch,
                                                 obs_metadata=obs_metadata)
            if chipName != None:
                tt = self.ccd_type_dict[self.camera[chipName].getType()]
                if tt == 'science':
                    idxObs.append(idx)
        idxObs = np.array(idxObs, int)
        return idxObs
예제 #15
0
    def testIcrsFromAppGeo(self):

        for mjd in (53525.0, 54316.3, 58463.7):
            for epoch in (2000.0, 1950.0, 2010.0):

                raRad, decRad = utils._icrsFromAppGeo(
                    self.raList,
                    self.decList,
                    epoch=epoch,
                    mjd=ModifiedJulianDate(TAI=mjd))

                raDeg, decDeg = utils.icrsFromAppGeo(
                    np.degrees(self.raList),
                    np.degrees(self.decList),
                    epoch=epoch,
                    mjd=ModifiedJulianDate(TAI=mjd))

                dRa = utils.arcsecFromRadians(np.abs(raRad -
                                                     np.radians(raDeg)))
                self.assertLess(dRa.max(), 1.0e-9)

                dDec = utils.arcsecFromRadians(
                    np.abs(decRad - np.radians(decDeg)))
                self.assertLess(dDec.max(), 1.0e-9)
예제 #16
0
 def ssoInFov(self,
              interpfuncs,
              simdata,
              rFov=1.75,
              useCamera=True,
              simdataRaCol='fieldRA',
              simdataDecCol='fieldDec',
              simdataExpMJDCol='expMJD'):
     """
     Return the indexes of the simdata observations where the object was inside the fov.
     """
     # See if the object is within 'rFov' of the center of the boresight.
     raSso = interpfuncs['ra'](simdata[simdataExpMJDCol])
     decSso = interpfuncs['dec'](simdata[simdataExpMJDCol])
     sep = angularSeparation(raSso, decSso,
                             np.degrees(simdata[simdataRaCol]),
                             np.degrees(simdata[simdataDecCol]))
     if not useCamera:
         idxObsRough = np.where(sep < rFov)[0]
         return idxObsRough
     # Or go on and use the camera footprint.
     idxObs = []
     idxObsRough = np.where(sep < self.cameraFov)[0]
     for idx in idxObsRough:
         mjd_date = simdata[idx][simdataExpMJDCol]
         mjd = ModifiedJulianDate(TAI=mjd_date)
         obs_metadata = ObservationMetaData(
             pointingRA=np.degrees(simdata[idx][simdataRaCol]),
             pointingDec=np.degrees(simdata[idx][simdataDecCol]),
             rotSkyPos=np.degrees(simdata[idx]['rotSkyPos']),
             mjd=mjd)
         raObj = np.array(
             [interpfuncs['ra'](simdata[idx][simdataExpMJDCol])])
         decObj = np.array(
             [interpfuncs['dec'](simdata[idx][simdataExpMJDCol])])
         # Catch the warnings from astropy about the time being in the future.
         with warnings.catch_warnings(record=False):
             warnings.simplefilter('ignore')
             chipNames = chipNameFromRaDecLSST(ra=raObj,
                                               dec=decObj,
                                               epoch=self.epoch,
                                               obs_metadata=obs_metadata)
         if chipNames != [None]:
             idxObs.append(idx)
     idxObs = np.array(idxObs)
     return idxObs
예제 #17
0
    def test_tt(self):
        """
        Verify that Terrestrial Time is TAI + 32.184 seconds
        as in equation 2.223-6 of

        Explanatory Supplement to the Astrnomical Almanac
        ed. Seidelmann, Kenneth P.
        1992, University Science Books

        Mostly, this test exists to catch any major API
        changes in astropy.time
        """

        rng = np.random.RandomState(115)
        tai_list = rng.random_sample(1000)*7000.0+50000.0
        for tai in tai_list:
            mjd = ModifiedJulianDate(TAI=tai)
            self.assertAlmostEqual(mjd.TT, tai + 32.184 / 86400.0, 15)
예제 #18
0
    def test_list(self):
        """
        Test that ModifiedJulianDate.get_list() gets results that are consistent
        with creating a list of ModifiedJulianDates by hand.
        """

        rng = np.random.RandomState(88)
        tol = 10  # decimal place tolerance

        tai_list = 40000.0 + 10000.0 * rng.random_sample(20)
        tai_list = np.append(tai_list, 59580.0 + 10000.0 * rng.random_sample(20))
        mjd_list = ModifiedJulianDate.get_list(TAI=tai_list)
        for tai, mjd in zip(tai_list, mjd_list):
            msg = "Offending TAI: %f" % tai
            control = ModifiedJulianDate(TAI=tai)
            self.assertAlmostEqual(mjd.TAI, tai, 11, msg=msg)
            self.assertAlmostEqual(mjd.TAI, control.TAI, tol, msg=msg)
            self.assertAlmostEqual(mjd.UTC, control.UTC, tol, msg=msg)
            self.assertAlmostEqual(mjd.UT1, control.UT1, tol, msg=msg)
            self.assertAlmostEqual(mjd.TT, control.TT, tol, msg=msg)
            self.assertAlmostEqual(mjd.TDB, control.TDB, tol, msg=msg)
            self.assertAlmostEqual(mjd.dut1, control.dut1, tol, msg=msg)

        utc_list = 40000.0 + 10000.0 * rng.random_sample(20)
        utc_list = np.append(utc_list, 59580.0 + 10000.0 * rng.random_sample(20))
        mjd_list = ModifiedJulianDate.get_list(UTC=utc_list)
        for utc, mjd in zip(utc_list, mjd_list):
            msg = "Offending UTC: %f" % utc
            control = ModifiedJulianDate(UTC=utc)
            self.assertAlmostEqual(mjd.UTC, utc, tol, msg=msg)
            self.assertAlmostEqual(mjd.TAI, control.TAI, tol, msg=msg)
            self.assertAlmostEqual(mjd.UTC, control.UTC, tol, msg=msg)
            self.assertAlmostEqual(mjd.UT1, control.UT1, tol, msg=msg)
            self.assertAlmostEqual(mjd.TT, control.TT, tol, msg=msg)
            self.assertAlmostEqual(mjd.TDB, control.TDB, tol, msg=msg)
            self.assertAlmostEqual(mjd.dut1, control.dut1, tol, msg=msg)

        # Now test the case where we only have dates in the future (this
        # is an edge case since good_dexes in ModifiedJulianDate._get_ut1_from_utc
        # will have len = 0
        tai_list = 60000.0 + 10000.0 * rng.random_sample(20)
        mjd_list = ModifiedJulianDate.get_list(TAI=tai_list)
        for tai, mjd in zip(tai_list, mjd_list):
            msg = "Offending TAI: %f" % tai
            control = ModifiedJulianDate(TAI=tai)
            self.assertAlmostEqual(mjd.TAI, tai, 11, msg=msg)
            self.assertAlmostEqual(mjd.TAI, control.TAI, tol, msg=msg)
            self.assertAlmostEqual(mjd.UTC, control.UTC, tol, msg=msg)
            self.assertAlmostEqual(mjd.UT1, control.UT1, tol, msg=msg)
            self.assertAlmostEqual(mjd.TT, control.TT, tol, msg=msg)
            self.assertAlmostEqual(mjd.TDB, control.TDB, tol, msg=msg)
            self.assertAlmostEqual(mjd.dut1, control.dut1, tol, msg=msg)
예제 #19
0
    def test_tdb(self):
        """
        Verify that TDB is within a few tens of microseconds of the value given
        by the approximation given by equation 2.222-1 of

        Explanatory Supplement to the Astrnomical Almanac
        ed. Seidelmann, Kenneth P.
        1992, University Science Books

        Mostly, this test exists to catch any major API
        changes in astropy.time
        """

        rng = np.random.RandomState(117)
        tai_list = rng.random_sample(1000)*10000.0 + 46000.0
        for tai in tai_list:
            mjd = ModifiedJulianDate(TAI=tai)
            g = np.radians(357.53 + 0.9856003 * (np.round(tai - 51544.5)))
            tdb_test = mjd.TT + (0.001658 * np.sin(g) + 0.000014 * np.sin(2.0*g)) / 86400.0
            dt = np.abs(tdb_test-mjd.TDB) * 8.64 * 1.0e10  # convert to microseconds
            self.assertLess(dt, 50)
예제 #20
0
    def test_force_values(self):
        """
        Test that we can force the properties of a ModifiedJulianDate to have
        specific values
        """
        tt = ModifiedJulianDate(TAI=59580.0)
        values = np.arange(6)
        tt._force_values(values)
        self.assertEqual(tt.TAI, 0.0)
        self.assertEqual(tt.UTC, 1.0)
        self.assertEqual(tt.TT, 2.0)
        self.assertEqual(tt.TDB, 3.0)
        self.assertEqual(tt.UT1, 4.0)
        self.assertEqual(tt.dut1, 5.0)

        tt = ModifiedJulianDate(UTC=59580.0)
        values = 2.0*np.arange(6)
        tt._force_values(values)
        self.assertEqual(tt.TAI, 0.0)
        self.assertEqual(tt.UTC, 2.0)
        self.assertEqual(tt.TT, 4.0)
        self.assertEqual(tt.TDB, 6.0)
        self.assertEqual(tt.UT1, 8.0)
        self.assertEqual(tt.dut1, 10.0)
예제 #21
0
    def test_alert_data_generation(self):

        dmag_cutoff = 0.005
        mag_name_to_int = {'u': 0, 'g': 1, 'r': 2, 'i': 3, 'z' : 4, 'y': 5}

        _max_var_param_str = self.max_str_len

        class StarAlertTestDBObj(StellarAlertDBObjMixin, CatalogDBObject):
            objid = 'star_alert'
            tableid = 'stars'
            idColKey = 'simobjid'
            raColName = 'ra'
            decColName = 'dec'
            objectTypeId = 0
            columns = [('raJ2000', 'ra*0.01745329252'),
                       ('decJ2000', 'dec*0.01745329252'),
                       ('parallax', 'px*0.01745329252/3600.0'),
                       ('properMotionRa', 'pmra*0.01745329252/3600.0'),
                       ('properMotionDec', 'pmdec*0.01745329252/3600.0'),
                       ('radialVelocity', 'vrad'),
                       ('variabilityParameters', 'varParamStr', str, _max_var_param_str)]

        class TestAlertsVarCatMixin(object):

            @register_method('alert_test')
            def applyAlertTest(self, valid_dexes, params, expmjd, variability_cache=None):
                if len(params) == 0:
                    return np.array([[], [], [], [], [], []])

                if isinstance(expmjd, numbers.Number):
                    dmags_out = np.zeros((6, self.num_variable_obj(params)))
                else:
                    dmags_out = np.zeros((6, self.num_variable_obj(params), len(expmjd)))

                for i_star in range(self.num_variable_obj(params)):
                    if params['amp'][i_star] is not None:
                        dmags = params['amp'][i_star]*np.cos(params['per'][i_star]*expmjd)
                        for i_filter in range(6):
                            dmags_out[i_filter][i_star] = dmags

                return dmags_out

        class TestAlertsVarCat(TestAlertsVarCatMixin, AlertStellarVariabilityCatalog):
            pass

        class TestAlertsTruthCat(TestAlertsVarCatMixin, CameraCoords, AstrometryStars,
                                 Variability, InstanceCatalog):
            column_outputs = ['uniqueId', 'chipName', 'dmagAlert', 'magAlert']

            camera = obs_lsst_phosim.PhosimMapper().camera

            @compound('delta_umag', 'delta_gmag', 'delta_rmag',
                      'delta_imag', 'delta_zmag', 'delta_ymag')
            def get_TruthVariability(self):
                return self.applyVariability(self.column_by_name('varParamStr'))

            @cached
            def get_dmagAlert(self):
                return self.column_by_name('delta_%smag' % self.obs_metadata.bandpass)

            @cached
            def get_magAlert(self):
                return self.column_by_name('%smag' % self.obs_metadata.bandpass) + \
                       self.column_by_name('dmagAlert')

        star_db = StarAlertTestDBObj(database=self.star_db_name, driver='sqlite')

        # assemble the true light curves for each object; we need to figure out
        # if their np.max(dMag) ever goes over dmag_cutoff; then we will know if
        # we are supposed to simulate them
        true_lc_dict = {}
        true_lc_obshistid_dict = {}
        is_visible_dict = {}
        obs_dict = {}
        max_obshistid = -1
        n_total_observations = 0
        for obs in self.obs_list:
            obs_dict[obs.OpsimMetaData['obsHistID']] = obs
            obshistid = obs.OpsimMetaData['obsHistID']
            if obshistid > max_obshistid:
                max_obshistid = obshistid
            cat = TestAlertsTruthCat(star_db, obs_metadata=obs)

            for line in cat.iter_catalog():
                if line[1] is None:
                    continue

                n_total_observations += 1
                if line[0] not in true_lc_dict:
                    true_lc_dict[line[0]] = {}
                    true_lc_obshistid_dict[line[0]] = []

                true_lc_dict[line[0]][obshistid] = line[2]
                true_lc_obshistid_dict[line[0]].append(obshistid)

                if line[0] not in is_visible_dict:
                    is_visible_dict[line[0]] = False

                if line[3] <= self.obs_mag_cutoff[mag_name_to_int[obs.bandpass]]:
                    is_visible_dict[line[0]] = True

        obshistid_bits = int(np.ceil(np.log(max_obshistid)/np.log(2)))

        skipped_due_to_mag = 0

        objects_to_simulate = []
        obshistid_unqid_set = set()
        for obj_id in true_lc_dict:

            dmag_max = -1.0
            for obshistid in true_lc_dict[obj_id]:
                if np.abs(true_lc_dict[obj_id][obshistid]) > dmag_max:
                    dmag_max = np.abs(true_lc_dict[obj_id][obshistid])

            if dmag_max >= dmag_cutoff:
                if not is_visible_dict[obj_id]:
                    skipped_due_to_mag += 1
                    continue

                objects_to_simulate.append(obj_id)
                for obshistid in true_lc_obshistid_dict[obj_id]:
                    obshistid_unqid_set.add((obj_id << obshistid_bits) + obshistid)

        self.assertGreater(len(objects_to_simulate), 10)
        self.assertGreater(skipped_due_to_mag, 0)

        log_file_name = tempfile.mktemp(dir=self.output_dir, suffix='log.txt')
        alert_gen = AlertDataGenerator(testing=True)

        alert_gen.subdivide_obs(self.obs_list, htmid_level=6)

        for htmid in alert_gen.htmid_list:
            alert_gen.alert_data_from_htmid(htmid, star_db,
                                            photometry_class=TestAlertsVarCat,
                                            output_prefix='alert_test',
                                            output_dir=self.output_dir,
                                            dmag_cutoff=dmag_cutoff,
                                            log_file_name=log_file_name)

        dummy_sed = Sed()

        bp_dict = BandpassDict.loadTotalBandpassesFromFiles()

        phot_params = PhotometricParameters()

        # First, verify that the contents of the sqlite files are all correct

        n_tot_simulated = 0

        alert_query = 'SELECT alert.uniqueId, alert.obshistId, meta.TAI, '
        alert_query += 'meta.band, quiescent.flux, alert.dflux, '
        alert_query += 'quiescent.snr, alert.snr, '
        alert_query += 'alert.ra, alert.dec, alert.chipNum, '
        alert_query += 'alert.xPix, alert.yPix, ast.pmRA, ast.pmDec, '
        alert_query += 'ast.parallax '
        alert_query += 'FROM alert_data AS alert '
        alert_query += 'INNER JOIN metadata AS meta ON meta.obshistId=alert.obshistId '
        alert_query += 'INNER JOIN quiescent_flux AS quiescent '
        alert_query += 'ON quiescent.uniqueId=alert.uniqueId '
        alert_query += 'AND quiescent.band=meta.band '
        alert_query += 'INNER JOIN baseline_astrometry AS ast '
        alert_query += 'ON ast.uniqueId=alert.uniqueId'

        alert_dtype = np.dtype([('uniqueId', int), ('obshistId', int),
                                ('TAI', float), ('band', int),
                                ('q_flux', float), ('dflux', float),
                                ('q_snr', float), ('tot_snr', float),
                                ('ra', float), ('dec', float),
                                ('chipNum', int), ('xPix', float), ('yPix', float),
                                ('pmRA', float), ('pmDec', float), ('parallax', float)])

        sqlite_file_list = os.listdir(self.output_dir)

        n_tot_simulated = 0
        obshistid_unqid_simulated_set = set()
        for file_name in sqlite_file_list:
            if not file_name.endswith('db'):
                continue
            full_name = os.path.join(self.output_dir, file_name)
            self.assertTrue(os.path.exists(full_name))
            alert_db = DBObject(full_name, driver='sqlite')
            alert_data = alert_db.execute_arbitrary(alert_query, dtype=alert_dtype)
            if len(alert_data) == 0:
                continue

            mjd_list = ModifiedJulianDate.get_list(TAI=alert_data['TAI'])
            for i_obj in range(len(alert_data)):
                n_tot_simulated += 1
                obshistid_unqid_simulated_set.add((alert_data['uniqueId'][i_obj] << obshistid_bits) +
                                                  alert_data['obshistId'][i_obj])

                unq = alert_data['uniqueId'][i_obj]
                obj_dex = (unq//1024)-1
                self.assertAlmostEqual(self.pmra_truth[obj_dex], 0.001*alert_data['pmRA'][i_obj], 4)
                self.assertAlmostEqual(self.pmdec_truth[obj_dex], 0.001*alert_data['pmDec'][i_obj], 4)
                self.assertAlmostEqual(self.px_truth[obj_dex], 0.001*alert_data['parallax'][i_obj], 4)

                ra_truth, dec_truth = applyProperMotion(self.ra_truth[obj_dex], self.dec_truth[obj_dex],
                                                        self.pmra_truth[obj_dex], self.pmdec_truth[obj_dex],
                                                        self.px_truth[obj_dex], self.vrad_truth[obj_dex],
                                                        mjd=mjd_list[i_obj])
                distance = angularSeparation(ra_truth, dec_truth,
                                             alert_data['ra'][i_obj], alert_data['dec'][i_obj])

                distance_arcsec = 3600.0*distance
                msg = '\ntruth: %e %e\nalert: %e %e\n' % (ra_truth, dec_truth,
                                                          alert_data['ra'][i_obj],
                                                          alert_data['dec'][i_obj])

                self.assertLess(distance_arcsec, 0.0005, msg=msg)

                obs = obs_dict[alert_data['obshistId'][i_obj]]


                chipname = chipNameFromRaDec(self.ra_truth[obj_dex], self.dec_truth[obj_dex],
                                             pm_ra=self.pmra_truth[obj_dex],
                                             pm_dec=self.pmdec_truth[obj_dex],
                                             parallax=self.px_truth[obj_dex],
                                             v_rad=self.vrad_truth[obj_dex],
                                             obs_metadata=obs,
                                             camera=self.camera)

                chipnum = int(chipname.replace('R', '').replace('S', '').
                              replace(' ', '').replace(';', '').replace(',', '').
                              replace(':', ''))

                self.assertEqual(chipnum, alert_data['chipNum'][i_obj])

                xpix, ypix = pixelCoordsFromRaDec(self.ra_truth[obj_dex], self.dec_truth[obj_dex],
                                                  pm_ra=self.pmra_truth[obj_dex],
                                                  pm_dec=self.pmdec_truth[obj_dex],
                                                  parallax=self.px_truth[obj_dex],
                                                  v_rad=self.vrad_truth[obj_dex],
                                                  obs_metadata=obs,
                                                  camera=self.camera)

                self.assertAlmostEqual(alert_data['xPix'][i_obj], xpix, 4)
                self.assertAlmostEqual(alert_data['yPix'][i_obj], ypix, 4)

                dmag_sim = -2.5*np.log10(1.0+alert_data['dflux'][i_obj]/alert_data['q_flux'][i_obj])
                self.assertAlmostEqual(true_lc_dict[alert_data['uniqueId'][i_obj]][alert_data['obshistId'][i_obj]],
                                       dmag_sim, 3)

                mag_name = ('u', 'g', 'r', 'i', 'z', 'y')[alert_data['band'][i_obj]]
                m5 = obs.m5[mag_name]

                q_mag = dummy_sed.magFromFlux(alert_data['q_flux'][i_obj])
                self.assertAlmostEqual(self.mag0_truth_dict[alert_data['band'][i_obj]][obj_dex],
                                       q_mag, 4)

                snr, gamma = calcSNR_m5(self.mag0_truth_dict[alert_data['band'][i_obj]][obj_dex],
                                        bp_dict[mag_name],
                                        self.obs_mag_cutoff[alert_data['band'][i_obj]],
                                        phot_params)

                self.assertAlmostEqual(snr/alert_data['q_snr'][i_obj], 1.0, 4)

                tot_mag = self.mag0_truth_dict[alert_data['band'][i_obj]][obj_dex] + \
                          true_lc_dict[alert_data['uniqueId'][i_obj]][alert_data['obshistId'][i_obj]]

                snr, gamma = calcSNR_m5(tot_mag, bp_dict[mag_name],
                                        m5, phot_params)
                self.assertAlmostEqual(snr/alert_data['tot_snr'][i_obj], 1.0, 4)

        for val in obshistid_unqid_set:
            self.assertIn(val, obshistid_unqid_simulated_set)
        self.assertEqual(len(obshistid_unqid_set), len(obshistid_unqid_simulated_set))

        astrometry_query = 'SELECT uniqueId, ra, dec, TAI '
        astrometry_query += 'FROM baseline_astrometry'
        astrometry_dtype = np.dtype([('uniqueId', int),
                                     ('ra', float),
                                     ('dec', float),
                                     ('TAI', float)])

        tai_list = []
        for obs in self.obs_list:
            tai_list.append(obs.mjd.TAI)
        tai_list = np.array(tai_list)

        n_tot_ast_simulated = 0
        for file_name in sqlite_file_list:
            if not file_name.endswith('db'):
                continue
            full_name = os.path.join(self.output_dir, file_name)
            self.assertTrue(os.path.exists(full_name))
            alert_db = DBObject(full_name, driver='sqlite')
            astrometry_data = alert_db.execute_arbitrary(astrometry_query, dtype=astrometry_dtype)

            if len(astrometry_data) == 0:
                continue

            mjd_list = ModifiedJulianDate.get_list(TAI=astrometry_data['TAI'])
            for i_obj in range(len(astrometry_data)):
                n_tot_ast_simulated += 1
                obj_dex = (astrometry_data['uniqueId'][i_obj]//1024) - 1
                ra_truth, dec_truth = applyProperMotion(self.ra_truth[obj_dex], self.dec_truth[obj_dex],
                                                        self.pmra_truth[obj_dex], self.pmdec_truth[obj_dex],
                                                        self.px_truth[obj_dex], self.vrad_truth[obj_dex],
                                                        mjd=mjd_list[i_obj])

                distance = angularSeparation(ra_truth, dec_truth,
                                             astrometry_data['ra'][i_obj],
                                             astrometry_data['dec'][i_obj])

                self.assertLess(3600.0*distance, 0.0005)

        del alert_gen
        gc.collect()
        self.assertGreater(n_tot_simulated, 10)
        self.assertGreater(len(obshistid_unqid_simulated_set), 10)
        self.assertLess(len(obshistid_unqid_simulated_set), n_total_observations)
        self.assertGreater(n_tot_ast_simulated, 0)
예제 #22
0
    def testAssignment(self):
        """
        Test that ObservationMetaData member variables get passed correctly
        """

        mjd = 5120.0
        RA = 1.5
        Dec = -1.1
        rotSkyPos = -10.0
        skyBrightness = 25.0

        testObsMD = ObservationMetaData()
        testObsMD.pointingRA = RA
        testObsMD.pointingDec = Dec
        testObsMD.rotSkyPos = rotSkyPos
        testObsMD.skyBrightness = skyBrightness
        testObsMD.mjd = mjd
        testObsMD.boundType = 'box'
        testObsMD.boundLength = [1.2, 3.0]

        self.assertAlmostEqual(testObsMD.pointingRA, RA, 10)
        self.assertAlmostEqual(testObsMD.pointingDec, Dec, 10)
        self.assertAlmostEqual(testObsMD.rotSkyPos, rotSkyPos, 10)
        self.assertAlmostEqual(testObsMD.skyBrightness, skyBrightness, 10)
        self.assertEqual(testObsMD.boundType, 'box')
        self.assertAlmostEqual(testObsMD.boundLength[0], 1.2, 10)
        self.assertAlmostEqual(testObsMD.boundLength[1], 3.0, 10)
        self.assertAlmostEqual(testObsMD.mjd.TAI, mjd, 10)

        # test reassignment

        testObsMD.pointingRA = RA + 1.0
        testObsMD.pointingDec = Dec + 1.0
        testObsMD.rotSkyPos = rotSkyPos + 1.0
        testObsMD.skyBrightness = skyBrightness + 1.0
        testObsMD.boundLength = 2.2
        testObsMD.boundType = 'circle'
        testObsMD.mjd = mjd + 10.0

        self.assertAlmostEqual(testObsMD.pointingRA, RA + 1.0, 10)
        self.assertAlmostEqual(testObsMD.pointingDec, Dec + 1.0, 10)
        self.assertAlmostEqual(testObsMD.rotSkyPos, rotSkyPos + 1.0, 10)
        self.assertAlmostEqual(testObsMD.skyBrightness, skyBrightness + 1.0,
                               10)
        self.assertEqual(testObsMD.boundType, 'circle')
        self.assertAlmostEqual(testObsMD.boundLength, 2.2, 10)
        self.assertAlmostEqual(testObsMD.mjd.TAI, mjd + 10.0, 10)

        testObsMD = ObservationMetaData(mjd=mjd,
                                        pointingRA=RA,
                                        pointingDec=Dec,
                                        rotSkyPos=rotSkyPos,
                                        bandpassName='z',
                                        skyBrightness=skyBrightness)

        self.assertAlmostEqual(testObsMD.mjd.TAI, 5120.0, 10)
        self.assertAlmostEqual(testObsMD.pointingRA, 1.5, 10)
        self.assertAlmostEqual(testObsMD.pointingDec, -1.1, 10)
        self.assertAlmostEqual(testObsMD.rotSkyPos, -10.0, 10)
        self.assertEqual(testObsMD.bandpass, 'z')
        self.assertAlmostEqual(testObsMD.skyBrightness, skyBrightness, 10)

        # test assigning ModifiedJulianDate
        obs = ObservationMetaData()
        mjd = ModifiedJulianDate(TAI=57388.0)
        obs.mjd = mjd
        self.assertEqual(obs.mjd, mjd)

        mjd2 = ModifiedJulianDate(TAI=45000.0)
        obs.mjd = mjd2
        self.assertEqual(obs.mjd, mjd2)
        self.assertNotEqual(obs.mjd, mjd)
예제 #23
0
            assert np.diff(obs_params['obsHistID']).min()>0

            obsid_query = np.array(htmid_to_obs[htmid_query])
            obs_dex = np.searchsorted(obs_params['obsHistID'].value, obsid_query)
            np.testing.assert_array_equal(obs_params['obsHistID'].value[obs_dex],
                                          obsid_query)

            ra_obs = obs_params['ra'].value[obs_dex]
            dec_obs = obs_params['dec'].value[obs_dex]
            mjd_obs = obs_params['mjd'].value[obs_dex]
            rotsky_obs = obs_params['rotSkyPos'].value[obs_dex]
            filter_obs = obs_params['filter'].value[obs_dex]
            m5_obs = obs_params['m5'].value[obs_dex]

            mjd_obj_list = ModifiedJulianDate.get_list(TAI=mjd_obs)
            obs_md_list = []
            for ii in range(len(ra_obs)):
                obs = ObservationMetaData(pointingRA=ra_obs[ii],
                                          pointingDec=dec_obs[ii],
                                          mjd=mjd_obj_list[ii],
                                          rotSkyPos=rotsky_obs[ii],
                                          bandpassName='ugrizy'[filter_obs[ii]])
                obs_md_list.append(obs)

            print('%d time steps' % len(filter_obs))

            constraint = 'isvar=1 '
            htmid_21_min = htmid_query<<2*(21-query_level)
            htmid_21_max = (htmid_query+1)<<2*(21-query_level)
            constraint += 'AND htmid>=%d AND htmid<%d' % (htmid_21_min, htmid_21_max)
예제 #24
0
파일: imSim.py 프로젝트: belaa/imSim
def extract_objects(df, header):
    """
    Extract the object information needed by the sims code
    and pack into a new dataframe.

    Parameters
    ----------
    df : pandas.DataFrame
        DataFrame containing the instance catalog object data.

    header : dictionary
        dictionary containing the PhoSim header cards as output
        by extract_commands()
        (necessary for correctly applying proper motion to stars)

    Returns
    -------
    pandas.DataFrame
        A DataFrame with the columns expected by the sims code.
    """
    # Check for unhandled source types and emit warning if any are present.
    valid_types = dict(point='pointSource',
                       sersic2d='sersic')
    invalid_types = set(df['SOURCE_TYPE']) - set(valid_types)
    if invalid_types:
        warnings.warn("Instance catalog contains unhandled source types:\n%s\nSkipping these."
                      % '\n'.join(invalid_types))

    columns = ('uniqueId', 'galSimType',
               'magNorm', 'sedFilepath', 'redshift',
               'raJ2000', 'decJ2000',
               'halfLightRadius',
               'minorAxis',
               'majorAxis',
               'positionAngle', 'sindex',
               'properMotionRa', 'properMotionDec',
               'parallax', 'radialVelocity')

    # Process point sources and galaxies separately.
    source_type = 'point'
    stars = df.query("SOURCE_TYPE=='%s'" % source_type)
    phosim_stars = pd.DataFrame(np.zeros((len(stars), len(columns))),
                                index=stars.index,
                                columns=columns)
    phosim_stars['uniqueId'] = pd.to_numeric(stars['VALUE']).tolist()
    phosim_stars['galSimType'] = valid_types[source_type]
    phosim_stars['magNorm'] = pd.to_numeric(stars['MAG_NORM']).tolist()
    phosim_stars['sedFilepath'] = stars['SED_NAME'].tolist()
    phosim_stars['redshift'] = pd.to_numeric(stars['REDSHIFT']).tolist()
    phosim_stars['raJ2000'] = pd.to_numeric(stars['RA']).tolist()
    phosim_stars['decJ2000'] = pd.to_numeric(stars['DEC']).tolist()
    phosim_stars['properMotionRa'] = pd.to_numeric(stars['PAR5']).tolist()
    phosim_stars['properMotionDec'] = pd.to_numeric(stars['PAR6']).tolist()
    phosim_stars['parallax'] = pd.to_numeric(stars['PAR7']).tolist()
    phosim_stars['radialVelocity'] = pd.to_numeric(stars['PAR8']).tolist()
    if len(phosim_stars) > 0:
        phosim_stars = extract_extinction(stars, phosim_stars, 1)

        mjd = ModifiedJulianDate(TAI=header['mjd'])
        raICRS, decICRS = applyProperMotion(phosim_stars.raJ2000.values,
                                            phosim_stars.decJ2000.values,
                                            phosim_stars.properMotionRa.values,
                                            phosim_stars.properMotionDec.values,
                                            phosim_stars.parallax.values,
                                            phosim_stars.radialVelocity.values,
                                            mjd=mjd)

        phosim_stars = phosim_stars.assign(raICRS=raICRS, decICRS=decICRS)

    source_type = 'sersic2d'
    galaxies = df.query("SOURCE_TYPE == '%s'" % source_type)
    phosim_galaxies = pd.DataFrame(np.zeros((len(galaxies), len(columns))),
                                   index=galaxies.index,
                                   columns=columns)
    phosim_galaxies['uniqueId'] = pd.to_numeric(galaxies['VALUE']).tolist()
    phosim_galaxies['galSimType'] = valid_types[source_type]
    phosim_galaxies['magNorm'] = pd.to_numeric(galaxies['MAG_NORM']).tolist()
    phosim_galaxies['sedFilepath'] = galaxies['SED_NAME'].tolist()
    phosim_galaxies['redshift'] = pd.to_numeric(galaxies['REDSHIFT']).tolist()
    phosim_galaxies['raJ2000'] = pd.to_numeric(galaxies['RA']).tolist()
    phosim_galaxies['decJ2000'] = pd.to_numeric(galaxies['DEC']).tolist()
    phosim_galaxies['majorAxis'] = \
        radiansFromArcsec(pd.to_numeric(galaxies['PAR1'])).tolist()
    phosim_galaxies['minorAxis'] = \
        radiansFromArcsec(pd.to_numeric(galaxies['PAR2'])).tolist()
    phosim_galaxies['halfLightRadius'] = phosim_galaxies['majorAxis']
    phosim_galaxies['positionAngle'] = \
        (np.pi/180.*pd.to_numeric(galaxies['PAR3'])).tolist()
    phosim_galaxies['sindex'] = pd.to_numeric(galaxies['PAR4']).tolist()
    n_gal = len(phosim_galaxies.raJ2000.values)
    phosim_galaxies = phosim_galaxies.assign(raICRS=phosim_galaxies.raJ2000,
                                             decICRS=phosim_galaxies.decJ2000,
                                             properMotionRa=np.zeros(n_gal),
                                             properMotionDec=np.zeros(n_gal),
                                             parallax=np.zeros(n_gal),
                                             radialVelocity=np.zeros(n_gal))

    if len(phosim_galaxies) > 0:
        phosim_galaxies = extract_extinction(galaxies, phosim_galaxies, 5)

    return pd.concat((phosim_stars, phosim_galaxies), ignore_index=True)
예제 #25
0
    def test_avro_alert_generation_diff_dmag(self):
        """
        Make sure everything works properly when the AlertDataGenerator
        and the AvroAlertGenerator have different dmag thresholds
        """
        dmag_cutoff_sqlite = 0.005
        dmag_cutoff_avro = 0.2
        mag_name_to_int = {'u': 0, 'g': 1, 'r': 2, 'i': 3, 'z': 4, 'y': 5}

        star_db = StarAlertTestDBObj_avro(database=self.star_db_name,
                                          driver='sqlite')

        # assemble a dict of all of the alerts that need to be generated

        obshistid_list = []
        for obs in self.obs_list:
            obshistid_list.append(obs.OpsimMetaData['obsHistID'])
        obshistid_max = max(obshistid_list)
        obshistid_bits = int(np.ceil(np.log(obshistid_max) / np.log(2.0)))

        true_alert_dict = {}
        obs_dict = {}
        ignored_sqlite = 0  # count number of alerts written to sqlite, but not avro
        for obs in self.obs_list:
            obs_dict[obs.OpsimMetaData['obsHistID']] = obs
            obshistid = obs.OpsimMetaData['obsHistID']
            cat = TestAlertsTruthCat_avro(star_db, obs_metadata=obs)
            cat.camera = obs_lsst_phosim.PhosimMapper().camera

            for line in cat.iter_catalog():
                if line[1] is None:
                    continue

                dmag = line[2]
                mag = line[3]
                if (np.abs(dmag) > dmag_cutoff_avro and mag <=
                        self.obs_mag_cutoff[mag_name_to_int[obs.bandpass]]):

                    alertId = (line[0] << obshistid_bits) + obshistid
                    self.assertNotIn(alertId, true_alert_dict)
                    true_alert_dict[alertId] = {}
                    true_alert_dict[alertId]['chipName'] = line[1]
                    true_alert_dict[alertId]['dmag'] = dmag
                    true_alert_dict[alertId]['mag'] = mag
                    true_alert_dict[alertId]['ra'] = np.degrees(line[4])
                    true_alert_dict[alertId]['decl'] = np.degrees(line[5])
                    true_alert_dict[alertId]['xPix'] = line[6]
                    true_alert_dict[alertId]['yPix'] = line[7]
                elif np.abs(dmag) > dmag_cutoff_sqlite:
                    ignored_sqlite += 1

        self.assertGreater(len(true_alert_dict), 10)

        self.assertGreater(ignored_sqlite,
                           50)  # just make sure that some sqlite
        # alerts were ignored by the more
        # stringent avro cut

        log_file_name = tempfile.mktemp(dir=self.alert_data_output_dir,
                                        suffix='log.txt')
        alert_gen = AlertDataGenerator(testing=True)

        alert_gen.subdivide_obs(self.obs_list, htmid_level=6)

        for htmid in alert_gen.htmid_list:
            alert_gen.alert_data_from_htmid(
                htmid,
                star_db,
                photometry_class=TestAlertsVarCat_avro,
                output_prefix='alert_test',
                output_dir=self.alert_data_output_dir,
                dmag_cutoff=dmag_cutoff_sqlite,
                log_file_name=log_file_name)

        obshistid_to_htmid = {}
        for htmid in alert_gen.htmid_list:
            for obs in alert_gen.obs_from_htmid(htmid):
                obshistid = obs.OpsimMetaData['obsHistID']
                if obshistid not in obshistid_to_htmid:
                    obshistid_to_htmid[obshistid] = []
                obshistid_to_htmid[obshistid].append(htmid)

        avro_gen = AvroAlertGenerator()
        avro_gen.load_schema(
            os.path.join(getPackageDir('sims_catUtils'), 'tests', 'testData',
                         'avroSchema'))
        sql_prefix_list = ['alert_test']
        out_prefix = 'test_avro'
        log_file_name = tempfile.mktemp(dir=self.avro_out_dir,
                                        prefix='test_avro',
                                        suffix='log.txt')
        for obshistid in obshistid_list:
            avro_gen.write_alerts(obshistid,
                                  self.alert_data_output_dir,
                                  sql_prefix_list,
                                  obshistid_to_htmid[obshistid],
                                  self.avro_out_dir,
                                  out_prefix,
                                  dmag_cutoff_avro,
                                  lock=None,
                                  log_file_name=log_file_name)

        list_of_avro_files = os.listdir(self.avro_out_dir)
        self.assertGreater(len(list_of_avro_files), 2)
        alert_ct = 0
        dummy_sed = Sed()
        bp_dict = BandpassDict.loadTotalBandpassesFromFiles()
        photParams = PhotometricParameters()
        diasourceId_set = set()
        for avro_file_name in list_of_avro_files:
            if avro_file_name.endswith('log.txt'):
                continue
            full_name = os.path.join(self.avro_out_dir, avro_file_name)
            with DataFileReader(open(full_name, 'rb'),
                                DatumReader()) as data_reader:
                for alert in data_reader:
                    alert_ct += 1
                    obshistid = alert['alertId'] >> 20
                    obs = obs_dict[obshistid]
                    uniqueId = alert['diaObject']['diaObjectId']
                    true_alert_id = (uniqueId << obshistid_bits) + obshistid
                    self.assertIn(true_alert_id, true_alert_dict)
                    self.assertEqual(alert['l1dbId'], uniqueId)

                    true_alert = true_alert_dict[true_alert_id]

                    diaSource = alert['diaSource']
                    self.assertAlmostEqual(diaSource['ra'], true_alert['ra'],
                                           10)
                    self.assertAlmostEqual(diaSource['decl'],
                                           true_alert['decl'], 10)
                    self.assertAlmostEqual(diaSource['x'], true_alert['xPix'],
                                           3)
                    self.assertAlmostEqual(diaSource['y'], true_alert['yPix'],
                                           3)
                    self.assertAlmostEqual(diaSource['midPointTai'],
                                           obs.mjd.TAI, 4)

                    true_tot_flux = dummy_sed.fluxFromMag(true_alert['mag'])
                    true_q_mag = true_alert['mag'] - true_alert['dmag']
                    true_q_flux = dummy_sed.fluxFromMag(true_q_mag)
                    true_dflux = true_tot_flux - true_q_flux
                    self.assertAlmostEqual(diaSource['psFlux'] / true_dflux,
                                           1.0, 6)
                    self.assertAlmostEqual(
                        diaSource['totFlux'] / true_tot_flux, 1.0, 6)
                    self.assertAlmostEqual(diaSource['diffFlux'] / true_dflux,
                                           1.0, 6)

                    true_tot_snr, gamma = calcSNR_m5(true_alert['mag'],
                                                     bp_dict[obs.bandpass],
                                                     obs.m5[obs.bandpass],
                                                     photParams)

                    true_q_snr, gamma = calcSNR_m5(
                        true_q_mag, bp_dict[obs.bandpass],
                        self.obs_mag_cutoff[mag_name_to_int[obs.bandpass]],
                        photParams)

                    true_tot_err = true_tot_flux / true_tot_snr
                    true_q_err = true_q_flux / true_q_snr
                    true_diff_err = np.sqrt(true_tot_err**2 + true_q_err**2)

                    self.assertAlmostEqual(
                        diaSource['snr'] / np.abs(true_dflux / true_diff_err),
                        1.0, 6)

                    self.assertAlmostEqual(
                        diaSource['totFluxErr'] / true_tot_err, 1.0, 6)
                    self.assertAlmostEqual(
                        diaSource['diffFluxErr'] / true_diff_err, 1.0, 6)

                    chipnum = int(true_alert['chipName'].replace(
                        'R', '').replace('S', '').replace(',', '').replace(
                            ':', '').replace(' ', ''))

                    true_ccdid = (chipnum * 10**7) + obshistid
                    self.assertEqual(true_ccdid, diaSource['ccdVisitId'])
                    self.assertEqual(uniqueId, diaSource['diaObjectId'])

                    self.assertNotIn(diaSource['diaSourceId'], diasourceId_set)
                    diasourceId_set.add(diaSource['diaSourceId'])

                    diaObject = alert['diaObject']
                    obj_dex = (uniqueId // 1024) - 1
                    self.assertAlmostEqual(
                        0.001 * diaObject['pmRa'] / self.pmra_truth[obj_dex],
                        1.0, 5)
                    self.assertAlmostEqual(
                        0.001 * diaObject['pmDecl'] /
                        self.pmdec_truth[obj_dex], 1.0, 5)
                    self.assertAlmostEqual(
                        0.001 * diaObject['parallax'] / self.px_truth[obj_dex],
                        1.0, 5)

                    (true_ra_base, true_dec_base) = applyProperMotion(
                        self.ra_truth[obj_dex],
                        self.dec_truth[obj_dex],
                        self.pmra_truth[obj_dex],
                        self.pmdec_truth[obj_dex],
                        self.px_truth[obj_dex],
                        self.vrad_truth[obj_dex],
                        mjd=ModifiedJulianDate(TAI=diaObject['radecTai']))

                    self.assertAlmostEqual(true_ra_base, diaObject['ra'], 7)
                    self.assertAlmostEqual(true_dec_base, diaObject['decl'], 7)

        self.assertEqual(alert_ct, len(true_alert_dict))
예제 #26
0
    def test_alert_data_generation(self):

        dmag_cutoff = 0.005
        mag_name_to_int = {'u': 0, 'g': 1, 'r': 2, 'i': 3, 'z' : 4, 'y': 5}

        _max_var_param_str = self.max_str_len

        class StarAlertTestDBObj(StellarAlertDBObjMixin, CatalogDBObject):
            objid = 'star_alert'
            tableid = 'stars'
            idColKey = 'simobjid'
            raColName = 'ra'
            decColName = 'dec'
            objectTypeId = 0
            columns = [('raJ2000', 'ra*0.01745329252'),
                       ('decJ2000', 'dec*0.01745329252'),
                       ('parallax', 'px*0.01745329252/3600.0'),
                       ('properMotionRa', 'pmra*0.01745329252/3600.0'),
                       ('properMotionDec', 'pmdec*0.01745329252/3600.0'),
                       ('radialVelocity', 'vrad'),
                       ('variabilityParameters', 'varParamStr', str, _max_var_param_str)]

        class TestAlertsVarCatMixin(object):

            @register_method('alert_test')
            def applyAlertTest(self, valid_dexes, params, expmjd, variability_cache=None):
                if len(params) == 0:
                    return np.array([[], [], [], [], [], []])

                if isinstance(expmjd, numbers.Number):
                    dmags_out = np.zeros((6, self.num_variable_obj(params)))
                else:
                    dmags_out = np.zeros((6, self.num_variable_obj(params), len(expmjd)))

                for i_star in range(self.num_variable_obj(params)):
                    if params['amp'][i_star] is not None:
                        dmags = params['amp'][i_star]*np.cos(params['per'][i_star]*expmjd)
                        for i_filter in range(6):
                            dmags_out[i_filter][i_star] = dmags

                return dmags_out

        class TestAlertsVarCat(TestAlertsVarCatMixin, AlertStellarVariabilityCatalog):
            pass

        class TestAlertsTruthCat(TestAlertsVarCatMixin, CameraCoordsLSST, AstrometryStars,
                                 Variability, InstanceCatalog):
            column_outputs = ['uniqueId', 'chipName', 'dmagAlert', 'magAlert']

            @compound('delta_umag', 'delta_gmag', 'delta_rmag',
                      'delta_imag', 'delta_zmag', 'delta_ymag')
            def get_TruthVariability(self):
                return self.applyVariability(self.column_by_name('varParamStr'))

            @cached
            def get_dmagAlert(self):
                return self.column_by_name('delta_%smag' % self.obs_metadata.bandpass)

            @cached
            def get_magAlert(self):
                return self.column_by_name('%smag' % self.obs_metadata.bandpass) + \
                       self.column_by_name('dmagAlert')

        star_db = StarAlertTestDBObj(database=self.star_db_name, driver='sqlite')

        # assemble the true light curves for each object; we need to figure out
        # if their np.max(dMag) ever goes over dmag_cutoff; then we will know if
        # we are supposed to simulate them
        true_lc_dict = {}
        true_lc_obshistid_dict = {}
        is_visible_dict = {}
        obs_dict = {}
        max_obshistid = -1
        n_total_observations = 0
        for obs in self.obs_list:
            obs_dict[obs.OpsimMetaData['obsHistID']] = obs
            obshistid = obs.OpsimMetaData['obsHistID']
            if obshistid > max_obshistid:
                max_obshistid = obshistid
            cat = TestAlertsTruthCat(star_db, obs_metadata=obs)

            for line in cat.iter_catalog():
                if line[1] is None:
                    continue

                n_total_observations += 1
                if line[0] not in true_lc_dict:
                    true_lc_dict[line[0]] = {}
                    true_lc_obshistid_dict[line[0]] = []

                true_lc_dict[line[0]][obshistid] = line[2]
                true_lc_obshistid_dict[line[0]].append(obshistid)

                if line[0] not in is_visible_dict:
                    is_visible_dict[line[0]] = False

                if line[3] <= self.obs_mag_cutoff[mag_name_to_int[obs.bandpass]]:
                    is_visible_dict[line[0]] = True

        obshistid_bits = int(np.ceil(np.log(max_obshistid)/np.log(2)))

        skipped_due_to_mag = 0

        objects_to_simulate = []
        obshistid_unqid_set = set()
        for obj_id in true_lc_dict:

            dmag_max = -1.0
            for obshistid in true_lc_dict[obj_id]:
                if np.abs(true_lc_dict[obj_id][obshistid]) > dmag_max:
                    dmag_max = np.abs(true_lc_dict[obj_id][obshistid])

            if dmag_max >= dmag_cutoff:
                if not is_visible_dict[obj_id]:
                    skipped_due_to_mag += 1
                    continue

                objects_to_simulate.append(obj_id)
                for obshistid in true_lc_obshistid_dict[obj_id]:
                    obshistid_unqid_set.add((obj_id << obshistid_bits) + obshistid)

        self.assertGreater(len(objects_to_simulate), 10)
        self.assertGreater(skipped_due_to_mag, 0)

        log_file_name = tempfile.mktemp(dir=self.output_dir, suffix='log.txt')
        alert_gen = AlertDataGenerator(testing=True)

        alert_gen.subdivide_obs(self.obs_list, htmid_level=6)

        for htmid in alert_gen.htmid_list:
            alert_gen.alert_data_from_htmid(htmid, star_db,
                                            photometry_class=TestAlertsVarCat,
                                            output_prefix='alert_test',
                                            output_dir=self.output_dir,
                                            dmag_cutoff=dmag_cutoff,
                                            log_file_name=log_file_name)

        dummy_sed = Sed()

        bp_dict = BandpassDict.loadTotalBandpassesFromFiles()

        phot_params = PhotometricParameters()

        # First, verify that the contents of the sqlite files are all correct

        n_tot_simulated = 0

        alert_query = 'SELECT alert.uniqueId, alert.obshistId, meta.TAI, '
        alert_query += 'meta.band, quiescent.flux, alert.dflux, '
        alert_query += 'quiescent.snr, alert.snr, '
        alert_query += 'alert.ra, alert.dec, alert.chipNum, '
        alert_query += 'alert.xPix, alert.yPix, ast.pmRA, ast.pmDec, '
        alert_query += 'ast.parallax '
        alert_query += 'FROM alert_data AS alert '
        alert_query += 'INNER JOIN metadata AS meta ON meta.obshistId=alert.obshistId '
        alert_query += 'INNER JOIN quiescent_flux AS quiescent '
        alert_query += 'ON quiescent.uniqueId=alert.uniqueId '
        alert_query += 'AND quiescent.band=meta.band '
        alert_query += 'INNER JOIN baseline_astrometry AS ast '
        alert_query += 'ON ast.uniqueId=alert.uniqueId'

        alert_dtype = np.dtype([('uniqueId', int), ('obshistId', int),
                                ('TAI', float), ('band', int),
                                ('q_flux', float), ('dflux', float),
                                ('q_snr', float), ('tot_snr', float),
                                ('ra', float), ('dec', float),
                                ('chipNum', int), ('xPix', float), ('yPix', float),
                                ('pmRA', float), ('pmDec', float), ('parallax', float)])

        sqlite_file_list = os.listdir(self.output_dir)

        n_tot_simulated = 0
        obshistid_unqid_simulated_set = set()
        for file_name in sqlite_file_list:
            if not file_name.endswith('db'):
                continue
            full_name = os.path.join(self.output_dir, file_name)
            self.assertTrue(os.path.exists(full_name))
            alert_db = DBObject(full_name, driver='sqlite')
            alert_data = alert_db.execute_arbitrary(alert_query, dtype=alert_dtype)
            if len(alert_data) == 0:
                continue

            mjd_list = ModifiedJulianDate.get_list(TAI=alert_data['TAI'])
            for i_obj in range(len(alert_data)):
                n_tot_simulated += 1
                obshistid_unqid_simulated_set.add((alert_data['uniqueId'][i_obj] << obshistid_bits) +
                                                  alert_data['obshistId'][i_obj])

                unq = alert_data['uniqueId'][i_obj]
                obj_dex = (unq//1024)-1
                self.assertAlmostEqual(self.pmra_truth[obj_dex], 0.001*alert_data['pmRA'][i_obj], 4)
                self.assertAlmostEqual(self.pmdec_truth[obj_dex], 0.001*alert_data['pmDec'][i_obj], 4)
                self.assertAlmostEqual(self.px_truth[obj_dex], 0.001*alert_data['parallax'][i_obj], 4)

                ra_truth, dec_truth = applyProperMotion(self.ra_truth[obj_dex], self.dec_truth[obj_dex],
                                                        self.pmra_truth[obj_dex], self.pmdec_truth[obj_dex],
                                                        self.px_truth[obj_dex], self.vrad_truth[obj_dex],
                                                        mjd=mjd_list[i_obj])
                distance = angularSeparation(ra_truth, dec_truth,
                                             alert_data['ra'][i_obj], alert_data['dec'][i_obj])

                distance_arcsec = 3600.0*distance
                msg = '\ntruth: %e %e\nalert: %e %e\n' % (ra_truth, dec_truth,
                                                          alert_data['ra'][i_obj],
                                                          alert_data['dec'][i_obj])

                self.assertLess(distance_arcsec, 0.0005, msg=msg)

                obs = obs_dict[alert_data['obshistId'][i_obj]]

                chipname = chipNameFromRaDecLSST(self.ra_truth[obj_dex], self.dec_truth[obj_dex],
                                                 pm_ra=self.pmra_truth[obj_dex],
                                                 pm_dec=self.pmdec_truth[obj_dex],
                                                 parallax=self.px_truth[obj_dex],
                                                 v_rad=self.vrad_truth[obj_dex],
                                                 obs_metadata=obs,
                                                 band=obs.bandpass)

                chipnum = int(chipname.replace('R', '').replace('S', '').
                              replace(' ', '').replace(';', '').replace(',', '').
                              replace(':', ''))

                self.assertEqual(chipnum, alert_data['chipNum'][i_obj])

                xpix, ypix = pixelCoordsFromRaDecLSST(self.ra_truth[obj_dex], self.dec_truth[obj_dex],
                                                      pm_ra=self.pmra_truth[obj_dex],
                                                      pm_dec=self.pmdec_truth[obj_dex],
                                                      parallax=self.px_truth[obj_dex],
                                                      v_rad=self.vrad_truth[obj_dex],
                                                      obs_metadata=obs,
                                                      band=obs.bandpass)

                self.assertAlmostEqual(alert_data['xPix'][i_obj], xpix, 4)
                self.assertAlmostEqual(alert_data['yPix'][i_obj], ypix, 4)

                dmag_sim = -2.5*np.log10(1.0+alert_data['dflux'][i_obj]/alert_data['q_flux'][i_obj])
                self.assertAlmostEqual(true_lc_dict[alert_data['uniqueId'][i_obj]][alert_data['obshistId'][i_obj]],
                                       dmag_sim, 3)

                mag_name = ('u', 'g', 'r', 'i', 'z', 'y')[alert_data['band'][i_obj]]
                m5 = obs.m5[mag_name]

                q_mag = dummy_sed.magFromFlux(alert_data['q_flux'][i_obj])
                self.assertAlmostEqual(self.mag0_truth_dict[alert_data['band'][i_obj]][obj_dex],
                                       q_mag, 4)

                snr, gamma = calcSNR_m5(self.mag0_truth_dict[alert_data['band'][i_obj]][obj_dex],
                                        bp_dict[mag_name],
                                        self.obs_mag_cutoff[alert_data['band'][i_obj]],
                                        phot_params)

                self.assertAlmostEqual(snr/alert_data['q_snr'][i_obj], 1.0, 4)

                tot_mag = self.mag0_truth_dict[alert_data['band'][i_obj]][obj_dex] + \
                          true_lc_dict[alert_data['uniqueId'][i_obj]][alert_data['obshistId'][i_obj]]

                snr, gamma = calcSNR_m5(tot_mag, bp_dict[mag_name],
                                        m5, phot_params)
                self.assertAlmostEqual(snr/alert_data['tot_snr'][i_obj], 1.0, 4)

        for val in obshistid_unqid_set:
            self.assertIn(val, obshistid_unqid_simulated_set)
        self.assertEqual(len(obshistid_unqid_set), len(obshistid_unqid_simulated_set))

        astrometry_query = 'SELECT uniqueId, ra, dec, TAI '
        astrometry_query += 'FROM baseline_astrometry'
        astrometry_dtype = np.dtype([('uniqueId', int),
                                     ('ra', float),
                                     ('dec', float),
                                     ('TAI', float)])

        tai_list = []
        for obs in self.obs_list:
            tai_list.append(obs.mjd.TAI)
        tai_list = np.array(tai_list)

        n_tot_ast_simulated = 0
        for file_name in sqlite_file_list:
            if not file_name.endswith('db'):
                continue
            full_name = os.path.join(self.output_dir, file_name)
            self.assertTrue(os.path.exists(full_name))
            alert_db = DBObject(full_name, driver='sqlite')
            astrometry_data = alert_db.execute_arbitrary(astrometry_query, dtype=astrometry_dtype)

            if len(astrometry_data) == 0:
                continue

            mjd_list = ModifiedJulianDate.get_list(TAI=astrometry_data['TAI'])
            for i_obj in range(len(astrometry_data)):
                n_tot_ast_simulated += 1
                obj_dex = (astrometry_data['uniqueId'][i_obj]//1024) - 1
                ra_truth, dec_truth = applyProperMotion(self.ra_truth[obj_dex], self.dec_truth[obj_dex],
                                                        self.pmra_truth[obj_dex], self.pmdec_truth[obj_dex],
                                                        self.px_truth[obj_dex], self.vrad_truth[obj_dex],
                                                        mjd=mjd_list[i_obj])

                distance = angularSeparation(ra_truth, dec_truth,
                                             astrometry_data['ra'][i_obj],
                                             astrometry_data['dec'][i_obj])

                self.assertLess(3600.0*distance, 0.0005)

        del alert_gen
        gc.collect()
        self.assertGreater(n_tot_simulated, 10)
        self.assertGreater(len(obshistid_unqid_simulated_set), 10)
        self.assertLess(len(obshistid_unqid_simulated_set), n_total_observations)
        self.assertGreater(n_tot_ast_simulated, 0)
예제 #27
0
    def test_agn_light_curves(self):
        """
        Test the AgnLightCurveGenerator by generating some AGN light
        curves and comparing them to the results obtained by generating a
        series of InstanceCatalogs containing the same objects at the same
        MJDs
        """

        raRange = (78.0, 85.0)
        decRange = (-69.0, -65.0)
        bandpass = '******'

        lc_gen = AgnLightCurveGenerator(self.agn_db, self.opsimDb)
        pointings = lc_gen.get_pointings(raRange, decRange, bandpass=bandpass)
        for row in pointings:
            for obs in row:
                mjd = ModifiedJulianDate(TAI=obs.mjd.TAI - 49000.0 + 59580.0)
                obs.mjd = mjd

        test_light_curves, truth_info = lc_gen.light_curves_from_pointings(
            pointings)

        self.assertGreater(len(test_light_curves),
                           2)  # make sure we got some light curves

        for unique_id in test_light_curves:
            # verify that the sources returned all do vary by making sure that the
            # np.diff run on the magnitudes reutrns something non-zero
            self.assertGreater(
                np.abs(np.diff(
                    test_light_curves[unique_id][bandpass]['mag'])).max(), 0.0)
            self.assertGreater(
                len(test_light_curves[unique_id][bandpass]['mjd']), 0)

        # Now test that specifying a small chunk_size does not change the output
        # light curves
        chunk_light_curves, truth_info = lc_gen.light_curves_from_pointings(
            pointings, chunk_size=1)
        self.assertGreater(len(chunk_light_curves), 2)

        for unique_id in test_light_curves:
            self.assertEqual(
                len(test_light_curves[unique_id][bandpass]['mjd']),
                len(chunk_light_curves[unique_id][bandpass]['mjd']))
            np.testing.assert_array_equal(
                test_light_curves[unique_id][bandpass]['mjd'],
                chunk_light_curves[unique_id][bandpass]['mjd'])
            np.testing.assert_array_equal(
                test_light_curves[unique_id][bandpass]['mag'],
                chunk_light_curves[unique_id][bandpass]['mag'])
            np.testing.assert_array_equal(
                test_light_curves[unique_id][bandpass]['error'],
                chunk_light_curves[unique_id][bandpass]['error'])

        # Now find all of the ObservationMetaData that were included in our
        # light curves, generate InstanceCatalogs from them separately,
        # and verify that the contents of the InstanceCatalogs agree with
        # the contents of the light curves.

        gen = ObservationMetaDataGenerator(database=self.opsimDb,
                                           driver='sqlite')

        obs_list = gen.getObservationMetaData(fieldRA=raRange,
                                              fieldDec=decRange,
                                              telescopeFilter=bandpass,
                                              boundLength=1.75)
        for obs in obs_list:
            mjd = ModifiedJulianDate(TAI=obs.mjd.TAI - 49000.0 + 59580.0)
            obs.mjd = mjd

        ct = 0
        for obs in obs_list:
            cat = agnControlCatalog(self.agn_db, obs_metadata=obs)

            for agn_obj in cat.iter_catalog():
                ct += 1
                lc = test_light_curves[agn_obj[0]][bandpass]
                dex = np.argmin(np.abs(lc['mjd'] - obs.mjd.TAI))
                self.assertLess(np.abs(lc['mjd'][dex] - obs.mjd.TAI), 1.0e-7)
                self.assertLess(np.abs(lc['mag'][dex] - agn_obj[3]), 1.0e-7)
                self.assertLess(np.abs(lc['error'][dex] - agn_obj[4]), 1.0e-7)

        # Verify that the catalogs and LightCurveGenerator returned the
        # same number of observations
        total_ct = 0
        for obj_name in test_light_curves:
            for band in test_light_curves[obj_name]:
                total_ct += len(test_light_curves[obj_name][band]['mjd'])
        self.assertEqual(ct, total_ct)
예제 #28
0
    def test_multiband_light_curves(self):
        """
        Check that multi-band light curves are returned correctly.
        """

        raRange = (78.0, 82.0)
        decRange = (-69.0, -65.0)
        bandpass = ('r', 'g')

        gen = AgnLightCurveGenerator(self.agn_db, self.opsimDb)
        pointings = gen.get_pointings(raRange, decRange, bandpass=bandpass)
        for row in pointings:
            for obs in row:
                mjd = ModifiedJulianDate(TAI=obs.mjd.TAI - 49000.0 + 59580.0)
                obs.mjd = mjd

        lc_dict, truth_info = gen.light_curves_from_pointings(pointings)
        self.assertGreater(len(lc_dict), 2)

        obs_gen = ObservationMetaDataGenerator(database=self.opsimDb,
                                               driver='sqlite')
        control_pointings_r = obs_gen.getObservationMetaData(
            fieldRA=raRange,
            fieldDec=decRange,
            telescopeFilter='r',
            boundLength=1.75)

        for obs in control_pointings_r:
            mjd = ModifiedJulianDate(TAI=obs.mjd.TAI - 49000.0 + 59580.0)
            obs.mjd = mjd

        control_pointings_g = obs_gen.getObservationMetaData(
            fieldRA=raRange,
            fieldDec=decRange,
            telescopeFilter='g',
            boundLength=1.75)
        for obs in control_pointings_g:
            mjd = ModifiedJulianDate(TAI=obs.mjd.TAI - 49000.0 + 59580.0)
            obs.mjd = mjd

        self.assertGreater(len(control_pointings_g), 0)
        self.assertGreater(len(control_pointings_r), 0)

        ct = 0
        for obs in control_pointings_r:
            cat = agnControlCatalog(self.agn_db, obs_metadata=obs)

            for star_obj in cat.iter_catalog():
                ct += 1
                lc = lc_dict[star_obj[0]]['r']
                dex = np.argmin(np.abs(lc['mjd'] - obs.mjd.TAI))
                self.assertLess(np.abs(lc['mjd'][dex] - obs.mjd.TAI), 1.0e-7)
                self.assertLess(np.abs(lc['mag'][dex] - star_obj[3]), 1.0e-7)
                self.assertLess(np.abs(lc['error'][dex] - star_obj[4]), 1.0e-7)

        for obs in control_pointings_g:
            cat = agnControlCatalog(self.agn_db, obs_metadata=obs)

            for star_obj in cat.iter_catalog():
                ct += 1
                lc = lc_dict[star_obj[0]]['g']
                dex = np.argmin(np.abs(lc['mjd'] - obs.mjd.TAI))
                self.assertLess(np.abs(lc['mjd'][dex] - obs.mjd.TAI), 1.0e-7)
                self.assertLess(np.abs(lc['mag'][dex] - star_obj[3]), 1.0e-7)
                self.assertLess(np.abs(lc['error'][dex] - star_obj[4]), 1.0e-7)

        # Verify that the catalogs and LightCurveGenerator returned the
        # same number of observations
        total_ct = 0
        for obj_name in lc_dict:
            for band in lc_dict[obj_name]:
                total_ct += len(lc_dict[obj_name][band]['mjd'])
        self.assertEqual(ct, total_ct)
예제 #29
0
    def test_agn_constraint(self):
        """
        Test that the light curve generator correctly ignores objects
        with varParamStr == None

        We do this by generating a database of two galaxies with AGN-like
        varParamStr and two stars with no varParamStr. We run this database
        through a LightCurveGenerator and an InstanceCatalog.  We verify that
        the LightCurveGenerator finds 2 AGN while the InstanceCatalog finds
        4 stars.
        """

        rng = np.random.RandomState(83)

        raRange = (80.8, 83.8)
        decRange = (-71.0, -69.0)
        bandpass = '******'

        agn_sed_name = "agn.spec"
        sed_name = "Burst.10E10.1Z.spec.gz"

        varparams = {
            'varMethodName': 'applyAgn',
            'pars': {
                'agn_tau': 20.0,
                'agn_sfu': 11.0,
                'agn_sfg': 12.0,
                'agn_sfr': 13.0,
                'agn_sfi': 14.0,
                'agn_sfz': 15.0,
                'agn_sfy': 16.0,
                't0_mjd': 49330.0,
                'seed': rng.randint(0, 200000)
            }
        }

        varParamStr = json.dumps(varparams)

        # create the dummy database
        db_name = tempfile.mktemp(prefix="agn_constraint_cat_sqlite",
                                  suffix=".db",
                                  dir=ROOT)
        conn = sqlite3.connect(db_name)
        c = conn.cursor()
        c.execute('''CREATE TABLE agn
                  (id int, ra real, dec real, redshift real,
                   sedFilenameDisk text, internalAvDisk real,
                   magNormDisk real,
                   sedFilenameBulge text, internalAvBulge real,
                   magNormBulge real,
                   sedFilenameAgn text, varParamStr text,
                   magNormAgn real)''')
        conn.commit()

        for ix, (rr, dd, zz, avb, mnb, avd, mnd, mnagn) in \
        enumerate(zip(rng.random_sample(4)*(raRange[1]-raRange[0])+raRange[0],
                      rng.random_sample(4)*(decRange[1]-decRange[0])+decRange[0],
                      rng.random_sample(4)*0.5+0.1,
                      rng.random_sample(4)*0.5+0.1, rng.random_sample(4)*3.0+17.0,
                      rng.random_sample(4)*0.5+0.1, rng.random_sample(4)*3.0+17.0,
                      rng.random_sample(4)*3.0+17.0)):

            if ix < 2:
                cmd = '''INSERT INTO agn VALUES(%d, %e, %e, %e, '%s', %e,
                         %e, '%s', %e, %e, '%s', '%s', %e)''' % \
                      (ix, rr, dd, zz, sed_name, avb, mnb, sed_name, avd, mnd,
                       agn_sed_name, varParamStr, mnagn)
            else:
                cmd = '''INSERT INTO agn VALUES(%d, %e, %e, %e, '%s', %e,
                         %e, '%s', %e, %e, '%s', NULL, %e)''' % \
                      (ix, rr, dd, zz, sed_name, avb, mnb, sed_name, avd, mnd,
                       agn_sed_name, mnagn)

            c.execute(cmd)

        conn.commit()

        # create a CatalogDBObject class to interface with the dummy database
        class dummyAgnDBObject(CatalogDBObject):
            database = db_name
            host = None
            driver = 'sqlite'
            tableid = 'agn'
            raColName = 'ra'
            decColName = 'dec'
            idColKey = 'id'
            objid = 'dummyAgn'
            skipRegistration = True
            objectTypeId = 99

            columns = [('raJ2000', 'ra*PI()/180.0', float),
                       ('decJ2000', 'dec*PI()/180.0', float)]

        agn_db = dummyAgnDBObject()

        # verify that the LightCurveGenerator finds the two variable stars
        lc_gen = AgnLightCurveGenerator(agn_db, self.opsimDb)
        ptngs = lc_gen.get_pointings(raRange, decRange, bandpass=bandpass)
        for row in ptngs:
            for obs in row:
                mjd = ModifiedJulianDate(TAI=obs.mjd.TAI - 49000.0 + 59580.0)
                obs.mjd = mjd

        lc_dict, truth_dict = lc_gen.light_curves_from_pointings(ptngs)
        self.assertEqual(len(lc_dict), 2)

        if os.path.exists(db_name):
            os.unlink(db_name)

        # verify that an InstanceCatalog finds all 4 stars
        obs = ptngs[0][0]
        cat = agnControlCatalog(agn_db, obs_metadata=obs)
        with lsst.utils.tests.getTempFilePath('.txt') as dummy_cat_name:
            cat.write_catalog(dummy_cat_name)
            with open(dummy_cat_name, 'r') as input_file:
                lines = input_file.readlines()
                self.assertEqual(len(lines), 5)
예제 #30
0
    def test_deepcopy(self):
        # make sure that deepcopy() creates identical
        # ModifiedJulianDates with different memory addresses
        mjd1 = ModifiedJulianDate(TAI=43590.0)
        mjd1.dut1
        deep_mjd2 = copy.deepcopy(mjd1)
        self.assertEqual(mjd1, deep_mjd2)
        self.assertNotEqual(mjd1.__repr__(), deep_mjd2.__repr__())
        self.assertEqual(mjd1.TAI, deep_mjd2.TAI)
        self.assertEqual(mjd1.dut1, deep_mjd2.dut1)
        equiv_mjd2 = mjd1
        self.assertEqual(mjd1, equiv_mjd2)
        self.assertEqual(mjd1.__repr__(), equiv_mjd2.__repr__())

        mjd1 = ModifiedJulianDate(UTC=43590.0)
        mjd1.dut1
        deep_mjd2 = copy.deepcopy(mjd1)
        self.assertEqual(mjd1, deep_mjd2)
        self.assertEqual(mjd1.UTC, deep_mjd2.UTC)
        self.assertEqual(mjd1.dut1, deep_mjd2.dut1)
        self.assertNotEqual(mjd1.__repr__(), deep_mjd2.__repr__())
        equiv_mjd2 = mjd1
        self.assertEqual(mjd1, equiv_mjd2)
        self.assertEqual(mjd1.__repr__(), equiv_mjd2.__repr__())

        # make sure that deepcopy() still works, even if you have called
        # all of the original ModifiedJulianDate's properties
        mjd1 = ModifiedJulianDate(TAI=42590.0)
        mjd1.UTC
        mjd1.dut1
        mjd1.UT1
        mjd1.TT
        mjd1.TDB
        mjd2 = copy.deepcopy(mjd1)
        self.assertEqual(mjd1.TAI, mjd2.TAI)
        self.assertEqual(mjd1.UTC, mjd2.UTC)
        self.assertEqual(mjd1.dut1, mjd2.dut1)
        self.assertEqual(mjd1.UT1, mjd2.UT1)
        self.assertEqual(mjd1.TT, mjd2.TT)
        self.assertEqual(mjd1.TDB, mjd2.TDB)
        self.assertEqual(mjd1, mjd2)
        self.assertNotEqual(mjd1.__repr__(), mjd2.__repr__())
예제 #31
0
    def testObservedFromPupil_noRefraction(self):
        """
        Test conversion from pupil coordinates to observed coordinates
        when includeRefraction=False
        """

        mjd = ModifiedJulianDate(TAI=53000.0)
        solarRA, solarDec = solarRaDec(mjd)

        # to make sure that we are more than 45 degrees from the Sun as required
        # for _icrsFromObserved to be at all accurate
        raCenter = solarRA + 100.0
        decCenter = solarDec - 30.0

        obs = ObservationMetaData(pointingRA=raCenter,
                                  pointingDec=decCenter,
                                  boundType='circle',
                                  boundLength=0.1,
                                  rotSkyPos=23.0,
                                  mjd=mjd)

        nSamples = 1000
        rng = np.random.RandomState(4453)
        ra = (rng.random_sample(nSamples) * 0.1 - 0.2) + np.radians(raCenter)
        dec = (rng.random_sample(nSamples) * 0.1 - 0.2) + np.radians(decCenter)
        xp, yp = _pupilCoordsFromRaDec(ra,
                                       dec,
                                       obs_metadata=obs,
                                       epoch=2000.0,
                                       includeRefraction=False)

        raObs, decObs = _observedFromICRS(ra,
                                          dec,
                                          obs_metadata=obs,
                                          epoch=2000.0,
                                          includeRefraction=False)

        raObs_test, decObs_test = _observedFromPupilCoords(
            xp, yp, obs_metadata=obs, epoch=2000.0, includeRefraction=False)

        dist = arcsecFromRadians(
            haversine(raObs, decObs, raObs_test, decObs_test))
        self.assertLess(dist.max(), 1.0e-6)

        # test output in degrees
        raObs_deg, decObs_deg = observedFromPupilCoords(
            xp, yp, obs_metadata=obs, epoch=2000.0, includeRefraction=False)

        np.testing.assert_array_almost_equal(raObs_deg,
                                             np.degrees(raObs_test),
                                             decimal=16)
        np.testing.assert_array_almost_equal(decObs_deg,
                                             np.degrees(decObs_test),
                                             decimal=16)

        # test one-at-a-time input
        for ii in range(len(raObs)):
            rr, dd = _observedFromPupilCoords(xp[ii],
                                              yp[ii],
                                              obs_metadata=obs,
                                              epoch=2000.0,
                                              includeRefraction=False)
            self.assertAlmostEqual(rr, raObs_test[ii], 16)
            self.assertAlmostEqual(dd, decObs_test[ii], 16)

            rr, dd = observedFromPupilCoords(xp[ii],
                                             yp[ii],
                                             obs_metadata=obs,
                                             epoch=2000.0,
                                             includeRefraction=False)
            self.assertAlmostEqual(rr, raObs_deg[ii], 16)
            self.assertAlmostEqual(dd, decObs_deg[ii], 16)