def ephemeris_start_time(self): """ Returns the ephemeris start time of the image. Expects spacecraft_id to be defined. This should be the integer naif ID code of the spacecraft. Returns ------- : float ephemeris start time of the image """ return spice.sct2e(self.spacecraft_id, super().ephemeris_start_time)
def __ClockDrift(self, enddate=False): if self.name != 'MPO': sclk_start = 0.0 sclk_end = 500000000 else: sclk_start = 3.9631239807361E+13/65536 sclk_end = 700000000 #sclk_end = spiceypy.gdpool('SCLK_PARTITION_END_{}'.format(str(-1*self.id)),0,1000)[0]/65536 step = 10000.0 if not enddate: et_end = self.time.getTime('finish','utc') else: et_end = spiceypy.utc2et(enddate) sclk = [] ephtime = [] utctime = [] for i in np.arange(sclk_start, sclk_end, step): sclk.append(i) sclkdp = i*65536 et = spiceypy.sct2e(self.id, sclkdp) ephtime.append(et) utcstr = spiceypy.et2utc(et, 'C', 3) utctime.append(utcstr) dates = [] drift = [] for j in range(0,len(ephtime),1): if ephtime[j] >= et_end: break drift.append((sclk[j]-sclk_start) - (ephtime[j] - ephtime[0])) dates.append(ephtime[j]) self.clock_dates = dates self.clock_drift = drift return
def scet_to_datetime(self, scet): """ Convert SCET to datetime. Parameters ---------- scet : `str`, `int`, `float` SCET time as number or spacecraft clock string e.g. `1.0` or `'625237315:44104'` Returns ------- `datetime.datetime` Datetime of SCET """ ephemeris_time = None if isinstance(scet, (float, int)): ephemeris_time = spiceypy.sct2e(SOLAR_ORBITER_ID, scet) elif isinstance(scet, str): ephemeris_time = spiceypy.scs2e(SOLAR_ORBITER_ID, scet) return spiceypy.et2datetime(ephemeris_time)
def met2utc(met_in, name_observer = 'NEW HORIZONS'): # met_in = 299348928.9358144 # name_observer = 'New Horizons' if (name_observer.upper().find('NEW HORIZONS') == -1): print('MET can be used only for New Horizons') return # Convert input to an array, even if it is not if hbt.is_array(met_in): met = np.array(met_in) else: met = np.array([met_in]) # If there are any commas in the MET, then remove them if (type(met[0]) == str): met = np.zeros(np.shape(met_in)) for i,met_i in enumerate(met_in): met[i] = float(met_in[i].replace(',', '')) sclk_ticks = np.array(met * 5e4) # Have to include np.array() -- not sure why. I guess a 1x1 np-array is demoted?? ntime = np.size(met_in) # Number of elements et = np.zeros(ntime) utc = np.zeros(ntime, dtype = 'U30') for i in range(np.size(ntime)): et[i] = sp.sct2e(-98, sclk_ticks[i]) utc[i] = sp.et2utc(et[i], 'C', 3) # utc[i] = sp_et2utc, et_i, 'ISOD', 3, utc_i if (ntime == 1): utc = utc[0] return utc
def scet_to_utc(self, scet): """ Convert SCET to UTC time string in ISO format. Parameters ---------- scet : `str`, `int`, `float` SCET time as a number or spacecraft clock string e.g. `1.0` or `625237315:44104` Returns ------- `str` UTC time string in ISO format """ # Obt to Ephemeris time (seconds past J2000) ephemeris_time = None if isinstance(scet, (float, int)): ephemeris_time = spiceypy.sct2e(SOLAR_ORBITER_ID, scet) elif isinstance(scet, str): ephemeris_time = spiceypy.scs2e(SOLAR_ORBITER_ID, scet) # Ephemeris time to Utc # Format of output epoch: ISOC (ISO Calendar format, UTC) # Digits of precision in fractional seconds: 6 return spiceypy.et2utc(ephemeris_time, "ISOC", 3)
def create_ck(kernels, frames_to_convert, fks, stop_ets, output_ck): """ Create CK from FKs and times at which the FKs end being valid """ ### FURNSH any kernels for kernel in kernels: sp.furnsh(kernel) ### Set last ET to None so it will be initialized in loop's first pass last_et = None ### Do not overwrite existing output CK assert (not sp.exists(output_ck) ) or dict()['Cannot overwrite existing CK[{}]'.format(output_ck)] ### Initialize CK handle to None ck_handle = None ### Loop over CKs while fks: ### Get FK and corresponding stop ET fk = fks.pop() stop_et = stop_ets.pop() ### Loop over reference frames (reffrms) for reffrm in frames_to_convert: ### Get reffrm ID, SCLK ID; N.B. latter comes from new FK reffrm_id = sp.gipool('FRAME_{}'.format(reffrm.upper()), 0, 1)[0] sclk_id = sp.gipool('CK_{}_{}'.format(reffrm_id, 'SCLK'), 0, 1)[0] ### Set start DP-SCLK of window for this old FK (outer loop) ### - Set to zero for first window ### - Covnert ET to DP-SCLK for subsequent windows if last_et is None: begtim = 0.0 else: begtim = sp.sce2t(sclk_id, last_et) ### Load old FK, get RELATIVE frame name, get time-invariant ### matrix, and unload old FK sp.furnsh(fk) relative_reffrm = sp.gcpool( 'TKFRAME_{}_{}'.format(reffrm_id, 'RELATIVE'), 0, 1, 99)[0] mtx = sp.pxform(relative_reffrm, reffrm, 0.0) sp.unload(fk) ### Covnert matrix to quaternion quat = sp.m2q(mtx) ### Calculate tick rate: seconds per tick rate = (sp.sct2e(sclk_id, 1e3) - sp.sct2e(sclk_id, 0.)) / 1e3 if doVerbose: ### if VERBOSE environment variable is present, log information print(( relative_reffrm, reffrm, fk, last_et, stop_et, '{:010.3f}'.format(1. / rate), quat, )) ### Set stop DP-SCLK of window if stop_et < -1e30: ### Use end of encoded DP_SCLK for final window endtim = sp.gdpool('SCLK_PARTITION_END_{}'.format(-sclk_id), 0, 999)[-1] else: ### Else convert stop ET to DP-SCLK endtim = sp.sce2t(sclk_id, stop_et) if doDebug: ### Debug output pprint.pprint( dict(fk=fk, reffrm=reffrm, reffrm_id=reffrm_id, relative_reffrm=relative_reffrm, rate=rate, begtim=begtim, endtim=endtim, diff=endtim - begtim, mtx=mtx, quat=quat)) ### Open CK, once if ck_handle is None: ck_handle = sp.ckopn(output_ck, 'ORX FK REPLACEMENT', 0) ### Write Type 2 CK segment with one record; angular velocity = 0 sp.ckw02(ck_handle, begtim, endtim, reffrm_id, relative_reffrm, '{}[{}]'.format(os.path.basename(fk), reffrm)[:40], 1, [begtim], [endtim], [quat], [[0., 0., 0.]], [rate]) ### Save stop ET for start ET of next pass last_et = stop_et ### Close CK if not (ck_handle is None): sp.ckcls(ck_handle)
def test_ck(kernels, frames_to_convert, fks, stop_ets, output_ck): """ Text CK against FKs at times at which the FKs are valid """ ### Load base kernels (LSK, new FK, SCLK) for kernel in kernels + [output_ck]: sp.furnsh(kernel) ### Set last ET to None so it will be initialized in loop's first pass last_et = None ### Create dict of info; keys will be new FK filenames dt = dict() while fks: ### Pop FK and stop ET off of lists fk = fks.pop() stop_et = stop_ets.pop() ### Create dict for this FK dt[fk] = dict() ### Loop over refernce frames for reffrm in frames_to_convert: ### Get reffrm ID, SCLK ID; N.B. latter comes from new FK reffrm_id = sp.gipool('FRAME_{}'.format(reffrm.upper()), 0, 1)[0] sclk_id = sp.gipool('CK_{}_{}'.format(reffrm_id, 'SCLK'), 0, 1)[0] ### Set start DP-SCLK of window for this old FK (outer loop) ### - Set to zero for first window ### - Covnert ET to DP-SCLK for subsequent windows if last_et is None: et_lo = sp.sct2e(sclk_id, 0.) else: et_lo = last_et ### Load old FK, get RELATIVE frame name, get time-invariant ### matrix, and unload old FK sp.furnsh(fk) relative_reffrm = sp.gcpool( 'TKFRAME_{}_{}'.format(reffrm_id, 'RELATIVE'), 0, 1, 99)[0] sp.unload(fk) ### Get ETs at which to do the tests: ### - 10s after start of window ### - 10s before end of window, or 1e6s after start if last window if stop_et < -1e30: et_test_lo = et_lo + 10. et_test_hi = et_lo + 1e6 else: et_delta = min([10., (stop_et - et_lo) / 3.]) et_test_lo = et_lo + et_delta et_test_hi = stop_et - et_delta ### Save the relative reffrm, the reffrm, the window, and an empty ### dict for this reffrm under this FK dt[fk][reffrm] = (relative_reffrm, et_test_lo, et_test_hi, dict()) ### For next pass last_et = stop_et ### Clear all kernels, and test sp.kclear() assert 0 == sp.ktotal('all') ### Load base kernels including new FK and new CK for kernel in kernels + [output_ck]: sp.furnsh(kernel) ### Loop over old FKs, reffrms, and ETs for fk in dt: for reffrm in dt[fk]: ### Retrieve relative reffrm, ETs and quat dict relative_reffrm, et_test_lo, et_test_hi, dtquat = dt[fk][reffrm] for et in ( et_test_lo, et_test_hi, ): ### Lookup CK-based matrix, convrt to and save quat at each ET dtquat[et] = sp.m2q(sp.pxform(relative_reffrm, reffrm, et)) ### Loop over the old FKs again for fk in dt: ### Clear all kernels, and test sp.kclear() assert 0 == sp.ktotal('all') ### Load only the old FK sp.furnsh(fk) ### Loop over reffrms, and ETs for reffrm in dt[fk]: relative_reffrm, et_test_lo, et_test_hi, dtquat = dt[fk][reffrm] for et in ( et_test_lo, et_test_hi, ): ### Calculate norm of difference of CK-based and FK-based quats quat_error = round( sp.vnorm(dtquat[et] - sp.m2q(sp.pxform(relative_reffrm, reffrm, et))), 16) ### Output that norm as an error for each case, which norm ### should be zero print( dict(fk=fk, quat_error=quat_error, relative_reffrm=relative_reffrm, reffrm=reffrm, et='{:015.4f}'.format(et)))
error0 = et0 - correct_et0 tpictr = '@YR-MON-DD-HR:MN:SC.##### ::TDB ::RND' correct_tdb0 = sp.timout(correct_et0, tpictr, 99) print(dict(error0=error0, correct_tdb0=correct_tdb0)) abscissa = list() ordinate = list() et1s = [et1, et0 + ((met1 - met0) * rate0 / tps)] start_et = min(et1s) - abs(error0) stop_et = max(et1s) + abs(error0) det = 0. ddet = 0.1 et = start_et + det while et <= stop_et: abscissa.append(det) ordinate.append(sp.sct2e(-98, sp.sce2t(-98, et)) - et) det += ddet et = start_et + det plt.plot(abscissa, ordinate) plt.xlabel('s past {}'.format(sp.timout(start_et, tpictr, 99))) plt.ylabel('ET=>SCLKdp=>ET error, s') plt.show()
### Convert list to string s_kernels = '[{}]'.format(','.join(bn_kernels)) ### Constants: NH SCLK sub-ticks per NH tick second, seconds per year tps, spy = 5e4, sp.jyear() ### Interpret datetime.datetime string as UTC and convert to MET seconds date2met = lambda dayt: sp.sce2t( -98, sp.utc2et(dayt.strftime('%Y-%m-%dT%H:%M:%S'))) / tps ### Fudge factor; NH MET clock shifts 2s during the launch day met_fudge = -2 ### ET and date and MET, all 1d after SCLK zero time et = sp.sct2e(-98, 0.) - met_fudge s_0 = sp.timout(et, 'Sun MON DD HR:MN:SC YYYY', 99) date0 = datetime.datetime.strptime(s_0, '%c') met0 = date2met(date0) + met_fudge ### Year, as a floating point value, at that time offset_to_launch = 2000 + ( (date0 - datetime.datetime(2000, 1, 1, 12)).total_seconds() / spy) ### Time of leapsecond events, from LSK leapsecs_met_y = [ offset_to_launch + (sp.sce2t(-98, sp.utc2et(s.strip())) / (tps * spy)) for s in """ 2009-JAN-1/00:00:00 2012-JUL-1/00:00:00 2015-JUL-1/00:00:00
def ephemeris_start_time(self): return spice.sct2e(self.spacecraft_id, super().ephemeris_start_time)
def ephemermis_stop_time(self): return spice.sct2e(self.spacecraft_id, self.ephemeris_stop_time)