def main():
    ts = load.timescale()
    t = ts.tt(2018, 1, 22, 9, 9, 20)
    trial_angles = 10, 20, 30, 40  # the error peaks around 20 degrees
    trial_elevations = 0, 6000, AU_M
    print(__doc__)
    for n in range(1, 5):
        print('=== {} iterations ==='.format(n))
        print('')
        for elevation_m in trial_elevations:
            for degrees in trial_angles:
                top = Topos(latitude_degrees=degrees, longitude_degrees=123,
                            elevation_m=elevation_m)
                xyz_au = top.at(t).position.au
                xyz_au = einsum('ij...,j...->i...', t.M, xyz_au)
                lat, lon, elev = reverse_terra(xyz_au, t.gast, n)
                lat = lat / DEG2RAD
                error_mas = 60.0 * 60.0 * 1000.0 * abs(degrees - lat)
                print('latitude {} degrees, elevation {} m'
                      ' -> error of {:.2f} mas'
                      .format(degrees, elevation_m, error_mas))
        print('')
    print("""\
Given that iterations=3 pushes the maximum error from tens of mas ("mas"
means " milli-arcsecond") down to hundredths of a mas, it is the value
we have chosen as a default.  A fourth iteration, if we ever chose to
perform one, pushes the error down to "0.00 mas".
""")
def test_earth_deflection():
    # The NOVAS library includes the Earth's gravitational deflection of
    # light for both topocentric observers and observers in Earth orbit,
    # but shuts this effect off once the object is behind the Earth 20%
    # of the way from its limb towards its center.  This test determines
    # whether Skyfield puts the resulting discontinuity in the same
    # place as the NOVAS library does.
    #
    # For more details see:
    # https://github.com/skyfielders/astronomy-notebooks/blob/master/Skyfield-Notes/Fixing-earth-deflection.ipynb

    t = load.timescale(delta_t=0.0)
    t = t.tt(2016, 7, 2, arange(10.5628, 10.5639, 0.0002))
    planets = load('de405.bsp')
    earth = planets['earth']
    mars = planets['mars']
    lowell = earth + Topos(latitude_degrees=35.2029, longitude_degrees=-111.6646)
    ra, dec, distance = lowell.at(t).observe(mars).apparent().radec()
    h = ra.hours
    hprime = diff(h)
    assert hprime[0] > 1.8e-8
    assert hprime[1] > 1.8e-8
    assert hprime[2] < 1.3e-8   # moment when nadir angle crosses 0.8
    assert hprime[3] > 1.8e-8
    assert hprime[4] > 1.8e-8
def compute_flight_time(planets, start_name, destination_name, g):
    start = planets[start_name + ' barycenter']
    destination = planets[destination_name + ' barycenter']
    ts = load.timescale()
    t = ts.now()
    astrometric = start.at(t).observe(destination)
    distance = astrometric.distance().km
    acceleration = acceleration_g_to_km_sec_sqr(g)
    time_of_flight = flip_and_burn(acceleration, distance)
    return time_of_flight
Exemple #4
0
def get_next_pass(satellite, satellite_name):
    # Create a time vector of 24 hours
    ts = load.timescale()
    current = datetime.datetime.now()
    minutes = range(current.minute, 60 * 24 + current.minute)
    t = ts.utc(current.year, current.month, current.day, current.hour, \
            minutes)

    orbit = (satellite - GROUND_STATION).at(t)
    alt, az, distance = orbit.altaz()

    above_horizon = alt.degrees > 0
    boundaries, = np.diff(above_horizon).nonzero()
    passes = boundaries.reshape(len(boundaries) // 2, 2)
    if len(passes) > 0:
        return passes[0]
    else:
        print("Error, no passes found for {}".format(satellite_name))
        sys.exit(2)
def calc_radec_w_proper_motion(ra, de, pmra, pmde, epoch=2018.):
    planets = load('/Users/gks/Dropbox/mypylib/notebooks/GIT/HETobs/de421.bsp')
    ts = load.timescale()
    earth = planets['earth']
    t = ts.utc(epoch)
    t_2000 = ts.utc(2000)
    ra_ang = Angle(degrees=ra)
    de_ang = Angle(degrees=de)
    star_obj = Star(ra=ra_ang,
                    dec=de_ang,
                    ra_mas_per_year=pmra,
                    dec_mas_per_year=pmde)
    astrometric = earth.at(t).observe(star_obj)
    ra_out, dec_out, dist_out = astrometric.radec()
    ra_new = ra_out.to(u.degree).value
    de_new = dec_out.to(u.degree).value
    print("Old:", ra, de)
    print("New:", ra_new, de_new)
    return ra_new, de_new
Exemple #6
0
    def plotear_planetas(self):
        planetas = load('de421.bsp')  #Cargando planetas

        self.earth, venus, sun, mercury, neptune, mars, saturn, jupyter, uranus, moon = planetas[
            'earth'], planetas['venus'], planetas['sun'], planetas[
                1], planetas[8], planetas['mars'], planetas[6], planetas[
                    5], planetas[7], planetas['moon']
        ts = load.timescale()
        t = ts.utc(self.fecha_hora.replace(tzinfo=utc))

        self.graficar_planeta(venus, t, 'Venus')
        self.graficar_planeta(mercury, t, 'Mercurio')
        self.graficar_planeta(mars, t, 'Marte')
        self.graficar_planeta(saturn, t, 'Saturno')
        self.graficar_planeta(jupyter, t, 'Jupiter')
        self.graficar_planeta(neptune, t, 'Neptuno')
        self.graficar_planeta(sun, t, 'Sol')
        self.graficar_planeta(moon, t, 'Luna')
        self.graficar_planeta(uranus, t, 'Urano')
Exemple #7
0
def greatest_elevation_schedule(ordered_events, location):

    pass_T = 120.  # length of minimum pass in seconds
    exposure_T = 20.  # length of exposure
    buffer_T = 40. + exposure_T  # time between exposures

    ts = load.timescale()
    site = wgs84.latlon(location[0], location[1], elevation_m=0)
    ccd_schedule = []
    jSec = 1.0 / 24 / 60 / 60  # second in julian time

    for event in ordered_events:
        elevations = list()
        for tdx, t in enumerate(np.linspace(event[1], event[2], 100)):
            difference = event[0] - site
            elevations.append(difference.at(ts.tt_jd(tdx)).elevation)

        event.append(event[1]
                     + (event[2]-event[1])/100*elevations.index(max(elevations)))
def main():
    print('Skyfield version: {0}'.format(skyfield.__version__))
    print('jplephem version: {0}'.format(version_of('jplephem')))
    print('sgp4 version: {0}'.format(version_of('sgp4')))

    ts = load.timescale()
    fmt = '%Y-%m-%d'

    final_leap = (ts._leap_tai[-1] - 1) / (24 * 60 * 60)
    print('Built-in leap seconds table ends with leap second at: {0}'.format(
        ts.tai_jd(final_leap).utc_strftime()))

    arrays = load_bundled_npy('iers.npz')
    daily_tt = arrays['tt_jd_minus_arange']
    daily_tt += np.arange(len(daily_tt))
    start = ts.tt_jd(daily_tt[0])
    end = ts.tt_jd(daily_tt[-1])
    print('Built-in ∆T table from finals2000A.all covers: {0} to {1}'.format(
        start.utc_strftime(fmt), end.utc_strftime(fmt)))
def main():
    ## get the global parameters
    global wcs, imgSize, refUTC, imgScale, mwa, ts, line1, line2, line3
    hdu = fits.open(
        str(args.obs) + "-" + str(args.midName) + "-1-0000-dirty.fits")
    wcs = WCS(hdu[0].header, naxis=2)
    imgSize = hdu[0].header["NAXIS1"]
    imgScale = np.abs(hdu[0].header["CDELT2"])
    refUTC = datetime.strptime(hdu[0].header["DATE-OBS"],
                               '%Y-%m-%dT%H:%M:%S.%f')

    ## get the relevant tle for the satellite
    line1, line2, line3 = obtainTLE(args.noradid)

    if args.debug:
        print("line1 {0}\nline2 {1}\nline3 {2}".format(line1, line2, line3))

    mwa = Topos("26.701276778 S", "116.670846137 E", elevation_m=377.827)
    ts = load.timescale()

    intrack_offset_array = np.linspace(-10, 10, 10)
    offtrack_offset_array = np.linspace(-0.5, 0.5, 10)

    all_combinations = [(a, b) for a in intrack_offset_array
                        for b in offtrack_offset_array]

    waterfall = np.zeros((10, 10, args.channels))

    for f in tqdm(range(args.channels)):
        if args.debug:
            print("working on channel {}".format(f))
        global utc_array, cube
        utc_array, cube = getCube(f)

        with multiprocessing.Pool(processes=28) as pool:
            results = pool.starmap(worker, all_combinations)

        results = np.array(results)
        waterfall[:, :, f] = results.reshape((10, 10))

    np.save(
        str(args.noradid) + "-" + str(args.obs) + "waterfall.npy", waterfall)
Exemple #10
0
def ccd_schedule(schedule, location):
    """
    Creates a schedule for use with and external
    Parameters:
        schedule:
        location:
    Returns:

    """
    # user inputs
    pass_T = 120.  # length of minimum pass in seconds
    exposure_T = 20.  # length of exposure
    buffer_T = 40. + exposure_T  # time between passes

    # predefinition
    ts = load.timescale()
    site = wgs84.latlon(float(location[0]), float(location[1]))
    ccd_schedule = []
    jSec = 1.0 / 24 / 60 / 60  # second in julian time

    # add first event, assuming first event is long enough
    event = schedule[0]
    difference = event[0] - site
    ccd_schedule.append([event[0], event[1], event[1] + buffer_T * jSec])
    ccd_schedule[0].extend([difference.at(ts.tt_jd(ccd_schedule[0][1]
                                          + exposure_T / 2. * jSec)),
                            difference.at(ts.tt_jd(ccd_schedule[0][2]
                                          + exposure_T / 2. * jSec))])

    for event in schedule[1:]:
        if event[1] - buffer_T * jSec > ccd_schedule[-1][2] \
        and event[2] > ccd_schedule[-1][2] + (buffer_T + pass_T) * jSec:
            difference = event[0] - site
            ccd_schedule.append([event[0], max(ccd_schedule[-1][2]
                                               + buffer_T*jSec, event[1])])
            ccd_schedule[-1].append(ccd_schedule[-1][1] + buffer_T * jSec)
            ccd_schedule[-1].extend([difference.at(ts.tt_jd(ccd_schedule[-1][1]
                                                            + exposure_T / 2.*jSec)),
                                     difference.at(ts.tt_jd(ccd_schedule[-1][2]
                                                            + exposure_T / 2.*jSec))])

    return ccd_schedule
def run():
    rospy.init_node('sun_seeker_node', anonymous=True)
    rospy.Subscriber('/clock', Clock, sim_time_callback)

    pub = rospy.Publisher('/sun_seeker/vector', Vector3, queue_size=1)
    rate = rospy.Rate(0.1)

    eph = load('de421.bsp')
    sun = eph['sun']
    moon = eph['moon']

    path = os.path.realpath(__file__)
    pc = PlanetaryConstants()
    pc.read_text(load('moon_080317.tf'))
    pc.read_text(load('pck00008.tpc'))
    pc.read_binary(load('moon_pa_de421_1900-2050.bpc'))

    frame = pc.build_frame_named('MOON_ME_DE421')
    place = moon + pc.build_latlon_degrees(frame, -86.79430, -21.18640)

    sun_angle_msg = Vector3()

    while not rospy.is_shutdown():
        dt = datetime.fromtimestamp(sim_time)
        dt_utc = dt.replace(tzinfo=pytz.UTC)
        ts = load.timescale()
        t = ts.from_datetime(dt_utc)

        sunpos = place.at(t).observe(sun).apparent()
        alt, az, distance = sunpos.altaz()

        sun_angle_msg.x = 0.0
        sun_angle_msg.y = alt.degrees
        sun_angle_msg.z = az.degrees

        if rospy.get_time() - last_msg_time < msg_timeout:
            rospy.loginfo('Publishing vector: x = {0:.3f}, y = {1:.3f}, z = {2:.3f}'.format(sun_angle_msg.x, sun_angle_msg.y, sun_angle_msg.z))
            pub.publish(sun_angle_msg)
        else:
            rospy.logwarn('Timeout {0:.1f} seconds: Is /clock publishing?'.format(msg_timeout))
        
        rate.sleep()
    def hour_angle(self, object_ra: float, object_dec: float, date=None):
        """
        Converts the provided right ascension (RA) of an object to its corresponding hour angle (HA), based on the
        provided date.

        Args:
            date: Desired date for the calculation of the hour angle
            object_ra (float): The right ascension of the object in J2000
            object_dec (float): Object's declination in J2000

        Todo:
            Check the reason that the the values for the HA differ by almost 2 minutes from the real ones

        Todo:
            Also add a solid documentation for the whole file, explaining in detail the parsed arguments

        Todo:
            Update the docstring of this function because there is a major change.

        Returns:
            float: Calculated hour angle
        """
        if date is None:
            date = self.current_time()
        else:
            if len(date) == 3:
                day = int(date[2])
                hour = (date[2] - day) * 24
                minute = (hour - int(hour)) * 60
                second = int(minute - int(minute)) * 60
                date = (date[0], date[1], day, int(hour), int(minute), second)

        object_coordinates = SkyCoord(ra=str(object_ra), dec=str(object_dec), unit='deg')
        equinox_time = Time(datetime.datetime(*date), scale='utc', location=self.location, format='datetime')
        ra_jnow = object_coordinates.transform_to(FK5(equinox=equinox_time)).ra

        # Get the local sidereal time
        time_scale = load.timescale()
        utc_time = time_scale.utc(*date)
        local_sidereal_time = utc_time.gast * 15 + self.location.lon.degree

        return round(local_sidereal_time - ra_jnow.degree, 6)  # Return the calculated hour angle
Exemple #13
0
def sun_earth_distance(date):
    """
	Input:
		- UTC datetime object
	Output:
		- Sun-Earth distance (meters)
	"""

    planets = load('de421.bsp')

    earth, sun = planets['earth'], planets['sun']

    ts = load.timescale()

    t = ts.utc(date.replace(tzinfo=utc))

    astrometric = earth.at(t).observe(sun)
    ra, dec, distance = astrometric.radec()

    return distance.m
def _convert_radec_to_altaz(ra, dec, lon, lat, height, time):
    """Convert a single position.

    This is done for easy code sharing with other tools.
    Skyfield does support arrays of positions.
    """

    radec = Star(ra=Angle(degrees=ra), dec=Angle(degrees=dec))

    earth = load(EPHEMERIS)['earth']
    location = earth + Topos(longitude_degrees=lon,
                             latitude_degrees=lat,
                             elevation_m=height * 1000.0)

    ts = load.timescale()
    obstime = ts.from_astropy(Time(time, scale='utc'))

    alt, az, _ = location.at(obstime).observe(radec).apparent().altaz(pressure_mbar=0)

    return dict(az=az.degrees, alt=alt.degrees)
Exemple #15
0
    def generate_report(self):
        # the tricky bits to get look angles for a list of times
        ts = load.timescale(builtin=True)

        # get rid of the milliseconds in there
        truth = ts.now().utc
        now_ish = ts.utc(truth[0],truth[1],truth[2],truth[3],truth[4],truth[5])
        now = now_ish.tt

        # make an arry with times incremented by really close to 30 sec
        # this looks weird since it is terrestrial time floating point
        run_time = arange(now, now + .5, .000347222)

        # feed that array to the time function as julian days
        t = ts.tt(jd=run_time)

        # spit out the positon and vector of our location
        astrometric = self.ant.at(t).observe(self.name).apparent()

        # convert this to alt and az lists
        alt, az, distance = astrometric.altaz()

        t_list = t.utc_strftime('%Y:%m:%d:%H:%M:%S')
        alt_list = alt.degrees.tolist()
        az_list = az.degrees.tolist()

        self.report = []
        self.rise_time = None
        self.fade_time = None

        for idx,item in enumerate(t_list):
            if alt_list[idx] < 10.0:
                continue
            else:
                if self.rise_time is None:
                    self.rise_time = t_list[idx]
                self.fade_time = t_list[idx]
                az_out = "{:.4f}".format(az_list[idx])
                alt_out = "{:.4f}".format(alt_list[idx])
                output = t_list[idx]+", "+az_out+", "+alt_out+"\n"
                self.report.append(output)
def get_servo(lat, lng, sat_name, timestamp):
    ts = load.timescale()
    lines = get_sat(sat_name)
    line1 = lines[0]
    line2 = lines[1]

    current_time = timestamp

    my_position = Topos(lat, lng)
    satellite = EarthSatellite(line1, line2, sat_name, ts)
    difference = satellite - my_position

    data = ""
    for i in range(720):

        dt_object = datetime.utcfromtimestamp(current_time)
        dt_object = dt_object.replace(tzinfo=utc)
        t = ts.utc(dt_object)

        topocentric = difference.at(t)

        alt, az, distance = topocentric.altaz()

        alt_d = alt.degrees
        az_d = az.degrees

        if (az_d > 180):
            alt_d = flit_alt(alt_d)
            az_d = az_d - 180

        if (az_d < 0):
            alt_d = flit_alt(alt_d)
            az_d = 180 + az_d

        # print(current_time,az_d,alt_d)

        data += str(current_time) + ', ' + str(
            translate(az_d, 0, 180, 2457, 7372)) + ", " + str(
                translate(alt_d, 0, 180, 2457, 7372)) + '\n'
        current_time += 1
    return data
Exemple #17
0
    def search(self, sat, lat, long, timeStart, timeEnd, tolerance):
        """
        Returns the time for which a satellite is over the given coordinates within the time range given
        
        :param satellite sat: The satellite of interest
        :param float lat: The latitude of the search point
        :param float lon: The longitude of the search point
        :param datetime timeStart: The beginning of the time range to search through
        :param datetime timeEnd: The end of the time range to search through
        :param float tolerance: How close a satellite needs to the point (in km)
        :returns: The time at which the satellite is over the given coordinates. Returns None if not found
        :rtype: datetime
        """

        self.satellite = self.satellites[sat.name]

        # Calculate orbital period
        n = float(sat.meanMotion)
        mu = 398600; # km^3/s^2
        a = mu**(1/3) / (2*n*pi/86400)**(2/3)
        T = 2*pi*(a**3/mu)**(1/2)

        # Determine dt
        ts = load.timescale()
        dt = timedelta(seconds = T/100)

        # Search for time
        t = timeStart
        while t <= timeEnd:
            currentTime = ts.utc(t.year, t.month, t.day, t.hour, t.minute,
                                    t.second)
            geocentric = self.satellite.at(currentTime)
            subpoint = geocentric.subpoint()
            currentLat = subpoint.latitude.degrees
            currentLong = subpoint.longitude.degrees
            if(haversine((lat, long), (currentLat, currentLong)) < tolerance):
                return t
            t = t + dt

        # If nothing found return None
        return None
Exemple #18
0
def test_radec_and_altaz_angles_and_rates():
    # HORIZONS test data in Skyfield repository: authorities/radec-altaz-rates
    ts = load.timescale()
    t = ts.utc(2021, 2, 3)
    top = wgs84.latlon(35.1844866, 248.347300, elevation_m=2106.9128)
    planets = load('de421.bsp')
    a = (planets['earth'] + top).at(t).observe(planets['mars']).apparent()

    # First, verify RA and declination.

    frame = framelib.true_equator_and_equinox_of_date
    dec, ra, distance, dec_rate, ra_rate, range_rate = (
        a.frame_latlon_and_rates(frame))

    arcseconds = 3600.0
    assert abs((ra.degrees - 40.75836) * arcseconds) < 0.04
    assert abs((dec.degrees - 17.16791) * arcseconds) < 0.005
    assert abs(distance.m - 1.21164331503552 * AU_M) < 120.0

    # Verify RA and declination rates of change.

    assert round(dec_rate.arcseconds.per_hour, 5) == 25.61352
    assert round(ra_rate.arcseconds.per_hour * cos(dec.radians),
                 4) == round(75.15571, 4)  # TODO: get last digit to agree?
    assert abs(range_rate.km_per_s - 16.7926932) < 2e-5

    # Verify altitude and azimuth.

    frame = top
    alt, az, distance, alt_rate, az_rate, range_rate = (
        a.frame_latlon_and_rates(frame))

    assert round(alt.degrees, 4) == 65.2758
    assert round(az.degrees, 4) == 131.8839
    assert abs(distance.m - 1.21164331503552 * AU_M) < 120.0

    # Verify altitude and azimuth rates of change.

    assert abs(range_rate.km_per_s - 16.7926932) < 2e-5
    assert round(alt_rate.arcseconds.per_minute, 2) == 548.66
    assert round(az_rate.arcseconds.per_minute * cos(alt.radians), 2) == 663.55
Exemple #19
0
 def __init__(self):
     self.gps = load.tle_file("https://celestrak.com/NORAD/elements/gps-ops.txt")
     self.galileo = load.tle_file("https://celestrak.com/NORAD/elements/galileo.txt")
     self.glonass = load.tle_file("https://celestrak.com/NORAD/elements/glo-ops.txt")
     self.beidou = load.tle_file("https://celestrak.com/NORAD/elements/beidou.txt")
     self.allsat = self.gps+self.galileo+self.glonass+self.beidou
     print('Loaded', len(self.allsat), 'satellites')
     # create dict where we can fetch a satellite using its name as key
     self.sats_by_name = {sat.name: sat for sat in self.allsat}
     # Define observatory for az,el calculation
     self.obs = Topos('57.393109 N', '11.917798 E') # OSO25m
     # Define timerange, https://rhodesmill.org/skyfield/time.html
     self.ts = load.timescale()
     self.tgps = False
     self.tgalileo = False
     self.tglonass = False
     self.tbeidou = False
     #self.sat2plot = self.gps+self.galileo
     self.sat2plot = []
     # Plot the data, awaiting key-press events
     self.plot()
def get_range_velocity(sat_name: str, obs_lat: float, obs_lon: float,
                       time: datetime) -> typing.List[float]:

    ts = load.timescale()
    if isinstance(time, str):
        time = parse(time)
    time = time.replace(tzinfo=utc)
    time = ts.utc(time) if time is not None else ts.now()

    observer = Topos(obs_lat, obs_lon)

    stations_url = "http://celestrak.com/NORAD/elements/stations.txt"
    satellites = load.tle(stations_url)

    sat = satellites[sat_name]

    relative_position = (sat - observer).at(time)
    # sat_velocity = sat.at(tnow).velocity.km_per_s
    range_velocity = relative_position.velocity.km_per_s

    return range_velocity
Exemple #21
0
def getSatMWA(line1, line2, line3):
    """
    creates a satellite object and observer object
    
    Paramters
    ---------
    line1   : tle line 1
    line2   : tle line 2
    line3   : tle line 3
    Returns
    -------
    satellite   : the sat object
    mwa         : the observer object
    ts          : the time object
    """

    ts = load.timescale(builtin=True)
    satellite = EarthSatellite(line2, line3, line1, ts)
    mwa = Topos("26.701276778 S", "116.670846137 E", elevation_m= 377.827)

    return satellite, mwa, ts
Exemple #22
0
def test_using_elevation_to_locate_center_of_moon():
    # Test the `elevation_m` parameter by using it to offset a Moon
    # surface location back to the Moon's center.

    ts = load.timescale()
    t = ts.utc(2020, 4, 23)

    eph = load('de421.bsp')
    a1 = eph['moon'].at(t)

    pc = PlanetaryConstants()
    pc.read_text(load('moon_080317.tf'))
    pc.read_text(load('pck00008.tpc'))
    pc.read_binary(load('moon_pa_de421_1900-2050.bpc'))
    frame = pc.build_frame_named('MOON_ME_DE421')

    place = pc.build_latlon_degrees(frame, 26.3, 313.2, -1737400)
    a2 = (eph['moon'] + place).at(t)

    mm = 1e-3
    assert max(abs(a1.position.m - a2.position.m)) < mm
Exemple #23
0
def get_adcs_vectors(time_data, tle_data):
    sun = JPL_EPH['sun']
    earth = JPL_EPH['earth']
    ts = load.timescale()
    label="Satellite"
    satellite = EarthSatellite(tle_data["line_1"], tle_data["line_2"], label, ts)
    time_instant = ts.utc(
        time_data["year"],
        time_data["month"],
        time_data["day"],
        time_data["hour"],
        time_data["min"],
        time_data["sec"],
    )
    tru_pos = earth + satellite
    sun_vector1 = tru_pos.at(time_instant).observe(sun).apparent().position.km
    sun_vector2 = satellite.at(time_instant).position.km
    # sun_vector = satellite.at(time_instant).observe(earth).apparent()
    # print(tru_pos.at(time_instant).position.km)
    # print(earth.at(time_instant).position.km)
    return [sun_vector1 - sun_vector2]
Exemple #24
0
def test_minor_planet():
    text = (b'00001    3.4   0.15 K205V 162.68631   73.73161   80.28698'
            b'   10.58862  0.0775571  0.21406009   2.7676569  0 MPO492748'
            b'  6751 115 1801-2019 0.60 M-v 30h Williams   0000      '
            b'(1) Ceres              20190915\n')

    ts = load.timescale()
    t = ts.utc(2020, 6, 17)
    eph = load('de421.bsp')
    df = mpc.load_mpcorb_dataframe(BytesIO(text))
    row = df.iloc[0]

    assert row.designation_packed == '00001'
    assert row.designation == '(1) Ceres'

    ceres = mpc.mpcorb_orbit(row, ts, GM_SUN)
    ra, dec, distance = eph['earth'].at(t).observe(eph['sun'] + ceres).radec()

    assert ceres.target == '(1) Ceres'
    assert abs(ra.hours - 23.1437) < 0.00005
    assert abs(dec.degrees - -17.323) < 0.0005
    def hour_angle_to_ra(self, object_ha: float, object_dec: float, date=None):
        """
        Convert the provided object's hour angle to its corresponding right ascension. This method assumes that ephem is
        properly calibrated. Also the date is assumed to be now.

        Todo:
            Check what happens in every case and if the conversion of degrees is needed

        Args:
            object_ha (float): Hour angle of the desired object
            object_dec (float): Declination of the object
            date (tuple): The desired date

        Returns:
            The current right ascension of the object in J2000
        """
        # Get the local sidereal time
        if date is None:
            date = self.current_time()  # Get the current time and date as needed
        else:
            if len(date) == 3:
                day = int(date[2])
                hour = (date[2] - day)*24
                minute = (hour - int(hour))*60
                second = int(minute - int(minute))*60
                date = (date[0], date[1], day, int(hour), int(minute), second)

        # Calculate the desired right ascension
        time_scale = load.timescale()
        utc_time = time_scale.utc(*date)
        local_sidereal_time = utc_time.gast * 15 + self.location.lon.degree
        calculated_ra = local_sidereal_time - object_ha  # Calculate the right ascension in JNOW

        # Calculate the right ascension of the provided object in J2000
        equinox_time = Time(datetime.datetime(*date), scale='utc', location=self.location, format='datetime')
        object_coordinates = SkyCoord(ra=str(calculated_ra), dec=str(object_dec), unit='deg',
                                      frame=FK5, equinox=equinox_time)
        ra_j2000 = object_coordinates.transform_to(FK5(equinox='J2000.0')).ra

        return round(ra_j2000.degree, 6)
def compare_obj(planets, code, year, month, day, hour=0, minute=0, second=0):
    '''
    compare position between jpl query and skyfield computation

    parameters:
    ----------
    code : 1,2,3,4,5,6,7,8,9,10,199,299,399,301

    year: int,
    month: int,
    day: int,
    hour: int default 0,
    minute: int default 0,
    second float default 0,
    '''

    # print(code)
    ts = load.timescale()
    t = ts.utc(year, month, day, hour, minute, second)
    objname = planets.names()[code][0]
    # print(objname)
    obj = planets[objname]
    icrf_sf = obj.at(t)
    # print(icrf_sf.position)
    icrf_sf_np = icrf_sf.position.km

    time = Time(t.utc_iso())
    times = time.tt+np.linspace(0, 1, 2)*u.s
    objquery = Horizons(id=str(code), id_type='majorbody', location='@0',
                        epochs={'start': times.value[0], 'stop': times.value[1], 'step': '1'})
    icrf_jpl = objquery.vectors(refplane='earth')
    icrf_jpl['x'].convert_unit_to('km')
    icrf_jpl['y'].convert_unit_to('km')
    icrf_jpl['z'].convert_unit_to('km')
    icrf_jpl_np = np.array(
        [icrf_jpl['x'][0], icrf_jpl['y'][0], icrf_jpl['z'][0]])
    print(objname + ' icrf_sf_np in km', icrf_sf_np)
    print(objname + ' icrf_jpl_np in km', icrf_jpl_np)
    print(objname + ' icrf_sf_np-icrf_jpl_np in km', icrf_sf_np-icrf_jpl_np)
    print()
def test_against_horizons():
    # See the following files in the Skyfield repository:
    #
    # horizons/ceres-orbital-elements
    # horizons/ceres-position

    ts = load.timescale(builtin=True)
    t = ts.tdb_jd(2458886.500000000)

    a = 2.768873850275102E+00  # A
    e = 7.705857791518426E-02  # EC
    p_au = a * (1 - e**2)  # Wikipedia

    k = KeplerOrbit.from_mean_anomaly(
        p=Distance(au=p_au),  # see above
        e=e,
        i=Angle(degrees=2.718528770987308E+01),
        Om=Angle(degrees=2.336112629072238E+01),
        w=Angle(degrees=1.328964361683606E+02),
        M=Angle(degrees=1.382501360489816E+02),
        epoch=t,  #?
        mu_km_s=None,
        mu_au_d=2.9591220828559093E-04,
        center=None,
        target=None,
        center_name=None,
        target_name=None,
    )
    r, v = k._at(t)[:2]
    sun_au = [
        -0.004105894975783999,
        0.006739680703224941,
        0.002956344702049446,
    ]
    horizons_au = [
        1.334875927366032E+00,
        -2.239607658161781E+00,
        -1.328895183461897E+00,
    ]
    assert max(abs(r + sun_au - horizons_au)) < 2e-15
Exemple #28
0
def sat_separations(params):
    '''
    Separation between a source and set of satellites.

    Parameters
    ----------
    params: list
        [[source_ra, source_dec], date]
    source_ra: float
        Right Ascension of source in radians.
    source_dec: float
        Declination of source in radians.
    date: datetime
        Date and time of observation.

    Returns
    -------
    separations: array
        Angular separation between each satellite and the source in degrees.
    '''

    source, t = params

    source_ra, source_dec = source

    satellites = get_sat_tles()

    ts = load.timescale()

    tt = ts.utc(*[int(x) for x in t.strftime('%Y %m %d %H %M %S').split()])
    mkat = Topos('30.7130 S', '21.4430 E')

    separations = np.zeros((len(satellites.items())))

    for j, sat in enumerate(satellites.items()):

        sat_ra, sat_dec = [(sat[1]-mkat).at(tt).radec(ts.J2000)[i].radians for i in range(2)]
        separations[j] = np.rad2deg(angular_separation(sat_ra, sat_dec, [source_ra, source_dec]))

    return separations
def readTLE(fileName='./india_tle.dat'):
    # tle referesh days
    refresh_days = 14
    # current date and time
    ts = load.timescale(builtin=True)
    t = ts.now()
    days = 1
    if not os.path.exists(fileName):
        # call create local tle function
        print("Creating new tle file")
        dict = getISROSatelliteList()
        saveTLE(dict, fileName)
        # load the new one
        satellites = load.tle(fileName)
    else:
        # load the local file
        satellites = load.tle(fileName)
        # get the first in the dictionary
        sat_id = list(satellites.keys())[0]
        satellite = satellites[sat_id]
        days = t - satellite.epoch
    # if older than refresh_days create new local tle and load new one
    if abs(days) > refresh_days:
        # call create local tle function
        print("Creating new tle file")
        dict = getISROSatelliteList()
        saveTLE(dict, fileName)
        # load the new one
        satellites = load.tle(fileName)
    # sats dictionary for easy search
    sats = {}
    for item in [satellites]:
        names = [key for key in item.keys()]
        for satname in names:
            sat = item[satname]
            satid = sat.model.satnum
            sats[satid] = sat
            sats[satname] = sat
    # return dictionary
    return sats
def readTLE(fileName='./india_tle.dat'):
    # tle referesh days
    refresh_days = 14
    # current date and time
    ts = load.timescale(builtin=True)
    t = ts.now()

    days = 1
    old_date = 0

    # call create local tle function
    print("Creating new tle file")
    dict = getISROSatelliteList()
    saveTLE(dict, fileName)
    # load the new one
    satellites = load.tle(fileName)

    if abs(days) > refresh_days:
        # call create local tle function
        print("Creating new tle file")
        # backup old tle
        backupFilename = Path(fileName).stem + old_date + '.dat'
        os.rename(fileName, backupFilename)
        # get the new one
        dict = getISROSatelliteList()
        saveTLE(dict, fileName)
        # load the new one
        satellites = load.tle(fileName)
    # sats dictionary for easy search
    sats = {}
    for item in [satellites]:
        names = [key for key in item.keys()]
        for satname in names:
            sat = item[satname]
            satid = sat.model.satnum
            sats[satid] = sat
            sats[satname] = sat
    # return dictionary
    return sats
def hip_position(hip_nr, temperature=15, pressure=1005):
    """ Returns uncorrected and refraction corrected apparent positions of stars in the Hipparcos catalogue.
    
        Position is specified to Waltz observer.
    """
    #Load list of planets and specify to earth to get obersver, then specify to location of Waltz
    planets = load('de421.bsp')
    earth = planets['earth']
    waltz = earth + Topos(
        '49.3978620896919 N', '8.724700212478638 E', elevation_m=562.0)

    #Load current time.
    ts = load.timescale()
    t = ts.now()
    #t=t.utc #Convert

    #Load star catalogue coordinates from hipparcos.py module
    star = hipparcos.get(hip_nr)

    #Compute astrometric and apparent coordinates for Waltz at time t
    astrometric = waltz.at(t).observe(star)
    apparent = astrometric.apparent()
    #Change to alt, az coordinates to compute refraction correction, then change back again
    #Change Temp and pressure
    alt, az, distancealt = apparent.altaz(temperature_C=temperature,
                                          pressure_mbar=pressure)
    corrected = apparent.from_altaz(alt=alt, az=az)

    #RA,DEC,Dist of refraction corrected positions
    ra_calc, dec_calc, distance = corrected.radec()

    #RA,DEC,Dist of refraction uncorrected positions
    ra_calc_without_refraction, dec_calc_without_refraction, distance = apparent.radec(
        epoch='date')

    return [
        ra_calc, dec_calc, ra_calc_without_refraction,
        dec_calc_without_refraction
    ]
    def _get_times(self, now: datetime) -> (datetime, datetime):
        midnight = now.replace(hour=0, minute=0, second=0, microsecond=0)
        next_midnight = midnight + timedelta(days=1)

        ts = load.timescale()
        t0 = ts.from_datetime(midnight)
        t1 = ts.from_datetime(next_midnight)
        eph = load_file(config['DE421_PATH'])
        bluffton = wgs84.latlon(config['COORDINATES']['N'] * N, config['COORDINATES']['E'] * E)
        f = almanac.dark_twilight_day(eph, bluffton)
        times, events = almanac.find_discrete(t0, t1, f)

        result = []
        previous_e = None
        for t, e in zip(times, events):
            if e == 4:
                result.append(t.astimezone(self.zone))
            if previous_e == 4:
                result.append(t.astimezone(self.zone))
            previous_e = e

        return result[0], result[1]
Exemple #33
0
    def rise_and_set_time(self, satellite):
        """
        Accepts a satellite, returns the next rise and set time for that satellite
        as a tuple of datetimes
        """

        # create skyfield latlon
        loc = wgs84.latlon(self.lat, self.lon)

        # create timescale
        ts = load.timescale()
        t0, t1 = ts.from_datetimes(self.time_window(1))

        # get events where satellite reaches altitude at location in time window
        times, _ = satellite.find_events(
            loc, t0, t1, altitude_degrees=self.altitude_degrees)

        # get rise and sent time for first event
        rise_time = times[0].utc_datetime()
        set_time = times[2].utc_datetime()

        return (rise_time, set_time)
def test_vectors():
    ts = load.timescale()
    t = ts.tt(2017, 1, 23, 10, 44)

    planets = load('de421.bsp')
    earth = planets['earth']
    mars = planets['mars']

    v = earth

    assert str(v) == """\
Sum of 2 vectors:
 + Segment 'de421.bsp' 0 SOLAR SYSTEM BARYCENTER -> 3 EARTH BARYCENTER
 + Segment 'de421.bsp' 3 EARTH BARYCENTER -> 399 EARTH"""

    assert repr(v) == "\
<VectorSum of 2 vectors 0 SOLAR SYSTEM BARYCENTER -> 399 EARTH>"

    assert str(v.at(t)) == "\
<Barycentric position and velocity at date t center=0 target=399>"

    v = earth - mars

    assert str(v) == """\
Sum of 4 vectors:
 - Segment 'de421.bsp' 4 MARS BARYCENTER -> 499 MARS
 - Segment 'de421.bsp' 0 SOLAR SYSTEM BARYCENTER -> 4 MARS BARYCENTER
 + Segment 'de421.bsp' 0 SOLAR SYSTEM BARYCENTER -> 3 EARTH BARYCENTER
 + Segment 'de421.bsp' 3 EARTH BARYCENTER -> 399 EARTH"""

    assert repr(v) == "\
<VectorSum of 4 vectors 499 MARS -> 399 EARTH>"

    assert str(v.at(t)) == "\
<Geometric position and velocity at date t center=499 target=399>"

    geocentric = Geocentric([0,0,0])
    assert geocentric.center == 399
Exemple #35
0
 def __init__(self, lg=None,obs=None,refraction_method=None):
   #
   self.lg=lg
   self.name='SF Skyfield'
   self.obs_astropy=obs
   self.refraction_method=refraction_method
   longitude,latitude,height=self.obs_astropy.to_geodetic()
   # positive values are used for eastern longitudes
   # ToDo
   # print(type(height))
   # print(str(height))
   # 3236.9999999999477 m
   # print(height.meter)
   # AttributeError: 'Quantity' object has no 'meter' member
   elevation=float(str(height).replace('m','').replace('meter',''))
   earth = planets['earth']
   # N +, E + hurray
   self.obs=earth.topos(
         latitude_degrees=latitude.degree,
         longitude_degrees=longitude.degree,
         elevation_m=elevation,
     )
   self.ts=load.timescale()
Exemple #36
0
def archived_tle():
    """
    Return a list of HST TLEs from space-track
    https://www.space-track.org/basicspacedata/query/class/tle/EPOCH/2015-01-01--2016-12-31/NORAD_CAT_ID/20580/orderby/TLE_LINE1%20ASC/format/tle
    
    HST_TLE.txt: 
    https://www.space-track.org/basicspacedata/query/class/tle/EPOCH/2009-08-01--2016-12-31/NORAD_CAT_ID/20580/orderby/TLE_LINE1%20ASC/format/tle
    
    """
    from skyfield.api import load
    from skyfield.constants import AU_KM
    import astropy.time
    
    ts = load.timescale()
    eph = load('de421.bsp')
    earth = eph['earth']
    #sat = earth.satellite('\n'.join(lines))
    
    #lines = open('2015-16_TLEs.txt').readlines()
    #lines = open('HST_TLE.txt').readlines()
    lines = open('HST_TLE_WFC3.txt').readlines()
    lines = [line.strip() for line in lines]

    N = len(lines)//2
    times = []
    strings = []
    
    for i in range(N):
        print(i,N)
        tle_str  = 'HST\n'+'\n'.join(lines[i*2:i*2+2])
        sat = earth.satellite(tle_str)
        t0 = astropy.time.Time(sat.epoch.utc_datetime())
        times.append(t0.mjd)
        strings.append(tle_str)
    
    return np.array(times), np.array(strings)
Exemple #37
0
def test_positions_skyfield():
    """
    Test positions against those generated by skyfield.
    """

    t = Time('1980-03-25 00:00')
    location = None

    # skyfield ephemeris
    planets = load('de421.bsp')
    ts = load.timescale()
    mercury, jupiter, moon = planets['mercury'], planets['jupiter barycenter'], planets['moon']
    earth = planets['earth']

    skyfield_t = ts.from_astropy(t)

    if location is not None:
        earth = earth.topos(latitude_degrees=location.latitude.to(u.deg).value,
                            longitude_degrees=location.longitude.to(u.deg).value,
                            elevation_m=location.height.to(u.m).value)

    skyfield_mercury = earth.at(skyfield_t).observe(mercury).apparent()
    skyfield_jupiter = earth.at(skyfield_t).observe(jupiter).apparent()
    skyfield_moon = earth.at(skyfield_t).observe(moon).apparent()

    if location is not None:
        obsgeoloc, obsgeovel = location.get_gcrs_posvel(t)
        frame = GCRS(obstime=t, obsgeoloc=obsgeoloc, obsgeovel=obsgeovel)
    else:
        frame = GCRS(obstime=t)

    ra, dec, dist = skyfield_mercury.radec(epoch='date')
    skyfield_mercury = SkyCoord(ra.to(u.deg), dec.to(u.deg), distance=dist.to(u.km),
                                frame=frame)
    ra, dec, dist = skyfield_jupiter.radec(epoch='date')
    skyfield_jupiter = SkyCoord(ra.to(u.deg), dec.to(u.deg), distance=dist.to(u.km),
                                frame=frame)
    ra, dec, dist = skyfield_moon.radec(epoch='date')
    skyfield_moon = SkyCoord(ra.to(u.deg), dec.to(u.deg), distance=dist.to(u.km),
                             frame=frame)

    moon_astropy = get_moon(t, location)
    mercury_astropy = get_body(t, 'mercury', location)
    jupiter_astropy = get_body(t, 'jupiter', location)

    # convert to true equator and equinox
    jupiter_astropy = _apparent_position_in_true_coordinates(jupiter_astropy)
    mercury_astropy = _apparent_position_in_true_coordinates(mercury_astropy)
    moon_astropy = _apparent_position_in_true_coordinates(moon_astropy)

    assert (moon_astropy.separation(skyfield_moon) <
            skyfield_angular_separation_tolerance)
    assert (moon_astropy.separation_3d(skyfield_moon) < skyfield_separation_tolerance)

    assert (jupiter_astropy.separation(skyfield_jupiter) <
            skyfield_angular_separation_tolerance)
    assert (jupiter_astropy.separation_3d(skyfield_jupiter) <
            skyfield_separation_tolerance)

    assert (mercury_astropy.separation(skyfield_mercury) <
            skyfield_angular_separation_tolerance)
    assert (mercury_astropy.separation_3d(skyfield_mercury) <
            skyfield_separation_tolerance)
Exemple #38
0
 def __init__(self, observer, time_list):
     self.earth = self._createearth()
     self.ts = load.timescale()
     self.time = self._createdatearray(time_list)
     self.obs = self._createobs(observer)
def predictStorms(startdate, predictdays, includeonlyiorelatedFlag, calcinterval, modeflag):
	global ts, iterDateUTCtime, th, L3, U1, modeset, JupiterRise, JupiterSet, SunRise, SunSet, includeonlyiorelated, predList
	
	modeset = modeflag
	includeonlyiorelated = includeonlyiorelatedFlag

	planets = load('de421.bsp')
	earthPlanet = planets['earth']

	inidt = datetime.strptime(startdate, '%Y%m%d')

	ts = load.timescale()
	initDateUTC = ts.utc(inidt.year, inidt.month, inidt.day, 0.0, 0.0, 0.0 ).utc_datetime()
	#print("initDateUTC: ", initDateUTC, type(initDateUTC))

	ephemObsPos = ephem.Observer()
	if radioConfig.stationLat[-1:] == "S":
		lonSign = "-"
	else:
		lonSign = ""
	ephemObsPos.lat  = lonSign + radioConfig.stationLat[0:-2]
	ephemObsPos.lon  = radioConfig.stationLon[0:-2]
	
	ephemObsPos.elev = radioConfig.stationElev

	#To get U.S. Naval Astronomical Almanac values, use these settings
	ephemObsPos.pressure= 0	
	# set the horizon that you want to use to one that is exactly 34 arcminutes lower 
	# than the normal horizon, to match the value by which the Navy reckons that 
	# an object at the horizon is refracted:
	ephemObsPos.horizon = '-0:34'

	myposition = earthPlanet + Topos(radioConfig.stationLat, radioConfig.stationLon)
	print("pyephem observer position: ", ephemObsPos)
	print("myposition: ", myposition)

	# 1) the central meridian longitude of Jupiter that faces us
	# 2) the position of the inner-most moon Io in its orbit around Jupiter

	L3 = 0
	U1 = 0
	th = 0.0

	predList = []

	iterDateUTC = initDateUTC
	finalDateUTC = initDateUTC + timedelta(days=(predictdays-1))

	#external loop on requested days:
	while iterDateUTC < finalDateUTC:
		ephemObsPos.date = (iterDateUTC +  + timedelta(hours=12) ).strftime('%Y-%m-%d %H:%M:%S')
		JupiterRise = ephem2datetime(str(ephemObsPos.previous_rising(ephem.Jupiter())))
		JupiterSet  = ephem2datetime(str(ephemObsPos.next_setting   (ephem.Jupiter())))
		JupiterNextRise = ephem2datetime(str(ephemObsPos.next_rising(ephem.Jupiter())))
		SunRise = ephem2datetime(str(ephemObsPos.next_rising(ephem.Sun())))
		SunSet  = ephem2datetime(str(ephemObsPos.next_setting(ephem.Sun())))

		#internal loop within a single day
		iterDateUTCtime = iterDateUTC
		endOfDayUTCtime = iterDateUTC + timedelta(days=1)
		while iterDateUTCtime < endOfDayUTCtime:
			#this way i will do the other calcs only when Jupiter is above the local horizon and the Sun is not visible:
			if ((iterDateUTCtime > JupiterRise and iterDateUTCtime < JupiterSet) or iterDateUTCtime > JupiterNextRise ) and (iterDateUTCtime < SunRise or iterDateUTCtime > SunSet):
				calcforjd()
			#calculate again every N minutes:
			iterDateUTCtime = iterDateUTCtime + timedelta(minutes=calcinterval)

		# since we have covered this day, let's go on with the next one:
		iterDateUTC = iterDateUTC + timedelta(days=1)

	return predList
Exemple #40
0
#!/usr/bin/env python
from skyfield.positionlib import ICRF
from skyfield.api import load,Topos

ts=load.timescale()
t=ts.now()
observer=Topos(latitude_degrees=52.8344,longitude_degrees=6.3785,elevation_m=10.0)
p=ICRF([0.0,0.0,0.0],observer_data=observer,t=t)
q=p.from_altaz(alt_degrees=30.0,az_degrees=30.0)

print(p,q)
def ts():
    yield load.timescale()
# this source is part of my Hackster.io project:  https://www.hackster.io/mariocannistra/radio-astronomy-with-rtl-sdr-raspberrypi-and-amazon-aws-iot-45b617

# this program will output the Jupiter-IO radio storm predictions in text format. 
# It's a port to python of an older QBasic program whose original source can be found 
# at http://www.spaceacademy.net.au/spacelab/projects/jovrad/jovrad.htm together with 
# good explanations about the theory and instructions to build a folded dipole antenna.

import raforpi
from skyfield.api import load
import sys
from datetime import datetime, timedelta
from pytz import timezone
import radioConfig
from dateutil.relativedelta import relativedelta

# the section below needs deeper check on the involved formulas:
print('\nJovicentric Declination of Earth: (to be checked)')
eph = load('jup310.bsp')
jupiter = eph['jupiter']
earth = eph['earth']

deyear = 2000
while deyear < 2020:
	initDateUTC = load.timescale().utc(deyear, 1, 1, 0.0, 0.0, 0.0 )
	geometry = jupiter.at( initDateUTC ).observe(earth)
	jcera, jcedec, jcedist = geometry.radec()
	jcinfo = 'year {}\tjcedec {}'.format( initDateUTC.utc_datetime().strftime('%Y%m%d'), jcedec )
	print(jcinfo)
	deyear = deyear + 1