def test_found_error_checker(): with pytest.raises(( spice.exceptions.SpiceyError, spice.exceptions.SpiceyPyError, spice.exceptions.NotFoundError, )): spice.bodc2n(-9991) spice.reset()
def test_found_check(): spice.kclear() spice.found_check_off() name, found = spice.bodc2n(-9991) assert not found spice.kclear() with spice.found_check(): with pytest.raises(spice.stypes.SpiceyError): name = spice.bodc2n(-9991) assert not spice.get_found_catch_state() spice.found_check_on() assert spice.get_found_catch_state() spice.kclear()
def test_disable_found_catch(): spice.kclear() with spice.no_found_check(): name, found = spice.bodc2n(-9991) assert not found with pytest.raises(spice.stypes.SpiceyError): spice.bodc2n(-9991) # try more hands on method spice.found_check_off() name, found = spice.bodc2n(-9991) assert not found spice.found_check_on() spice.kclear()
def info(self): """Read and Output info about the loaded kernels """ spice.kclear() spice.furnsh(self.metakernel) self.spkList = [ self.SpkPlanet, self.SpkEros, self.SpkEros2, self.SpkMath, self.SpkNearLanded, self.SpkNearOrbit, self.SpkStations ] self.ckList = [self.Ck] self.pckList = [self.PckEros1, self.PckEros2] # check SPK coverage self.bodies = {} self.bodies_coverage = {} for spk in self.spkList: idcell = spice.spkobj(spk) for code in idcell: cover = spice.stypes.SPICEDOUBLE_CELL(1000) spice.spkcov(spk, code, cover) self.bodies[str(code)] = spice.bodc2n(code) self.bodies[spice.bodc2n(code)] = code self.bodies_coverage[str(code)] = [x for x in cover] self.bodies_coverage[spice.bodc2n(code)] = [x for x in cover] # check CK coverage self.ckframes = {} self.ckframes_coverage = {} for ck in self.ckList: idcell = spice.ckobj(ck) for code in idcell: cover = spice.ckcov(ck, code, True, 'SEGMENT', 0.0, 'TDB') self.ckframes[str(code)] = spice.frmnam(code) self.ckframes[spice.frmnam(code)] = code self.ckframes_coverage[str(code)] = [x for x in cover] self.ckframes_coverage[spice.frmnam(code)] = [x for x in cover] # check pck coverage self.pckframes = {} for pck in self.pckList: ids = spice.stypes.SPICEINT_CELL(1000) spice.pckfrm(pck, ids) for code in ids: self.pckframes[str(code)] = spice.frmnam(code) self.pckframes[spice.frmnam(code)] = code spice.kclear()
def __init__(self, sensor, host=object(), target=object(), time=object()): if isinstance(sensor, str): name = sensor id = cspice.bodn2c(sensor) else: id = sensor name = cspice.bodc2n(sensor) room = 99 shapelen = 1000 framelen = 1000 fov_shape, frame, bsight, n, fov_bounds = cspice.getfov( id, room, shapelen, framelen) self.host = host self.target = target self.time = time self.name = name self.id = id self.fov_shape = fov_shape self.frame = frame self.bsight_ins = bsight self.fov_bounds = fov_bounds self.bsight_obs = [] self.spoint = []
def naifName(bodyInt): try: naifName = spice.bodc2n(bodyInt) return naifName except spice.stypes.SpiceyError as e: print("ERROR: INVALID SPICE NAIF ID ENTERED") raise e
def _recursive_call(i): if i <= 0: return else: with spice.no_found_check(): name, found = spice.bodc2n(-9991) assert not found _recursive_call(i - 1)
def search_solar_objects(obsinfo): solar_objects = [] count = spice.ktotal("spk") for which in range(count): filename, _filetype, _source, _handle = spice.kdata(which, "spk") ids = spice.spkobj(filename) for i in range(spice.card(ids)): obj = ids[i] target = spice.bodc2n(obj) if is_target_in_fov( obsinfo.inst, target, obsinfo.et, obsinfo.abcorr, obsinfo.obsrvr, ): solar_objects.append(get_solar_object(obsinfo, obj, target)) return solar_objects
def __init__(self, body, time=object(), target=None): if isinstance(body, str): name = body id = spiceypy.bodn2c(body) else: id = body name = spiceypy.bodc2n(body) if target: self.target = target self.name = name self.id = id self.time = time # # Parameters for the Geometry Computation # self.previous_tw = [] self.geometry_flag = False
def id(self, id): self._id = id try: self._name = spiceypy.bodc2n(id) except spiceytypes.SpiceyError: raise ValueError(f'id "{id}" not known by SPICE')
def test_foundErrorChecker(): with pytest.raises(spice.stypes.SpiceyError): spice.bodc2n(-9991) spice.reset()
def detectCloseApproaches(self, output_file, spacecraft_SPICE_ID, body_SPICE_ID, body_radius, epoch_windows): for window in epoch_windows: # create a close approach object self.close_approaches.append(CloseApproach()) self.close_approaches[-1].target_body_SPICE_ID = body_SPICE_ID self.close_approaches[-1].target_body = spice.bodc2n(body_SPICE_ID) left_epoch = spice.str2et(window[0]) right_epoch = spice.str2et(window[1]) middle_epoch = (right_epoch - left_epoch) / 2.0 + left_epoch left_state, left_light_times = spice.spkez(spacecraft_SPICE_ID, left_epoch, 'J2000', 'NONE', body_SPICE_ID) right_state, right_light_times = spice.spkez( spacecraft_SPICE_ID, right_epoch, 'J2000', 'NONE', body_SPICE_ID) middle_state, middle_light_times = spice.spkez( spacecraft_SPICE_ID, middle_epoch, 'J2000', 'NONE', body_SPICE_ID) left_distance = np.sqrt(left_state[0]**2 + left_state[1]**2 + left_state[2]**2) right_distance = np.sqrt(right_state[0]**2 + right_state[1]**2 + right_state[2]**2) middle_distance = np.sqrt(middle_state[0]**2 + middle_state[1]**2 + middle_state[2]**2) # handle the case where left epoch is post periapse and we must be on an ellipse if middle_distance > left_distance and middle_distance > right_distance: # either left or right must be the closest approach if left_distance > right_distance: # right is closest approach self.close_approaches[-1].spacecraft_state = right_state else: # left is closest approach self.close_approaches[-1].spacecraft_state = left_state self.close_approaches[ -1].spacecraft_altitude = left_distance - body_radius break # middle must be closer than left and right # we need to determine if our middle is before or after periapse # look a little bit into the future to see if we are getting closer to the body or farther away peek_epoch = middle_epoch + 1.0 peek_state, middle_light_times = spice.spkez( spacecraft_SPICE_ID, peek_epoch, 'J2000', 'NONE', body_SPICE_ID) peek_distance = np.sqrt(peek_state[0]**2 + peek_state[1]**2 + peek_state[2]**2) if peek_distance > middle_distance: # we have passed periapse, therefore we need to bracket with left_epoch right_epoch = middle_epoch else: left_epoch = middle_epoch iterations = 0 tol = 0.001 while iterations < 100: middle_epoch = (right_epoch - left_epoch) / 2.0 + left_epoch left_state, left_light_times = spice.spkez( spacecraft_SPICE_ID, left_epoch, 'J2000', 'NONE', body_SPICE_ID) right_state, right_light_times = spice.spkez( spacecraft_SPICE_ID, right_epoch, 'J2000', 'NONE', body_SPICE_ID) middle_state, middle_light_times = spice.spkez( spacecraft_SPICE_ID, middle_epoch, 'J2000', 'NONE', body_SPICE_ID) left_distance = np.sqrt(left_state[0]**2 + left_state[1]**2 + left_state[2]**2) right_distance = np.sqrt(right_state[0]**2 + right_state[1]**2 + right_state[2]**2) middle_distance = np.sqrt(middle_state[0]**2 + middle_state[1]**2 + middle_state[2]**2) if np.abs(left_distance - right_distance) < tol: closest_approach_distance = middle_distance break # determine where the left, middle and right points are located w.r.t. periapse time_step = 0.001 middle_peek_state, middle_light_times = spice.spkez( spacecraft_SPICE_ID, middle_epoch + time_step, 'J2000', 'NONE', body_SPICE_ID) middle_peek_distance = np.sqrt(middle_peek_state[0]**2 + middle_peek_state[1]**2 + middle_peek_state[2]**2) if middle_peek_distance - middle_distance < 0.0: left_epoch = middle_epoch elif middle_peek_distance - middle_distance > 0.0: right_epoch = middle_epoch self.close_approaches[ -1].Julian_date = middle_epoch / 86400.0 + 2451545.0 self.close_approaches[-1].spacecraft_state = middle_state self.close_approaches[ -1].spacecraft_altitude = closest_approach_distance - body_radius
def test_error_to_str(): try: spice.bodc2n(-9991) except spice.exceptions.SpiceyError as sp: assert str(sp) != ""
def cov_int(object_cov, object_id, kernel, time_format='TDB', global_boundary=False, report=False): """ Generates a list of time windows out of a SPICE cell for which either the SPICE API spkcov_c or ckcov_c have been run. :param object_cov: SPICE :type object_cov: :param object_id: Object ID or Name for which we provide the coverage :type object_id: Union[str, int] :param kernel: Kernel name for which the coverage is being checked :type kernel: str :param time_format: Desired output format; 'UTC' or 'CAL' :type time_format: str :param global_boundary: Boolean to indicate whether if we want all the coverage windows or only the absolute start and finish coverage times :type global_boundary: bool :param report: If True prints the resulting coverage on the screen :type report: bool :return: Time Windows in the shape of a list :rtype: list """ boundaries = False if '/' in kernel: kernel = kernel.split('/')[-1] # # Reporting should only be activated if we are not asking for global # boundaries. # if report and not global_boundary: try: body_name = spiceypy.bodc2n(object_id) except: body_name = spiceypy.frmnam(object_id, 60) print("Coverage for {} in {} [{}]:".format(body_name, kernel, time_format)) number_of_intervals = list(range(spiceypy.wncard(object_cov))) interval_start_list = [] interval_finish_list = [] coverage = [] for element in number_of_intervals: et_boundaries = spiceypy.wnfetd(object_cov, element) if time_format == 'CAL' or time_format == 'UTC': boundaries = et2cal(et_boundaries, format=time_format) else: boundaries = et_boundaries interval_start = boundaries[0] interval_finish = boundaries[1] if report and not global_boundary: print("Interval {}: {} - {}\n".format(element, boundaries[0], boundaries[1])) coverage.append(interval_start) coverage.append(interval_finish) interval_start_list.append(interval_start) interval_finish_list.append(interval_finish) # # If the global_boundary parameter is set the only output is the global # coverage start and finish # if global_boundary: start_time = min(interval_start) finish_time = max(interval_finish) coverage = et2cal([start_time, finish_time], format=time_format) return coverage
def printReport(self, SPICEbody=399, reportfilename='default_body_distance_report.csv', units='AU'): #we need to load all of the SPICEness import spiceypy import os spiceypy.furnsh(self.myOptions.universe_folder + '/ephemeris_files/' + self.myOptions.SPICE_leap_seconds_kernel) spiceypy.furnsh(self.myOptions.universe_folder + '/ephemeris_files/' + self.myOptions.SPICE_reference_frame_kernel) for dirpath, dirnames, filenames in os.walk( self.myOptions.universe_folder + '/ephemeris_files/'): for file in filenames: sourcefile = os.path.join(dirpath, file) if sourcefile.endswith('.bsp'): spiceypy.furnsh(sourcefile) with open(reportfilename, 'w') as file: #all operations file.write( 'Gregorian date (ET/TDB), Julian date (ET/TDB), Spacecraft distance from ' + spiceypy.bodc2n(SPICEbody) + ' (' + str(SPICEbody) + ') ' + ' (' + units + ')\n') for recordIndex in range(0, len(self.ephemeris_file_data)): myRecord = self.ephemeris_file_data[recordIndex] epoch = myRecord.julian_date seconds_since_J2000 = spiceypy.str2et(str(epoch) + " JD TDB") x_spacecraft = myRecord.spacecraft_position_x y_spacecraft = myRecord.spacecraft_position_y z_spacecraft = myRecord.spacecraft_position_z try: [body_state, light_time] = spiceypy.spkez(SPICEbody, seconds_since_J2000, 'J2000', 'NONE', 10) except: print( 'I don\'t have enough information to tell you the position of ' + str(SPICEbody) + ' with respect to the Sun on ' + epoch + '\n') x_body = body_state[0] y_body = body_state[1] z_body = body_state[2] x_relative = x_spacecraft - x_body y_relative = y_spacecraft - y_body z_relative = z_spacecraft - z_body r_relative = (x_relative**2 + y_relative**2 + z_relative**2)**0.5 if units == 'AU': r_relative /= 149597870.691 elif units != 'km': raise ('I don\'t know what a ' + units + ' is!') file.write(myRecord.gregorian_date + ',' + str(myRecord.julian_date) + ',' + str(r_relative) + '\n') #now we can unload all the SPICE kernels spiceypy.unload(self.myOptions.universe_folder + '/ephemeris_files/' + self.myOptions.SPICE_leap_seconds_kernel) spiceypy.unload(self.myOptions.universe_folder + '/ephemeris_files/' + self.myOptions.SPICE_reference_frame_kernel) for dirpath, dirnames, filenames in os.walk( self.myOptions.universe_folder + '/ephemeris_files/'): for file in filenames: sourcefile = os.path.join(dirpath, file) if sourcefile.endswith('.bsp'): spiceypy.unload(sourcefile)
def test_foundErrorChecker(): with pytest.raises(spice.stypes.SpiceyError): spice.bodc2n(-9991)