def producegeometrylamda(et, sv, when): [TGO, _] = spice.spkpos(sv.front, et - when, sv.fframe, 'NONE', sv.target) [MEX, _] = spice.spkpos(sv.front, et - when, sv.fframe, 'NONE', sv.obs) dist = math.floor(spice.vdist(TGO, MEX)) print(dist) # NEED TO PRODUCE VECTOR OF SZA AND HEIGHTS THAT ARE 'DIST' LONG [13242.9 m] *comp expensive # start by making DIST length vector, 3 height, for every meter from mex to tgo # MAYBE FIND THE UNIT VECTOR AND ADD ONE IN ITS DIRECTION!! angleseparation = (spice.vsep(MEX, TGO)) * (180 / math.pi ) # angle taken a mars center initialangle = (spice.vsep(-MEX, (TGO - MEX))) * ( 180 / math.pi ) # angle taken at mars-MEX-tgo, that points to tgo. needed for the bending functions original starting angle #script needs to work via periods of ray and not meters. [totalperiods is the main iterable, not meters] vacuumwavelength = constants.c / 437.1e6 scale = 1 # scale =10, means we are itertating per 100 wavelenghts instead of 1000 (default 1000 because SPICE works in km) wavelengthsinameter = 1 / vacuumwavelength a = wavelengthsinameter * dist * scale total1000periods = math.floor(a) # ~that many thousands of periods remainingdistance = (vacuumwavelength / scale) * ( (wavelengthsinameter * dist * scale) - total1000periods ) # quanitfy the remaineder, this distance can # added later, this remaining portion is extreamly high altitude (near Target) and has no refractive effects. therfor simply added (km) #total1000periods = total1000periods.astype(int) sc2sc = TGO - MEX norm = np.linalg.norm(sc2sc) unitsc2sc = sc2sc / (norm * vacuumwavelength * scale ) #this needs to shrink if the repeatable expands points = np.empty([3, total1000periods]) sza = np.empty([1, total1000periods]) marsrad = spice.bodvrd(sv.front, 'RADII', 3) flatteningcoefficient = (marsrad[1][0] - marsrad[1][2]) / marsrad[1][0] equatorialradii = marsrad[1][0] # find direction of sun, it will not change much during the occultation. so only calc it once [SUN, _] = spice.spkpos(sv.front, et, sv.fframe, 'NONE', 'SUN') for i in range(total1000periods): point = MEX + ( i * unitsc2sc ) #move along ray, 1000 wavelength distance at a time (685 m). but unitsc2sc is in km... sza[0, i] = spice.vsep(SUN, point) points[:, i] = spice.recgeo(point, equatorialradii, flatteningcoefficient) points[0, i] = (points[0, i] * (-180 / math.pi)) points[1, i] = (points[1, i] * (-180 / math.pi)) print((i / math.floor(total1000periods)) * 100) ray = np.concatenate((points, sza), axis=0) print('stop here') return ray, dist, angleseparation, initialangle, total1000periods, vacuumwavelength, remainingdistance
def producegeometrymeter(et, sv, when): [TGO, _] = spice.spkpos(sv.front, et - when, sv.fframe, 'NONE', sv.target) [MEX, _] = spice.spkpos(sv.front, et - when, sv.fframe, 'NONE', sv.obs) dist = math.floor(spice.vdist(TGO, MEX)) print(dist) # NEED TO PRODUCE VECTOR OF SZA AND HEIGHTS THAT ARE 'DIST' LONG [13242.9 m] *comp expensive # start by making DIST length vector, 3 height, for every meter from mex to tgo # MAYBE FIND THE UNIT VECTOR AND ADD ONE IN ITS DIRECTION!! angleseparation = (spice.vsep(MEX, TGO)) # angle taken a mars center initialangle = (spice.vsep(-MEX, (TGO - MEX))) * ( 180 / math.pi ) # angle taken at mars-MEX-tgo, that points to tgo. needed for the bending functions original starting angle #script needs to work via periods of ray and not meters. [totalperiods is the main iterable, not meters] scale = 0.1 # scale =10, means we are itertating per 100 wavelenghts instead of 1000 (default 1000 because SPICE works in km) dist = math.floor(dist) # km sc2sc = TGO - MEX norm = np.linalg.norm(sc2sc) unitsc2sc = sc2sc / norm #this needs to shrink if the repeatable expands points = np.empty([3, dist]) sza = np.empty([1, dist]) angleprogression = np.empty([1, dist]) xyzpoints = np.zeros([3, dist]) marsrad = spice.bodvrd(sv.front, 'RADII', 3) flatteningcoefficient = (marsrad[1][0] - marsrad[1][2]) / marsrad[1][0] equatorialradii = marsrad[1][0] # find direction of sun, it will not change much during the occultation. so only calc it once [SUN, _] = spice.spkpos(sv.front, et, sv.fframe, 'NONE', 'SUN') for i in range(dist): xyzpoint = MEX + ( i * unitsc2sc ) #move along ray, 1000 wavelength distance at a time (685 m). but unitsc2sc is in km... xyzpoints[:, i] = xyzpoint sza[0, i] = spice.vsep(SUN, xyzpoint) angleprogression[0, i] = (spice.vsep(xyzpoint, MEX)) * (180 / math.pi) points[:, i] = spice.recgeo(xyzpoint, equatorialradii, flatteningcoefficient) points[0, i] = (points[0, i] * (-180 / math.pi)) points[1, i] = (points[1, i] * (-180 / math.pi)) print((i / math.floor(dist)) * 100) ray = np.concatenate((points, sza), axis=0) #plt.plot(angleprogression[0,:], ray[2,:]) #plt.show() # ray is in lat/lon/alt + sza and xyzpoints is cartesian, both describe the same thing return ray, dist, unitsc2sc, angleseparation, initialangle, MEX, TGO, xyzpoints, angleprogression
def producegeometrymeter(et, sv, when): [TGO, _] = spice.spkpos(sv.front, et - when, sv.fframe, 'NONE', sv.target) [MEX, _] = spice.spkpos(sv.front, et - when, sv.fframe, 'NONE', sv.obs) dist = math.floor(spice.vdist(TGO, MEX)) angleseparation = (spice.vsep(MEX, TGO)) # angle taken a mars center initialangle = (spice.vsep(-MEX, (TGO - MEX))) * ( 180 / math.pi ) # angle taken at mars-MEX-tgo, that points to tgo. needed for the bending functions original starting angle #script needs to work via periods of ray and not meters. [totalperiods is the main iterable, not meters] sc2sc = TGO - MEX norm = np.linalg.norm(sc2sc) unitsc2sc = sc2sc / norm #this needs to shrink if the repeatable expands points = np.empty([3, dist]) sza = np.empty([1, dist]) angleprogression = np.empty([1, dist]) xyzpoints = np.zeros([3, dist]) marsrad = spice.bodvrd(sv.front, 'RADII', 3) flatteningcoefficient = (marsrad[1][0] - marsrad[1][2]) / marsrad[1][0] equatorialradii = marsrad[1][0] # find direction of sun, it will not change much during the occultation. so only calc it once [SUN, _] = spice.spkpos(sv.front, et, sv.fframe, 'NONE', 'SUN') for i in range(dist): xyzpoint = MEX + ( i * unitsc2sc ) #move along ray, 1000 wavelength distance at a time (685 m). but unitsc2sc is in km... xyzpoints[:, i] = xyzpoint sza[0, i] = spice.vsep(SUN, xyzpoint) angleprogression[0, i] = (spice.vsep(xyzpoint, MEX)) * (180 / math.pi) points[:, i] = spice.recgeo(xyzpoint, equatorialradii, flatteningcoefficient) points[0, i] = (points[0, i] * (-180 / math.pi)) points[1, i] = (points[1, i] * (-180 / math.pi)) ray = np.concatenate((points, sza), axis=0) # important for when sza is included #plt.plot(angleprogression[0,:], ray[2,:]) #plt.show() # ray is in lat/lon/alt + sza and xyzpoints is cartesian, both describe the same thing return initialangle, MEX, TGO, xyzpoints
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 calculate_body_resolutions(self, data) : self.resolutions = np.zeros(shape=[data.shape[0] - 1, data.shape[1] - 1]) for (py, px), value in np.ndenumerate(self.resolutions): lon1 = np.deg2rad(data[py, px, self.map['lon']]) lat1 = np.deg2rad(data[py, px, self.map['lat']]) lon2 = np.deg2rad(data[py + 1, px + 1, self.map['lon']]) lat2 = np.deg2rad(data[py + 1, px + 1, self.map['lat']]) if (np.deg2rad(-1000.0) in [lon1, lat1, lon2, lat2]) : continue point1 = spice.srfrec(self.target_id, lon1, lat1) point2 = spice.srfrec(self.target_id, lon2, lat2) distance = spice.vdist(point1, point2) if (distance) : self.resolutions[py, px] = distance # This may not work try: ontarget = self.resolutions[np.nonzero(self.resolutions)] except: ontarget = [-1000.0] # if not ontarget: ontarget = [-1000.0] self.data['res_max'] = np.max(ontarget) self.data['res_min'] = np.min(ontarget) self.data['res_avg'] = np.mean(ontarget) print(self.data['res_avg']) return self.resolutions
def producegeometrymeter(MEX, TGO): #maybe completly thin this out, you know this is moslty pointless, what does it actually make class SpiceVariables: obs = '-41' # NAIF code for MEX '-74' target = '-143' # NAIF code for TGO ['EARTH'/'SUN'/ a groundstation etc] 'MARS ODYSSEY' obsfrm = 'IAU_MARS' abcorr = 'NONE' crdsys = 'LATITUDINAL' coord = 'LATITUDE' stepsz = 1.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() #THIS COULD BE REMOVED # [TGO, _] = spice.spkpos(sv.front, et-when, sv.fframe, 'NONE', sv.target) # [MEX, _] = spice.spkpos(sv.front, et-when, sv.fframe, 'NONE', sv.obs) TGO = TGO + 0 MEX = MEX + 0 #force to be non-strided dist = math.floor(spice.vdist(TGO, MEX)) angleseparation = (spice.vsep(MEX, TGO)) # angle taken a mars center initialangle = (spice.vsep(-MEX, (TGO - MEX))) * ( 180 / math.pi ) # angle taken at mars-MEX-tgo, that points to tgo. needed for the bending functions original starting angle #script needs to work via periods of ray and not meters. [totalperiods is the main iterable, not meters] sc2sc = TGO - MEX norm = np.linalg.norm(sc2sc) unitsc2sc = sc2sc / norm #this needs to shrink if the repeatable expands points = np.empty([3, dist]) sza = np.empty([1, dist]) angleprogression = np.empty([1, dist]) xyzpoints = np.zeros([3, dist]) marsrad = spice.bodvrd(sv.front, 'RADII', 3) flatteningcoefficient = (marsrad[1][0] - marsrad[1][2]) / marsrad[1][0] equatorialradii = marsrad[1][0] # find direction of sun, it will not change much during the occultation. so only calc it once #[SUN, _] = spice.spkpos(sv.front, et, sv.fframe, 'NONE', 'SUN') for i in range(dist): xyzpoint = MEX + ( i * unitsc2sc ) #move along ray, 1000 wavelength distance at a time (685 m). but unitsc2sc is in km... xyzpoints[:, i] = xyzpoint #sza[0,i] = spice.vsep(SUN,xyzpoint) angleprogression[0, i] = (spice.vsep(xyzpoint, MEX)) * (180 / math.pi) points[:, i] = spice.recgeo(xyzpoint, equatorialradii, flatteningcoefficient) points[0, i] = (points[0, i] * (-180 / math.pi)) points[1, i] = (points[1, i] * (-180 / math.pi)) # ray = np.concatenate((points,sza), axis=0) # important for when sza is included #plt.plot(angleprogression[0,:], ray[2,:]) #plt.show() # ray is in lat/lon/alt + sza and xyzpoints is cartesian, both describe the same thing return initialangle, xyzpoints
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 get_planet_magnitude(object_id, pos_planet, pos_basis): """ Planet and Moon magnitudes """ planet_abs_mag = { 199: -0.42, # OBJECT_ID_MERCURY 299: -4.40, # OBJECT_ID_VENUS 399: -2.96, # OBJECT_ID_EARTH 499: -1.52, # OBJECT_ID_MARS 599: -9.40, # OBJECT_ID_JUPITER 699: -8.68, # OBJECT_ID_SATURN 799: -7.19, # OBJECT_ID_URANUS 899: -6.87, # OBJECT_ID_NEPTUNE 999: -1.00, # OBJECT_ID_PLUTO } # distance between each objects in AU d_planet_basis = spice.vdist(pos_planet, pos_basis) d_planet_basis = spice.convrt(d_planet_basis, "km", "AU") d_planet_sun = spice.vnorm(pos_planet) d_planet_sun = spice.convrt(d_planet_sun, "km", "AU") d_sun_basis = spice.vnorm(pos_basis) d_sun_basis = spice.convrt(d_sun_basis, "km", "AU") if object_id == OBJECT_ID_SUN: return -27.3 + 5.0 * np.log10(d_sun_basis) elif object_id == OBJECT_ID_MOON: return 0.38 elif object_id in [ OBJECT_ID_MERCURY, OBJECT_ID_VENUS, OBJECT_ID_EARTH, OBJECT_ID_MARS, OBJECT_ID_JUPITER, OBJECT_ID_SATURN, OBJECT_ID_URANUS, OBJECT_ID_NEPTUNE, OBJECT_ID_PLUTO, ]: pass else: return None mag = planet_abs_mag[object_id] mag += 5.0 * np.log10(d_planet_basis * d_planet_sun) if object_id <= OBJECT_ID_JUPITER: pa = 0.0 tpa = (d_planet_sun**2 + d_planet_basis**2 - d_sun_basis) / (2.0 * d_planet_sun * d_planet_basis) tpa = np.clip(tpa, -1.0, 1.0) pa = np.degrees(np.arccos(tpa)) if object_id == OBJECT_ID_MERCURY: mag += (0.0380 - 0.000273 * pa + 0.000002 * pa * pa) * pa elif object_id == OBJECT_ID_VENUS: mag += (0.0009 + 0.000239 * pa - 0.00000065 * pa * pa) * pa elif object_id == OBJECT_ID_MARS: mag += 0.016 * pa elif object_id == OBJECT_ID_JUPITER: mag += 0.005 * pa elif object_id == OBJECT_ID_SATURN: mag -= 1.1 * 0.3 return mag