def create_subdirname(obstime, with_seconds=False, **kwargs): """Generate the pps subdirectory name from the start observation time, ex.: 'npp_20120405_0037_02270'""" sat = kwargs.get('platform_name', 'npp') platform_name = PLATFORM_NAME.get(sat, sat) if "orbit" in kwargs: orbnum = int(kwargs['orbit']) else: from pyorbital.orbital import Orbital from cspp_runner import orbitno try: tle = orbitno.get_tle(TLE_SATNAME.get(platform_name), obstime) orbital_ = Orbital(tle.platform, line1=tle.line1, line2=tle.line2) orbnum = orbital_.get_orbit_number(obstime, tbus_style=TBUS_STYLE) except orbitno.NoTleFile: LOG.error('Not able to determine orbit number!') import traceback traceback.print_exc(file=sys.stderr) orbnum = 1 if with_seconds: return platform_name + obstime.strftime( '_%Y%m%d_%H%M%S_') + '%.5d' % orbnum else: return platform_name + obstime.strftime( '_%Y%m%d_%H%M_') + '%.5d' % orbnum
def get_satellite_lat_lon(norad_id, tle_line1, tle_line2, date_time): username = '******' password = '******' base_url = 'https://www.space-track.org/' login_url = base_url + 'ajaxauth/login' query = base_url + "/basicspacedata/query/class/satcat/NORAD_CAT_ID/" + \ norad_id + \ "/orderby/NORAD_CAT_ID asc/metadata/false" data = {'identity': username, 'password': password, 'query': query} # Makes a POST REST call to space-track.org and return the result as a list of JSON try: resp = requests.post(login_url, data=data) except requests.exceptions.RequestException as err: print("POST RESTful call unsuccessful - unable to obtain LAT/LON : " + err) tip_data_list = json.loads(resp.text) satellite_name = str(tip_data_list[0].get('SATNAME')) orb = Orbital(satellite=satellite_name, line1=tle_line1, line2=tle_line2) # Gets longitude, latitude and altitude of the satellite: lon, lan, alt = orb.get_lonlatalt(date_time) print("------------------------- DATE & TIME IN UTC : " + str(date_time) + " -------------------------") print("LONGITUDE = " + str(lon)) print("LATITUDE = " + str(lan)) return lon, lan
def update_graph_live(n): data = {'time': [], 'Latitude': [], 'Longitude': [], 'Altitude': []} sat = Orbital('TERRA') # Collect some data for seconds in range(0, 3600, 20): time = datetime.datetime.now() - datetime.timedelta(seconds=seconds) data['time'].append(time) lon, lat, alt = sat.get_lonlatalt(time) data['Longitude'].append(lon) data['Latitude'].append(lat) data['Altitude'].append(alt) # Create the graph with subplots result = make_subplots(cols=1, rows=2, vertical_spacing=0.2, ) result['layout']['margin'] = {'b': 30, 'l': 30, 'r': 10, 't': 10, } result['layout']['legend'] = {'x': 0, 'xanchor': 'left', 'y': 1, } result.append_trace({'mode': 'lines+markers', 'name': 'Altitude', 'type': 'scatter', 'x': data['time'], 'y': data['Altitude'], }, 1, 1) result.append_trace( {'mode': 'lines+markers', 'name': 'Longitude vs Latitude', 'text': data['time'], 'type': 'scatter', 'x': data['Longitude'], 'y': data['Latitude'], }, 2, 1) return result
def get_angles(self): self.get_times() tle1, tle2 = self.get_tle_lines() orb = Orbital(self.spacecrafts_orbital[self.spacecraft_id], line1=tle1, line2=tle2) sat_azi, sat_elev = orb.get_observer_look(self.times[:, np.newaxis], self.lons, self.lats, 0) sat_zenith = 90 - sat_elev sun_zenith = astronomy.sun_zenith_angle(self.times[:, np.newaxis], self.lons, self.lats) alt, sun_azi = astronomy.get_alt_az(self.times[:, np.newaxis], self.lons, self.lats) del alt sun_azi = np.rad2deg(sun_azi) sun_azi = np.where(sun_azi < 0, sun_azi + 180, sun_azi - 180) rel_azi = abs(sat_azi - sun_azi) rel_azi = np.where(rel_azi > 180.0, 360.0 - rel_azi, rel_azi) return sat_azi, sat_zenith, sun_azi, sun_zenith, rel_azi
def getGPSPosition(platformName, tleFile, dateTime): orb = Orbital(platformName, tleFile) lon, lat, alt = orb.get_lonlatalt(dateTime) #reading the TLE file file = open(tleFile) data = file.read().replace("\n","::") arr = data.split("::") for i in range(len(arr)): if platformName.rstrip() == arr[i].rstrip(): tleOne= arr[i+1] tleTwo = arr[i+2] file.close() sat = ephem.readtle(platformName, tleOne, tleTwo) #compute satellite position sat.compute(dateTime) satlat = math.degrees(sat.sublat) satlon = math.degrees(sat.sublong) satele = sat.elevation satsize = sat.size satrad = sat.radius satecl = sat.eclipsed satasc = sat.a_ra satdecl = sat.a_dec return [satlon, satlat, satele, satsize, satrad, satecl, satasc, satdecl]
def __init__(self, aoi, sat, instrument="AVHRR"): OrbitalLayer.__init__(self, aoi, sat, instrument) # instantiate orbital module config_file_path = "" try: config_file_path = os.environ['PYGRANULE_CONFIG_PATH'] except KeyError: print "pygranule config file path missing. Has the 'PYGRANULE_CONFIG_PATH' environment variable been set?" default_tle_file = config_file_path + "/default.tle" try: self.orbital = Orbital(sat, default_tle_file) except: print "Failed to open default tle file:", default_tle_file print "Downloading from internet:" try: self.orbital = Orbital(sat) except: raise OrbitalLayerError( "Pyorbital Failed to fetch TLE from internet.") # create scan geometry - one scan line. if instrument == "AVHRR": scan_steps = np.arange(0, self.instrument_info['scan_steps'], self.instrument_info['scan_steps'] / 8 - 1) scan_steps[-1] = self.instrument_info['scan_steps'] - 1 self.scan_geom = avhrr(1, scan_steps) elif instrument == "VIIRS": self.scan_geom = viirs(1)
def __init__(self, aoi, sat, instrument="AVHRR"): OrbitalLayer.__init__(self,aoi,sat,instrument) # instantiate orbital module config_file_path = "" try: config_file_path = os.environ['PYGRANULE_CONFIG_PATH'] except KeyError: print "pygranule config file path missing. Has the 'PYGRANULE_CONFIG_PATH' environment variable been set?" default_tle_file = config_file_path+"/default.tle" try: self.orbital = Orbital(sat,default_tle_file) except: print "Failed to open default tle file:", default_tle_file print "Downloading from internet:" try: self.orbital = Orbital(sat) except: raise OrbitalLayerError("Pyorbital Failed to fetch TLE from internet.") # create scan geometry - one scan line. if instrument == "AVHRR": scan_steps = np.arange(0,self.instrument_info['scan_steps'],self.instrument_info['scan_steps']/8-1) scan_steps[-1] = self.instrument_info['scan_steps']-1 self.scan_geom = avhrr(1,scan_steps) elif instrument == "VIIRS": self.scan_geom = viirs(1)
def serialPortRead(passNumber): #passes = satOrb.get_next_passes(datetime.utcnow(),120, -30.8047389406, 72.9167, 180.85) #next get number of passes the user wants satOrb = Orbital(satName, tleFile) passes = satOrb.get_next_passes(current_time,int(passNumber), home.lat, home.lon, home.elevation) for eachPass in passes: rise = eachPass[0] fall = eachPass[1] apex = eachPass[2] # Lon, Lat obsRiseAngle, obsRiseElv = satOrb.get_observer_look(rise, home.lat, home.lon, home.elevation) obsFallAngle, obsFallElv = satOrb.get_observer_look(fall, home.lat, home.lon, home.elevation) obsApexAngle, obsApexElv = satOrb.get_observer_look(apex, home.lat, home.lon, home.elevation) print("observer apex", obsApexElv) print("Rise Time:", rise, "Azimuth:", round(obsRiseAngle, 2), '(', azimuthDirection(obsRiseAngle), ')', "Elevation:", abs(round(obsRiseElv, 2))) print("Apex Time:", apex, "Azimuth:", round(obsApexAngle, 2), '(', azimuthDirection(obsApexAngle), ')', "Elevation:", abs(round(obsApexElv, 2))) print("Fall Time:", fall, "Azimuth:", round(obsFallAngle, 2), '(', azimuthDirection(obsFallAngle), ')', "Elevation:", abs(round(obsFallElv, 2))) print() return
def predict_next_passes(tle_dir: str, satellites: dict, station_location: dict, min_elevation: float, for_next_hours: int) -> list: all_passes = [] time_now_utc = datetime.datetime.utcnow() for sat_name in satellites: sat = satellites[sat_name] sat_type = sat["type"] orbital = Orbital(sat_name, tle_file="{}/{}/{}.tle".format( tle_dir, sat_type, sat_name)) passes = orbital.get_next_passes(time_now_utc + datetime.timedelta(seconds=-60 * 20), for_next_hours, station_location["lon"], station_location["lat"], station_location["alt"], horizon=min_elevation) all_passes += [{ "type": sat_type, "name": sat_name, "rise_time": pas[0], "fall_time": pas[1], "duration": (pas[1] - pas[0]).total_seconds() } for pas in passes] all_passes.sort(key=lambda t: t["rise_time"]) return all_passes
def get_last_valid_tle_lines(platform_name, epoch): if os.path.exists(os.path.join(REF_DIR, platform_name)): with open(os.path.join(REF_DIR, platform_name)) as fd: ref_lines = fd.readlines() ref_orb = Orbital(platform_name, line1=ref_lines[1], line2=ref_lines[2]) if abs(epoch - ref_orb.tle.epoch) < timedelta(days=7): return ref_lines else: logger.info("cached TLE too old, refreshing") orbit = get_valid_orbit(platform_name, epoch) files = sorted(get_files(), key=os.path.getctime) for tle_file in reversed(files): try: orb = Orbital(platform_name, tle_file=tle_file) except AttributeError: continue except ChecksumError: continue if orb.get_orbit_number(epoch) == orbit: lines = [orb.tle._platform, orb.tle._line1, orb.tle._line2] with open(os.path.join(REF_DIR, platform_name), "w") as fd: fd.write("\n".join(lines)) return lines
def update_graph_scatter(n): satellite = Orbital('TERRA') tiempo = [] Latitude = [] Longitude = [] Altitude = [] valor = [] v = [] X.append(datetime.datetime.now() - datetime.timedelta()) Y.append(random.randrange(-20, 20)) #datetime.datetime.now().time() for i in range(2 * n): v = random.randrange(-20, 20) time = datetime.datetime.now() - datetime.timedelta(seconds=i * 20) lon, lat, alt = satellite.get_lonlatalt(time) Longitude.append(lon) Latitude.append(lat) Altitude.append(alt) tiempo.append(time) valor.append(v) trace1 = go.Scatter(x=list(tiempo), y=list(Altitude), name='Altitud', mode='lines+markers') return { 'data': [trace1], 'layout': go.Layout(transition={ 'duration': 1, 'easing': 'cubic-in-out' }) }
def time_above_the_horizon(ground_position_lat, ground_position_lon, date, date_format = "%d/%m/%Y", time_window = 24, satellite_sensor = 'aqua', elevation = 0): '''time_above_the_horizon calculates the observation times of satellite passes for the day and time window of a given position on the earth. It is based on pyorbital functions. ground_position_lat = -19.2590 # The latitude of the ground position (int) ground_position_lon = 146.8169 # The longitude of the ground position (int) date = '21/06/2016' # date of the day to find passes on. (This is techincally in local time for your location an is converted to UTC internally here.) (string) date_format = "%d/%m/%Y" # the format of thh date string (string) satellite_sensor = 'aqua' # the name of the satellite sensor you are tracking (string). for VIIRS use 'SUOMI NPP' time_window = 24 # Number of hours to find passes (int) elevation = 0 # the elevation of horizon to compute risetime and falltime. (int) Returns: [(rise-time, fall-time, max-elevation-time), ...] as datetime objects in the UTC time zone. Contact: [email protected] ''' # check the lat and lons to be sensible. futs.check_for_sensible_lat_long([ground_position_lat, ground_position_lon]) #set up the satellite orb = Orbital(satellite_sensor) # convert the local time to a utc time. utc_date = futs.local_to_utc(futs.which_time_zone(ground_position_lat, ground_position_lon), date, date_format) # do calcs and remove the utc awareness from the utc_date so that pyorbital can use it. time_satellite_is_above_horizon = orb.get_next_passes(utc_date.replace(tzinfo=None), time_window, ground_position_lon, ground_position_lon, elevation) return time_satellite_is_above_horizon
def compute_pixels(orb, sgeom, times, rpy=(0.0, 0.0, 0.0)): """Compute cartesian coordinates of the pixels in instrument scan.""" if isinstance(orb, (list, tuple)): tle1, tle2 = orb orb = Orbital("mysatellite", line1=tle1, line2=tle2) # get position and velocity for each time of each pixel pos, vel = orb.get_position(times, normalize=False) # now, get the vectors pointing to each pixel vectors = sgeom.vectors(pos, vel, *rpy) # compute intersection of lines (directed by vectors and passing through # (0, 0, 0)) and ellipsoid. Derived from: # http://en.wikipedia.org/wiki/Line%E2%80%93sphere_intersection # do the computation between line and ellipsoid (WGS 84) # NB: AAPP uses GRS 80... centre = -pos a__ = 6378.137 # km # b__ = 6356.75231414 # km, GRS80 b__ = 6356.752314245 # km, WGS84 radius = np.array([[1 / a__, 1 / a__, 1 / b__]]).T shape = vectors.shape xr_ = vectors.reshape([3, -1]) * radius cr_ = centre.reshape([3, -1]) * radius ldotc = np.einsum("ij,ij->j", xr_, cr_) lsq = np.einsum("ij,ij->j", xr_, xr_) csq = np.einsum("ij,ij->j", cr_, cr_) d1_ = (ldotc - np.sqrt(ldotc ** 2 - csq * lsq + lsq)) / lsq # return the actual pixel positions return vectors * d1_.reshape(shape[1:]) - centre
def __init__(self, ground_station, satellite_tle): """Constructor: ground station as GroundStation, satellite TLE as TleManipulator""" self.__ground_station = ground_station self.__satellite_tle = satellite_tle self.__orb = Orbital(str(self.__satellite_tle.get_satellite_number()), \ line1=self.__satellite_tle.get_line1(), \ line2=self.__satellite_tle.get_line2())
def update_graph_live(n): satellite = Orbital("TERRA") data = {"time": [], "Latitude": [], "Longitude": [], "Altitude": []} # Collect some data for i in range(180): time = datetime.datetime.now() - datetime.timedelta(seconds=i * 20) lon, lat, alt = satellite.get_lonlatalt(time) data["Longitude"].append(lon) data["Latitude"].append(lat) data["Altitude"].append(alt) data["time"].append(time) # Create the graph with subplots fig = plotly.tools.make_subplots(rows=2, cols=1, vertical_spacing=0.2) fig["layout"]["margin"] = {"l": 30, "r": 10, "b": 30, "t": 10} fig["layout"]["legend"] = {"x": 0, "y": 1, "xanchor": "left"} fig.append_trace( {"x": data["time"], "y": data["Altitude"], "name": "Altitude", "mode": "lines+markers", "type": "scatter"}, 1, 1 ) fig.append_trace( { "x": data["Longitude"], "y": data["Latitude"], "text": data["time"], "name": "Longitude vs Latitude", "mode": "lines+markers", "type": "scatter", }, 2, 1, ) return fig
def propagate_orbits(TLE_path, days): num_mins = int(days * 24 * 60) time_list = [ datetime.datetime(2020, 1, 1, 0, 0, 0, 0) + datetime.timedelta(seconds=60 * x) for x in range(0, num_mins) ] num = 0 table = pd.DataFrame(time_list, columns=["Time"]) file = open(TLE_path, "r") a = file.readline() b = file.readline() # Iterate over TLE file while a != '' and b != '': orb = Orbital("sat{}".format(num), line1=a, line2=b) pos_list = [] for time in time_list: pos = orb.get_position(time, normalize=False) pos_list.append(pos) table[str(num)] = pos_list num += 1 a = file.readline() b = file.readline() file.close() return table
def GetGPSPosition(platformName, tleFile, dateTime): orb = Orbital(platformName, tleFile) lon, lat, alt = orb.get_lonlatalt(dateTime) return [lon, lat, alt, dateTime]
def create_orbital_track_shapefile_for_day (track_day, step, dur): # получаем TLE для NOAA-19 tle_1 = '1 33591U 09005A 21067.53688389 .00000027 00000-0 40065-4 0 9999' tle_2 = '2 33591 99.1917 85.7021 0014730 58.0337 302.2263 14.12454575622414' # Создаём экземляр класса Orbital orb = Orbital("N", line1=tle_1, line2=tle_2) i = 0 minutes = 0 coord = np.arange(3*dur).reshape(dur, 3) while minutes < dur: # Расчитаем час, минуту, секунду (для текущего шага) utc_hour = int(minutes // 60) utc_minutes = int((minutes - (utc_hour*60)) // 1) utc_seconds = int(round((minutes - (utc_hour*60) - utc_minutes)*60)) utc_string = str(utc_hour) + '-' + str(utc_minutes) + '-' + str(utc_seconds) utc_time = datetime(track_day.year,track_day.month,track_day.day,utc_hour,utc_minutes,utc_seconds) # Считаем положение спутника lon, lat, alt = orb.get_lonlatalt(utc_time) coord[i] [0] = lon coord[i] [1] = lat coord[i] [2] = alt + 6400 i += 1 minutes += step return coord
def _get_sat_angles_with_tle(self): tle1, tle2 = self.get_tle_lines() orb = Orbital(self.spacecrafts_orbital[self.spacecraft_id], line1=tle1, line2=tle2) sat_azi, sat_elev = orb.get_observer_look(self.times[:, np.newaxis], self.lons, self.lats, 0) return sat_azi, sat_elev
def get_satellite_coordinates(lon, lat, alt, satellite_id): try: satellite = Satellite.objects.get(id=satellite_id) orb = Orbital(satellite.codename) now = datetime.utcnow() return orb.get_observer_look(now, lon, lat, alt) except Satellite.DoesNotExist: return None
def get_xyz(t): orb = Orbital("TJREVERB", tle_file=(Path(__file__).parent.resolve() / "tjreverb_tle.txt")) return ({ 'xyz_pos': orb.get_position(t)[0], 'xyz_vel': orb.get_position(t)[1] })
def get_lonlat(scene, row, col): """Get the longitutes and latitudes for the give *rows* and *cols*. """ try: filename = get_filename(scene, "granules") except IOError: #from mpop.satin.eps1a import get_lonlat_avhrr # return get_lonlat_avhrr(scene, row, col) from pyorbital.orbital import Orbital import pyproj from datetime import timedelta start_time = scene.time_slot end_time = scene.time_slot + timedelta(minutes=3) orbital = Orbital("METOP-A") track_start = orbital.get_lonlatalt(start_time) track_end = orbital.get_lonlatalt(end_time) geod = pyproj.Geod(ellps='WGS84') az_fwd, az_back, dist = geod.inv(track_start[0], track_start[1], track_end[0], track_end[1]) del dist M02_WIDTH = 2821885.8962408099 pos = ((col - 1024) * M02_WIDTH) / 2048.0 if row > 520: lonlatdist = geod.fwd(track_end[0], track_end[1], az_back - 86.253533216206648, -pos) else: lonlatdist = geod.fwd(track_start[0], track_start[1], az_fwd - 86.253533216206648, pos) return lonlatdist[0], lonlatdist[1] try: if scene.lons is None or scene.lats is None: records, form = read_raw(filename) mdrs = [record[1] for record in records if record[0] == "mdr"] sphrs = [record for record in records if record[0] == "sphr"] sphr = sphrs[0][1] scene.lons, scene.lats = _get_lonlats(mdrs, sphr, form) return scene.lons[row, col], scene.lats[row, col] except AttributeError: records, form = read_raw(filename) mdrs = [record[1] for record in records if record[0] == "mdr"] sphrs = [record for record in records if record[0] == "sphr"] sphr = sphrs[0][1] scene.lons, scene.lats = _get_lonlats(mdrs, sphr, form) return scene.lons[row, col], scene.lats[row, col]
def get_lla(t): orb = Orbital("TJREVERB", tle_file=(Path(__file__).parent.resolve() / "tjreverb_tle.txt")) return ({ 'lat': orb.get_lonlatalt(t)[0], 'lon': orb.get_lonlatalt(t)[1], 'alt': orb.get_lonlatalt(t)[2] })
def update_graph_live(n): satellite = Orbital('TERRA') data = { 'time': [], 'Latitude': [], 'Longitude': [], 'Altitude': [] } # Collect some data for i in range(180): time = datetime.datetime.now() - datetime.timedelta(seconds=i*20) lon, lat, alt = satellite.get_lonlatalt( time ) data['Longitude'].append(lon) data['Latitude'].append(lat) data['Altitude'].append(alt) data['time'].append(time) # Create the graph with subplots fig = plotly.tools.make_subplots(rows=2, cols=2, vertical_spacing=0.2) fig['layout']['margin'] = { 'l': 30, 'r': 10, 'b': 30, 't': 10 } fig['layout']['legend'] = {'x': 0, 'y': 1, 'xanchor': 'left'} fig.append_trace ({ 'x': data['time'], 'y': data['Altitude'], 'name': 'Altitude', 'mode': 'lines+markers', 'type': 'scatter' }, 1, 1) j = go.Scatter( x =data['Longitude'], y= data['Latitude'], text= data['time'], name= 'Longitude vs Latitude', mode= 'lines+markers', type= 'scatter' ) #trace = go.Figure(data = airports) #trace = [i,j] fig.append_trace(j , 2, 1) #fig.append_trace(j , 2, 1) return fig
def runProp(): #orb = Orbital(tle) orb = Orbital("TJREVERB", tle_file="FILE PATH TO TLE") now = datetime.utcnow() #print(tle.inclination) #print(orb.get_position(now)) print(orb.get_lonlatalt(now)) print() print(orb.get_next_passes(now, 12, -77.10428, 8.88101, 276, tol=0.001, horizon=0))
def create_orbital_track_shapefile_for_day(year, month, day, step_minutes, tle_line1, tle_line2, output_shapefile): try: orb = Orbital("N", tle_file=None, line1=tle_line1, line2=tle_line2) except (ChecksumError): print 'Invalid TLE' return 2 try: year = int(year) month = int(month) day = int(day) step_minutes = float(step_minutes) except: print 'Invalid date' return 3 w = shapefile.Writer(shapefile.POINT) w.field('ID', 'C', 40) w.field('TIME', 'C', 40) w.field('LAT', 'C', 40) w.field('LON', 'C', 40) i = 0 minutes = 0 while minutes < 1440: utc_hour = int(minutes // 60) utc_minutes = int((minutes - (utc_hour * 60)) // 1) utc_seconds = int(round( (minutes - (utc_hour * 60) - utc_minutes) * 60)) utc_string = str(utc_hour) + '-' + str(utc_minutes) + '-' + str( utc_seconds) utc_time = datetime.datetime(year, month, day, utc_hour, utc_minutes, utc_seconds) lon, lat, alt = orb.get_lonlatalt(utc_time) w.point(lon, lat) w.record(str(i), utc_string, str(lat), str(lon)) i += 1 minutes += step_minutes try: prj = open("%s.prj" % output_shapefile.replace('.shp', ''), "w") epsg = 'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]]' prj.write(epsg) prj.close() w.save(output_shapefile) except: print 'Unable to save shapefile' return 4
def serial_az_el(name, stop_time=( datetime.utcnow())): # sends data over serial to arduino format (az, el) satellite = Orbital(name, tle_file=nextPass.path_to_tle) now = datetime.utcnow() while int( (stop_time - now).total_seconds()) >= 0: # while pass is occurring now = datetime.utcnow() print( satellite.get_observer_look(now, nextPass.lon, nextPass.lat, nextPass.alt)) # print (az, el) sleep(2) # wait 2 seconds
def test_63(self): """Check that no runtimewarning is raised, #63.""" import warnings from pyorbital.orbital import Orbital from dateutil import parser warnings.filterwarnings('error') orb = Orbital("Suomi-NPP", line1="1 37849U 11061A 19292.84582509 .00000011 00000-0 25668-4 0 9997", line2="2 37849 98.7092 229.3263 0000715 98.5313 290.6262 14.19554485413345") orb.get_next_passes(parser.parse("2019-10-21 16:00:00"), 12, 123.29736, -13.93763, 0) warnings.filterwarnings('default')
def ground_truth(lat, lon, time, sat, duration): orb = Orbital(sat, tle_file="active.txt") delta = timedelta(seconds=1) azs = [] els = [] for i in range(duration): az, el = pwm_for(*orb.get_observer_look(time, lon, lat, 0)) azs.append(az) els.append(el) time += delta return azs, els
def update_satellite(self, satellite): """Update satellite and renew the orbital instance. """ if satellite != self._satellite: self._satellite = satellite if self._tle_files is not None: filelist = glob(self._tle_files) tle_file = max(filelist, key=lambda x: os.stat(x).st_mtime) else: tle_file = None self._orbital = Orbital(self._satellite.upper(), tle_file)
def __init__(self,name,file): self.file = file self.orbital = Orbital(name,file) self.xyz=[[],[],[]] self.now = datetime.now() self.position = self.orbital.get_position(self.now,False) for i in range(0,2000): self.now += timedelta(seconds=4) position = self.orbital.get_position(self.now,False) for i in range(0,3): self.xyz[i].append(position[0][i])
def get_valid_orbit(platform_name, epoch): orb_nums = [] for tle_file in sorted(get_files(), reverse=True): try: orb = Orbital(platform_name, tle_file=tle_file) except AttributeError: continue except ChecksumError: continue orb_nums.append(orb.get_orbit_number(epoch)) return int(round(np.median(orb_nums)))
def create_orbital_track_shapefile_for_day (year, month, day, step_minutes, tle_line1, tle_line2, sat_name): try: orb = Orbital("N",tle_file=None,line1=tle_line1, line2=tle_line2) except: raise NameError try: year = int(year) month = int(month) day = int(day) step_minutes = float(step_minutes) except: raise TypeError trackLayerName = 'Track Layer (' + str(sat_name) + ': ' + str(year) + ':' + str(month) + ':' + str(day) + ')' trackLayer = QgsVectorLayer("Point", trackLayerName, "memory") trackLayer.setCrs(QgsCoordinateReferenceSystem(4326)) trackLayerDataProvider = trackLayer.dataProvider() trackLayer.startEditing() trackLayerDataProvider.addAttributes( [ QgsField("ID", QVariant.Int), QgsField("TIME", QVariant.String), QgsField("LAT", QVariant.Double), QgsField("LON", QVariant.Double)] ) i = 0 minutes = 0 while minutes < 1440: QApplication.processEvents() utc_hour = int(minutes // 60) utc_minutes = int((minutes - (utc_hour*60)) // 1) utc_seconds = int(round((minutes - (utc_hour*60) - utc_minutes)*60)) utc_string = str(utc_hour) + ':' + str(utc_minutes) + ':' + str(utc_seconds) utc_time = datetime.datetime(year,month,day,utc_hour,utc_minutes,utc_seconds) lon, lat, alt = orb.get_lonlatalt(utc_time) trackPoint = QgsFeature() trackPoint.setGeometry(QgsGeometry.fromPoint(QgsPoint(lon,lat))) trackPoint.setAttributes([i,utc_string,float(lat),float(lon)]) trackLayerDataProvider.addFeatures ([trackPoint]) i += 1 minutes += step_minutes trackLayer.commitChanges() trackLayer.updateExtents() return trackLayer
def track(): # tle = tlefile.read('ISS', 'orbit.txt') orbit = Orbital('ISS', 'Telescope/orbit.txt') while True: now = datetime.utcnow() # print(now) coords = (orbit.get_position(now)[0]) # print(orbit.get_lonlatalt(now)) # print(coords) print(convertCartesianToRaDec(coords[0], coords[1], coords[2])) time.sleep(1)
def get_view_zen_angles(sat_name, tle_filename, area_def_name, time_slot): """Calculate the satellite zenith angles for the given satellite (*sat_name*, *tle_filename*), *area_def_name* and *time slot*. Stores the result in the given *cache* parameter. """ try: from pyorbital.orbital import Orbital except ImportError: LOGGER.warning("Could not load pyorbital modules") return area_def = get_area_def(area_def_name) lons, lats = area_def.get_lonlats() orbital_obj = Orbital(sat_name, tle_filename) elevation = orbital_obj.get_observer_look(time_slot, lons, lats, 0)[1] view_zen_data = np.subtract(90, np.ma.masked_outside(elevation, 0, 90)) return view_zen_data
def extractDataset(self, satelliteName='ISS (ZARYA)', sourceDirectory=generateFilename(description = "stations", extension = ".txt", dateToday = False), referenceDate = (2015,10,28,0,0,0), numberOfSamples = 1440, numberOfInputs = 4, incrementSeconds = 60): self.satelliteName = satelliteName self.sourceDirectory = sourceDirectory self.referenceDate = referenceDate self.numberOfSamples = numberOfSamples self.numberOfInputs = numberOfInputs self.dataset = np.zeros(shape=[1,self.numberOfInputs]) self.incrementSeconds = incrementSeconds self.min = 0 self.max = 0 self.min_dataset = 0 self.max_dataset = 0 try: # reading input data input_data = Orbital(self.satelliteName, self.sourceDirectory) # calculate date date = datetime.datetime(*self.referenceDate) #1440 for the number of minutes in a day for point_n in xrange(self.numberOfSamples): #each point will be collected with a specified difference of seconds date += datetime.timedelta(0,incrementSeconds) output_data = input_data.get_position(date,normalize=False) self.dataset = np.vstack([self.dataset, np.append(output_data[0],[point_n + referenceDate[4]])]) self.dataset = np.delete(self.dataset,0,0) return 0 except: return 1
def __init__(self): self.ground_lat = EARTH_STATION_LAT self.ground_long = EARTH_STATION_LONG self.observer = ephem.Observer() self.observer.lat = self.ground_lat self.observer.long = self.ground_long self.observer.date = datetime.utcnow() self.tle = IN_TLE_FILE self.tles = [] self.satellite_name = TRK_SATELLITE self.orb = Orbital(self.satellite_name,tle_file=self.tle)
def create_subdirname(obstime, with_seconds=False, **kwargs): """Generate the pps subdirectory name from the start observation time, ex.: 'npp_20120405_0037_02270'""" if "orbit" in kwargs: orbnum = int(kwargs['orbit']) else: from pyorbital.orbital import Orbital from npp_runner import orbitno try: tle = orbitno.get_tle('npp', obstime) orbital_ = Orbital(tle.platform, line1=tle.line1, line2=tle.line2) orbnum = orbital_.get_orbit_number(obstime, tbus_style=TBUS_STYLE) except orbitno.NoTleFile: LOG.error('Not able to determine orbit number!') import traceback traceback.print_exc(file=sys.stderr) orbnum = 1 if with_seconds: return obstime.strftime('npp_%Y%m%d_%H%M%S_') + '%.5d' % orbnum else: return obstime.strftime('npp_%Y%m%d_%H%M_') + '%.5d' % orbnum
def on_opened(self, event): fname = os.path.split(event.src_path)[1] if self._file is None and fnmatch(fname, self._file_pattern): logger.debug("Opening: " + event.src_path) self._filename = event.src_path self._file = open(event.src_path, "rb") self._where = 0 self._satellite = " ".join(event.src_path.split("_")[1:3])[:-5] if self._tle_files is not None: filelist = glob(self._tle_files) tle_file = max(filelist, key=lambda x: os.stat(x).st_mtime) else: tle_file = None self._orbital = Orbital(self._satellite, tle_file)
class NPP_Orbit: # Constructor of NPP_Orbit def __init__(self): self.ground_lat = EARTH_STATION_LAT self.ground_long = EARTH_STATION_LONG self.observer = ephem.Observer() self.observer.lat = self.ground_lat self.observer.long = self.ground_long self.observer.date = datetime.utcnow() self.tle = IN_TLE_FILE self.tles = [] self.satellite_name = TRK_SATELLITE self.orb = Orbital(self.satellite_name,tle_file=self.tle) # Functions def read_tle(self): self.tles = open(self.tle, 'r').readlines() self.tles = [item.strip() for item in self.tles] self.tles = [(self.tles[i], self.tles[i+1], self.tles[i+2]) \ for i in xrange(0, len(self.tles)-2, 3)] return def get_pass_num_t(self,yyyy,mm,dd,hh,mn,ss): indate = str(yyyy) + '-' + str(mm) + '-' +str(dd) + ' ' +\ str(hh) + ':' + str(mn) + ':' + str(ss) self.observer.date = indate for tle in self.tles: if tle[0].strip() == self.satellite_name: sat = ephem.readtle(tle[0],tle[1],tle[2]) rt, ra, tt, ta, st, sa = self.observer.next_pass(sat) num = self.orb.get_orbit_number(datetime.strptime(str(tt), "%Y/%m/%d %H:%M:%S"),tbus_style=True) return num def __del__(self): pass
def SatStats(): #tle = r"C:\Users\Jake\Python\TLE Files\stations-tle.txt" # Download TLE file #downloadUrl = "http://www.celestrak.com/NORAD/elements/stations.txt" #urllib.request.urlretrieve(downloadUrl, tle) tle = GetTLEFile() stationList = GetStationList(tle) try: while(True): stationNumber = input("Enter Station Number: ") print() if stationNumber == 'n': for name in enumerate(stationList): print(name[0], ':', name[1].replace('\n', '')) print() else: break stationNumber = int(stationNumber) if stationNumber < len(stationList): # Get Platform Object station = stationList[stationNumber] stationObject = tlefile.read(station, tle) GoogleSearch(station) # Print Platform Info PrintTLEInfo(stationObject, station) lon, lat, alt, now = GetGPSPosition(station, tle, datetime.utcnow()) dmLon, dmLat = DegreeMinutes(lon, lat) print("Current GPS location:\n", "Latitude: ", lat, " Longitude: ", lon, " Altitude (km): ", alt, sep='') print("Current GPS location:\n", "Latitude: ", dmLat, " Longitude: ", dmLon, " Altitude (km): ", alt, sep='') satOrb = Orbital(station, tle) print() PrintFreqData(GetFreqData(station, "C:/Users/Jake/Python/Satellite Tracker/frequencies/satfreqlist.csv")) passes = satOrb.get_next_passes(datetime.utcnow(), 120, -90.5546910, 38.6475290, 180.85) print("Next passes in 5 days (Max Elevation Above 20 deg):") for eachPass in passes: rise = eachPass[0] fall = eachPass[1] apex = eachPass[2] # Lon, Lat obsRiseAngle, obsRiseElv = satOrb.get_observer_look(rise, -90.5546910, 38.6475290, 180.85) obsFallAngle, obsFallElv = satOrb.get_observer_look(fall, -90.5546910, 38.6475290, 180.85) obsApexAngle, obsApexElv = satOrb.get_observer_look(apex, -90.5546910, 38.6475290, 180.85) if obsApexElv >= 20.0: print("Rise Time:", rise, "Azimuth:", round(obsRiseAngle, 2), '(', AzimuthDirection(obsRiseAngle), ')', "Elevation:", abs(round(obsRiseElv, 2))) print("Apex Time:", apex, "Azimuth:", round(obsApexAngle, 2), '(', AzimuthDirection(obsApexAngle), ')', "Elevation:", abs(round(obsApexElv, 2))) print("Fall Time:", fall, "Azimuth:", round(obsFallAngle, 2), '(', AzimuthDirection(obsFallAngle), ')', "Elevation:", abs(round(obsFallElv, 2))) print() except: pass
import time import calendar SIDERAL_DAY_SEC = 86164.0905 MU = 398600 # Earth standard gravitational parameter satellite = sys.argv[1] userLat = float(sys.argv[2]) userLng = float(sys.argv[3]) userAlt = float(sys.argv[4]) line1 = sys.argv[5] line2 = sys.argv[6] tle = tlefile.read(satellite, None, line1, line2) orb = Orbital(satellite, None, line1, line2) now = datetime.utcnow() # Get normalized position and velocity of the satellite: pos, vel = orb.get_position(now) # Get longitude, latitude and altitude of the satellite: position = orb.get_lonlatalt(now) data = {} timestamp = calendar.timegm(now.utctimetuple()) az, el = orb.get_observer_look(now, userLng, userLat, userAlt); data['user_view'] = {}
def getUpcomingPasses(satellite_name,satellite_swath,tle_information, passes_begin_time, passes_period): observer = ephem.Observer() observer.lat = GROUND_STATION[0] observer.long = GROUND_STATION[1] #updatetime = 0 period = passes_period #Get most recent TLE for determining upcoming passes from now tles = tle_information # make a list of dicts to hold the upcoming pass information for the selected satellites SCHEDULE = [] observer.date = passes_begin_time while 1: for tle in tles: if tle[0].strip()== satellite_name: #TODO clean up the use of pyephem versus orbital. Orbital can give a orbit number and does many of the pyephem functions #TODO add the individual acquisitions as layers in the same ogr output #TODO use an appropriate google earth icon for satellites at a visible display resolution with a name tag and minutesaway #TODO print output to logging satname = str(tle[0]).replace(" ","_") sat = ephem.readtle(tle[0],tle[1],tle[2]) twole = tlefile.read(tle[0],DATA_IN_DIR+'tles.txt') now = datetime.utcnow() #TODO check age of TLE - if older than x days get_tle() # print "TLE EPOCH:",twole.epoch oi = float(str.split(tle[2],' ')[3]) orb = Orbital(tle[0]) attributes = [] rt, ra, tt, ta, st, sa = observer.next_pass(sat) # Determine is pass descending or ascending sat.compute(rt) aos_lat = sat.sublat.real*(180/math.pi) sat.compute(st) los_lat = sat.sublat.real*(180/math.pi) if (aos_lat > los_lat): # print "PASS = descending" node = "descending" else: # print "PASS = ascending" node = "ascending" oi = 360 - oi AOStime = datetime.strptime(str(rt), "%Y/%m/%d %H:%M:%S") minutesaway = (AOStime-now).seconds/60.0 # print "Satellie = ", satname # print "Minutes to horizon = ", minutesaway # print "AOStime = ", rt # print "LOStime = ", st # print "Transit time = ", tt # ----------------------------------------------------------------------------- # This is a test routine for calculating Az, El angles # ----------------------------------------------------------------------------- orad = orb.get_lonlatalt(datetime.strptime(str(rt), "%Y/%m/%d %H:%M:%S"))[2] # print '&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&' test_az_el_cal(orb,observer, rt, ra, tt, ta, st, sa,orad) # print '&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&' # attributes = {'Satellite name': satname, 'Orbit height': orad, 'Orbit': orb.get_orbit_number(datetime.strptime(str(rt), "%Y/%m/%d %H:%M:%S")), \ # attributes = {'Satellite name': satname, 'Orbit height': orad, 'Orbit': orb.get_orbit_number(datetime.strptime(str(tt), "%Y/%m/%d %H:%M:%S")), \ 'Current time': str(now),'Minutes to horizon': minutesaway, 'AOS time': str(rt), \ 'LOS time': str(st), 'Transit time': str(tt), 'Node': node} # Append the attributes to the list of acquisitions for the acquisition period if not any ((x['Satellite name'] == satname and x['Orbit'] == orb.get_orbit_number(datetime.strptime(str(rt), "%Y/%m/%d %H:%M:%S")))for x in SCHEDULE): # if not any ((x['Satellite name'] == satname and x['Orbit'] == orb.get_orbit_number(datetime.strptime(str(tt), "%Y/%m/%d %H:%M:%S")))for x in SCHEDULE): SCHEDULE.append(attributes) # Step from AOS to LOS in 100 second intervals # delta = timedelta(seconds=100) delta = timedelta(seconds=DELTA_TIME_STEP) deltatime = datetime.strptime(str(rt), "%Y/%m/%d %H:%M:%S") geoeastpoint = [] geowestpoint = [] geotrack = [] # print "DELTATIME", deltatime # print "SETTING TIME", datetime.strptime(str(st), "%Y/%m/%d %H:%M:%S") # Tesing for next satellite # -------------------------------------------------------------------------------------------- # -------------------------------------------------------------------------------------------- # The following set of lines have been for testing while making comparision in seconds # instead of string comparisiom # -------------------------------------------------------------------------------------------- # -------------------------------------------------------------------------------------------- # print '================ Testing Loop starts ===========================================' # print 'deltatime = ',deltatime # print 'Secs Time = ', get_time_secs(str(deltatime).replace("-","/")) # print 'st = ',str(datetime.strptime(str(st), "%Y/%m/%d %H:%M:%S")) # print 'st in Secs Time = ',get_time_secs(str(datetime.strptime(str(st), "%Y/%m/%d %H:%M:%S")).replace('-','/')) # print '================ Testing Loop Ends ===========================================' # The following if statement has ben included on the basis of dpoch seconds # if get_time_secs(str(deltatime).replace("-","/")) >= \ get_time_secs(str(datetime.strptime(str(st), "%Y/%m/%d %H:%M:%S")).replace('-','/')): return() print 'Delta Time = ',deltatime print 'date time = ',datetime.strptime(str(st), "%Y/%m/%d %H:%M:%S") print '---------------------------' # if deltatime >= datetime.strptime(str(st), "%Y/%m/%d %H:%M:%S"): # return() while deltatime < datetime.strptime(str(st), "%Y/%m/%d %H:%M:%S"): sat.compute(deltatime) geotrack.append({'lat2': sat.sublat.real*(180/math.pi), \ 'lon2': sat.sublong.real*(180/math.pi), \ 'alt2': orb.get_lonlatalt(datetime.strptime(str(rt), "%Y/%m/%d %H:%M:%S"))[2]*1000}) eastaz = getEffectiveHeading(sat,oi,sat.sublat.real*(180/math.pi), sat.sublong.real*(180/math.pi), orad, sat._n)+90 westaz = getEffectiveHeading(sat,oi,sat.sublat.real*(180/math.pi), sat.sublong.real*(180/math.pi), orad, sat._n)+270 #Set ground swath per satellite sensor #TODO use view angle check to refine step from satellite track see IFOV swath = float(satellite_swath)/2. geoeastpoint.append(Geodesic.WGS84.Direct(sat.sublat.real*180/math.pi, sat.sublong.real*180/math.pi, eastaz, swath)) geowestpoint.append(Geodesic.WGS84.Direct(sat.sublat.real*180/math.pi, sat.sublong.real*180/math.pi, westaz, swath)) deltatime = deltatime+delta # Create current location ogr output nowpoint = [{'lat2':orb.get_lonlatalt(datetime.utcnow())[1],'lon2':orb.get_lonlatalt(datetime.utcnow())[0],'alt2':orb.get_lonlatalt(datetime.utcnow())[2]*1000}] #TODO ensure the now attributes are actually attributes for the current position of the satellite and include relevant next pass information...tricky? #if ((attributes['Orbit']==orb.get_orbit_number(datetime.utcnow()))and(AOStime<now)): now_attributes = {'Satellite name': satname, 'Orbit height': orb.get_lonlatalt(datetime.utcnow())[2], 'Orbit': orb.get_orbit_number(datetime.utcnow()), \ 'Current time': str(now),'Minutes to horizon': "N/A", 'AOS time': "N/A", \ 'LOS time': "N/A", 'Transit time': "N/A", 'Node': "N/A"} #now_attributes=attributes #CURRENT_POSITION_FILENAME = satname+"_current_position.kml" CURRENT_POSITION_FILENAME = OUTPUT_DIR+satname+"_current_position.kml" #TODO draw the current orbit forward for the passes period time from the satellite position as a long stepped ogr line getVectorFile(now_attributes,nowpoint,'point', CURRENT_POSITION_FILENAME, 'KML') polypoints = [] for x in geowestpoint: polypoints.append({'lat2':x['lat2'],'lon2':x['lon2']}) for x in reversed(geoeastpoint): polypoints.append({'lat2':x['lat2'],'lon2':x['lon2']}) if len(polypoints)>0: polypoints.append({'lat2':geowestpoint[0]['lat2'],'lon2':geowestpoint[0]['lon2']}) # Create swath footprint ogr output SWATH_FILENAME = os.path.join(output_path,satname+"."+str(orb.get_orbit_number(datetime.strptime(str(rt),"%Y/%m/%d %H:%M:%S")))+".ALICE.orbit_swath.kml") ORBIT_FILENAME = os.path.join(output_path,satname+"."+str(orb.get_orbit_number(datetime.strptime(str(rt),"%Y/%m/%d %H:%M:%S")))+".ALICE.orbit_track.kml") TRACKING_SWATH_FILENAME = os.path.join(output_path,satname+"_tracking_now.kml") # Create currently acquiring polygon #TODO def this # Step from AOS to current time second intervals observer.date=datetime.utcnow() sat.compute(observer) # tkdelta = timedelta(seconds=100) tkdelta = timedelta(seconds=DELTA_TIME_STEP) tkrt, tkra, tktt, tkta, tkst, tksa = observer.next_pass(sat) tkdeltatime = datetime.utcnow() tkgeoeastpoint = [] tkgeowestpoint = [] tkgeotrack = [] while tkdeltatime < (datetime.utcnow() or datetime.strptime(str(tkst),"%Y/%m/%d %H:%M:%S")): sat.compute(tkdeltatime) tkgeotrack.append({'lat2':sat.sublat.real*(180/math.pi),'lon2':sat.sublong.real*(180/math.pi),'alt2':orb.get_lonlatalt(datetime.strptime(str(rt),"%Y/%m/%d %H:%M:%S"))[2]}) tkeastaz = getEffectiveHeading(sat,oi,sat.sublat.real*(180/math.pi), sat.sublong.real*(180/math.pi),orad,sat._n)+90 tkwestaz = getEffectiveHeading(sat,oi,sat.sublat.real*(180/math.pi), sat.sublong.real*(180/math.pi),orad,sat._n)+270 #TODO use view angle check to refine step from satellite track see IFOV tkswath = float(satellite_swath)/2. tkgeoeastpoint.append(Geodesic.WGS84.Direct(sat.sublat.real*180/math.pi, sat.sublong.real*180/math.pi, tkeastaz, tkswath)) tkgeowestpoint.append(Geodesic.WGS84.Direct(sat.sublat.real*180/math.pi, sat.sublong.real*180/math.pi, tkwestaz, tkswath)) tkdeltatime = tkdeltatime+tkdelta tkpolypoints = [] for x in tkgeowestpoint: tkpolypoints.append({'lat2':x['lat2'],'lon2':x['lon2']}) for x in reversed(tkgeoeastpoint): tkpolypoints.append({'lat2':x['lat2'],'lon2':x['lon2']}) if len(tkpolypoints)>0: tkpolypoints.append({'lat2':tkgeowestpoint[0]['lat2'],'lon2':tkgeowestpoint[0]['lon2']}) if not ((attributes['Node']=="ascending")and(satname not in ("AQUA"))): # Create swath ogr output getVectorFile(attributes,polypoints,'polygon', SWATH_FILENAME, 'KML') # Create orbit track ogr output getVectorFile(attributes,geotrack,'line', ORBIT_FILENAME, 'KML') # Create currently acquiring ogr output if ((now >= datetime.strptime(str(tkrt),"%Y/%m/%d %H:%M:%S")) and (now <= datetime.strptime(str(tkst),"%Y/%m/%d %H:%M:%S"))): getVectorFile(now_attributes,tkpolypoints,'polygon', TRACKING_SWATH_FILENAME, 'KML') if minutesaway <= period: # print tle[0], 'WILL BE MAKING A PASS IN ', minutesaway, " MINUTES" # print ' Rise Azimuth: ', ra # print ' Transit Time: ', tt # print ' Transit Altitude: ', ta # print ' Set Time: ', st # print ' Set Azimuth: ', sa # print '=================================================' # print 'Satellite Name = ',satellite_name for x in sorted(SCHEDULE, key=lambda k: k['AOS time']): # print x output_orbit_parameters(x) # For dictionary entries with 'LOS time' older than now time - remove if ((datetime.strptime(str(x['LOS time']),"%Y/%m/%d %H:%M:%S"))<(datetime.utcnow())): # Delete output ogr if os.path.exists(os.path.join(output_path,satname+"."+str(x['Orbit'])+".ALICE.orbit_swath.kml")): os.remove(os.path.join(output_path,satname+"."+str(x['Orbit'])+".ALICE.orbit_swath.kml")) if os.path.exists(os.path.join(output_path,satname+"."+str(x['Orbit'])+".ALICE.orbit_track.kml")): os.remove(os.path.join(output_path,satname+"."+str(x['Orbit'])+".ALICE.orbit_track.kml")) # Delete dictionary entry for pass SCHEDULE.remove(x) # Unlikely - if no entries in the SCHEDULE don't try to print it if len(SCHEDULE)>0: print (datetime.strptime(str(SCHEDULE[0]['AOS time']),"%Y/%m/%d %H:%M:%S")) # If the AOS time is less than now + the time delta, shift the time to the latest recorded pass LOS time if ((datetime.strptime(str(SCHEDULE[len(SCHEDULE)-1]['AOS time']),"%Y/%m/%d %H:%M:%S")<(datetime.utcnow()+timedelta(minutes=period)))): observer.date = (datetime.strptime(str(SCHEDULE[len(SCHEDULE)-1]['LOS time']),"%Y/%m/%d %H:%M:%S")+timedelta(minutes=5)) # Recompute the satellite position for the update time sat.compute(observer) # print "MODIFIED OBSERVER DATE",observer.date else: # print "--------NOTHING TO MODIFY MOVING TO NEXT SATELLITE IN LIST------" #TODO - write to html # Exit the def if the SCHEDULE isn't able to update because there are no passes in the acquisition window return () # print 'Before Time Sleep ......' # print 'Loop for While .........' print '=============================================================================' time.sleep(1*SLEEP_STATUS) return ()
class FileStreamer(FileSystemEventHandler): """Get the updates from files. TODO: separate holder from file handling. """ def __init__(self, holder, configfile, *args, **kwargs): FileSystemEventHandler.__init__(self, *args, **kwargs) self._file = None self._filename = "" self._where = 0 self._satellite = "" self._orbital = None cfg = ConfigParser() cfg.read(configfile) self._coords = cfg.get("local_reception", "coordinates").split(" ") self._coords = [float(self._coords[0]), float(self._coords[1]), float(self._coords[2])] self._station = cfg.get("local_reception", "station") logger.debug("Station " + self._station + " located at: " + str(self._coords)) try: self._tle_files = cfg.get("local_reception", "tle_files") except NoOptionError: self._tle_files = None self._file_pattern = cfg.get("local_reception", "file_pattern") self.scanlines = holder self._warn = True def update_satellite(self, satellite): """Update satellite and renew the orbital instance. """ if satellite != self._satellite: self._satellite = satellite if self._tle_files is not None: filelist = glob(self._tle_files) tle_file = max(filelist, key=lambda x: os.stat(x).st_mtime) else: tle_file = None self._orbital = Orbital(self._satellite.upper(), tle_file) def on_created(self, event): """Callback when file is created. """ if event.src_path != self._filename: if self._filename: logger.info("Closing: " + self._filename) if self._file: self._file.close() self._file = None self._filename = "" self._where = 0 self._satellite = "" self._warn = True logger.info("New file detected: " + event.src_path) def on_opened(self, event): """Callback when file is opened """ fname = os.path.split(event.src_path)[1] if self._file is None and fnmatch(fname, self._file_pattern): logger.info("File opened: " + event.src_path) self._filename = event.src_path self._file = open(event.src_path, "rb") self._where = 0 self._satellite = "" self._orbital = None self._warn = True def on_modified(self, event): self.on_opened(event) if event.src_path != self._filename: return self._file.seek(self._where) line = self._file.read(LINE_SIZE) while len(line) == LINE_SIZE: line_start = self._where self._where = self._file.tell() dtype = np.dtype([('frame_sync', '>u2', (6, )), ('id', [('id', '>u2'), ('spare', '>u2')]), ('timecode', '>u2', (4, )), ('telemetry', [("ramp_calibration", '>u2', (5, )), ("PRT", '>u2', (3, )), ("ch3_patch_temp", '>u2'), ("spare", '>u2'),]), ('back_scan', '>u2', (10, 3)), ('space_data', '>u2', (10, 5)), ('sync', '>u2'), ('TIP_data', '>u2', (520, )), ('spare', '>u2', (127, )), ('image_data', '>u2', (2048, 5)), ('aux_sync', '>u2', (100, ))]) array = np.fromstring(line, dtype=dtype) if np.all(abs(HRPT_SYNC_START - array["frame_sync"]) > 1): array = array.newbyteorder() # FIXME: this means server can only share 1 year of hrpt data. now = datetime.utcnow() year = now.year utctime = datetime(year, 1, 1) + timecode(array["timecode"][0]) if utctime > now: # Can't have data from the future... yet :) utctime = (datetime(year - 1, 1, 1) + timecode(array["timecode"][0])) # Check that we receive real-time data if not (np.all(array['aux_sync'] == HRPT_SYNC) and np.all(array['frame_sync'] == HRPT_SYNC_START)): logger.info("Garbage line: " + str(utctime)) line = self._file.read(LINE_SIZE) continue if (now - utctime).days > 7 and self._warn: logger.warning("Data is more than a week old: " + str(utctime)) self._warn = False satellite = SATELLITES[((array["id"]["id"] >> 3) & 15)[0]] self.update_satellite(satellite) elevation = self._orbital.get_observer_look(utctime, *self._coords)[1] logger.debug("Got line " + utctime.isoformat() + " " + self._satellite + " " + str(elevation)) # TODO: # - serve also already present files # - timeout and close the file self.scanlines.add_scanline(self._satellite, utctime, elevation, line_start, self._filename, line) line = self._file.read(LINE_SIZE) self._file.seek(self._where)
while True: lat2 = lat c = 1/(np.sqrt(1 - e2 * (np.sin(lat2) ** 2))) lat = np.arctan2(pos_z + c * e2 *np.sin(lat2), r) if np.all(abs(lat - lat2) < 1e-10): break alt = r / np.cos(lat)- c; alt *= A return np.rad2deg(lon), np.rad2deg(lat), alt ### END OF DIRTY STUFF def compute_pixels((tle1, tle2), sgeom, start_of_scan): """Compute cartesian coordinates of the pixels in instrument scan. """ orb = Orbital("mysatellite", line1=tle1, line2=tle2) # times for each pixel times = sgeom.times(start_of_scan) # get position and velocity for each time of each pixel pos, vel = orb.get_position(times, normalize=False) # now, get the vectors pointing to each pixel vectors = sgeom.vectors(pos, vel) ## compute intersection of lines (directed by vectors and passing through ## (0, 0, 0)) and sphere ## http://en.wikipedia.org/wiki/Line%E2%80%93sphere_intersection # get the radius of the earth at the given times
lat2 = lat c = 1 / (np.sqrt(1 - e2 * (np.sin(lat2) ** 2))) lat = np.arctan2(pos_z + c * e2 * np.sin(lat2), r) if np.all(abs(lat - lat2) < 1e-10): break alt = r / np.cos(lat) - c alt *= A return np.rad2deg(lon), np.rad2deg(lat), alt # END OF DIRTY STUFF def compute_pixels((tle1, tle2), sgeom, times, rpy=(0.0, 0.0, 0.0)): """Compute cartesian coordinates of the pixels in instrument scan. """ orb = Orbital("mysatellite", line1=tle1, line2=tle2) # get position and velocity for each time of each pixel pos, vel = orb.get_position(times, normalize=False) # now, get the vectors pointing to each pixel vectors = sgeom.vectors(pos, vel, *rpy) # compute intersection of lines (directed by vectors and passing through # (0, 0, 0)) and ellipsoid. Derived from: # http://en.wikipedia.org/wiki/Line%E2%80%93sphere_intersection # do the computation between line and ellipsoid (WGS 84) # NB: AAPP uses GRS 80... centre = -pos a__ = 6378.137 # km
def replace_orbitno(filename): stamp = get_npp_stamp(filename) # Correct h5 attributes no_date = datetime(1958, 1, 1) epsilon_time = timedelta(days=2) import h5py def _get_a_good_time(name, obj): del name if isinstance(obj, h5py.Dataset): date_key, time_key = ('Ending_Date', 'Ending_Time') if date_key in obj.attrs.keys(): if not good_time_val_[0]: time_val = datetime.strptime( obj.attrs[date_key][0][0] + obj.attrs[time_key][0][0], '%Y%m%d%H%M%S.%fZ') if abs(time_val - no_date) > epsilon_time: good_time_val_[0] = time_val def _check_orbitno(name, obj): del name if isinstance(obj, h5py.Dataset): for date_key, time_key, orbit_key in ( ('AggregateBeginningDate', 'AggregateBeginningTime', 'AggregateBeginningOrbitNumber'), ('AggregateEndingDate', 'AggregateEndingTime', 'AggregateEndingOrbitNumber'), ('Beginning_Date', 'Beginning_Time', 'N_Beginning_Orbit_Number')): if orbit_key in obj.attrs.keys(): time_val = datetime.strptime( obj.attrs[date_key][0][0] + obj.attrs[time_key][0][0], '%Y%m%d%H%M%S.%fZ') # Check for no date (1958) problem: if abs(time_val - no_date) < epsilon_time: LOG.info("Start time wrong: %s", time_val.strftime('%Y%m%d')) LOG.info("Will use the first good end time encounter " + "in file to determine orbit number") time_val = good_time_val_[0] orbit_val = orbital_.get_orbit_number(time_val, tbus_style=TBUS_STYLE) obj.attrs.modify(orbit_key, [[orbit_val]]) counter_[0] += 1 # Correct h5 attributes orbital_ = Orbital(TLE_SATNAME[stamp.platform]) orbit = orbital_.get_orbit_number(stamp.start_time, tbus_style=TBUS_STYLE) LOG.info("Replacing orbit number %05d with %05d", stamp.orbit_number, orbit) fp = h5py.File(filename, 'r+') try: good_time_val_ = [None] fp.visititems(_get_a_good_time) counter_ = [0] fp.visititems(_check_orbitno) if counter_[0] == 0: raise IOError( "Failed replacing orbit number in hdf5 attributes '%s'" % filename) LOG.info("Replaced orbit number in %d attributes", counter_[0]) finally: fp.close() # Correct filename dname, fname = os.path.split(filename) fname, n = _re_replace_orbitno.subn('_b%05d' % orbit, fname) if n != 1: raise IOError("Failed replacing orbit number in filename '%s'" % fname) return os.path.join(dname, fname), orbit
class FileStreamer(FileSystemEventHandler): """Get the updates from files. TODO: separate holder from file handling. """ def __init__(self, holder, configfile, *args, **kwargs): FileSystemEventHandler.__init__(self, *args, **kwargs) self._file = None self._filename = "" self._where = 0 self._satellite = "" self._orbital = None cfg = ConfigParser() cfg.read(configfile) self._coords = cfg.get("local_reception", "coordinates").split(" ") self._coords = [float(self._coords[0]), float(self._coords[1]), float(self._coords[2])] logger.debug(self._coords) try: self._tle_files = cfg.get("local_reception", "tle_files") except NoOptionError: self._tle_files = None self._file_pattern = cfg.get("local_reception", "file_pattern") self.scanlines = holder def on_created(self, event): if event.src_path != self._filename: logger.debug("Closing: " + self._filename) if self._file: self._file.close() self._file = None self._filename = "" self._where = 0 self._satellite = "" logger.debug("Creating: " + event.src_path) def on_opened(self, event): fname = os.path.split(event.src_path)[1] if self._file is None and fnmatch(fname, self._file_pattern): logger.debug("Opening: " + event.src_path) self._filename = event.src_path self._file = open(event.src_path, "rb") self._where = 0 self._satellite = " ".join(event.src_path.split("_")[1:3])[:-5] if self._tle_files is not None: filelist = glob(self._tle_files) tle_file = max(filelist, key=lambda x: os.stat(x).st_mtime) else: tle_file = None self._orbital = Orbital(self._satellite, tle_file) def on_modified(self, event): self.on_opened(event) if event.src_path != self._filename: return self._file.seek(self._where) line = self._file.read(LINE_SIZE) while len(line) == LINE_SIZE: line_start = self._where self._where = self._file.tell() dtype = np.dtype([('frame_sync', '>u2', (6, )), ('id', [('id', '>u2'), ('spare', '>u2')]), ('timecode', '>u2', (4, )), ('telemetry', [("ramp_calibration", '>u2', (5, )), ("PRT", '>u2', (3, )), ("ch3_patch_temp", '>u2'), ("spare", '>u2'),]), ('back_scan', '>u2', (10, 3)), ('space_data', '>u2', (10, 5)), ('sync', '>u2'), ('TIP_data', '>u2', (520, )), ('spare', '>u2', (127, )), ('image_data', '>u2', (2048, 5)), ('aux_sync', '>u2', (100, ))]) array = np.fromstring(line, dtype=dtype) if np.all(abs(HRPT_SYNC_START - array["frame_sync"]) > 1): array = array.newbyteorder() # FIXME: this is bad!!!! Should not get the year from the filename year = int(os.path.split(event.src_path)[1][:4]) utctime = datetime(year, 1, 1) + timecode(array["timecode"][0]) # Check that we receive real-time data if not (np.all(array['aux_sync'] == HRPT_SYNC) and np.all(array['frame_sync'] == HRPT_SYNC_START)): logger.info("Garbage line: " + str(utctime)) line = self._file.read(LINE_SIZE) continue elevation = self._orbital.get_observer_look(utctime, *self._coords)[1] logger.info("Got line " + utctime.isoformat() + " " + self._satellite + " " + str(elevation)) # TODO: # - serve also already present files # - timeout and close the file self.scanlines.add_scanline(self._satellite, utctime, elevation, line_start, self._filename, line) line = self._file.read(LINE_SIZE) self._file.seek(self._where)
def getUpcomingPasses(satellite_name, tle_information, passes_begin_time, passes_period): observer = ephem.Observer() observer.lat = ground_station[0] observer.long = ground_station[1] #updatetime = 0 period = passes_period #Get most recent TLE for determining upcoming passes from now tles = tle_information # make a list of dicts to hold the upcoming pass information for the selected satellites schedule = [] observer.date = passes_begin_time while 1: print "---------------------------------------" for tle in tles: if tle[0] == satellite_name: #TODO clean up the use of pyephem versus orbital. Orbital can give a orbit number and does many of the pyephem functions #TODO add the individual acquisitions as layers in the same ogr output #TODO use an appropriate google earth icon for satellites at a visible display resolution with a name tag and minutesaway #TODO print output to logging satname = str(tle[0]).replace(" ","_") sat = ephem.readtle(tle[0],tle[1],tle[2]) twole = tlefile.read(tle[0],'tles.txt') now = datetime.utcnow() #TODO check age of TLE - if older than x days get_tle() print "TLE EPOCH:",twole.epoch #if twole.epoch < now - timedelta(days=5): # get_tles() # satname = str(tle[0]).replace(" ","_") # sat = ephem.readtle(tle[0],tle[1],tle[2]) # twole = tlefile.read(tle[0],'tles.txt') print "---------------------------------------" print tle[0] oi = float(str.split(tle[2],' ')[3]) orb = Orbital(tle[0]) attributes = [] rt, ra, tt, ta, st, sa = observer.next_pass(sat) # Determine is pass descending or ascending sat.compute(rt) aos_lat = sat.sublat.real*(180/math.pi) sat.compute(st) los_lat = sat.sublat.real*(180/math.pi) if (aos_lat > los_lat): print "PASS = descending" node = "descending" else: print "PASS = ascending" node = "ascending" oi = 360 - oi AOStime = datetime.strptime(str(rt), "%Y/%m/%d %H:%M:%S") minutesaway = (AOStime-now).seconds/60.0 print "Minutes to horizon = ", minutesaway print "AOStime = ", rt print "LOStime = ", st print "Transit time = ", tt orad = orb.get_lonlatalt(datetime.strptime(str(rt), "%Y/%m/%d %H:%M:%S"))[2] attributes = {'Satellite name': satname, 'Orbit height': orad, 'Orbit': orb.get_orbit_number(datetime.strptime(str(rt), "%Y/%m/%d %H:%M:%S")), \ 'Current time': str(now),'Minutes to horizon': minutesaway, 'AOS time': str(rt), \ 'LOS time': str(st), 'Transit time': str(tt), 'Node': node} # Append the attributes to the list of acquisitions for the acquisition period if not any ((x['Satellite name'] == satname and x['Orbit'] == orb.get_orbit_number(datetime.strptime(str(rt), "%Y/%m/%d %H:%M:%S")))for x in schedule): schedule.append(attributes) # Step from AOS to LOS in 100 second intervals delta = timedelta(seconds=100) deltatime = datetime.strptime(str(rt), "%Y/%m/%d %H:%M:%S") geoeastpoint = [] geowestpoint = [] geotrack = [] print "DELTATIME", deltatime print "SETTING TIME", datetime.strptime(str(st), "%Y/%m/%d %H:%M:%S") while deltatime < datetime.strptime(str(st), "%Y/%m/%d %H:%M:%S"): sat.compute(deltatime) geotrack.append({'lat2': sat.sublat.real*(180/math.pi), \ 'lon2': sat.sublong.real*(180/math.pi), \ 'alt2': orb.get_lonlatalt(datetime.strptime(str(rt), "%Y/%m/%d %H:%M:%S"))[2]*1000}) eastaz = getEffectiveHeading(sat,oi,sat.sublat.real*(180/math.pi), sat.sublong.real*(180/math.pi), orad, sat._n)+90 westaz = getEffectiveHeading(sat,oi,sat.sublat.real*(180/math.pi), sat.sublong.real*(180/math.pi), orad, sat._n)+270 #Set ground swath per satellite sensor #TODO use view angle check to refine step from satellite track see IFOV if tle[0] in ("LANDSAT 8","LANDSAT 7"): swath = 185000/2 if tle[0] in ("TERRA","AQUA"): swath = 2330000/2 if tle[0] in ("NOAA 15", "NOAA 18", "NOAA 19"): swath = 1100000/2 if tle[0] == "SUOMI NPP": swath = 2200000/2 geoeastpoint.append(Geodesic.WGS84.Direct(sat.sublat.real*180/math.pi, sat.sublong.real*180/math.pi, eastaz, swath)) geowestpoint.append(Geodesic.WGS84.Direct(sat.sublat.real*180/math.pi, sat.sublong.real*180/math.pi, westaz, swath)) deltatime = deltatime+delta # Create current location ogr output nowpoint = [{'lat2':orb.get_lonlatalt(datetime.utcnow())[1],'lon2':orb.get_lonlatalt(datetime.utcnow())[0],'alt2':orb.get_lonlatalt(datetime.utcnow())[2]*1000}] #TODO ensure the now attributes are actually attributes for the current position of the satellite and include relevant next pass information...tricky? #if ((attributes['Orbit']==orb.get_orbit_number(datetime.utcnow()))and(AOStime<now)): now_attributes = {'Satellite name': satname, 'Orbit height': orb.get_lonlatalt(datetime.utcnow())[2], 'Orbit': orb.get_orbit_number(datetime.utcnow()), \ 'Current time': str(now),'Minutes to horizon': "N/A", 'AOS time': "N/A", \ 'LOS time': "N/A", 'Transit time': "N/A", 'Node': "N/A"} #now_attributes=attributes CURRENT_POSITION_FILENAME = satname+"_current_position.kml" #TODO draw the current orbit forward for the passes period time from the satellite position as a long stepped ogr line getVectorFile(now_attributes,nowpoint,'point', CURRENT_POSITION_FILENAME, 'KML') polypoints = [] for x in geowestpoint: polypoints.append({'lat2':x['lat2'],'lon2':x['lon2']}) for x in reversed(geoeastpoint): polypoints.append({'lat2':x['lat2'],'lon2':x['lon2']}) if len(polypoints)>0: polypoints.append({'lat2':geowestpoint[0]['lat2'],'lon2':geowestpoint[0]['lon2']}) # Create swath footprint ogr output SWATH_FILENAME = os.path.join(output_path,satname+"."+str(orb.get_orbit_number(datetime.strptime(str(rt),"%Y/%m/%d %H:%M:%S")))+".ALICE.orbit_swath.kml") ORBIT_FILENAME = os.path.join(output_path,satname+"."+str(orb.get_orbit_number(datetime.strptime(str(rt),"%Y/%m/%d %H:%M:%S")))+".ALICE.orbit_track.kml") TRACKING_SWATH_FILENAME = os.path.join(output_path,satname+"_tracking_now.kml") # Create currently acquiring polygon #TODO def this # Step from AOS to current time second intervals observer.date=datetime.utcnow() sat.compute(observer) tkdelta = timedelta(seconds=100) tkrt, tkra, tktt, tkta, tkst, tksa = observer.next_pass(sat) tkdeltatime = datetime.utcnow() tkgeoeastpoint = [] tkgeowestpoint = [] tkgeotrack = [] while tkdeltatime < (datetime.utcnow() or datetime.strptime(str(tkst),"%Y/%m/%d %H:%M:%S")): sat.compute(tkdeltatime) tkgeotrack.append({'lat2':sat.sublat.real*(180/math.pi),'lon2':sat.sublong.real*(180/math.pi),'alt2':orb.get_lonlatalt(datetime.strptime(str(rt),"%Y/%m/%d %H:%M:%S"))[2]}) tkeastaz = getEffectiveHeading(sat,oi,sat.sublat.real*(180/math.pi), sat.sublong.real*(180/math.pi),orad,sat._n)+90 tkwestaz = getEffectiveHeading(sat,oi,sat.sublat.real*(180/math.pi), sat.sublong.real*(180/math.pi),orad,sat._n)+270 #TODO use view angle check to refine step from satellite track see IFOV if tle[0] in ("LANDSAT 8","LANDSAT 7"): tkswath = 185000/2 if tle[0] in ("TERRA","AQUA"): tkswath = 2330000/2 if tle[0] in ("NOAA 15", "NOAA 18", "NOAA 19"): tkswath = 1100000/2 if tle[0] == "SUOMI NPP": tkswath = 2200000/2 tkgeoeastpoint.append(Geodesic.WGS84.Direct(sat.sublat.real*180/math.pi, sat.sublong.real*180/math.pi, tkeastaz, tkswath)) tkgeowestpoint.append(Geodesic.WGS84.Direct(sat.sublat.real*180/math.pi, sat.sublong.real*180/math.pi, tkwestaz, tkswath)) tkdeltatime = tkdeltatime+tkdelta tkpolypoints = [] for x in tkgeowestpoint: tkpolypoints.append({'lat2':x['lat2'],'lon2':x['lon2']}) for x in reversed(tkgeoeastpoint): tkpolypoints.append({'lat2':x['lat2'],'lon2':x['lon2']}) if len(tkpolypoints)>0: tkpolypoints.append({'lat2':tkgeowestpoint[0]['lat2'],'lon2':tkgeowestpoint[0]['lon2']}) if not ((attributes['Node']=="ascending")and(satname not in ("AQUA"))): # Create swath ogr output getVectorFile(attributes,polypoints,'polygon', SWATH_FILENAME, 'KML') # Create orbit track ogr output getVectorFile(attributes,geotrack,'line', ORBIT_FILENAME, 'KML') # Create currently acquiring ogr output if ((now >= datetime.strptime(str(tkrt),"%Y/%m/%d %H:%M:%S")) and (now <= datetime.strptime(str(tkst),"%Y/%m/%d %H:%M:%S"))): getVectorFile(now_attributes,tkpolypoints,'polygon', TRACKING_SWATH_FILENAME, 'KML') if minutesaway <= period: print "---------------------------------------" print tle[0], 'WILL BE MAKING A PASS IN ', minutesaway, " MINUTES" print ' Rise Azimuth: ', ra print ' Transit Time: ', tt print ' Transit Altitude: ', ta print ' Set Time: ', st print ' Set Azimuth: ', sa for x in sorted(schedule, key=lambda k: k['AOS time']): print x # For dictionary entries with 'LOS time' older than now time - remove if ((datetime.strptime(str(x['LOS time']),"%Y/%m/%d %H:%M:%S"))<(datetime.utcnow())): # Delete output ogr if os.path.exists(os.path.join(output_path,satname+"."+str(x['Orbit'])+".ALICE.orbit_swath.kml")): os.remove(os.path.join(output_path,satname+"."+str(x['Orbit'])+".ALICE.orbit_swath.kml")) if os.path.exists(os.path.join(output_path,satname+"."+str(x['Orbit'])+".ALICE.orbit_track.kml")): os.remove(os.path.join(output_path,satname+"."+str(x['Orbit'])+".ALICE.orbit_track.kml")) # Delete dictionary entry for pass schedule.remove(x) # Unlikely - if no entries in the schedule don't try to print it if len(schedule)>0: print (datetime.strptime(str(schedule[0]['AOS time']),"%Y/%m/%d %H:%M:%S")) # If the AOS time is less than now + the time delta, shift the time to the latest recorded pass LOS time if ((datetime.strptime(str(schedule[len(schedule)-1]['AOS time']),"%Y/%m/%d %H:%M:%S")<(datetime.utcnow()+timedelta(minutes=period)))): observer.date = (datetime.strptime(str(schedule[len(schedule)-1]['LOS time']),"%Y/%m/%d %H:%M:%S")+timedelta(minutes=5)) # Recompute the satellite position for the update time sat.compute(observer) print "MODIFIED OBSERVER DATE",observer.date else: print "--------NOTHING TO MODIFY MOVING TO NEXT SATELLITE IN LIST------" #TODO - write to html # Exit the def if the schedule isn't able to update because there are no passes in the acquisition window return () time.sleep(1*sleep_status) return ()
def set_tle(self, line1, line2): # for now restart pyorbital with these new elements. del self.orbital self.orbital = Orbital(self.sat,line1=line1, line2=line2)
class PyOrbitalLayer(OrbitalLayer): """ pyorbital based orbital layer """ __implements__ = (OrbitalLayer,) def __init__(self, aoi, sat, instrument="AVHRR"): OrbitalLayer.__init__(self,aoi,sat,instrument) # instantiate orbital module config_file_path = "" try: config_file_path = os.environ['PYGRANULE_CONFIG_PATH'] except KeyError: print "pygranule config file path missing. Has the 'PYGRANULE_CONFIG_PATH' environment variable been set?" default_tle_file = config_file_path+"/default.tle" try: self.orbital = Orbital(sat,default_tle_file) except: print "Failed to open default tle file:", default_tle_file print "Downloading from internet:" try: self.orbital = Orbital(sat) except: raise OrbitalLayerError("Pyorbital Failed to fetch TLE from internet.") # create scan geometry - one scan line. if instrument == "AVHRR": scan_steps = np.arange(0,self.instrument_info['scan_steps'],self.instrument_info['scan_steps']/8-1) scan_steps[-1] = self.instrument_info['scan_steps']-1 self.scan_geom = avhrr(1,scan_steps) elif instrument == "VIIRS": self.scan_geom = viirs(1) def set_tle(self, line1, line2): # for now restart pyorbital with these new elements. del self.orbital self.orbital = Orbital(self.sat,line1=line1, line2=line2) def orbital_period(self): return 24*60/self.orbital.tle.mean_motion def scan_line_lonlats(self, t): """ Returns a single instrument scan line starting at datetime t """ s_times = self.scan_geom.times(t) pixels_pos = compute_pixels((self.orbital.tle.line1, self.orbital.tle.line2), self.scan_geom, s_times) pos_time = get_lonlatalt(pixels_pos, s_times) return np.array((pos_time[0],pos_time[1])) def next_transit(self, start=datetime.now(), resolution=100): """ Next transit time relative to center of aoi. Resolution accuracy defined by subdivision of orbital period. """ # accuracy in mintues from mean orbital period dt = self.orbital_period()/resolution # observer position alt = 0.0 lon, lat = self.aoi_center() # NOTE: For now I do not use the pyorbital # get_next_passes. Because it accepts integer (not float) hours # for the search period, and the accuracy of the transit time # search is not obvious to me at the moment. # Also I would like to allow negative transit time altitudes # - transits below horizon. # Therefore I re-implement the search myself, here to have more control: t_offsets = np.arange(0.0,self.orbital_period()*1.2,dt) e = np.array( [ self.orbital.get_observer_look(start + timedelta(minutes=t_offset), lon, lat, alt)[1] \ for t_offset in t_offsets ] ) # search for local maxima b = (np.roll(e,1)<e)&(np.roll(e,-1)<e) idx = np.where(b[1:]==True)[0][0]+1 #i.e. do not accept index 0 as maximum... ## return a quadratic maximum for good accuracy based on data. ## Quadratic fit to 3 points around maximum elevation ## seems to improve accuracy by 100-fold. x,y = t_offsets[idx-1:idx+2],e[idx-1:idx+2] fit = np.polyfit(x,y,2) t = -fit[1]/(2.0*fit[0]) #from matplotlib import pyplot as plt #plt.plot(x,y,'x') #fitx = np.arange(x[0]-1,x[2]+1,0.1) #fity = fit[2]+fit[1]*fitx+fit[0]*(fitx**2) #plt.plot(fitx,fity,'r-') #plt.show() return start + timedelta(minutes=t)