Esempio n. 1
0
    def __init__(self, satellite, risetime, falltime, **kwargs):
        SimplePass.__init__(self, satellite, risetime, falltime)

        logger.debug("kwargs: %s", str(kwargs))
        orb = kwargs.get('orb', None)
        uptime = kwargs.get('uptime', None)
        instrument = kwargs.get('instrument', None)
        tle1 = kwargs.get('tle1', None)
        tle2 = kwargs.get('tle2', None)
        logger.debug("instrument: %s", str(instrument))

        if isinstance(instrument, (list, set)):
            if 'avhrr' in instrument:
                logger.warning("Instrument is a sequence! Assume avhrr...")
                instrument = 'avhrr'
            elif 'viirs' in instrument:
                logger.warning("Instrument is a sequence! Assume viirs...")
                instrument = 'viirs'
            elif 'modis' in instrument:
                logger.warning("Instrument is a sequence! Assume modis...")
                instrument = 'modis'
            elif 'mersi' in instrument:
                logger.warning("Instrument is a sequence! Assume mersi...")
                instrument = 'mersi'
            elif 'mersi-2' in instrument:
                logger.warning("Instrument is a sequence! Assume mersi-2...")
                instrument = 'mersi-2'
            else:
                raise TypeError(
                    "Instrument is a sequence! Don't know which one to choose!"
                )

        default = NUMBER_OF_FOVS.get(instrument, 2048)
        self.number_of_fovs = kwargs.get('number_of_fovs', default)
        # The frequency shouldn't actualy depend on the number of FOVS along a scanline should it!?
        # frequency = kwargs.get('frequency', int(self.number_of_fovs / 4))
        frequency = kwargs.get('frequency', 300)

        self.station = None
        self.max_elev = None
        self.uptime = uptime or (risetime + (falltime - risetime) / 2)
        self.instrument = instrument
        self.frequency = frequency
        if orb:
            self.orb = orb
        else:
            try:
                self.orb = orbital.Orbital(satellite, line1=tle1, line2=tle2)
            except KeyError as err:
                logger.debug('Failed in PyOrbital: %s', str(err))
                self.orb = orbital.Orbital(NOAA20_NAME.get(
                    satellite, satellite),
                                           line1=tle1,
                                           line2=tle2)
                logger.info('Using satellite name %s instead',
                            str(NOAA20_NAME.get(satellite, satellite)))

        self._boundary = None
Esempio n. 2
0
def get_npp_orbit_number(obstime):
    """Get the orbit number for the Suomi NPP RDR/SDR file given the
    observation start time. The orbit number"""

    sat = orb.Orbital('SUOMI NPP')

    return sat.get_orbit_number(obstime)
Esempio n. 3
0
    def test_get_equatorial_crossing_time(self, get_orbit_number, utc2local):
        def get_orbit_number_patched(utc_time, **kwargs):
            utc_time = np.datetime64(utc_time)
            diff = (utc_time -
                    np.datetime64('2009-07-01 12:38:12')) / np.timedelta64(
                        7200, 's')
            return 1234 + diff

        get_orbit_number.side_effect = get_orbit_number_patched
        utc2local.return_value = 'local_time'
        sat = orbital.Orbital("METOP-A",
                              line1="1 29499U 06044A   13060.48822809  "
                              ".00000017  00000-0  27793-4 0  9819",
                              line2="2 29499  98.6639 121.6164 0001449  "
                              "71.9056  43.3132 14.21510544330271")

        # Ascending node
        res = sat.get_equatorial_crossing_time(tstart=datetime(2009, 7, 1, 12),
                                               tend=datetime(2009, 7, 1, 13))
        exp = datetime(2009, 7, 1, 12, 38, 12)
        self.assertTrue((res - exp) < timedelta(seconds=0.01))

        # Descending node
        res = sat.get_equatorial_crossing_time(tstart=datetime(2009, 7, 1, 12),
                                               tend=datetime(
                                                   2009, 7, 1, 14, 0),
                                               node='descending')
        exp = datetime(2009, 7, 1, 13, 38, 12)
        self.assertTrue((res - exp) < timedelta(seconds=0.01))

        # Conversion to local time
        res = sat.get_equatorial_crossing_time(tstart=datetime(2009, 7, 1, 12),
                                               tend=datetime(2009, 7, 1, 14),
                                               local_time=True)
        self.assertEqual(res, 'local_time')
Esempio n. 4
0
 def test_get_orbit_number(self):
     """Testing getting the orbitnumber from the tle"""
     sat = orbital.Orbital("NPP",
                           line1="1 37849U 11061A   12017.90990040 -.00000112  00000-0 -32693-4 0   772",
                           line2="2 37849  98.7026 317.8811 0001845  92.4533 267.6830 14.19582686 11574")
     dobj = datetime(2012, 1, 18, 8, 4, 19)
     orbnum = sat.get_orbit_number(dobj)
     self.assertEqual(orbnum, 1163)
Esempio n. 5
0
 def test_orbit_num_an(self):
     sat = orbital.Orbital("METOP-A",
                           line1="1 29499U 06044A   11254.96536486  "
                           ".00000092  00000-0  62081-4 0  5221",
                           line2="2 29499  98.6804 312.6735 0001758 "
                           "111.9178 248.2152 14.21501774254058")
     d = datetime(2011, 9, 14, 5, 30)
     self.assertEqual(sat.get_orbit_number(d), 25437)
Esempio n. 6
0
 def test_orbit_num_non_an(self):
     sat = orbital.Orbital("METOP-A",
                           line1="1 29499U 06044A   13060.48822809  "
                           ".00000017  00000-0  27793-4 0  9819",
                           line2="2 29499  98.6639 121.6164 0001449  "
                           "71.9056  43.3132 14.21510544330271")
     dt = np.timedelta64(98, 'm')
     self.assertEqual(sat.get_orbit_number(sat.tle.epoch + dt), 33028)
Esempio n. 7
0
 def test_utc2local(self, get_lonlatalt):
     get_lonlatalt.return_value = -45, None, None
     sat = orbital.Orbital("METOP-A",
                           line1="1 29499U 06044A   13060.48822809  "
                           ".00000017  00000-0  27793-4 0  9819",
                           line2="2 29499  98.6639 121.6164 0001449  "
                           "71.9056  43.3132 14.21510544330271")
     self.assertEqual(sat.utc2local(datetime(2009, 7, 1, 12)),
                      datetime(2009, 7, 1, 9))
Esempio n. 8
0
def get_npp_orbit_number(obstime):
    """Get the orbit number for the Suomi NPP RDR/SDR file given the
    observation start time. The orbit number"""

    deltat = timedelta(days=1)
    datestr = obstime.strftime('%Y%m%d')
    try:
        sat = orb.Orbital('SUOMI NPP',
                          tle_file=os.path.join(TLEDIR,
                                                'tle-%s.txt' % datestr))
    except IOError:
        datestr = (obstime - deltat).strftime('%Y%m%d')
        sat = orb.Orbital('SUOMI NPP',
                          tle_file=os.path.join(TLEDIR,
                                                'tle-%s.txt' % datestr))

    orbit = sat.get_orbit_number(obstime)

    return orbit
Esempio n. 9
0
 def test_observer_look(self):
     sat = orbital.Orbital("ISS (ZARYA)",
                           line1="1 25544U 98067A   03097.78853147  .00021906  00000-0  28403-3 0  8652",
                           line2="2 25544  51.6361  13.7980 0004256  35.6671  59.2566 15.58778559250029")
     d = datetime(2003, 3, 23, 0, 3, 22)
     az, el = sat.get_observer_look(d, -84.39733, 33.775867, 0)
     expected_az = 122.45169655331965
     expected_el = 1.9800219611255456
     self.assertTrue(np.abs(az - expected_az) < eps_deg, 'Calculation of azimut failed')
     self.assertTrue(np.abs(el - expected_el) < eps_deg, 'Calculation of elevation failed')
Esempio n. 10
0
 def __init__(self, path, duration):
     self.lat = 55.8667
     self.lon = -4.4333
     self.alt = 125
     self.duration = duration
     f = open("%s" % path, 'r')
     sat = f.readline()
     line1 = f.readline()
     line2 = f.readline()
     self.orb = orbital.Orbital(sat, path, line1, line2)
Esempio n. 11
0
    def test_get_next_passes_issue_22(self):
        """Check that max"""
        line1 = '1 28654U 05018A   21083.16603416  .00000102  00000-0  79268-4 0  9999'
        line2 = '2 28654  99.0035 147.6583 0014816 159.4931 200.6838 14.12591533816498'

        orb = orbital.Orbital("NOAA 18", line1=line1, line2=line2)
        t = datetime(2021, 3, 9, 22)
        next_passes = orb.get_next_passes(t, 1, -15.6335, 27.762, 0.)
        rise, fall, max_elevation = next_passes[0]
        assert rise < max_elevation < fall
        print(next_passes)
Esempio n. 12
0
    def test_get_next_passes_apogee(self):
        """Regression test #22."""
        line1 = "1 24793U 97020B   18065.48735489  .00000075  00000-0  19863-4 0  9994"
        line2 = "2 24793  86.3994 209.3241 0002020  89.8714 270.2713 14.34246429 90794"

        orb = orbital.Orbital('IRIDIUM 7 [+]', line1=line1, line2=line2)
        d = datetime(2018, 3, 7, 3, 30, 15)
        res = orb.get_next_passes(d, 1, 170.556, -43.368, 0.5, horizon=40)
        self.assertTrue(
            abs(res[0][2] -
                datetime(2018, 3, 7, 3, 48, 13, 178439)) < timedelta(
                    seconds=0.01))
Esempio n. 13
0
 def test_sublonlat(self):
     sat = orbital.Orbital("ISS (ZARYA)",
                           line1="1 25544U 98067A   03097.78853147  .00021906  00000-0  28403-3 0  8652",
                           line2="2 25544  51.6361  13.7980 0004256  35.6671  59.2566 15.58778559250029")
     d = datetime(2003, 3, 23, 0, 3, 22)
     lon, lat, alt = sat.get_lonlatalt(d)
     expected_lon = -68.199894472013213
     expected_lat = 23.159747677881075
     expected_alt = 392.01953430856935
     self.assertTrue(np.abs(lon - expected_lon) < eps_deg, 'Calculation of sublon failed')
     self.assertTrue(np.abs(lat - expected_lat) < eps_deg, 'Calculation of sublat failed')
     self.assertTrue(np.abs(alt - expected_alt) < eps_deg, 'Calculation of altitude failed')
Esempio n. 14
0
def get_passes(ground_cor, alt, satellite_name, start_time, length, min_angle):
    satellite = orbital.Orbital(satellite_name)
    passes = satellite.get_next_passes(start_time + timedelta(seconds=1),
                                       length, ground_cor[1], ground_cor[0],
                                       alt)
    ret = []
    for line in passes:
        angle = (satellite.get_observer_look(line[2], ground_cor[1],
                                             ground_cor[0], alt))[1]
        if (angle >= (float)(min_angle)):
            p = [line[0], line[1] - line[0]]
            p.append(angle)
            ret.append(p)
    return ret
Esempio n. 15
0
 def test_orbit_num_equator(self):
     sat = orbital.Orbital("SUOMI NPP",
                           line1="1 37849U 11061A   13061.24611272  .00000048  00000-0  43679-4 0  4334",
                           line2="2 37849  98.7444   1.0588 0001264  63.8791 102.8546 14.19528338 69643")
     t1 = datetime(2013, 3, 2, 22, 2, 25)
     t2 = datetime(2013, 3, 2, 22, 2, 26)
     on1 = sat.get_orbit_number(t1)
     on2 = sat.get_orbit_number(t2)
     self.assertEqual(on1, 6973)
     self.assertEqual(on2, 6974)
     pos1, vel1 = sat.get_position(t1, normalize=False)
     pos2, vel2 = sat.get_position(t2, normalize=False)
     del vel1, vel2
     self.assertTrue(pos1[2] < 0)
     self.assertTrue(pos2[2] > 0)
Esempio n. 16
0
def get_metop_orbit(satellite, timestamp):
    from sat_schedules import fetch_tle
    from pyorbital import orbital
    satnames = {'M01': 'METOP-B', 'M02': 'METOP-A', 'M03': 'METOP-C'}
    try:
        satname = satnames[satellite]
    except KeyError:
        print >> sys.stderr, "ERROR, This 'get_metop_orbit' only work for METOP satellites"
        return 0
    tles = fetch_tle.get_tle(timestamp)
    if not tles:
        return 0
    l1, l2 = tles.get(satname)
    orb = orbital.Orbital(satname, line1=l1, line2=l2)
    return orb.get_orbit_number(timestamp, tbus_style=True)
 def __init__(self, tle, orbitOffset):
     self.tle = tle
     self.orbitOffset = orbitOffset
     (name, line1, line2) = tle.split("\n")[0:3]
     name = name.strip()
     line1 = line1.strip()
     line2 = line2.strip()
     self.name = name
     self.line1 = line1
     self.line2 = line2
     yyyy = "20" + line1[18:20]
     yday = line1[20:32]
     self.epoch = ephem.Date(ephem.Date(yyyy + "/1/1") + float(yday) - 1.0)
     # For ephem
     self.sat = ephem.readtle(name, line1, line2)
     # For pyorbital (to get orbit number)
     self.osat = orbital.Orbital(name, line1=line1, line2=line2)
Esempio n. 18
0
def add_product(dcm, filename):
    info = filename.split('_')
    satname = info[0]
    orbit = int(info[3])
    time_start = datetime.strptime(info[1] + info[2], '%Y%m%d%H%M')
    time_end = time_start + timedelta(minutes=3)

    ft = dcm.get_file_type('PPS_cloud_type_granule')
    ff = dcm.get_file_format('HDF5')

    nf = dcm.create_file(filename, file_type=ft, file_format=ff)
   
    p = dcm.get_parameter('time_start')
    pv = dcm.create_parameter_value(time_start.isoformat(), file_obj=nf, parameter=p)
    p = dcm.get_parameter('time_end')
    pv = dcm.create_parameter_value(time_end.isoformat(), file_obj=nf, parameter=p)
    p = dcm.get_parameter('orbit_number')
    pv = dcm.create_parameter_value(orbit, file_obj=nf, parameter=p)
    p = dcm.get_parameter('satellite_name')
    pv = dcm.create_parameter_value(satname, file_obj=nf, parameter=p)

    sat = orbital.Orbital(sat_lookup.get(satname, satname), tle_file=get_latest_tle())

    dt = timedelta(seconds=10)
    print time_start
    current_time = time_start
    lonlat_list = []
    while current_time <= time_end:
        pos = sat.get_lonlatalt(current_time)
        lonlat_list.append(pos[:2])
        current_time += dt

    value = 'LINESTRING ('
    for i, item in enumerate(lonlat_list):
        if i == 0:
            value += '%s %s' % (item[0], item[1])
        else:
            value += ' ,%s %s' % (item[0], item[1])
    value += ')'

    wkt_o = shapely.wkt.loads(value)
    p_track = dcm.get_parameter('sub_satellite_track')
    pls = dcm.create_parameter_linestring(wkt_o, file_obj=nf, parameter=p_track)

    dcm.save()
Esempio n. 19
0
def granule_inside_area(start_time, end_time, platform_name, area_def):
    """Check if the IASI granule is over area interest, using the times from the
    filename

    """

    metop = orbital.Orbital(PLATFORMS.get(platform_name, platform_name))
    corners = area_def.corners

    is_inside = False
    for dtobj in [start_time, end_time]:
        lon, lat, dummy = metop.get_lonlatalt(dtobj)
        point = Coordinate(lon, lat)
        if point_inside(point, corners):
            is_inside = True
            break

    return is_inside
Esempio n. 20
0
    def test_get_next_passes_tricky(self):
        """ Check issue #34 for reference """
        line1 = "1 43125U 18004Q   18251.42128650 " \
            "+.00001666 +00000-0 +73564-4 0  9991"

        line2 = "2 43125 097.5269 314.3317 0010735 "\
            "157.6344 202.5362 15.23132245036381"

        orb = orbital.Orbital('LEMUR-2-BROWNCOW', line1=line1, line2=line2)
        d = datetime(2018, 9, 8)

        res = orb.get_next_passes(d, 72, -8.174163, 51.953319, 0.05, horizon=5)

        self.assertTrue(abs(
            res[0][2] - datetime(2018, 9, 8, 9, 5, 46, 375248)) <
            timedelta(seconds=0.01))
        self.assertTrue(abs(
            res[-1][2] - datetime(2018, 9, 10, 22, 15, 3, 143469)) <
            timedelta(seconds=0.01))

        self.assertTrue(len(res) == 15)
def lambda_handler(event, context):
    tle_path = '/tmp/tle'

    now = datetime.utcnow()

    with open('./awesome_satellites.json') as file_data:
        awesome_satellites = json.load(file_data)

    tlefile.fetch(tle_path)

    for satellite in awesome_satellites:
        sat_orbital = orbital.Orbital(satellite['name'], tle_file=tle_path)

        next_passes = sat_orbital.get_next_passes(now, 24, event['lon'],
                                                  event['lat'], event['alt'])

        for next_pass in next_passes:
            (start, end, maximum) = next_pass

            publish_sns({
                'satellite': satellite,
                'pass_begin': start.isoformat(),
                'pass_end': end.isoformat()
            })
Esempio n. 22
0
def get_next_passes(satellites,
                    utctime,
                    forward,
                    coords,
                    tle_file=None,
                    aqua_terra_dumps=None,
                    min_pass=MIN_PASS,
                    local_horizon=0):
    """Get the next passes for *satellites*, starting at *utctime*, for a
    duration of *forward* hours, with observer at *coords* ie lon (°E), lat
    (°N), altitude (km). Uses *tle_file* if provided, downloads from celestrack
    otherwise.

    Metop-A, Terra and Aqua need special treatment due to downlink restrictions.
    """
    passes = {}

    if tle_file is None and 'TLES' not in os.environ:
        fp_, tle_file = mkstemp(prefix="tle", dir="/tmp")
        os.close(fp_)
        logger.info("Fetch tle info from internet")
        tlefile.fetch(tle_file)

    if not os.path.exists(tle_file) and 'TLES' not in os.environ:
        logger.info("Fetch tle info from internet")
        tlefile.fetch(tle_file)

    for sat in satellites:
        if not hasattr(sat, 'name'):
            from trollsched.schedule import Satellite
            sat = Satellite(sat, 0, 0)

        satorb = orbital.Orbital(sat.name, tle_file=tle_file)
        passlist = satorb.get_next_passes(utctime,
                                          forward,
                                          horizon=local_horizon,
                                          *coords)

        if sat.name.lower() == "metop-a":
            # Take care of metop-a special case
            passes["metop-a"] = get_metopa_passes(sat, passlist, satorb)
        elif sat.name.lower() in ["aqua", "terra"] and aqua_terra_dumps:
            # Take care of aqua (dumps in svalbard and poker flat)
            # Get the Terra/Aqua passes and fill the passes dict:
            get_terra_aqua_passes(passes, utctime, forward, sat, passlist,
                                  satorb, aqua_terra_dumps)
        else:
            if sat.name.upper() in VIIRS_PLATFORM_NAMES:
                instrument = "viirs"
            elif sat.name.lower().startswith(
                    "metop") or sat.name.lower().startswith("noaa"):
                instrument = "avhrr"
            elif sat.name.lower() in ["aqua",
                                      "terra"]:  # when aqua_terra_dumps=False
                instrument = "modis"
            elif sat.name.upper() in MERSI_PLATFORM_NAMES:
                instrument = "mersi"
            elif sat.name.upper() in MERSI2_PLATFORM_NAMES:
                instrument = "mersi-2"
            else:
                instrument = "unknown"

            passes[sat.name] = [
                Pass(sat,
                     rtime,
                     ftime,
                     orb=satorb,
                     uptime=uptime,
                     instrument=instrument)
                for rtime, ftime, uptime in passlist
                if ftime - rtime > timedelta(minutes=MIN_PASS)
            ]

    return set(fctools_reduce(operator.concat, list(passes.values())))
Esempio n. 23
0
# --------------------------------------------------------------------------- #
# Read command line arguments
argv = sys.argv
if len(argv) < 2:
    print "Usage: python orbit.py <TLE_FILENAME>"

TLE_FILENAME = argv[1]
CALC_START = datetime.utcnow()
CALC_PERIOD = 12 * 3600
CALC_RESOLUTION = 30
OBSERVATOR = (51.049754, 13.757227, 92.0)

# --------------------------------------------------------------------------- #
SATNAME = os.path.basename(TLE_FILENAME)[0:-4]
orbit = orbital.Orbital(SATNAME, TLE_FILENAME)
OBSERV_PARAM = (OBSERVATOR[1], OBSERVATOR[0], OBSERVATOR[2])

# --------------------------------------------------------------------------- #
# calculate all positions
calculated = []
startTimestamp = time.mktime(CALC_START.timetuple())
startDatetime = CALC_START
incTimestamp = CALC_RESOLUTION
incDatetime = timedelta(seconds=CALC_RESOLUTION)
endTimestamp = startTimestamp + CALC_PERIOD
nowDatetime = CALC_START
nowTimestamp = startTimestamp
while nowTimestamp < endTimestamp:
    coordSpherical = orbit.get_lonlatalt(nowDatetime)
    coordObserver = orbit.get_observer_look(nowDatetime, *OBSERV_PARAM)
Esempio n. 24
0
def get_orbitnumbers_to_nppfile(npp_file):
    """Browse the RDR/SDR file and get granule start/end times, and determine
    the correct orbit numbers for those times, to be later corrected in the
    file."""
    fobj = h5py.File(npp_file, 'r')

    # First get all start and end date/time of the granules:
    obstimes = {}
    start_obstime = None
    end_obstime = None
    for group in fobj['/Data_Products'].keys():
        for dset in fobj['/Data_Products'][group]:
            # Get begining and ending date/time:
            for begin_end in ['Beginning', 'Ending']:
                try:
                    time_key = 'Aggregate' + begin_end + 'Time'
                    date_key = 'Aggregate' + begin_end + 'Date'
                    x_date = fobj['/Data_Products'][group][dset].attrs[
                        date_key]
                    x_time = fobj['/Data_Products'][group][dset].attrs[
                        time_key]
                    if not start_obstime and begin_end == 'Beginning':
                        # Ex.: '20120405'+'021645'
                        datetime_str = (x_date[0][0] +
                                        x_time[0][0].split('.')[0])
                        start_obstime = datetime.strptime(
                            datetime_str, '%Y%m%d%H%M%S')
                    if not end_obstime and begin_end == 'Ending':
                        # Ex.: '20120405'+'021645'
                        datetime_str = (x_date[0][0] +
                                        x_time[0][0].split('.')[0])
                        end_obstime = datetime.strptime(
                            datetime_str, '%Y%m%d%H%M%S')
                except KeyError:
                    time_key = begin_end + '_Time'
                    date_key = begin_end + '_Date'
                    x_date = fobj['/Data_Products'][group][dset].attrs[
                        date_key]
                    x_time = fobj['/Data_Products'][group][dset].attrs[
                        time_key]

                datetime_str = (x_date[0][0] + x_time[0][0].split('.')[0])
                obstimes[group + dset + begin_end] = datetime.strptime(
                    datetime_str, '%Y%m%d%H%M%S')

    fobj.close()

    if not start_obstime and not end_obstime:
        raise IOError("Failed getting the granule start and end times")

    # Check for no date (1958) problem:
    dt1958 = datetime(1958, 1, 1)
    if abs(start_obstime - dt1958) < timedelta(days=2):
        print("Start time wrong: %s" % start_obstime.strftime('%Y%m%d'))
        print("Will use the end time to determine orbit number")
        if abs(end_obstime - dt1958) < timedelta(days=2):
            raise IOError("Both start time and end time is far off in file!")
        obstime = end_obstime
    else:
        obstime = start_obstime

    sat = orb.Orbital('SUOMI NPP')

    # Get the start orbit number:
    orbits = {}
    start_orbnum = sat.get_orbit_number(obstime)
    orbits['start'] = start_orbnum

    # Get all orbit numbers for the swath.
    # Check for erroneous date-times (1958):
    prev_okay_obstime = obstime
    for key in obstimes:
        if abs(obstimes[key] - dt1958) < timedelta(days=2):
            obstime = prev_okay_obstime
        else:
            obstime = obstimes[key]

        orbits[key] = sat.get_orbit_number(obstime)

    print("Orbit numbers in swath:")
    for key in obstimes:
        print(orbits[key], )
    print()

    return orbits
def cubesat_t(cubesat, x):
    TCP_IP = '127.0.0.1'
    TCP_PORT = 5005
    BUFFER_SIZE = 1024
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    if x == 1:
        s.connect((TCP_IP, TCP_PORT))
    response = urllib2.urlopen(
        'http://celestrak.com/NORAD/elements/cubesat.txt')
    html = response.read()
    f = open('tle1.txt', 'r+')
    f.write(html)
    f.close()
    tle = tlefile.read(cubesat, 'tle1.txt')
    inc = tle.inclination
    print(inc)
    lon, lat = -1.394, 50.9354
    alt = 41
    utc_time = datetime.datetime.utcnow()

    passhrs = 20
    o = orbital.Orbital('tisat 1', 'tle1.txt')
    print(o)
    p = o.get_next_passes(utc_time, passhrs, lon, lat, alt)
    print(p)
    for i in range(0, len(p)):
        d1 = o.get_observer_look(p[i][0], lon, lat, alt)
        d2 = o.get_observer_look(p[i][1], lon, lat, alt)
        d3 = o.get_observer_look(p[i][2], lon, lat, alt)
        print(i + 1)
        print 'start time:', p[i][0]
        print 'AOS azimuth, elevation:', d1[0], d1[1]
        print 'maximum elevation time:', p[i][2]
        print 'Max azimuth, elevation:', d3[0], d3[1]
        print 'end time:', p[i][1]
        print 'LOS azimuth, elevation:', d2[0], d2[1]
    ip = 0
    t = [1]
    for i in range(len(t)):
        l = p[i][0]
        dt = 2
        if l.minute != 0 and l.minute != 1:
            utctime2 = datetime.datetime(l.year, l.month, l.day, l.hour,
                                         l.minute - 2, l.second)
        else:
            utctime2 = datetime.datetime(l.year, l.month, l.day, l.hour - 1,
                                         59, l.second)
        if (utctime2.second % 2 == 0):
            utctime1 = utctime2
        else:
            utctime2 = datetime.datetime(l.year, l.month, l.day, l.hour - 1,
                                         59, l.second - 1)
            utctime1 = utctime2
        while p[i][1] >= utctime1:
            if utctime1.second < 58:
                utctime1 = datetime.datetime(utctime1.year, utctime1.month,
                                             utctime1.day, utctime1.hour,
                                             utctime1.minute,
                                             utctime1.second + dt)
            elif utctime1.second == 58:
                if utctime1.minute < 59:
                    utctime1 = datetime.datetime(utctime1.year, utctime1.month,
                                                 utctime1.day, utctime1.hour,
                                                 utctime1.minute + 1, 0)
                elif utctime1.minute == 59:
                    if utctime1.hour < 23:
                        utctime1 = datetime.datetime(utctime1.year,
                                                     utctime1.month,
                                                     utctime1.day,
                                                     utctime1.hour + 1, 0, 0)
                    elif utctime1.hour == 23:
                        if utctime1.month in [1, 3, 5, 7, 8, 10, 12
                                              ] and utctime1.day < 31:
                            utctime1 = datetime.datetime(
                                utctime1.year, utctime1.month,
                                utctime1.day + 1, 0, 0, 0)
                        elif utctime1.month in [1, 3, 5, 7, 8, 10, 12
                                                ] and utctime1.day == 31:
                            utctime1 = datetime.datetime(
                                utctime1.year, utctime1.month + 1, 1, 0, 0, 0)
                        elif utctime1.month in [4, 6, 9, 11
                                                ] and utctime1.month < 30:
                            utctime1 = datetime.datetime(
                                utctime1.year, utctime1.day, utctime1.day + 1,
                                0, 0, 0)
                        elif utctime1.month in [4, 6, 9, 11
                                                ] and utctime1.month == 30:
                            utctime1 = datetime.datetime(
                                utctime1.year, utctime1.day + 1, 1, 0, 0, 0)
            if p[i][0] <= utctime1:
                look = o.get_observer_look(utctime1, lon, lat, alt)
                "print look,utctime1"
                angle = ["%.3G" % (look[0]), "%.3G" % (look[1])]
                msg1 = str(angle[0]) + ',' + str(angle[1])
                if x == 1:
                    s.send(msg1)
                print msg1
                time.sleep(2)
            ip = ip + 1
    return ()
Esempio n. 26
0
def get_location_time(satellite_name, unix_UTC_time):
    satellite = orbital.Orbital(satellite_name)
    return satellite.get_position(datetime.utcfromtimestamp(unix_UTC_time))
Esempio n. 27
0
    def setUp(self):
        """Set up"""
        from pyorbital import orbital
        from trollsched.schedule import Satellite

        self.utctime = datetime(2018, 11, 28, 10, 0)
        self.satellites = [
            "noaa-20",
        ]
        self.tles = {'noaa-20': {}}
        self.tles['noaa-20'][
            'line1'] = "1 43013U 17073A   18331.00000000  .00000048  00000-0  22749-4 0  3056"
        self.tles['noaa-20'][
            'line2'] = "2 43013 098.7413 267.0121 0001419 108.5818 058.1314 14.19552981053016"

        self.aquas = [
            "aqua",
        ]
        self.terras = [
            "terra",
        ]
        self.terra = Satellite('terra', 0, 0)
        self.metopa = Satellite('metop-a', 0, 0)

        self.tles['aqua'] = {}
        self.tles['aqua'][
            'line1'] = "1 27424U 02022A   18332.21220389  .00000093  00000-0  30754-4 0  9994"
        self.tles['aqua'][
            'line2'] = "2 27424  98.2121 270.9368 0001045 343.9225 155.8703 14.57111538881313"
        self.tles['terra'] = {}
        self.tles['terra'][
            'line1'] = "1 25994U 99068A   18338.20920286  .00000076  00000-0  26867-4 0  9999"
        self.tles['terra'][
            'line2'] = "2 25994  98.2142  50.5750 0000577 102.5211 257.6060 14.57132862  8586"
        self.tles['metop-a'] = {}
        self.tles['metop-a'][
            'line1'] = "1 29499U 06044A   18338.30873671  .00000000  00000+0  31223-4 0 00013"
        self.tles['metop-a'][
            'line2'] = "2 29499  98.6045  31.7725 0001942  91.8780 346.4884 14.21536046629175"

        self.orb = orbital.Orbital('NOAA 20',
                                   line1=self.tles['noaa-20']['line1'],
                                   line2=self.tles['noaa-20']['line2'])
        self.aqua_orb = orbital.Orbital('AQUA',
                                        line1=self.tles['aqua']['line1'],
                                        line2=self.tles['aqua']['line2'])
        self.terra_orb = orbital.Orbital('TERRA',
                                         line1=self.tles['terra']['line1'],
                                         line2=self.tles['terra']['line2'])
        self.metopa_orb = orbital.Orbital('Metop-A',
                                          line1=self.tles['metop-a']['line1'],
                                          line2=self.tles['metop-a']['line2'])

        # These values were used to generate the get_next_passes list mock:
        # utctime = datetime(2018, 12, 4, 9, 0)
        # forward = 6
        # coords = (16, 58, 0)
        self.metopa_passlist = [
            (datetime(2018, 12, 4, 9, 10, 4,
                      574801), datetime(2018, 12, 4, 9, 25, 29, 157194),
             datetime(2018, 12, 4, 9, 17, 48, 530484)),
            (datetime(2018, 12, 4, 10, 50, 23,
                      899232), datetime(2018, 12, 4, 11, 4, 2, 335184),
             datetime(2018, 12, 4, 10, 57, 13, 691637)),
            (datetime(2018, 12, 4, 12, 30, 24,
                      97160), datetime(2018, 12, 4, 12, 40, 42, 403698),
             datetime(2018, 12, 4, 12, 35, 33, 317647)),
            (datetime(2018, 12, 4, 14, 9, 1,
                      937869), datetime(2018, 12, 4, 14, 17, 20, 556654),
             datetime(2018, 12, 4, 14, 13, 11, 247497))
        ]

        self.dumpdata = [{
            'los': datetime(2018, 11, 28, 10, 0, 30),
            'station': 'USAK05',
            'aos': datetime(2018, 11, 28, 9, 50, 24),
            'elev': '11.188'
        }, {
            'los': datetime(2018, 11, 28, 11, 39, 47),
            'station': 'AS2',
            'aos': datetime(2018, 11, 28, 11, 28, 51),
            'elev': '39.235'
        }, {
            'los': datetime(2018, 11, 28, 13, 19, 8),
            'station': 'USAK05',
            'aos': datetime(2018, 11, 28, 13, 6, 36),
            'elev': '58.249'
        }, {
            'los': datetime(2018, 11, 28, 14, 54, 25),
            'station': 'AS2',
            'aos': datetime(2018, 11, 28, 14, 44, 37),
            'elev': '22.403'
        }, {
            'los': datetime(2018, 11, 28, 16, 27, 22),
            'station': 'SG1',
            'aos': datetime(2018, 11, 28, 16, 16, 58),
            'elev': '9.521'
        }]
        self.dumpdata_terra = [{
            'los': datetime(2018, 11, 20, 23, 24, 41),
            'station': 'SG2',
            'aos': datetime(2018, 11, 20, 23, 12, 32),
            'elev': '17.4526'
        }, {
            'los': datetime(2018, 11, 22, 23, 19, 21),
            'station': 'AS3',
            'aos': datetime(2018, 11, 22, 23, 8, 55),
            'elev': '28.9558'
        }, {
            'los': datetime(2018, 11, 22, 23, 19, 21),
            'station': 'AS3',
            'aos': datetime(2018, 11, 22, 23, 8, 55),
            'elev': '28.9558'
        }, {
            'los': datetime(2018, 11, 26, 22, 47, 34),
            'station': 'SG1',
            'aos': datetime(2018, 11, 26, 22, 34, 58),
            'elev': '21.5694'
        }, {
            'los': datetime(2018, 11, 26, 22, 47, 34),
            'station': 'SG1',
            'aos': datetime(2018, 11, 26, 22, 34, 58),
            'elev': '21.5694'
        }, {
            'los': datetime(2018, 11, 26, 22, 47, 34),
            'station': 'SG1',
            'aos': datetime(2018, 11, 26, 22, 34, 58),
            'elev': '21.5694'
        }, {
            'los': datetime(2018, 11, 27, 23, 30, 44),
            'station': 'SG2',
            'aos': datetime(2018, 11, 27, 23, 18, 39),
            'elev': '16.8795'
        }, {
            'los': datetime(2018, 11, 27, 23, 30, 44),
            'station': 'SG2',
            'aos': datetime(2018, 11, 27, 23, 18, 39),
            'elev': '16.8795'
        }, {
            'los': datetime(2018, 11, 28, 22, 43, 53),
            'station': 'USAK05',
            'aos': datetime(2018, 11, 28, 22, 31, 57),
            'elev': '40.9264'
        }, {
            'los': datetime(2018, 11, 28, 22, 43, 53),
            'station': 'USAK05',
            'aos': datetime(2018, 11, 28, 22, 31, 57),
            'elev': '40.9264'
        }, {
            'los': datetime(2018, 11, 29, 23, 25, 11),
            'station': 'USAK05',
            'aos': datetime(2018, 11, 29, 23, 14, 47),
            'elev': '26.9937'
        }, {
            'los': datetime(2018, 11, 29, 23, 25, 11),
            'station': 'USAK05',
            'aos': datetime(2018, 11, 29, 23, 14, 47),
            'elev': '26.9937'
        }, {
            'los': datetime(2018, 11, 30, 22, 31, 3),
            'station': 'AS2',
            'aos': datetime(2018, 11, 30, 22, 19, 48),
            'elev': '47.8599'
        }, {
            'los': datetime(2018, 12, 1, 1, 29, 2),
            'station': 'WG1',
            'aos': datetime(2018, 12, 1, 1, 21, 11),
            'elev': '8.0543'
        }, {
            'los': datetime(2018, 11, 30, 22, 31, 3),
            'station': 'AS2',
            'aos': datetime(2018, 11, 30, 22, 19, 48),
            'elev': '47.8599'
        }, {
            'los': datetime(2018, 12, 1, 1, 29, 2),
            'station': 'WG1',
            'aos': datetime(2018, 12, 1, 1, 21, 11),
            'elev': '8.0543'
        }, {
            'los': datetime(2018, 12, 3, 1, 28, 14),
            'station': 'SG2',
            'aos': datetime(2018, 12, 3, 1, 17, 53),
            'elev': '9.2428'
        }, {
            'los': datetime(2018, 12, 3, 22, 53, 35),
            'station': 'SG1',
            'aos': datetime(2018, 12, 3, 22, 41, 5),
            'elev': '20.8371'
        }, {
            'los': datetime(2018, 12, 3, 22, 53, 35),
            'station': 'SG1',
            'aos': datetime(2018, 12, 3, 22, 41, 5),
            'elev': '20.8371'
        }, {
            'los': datetime(2018, 12, 4, 23, 43, 5),
            'station': 'AS2',
            'aos': datetime(2018, 12, 4, 23, 33, 8),
            'elev': '23.546'
        }]
Esempio n. 28
0
from datetime import datetime

from tabulate import tabulate
from pyorbital import orbital

# --------------------------------------------------------------------------- #
satCache = {}
tleList = os.listdir('./tlefiles')
for each in tleList:
    fullpath = os.path.join('tlefiles', each)
    if not os.path.isfile(fullpath):
        continue
    if not each.endswith('.tle'):
        continue
    satName = each[0:-4].lower()
    satCache[satName] = orbital.Orbital(satName, fullpath)

# --------------------------------------------------------------------------- #

OBSERVATOR = (51.049754, 13.757227, 92.0)
NOWTIME = datetime.utcnow()
EMAX_MINIMAL = 10.0 # minimal max-elevation for calculating satellite passes
PASS_PERIOD = 24 # hours for calculating next passes

# --------------------------------------------------------------------------- #
# calculate all passes of all satellites
calculated = []

OBSERV_PARAM = (OBSERVATOR[1], OBSERVATOR[0], OBSERVATOR[2])
for satName in satCache:
    sat = satCache[satName]
Esempio n. 29
0
def generate_process_config(msg, config):
    """
    Check sensors to process and setup config for this

    Need to check if it is a collection or file message. Then get sensor information from this.
    """

    # All possible instruments to process initialized to false.
    config['process_amsua'] = False
    config['process_amsub'] = False
    config['process_hirs'] = False
    config['process_avhrr'] = False
    config['process_msu'] = False
    config['process_mhs'] = False
    config['process_dcs'] = False

    # Check sensors and file as given in the incomming message
    # Note: zip iterates two list at the same time
    if 'dataset' in msg.data:
        LOG.debug("Checking dataset")
        for sensor, sensor_filename in zip(msg.data['sensor'],
                                           msg.data['dataset']):
            LOG.debug("{} {}".format(sensor, sensor_filename['uri']))
            process_name = "process_{}".format(
                config['aapp_static_configuration']
                ['sensor_name_converter'].get(sensor, sensor))
            config[process_name] = True

            # Name of the input file for given instrument
            input_file_name = "input_{}_file".format(
                config['aapp_static_configuration']
                ['sensor_name_converter'].get(sensor, sensor))
            # print urlparse(sensor_filename['uri']).path
            config[input_file_name] = urlparse(sensor_filename['uri']).path

    elif 'uri' in msg.data:
        LOG.debug("Checking uri")
        # Need to force list
        if type(msg.data["sensor"]) not in (tuple, list, set):
            msg.data["sensor"] = [msg.data["sensor"]]

        LOG.debug("sensor: {}".format(msg.data["sensor"]))

        for sensor in msg.data['sensor']:
            process_name = "process_{}".format(
                config['aapp_static_configuration']
                ['sensor_name_converter'].get(sensor, sensor))
            LOG.debug("{} {}".format(sensor, process_name))
            config[process_name] = True

            # For POES 18 and 19 and the METOPs there are MHS. but no AMSU-B.
            # AAPP processing handles MHS as AMSU-B
            if (('NOAA' in msg.data['platform_name'].upper()
                 and int(msg.data['platform_name'][-2:]) >= 18) or
                ('METOP' in msg.data['platform_name'].upper())
                ) and config['process_mhs']:
                config['process_amsub'] = True

            # Name of the input file for given instrument
            # Needed for METOP processing
            input_file_name = "input_{}_file".format(
                config['aapp_static_configuration']
                ['sensor_name_converter'].get(sensor, sensor))
            config[input_file_name] = urlparse(msg.data['uri']).path

        # Needed for POES processing
        config['input_hrpt_file'] = urlparse(msg.data['uri']).path

    else:
        LOG.error(
            "Could not find needed dataset or uri in message. Can not handle.")
        return False

    # Be sure to set MHS process to False for NOAA15 as there is no MHS, but amsu-b
    if ('NOAA' in msg.data['platform_name'].upper() and int(
            msg.data['platform_name'][-2:]) == 15) and config['process_mhs']:
        config['process_mhs'] = False

    # Check if processing for this platform should be altered
    # due to config.
    if 'instrument_skipped_in_processing' in config['aapp_processes'][
            config.process_name]:
        for platform_name in config['aapp_processes'][
                config.process_name]['instrument_skipped_in_processing']:
            _platform_name = platform_name.keys()[0]
            if _platform_name.upper() == msg.data['platform_name'].upper():
                for sensor in msg.data['sensor']:
                    for skip_sensor in platform_name[_platform_name]:
                        if skip_sensor == sensor:
                            process_name = "process_{}".format(
                                config['aapp_static_configuration']
                                ['sensor_name_converter'].get(sensor, sensor))
                            if config[process_name]:
                                LOG.debug(
                                    "Skipping processing of sensor: {} as of config."
                                    .format(skip_sensor))
                                config[process_name] = False

    config['calibration_location'] = "-c -l"
    config['a_tovs'] = list("ATOVS")

    if 'keep_orbit_number_from_message' in config['aapp_processes'][
            config.process_name] and 'orbit_number' in msg.data:
        config['orbit_number'] = int(msg.data['orbit_number'])
    else:
        # Check the case of no orbit number in message, typically EARS stream
        start_orbnum = None
        try:
            import pyorbital.orbital as orb
            LOG.debug("platform_name: {}".format(msg.data['platform_name']))
            sat = orb.Orbital(config['aapp_static_configuration']
                              ['tle_platform_name_aliases'].get(
                                  msg.data['platform_name'],
                                  msg.data['platform_name']))
            start_orbnum = sat.get_orbit_number(msg.data['start_time'])
        except ImportError:
            LOG.warning("Failed importing pyorbital, " +
                        "cannot calculate orbit number")
        except AttributeError:
            LOG.warning("Failed calculating orbit number using pyorbital")
            LOG.warning("platform name in msg and config = " + str(
                config['aapp_static_configuration']
                ['tle_platform_name_aliases'].get(msg.data['platform_name'],
                                                  msg.data['platform_name'])) +
                        " " + str(config['platform_name']))
        LOG.info("Orbit number determined from pyorbital = " +
                 str(start_orbnum))
        try:
            config['orbit_number'] = int(msg.data['orbit_number'])
        except KeyError:
            LOG.warning("No orbit_number in message! Set to none...")
            config['orbit_number'] = None

        if start_orbnum and config['orbit_number'] != start_orbnum:
            LOG.warning("Correcting orbit number: Orbit now = " +
                        str(start_orbnum) + " Before = " +
                        str(config['orbit_number']))
            config['orbit_number'] = start_orbnum
        else:
            LOG.debug("Orbit number in message determined"
                      "to be okay and not changed...")
            config['orbit_number'] = int(msg.data['orbit_number'])

    # How to give the platform name?
    # Which format?
    # Used are for Metop:
    #Metop-A/'Metop A'/'METOP A'
    # M02
    # metop02
    # Throughout this processing the last convention is used!
    if msg.data['platform_name'] in config['aapp_static_configuration'][
            'platform_name_aliases']:
        config['platform_name'] = config['aapp_static_configuration'][
            'platform_name_aliases'][msg.data['platform_name']]
        # print config['platform_name']
        # TODO Should not use satellite_name

        config['satellite_name'] = config['platform_name']
    else:
        LOG.error(
            "Failed to replace platform_name: {}. Can not continue.".format(
                msg.data['platform_name']))
        return False

    config['start_time'] = msg.data['start_time']

    return True
Esempio n. 30
0
class AappLvl1Processor(object):
    """
    Container for the Metop/NOAA level-1 processing based on AAPP

    """
    def __init__(self):

        self.lvl1_home = OPTIONS['aapp_out_dir']
        self.fullswath = True  # Always a full swath (never HRPT granules)
        self.ishmf = False
        self.working_dir = None
        self.level0_filename = None
        self.starttime = None
        self.endtime = None
        self.platform_name = "Unknown"
        self.satnum = "0"
        self.orbit = "00000"
        self.result_files = None
        self.level0files = None

        self.job_register = {}

        self.initialise()

    def initialise(self):
        """Initialise the processor"""
        self.working_dir = None
        self.level0_filename = None
        self.starttime = None
        self.endtime = None
        self.platform_name = "Unknown"
        self.satnum = "0"
        self.orbit = "00000"
        self.result_files = []
        self.level0files = {}

    def cleanup_aapp_workdir(self):
        """Clean up the AAPP working dir after processing"""

        filelist = glob('%s/*' % self.working_dir)
        dummy = [os.remove(s) for s in filelist if os.path.isfile(s)]
        filelist = glob('%s/*' % self.working_dir)
        LOG.info("Number of items left after cleaning working dir = " +
                 str(len(filelist)))
        LOG.debug("Files: " + str(filelist))
        shutil.rmtree(self.working_dir)
        return

    def pack_aapplvl1_files(self, subd):
        return pack_aapplvl1_files(self.result_files, self.lvl1_home, subd,
                                   self.satnum)

    def move_lvl1dir(self):
        if len(self.result_files) == 0:
            LOG.warning("No files in directory to move!")
            return {}

        # Get the subdirname:
        path = os.path.dirname(self.result_files[0])
        subd = os.path.basename(path)
        LOG.debug("path = " + str(path))
        LOG.debug("lvl1_home = " + self.lvl1_home)
        try:
            shutil.move(path, self.lvl1_home)
        except shutil.Error:
            LOG.warning("Directory already exists: " + str(subd))

        if self.orbit == '00000' or self.orbit == None:
            # Extract the orbit number from the sub-dir name:
            dummy, dummy, dummy, self.orbit = subd.split('_')

        # Return a dict with sensor and level for each filename:
        filenames = glob(os.path.join(self.lvl1_home, subd, '*'))
        LOG.info(filenames)

        retv = {}
        for fname in filenames:
            mstr = os.path.basename(fname).split('_')[0]
            if mstr == 'hrpt':
                lvl = '1b'
                instr = 'avhrr/3'
            else:
                lvl = mstr[-2:]
                try:
                    instr = SENSOR_NAME_CONVERTER[mstr[0:-3]]
                except KeyError:
                    LOG.warning("Sensor name will not be converted %s" %
                                str(mstr[0:-3]))
                    LOG.debug("mstr = " + str(mstr))
                    instr = mstr[0:-3]

            retv[fname] = {'level': lvl, 'sensor': instr}

        LOG.info(str(retv))

        return retv

    def run(self, msg):
        """Start the AAPP level 1 processing on either a NOAA HRPT file or a
        set of Metop HRPT files"""

        # Avoid 'collections' and other stuff:
        if msg is None or msg.type != 'file':
            return True

        LOG.debug("Received message: " + str(msg))
        LOG.debug("Supported Metop satellites: " +
                  str(SUPPORTED_METOP_SATELLITES))
        try:
            if (msg.data['platform_name'] not in SUPPORTED_NOAA_SATELLITES
                    and msg.data['platform_name']
                    not in SUPPORTED_METOP_SATELLITES):
                LOG.info("Not a NOAA/Metop scene. Continue...")
                return True
        except Exception, err:
            LOG.warning(str(err))
            return True

        self.platform_name = msg.data['platform_name']
        LOG.debug("Satellite = " + str(self.platform_name))

        LOG.debug("")
        LOG.debug("\tMessage:")
        LOG.debug(str(msg))
        urlobj = urlparse(msg.data['uri'])
        server = urlobj.netloc
        LOG.debug('Server = <' + str(server) + '>')
        if len(server) > 0 and server != SERVERNAME:
            LOG.warning("Server %s not the current one: %s" %
                        (str(server), SERVERNAME))
            return True

        LOG.info("Ok... " + str(urlobj.netloc))
        LOG.info("Sat and Sensor: " + str(msg.data['platform_name']) + " " +
                 str(msg.data['sensor']))

        self.starttime = msg.data['start_time']
        try:
            self.endtime = msg.data['end_time']
        except KeyError:
            LOG.warning(
                "No end_time in message! Guessing start_time + 14 minutes...")
            self.endtime = msg.data['start_time'] + timedelta(seconds=60 * 14)

        start_orbnum = None
        try:
            import pyorbital.orbital as orb
            sat = orb.Orbital(
                TLE_SATNAME.get(self.platform_name, self.platform_name))
            start_orbnum = sat.get_orbit_number(self.starttime)
        except ImportError:
            LOG.warning("Failed importing pyorbital, " +
                        "cannot calculate orbit number")
        except AttributeError:
            LOG.warning("Failed calculating orbit number using pyorbital")
            LOG.warning(
                "platform name = " +
                str(TLE_SATNAME.get(self.platform_name, self.platform_name)) +
                " " + str(self.platform_name))

        LOG.info("Orbit number determined from pyorbital = " +
                 str(start_orbnum))
        try:
            self.orbit = int(msg.data['orbit_number'])
        except KeyError:
            LOG.warning("No orbit_number in message! Set to none...")
            self.orbit = None

        if start_orbnum and self.orbit != start_orbnum:
            LOG.warning("Correcting orbit number: Orbit now = " +
                        str(start_orbnum) + " Before = " + str(self.orbit))
            self.orbit = start_orbnum
        else:
            LOG.debug(
                'Orbit number in message determined to be okay and not changed...'
            )

        if self.platform_name in SUPPORTED_METOP_SATELLITES:
            metop_id = SATELLITE_NAME[self.platform_name].split('metop')[1]
            self.satnum = METOP_NUMBER.get(metop_id, metop_id)
        else:
            self.satnum = SATELLITE_NAME[self.platform_name].strip('noaa')

        year = self.starttime.year
        keyname = str(self.platform_name)
        LOG.debug("Keyname = " + str(keyname))
        LOG.debug("Start: job register = " + str(self.job_register))

        # Use sat id, start and end time as the unique identifier of the scene!
        if keyname in self.job_register and len(
                self.job_register[keyname]) > 0:
            # Go through list of start,end time tuples and see if the current
            # scene overlaps with any:
            status = overlapping_timeinterval((self.starttime, self.endtime),
                                              self.job_register[keyname])
            if status:
                LOG.warning(
                    "Processing of scene " + keyname + " " + str(status[0]) +
                    " " + str(status[1]) +
                    " with overlapping time have been launched previously")
                LOG.info("Skip it...")
                return True
            else:
                LOG.debug("No overlap with any recently processed scenes...")

        scene_id = (str(self.platform_name) + '_' +
                    self.starttime.strftime('%Y%m%d%H%M%S') + '_' +
                    self.endtime.strftime('%Y%m%d%H%M%S'))
        LOG.debug("scene_id = " + str(scene_id))

        # Check for keys representing the same scene (slightly different
        # start/end times):
        LOG.debug("Level-0files = " + str(self.level0files))
        for key in self.level0files:
            pltrfn, startt, endt = key.split('_')
            if not self.platform_name == pltrfn:
                continue
            t1_ = datetime.strptime(startt, '%Y%m%d%H%M%S')
            t2_ = datetime.strptime(endt, '%Y%m%d%H%M%S')
            if (abs(self.starttime - t1_).seconds < 60
                    and abs(self.endtime - t2_).seconds < 60):
                # It is the same scene!
                LOG.debug(
                    "It is the same scene, though the file times differ a bit..."
                )
                scene_id = key
                break

        LOG.debug("scene_id = " + str(scene_id))
        if scene_id in self.level0files:
            LOG.debug("Level-0files = " + str(self.level0files[scene_id]))
        else:
            LOG.debug("No level-0files yet...")

        self.level0_filename = urlobj.path
        dummy, fname = os.path.split(self.level0_filename)

        if fname.find('.hmf') > 0:
            self.ishmf = True
        else:
            LOG.info("File is not a hmf file, " +
                     "probably a Metop file or a NOAA from DMI: " + str(fname))

        LOG.debug("Sensor = " + str(msg.data['sensor']))
        LOG.debug("type: " + str(type(msg.data['sensor'])))
        if type(msg.data['sensor']) in [str, unicode]:
            sensors = [msg.data['sensor']]
        elif type(msg.data['sensor']) is list:
            sensors = msg.data['sensor']
        else:
            sensors = []
            LOG.warning('Failed interpreting sensor(s)!')

        LOG.info("Sensor(s): " + str(sensors))
        sensor_ok = False
        for sensor in sensors:
            if sensor in SENSOR_NAMES:
                sensor_ok = True
                break
        if not sensor_ok:
            LOG.info("No required sensors....")
            return True

        if scene_id not in self.level0files:
            LOG.debug("Reset level0files: scene_id = " + str(scene_id))
            self.level0files[scene_id] = []

        for sensor in sensors:
            item = (self.level0_filename, sensor)
            if item not in self.level0files[scene_id]:
                self.level0files[scene_id].append(item)
                LOG.debug("Appending item to list: " + str(item))
            else:
                LOG.debug("item already in list: " + str(item))

        if len(self.level0files[scene_id]) < 4:
            LOG.info("Not enough sensor data available yet. " +
                     "Level-0files = " + str(self.level0files[scene_id]))
            return True
        else:
            LOG.info("Level 0 files ready: " + str(self.level0files[scene_id]))

        if not self.working_dir:
            try:
                self.working_dir = tempfile.mkdtemp(dir=AAPP_WORKDIR)
            except OSError:
                self.working_dir = tempfile.mkdtemp()
            finally:
                LOG.info("Create new working dir...")

        LOG.info("Working dir = " + str(self.working_dir))

        my_env = os.environ.copy()
        my_env['DYN_WRK_DIR'] = self.working_dir
        LOG.info("working dir: self.working_dir = " + str(self.working_dir))
        for envkey in my_env:
            LOG.debug("ENV: " + str(envkey) + " " + str(my_env[envkey]))

        if self.platform_name in SUPPORTED_NOAA_SATELLITES:
            LOG.info("This is a NOAA scene. Start the NOAA processing!")
            LOG.info("Process the file %s" % self.level0_filename)

            cmdseq = (NOAA_RUN_SCRIPT + ' -Y ' + str(year) + ' ' +
                      self.level0_filename)
            LOG.info("Command sequence: " + str(cmdseq))
            # Run the command:
            aapplvl1_proc = Popen(cmdseq,
                                  cwd=self.working_dir,
                                  shell=True,
                                  env=my_env,
                                  stderr=PIPE,
                                  stdout=PIPE)

        elif self.platform_name in SUPPORTED_METOP_SATELLITES:
            LOG.info("This is a Metop scene. Start the METOP processing!")
            LOG.info("Process the scene %s %s" %
                     (self.platform_name, str(self.orbit)))

            sensor_filename = {}
            for (fname, instr) in self.level0files[scene_id]:
                sensor_filename[instr] = os.path.basename(fname)

            for instr in sensor_filename.keys():
                if instr not in SENSOR_NAMES:
                    LOG.error("Sensor name mismatch! name = " + str(instr))
                    return True

            cmdstr = "%s -d %s -a %s -u %s -m %s -h %s -o %s" % (
                METOP_RUN_SCRIPT, METOP_IN_DIR, sensor_filename['avhrr/3'],
                sensor_filename['amsu-a'], sensor_filename['mhs'],
                sensor_filename['hirs/4'], AAPP_OUT_DIR)
            LOG.info("Command sequence: " + str(cmdstr))
            # Run the command:
            aapplvl1_proc = Popen(cmdstr,
                                  cwd=self.working_dir,
                                  shell=True,
                                  env=my_env,
                                  stderr=PIPE,
                                  stdout=PIPE)

        # Taking the stderr before stdout seems to be better preventing a
        # hangup!  AD, 2013-03-07
        while True:
            line = nonblock_read(aapplvl1_proc.stderr)
            if not line:
                break
            LOG.info(line)

        while True:
            line = nonblock_read(aapplvl1_proc.stdout)
            if not line:
                break
            LOG.info(line)

        aapplvl1_proc.poll()
        dummy = aapplvl1_proc.returncode
        LOG.info("Before call to communicate:")
        out, err = aapplvl1_proc.communicate()

        lines = out.splitlines()
        for line in lines:
            LOG.info(line)

        lines = err.splitlines()
        for line in lines:
            LOG.info(line)

        LOG.info("Communicate done...")

        LOG.info("Ready with AAPP level-1 processing on NOAA scene: " +
                 str(fname))
        LOG.info("working dir: self.working_dir = " + str(self.working_dir))

        # Add to job register to avoid this to be run again
        if keyname not in self.job_register.keys():
            self.job_register[keyname] = []

        self.job_register[keyname].append((self.starttime, self.endtime))
        LOG.debug("End: job register = " + str(self.job_register))

        # Block any future run on this scene for x (e.g. 10) minutes from now
        t__ = threading.Timer(10 * 60.0,
                              reset_job_registry,
                              args=(self.job_register, str(self.platform_name),
                                    (self.starttime, self.endtime)))
        t__.start()

        LOG.debug("After timer call: job register = " + str(self.job_register))

        self.result_files = get_aapp_lvl1_files(self.working_dir,
                                                msg.data['platform_name'])

        LOG.info("Output files: " + str(self.result_files))

        statresult = aapp_stat.do_noaa_and_metop(
            self.level0_filename,
            SATELLITE_NAME.get(self.platform_name, self.platform_name),
            self.starttime)
        if os.path.exists(_AAPP_STAT_FILE):
            fd = open(_AAPP_STAT_FILE, "r")
            lines = fd.readlines()
            fd.close()
        else:
            lines = []

        lines = lines + [statresult + '\n']
        fd = open(_AAPP_STAT_FILE, "w")
        fd.writelines(lines)
        fd.close()

        return False