Пример #1
0
    def testNaNs(self):
        """
        Test how _pupilCoordsFromRaDec handles improper values
        """
        obs = ObservationMetaData(pointingRA=42.0, pointingDec=-28.0,
                                  rotSkyPos=111.0, mjd=42356.0)
        nSamples = 100
        rng = np.random.RandomState(42)
        raList = np.radians(rng.random_sample(nSamples) * 2.0 + 42.0)
        decList = np.radians(rng.random_sample(nSamples) * 2.0 - 28.0)

        xControl, yControl = _pupilCoordsFromRaDec(raList, decList,
                                                   obs_metadata=obs,
                                                   epoch=2000.0)

        raList[5] = np.NaN
        decList[5] = np.NaN
        raList[15] = np.NaN
        decList[20] = np.NaN
        raList[30] = np.radians(42.0) + np.pi

        xTest, yTest = _pupilCoordsFromRaDec(raList, decList,
                                             obs_metadata=obs,
                                             epoch=2000.0)

        for ix, (xc, yc, xt, yt) in \
                enumerate(zip(xControl, yControl, xTest, yTest)):
            if ix != 5 and ix != 15 and ix != 20 and ix != 30:
                self.assertAlmostEqual(xc, xt, 10)
                self.assertAlmostEqual(yc, yt, 10)
                self.assertFalse(np.isnan(xt))
                self.assertFalse(np.isnan(yt))
            else:
                np.testing.assert_equal(xt, np.NaN)
                np.testing.assert_equal(yt, np.NaN)
    def testNaNs(self):
        """
        Test how _pupilCoordsFromRaDec handles improper values
        """
        obs = ObservationMetaData(pointingRA=42.0, pointingDec=-28.0,
                                  rotSkyPos=111.0, mjd=42356.0)
        nSamples = 100
        rng = np.random.RandomState(42)
        raList = np.radians(rng.random_sample(nSamples) * 2.0 + 42.0)
        decList = np.radians(rng.random_sample(nSamples) * 2.0 - 28.0)

        xControl, yControl = _pupilCoordsFromRaDec(raList, decList,
                                                   obs_metadata=obs,
                                                   epoch=2000.0)

        raList[5] = np.NaN
        decList[5] = np.NaN
        raList[15] = np.NaN
        decList[20] = np.NaN
        raList[30] = np.radians(42.0) + np.pi

        xTest, yTest = _pupilCoordsFromRaDec(raList, decList,
                                             obs_metadata=obs,
                                             epoch=2000.0)

        for ix, (xc, yc, xt, yt) in \
                enumerate(zip(xControl, yControl, xTest, yTest)):
            if ix != 5 and ix != 15 and ix != 20 and ix != 30:
                self.assertAlmostEqual(xc, xt, 10)
                self.assertAlmostEqual(yc, yt, 10)
                self.assertFalse(np.isnan(xt))
                self.assertFalse(np.isnan(yt))
            else:
                np.testing.assert_equal(xt, np.NaN)
                np.testing.assert_equal(yt, np.NaN)
Пример #3
0
    def testObservedFromPupil(self):
        """
        Test conversion from pupil coordinates to observed coordinates
        """

        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=True)

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

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

        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=True)

        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=True)
            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=True)
            self.assertAlmostEqual(rr, raObs_deg[ii], 16)
            self.assertAlmostEqual(dd, decObs_deg[ii], 16)
Пример #4
0
    def testpupilCoordsFromRaDec(self):
        obs = ObservationMetaData(pointingRA=23.5,
                                  pointingDec=-115.0,
                                  mjd=42351.0,
                                  rotSkyPos=127.0)

        # need to make sure the test points are tightly distributed around the bore site, or
        # PALPY will throw an error
        raList = self.rng.random_sample(
            self.nStars) * np.radians(1.0) + np.radians(23.5)
        decList = self.rng.random_sample(
            self.nStars) * np.radians(1.0) + np.radians(-115.0)

        xpControl, ypControl = utils._pupilCoordsFromRaDec(raList,
                                                           decList,
                                                           obs_metadata=obs,
                                                           epoch=2000.0)

        xpTest, ypTest = utils.pupilCoordsFromRaDec(np.degrees(raList),
                                                    np.degrees(decList),
                                                    obs_metadata=obs,
                                                    epoch=2000.0)

        dx = utils.arcsecFromRadians(xpControl - xpTest)
        np.testing.assert_array_almost_equal(dx, np.zeros(self.nStars), 9)

        dy = utils.arcsecFromRadians(ypControl - ypTest)
        np.testing.assert_array_almost_equal(dy, np.zeros(self.nStars), 9)
    def testRaDecFromPupil(self):
        """
        Test conversion from pupil coordinates back to Ra, Dec
        """

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

        # 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
        numpy.random.seed(42)
        ra = (numpy.random.random_sample(nSamples)*0.1-0.2) + numpy.radians(raCenter)
        dec = (numpy.random.random_sample(nSamples)*0.1-0.2) + numpy.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 = numpy.argmax(distance)
        worstSolarDistance = distanceToSun(numpy.degrees(ra[dex]), numpy.degrees(dec[dex]), mjd.TDB)
        msg = "_raDecFromPupilCoords off by %e arcsec at distance to Sun of %e degrees" % \
        (distance.max(), worstSolarDistance)
        self.assertLess(distance.max(), 0.005, msg=msg)
Пример #6
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)
Пример #7
0
    def testRaDecFromPupil_noRefraction(self):
        """
        Test conversion from pupil coordinates back to Ra, Dec
        with includeRefraction=False
        """

        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,
                                       includeRefraction=False)

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

        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,
                                                includeRefraction=False)
            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 _focalPlaneCoordsFromRaDec(ra, dec, obs_metadata=None, epoch=None, camera=None):
    """
    Get the focal plane coordinates for all objects in the catalog.

    @param [in] ra is a numpy array in radians.
    In the International Celestial Reference System.

    @param [in] dec is a numpy array in radians.
    In the International Celestial Reference System.

    @param [in] obs_metadata is an ObservationMetaData object describing the telescope
    pointing (only if specifying RA and Dec rather than pupil coordinates)

    @param [in] epoch is the julian epoch of the mean equinox used for coordinate transformations
    (in years; only if specifying RA and Dec rather than pupil coordinates)

    @param [in] camera is an afw.cameraGeom camera object

    @param [out] a 2-D numpy array in which the first row is the x
    focal plane coordinate and the second row is the y focal plane
    coordinate (both in millimeters)
    """

    if not isinstance(ra, numpy.ndarray) or not isinstance(dec, numpy.ndarray):
        raise RuntimeError("You must pass numpy arrays of RA and Dec to focalPlaneCoordsFromRaDec")

    if len(ra) != len(dec):
        raise RuntimeError("You specified %d RAs and %d Decs in focalPlaneCoordsFromRaDec" %
                           (len(ra), len(dec)))

    if epoch is None:
        raise RuntimeError("You have to specify an epoch to run " + \
                            "focalPlaneCoordsFromRaDec")

    if obs_metadata is None:
        raise RuntimeError("You have to specify an ObservationMetaData to run " + \
                               "focalPlaneCoordsFromRaDec")


    if obs_metadata.mjd is None:
        raise RuntimeError("You need to pass an ObservationMetaData with an " \
                           + "mjd into focalPlaneCoordsFromRaDec")

    if obs_metadata.rotSkyPos is None:
        raise RuntimeError("You need to pass an ObservationMetaData with a " \
                           + "rotSkyPos into focalPlaneCoordsFromRaDec")


    xPupil, yPupil = _pupilCoordsFromRaDec(ra, dec, obs_metadata=obs_metadata,
                                                epoch=epoch)

    return focalPlaneCoordsFromPupilCoords(xPupil, yPupil, camera=camera)
def _chipNameFromRaDec(ra, dec, obs_metadata=None, epoch=None, camera=None,
                           allow_multiple_chips=False):
    """
    Return the names of science detectors that see the object specified by
    either (xPupil, yPupil).  Note: this method does not return
    the name of guide, focus, or wavefront detectors.

    @param [in] ra in radians (a numpy array).
    In the International Celestial Reference System.

    @param [in] dec in radians (a numpy array).
    In the International Celestial Reference System.

    @param [in] obs_metadata is an ObservationMetaData characterizing the telescope pointing

    @param [in] epoch is the epoch in Julian years of the equinox against which RA and Dec are
    measured

    @param [in] camera is an afw.cameraGeom camera instance characterizing the camera

    @param [in] allow_multiple_chips is a boolean (default False) indicating whether or not
    this method will allow objects to be visible on more than one chip.  If it is 'False'
    and an object appears on more than one chip, an exception will be raised.  If it is 'True'
    and an object falls on more than one chip, it will still only return the first chip in the
    list of chips returned. THIS BEHAVIOR SHOULD BE FIXED IN A FUTURE TICKET.

    @param [out] a numpy array of chip names (science detectors only)
    """

    if not isinstance(ra, numpy.ndarray) or not isinstance(dec, numpy.ndarray):
        raise RuntimeError("You need to pass numpy arrays of RA and Dec to chipName")

    if len(ra) != len(dec):
        raise RuntimeError("You passed %d RAs and %d Decs " % (len(ra), len(dec)) +
                           "to chipName.")

    if epoch is None:
        raise RuntimeError("You need to pass an epoch into chipName")

    if obs_metadata is None:
        raise RuntimeError("You need to pass an ObservationMetaData into chipName")

    if obs_metadata.mjd is None:
        raise RuntimeError("You need to pass an ObservationMetaData with an mjd into chipName")

    if obs_metadata.rotSkyPos is None:
        raise RuntimeError("You need to pass an ObservationMetaData with a rotSkyPos into chipName")

    xp, yp = _pupilCoordsFromRaDec(ra, dec, obs_metadata=obs_metadata, epoch=epoch)
    return chipNameFromPupilCoords(xp, yp, camera=camera, allow_multiple_chips=allow_multiple_chips)
    def testpupilCoordsFromRaDec(self):
        obs = ObservationMetaData(pointingRA=23.5, pointingDec=-115.0, mjd=42351.0, rotSkyPos=127.0)

        # need to make sure the test points are tightly distributed around the bore site, or
        # PALPY will throw an error
        raList = np.random.random_sample(self.nStars)*np.radians(1.0) + np.radians(23.5)
        decList = np.random.random_sample(self.nStars)*np.radians(1.0) + np.radians(-115.0)

        xpControl, ypControl = utils._pupilCoordsFromRaDec(raList, decList,
                                                                     obs_metadata=obs, epoch=2000.0)

        xpTest, ypTest = utils.pupilCoordsFromRaDec(np.degrees(raList), np.degrees(decList),
                                                              obs_metadata=obs, epoch=2000.0)

        dx = utils.arcsecFromRadians(xpControl-xpTest)
        np.testing.assert_array_almost_equal(dx, np.zeros(self.nStars), 9)

        dy = utils.arcsecFromRadians(ypControl-ypTest)
        np.testing.assert_array_almost_equal(dy, np.zeros(self.nStars), 9)
    def testExceptions(self):
        """
        Test that exceptions are raised when they ought to be
        """
        obs_metadata = ObservationMetaData(pointingRA=25.0,
                                           pointingDec=25.0,
                                           rotSkyPos=25.0,
                                           mjd=52000.0)

        numpy.random.seed(42)
        ra = numpy.random.random_sample(10)*numpy.radians(1.0) + numpy.radians(obs_metadata.pointingRA)
        dec = numpy.random.random_sample(10)*numpy.radians(1.0) + numpy.radians(obs_metadata.pointingDec)
        raShort = numpy.array([1.0])
        decShort = numpy.array([1.0])

        #test without epoch
        self.assertRaises(RuntimeError, _pupilCoordsFromRaDec, ra, dec,
                          obs_metadata=obs_metadata)

        #test without obs_metadata
        self.assertRaises(RuntimeError, _pupilCoordsFromRaDec, ra, dec,
                          epoch=2000.0)

        #test without pointingRA
        dummy = ObservationMetaData(pointingDec=obs_metadata.pointingDec,
                                    rotSkyPos=obs_metadata.rotSkyPos,
                                    mjd=obs_metadata.mjd)
        self.assertRaises(RuntimeError, _pupilCoordsFromRaDec, ra, dec,
                          epoch=2000.0, obs_metadata=dummy)

        #test without pointingDec
        dummy = ObservationMetaData(pointingRA=obs_metadata.pointingRA,
                                    rotSkyPos=obs_metadata.rotSkyPos,
                                    mjd=obs_metadata.mjd)
        self.assertRaises(RuntimeError, _pupilCoordsFromRaDec, ra, dec,
                          epoch=2000.0, obs_metadata=dummy)

        #test without rotSkyPos
        dummy = ObservationMetaData(pointingRA=obs_metadata.pointingRA,
                                    pointingDec=obs_metadata.pointingDec,
                                    mjd=obs_metadata.mjd)
        self.assertRaises(RuntimeError, _pupilCoordsFromRaDec, ra, dec,
                          epoch=2000.0, obs_metadata=dummy)

        #test without mjd
        dummy = ObservationMetaData(pointingRA=obs_metadata.pointingRA,
                                    pointingDec=obs_metadata.pointingDec,
                                    rotSkyPos=obs_metadata.rotSkyPos)
        self.assertRaises(RuntimeError, _pupilCoordsFromRaDec, ra, dec,
                          epoch=2000.0, obs_metadata=dummy)


        #test for mismatches
        dummy = ObservationMetaData(pointingRA=obs_metadata.pointingRA,
                                    pointingDec=obs_metadata.pointingDec,
                                    rotSkyPos=obs_metadata.rotSkyPos,
                                    mjd=obs_metadata.mjd)

        self.assertRaises(RuntimeError, _pupilCoordsFromRaDec, ra, decShort, epoch=2000.0,
                          obs_metadata=dummy)

        self.assertRaises(RuntimeError, _pupilCoordsFromRaDec, raShort, dec, epoch=2000.0,
                          obs_metadata=dummy)

        #test that it actually runs
        test = _pupilCoordsFromRaDec(ra, dec, obs_metadata=obs_metadata, epoch=2000.0)
Пример #12
0
    def test_with_proper_motion(self):
        """
        Test that calculating pupil coordinates in the presence of proper motion, parallax,
        and radial velocity is equivalent to
        observedFromICRS -> icrsFromObserved -> pupilCoordsFromRaDec
        (mostly to make surethat pupilCoordsFromRaDec is correctly calling observedFromICRS
        with non-zero proper motion, etc.)
        """
        rng = np.random.RandomState(38442)
        is_valid = False
        while not is_valid:
            mjd_tai = 59580.0 + 10000.0*rng.random_sample()
            obs = ObservationMetaData(mjd=mjd_tai)
            ra, dec = raDecFromAltAz(78.0, 112.0, obs)
            dd = distanceToSun(ra, dec, obs.mjd)
            if dd > 45.0:
                is_valid = True

        n_obj = 1000
        rr = rng.random_sample(n_obj)*2.0
        theta = rng.random_sample(n_obj)*2.0*np.pi
        ra_list = ra + rr*np.cos(theta)
        dec_list = dec + rr*np.sin(theta)
        obs = ObservationMetaData(pointingRA=ra, pointingDec=dec, mjd=mjd_tai, rotSkyPos=19.0)

        pm_ra_list = rng.random_sample(n_obj)*100.0 - 50.0
        pm_dec_list = rng.random_sample(n_obj)*100.0 - 50.0
        px_list = rng.random_sample(n_obj) + 0.05
        v_rad_list = rng.random_sample(n_obj)*600.0 - 300.0

        for includeRefraction in (True, False):

            ra_obs, dec_obs = observedFromICRS(ra_list, dec_list,
                                               pm_ra=pm_ra_list, pm_dec=pm_dec_list,
                                               parallax=px_list, v_rad=v_rad_list,
                                               obs_metadata=obs, epoch=2000.0,
                                               includeRefraction=includeRefraction)

            ra_icrs, dec_icrs = icrsFromObserved(ra_obs, dec_obs, obs_metadata=obs,
                                                 epoch=2000.0, includeRefraction=includeRefraction)

            xp_control, yp_control = pupilCoordsFromRaDec(ra_icrs, dec_icrs, obs_metadata=obs,
                                                          epoch=2000.0, includeRefraction=includeRefraction)

            xp_test, yp_test = pupilCoordsFromRaDec(ra_list, dec_list,
                                                    pm_ra=pm_ra_list, pm_dec=pm_dec_list,
                                                    parallax=px_list, v_rad=v_rad_list,
                                                    obs_metadata=obs, epoch=2000.0,
                                                    includeRefraction=includeRefraction)

            distance = arcsecFromRadians(np.sqrt(np.power(xp_test-xp_control, 2) +
                                                 np.power(yp_test-yp_control, 2)))
            self.assertLess(distance.max(), 0.006)

            # now test it in radians
            xp_rad, yp_rad = _pupilCoordsFromRaDec(np.radians(ra_list), np.radians(dec_list),
                                                   pm_ra=radiansFromArcsec(pm_ra_list),
                                                   pm_dec=radiansFromArcsec(pm_dec_list),
                                                   parallax=radiansFromArcsec(px_list),
                                                   v_rad=v_rad_list,
                                                   obs_metadata=obs, epoch=2000.0,
                                                   includeRefraction=includeRefraction)

            np.testing.assert_array_equal(xp_rad, xp_test)
            np.testing.assert_array_equal(yp_rad, yp_test)

            # now test it with proper motion = 0
            ra_obs, dec_obs = observedFromICRS(ra_list, dec_list,
                                               parallax=px_list, v_rad=v_rad_list,
                                               obs_metadata=obs, epoch=2000.0,
                                               includeRefraction=includeRefraction)

            ra_icrs, dec_icrs = icrsFromObserved(ra_obs, dec_obs, obs_metadata=obs,
                                                 epoch=2000.0, includeRefraction=includeRefraction)

            xp_control, yp_control = pupilCoordsFromRaDec(ra_icrs, dec_icrs, obs_metadata=obs,
                                                          epoch=2000.0, includeRefraction=includeRefraction)

            xp_test, yp_test = pupilCoordsFromRaDec(ra_list, dec_list,
                                                    parallax=px_list, v_rad=v_rad_list,
                                                    obs_metadata=obs, epoch=2000.0,
                                                    includeRefraction=includeRefraction)

            distance = arcsecFromRadians(np.sqrt(np.power(xp_test-xp_control, 2) +
                                                 np.power(yp_test-yp_control, 2)))
            self.assertLess(distance.max(), 1.0e-6)
Пример #13
0
    def testExceptions(self):
        """
        Test that exceptions are raised when they ought to be
        """
        obs_metadata = ObservationMetaData(pointingRA=25.0,
                                           pointingDec=25.0,
                                           rotSkyPos=25.0,
                                           mjd=52000.0)

        rng = np.random.RandomState(42)
        ra = rng.random_sample(10) * np.radians(1.0) + np.radians(obs_metadata.pointingRA)
        dec = rng.random_sample(10) * np.radians(1.0) + np.radians(obs_metadata.pointingDec)
        raShort = np.array([1.0])
        decShort = np.array([1.0])

        # test without obs_metadata
        self.assertRaises(RuntimeError, _pupilCoordsFromRaDec, ra, dec,
                          epoch=2000.0)

        # test without pointingRA
        dummy = ObservationMetaData(pointingDec=obs_metadata.pointingDec,
                                    rotSkyPos=obs_metadata.rotSkyPos,
                                    mjd=obs_metadata.mjd)
        self.assertRaises(RuntimeError, _pupilCoordsFromRaDec, ra, dec,
                          epoch=2000.0, obs_metadata=dummy)

        # test without pointingDec
        dummy = ObservationMetaData(pointingRA=obs_metadata.pointingRA,
                                    rotSkyPos=obs_metadata.rotSkyPos,
                                    mjd=obs_metadata.mjd)
        self.assertRaises(RuntimeError, _pupilCoordsFromRaDec, ra, dec,
                          epoch=2000.0, obs_metadata=dummy)

        # test without rotSkyPos
        dummy = ObservationMetaData(pointingRA=obs_metadata.pointingRA,
                                    pointingDec=obs_metadata.pointingDec,
                                    mjd=obs_metadata.mjd)
        self.assertRaises(RuntimeError, _pupilCoordsFromRaDec, ra, dec,
                          epoch=2000.0, obs_metadata=dummy)

        # test without mjd
        dummy = ObservationMetaData(pointingRA=obs_metadata.pointingRA,
                                    pointingDec=obs_metadata.pointingDec,
                                    rotSkyPos=obs_metadata.rotSkyPos)
        self.assertRaises(RuntimeError, _pupilCoordsFromRaDec, ra, dec,
                          epoch=2000.0, obs_metadata=dummy)

        # test for mismatches
        dummy = ObservationMetaData(pointingRA=obs_metadata.pointingRA,
                                    pointingDec=obs_metadata.pointingDec,
                                    rotSkyPos=obs_metadata.rotSkyPos,
                                    mjd=obs_metadata.mjd)

        self.assertRaises(RuntimeError, _pupilCoordsFromRaDec, ra, decShort, epoch=2000.0,
                          obs_metadata=dummy)

        self.assertRaises(RuntimeError, _pupilCoordsFromRaDec, raShort, dec, epoch=2000.0,
                          obs_metadata=dummy)

        # test that it actually runs (and that passing in either numpy arrays or floats gives
        # the same results)
        xx_arr, yy_arr = _pupilCoordsFromRaDec(ra, dec, obs_metadata=obs_metadata)
        self.assertIsInstance(xx_arr, np.ndarray)
        self.assertIsInstance(yy_arr, np.ndarray)

        for ix in range(len(ra)):
            xx_f, yy_f = _pupilCoordsFromRaDec(ra[ix], dec[ix], obs_metadata=obs_metadata)
            self.assertIsInstance(xx_f, np.float)
            self.assertIsInstance(yy_f, np.float)
            self.assertAlmostEqual(xx_arr[ix], xx_f, 12)
            self.assertAlmostEqual(yy_arr[ix], yy_f, 12)
            self.assertFalse(np.isnan(xx_f))
            self.assertFalse(np.isnan(yy_f))
Пример #14
0
    def test_object_extraction_stars(self):
        """
        Test that method to get GalSimCelestialObjects from
        InstanceCatalogs works
        """
        commands = desc.imsim.metadata_from_file(self.phosim_file)
        obs_md = desc.imsim.phosim_obs_metadata(commands)
        phot_params = desc.imsim.photometricParameters(commands)
        with desc.imsim.fopen(self.phosim_file, mode='rt') as input_:
            lines = [x for x in input_ if x.startswith('object')]

        truth_dtype = np.dtype([('uniqueId', str, 200), ('x_pupil', float),
                                ('y_pupil', float), ('sedFilename', str, 200),
                                ('magNorm', float), ('raJ2000', float),
                                ('decJ2000', float), ('pmRA', float),
                                ('pmDec', float), ('parallax', float),
                                ('v_rad', float), ('Av', float),
                                ('Rv', float)])

        truth_data = np.genfromtxt(os.path.join(self.data_dir,
                                                'truth_stars.txt'),
                                   dtype=truth_dtype,
                                   delimiter=';')

        truth_data.sort()

        gs_object_arr, gs_object_dict \
            = sources_from_list(lines, obs_md, phot_params, self.phosim_file)

        id_arr = [None] * len(gs_object_arr)
        for i_obj in range(len(gs_object_arr)):
            id_arr[i_obj] = gs_object_arr[i_obj].uniqueId
        id_arr = sorted(id_arr)
        np.testing.assert_array_equal(truth_data['uniqueId'], id_arr)

        ######## test that pupil coordinates are correct to within
        ######## half a milliarcsecond

        x_pup_test, y_pup_test = _pupilCoordsFromRaDec(
            truth_data['raJ2000'],
            truth_data['decJ2000'],
            pm_ra=truth_data['pmRA'],
            pm_dec=truth_data['pmDec'],
            v_rad=truth_data['v_rad'],
            parallax=truth_data['parallax'],
            obs_metadata=obs_md)

        for gs_obj in gs_object_arr:
            i_obj = np.where(truth_data['uniqueId'] == gs_obj.uniqueId)[0][0]
            dd = np.sqrt((x_pup_test[i_obj] - gs_obj.xPupilRadians)**2 +
                         (y_pup_test[i_obj] - gs_obj.yPupilRadians)**2)
            dd = arcsecFromRadians(dd)
            self.assertLess(dd, 0.0005)

        ######## test that fluxes are correctly calculated

        bp_dict = BandpassDict.loadTotalBandpassesFromFiles()
        imsim_bp = Bandpass()
        imsim_bp.imsimBandpass()
        phot_params = PhotometricParameters(nexp=1, exptime=30.0)

        for gs_obj in gs_object_arr:
            i_obj = np.where(truth_data['uniqueId'] == gs_obj.uniqueId)[0][0]
            sed = Sed()
            full_sed_name = os.path.join(os.environ['SIMS_SED_LIBRARY_DIR'],
                                         truth_data['sedFilename'][i_obj])
            sed.readSED_flambda(full_sed_name)
            fnorm = sed.calcFluxNorm(truth_data['magNorm'][i_obj], imsim_bp)
            sed.multiplyFluxNorm(fnorm)
            sed.resampleSED(wavelen_match=bp_dict.wavelenMatch)
            a_x, b_x = sed.setupCCM_ab()
            sed.addDust(a_x,
                        b_x,
                        A_v=truth_data['Av'][i_obj],
                        R_v=truth_data['Rv'][i_obj])

            for bp in ('u', 'g', 'r', 'i', 'z', 'y'):
                flux = sed.calcADU(bp_dict[bp], phot_params) * phot_params.gain
                self.assertAlmostEqual(flux / gs_obj.flux(bp), 1.0, 10)

        ######## test that objects are assigned to the right chip in
        ######## gs_object_dict

        unique_id_dict = {}
        for chip_name in gs_object_dict:
            local_unique_id_list = []
            for gs_object in gs_object_dict[chip_name]:
                local_unique_id_list.append(gs_object.uniqueId)
            local_unique_id_list = set(local_unique_id_list)
            unique_id_dict[chip_name] = local_unique_id_list

        valid = 0
        valid_chip_names = set()
        for unq, xpup, ypup in zip(truth_data['uniqueId'],
                                   truth_data['x_pupil'],
                                   truth_data['y_pupil']):

            chip_name = chipNameFromPupilCoordsLSST(xpup, ypup)
            if chip_name is not None:
                self.assertIn(unq, unique_id_dict[chip_name])
                valid_chip_names.add(chip_name)
                valid += 1

        self.assertGreater(valid, 10)
        self.assertGreater(len(valid_chip_names), 5)
Пример #15
0
    def testUtilityMethods(self):
        """
        Generate a catalog using the methods from AstrometryUtils.py and CameraUtils.py.
        Read that data in, and then recalculate the values 'by hand' to make sure
        that they are consistent.
        """

        catName = os.path.join(getPackageDir('sims_catUtils'), 'tests', 'scratchSpace',
                               'AstrometryUtilityCatalog.txt')

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

        self.cat.write_catalog(catName)

        dtype = [('id', int),
                 ('raICRS', float), ('decICRS', float),
                 ('parallax', float), ('radial_velocity', float),
                 ('x_pupil', float), ('y_pupil', float), ('chipName', str, 11),
                 ('xPix', float), ('yPix', float),
                 ('xFocalPlane', float), ('yFocalPlane', float)]

        baselineData = np.genfromtxt(catName, dtype=dtype, delimiter=';')

        self.assertGreater(len(baselineData), 0)

        pupilTest = _pupilCoordsFromRaDec(baselineData['raICRS'],
                                          baselineData['decICRS'],
                                          parallax=baselineData['parallax'],
                                          v_rad=baselineData['radial_velocity'],
                                          obs_metadata=self.obs_metadata,
                                          epoch=2000.0)

        for (xxtest, yytest, xx, yy) in \
                zip(pupilTest[0], pupilTest[1], baselineData['x_pupil'], baselineData['y_pupil']):
            self.assertAlmostEqual(xxtest, xx, 6)
            self.assertAlmostEqual(yytest, yy, 6)

        focalTest = focalPlaneCoordsFromPupilCoords(pupilTest[0], pupilTest[1], camera=self.cat.camera)

        focalRa = _focalPlaneCoordsFromRaDec(baselineData['raICRS'], baselineData['decICRS'],
                                             parallax=baselineData['parallax'],
                                             v_rad=baselineData['radial_velocity'],
                                             epoch=self.cat.db_obj.epoch, obs_metadata=self.cat.obs_metadata,
                                             camera=self.cat.camera)

        for (xxtest, yytest, xxra, yyra, xx, yy) in \
                zip(focalTest[0], focalTest[1], focalRa[0], focalRa[1],
                    baselineData['xFocalPlane'], baselineData['yFocalPlane']):

            self.assertAlmostEqual(xxtest, xx, 6)
            self.assertAlmostEqual(yytest, yy, 6)
            self.assertAlmostEqual(xxra, xx, 6)
            self.assertAlmostEqual(yyra, yy, 6)

        pixTest = pixelCoordsFromPupilCoords(pupilTest[0], pupilTest[1], camera=self.cat.camera)

        pixTestRaDec = _pixelCoordsFromRaDec(baselineData['raICRS'], baselineData['decICRS'],
                                             parallax=baselineData['parallax'],
                                             v_rad=baselineData['radial_velocity'],
                                             epoch=self.cat.db_obj.epoch,
                                             obs_metadata=self.cat.obs_metadata,
                                             camera=self.cat.camera)

        for (xxtest, yytest, xxra, yyra, xx, yy) in \
                zip(pixTest[0], pixTest[1], pixTestRaDec[0], pixTestRaDec[1],
                    baselineData['xPix'], baselineData['yPix']):

            if not np.isnan(xx) and not np.isnan(yy):
                self.assertAlmostEqual(xxtest, xx, 5)
                self.assertAlmostEqual(yytest, yy, 5)
                self.assertAlmostEqual(xxra, xx, 5)
                self.assertAlmostEqual(yyra, yy, 5)
            else:
                np.testing.assert_equal(xx, np.NaN)
                np.testing.assert_equal(yy, np.NaN)
                np.testing.assert_equal(xxra, np.NaN)
                np.testing.assert_equal(yyra, np.NaN)
                np.testing.assert_equal(xxtest, np.NaN)
                np.testing.assert_equal(yytest, np.NaN)

        nameTest = chipNameFromPupilCoords(pupilTest[0], pupilTest[1],
                                           camera=self.cat.camera)

        nameRA = _chipNameFromRaDec(baselineData['raICRS'], baselineData['decICRS'],
                                    epoch=self.cat.db_obj.epoch, obs_metadata=self.cat.obs_metadata,
                                    camera=self.cat.camera)

        is_none = 0
        for (ntest, nra, ncontrol) in zip(nameTest, nameRA, baselineData['chipName']):
            if ncontrol != 'None':
                self.assertEqual(ntest, ncontrol)
                self.assertEqual(nra, ncontrol)
            else:
                is_none += 1
                self.assertIsNone(ntest)
                self.assertIsNone(nra)

        self.assertGreater(is_none, 0)
        self.assertLess(is_none, len(baselineData))

        if os.path.exists(catName):
            os.unlink(catName)
Пример #16
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)
Пример #17
0
    def test_object_extraction_galaxies(self):
        """
        Test that method to get GalSimCelestialObjects from
        InstanceCatalogs works
        """
        galaxy_phosim_file = os.path.join(self.data_dir, 'phosim_galaxies.txt')
        commands = desc.imsim.metadata_from_file(galaxy_phosim_file)
        obs_md = desc.imsim.phosim_obs_metadata(commands)
        phot_params = desc.imsim.photometricParameters(commands)
        (gs_object_arr, gs_object_dict) = desc.imsim.sources_from_file(
            galaxy_phosim_file, obs_md, phot_params)

        id_arr = np.zeros(len(gs_object_arr), dtype=int)
        for i_obj in range(len(gs_object_arr)):
            id_arr[i_obj] = gs_object_arr[i_obj].uniqueId

        truth_dtype = np.dtype([('uniqueId', int), ('x_pupil', float),
                                ('y_pupil', float), ('sedFilename', str, 200),
                                ('magNorm', float), ('raJ2000', float),
                                ('decJ2000', float), ('redshift', float),
                                ('gamma1', float), ('gamma2', float),
                                ('kappa', float), ('galacticAv', float),
                                ('galacticRv', float), ('internalAv', float),
                                ('internalRv', float), ('minorAxis', float),
                                ('majorAxis', float), ('positionAngle', float),
                                ('sindex', float)])

        truth_data = np.genfromtxt(os.path.join(self.data_dir,
                                                'truth_galaxies.txt'),
                                   dtype=truth_dtype,
                                   delimiter=';')

        np.testing.assert_array_equal(truth_data['uniqueId'], id_arr)

        ######## test that galaxy parameters are correctly read in

        g1 = truth_data['gamma1'] / (1.0 - truth_data['kappa'])
        g2 = truth_data['gamma2'] / (1.0 - truth_data['kappa'])
        mu = 1.0 / ((1.0 - truth_data['kappa'])**2 -
                    (truth_data['gamma1']**2 + truth_data['gamma2']**2))
        for i_obj, gs_obj in enumerate(gs_object_arr):
            self.assertAlmostEqual(gs_obj.mu / mu[i_obj], 1.0, 6)
            self.assertAlmostEqual(gs_obj.g1 / g1[i_obj], 1.0, 6)
            self.assertAlmostEqual(gs_obj.g2 / g2[i_obj], 1.0, 6)
            self.assertGreater(np.abs(gs_obj.mu), 0.0)
            self.assertGreater(np.abs(gs_obj.g1), 0.0)
            self.assertGreater(np.abs(gs_obj.g2), 0.0)

            self.assertAlmostEqual(gs_obj.halfLightRadiusRadians,
                                   truth_data['majorAxis'][i_obj], 13)
            self.assertAlmostEqual(gs_obj.minorAxisRadians,
                                   truth_data['minorAxis'][i_obj], 13)
            self.assertAlmostEqual(gs_obj.majorAxisRadians,
                                   truth_data['majorAxis'][i_obj], 13)
            self.assertAlmostEqual(gs_obj.positionAngleRadians,
                                   truth_data['positionAngle'][i_obj], 7)
            self.assertAlmostEqual(gs_obj.sindex, truth_data['sindex'][i_obj],
                                   10)

        ######## test that pupil coordinates are correct to within
        ######## half a milliarcsecond

        x_pup_test, y_pup_test = _pupilCoordsFromRaDec(truth_data['raJ2000'],
                                                       truth_data['decJ2000'],
                                                       obs_metadata=obs_md)

        for i_obj, gs_obj in enumerate(gs_object_arr):
            self.assertEqual(truth_data['uniqueId'][i_obj], gs_obj.uniqueId)
            dd = np.sqrt((x_pup_test[i_obj] - gs_obj.xPupilRadians)**2 +
                         (y_pup_test[i_obj] - gs_obj.yPupilRadians)**2)
            dd = arcsecFromRadians(dd)
            self.assertLess(dd, 0.0005)

        ######## test that fluxes are correctly calculated

        bp_dict = BandpassDict.loadTotalBandpassesFromFiles()
        imsim_bp = Bandpass()
        imsim_bp.imsimBandpass()
        phot_params = PhotometricParameters(nexp=1, exptime=30.0)

        for i_obj, gs_obj in enumerate(gs_object_arr):
            sed = Sed()
            full_sed_name = os.path.join(os.environ['SIMS_SED_LIBRARY_DIR'],
                                         truth_data['sedFilename'][i_obj])
            sed.readSED_flambda(full_sed_name)
            fnorm = sed.calcFluxNorm(truth_data['magNorm'][i_obj], imsim_bp)
            sed.multiplyFluxNorm(fnorm)

            a_x, b_x = sed.setupCCMab()
            sed.addCCMDust(a_x,
                           b_x,
                           A_v=truth_data['internalAv'][i_obj],
                           R_v=truth_data['internalRv'][i_obj])

            sed.redshiftSED(truth_data['redshift'][i_obj], dimming=True)
            sed.resampleSED(wavelen_match=bp_dict.wavelenMatch)
            a_x, b_x = sed.setupCCMab()
            sed.addCCMDust(a_x,
                           b_x,
                           A_v=truth_data['galacticAv'][i_obj],
                           R_v=truth_data['galacticRv'][i_obj])

            for bp in ('u', 'g', 'r', 'i', 'z', 'y'):
                flux = sed.calcADU(bp_dict[bp], phot_params) * phot_params.gain
                self.assertAlmostEqual(flux / gs_obj.flux(bp), 1.0, 6)

        ######## test that objects are assigned to the right chip in
        ######## gs_object_dict

        unique_id_dict = {}
        for chip_name in gs_object_dict:
            local_unique_id_list = []
            for gs_object in gs_object_dict[chip_name]:
                local_unique_id_list.append(gs_object.uniqueId)
            local_unique_id_list = set(local_unique_id_list)
            unique_id_dict[chip_name] = local_unique_id_list

        valid = 0
        valid_chip_names = set()
        for unq, xpup, ypup in zip(truth_data['uniqueId'],
                                   truth_data['x_pupil'],
                                   truth_data['y_pupil']):

            chip_name = chipNameFromPupilCoordsLSST(xpup, ypup)[0]
            if chip_name is not None:
                self.assertIn(unq, unique_id_dict[chip_name])
                valid_chip_names.add(chip_name)
                valid += 1

        self.assertGreater(valid, 10)
        self.assertGreater(len(valid_chip_names), 5)
Пример #18
0
def _chipNameFromRaDecLSST(ra,
                           dec,
                           pm_ra=None,
                           pm_dec=None,
                           parallax=None,
                           v_rad=None,
                           obs_metadata=None,
                           epoch=2000.0,
                           allow_multiple_chips=False,
                           band='r'):
    """
    Return the names of detectors on the LSST camera that see the object specified by
    (RA, Dec) in radians.

    @param [in] ra in radians (a numpy array or a float).
    In the International Celestial Reference System.

    @param [in] dec in radians (a numpy array or a float).
    In the International Celestial Reference System.

    @param [in] pm_ra is proper motion in RA multiplied by cos(Dec) (radians/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] pm_dec is proper motion in dec (radians/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] parallax is parallax in radians
    Can be a numpy array or a number or None (default=None).

    @param [in] v_rad is radial velocity (km/s)
    Can be a numpy array or a number or None (default=None).

    @param [in] obs_metadata is an ObservationMetaData characterizing the telescope pointing

    @param [in] epoch is the epoch in Julian years of the equinox against which RA and Dec are
    measured.  Default is 2000.

    @param [in] allow_multiple_chips is a boolean (default False) indicating whether or not
    this method will allow objects to be visible on more than one chip.  If it is 'False'
    and an object appears on more than one chip, only the first chip will appear in the list of
    chipNames but NO WARNING WILL BE EMITTED.  If it is 'True' and an object falls on more than one
    chip, a list of chipNames will appear for that object.

    @param [in] band is the filter we are simulating (Default=r)

    @param [out] the name(s) of the chips on which ra, dec fall (will be a numpy
    array if more than one)
    """

    are_arrays = _validate_inputs([ra, dec], ['ra', 'dec'],
                                  "chipNameFromRaDecLSST")

    if epoch is None:
        raise RuntimeError("You need to pass an epoch into chipName")

    if obs_metadata is None:
        raise RuntimeError(
            "You need to pass an ObservationMetaData into chipName")

    if obs_metadata.mjd is None:
        raise RuntimeError(
            "You need to pass an ObservationMetaData with an mjd into chipName"
        )

    if obs_metadata.rotSkyPos is None:
        raise RuntimeError(
            "You need to pass an ObservationMetaData with a rotSkyPos into chipName"
        )

    xp, yp = _pupilCoordsFromRaDec(ra,
                                   dec,
                                   pm_ra=pm_ra,
                                   pm_dec=pm_dec,
                                   parallax=parallax,
                                   v_rad=v_rad,
                                   obs_metadata=obs_metadata,
                                   epoch=epoch)

    return chipNameFromPupilCoordsLSST(
        xp, yp, allow_multiple_chips=allow_multiple_chips, band=band)
def _pixelCoordsFromRaDec(ra, dec, obs_metadata=None, epoch=None,
                          chipNames=None, camera=None, includeDistortion=True):
    """
    Get the pixel positions (or nan if not on a chip) for objects based
    on their RA, and Dec (in radians)

    @param [in] ra is a numpy array containing the RA of the objects in radians.
    In the International Celestial Reference System.

    @param [in] dec is a numpy array containing the Dec of the objects in radians.
    In the International Celestial Reference System.

    @param [in] obs_metadata is an ObservationMetaData characterizing the telescope
    pointing.

    @param [in] epoch is the epoch in Julian years of the equinox against which
    RA is measured.

    @param [in] chipNames a numpy array of chipNames.  If it is None, this method will call chipName
    to find the array.  The option exists for the user to specify chipNames, just in case the user
    has already called chipName for some reason.

    @param [in] camera is an afwCameraGeom object specifying the attributes of the camera.
    This is an optional argument to be passed to chipName.

    @param [in] includeDistortion is a boolean.  If True (default), then this method will
    return the true pixel coordinates with optical distortion included.  If False, this
    method will return TAN_PIXEL coordinates, which are the pixel coordinates with
    estimated optical distortion removed.  See the documentation in afw.cameraGeom for more
    details.

    @param [out] a 2-D numpy array in which the first row is the x pixel coordinate
    and the second row is the y pixel coordinate
    """

    if epoch is None:
        raise RuntimeError("You need to pass an epoch into pixelCoordsFromRaDec")

    if obs_metadata is None:
        raise RuntimeError("You need to pass an ObservationMetaData into pixelCoordsFromRaDec")

    if obs_metadata.mjd is None:
        raise RuntimeError("You need to pass an ObservationMetaData with an mjd into " \
                           + "pixelCoordsFromRaDec")

    if obs_metadata.rotSkyPos is None:
        raise RuntimeError("You need to pass an ObservationMetaData with a rotSkyPos into " \
                           + "pixelCoordsFromRaDec")

    if not isinstance(ra, numpy.ndarray) or not isinstance(dec, numpy.ndarray):
        raise RuntimeError("You need to pass numpy arrays of RA and Dec to pixelCoordsFromRaDec")

    if len(ra) != len(dec):
        raise RuntimeError("You passed %d RA and %d Dec coordinates " % (len(ra), len(dec)) +
                           "to pixelCoordsFromRaDec")

    if chipNames is not None:
        if len(ra) != len(chipNames):
            raise RuntimeError("You passed %d points but %d chipNames to pixelCoordsFromRaDec" %
                               (len(ra), len(chipNames)))

    xPupil, yPupil = _pupilCoordsFromRaDec(ra, dec, obs_metadata=obs_metadata, epoch=epoch)
    return pixelCoordsFromPupilCoords(xPupil, yPupil, chipNames=chipNames, camera=camera,
                                      includeDistortion=includeDistortion)
    def testUtilityMethods(self):
        """
        Generate a catalog using the methods from AstrometryUtils.py and CameraUtils.py.
        Read that data in, and then recalculate the values 'by hand' to make sure
        that they are consistent.
        """

        catName = os.path.join(getPackageDir('sims_catUtils'), 'tests', 'scratchSpace',
                               'AstrometryUtilityCatalog.txt')

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

        self.cat.write_catalog(catName)

        dtype = [('id',int),
                 ('raICRS',float), ('decICRS',float),
                 ('x_pupil',float), ('y_pupil',float), ('chipName',str,11),
                 ('xPix',float), ('yPix',float),
                 ('xFocalPlane',float), ('yFocalPlane',float)]

        baselineData = numpy.loadtxt(catName, dtype=dtype, delimiter=';')

        self.assertGreater(len(baselineData), 0)

        pupilTest = _pupilCoordsFromRaDec(baselineData['raICRS'],
                                              baselineData['decICRS'],
                                              obs_metadata=self.obs_metadata,
                                              epoch=2000.0)

        for (xxtest, yytest, xx, yy) in \
                zip(pupilTest[0], pupilTest[1], baselineData['x_pupil'], baselineData['y_pupil']):
            self.assertAlmostEqual(xxtest,xx,6)
            self.assertAlmostEqual(yytest,yy,6)

        focalTest = focalPlaneCoordsFromPupilCoords(pupilTest[0], pupilTest[1], camera=self.cat.camera)

        focalRa = _focalPlaneCoordsFromRaDec(baselineData['raICRS'], baselineData['decICRS'],
                                             epoch=self.cat.db_obj.epoch, obs_metadata=self.cat.obs_metadata,
                                             camera=self.cat.camera)

        for (xxtest, yytest, xxra, yyra, xx, yy) in \
                zip(focalTest[0], focalTest[1], focalRa[0], focalRa[1],
                        baselineData['xFocalPlane'], baselineData['yFocalPlane']):

            self.assertAlmostEqual(xxtest,xx,6)
            self.assertAlmostEqual(yytest,yy,6)
            self.assertAlmostEqual(xxra,xx,6)
            self.assertAlmostEqual(yyra,yy,6)

        pixTest = pixelCoordsFromPupilCoords(pupilTest[0], pupilTest[1], camera=self.cat.camera)

        pixTestRaDec = _pixelCoordsFromRaDec(baselineData['raICRS'], baselineData['decICRS'],
                                             epoch=self.cat.db_obj.epoch,
                                             obs_metadata=self.cat.obs_metadata,
                                             camera=self.cat.camera)

        for (xxtest, yytest, xxra, yyra, xx, yy) in \
                zip(pixTest[0], pixTest[1], pixTestRaDec[0], pixTestRaDec[1],
                           baselineData['xPix'], baselineData['yPix']):

            if not numpy.isnan(xx) and not numpy.isnan(yy):
                self.assertAlmostEqual(xxtest,xx,5)
                self.assertAlmostEqual(yytest,yy,5)
                self.assertAlmostEqual(xxra,xx,5)
                self.assertAlmostEqual(yyra,yy,5)
            else:
                self.assertTrue(numpy.isnan(xx))
                self.assertTrue(numpy.isnan(yy))
                self.assertTrue(numpy.isnan(xxra))
                self.assertTrue(numpy.isnan(yyra))
                self.assertTrue(numpy.isnan(xxtest))
                self.assertTrue(numpy.isnan(yytest))


        nameTest = chipNameFromPupilCoords(pupilTest[0], pupilTest[1],
                                           camera=self.cat.camera)

        nameRA = _chipNameFromRaDec(baselineData['raICRS'], baselineData['decICRS'],
                                    epoch=self.cat.db_obj.epoch, obs_metadata=self.cat.obs_metadata,
                                    camera=self.cat.camera)

        for (ntest, nra, ncontrol) in zip(nameTest, nameRA, baselineData['chipName']):
            if ncontrol != 'None':
                self.assertEqual(ntest,ncontrol)
                self.assertEqual(nra,ncontrol)
            else:
                self.assertTrue(ntest is None)
                self.assertTrue(nra is None)

        if os.path.exists(catName):
            os.unlink(catName)
Пример #21
0
def _pixelCoordsFromRaDec(ra, dec, pm_ra=None, pm_dec=None, parallax=None, v_rad=None,
                          obs_metadata=None,
                          chipName=None, camera=None,
                          epoch=2000.0, includeDistortion=True):
    """
    Get the pixel positions (or nan if not on a chip) for objects based
    on their RA, and Dec (in radians)

    @param [in] ra is in radians in the International Celestial Reference System.
    Can be either a float or a numpy array.

    @param [in] dec is in radians in the International Celestial Reference System.
    Can be either a float or a numpy array.

    @param [in] pm_ra is proper motion in RA multiplied by cos(Dec) (radians/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] pm_dec is proper motion in dec (radians/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] parallax is parallax in radians
    Can be a numpy array or a number or None (default=None).

    @param [in] v_rad is radial velocity (km/s)
    Can be a numpy array or a number or None (default=None).

    @param [in] obs_metadata is an ObservationMetaData characterizing the telescope
    pointing.

    @param [in] epoch is the epoch in Julian years of the equinox against which
    RA is measured.  Default is 2000.

    @param [in] chipName designates the names of the chips on which the pixel
    coordinates will be reckoned.  Can be either single value, an array, or None.
    If an array, there must be as many chipNames as there are (RA, Dec) pairs.
    If a single value, all of the pixel coordinates will be reckoned on the same
    chip.  If None, this method will calculate which chip each(RA, Dec) pair actually
    falls on, and return pixel coordinates for each (RA, Dec) pair on the appropriate
    chip.  Default is None.

    @param [in] camera is an afwCameraGeom object specifying the attributes of the camera.
    This is an optional argument to be passed to chipName.

    @param [in] includeDistortion is a boolean.  If True (default), then this method will
    return the true pixel coordinates with optical distortion included.  If False, this
    method will return TAN_PIXEL coordinates, which are the pixel coordinates with
    estimated optical distortion removed.  See the documentation in afw.cameraGeom for more
    details.

    @param [out] a 2-D numpy array in which the first row is the x pixel coordinate
    and the second row is the y pixel coordinate
    """

    are_arrays, \
    chipNameList = _validate_inputs_and_chipname([ra, dec], ['ra', 'dec'],
                                                 'pixelCoordsFromRaDec',
                                                 chipName)

    if epoch is None:
        raise RuntimeError("You need to pass an epoch into pixelCoordsFromRaDec")

    if obs_metadata is None:
        raise RuntimeError("You need to pass an ObservationMetaData into pixelCoordsFromRaDec")

    if obs_metadata.mjd is None:
        raise RuntimeError("You need to pass an ObservationMetaData with an mjd into "
                           "pixelCoordsFromRaDec")

    if obs_metadata.rotSkyPos is None:
        raise RuntimeError("You need to pass an ObservationMetaData with a rotSkyPos into "
                           "pixelCoordsFromRaDec")

    xPupil, yPupil = _pupilCoordsFromRaDec(ra, dec,
                                           pm_ra=pm_ra, pm_dec=pm_dec,
                                           parallax=parallax, v_rad=v_rad,
                                           obs_metadata=obs_metadata, epoch=epoch)

    return pixelCoordsFromPupilCoords(xPupil, yPupil, chipName=chipNameList, camera=camera,
                                      includeDistortion=includeDistortion)
Пример #22
0
def _chipNameFromRaDec(ra, dec, pm_ra=None, pm_dec=None, parallax=None, v_rad=None,
                       obs_metadata=None, camera=None,
                       epoch=2000.0, allow_multiple_chips=False):
    """
    Return the names of detectors that see the object specified by
    (RA, Dec)  in radians.

    @param [in] ra in radians (a numpy array or a float).
    In the International Celestial Reference System.

    @param [in] dec in radians (a numpy array or a float).
    In the International Celestial Reference System.

    @param [in] pm_ra is proper motion in RA multiplied by cos(Dec) (radians/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] pm_dec is proper motion in dec (radians/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] parallax is parallax in radians
    Can be a numpy array or a number or None (default=None).

    @param [in] v_rad is radial velocity (km/s)
    Can be a numpy array or a number or None (default=None).


    @param [in] obs_metadata is an ObservationMetaData characterizing the telescope pointing

    @param [in] epoch is the epoch in Julian years of the equinox against which RA and Dec are
    measured.  Default is 2000.

    @param [in] camera is an afw.cameraGeom camera instance characterizing the camera

    @param [in] allow_multiple_chips is a boolean (default False) indicating whether or not
    this method will allow objects to be visible on more than one chip.  If it is 'False'
    and an object appears on more than one chip, an exception will be raised.  If it is 'True'
    and an object falls on more than one chip, it will still only return the first chip in the
    list of chips returned. THIS BEHAVIOR SHOULD BE FIXED IN A FUTURE TICKET.

    @param [out] the name(s) of the chips on which ra, dec fall (will be a numpy
    array if more than one)
    """

    are_arrays = _validate_inputs([ra, dec], ['ra', 'dec'], "chipNameFromRaDec")

    if epoch is None:
        raise RuntimeError("You need to pass an epoch into chipName")

    if obs_metadata is None:
        raise RuntimeError("You need to pass an ObservationMetaData into chipName")

    if obs_metadata.mjd is None:
        raise RuntimeError("You need to pass an ObservationMetaData with an mjd into chipName")

    if obs_metadata.rotSkyPos is None:
        raise RuntimeError("You need to pass an ObservationMetaData with a rotSkyPos into chipName")

    if not are_arrays:
        ra = np.array([ra])
        dec = np.array([dec])

    xp, yp = _pupilCoordsFromRaDec(ra, dec,
                                   pm_ra=pm_ra, pm_dec=pm_dec, parallax=parallax, v_rad=v_rad,
                                   obs_metadata=obs_metadata, epoch=epoch)

    ans = chipNameFromPupilCoords(xp, yp, camera=camera, allow_multiple_chips=allow_multiple_chips)

    if not are_arrays:
        return ans[0]
    return ans
Пример #23
0
    def test_with_proper_motion(self):
        """
        Test that calculating pupil coordinates in the presence of proper motion, parallax,
        and radial velocity is equivalent to
        observedFromICRS -> icrsFromObserved -> pupilCoordsFromRaDec
        (mostly to make surethat pupilCoordsFromRaDec is correctly calling observedFromICRS
        with non-zero proper motion, etc.)
        """
        rng = np.random.RandomState(38442)
        is_valid = False
        while not is_valid:
            mjd_tai = 59580.0 + 10000.0 * rng.random_sample()
            obs = ObservationMetaData(mjd=mjd_tai)
            ra, dec = raDecFromAltAz(78.0, 112.0, obs)
            dd = distanceToSun(ra, dec, obs.mjd)
            if dd > 45.0:
                is_valid = True

        n_obj = 1000
        rr = rng.random_sample(n_obj) * 2.0
        theta = rng.random_sample(n_obj) * 2.0 * np.pi
        ra_list = ra + rr * np.cos(theta)
        dec_list = dec + rr * np.sin(theta)
        obs = ObservationMetaData(pointingRA=ra,
                                  pointingDec=dec,
                                  mjd=mjd_tai,
                                  rotSkyPos=19.0)

        pm_ra_list = rng.random_sample(n_obj) * 100.0 - 50.0
        pm_dec_list = rng.random_sample(n_obj) * 100.0 - 50.0
        px_list = rng.random_sample(n_obj) + 0.05
        v_rad_list = rng.random_sample(n_obj) * 600.0 - 300.0

        for includeRefraction in (True, False):

            ra_obs, dec_obs = observedFromICRS(
                ra_list,
                dec_list,
                pm_ra=pm_ra_list,
                pm_dec=pm_dec_list,
                parallax=px_list,
                v_rad=v_rad_list,
                obs_metadata=obs,
                epoch=2000.0,
                includeRefraction=includeRefraction)

            ra_icrs, dec_icrs = icrsFromObserved(
                ra_obs,
                dec_obs,
                obs_metadata=obs,
                epoch=2000.0,
                includeRefraction=includeRefraction)

            xp_control, yp_control = pupilCoordsFromRaDec(
                ra_icrs,
                dec_icrs,
                obs_metadata=obs,
                epoch=2000.0,
                includeRefraction=includeRefraction)

            xp_test, yp_test = pupilCoordsFromRaDec(
                ra_list,
                dec_list,
                pm_ra=pm_ra_list,
                pm_dec=pm_dec_list,
                parallax=px_list,
                v_rad=v_rad_list,
                obs_metadata=obs,
                epoch=2000.0,
                includeRefraction=includeRefraction)

            distance = arcsecFromRadians(
                np.sqrt(
                    np.power(xp_test - xp_control, 2) +
                    np.power(yp_test - yp_control, 2)))
            self.assertLess(distance.max(), 0.006)

            # now test it in radians
            xp_rad, yp_rad = _pupilCoordsFromRaDec(
                np.radians(ra_list),
                np.radians(dec_list),
                pm_ra=radiansFromArcsec(pm_ra_list),
                pm_dec=radiansFromArcsec(pm_dec_list),
                parallax=radiansFromArcsec(px_list),
                v_rad=v_rad_list,
                obs_metadata=obs,
                epoch=2000.0,
                includeRefraction=includeRefraction)

            np.testing.assert_array_equal(xp_rad, xp_test)
            np.testing.assert_array_equal(yp_rad, yp_test)

            # now test it with proper motion = 0
            ra_obs, dec_obs = observedFromICRS(
                ra_list,
                dec_list,
                parallax=px_list,
                v_rad=v_rad_list,
                obs_metadata=obs,
                epoch=2000.0,
                includeRefraction=includeRefraction)

            ra_icrs, dec_icrs = icrsFromObserved(
                ra_obs,
                dec_obs,
                obs_metadata=obs,
                epoch=2000.0,
                includeRefraction=includeRefraction)

            xp_control, yp_control = pupilCoordsFromRaDec(
                ra_icrs,
                dec_icrs,
                obs_metadata=obs,
                epoch=2000.0,
                includeRefraction=includeRefraction)

            xp_test, yp_test = pupilCoordsFromRaDec(
                ra_list,
                dec_list,
                parallax=px_list,
                v_rad=v_rad_list,
                obs_metadata=obs,
                epoch=2000.0,
                includeRefraction=includeRefraction)

            distance = arcsecFromRadians(
                np.sqrt(
                    np.power(xp_test - xp_control, 2) +
                    np.power(yp_test - yp_control, 2)))
            self.assertLess(distance.max(), 1.0e-6)
Пример #24
0
def _focalPlaneCoordsFromRaDec(ra,
                               dec,
                               pm_ra=None,
                               pm_dec=None,
                               parallax=None,
                               v_rad=None,
                               obs_metadata=None,
                               epoch=2000.0,
                               camera=None):
    """
    Get the focal plane coordinates for all objects in the catalog.

    @param [in] ra is in radians in the International Celestial Reference System.
    Can be either a float or a numpy array.

    @param [in] dec is in radians in the International Celestial Reference System.
    Can be either a float or a numpy array.

    @param [in] pm_ra is proper motion in RA multiplied by cos(Dec) (radians/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] pm_dec is proper motion in dec (radians/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] parallax is parallax in radians
    Can be a numpy array or a number or None (default=None).

    @param [in] v_rad is radial velocity (km/s)
    Can be a numpy array or a number or None (default=None).


    @param [in] obs_metadata is an ObservationMetaData object describing the telescope
    pointing (only if specifying RA and Dec rather than pupil coordinates)

    @param [in] epoch is the julian epoch of the mean equinox used for coordinate transformations
    (in years; only if specifying RA and Dec rather than pupil coordinates; default is 2000)

    @param [in] camera is an afw.cameraGeom camera object

    @param [out] a 2-D numpy array in which the first row is the x
    focal plane coordinate and the second row is the y focal plane
    coordinate (both in millimeters)
    """

    _validate_inputs([ra, dec], ['ra', 'dec'], 'focalPlaneCoordsFromRaDec')

    if epoch is None:
        raise RuntimeError("You have to specify an epoch to run "
                           "focalPlaneCoordsFromRaDec")

    if obs_metadata is None:
        raise RuntimeError("You have to specify an ObservationMetaData to run "
                           "focalPlaneCoordsFromRaDec")

    if obs_metadata.mjd is None:
        raise RuntimeError("You need to pass an ObservationMetaData with an "
                           "mjd into focalPlaneCoordsFromRaDec")

    if obs_metadata.rotSkyPos is None:
        raise RuntimeError("You need to pass an ObservationMetaData with a "
                           "rotSkyPos into focalPlaneCoordsFromRaDec")

    xPupil, yPupil = _pupilCoordsFromRaDec(ra,
                                           dec,
                                           pm_ra=pm_ra,
                                           pm_dec=pm_dec,
                                           parallax=parallax,
                                           v_rad=v_rad,
                                           obs_metadata=obs_metadata,
                                           epoch=epoch)

    return focalPlaneCoordsFromPupilCoords(xPupil, yPupil, camera=camera)
Пример #25
0
    def testUtilityMethods(self):
        """
        Generate a catalog using the methods from AstrometryUtils.py and CameraUtils.py.
        Read that data in, and then recalculate the values 'by hand' to make sure
        that they are consistent.
        """

        with lsst.utils.tests.getTempFilePath('.txt') as catName:
            self.cat.write_catalog(catName)

            dtype = [('id', int),
                     ('raICRS', float), ('decICRS', float),
                     ('parallax', float), ('radial_velocity', float),
                     ('x_pupil', float), ('y_pupil', float), ('chipName', str, 11),
                     ('xPix', float), ('yPix', float),
                     ('xFocalPlane', float), ('yFocalPlane', float)]

            baselineData = np.genfromtxt(catName, dtype=dtype, delimiter=';')

        self.assertGreater(len(baselineData), 0)

        pupilTest = _pupilCoordsFromRaDec(baselineData['raICRS'],
                                          baselineData['decICRS'],
                                          parallax=baselineData['parallax'],
                                          v_rad=baselineData['radial_velocity'],
                                          obs_metadata=self.obs_metadata,
                                          epoch=2000.0)

        for (xxtest, yytest, xx, yy) in \
                zip(pupilTest[0], pupilTest[1], baselineData['x_pupil'], baselineData['y_pupil']):
            self.assertAlmostEqual(xxtest, xx, 6)
            self.assertAlmostEqual(yytest, yy, 6)

        focalTest = focalPlaneCoordsFromPupilCoords(pupilTest[0], pupilTest[1], camera=self.cat.camera)

        focalRa = _focalPlaneCoordsFromRaDec(baselineData['raICRS'], baselineData['decICRS'],
                                             parallax=baselineData['parallax'],
                                             v_rad=baselineData['radial_velocity'],
                                             epoch=self.cat.db_obj.epoch, obs_metadata=self.cat.obs_metadata,
                                             camera=self.cat.camera)

        for (xxtest, yytest, xxra, yyra, xx, yy) in \
                zip(focalTest[0], focalTest[1], focalRa[0], focalRa[1],
                    baselineData['xFocalPlane'], baselineData['yFocalPlane']):

            self.assertAlmostEqual(xxtest, xx, 6)
            self.assertAlmostEqual(yytest, yy, 6)
            self.assertAlmostEqual(xxra, xx, 6)
            self.assertAlmostEqual(yyra, yy, 6)

        pixTest = pixelCoordsFromPupilCoords(pupilTest[0], pupilTest[1], camera=self.cat.camera)

        pixTestRaDec = _pixelCoordsFromRaDec(baselineData['raICRS'], baselineData['decICRS'],
                                             parallax=baselineData['parallax'],
                                             v_rad=baselineData['radial_velocity'],
                                             epoch=self.cat.db_obj.epoch,
                                             obs_metadata=self.cat.obs_metadata,
                                             camera=self.cat.camera)

        for (xxtest, yytest, xxra, yyra, xx, yy) in \
                zip(pixTest[0], pixTest[1], pixTestRaDec[0], pixTestRaDec[1],
                    baselineData['xPix'], baselineData['yPix']):

            if not np.isnan(xx) and not np.isnan(yy):
                self.assertAlmostEqual(xxtest, xx, 5)
                self.assertAlmostEqual(yytest, yy, 5)
                self.assertAlmostEqual(xxra, xx, 5)
                self.assertAlmostEqual(yyra, yy, 5)
            else:
                np.testing.assert_equal(xx, np.NaN)
                np.testing.assert_equal(yy, np.NaN)
                np.testing.assert_equal(xxra, np.NaN)
                np.testing.assert_equal(yyra, np.NaN)
                np.testing.assert_equal(xxtest, np.NaN)
                np.testing.assert_equal(yytest, np.NaN)

        nameTest = chipNameFromPupilCoords(pupilTest[0], pupilTest[1],
                                           camera=self.cat.camera)

        nameRA = _chipNameFromRaDec(baselineData['raICRS'], baselineData['decICRS'],
                                    epoch=self.cat.db_obj.epoch, obs_metadata=self.cat.obs_metadata,
                                    camera=self.cat.camera)

        is_none = 0
        for (ntest, nra, ncontrol) in zip(nameTest, nameRA, baselineData['chipName']):
            if ncontrol != 'None':
                self.assertEqual(ntest, ncontrol)
                self.assertEqual(nra, ncontrol)
            else:
                is_none += 1
                self.assertIsNone(ntest)
                self.assertIsNone(nra)

        self.assertGreater(is_none, 0)
        self.assertLess(is_none, len(baselineData))
Пример #26
0
def _chipNameFromRaDec(ra,
                       dec,
                       pm_ra=None,
                       pm_dec=None,
                       parallax=None,
                       v_rad=None,
                       obs_metadata=None,
                       camera=None,
                       epoch=2000.0,
                       allow_multiple_chips=False):
    """
    Return the names of detectors that see the object specified by
    (RA, Dec)  in radians.

    @param [in] ra in radians (a numpy array or a float).
    In the International Celestial Reference System.

    @param [in] dec in radians (a numpy array or a float).
    In the International Celestial Reference System.

    @param [in] pm_ra is proper motion in RA multiplied by cos(Dec) (radians/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] pm_dec is proper motion in dec (radians/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] parallax is parallax in radians
    Can be a numpy array or a number or None (default=None).

    @param [in] v_rad is radial velocity (km/s)
    Can be a numpy array or a number or None (default=None).


    @param [in] obs_metadata is an ObservationMetaData characterizing the telescope pointing

    @param [in] epoch is the epoch in Julian years of the equinox against which RA and Dec are
    measured.  Default is 2000.

    @param [in] camera is an afw.cameraGeom camera instance characterizing the camera

    @param [in] allow_multiple_chips is a boolean (default False) indicating whether or not
    this method will allow objects to be visible on more than one chip.  If it is 'False'
    and an object appears on more than one chip, an exception will be raised.  If it is 'True'
    and an object falls on more than one chip, it will still only return the first chip in the
    list of chips returned. THIS BEHAVIOR SHOULD BE FIXED IN A FUTURE TICKET.

    @param [out] the name(s) of the chips on which ra, dec fall (will be a numpy
    array if more than one)
    """

    are_arrays = _validate_inputs([ra, dec], ['ra', 'dec'],
                                  "chipNameFromRaDec")

    if epoch is None:
        raise RuntimeError("You need to pass an epoch into chipName")

    if obs_metadata is None:
        raise RuntimeError(
            "You need to pass an ObservationMetaData into chipName")

    if obs_metadata.mjd is None:
        raise RuntimeError(
            "You need to pass an ObservationMetaData with an mjd into chipName"
        )

    if obs_metadata.rotSkyPos is None:
        raise RuntimeError(
            "You need to pass an ObservationMetaData with a rotSkyPos into chipName"
        )

    if not are_arrays:
        ra = np.array([ra])
        dec = np.array([dec])

    xp, yp = _pupilCoordsFromRaDec(ra,
                                   dec,
                                   pm_ra=pm_ra,
                                   pm_dec=pm_dec,
                                   parallax=parallax,
                                   v_rad=v_rad,
                                   obs_metadata=obs_metadata,
                                   epoch=epoch)

    ans = chipNameFromPupilCoords(xp,
                                  yp,
                                  camera=camera,
                                  allow_multiple_chips=allow_multiple_chips)

    if not are_arrays:
        return ans[0]
    return ans
Пример #27
0
    def testCardinalDirections(self):
        """
        This unit test verifies that the following conventions hold:

        if rotSkyPos = 0, then north is +y the camera and east is +x

        if rotSkyPos = -90, then north is -x on the camera and east is +y

        if rotSkyPos = 90, then north is +x on the camera and east is -y

        if rotSkyPos = 180, then north is -y on the camera and east is -x

        This is consistent with rotSkyPos = rotTelPos - parallacticAngle

        parallacticAngle is negative when the pointing is east of the meridian.
        http://www.petermeadows.com/html/parallactic.html

        rotTelPos is the angle between up on the telescope and up on
        the camera, where positive rotTelPos goes from north to west
        (from an email sent to me by LynneJones)

        I have verified that OpSim follows the rotSkyPos = rotTelPos - paralacticAngle
        convention.

        I have verified that altAzPaFromRaDec follows the convention that objects
        east of the meridian have a negative parallactic angle.  (altAzPaFromRaDec
        uses PALPY under the hood, so it can probably be taken as correct)

        It will verify this convention for multiple random pointings.
        """

        epoch = 2000.0
        mjd = 42350.0
        rng = np.random.RandomState(42)
        raList = rng.random_sample(10) * 360.0
        decList = rng.random_sample(10) * 180.0 - 90.0

        for rotSkyPos in np.arange(-90.0, 181.0, 90.0):
            for ra, dec in zip(raList, decList):
                obs = ObservationMetaData(pointingRA=ra,
                                          pointingDec=dec,
                                          mjd=mjd,
                                          rotSkyPos=rotSkyPos)

                ra_obs, dec_obs = _observedFromICRS(np.radians([ra]), np.radians([dec]),
                                                    obs_metadata=obs, epoch=2000.0,
                                                    includeRefraction=True)

                # test points that are displaced just to the (E, W, N, S) of the pointing
                # in observed geocentric RA, Dec; verify that the pupil coordinates
                # change as expected
                raTest_obs = ra_obs[0] + np.array([0.01, -0.01, 0.0, 0.0])
                decTest_obs = dec_obs[0] + np.array([0.0, 0.0, 0.01, -0.01])
                raTest, decTest = _icrsFromObserved(raTest_obs, decTest_obs, obs_metadata=obs,
                                                    epoch=2000.0, includeRefraction=True)

                x, y = _pupilCoordsFromRaDec(raTest, decTest, obs_metadata=obs, epoch=epoch)

                lon, lat = _nativeLonLatFromRaDec(raTest, decTest, obs)
                rr = np.abs(np.cos(lat) / np.sin(lat))

                if np.abs(rotSkyPos) < 0.01:  # rotSkyPos == 0
                    control_x = np.array([1.0 * rr[0], -1.0 * rr[1], 0.0, 0.0])
                    control_y = np.array([0.0, 0.0, 1.0 * rr[2], -1.0 * rr[3]])
                elif np.abs(rotSkyPos + 90.0) < 0.01:  # rotSkyPos == -90
                    control_x = np.array([0.0, 0.0, -1.0 * rr[2], 1.0 * rr[3]])
                    control_y = np.array([1.0 * rr[0], -1.0 * rr[1], 0.0, 0.0])
                elif np.abs(rotSkyPos - 90.0) < 0.01:  # rotSkyPos == 90
                    control_x = np.array([0.0, 0.0, 1.0 * rr[2], -1.0 * rr[3]])
                    control_y = np.array([-1.0 * rr[0], +1.0 * rr[1], 0.0, 0.0])
                elif np.abs(rotSkyPos - 180.0) < 0.01:  # rotSkyPos == 180
                    control_x = np.array([-1.0 * rr[0], +1.0 * rr[1], 0.0, 0.0])
                    control_y = np.array([0.0, 0.0, -1.0 * rr[2], 1.0 * rr[3]])

                msg = 'failed on rotSkyPos == %e\n' % rotSkyPos
                msg += 'control_x %s\n' % str(control_x)
                msg += 'test_x %s\n' % str(x)
                msg += 'control_y %s\n' % str(control_y)
                msg += 'test_y %s\n' % str(y)

                dx = np.array([xx / cc if np.abs(cc) > 1.0e-10 else 1.0 - xx for xx, cc in zip(x, control_x)])
                dy = np.array([yy / cc if np.abs(cc) > 1.0e-10 else 1.0 - yy for yy, cc in zip(y, control_y)])
                self.assertLess(np.abs(dx-np.ones(4)).max(), 0.001, msg=msg)
                self.assertLess(np.abs(dy-np.ones(4)).max(), 0.001, msg=msg)
Пример #28
0
def _pixelCoordsFromRaDecLSST(ra,
                              dec,
                              pm_ra=None,
                              pm_dec=None,
                              parallax=None,
                              v_rad=None,
                              obs_metadata=None,
                              chipName=None,
                              camera=None,
                              epoch=2000.0,
                              includeDistortion=True,
                              band='r'):
    """
    Get the pixel positions on the LSST camera (or nan if not on a chip) for objects based
    on their RA, and Dec (in radians)

    @param [in] ra is in radians in the International Celestial Reference System.
    Can be either a float or a numpy array.

    @param [in] dec is in radians in the International Celestial Reference System.
    Can be either a float or a numpy array.

    @param [in] pm_ra is proper motion in RA multiplied by cos(Dec) (radians/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] pm_dec is proper motion in dec (radians/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] parallax is parallax in radians
    Can be a numpy array or a number or None (default=None).

    @param [in] v_rad is radial velocity (km/s)
    Can be a numpy array or a number or None (default=None).

    @param [in] obs_metadata is an ObservationMetaData characterizing the telescope
    pointing.

    @param [in] epoch is the epoch in Julian years of the equinox against which
    RA is measured.  Default is 2000.

    @param [in] chipName designates the names of the chips on which the pixel
    coordinates will be reckoned.  Can be either single value, an array, or None.
    If an array, there must be as many chipNames as there are (RA, Dec) pairs.
    If a single value, all of the pixel coordinates will be reckoned on the same
    chip.  If None, this method will calculate which chip each(RA, Dec) pair actually
    falls on, and return pixel coordinates for each (RA, Dec) pair on the appropriate
    chip.  Default is None.

    @param [in] camera is an afwCameraGeom object specifying the attributes of the camera.
    This is an optional argument to be passed to chipName.

    @param [in] includeDistortion is a boolean.  If True (default), then this method will
    return the true pixel coordinates with optical distortion included.  If False, this
    method will return TAN_PIXEL coordinates, which are the pixel coordinates with
    estimated optical distortion removed.  See the documentation in afw.cameraGeom for more
    details.

    @param [in] band is the filter we are simulating ('u', 'g', 'r', etc.) Default='r'

    @param [out] a 2-D numpy array in which the first row is the x pixel coordinate
    and the second row is the y pixel coordinate
    """

    if epoch is None:
        raise RuntimeError(
            "You need to pass an epoch into pixelCoordsFromRaDec")

    if obs_metadata is None:
        raise RuntimeError(
            "You need to pass an ObservationMetaData into pixelCoordsFromRaDec"
        )

    if obs_metadata.mjd is None:
        raise RuntimeError(
            "You need to pass an ObservationMetaData with an mjd into "
            "pixelCoordsFromRaDec")

    if obs_metadata.rotSkyPos is None:
        raise RuntimeError(
            "You need to pass an ObservationMetaData with a rotSkyPos into "
            "pixelCoordsFromRaDec")

    xPupil, yPupil = _pupilCoordsFromRaDec(ra,
                                           dec,
                                           pm_ra=pm_ra,
                                           pm_dec=pm_dec,
                                           parallax=parallax,
                                           v_rad=v_rad,
                                           obs_metadata=obs_metadata,
                                           epoch=epoch)

    return pixelCoordsFromPupilCoordsLSST(xPupil,
                                          yPupil,
                                          chipName=chipName,
                                          band=band,
                                          includeDistortion=includeDistortion)
Пример #29
0
    def testCardinalDirections(self):
        """
        This unit test verifies that the following conventions hold:

        if rotSkyPos = 0, then north is +y the camera and east is +x

        if rotSkyPos = -90, then north is -x on the camera and east is +y

        if rotSkyPos = 90, then north is +x on the camera and east is -y

        if rotSkyPos = 180, then north is -y on the camera and east is -x

        This is consistent with rotSkyPos = rotTelPos - parallacticAngle

        parallacticAngle is negative when the pointing is east of the meridian.
        http://www.petermeadows.com/html/parallactic.html

        rotTelPos is the angle between up on the telescope and up on
        the camera, where positive rotTelPos goes from north to west
        (from an email sent to me by LynneJones)

        I have verified that OpSim follows the rotSkyPos = rotTelPos - paralacticAngle
        convention.

        I have verified that altAzPaFromRaDec follows the convention that objects
        east of the meridian have a negative parallactic angle.  (altAzPaFromRaDec
        uses PALPY under the hood, so it can probably be taken as correct)

        It will verify this convention for multiple random pointings.
        """

        epoch = 2000.0
        mjd = 42350.0
        rng = np.random.RandomState(42)
        raList = rng.random_sample(10) * 360.0
        decList = rng.random_sample(10) * 180.0 - 90.0

        for rotSkyPos in np.arange(-90.0, 181.0, 90.0):
            for ra, dec in zip(raList, decList):
                obs = ObservationMetaData(pointingRA=ra,
                                          pointingDec=dec,
                                          mjd=mjd,
                                          rotSkyPos=rotSkyPos)

                ra_obs, dec_obs = _observedFromICRS(np.radians([ra]),
                                                    np.radians([dec]),
                                                    obs_metadata=obs,
                                                    epoch=2000.0,
                                                    includeRefraction=True)

                # test points that are displaced just to the (E, W, N, S) of the pointing
                # in observed geocentric RA, Dec; verify that the pupil coordinates
                # change as expected
                raTest_obs = ra_obs[0] + np.array([0.01, -0.01, 0.0, 0.0])
                decTest_obs = dec_obs[0] + np.array([0.0, 0.0, 0.01, -0.01])
                raTest, decTest = _icrsFromObserved(raTest_obs,
                                                    decTest_obs,
                                                    obs_metadata=obs,
                                                    epoch=2000.0,
                                                    includeRefraction=True)

                x, y = _pupilCoordsFromRaDec(raTest,
                                             decTest,
                                             obs_metadata=obs,
                                             epoch=epoch)

                lon, lat = _nativeLonLatFromRaDec(raTest, decTest, obs)
                rr = np.abs(np.cos(lat) / np.sin(lat))

                if np.abs(rotSkyPos) < 0.01:  # rotSkyPos == 0
                    control_x = np.array([1.0 * rr[0], -1.0 * rr[1], 0.0, 0.0])
                    control_y = np.array([0.0, 0.0, 1.0 * rr[2], -1.0 * rr[3]])
                elif np.abs(rotSkyPos + 90.0) < 0.01:  # rotSkyPos == -90
                    control_x = np.array([0.0, 0.0, -1.0 * rr[2], 1.0 * rr[3]])
                    control_y = np.array([1.0 * rr[0], -1.0 * rr[1], 0.0, 0.0])
                elif np.abs(rotSkyPos - 90.0) < 0.01:  # rotSkyPos == 90
                    control_x = np.array([0.0, 0.0, 1.0 * rr[2], -1.0 * rr[3]])
                    control_y = np.array(
                        [-1.0 * rr[0], +1.0 * rr[1], 0.0, 0.0])
                elif np.abs(rotSkyPos - 180.0) < 0.01:  # rotSkyPos == 180
                    control_x = np.array(
                        [-1.0 * rr[0], +1.0 * rr[1], 0.0, 0.0])
                    control_y = np.array([0.0, 0.0, -1.0 * rr[2], 1.0 * rr[3]])

                msg = 'failed on rotSkyPos == %e\n' % rotSkyPos
                msg += 'control_x %s\n' % str(control_x)
                msg += 'test_x %s\n' % str(x)
                msg += 'control_y %s\n' % str(control_y)
                msg += 'test_y %s\n' % str(y)

                dx = np.array([
                    xx / cc if np.abs(cc) > 1.0e-10 else 1.0 - xx
                    for xx, cc in zip(x, control_x)
                ])
                dy = np.array([
                    yy / cc if np.abs(cc) > 1.0e-10 else 1.0 - yy
                    for yy, cc in zip(y, control_y)
                ])
                self.assertLess(np.abs(dx - np.ones(4)).max(), 0.001, msg=msg)
                self.assertLess(np.abs(dy - np.ones(4)).max(), 0.001, msg=msg)
Пример #30
0
def _focalPlaneCoordsFromRaDec(ra, dec, pm_ra=None, pm_dec=None, parallax=None, v_rad=None,
                               obs_metadata=None, epoch=2000.0, camera=None):
    """
    Get the focal plane coordinates for all objects in the catalog.

    @param [in] ra is in radians in the International Celestial Reference System.
    Can be either a float or a numpy array.

    @param [in] dec is in radians in the International Celestial Reference System.
    Can be either a float or a numpy array.

    @param [in] pm_ra is proper motion in RA multiplied by cos(Dec) (radians/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] pm_dec is proper motion in dec (radians/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] parallax is parallax in radians
    Can be a numpy array or a number or None (default=None).

    @param [in] v_rad is radial velocity (km/s)
    Can be a numpy array or a number or None (default=None).


    @param [in] obs_metadata is an ObservationMetaData object describing the telescope
    pointing (only if specifying RA and Dec rather than pupil coordinates)

    @param [in] epoch is the julian epoch of the mean equinox used for coordinate transformations
    (in years; only if specifying RA and Dec rather than pupil coordinates; default is 2000)

    @param [in] camera is an afw.cameraGeom camera object

    @param [out] a 2-D numpy array in which the first row is the x
    focal plane coordinate and the second row is the y focal plane
    coordinate (both in millimeters)
    """

    _validate_inputs([ra, dec], ['ra', 'dec'], 'focalPlaneCoordsFromRaDec')

    if epoch is None:
        raise RuntimeError("You have to specify an epoch to run "
                           "focalPlaneCoordsFromRaDec")

    if obs_metadata is None:
        raise RuntimeError("You have to specify an ObservationMetaData to run "
                           "focalPlaneCoordsFromRaDec")

    if obs_metadata.mjd is None:
        raise RuntimeError("You need to pass an ObservationMetaData with an "
                           "mjd into focalPlaneCoordsFromRaDec")

    if obs_metadata.rotSkyPos is None:
        raise RuntimeError("You need to pass an ObservationMetaData with a "
                           "rotSkyPos into focalPlaneCoordsFromRaDec")

    xPupil, yPupil = _pupilCoordsFromRaDec(ra, dec,
                                           pm_ra=pm_ra, pm_dec=pm_dec,
                                           parallax=parallax, v_rad=v_rad,
                                           obs_metadata=obs_metadata,
                                           epoch=epoch)

    return focalPlaneCoordsFromPupilCoords(xPupil, yPupil, camera=camera)
Пример #31
0
    def testExceptions(self):
        """
        Test that exceptions are raised when they ought to be
        """
        obs_metadata = ObservationMetaData(pointingRA=25.0,
                                           pointingDec=25.0,
                                           rotSkyPos=25.0,
                                           mjd=52000.0)

        rng = np.random.RandomState(42)
        ra = rng.random_sample(10) * np.radians(1.0) + np.radians(
            obs_metadata.pointingRA)
        dec = rng.random_sample(10) * np.radians(1.0) + np.radians(
            obs_metadata.pointingDec)
        raShort = np.array([1.0])
        decShort = np.array([1.0])

        # test without obs_metadata
        self.assertRaises(RuntimeError,
                          _pupilCoordsFromRaDec,
                          ra,
                          dec,
                          epoch=2000.0)

        # test without pointingRA
        dummy = ObservationMetaData(pointingDec=obs_metadata.pointingDec,
                                    rotSkyPos=obs_metadata.rotSkyPos,
                                    mjd=obs_metadata.mjd)
        self.assertRaises(RuntimeError,
                          _pupilCoordsFromRaDec,
                          ra,
                          dec,
                          epoch=2000.0,
                          obs_metadata=dummy)

        # test without pointingDec
        dummy = ObservationMetaData(pointingRA=obs_metadata.pointingRA,
                                    rotSkyPos=obs_metadata.rotSkyPos,
                                    mjd=obs_metadata.mjd)
        self.assertRaises(RuntimeError,
                          _pupilCoordsFromRaDec,
                          ra,
                          dec,
                          epoch=2000.0,
                          obs_metadata=dummy)

        # test without rotSkyPos
        dummy = ObservationMetaData(pointingRA=obs_metadata.pointingRA,
                                    pointingDec=obs_metadata.pointingDec,
                                    mjd=obs_metadata.mjd)
        self.assertRaises(RuntimeError,
                          _pupilCoordsFromRaDec,
                          ra,
                          dec,
                          epoch=2000.0,
                          obs_metadata=dummy)

        # test without mjd
        dummy = ObservationMetaData(pointingRA=obs_metadata.pointingRA,
                                    pointingDec=obs_metadata.pointingDec,
                                    rotSkyPos=obs_metadata.rotSkyPos)
        self.assertRaises(RuntimeError,
                          _pupilCoordsFromRaDec,
                          ra,
                          dec,
                          epoch=2000.0,
                          obs_metadata=dummy)

        # test for mismatches
        dummy = ObservationMetaData(pointingRA=obs_metadata.pointingRA,
                                    pointingDec=obs_metadata.pointingDec,
                                    rotSkyPos=obs_metadata.rotSkyPos,
                                    mjd=obs_metadata.mjd)

        self.assertRaises(RuntimeError,
                          _pupilCoordsFromRaDec,
                          ra,
                          decShort,
                          epoch=2000.0,
                          obs_metadata=dummy)

        self.assertRaises(RuntimeError,
                          _pupilCoordsFromRaDec,
                          raShort,
                          dec,
                          epoch=2000.0,
                          obs_metadata=dummy)

        # test that it actually runs (and that passing in either numpy arrays or floats gives
        # the same results)
        xx_arr, yy_arr = _pupilCoordsFromRaDec(ra,
                                               dec,
                                               obs_metadata=obs_metadata)
        self.assertIsInstance(xx_arr, np.ndarray)
        self.assertIsInstance(yy_arr, np.ndarray)

        for ix in range(len(ra)):
            xx_f, yy_f = _pupilCoordsFromRaDec(ra[ix],
                                               dec[ix],
                                               obs_metadata=obs_metadata)
            self.assertIsInstance(xx_f, np.float)
            self.assertIsInstance(yy_f, np.float)
            self.assertAlmostEqual(xx_arr[ix], xx_f, 12)
            self.assertAlmostEqual(yy_arr[ix], yy_f, 12)
            self.assertFalse(np.isnan(xx_f))
            self.assertFalse(np.isnan(yy_f))