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
Example #4
0
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
Example #7
0
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))
Example #8
0
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