def _run(self, simData): ra_pi_amp = np.zeros(np.size(simData), dtype=[('ra_pi_amp', 'float')]) dec_pi_amp = np.zeros(np.size(simData), dtype=[('dec_pi_amp', 'float')]) ra_geo1 = np.zeros(np.size(simData), dtype='float') dec_geo1 = np.zeros(np.size(simData), dtype='float') ra_geo = np.zeros(np.size(simData), dtype='float') dec_geo = np.zeros(np.size(simData), dtype='float') ra = simData[self.raCol] dec = simData[self.decCol] if self.raDecDeg: ra = np.radians(ra) dec = np.radians(dec) for i, ack in enumerate(simData): mtoa_params = palpy.mappa(2000., simData[self.dateCol][i]) # Object with a 1 arcsec parallax ra_geo1[i], dec_geo1[i] = palpy.mapqk(ra[i], dec[i], 0., 0., 1., 0., mtoa_params) # Object with no parallax ra_geo[i], dec_geo[i] = palpy.mapqk(ra[i], dec[i], 0., 0., 0., 0., mtoa_params) x_geo1, y_geo1 = self._gnomonic_project_toxy(ra_geo1, dec_geo1, ra, dec) x_geo, y_geo = self._gnomonic_project_toxy(ra_geo, dec_geo, ra, dec) ra_pi_amp[:] = np.degrees(x_geo1 - x_geo) * 3600. dec_pi_amp[:] = np.degrees(y_geo1 - y_geo) * 3600. simData['ra_pi_amp'] = ra_pi_amp simData['dec_pi_amp'] = dec_pi_amp return simData
def _run(self, simData, cols_present=False): if cols_present: # Column already present in data; assume it is correct and does not need recalculating. return simData ra_pi_amp = np.zeros(np.size(simData), dtype=[('ra_pi_amp', 'float')]) dec_pi_amp = np.zeros(np.size(simData), dtype=[('dec_pi_amp', 'float')]) ra_geo1 = np.zeros(np.size(simData), dtype='float') dec_geo1 = np.zeros(np.size(simData), dtype='float') ra_geo = np.zeros(np.size(simData), dtype='float') dec_geo = np.zeros(np.size(simData), dtype='float') ra = simData[self.raCol] dec = simData[self.decCol] if self.degrees: ra = np.radians(ra) dec = np.radians(dec) for i, ack in enumerate(simData): mtoa_params = palpy.mappa(2000., simData[self.dateCol][i]) # Object with a 1 arcsec parallax ra_geo1[i], dec_geo1[i] = palpy.mapqk(ra[i], dec[i], 0., 0., 1., 0., mtoa_params) # Object with no parallax ra_geo[i], dec_geo[i] = palpy.mapqk(ra[i], dec[i], 0., 0., 0., 0., mtoa_params) x_geo1, y_geo1 = self._gnomonic_project_toxy(ra_geo1, dec_geo1, ra, dec) x_geo, y_geo = self._gnomonic_project_toxy(ra_geo, dec_geo, ra, dec) # Return ra_pi_amp and dec_pi_amp in arcseconds. ra_pi_amp[:] = np.degrees(x_geo1-x_geo)*3600. dec_pi_amp[:] = np.degrees(y_geo1-y_geo)*3600. simData['ra_pi_amp'] = ra_pi_amp simData['dec_pi_amp'] = dec_pi_amp return simData
def _run(self, simData): ra_pi_amp = np.zeros(np.size(simData), dtype=[('ra_pi_amp','float')]) dec_pi_amp = np.zeros(np.size(simData), dtype=[('dec_pi_amp','float')]) ra_geo1 = np.zeros(np.size(simData), dtype='float') dec_geo1 = np.zeros(np.size(simData), dtype='float') ra_geo = np.zeros(np.size(simData), dtype='float') dec_geo = np.zeros(np.size(simData), dtype='float') for i,ack in enumerate(simData): mtoa_params = palpy.mappa(2000., simData[self.dateCol][i]) ra_geo1[i],dec_geo1[i] = palpy.mapqk(simData[self.raCol][i],simData[self.decCol][i], 0.,0.,1.,0.,mtoa_params) ra_geo[i],dec_geo[i] = palpy.mapqk(simData[self.raCol][i],simData[self.decCol][i], 0.,0.,0.,0.,mtoa_params) x_geo1,y_geo1 = self._gnomonic_project_toxy(ra_geo1, dec_geo1, simData[self.raCol],simData[self.decCol]) x_geo, y_geo = self._gnomonic_project_toxy(ra_geo, dec_geo, simData[self.raCol], simData[self.decCol]) ra_pi_amp[:] = np.degrees(x_geo1-x_geo)*3600. dec_pi_amp[:] = np.degrees(y_geo1-y_geo)*3600. simData['ra_pi_amp'] = ra_pi_amp simData['dec_pi_amp'] = dec_pi_amp return simData
def testParallax(self): """ This test will output a catalog of ICRS and observed positions. It will also output the quantities (proper motion, radial velocity, and parallax) needed to apply the transformaiton between the two. It will then run the catalog through PALPY and verify that the catalog generating code correctly applied the transformations. """ # create and write a catalog that performs astrometric transformations # on a cartoon star database cat = parallaxTestCatalog(self.starDBObject, obs_metadata=self.obs_metadata) parallaxName = os.path.join(getPackageDir('sims_catUtils'), 'tests', 'scratchSpace', 'parallaxCatalog.sav') if os.path.exists(parallaxName): os.unlink(parallaxName) cat.write_catalog(parallaxName) data = np.genfromtxt(parallaxName, delimiter=',') self.assertGreater(len(data), 0) epoch = cat.db_obj.epoch mjd = cat.obs_metadata.mjd prms = pal.mappa(epoch, mjd.TDB) for vv in data: # run the PALPY routines that actuall do astrometry `by hand' and compare # the results to the contents of the catalog ra0 = np.radians(vv[0]) dec0 = np.radians(vv[1]) pmra = np.radians(vv[4]) pmdec = np.radians(vv[5]) rv = vv[6] px = vv[7] ra_apparent, dec_apparent = pal.mapqk(ra0, dec0, pmra, pmdec, px, rv, prms) ra_apparent = np.array([ra_apparent]) dec_apparent = np.array([dec_apparent]) raObserved, decObserved = _observedFromAppGeo(ra_apparent, dec_apparent, obs_metadata=cat.obs_metadata) self.assertAlmostEqual(raObserved[0], np.radians(vv[2]), 7) self.assertAlmostEqual(decObserved[0], np.radians(vv[3]), 7) if os.path.exists(parallaxName): os.unlink(parallaxName)
def testParallax(self): """ This test will output a catalog of ICRS and observed positions. It will also output the quantities (proper motion, radial velocity, and parallax) needed to apply the transformaiton between the two. It will then run the catalog through PALPY and verify that the catalog generating code correctly applied the transformations. """ #create and write a catalog that performs astrometric transformations #on a cartoon star database cat = parallaxTestCatalog(self.starDBObject, obs_metadata=self.obs_metadata) parallaxName = os.path.join(getPackageDir('sims_catUtils'), 'tests', 'scratchSpace', 'parallaxCatalog.sav') if os.path.exists(parallaxName): os.unlink(parallaxName) cat.write_catalog(parallaxName) data = numpy.genfromtxt(parallaxName,delimiter=',') self.assertGreater(len(data), 0) epoch = cat.db_obj.epoch mjd = cat.obs_metadata.mjd prms = pal.mappa(epoch, mjd.TDB) for vv in data: #run the PALPY routines that actuall do astrometry `by hand' and compare #the results to the contents of the catalog ra0 = numpy.radians(vv[0]) dec0 = numpy.radians(vv[1]) pmra = numpy.radians(vv[4]) pmdec = numpy.radians(vv[5]) rv = vv[6] px = vv[7] ra_apparent, dec_apparent = pal.mapqk(ra0, dec0, pmra, pmdec, px, rv, prms) ra_apparent = numpy.array([ra_apparent]) dec_apparent = numpy.array([dec_apparent]) raObserved, decObserved = _observedFromAppGeo(ra_apparent, dec_apparent, obs_metadata=cat.obs_metadata) self.assertAlmostEqual(raObserved[0],numpy.radians(vv[2]),7) self.assertAlmostEqual(decObserved[0],numpy.radians(vv[3]),7) if os.path.exists(parallaxName): os.unlink(parallaxName)
def _appGeoFromICRS(ra, dec, pm_ra=None, pm_dec=None, parallax=None, v_rad=None, epoch=2000.0, mjd=None): """ Convert the mean position (RA, Dec) in the International Celestial Reference System (ICRS) to the mean apparent geocentric position units: ra (radians), dec (radians), pm_ra (radians/year), pm_dec (radians/year), parallax (radians), v_rad (km/sec; positive if receding), epoch (Julian years) @param [in] ra in radians (ICRS). Can be a numpy array or a number. @param [in] dec in radians (ICRS). Can be a numpy array or a number. @param [in] pm_ra is ra proper motion multiplied by cos(Dec) in radians/year. Can be a numpy array or a number or None. @param [in] pm_dec is dec proper motion in radians/year. Can be a numpy array or a number or None. @param [in] parallax in radians. Can be a numpy array or a number or None. @param [in] v_rad is radial velocity in km/sec (positive if the object is receding). Can be a numpy array or a number or None. @param [in] epoch is the julian epoch (in years) of the equinox against which to measure RA (default: 2000.0) @param [in] mjd is an instantiation of the ModifiedJulianDate class representing the date of the observation @param [out] a 2-D numpy array in which the first row is the apparent geocentric RAand the second row is the apparent geocentric Dec (both in radians) """ if mjd is None: raise RuntimeError("cannot call appGeoFromICRS; mjd is None") include_px = False if (pm_ra is not None or pm_dec is not None or v_rad is not None or parallax is not None): include_px = True if isinstance(ra, np.ndarray): fill_value = np.zeros(len(ra), dtype=float) else: fill_value = 0.0 if pm_ra is None: pm_ra = fill_value if pm_dec is None: pm_dec = fill_value if v_rad is None: v_rad = fill_value if parallax is None: parallax = fill_value are_arrays = _validate_inputs( [ra, dec, pm_ra, pm_dec, v_rad, parallax], ['ra', 'dec', 'pm_ra', 'pm_dec', 'v_rad', 'parallax'], "appGeoFromICRS") else: are_arrays = _validate_inputs([ra, dec], ['ra', 'dec'], "appGeoFromICRS") # Define star independent mean to apparent place parameters # palpy.mappa calculates the star-independent parameters # needed to correct RA and Dec # e.g the Earth barycentric and heliocentric position and velocity, # the precession-nutation matrix, etc. # # arguments of palpy.mappa are: # epoch of mean equinox to be used (Julian) # # date (MJD) prms = palpy.mappa(epoch, mjd.TDB) # palpy.mapqk does a quick mean to apparent place calculation using # the output of palpy.mappa # # Taken from the palpy source code (palMap.c which calls both palMappa and palMapqk): # The accuracy is sub-milliarcsecond, limited by the # precession-nutation model (see palPrenut for details). if include_px: # because PAL and ERFA expect proper motion in terms of "coordinate # angle; not true angle" (as stated in erfa/starpm.c documentation) pm_ra_corrected = pm_ra / np.cos(dec) if are_arrays: if include_px: raOut, decOut = palpy.mapqkVector(ra, dec, pm_ra_corrected, pm_dec, arcsecFromRadians(parallax), v_rad, prms) else: raOut, decOut = palpy.mapqkzVector(ra, dec, prms) else: if include_px: raOut, decOut = palpy.mapqk(ra, dec, pm_ra_corrected, pm_dec, arcsecFromRadians(parallax), v_rad, prms) else: raOut, decOut = palpy.mapqkz(ra, dec, prms) return np.array([raOut, decOut])