def testRaDecFromPupil(self): """ Test conversion from pupil coordinates back to Ra, Dec """ mjd = ModifiedJulianDate(TAI=52000.0) solarRA, solarDec = solarRaDec(mjd) # to make sure that we are more than 45 degrees from the Sun as required # for _icrsFromObserved to be at all accurate raCenter = solarRA + 100.0 decCenter = solarDec - 30.0 obs = ObservationMetaData(pointingRA=raCenter, pointingDec=decCenter, boundType='circle', boundLength=0.1, rotSkyPos=23.0, mjd=mjd) nSamples = 1000 rng = np.random.RandomState(42) ra = (rng.random_sample(nSamples) * 0.1 - 0.2) + np.radians(raCenter) dec = (rng.random_sample(nSamples) * 0.1 - 0.2) + np.radians(decCenter) xp, yp = _pupilCoordsFromRaDec(ra, dec, obs_metadata=obs, epoch=2000.0) raTest, decTest = _raDecFromPupilCoords(xp, yp, obs_metadata=obs, epoch=2000.0) distance = arcsecFromRadians(haversine(ra, dec, raTest, decTest)) dex = np.argmax(distance) worstSolarDistance = distanceToSun(np.degrees(ra[dex]), np.degrees(dec[dex]), mjd) msg = "_raDecFromPupilCoords off by %e arcsec at distance to Sun of %e degrees" % \ (distance.max(), worstSolarDistance) self.assertLess(distance.max(), 1.0e-6, msg=msg) # now check that passing in the xp, yp values one at a time still gives # the right answer for ix in range(len(ra)): ra_f, dec_f = _raDecFromPupilCoords(xp[ix], yp[ix], obs_metadata=obs, epoch=2000.0) self.assertIsInstance(ra_f, np.float) self.assertIsInstance(dec_f, np.float) dist_f = arcsecFromRadians( haversine(ra_f, dec_f, raTest[ix], decTest[ix])) self.assertLess(dist_f, 1.0e-9)
def 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 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)
def testraDecFromPupilCoords(self): obs = ObservationMetaData(pointingRA=23.5, pointingDec=-115.0, mjd=42351.0, rotSkyPos=127.0) xpList = np.random.random_sample(100)*0.25*np.pi ypList = np.random.random_sample(100)*0.25*np.pi raRad, decRad = utils._raDecFromPupilCoords(xpList, ypList, obs_metadata=obs, epoch=2000.0) raDeg, decDeg = utils.raDecFromPupilCoords(xpList, ypList, obs_metadata=obs, epoch=2000.0) dRa = utils.arcsecFromRadians(raRad-np.radians(raDeg)) np.testing.assert_array_almost_equal(dRa, np.zeros(len(xpList)), 9) dDec = utils.arcsecFromRadians(decRad-np.radians(decDeg)) np.testing.assert_array_almost_equal(dDec, np.zeros(len(xpList)), 9)
def testraDecFromPupilCoords(self): obs = ObservationMetaData(pointingRA=23.5, pointingDec=-115.0, mjd=42351.0, rotSkyPos=127.0) xpList = self.rng.random_sample(100) * 0.25 * np.pi ypList = self.rng.random_sample(100) * 0.25 * np.pi raRad, decRad = utils._raDecFromPupilCoords(xpList, ypList, obs_metadata=obs, epoch=2000.0) raDeg, decDeg = utils.raDecFromPupilCoords(xpList, ypList, obs_metadata=obs, epoch=2000.0) dRa = utils.arcsecFromRadians(raRad - np.radians(raDeg)) np.testing.assert_array_almost_equal(dRa, np.zeros(len(xpList)), 9) dDec = utils.arcsecFromRadians(decRad - np.radians(decDeg)) np.testing.assert_array_almost_equal(dDec, np.zeros(len(xpList)), 9)
def _raDecFromPixelCoordsLSST(xPix, yPix, chipName, band='r', obs_metadata=None, epoch=2000.0, includeDistortion=True): """ Convert pixel coordinates into RA, Dec @param [in] xPix is the x pixel coordinate. It can be either a float or a numpy array. @param [in] yPix is the y pixel coordinate. It can be either a float or a numpy array. @param [in] chipName is the name of the chip(s) on which the pixel coordinates are defined. This can be a list (in which case there should be one chip name for each (xPix, yPix) coordinate pair), or a single value (in which case, all of the (xPix, yPix) points will be reckoned on that chip). @param [in] band is the filter we are simulating (default=r) @param [in] obs_metadata is an ObservationMetaData defining the pointing @param [in] epoch is the mean epoch in years of the celestial coordinate system. Default is 2000. @param [in] includeDistortion is a boolean. If True (default), then this method will expect the true pixel coordinates with optical distortion included. If False, this method will expect 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 RA coordinate and the second row is the Dec coordinate (both in radians; in the International Celestial Reference System) WARNING: This method does not account for apparent motion due to parallax. This method is only useful for mapping positions on a theoretical focal plane to positions on the celestial sphere. """ are_arrays, \ chipNameList = _validate_inputs_and_chipname([xPix, yPix], ['xPix', 'yPix'], 'raDecFromPixelCoords', chipName, chipname_can_be_none=False) if epoch is None: raise RuntimeError( "You cannot call raDecFromPixelCoords without specifying an epoch") if obs_metadata is None: raise RuntimeError( "You cannot call raDecFromPixelCoords without an ObservationMetaData" ) if obs_metadata.mjd is None: raise RuntimeError( "The ObservationMetaData in raDecFromPixelCoords must have an mjd") if obs_metadata.rotSkyPos is None: raise RuntimeError( "The ObservationMetaData in raDecFromPixelCoords must have a rotSkyPos" ) xPupilList, yPupilList = pupilCoordsFromPixelCoordsLSST( xPix, yPix, chipNameList, band=band, includeDistortion=includeDistortion) raOut, decOut = _raDecFromPupilCoords(xPupilList, yPupilList, obs_metadata=obs_metadata, epoch=epoch) return np.array([raOut, decOut])
def _raDecFromPixelCoords(xPix, yPix, chipName, camera=None, obs_metadata=None, epoch=2000.0, includeDistortion=True): """ Convert pixel coordinates into RA, Dec @param [in] xPix is the x pixel coordinate. It can be either a float or a numpy array. @param [in] yPix is the y pixel coordinate. It can be either a float or a numpy array. @param [in] chipName is the name of the chip(s) on which the pixel coordinates are defined. This can be a list (in which case there should be one chip name for each (xPix, yPix) coordinate pair), or a single value (in which case, all of the (xPix, yPix) points will be reckoned on that chip). @param [in] camera is an afw.CameraGeom.camera object defining the camera @param [in] obs_metadata is an ObservationMetaData defining the pointing @param [in] epoch is the mean epoch in years of the celestial coordinate system. Default is 2000. @param [in] includeDistortion is a boolean. If True (default), then this method will expect the true pixel coordinates with optical distortion included. If False, this method will expect 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 RA coordinate and the second row is the Dec coordinate (both in radians; in the International Celestial Reference System) WARNING: This method does not account for apparent motion due to parallax. This method is only useful for mapping positions on a theoretical focal plane to positions on the celestial sphere. """ are_arrays, \ chipNameList = _validate_inputs_and_chipname([xPix, yPix], ['xPix', 'yPix'], 'raDecFromPixelCoords', chipName, chipname_can_be_none=False) if camera is None: raise RuntimeError("You cannot call raDecFromPixelCoords without specifying a camera") if epoch is None: raise RuntimeError("You cannot call raDecFromPixelCoords without specifying an epoch") if obs_metadata is None: raise RuntimeError("You cannot call raDecFromPixelCoords without an ObservationMetaData") if obs_metadata.mjd is None: raise RuntimeError("The ObservationMetaData in raDecFromPixelCoords must have an mjd") if obs_metadata.rotSkyPos is None: raise RuntimeError("The ObservationMetaData in raDecFromPixelCoords must have a rotSkyPos") xPupilList, yPupilList = pupilCoordsFromPixelCoords(xPix, yPix, chipNameList, camera=camera, includeDistortion=includeDistortion) raOut, decOut = _raDecFromPupilCoords(xPupilList, yPupilList, obs_metadata=obs_metadata, epoch=epoch) return np.array([raOut, decOut])
def _raDecFromPixelCoords(xPixList, yPixList, chipNameList, camera=None, obs_metadata=None, epoch=None, includeDistortion=True): """ Convert pixel coordinates into RA, Dec @param [in] xPixList is a numpy array of x pixel coordinates @param [in] yPixList is a numpy array of y pixel coordinates @param [in] chipNameList is a numpy array of chip names (corresponding to the points in xPixList and yPixList) @param [in] camera is an afw.CameraGeom.camera object defining the camera @param [in] obs_metadata is an ObservationMetaData defining the pointing @param [in] epoch is the mean epoch in years of the celestial coordinate system @param [in] includeDistortion is a boolean. If True (default), then this method will expect the true pixel coordinates with optical distortion included. If False, this method will expect 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 RA coordinate and the second row is the Dec coordinate (both in radians; in the International Celestial Reference System) """ if camera is None: raise RuntimeError("You cannot call raDecFromPixelCoords without specifying a camera") if epoch is None: raise RuntimeError("You cannot call raDecFromPixelCoords without specifying an epoch") if obs_metadata is None: raise RuntimeError("You cannot call raDecFromPixelCoords without an ObservationMetaData") if obs_metadata.mjd is None: raise RuntimeError("The ObservationMetaData in raDecFromPixelCoords must have an mjd") if obs_metadata.rotSkyPos is None: raise RuntimeError("The ObservationMetaData in raDecFromPixelCoords must have a rotSkyPos") if not isinstance(xPixList, numpy.ndarray) or not isinstance(yPixList, numpy.ndarray): raise RuntimeError("You must pass numpy arrays of xPix and yPix to raDecFromPixelCoords") if len(xPixList)!=len(yPixList): raise RuntimeError("You passed %d xPix coordinates but %d yPix coordinates " \ % (len(xPixList), len(yPixList)) \ +"to raDecFromPixelCoords") if len(xPixList)!=len(chipNameList): raise RuntimeError("You passed %d pixel coordinate pairs but %d chip names " \ % (len(xPixList), len(chipNameList)) \ +"to raDecFromPixelCoords") xPupilList, yPupilList = pupilCoordsFromPixelCoords(xPixList, yPixList, chipNameList, camera=camera, includeDistortion=includeDistortion) raOut, decOut = _raDecFromPupilCoords(xPupilList, yPupilList, obs_metadata=obs_metadata, epoch=epoch) return numpy.array([raOut, decOut])