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)
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
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: