Exemple #1
0
    def computeOccultations(self, observer_in, occultation_bodies_in,
                            target_in, target_shape_in, target_frame_in,
                            step_size_in, aberration_correction_in,
                            greg_format_string_in):

        self.greg_format_string = greg_format_string_in
        split_string = self.greg_format_string.split(' ')
        self.time_system_string = [i for i in split_string if '::' in i][0][2:]

        self.observer = str(observer_in)
        self.occultation_bodies = occultation_bodies_in
        self.target = target_in
        self.target_shape = target_shape_in
        self.target_frame = target_frame_in
        self.search_step_size = step_size_in
        self.aberration_correction = aberration_correction_in
        self.cumulative_results = {}
        for body in self.occultation_bodies:
            # add a new key to the results dictionary for this body
            self.cumulative_results[body.name] = []
            for occultation_type in body.occultation_types:
                body.search_start_ET_seconds = spice.str2et(body.search_start)
                body.search_end_ET_seconds = spice.str2et(body.search_end)
                spice.wninsd(body.search_start_ET_seconds,
                             body.search_end_ET_seconds,
                             self.SPICE_search_window)
                spice.gfoclt(occultation_type, body.name, body.shape,
                             body.frame, self.target, self.target_shape,
                             self.target_frame, self.aberration_correction,
                             self.observer, self.search_step_size,
                             self.SPICE_search_window, self.results_window)
                winsiz = spice.wncard(self.results_window)
                for body_index in range(winsiz):
                    [intbeg, intend] = spice.wnfetd(self.results_window,
                                                    body_index)
                    btmstr = spice.timout(intbeg, self.greg_format_string)
                    etmstr = spice.timout(intend, self.greg_format_string)
                    occultation_event = OccultationEvent()
                    occultation_event.start = btmstr
                    occultation_event.stop = etmstr
                    occultation_event.start_JD = greg2Julian(btmstr)
                    occultation_event.stop_JD = greg2Julian(etmstr)
                    occultation_event.duration = intend - intbeg
                    occultation_event.type = occultation_type
                    occultation_event.observer = self.observer
                    occultation_event.occulting_body = body.name
                    occultation_event.occulting_body_shape = body.shape
                    occultation_event.target = self.target
                    occultation_event.target_body_shape = self.target_shape
                    self.cumulative_results[body.name].append(
                        occultation_event)
Exemple #2
0
def occultations(body1, body2, start, end):
    cnfine = spiceypy.utils.support_types.SPICEDOUBLE_CELL(MAXWIN)
    result = spiceypy.utils.support_types.SPICEDOUBLE_CELL(MAXWIN)

    # Obtain the TDB time bounds of the confinement
    # window, which is a single interval in this case.
    et0 = spiceypy.str2et(start)
    et1 = spiceypy.str2et(end)

    # Insert the time bounds into the confinement window
    spiceypy.wninsd(et0, et1, cnfine)

    # 15-minute step. Ignore any occultations lasting less than 15 minutes.
    # Units are TDB seconds.
    step = 900.0

    obsrvr = "Earth"

    # Loop over the occultation types.
    for occtype in types:
        # For each type, do a search for both transits of
        # Titan across Saturn and occultations of Titan by Saturn.
        for j in range(2):
            if not j:
                front = body1
                fframe = "IAU_" + body1
                back = body2
                bframe = "IAU_" + body2
            else:
                front = body2
                fframe = "IAU_" + body2
                back = body1
                bframe = "IAU_" + body1

            spiceypy.gfoclt(occtype, front, "ellipsoid", fframe, back,
                            "ellipsoid", bframe, "lt", obsrvr, step, cnfine,
                            result)

            # Display the results
            print()
            title = spiceypy.repmc("Condition: # occultation of # by #", "#",
                                   occtype)
            title = spiceypy.repmc(title, "#", back)
            title = spiceypy.repmc(title, "#", front)
            print(title)

            for r in result:
                print(spiceypy.timout(r, "YYYY Mon DD HR:MN:SC"))
def core():
    class SpiceVariables:
        obs = '-74'  # NAIF code for MEX
        target = 'MARS ODYSSEY'  # NAIF code for TGO ['EARTH'/'SUN'/ a groundstation etc]
        obsfrm = 'IAU_MARS'
        abcorr = 'NONE'
        crdsys = 'LATITUDINAL'
        coord = 'LATITUDE'
        stepsz = 100.0  # Check every 300 seconds if there is an occultation
        MAXILV = 100000  #Max number of occultations that can be returned by gfoclt
        bshape = 'POINT'
        fshape = 'DSK/UNPRIORITIZED'
        front = 'MARS'
        fframe = 'IAU_MARS'
        TFMT = 'YYYY-MM-DD HR:MN:SC'  # Format that Cosmographia understands

    sv = SpiceVariables()

    #-----------------------------------------------------<VALUES TO EDIT REGULARLY>----------------------------------------
    # If you only wish to analysis mutual [cross-link] occultation between MEX and TGO, then this is the only section that
    # needs to be edited
    start = '2020 MAR 1'
    stop = '2020 MAR 3'
    OCCSELECTION = 17  # Which occultation do you wish to see in Cosmographia? [optional]
    here = path.abspath(path.dirname(__file__))
    PathtoMetaKernel1 = here + '/TGO/krns/mk/em16_plan.tm'
    PathtoMetaKernel2 = here + '/MEX/krns/mk/MEX_OPS.tm'
    #-----------------------------------------------------------------------------------------------------------------------

    spice.furnsh(PathtoMetaKernel1)
    spice.furnsh(PathtoMetaKernel2)

    sv = SpiceVariables()

    # Setting Variables
    ingresslist = np.array([1.0], dtype=float)
    etbeg = spice.str2et(start)
    etend = spice.str2et(stop)

    # Form a windows that gfoclt can populate
    window = stypes.SPICEDOUBLE_CELL(2)
    spice.wninsd(etbeg, etend, window)
    occwindow = stypes.SPICEDOUBLE_CELL(sv.MAXILV)

    #find occultation windows between the dates listed above [ most comp cost in this function]
    spice.gfoclt('ANY', sv.front, sv.fshape, sv.fframe, sv.target, sv.bshape,
                 'J2000', sv.abcorr, sv.obs, sv.stepsz, window, occwindow)

    winsiz = spice.wncard(occwindow)  # Find cardinality (number of windows)

    #initialize lists to form dataframe
    lon, lat, dist, sza, angle = (np.ones(winsiz - 1) for i in range(5))

    # Enter the ingress epochs into a dataframe
    occlist = np.ones((winsiz, 3))
    for i in range(winsiz):
        [ingress, egress
         ] = spice.wnfetd(occwindow,
                          i)  # extract the begining and ends of the windows
        if i == 1:
            ingresslist = ingress
        else:
            ingresslist = np.append(ingresslist, [ingress])

    occs = pd.DataFrame(ingresslist, columns=['Time'])
    occ = occs.Time[OCCSELECTION]

    return occ


# sv = main.SpiceVariables()
# occ = core()
#print("strange result:", occ)

# #print(result)

# #form the dataframe
# length = 120
# occs = pd.DataFrame(ingresslist, columns=['Time'])
# residualdoppler = np.zeros(length)
# velocitydoppler = np.zeros(length)
# RESIDUALSUM = np.zeros(length)
# #Calculate the residual doppler as the sum of the neutral and ionosphere
# tic  = timer.perf_counter()
# for time in tqdm(range(length)): #begin time at occultation epoch and go to 2 mins pior

#     ray, dist, totalperiods, remainingdistance = main.producegeometrylamda(occs.Time[OCCSELECTION], sv, time*8)# Produce geometry in wavelenghts to investigate electric distance

#     _,_,_,_, alt = main.Location(occs.Time[OCCSELECTION], sv, time*8)

#     ionoresidual = atmosphere.iono(ray[2,:],totalperiods)
#     neutralresidual = atmosphere.neutral(ray[2,:],totalperiods)
#     residual = 1 + (ionoresidual + neutralresidual)

#     # plt.plot(range(totalperiods),residual[0,:])
#     # plt.title("Refractive Index through Propergation of Ray")
#     # plt.xlabel("MEX->TGO distance (km)")
#     # plt.ylabel("Refractive Index")
#     # plt.show()

#     #DO A TEST TO SEE IF THE NET REFRACTIVE INDEX CHANGES OVER TIME, THEN U CAN HONE IN ON THE ERRRO
#     # account for the plus 1

#     [electricdistance, geometric, resdopplershift] = main.doppler(residual, totalperiods, dist, remainingdistance)
#     miss = electricdistance - dist + remainingdistance # a possitive number as electric distance is greater that geometric due to iono
#     howwrongurcodeis = geometric - dist # is this purly due to rounding of that 9945 (each 1 is ~685 m)
#     residualdoppler[time] = resdopplershift

#     #find the geometric doppler too UNTESTED MODULE
#     sc2scstates = spice.spkezr(sv.target, (occs.Time[OCCSELECTION] - time*8), sv.fframe, 'LT+S', sv.obs)
#     velocityvector = sc2scstates[0][3:6]
#     velocityvector = velocityvector[0:3]
#     positionalvector =  sc2scstates[0][0:3]
#     positionalvector = positionalvector[0:3]
#     velocityangle = spice.vsep( positionalvector, velocityvector) #rads
#     relativevelocity = np.linalg.norm(velocityvector) * np.cos(velocityangle)
#     geometricdopplershift = -(relativevelocity/constants.c) * 437.1e6
#     velocitydoppler[time] = geometricdopplershift *1000 # becuase spice is in km and c is in m

# toc = timer.perf_counter()
# passingtime = toc-tic
# print('elapsed time in seconds:', passingtime)
# noise = np.random.normal(0,50,velocitydoppler.shape)
# RESIDUALSUM = residualdoppler + velocitydoppler + noise

# fig, ax = plt.subplots(3)
# ax[0].plot(range(-960,0,8),velocitydoppler[: : -1] )
# ax[0].set_title('Geometric', loc='left')
# ax[0].set_xlabel('Time after Occ (s)')
# ax[0].set_ylabel('Doppler Shift (Hz)')
# ax[1].plot(range(-960,0,8),residualdoppler[: : -1] )
# ax[1].set_title('Residual', loc='left')
# ax[1].set_xlabel('Time after Occ (s)')
# ax[1].set_ylabel('Doppler Shift (Hz)')
# ax[2].plot(range(-960,0,8),RESIDUALSUM[: : -1])
# ax[2].set_title('Product + Noise', loc='left')
# ax[2].set_xlabel('Time to Horizon Epoch (s)')
# ax[2].set_ylabel('Doppler Shift (Hz)')
# plt.show()

# #then add noise
Exemple #4
0
    spice.furnsh(sd.pck00010)

    sc = SC({
        'date0': '2021-03-03 22:10:35 TDB',
        'coes': [7480.0, 0.09, 5.5, 6.26, 5.95, 0.2],
        'tspan': '40',
    })

    st.write_bsp(sc.ets, sc.states[:, :6], {'bsp_fn': 'leo.bsp'})
    spice.furnsh('leo.bsp')

    et0 = spice.str2et('2021-03-03 22:10:40 TDB')
    etf = spice.str2et('2021-03-04 TDB')

    timecell = spice.utils.support_types.SPICEDOUBLE_CELL(2)
    spice.appndd(et0, timecell)
    spice.appndd(etf, timecell)

    cell = spice.gfoclt('ANY', '399', 'ELLIPSOID', 'IAU_EARTH', '10',
                        'ELLIPSOID', 'IAU_SUN', 'LT', '-999', 120.0, timecell)
    ets_SPICE = spice.wnfetd(cell, 0)
    cal0 = spice.et2utc(ets_SPICE[0], 'C', 1)
    cal1 = spice.et2utc(ets_SPICE[1], 'C', 1)
    print('\n*** SPICE RESULTS ***')
    print(f'{cal0} --> {cal1}')

    sc.plot_3d()
    sc.calc_eclipses(vv=True)

    sc.plot_eclipse_array({'time_unit': 'seconds', 'show': True})
# pd.DataFrame(geometricdopplershift).to_csv("geometricdopplershift.csv")

# Setting Variables
ingresslist = np.array([1.0], dtype=float)
egresslist = np.array([1.0], dtype=float)
etbeg = spice.str2et(start)
etend = spice.str2et(stop)

# Form a windows that gfoclt can populate
window = stypes.SPICEDOUBLE_CELL(2)
spice.wninsd(etbeg, etend, window)
occwindow = stypes.SPICEDOUBLE_CELL(sv.MAXILV)

# find occultation windows between the dates listed above [ most comp cost in this function]
spice.gfoclt('ANY', sv.front, sv.fshape, sv.fframe, sv.target, sv.bshape, '',
             sv.abcorr, sv.obs, sv.stepsz, window, occwindow)

winsiz = spice.wncard(occwindow)  # Find cardinality (number of windows)

# initialize lists to form dataframe
lon, lat, dist, sza, angle = (np.ones(winsiz - 1) for i in range(5))

# Enter the ingress epochs into a dataframe
occlist = np.ones((winsiz, 3))
for i in range(winsiz):
    # extract the begining and ends of the windows
    [ingress, egress] = spice.wnfetd(occwindow, i)
    if i == 1:
        ingresslist = ingress
        egresslist = egress
    else: