Пример #1
0
def cassini_surfintercerpt(utc, output=False):
    target = 'TITAN'
    fixref = 'IAU_TITAN'
    dref = 'IAU_TITAN'
    method = 'ELLIPSOID'
    abcorr = 'NONE'
    obsrvr = 'CASSINI'
    state = cassini_phase(utc)
    dvec = spice.vhat(-state[:3])

    et = spice.str2et(utc)

    [point, trgepc, srfvec] = spice.sincpt(method, target, et, fixref, abcorr,
                                           obsrvr, dref, dvec)
    temp = spice.reclat(point)

    radius = temp[0]
    colat = 90 + spice.convrt(temp[1], "RADIANS", "DEGREES")
    lon = np.mod(spice.convrt(temp[2], "RADIANS", "DEGREES"), 360)

    if output:
        print("Distance to Intercept Point", spice.vnorm(srfvec))
        print("Radius", radius)
        print("Colatitude", colat)
        print("Longtitude", lon)

    return point, [radius, colat, lon], spice.vnorm(srfvec)
Пример #2
0
def convertAst(a):

    pos1 = sp.convrt(a[0], 'KM', 'AU')
    pos2 = sp.convrt(a[1], 'KM', 'AU')
    pos3 = sp.convrt(a[2], 'KM', 'AU')
    vel1 = a[3] * (86400 / 149597870.700)
    vel2 = a[4] * (86400 / 149597870.700)
    vel3 = a[5] * (86400 / 149597870.700)
    return np.array([pos1, pos2, pos3, vel1, vel2, vel3])
Пример #3
0
def search_stars(obsinfo, mag_limit=7.0):
    query = ("SELECT"
             " CATALOG_NUMBER,RA,DEC,VISUAL_MAGNITUDE,PARLAX,SPECTRAL_TYPE"
             " FROM HIPPARCOS")
    nmrows, _error, _errmsg = spice.ekfind(query)
    stars = []
    for row in range(nmrows):
        ra = spice.ekgd(1, row, 0)[0] * spice.rpd()
        dec = spice.ekgd(2, row, 0)[0] * spice.rpd()
        mag = spice.ekgd(3, row, 0)[0]
        vec = spice.radrec(1.0, ra, dec)
        tvec = spice.mxv(obsinfo.ref2obsmtx, vec)
        _tpa, tdist = vec_padist(obsinfo.center, tvec)
        if tdist < obsinfo.fov.fovmax and mag < mag_limit:
            parallax = spice.ekgd(4, row, 0)[0]
            spectral = spice.ekgc(5, row, 0)[0]
            distance = 1.0 / np.tan(parallax * spice.rpd())
            distance = spice.convrt(distance, "AU", "km")
            pos = tvec * distance
            vp = viewport_frustum(obsinfo.fov.bounds_rect, obsinfo.width,
                                  obsinfo.height, pos)
            star = {
                "hip_id": spice.ekgi(0, row, 0)[0],
                "position": tvec,
                "ra": ra,
                "dec": dec,
                "spectral_type": spectral,
                "visual_magnitude": mag,
                "distance": distance,
                "image_pos": vp[0:2],
                "color": get_star_color(spectral),
            }
            stars.append(star)
    return stars
if __name__ == "__main__":
    # Script expects first argument to be a UTC timestamp
    if len(sys.argv) > 1:
        input_utc = sys.argv[1]
    else:
        input_utc = '2016-01-12T22:35:07.584'  # default for testing
    # Load the necessary data files
    sp.furnsh(KERNELS)
    # Convert input time to ephemeris time
    epoch = sp.str2et(input_utc)
    # State (position and velocity in cartesian coordinates)
    # of Kepler (-227) as seen from EARTH in the J2000 coordinate frame.
    state, lt, = sp.spkezr("-227", epoch, "J2000", "NONE", "EARTH")
    # Show the output
    print("Input time = {}".format(input_utc))
    print("")
    print("# Position of Kepler in the geocentric J2000 frame")
    print("X = {:.8f} AU".format(sp.convrt(state[0], 'km', 'AU')))
    print("Y = {:.8f} AU".format(sp.convrt(state[1], 'km', 'AU')))
    print("Z = {:.8f} AU".format(sp.convrt(state[2], 'km', 'AU')))
    print("")
    print("# Velocity of Kepler in the geocentric J2000 frame")
    print("dX = {:.8f} AU/s".format(sp.convrt(state[3], 'km', 'AU')))
    print("dY = {:.8f} AU/s".format(sp.convrt(state[4], 'km', 'AU')))
    print("dZ = {:.8f} AU/s".format(sp.convrt(state[5], 'km', 'AU')))
    # As a sanity check, print the speed
    speed = (state[3]**2 + state[4]**2 + state[5]**2)**.5
    print("")
    print("# Orbital speed [sqrt(dX^2 + dY^2 + dZ^2)]")
    print("Speed = {:.8f} AU/s".format(sp.convrt(speed, 'km', 'AU')))
# from the Sun
STATE_VEC_JUPITER, _ = spiceypy.spkgeo(targ=5, \
                                       et=SAMPLE_ET, \
                                       ref='ECLIPJ2000', \
                                       obs=10)

# Get the G*M value of the Sun
_, GM_SUN = spiceypy.bodvcd(bodyid=10, item='GM', maxn=1)
GM_SUN = GM_SUN[0]

# Compute the orbital elements of Jupiter ...
ORB_ELEM_JUPITER = spiceypy.oscltx(STATE_VEC_JUPITER, SAMPLE_ET, GM_SUN)

# ... extract the semi-major axis and convert it from km to AU
A_JUPITER_KM = ORB_ELEM_JUPITER[-2]
A_JUPITER_AU = spiceypy.convrt(A_JUPITER_KM, 'km', 'AU')

#%%

# Set the inclination range (however, only from 0 to 90 degrees) and convert
# the degrees values to radians
INCL_RANGE_DEG = np.linspace(0, 90, 100)
INCL_RANGE_RAD = np.radians(INCL_RANGE_DEG)

# Set an array for the eccentricity
E_RANGE = np.linspace(0, 1, 100)

# Tisserand parameter w.r.t. to Jupiter as a lambda function (a is the
# semi-major axis, i is the inclination and e is the eccentricty of the
# object)
tisserand_jup = lambda a, i, e: (A_JUPITER_AU / a) \
def main():

    # **Load necessary kernels from metafile**

    f_manage_kernels(
        r"E:\Data Science Projects\Space Science\SpaceScience-P2-SSBandSunWobbling\references\SPICE_kernels_metafile_P2.txt"
    )

    # **Compute position of SSB wrt Sun**

    #First, we compute the position vectors of the SSB wrt the Sun at a
    #randomly chosen time. Let's choose the time as my birthday (24 April 1988,
    #9AM).
    init_time_utc = dt.datetime(year=1988,\
                                month=4,\
                                day=24,\
                                hour=9,\
                                minute=0,\
                                second=0)
    #We shall convert this time from UTC to ET.
    init_time_et, init_time_utc_str = f_convert_utc_to_et(init_time_utc)

    #Compute the position of SSB wrt Sun
    SSB_position_init = f_calc_position(init_time_et)
    #Report position
    print(f"On {init_time_utc_str}: \n\nPosition of SSB wrt Sun: \n \
          X-axis = {SSB_position_init[0]} km \n \
          Y-axis = {SSB_position_init[1]} km \n \
          Z-axis = {SSB_position_init[2]} km")

    #Compute distance of SSB from Sun in km
    SSB_sun_distance = math.sqrt(SSB_position_init[0]**2.0 \
                                 + SSB_position_init[1]**2.0 \
                                 + SSB_position_init[2]**2.0)
    #Convert km to AU
    SSB_sun_distance_AU = spiceypy.convrt(SSB_sun_distance, 'km', 'AU')
    #Report value
    print(f"Distance between SSB and Sun in km: {SSB_sun_distance} km")
    print(f"Distance between SSB and Sun in AU: {SSB_sun_distance_AU} AU")

    # **visualise the SSB wrt Sun**

    #We need to first scale the distance to the radius of the Sun using bodvcd
    #function.
    _, radii_sun = spiceypy.bodvcd(bodyid=10, item='RADII', maxn=3)
    radius_sun = radii_sun[0]
    #Scale position of SSB to radius of Sun
    SSB_position_init_scaled = f_scale_distance(SSB_position_init, radius_sun)

    #Plot using matplotlib
    # We only plot the x, y components (view on the ecliptic plane)
    SSB_position_init_scaled_xy = SSB_position_init_scaled[0:2]
    fig,ax = f_plot_SSB_position(SSB_position_init_scaled_xy[0],\
                                 SSB_position_init_scaled_xy[1])
    #Add plot title
    plt.title(f"Position of SSB wrt Centre of Sun on {init_time_utc_str}")
    #Annotate SSB datapoint
    SSB_label = "SSB ({:.2f},{:.2f})".format(SSB_position_init_scaled_xy[0],\
                     SSB_position_init_scaled_xy[1])
    plt.annotate(SSB_label,(SSB_position_init_scaled_xy[0],\
                            SSB_position_init_scaled_xy[1]+0.1))
    # Saving the figure in high quality
    plt.savefig(
        r'E:\Data Science Projects\Space Science\SpaceScience-P2-SSBandSunWobbling\reports\figures\SSB_WRT_SUN_INIT.png',
        dpi=300)
    plt.show()

    # === Compute position of SSB wrt Sun over a certain time period ===

    #Now we shall look the change in position of SSB wrt Sun over a certain
    #time period. Let us choose a time period of 30 years starting from the
    #time chosen in previous section.
    delta_days = 30 * 365
    end_time_utc = init_time_utc + dt.timedelta(days=delta_days)
    end_time_et, end_time_utc_str = f_convert_utc_to_et(end_time_utc)

    # **Side Note**
    #Here we can see why it is important to change time from UTC to ET. The
    #conversion helps to take into account leap years as well. When we use UTC,
    #the total number of seconds in the given time period of 30 years is:
    #30years*365days*24hours*60minutes*60seconds
    print("Covered UTC time interval in seconds: %s\n" %
          (30 * 365 * 24 * 60 * 60))
    #The number of seconds after converting to ET are:
    print("Covered ET time interval in seconds: %s\n" \
          %(end_time_et - init_time_et))
    #The printed results show that there is a difference of 13.0000644 seconds
    #between the two calculated time intervals. These are the leapseconds
    #added while converting UTC to ET. While these 13 seconds do not matter
    #much in the current program, they could have critical impact on space
    #mission projects. A lot can happen in 13 seconds in space.

    #The Earth moves about 390 km through space in 13 seconds.
    #The ISS travels almost 105 km around the Earth in 13 seconds.
    #An space-walking astronaut with a punctured suit has only 15 seconds
    #before losing consciousness.
    #**End of Side Note**

    #**Record SSB position for each day**
    # Create a numpy array that covers a time interval in delta = 1 day step
    time_interval_et = np.linspace(init_time_et, end_time_et, delta_days)

    #Compute SSB position wrt Sun for each day

    #Set an empty list to store x, y, z components for each time step
    SSB_position_interval = []

    #Compute position of SSB wrt sun for each time step.
    for time_interval_et_f in time_interval_et:
        _position = f_calc_position(time_interval_et_f)
        #Append the result to the final list
        SSB_position_interval.append(_position)
    #Convert the list to a numpy array
    SSB_position_interval = np.array(SSB_position_interval)

    #Scale the position values using the Sun's radius
    SSB_position_interval_scaled = f_scale_distance(SSB_position_interval,\
                                                    radius_sun)

    #Plot using matplotlib
    # We only plot the x, y components (view on the ecliptic plane)
    SSB_position_interval_scaled_xy = SSB_position_interval_scaled[:, 0:2]
    fig,ax = f_plot_SSB_position(SSB_position_interval_scaled_xy[:,0],\
                                 SSB_position_interval_scaled_xy[:,1])
    #Add plot title
    plt.title(f"Position of SSB wrt Centre of Sun between {init_time_utc_str}\
              and {end_time_utc_str}")
    #Add annotations
    plt.annotate("Day 1",(SSB_position_interval_scaled_xy[0,0],\
                            SSB_position_interval_scaled_xy[0,1]+0.1))
    plt.annotate("30 yrs later",(SSB_position_interval_scaled_xy[-1,0]-0.1,\
                            SSB_position_interval_scaled_xy[-1,1]-0.1))

    # Saving the figure in high quality
    plt.savefig(
        r'E:\Data Science Projects\Space Science\SpaceScience-P2-SSBandSunWobbling\reports\figures\SSB_WRT_SUN_30_YEARS.png',
        dpi=300)
    plt.show()

    # === How many days is the SSB outside the Sun? ===

    #First, we compute the euclidean distance between the SSB and Sun.
    SSB_position_interval_scaled = np.linalg.norm(SSB_position_interval_scaled,\
                                                 axis=1)
    print('\nComputation time: %s days' % delta_days)
    # Compute number of days outside the Sun
    SSB_outside_sun_days = len(np.where(SSB_position_interval_scaled > 1)[0])
    print('Fraction of time where the SSB\n' \
          'was outside the Sun: %.2f %%' \
          % (100 * SSB_outside_sun_days / delta_days))

    # === When was SSB closest to the Sun? ===

    #Find minimum euclidean distance in selected time interval
    SSB_position_interval_scaled = list(SSB_position_interval_scaled)
    SSB_position_interval_scaled_min = min(SSB_position_interval_scaled)
    #Find day when distance was minimum
    SSB_min_day = SSB_position_interval_scaled.index(
        SSB_position_interval_scaled_min)
    #Convert that day to UTC
    SSB_min_day_utc = init_time_utc + dt.timedelta(days=SSB_min_day)
    #Report
    print(f"\nSSB was closest to centre of Sun on {SSB_min_day_utc},")
    print(f"i.e. {round(SSB_min_day/365,2)} years later.")
    print(
        f"It was only {round(SSB_position_interval_scaled_min*radius_sun,2)} km away."
    )

    # === When was SSB farthest from the Sun? ===

    #Find maximum euclidean distance in selected time interval
    SSB_position_interval_scaled = list(SSB_position_interval_scaled)
    SSB_position_interval_scaled_max = max(SSB_position_interval_scaled)
    #Find day when distance was minimum
    SSB_max_day = SSB_position_interval_scaled.index(
        SSB_position_interval_scaled_max)
    #Convert that day to UTC
    SSB_max_day_utc = init_time_utc + dt.timedelta(days=SSB_max_day)
    #Report
    print(f"\nSSB was farthest from centre of Sun on {SSB_max_day_utc},")
    print(f"i.e. {round(SSB_max_day/365,2)} years later.")
    print(
        f"It was {round(SSB_position_interval_scaled_max*radius_sun,2)} km away."
    )
########################################################################
if "__main__" == __name__:

    ### FURNSH (SPICE furnish operation i.e. load kernel ) this script as a kernel,
    ### as well as any command-line arguments
    ### - skip any argument th at is --debug
    map(sp.furnsh, [arg for arg in sys.argv if arg != '--debug'])

    ### Set debug flag to True if --debug was an argument, else to False
    doDebug = '--debug' in sys.argv

    ### SPICE names of Clock, minute hand, hour hand
    sClock, sMinute, sHour = sNames = "CLOCK MINUTE HOUR".split()

    ### SPICE works in seconds; get seconds per minute, per hour, per day
    spm = sp.convrt(1.0, 'minutes', 'seconds')
    sph = sp.convrt(1.0, 'hours', 'seconds')
    hpd = sp.convrt(1.0, 'days', 'hours')
    spd = sp.spd()

    ### Other constants:  2*PI; degrees/radian
    twopi = sp.twopi()
    dpr = sp.dpr()

    ### Get start time (TDB) and SPK filename from kernel pool
    et0 = sp.gdpool('ET0', 0, 1)[0]
    fnClockSpk = sp.gcpool('CLOCKSPK', 0, 1, 99)[0]

    ### Make clock SPK if it does not exist
    if not os.path.exists(fnClockSpk):
#%%

# Get the G*M value for the Sun
_, GM_SUN_PRE = spiceypy.bodvcd(bodyid=10, item='GM', maxn=1)

GM_SUN = GM_SUN_PRE[0]

#%%

# Compute the orbital elements of Ceres using the computed state vector
CERES_ORBITAL_ELEMENTS = spiceypy.oscltx(state=CERES_STATE_VECTOR, \
                                         et=DATETIME_ET, \
                                         mu=GM_SUN)

# Set and convert the semi-major axis and perihelion from km to AU
CERES_SEMI_MAJOR_AU = spiceypy.convrt(CERES_ORBITAL_ELEMENTS[9], \
                                      inunit='km', outunit='AU')
CERES_PERIHELION_AU = spiceypy.convrt(CERES_ORBITAL_ELEMENTS[0], \
                                      inunit='km', outunit='AU')

# Set the eccentricity
CERES_ECC = CERES_ORBITAL_ELEMENTS[1]

# Set and convert miscellaneous angular values from radians to degrees:
# inc: Inclination
# lnode: Longitude of ascending node
# argp: Argument of perihelion
CERES_INC_DEG = np.degrees(CERES_ORBITAL_ELEMENTS[2])
CERES_LNODE_DEG = np.degrees(CERES_ORBITAL_ELEMENTS[3])
CERES_ARGP_DEG = np.degrees(CERES_ORBITAL_ELEMENTS[4])

# Set the orbit period. Convert from seconds to years
                                        AST_2020JX1_ARGP_DEG, \
                                        AST_2020JX1_I_DEG], \
                                  cov=AST_2020JX1_COV_MAT, size=1000)

#%%

# Store all re-samples now in a pandas dataframe. Consider the order of the
# orbital elements as defined by the covariance matrix
ast_2020_jx1_df = pd.DataFrame([])

# Eccentricity
ast_2020_jx1_df.loc[:, 'ECC'] = AST_2020_JX1_SAMPLE[:, 0]

# Perihelion (convert AU to km)
ast_2020_jx1_df.loc[:, 'PERIH_KM'] = \
    spiceypy.convrt(AST_2020_JX1_SAMPLE[:, 1], 'AU', 'km')

# Epoch in JD
ast_2020_jx1_df.loc[:, 'EPOCH_JD'] = AST_2020_JX1_SAMPLE[:, 2]

# Convert Epoch given in JD to Ephemeris Time
ast_2020_jx1_df.loc[:, 'EPOCH_ET'] = \
    ast_2020_jx1_df['EPOCH_JD'].apply(lambda x: \
                                      spiceypy.utc2et(str(x) + ' JD'))

# Longitude of ascending node, argument of periapsis and the inclination
# (in radians)
ast_2020_jx1_df.loc[:, 'LNODE_RAD'] = np.radians(AST_2020_JX1_SAMPLE[:, 3])
ast_2020_jx1_df.loc[:, 'ARGP_RAD'] = np.radians(AST_2020_JX1_SAMPLE[:, 4])
ast_2020_jx1_df.loc[:, 'I_RAD'] = np.radians(AST_2020_JX1_SAMPLE[:, 5])
Пример #10
0
def main():

    # ** Convert today's time at midnight from UTC to ephemeric time ET **

    #Get today's date
    date_today_utc = dt.datetime.today()
    #Convert datetime to string, replacing time with midnight
    date_today_utc = date_today_utc.strftime('%Y-%m-%dT00:00:00')

    #Get time conversion information from a lsk kernel 'naif0012.tls'
    spiceypy.furnsh(
        'E:\Data Science Projects\Space Science\SpaceScience-P1-EarthStateVectors\data\external\_kernels\lsk/naif0012.tls'
    )
    #Convert UTC to ET using SPICE function 'utc2et'
    et_today = spiceypy.utc2et(date_today_utc)

    # ** Compute the position and velocity of the Earth with respect to the Sun **

    #First load a spk kernel 'de432s.bsp' for positional information of planets.

    #    How to find the relevant kernel?
    #    At https://naif.jpl.nasa.gov/pub/naif/ we navigate to generic_kernels/spk/
    #    planets, since we are trying to find the trajectory of our planet. We
    #    browse the aa_summaries.txt file. The last line of each summary shows the
    #    time range covered in each kernel. The time period of de432s is suitable.

    spiceypy.furnsh(
        'E:\Data Science Projects\Space Science\SpaceScience-P1-EarthStateVectors\data\external/_kernels/spk/de432s.bsp'
    )

    #Use spkgeo function to compute Earth state vectors
    earth_state_wrt_sun, earth_sun_lt = spiceypy.spkgeo(targ=399, \
                                                        et=et_today, \
                                                        ref='ECLIPJ2000', \
                                                        obs=10)

    #Report position vector of Earth
    print(f"Position of Earth wrt Sun on {date_today_utc} is: \n \
          {earth_state_wrt_sun}",
          file=outfile)

    #Check whether computation is correct
    #
    #    We check the veracity of the computed position vectors by using the result
    #    to compute the distance between Earth and Sun. If it is around 1 AU, then
    #    the computation is satisfactory. ("around" 1AU because Earth's orbit is
    #    elliptical, ot perfectly circular)
    #
    #Compute distance between Earth and Sun in km
    earth_sun_distance = math.sqrt(earth_state_wrt_sun[0]**2.0 \
                                 + earth_state_wrt_sun[1]**2.0 \
                                 + earth_state_wrt_sun[2]**2.0)
    #Convert km to AU
    earth_sun_distance_AU = spiceypy.convrt(earth_sun_distance, 'km', 'AU')
    #Report value
    print(f"Current distance between the Earth and the Sun in AU: \
          {earth_sun_distance_AU}",
          file=outfile)

    # ** Compute Orbital Speed of Earth **
    #First we compute actual current orbital speed of Earth around Sun
    earth_orb_speed_wrt_sun = math.sqrt(earth_state_wrt_sun[3]**2.0 \
                                  + earth_state_wrt_sun[4]**2.0 \
                                  + earth_state_wrt_sun[5]**2.0)
    #Report current orbital speed of Earth
    print(f"Current orbital speed of the Earth around the Sun in km/s: \
      {earth_orb_speed_wrt_sun}",
          file=outfile)

    #Now we compute theoretical orbital speed of Earth around Sun
    #
    #    For this, we need the equation to determine the orbital speed. We assume
    #    that the Sun's mass is greater than the mass of the Earth and we assume
    #    that our planet is moving on an almost circular orbit. The orbit velocity
    #    $v_{\text{orb}}$ can be approximated with, where $G$ is the gravitational
    #    constant, $M$ is the mass of the Sun and $r$ is the distance between the
    #    Earth and the Sun:
    #    \begin{align}
    #        v_{\text{orb}}\approx\sqrt{\frac{GM}{r}}
    #    \end{align}
    #
    #    The G*M values for different objects are found in a pck file 'gm_de431.tpc'
    #
    #Load pck kernel for G*M value
    spiceypy.furnsh(
        'E:\Data Science Projects\Space Science\SpaceScience-P1-EarthStateVectors\data\external/_kernels/pck/gm_de431.tpc'
    )
    _, GM_SUN = spiceypy.bodvcd(bodyid=10, item='GM', maxn=1)
    #Compute theoretical orbital speed
    v_orb_func = lambda gm, r: math.sqrt(gm / r)
    earth_orb_speed_wrt_sun_theory = v_orb_func(GM_SUN[0], earth_sun_distance)
    #Report theoretical value
    print(f"Theoretical orbital speed of the Earth around the Sun in km/s: \
      {earth_orb_speed_wrt_sun_theory}",
          file=outfile)
# Compute the state vectors corresponding orbital elements
comet_67p_df.loc[:, 'STATE_VEC_ORB_ELEM'] = \
    comet_67p_df.apply(lambda x: spiceypy.oscltx(state=x['STATE_VEC'], \
                                                 et=x['ET'], \
                                                 mu=GM_SUN), \
                       axis=1)

#%%

# Assign miscellaneous orbital elements as individual columns
# Set the perihelion. Convert km to AU
comet_67p_df.loc[:, 'PERIHELION_AU'] = \
    comet_67p_df['STATE_VEC_ORB_ELEM'].apply(lambda x: \
                                             spiceypy.convrt(x[0], \
                                                             inunit='km', \
                                                             outunit='AU'))

# Set the eccentricity
comet_67p_df.loc[:, 'ECCENTRICITY'] = \
    comet_67p_df['STATE_VEC_ORB_ELEM'].apply(lambda x: x[1])

# Set the inclination in degrees
comet_67p_df.loc[:, 'INCLINATION_DEG'] = \
    comet_67p_df['STATE_VEC_ORB_ELEM'].apply(lambda x: np.degrees(x[2]))

# Set the longitude of ascending node in degrees
comet_67p_df.loc[:, 'LONG_OF_ASC_NODE_DEG'] = \
    comet_67p_df['STATE_VEC_ORB_ELEM'].apply(lambda x: np.degrees(x[3]))

# Set the argument of perihelion in degrees
Пример #12
0
ceres_df.loc[:, 'UTC_PARSED'] = DATETIME_RANGE.strftime('%Y-%j')

# Convert the date-time to Ephemeris Time
ceres_df.loc[:, 'ET_TIME'] = ceres_df['UTC_TIME'] \
                                 .apply(lambda x: spiceypy.utc2et(str(x)))

#%%

# Compute the distance between Ceres and the Sun and convert the resulting
# distance value given in km to AU
ceres_df.loc[:, 'DIST_SUN_AU'] = \
    ceres_df['ET_TIME'].apply(lambda x: \
        spiceypy.convrt( \
            spiceypy.vnorm( \
                spiceypy.spkgps(targ=CERES_ID, \
                                et=x, \
                                ref='ECLIPJ2000', \
                                obs=10)[0]), \
            'km', 'AU'))

# # Compute the distance between Ceres and the Earth and convert the resulting
# distance value given in km to AU
ceres_df.loc[:, 'DIST_EARTH_AU'] = \
    ceres_df['ET_TIME'].apply(lambda x: \
        spiceypy.convrt( \
            spiceypy.vnorm( \
                spiceypy.spkgps(targ=CERES_ID, \
                                et=x, \
                                ref='ECLIPJ2000', \
                                obs=399)[0]), \
            'km', 'AU'))
# Connect to the comet database
CON = sqlite3.connect('../_databases/_comets/mpc_comets.db')

# Extract orbit data of the comet C/2019 Y4 (ATLAS)
ATLAS_ORB_EL = pd.read_sql('SELECT NAME, PERIHELION_AU, ' \
                           'ECCENTRICITY, INCLINATION_DEG, ' \
                           'LONG_OF_ASC_NODE_DEG, ARG_OF_PERIH_DEG, ' \
                           'MEAN_ANOMALY_DEG, EPOCH_ET ' \
                           'FROM comets_main ' \
                           'WHERE NAME="C/2019 Y4 (ATLAS)"', CON)

# Convert the perihelion, that is given in AU, to km
ATLAS_ORB_EL.loc[:, 'PERIHELION_KM'] =  \
    ATLAS_ORB_EL['PERIHELION_AU'].apply(lambda x: \
                                        spiceypy.convrt(x, inunit='AU', \
                                                        outunit='km'))

# Convert all angular parameters to radians, since the entries in the database
# are stored in degrees. The for-loop iterates through all column names that
# contain the word "DEG"
for angle_col_name in [col for col in ATLAS_ORB_EL.columns if 'DEG' in col]:
    ATLAS_ORB_EL.loc[:, angle_col_name.replace('DEG', 'RAD')] = \
        np.radians(ATLAS_ORB_EL[angle_col_name])

# Add the G*M value of the Sun
ATLAS_ORB_EL.loc[:, 'SUN_GM'] = GM_SUN

#%%

# Extract all orbital elements / information in a SPICE compatible order (see
# function conics)
Пример #14
0
"""
Compare gaiaif_util.py corrections for parallax and stellar aberration
to equivalent correction in SPICE

"""
import os
import math
import fov_cmd
import sqlite3 as sl3
import spiceypy as sp
import gaiaif_util as gifu

### Setup debugging and conversions; define some string constants
do_debug = 'DEBUG' in os.environ
rpd, aupkm = sp.rpd(), sp.convrt(1., 'km', 'au')
(
    earth,
    ssb,
    j2000,
    none,
    LT,
    LTS,
    ra_dec,
    declination,
    equals,
) = 'earth 0 j2000 none lt lt+s ra/dec declination ='.upper().split()

sp.furnsh('de421.bsp')

gaia_db = 'gaia.sqlite3'
Пример #15
0
import os
import sys
import math
import numpy
import spiceypy as sp

try: dpr
except:
  dpr = sp.dpr()                                       ### degree / Radian
  rpd = sp.rpd()                                       ### Radian / degree
  rpmas = sp.convrt(1.,'arcseconds','radians') * 1e-3  ### Radian / milliarcsecond
  aupkm = sp.convrt(1.,'km','au')                      ### Astonomical Unit / kilometer
  recip_clight = 1.0 / sp.clight()


########################################################################
class FOV(object):
  """
Field-Of-View (FOV) and methods to determine if a ray is inside the FOV

Attributes

.L            Length of FOV argument to .__init__
.fovtype      FOV type:  FOV.CIRCLETYPE; RADECBOXTYPE;,.POLYGONTYPE
.radecdegs    List of [RA,Dec] pairs of input vectors/vertices, degrees
.uvfovxyzs    List of Unit vectors of [X,Y,Z] triples of input vectors
.hangdeg      Cone half-angle for circle FOV, degrees
.hangrad      Cone half-angle for circle FOV, radians
.radec_boxes  List of lists:  FOV bounding boxes; ralo,rahi,declo,dechi
.convex       True is FOV is convex, else False
EARTH_STATE_WRT_SUN, EARTH_SUN_LT = sp.spkgeo(targ=399 \
                                                    ,et=ET_TODAY_MIDNIGHT \
                                                    ,ref='ECLIPJ2000' \
                                                    ,obs=10
                                                    )

print("state vector of the earth wrt the sun for \"today\" (midnight): {0}".
      format(EARTH_STATE_WRT_SUN))

# check AU
EARTH_SUN_DISTANCE = math.sqrt(EARTH_STATE_WRT_SUN[0] ** 2 \
                                + EARTH_STATE_WRT_SUN[1] ** 2 \
                                + EARTH_STATE_WRT_SUN[2] ** 2
                                )

EARTH_SUN_DISTANCE_AU = sp.convrt(EARTH_SUN_DISTANCE, 'km', 'AU')

print('CURRENT distance between Earth and Sun in AU: {0}'.format(
    EARTH_SUN_DISTANCE_AU))

EARTH_ORB_SPEED_WRT_SUN = math.sqrt(EARTH_STATE_WRT_SUN[3] ** 2 \
                                + EARTH_STATE_WRT_SUN[4] ** 2 \
                                + EARTH_STATE_WRT_SUN[5] ** 2
                                )
print('Current orbital speed of earth and around the sun in km/s: {0}'.format(
    EARTH_ORB_SPEED_WRT_SUN))

_, GM_SUN = sp.bodvcd(bodyid=10, item='GM', maxn=1)
V_ORB_FUNC = lambda gm, r: math.sqrt(gm / r)
EARTH_ORB_SPEED_WRT_SUN_THEORY = V_ORB_FUNC(GM_SUN[0], EARTH_SUN_DISTANCE)
#%%

# Let's compute a state vector of the comet Hale-Bopp as an example

# Extract the G*M value of the Sun and assign it to a constant
_, GM_SUN_PRE = spiceypy.bodvcd(bodyid=10, item='GM', maxn=1)
GM_SUN = GM_SUN_PRE[0]

# Get the Hale-Bopp data
HALE_BOPP_DF = c_df.loc[c_df['Designation_and_name'].str.contains('Hale-Bopp')]

# Set an array with orbital elements in a required format for the conics
# function. Note: the mean anomaly is 0 degrees and will be set as a default
# value in the SQLite database
HALE_BOPP_ORB_ELEM = [spiceypy.convrt(HALE_BOPP_DF['Perihelion_dist'] \
                                      .iloc[0], 'AU', 'km'), \
                      HALE_BOPP_DF['e'].iloc[0], \
                      np.radians(HALE_BOPP_DF['i'].iloc[0]), \
                      np.radians(HALE_BOPP_DF['Node'].iloc[0]), \
                      np.radians(HALE_BOPP_DF['Peri'].iloc[0]), \
                      0.0, \
                      HALE_BOPP_DF['EPOCH_ET'].iloc[0], \
                      GM_SUN]

#%%

# Compute the state vector for midnight 2020-05-10
HALE_BOPP_ST_VEC = spiceypy.conics(HALE_BOPP_ORB_ELEM, \
                                   spiceypy.utc2et('2020-05-10'))

# Compare with results from https://ssd.jpl.nasa.gov/horizons.cgi
Пример #18
0
# In[14]:


print(Earth_Sun_Light_Time)


# In[15]:


Earth_Sun_Dinstance = math.sqrt(Earth_State_Sun[0]**2.0                              + Earth_State_Sun[1]**2.0                              + Earth_State_Sun[2]**2.0)


# In[16]:


Earth_Sun_Dinstance_AU = spiceypy.convrt(Earth_Sun_Dinstance, 'km', 'AU')


print('Current distance between the Earth and the Sun in AU:', Earth_Sun_Dinstance_AU)


# In[17]:



velocity = math.sqrt(Earth_State_Sun[3]**2.0                                   + Earth_State_Sun[4]**2.0                                   + Earth_State_Sun[5]**2.0)


print('Current orbital speed of the Earth around the Sun in km/s:', velocity)

Пример #19
0
def get_planet_magnitude(object_id, pos_planet, pos_basis):
    """ Planet and Moon magnitudes """

    planet_abs_mag = {
        199: -0.42,  # OBJECT_ID_MERCURY
        299: -4.40,  # OBJECT_ID_VENUS
        399: -2.96,  # OBJECT_ID_EARTH
        499: -1.52,  # OBJECT_ID_MARS
        599: -9.40,  # OBJECT_ID_JUPITER
        699: -8.68,  # OBJECT_ID_SATURN
        799: -7.19,  # OBJECT_ID_URANUS
        899: -6.87,  # OBJECT_ID_NEPTUNE
        999: -1.00,  # OBJECT_ID_PLUTO
    }

    # distance between each objects in AU
    d_planet_basis = spice.vdist(pos_planet, pos_basis)
    d_planet_basis = spice.convrt(d_planet_basis, "km", "AU")
    d_planet_sun = spice.vnorm(pos_planet)
    d_planet_sun = spice.convrt(d_planet_sun, "km", "AU")
    d_sun_basis = spice.vnorm(pos_basis)
    d_sun_basis = spice.convrt(d_sun_basis, "km", "AU")

    if object_id == OBJECT_ID_SUN:
        return -27.3 + 5.0 * np.log10(d_sun_basis)
    elif object_id == OBJECT_ID_MOON:
        return 0.38
    elif object_id in [
            OBJECT_ID_MERCURY,
            OBJECT_ID_VENUS,
            OBJECT_ID_EARTH,
            OBJECT_ID_MARS,
            OBJECT_ID_JUPITER,
            OBJECT_ID_SATURN,
            OBJECT_ID_URANUS,
            OBJECT_ID_NEPTUNE,
            OBJECT_ID_PLUTO,
    ]:
        pass
    else:
        return None

    mag = planet_abs_mag[object_id]
    mag += 5.0 * np.log10(d_planet_basis * d_planet_sun)

    if object_id <= OBJECT_ID_JUPITER:
        pa = 0.0
        tpa = (d_planet_sun**2 + d_planet_basis**2 -
               d_sun_basis) / (2.0 * d_planet_sun * d_planet_basis)
        tpa = np.clip(tpa, -1.0, 1.0)
        pa = np.degrees(np.arccos(tpa))

        if object_id == OBJECT_ID_MERCURY:
            mag += (0.0380 - 0.000273 * pa + 0.000002 * pa * pa) * pa
        elif object_id == OBJECT_ID_VENUS:
            mag += (0.0009 + 0.000239 * pa - 0.00000065 * pa * pa) * pa
        elif object_id == OBJECT_ID_MARS:
            mag += 0.016 * pa
        elif object_id == OBJECT_ID_JUPITER:
            mag += 0.005 * pa
    elif object_id == OBJECT_ID_SATURN:
        mag -= 1.1 * 0.3
    return mag