def test_regression_4926(): times = Time('2010-01-1') + np.arange(20) * u.day green = get_builtin_sites()['greenwich'] # this is the regression test moon = get_moon(times, green) # this is an additional test to make sure the GCRS->ICRS transform works for complex shapes moon.transform_to(ICRS()) # and some others to increase coverage of transforms moon.transform_to(HCRS(obstime="J2000")) moon.transform_to(HCRS(obstime=times))
def test_regression_3920(): """ Issue: https://github.com/astropy/astropy/issues/3920 """ loc = EarthLocation.from_geodetic(0 * u.deg, 0 * u.deg, 0) time = Time('2010-1-1') aa = AltAz(location=loc, obstime=time) sc = SkyCoord(10 * u.deg, 3 * u.deg) assert sc.transform_to(aa).shape == tuple() # That part makes sense: the input is a scalar so the output is too sc2 = SkyCoord(10 * u.deg, 3 * u.deg, 1 * u.AU) assert sc2.transform_to(aa).shape == tuple() # in 3920 that assert fails, because the shape is (1,) # check that the same behavior occurs even if transform is from low-level classes icoo = ICRS(sc.data) icoo2 = ICRS(sc2.data) assert icoo.transform_to(aa).shape == tuple() assert icoo2.transform_to(aa).shape == tuple()
def _wcs_to_celestial_frame_builtin(wcs): # Import astropy.coordinates here to avoid circular imports from astropy.coordinates import FK4, FK4NoETerms, FK5, ICRS, ITRS, Galactic # Import astropy.time here otherwise setup.py fails before extensions are compiled from astropy.time import Time if wcs.wcs.lng == -1 or wcs.wcs.lat == -1: return None radesys = wcs.wcs.radesys if np.isnan(wcs.wcs.equinox): equinox = None else: equinox = wcs.wcs.equinox xcoord = wcs.wcs.ctype[wcs.wcs.lng][:4] ycoord = wcs.wcs.ctype[wcs.wcs.lat][:4] # Apply logic from FITS standard to determine the default radesys if radesys == '' and xcoord == 'RA--' and ycoord == 'DEC-': if equinox is None: radesys = "ICRS" elif equinox < 1984.: radesys = "FK4" else: radesys = "FK5" if radesys == 'FK4': if equinox is not None: equinox = Time(equinox, format='byear') frame = FK4(equinox=equinox) elif radesys == 'FK4-NO-E': if equinox is not None: equinox = Time(equinox, format='byear') frame = FK4NoETerms(equinox=equinox) elif radesys == 'FK5': if equinox is not None: equinox = Time(equinox, format='jyear') frame = FK5(equinox=equinox) elif radesys == 'ICRS': frame = ICRS() else: if xcoord == 'GLON' and ycoord == 'GLAT': frame = Galactic() elif xcoord == 'TLON' and ycoord == 'TLAT': frame = ITRS(obstime=wcs.wcs.dateobs or None) else: frame = None return frame
def test_matching_function_3d_and_sky(): from astropy.coordinates import ICRS from astropy.coordinates.matching import match_coordinates_3d, match_coordinates_sky cmatch = ICRS([4, 2.1] * u.degree, [0, 0] * u.degree, distance=[1, 5] * u.kpc) ccatalog = ICRS([1, 2, 3, 4] * u.degree, [0, 0, 0, 0] * u.degree, distance=[1, 1, 1, 5] * u.kpc) idx, d2d, d3d = match_coordinates_3d(cmatch, ccatalog) npt.assert_array_equal(idx, [2, 3]) assert_allclose(d2d, [1, 1.9] * u.deg) assert np.abs(d3d[0].to_value(u.kpc) - np.radians(1)) < 1e-6 assert np.abs(d3d[1].to_value(u.kpc) - 5 * np.radians(1.9)) < 1e-5 idx, d2d, d3d = match_coordinates_sky(cmatch, ccatalog) npt.assert_array_equal(idx, [3, 1]) assert_allclose(d2d, [0, 0.1] * u.deg) assert_allclose(d3d, [4, 4.0000019] * u.kpc)
def get_body_heliographic_stonyhurst(body, time='now', observer=None): """ Return a `~sunpy.coordinates.frames.HeliographicStonyhurst` frame for the location of a solar-system body at a specified time. The location can be corrected for light travel time to an observer. Parameters ---------- body : `str` The solar-system body for which to calculate positions time : {parse_time_types} Time to use in a parse_time-compatible format observer : `~astropy.coordinates.SkyCoord` If None, the returned coordinate is the instantaneous or "true" location. If not None, the returned coordinate is the astrometric location (i.e., accounts for light travel time to the specified observer) Returns ------- out : `~sunpy.coordinates.frames.HeliographicStonyhurst` Location of the solar-system body in the `~sunpy.coordinates.HeliographicStonyhurst` frame Notes ----- There is no correction for aberration due to observer motion. For a body close to the Sun in angular direction relative to the observer, the correction can be negligible because the apparent location of the body will shift in tandem with the Sun. """ obstime = parse_time(time) if observer is None: body_icrs = get_body_barycentric(body, obstime) else: observer_icrs = SkyCoord(observer).icrs.cartesian # This implementation is modeled after Astropy's `_get_apparent_body_position` light_travel_time = 0.*u.s emitted_time = obstime delta_light_travel_time = 1.*u.s # placeholder value while np.any(np.fabs(delta_light_travel_time) > 1.0e-8*u.s): body_icrs = get_body_barycentric(body, emitted_time) distance = (body_icrs - observer_icrs).norm() delta_light_travel_time = light_travel_time - distance / speed_of_light light_travel_time = distance / speed_of_light emitted_time = obstime - light_travel_time log.info(f"Apparent body location accounts for {light_travel_time.to('s').value:.2f}" " seconds of light travel time") body_hgs = ICRS(body_icrs).transform_to(HGS(obstime=obstime)) return body_hgs
def _wcs_to_celestial_frame_builtin(wcs): from astropy.coordinates import FK4, FK4NoETerms, FK5, ICRS, Galactic from astropy.time import Time from astropy.wcs import WCSSUB_CELESTIAL # Keep only the celestial part of the axes wcs = wcs.sub([WCSSUB_CELESTIAL]) if wcs.wcs.lng == -1 or wcs.wcs.lat == -1: return None radesys = wcs.wcs.radesys if np.isnan(wcs.wcs.equinox): equinox = None else: equinox = wcs.wcs.equinox xcoord = wcs.wcs.ctype[0][:4] ycoord = wcs.wcs.ctype[1][:4] # Apply logic from FITS standard to determine the default radesys if radesys == '' and xcoord == 'RA--' and ycoord == 'DEC-': if equinox is None: radesys = "ICRS" elif equinox < 1984.: radesys = "FK4" else: radesys = "FK5" if radesys == 'FK4': if equinox is not None: equinox = Time(equinox, format='byear') frame = FK4(equinox=equinox) elif radesys == 'FK4-NO-E': if equinox is not None: equinox = Time(equinox, format='byear') frame = FK4NoETerms(equinox=equinox) elif radesys == 'FK5': if equinox is not None: equinox = Time(equinox, format='jyear') frame = FK5(equinox=equinox) elif radesys == 'ICRS': frame = ICRS() else: if xcoord == 'GLON' and ycoord == 'GLAT': frame = Galactic() else: frame = None return frame
def do(self): """Inspect files!""" search = self.get_keywords() files = self.get_files() print("Searching {:d} files".format(len(files))) data = FITSHeaderTable.fromfiles(files).normalize(search.keys()).search(**search) print("Fixing {:d} files".format(len(data.files))) self.log.info("Command: {:s} {:s}".format(sys.argv[0],self.command)) self.log.info("Fixing {:d} of {:d} files.".format(len(data.files), len(files))) self.locations = {} self.files = collections.defaultdict(list) self.updated = collections.Counter() exceptions = 0 for header in data: try: location = header["OBJECT"] coords = ICRS(header["RA"], header["DEC"], unit=(u.deg, u.deg)) except Exception as e: self.log.exception(e) exceptions += 1 if exceptions > 10: raise continue if len(self.locations): if self.check_for_collision(coords, location): location = self.handle_collision(header.filename, location, coords) if location in self.locations: location = self.handle_match(header.filename, location, coords) self.locations[location] = coords self.files[location] += [header.filename] for location in self.files: for filename in self.files[location]: with fits.open(filename, mode='update', ignore_missing_end=True) as HDUs: if HDUs[0].header.get("OBJECT") != location: old_location = HDUs[0].header.get("OBJECT") print("Fixing header for '{}'".format(filename)) print("{} -> {}".format(old_location, location)) HDUs[0].header["OBJECT"] = (location, "MODIFIED") HDUs[0].header["HISTORY"] = "OLD OBJECT {}".format(old_location) HDUs[0].header["HISTORY"] = "OBJECT changed {} -> {}".format(old_location, location) HDUs.flush(output_verify='fix') self.updated[location] += 1 print("Updated {} OBJECT keywords for {} locations.".format(sum(self.updated.values()), len(self.updated)))
async def mtptg_telemetry(self) -> None: while self.run_telemetry_loop: if (self.controllers.mtptg.evt_summaryState.data.summaryState == salobj.State.ENABLED): now = Time.now() await self.controllers.mtptg.tel_timeAndDate.set_write( timestamp=now.unix_tai, utc=now.utc.mjd, lst=now.sidereal_time("mean", self.location.lon).value, ) if self.tracking: radec_icrs = ICRS( Angle( self.controllers.mtptg.evt_currentTarget.data.ra, unit=u.radian, ), Angle( self.controllers.mtptg.evt_currentTarget.data. declination, unit=u.radian, ), ) coord_frame_altaz = AltAz(location=self.location, obstime=now) alt_az = radec_icrs.transform_to(coord_frame_altaz) await self.controllers.mtptg.evt_currentTarget.set_write( timestamp=now.tai.mjd, azDegs=alt_az.az.deg, elDegs=alt_az.alt.deg, ) self.controllers.mtmount.tel_azimuth.set( **{self.mtmount_demand_position_name: alt_az.az.deg}) self.controllers.mtmount.tel_elevation.set( **{self.mtmount_demand_position_name: alt_az.alt.deg}) self.controllers.mtrotator.tel_rotation.set( demandPosition=self.controllers.mtptg. evt_currentTarget.data.rotPA) self.controllers.mtmount.evt_target.set( elevation=alt_az.alt.deg, azimuth=alt_az.az.deg, ) await asyncio.sleep(HEARTBEAT_INTERVAL)
def sdss_IAU_id_to_ra_dec(sdssids, matchtocatalog=None): """ Converts IAU SDSS identifiers (e.g.,"J151503.37+421253.9") to their RA/Decs Returns an ICRS object if `matchtocatalog` is None, otherwise `catalogidx, skysep` """ import re from astropy.coordinates import ICRS, Latitude, Longitude rex = re.compile(r'J(\d{2})(\d{2})(\d{2}(?:\.\d{1,2})?)' r'([+-])(\d{2})(\d{2})(\d{2}(?:\.\d)?)') if isinstance(sdssids, six.string_types): sdssids = [sdssids] ras = [] decs = [] for idi in sdssids: res = rex.match(idi) if res is None: raise ValueError('Could not match ' + idi) res = res.groups() rah, ram, rasc = res[:3] desgn, ded, dem, des = res[-4:] ras.append(':'.join((rah, ram, rasc))) decs.append(desgn + ':'.join((ded, dem, des))) coords = ICRS(ra=Longitude(ras, u.hourangle), dec=Latitude(decs, u.degree)) if matchtocatalog: if not hasattr(matchtocatalog, 'match_to_catalog_sky'): matchtocatalog = ICRS(ra=np.array(matchtocatalog['ra']) * u.deg, dec=np.array(matchtocatalog['dec']) * u.deg) idx, sep, sep3d = coords.match_to_catalog_sky(matchtocatalog) return idx, sep.to(u.arcsec) else: return coords
def reg2moc(region, moc_field, wcs, moc_order=15): """ Transform a the intersection of moc_field with a Region object into a MOC. """ list_cells = np.array([c for c in moc_field.flattened()]) hp = HEALPix(nside=2**moc_order, order='nested', frame=ICRS()) cells_skycoords = hp.healpix_to_skycoord(list_cells) mask = region.contains(cells_skycoords, wcs) region_moc = MOC(moc_order, list_cells[mask]) return region_moc
def from_body_ephem(cls, body, epoch=None): """Return osculating `Orbit` of a body at a given time. """ # TODO: https://github.com/poliastro/poliastro/issues/445 if not epoch: epoch = time.Time.now().tdb elif epoch.scale != "tdb": epoch = epoch.tdb warn( "Input time was converted to scale='tdb' with value " "{}. Use Time(..., scale='tdb') instead.".format( epoch.tdb.value), TimeScaleWarning, ) r, v = get_body_barycentric_posvel(body.name, epoch) if body == Moon: # TODO: The attractor is in fact the Earth-Moon Barycenter icrs_cart = r.with_differentials( v.represent_as(CartesianDifferential)) gcrs_cart = (ICRS(icrs_cart).transform_to( GCRS(obstime=epoch)).represent_as(CartesianRepresentation)) ss = cls.from_vectors( Earth, gcrs_cart.xyz.to(u.km), gcrs_cart.differentials["s"].d_xyz.to(u.km / u.day), epoch, ) else: # TODO: The attractor is not really the Sun, but the Solar System # Barycenter ss = cls.from_vectors(Sun, r.xyz.to(u.km), v.xyz.to(u.km / u.day), epoch) ss._frame = ICRS() # Hack! return ss
def __init__(self, *args, **kwargs): # based on Luri et al 2020 including "main" line in table 5 default_params = { 'gal_coord': ICRS(ra=81.28 * u.degree, dec=-69.78 * u.degree), "gal_distance": 49.5 * u.kpc, "galvel_heliocentric": r.CartesianDifferential([439.0, 91.7, 262.2] * (u.km / u.s)), "inclination": 34.08 * u.degree, "PA": 309.9 * u.degree, } kwds = dict() kwds.update(default_params) kwds.update(kwargs) super().__init__(*args, **kwds)
def __init__(self, *args, **kwargs): # these values for comparison with vdm12 transformation - not necessarily current default_params = { 'gal_coord': ICRS(ra=10.68470833 * u.degree, dec=41.26875 * u.degree), "gal_distance": 770.0 * u.kpc, "galvel_heliocentric": r.CartesianDifferential([178.9, -138.8, -301.] * (u.km / u.s)), "inclination": (-77.) * u.degree, "PA": 37. * u.degree, } kwds = dict() kwds.update(default_params) kwds.update(kwargs) super().__init__(*args, **kwds)
def vec2pix(l, b): if galactic: f = ICRS(l * u.rad, b * u.rad) g = f.transform_to(Galactic) l, b = g.l.rad, g.b.rad theta = np.pi / 2 - b phi = l if interp: return get_interp_val(data, theta, phi, nest=nest) return data[ang2pix(nside, theta, phi, nest=nest)]
def writeDS9reg(catalog, regfile, color='green', shape='diamond', linewidth=1): """ Write out a DS9 region file from the given catalog catalog may be a file name or an astropy table object. """ from astropy.coordinates import ICRS from astropy import units as u from astropy.io import ascii if isinstance(catalog, str): catalog = ascii.read(catalog) fout = open(regfile, 'w') print("# Region file format: DS9 version 5.4", file=fout) print( 'global color=%s font="times 16 bold" select=1 edit=1 move=0 delete=1 include=1 fixed=0 width=%i' % (color, linewidth), file=fout) for row in catalog: RA = row['RA'] DEC = row['DEC'] if ':' in str(RA): coord = ICRS(ra=RA, dec=DEC, unit=(u.hour, u.degree)) else: coord = ICRS(ra=RA, dec=DEC, unit=(u.degree, u.degree)) xstr = coord.ra.to_string(unit=u.hour, decimal=False, pad=True, sep=':', precision=2) ystr = coord.dec.to_string(unit=u.degree, decimal=False, pad=True, alwayssign=True, sep=':', precision=1) print('point %s %s # point=%s' % (xstr, ystr, shape), file=fout) fout.close()
def test_icrs_gcrs(icoo): """ Check ICRS<->GCRS for consistency """ gcrscoo = icoo.transform_to(gcrs_frames[0]) # uses the default time # first do a round-tripping test icoo2 = gcrscoo.transform_to(ICRS()) assert_allclose(icoo.distance, icoo2.distance) assert_allclose(icoo.ra, icoo2.ra) assert_allclose(icoo.dec, icoo2.dec) assert isinstance(icoo2.data, icoo.data.__class__) # now check that a different time yields different answers gcrscoo2 = icoo.transform_to(gcrs_frames[1]) assert not allclose(gcrscoo.ra, gcrscoo2.ra, rtol=1e-8, atol=1e-10*u.deg) assert not allclose(gcrscoo.dec, gcrscoo2.dec, rtol=1e-8, atol=1e-10*u.deg) # now check that the cirs self-transform works as expected gcrscoo3 = gcrscoo.transform_to(gcrs_frames[0]) # should be a no-op assert_allclose(gcrscoo.ra, gcrscoo3.ra) assert_allclose(gcrscoo.dec, gcrscoo3.dec) gcrscoo4 = gcrscoo.transform_to(gcrs_frames[1]) # should be different assert not allclose(gcrscoo4.ra, gcrscoo.ra, rtol=1e-8, atol=1e-10*u.deg) assert not allclose(gcrscoo4.dec, gcrscoo.dec, rtol=1e-8, atol=1e-10*u.deg) gcrscoo5 = gcrscoo4.transform_to(gcrs_frames[0]) # should be back to the same assert_allclose(gcrscoo.ra, gcrscoo5.ra, rtol=1e-8, atol=1e-10*u.deg) assert_allclose(gcrscoo.dec, gcrscoo5.dec, rtol=1e-8, atol=1e-10*u.deg) # also make sure that a GCRS with a different geoloc/geovel gets a different answer # roughly a moon-like frame gframe3 = GCRS(obsgeoloc=[385000., 0, 0]*u.km, obsgeovel=[1, 0, 0]*u.km/u.s) gcrscoo6 = icoo.transform_to(gframe3) # should be different assert not allclose(gcrscoo.ra, gcrscoo6.ra, rtol=1e-8, atol=1e-10*u.deg) assert not allclose(gcrscoo.dec, gcrscoo6.dec, rtol=1e-8, atol=1e-10*u.deg) icooviag3 = gcrscoo6.transform_to(ICRS()) # and now back to the original assert_allclose(icoo.ra, icooviag3.ra) assert_allclose(icoo.dec, icooviag3.dec)
def grouping_ICRS(df, group_select, ra_dec_region=None): """ Puts data sample into ICRS equitorial frame based on chosen stellar group Parameters ---------- df : pd.DataFrame Complete sample of data group_select : list List of group label numbers to include for analysis Returns ------- ICRS ICRS coordinate frame """ df_group = df[df['label'].isin(group_select)] df_group = with_rv_only(df_group) if ra_dec_region != None: ra_select = ra_dec_region[0] dec_select = ra_dec_region[1] df_group = df_group.loc[(df_group.ra > ra_select[0]) & (df_group.ra < ra_select[1]) & (df_group.dec > dec_select[0]) & (df_group.dec < dec_select[1])] rv_apogee = (df_group.vhelio.dropna()).values x_apogee = df_group.loc[df_group.vhelio.notnull()].ra.values y_apogee = df_group.loc[df_group.vhelio.notnull()].dec.values dx_apogee = df_group.loc[df_group.vhelio.notnull()].pmra.values dy_apogee = df_group.loc[df_group.vhelio.notnull()].pmdec.values z_apogee = 1000 / df_group.loc[df_group.vhelio.notnull()].parallax.values rv_gaia = (df_group.radial_velocity.dropna()).values x_gaia = df_group.loc[df_group.radial_velocity.notnull()].ra.values y_gaia = df_group.loc[df_group.radial_velocity.notnull()].dec.values dx_gaia = df_group.loc[df_group.radial_velocity.notnull()].pmra.values dy_gaia = df_group.loc[df_group.radial_velocity.notnull()].pmdec.values z_gaia = 1000 / df_group.loc[ df_group.radial_velocity.notnull()].parallax.values rv = np.concatenate((rv_apogee, rv_gaia)) x = np.concatenate((x_apogee, x_gaia)) y = np.concatenate((y_apogee, y_gaia)) z = np.concatenate((z_apogee, z_gaia)) dx = np.concatenate((dx_apogee, dx_gaia)) dy = np.concatenate((dy_apogee, dy_gaia)) return ICRS(ra=x * u.deg, dec=y * u.deg, distance=z * u.parsec, pm_ra_cosdec=dx * (u.mas / u.yr), pm_dec=dy * (u.mas / u.yr), radial_velocity=rv * (u.km / u.s))
def boundingbox_params(): """ Create possible bounding box input coordinates and args for inputs to the bounding box tests. """ bottom_left_icrs = SkyCoord(ICRS(ra=1 * u.deg, dec=2 * u.deg, distance=150000000 * u.km), obstime='2021-01-02T12:34:56') top_right_icrs = SkyCoord(ICRS(ra=3 * u.deg, dec=4 * u.deg, distance=150000000 * u.km), obstime='2021-01-02T12:34:56') bottom_left_vector_icrs = SkyCoord([ ICRS(ra=1 * u.deg, dec=2 * u.deg, distance=150000000 * u.km), ICRS(ra=3 * u.deg, dec=4 * u.deg, distance=150000000 * u.km) ], obstime='2021-01-02T12:34:56') bottom_left = SkyCoord(1 * u.deg, 1 * u.deg, frame='heliographic_stonyhurst', obstime='2021-01-02T12:34:56') top_right = SkyCoord(2 * u.deg, 2 * u.deg, frame='heliographic_stonyhurst', obstime='2021-01-02T12:34:56') width = 3.4 * u.deg height = 1.2 * u.deg yield { # bottom_left, top_right, width, height "bottom left vector icrs": [bottom_left_vector_icrs, None, None, None], "bottom left top right icrs": [bottom_left_icrs, top_right_icrs, None, None], "bottom left top right": [bottom_left, top_right, None, None], "bottom left width height": [bottom_left, None, width, height], }
def match_TGSS_catalogue(TGSS_cat, MSSS_cat, mosaic_name, inverse_match=False): if inverse_match == False: c_tgss = ICRS(ra=Angle(TGSS_cat['RA'], unit=u.deg), dec=Angle(TGSS_cat['DEC'], unit=u.deg)) c_msss = ICRS(ra=Angle(MSSS_cat['RA'], unit=u.deg), dec=Angle(MSSS_cat['DEC'], unit=u.deg)) idx, d2d, d3d = match_coordinates_sky( c_msss, c_tgss) #matches. idx in second one matching first. tbdata = hstack( [Table(MSSS_cat), Table(TGSS_cat[idx])], join_type='exact') #join tables together return tbdata if inverse_match == True: #crossmatch TGSS to MSSS, so first grab only small TGSS area pos = (int(mosaic_name[1:4]), int(mosaic_name[5:7])) service = vo.dal.SCSService( "http://vo.astron.nl/tgssadr/q/cone/scs.xml?") print( 'querying TGSS catalogue through PYVO around {0} ...'.format(pos)) resultset = service.search(pos=pos, radius=5, verbosity=0) TGSS_cat = resultset.table #Convert TGSS units to arcseconds and keep column names consistent to MSSS, because PYVO query has different column names to downlodable catalogue from website. TGSS_cat['e_DEC'] /= 3600 TGSS_cat['e_RA'] /= 3600 TGSS_cat['e_RA'].name = 'E_RA' TGSS_cat['e_DEC'].name = 'E_DEC' #TGSS_cat['RA']+=0.5 #offset to test scatter for forced no matches #prep data for crossmatching c_tgss = ICRS(ra=Angle(TGSS_cat['RA'], unit=u.deg), dec=Angle(TGSS_cat['DEC'], unit=u.deg)) c_msss = ICRS(ra=Angle(MSSS_cat['RA'], unit=u.deg), dec=Angle(MSSS_cat['DEC'], unit=u.deg)) idx, d2d, d3d = match_coordinates_sky( c_tgss, c_msss) #find closest MSSS source for each TGSS source. tbdata = hstack( [Table(TGSS_cat), Table(MSSS_cat[idx])], join_type='exact') #join tables together. return tbdata
def match(cat, other_cat, ra1, dec1, ra2, dec2, dist='0d0m1s'): #ra2, dec2 correspond to cat ''' Finds the entries in a catalog cat with corresponsing ra2 and dec2 that match with a list or coordinates (ra1,dec1) ''' ra1, ra2, dec1, dec2 = Angle(ra1), Angle(ra2), Angle(dec1), Angle(dec2) c = ICRS(ra=ra2, dec=dec2) catalog = ICRS(ra=ra1, dec=dec1) idx, d2d, d3d = match_coordinates_sky( c, catalog, nthneighbor=1 ) #idx are indices into catalog that are the closest objects to each of the coordinates in c second_match_idx = are_within_bounds(idx, d2d, '0d0m0s', dist) other_idx, other_d2d, other_d3d = match_coordinates_sky(catalog, c, nthneighbor=1) other_second_match_idx = are_within_bounds(other_idx, other_d2d, '0d0m0s', dist) match_ID = [i for j, i in enumerate(cat[0]) if j in second_match_idx] try: match_2mass_ID = [ i for j, i in enumerate(cat[3]) if j in second_match_idx ] except IndexError: match_2mass_ID = [] match_Ra = [i for j, i in enumerate(cat[1]) if j in second_match_idx] match_Dec = [i for j, i in enumerate(cat[2]) if j in second_match_idx] other_match_ID = [ i for j, i in enumerate(other_cat[0]) if j in other_second_match_idx ] return second_match_idx, match_ID, match_Ra, match_Dec, str( len(second_match_idx)), other_match_ID, match_2mass_ID
def test_get_skycoord(): m31 = SkyCoord(10.6847083 * u.deg, 41.26875 * u.deg) m31_with_distance = SkyCoord(10.6847083 * u.deg, 41.26875 * u.deg, 780 * u.kpc) subaru = Observer.at_site('subaru') time = Time("2016-01-22 12:00") pos, vel = subaru.location.get_gcrs_posvel(time) gcrs_frame = GCRS(obstime=Time("2016-01-22 12:00"), obsgeoloc=pos, obsgeovel=vel) m31_gcrs = m31.transform_to(gcrs_frame) m31_gcrs_with_distance = m31_with_distance.transform_to(gcrs_frame) coo = get_skycoord(m31) assert coo.is_equivalent_frame(ICRS()) with pytest.raises(TypeError) as exc_info: len(coo) coo = get_skycoord([m31]) assert coo.is_equivalent_frame(ICRS()) assert len(coo) == 1 coo = get_skycoord([m31, m31_gcrs]) assert coo.is_equivalent_frame(ICRS()) assert len(coo) == 2 coo = get_skycoord([m31_with_distance, m31_gcrs_with_distance]) assert coo.is_equivalent_frame(ICRS()) assert len(coo) == 2 coo = get_skycoord( [m31, m31_gcrs, m31_gcrs_with_distance, m31_with_distance]) assert coo.is_equivalent_frame(ICRS()) assert len(coo) == 4 coo = get_skycoord([m31_gcrs, m31_gcrs_with_distance]) assert coo.is_equivalent_frame(m31_gcrs.frame) assert len(coo) == 2
def test_precessedgeocentric_loopback(): from_coo = PrecessedGeocentric(1 * u.deg, 2 * u.deg, 3 * u.AU, obstime='2001-01-01', equinox='2001-01-01') # Change just the obstime to_frame = PrecessedGeocentric(obstime='2001-06-30', equinox='2001-01-01') explicit_coo = from_coo.transform_to(ICRS()).transform_to(to_frame) implicit_coo = from_coo.transform_to(to_frame) # Confirm that the explicit transformation changes the coordinate assert not allclose(explicit_coo.ra, from_coo.ra, rtol=1e-10) assert not allclose(explicit_coo.dec, from_coo.dec, rtol=1e-10) assert not allclose(explicit_coo.distance, from_coo.distance, rtol=1e-10) # Confirm that the loopback matches the explicit transformation assert_allclose(explicit_coo.ra, implicit_coo.ra, rtol=1e-10) assert_allclose(explicit_coo.dec, implicit_coo.dec, rtol=1e-10) assert_allclose(explicit_coo.distance, implicit_coo.distance, rtol=1e-10) # Change just the equinox to_frame = PrecessedGeocentric(obstime='2001-01-01', equinox='2001-06-30') explicit_coo = from_coo.transform_to(ICRS()).transform_to(to_frame) implicit_coo = from_coo.transform_to(to_frame) # Confirm that the explicit transformation changes the direction but not the distance assert not allclose(explicit_coo.ra, from_coo.ra, rtol=1e-10) assert not allclose(explicit_coo.dec, from_coo.dec, rtol=1e-10) assert allclose(explicit_coo.distance, from_coo.distance, rtol=1e-10) # Confirm that the loopback matches the explicit transformation assert_allclose(explicit_coo.ra, implicit_coo.ra, rtol=1e-10) assert_allclose(explicit_coo.dec, implicit_coo.dec, rtol=1e-10) assert_allclose(explicit_coo.distance, implicit_coo.distance, rtol=1e-10)
def azel2radec(az_deg, el_deg, lat_deg, lon_deg, t): if Time is None: raise ImportError('You need to install AstroPy') t = str2dt(t) obs = EarthLocation(lat=lat_deg * u.deg, lon=lon_deg * u.deg) direc = AltAz(location=obs, obstime=Time(t), az=az_deg * u.deg, alt=el_deg * u.deg) sky = SkyCoord(direc.transform_to(ICRS())) return sky.ra.deg, sky.dec.deg
def __init__(self, *args, **kwargs): # these values for comparison with vdm12 transformation - not necessarily current default_params = { 'gal_coord': ICRS(ra=23.4621 * u.degree, dec=30.65994167 * u.degree), "gal_distance": 794.0 * u.kpc, # "gal_distance": 810.0 * u.kpc, "galvel_heliocentric": r.CartesianDifferential([87.3, 28.2, -180.] * (u.km / u.s)), "inclination": (-55.) * u.degree, "PA": 23. * u.degree, } kwds = dict() kwds.update(default_params) kwds.update(kwargs) super().__init__(*args, **kwds)
def vec2pix(lon, lat): gal = ICRS(lon * u.rad, lat * u.rad).transform_to(Galactic) lon, lat = gal.l.rad, gal.b.rad lon = (lon + np.pi) % (2 * np.pi) - np.pi # ensure in range [-pi, pi] ix = (lon0 - lon) * dx ix = np.round(ix).astype(int) ix = np.clip(ix, 0, nx - 1) iy = (lat0 - lat) * dy # *assume* in range [-pi/2, pi/2] iy = np.round(iy).astype(int) iy = np.clip(iy, 0, ny - 1) return data[iy, ix]
def vec2pix(lon, lat): ecl = ICRS(lon * u.rad, lat * u.rad).transform_to(Ecliptic) lon, lat = ecl.lon.rad, ecl.lat.rad lon = lon % (2 * np.pi) - np.pi # ensure in range [-pi, pi] ix = (lon0 - lon) * dx ix = np.round(ix).astype(int) ix = np.clip(ix, 0, nx - 1) iy = (lat0 - lat) * dy # *assume* in range [-pi/2, pi/2] iy = np.round(iy).astype(int) iy = np.clip(iy, 0, ny - 1) return data[iy, ix]
def radec_from_pointing_object( pointing, # default output in degrees as_radians=False, as_string=False): """Astropy object to ICRS format as strings""" pnt_radec = pointing.transform_to(ICRS()) if as_string: ra_hms, dec_dms = radec_to_string(pnt_radec.ra, pnt_radec.dec) return ra_hms, dec_dms elif as_radians: return pnt_radec.ra.rad, pnt_radec.dec.rad else: return pnt_radec.ra.deg, pnt_radec.dec.deg
def rf_cartesian(input_coord_sys, average_velocity=None): """ Convert to reference frame of stellar group after subtraction of LSR (U,V,W) = (11.1,12.24,7.25) kms^-1 defined in Schönrich et al. (2010) and leave it in cartesian coordinates. Parameters ---------- input_coord_sys : ICRS ICRS input of group for analysis average_velocity : tuple average cartesian velocity to be subtracted if known, else computes it here Returns ------- ICRS ICRS frame """ galactic = input_coord_sys.transform_to( GalacticLSR) # This conversion implicitly subtracts off the LSR galactic.representation_type = 'cartesian' galactic.differential_type = 'cartesian' x_new = galactic.cartesian.x y_new = galactic.cartesian.y z_new = galactic.cartesian.z if average_velocity == None: dx_median = np.median(galactic.velocity.d_x.value) dy_median = np.median(galactic.velocity.d_y.value) dz_median = np.median(galactic.velocity.d_z.value) print( 'median(dx) = {} km/s, median(dy) = {} km/s, median(dz) = {} km/s'. format(dx_median, dy_median, dz_median)) else: dx_median = average_velocity[0] dy_median = average_velocity[1] dz_median = average_velocity[2] dx_new = (galactic.velocity.d_x.value - dx_median) * (u.km / u.s) dy_new = (galactic.velocity.d_y.value - dy_median) * (u.km / u.s) dz_new = (galactic.velocity.d_z.value - dz_median) * (u.km / u.s) cartesian_representation = ICRS( x_new, y_new, z_new, dx_new, dy_new, dz_new, representation_type=CartesianRepresentation, differential_type=CartesianDifferential) return cartesian_representation
def correct_rgc(coord, glx_ctr=ICRS('00h42m44.33s +41d16m07.5s'), glx_PA=Angle('37d42m54s'), glx_incl=Angle('77.5d'), glx_dist=Distance(785, unit=u.kpc)): """Computes deprojected galactocentric distance. Inspired by: http://idl-moustakas.googlecode.com/svn-history/ r560/trunk/impro/hiiregions/im_hiiregion_deproject.pro Parameters ---------- coord : :class:`astropy.coordinates.ICRS` Coordinate of points to compute galactocentric distance for. Can be either a single coordinate, or array of coordinates. glx_ctr : :class:`astropy.coordinates.ICRS` Galaxy center. glx_PA : :class:`astropy.coordinates.Angle` Position angle of galaxy disk. glx_incl : :class:`astropy.coordinates.Angle` Inclination angle of the galaxy disk. glx_dist : :class:`astropy.coordinates.Distance` Distance to galaxy. Returns ------- obj_dist : class:`astropy.coordinates.Distance` Galactocentric distance(s) for coordinate point(s). """ # distance from coord to glx centre sky_radius = glx_ctr.separation(coord) avg_dec = 0.5 * (glx_ctr.dec + coord.dec).radian x = (glx_ctr.ra - coord.ra) * np.cos(avg_dec) y = glx_ctr.dec - coord.dec # azimuthal angle from coord to glx -- not completely happy with this phi = glx_PA - Angle('90d') \ + Angle(np.arctan(y.arcsec / x.arcsec), unit=u.rad) # convert to coordinates in rotated frame, where y-axis is galaxy major # ax; have to convert to arcmin b/c can't do sqrt(x^2+y^2) when x and y # are angles xp = (sky_radius * np.cos(phi.radian)).arcmin yp = (sky_radius * np.sin(phi.radian)).arcmin # de-project ypp = yp / np.cos(glx_incl.radian) obj_radius = np.sqrt(xp**2 + ypp**2) # in arcmin obj_dist = Distance(Angle(obj_radius, unit=u.arcmin).radian * glx_dist, unit=glx_dist.unit) return obj_dist
def test_icrs_altaz_moonish(testframe): """ Check that something expressed in *ICRS* as being moon-like goes to the right AltAz distance """ # we use epv00 instead of get_sun because get_sun includes aberration earth_pv_helio, earth_pv_bary = erfa.epv00(*get_jd12(testframe.obstime, 'tdb')) earth_icrs_xyz = earth_pv_bary[0]*u.au moonoffset = [0, 0, MOONDIST.value]*MOONDIST.unit moonish_icrs = ICRS(CartesianRepresentation(earth_icrs_xyz + moonoffset)) moonaa = moonish_icrs.transform_to(testframe) # now check that the distance change is similar to earth radius assert 1000*u.km < np.abs(moonaa.distance - MOONDIST).to(u.au) < 7000*u.km