def TEME2ECI_pos(Pos_TEME, t):

    T = Time(t, format='jd', scale='utc')

    dist_vect = norm(Pos_TEME, axis=0)
    ra_vect = np.arctan2(Pos_TEME[1], Pos_TEME[0])
    dec_vect = np.arcsin(Pos_TEME[2] / dist_vect)

    Pos_TEME_SC = PrecessedGeocentric(ra=ra_vect * u.rad, 
        dec=dec_vect * u.rad, distance=dist_vect * u.m, equinox=T, obstime=T)
    Pos_ECI_SC = Pos_TEME_SC.transform_to(GCRS(obstime=T))
    Pos_ECI = np.vstack(Pos_ECI_SC.cartesian.xyz.value)

    return Pos_ECI
def test_transforms_diff(sc):
    # note that arguably this *should* fail for the no-distance cases: 3D
    # information is necessary to truly solve this, hence the xfail
    if not sc.distance.unit.is_equivalent(u.m):
        pytest.xfail('Should fail for no-distance cases')
    else:
        trans = sc.transform_to(PrecessedGeocentric(equinox='B1975'))
        assert isinstance(trans.frame, PrecessedGeocentric)
예제 #3
0
def test_precessed_geocentric_different_obstime():
    # Create two PrecessedGeocentric frames with different obstime
    precessedgeo1 = PrecessedGeocentric(obstime='2021-09-07')
    precessedgeo2 = PrecessedGeocentric(obstime='2021-06-07')

    # GCRS->PrecessedGeocentric should give different results for the two frames
    gcrs_coord = GCRS(10 * u.deg,
                      20 * u.deg,
                      3 * u.AU,
                      obstime=precessedgeo1.obstime)
    pg_coord1 = gcrs_coord.transform_to(precessedgeo1)
    pg_coord2 = gcrs_coord.transform_to(precessedgeo2)
    assert not pg_coord1.is_equivalent_frame(pg_coord2)
    assert not allclose(pg_coord1.cartesian.xyz, pg_coord2.cartesian.xyz)

    # Looping back to GCRS should return the original coordinate
    loopback1 = pg_coord1.transform_to(gcrs_coord)
    loopback2 = pg_coord2.transform_to(gcrs_coord)
    assert loopback1.is_equivalent_frame(gcrs_coord)
    assert loopback2.is_equivalent_frame(gcrs_coord)
    assert_allclose(loopback1.cartesian.xyz, gcrs_coord.cartesian.xyz)
    assert_allclose(loopback2.cartesian.xyz, gcrs_coord.cartesian.xyz)
예제 #4
0
def test_precessed_geocentric():
    assert PrecessedGeocentric().equinox.jd == Time('J2000').jd

    gcrs_coo = GCRS(180 * u.deg, 2 * u.deg, distance=10000 * u.km)
    pgeo_coo = gcrs_coo.transform_to(PrecessedGeocentric())
    assert np.abs(gcrs_coo.ra - pgeo_coo.ra) > 10 * u.marcsec
    assert np.abs(gcrs_coo.dec - pgeo_coo.dec) > 10 * u.marcsec
    assert_allclose(gcrs_coo.distance, pgeo_coo.distance)

    gcrs_roundtrip = pgeo_coo.transform_to(GCRS())
    assert_allclose(gcrs_coo.ra, gcrs_roundtrip.ra)
    assert_allclose(gcrs_coo.dec, gcrs_roundtrip.dec)
    assert_allclose(gcrs_coo.distance, gcrs_roundtrip.distance)

    pgeo_coo2 = gcrs_coo.transform_to(PrecessedGeocentric(equinox='B1850'))
    assert np.abs(gcrs_coo.ra - pgeo_coo2.ra) > 1.5 * u.deg
    assert np.abs(gcrs_coo.dec - pgeo_coo2.dec) > 0.5 * u.deg
    assert_allclose(gcrs_coo.distance, pgeo_coo2.distance)

    gcrs2_roundtrip = pgeo_coo2.transform_to(GCRS())
    assert_allclose(gcrs_coo.ra, gcrs2_roundtrip.ra)
    assert_allclose(gcrs_coo.dec, gcrs2_roundtrip.dec)
    assert_allclose(gcrs_coo.distance, gcrs2_roundtrip.distance)
def ECI2TEME_pos(Pos_ECI, t):

    T = Time(t, format='jd', scale='utc')
    precessed_frame = PrecessedGeocentric(equinox=T, obstime=T)

    dist_vect = norm(Pos_ECI, axis=0)
    ra_vect = np.arctan2(Pos_ECI[1], Pos_ECI[0])
    dec_vect = np.arcsin(Pos_ECI[2] / dist_vect)

    Pos_ECI_SC = GCRS(ra=ra_vect * u.rad, dec=dec_vect * u.rad, 
        distance=dist_vect * u.m, obstime=T)
    Pos_TEME_SC = Pos_ECI_SC.transform_to(precessed_frame)
    Pos_TEME = np.vstack(Pos_TEME_SC.cartesian.xyz.value)

    return Pos_TEME
예제 #6
0
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)
예제 #7
0
def get_sun_P(time='now'):
    """
    Return the position (P) angle for the Sun at a specified time, which is the angle between
    geocentric north and solar north as seen from Earth, measured eastward from geocentric north.
    The range of P is +/-26.3 degrees.

    Parameters
    ----------
    time : various
        Time to use as `~astropy.time.Time` or in a parse_time-compatible format

    Returns
    -------
    out : `~astropy.coordinates.Angle`
        The position angle
    """
    obstime = parse_time(time)

    # Define the frame where its Z axis is aligned with geocentric north
    geocentric = PrecessedGeocentric(equinox=obstime, obstime=obstime)

    return _sun_north_angle_to_z(geocentric)
예제 #8
0
def currentgeocentframe(time) : 
# Generate a PrecessedGeocentric frame for the current equinox.
   time_ep = 2000. + (time.jd - thorconsts.J2000) / 365.25
   eq = "J%7.2f" % (time_ep)
#   print eq
   return PrecessedGeocentric(equinox = eq)
예제 #9
0
# -*- coding: utf-8 -*-
"""
Created on Sat Feb  1 16:59:43 2020
https://qiita.com/phyblas/items/a801b0f319742245ad2e
@author: PC
"""

from astropy.coordinates import SkyCoord, PrecessedGeocentric

b1875 = PrecessedGeocentric(equinox='B1875')

b1875_hokkyoku = SkyCoord(ra=0, dec=90, unit='deg', frame=b1875)
print(b1875_hokkyoku)

b1875_hokkyoku_icrs = b1875_hokkyoku.transform_to('icrs')
print(b1875_hokkyoku_icrs)
예제 #10
0
def obj_sight(date,objname,lonstr,latstr,tzinhours,approx=True):
    """
    date: string, date of observing. 
    objname : string, name of sun, moon or planet in solar system.
    lonstr : string, longitute of observing location on earth.
    latstr : string, latitute of observing location on earth.
    ltzinhours : float, time zone in hours of observing location.
    approx : bool, True for delta_ut1_utc=0
    return : print out rise time, set time, transit time and cooresponding alt/az.
    """
    lon=Angle(lonstr)
    lat=Angle(latstr)
    if objname=='sun':
      r_obj=const.R_sun.to('m').value
    else:
      if objname=="moon":
        r_obj=1737000
    #halfdisk=Angle(diskanglestr)*0.5
    date=Time(Time(date,out_subfmt='date').iso)
    times=date+np.linspace(0.,1440.,1441)*TimeDelta(60,format='sec')  # 每分鐘計算位置
    deltat=tzinhours*TimeDelta(3600,format='sec')
    a=const.R_earth.to('m').value       # 地球半徑
    with solar_system_ephemeris.set('jpl'):
        n=len(times)
        gmttimes=times-deltat   # 世界時間 UTC
        # 標的物在真赤道座標系統座標
        bodies=get_body(objname,gmttimes).transform_to(PrecessedGeocentric(equinox=gmttimes)) 
        if approx:
          gmttimes.delta_ut1_utc = 0. 
        sides=gmttimes.sidereal_time('apparent', 'greenwich')+lon    # local sidereal time
        x=bodies.cartesian.x.to('m').value        # x,y,z為標的物在及時赤道座標系統的直角座標   
        y=bodies.cartesian.y.to('m').value
        z=bodies.cartesian.z.to('m').value
        px=np.array(a*np.cos(lat)*np.cos(sides))  # px,py,pz 為觀測地在真赤道座標系統的直角坐標
        py=np.array(a*np.cos(lat)*np.sin(sides))
        pz=np.array(a*np.sin(lat)*np.ones(n))
    positions=np.vstack((px,py,pz)).T  # n x 3 array
    objs=np.vstack((x,y,z)).T          # n x 3 array
    # e_z 的每一行為天頂方向單位向量,e_n的每一行為地表往北單位向量,e_e的每一行為地表往東單位向量
    e_z=np.vstack((np.cos(lat)*np.cos(sides),np.cos(lat)*np.sin(sides),np.sin(lat)*np.ones(n)))  # 3 x n
    e_n=np.vstack((-np.sin(lat)*np.cos(sides),-np.sin(lat)*np.sin(sides),np.cos(lat)*np.ones(n))) # 3 x n
    e_e=np.vstack((-np.sin(sides),np.cos(sides),np.zeros(n)))                 # 3 x n
    coords=np.zeros((n,3))   # coords 的每一列代表標的物在地表座標系統的直角坐標
    az=np.zeros(n)           # az 標的物的方位角,北方為0,往東為正,正東方90度,正南方180度,正西方270度。
    alt=np.zeros(n)          # alt 標的物的仰角
    for i in range(n):
        coords[i]=np.array(np.vstack((e_e[:,i],e_n[:,i],e_z[:,i]))).dot(objs[i]-positions[i])
        r=np.sqrt(coords[i][0]**2+coords[i][1]**2)
        rho=np.sqrt(coords[i][0]**2+coords[i][1]**2+coords[i][2]**2)
        alt[i]=np.arcsin(coords[i][2]/rho)*180/np.pi
        az[i]=np.arctan2(coords[i][0],coords[i][1])*180/np.pi
        if az[i]<0:
            az[i]=az[i]+360
    if objname=="sun" or objname=="moon" :
      halfdisk=np.arcsin(r_obj/rho)*180/np.pi*u.deg
    else :
      halfdisk=0*u.deg
    thresh=-(halfdisk+Angle("0d34m0s")).deg   # 大氣折射,讓光線轉彎了34角分
    altdiff=alt-thresh        # altdif 變號的時候就是標的物升起或沉沒的區間,用內插進行估計
    for i in range(len(times)-1):
        if altdiff[i]*altdiff[i+1] <=0 :
            t=times[i]+(times[i+1]-times[i])*(0-altdiff[i])/(altdiff[i+1]-altdiff[i])
            if altdiff[i]<0:
                print("出",t,"方位",az[i])
            else:
                print("沒",t,"方位",az[i])
        if not (az[i] // 180 == az[i+1] // 180) and alt[i]>0:
            if np.abs(az[i]-180)<30:
                ratio=(180-az[i])/(az[i+1]-az[i])
                t=times[i]+(times[i+1]-times[i])*ratio
                print("中天",t,"仰角",alt[i]+(alt[i+1]-alt[i])*ratio,"方位","南")
            else:
                left=az[i]
                right=az[i+1]
                if left>300:
                    left=left-360
                if right>300:
                    right=right-360
                ratio=(0-left)/(az[i+1]-az[i])
                t=times[i]+(times[i+1]-times[i])*ratio
                print("中天",t,"仰角",alt[i]+(alt[i+1]-alt[i])*ratio,"方位","南")