def setup_skyfield_loader(cfg): ''' setup skyfield loader ''' cwd = os.getcwd() fp_load = '/'.join([cwd, cfg['data']['sf_path']]) if not os.path.exists(fp_load): print('Skyfield data path doesn\'t exist: {:s}'.format(fp_load)) print("creating...") os.makedirs(fp_load) load = sf.Loader(fp_load, verbose=True) return load
def get_seasons(timezone_name, year): ts = api.load.timescale(builtin=True) load = api.Loader('/var/data') eph = load('de430t.bsp') localtz = timezone(timezone_name) t0 = ts.utc(year) # midnight Jan 1 t1 = ts.utc(year + 1) # midnight Jan 1 following year t, y = almanac.find_discrete(t0, t1, almanac.seasons(eph)) season = {} for yi, ti in zip(y, t): season[almanac.SEASON_EVENTS[yi]] = ti.utc_datetime().astimezone(localtz) eph.close() return season
def _risesetextremes(lat, lon, tzstr, startYear, years, verbose=False): ts = api.load.timescale() load = api.Loader('/var/data') e = load('de430t.bsp') # earth = planets['earth'] tz = timezone(tzstr) bluffton = api.Topos(lat, lon) t0 = ts.utc(startYear, 1, 1) t1 = ts.utc(startYear+years, 1, 1) t, y = almanac.find_discrete(t0, t1, almanac.sunrise_sunset(e, bluffton)) if verbose: print ('done') result = dict() prevrise = None for ti, yi in zip(t, y): dt, _ = ti.astimezone_and_leap_second(tz) if yi: x = 'rise' else: x = 'set' year = str(dt.year) if year not in result.keys(): result[year] = {'rises': [], 'rise_hr': [], 'sets': [], 'set_hr': [], 'sunlight': [] } hrs = dt.hour + dt.minute/60.0 + dt.second/3600.0 result[year][f"{x}s"].append(dt) result[year][f"{x}_hr"].append(hrs) if yi: prevrise = ti else: if prevrise is not None: result[year]['sunlight'].append((ti - prevrise)*24.0) return result
def init_data(): global PLANETS, TIMESCALE, S_MWAPOS if (PLANETS is None) or (TIMESCALE is None) or (S_MWAPOS is None): if 'XDG_CACHE_HOME' in os.environ: datadir = os.environ['XDG_CACHE_HOME'] + '/skyfield' else: datadir = '/tmp' skyfield_loader = si.Loader(datadir, verbose=False, expire=True) try: PLANETS = skyfield_loader('de421.bsp') except: PLANETS = skyfield_loader( 'https://naif.jpl.nasa.gov/pub/naif/generic_kernels/spk/planets/a_old_versions/de421.bsp' ) TIMESCALE = skyfield_loader.timescale( builtin=True) # TODO - set back to True when new version released S_MWAPOS = PLANETS[ 'earth'] + MWA_TOPO # with replacement for USNO server.
def __init__(self, path=None, expire=True, ephemeris='de421.bsp'): import os self._ephemeris_name = ephemeris if path is None: if 'CAPUT_SKYFIELD_PATH' in os.environ: path = os.environ['CAPUT_SKYFIELD_PATH'] else: path = os.path.join(os.path.dirname(__file__), 'data', '') # Defer failure if Skyfield is not available until we try to load # anything try: from skyfield import api self._load = api.Loader(path, expire=expire) except ImportError: pass
def load(): path = tempfile.mkdtemp() try: yield api.Loader(path) finally: shutil.rmtree(path)
# # The terms of the AGPL v3 license can be found in the main directory of this # repository. # Generate a list of ephemerides using pyephem. # The output of this script is used in the test in src/swe.c import ephem import json import skyfield.api as sf from skyfield.data import hipparcos from math import * # Load all the needed kernels. loader = sf.Loader('./tmp') de421 = loader('de421.bsp') jup365 = loader('jup365.bsp') mar097 = loader('https://naif.jpl.nasa.gov/pub/naif/generic_kernels/spk/' 'satellites/mar097.bsp') def JD_to_besselian_epoch(jd): return 2000.0 + (jd - 2451545.0) / 365.25 # Compute target using skyfield. def compute(target, kernel=de421, name=None, topo=None,
print(fp_cfg) if not os.path.isfile(fp_cfg) == True: print('ERROR: Invalid Configuration File: {:s}'.format(fp_cfg)) sys.exit() print('Importing configuration File: {:s}'.format(fp_cfg)) with open(fp_cfg, 'r') as json_data: cfg = json.load(json_data) json_data.close() print(cfg) #set up data path fp_load = '/'.join([cwd, cfg['data_path']]) if not os.path.exists(fp_load): print('Skyfield data path doesn\'t exist: {:s}'.format(fp_load)) os.makedirs(fp_load) load = sf.Loader(fp_load, verbose=True) #load timescale object ts = load.timescale() #load almanac e = load('de421.bsp') earth = e['earth'] sun = e['sun'] print('Earth:', earth) print(' Sun:', sun) fp_bsp = '/'.join([cwd, cfg['data_path'], cfg['bsp_file']]) if not os.path.isfile(fp_bsp) == True: print('ERROR: Invalid BSP File: {:s}'.format(fp_bsp)) sys.exit() k21 = SPKType21.open(fp_bsp) spkid = k21.segments[0].target
from datetime import datetime from flask import Flask, jsonify, abort from skyfield import api as skyapi from skyfield import named_stars app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello World!' load = skyapi.Loader('./data') ts = load.timescale() planets = load('de405.bsp') earth = planets['earth'] PRINCETON_EARTH = skyapi.Topos('40.3440 N', '74.6514 W') STARS = [skyapi.NamedStar(star) for star in named_stars.named_star_dict.keys()] def star_data(stars, loc, time): altaz = [loc.at(time).observe(s).apparent().altaz() for s in stars] return [(altaz_[0].degrees, altaz_[1].degrees) for altaz_ in altaz] # data = [] # for star in stars: # obs = princeton.at(now).observe(s) # alt, az, d = obs.apparent().altaz()
def rad_to_degminsec(angle, fmt="{deg:01d}deg {min:01d}' {sec:0.1f}\""): """ Given an angle in radians, return it as a degrees arcmin arcsec string where degrees is in [0 .. 360) """ angle = degrees(angle) % 360. deg = int(angle) rem = 60. * (angle - deg) min_ = int(rem) sec = 60. * (rem - min_) return fmt.format(deg=deg, min=min_, sec=sec) # load ephemeris data load = api.Loader("d:/skyfield-data") # set up data dir data = load("de435.bsp") # load JPL ephemerides # set locations earth = data["Earth"] # Earth CoM lex = api.Topos('35.65 N', '88.39 W') # city offsets from Earth-center zag = api.Topos('45.81 N', '15.98 W') moon = data["Moon"] # Moon CoM # set timescale ts = load.timescale() photo_time = ts.utc(2019, 2, 20, 4, 13) # UTC time of Lexington photo # find alt/az of Moon lex_moon = (earth + lex).at(photo_time).observe(moon) print("Lexington:", lex_moon.apparent().altaz("standard"))
import unittest from pprint import pprint from skyfield import api, almanac import pandas as pd import simple_cache import numpy as np pd.set_option('display.max_columns', 999) import datetime import isodate from pytz import timezone import argparse ts = api.load.timescale(builtin=True) load = api.Loader('/var/data') equinoxen = ['Vernal', 'Autumnal'] utcnow = datetime.datetime.utcnow() @simple_cache.cache_it(filename=".seasons.cache", ttl=1200000) def get_seasons(timezone_name, year): ts = api.load.timescale(builtin=True) load = api.Loader('/var/data') eph = load('de430t.bsp') localtz = timezone(timezone_name) t0 = ts.utc(year) # midnight Jan 1 t1 = ts.utc(year + 1) # midnight Jan 1 following year t, y = almanac.find_discrete(t0, t1, almanac.seasons(eph)) season = {} for yi, ti in zip(y, t): season[almanac.SEASON_EVENTS[yi]] = ti.utc_datetime().astimezone(localtz)
def get_stars(zip_code, date_utc) -> list: """ :rtype: list :param zip_code: user zip code or coordinates :param date_utc: current time in UTC :return: returns a df of the bright stars """ load = api.Loader('./tmp/data') manhattan_beach = api.Topos('33.881519 S', '118.388177 W') # TODO change location ephemeris = load('de421.bsp') # download JPL ephemeris earth = ephemeris['earth'] with load.open(data.hipparcos.URL) as f: df = data.hipparcos.load_dataframe(f) bright = df[df['magnitude'] <= 5.5] # don't know what this does tbh ts = load.timescale() t = ts.utc(2020, 12, 20) # TODO set the date here df = df[df['ra_degrees'].notnull()] # remove nulls values bright = df[df['magnitude'] <= 5.5] # Prevent apparent magnitude from being greater than 5.5 bright_stars = api.Star.from_dataframe(bright) astrometric = earth.at(t).observe(bright_stars) ra, dec, distance = astrometric.radec() # ra.hours, dec.degrees, & distance.au returns ndarrays ra_array = ra.hours.tolist() dec_array = dec.degrees.tolist() distance_array = distance.au.tolist() apparent_magnitude_array = [] for row_label, row in bright.iterrows(): # grab magnitudes of stars apparent_magnitude_array.append(row[0]) orig = [] for i in range(len(ra_array)): orig.append([ apparent_magnitude_array[i], ra_array[i], dec_array[i], distance_array[i] ]) sorted_list = [] for i in range(len(orig)): n = 0 inserted = False while n < len(sorted_list) and not inserted: if orig[i][2] <= sorted_list[n][2]: # shift items after index n and insert curr at n sorted_list.insert(n, orig[i]) inserted = True else: n += 1 if not inserted: # curr has not been inserted in sorted_list yet - will be inserted at the end (x is largest) sorted_list.append(orig[i]) return sorted_list
# -*- coding: utf-8 -*- #%% # reset ide %reset -f #%% from datetime import datetime import urllib from skyfield import api as sf datadir = '/home/g/python/python-skyfield/' loader = sf.Loader(datadir, expire=False) import simplekml kml = simplekml.Kml() lats = [] lngs = [] elevation = [] satellites = loader.tle('http://celestrak.com/NORAD/elements/stations.txt') satellite = satellites['ISS (ZARYA)'] now = datetime.utcnow() ts = loader.timescale() for i in range(now.hour, now.hour+24): t = ts.utc(now.year, now.month, now.day, i, range(0, 59), 0)
# Graph the variation in Earth-Moon distance over time # There are a bunch of different implementations of Python; # I happen to like Anaconda, https://www.anaconda.com/distribution/ # it's a scientific-oriented version that has a lot of modules # precompiled for Windows which can otherwise be problematic to install. # Skyfield docs at https://rhodesmill.org/skyfield/ # install as: pip install skyfield from skyfield import almanac, api # Matplotlib docs at https://matplotlib.org/users/index.html import matplotlib.pyplot as plt # Load ephemeris data load = api.Loader("d:/skyfield-data") # which directory to store your BSP files in # BSP files are precomputed tables of planet location at time intervals, # prepared by JPL by numeric integration; skyfield can find very precise # planet locations at any time by interpolating between intervals. # You can get different files, covering different sets of planets and moons # at varying precision over varying periods; some of the files can get quite large. # data = load("de421.bsp") # default base data set data = load("de435.bsp") # Extended data set (higher precision over longer time period) # You may have to download this manually from JPL - about 114 MB # See https://naif.jpl.nasa.gov/pub/naif/generic_kernels/spk/planets/ # Init bodies sun = data["Sun"] earth = data["Earth"] moon = data["Moon"] # Set up a timescale (a date or list of dates)
import constants as const import satellites as sat import numpy as np import matplotlib.pyplot as plt import csv import datetime as dt import os from collections import defaultdict from skyfield import api as skyapi, toposlib as topo pi = np.pi gps_loader = skyapi.Loader(".\\data", verbose=False, expire=True) gps_sats = list(set(gps_loader.tle("gps-ops.txt").values())) #setup names for gps_sat in gps_sats: gps_sat.name = gps_sat.name[-3:-1].strip('0') ts = gps_loader.timescale(builtin=True) now = dt.datetime.now() rocket = sat.Observer(latitude_degrees=const.LAT_UBC_DEGREES, longitude_degrees=const.LONG_UBC_DEGREES, elevation_m=const.ELEV_UBC) log_fold = os.path.join("logs", f"datalog_" + now.strftime("%Y%m%d_%H%M%S"))
df = pd.read_csv(in_f) df.name = cfg['data_file'].split("_")[1] df['datetime'] = pd.to_datetime(df['datetime_str'], utc=True) # df['datetime'] = df['datetime'].tz_localize('UTC') doppler = sat_utils.Doppler_Shift(cfg['satellite']['freq'], df['Range Rate [km/sec]'] * 1000.0) df['Doppler Center [Hz]'] = doppler['center'] df['Doppler Offset [Hz]'] = doppler['offset'] print(df.keys().to_list()) lam = sat_utils.Freq_2_Lambda(cfg['satellite']['freq']) df['Path Loss [dB]'] = sat_utils.Path_Loss(df['Range [km]'] * 1000.0, lam) #----Setup Skyfield Parameters---- load = sf.Loader('/'.join([cwd, cfg['data_path']]), verbose=True) #load timescale object ts = load.timescale() t = ts.utc(df['datetime']) #load almanac e = load('de421.bsp') earth = e['earth'] sun = e['sun'] #setup ground station gs = sf.Topos(latitude_degrees=cfg['gs']['latitude'], longitude_degrees=cfg['gs']['longitude'], elevation_m=cfg['gs']['altitude_m']) print(cfg['gs']['name'], gs) astrometric = (earth + gs).at(t).observe(sun) el, az, rho = astrometric.apparent().altaz()
# Find the relative acceleration of the Moon due to the Sun and Earth from skyfield import almanac, api import matplotlib.pyplot as plt # load ephemeris data load = api.Loader("d:/skyfield-data") # save-data directory data = load("de435.bsp") # Note: you may have to download this manually from JPL. # Large file - about 114 MB. # init bodies sun = data["Sun"] earth = data["Earth"] moon = data["Moon"] # set up timescale ts = load.timescale() t1 = ts.utc(2018, 3, range(24, 24+365)) # 2018/03/24 to 2019/03/23 = 365 days # find accelerations sun_locs = moon.at(t1).observe(sun) sun_gm = 1.327e20 sun_acc = sun_gm / sun_locs.distance().m ** 2. earth_locs = moon.at(t1).observe(earth) earth_gm = 3.986e14 earth_acc = earth_gm / earth_locs.distance().m ** 2. # plot the results xs = t1.utc_datetime() plt.plot(xs, sun_acc, "r-", xs, earth_acc, "b-")
def format_dt(dt): return dt.strftime('%m/%d/%Y %H:%M:%S') def topo_from_data(lat, lon, alt): return api.Topos(lat, lon, elevation_m=alt) def loc_from_data(lat, lon, alt): topo = topo_from_data(lat, lon, alt) return earth + topo if '__main__' == __name__: logging.info('Loading timescale.') loader = api.Loader(data_dir, expire=True, verbose=True) data_downloaded = True # This is quite intense on a RPi Zero, should be a cmd line flag: if LOAD_HIPPARCOS: with loader.open(hipparcos.URL) as f: logging.info('Loading Hipparcos catalog') df = hipparcos.load_dataframe(f) logging.info('%s', loader.log) else: # verbose displays progress bar when downloading loader = api.Loader(data_dir, expire=False, verbose=False) try: ts = loader.timescale() except: logging.warning(
help="Camera Configuration File Path", action="store") cfg.add_argument('--spk_file', dest='spk_file', type=str, default="2523620.bsp", help="Configuration File", action="store") args = parser.parse_args() #--------END Command Line argument parser------------------------------------------------------ #subprocess.run(["reset"]) if not os.path.exists(args.data_path): print('Data path doesn\'t exist: {:s}'.format(args.data_path)) os.makedirs(args.data_path) load = sf.Loader(args.data_path, verbose=True) #load timescale object ts = load.timescale() #setup SPK/BSP file path fp_spk = '/'.join([args.data_path, args.spk_file]) print(fp_spk) if not os.path.isfile(fp_spk) == True: print('ERROR: Invalid SPK/BSP File Path: {:s}'.format(fp_spk)) sys.exit() print('Importing configuration File: {:s}'.format(fp_spk)) #load SPK/BSP e = load(fp_spk) print(e) sys.exit()
from datetime import datetime, timezone, timedelta from math import ceil, floor from skyfield import almanac, timelib, api import pprint # ts = None # e = None sky_load = api.Loader('./sky_data') ts = sky_load.timescale() # timescale e = sky_load('de438.bsp') # write code to automatically propagate these dates init_year = None last_year = None start_second = None end_second = None equinox_day = 21 equinox_month = 3 # full_moon = datetime(2019,5,18,21,11,tzinfo=timezone.utc) # test_date = datetime(2019,3,20,tzinfo=timezone.utc) # print(test_date.date()) def march_equinox(year): # must be 15 day range minimum, apparently? t0 = ts.utc(year, 3, 13) t1 = ts.utc(year, 3, 28) tstamp, phase = almanac.find_discrete(t0, t1, almanac.seasons(e)) for phi, ti in zip(phase, tstamp):