def spice_positions(self, et: float): """Calculate MAVEN spacecraft position, Mars solar longitude, and the subsolar position for a given ephemeris time. Parameters ---------- et Input epoch in ephemeris seconds past J2000. Returns ------- et : array The input ephemeris times. Just givin'em back. subsc_lat : array Sub-spacecraft latitudes in degrees. subsc_lon : array Sub-spacecraft longitudes in degrees. sc_alt_km : array Sub-spacecraft altitudes in kilometers. ls : array Mars solar longitudes in degrees. subsolar_lat : array Sub-solar latitudes in degrees. subsolar_lon : array Sub-solar longitudes in degrees. mars_sun_km: array """ spoint, trgepc, srfvec = \ spice.subpnt('Intercept: ellipsoid', self.__target, et, 'IAU_MARS', self.__abcorr, self.__observer) _, _, srvec_sun = \ spice.subpnt('Intercept: ellipsoid', self.__target, et, 'IAU_MARS', self.__abcorr, 'SUN') rpoint, colatpoint, lonpoint = spice.recsph(spoint) if lonpoint > np.pi: lonpoint -= 2 * np.pi subsc_lat = 90 - np.degrees(colatpoint) subsc_lon = np.degrees(lonpoint) sc_alt_km = np.sqrt(np.sum(srfvec**2)) mars_sun_km = np.sqrt(np.sum(srvec_sun**2)) # calculate subsolar position sspoint, strgepc, ssrfvec = \ spice.subslr('Intercept: ellipsoid', self.__target, et, 'IAU_MARS', self.__abcorr, self.__observer) srpoint, scolatpoint, slonpoint = spice.recsph(sspoint) if slonpoint > np.pi: slonpoint -= 2 * np.pi subsolar_lat = 90 - np.degrees(scolatpoint) subsolar_lon = np.degrees(slonpoint) ls = np.degrees(spice.lspcn(self.__target, et, self.__abcorr)) return et, subsc_lat, subsc_lon, sc_alt_km, ls, subsolar_lat, \ subsolar_lon, mars_sun_km
def find_sub_pt(self): ''' Finds the sub-observer point in the IAU_[target] frame and also the in the J2000 frame as seen from Earth. Also creates a vector from Earth to the sub-obs point in the J2000 frame for future use. ''' ## get the position of the sub-obs point in the J2000 frame self.subptvec, self.subptep, self.subpntobsvec = \ spiceypy.subpnt('INTERCEPT/ELLIPSOID', self.target, \ self.et, self.target_frame, 'CN', 'EARTH') ## convert to lat/lon self.subptlon, self.subptlat, _ = \ spiceypy.recpgr(self.target, self.subptvec, \ self.radii[0], self.flattening) ## convert the line of sight vector to J2000 px1 = spiceypy.pxfrm2(self.target_frame, 'J2000', \ self.subptep, self.et) self.subptJ2000 = np.matmul(px1, self.subpntobsvec) ## get the RA/DEC of the sub-obs point self.subRA, self.subDec = spiceypy.recrad(self.subptJ2000)[1:] self.RADec0 = np.array([self.subRA, self.subDec])
def get_pixel_size_km(probe: str, body: str, time: datetime, fov_full_angle_deg: float, fov_full_px: int) -> float: """ Calculates size of one pixel on body's surface in km at given time. :param probe: SPICE name of probe :param body: SPICE name of target body :param time: datetime of computation :param fov_full_angle_deg: full angle of one FOV dimension :param fov_full_px: full pixel count of the same FOV dimension :return: length of square covered by one pixel in kilometers """ if fov_full_angle_deg <= 0.0: raise ValueError("fov_full_angle_deg must be positive.") if fov_full_angle_deg > 90.0: raise ValueError( f"with fov_full_angle_deg = {fov_full_angle_deg} the calculation would be wildly inaccurate." ) if fov_full_px < 1: raise ValueError("fov_full_px must be at least 1") et = datetime2et(time) nadir_vec = spy.subpnt("INTERCEPT/ELLIPSOID", body, et, f"IAU_{body}", "LT+S", probe)[2] nadir_dist = spy.vnorm(nadir_vec) half_angle_rad = 0.5 * fov_full_angle_deg * np.pi / 180 fov_half_px = fov_full_px / 2 half_angle_km = np.tan(half_angle_rad) * nadir_dist return half_angle_km / fov_half_px
def spice_positions(et): """ Calculates MAVEN spacecraft position, Mars solar longitude, and subsolar position for a given ephemeris time. Parameters ---------- et : float Input epoch in ephemeris seconds past J2000. Returns ------- et : array The input ephemeris times. Just givin'em back. subsc_lat : array Sub-spacecraft latitudes in degrees. subsc_lon : array Sub-spacecraft longitudes in degrees. sc_alt_km : array Sub-spacecraft altitudes in kilometers. ls : array Mars solar longitudes in degrees. subsolar_lat : array Sub-solar latitudes in degrees. subsolar_lon : array Sub-solar longitudes in degrees. """ # do a bunch of SPICE stuff only Justin understands... target = 'Mars' abcorr = 'LT+S' observer = 'MAVEN' spoint, trgepc, srfvec = spice.subpnt('Intercept: ellipsoid', target, et, 'IAU_MARS', abcorr, observer) rpoint, colatpoint, lonpoint = spice.recsph(spoint) if lonpoint > np.pi: lonpoint -= 2 * np.pi subsc_lat = 90 - np.degrees(colatpoint) subsc_lon = np.degrees(lonpoint) sc_alt_km = np.sqrt(np.sum(srfvec ** 2)) # calculate subsolar position sspoint, strgepc, ssrfvec = spice.subslr('Intercept: ellipsoid', target, et, 'IAU_MARS', abcorr, observer) srpoint, scolatpoint, slonpoint = spice.recsph(sspoint) if slonpoint > np.pi: slonpoint -= 2 * np.pi subsolar_lat = 90 - np.degrees(scolatpoint) subsolar_lon = np.degrees(slonpoint) # calculate solar longitude ls = spice.lspcn(target, et, abcorr) ls = np.degrees(ls) # return the position information return et, subsc_lat, subsc_lon, sc_alt_km, ls, subsolar_lat, subsolar_lon
def get_nadir_point_surface_velocity_kps(probe: str, body: str, time: datetime, delta_s: float = 10.0) -> float: """ Computes surface velocity of nadir point of given probe at given time on given body. :param probe: SPICE name of probe :param body: SPICE name of target body :param time: datetime of computation :param delta_s: delta time used for computation of derivative :return: Velocity of nadir point across surface [km/s] """ if delta_s <= 0.0: raise ValueError("delta_s must be positive.") start = datetime2et(time) end = datetime2et(time + timedelta(seconds=delta_s)) nadir_points = [ spy.subpnt("INTERCEPT/ELLIPSOID", body, et, f"IAU_{body}", "LT+S", probe)[0] for et in (start, end) ] distance = spy.vdist(*nadir_points) return distance / delta_s
def sc_pos(self, timestr): # Convert the timestring to ephemeris time self.et = spice.str2et(str(timestr)) self.et = self.et + self.time_offset self.data['sc_wrt_planet'], self.data['target_light_time'] = spice.spkpos(self.spacecraft, self.et, self.iref, 'NONE', self.target) self.data['target_distance'] = spice.vnorm(self.data['sc_wrt_planet']) self.data['sc_wrt_sun'], light_times = spice.spkpos(self.spacecraft, self.et, self.iref, 'NONE', 'SUN') #self.ticks = spice.sce2t(self.sc_id, self.et) # Retrieve the position of the spacecraft relative to the target state, self.ltcorr = spice.spkezr(self.target, self.et, self.iref, self.abcorr, self.spacecraft) scloc = state[0:3] # Get the sub-spacecraft coordinates point, epoch, vector = spice.subpnt('NEAR POINT/ELLIPSOID', self.target, self.et, self.framestring, self.abcorr, self.spacecraft) self.distance, self.data['lon_sc'], self.data['lat_sc'] = spice.reclat(point) # Get the localtime of the spaceship hr, min, sc, time, ampm = spice.et2lst(self.et, self.target_id, self.data['lon_sc'], 'PLANETOCENTRIC') self.data['localtime_sc'] = hr + min / 60.0 + sc / 3600.0 # Get the subsolar coordinates point, epoch, vector = spice.subslr('NEAR POINT/ELLIPSOID', self.target, self.et, self.framestring, self.abcorr, self.spacecraft) distance, self.data['lon_sun'], self.data['lat_sun'] = spice.reclat(point) # Convert angles from radians to degrees for key in ['lat_sc', 'lon_sc', 'lat_sun', 'lon_sun'] : self.data[key] = np.rad2deg(self.data[key]) for key in ['lon_sc', 'lon_sun'] : self.data[key] = self.data[key] % 360 state_planet = spice.spkssb(self.target_id, self.et, self.iref) inert2p = spice.pxform(self.iref, self.framestring, self.et) self.scloc = np.matmul(-inert2p, scloc) self.i2p = spice.pxform(self.instrument, self.framestring, self.et) return self.data
def bodyHA(body,et,qlon): import spiceypy as sp # SUB POINT POSITION pos=sp.subpnt("Intercept: ellipsoid", "EARTH",et,"IAU_EARTH","NONE", body) lpos=sp.recpgr("EARTH",pos[0],REARTH,FEARTH); # LATITUDE AND LONGITUDE lon=lpos[0]*RAD lat=lpos[1]*RAD # print d2s(lon),d2s(lat) # DIFFERENCE IN LONGITUDE dlon=numpy.mod(qlon-lon,360) # HOUR ANGLE # H = LST - ALPHA ha=dlon return ha
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
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
def rotated_transform(et): """ Calculate the rotated pole transform for a particular orbit to replicate the viewing geometry at MAVEN apoapse. Parameters ---------- et : obj MAVEN apoapsis ephemeris time. Returns ------- transform : ??? A Cartopy rotated pole transform. """ # calculate various parameters using SPICE target = 'Mars' frame = 'MAVEN_MME_2000' abcorr = 'LT+S' observer = 'MAVEN' state, ltime = spice.spkezr(target, et, frame, abcorr, observer) spoint, trgepc, srfvec = spice.subpnt('Intercept: ellipsoid', target, et, 'IAU_MARS', abcorr, observer) rpoint, colatpoint, lonpoint = spice.recsph(spoint) if lonpoint < 0.: lonpoint += 2 * np.pi G = 6.673e-11 * 6.4273e23 r = 1e3 * state[0:3] v = 1e3 * state[3:6] h = np.cross(r, v) n = h / np.linalg.norm(h) ev = np.cross(v, h) / G - r / np.linalg.norm(r) evn = ev / np.linalg.norm(ev) b = np.cross(evn, n) # get the sub-spacecraft latitude and longitude, and altitude (converted to meters) sublat = 90 - np.degrees(colatpoint) sublon = np.degrees(lonpoint) if sublon > 180: sublon -= 360 alt = np.sqrt(np.sum(srfvec**2)) * 1e3 # north pole unit vector in the IAU Mars basis polar_vector = [0, 0, 1] # when hovering over the sub-spacecraft point unrotated (the meridian of the point is a straight vertical line, # this is the exact view when using cartopy's NearsidePerspective or Orthographic with central_longitude and # central latitude set to the sub-spacecraft point), calculate the angle by which the planet must be rotated # about the sub-spacecraft point angle = np.arctan2(np.dot(polar_vector, -b), np.dot(polar_vector, n)) # first, rotate the pole to a different latitude given the subspacecraft latitude # cartopy's RotatedPole uses the location of the dateline (-180) as the lon_0 coordinate of the north pole pole_lat = 90 + sublat pole_lon = -180 # convert pole latitude to colatitude (for spherical coordinates) # also convert to radians for use with numpy trigonometric functions phi = pole_lon * np.pi / 180 theta = (90 - pole_lat) * np.pi / 180 # calculate the Cartesian vector pointing to the pole polar_vector = [ np.cos(phi) * np.sin(theta), np.sin(phi) * np.sin(theta), np.cos(theta) ] # by rotating the pole, the observer's sub-point in cartopy's un-transformed coordinates is (0,0) # the rotation axis is therefore the x-axis rotation_axis = [1, 0, 0] # rotate the polar vector by the calculated angle rotated_polar_vector = np.dot(rotation_matrix(rotation_axis, -angle), polar_vector) # get the new polar latitude and longitude after the rotation, with longitude offset to dateline rotated_polar_lon = np.arctan( rotated_polar_vector[1] / rotated_polar_vector[0]) * 180 / np.pi - 180 if sublat < 0: rotated_polar_lat = 90 - np.arccos( rotated_polar_vector[2] / np.linalg.norm(rotated_polar_vector)) * 180 / np.pi else: rotated_polar_lat = 90 + np.arccos( rotated_polar_vector[2] / np.linalg.norm(rotated_polar_vector)) * 180 / np.pi # calculate a RotatedPole transform for the rotated pole position transform = ccrs.RotatedPole(pole_latitude=rotated_polar_lat, pole_longitude=rotated_polar_lon, central_rotated_longitude=0) # transform the viewer (0,0) point tcoords = transform.transform_point(0, 0, ccrs.PlateCarree()) # find the angle by which the planet needs to be rotated about it's rotated polar axis and calculate a new # RotatedPole transform including this angle rotation rot_ang = sublon - tcoords[0] transform = ccrs.RotatedPole(pole_latitude=rotated_polar_lat, pole_longitude=rotated_polar_lon, central_rotated_longitude=rot_ang) return transform, alt
RSOLAR = RSOLAR_l11 if hdulist[0].header['SFORMAT'] == '4X4': RSOLAR = RSOLAR_l44 if IS_MVIC: exptime = 10 # Tod's MVIC Pan Frame mosaics are all 10 sec exposures, and averaged (not summed). RSOLAR = RSOLAR_mpf FSOLAR = FSOLAR_MPF #============================================================================== # Dummy check: Calculate sub-sc latitude using SPICE, rather than from FITS header [concl: working fine] #============================================================================== (vec,ltime) = sp.spkezr('Pluto', et, 'J2000', 'LT+S', 'New Horizons') (subpnt_rec, junk, junk) = sp.subpnt('Intercept: ellipsoid', 'Pluto', et, 'IAU_PLUTO', 'LT+S', 'New Horizons') (rad_spice, lon_subsc_spice, lat_subsc_spice) = sp.reclat(subpnt_rec) print("Sub-sc lat = {} [FITS]; {} [SPICE]".format(lat_subsc, hbt.r2d * lat_subsc_spice)) #============================================================================== # Convert from DN to irradiance (ergs/cm2/s/sr/A). From Hal's writeup. #============================================================================== dn = dn_median_clean_arr I = dn / exptime / RSOLAR # Convert from irradiance to I/F. From Hal's writeup. iof = math.pi * I * dist_au**2 / FSOLAR
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))
def subpnt(self): "output = (spoint, trgepoch, srfvec)" output = spice.subpnt(self.method, self.target, self.et, self.ref_frame, self.corr, self.obs) return output
def SC(self, utc, method='INTERCEPT/ELLIPSOID', abcorr='CN+S'): '''Sub-spacecraft point''' et = spice.str2et(utc) pos, _, _ = spice.subpnt(method, self.targ, et, self.ref, abcorr, self.obs) return lonlat( pos )