コード例 #1
0
ファイル: sun_angular_size.py プロジェクト: irthomas/work
def get_sun_sizes(utc_start, utc_end, step_size):
    """get sun angular size and time steps given start and end times"""
    #spice constants
    abcorr = "None"
    #tolerance = "1"
    #method = "Intercept: ellipsoid"
    #prec = 3
    #shape = "Ellipsoid"

    #load spiceypy kernels
    os.chdir(KERNEL_DIRECTORY)
    sp.furnsh(KERNEL_DIRECTORY + os.sep + METAKERNEL_NAME)
    print(sp.tkvrsn("toolkit"))
    os.chdir(BASE_DIRECTORY)
    utctimestart = sp.str2et(utc_start)
    utctimeend = sp.str2et(utc_end)

    durationseconds = utctimeend - utctimestart
    nsteps = int(np.floor(durationseconds / step_size))
    timesteps = np.arange(nsteps) * step_size + utctimestart

    ref = "J2000"
    observer = "-143"
    target = "SUN"
    #get TGO-SUN pos
    tgo2sunpos = [
        sp.spkpos(target, time, ref, abcorr, observer)[0] for time in timesteps
    ]
    sunaxes = sp.bodvrd("SUN", "RADII", 3)[1][0]  #get mars axis values

    return ([np.arctan((sunaxes*2.0)/np.linalg.norm(tgo2sunVector))*sp.dpr()*60.0 \
                for tgo2sunVector in tgo2sunpos], timesteps)
コード例 #2
0
ファイル: test_spiceypy.py プロジェクト: skulumani/astro
class TestSpiceyPyFunctions():
    cass = kernels.CassiniKernels()
    spice.furnsh(cass.metakernel) 
    utc = ['Jun 20, 2004', 'Dec 1, 2005']

    etOne = spice.str2et(utc[0])
    etTwo = spice.str2et(utc[1])
    step = 4000
    times = np.linspace(etOne, etTwo, step) 
    spice.kclear()
    def test_spiceypy_cassini(self):
        spice.furnsh(self.cass.metakernel)
        true_initial_pos = [-5461446.61080924 ,-4434793.40785864 ,-1200385.93315424]
        positions, lightTimes = spice.spkpos('Cassini', self.times, 'J2000', 'None', 'SATURN BARYCENTER')
        np.testing.assert_array_almost_equal(positions[0], true_initial_pos)
        spice.kclear()

    def test_spicepy_rotation_matrix_identity(self):
        spice.furnsh(self.cass.metakernel)
        R_E2E = spice.pxform('IAU_EARTH', 'IAU_EARTH', self.etOne)
        np.testing.assert_array_almost_equal(R_E2E, np.eye(3))
        spice.kclear()

    # @pytest.mark.skip('failing')
    def test_spicepy_state_transformation(self):
        spice.furnsh(self.cass.metakernel)
        T = spice.sxform('IAU_EARTH', 'IAU_SATURN', self.etOne)
        R = spice.pxform('IAU_EARTH', 'IAU_SATURN', self.etOne)
        (Rout, wout) = spice.xf2rav(T)
        np.testing.assert_array_almost_equal(Rout, R)
        spice.kclear()
コード例 #3
0
    def generateepochs(self, start, end, step):
        """Generate list of times using start and end times and number of steps

        Parameters
        ----------

            start : float
                Starting time (MJD)
            end : float
                Ending time (MJD)
                Same size as t
            step : float 
                Step size (days)  
         
        """

        start = float(start)
        end = float(end)
        step = float(step)
        self.step = step  # Used in save module. Should get rid of this.
        n_times = 1 + (end - start) / step

        self.times = np.arange(start, end, step)
        self.timesjd = self.times + shared.mjd2jd
        self.timeset = np.zeros(len(self.times) + 1)

        initialtime = self.svec[0][8] + shared.mjd2jd
        self.timeset[0] = sp.str2et('JD ' + repr(initialtime))
        for i in range(1, len(self.timeset)):
            self.timeset[i] = sp.str2et('JD ' + repr(self.timesjd[i - 1]))

        # Formatting the times in the way openorb wants it
        twos = np.repeat(2, len(self.times))
        tmp = np.stack((self.times, twos))
        self.times = np.swapaxes(tmp, 0, 1)
コード例 #4
0
def relative_position(obj, reference, ettemp, frame='J2000'):
    kernels = load_kernels()

    if isinstance(ettemp, Time):
        et = spice.str2et(ettemp.isot)
    elif isinstance(ettemp, float):
        et = ettemp
    else:
        et = [
            spice.str2et(e.isot) if type(e) == type(Time.now()) else e
            for e in ettemp
        ]

    abcor = 'LT+S'

    if isinstance(et, float):
        posvel, lt = spice.spkezr(obj, et, frame, abcor, reference)
        pos, vel = posvel[:3], posvel[3:]
    else:
        pos = np.zeros((len(et), 3))
        vel = np.zeros((len(et), 3))
        for i, t in enumerate(et):
            posvel, lt = spice.spkezr(obj, t, frame, abcor, reference)
            pos[i, :] = np.array(posvel[:3])
            vel[i, :] = np.array(posvel[3:])
    pos *= u.km
    vel *= u.km / u.s

    for k in kernels:
        spice.unload(k)

    return pos, vel
コード例 #5
0
def write_positions(
    utc_start,
    utc_end,
    steps,
):
    """
    Write positions of earth and moon in output file.
    Input:
        -utc_start              str (format YYYYmmdd)
        -utc_end                str (format YYYYmmdd)
        -steps                  int
    """

    # read kernel files paths and some constants from config
    dark_side_path = os.path.dirname(
        os.path.dirname(os.path.realpath(__file__)))
    config = configparser.ConfigParser()
    config.read(os.path.join(dark_side_path, "config", "config.ini"))
    spk_kernel = config["spice"]["spk_kernel"]
    lsk_kernel = config["spice"]["lsk_kernel"]
    reference_frame = config["spice"]["reference_frame"]
    aberration_correction = config["spice"]["aberration_correction"]

    # load kernels
    spice.furnsh(spk_kernel)
    spice.furnsh(lsk_kernel)

    # compute ET times
    et_start = spice.str2et(format_date_for_spice(utc_start))
    et_end = spice.str2et(format_date_for_spice(utc_end))
    times = [x * (et_end - et_start) / steps + et_start for x in range(steps)]

    # load positions
    earth_positions, _ = spice.spkpos("EARTH", times, reference_frame,
                                      aberration_correction, "SUN")
    moon_positions, _ = spice.spkpos("MOON", times, reference_frame,
                                     aberration_correction, "EARTH")

    # create output dir
    output_dir = os.path.join(
        dark_side_path,
        "data",
    )
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    # write results in output files
    write_output_file(os.path.join(output_dir, "earth.txt"), [
        "{:15.8f}, {:15.8f}, {:15.8f}".format(pos[0], pos[1], pos[2])
        for pos in earth_positions
    ])
    write_output_file(os.path.join(output_dir, "moon.txt"), [
        "{:15.8f}, {:15.8f}, {:15.8f}".format(pos[0], pos[1], pos[2])
        for pos in moon_positions
    ])
    write_output_file(os.path.join(output_dir, "times.txt"), [
        "{}".format(format_date_from_spice(spice.et2utc(time, "C", 0)))
        for time in times
    ])
コード例 #6
0
ファイル: test_spiceypy.py プロジェクト: skulumani/astro
 def test_near_landing_coverage(self):
     spice.furnsh(self.near.metakernel)
     utc = ['Feb 12, 2001 12:00:00 UTC', 'Feb 12, 2001 20:05:00 UTC']
     etone = 35251264.18507089
     ettwo = 35280364.18507829
     np.testing.assert_almost_equal(spice.str2et(utc[0]), etone)
     np.testing.assert_almost_equal(spice.str2et(utc[1]), ettwo)
     spice.kclear()
コード例 #7
0
def build_model_spec_dict(lbl_file,
                          cube_file,
                          spacecraft_state,
                          instrument_orientation,
                          scalar=1.0,
                          verbose=False):
    image_time = info.get_field_value(lbl_file, "IMAGE_TIME")
    interframe_delay = float(info.get_field_value(lbl_file,
                                                  "INTERFRAME_DELAY")) + 0.001

    start_time = spice.str2et(info.get_field_value(lbl_file,
                                                   "START_TIME")) + 0.06188
    stop_time = spice.str2et(info.get_field_value(lbl_file,
                                                  "STOP_TIME")) + 0.06188
    mid_time = (start_time + stop_time) / 2.0

    min_lat = float(
        scripting.getkey(cube_file, "MinimumLatitude", grpname="Mapping"))
    max_lat = float(
        scripting.getkey(cube_file, "MaximumLatitude", grpname="Mapping"))
    min_lon = float(
        scripting.getkey(cube_file, "MinimumLongitude", grpname="Mapping"))
    max_lon = float(
        scripting.getkey(cube_file, "MaximumLongitude", grpname="Mapping"))

    rot = rotation_matrix_to_euler_angles(instrument_orientation)
    rot = radians_xyz_to_degrees_xyz(rot)

    if verbose:
        print_r("Image Time: ", image_time)
        print_r("Interframe Delay: ", interframe_delay)
        print_r("Start Time: ", start_time)
        print_r("Stop Time: ", stop_time)
        print_r("Middle Time: ", mid_time)
        print_r("Minimum Latitude: ", min_lat)
        print_r("Maximum Latitude: ", max_lat)
        print_r("Minimum Longitude: ", min_lon)
        print_r("Maximum Longitude: ", max_lon)
        print_r("Scalar: ", scalar)
        print_r("Spacecraft Location: ", spacecraft_state * scalar)
        print_r("JunoCam Orientation: ", rot)

    model_spec_dict = {
        "image_time": image_time,
        "interframe_delay": interframe_delay,
        "start_time": start_time,
        "stop_time": stop_time,
        "middle_time": mid_time,
        "latitude_minimum": min_lat,
        "latitude_maximum": max_lat,
        "longitude_minimum": min_lon,
        "longitude_maximum": max_lon,
        "scalar": scalar,
        "spacecraft_location": (spacecraft_state * scalar).tolist(),
        "instrument_orientation": rot.tolist()
    }

    return model_spec_dict
コード例 #8
0
    def computeDataFrameGeometries(self, data_frames, greg_format_string,
                                   julian_format_string):

        for data_frame in data_frames:
            self.greg_format_string = greg_format_string
            self.julian_format_string = julian_format_string
            greg_split_string = self.greg_format_string.split(' ')
            data_frame.greg_time_system_string = [
                i for i in greg_split_string if '::' in i
            ][0][2:]
            julian_split_string = self.julian_format_string.split(' ')
            data_frame.julian_time_system_string = [
                i for i in julian_split_string if '::' in i
            ][0][2:]
            current_epoch = data_frame.start_epoch
            current_epoch = spice.str2et(current_epoch)
            stop_epoch = spice.str2et(data_frame.stop_epoch)
            time_remaining = stop_epoch - current_epoch

            while time_remaining >= 0.0:
                greg_date_string = spice.timout(current_epoch,
                                                self.greg_format_string)
                JD_date = spice.timout(current_epoch,
                                       self.julian_format_string)
                for body_pair in data_frame.body_pairs:
                    # get target body state
                    body_state, light_times = spice.spkez(
                        spice.bodn2c(body_pair[1]), current_epoch,
                        data_frame.frame, 'NONE', spice.bodn2c(body_pair[0]))
                    distance_km = self.np.linalg.norm(body_state[0:3])
                    distance_AU = distance_km / self.AU
                    data_frame.data[body_pair[0]][body_pair[1]].append([
                        greg_date_string, JD_date, body_state, distance_km,
                        distance_AU
                    ])

                # compute solar geometries
                SEP_angle, SPE_angle = self.computeSEPandSPEangles(
                    current_epoch, data_frame.spacecraft_SPICE_ID)
                data_frame.data['SEP'].append(
                    [greg_date_string, JD_date, SEP_angle])
                data_frame.data['SPE'].append(
                    [greg_date_string, JD_date, SPE_angle])

                # compute any eclipses
                self.computeCircleCircleOccultations(current_epoch,
                                                     greg_date_string, JD_date,
                                                     data_frame)

                if time_remaining == 0.0:
                    break
                else:
                    if time_remaining >= data_frame.time_step:
                        current_epoch += data_frame.time_step
                        time_remaining -= data_frame.time_step
                    else:
                        time_remaining -= stop_epoch - current_epoch
                        current_epoch += stop_epoch - current_epoch
コード例 #9
0
def cal2et(time, format='UTC', support_ker=False, unload=False):
    """
    Converts UTC or Calendar TDB (CAL) time to Ephemeris Time (ET). Accepts
    a single time or a lists of times. This function assumes that the support
    kernels (meta-kernel or leapseconds) kernel has been loaded.

    :param time: Input UTC or CAL time
    :type time: Union[float, list]
    :param format: Input format; 'UTC' or 'CAL'
    :type format: str
    :param unload: If True it will unload the input meta-kernel
    :type unload: bool
    :return: Output ET
    :rtype: Union[str, list]
    """
    out_list = []

    if isinstance(time, str):
        time = [time]

    #
    # We need to specify that is Calendar format in TDB. If it is UTC we need
    # to load the support kernels
    #
    if support_ker:
        spiceypy.furnsh(support_ker)

    if format == 'CAL':
        time[:] = [x.replace('T', ' ') for x in time]
        time[:] = [x + ' TDB' for x in time]

    for element in time:

        try:
            if format == 'UTC':
                out_elm = spiceypy.utc2et(element)

            elif format == 'CAL':
                out_elm = spiceypy.str2et(element)
            else:
                out_elm = element
        except:
            out_elm = spiceypy.str2et(element)

        out_list.append(out_elm)

    if len(out_list) == 1:
        out_time = out_list[0]
    else:
        out_time = out_list

    if unload:
        spiceypy.unload(support_ker)

    return out_time
コード例 #10
0
def FinderReboundf51_2(t, years, arr, times, vecs, IDs):
    '''
    
    Finds the radec of objects in the jovian system from the pansstars observatory a number of years before
    the time of observation and integrates it to the time of observation using rebound.
    
    Arguments:
    
    name: str
    
    The name of the object in spice documentation. See Summary_Names.txt
    
    t: float
    
    A julian date
    
    '''
    thor = Time(t, format='jd', scale='utc')
    thor = thor.tt.value
    tstr = "jd " + str(t) + " utc"
    ts = spice.str2et(tstr)
    get_earth = get_astroquery_function('0', 'geometric', 'f51')
    sec_year = 86400 * 365.25
    sim = Integrator(ts - years * sec_year, ts, [
        '1', '2', '3', '4', '6', '7', '8', 'Jupiter', 'Io', 'Europa',
        'Ganymede', 'Callisto'
    ], [
        MMercuryB, MVenusB, MEarthB, MMarsB, MSaturnB, MUranusB, MNeptuneB,
        MJupiter, MIo, MEuropa, MGanymede, MCallisto
    ], [9, 10, 11, 12, 13, 14, 15], GMSun, arr)
    ttemp = ts
    radec = []
    for j in range(0, len(times)):
        temp = "jd " + str(times[j]) + " utc"
        ttemp2 = spice.str2et(temp)
        k = sim.t + (ttemp2 - ttemp) / 86400
        ttemp = ttemp2
        sim.integrate(k)
        thor = Time(times[j], format='jd', scale='utc')
        thor = thor.tt.value
        ps = sim.particles
        dist = np.sqrt((ps[-1].x - ps[3].x)**2 + (ps[-1].y - ps[3].y)**2 +
                       (ps[-1].z - ps[3].z)**2)
        ltime = float(((dist * u.AU).to(u.m) / c) / u.s)
        k = sim.t - ltime / (24 * 3600)
        sim.integrate(k)
        ps = sim.particles
        AnSun = np.array([float(ps[-1].x), float(ps[-1].y), float(ps[-1].z)])
        #F51Sun = get_earth(thor)
        #vecs.append(F51Sun[0])
        vectors = AnSun + vecs[j][0]
        radec.append(np.array([CordConv(vectors), times[j], IDs[j]]))
        k = sim.t + ltime / (24 * 3600)
        sim.integrate(k)
    return radec
コード例 #11
0
ファイル: test_spiceypy.py プロジェクト: skulumani/astro
    def test_msi_frame_transformation_fixed(self):
        spice.kclear()
        spice.furnsh(self.near.metakernel)
        etone = spice.str2et('Jan 1, 2001 10:04:02.2 UTC')
        ettwo = spice.str2et('Feb 12, 2001 18:03:02.6 UTC')

        Rone = spice.pxform(self.near.near_body_frame, 
                self.near.near_msi_frame, etone)
        Rtwo = spice.pxform(self.near.near_body_frame,
                self.near.near_msi_frame, ettwo)
        np.testing.assert_array_almost_equal(Rone, Rtwo)
        spice.kclear()
コード例 #12
0
    def CA(self, utc_0, utc_1, step=120, abcorr='CN+S'):
        '''Search Close Approch time and distance'''
        et_0 = spice.str2et(utc_0)
        et_1 = spice.str2et(utc_1)
        times = [x * (et_1-et_0)/step + et_0 for x in range(step)]
        pos, _ = spice.spkpos(self.targ, times, self.ref, abcorr, self.obs)
        dists = np.sqrt(np.sum(np.power(pos, 2), 1))

        # Find the smallest distance
        ca_i = np.argmin(dists)
        ca_et = times[ca_i]
        ca_dist = dists[ca_i]
        return spice.et2utc(ca_et, 'ISOC', 5), ca_dist
コード例 #13
0
def gregDateOffsetCalculator(gregorian_date, delta_days, time_system_string):

    # returns the time_system_string Gregorian date, offset from the input date string by delta_days
    # gregorian_date: SPICE compatible Gregorian date string
    # delta_days: number of days that you want to advance the Gregorian date string by
    # time_system_string: string representation of the output requested for the gregorian_date's time system (e.g. "TDB", "UTC" etc.)

    return spice.timout(
        spice.str2et(
            str(
                spice.str2et(gregorian_date) / 86400.0 + 2451545.0 +
                delta_days) + " JD TDB"),
        "YYYY Mon DD ::" + time_system_string + " HR:MN:SC.######")
コード例 #14
0
    def computeOccultations(self, observer_in, occultation_bodies_in,
                            target_in, target_shape_in, target_frame_in,
                            step_size_in, aberration_correction_in,
                            greg_format_string_in):

        self.greg_format_string = greg_format_string_in
        split_string = self.greg_format_string.split(' ')
        self.time_system_string = [i for i in split_string if '::' in i][0][2:]

        self.observer = str(observer_in)
        self.occultation_bodies = occultation_bodies_in
        self.target = target_in
        self.target_shape = target_shape_in
        self.target_frame = target_frame_in
        self.search_step_size = step_size_in
        self.aberration_correction = aberration_correction_in
        self.cumulative_results = {}
        for body in self.occultation_bodies:
            # add a new key to the results dictionary for this body
            self.cumulative_results[body.name] = []
            for occultation_type in body.occultation_types:
                body.search_start_ET_seconds = spice.str2et(body.search_start)
                body.search_end_ET_seconds = spice.str2et(body.search_end)
                spice.wninsd(body.search_start_ET_seconds,
                             body.search_end_ET_seconds,
                             self.SPICE_search_window)
                spice.gfoclt(occultation_type, body.name, body.shape,
                             body.frame, self.target, self.target_shape,
                             self.target_frame, self.aberration_correction,
                             self.observer, self.search_step_size,
                             self.SPICE_search_window, self.results_window)
                winsiz = spice.wncard(self.results_window)
                for body_index in range(winsiz):
                    [intbeg, intend] = spice.wnfetd(self.results_window,
                                                    body_index)
                    btmstr = spice.timout(intbeg, self.greg_format_string)
                    etmstr = spice.timout(intend, self.greg_format_string)
                    occultation_event = OccultationEvent()
                    occultation_event.start = btmstr
                    occultation_event.stop = etmstr
                    occultation_event.start_JD = greg2Julian(btmstr)
                    occultation_event.stop_JD = greg2Julian(etmstr)
                    occultation_event.duration = intend - intbeg
                    occultation_event.type = occultation_type
                    occultation_event.observer = self.observer
                    occultation_event.occulting_body = body.name
                    occultation_event.occulting_body_shape = body.shape
                    occultation_event.target = self.target
                    occultation_event.target_body_shape = self.target_shape
                    self.cumulative_results[body.name].append(
                        occultation_event)
コード例 #15
0
ファイル: test_ITVIM.py プロジェクト: alfonsogonzalez/AWP
def test_EVME_1966(plot=False):
    '''
	Earth-Venus-Mars-Earth (EVME) 2 year trajectory
	launching in 1966
	Example comes from Richard Battin's book
	called "Astronautical Guidance"
	'''
    spice.furnsh(sd.leapseconds_kernel)
    spice.furnsh(sd.de432)

    sequence = [{
        'planet': 3,
        'time': '1966-02-10',
        'tm': -1
    }, {
        'planet': 2,
        'planet_mu': pd.venus['mu'],
        'time': '1966-07-07',
        'tm': 1,
        'tol': 1e-5
    }, {
        'planet': 4,
        'planet_mu': pd.mars['mu'],
        'time': '1967-01-10',
        'tm': -1,
        'tol': 1e-5
    }, {
        'planet': 3,
        'planet_mu': pd.earth['mu'],
        'time': '1967-12-18',
        'tol': 1e-5
    }]
    itvim = ITVIM({'sequence': sequence})
    itvim.print_summary()

    t0_target = spice.str2et('1966-02-06')
    t1_target = spice.str2et('1966-07-09')
    t2_target = spice.str2et('1967-01-24')
    t3_target = spice.str2et('1967-12-17')
    t_targets = [t0_target, t1_target, t2_target, t3_target]
    t_tol = 90 * 24 * 3600.0  # t2_target is about 3 days different

    if plot:
        itvim.plot_orbits({
            'planets': [pd.venus, pd.earth, pd.mars],
            'colors': ['m', 'c', 'lime'],
            'sc_labels': ['SC0', 'SC1', 'SC2'],
            'traj_lws': 2,
            'show': True
        })
コード例 #16
0
def occultations(body1, body2, start, end):
    cnfine = spiceypy.utils.support_types.SPICEDOUBLE_CELL(MAXWIN)
    result = spiceypy.utils.support_types.SPICEDOUBLE_CELL(MAXWIN)

    # Obtain the TDB time bounds of the confinement
    # window, which is a single interval in this case.
    et0 = spiceypy.str2et(start)
    et1 = spiceypy.str2et(end)

    # Insert the time bounds into the confinement window
    spiceypy.wninsd(et0, et1, cnfine)

    # 15-minute step. Ignore any occultations lasting less than 15 minutes.
    # Units are TDB seconds.
    step = 900.0

    obsrvr = "Earth"

    # Loop over the occultation types.
    for occtype in types:
        # For each type, do a search for both transits of
        # Titan across Saturn and occultations of Titan by Saturn.
        for j in range(2):
            if not j:
                front = body1
                fframe = "IAU_" + body1
                back = body2
                bframe = "IAU_" + body2
            else:
                front = body2
                fframe = "IAU_" + body2
                back = body1
                bframe = "IAU_" + body1

            spiceypy.gfoclt(occtype, front, "ellipsoid", fframe, back,
                            "ellipsoid", bframe, "lt", obsrvr, step, cnfine,
                            result)

            # Display the results
            print()
            title = spiceypy.repmc("Condition: # occultation of # by #", "#",
                                   occtype)
            title = spiceypy.repmc(title, "#", back)
            title = spiceypy.repmc(title, "#", front)
            print(title)

            for r in result:
                print(spiceypy.timout(r, "YYYY Mon DD HR:MN:SC"))
コード例 #17
0
def lon_lat_r(body, time, earth_radius=6371e3):
    """
    Use SPICE software to get longitude and latitude of the point on Earth at
    which <body> is in zenith and the distance between the barycenters of Earth
    and <body> at a specified <time> (in UTC). We're pretending the earth is a
    sphere here, as is commonly done in tidal studies (and presumably is done in
    the ocean model this is fed into).

    Input:
      body         - SPICE name of the body (e.g. "SUN" or "MOON")
      time         - date and time in datetime format (UTC)
      earth_radius - radius of the earth (default 6371e3 m)
    Output:
      lon, lat     - longitude and latitude at which <body> is in zenith
      r            - range of the body (distance between barycenters)
    """

    # convert UTC time to ephemeris time
    time = spice.str2et(str(time) + " UTC")

    # get position in rectangular coordinate system (body frame of Earth)
    pos_rec, _ = spice.spkpos(body, time, "ITRF93", "NONE", "EARTH")

    # transform to geodetic coordinates assuming zero flatness (to get lat/lon)
    pos_geo = spice.recgeo(pos_rec, earth_radius / 1e3, 0)

    # transform to range, right ascension, declination (to get range)
    pos_rad = spice.recrad(pos_rec)

    # isolate coordinates we'll need (and convert from km to m)
    lon = pos_geo[0]
    lat = pos_geo[1]
    r = pos_rad[0] * 1e3

    return lon, lat, r
コード例 #18
0
ファイル: spice.py プロジェクト: vigneshtdev/heliopy
    def generate_positions(self, times, observing_body, frame):
        """
        Generate positions from a spice kernel.

        Parameters
        ----------
        times : iterable of `datetime`
            An iterable (e.g. a `list`) of `datetime` objects at which the
            positions are calculated.
        observing_body : str
            The observing body. Output position vectors are given relative to
            the position of this body.
            See https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html
            for a list of bodies.
        frame : str
            The coordinate system to return the positions in.
            See https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/frames.html
            for a list of frames.
        """
        # Spice needs a funny set of times
        fmt = '%b %d, %Y'
        spice_times = [spiceypy.str2et(time.strftime(fmt)) for time in times]
        observing_body = observing_body
        # 'None' specifies no light-travel time correction
        positions, lightTimes = spiceypy.spkpos(self.target, spice_times,
                                                frame, 'None', observing_body)
        positions = np.array(positions) * u.km

        self._times = times
        self._positions = positions
        self._x = positions[:, 0]
        self._y = positions[:, 1]
        self._z = positions[:, 2]
        self._generated = True
        self._observing_body = observing_body
def getNacCenterAndRotationAtTime(imname):
    '''
    Extract the rotation of the spacecraft and its position for the given picture
    Notice that WAV and NAC can be considered aligned on the same axis and centred in the spacecraft
    so it can be used the same way independently by the camera
    :param imname: the input picture filename
    :return: the centre and the rotation matrix of the spacecraft
    '''
    os.chdir(spice_kernels_dir)  # or spyceypy will not work
    spiceypy.furnsh(spice_kernels_dir + os.path.sep +
                    furnsh_file)  #load the kernels from furnsh

    tstr = extractTimeString(
        imname)  # get only the time string from the filename
    t = spiceypy.str2et(tstr)  # transform the string to a time

    # get the position of Rosetta spacecraft in 67p refence frame, centred in 67P + light time corr (not really needed)
    pos = spiceypy.spkpos("ROSETTA", t, "67P/C-G_CK", "LT+S", "67P/C-G")[0]
    # pos = spiceypy.spkpos("ROSETTA", t, "ROS_OSIRIS_NAC", "LT+S", "67P/C-G")[0]

    print("Found position: {}".format(pos))

    #and the rotation - we use NAC but it is the same for the WAC
    # R = spiceypy.pxform("67P/C-G_CK", "ROS_OSIRIS_NAC", t);
    # rotation matrix of the nac camera, in respect to 67P reference frame
    R = spiceypy.pxform("ROS_OSIRIS_NAC", "67P/C-G_CK", t)
    return np.array(pos), np.array(R)
コード例 #20
0
    def mjd2et(self, time):
        """Convert MJD to ET

        """

        time = time + 2400000.5
        return (sp.str2et('JD ' + repr(time)))
コード例 #21
0
 def ephemeris_stop_time(self):
     if self.spacecraft_clock_stop_count:
         return spice.scs2e(self.spacecraft_id,
                            self.spacecraft_clock_stop_count)
     else:
         return spice.str2et(
             self.utc_stop_time.strftime("%Y-%m-%d %H:%M:%S"))
コード例 #22
0
def epoch(utc):
    '''
    Converts two UTC dates to julian time and calculate the change in epoch
    Args:
        utc - mission start and end dates as two strings in an array
    Returns:
        etOne - start date in julian time
        etTwo - end date in julian time
        dt - change in epoch in seconds
    '''
    # convert to julian time
    etOne = spice.str2et(utc[0])
    etTwo = spice.str2et(utc[1])
    # difference in epoch
    dt = etTwo - etOne
    return etOne, etTwo, dt
コード例 #23
0
    def generateDistanceReport(self,
                               output_file,
                               ephemeris_file,
                               body_SPICE_IDs=[]):
        header_row = "Gregorian_date_TDB, Julian_date_TDB, "
        for bodyID in body_SPICE_IDs:
            pass

        ephem_file_rows = self.ephemeris_file_reader.parseEMTGephemerisFile(
            ephemeris_file)
        for ephem_row in ephem_file_rows:
            # compute distance from the Sun
            spacecraft_distance_from_sun = np.sqrt(
                ephem_row.spacecraft_position_x**2 +
                ephem_row.spacecraft_position_y**2 +
                ephem_row.spacecraft_position_z**2)

            for bodyID in body_SPICE_IDs:
                # get the distance from the Sun to the body
                current_seconds_past_J2000 = spice.str2et(
                    ephem_row.gregorian_date)
                body_state_ICRF, sun_body_light_times = spice.spkez(
                    10, current_seconds_past_J2000, 'J2000', 'NONE', bodyID)
                spacecraft_distance_from_body = np.sqrt(
                    (ephem_row.spacecraft_position_x - body_state_ICRF[0])**2 +
                    (ephem_row.spacecraft_position_y - body_state_ICRF[1])**2 +
                    (ephem_row.spacecraft_position_z - body_state_ICRF[2])**2)
コード例 #24
0
def FinderSpicef51(name, t):
    '''
    
    Finds the radec of objects in the jovian system from the pansstars observatory. Used to test the correspondence
    of spice and Horizons.
    
    Arguments:
    
    name: str
    
    The name of the object in spice documentation. See Summary_Names.txt
    
    t: float
    
    A julian date
    
    '''
    thor = Time(t, format='jd', scale='utc')
    thor = thor.tt.value
    tstr = "jd " + str(t) + " utc"
    ts = spice.str2et(tstr)
    get_earth = get_astroquery_function('0', 'geometric', 'f51')
    get_jup = get_spice_function(name, "NONE", "0")
    exyz = get_earth(thor)
    jxyz = get_jup(ts)
    fxyz = LT(ts, -exyz[0], get_jup)
    vectors = fxyz[0] + exyz[0]
    return CordConv(vectors)
コード例 #25
0
    def populateManeuverData(self, control_segment_data):
        """Parses the data from a single row in a .mission_meneuver_spec file into multiple maneuver event objects"""
        data_index = 0
        for maneuver in self.maneuvers:
            maneuver.frame = control_segment_data[data_index].strip()
            maneuver.gregorian_date = control_segment_data[data_index +
                                                           1].strip()

            # if no time system is specified, assume it is TDB
            if "TDB" not in maneuver.gregorian_date or "TDT" not in maneuver.gregorian_date or "UTC" not in maneuver.gregorian_date:
                maneuver.gregorian_date = maneuver.gregorian_date + " TDB"

            maneuver.julian_date = spice.str2et(
                maneuver.gregorian_date) / 86400.0 + 2451545.0
            maneuver.GMAT_julian_date = SpiceyUtil.greg2GMATJulian(
                maneuver.gregorian_date)
            maneuver.control_x = float(control_segment_data[data_index + 2])
            maneuver.control_y = float(control_segment_data[data_index + 3])
            maneuver.control_z = float(control_segment_data[data_index + 4])
            maneuver.control_magnitude = float(
                control_segment_data[data_index + 5])
            maneuver.starting_spacecraft_mass = float(
                control_segment_data[data_index + 6])
            maneuver.mass_flow_rate = float(control_segment_data[data_index +
                                                                 7])
            maneuver.duty_cycle = float(control_segment_data[data_index + 8])
            maneuver.final_spacecraft_mass = float(
                control_segment_data[data_index + 9])
            maneuver.delta_v = float(control_segment_data[data_index + 10])
            maneuver.duration = float(control_segment_data[data_index + 11])
            maneuver.epochET_seconds = float(control_segment_data[data_index +
                                                                  12])
            data_index = data_index + 13
コード例 #26
0
def datetime2et(time: datetime) -> float:
    """ Convert datetime to SPICE ephemeris time."""
    if isinstance(time, float):
        return time
    if not isinstance(time, datetime):
        raise TypeError("Time must be a float or a datetime object.")
    return spy.str2et(time.isoformat())
コード例 #27
0
    def nightlystates(self,timerange):
        
        """ Generate asteroid state at every midnight within the input time range
        
        Expects integer MJD dates (midnight). Generates geocentric coordinates
        (range, RA, DEC, rangerate, dRA, dDec) for the asteroid at each midnight
        between, and including, start and end.

        Parameters
        ----------
            timerange: 2 element float numpy array
                [Starting time, Ending time] (MJD)
                
        """

        # Converting from MJD to JD and computing number of days including endpoints
        start=int(timerange[0])+shared.mjd2jd
        stop =int(timerange[-1])+shared.mjd2jd
        ndays=int(stop-start)+1

        # Loading SPK
        try:
            sp.furnsh(self.spkname)
        except:
            sys.exit("Cannot load %s" %(self.spkname))

        # Initializing state variables
        self.nightlyt=np.zeros(ndays)
        self.nightlyr=np.zeros(ndays)
        self.nightlydr=np.zeros(ndays)
        self.nightlyra=np.zeros(ndays)
        self.nightlydra=np.zeros(ndays)
        self.nightlydec=np.zeros(ndays)
        self.nightlyddec=np.zeros(ndays)
 
        counter = -1

        for i in np.linspace(start,stop,num=ndays):

            counter += 1

            # Converting from UTC to ET
            timeet=sp.str2et('JD '+repr(i))

            # Finding direction of asteroids from geocenter
            # Finding states wrt station adds 4 days for 1e6 objects

            asteroidsvec=sp.spkezr(str(self.spiceid),timeet,"J2000","LT","Earth") # Units are km and km/s
            
            # Converting from Rectangular to Latitudinal coordinates.
            # tmp is a 6 element vector (R, Long, Lat, Dr, Dlong, Dlat) Units are radians and radians/s
            tmp=sp.xfmsta(asteroidsvec[0][0:6],"RECTANGULAR","LATITUDINAL"," ")

            self.nightlyt[counter]   = i
            self.nightlyr[counter]   = tmp[0]
            self.nightlydr[counter]  = tmp[3]
            self.nightlyra[counter]  = tmp[1]
            self.nightlydra[counter] = tmp[4]
            self.nightlydec[counter] = tmp[2]
            self.nightlyddec[counter]= tmp[5]
コード例 #28
0
def cassini_surfintercerpt(utc, output=False):
    target = 'TITAN'
    fixref = 'IAU_TITAN'
    dref = 'IAU_TITAN'
    method = 'ELLIPSOID'
    abcorr = 'NONE'
    obsrvr = 'CASSINI'
    state = cassini_phase(utc)
    dvec = spice.vhat(-state[:3])

    et = spice.str2et(utc)

    [point, trgepc, srfvec] = spice.sincpt(method, target, et, fixref, abcorr,
                                           obsrvr, dref, dvec)
    temp = spice.reclat(point)

    radius = temp[0]
    colat = 90 + spice.convrt(temp[1], "RADIANS", "DEGREES")
    lon = np.mod(spice.convrt(temp[2], "RADIANS", "DEGREES"), 360)

    if output:
        print("Distance to Intercept Point", spice.vnorm(srfvec))
        print("Radius", radius)
        print("Colatitude", colat)
        print("Longtitude", lon)

    return point, [radius, colat, lon], spice.vnorm(srfvec)
コード例 #29
0
    def mjd2et(self, time):
        """Convert MJD to ET (seconds past J2000)

        """

        time = time + shared.mjd2jd
        return (sp.str2et('JD ' + repr(time)))
コード例 #30
0
ファイル: test_ITVIM.py プロジェクト: alfonsogonzalez/AWP
def test_ITVIM_EME_1963_2_year(plot=False):
    '''
	Earth-Mars-Earth (EME) 2 year trajectory
	launching in 1963
	Example comes from Richard Battin's book
	called "Astronautical Guidance"
	'''
    spice.furnsh(sd.leapseconds_kernel)
    spice.furnsh(sd.de432)

    sequence = [{
        'planet': 3,
        'time': '1963-06-21',
        'tm': -1
    }, {
        'planet': 4,
        'planet_mu': pd.mars['mu'],
        'time': '1964-12-30 20:20:21.5',
        'tm': 1,
        'tol': 1e-5
    }, {
        'planet': 3,
        'time': '1965-05-14',
        'tol': 1e-5
    }]
    itvim = ITVIM({'sequence': sequence})
    itvim.print_summary()

    vinf_target0 = 18200.0 * nt.fps2kms
    vinf_target1 = 28852.0 * nt.fps2kms
    vinf_tol = 0.05
    rp_target = 7892.0 * nt.mi2km + pd.mars['radius']
    rp_tol = 1
    t0_target = spice.str2et('1963-06-21')
    t1_target = spice.str2et('1964-12-31')
    t2_target = spice.str2et('1963-06-21')
    t_tol = 1 * 24 * 3600.0

    assert itvim.seq[0]['v_infinity'] == pytest.approx(vinf_target0,
                                                       abs=vinf_tol)
    assert itvim.seq[1]['v_infinity'] == pytest.approx(vinf_target1,
                                                       abs=vinf_tol)
    assert itvim.seq[1]['periapsis'] == pytest.approx(rp_target, abs=rp_tol)
    assert itvim.seq[1]['et'] == pytest.approx(t1_target, abs=t_tol)

    if plot:
        itvim.plot_orbits()
コード例 #31
0
ファイル: tquakes.py プロジェクト: seap-udea/tQuakes
def dtime2etjd(dtime):
    import spiceypy as sp

    # dtime in DATETIME_FORMAT="%d/%m/%y %H:%M:%S"
    dtime=datetime.datetime.strptime(dtime,DATETIME_FORMAT)
    dtime=dtime.strftime("%m/%d/%Y %H:%M:%S.%f")
    qet=sp.str2et(dtime)
    qjd=et2jd(qet)

    return qet,qjd
コード例 #32
0
ファイル: time.py プロジェクト: johnnycakes79/pyops
def datetime_to_et(dtime, scale='UTC'):
    """
    convert a python datetime to SPICE ephemerides seconds (TBD)

    Args:
        dtime (datetime): python datetime
        scale (str, optional): time scale of input time (default: UTC)

    Returns:
        float: SPICE ephemerides sceonds (TBD)
    """
    return spice.str2et(dtime.strftime(
        '%m/%d/%y %H:%M:%S.%f ({})'.format(scale)))
コード例 #33
0
ファイル: vgCenter.py プロジェクト: bburns/PyVoyager
def getTargetPosition(target, craft, camera, time):
    """
    get position of target in world coordinates relative to the observing craft.
    """
    
    # get target code
    targetId = spice.bodn2c(target) # eg 'Jupiter'->599

    # get spacecraft instrument        
    spacecraft = -31 if craft=='Voyager1' else -32
    spacecraftBus = spacecraft * 1000
    spacecraftScanPlatform = spacecraftBus - 100
    spacecraftNarrowCamera = spacecraftScanPlatform - 1
    spacecraftWideCamera = spacecraftScanPlatform - 2
    # instrument = spacecraftBus # use for NAIF continuous kernels
    instrument = spacecraftScanPlatform # use for PDS discrete kernels

    # get ephemeris time
    # note: target and spacecraft locations are stored relative to J2000
    # time is utc time as string
    ephemerisTime = spice.str2et(time) # seconds since J2000 (will be negative)
    # sclkch = spice.sce2s(spacecraft, ephemerisTime) # spacecraft clock ticks, string
    # sclkdp = spice.sce2c(spacecraft, ephemerisTime) # spacecraft clock ticks, double
    clockTicks = spice.sce2c(spacecraft, ephemerisTime) # spacecraft clock ticks, double
    # print 'clockTicks',clockTicks

    # get position of target relative to spacecraft
    # this is the direction from craft to target in ECLIPB1950 frame
    observer = 'Voyager ' + craft[-1] # eg 'Voyager 1'
    frame = 'ECLIPB1950' # coordinate frame
    abberationCorrection = 'NONE'
    position, lightTime = spice.spkpos(target, ephemerisTime, frame,
                                       abberationCorrection, observer)
    # print 'target position relative to observer', position

    return position
コード例 #34
0
ファイル: astronomy-cycles.py プロジェクト: seap-udea/tQuakes
# EARTH SURFACE GRAVITY
g=9.8 # m/s^2

# DOODSON CONSTANTS (Hendershott, Lecture on Tides)
Dmoon=0.2675*g # m/s^2
Dsun=0.4605*Dmoon # m/s^2

# MEAN ORBITAL DISTANCE
Rmoon=3.84399e5 # m
Rsun=1.49598023e8 # m

# ######################################################################
# SPICE RELATED ROUTINES
# ######################################################################
# Ephemeris time: et=sp.str2et("01/01/2015 00:00:00.000 UTC")
etini=sp.str2et("01/01/%s 00:00:00.000 UTC"%yini)
jdini=et2jd(etini)
etend=sp.str2et("01/01/%s 00:00:00.000 UTC"%yend)
print "Number of days:",(etend-etini)/DAY
det=1.0*DAY/6
det=1*HOUR

astronomy=[]
et=etini
while True:
    # STATE VECTOR MOON AND SUN
    rmoon=sp.spkezr("MOON",et,"J2000","NONE","399")
    rsun=sp.spkezr("SUN",et,"J2000","NONE","399")
    Rm,vm=normX(rmoon)
    Rs,vs=normX(rsun)
    V=Dmoon*(Rmoon/Rm)**3+Dsun*(Rsun/Rs)**3
コード例 #35
0
ファイル: insertquakes.py プロジェクト: seap-udea/tQuakes
    # GENERATE A RANDOM ID
    q=1
    while q:
        quakeid=randomStr(7)
        q=db.execute("select quakeid from Quakes where quakeid='%s';"%quakeid)
    quake["quakeid"]=quakeid
    print "\tQuake id: ",quakeid

    # CALCULATE JULIAN DAY AND EPHEMERIS TIME
    quake["qdatetime"]=quake["Fecha"]+" "+quake["Hora UTC"];
    """
    qdate=datetime.datetime.strptime(quake["qdatetime"],DATETIME_FORMAT)
    quake["qjd"]=date2jd(qdate)
    """
    dtime=qdate.strftime("%m/%d/%Y %H:%M:%S.%f")
    qet=sp.str2et(dtime)
    qjd=et2jd(et)
    quake["qet"]="%.3f"%et
    quake["qjd"]="%.6f"%qjd

    # CALCULATE HOUR ANGLE OF THE MOON AND THE SUN
    qlon=float(quake["Longitud"])
    hmoon=bodyHA("MOON",qet,qlon)
    hsun=bodyHA("SUN",qet,qlon)
    quake["hmoon"]="%.5f"%(hmoon)
    quake["hsun"]="%.5f"%(hsun)

    print "\tDate: ",quake["qdatetime"]
    print "\tJD: ",quake["qjd"]
    print "\tET: ",quake["qet"]
コード例 #36
0
ファイル: vgMap.py プロジェクト: bburns/PyVoyager
def vgMap(filterVolumes=None, optionOverwrite=False, directCall=True):

    "Build up 2d color map"

    # # cmd = "echo $ISISROOT"
    # cmd = "env | ag ^ISIS"
    # s = lib.system(cmd)
    # print s


    # load SPICE kernels (data files) with camera and target positions, etc
    libspice.loadKernels()

    # read small dbs into memory
    # centeringInfo = lib.readCsv(config.dbCentering) # when to turn centering on/off
    retargetingInfo = lib.readCsv(config.dbRetargeting) # remapping listed targets
    csvPositions, fPositions = lib.openCsvReader(config.dbPositions) # for target size

    # # dictionary to keep track of last image file in target sequence (eg for Ariel flyby)
    # lastImageInTargetSequence = {}

    # size of 2d map
    mymax = 800
    mxmax = 2 * mymax
    mxcenter = mxmax/2
    mycenter = mymax/2

    # set up blank mapping arrays: h(x,y) = (hx(x,y), hy(x,y))
    # h tells map where to pull its pixels from - ie map(mx,my) = im(h(mx,my))
    hx = np.zeros((mymax,mxmax),np.float32)
    hy = np.zeros((mymax,mxmax),np.float32)

    # make blank maps for each color channel
    #. each system-craft-target-camera-channel will need its own png map file to write to and colorize from
    # store in a map folder
    # bluemap = np.zeros((mymax,mxmax),np.float32)
    bluemap = np.zeros((mymax,mxmax),np.uint8)
    # each might also need a count map, if wind up averaging things together to smooth things out
    # would prefer to avoid it if possible though - adds more complexity and i/o
    countmap = np.zeros((mymax,mxmax),np.uint8)

    # iterate through all available images, filter on desired volume or image
    csvFiles, fFiles = lib.openCsvReader(config.dbFiles)
    nfile = 1
    for rowFiles in csvFiles:
        volume = rowFiles[config.colFilesVolume]
        fileId = rowFiles[config.colFilesFileId]

        # filter to given volume
        # if volume!=filterVolume: continue

        # get image properties
        filter = rowFiles[config.colFilesFilter]
        system = rowFiles[config.colFilesSystem]
        craft = rowFiles[config.colFilesCraft]
        target = rowFiles[config.colFilesTarget]
        camera = rowFiles[config.colFilesCamera]
        time = rowFiles[config.colFilesTime]
        note = rowFiles[config.colFilesNote]

        # relabel target field if necessary
        target = lib.retarget(retargetingInfo, fileId, target)

        #. skip others
        if fileId!='C1465335': continue

        # get cube filename
        cubefile = lib.getFilepath('import', volume, fileId)
        if not os.path.isfile(cubefile):
            # print 'warning file not found', cubefile
            continue #. for now


        # get folders
        importSubfolder = lib.getSubfolder('import', volume)
        jpegSubfolder = importSubfolder + 'jpegs/'
        # mapSubfolder = importSubfolder + 'maps/'
        mapSubfolder = importSubfolder #. for now
        lib.mkdir(jpegSubfolder)
        lib.mkdir(mapSubfolder)

        # export as jpeg
        imagefile = jpegSubfolder + fileId + '.jpg'
        # if not os.path.isfile(imagefile):
        if 1:
            cmd = "isis2std from=%s to=%s format=jpeg" % (cubefile, imagefile)
            print cmd
            lib.system(cmd)

        # print 'Volume %s mapping %d: %s      \r' % (volume,nfile,infile),
        # print 'Volume %s mapping %d: %s' % (volume,nfile,infile)
        nfile += 1


        # get target code, eg Jupiter
        targetId = spice.bodn2c(target) # eg 'Jupiter'->599
        # print target, targetId

        # get instrument
        spacecraft = -31 if craft=='Voyager1' else -32
        spacecraftBus = spacecraft * 1000 # eg -31000
        spacecraftScanPlatform = spacecraftBus - 100 # eg -31100
        spacecraftNarrowCamera = spacecraftScanPlatform - 1 # eg -31101
        spacecraftWideCamera = spacecraftScanPlatform - 2 # eg -31102
        # instrument = spacecraftBus # eg -31000, use for NAIF continuous kernels
        instrument = spacecraftScanPlatform # eg -31100, use for PDS discrete kernels

        # get ephemeris time
        ephemerisTime = spice.str2et(time) # seconds since J2000 (will be negative)

        # world coordinate frame to use
        # (ECLIPB1950 is how the voyager and planet positions are encoded)
        frame = 'ECLIPB1950'

        # get world-to-camera matrix (camera pointing matrix)
        # C is a transformation matrix from ELIPB1950 to the instrument-fixed frame
        # at the given time
        C = getCameraMatrix(frame, spacecraft, instrument, ephemerisTime)
        print 'C=camera pointing matrix - transform world to camera coords'
        print C

        # get world-to-body matrix
        # B = getBodyMatrix(frame, targetId, ephemerisTime)
        B = spice.tipbod(frame, targetId, ephemerisTime)
        print 'B=world to body/target frame matrix'
        print B


        # get boresight vector
        # this is just the third row of the C-matrix, *per spice docs*
        boresight = C[2]
        print 'boresight pointing vector',boresight

        # get location of prime meridian
        rotationRate = 870.5366420 # deg/day for great red spot
        primeMeridian = rotationRate /24/60/60 * ephemerisTime # deg
        print 'primeMeridian (deg)', primeMeridian % 360
        primeMeridianRadians = primeMeridian * math.pi/180

        # get target position in world coordinates
        # ie vector from craft to target
        # and distance
        observer = 'Voyager ' + craft[-1] # eg Voyager 1
        abberationCorrection = 'NONE'
        position, lightTime = spice.spkpos(target, ephemerisTime, frame,
                                           abberationCorrection, observer)
        # position = getObserverToTargetVector(frame, observer, target, ephemerisTime)
        distance = libspice.getDistance(position)
        posnormal = position / distance
        print 'target position relative to observer',position
        print 'distance in km',distance
        print 'position normalized', posnormal

        # see how different boresight and position vector are
        dot = np.dot(boresight, posnormal)
        theta = math.acos(dot) * 180/math.pi
        print 'angle between boresight and position vector', theta


        # what longitudes are visible?
        #.. get from position of craft
        visibleLongitudesMin = 0
        visibleLongitudesMax = math.pi

        # get tilt of north pole relative to image y-axis
        npRadians = getNorthPoleAngle(target, position, C, B, camera)

        # get axial tilt rotation matrix
        cc = math.cos(npRadians)
        ss = math.sin(npRadians)
        mTilt = np.array([[cc,-ss],[ss,cc]])

        # get expected angular size (as fraction of frame) and radius
        imageFraction = lib.getImageFraction(csvPositions, fileId)
        targetRadiusPx = int(400*imageFraction) #.param

        # read the (centered) image
        im = cv2.imread(imagefile)

        # draw the target's north pole on image
        # im = drawNorthPole(im)

        # build hx,hy arrays, which tell map where to pull pixels from in source image
        # m: map (0 to mxmax, 0 to mymax)
        r = targetRadiusPx # pixels
        for mx in xrange(mxmax): # eg 0 to 1600
            for my in xrange(mymax): # eg 0 to 800

                # q: map (0 to 2pi, -1 to 1)
                qx = float(mx) / mxmax * 2 * math.pi + primeMeridianRadians
                qx = qx % (2 * math.pi) # 0 to 2pi
                qy = -float(my-mycenter)/mycenter # 1 to -1

                # s: image (-1 to 1, -1 to 1)
                sx = -math.sqrt(1 - qy**2) * math.cos(qx) # -1 to 1
                sy = qy # 1 to -1

                # rotate s to account for axial tilt relative to camera up axis
                # ie s = mTilt * s
                s = np.array([sx,sy])
                s = np.dot(mTilt,s)
                sx,sy = s

                # p: image (0 to 800, 0 to 800)
                px = sx * r + 400 # 0 to 800
                py = -sy * r + 400 # 0 to 800

                # hx[my][mx] = px
                # hy[my][mx] = py
                visible = (qx >= visibleLongitudesMin) and (qx <= visibleLongitudesMax)
                if visible:
                    hx[my][mx] = px
                    hy[my][mx] = py
                else:
                    hx[my][mx] = 0
                    hy[my][mx] = 0

        # do map projection
        map = cv2.remap(im, hx, hy, cv2.INTER_LINEAR)
        map = map[:,:,0]
        # map = np.array(map, np.float32)
        libimg.show(map)

        # save map as png file
        mapfile = mapSubfolder + fileId + '-map.png'
        cv2.imwrite(mapfile, map)

        sys.exit(0)


        # #. now need to blend this into the main map for this filter

        # # print type(map[0][0])
        # # print type(bluemap[0][0])

        # # bluemap = cv2.addWeighted(bluemap, 0.5, map, 0.5, 0)

        # # ret, countzero = cv2.threshold(countmap, 0,255, cv2.THRESH_BINARY)
        # # ret, countone = cv2.threshold(countmap, 0,255, cv2.THRESH_BINARY)
        # # countzero = 255-countone
        # # ret, mapMask = cv2.threshold(map, 1, 255, cv2.THRESH_BINARY)
        # # mapMask = cv2.bitwise_and(countzero, mapMask)
        # # c = mapMask & 1
        # # countmap += c

        # # libimg.show(countmap)

        # # ret, mapnonzero = cv2.threshold(map, 0,1, cv2.THRESH_BINARY)
        # ret, mapnonzero = cv2.threshold(map, 1,1, cv2.THRESH_BINARY)

        # countmapPlusOne = countmap + 1
        # countmap2 = countmap + 1-mapnonzero
        # base = np.array(bluemap, np.float32)
        # # base = base * countmap / countmapPlusOne
        # base = base * countmap2 / countmapPlusOne
        # newmap = np.array(map, np.float32)
        # newmap = newmap / countmapPlusOne
        # newbase = base + newmap
        # newbase = np.array(newbase, np.uint8)

        # # increment countmap where map image data exists
        # countmap += mapnonzero
        # # countmap = cv2.bitwise_and(countmap, mapnonzero)
        # countmap = np.clip(countmap, 0, 4)

        # bluemap = newbase
        # libimg.show(bluemap)



        # # # libimg.show(mapMask)
        # # mapMaskInv = 255-mapMask
        # # # libimg.show(mapMaskInv)

        # # bluemapSame = cv2.bitwise_and(bluemap, mapMaskInv)
        # # bluemapChange = cv2.bitwise_and(bluemap, mapMask)
        # # bluemapChange = cv2.addWeighted(bluemapChange, 0.5, map, 0.5, 0)
        # # # bluemapNew = cv2.bitwise_and(map, mapMask)

        # # bluemap = bluemapSame + bluemapChange
        # # # bluemap = bluemapSame + bluemapNew
        # # libimg.show(bluemap)


        # # bluemap = cv2.bitwise_and(bluemap, mapMaskInv)
        # # libimg.show(bluemap)
        # # bluemap = bluemap + map
        # # libimg.show(bluemap)


        # # if nfile>0:
        # # if nfile>3:
        # # if nfile>5:
        # if nfile>8:
        #     sys.exit(0)


    fPositions.close()
    fFiles.close()

    print
コード例 #37
0
ファイル: main.py プロジェクト: abieler/3d-tool
    s.data.cell_data.scalars = np.cos(phaseAngle)
    surf = mlab.pipeline.surface(s)
    surf.contour.filled_contours = True
    surf.contour.minimum_contour = 0.0
    surf.contour.maximum_contour = 1.0
    surf.module_manager.scalar_lut_manager.data_range = (0,1)
    mlab.view(v)
    mlab.draw()

r_hat_virtis = np.array([0,0,1])
spice.furnsh("../input/spiceMetafile.tm")

# t = time for which the pointing is calculated
t = datetime.datetime(2015,4,25,0,28)
timeStamp = datetime.datetime.strftime(t, '%Y-%m-%dT%H:%M:%S')
et = spice.str2et(timeStamp)

# define virtis bore sight vector, first in instrument reference frame
# (which is [0,0,1]) and then rotate this vector into the comet centric
# frame of reference for the given time t.
rVirtis_hat = np.array([0,0,1])
R = spice.pxform('ROS_OSIRIS_NAC','67P/C-G_CK', et)
rVirtis_hat = np.dot(R, rVirtis_hat)
nPixelsX = 3
nPixelsY = 3
pVectors = pointing_vectors(nPixelsX, nPixelsY)

################################################################################
# compute coordinates of S/C and Sun in the comet body centric frame
m2km = 1000
observer = 'CHURYUMOV-GERASIMENKO'
コード例 #38
0
ファイル: test.py プロジェクト: bburns/PyVoyager
    prec = 0
    s = spice.et2utc(et, formatStr, prec, lenout=256)
    return s

def getDistance(x,y,z):
    return math.sqrt(x**2+y**2+z**2)


# load kernels (data files)
spice.furnsh('naif0012.tls') # leap second data
spice.furnsh('Voyager_1.a54206u_V0.2_merged.bsp')
spice.furnsh('Voyager_2.m05016u.merged.bsp')
# spice.furnsh('jup100.bsp') # jupiter satellite data (20mb)

# get ephemeris time (seconds since J2000)
etStart = spice.str2et(utcStart)
etStop = spice.str2et(utcStop)

# get time range
nsteps = 50
etTimes = [i*(etStop-etStart)/nsteps + etStart for i in range(nsteps)]

# get vectors from observer to target
# see http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/spkpos_c.html
frame = 'J2000'
abcorr = 'NONE' # abberation correction
positions, lightTimes = spice.spkpos(target, etTimes, frame, abcorr, observer)



コード例 #39
0
ファイル: vgPlot.py プロジェクト: bburns/PyVoyager
def vgPlot():
    
    "create plot for each system flyby"

    loadSpice()

    #. loop through these, save each file to stepxx_maps/map-Jupiter-Voyager1.jpg etc
    #. crop each file when done to a square
    #. vg titles could use these for titlepage for each system flyby
    #. might as well draw info on maps here - Voyager 1 at Jupiter, date, etc - futura font


    # note: azimuthElevation values were determined with the plot viewer
    class Flyby:
        bodies = None
        date = None
        ndays = None
        axisMax = 1e6 # km
        axisCenter = (0,0,0)
        azimuthElevation = None

    flybys = []

    flyby = Flyby()
    flyby.bodies = ['Jupiter', 'Voyager 1', 'Io', 'Europa', 'Ganymede', 'Callisto']
    flyby.date = "1979-03-05"
    flyby.ndays = 4
    flyby.axisMax = 1e6 # km
    flyby.axisCenter = (0.6e6,-0.2e6,0)
    flyby.azimuthElevation = (-100,48)
    flybys.append(flyby)

    flyby = Flyby()
    flyby.bodies = ['Saturn', 'Voyager 1','Titan','Enceladus','Rhea','Mimas','Tethys','Dione']
    flyby.date = "1980-11-12"
    flyby.ndays = 3
    flyby.axisMax = 0.6e6 # km
    flyby.axisCenter = (-0.4e6,-0.4e6,0)
    flyby.azimuthElevation = (80,97)
    flybys.append(flyby)

    flyby = Flyby()
    flyby.bodies = ['Jupiter', 'Voyager 2', 'Io', 'Europa', 'Ganymede', 'Callisto']
    flyby.date = "1979-07-09"
    flyby.ndays = 5
    flyby.axisMax = 1e6 # km
    flyby.axisCenter = (-0.2e6,0,0)
    flyby.azimuthElevation = (102,107)
    flybys.append(flyby)

    flyby = Flyby()
    flyby.bodies = ['Saturn','Voyager 2','Titan','Enceladus','Rhea','Mimas','Tethys','Dione']
    flyby.date = "1981-08-26"
    flyby.ndays = 2
    flyby.axisMax = 0.6e6 # km
    flyby.axisCenter = (-0.2e6,0.1e6,0)
    flyby.azimuthElevation = (172,82)
    flybys.append(flyby)

    flyby = Flyby()
    flyby.bodies = ['Uranus','Voyager 2','Ariel','Miranda','Oberon','Titania','Umbriel']
    flyby.date = "1986-01-25"
    flyby.ndays = 2
    flyby.axisMax = 0.4e6 # km
    flyby.azimuthElevation = (-82,-7)
    flybys.append(flyby)

    flyby = Flyby()
    flyby.bodies = ['Neptune','Voyager 2','Triton'] # proteus not in kernels
    flyby.date = "1989-08-25"
    flyby.ndays = 2
    flyby.axisMax = 1e6 # km
    flyby.azimuthElevation = (-62,40)
    flybys.append(flyby)


    for flyby in flybys:

        planet = flyby.bodies[0]
        observer = flyby.bodies[1]
        
        print 'Generating plot for %s at %s' % (observer, planet)

        nsteps = 100 # plot density

        # get ephemeris time around closest approach (seconds since J2000)
        etClosest = int(spice.str2et(flyby.date))
        etStart = int(etClosest - flyby.ndays * 24*60*60 / 2)
        etEnd = int(etClosest + flyby.ndays * 24*60*60 / 2)
        etStep = int((etEnd - etStart) / nsteps)

        # initialize data structs
        ets = []
        positions = []
        minDist = {}
        minPos = {}
        for body in flyby.bodies:
            minDist[body] = 9e15

        # loop over time range, get positions
        for et in xrange(etStart, etEnd, etStep):
            row = []
            for body in flyby.bodies:
                # get position of body (voyager or moon) relative to planet (eg Jupiter).
                # position is an (x,y,z) coordinate in the given frame of reference.
                frame = 'J2000'
                abberationCorrection = 'NONE'
                position, lightTime = spice.spkpos(planet, et, frame, abberationCorrection, body)

                # save time and position to arrays
                ets.append(et)
                row.append(position)

                # find closest approach of voyager to each body
                if body==observer: # voyager
                    posVoyager = position # save for other bodies
                    # distance = int(libspice.getDistance(position))
                    # if distance < minDist[body]:
                        # minDist[body] = distance
                        # minPos[body] = position
                elif body==planet:
                    pass
                else:
                    # get distance to voyager, km
                    posToVoyager = position-posVoyager
                    distance = int(libspice.getDistance(posToVoyager))
                    if distance < minDist[body]:
                        minDist[body] = distance
                        minPos[body] = position
            positions.append(row)

        # make the map
        plotMap(flyby, positions, minPos)

    # all done - clean up the kernels
    spice.kclear()
コード例 #40
0
ファイル: vgCenter.py プロジェクト: bburns/PyVoyager
def getCameraMatrix(craft, camera, time):
    """
    get the camera matrix for the given craft and camera at a utc time. 
    assumes libimg.loadKernels has been called.
    returns C, the 3x3 rotation matrix as a numpy array. 
    """
    
    # get target code
    # targetId = spice.bodn2c(target) # eg 'Jupiter'->599

    # get spacecraft instrument        
    spacecraft = -31 if craft=='Voyager1' else -32
    spacecraftBus = spacecraft * 1000
    spacecraftScanPlatform = spacecraftBus - 100
    spacecraftNarrowCamera = spacecraftScanPlatform - 1
    spacecraftWideCamera = spacecraftScanPlatform - 2
    # instrument = spacecraftBus # use for NAIF continuous kernels
    instrument = spacecraftScanPlatform # use for PDS discrete kernels

    # get field of view and focal length
    # f is the focal length relative to the screen halfwidth of 1.0
    # i.e. screen coordinates are -1.0 to 1.0
    #. use ik
    # print 'camera',camera
    fov = config.cameraFOVs[camera] # degrees - 0.424 or 3.169
    screenHalfwidth = 1.0
    f = screenHalfwidth / math.tan(fov/2 * math.pi/180) 
    # print 'f=focal length',f
    
    # get ephemeris time
    # note: target and spacecraft locations are stored relative to J2000
    # time is utc time as string
    ephemerisTime = spice.str2et(time) # seconds since J2000 (will be negative)
    # sclkch = spice.sce2s(spacecraft, ephemerisTime) # spacecraft clock ticks, string
    # sclkdp = spice.sce2c(spacecraft, ephemerisTime) # spacecraft clock ticks, double
    clockTicks = spice.sce2c(spacecraft, ephemerisTime) # spacecraft clock ticks, double
    # print 'clockTicks',clockTicks

    # # get position of target relative to spacecraft
    # # this is the direction from craft to target in ECLIPB1950 frame
    # observer = 'Voyager ' + craft[-1] # eg 'Voyager 1'
    # frame = 'ECLIPB1950' # coordinate frame
    # abberationCorrection = 'NONE'
    # position, lightTime = spice.spkpos(target, ephemerisTime, frame,
    #                                    abberationCorrection, observer)
    # print 'target position relative to observer', position

    # get camera pointing matrix C
    # C is the world-to-camera transformation matrix.
    # ie C is a rotation matrix from the base frame 'frame' to
    # the instrument-fixed frame at the time clockTicks +/- tolerance.
    # https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/ckgp_c.html
    tolerance = spice.sctiks(spacecraft, "0:00:800") # time tolerance
    frame = 'ECLIPB1950' # coordinate frame
    # ckgp is 'camera kernel get pointing'
    # note: the pointing information is stored in the time frame J2000,
    # but the coordinates are in the ECLIPB1950 coordinate frame.
    C, clkout, found = spice.ckgp(instrument, clockTicks, tolerance, frame)
    # print 'C=camera pointing matrix - transform world to camera coords'
    # print C

    return C