예제 #1
0
def get_next_passes(satellites,
                    utctime,
                    forward,
                    coords,
                    tle_file=None,
                    aqua_terra_dumps=None):
    """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, *coords)

        if sat.name == "metop-a":
            # Take care of metop-a
            passes["metop-a"] = get_metopa_passes(sat, passlist, satorb)

        elif sat.name 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.upper() in MERSI2_PLATFORM_NAMES:
                instrument = "mersi2"
            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())))
예제 #2
0
 def update(self, urls):
     """fetch supplied list of urls into tle.txt"""
     tlefile.fetch('/home/stacstation/eclipse-workspace/tle.txt', urls)
     """create separate tle file for each satellite in tle.txt"""
     file = open('/home/stacstation/eclipse-workspace/tle.txt')
     buffer = []
     i = 0
     for line in file:
         buffer.append(line)
         i += 1
         if i == 3:
             fileout = open(
                 '/home/stacstation/eclipse-workspace/%s.txt' %
                 (buffer[0].strip()), "w")
             for item in buffer:
                 fileout.write(item)
             i = 0
             buffer = []
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()
            })
예제 #4
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())))
예제 #5
0
def get_next_passes(satellites, utctime, forward, coords, tle_file=None):
    """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.
    """
    passes = {}
    orbitals = {}

    if tle_file is None:
        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):
        logger.info("Fetch tle info from internet")
        tlefile.fetch(tle_file)

    for sat in satellites:
        satorb = orbital.Orbital(sat, tle_file=tle_file)
        orbitals[sat] = satorb
        passlist = satorb.get_next_passes(utctime,
                                          forward,
                                          *coords)
        if sat.lower().startswith("metop") or sat.lower().startswith("noaa"):
            instrument = "avhrr"
        elif sat in ["aqua", "terra"]:
            instrument = "modis"
        elif sat.endswith("npp"):
            instrument = "viirs"
        else:
            instrument = "unknown"
        # take care of metop-a
        if sat == "metop-a":
            metop_passes = [Pass(sat, rtime, ftime, satorb, uptime, instrument)
                            for rtime, ftime, uptime in passlist if rtime < ftime]

            passes["metop-a"] = []
            for overpass in metop_passes:
                if overpass.pass_direction() == "descending":
                    new_rise = overpass.slsearch(60)
                    if new_rise is not None and new_rise < overpass.falltime:
                        overpass.risetime = new_rise
                        overpass.boundary = SwathBoundary(overpass)
                        if overpass.seconds() > MIN_PASS * 60:
                            passes["metop-a"].append(overpass)
        # take care of aqua (dumps in svalbard and poker flat)
        elif sat == "aqua":

            wpcoords = (-75.457222, 37.938611, 0)
            passlist_wp = satorb.get_next_passes(utctime - timedelta(minutes=30),
                                                 forward + 1,
                                                 *wpcoords)
            wp_passes = [Pass(sat, rtime, ftime, satorb, uptime, instrument)
                         for rtime, ftime, uptime in passlist_wp if rtime < ftime]

            svcoords = (15.399, 78.228, 0)
            passlist_sv = satorb.get_next_passes(utctime - timedelta(minutes=30),
                                                 forward + 1,
                                                 *svcoords)
            sv_passes = [Pass(sat, rtime, ftime, satorb, uptime, instrument)
                         for rtime, ftime, uptime in passlist_sv if rtime < ftime]
            pfcoords = (-147.43, 65.12, 0.51)
            passlist_pf = satorb.get_next_passes(utctime - timedelta(minutes=30),
                                                 forward + 1,
                                                 *pfcoords)
            pf_passes = [Pass(sat, rtime, ftime, satorb, uptime, instrument)
                         for rtime, ftime, uptime in passlist_pf if rtime < ftime]

            aqua_passes = [Pass(sat, rtime, ftime, satorb, uptime, instrument)
                           for rtime, ftime, uptime in passlist if rtime < ftime]

            dumps = get_aqua_dumps_from_ftp(utctime - timedelta(minutes=30),
                                            utctime +
                                            timedelta(hours=forward + 0.5),
                                            satorb)

            # remove the known dumps
            for dump in dumps:
                # print "*", dump.station, dump, dump.max_elev
                logger.debug("dump from ftp: " + str((dump.station, dump,
                                                      dump.max_elev)))
                for i, sv_pass in enumerate(sv_passes):
                    if sv_pass.overlaps(dump, timedelta(minutes=40)):
                        sv_elevation = sv_pass.orb.get_observer_look(sv_pass.uptime,
                                                                     *svcoords)[1]
                        logger.debug("Computed " + str(("SG", sv_pass,
                                                        sv_elevation)))
                        del sv_passes[i]
                for i, pf_pass in enumerate(pf_passes):
                    if pf_pass.overlaps(dump, timedelta(minutes=40)):
                        pf_elevation = pf_pass.orb.get_observer_look(pf_pass.uptime,
                                                                     *pfcoords)[1]
                        logger.debug("Computed " + str(("PF", pf_pass,
                                                        pf_elevation)))
                        del pf_passes[i]
                for i, wp_pass in enumerate(wp_passes):
                    if wp_pass.overlaps(dump, timedelta(minutes=40)):
                        wp_elevation = wp_pass.orb.get_observer_look(wp_pass.uptime,
                                                                     *wpcoords)[1]
                        logger.debug("Computed " + str(("WP", wp_pass,
                                                        wp_elevation)))
                        del wp_passes[i]

            # sort out dump passes first
            # between sv an pf, we take the one with the highest elevation if
            # pf < 20°, pf otherwise
            # I think wp is also used if sv is the only other alternative
            used_pf = []
            for sv_pass in sv_passes:
                found_pass = False
                for pf_pass in pf_passes:
                    if sv_pass.overlaps(pf_pass):
                        found_pass = True
                        used_pf.append(pf_pass)
                        sv_elevation = sv_pass.orb.get_observer_look(sv_pass.uptime,
                                                                     *svcoords)[1]
                        pf_elevation = pf_pass.orb.get_observer_look(pf_pass.uptime,
                                                                     *pfcoords)[1]
                        if pf_elevation > 20:
                            dumps.append(pf_pass)
                        elif sv_elevation > pf_elevation:
                            dumps.append(sv_pass)
                        else:
                            dumps.append(pf_pass)
                        break
                if not found_pass:
                    dumps.append(sv_pass)

            for pf_pass in pf_passes:
                if pf_pass not in used_pf:
                    dumps.append(pf_pass)

            passes["aqua"] = []
            for overpass in aqua_passes:
                add = True
                for dump_pass in dumps:
                    if dump_pass.overlaps(overpass):
                        if (dump_pass.uptime < overpass.uptime and
                                dump_pass.falltime > overpass.risetime):
                            logger.debug("adjusting " + str(overpass)
                                         + " to new risetime " +
                                         str(dump_pass.falltime))
                            overpass.risetime = dump_pass.falltime
                            overpass.boundary = SwathBoundary(overpass)
                        elif (dump_pass.uptime >= overpass.uptime and
                              dump_pass.risetime < overpass.falltime):
                            logger.debug("adjusting " + str(overpass)
                                         + " to new falltime " +
                                         str(dump_pass.risetime))
                            overpass.falltime = dump_pass.risetime
                            overpass.boundary = SwathBoundary(overpass)
                        if overpass.falltime <= overpass.risetime:
                            add = False
                            logger.debug("skipping " + str(overpass))
                if add and overpass.seconds() > MIN_PASS * 60:
                    passes["aqua"].append(overpass)

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

    return set(reduce(operator.concat, passes.values()))
예제 #6
0
 def updateTLEfromNet(self):
     tlefile.TLE_URLS = ("https://celestrak.com/NORAD/elements/argos.txt", )
     tlefile.fetch("TLE/argos.txt")
     tlefile.TLE_URLS = (
         "https://celestrak.com/NORAD/elements/cubesat.txt", )
     tlefile.fetch("TLE/cubesat.txt")
     tlefile.TLE_URLS = ("https://celestrak.com/NORAD/elements/dmc.txt", )
     tlefile.fetch("TLE/dmc.txt")
     tlefile.TLE_URLS = ("https://celestrak.com/NORAD/elements/goes.txt", )
     tlefile.fetch("TLE/goes.txt")
     tlefile.TLE_URLS = (
         "https://celestrak.com/NORAD/elements/intelsat.txt", )
     tlefile.fetch("TLE/intelsat.txt")
     tlefile.TLE_URLS = (
         "https://celestrak.com/NORAD/elements/iridium.txt", )
     tlefile.fetch("TLE/iridium.txt")
     tlefile.TLE_URLS = (
         "https://celestrak.com/NORAD/elements/iridium-NEXT.txt", )
     tlefile.fetch("TLE/iridium-NEXT.txt")
     tlefile.TLE_URLS = (
         "https://celestrak.com/NORAD/elements/molniya.txt", )
     tlefile.fetch("TLE/molniya.txt")
     tlefile.TLE_URLS = ("https://celestrak.com/NORAD/elements/noaa.txt", )
     tlefile.fetch("TLE/noaa.txt")
     tlefile.TLE_URLS = (
         "https://celestrak.com/NORAD/elements/planet.txt", )
     tlefile.fetch("TLE/planet.txt")
     tlefile.TLE_URLS = (
         "https://celestrak.com/NORAD/elements/resource.txt", )
     tlefile.fetch("TLE/resource.txt")
     tlefile.TLE_URLS = (
         "https://celestrak.com/NORAD/elements/sarsat.txt", )
     tlefile.fetch("TLE/sarsat.txt")
     tlefile.TLE_URLS = ("https://celestrak.com/NORAD/elements/spire.txt", )
     tlefile.fetch("TLE/spire.txt")
     tlefile.TLE_URLS = ("https://celestrak.com/NORAD/elements/tdrss.txt", )
     tlefile.fetch("TLE/tdrss.txt")
     tlefile.TLE_URLS = (
         "https://celestrak.com/NORAD/elements/tle-new.txt", )
     tlefile.fetch("TLE/tle-new.txt")
     tlefile.TLE_URLS = (
         "https://celestrak.com/NORAD/elements/visual.txt", )
     tlefile.fetch("TLE/visual.txt")
     tlefile.TLE_URLS = (
         "https://celestrak.com/NORAD/elements/weather.txt", )
     tlefile.fetch("TLE/weather.txt")