Beispiel #1
0
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
Beispiel #2
0
    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
Beispiel #3
0
class Satellite:
    """ Retrieve orbital parameters of the selected LEO object """
    def __init__(self, name):
        urllib.request.urlretrieve(
            'http://celestrak.com/NORAD/elements/stations.txt', 'stations.txt')
        self.orb = Orbital(name, 'stations.txt')
        self.data = []

    def azimuth(self):
        """ Return object azimuth """
        self.__update_data()
        return self.data[0]

    def elevation(self):
        """ Return object elevation """
        self.__update_data()
        return self.data[1]

    def __update_data(self):
        self.data = self.orb.get_observer_look(datetime.utcnow(), 25.279652,
                                               54.687157, 1)

    def is_up(self):
        """ Return object elevation """
        self.__update_data()
        return True if self.data[1] > 10 else False
Beispiel #4
0
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
Beispiel #5
0
 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
Beispiel #6
0
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
Beispiel #7
0
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
Beispiel #8
0
    def get_angles(self):
        """Get azimuth and zenith angles.

        Azimuth angle definition is the same as in pyorbital, but with
        different units (degrees not radians for sun azimuth angles)
        and different ranges.

        Returns:
            sat_azi: satellite azimuth angle
                degree clockwise from north in range ]-180, 180],
            sat_zentih: satellite zenith angles in degrees in range [0,90],
            sun_azi: sun azimuth angle
                degree clockwise from north in range ]-180, 180],
            sun_zentih: sun zenith angles in degrees in range [0,90],
            rel_azi: absolute azimuth angle difference in degrees between sun
                and sensor in range [0, 180]

        """
        self.get_times()
        self.get_lonlat()
        tle1, tle2 = self.get_tle_lines()
        times = self.times
        orb = Orbital(self.spacecrafts_orbital[self.spacecraft_id],
                      line1=tle1,
                      line2=tle2)

        sat_azi, sat_elev = orb.get_observer_look(times[:, np.newaxis],
                                                  self.lons, self.lats, 0)

        sat_zenith = 90 - sat_elev

        sun_zenith = astronomy.sun_zenith_angle(times[:, np.newaxis],
                                                self.lons, self.lats)

        alt, sun_azi = astronomy.get_alt_az(times[:, np.newaxis], self.lons,
                                            self.lats)
        del alt
        sun_azi = np.rad2deg(sun_azi)
        rel_azi = get_absolute_azimuth_angle_diff(sun_azi, sat_azi)

        # Scale angles range to half open interval ]-180, 180]
        sat_azi = centered_modulus(sat_azi, 360.0)
        sun_azi = centered_modulus(sun_azi, 360.0)

        # Mask corrupt scanlines
        for arr in (sat_azi, sat_zenith, sun_azi, sun_zenith, rel_azi):
            arr[self.mask] = np.nan

        return sat_azi, sat_zenith, sun_azi, sun_zenith, rel_azi
def get_parallaxed_coor(sat, tle, t, lat, lon, alt, h):
    """

    """
    # Setup orbital class with TLE file
    orbit = Orbital(sat, line1=tle.line1, line2=tle.line2)
    pos = orbit.get_position(t)
    # Calculate observer azimuth and elevation
    azi, ele = orbit.get_observer_look(t, lon, lat, alt)
    # Apply parallax correction for given heights
    x, y, z = parallax_corr(h, azi, ele)
    # WGS84 parameters
    f = 1 / 298.257223563
    a = 6378137.
    # Convert coordinates and azimuth to radians
    radlat = np.deg2rad(lat)
    radlon = np.deg2rad(lon)
    radazi = np.deg2rad(azi)
    # Calculate shifted point coordinates
    nlat, nlon, nazi = vinc_pt(f, a, radlat, radlon, radazi, z)
    # Reconvert to degree
    nlat = np.rad2deg(nlat)
    nlon = np.rad2deg(nlon)
    nazi = np.rad2deg(nazi)

    info = "\n--------------------------------------------------------" + \
           "\n      ----- Parallax correction summary -----" +\
           "\n--------------------------------------------------------" + \
           "\n Satellite Name: " + sat + \
           "\n Observation Time: " + \
           datetime.datetime.strftime(t, "%Y-%m-%d %H:%M:%S") + \
           "\n Satellite Position: " + str(pos[0]) + \
           "\n Satellite Velocity: " + str(pos[1]) + \
           "\n-----------------------------------" + \
           "\n Latitude: " + str(lat) + \
           "\n Longitude: " + str(lon) + \
           "\n Altitude: " + \
           str(alt) + "\n Height: " + str(h) + \
           "\n-----------------------------------" +\
           "\n Azimuth: " + str(azi) + \
           "\n Elevation: " + str(ele) + \
           "\n Parallax Distance: " + str(z) + \
           "\n New Latitude: " + str(nlat) + \
           "\n New Longitude: " + str(nlon) + \
           "\n--------------------------------------------------------"
    logger.debug(info)

    return(z, nlat, nlon)
Beispiel #10
0
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 getSentinel2Geometry(startDateUTC, lengthDays, lat, lon, alt=0.0, mission="Sentinel-2a",
                         tleFile="../TLE/norad_resource_tle.txt"):
    """Calculate approximate geometry for Sentinel overpasses.
    Approximate because it assumes maximum satellite elevation
    is the time at which target is imaged.

    :param startDateUTC: a datetime object specifying when to start prediction.
    :type startDateUTC: object
    :param lengthDays: number of days over which to perform calculations.
    :type lengthDays: int
    :param lat: latitude of target.
    :type lat: float
    :param lon: longitude of target.
    :type lon: float
    :param alt: altitude of target (in km).
    :type alt: float
    :param mission: mission name as in TLE file.
    :type mission: str
    :param tleFile: TLE file.
    :type tleFile: str
    :return: a python list containing instances of the sensorGeometry class arranged in date order.
    :rtype: list
    """
    orb = Orbital(mission, tleFile)
    passes = orb.get_next_passes(startDateUTC, 24 * lengthDays, lon, lat, alt)

    geomList = []

    for p in passes:
        look = orb.get_observer_look(p[2], lon, lat, alt)
        vza = 90 - look[1]
        vaa = look[0]
        sza = ast.sun_zenith_angle(p[2], lon, lat)
        saa = np.rad2deg(ast.get_alt_az(p[2], lon, lat)[1])

        if sza < 90 and vza < 10.3:
            thisGeom = sensorGeometry()
            thisGeom.date_utc = p[2]
            thisGeom.vza = vza
            thisGeom.vaa = vaa
            thisGeom.sza = sza
            thisGeom.saa = saa
            geomList.append(thisGeom)

    return geomList
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
Beispiel #13
0
def plot_iss(ax, obs_time, obs_loc, tle=None):
    """
    Put International Space Station on the plot. The function uses TLE list if
    it was given or tries to retrieve it via PyOrbital package
    """

    if tle is None:
        from pyorbital.orbital import Orbital
        print("request ISS' two-line elements via PyOrbital...")
        orb = Orbital("ISS (ZARYA)")
        iss = orb.get_observer_look(obs_time.value, obs_loc.lon.value,
                                    obs_loc.lat.value, obs_loc.height.value)
        iss_coord = SkyCoord(iss[0],
                             iss[1],
                             unit='deg',
                             frame='altaz',
                             obstime=obs_time,
                             location=obs_loc)
    else:
        import ephem
        iss = ephem.readtle('ISS', tle[0], tle[1])
        location = ephem.Observer()
        location.lat = str(obs_loc.lat.value)
        location.lon = str(obs_loc.lon.value)
        location.date = obs_time.value
        iss.compute(location)
        iss_coord = SkyCoord(iss.az,
                             iss.alt,
                             unit='rad',
                             frame='altaz',
                             obstime=obs_time,
                             location=obs_loc)

    iss_coord = iss_coord.transform_to('icrs')

    ax.plot([iss_coord.ra.radian], [-iss_coord.dec.value + 45],
            label='ISS',
            linestyle='',
            color='green',
            marker='$⋈$',
            markersize=markers['iss'])

    print("ISS is plotted")
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)
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    
Beispiel #16
0
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)
Beispiel #17
0
def trackHotspotSatellite(arglist=None):

    parser = ArgumentRecorder(
        description=
        'Track satellite position, bearing, previous and next passdatetimes from hotspot data.',
        fromfile_prefix_chars='@')

    parser.add_argument('-v', '--verbosity', type=int, default=1, private=True)

    parser.add_argument('-u',
                        '--user',
                        type=str,
                        required=True,
                        help="PostgreSQL username")
    parser.add_argument('-d',
                        '--database',
                        type=str,
                        required=True,
                        help="PostgreSQL database")

    parser.add_argument('-l',
                        '--limit',
                        type=int,
                        help='Limit number of rows to process')

    parser.add_argument('-t',
                        '--tlefile',
                        type=str,
                        required=True,
                        help='File containing TLE data')
    parser.add_argument('-w',
                        '--where',
                        type=str,
                        required=True,
                        help="'Where' clause to select hotspots")
    parser.add_argument('-H',
                        '--hotspots',
                        type=str,
                        default='hotspots',
                        help="Hotspot table name")
    parser.add_argument(
        '-s',
        '--suffix',
        type=str,
        required=True,
        help="Suffix to append to 'hotspots' to get output table name")
    parser.add_argument('-D',
                        '--drop-table',
                        action='store_true',
                        help='Drop output table if it exists')

    parser.add_argument('--logfile',
                        type=str,
                        help="Logfile, default is 'hotspots'_'suffix'.log",
                        private=True)
    parser.add_argument('--no-logfile',
                        action='store_true',
                        help='Do not output descriptive comments')

    args = parser.parse_args(arglist)

    if not args.no_logfile:
        if not args.logfile:
            args.logfile = args.hotspots + '_' + args.suffix + '.log'

        if os.path.exists(args.logfile):
            shutil.move(args.logfile,
                        args.logfile.split('/')[-1].rsplit('.', 1)[0] + '.bak')

        logfile = open(args.logfile, 'w')
        parser.write_comments(args,
                              logfile,
                              incomments=ArgumentHelper.separator())
        logfile.close()

    satcodes = {'N': 37849, 'Terra': 25994, 'Aqua': 27424}

    tledict = {}
    for norad_id in satcodes.values():
        tledict[norad_id] = ()

    tlefile = open(args.tlefile, 'r')
    line1 = tlefile.readline().rstrip()
    while len(line1) > 1:
        norad_id = int(line1[2:7])
        year2d = int(line1[18:20])
        daynum = float(line1[20:32])
        tledate = datetime(2000 + year2d if year2d <= 56 else 1900 + year2d, 1,
                           1) + timedelta(days=daynum)
        line2 = tlefile.readline().rstrip()
        tledict[norad_id] += ((tledate, line1, line2), )
        line1 = tlefile.readline().rstrip()

    psqlin = subprocess.Popen([
        'psql', args.database, args.user, '--quiet', '--command',
        r'\timing off', '--command',
        r'\copy (SELECT * FROM ' + args.hotspots + ' WHERE ' + args.where +
        ' ORDER BY acq_date + acq_time) TO STDOUT CSV HEADER'
    ],
                              stdout=subprocess.PIPE,
                              encoding='UTF-8')

    satcsv = csv.DictReader(psqlin.stdout)

    psqlout = subprocess.Popen([
        'psql', args.database, args.user, '--quiet', '--command',
        r'\timing off'
    ] + ([
        '--command', 'DROP TABLE IF EXISTS ' + args.hotspots + '_' +
        args.suffix
    ] if args.drop_table else []) + [
        '--command', 'CREATE TABLE ' + args.hotspots + '_' + args.suffix +
        ' AS TABLE ' + args.hotspots + ' WITH NO DATA', '--command',
        'ALTER TABLE ' + args.hotspots + '_' + args.suffix + '     \
                                                  ADD COLUMN pass_azimuth NUMERIC(8,5),                 \
                                                  ADD COLUMN pass_elevation NUMERIC(8,5),               \
                                                  ADD COLUMN pass_bearing NUMERIC(8,5),                 \
                                                  ADD COLUMN pass_datetime TIMESTAMP WITHOUT TIME ZONE, \
                                                  ADD COLUMN prev_azimuth NUMERIC(8,5),                 \
                                                  ADD COLUMN prev_elevation NUMERIC(8,5),               \
                                                  ADD COLUMN prev_datetime TIMESTAMP WITHOUT TIME ZONE, \
                                                  ADD COLUMN next_azimuth NUMERIC(8,5),                 \
                                                  ADD COLUMN next_elevation NUMERIC(8,5),               \
                                                  ADD COLUMN next_datetime TIMESTAMP WITHOUT TIME ZONE, \
                                                  DROP COLUMN IF EXISTS geometry,                       \
                                                  ADD COLUMN geometry geometry GENERATED ALWAYS AS (ST_Rotate(ST_MakeEnvelope((ST_X(ST_Transform(ST_SetSRID(ST_MakePoint((longitude)::DOUBLE PRECISION, (latitude)::DOUBLE PRECISION), 4326), 28350)) - ((scan * (500)::NUMERIC))::DOUBLE PRECISION), (ST_Y(ST_Transform(ST_SetSRID(ST_MakePoint((longitude)::DOUBLE PRECISION, (latitude)::DOUBLE PRECISION), 4326), 28350)) - ((track * (500)::NUMERIC))::DOUBLE PRECISION), (ST_X(ST_Transform(ST_SetSRID(ST_MakePoint((longitude)::DOUBLE PRECISION, (latitude)::DOUBLE PRECISION), 4326), 28350)) + ((scan * (500)::NUMERIC))::DOUBLE PRECISION), (ST_Y(ST_Transform(ST_SetSRID(ST_MakePoint((longitude)::DOUBLE PRECISION, (latitude)::DOUBLE PRECISION), 4326), 28350)) + ((track * (500)::NUMERIC))::DOUBLE PRECISION), 28350), ((((- pass_bearing) * 3.1415926) / (180)::NUMERIC))::DOUBLE PRECISION, ST_Transform(ST_SetSRID(ST_MakePoint((longitude)::DOUBLE PRECISION, (latitude)::DOUBLE PRECISION), 4326), 28350))) STORED',
        '--command', r'\copy ' + args.hotspots + '_' + args.suffix +
        ' FROM STDIN CSV HEADER', '--command',
        'ALTER TABLE ' + args.hotspots + '_' + args.suffix + '     \
                                                  ADD COLUMN id SERIAL'
    ],
                               stdin=subprocess.PIPE,
                               encoding='UTF-8')

    satout = csv.DictWriter(
        psqlout.stdin,
        fieldnames=satcsv.fieldnames + [
            'pass_azimuth', 'pass_elevation', 'pass_bearing', 'pass_datetime',
            'prev_azimuth', 'prev_elevation', 'prev_datetime', 'next_azimuth',
            'next_elevation', 'next_datetime'
        ])

    minelevation = 90
    tleindexes = {}
    lastdatetime = datetime(MINYEAR, 1, 1)
    lastline1 = None
    lastline2 = None
    inrowcount = 0
    for satline in satcsv:
        thisdatetime = dateparser.parse(satline['acq_date'] + ' ' +
                                        satline['acq_time'])
        satcode = satcodes[satline['satellite']]
        tletuples = tledict[satcode]
        tleidx = tleindexes.get(satcode, 0)
        assert (thisdatetime >= lastdatetime)
        lastdatetime = thisdatetime
        while tletuples[tleidx + 1][0] <= thisdatetime - timedelta(hours=12):
            tleidx += 1
        tleindexes[satcode] = tleidx

        tletuple = tletuples[tleidx]
        line1 = tletuple[1]
        line2 = tletuple[2]

        if line1 != lastline1 or line2 != lastline2:
            orb = Orbital("", line1=line1, line2=line2)
            lastline1 = line1
            lastline2 = line2

        passdatetimes = [
            next_pass[2]
            for next_pass in orb.get_next_passes(thisdatetime -
                                                 timedelta(hours=24),
                                                 48,
                                                 float(satline['longitude']),
                                                 float(satline['latitude']),
                                                 0,
                                                 horizon=0)
        ]

        nearpasses = []
        leastoffset = 999999
        leastoffsetidx = None
        for passidx in range(len(passdatetimes)):
            max_elevation_time = passdatetimes[passidx]
            (azimuth,
             elevation) = orb.get_observer_look(max_elevation_time,
                                                float(satline['longitude']),
                                                float(satline['latitude']), 0)
            thisoffset = (max_elevation_time - thisdatetime).total_seconds()
            if abs(thisoffset) < abs(leastoffset):
                leastoffsetidx = len(nearpasses)
                leastoffset = thisoffset

            nearpasses += [(max_elevation_time, azimuth, elevation)]

        if abs(leastoffset) > 600:
            print("WARNING: offset=", leastoffset, "prev offset=",
                  (nearpasses[leastoffsetidx - 1][0] -
                   thisdatetime).total_seconds() if leastoffsetidx > 0 else "",
                  "next offset=", (nearpasses[leastoffsetidx + 1][0] -
                                   thisdatetime).total_seconds()
                  if leastoffsetidx < len(nearpasses) - 1 else "",
                  " satellite ", satline['satellite'])
            #print("   ", satline)

        if len(nearpasses):
            nearestpass = nearpasses[leastoffsetidx]
            satline['pass_datetime'] = nearestpass[0]
            satline['pass_azimuth'] = nearestpass[1]
            satline['pass_elevation'] = nearestpass[2]

            (lon1, lat1, alt1) = orb.get_lonlatalt(max_elevation_time -
                                                   timedelta(seconds=30))
            (lon2, lat2, alt2) = orb.get_lonlatalt(max_elevation_time +
                                                   timedelta(seconds=30))
            point1 = (lon1, lat1)
            point2 = (lon2, lat2)
            bearing = sphere.bearing(point1, point2)
            satline['pass_bearing'] = bearing

            if leastoffsetidx > 0:
                prevpass = nearpasses[leastoffsetidx - 1]
                satline['prev_datetime'] = prevpass[0]
                satline['prev_azimuth'] = prevpass[1]
                satline['prev_elevation'] = prevpass[2]

            if leastoffsetidx < len(nearpasses) - 1:
                nextpass = nearpasses[leastoffsetidx + 1]
                satline['next_datetime'] = nextpass[0]
                satline['next_azimuth'] = nextpass[1]
                satline['next_elevation'] = nextpass[2]

        satout.writerow(satline)

        inrowcount += 1
        if args.limit and inrowcount == args.limit:
            break
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
Beispiel #19
0
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)        
Beispiel #20
0
def get_site_passes(
    satno, site, duration, filename
):  # Duration in hours from current time,  # filename = file with TLEs in it

    now = datetime.utcnow()  # set time to current time
    sat = Orbital(satellite='None',
                  line1=getTLE(satno, filename)[0],
                  line2=getTLE(satno, filename)[1])
    x = Orbital.get_next_passes(
        sat,
        now,
        duration,
        site[1],
        site[0],
        site[2],
        tol=0.001,
        horizon=site[3])  # builds list of all passes that break 3 degrees
    passes = []  # begins empty list for passes
    for i in x:
        en = Orbital.get_observer_look(sat, i[0], site[1], site[0],
                                       site[2])  # Gets entry Az & El
        ex = Orbital.get_observer_look(sat, i[1], site[1], site[0],
                                       site[2])  # Gets exitAz & El
        hi = Orbital.get_observer_look(sat, i[2], site[1], site[0],
                                       site[2])  # Gets exitAz & El
        p1 = Orbital.get_observer_look(sat, i[0], site[1], site[0],
                                       site[2])[0]  # az at 3 degree entry
        p2 = Orbital.get_observer_look(sat, i[0] + timedelta(seconds=1),
                                       site[1], site[0],
                                       site[2])[0]  # p1 1 seconds later
        p3 = Orbital.get_observer_look(sat, i[1], site[1], site[0],
                                       site[2])[0]  # az at 3 degree exit

        print(site[8], "Pass Start:", i[0], "Enter Az", en[0], "Pass Term:",
              i[1], "Exit Az:", ex[0], "MaxEl:",
              hi[1])  # prints passes (used for dev)

        if site[4] < en[0] < site[5] or site[6] < en[0] < site[
                7]:  # if satellite enters FOV on face *checkpass*
            len = int(
                (i[1] - i[0]).total_seconds())  # length of pass in seconds
            passes.append(
                i[0]
            )  # appedns check passes to passes list            print("Check Pass | Az:", en[0])  # prints pass info (used for dev)

        elif not site[4] < en[0] < site[5]:  # if enters FOV not on face1
            print("Fence Pass | Az:", ex[0])  # prints pass info (used for dev)

            if (p1 - p2) < 0:  # if the azimuth is growing after 5 seconds
                rx = i[
                    0]  # Sets variables so it doesn't mess up other operations
                while p1 <= site[
                        6]:  # looks for when azimuth breaches sides of coverage
                    p1 = Orbital.get_observer_look(
                        sat, rx, site[1], site[0],
                        site[2])[0]  # gets new azimuth
                    rx = rx + timedelta(
                        seconds=10
                    )  # sets time for 10s later to retrieve azimuth at that time
                print("Fence Time:", rx, "Angle:",
                      p1)  # prints pass info (used for dev)
                len = int((i[1] - rx).total_seconds())
                passes.append(rx)

            if (p1 - p2) > 0:  # if the azimuth is shrinking after 5 seconds
                rx = i[
                    0]  # Sets variables so it doesn't mess up other operations
                while p1 >= site[
                        6]:  # looks for when azimuth breaches sides of coverage
                    p1 = Orbital.get_observer_look(
                        sat, rx, site[1], site[0],
                        site[2])[0]  # gets new azimuth
                    rx = rx + timedelta(seconds=10)
                print("Fence Time:", rx, "Angle:",
                      p1)  # prints passe info (used for dev)
                len = int((i[1] - rx).total_seconds())
                passes.append(rx)  # appedns check passes to passes list

        elif not site[6] < en[0] < site[7]:  # if enters FOV not on face2
            print("Fence Pass | Az:", ex[0])  # prints pass info (used for dev)

            if (p1 - p2) < 0:  # if the azimuth is growing after 5 seconds
                rx = i[
                    0]  # Sets variables so it doesn't mess up other operations
                while p1 <= site[
                        6]:  # looks for when azimuth breaches sides of coverage
                    p1 = Orbital.get_observer_look(
                        sat, rx, site[1], site[0],
                        site[2])[0]  # gets new azimuth
                    rx = rx + timedelta(
                        seconds=10
                    )  # sets time for 10s later to retrieve azimuth at that time
                print("Fence Time:", rx, "Angle:",
                      p1)  # prints pass info (used for dev)
                len = int((i[1] - rx).total_seconds())

                passes.append(rx)  # appedns check passes to passes list

            if (p1 - p2) > 0:  # if the azimuth is shrinking after 5 seconds
                rx = i[
                    0]  # Sets variables so it doesn't mess up other operations
                while p1 >= site[
                        6]:  # looks for when azimuth breaches sides of coverage
                    p1 = Orbital.get_observer_look(
                        sat, rx, site[1], site[0],
                        site[2])[0]  # gets new azimuth
                    rx = rx + timedelta(
                        seconds=10
                    )  # sets time for 10s later to retrieve azimuth at that time
                print("Fence Time:", rx, "Angle:",
                      p1)  # prints pass info (used for dev)
                len = int((i[1] - rx).total_seconds())

                passes.append(rx)  # appedns check passes to passes list

        if len < 0:
            print("Not a Pass")
        elif len < 180:
            print("Pass Length: ", len, "sec (short)")
        else:
            print("Pass Length: ", len, "sec")
    return passes  # Returns datetime objects for all passes
Beispiel #21
0
def parseISSTLEFile():
    orb = Orbital("iss (zarya)", tle_filename)
    utc_time = datetime.utcnow()
    return orb.get_lonlatalt(utc_time) + orb.get_observer_look(
        utc_time, location[0], location[1], 0)
Beispiel #22
0

lat, lon, alt = 29.76, -95.36, 0

lat_rad = math.radians(lat)
lon_rad = math.radians(lon)

R_ECEF_to_NED = np.matrix([
                            [-math.sin(lat_rad)*math.cos(lon_rad), -math.sin(lat_rad)*math.sin(lon_rad),  math.cos(lat_rad)],
                            [-math.sin(lon_rad),                    math.cos(lon_rad),                    0                ],
                            [-math.cos(lat_rad)*math.cos(lon_rad), -math.cos(lat_rad)*math.sin(lon_rad), -math.sin(lat_rad)] 
                          ])
#iss_sat_num = 25544
orb = Orbital('ISS (ZARYA)')
now = datetime.utcnow()
look = orb.get_observer_look(now, lon, lat, alt) # NOTE: lon is first, lat is second!
iss_llh = orb.get_lonlatalt(now)

print("ISS (lat lon alt) = ({}, {}, {})".format(iss_llh[1], iss_llh[0], iss_llh[2]))
print('ISS is {} deg east of north and {} degrees above the horizon'.format(look[0], look[1])) 
#print(astronomy.sun_zenith_angle(now, lon, lat))

iss_pos_m = lat_lon_to_ecef(iss_llh[1],                     # lat
                            iss_llh[0],                     # lon
                            earth_rad_m+(iss_llh[2]*1000))  # height (m) (need to cvt km to m)

obs_pos_m = lat_lon_to_ecef(lat, lon)

print('ECEF pos: {} m'.format(iss_pos_m))
print('obs ECEF pos: {} m'.format(obs_pos_m))
Beispiel #23
0
TLE_FILE_NAME = 'cubesat.txt'
ALTITUDE_ASL = 0
LAT = 64.146
LONG = 21.942

passhour = 0

while passhour < 24:
    # set the date with a variable for the hour
    d = datetime(2020, 5, 9, passhour, 0, 0)
    orb = Orbital('CUBESAT', 'cubesat.txt')
    # generate pass information for the hour specified
    passes = orb.get_next_passes(d, 1, LONG, LAT, ALTITUDE_ASL, horizon=1)
    # if there is no pass for the current value of passhour, the length will be zero
    if len(passes) > 0:
        rise_az, rise_el = orb.get_observer_look(passes[0][0], LONG, LAT,
                                                 ALTITUDE_ASL)
        transit_az, transit_el = orb.get_observer_look(passes[0][2], LONG, LAT,
                                                       ALTITUDE_ASL)
        set_az, set_el = orb.get_observer_look(passes[0][1], LONG, LAT,
                                               ALTITUDE_ASL)

        # print out the pass info
        print("CUBESAT")
        print(passes[0][0], rise_az, rise_el)
        print(passes[0][2], transit_az, transit_el)
        print(passes[0][1], set_az, set_el)
        print()
        # use datetime.strptime() to split the pass time into its componenet parts
        # set the hour of the current pass
        passtring = datetime.strptime(str(passes[0][0]),
                                      '%Y-%m-%d %H:%M:%S.%f')
class InviewCalculator:
    """Class to compute inviews above a specified elevation angle from a latitude, longitude, elevation to a satellite (number) """

    # Constructor
    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())

    # Member functions

    def __repr__(self):
        """Returns a string representing an instance of this class."""
        out = 'Inview Calculator:\n' \
              'latitude=%f, longitude=%f, elevation=%f, ' \
              'minimum elevation angle=%s, satellite TLE=\n%s' % \
              (self.__ground_station.get_latitude(), self.__ground_station.get_longitude(), self.__ground_station.get_minimum_elevation_angle(), \
               self.__ground_station.get_minimum_elevation_angle(), self.__satellite_tle)
        return out

    def compute_inviews(self, in_start_time, in_end_time):
        """Method to compute inviews (in UTC) for the initialized location, elevation angle, and satellite over a specified time period.  Returns a list of inview start/stop times, accurate to the nearest second and using the latest available TLE when the method is called."""
        # NOTE:  pyorbital EXPECTS naive date/times and interprets them
        # as UTC... so we need to satisfy it; however, we are making this
        # module DATETIME AWARE, so RETURN VALUES are DATETIME AWARE!!
        # Also, all naive inputs are assumed to be UTC and all aware inputs
        # are converted to UTC (and then made naive)
        if (in_start_time.tzinfo is not None):
            temp = in_start_time.astimezone(UTC)
            start_time = datetime(temp.year, temp.month, temp.day, \
                                  temp.hour, temp.minute, temp.second)
        else:
            start_time = in_start_time
        if (in_end_time.tzinfo is not None):
            temp = in_end_time.astimezone(UTC)
            end_time = datetime(temp.year, temp.month, temp.day, \
                                temp.hour, temp.minute, temp.second)
        else:
            end_time = in_end_time
        # start_time, end_time are now naive
        inviews = []
        time = start_time
        up = 0
        el_increasing = 0
        maxel = 0
        try:
            (az, el) = self.__orb.get_observer_look(time, self.__ground_station.get_longitude(), \
                                                    self.__ground_station.get_latitude(), \
                                                    self.__ground_station.get_minimum_elevation_angle())
            if (el > self.__ground_station.get_minimum_elevation_angle()):
                # start the first inview at the input start_time
                up = 1
                el_increasing = 1
                rising = time
            # Step through time, looking for inview starts and ends
            while (time < end_time):
                (az, el) = self.__orb.get_observer_look(time, self.__ground_station.get_longitude(), \
                                                        self.__ground_station.get_latitude(), \
                                                        self.__ground_station.get_minimum_elevation_angle())
                if (el > self.__ground_station.get_minimum_elevation_angle()
                    ) and (up == 0):
                    rising = self.__find_exact_crossing(time, up)
                    el_increasing = 1
                    up = 1
                if (el < self.__ground_station.get_minimum_elevation_angle()
                    ) and (up == 1):
                    # make sure to append AWARE datetimes
                    crossing = self.__find_exact_crossing(time, up)
                    inviews.append((rising.replace(tzinfo=UTC), \
                                    crossing.replace(tzinfo=UTC), \
                                    maxel))
                    el_increasing = 0
                    up = 0
                    maxel = 0
                if (el > self.__ground_station.get_minimum_elevation_angle()):
                    if (el > maxel):
                        maxel = el
                    elif (
                            el_increasing
                    ):  # First point after el starts decreasing... find the exact max el
                        el_increasing = 0
                        maxel = self.__find_exact_maxel(time, maxel)
                time += self.__oneminute
            if (up == 1):
                # end the last inview at the input end_time
                # make sure to append AWARE datetimes
                inviews.append((rising.replace(tzinfo=UTC), \
                                end_time.replace(tzinfo=UTC), \
                                maxel))

            return inviews
        except NotImplementedError:  # Does not seem to work?
            print("NotImplementedError computing inviews.  Date/time = %s-%s-%sT%s:%s:%s, satellite number = %s" % \
                (time.year, time.month, time.day, time.hour, time.minute, time.second, self.__satellite_tle.get_satellite_number()))
            sys.stdout.flush()
            raise
        except:  # Does not seem to work?
            print("Unknown exception computing inviews.  Date/time = %s-%s-%sT%s:%s:%s, satellite number = %s" % \
                (time.year, time.month, time.day, time.hour, time.minute, time.second, self.__satellite_tle.get_satellite_number()))
            sys.stdout.flush()
            raise

    def print_inviews(self, inviews):
        """Method to print a table of inviews... assumes that inviews contains the data for such a table"""
        for iv in inviews:
            print("Rise: %s, Set: %s, Maximum Elevation: %f" %
                  (iv[0], iv[1], iv[2]))

    def compute_azels(self, in_start_time, in_end_time, time_step_seconds):
        """Method to compute az/el angles at time_step intervals during the input time period, INDEPENDENT of whether the satellite is actually in view """
        # NOTE:  pyorbital EXPECTS naive date/times and interprets them
        # as UTC... so we need to satisfy it; however, we are making this
        # module DATETIME AWARE, so RETURN VALUES are DATETIME AWARE!!
        # Also, all naive inputs are assumed to be UTC and all aware inputs
        # are converted to UTC (and then made naive)
        if (in_start_time.tzinfo is not None):
            temp = in_start_time.astimezone(UTC)
            start_time = datetime(temp.year, temp.month, temp.day, \
                                  temp.hour, temp.minute, temp.second)
        else:
            start_time = in_start_time
        if (in_end_time.tzinfo is not None):
            temp = in_end_time.astimezone(UTC)
            end_time = datetime(temp.year, temp.month, temp.day, \
                                temp.hour, temp.minute, temp.second)
        else:
            end_time = in_end_time
        # start_time, end_time are now naive
        try:
            delta = timedelta(seconds=time_step_seconds)
        except:
            delta = timedelta(seconds=60)
        azels = []
        time = start_time
        # Naively compute the table... i.e. compute time, az, el for the
        # input duration at each time step... no matter whether the satellite
        # is really inview or not!
        while (time < end_time + delta):
            (az, el) = self.__orb.get_observer_look(time, self.__ground_station.get_longitude(), \
                                                    self.__ground_station.get_latitude(), \
                                                    self.__ground_station.get_minimum_elevation_angle())
            range_km = self.__compute_range(time)
            outtime = time.replace(tzinfo=UTC)  # time is unmodified!
            azels.append((outtime, az, el, range_km))
            time += delta

        return azels

    def __compute_range(self, utc_time):
        """Method to compute range in kilometers from observer to satellite at *naive* UTC time utc_time"""
        # N.B. pyorbital works in kilometers
        (pos_x, pos_y,
         pos_z), (vel_x, vel_y,
                  vel_z) = self.__orb.get_position(utc_time, normalize=False)
        (opos_x, opos_y, opos_z), (ovel_x, ovel_y, ovel_z) = astronomy.observer_position(utc_time, \
                self.__ground_station.get_longitude(), self.__ground_station.get_latitude(), self.__ground_station.get_elevation_in_meters()/1000.0)
        dx = pos_x - opos_x
        dy = pos_y - opos_y
        dz = pos_z - opos_z
        return math.sqrt(dx * dx + dy * dy + dz * dz)  # km

    # up is what it is **before** the crossing
    def __find_exact_crossing(self, time, up):
        """Private method to refine an in view/out of view crossing time from the nearest minute to the nearest second."""
        exacttime = time
        # The crossing occurred in the minute before now... search backwards
        # for the exact second of crossing
        for j in range(0, 60):
            exacttime -= self.__onesecond
            (az, el) = self.__orb.get_observer_look(exacttime, \
                                                    self.__ground_station.get_longitude(), \
                                                    self.__ground_station.get_latitude(), \
                                                    self.__ground_station.get_minimum_elevation_angle())
            if ((el > self.__ground_station.get_minimum_elevation_angle()) and (up == 1)) or \
               ((el < self.__ground_station.get_minimum_elevation_angle()) and (up == 0)):
                break
        return exacttime

    def __find_exact_maxel(self, time, maxel):
        """Private method to refine the maximum elevation from occuring at the nearest minute to the nearest second."""
        exacttime = time
        # The maximum elevation occurred in the **two** minutes before now... search backwards
        # for the exact second of maximum elevation
        for j in range(0, 120):
            exacttime -= self.__onesecond
            (az, el) = self.__orb.get_observer_look(exacttime, \
                                                    self.__ground_station.get_longitude(), \
                                                    self.__ground_station.get_latitude(), \
                                                    self.__ground_station.get_minimum_elevation_angle())
            if (el > maxel):
                maxel = el
        return maxel

    # Class member constants
    __onesecond = timedelta(seconds=1)
    __oneminute = timedelta(minutes=1)
Beispiel #25
0
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'] = {}
data['user_view']['azimuth'] = az
data['user_view']['elevation'] = el

data['timestamp'] = timestamp
data['satellite'] = satellite

data['tle'] = {};
data['tle']['arg_perigee'] = orb.tle.arg_perigee
data['tle']['bstar'] = orb.tle.bstar
data['tle']['classification'] = orb.tle.classification
data['tle']['element_number'] = orb.tle.element_number
data['tle']['ephemeris_type'] = orb.tle.ephemeris_type
data['tle']['epoch'] = (orb.tle.epoch - datetime(1970, 1, 1)).total_seconds()
Beispiel #26
0
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)        
Beispiel #27
0
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)
Beispiel #28
0
eph.compute(ephObserver)

data = {}
data['next_pass'] = {}
data['next_pass']['until'] = "%d" % round((rt - ephemNow) * 3600 * 24)
data['next_pass']['rise_time'] = calendar.timegm(rt.datetime().utctimetuple())
data['next_pass']['transit_time'] = calendar.timegm(tt.datetime().utctimetuple())
data['next_pass']['set_time'] = calendar.timegm(st.datetime().utctimetuple())
data['next_pass']['rise_azimuth'] = "%5.1f" % math.degrees(razi)
data['next_pass']['max_elevation'] = "%5.1f" % math.degrees(televation)
data['next_pass']['set_azimuth'] = "%5.1f" % math.degrees(sazi)

# azimuth = eph.az
# elevation = eph.alt
azimuth, elevation = orb.get_observer_look(now, userLng, userLat, userAlt);

data['user_view'] = {}
data['user_view']['azimuth'] = azimuth
data['user_view']['elevation'] = elevation

data['timestamp'] = timestamp
data['satellite'] = satellite

data['tle'] = {};
data['tle']['first_line'] = line1
data['tle']['second_line'] = line2
data['tle']['arg_perigee'] = orb.tle.arg_perigee
data['tle']['bstar'] = orb.tle.bstar
data['tle']['classification'] = orb.tle.classification
data['tle']['element_number'] = orb.tle.element_number
Beispiel #29
0
tle = StringIO()
tle.write(amateur_file)
orb = Orbital(
    "AO-7",
    line1=
    "1 07530U 74089B   19134.19581420 -.00000034  00000-0  67853-4 0  9992",
    line2=
    "2 07530 101.7410 102.2252 0012571  56.5062  14.6811 12.53638015 36076")
now = datetime.utcnow()
# arrayat=Orbital.get_observer_look(lon=120.77,lat=15.15,alt=0.020)
pprint(orb)
# >>> # Get longitude, latitude and altitude of the satellite: >>>
pprint(orb.get_lonlatalt(now))
passes = orb.get_next_passes(now, length=4, lon=120.77, lat=15.15, alt=0.02)
#
# Each Pass a tuple of 3, rise, set, max ele
#
start_pass = passes[0][0]
end_pass = passes[0][1]
min_elevation = 10
while (start_pass < end_pass):
    sky_location = orb.get_observer_look(start_pass,
                                         lon=120.77,
                                         lat=15.15,
                                         alt=0.02)
    if sky_location[1] >= min_elevation:
        print("Az  {:6.2f}  Ele {:6.2f} ".format(sky_location[0],
                                                 sky_location[1]))

    start_pass = start_pass + timedelta(seconds=60)
print("Pass ended")
def get_satellite_geometry(startDateUTC,
                           lengthDays,
                           lon,
                           lat,
                           alt=0.0,
                           mission="Sentinel-2a",
                           tleFile="/data/tle/norad_resource_tle.txt"):
    """Calculate approximate geometry for Sentinel overpasses.
    Approximate because it assumes maximum satellite elevation
    is the time at which target is imaged.

    :param startDateUTC: a datetime object specifying when to start prediction.
    :type startDateUTC: object
    :param lengthDays: number of days over which to perform calculations.
    :type lengthDays: int
    :param lat: latitude of target.
    :type lat: float
    :param lon: longitude of target.
    :type lon: float
    :param alt: altitude of target (in km).
    :type alt: float
    :param mission: mission name as in TLE file.
    :type mission: str
    :param tleFile: TLE file.
    :type tleFile: str
    :return: a python list containing instances of the sensorGeometry class arranged in date order.
    :rtype: list
    """
    orb = Orbital(mission, tleFile)
    passes = orb.get_next_passes(startDateUTC, 24 * lengthDays, lon, lat, alt)

    geom_inst = SensorGeometry()
    geom_inst.date_utc = []
    geom_inst.vza = []
    geom_inst.vaa = []
    geom_inst.sza = []
    geom_inst.saa = []

    for p in passes:
        look = orb.get_observer_look(p[2], lon, lat, alt)
        vza = 90 - look[1]
        vaa = look[0]
        sza = ast.sun_zenith_angle(p[2], lon, lat)
        saa = np.rad2deg(ast.get_alt_az(p[2], lon, lat)[1])

        if mission == 'Sentinel-1b':
            if 75 < vaa < 105 and 20. < vza < 45.:  # vaa usually [0, 180], testing observation times
                geom_inst.date_utc.append(p[2])
                geom_inst.vza.append(vza)
                geom_inst.vaa.append(vaa)
                geom_inst.sza.append(sza)
                geom_inst.saa.append(saa)
        elif mission == 'Sentinel-1a':
            if 75 < vaa < 105 and 20. < vza < 45.:  # vaa usually [0, 180], testing observation times
                geom_inst.date_utc.append(p[2])
                geom_inst.vza.append(vza)
                geom_inst.vaa.append(vaa)
                geom_inst.sza.append(sza)
                geom_inst.saa.append(saa)
        elif mission == 'Sentinel-2a':
            if sza < 90 and vza < 10.3:
                geom_inst.date_utc.append(p[2])
                geom_inst.vza.append(vza)
                geom_inst.vaa.append(vaa)
                geom_inst.sza.append(sza)
                geom_inst.saa.append(saa)

    return geom_inst
Beispiel #31
0
class Test_NightFogLowStratusAlgorithm(unittest.TestCase):
    def setUp(self):
        # Load test data
        inputs = np.dsplit(testdata_night, 14)
        self.ir108 = inputs[0]
        self.ir039 = inputs[1]
        self.vis008 = inputs[2]
        self.nir016 = inputs[3]
        self.vis006 = inputs[4]
        self.ir087 = inputs[5]
        self.ir120 = inputs[6]
        self.elev = inputs[7]
        self.cot = inputs[8]
        self.reff = inputs[9]
        self.lwp = inputs[10]
        self.lat = inputs[11]
        self.lon = inputs[12]
        self.cth = inputs[13]

        self.time = datetime(2013, 11, 12, 6, 00, 00)
        # METEOSAT-10 (MSG-3) TLE file from 01.08.2017
        # http://celestrak.com/NORAD/elements/weather.txt
        line1 = "1 38552U 12035B   17212.14216600 -.00000019  00000-0  00000-0 0  9998"
        line2 = "2 38552   0.8450 357.8180 0002245 136.4998 225.6885  1.00275354 18379"
        # Import TLE file
        self.tle = tlefile.read('meteosat 10', line1=line1, line2=line2)
        self.orbital = Orbital('meteosat 10',
                               line1=self.tle.line1,
                               line2=self.tle.line2)
        # Compute satellite zenith angle
        azi, ele = self.orbital.get_observer_look(self.time, self.lon,
                                                  self.lat, self.elev)
        self.sza = ele

        self.input = {
            'ir108': self.ir108,
            'ir039': self.ir039,
            'lat': self.lat,
            'lon': self.lon,
            'time': self.time,
            'plot': True,
            'save': True,
            'dir': '/tmp/FLS',
            'resize': '5',
            'sza': self.sza
        }

        inputs = np.dsplit(testdata_night2, 14)
        self.ir108 = inputs[0]
        self.ir039 = inputs[1]
        self.vis008 = inputs[2]
        self.nir016 = inputs[3]
        self.vis006 = inputs[4]
        self.ir087 = inputs[5]
        self.ir120 = inputs[6]
        self.elev = inputs[7]
        self.cot = inputs[8]
        self.reff = inputs[9]
        self.lwp = inputs[10]
        self.lat = inputs[11]
        self.lon = inputs[12]
        self.cth = inputs[13]

        self.time = datetime(2013, 12, 1, 4, 00, 00)

        self.input2 = {
            'ir108': self.ir108,
            'ir039': self.ir039,
            'lat': self.lat,
            'lon': self.lon,
            'time': self.time,
            'plot': True,
            'save': True,
            'dir': '/tmp/FLS',
            'resize': '5',
            'sza': self.sza
        }

    def tearDown(self):
        pass

    def test_nightfls_algorithm(self):
        flsalgo = NightFogLowStratusAlgorithm(**self.input)
        ret, mask = flsalgo.run()
        self.assertEqual(flsalgo.ir108.shape, (141, 298))
        self.assertEqual(ret.shape, (141, 298))
        self.assertEqual(flsalgo.shape, (141, 298))
        self.assertEqual(np.ma.is_mask(flsalgo.mask), True)

    def test_nightfls_algorithm2(self):
        flsalgo = NightFogLowStratusAlgorithm(**self.input2)
        ret, mask = flsalgo.run()
        self.assertEqual(flsalgo.ir108.shape, (141, 298))
        self.assertEqual(ret.shape, (141, 298))
        self.assertEqual(flsalgo.shape, (141, 298))
        self.assertEqual(np.ma.is_mask(flsalgo.mask), True)

    def test_nightfls_turningpoints_with_valley(self):
        y = np.array([1, 2, 4, 7, 5, 2, 0, 2, 3, 4, 6])
        flsalgo = NightFogLowStratusAlgorithm(**self.input)
        tvalues, valleys = flsalgo.get_turningpoints(y)
        self.assertEqual(tvalues[5], True)
        self.assertEqual(tvalues[2], True)
        self.assertEqual(np.sum(tvalues), 2)
        self.assertEqual(np.alen(valleys), 1)
        self.assertEqual(valleys, 0)

    def test_nightfls_turningpoints_with_thres(self):
        y = np.array([1, 2, 4, 7, 5, 2, 0, 2, 3, 4, 6])
        x = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
        flsalgo = NightFogLowStratusAlgorithm(**self.input)
        tvalues, thres = flsalgo.get_turningpoints(y, x)
        self.assertEqual(tvalues[5], True)
        self.assertEqual(tvalues[2], True)
        self.assertEqual(np.sum(tvalues), 2)
        self.assertEqual(np.alen(thres), 1)
        self.assertEqual(thres, 7)

    def test_nightfls_turningpoints_no_valley(self):
        y = np.array([1, 2, 4, 7, 5, 2, 1, 1, 1, 0])
        flsalgo = NightFogLowStratusAlgorithm(**self.input)
        tvalues, valleys = flsalgo.get_turningpoints(y)
        self.assertEqual(tvalues[2], True)
        self.assertEqual(np.sum(tvalues), 1)
        self.assertEqual(np.alen(valleys), 0)

    def test_nightfls_slope(self):
        y = np.array([1, 2, 4, 7, 5, 2, 1, 1, 1, 0])
        x = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
        flsalgo = NightFogLowStratusAlgorithm(**self.input)
        slope, thres = flsalgo.get_slope(y, x)
        self.assertEqual(slope[2], 3)
        self.assertEqual(slope[8], -1)
        self.assertEqual(np.alen(slope), 9)
        self.assertEqual(thres, 6)
Beispiel #32
0
current_time = datetime.utcfromtimestamp(time)


def pwm_for(az, el):
    low = pwm_min
    high = pwm_max

    if (az > 180):
        az -= 180
        el = 180 - el

    az_pwm = (az / 180) * (high - low) + low
    el_pwm = (el / 180) * (high - low) + low

    return az_pwm, el_pwm


delta = timedelta(seconds=step)
for i in range(duration):
    az, el = orb.get_observer_look(current_time, lon, lat, 0)
    paz, pel = (pwm_for(az, el))
    res = (", ".join(
        [str(time + i),
         str(int(round(paz))),
         str(int(round(pel)))]))
    con.send(res.encode("utf8") + b"\n")
    current_time += delta

con.send(b"\n")
print(con.recv(1024).decode("utf8"))