appsUnsorted.plot_galileo_moons_orbitΒΆ

''' Plot Gallilean Moon position and Galileo satellite orbit.
'''
import sys
import datetime
import dateutil.parser
import calendar

from optparse import OptionParser

import matplotlib.pyplot as plt
import numpy as np

from matplotlib.patches import Circle, Wedge

import pyana.pep.pep_spice
import pyana.pep.galileo_orbit

def get_traj(moon, tc, dur_orbit, del_orbit, frame, center):
    ''' Return the trajectory of the moon

    :returns: np.array with (N, 3) shape where N is the data number
        calculated from ``tc``, ``dur_orbit`` and ``del_orbit``.
    '''
    # Plotting oribt, start and end time
    t0 = tc - dur_orbit
    t1 = tc + dur_orbit

    torblist = []
    torblist = []

    t = tc
    while t >= t0:
        torblist.append(t)
        t = t - del_orbit

    t = tc
    while t <= t1:
        torblist.append(t)
        t = t + del_orbit

    torblist = list(set(torblist))
    torblist.sort()

    pepsp = pyana.pep.pep_spice.get_default_pepspice()

    moons_orbit = []
    for t in torblist:
        pos, vel = pepsp.get_posvel(moon, t, frame, center)
        pos = pos
        moons_orbit.append(pos)

    return np.array(moons_orbit)


def plotmain(tc, output=None, duration=None):

    moons = ['Io', 'Europa', 'Ganymede', 'Callisto']
    rmoon = {'Io': 1816., 'Europa': 1569., 'Ganymede': 2631., 'Callisto': 2410.}
    center = "Jupiter"
    frame = "JSE"

    # For plotting orbit.  Duration and resolution
#    dur_orbit = datetime.timedelta(days=1)
    del_orbit = datetime.timedelta(hours=1)
#    label_orbit = datetime.timedelta(hours=6)

    norm = 71492.

    pepsp = pyana.pep.pep_spice.get_default_pepspice()

    moons_positions = [pepsp.get_posvel(moon, tc, frame, center)[0] / norm for moon in moons]

    moons_orbits = [get_traj('Io', tc, datetime.timedelta(days=1.769) / 2, del_orbit, frame, center) / norm,
                    get_traj('Europa', tc, datetime.timedelta(days=3.551) / 2, del_orbit, frame, center) / norm,
                    get_traj('Ganymede', tc, datetime.timedelta(days=7.155) / 2, del_orbit, frame, center) / norm,
                    get_traj('Callisto', tc, datetime.timedelta(days=16.69) / 2, del_orbit, frame, center) / norm,
                    ]

    # Galileo orbit

    gal = pyana.pep.galileo_orbit.GalileoOrbit()

    if tc < gal.t0() or tc > gal.t1():
        raise ValueError('Given time (%s) is not included in Galileo orbit data (%s - %s)' % (tc, t0, t1))
    

    del_gal = datetime.timedelta(minutes=120)  # Every 1 minutes
    if duration == None:
        t0 = gal.t0()
        t1 = gal.t1()
    else:
        t0 = tc - datetime.timedelta(seconds=duration)
        t1 = tc + datetime.timedelta(seconds=duration)

    tlist = [tc]
    tt = tc - del_gal
    while tt >= t0:
        print(tt, len(tlist))
        tlist.append(tt)
        tt = tt - del_gal
    tt = tc + del_gal
    while tt <= t1:
        print(tt, len(tlist))
        tlist.append(tt)
        tt = tt + del_gal

    tlist.sort()

    print('Time list length = %d' % len(tlist))

    poslist = gal.get_positions(tlist)

    gal_pos = gal.get_positions(tc)

    # Plotting

    fig = plt.figure()
    ax = fig.add_subplot(111)

#    ax.plot([0], [0], 'kx', label=center)
    jupiter_body = Circle((0, 0), 71492. / norm, edgecolor='k', fill=False, alpha=0.5)
    ax.add_patch(jupiter_body)
    jupiter_dark = Wedge((0, 0), 71492. / norm, 90., 270., color='k', alpha=0.5)
    ax.add_patch(jupiter_dark)
    ax.annotate('J', (0, 0))

    for moonspos, moon in zip(moons_positions, moons):
        ax.plot([moonspos[0]], [moonspos[1]], 'k.')
        moon_body = Circle((moonspos[0], moonspos[1]), rmoon[moon] / norm, edgecolor='k', fill=False, alpha=0.5)
        ax.add_patch(moon_body)
        ax.annotate(moon[0], (moonspos[0], moonspos[1]))

    for moons_orbit in moons_orbits:
        ax.plot(moons_orbit[:, 0], moons_orbit[:, 1], 'k--')

    ax.plot(poslist[:, 0], poslist[:, 1], 'k:')
    ax.plot([gal_pos[0]], [gal_pos[1]], 'ko')
    ax.annotate('SC', (gal_pos[0], gal_pos[1]))

    ax.set_xlim(-30, 30)
    ax.set_ylim(-30, 30)

    xlim = ax.get_xlim()
    ax.set_xlim(xlim[::-1])  # To swap. Left is the sun.
    ax.grid()
    ax.set_aspect('equal')

    ax.set_xlabel('X_JSE [Rj]')
    ax.set_ylabel('Y_JSE [Rj]')


    ax.set_title('%s' % tc.strftime('%F %T'))

    if output != None:
        fig.savefig(output)

    return fig

def main():
    # Parsing the argument

    usage = 'USAGE:  %prog  [options]  yyyy-mm-ddThh:mm:ss'
    parser = OptionParser(usage)

    parser.add_option('-o', dest='outputfigname', default=None, help='Output figure name')
    parser.add_option('-d', dest='duration', default=None,
            help='Duration of plotting Galileo trajectory in seconds w.r.t the given time.')

    (options, args) = parser.parse_args()
    if len(args) != 1:
        parser.error('Must specify the time.')

    fig = plotmain(dateutil.parser.parse(args[0]), output=options.outputfigname, duration=options.duration)
    
    return fig

if __name__ == "__main__":
    val = main()