コード例 #1
0
def cassini_titan_altlatlon(tempdatetime):
    et = spice.datetime2et(tempdatetime)

    state, ltime = spice.spkezr('CASSINI', et, 'IAU_TITAN', 'NONE', 'TITAN')
    lon, lat, alt = spice.recpgr('TITAN', state[:3], spice.bodvrd('TITAN', 'RADII', 3)[1][0], 2.64e-4)

    return alt, lat * spice.dpr(), lon * spice.dpr()
コード例 #2
0
def cassini_altlatlon(utc, target='TITAN', output=False):
    state = cassini_phase(utc)

    lon, lat, alt = spice.recpgr(target, state[:3],
                                 spice.bodvrd(target, 'RADII', 3)[1][0],
                                 2.64e-4)

    if output:
        print("ALtitude", alt)
        print("Latitude", lat * spice.dpr())
        print("Longtitude", lon * spice.dpr())

    return alt, lat * spice.dpr(), lon * spice.dpr()
コード例 #3
0
ファイル: plot_fov_v02.py プロジェクト: irthomas/work
def printBoresights(angleSeparationA, angleSeparationB):
    """input manual rotation angles from SPICE kernels to calculate new and old boresight"""
    oldSoBoresight = [0.0, 0.0, 1.0]
    oldUVISBoresight = [0.0, 0.0, 1.0]
    rotationMatrixSoUVIS = sp.pxform("TGO_NOMAD_SO", "TGO_NOMAD_UVIS_OCC",
                                     sp.utc2et("2018 APR 01 00:00:00 UTC"))
    oldSoBoresightUVIS = np.dot(oldSoBoresight, rotationMatrixSoUVIS.T)
    oldBoresightSeparation = sp.vsep(oldUVISBoresight,
                                     oldSoBoresightUVIS) * sp.dpr() * 60.0
    print("oldBoresightSeparation")
    print(oldBoresightSeparation)

    print("angleSeparationB")
    print(angleSeparationB)
    #####SAVE THIS IT WORKS!!!######
    newSoBoresightTGO = np.asfarray([
            -1.0 * np.sin(angleSeparationB / sp.dpr()), \
            np.sin(angleSeparationA / sp.dpr()) * np.cos(angleSeparationB / sp.dpr()), \
            np.cos(angleSeparationA / sp.dpr()) * np.cos(angleSeparationB / sp.dpr())])

    print("newSoBoresightTGO, vnorm = %0.6f" % sp.vnorm(newSoBoresightTGO))
    print(newSoBoresightTGO)

    newUVISBoresightTGO = np.asfarray(
        [-0.922221097920913, -0.386613383297695, 0.006207330031467])
    oldSoBoresightTGO = np.asfarray([-0.92156, -0.38819, 0.00618])
    oldUVISBoresightTGO = np.asfarray(
        [-0.92207347097, -0.3869614566418, 0.0064300242046])

    oldNewSoBoresightSeparation = sp.vsep(newSoBoresightTGO,
                                          oldSoBoresightTGO) * sp.dpr() * 60.0
    print("oldNewSoBoresightSeparation")
    print(oldNewSoBoresightSeparation)

    oldNewUVISBoresightSeparation = sp.vsep(
        newUVISBoresightTGO, oldUVISBoresightTGO) * sp.dpr() * 60.0
    print("oldNewUVISBoresightSeparation")
    print(oldNewUVISBoresightSeparation)

    newSoUVISBoresightSeparation = sp.vsep(
        newSoBoresightTGO, newUVISBoresightTGO) * sp.dpr() * 60.0
    print("newSoUVISBoresightSeparation")
    print(newSoUVISBoresightSeparation)

    oldSoUVISBoresightSeparation = sp.vsep(
        oldSoBoresightTGO, oldUVISBoresightTGO) * sp.dpr() * 60.0
    print("oldSoUVISBoresightSeparation")
    print(oldSoUVISBoresightSeparation)
コード例 #4
0
ファイル: sun_angular_size.py プロジェクト: irthomas/work
def get_sun_sizes(utc_start, utc_end, step_size):
    """get sun angular size and time steps given start and end times"""
    #spice constants
    abcorr = "None"
    #tolerance = "1"
    #method = "Intercept: ellipsoid"
    #prec = 3
    #shape = "Ellipsoid"

    #load spiceypy kernels
    os.chdir(KERNEL_DIRECTORY)
    sp.furnsh(KERNEL_DIRECTORY + os.sep + METAKERNEL_NAME)
    print(sp.tkvrsn("toolkit"))
    os.chdir(BASE_DIRECTORY)
    utctimestart = sp.str2et(utc_start)
    utctimeend = sp.str2et(utc_end)

    durationseconds = utctimeend - utctimestart
    nsteps = int(np.floor(durationseconds / step_size))
    timesteps = np.arange(nsteps) * step_size + utctimestart

    ref = "J2000"
    observer = "-143"
    target = "SUN"
    #get TGO-SUN pos
    tgo2sunpos = [
        sp.spkpos(target, time, ref, abcorr, observer)[0] for time in timesteps
    ]
    sunaxes = sp.bodvrd("SUN", "RADII", 3)[1][0]  #get mars axis values

    return ([np.arctan((sunaxes*2.0)/np.linalg.norm(tgo2sunVector))*sp.dpr()*60.0 \
                for tgo2sunVector in tgo2sunpos], timesteps)
コード例 #5
0
def get_geometry_info(obs2refmtx, fov, width, height):
    cvec = spice.vhat(fov.bounds_rect.center_vec)
    cvec_ref = spice.mxv(obs2refmtx, cvec)

    # Azimuth in the upward direction of the screen
    mvec = spice.vhat(fov.bounds_rect.top_vec)
    mvec_ref = spice.mxv(obs2refmtx, mvec)
    pa, dist = vec_padist(cvec_ref, mvec_ref)
    pos_angle = pa * spice.dpr()

    # Pixel resolution up to the center of the screen top edge
    vp = viewport_frustum(fov.bounds_rect, width, height, mvec)
    angle_res = dist / (height / 2.0 - vp[1]) * spice.dpr()
    _, ra, dec = spice.recrad(cvec_ref)

    return pos_angle, angle_res, ra * spice.dpr(), dec * spice.dpr()
コード例 #6
0
ファイル: crossingextract.py プロジェクト: aaschok/Juno
def dataToPickle():
    orbits_begin = {1:'2016-07-31T19:46:02',
                            2:'2016-09-23T03:44:48',
                            3:'2016-11-15T05:36:45',
                            4:'2017-01-07T03:11:30',
                            5:'2017-02-28T22:55:48',
                            6:'2017-04-22T19:14:57'}
    
    file_dict = {}
    metaKernel = 'juno_2019_v03.tm'
    spice.furnsh(metaKernel)

    start_time = datetime.datetime.strptime(orbits_begin[1],'%Y-%m-%dT%H:%M:%S')
    
    end_time = datetime.datetime.strptime(orbits_begin[2],'%Y-%m-%dT%H:%M:%S')
    
    data_folder = pathlib.Path(r'..\data\fgm')
    p = re.compile(r'\d{7}')
    
    for parent,child,files in os.walk(data_folder):
        for name in files:
            if name.endswith('.csv'):
                file_path = os.path.join(data_folder,name)
                
                search = p.search(name).group()
                date = datetime.datetime.strptime(search,'%Y%j')
                
                if date.date() >= start_time.date() and date.date() <= end_time.date():
                    iso_date = date.strftime('%Y-%m-%d')
                    if iso_date not in file_dict.keys():
                        file_dict[iso_date] = [file_path]
                    elif iso_date in file_dict.keys() and file_dict[iso_date] != file_path: 
                        file_dict[iso_date].append(file_path)
    
    for date in file_dict.keys():
        fgmdf = pd.DataFrame(data={'TIME':[],'BX':[],'BY':[],'BZ':[],'LAT':[]})
        save_date = datetime.datetime.strptime(date,'%Y-%m-%d')
        file_list = file_dict[date]
        for file in file_list:
            
            temp = pd.read_csv(file)
            datetime_list = temp['SAMPLE UTC']
            time_list = [datetime.datetime.fromisoformat(i).strftime('%H:%M:%S') for i in datetime_list]
            
            for index,time in enumerate(datetime_list):
                
                position, lighttime = spice.spkpos('JUNO',spice.utc2et(time),'IAU_JUPITER','NONE','JUPITER')
            
                vectorPos = spice.vpack(position[0],position[1],position[2])
                radii,longitude,latitude = spice.reclat(vectorPos)
                lat = latitude*spice.dpr()
                
                if lat >= -10 and lat <= 10:
                    fgmdf = fgmdf.append({'TIME':time,'BX':temp['BX PLANETOCENTRIC'][index],'BY':temp['BY PLANETOCENTRIC'][index],'BZ':temp['BZ PLANETOCENTRIC'][index],'LAT':lat},ignore_index=True)
        fgmdf = fgmdf.sort_values(by=['TIME'])
        save_name = f'{save_date.strftime("%Y%m%d")}'
        save_path = pathlib.Path(f'..\data\pickledfgm\jno_fgm_{save_name}.pkl')
        pickledf = fgmdf.to_pickle(save_path)
        print(f'Saved pickle {date}')                                     
コード例 #7
0
def findBoresightUsed(et, boresight_vectors, boresight_names):

    obs2SunVector = sp.spkpos("SUN", et, SPICE_REFERENCE_FRAME, SPICE_ABERRATION_CORRECTION, SPICE_OBSERVER)
    
    v_norm = obs2SunVector[0]/sp.vnorm(obs2SunVector[0])
    
    v_sep_min = 999.0
    for boresight_vector, boresight_name in zip(boresight_vectors, boresight_names):
        v_sep = sp.vsep(v_norm, boresight_vector) * sp.dpr() * 60.0 #arcmins difference
        if v_sep < v_sep_min:
            v_sep_min = v_sep
            boresight_found = boresight_name
    return boresight_found, v_sep_min
コード例 #8
0
ファイル: spice.py プロジェクト: RichardHaythorn/cassinipy
def caps_ramdirection_azielv(tempdatetime, observ='titan'):
    """
    Returns the azimuth and elevation of the ramdirection
    """
    ram_unit = cassini_ramdirection_SCframe(tempdatetime, observ=observ)

    sc2CAPS = np.array(([0, -1, 0],
                        [-1, 0, 0],
                        [0, 0, -1]))
    ram_unit_CAPS = spice.mxv(sc2CAPS, ram_unit)
    # print(ram_unit_CAPS)
    ram_unit_azielv = np.array(spice.reclat(ram_unit_CAPS)[1:]) * spice.dpr()

    return ram_unit_azielv[0], ram_unit_azielv[1]
コード例 #9
0
    def __init__(self, inst_id):
        fov = spice.getfov(inst_id, Fov.MAX_ROOMS)
        self._shape = fov[0]
        self._frame = fov[1]
        self._boresight = fov[2]
        self._nbounds = fov[3]
        self._bounds = fov[4]

        self._bounds_rect = self._calc_bounds_rect()
        self._fovmax = self._calc_fovmax()
        self._fovy = (
            spice.vsep(self.bounds_rect.center_vec, self.bounds_rect.top_vec) *
            2.0 * spice.dpr())
        self._aspect = self.bounds_rect.aspect
コード例 #10
0
    def positionData(self):
        # spice.furnsh(self.meta) #loads the meta kernel that will load all kernels needed

        time = spice.utc2et(self.time)

        self.position, lighttime = spice.spkpos(
            'JUNO', time, 'IAU_JUPITER', 'NONE', 'JUPITER'
        )  #Finds the position in cartesian coords relative to jupiter

        pos = spice.vpack(self.position[0], self.position[1],
                          self.position[2])  #Packs the position into a vector
        self.distance, self.longitude, self.latitude = spice.reclat(
            pos)  #Finds radial dist, latitide and longitude
        self.latitude *= spice.dpr()
        self.distance /= 69911
コード例 #11
0
    def __init__(self, inst, et, abcorr, obsrvr, width, height, mag_limit):
        # input parameter
        self.inst = inst
        self.et = et
        self.abcorr = abcorr
        self.obsrvr = obsrvr
        self.width = width
        self.height = height

        # parameters equivalent to input parameter
        self.date = spice.et2utc(et, "ISOC", 3)
        self.inst_id = spice.bodn2c(inst)

        # Instrument FOV
        self.fov = Fov(self.inst_id)
        self.fov_in_degrees = self.fov.fovmax * 2.0 * spice.dpr()

        # geometry information
        self.pos, _ = spice.spkpos(obsrvr, et, self.fov.frame, abcorr, "SUN")
        self.obs2refmtx = spice.pxform(self.fov.frame, "J2000", et)
        self.ref2obsmtx = spice.pxform("J2000", self.fov.frame, et)

        # screen information
        pos_angle, angle_res, ra, dec = get_geometry_info(
            self.obs2refmtx, self.fov, width, height
        )

        self.center = self.fov.bounds_rect.center_vec
        self.pos_angle = pos_angle
        self.angle_res = angle_res
        self.ra = ra
        self.dec = dec

        # searched objects
        self.solar_objects = search_solar_objects(self)
        self.stars = search_stars(self, mag_limit)
コード例 #12
0
ファイル: plots_for_fabiana.py プロジェクト: irthomas/work
Created on Mon Sep  3 11:31:52 2018

@author: iant
"""
import spiceypy as sp
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

method = "Ellipsoid"
target = "MARS"
fixref = "IAU_MARS"
abcorr = "None"
obsrvr = "SUN"

spoint = sp.latrec(3390, -24.6 / sp.dpr(), 18.3 / sp.dpr())
et = sp.utc2et("2003 OCT 28, 00:00:00")

step = 60

for loop in range(100):
    time = et + step * loop
    time_string = sp.et2utc(time, "C", 0)
    sza = sp.ilumin(method, target, time, fixref, abcorr, obsrvr,
                    spoint)[3] * sp.dpr()


def writeLog(file_name, lines_to_write):
    """function to append log file"""
    #    global LOG_PATHS
    logFile = open(file_name + ".csv", 'w')
コード例 #13
0
ファイル: spice_calcs_v03b.py プロジェクト: irthomas/work
        #make pointing vectors between tgo and sun positions
        line_vectors = tgo2sun_pos  #np.asfarray([[tgo_vec[0]-sun_vec[0],tgo_vec[1]-sun_vec[1],tgo_vec[2]-sun_vec[2]] for tgo_vec,sun_vec in zip(list(tgo_pos),list(sun_pos))])

        #calculate surface tangent point using pointing vectors and tgo position vs time
        print("Calculating tangent points")
        tangent_coords = np.asfarray([
            sp.npedln(mars_axes[0], mars_axes[1], mars_axes[2], line_point,
                      line_vector)[0] for line_point, line_vector in zip(
                          list(line_points), list(line_vectors))
        ])
        tangent_lonlats1 = np.asfarray([
            sp.reclat(tangent_coord) for tangent_coord in list(tangent_coords)
        ])
        tangent_lonlats = np.asfarray(
            [[tangent_lonlat[1] * sp.dpr(), tangent_lonlat[2] * sp.dpr()]
             for tangent_lonlat in list(tangent_lonlats1)])
        tangent_lsts = [
            sp.et2lst(time, 499, (tangent_lonlat[0] / sp.dpr()),
                      "PLANETOCENTRIC")[3]
            for time, tangent_lonlat in zip(list(times), list(tangent_lonlats))
        ]
        tangent_lsts_hours = np.asfarray([
            np.float(tangent_lst[0:2]) + np.float(tangent_lst[3:5]) / 60.0 +
            np.float(tangent_lst[6:8]) / 3600.0 for tangent_lst in tangent_lsts
        ])

        nadir_lonlats = np.asfarray(
            [sp.reclat(mars2tgo)
             for mars2tgo in list(mars2tgo_pos)])[:, 1:3] * sp.dpr()
        nadir_lsts = [
コード例 #14
0
def lsubs(et):

    return sp.lspcn("MARS", et, abcorr) * sp.dpr()
コード例 #15
0
def do_main(argv):

    sp.kclear()
    halfpi, dpr = sp.halfpi(), sp.dpr()

    fnck = 'out.bc'
    target = 'TEMPEL 1'
    frame = 'DIF_SPACECRAFT'
    for arg in argv:
        if arg.startswith('--ck='):
            fnck = arg[5:]
        elif arg.startswith('--target='):
            target = arg[9:]
        elif arg.startswith('--k='):
            sp.furnsh(arg[4:])
        else:
            assert False, 'Unknown argument [{0}]'.format(arg)

    frameid = sp.gipool('FRAME_{0}'.format(frame), 0, 1)[0]
    scid = sp.gipool('CK_{0}_SPK'.format(frameid), 0, 1)[0]
    scname = sp.bodc2s(scid, 99)
    cover = sp.stypes.SPICEDOUBLE_CELL(200)
    sp.scard(0, cover)
    cover = sp.ckcov(fnck, frameid, False, "INTERVAL", 0.0, "TDB")
    sp.furnsh(fnck)
    vbore = sp.vpack(-1, 0, 0)
    vorbitnorm = sp.vpack(0, 1, 0)
    for ipair in range(sp.wncard(cover)):
        et0, etend = sp.wnfetd(cover, 0)

        etlast, ettca, niter = et0, (et0 + etend) * 0.5, 0

        while ettca != etlast and niter < 20:
            etlast = ettca
            state6 = sp.spkezr(target, ettca, "j2000", "none", scname)[0]
            vpos, vvel = state6[:3], state6[3:]
            det = sp.vdot(vvel, vpos) / sp.vdot(vvel, vvel)
            ettca -= det
            niter += 1

        print(dict(
            TCAtdb=sp.etcal(ettca, 99),
            niter=niter,
        ))

        et = et0
        ets, boreerrs, orbitnormerrs = list(), list(), list()
        while et <= etend:
            state6 = sp.spkezr(target, et, frame, "none", scname)[0]
            vpos, vvel = state6[:3], state6[3:]
            ets.append(et - et0)
            boreerrs.append(dpr * sp.vsep(vbore, vpos))
            orbitnormerrs.append(dpr * (sp.vsep(vbore, vorbitnorm) - halfpi))
            et += max([0.01, 0.1 * abs(cos(sp.vsep(vpos, vvel)))])
        try:
            plt.plot(ets, orbitnormerrs, 'o', label='Orbit normal error')
            plt.plot(ets, boreerrs, 'o', label='Boresight error')
            plt.axvline(ettca - et0, label='TCA')
            plt.xlabel('Time, s past {0} TDB'.format(sp.etcal(et0, 99)))
            plt.ylabel('Error, deg')
            plt.legend(loc='best')
            plt.show()
        except:
            if do_debug:
                import traceback as tb
                tb.print_exc()
            print(boreerrs[::1000])
            print(orbitnormerrs[::1000])
コード例 #16
0
def caps_crosstrack_latlon(time, negwindspeed, poswindspeed, anodes=False):
    anode_vecs = []
    anode_seps = [[], [], [], [], [], [], [], []]
    beamanodes = []

    # print(time)
    beamanodes.append(np.mean(ELS_ramanodes(time)) + 1)
    state = cassini_phase(time.strftime('%Y-%m-%dT%H:%M:%S'))
    # crossvec = caps_crosstrack(time, windspeed) * abs(windspeed) * 1e-3 #Old Method
    crossvec, anode1, anode8 = caps_crosstrack_spice(
        time, np.mean([negwindspeed, poswindspeed]))  # SPICE Plane method
    crossvec_neg = crossvec * 1e-3
    crossvec_pos = crossvec * 1e-3

    print("crossvec", crossvec_neg, crossvec_pos)
    newstate_neg = list(state[:3]) + list(crossvec_neg)
    newstate_pos = list(state[:3]) + list(crossvec_pos)
    transformed_state_neg = spice.xfmsta(newstate_neg, 'RECTANGULAR',
                                         'Latitudinal', "TITAN")
    transformed_state_pos = spice.xfmsta(newstate_pos, 'RECTANGULAR',
                                         'Latitudinal', "TITAN")
    print("test state", newstate_neg, newstate_pos)
    print("test xfmsta", transformed_state_neg, transformed_state_pos)
    alt = transformed_state_neg[0]
    lon = transformed_state_neg[1] * spice.dpr()
    lat = transformed_state_neg[2] * spice.dpr()

    if anodes:
        anode_vecs.append(caps_all_anodes(time))
        for anodecounter, i in enumerate(anode_vecs[-1]):
            anode_seps[anodecounter].append(
                spice.vsep(spice.vhat(state[3:]),
                           spice.vhat(anode_vecs[-1][anodecounter])) *
                spice.dpr())
        print("anode_vecs", anode_vecs)
        print("anode_seps", anode_seps)
    dvec_neg = [
        transformed_state_neg[4], transformed_state_neg[5],
        transformed_state_neg[3]
    ]
    dvec_pos = [
        transformed_state_pos[4], transformed_state_pos[5],
        transformed_state_pos[3]
    ]
    print("dvec xfmsta", dvec_neg, dvec_pos)
    print(lon, lat, alt)

    titanrad = spice.bodvrd('TITAN', 'RADII', 3)[1][0]  # Get Titan Radius
    mag_test_neg = spice.unorm([
        dvec_neg[0] * (alt + titanrad) * 1e3,
        dvec_neg[1] * (alt + titanrad) * 1e3, dvec_neg[2] * 1e3
    ])
    mag_test_pos = spice.unorm([
        dvec_pos[0] * (alt + titanrad) * 1e3,
        dvec_pos[1] * (alt + titanrad) * 1e3, dvec_pos[2] * 1e3
    ])
    # Convert Lat/Lon from rad/s to m/s, convert Alt from km/s to m/s. Forms Unit Vector here
    print("mag test", mag_test_pos)

    dlon_neg = mag_test_neg[0][0] * abs(negwindspeed)
    dlat_neg = mag_test_neg[0][1] * abs(negwindspeed)
    dalt_neg = mag_test_neg[0][2] * abs(negwindspeed)

    dlon_pos = mag_test_pos[0][0] * abs(poswindspeed)
    dlat_pos = mag_test_pos[0][1] * abs(poswindspeed)
    dalt_pos = mag_test_pos[0][2] * abs(poswindspeed)

    return lon, lat, alt, dlon_neg, dlat_neg, dalt_neg, dlon_pos, dlat_pos, dalt_pos
コード例 #17
0
typein = "PLANETOCENTRIC"
body = 499

etStart = sp.utc2et("2018MAR24-11:50:00 UTC")
etEnd = sp.utc2et("2020MAR24-11:50:00 UTC")

ets = np.linspace(etStart, etEnd, num=180)

writeOutput("UTC Time, LSubS, Longitude, Latitude, Local Solar Time")
for et in list(ets):

    lSubS = lsubs(et)
    terminatorPoints = sp.edterm(trmtyp, source, target, et, ref, abcorr,
                                 observer, npts)

    terminatorLatLonsRad = np.asfarray([
        sp.reclat(terminatorPoint)[1:3]
        for terminatorPoint in terminatorPoints[2]
    ])

    terminatorLatLonsDeg = terminatorLatLonsRad * sp.dpr()

    terminatorLSTs = [
        sp.et2lst(et, body, terminatorLatLonRad[0], typein)[3]
        for terminatorLatLonRad in list(terminatorLatLonsRad)
    ]

    for index, terminatorLST in enumerate(terminatorLSTs):
        writeOutput("%s,%0.2f,%0.2f,%0.2f,%s" %
                    (et2utc(et), lSubS, terminatorLatLonsDeg[index, 0],
                     terminatorLatLonsDeg[index, 1], terminatorLST))
コード例 #18
0
ファイル: mrotat.py プロジェクト: isabella232/spice-examples
def mrotat():
    #
    # Convert our UTC string to seconds past J2000 TDB.
    #
    timstr = '2007 JAN 1 00:00:00'
    et = spiceypy.str2et(timstr)

    #
    # Look up the apparent position of the Earth relative
    # to the Moon's center in the IAU_MOON frame at ET.
    #
    [imoonv, ltime] = spiceypy.spkpos('earth', et, 'iau_moon', 'lt+s', 'moon')

    #
    #Express the Earth direction in terms of longitude
    #and latitude in the IAU_MOON frame.
    #
    [r, lon, lat] = spiceypy.reclat(imoonv)

    print('\n'
          'Moon-Earth direction using low accuracy\n'
          'PCK and IAU_MOON frame:\n'
          'Earth lon (deg):        {0:15.6f}\n'
          'Earth lat (deg):        {1:15.6f}\n'.format(lon * spiceypy.dpr(),
                                                       lat * spiceypy.dpr()))
    #
    # Look up the apparent position of the Earth relative
    # to the Moon's center in the MOON_ME frame at ET.
    #
    [mmoonv, ltime] = spiceypy.spkpos('earth', et, 'moon_me', 'lt+s', 'moon')
    #
    # Express the Earth direction in terms of longitude
    # and latitude in the MOON_ME frame.
    #
    [r, lon, lat] = spiceypy.reclat(mmoonv)

    print('Moon-Earth direction using high accuracy\n'
          'PCK and MOON_ME frame:\n'
          'Earth lon (deg):        {0:15.6f}\n'
          'Earth lat (deg):        {1:15.6f}\n'.format(lon * spiceypy.dpr(),
                                                       lat * spiceypy.dpr()))
    #
    # Find the angular separation of the Earth position
    # vectors in degrees.
    #
    sep = spiceypy.dpr() * spiceypy.vsep(imoonv, mmoonv)

    print('For IAU_MOON vs MOON_ME frames:')
    print('Moon-Earth vector separation angle (deg):     '
          '{:15.6f}\n'.format(sep))
    #
    # Look up the apparent position of the Earth relative
    # to the Moon's center in the MOON_PA frame at ET.
    #
    [pmoonv, ltime] = spiceypy.spkpos('earth', et, 'moon_pa', 'lt+s', 'moon')
    #
    # Express the Earth direction in terms of longitude
    # and latitude in the MOON_PA frame.
    #
    [r, lon, lat] = spiceypy.reclat(pmoonv)

    print('Moon-Earth direction using high accuracy\n'
          'PCK and MOON_PA frame:\n'
          'Earth lon (deg):        {0:15.6f}\n'
          'Earth lat (deg):        {1:15.6f}\n'.format(lon * spiceypy.dpr(),
                                                       lat * spiceypy.dpr()))
    #
    # Find the angular separation of the Earth position
    # vectors in degrees.
    #
    sep = spiceypy.dpr() * spiceypy.vsep(pmoonv, mmoonv)

    print('For MOON_PA vs MOON_ME frames:')
    print('Moon-Earth vector separation angle (deg):     '
          '{:15.6f}\n'.format(sep))
    #
    # Find the apparent sub-Earth point on the Moon at ET
    # using the MOON_ME frame.
    #
    [msub, trgepc, srfvec] = spiceypy.subpnt('near point: ellipsoid', 'moon',
                                             et, 'moon_me', 'lt+s', 'earth')
    #
    # Display the sub-point in latitudinal coordinates.
    #
    [r, lon, lat] = spiceypy.reclat(msub)

    print('Sub-Earth point on Moon using high accuracy\n'
          'PCK and MOON_ME frame:\n'
          'Sub-Earth lon (deg):   {0:15.6f}\n'
          'Sub-Earth lat (deg):   {1:15.6f}\n'.format(lon * spiceypy.dpr(),
                                                      lat * spiceypy.dpr()))
    #
    # Find the apparent sub-Earth point on the Moon at
    # ET using the MOON_PA frame.
    #
    [psub, trgepc, srfvec] = spiceypy.subpnt('near point: ellipsoid', 'moon',
                                             et, 'moon_pa', 'lt+s', 'earth')
    #
    # Display the sub-point in latitudinal coordinates.
    #
    [r, lon, lat] = spiceypy.reclat(psub)

    print('Sub-Earth point on Moon using high accuracy\n'
          'PCK and MOON_PA frame:\n'
          'Sub-Earth lon (deg):   {0:15.6f}\n'
          'Sub-Earth lat (deg):   {1:15.6f}\n'.format(lon * spiceypy.dpr(),
                                                      lat * spiceypy.dpr()))
    #
    # Find the distance between the sub-Earth points
    # in km.
    #
    dist = spiceypy.vdist(msub, psub)

    print('Distance between sub-Earth points (km): ' '{:15.6f}\n'.format(dist))
コード例 #19
0
    def __Geometry(self, boresight=''):

        #if self.geometry_flag is True and \
        #                self.time.window.all() == self.previous_tw.all():
        #    return

        distance = []
        altitude = []
        boresight_latitude = []
        boresight_longitude = []
        latitude = []
        longitude = []
        subpoint_xyz = []
        subpoint_pgc = []
        subpoint_pcc = []
        zaxis_target_angle = []
        myaxis_target_angle = []
        yaxis_target_angle = []
        xaxis_target_angle = []
        beta_angle = []

        qs, qx, qy, qz = [], [], [] ,[]
        x, y, z = [],[],[]


        tar = self.target
        time = self.time

        for et in time.window:

            try:
                #
                # Compute the distance
                #
                ptarg, lt = spiceypy.spkpos(tar.name, et, tar.frame, time.abcorr,
                                          self.name)
                x.append(ptarg[0])
                y.append(ptarg[1])
                z.append(ptarg[2])

                vout, vmag = spiceypy.unorm(ptarg)
                distance.append(vmag)


                #
                # Compute the geometric sub-observer point.
                #
                if tar.frame == 'MARSIAU':
                    tar_frame = 'IAU_MARS'
                else:
                    tar_frame = tar.frame
                spoint, trgepc, srfvec = spiceypy.subpnt(tar.method, tar.name, et,
                                                       tar_frame, time.abcorr,
                                                       self.name)
                subpoint_xyz.append(spoint)

                #
                # Compute the observer's altitude from SPOINT.
                #
                dist = spiceypy.vnorm(srfvec)
                altitude.append(dist)


                #
                # Convert the sub-observer point's rectangular coordinates to
                # planetographic longitude, latitude and altitude.
                #
                spglon, spglat, spgalt = spiceypy.recpgr(tar.name, spoint,
                                                       tar.radii_equ, tar.flat)

                #
                # Convert radians to degrees.
                #
                spglon *= spiceypy.dpr()
                spglat *= spiceypy.dpr()

                subpoint_pgc.append([spglon, spglat, spgalt])

                #
                #  Convert sub-observer point's rectangular coordinates to
                #  planetocentric radius, longitude, and latitude.
                #
                spcrad, spclon, spclat = spiceypy.reclat(spoint)


                #
                # Convert radians to degrees.
                #
                spclon *= spiceypy.dpr()
                spclat *= spiceypy.dpr()

                subpoint_pcc.append([spclon, spclat, spcrad])
                latitude.append(spclat) #TODO: Remove with list extraction
                longitude.append(spclon)  # TODO: Remove with list extraction

                #
                # Compute the geometric sub-boresight point.
                #
                if tar.frame == 'MARSIAU':
                    tar_frame = 'IAU_MARS'
                else:
                    tar_frame = tar.frame


                if boresight:
                    try:
                        id = spiceypy.bodn2c(boresight)
                        (shape,framen, bsight, n, bounds) = spiceypy.getfov(id, 80)
                        mat = spiceypy.pxform(framen,tar_frame,et)
                    except:
                        framen = boresight
                        bsight = 0,0,1
                else:
                    bsight = self.name

                try:
                    if tar.method == 'INTERCEPT/ELLIPSOID':
                        method = 'ELLIPSOID'
                    else:
                        method = tar.method
                    spoint, trgepc, srfvec = spiceypy.sincpt(method, tar.name, et,
                                                           tar_frame, time.abcorr,
                                                           self.name, framen,
                                                           bsight)

                    #
                    # Convert the sub-observer point's rectangular coordinates to
                    # planetographic longitude, latitude and altitude.
                    #
                    spglon, spglat, spgalt = spiceypy.recpgr(tar.name, spoint,
                                                           tar.radii_equ, tar.flat)

                    #
                    # Convert radians to degrees.
                    #
                    spglon *= spiceypy.dpr()
                    spglat *= spiceypy.dpr()


                    #
                    #  Convert sub-observer point's rectangular coordinates to
                    #  planetocentric radius, longitude, and latitude.
                    #
                    spcrad, spclon, spclat = spiceypy.reclat(spoint)


                    #
                    # Convert radians to degrees.
                    #
                    spclon *= spiceypy.dpr()
                    spclat *= spiceypy.dpr()

                    boresight_latitude.append(spclat)
                    boresight_longitude.append(spclon)

                except:
                    pass

                #
                # Compute the angle between the observer's S/C axis and the
                # geometric sub-observer point
                #
                obs_tar, ltime = spiceypy.spkpos(tar.name, et,
                                                       'J2000', time.abcorr,
                                                       self.name)
                obs_zaxis  = [0,  0, 1]
                obs_myaxis = [0, -1, 0]
                obs_yaxis = [0, 1, 0]
                obs_xaxis = [1, 0, 0]

                #
                # We need to account for when there is no CK attitude available.
                #
                try:
                    matrix = spiceypy.pxform(self.frame, 'J2000', et)

                    z_vecout = spiceypy.mxv(matrix, obs_zaxis)
                    zax_target_angle = spiceypy.vsep(z_vecout, obs_tar)
                    zax_target_angle *= spiceypy.dpr()
                    zaxis_target_angle.append(zax_target_angle)

                    my_vecout = spiceypy.mxv(matrix, obs_myaxis)
                    myax_target_angle = spiceypy.vsep(my_vecout, obs_tar)
                    myax_target_angle *= spiceypy.dpr()
                    myaxis_target_angle.append(myax_target_angle)

                    y_vecout = spiceypy.mxv(matrix, obs_myaxis)
                    yax_target_angle = spiceypy.vsep(y_vecout, obs_tar)
                    yax_target_angle *= spiceypy.dpr()
                    yaxis_target_angle.append(yax_target_angle)

                    x_vecout = spiceypy.mxv(matrix, obs_myaxis)
                    xax_target_angle = spiceypy.vsep(x_vecout, obs_tar)
                    xax_target_angle *= spiceypy.dpr()
                    xaxis_target_angle.append(xax_target_angle)


                    quat = spiceypy.m2q(spiceypy.invert(matrix))
                    qs.append(quat[0])
                    qx.append(-1*quat[1])
                    qy.append(-1*quat[2])
                    qz.append(-1*quat[3])

                except:
                    zaxis_target_angle.append(0.0)
                    myaxis_target_angle.append(0.0)
                    yaxis_target_angle.append(0.0)
                    xaxis_target_angle.append(0.0)
                    qs.append(0.0)
                    qx.append(0.0)
                    qy.append(0.0)
                    qz.append(0.0)

                beta_angle.append(spiops.beta_angle(self.name, self.target.name,
                                                    et))
            except:
                boresight_latitude = 0
                boresight_longitude = 0
                distance = 0
                altitude = 0
                latitude = 0
                longitude = 0
                subpoint_xyz = [0,0,0]
                subpoint_pgc =  [0,0,0]
                subpoint_pcc =  [0,0,0]
                zaxis_target_angle = 0
                myaxis_target_angle = 0
                yaxis_target_angle = 0
                xaxis_target_angle = 0
                beta_angle = 0
                (qx, qy, qz, qs) = 0, 0, 0, 0
                (x, y, z) = 0, 0, 0

        self.boresight_latitude = boresight_latitude
        self.boresight_longitude = boresight_longitude
        self.distance = distance
        self.altitude = altitude
        self.latitude = latitude
        self.longitude = longitude
        self.subpoint_xyz = subpoint_xyz
        self.subpoint_pgc = subpoint_pgc
        self.subpoint_pcc = subpoint_pcc
        self.zaxis_target_angle = zaxis_target_angle
        self.myaxis_target_angle = myaxis_target_angle
        self.yaxis_target_angle = yaxis_target_angle
        self.xaxis_target_angle = xaxis_target_angle
        self.beta_angle = beta_angle
        self.quaternions = [qx, qy, qz, qs]
        self.trajectory = [x,y,z]

        self.geometry_flag = True
        self.previous_tw = self.time.window

        return
コード例 #20
0
import spiceypy as sp
import traceback as tb

do_debug = 'DEBUG' in os.environ

########################################################################
### Parse command-line argument(s), setup parameters

### --hang=<cone half-angle, degrees>
default_hang = 30.0
hangdeg = float(
    ([default_hang] +
     [s[7:] for s in sys.argv[1:] if s.startswith('--hang=')]).pop())

### Conversion factors between degrees and radians
dpr, rpd = sp.dpr(), sp.rpd()

### Cone half-angle and samples of Declinations, from 0 to (89.5-delta)
decdegs = [(0.5 * decdec) - (decdec > 0 and 1e-6 or 0)
           for decdec in range(180)]

### Convert to radians
hangrad = rpd * hangdeg
decrads = [rpd * decdeg for decdeg in decdegs]

### Trig functions of same
tansqhang = math.tan(hangrad)**2
sinhang = math.sin(hangrad)
coshang = math.cos(hangrad)

### List of triples of tan(Dec) squared, cos(Dec), and Dec
コード例 #21
0
ファイル: plot_engineering_v02.py プロジェクト: irthomas/work
def writeTimeLsToFile():
    """make list of time vs ls"""
    SPICE_TARGET = "MARS"
    SPICE_ABERRATION_CORRECTION = "None"
    
    DATETIME_FORMAT = "%d/%m/%Y %H:%M"
    
    
    from datetime import datetime, timedelta
    
    linesToWrite = []
    datetimeStart = datetime(2018, 3, 1, 0, 0, 0, 0)
    for hoursToAdd in range(0, 24*31*12*3, 6): #3 years
        newDatetime = (datetimeStart + timedelta(hours=hoursToAdd)).strftime(DATETIME_FORMAT)
        ls = sp.lspcn(SPICE_TARGET, sp.utc2et(str(datetimeStart + timedelta(hours=hoursToAdd))), SPICE_ABERRATION_CORRECTION) * sp.dpr()
        linesToWrite.append("%s\t%0.1f" %(newDatetime, ls))
    
    writeOutput("Time_vs_Ls.txt", linesToWrite)
コード例 #22
0
ファイル: plot_fov_v02.py プロジェクト: irthomas/work
def analyseLineScan(hdf5Files, hdf5Filenames, titles):
    #    referenceFrame = "TGO_NOMAD_UVIS_OCC"
    referenceFrame = "TGO_NOMAD_SO"
    #    referenceFrame = "TGO_SPACECRAFT"

    fig, ax = plt.subplots(figsize=(FIG_X, FIG_Y))
    #new boresight X direction is assumed to be zero if not calculated
    meanParFit = 0.0
    #new boresight Y direction is assumed to be zero if not calculated
    meanPerpFit = 0.0
    for fileIndex, hdf5File in enumerate(hdf5Files):

        #add indices bounding each pass across the sun
        if hdf5Filenames[fileIndex] in ["20180511_084630_0p3a_SO_1_C"]:
            lineScanCentreIndicesAll = [
                range(60, 120, 1),
                range(280, 340, 1),
                range(400, 490, 1),
                range(630, 720, 1),
                range(760, 850, 1),
                range(990, 1060, 1),
                range(1150, 1200, 1)
            ]
            completeLineScanIndices = range(7)
            analyse = True
            parallel = True
            firstBinRow = 116
            firstBinScience = 0
        elif hdf5Filenames[fileIndex] in ["20180428_023343_0p3a_SO_1_C"]:
            lineScanCentreIndicesAll = [
                range(230, 370, 1),
                range(380, 520, 1),
                range(520, 680, 1)
            ]
            completeLineScanIndices = range(3)
            analyse = False
            parallel = False
            firstBinRow = 116
            firstBinScience = 0
        elif hdf5Filenames[fileIndex] in ["20180522_221149_0p3a_SO_1_C"]:
            lineScanCentreIndicesAll = [
                range(280, 300, 1),
                range(440, 470, 1),
                range(590, 650, 1),
                range(760, 815, 1),
                range(925, 970, 1),
                range(1100, 1120, 1)
            ]
            completeLineScanIndices = range(1, 5, 1)
            analyse = True
            parallel = False
            firstBinRow = 116
            firstBinScience = 0
        elif hdf5Filenames[fileIndex] in ["20180821_193241_0p3a_SO_1_C"]:
            lineScanCentreIndicesAll = [
                range(60, 120, 1),
                range(280, 340, 1),
                range(400, 490, 1),
                range(630, 720, 1),
                range(760, 850, 1),
                range(990, 1060, 1),
                range(1150, 1200, 1)
            ]
            completeLineScanIndices = range(7)
            analyse = True
            parallel = True
            firstBinRow = 128
            firstBinScience = 1
        elif hdf5Filenames[fileIndex] in ["20180828_223824_0p3a_SO_1_C"]:
            lineScanCentreIndicesAll = [
                range(60, 140, 1),
                range(250, 330, 1),
                range(430, 510, 1),
                range(610, 690, 1),
                range(790, 870, 1),
                range(960, 1030, 1),
                range(1150, 1220, 1)
            ]
            completeLineScanIndices = range(1, 5, 1)
            analyse = True
            parallel = False
            firstBinRow = 128
            firstBinScience = 1
        else:
            print("Error: please add filename and indices to list")
            detectorDataAll = get_dataset_contents(hdf5File, "Y")[0]
            print(detectorDataAll.shape)
            plt.figure()
            plt.plot(detectorDataAll[:, :, 200])

        hdf5File = hdf5Files[fileIndex]
        print("Reading in file %i: %s" % (fileIndex + 1, obspaths[fileIndex]))

        detectorDataAll = get_dataset_contents(hdf5File, "Y")[0]
        binsAll = get_dataset_contents(hdf5File, "Bins")[0]
        observationTimeStringsAll = get_dataset_contents(
            hdf5File, "ObservationDateTime")[0]
        #        hdf5File.close()

        centreBinIndices = np.where(
            binsAll[:, 0,
                    0] == firstBinRow)[0]  #window stepping, so find 1st bin
        centreRowIndex = np.where(binsAll[firstBinScience, :, 0] == 128)[
            0]  #then find which row is the centre of the detector in that bin
        centrePixelIndex = 200

        detectorDataCentreFrames = detectorDataAll[
            centreBinIndices, :, :]  #get data for frames containing centre bins
        observationTimeStringsCentreFrames = observationTimeStringsAll[
            centreBinIndices, :]
        observationTimesCentreFrames = np.asfarray([
            np.mean(
                [sp.utc2et(timeCentreFrame[0]),
                 sp.utc2et(timeCentreFrame[1])])
            for timeCentreFrame in list(observationTimeStringsCentreFrames)
        ])

        detectorDataCentrePixel = detectorDataCentreFrames[:, centreRowIndex,
                                                           centrePixelIndex]  #get data for detector centre row

        centreLineCentrePixel = detectorDataCentreFrames[:, centreRowIndex,
                                                         centrePixelIndex].flatten(
                                                         )
        nFrames = centreLineCentrePixel.shape[0]
        maxValuesFrameIndices = []
        maxValuesPixelCounts = []

        plt.figure(figsize=(FIG_X, FIG_Y))
        for lineScanCentreIndices in lineScanCentreIndicesAll:
            centreLineCentrePixelFit = polynomialFitSimple(
                np.arange(len(centreLineCentrePixel[lineScanCentreIndices])),
                centreLineCentrePixel[lineScanCentreIndices], 5)
            indexMaxValue = centreLineCentrePixelFit.argmax()
            maxValuesFrameIndices.append(lineScanCentreIndices[indexMaxValue])
            maxValuesPixelCounts.append(
                centreLineCentrePixelFit[indexMaxValue])
            plt.plot(lineScanCentreIndices, centreLineCentrePixelFit)
        plt.plot(centreLineCentrePixel)
        plt.scatter(maxValuesFrameIndices, maxValuesPixelCounts, c="k")

        maxValuesFrameIndices = np.asarray(maxValuesFrameIndices)
        maxValuesPixelCounts = np.asarray(maxValuesPixelCounts)

        maxValuesVectors = np.asfarray([
            get_vector(datetime, referenceFrame)
            for datetime in observationTimesCentreFrames[maxValuesFrameIndices]
        ])

        #find peak of curves (but don't use for calculation, only for plottingS)
        maxValuesPerpFit = polynomialFitSimple(
            maxValuesFrameIndices[completeLineScanIndices],
            maxValuesPixelCounts[completeLineScanIndices],
            2,
            x_out=np.arange(nFrames))
        plt.plot(np.arange(nFrames), maxValuesPerpFit)
        maxPerpIndex = maxValuesPerpFit.argmax()
        plt.scatter(maxPerpIndex, maxValuesPerpFit[maxPerpIndex])

        unitVectors = np.asfarray([
            get_vector(datetime, referenceFrame)
            for datetime in observationTimesCentreFrames
        ])
        #        marker_colour = np.log(detectorDataCentrePixel+1000).flatten()
        marker_colour = detectorDataCentrePixel.flatten()
        ax.set_xlim([-0.004, 0.004])
        ax.set_ylim([-0.004, 0.004])
        ax.set_xlabel("%s FRAME X" % referenceFrame)
        ax.set_ylabel("%s FRAME Y" % referenceFrame)
        ax.scatter(unitVectors[:, 0],
                   unitVectors[:, 1],
                   c=marker_colour,
                   vmin=300000,
                   alpha=0.5,
                   cmap="jet",
                   linewidths=0)
        ax.set_aspect("equal")

        ax.scatter(maxValuesVectors[:, 0], maxValuesVectors[:, 1], c="k")

        if analyse:
            if parallel:
                #mean X
                meanParFit = np.mean(maxValuesVectors[:, 0])

                ax.scatter(0.0, 0.0, marker="x", c="k", s=160)
                ax.plot([meanParFit, meanParFit],
                        [maxValuesVectors[0, 1], maxValuesVectors[-1, 1]], "k")

                vectorOrigin = [0.0, 0.0, 1.0]
                vectorNew = [meanParFit, meanPerpFit, 0.0]
                vectorNew[2] = np.sqrt(1.0 - vectorNew[0]**2 - vectorNew[1]**2)
                print("vectorNew (1 direction only)")
                print(vectorNew)

                angleSeparation = sp.vsep(vectorOrigin,
                                          vectorNew) * sp.dpr() * 60.0
                print("angleSeparation (1 direction only)")
                print(angleSeparation)
            else:
                #mean Y
                meanPerpFit = np.mean(maxValuesVectors[:, 1])

                ax.scatter(0.0, 0.0, marker="x", c="k", s=160)
                ax.plot([maxValuesVectors[0, 0], maxValuesVectors[-1, 0]],
                        [meanPerpFit, meanPerpFit], "k")

                vectorOrigin = [0.0, 0.0, 1.0]
                vectorNew = [meanParFit, meanPerpFit, 0.0]
                vectorNew[2] = np.sqrt(1.0 - vectorNew[0]**2 - vectorNew[1]**2)
                print("vectorNew (1 direction only)")
                print(vectorNew)

                angleSeparation = sp.vsep(vectorOrigin,
                                          vectorNew) * sp.dpr() * 60.0
                print("angleSeparation (1 direction only)")
                print(angleSeparation)

    if meanParFit != 0.0 and meanPerpFit != 0.0:
        """plot and label new/old boresights on plot"""
        ax.scatter(0.0, 0.0, marker="x", c="k", s=160)
        #        ax.scatter(meanParFit,meanPerpFit, marker="x", c="k", s=160)
        offset = 0.0001
        ax.text(0.0 + offset, 0.0 + offset * 1.5, "Origin")
        #        ax.text(meanParFit+offset,meanPerpFit-offset*2.0,"New Boresight")

        ax.plot([meanParFit, meanParFit],
                [maxValuesVectors[0, 1], maxValuesVectors[-1, 1]], "k")
        ax.plot([meanParFit, meanParFit],
                [np.min(unitVectors[:, 1]),
                 np.max(unitVectors[:, 1])], "k")
        circle1 = plt.Circle((0.0, 0.0),
                             10.0 / 60.0 / sp.dpr(),
                             color='k',
                             alpha=0.1)
        #        circle1 = plt.Circle((meanParFit,meanPerpFit), 10.0/60.0/sp.dpr(), color='k', alpha=0.1)
        ax.add_artist(circle1)
コード例 #23
0
ファイル: crossingextract.py プロジェクト: aaschok/Juno
    def getFGMData(self,fgm_folder):
        #Mag data for each cooresponding crossing is found
        self.file_dict = {}
        p = re.compile(r'\d{7}')
        for parent,child,files in os.walk(fgm_folder):
            for file_name in files:
                if file_name.endswith('.csv'):
                    file_path = os.path.join(fgm_folder,file_name)
                    date = p.search(file_name).group()
                    date_iso = datetime.datetime.strptime(date,'%Y%j').strftime('%Y-%m-%d')
                    
                    match = self.crossingdf.loc[self.crossingdf['DATE'] == date_iso]
                    self.cdfdf = self.cdfdf.append(match,ignore_index = True)
                    if date_iso not in self.file_dict.keys():
                        self.file_dict[date_iso] = file_path

        #The mag data is sorted through and two hours on either side of the crossing is pulled
        for row in self.cdfdf.itertuples():
            date = row[1]
            time = row[2]
            type = row[3]
            
            crossing_stamp = datetime.datetime.strptime(f'{date}T{time}','%Y-%m-%dT%H:%M:%S')
            if date in self.file_dict.keys():
                
                fgm_data = pd.read_csv(self.file_dict[date])
                time_list = [datetime.datetime.fromisoformat(i) for i in fgm_data['SAMPLE UTC']]
                #crossing_index = min(time_list,key=lambda x: abs(x-crossing_stamp))
                crossing_index_plus = time_list.index(min(time_list,key=lambda x: abs(x-(crossing_stamp+datetime.timedelta(hours=2)))))
                crossing_index_minus = time_list.index(min(time_list,key=lambda x: abs(x-(crossing_stamp-datetime.timedelta(hours=2)))))
                save_time_list = [i.isoformat() for i in time_list[crossing_index_minus:crossing_index_plus+1]]

                spice.furnsh('juno_2019_v03.tm')
                spice_time_list = [spice.utc2et(i) for i in save_time_list]
                position_list = []
                latitude_list = []
                x,y,z=[],[],[]
                for spice_time in spice_time_list:
                    pos,lt = spice.spkpos('JUNO',spice_time,'IAU_JUPITER','NONE','JUPITER')
                    pos_vec = spice.vpack(pos[0],pos[1],pos[2])
                    rad_pos,long,lat = spice.reclat(pos_vec)
                    lat *= spice.dpr()
                    rad_pos /= 69911

                    pos,lt = spice.spkpos('JUNO',spice_time,'IAU_SUN','NONE','JUPITER')
                    x.append(pos[0])
                    y.append(pos[1])
                    z.append(pos[2])

                    position_list.append(rad_pos)
                    latitude_list.append(lat)
                spice.kclear()

                file_save_date = crossing_stamp.strftime('%Y%jT%H%M%S') + f'_{type}'
                cdf_file = pycdf.CDF(f'..\crossings\cdf\jno_mag_{file_save_date}.cdf','')
                cdf_file.attrs['Author'] = 'Andrew Schok'
                cdf_file['TIME'] = save_time_list
                cdf_file['BX DATA'] = fgm_data['BX PLANETOCENTRIC'][crossing_index_minus:crossing_index_plus+1]
                cdf_file['BX DATA'].attrs['units'] = 'nT'
                cdf_file['BY DATA'] = fgm_data['BY PLANETOCENTRIC'][crossing_index_minus:crossing_index_plus+1]
                cdf_file['BY DATA'].attrs['units'] = 'nT'
                cdf_file['BZ DATA'] = fgm_data['BZ PLANETOCENTRIC'][crossing_index_minus:crossing_index_plus+1]
                cdf_file['BZ DATA'].attrs['units'] = 'nT'
                cdf_file['X POSITION'] = x
                cdf_file['X POSITION'].attrs['units'] = 'km'
                cdf_file['Y POSITION'] = y
                cdf_file['Y POSITION'].attrs['units'] = 'km'
                cdf_file['Z POSITION'] = z
                cdf_file['Z POSITION'].attrs['units'] = 'km'
                cdf_file['RADIAL DISTANCE'] = position_list
                cdf_file['RADIAL DISTANCE'].attrs['units'] = 'Rj'
                cdf_file['LATITUDE'] = latitude_list
                cdf_file['LATITUDE'].attrs['units'] = 'deg'

                cdf_file.close()
                print(f'Created CDF for {type} crossing {crossing_stamp.strftime("%Y-%m-%dT%H:%M:%S")}')
コード例 #24
0
ファイル: gaiaif_util.py プロジェクト: drbitboy/gaiaif
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
コード例 #25
0
ファイル: vector_testing.py プロジェクト: irthomas/work
    BASE_DIRECTORY = os.path.normcase(r"C:\Users\ithom\Dropbox\NOMAD\Python")
    KERNEL_DIRECTORY = os.path.normcase(r"D:\kernels\kernels\mk")
    FIG_X = 18
    FIG_Y = 9
"""load spiceypy kernels"""
METAKERNEL_NAME = r"em16_ops_win.tm"
os.chdir(KERNEL_DIRECTORY)
sp.furnsh(KERNEL_DIRECTORY + os.sep + METAKERNEL_NAME)
print(sp.tkvrsn("toolkit"))
os.chdir(BASE_DIRECTORY)

origin = np.asfarray([0.0, 0.0, 0.0])

#vectorOffsetX = 3.0**(-1/2)
#vectorOffsetY = 3.0**(-1/2)
vectorOffsetX = np.arcsin(1.9992 / sp.dpr())  #2 degrees
vectorOffsetY = np.arcsin(15.0 * 88 / 90 / sp.dpr())  #15
vectorOffsetZ = np.sqrt(1.0 - vectorOffsetX**2 - vectorOffsetY**2)

vector = np.asfarray([vectorOffsetX, vectorOffsetY, vectorOffsetZ])
vectorMagnitude = sp.vnorm(vector)  #should be 1

vector2 = np.asfarray([0.0, 0.0, 1.0])

angleSeparation = sp.vsep(vector / vectorMagnitude, vector2) * sp.dpr()

#X to Z
#vectorA = np.asfarray([vector[0], 0.0, vector[2]])/sp.vnorm([vector[0], 0.0, vector[2]])
vectorA = np.asfarray([vector[0], 0.0, np.sqrt(1.0 - vector[0]**2)])
angleSeparationA = sp.vsep(vectorA / sp.vnorm(vectorA), vector2) * sp.dpr()
コード例 #26
0
target = "SUN"

datetime_start = datetime(year=2018, month=4, day=21)
datetimes = [datetime_start + timedelta(days=x) for x in range(365 * 4)]

date_strs = [datetime.strftime(x, "%Y-%m-%d") for x in datetimes]
date_ets = [sp.str2et(x) for x in date_strs]
tgo_pos = np.asfarray([
    sp.spkpos(target, time, ref, abcorr, observer)[0]
    for time in list(date_ets)
])

tgo_dist = la.norm(tgo_pos, axis=1)
code = sp.bodn2c(target)
pradii = sp.bodvcd(code, 'RADII', 3)  # 10 = Sun
sun_radius = pradii[1][0]
sun_diameter_arcmins = np.arctan(sun_radius / tgo_dist) * sp.dpr() * 60.0 * 2.0

fig, ax = plt.subplots(figsize=(FIG_X, FIG_Y - 1))

ax.plot_date(datetimes, sun_diameter_arcmins, linestyle="-", ms=0)

ax.set_xlabel("Date")
ax.set_ylabel("Solar diameter as seen from TGO (arcminutes)")
ax.set_title("Apparent diameter of Sun since start of TGO mission")

ax.xaxis.set_major_locator(MonthLocator(bymonth=None, interval=6, tz=None))
fig.tight_layout()
if SAVE_FIGS:
    plt.savefig("sun_apparent_diameter.png")
コード例 #27
0
def geometry(et, bsight, target, frame, sensor, observer=''):

    if not observer:
        observer = sensor

    # Time tag [UTC]
    # pixel id [(x,y)]
    # corner id [(x,y)]

    # Requested geometry

    # lat lon intersection (planetocentric)
    # lat lon subspacecraft
    # lat lon subsolar
    # target distance intersection
    # target angular diameter
    # local solar time intersection
    # phase angle intersection
    # emission angle intersection
    # incidence angle intersection

    #
    # We retrieve the camera information using GETFOV. More info available:
    #
    #   https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/getfov_c.html
    #
    sensor_id = spiceypy.bodn2c(sensor)
    (shape, sensor_frame, ibsight, vectors,
     bounds) = spiceypy.getfov(sensor_id, 100)

    visible = spiceypy.fovtrg(sensor, target, 'ELLIPSOID', frame, 'LT+S',
                              observer, et)

    if not visible:
        return 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

    tarid = spiceypy.bodn2c(target)

    n, radii = spiceypy.bodvrd(target, 'RADII', 3)
    re = radii[0]
    rp = radii[2]
    f = (re - rp) / re

    try:
        #
        # https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/sincpt_c.html
        #
        # For each pixel we compute the possible intersection with the target, if
        # the target is intersected we then compute the illumination angles. We
        # use the following SPICE APIs: SINCPT and ILLUMF
        #
        #   https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/sincpt_c.html
        #   https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/illumf_c.html
        #
        (spoint, trgepc, srfvec) = \
            spiceypy.sincpt('ELLIPSOID', target, et, frame, 'LT+S', observer, sensor_frame, bsight)

        (tarlon, tarlat, taralt) = spiceypy.recgeo(spoint, re, f)
        tardis = spiceypy.vnorm(srfvec)

        #
        # Angular diameter
        #
        tarang = np.degrees(
            2 * np.arctan(max(radii) / spiceypy.vnorm(spoint + srfvec)))

        #
        # https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/illumf_c.html
        #
        (trgenpc, srfvec, phase, incdnc, emissn, visiblef, iluminatedf) = \
             spiceypy.illumf('ELLIPSOID', target, 'SUN', et, frame, 'LT+S', observer, spoint)

        phase *= spiceypy.dpr()
        incdnc *= spiceypy.dpr()
        emissn *= spiceypy.dpr()

        #
        # https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/et2lst_c.html
        #
        #    VARIABLE  I/O  DESCRIPTION
        #    --------  ---  --------------------------------------------------
        #    et         I   Epoch in seconds past J2000 epoch.
        #    body       I   ID-code of the body of interest.
        #    lon        I   Longitude of surface point (RADIANS).
        #    type       I   Type of longitude "PLANETOCENTRIC", etc.
        #    timlen     I   Available room in output time string.
        #    ampmlen    I   Available room in output `ampm' string.
        #    hr         O   Local hour on a "24 hour" clock.
        #    mn         O   Minutes past the hour.
        #    sc         O   Seconds past the minute.
        #    time       O   String giving local time on 24 hour clock.
        #    ampm       O   String giving time on A.M./ P.M. scale.
        (hr, mn, sc, ltime, ampm) = \
            spiceypy.et2lst(et, tarid, tarlon, 'PLANETOCENTRIC', 80, 80)

        #
        # https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/subpnt_c.html
        #
        #    Variable  I/O  Description
        #    --------  ---  --------------------------------------------------
        #    method     I   Computation method.
        #    target     I   Name of target body.
        #    et         I   Epoch in TDB seconds past J2000 TDB.
        #    fixref     I   Body-fixed, body-centered target body frame.
        #    abcorr     I   Aberration correction flag.
        #    obsrvr     I   Name of observing body.
        #    spoint     O   Sub-observer point on the target body.
        #    trgepc     O   Sub-observer point epoch.
        #    srfvec     O   Vector from observer to sub-observer point
        #
        (spoint, trgepc, srfev) = \
            spiceypy.subpnt('INTERCEPT/ELLIPSOID', target, et, frame, 'LT+S', observer)

        (sublon, sublat, subalt) = spiceypy.recgeo(spoint, re, f)

        #
        # https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/subslr_c.html
        #
        #    Variable  I/O  Description
        #    --------  ---  --------------------------------------------------
        #    method     I   Computation method.
        #    target     I   Name of target body.
        #    et         I   Epoch in ephemeris seconds past J2000 TDB.
        #    fixref     I   Body-fixed, body-centered target body frame.
        #    abcorr     I   Aberration correction.
        #    obsrvr     I   Name of observing body.
        #    spoint     O   Sub-solar point on the target body.
        #    trgepc     O   Sub-solar point epoch.
        #    srfvec     O   Vector from observer to sub-solar point.
        #
        (spoint, trgepc, srfev) = \
            spiceypy.subslr('INTERCEPT/ELLIPSOID', target, et, frame, 'LT+S', observer)

        (sunlon, sunlat, sunalt) = spiceypy.recgeo(spoint, re, f)

        return tarlon, tarlat, sublon, sublat, sunlon, sunlat, tardis, tarang, ltime, phase, emissn, incdnc

    except:
        return 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
コード例 #28
0
def caps_crosstrack_spice(tempdatetime, windspeed):
    et = spice.datetime2et(tempdatetime)
    sclkdp = spice.sce2c(
        -82, et)  # converts an et to a continuous encoded sc clock (ticks)

    state, ltime = spice.spkezr("CASSINI", et, "IAU_TITAN", "NONE", "titan")
    ramdir = spice.vhat(state[3:6])
    # print("ramdir",ramdir)

    # Gets Attitude
    sclkdp = spice.sce2c(
        -82, et)  # converts an et to a continuous encoded sc clock (ticks)
    ckgp_output = spice.ckgp(-82000, sclkdp, 0, "IAU_TITAN")
    cmat = ckgp_output[0]
    print("cmat", cmat)

    ram_unit = spice.mxv(cmat, ramdir)  # Ram Unit in SC coords
    # print("ram_unit", ram_unit)
    anglediff = spice.vsepg(
        ram_unit[:2], np.array([0, 1, 0]),
        2)  # Find azimuthal angle between normal boresight and ram direction
    # print("anglediff", anglediff * spice.dpr())
    cassini_ram_mat = spice.rotate(-anglediff, 3)
    # print("cassini_ram_mat", cassini_ram_mat)
    # Rotates rotational axis with actuation
    # cassini_caps_mat = spice.ckgp(-82821, sclkdp, 0, 'CASSINI_CAPS_BASE')[0]  # Rotation matrix of actuation
    # print("cassini_caps_mat", cassini_caps_mat)
    anode_rotational_axis = spice.mxv(cassini_ram_mat,
                                      np.array([1, 0,
                                                0]))  # Rotate with actuator
    print("Rotational Axis", anode_rotational_axis)

    rotationmatrix_1 = spice.spiceypy.axisar(anode_rotational_axis,
                                             -70 * spice.rpd())
    rotationmatrix_2 = spice.spiceypy.axisar(anode_rotational_axis,
                                             70 * spice.rpd())

    ram_unit_rotated1 = spice.mxv(rotationmatrix_1, ram_unit)
    ram_unit_rotated2 = spice.mxv(rotationmatrix_2, ram_unit)
    scframe_spiceplane = spice.psv2pl([0, 0, 0], ram_unit_rotated1,
                                      ram_unit_rotated2)
    print("ram_unit", ram_unit, ram_unit_rotated1, ram_unit_rotated2)
    print("SC frame spice normal",
          spice.psv2pl([0, 0, 0], ram_unit_rotated1, ram_unit_rotated2))
    cmat_t = spice.xpose(cmat)
    ram_unit_rotated1_titan = spice.mxv(
        cmat_t, ram_unit_rotated1)  # Transform back to IAU Titan Frame
    ram_unit_rotated2_titan = spice.mxv(
        cmat_t, ram_unit_rotated2)  # Transform back to IAU Titan Frame
    spiceplanenormal = spice.mxv(cmat_t, spice.pl2nvp(scframe_spiceplane)[0])

    # Old method finding normal in titan frame
    # spiceplane = spice.psv2pl(state[:3], ram_unit_rotated1_titan, ram_unit_rotated2_titan)
    # spiceplanenormal = spice.pl2nvp(spiceplane)[0]

    print("SPICE NORMAL", spiceplanenormal)
    # print("Spice normal, sc frame", scframe_spicenormal_titan)

    if windspeed > 0:
        spiceplanenormal = -1 * spiceplanenormal
        print("spice plane fipped", windspeed, spiceplanenormal)

    print("vsep titan frame",
          spice.vsep(ramdir, spiceplanenormal) * spice.dpr())

    return spiceplanenormal, ram_unit_rotated1_titan, ram_unit_rotated2_titan
コード例 #29
0
ファイル: fov_cmd.py プロジェクト: drbitboy/gaiaif
  --mags (Retrieve all magnitudes, phot_*_mean_mag)
  --heavy (Retrieve source_id, errors and corr. coeffs, , *error, *corr)
  --obspos=X,Y,Z (Observer position, km, triggers parallax correction)
  --obsvel=VX,VY,VZ (Observer velocity, km/s, triggers stellar aberration correction)
  --obsy=YYYY.ddd (Observer time, fractional year, triggers proper motion correction)

"""

import os
import sys
import pprint
import sqlite3 as sl3
import spiceypy as sp
import gaiaif_util as gifu

dpr = sp.dpr()

### Allowed magnitude types
magtypes = set('g bp rp'.split())

do_debug = 'DEBUG' in os.environ


########################################################################
def gaiaif(fov_vertices
          ,rtn_limit=200
          ,magmin=None,magmax=None
          ,mag_type='g'
          ,radec_buffer=0.0   ### Not yet implemented
          ,gaia_sl3='gaia.sqlite3'
          ,j2000=False
コード例 #30
0
def cassini_titan_test(flyby, anodes=False):
    times = []
    states = []
    lons, lats, alts = [], [], []
    crossvecs_lonlatalts = []
    crossvecs_lonlatalts_spicenormal = []
    cmats = []
    vecs = []
    anode_vecs = []
    anode_seps = [[], [], [], [], [], [], [], []]
    anodes1, anodes8 = [], []
    crossvecs = []
    angularseparations = []
    beamanodes = []
    spiceplanenormals = []

    windsdf = pd.read_csv("crosswinds_full.csv", index_col=0, parse_dates=True)
    tempdf = windsdf[windsdf['Flyby'] == flyby]
    for tempdatetime, negwindspeed, poswindspeed in zip(
            pd.to_datetime(tempdf['Bulk Time']),
            tempdf["Negative crosstrack velocity"],
            tempdf["Positive crosstrack velocity"]):
        print("---------")
        print(tempdatetime)
        times.append(tempdatetime)
        beamanodes.append(np.mean(ELS_ramanodes(tempdatetime)) + 1)
        states.append(cassini_phase(
            tempdatetime.strftime('%Y-%m-%dT%H:%M:%S')))
        # print(states[-1])
        lon, lat, alt = spice.recpgr("TITAN", states[-1][:3],
                                     spice.bodvrd("TITAN", 'RADII', 3)[1][0],
                                     1.44e-4)
        lons.append(lon * spice.dpr())
        lats.append(lat * spice.dpr())
        alts.append(alt)
        # vecs.append(cassini_act_2_titan(tempdatetime))
        crossvec = caps_crosstrack(tempdatetime,
                                   np.mean([negwindspeed, poswindspeed]))
        print("crossvec", crossvec)
        testspicenormal, anode1, anode8 = caps_crosstrack_spice(
            tempdatetime, np.mean([negwindspeed, poswindspeed]))
        anodes1.append(anode1)
        anodes8.append(anode8)
        spiceplanenormals.append(testspicenormal)
        print("test spice normal", testspicenormal)
        jacobian = spice.dpgrdr("TITAN", states[-1][0], states[-1][1],
                                states[-1][2],
                                spice.bodvrd('TITAN', 'RADII',
                                             3)[1][0], 1.44e-4)
        # print("jacobian", jacobian)
        crossvec_lonlatalt = spice.mxv(jacobian, spice.vhat(crossvec))
        crossvec_lonlatalt_spicenormal = spice.mxv(jacobian, testspicenormal)

        # print("recpgr", lon, lat, alt)
        # print("crossvec latlon", crossvec_lonlatalt)
        # print("crossvec latlon vhat", spice.vhat(crossvec_latlon))
        crossvecs.append(crossvec)
        crossvecs_lonlatalts.append(crossvec_lonlatalt)
        crossvecs_lonlatalts_spicenormal.append(crossvec_lonlatalt_spicenormal)
        # print("Time", tempdatetime)
        # print("position", states[-1][:3])
        # print("velocity", spice.vhat(states[-1][3:]))
        # print("direction", spice.vhat(vecs[-1]))

        # if anodes:
        #     anode_vecs.append(caps_all_anodes(tempdatetime))
        #     print("anode vecs 1 & 8", anode_vecs[-1][0], anode_vecs[-1][7])
        #     # spiceplanenormal = spice.psv2pl(states[-1][:3],anode_vecs[-1][0],anode_vecs[-1][7])
        #     # print("SPICE NORMAL", spice.pl2nvp(spiceplanenormal))
        #     #
        #     # spiceplanenormals.append(-1*spice.pl2nvp(spiceplanenormal)[0])
        #     # print("Crossvec", crossvec)
        #     for anodecounter, i in enumerate(anode_vecs[-1]):
        #         # print(anodecounter,anode_vecs[-1][anodecounter])
        #         anode_seps[anodecounter].append(
        #             spice.vsep(spice.vhat(states[-1][3:]), spice.vhat(anode_vecs[-1][anodecounter])) * spice.dpr())
        # print("anodeseps",anode_seps)
        # print("Angular Separation", spice.vsep(spice.vhat(states[-1][3:]), spice.vhat(vecs[-1])) * spice.dpr())

    x, y, z, u, v, w = [], [], [], [], [], []

    for i in states:
        x.append(i[0])
        y.append(i[1])
        z.append(i[2])

    # CAPS direction
    for i in vecs:
        u.append(i[0])
        v.append(i[1])
        w.append(i[2])

    # Crosstrack
    u2, v2, w2 = [], [], []
    for j in crossvecs:
        u2.append(j[0])
        v2.append(j[1])
        w2.append(j[2])

    # SPICE plane normal
    u3, v3, w3 = [], [], []
    for j in spiceplanenormals:
        u3.append(j[0])
        v3.append(j[1])
        w3.append(j[2])

    # Ram Direction
    u1, v1, w1 = [], [], []
    for i in states:
        u1.append(i[3])
        v1.append(i[4])
        w1.append(i[5])

    fig = plt.figure()

    u = np.linspace(0, 2 * np.pi, 50)
    v = np.linspace(0, np.pi, 50)
    x_sphere = 2574.7 * np.outer(np.cos(u), np.sin(v))
    y_sphere = 2574.7 * np.outer(np.sin(u), np.sin(v))
    z_sphere = 2574.7 * np.outer(np.ones(np.size(u)), np.cos(v))

    ax = fig.add_subplot(111, projection='3d')
    # Plot the surface
    # ax.plot_wireframe(x_sphere, y_sphere, z_sphere, color='b')
    # ax.plot(x, y, z, alpha=0.5, color='k')
    if anodes:
        for timecounter, (i, j) in enumerate(zip(anodes1, anodes8)):
            X = x[timecounter]
            Y = y[timecounter]
            Z = z[timecounter]
            # print(i)
            # for anodecounter, j in enumerate(i):
            #     if anodecounter in [0, 7]:
            #         ax.quiver(X, Y, Z, j[0], j[1], j[2], length=20, color='C' + str(anodecounter))
            # print(timecounter, i, j)
            ax.quiver(X, Y, Z, i[0], i[1], i[2], length=30, color='C1')
            ax.quiver(X, Y, Z, j[0], j[1], j[2], length=30, color='C2')

    ax.quiver(x, y, z, u2, v2, w2, length=30, color='m')
    ax.quiver(x, y, z, u1, v1, w1, length=5, color='k')
    ax.quiver(x, y, z, u3, v3, w3, length=30, color='r')
    ax.set_xlabel("X")
    ax.set_ylabel("Y")
    ax.set_zlabel("Z")
    ax.set_xlim(min(x), max(x))
    ax.set_ylim(min(y), max(y))
    ax.set_zlim(min(z), max(z))

    dlat, dlon = [], []
    for i in crossvecs_lonlatalts:
        dlat.append(i[1])
        dlon.append(i[0])

    dlat_spicenormal, dlon_spicenormal = [], []
    for i in crossvecs_lonlatalts_spicenormal:
        dlat_spicenormal.append(i[1])
        dlon_spicenormal.append(i[0])

    fig2, ax2 = plt.subplots()
    ax2.plot(lons, lats)
    ax2.quiver(lons, lats, dlon, dlat)
    ax2.quiver(lons, lats, dlon_spicenormal, dlat_spicenormal, color='r')
    ax2.set_xlabel("Longitude")
    ax2.set_ylabel("Latitude")
    ax2.grid()