예제 #1
0
    def test_arctic_is_not_antarctic(self):

        tstart = datetime(2021, 2, 3, 16, 28, 3)
        tend = datetime(2021, 2, 3, 16, 31, 3)

        overp = Pass('Metop-B',
                     tstart,
                     tend,
                     orb=self.mborb,
                     instrument='avhrr')

        cov_south = overp.area_coverage(self.antarctica)
        cov_north = overp.area_coverage(self.arctica)

        assert cov_north == 0
        assert cov_south != 0
예제 #2
0
    def find_sectors(self):
        """Identify sectors with at least some coverage by the provided scene.

        Returns
        -------
        list
            area_id of each sector with some coverage.
        """
        data = self.message.data
        overpass = Pass(
            data["platform_name"],
            self.scene.start_time,
            self.scene.end_time,
            instrument="viirs",
        )
        logger.debug(f"Created overpass {overpass}")
        logger.debug(f"args: {data['platform_name']} :: "
                     "{self.scene.start_time} :: {self.scene.end_time}")
        sectors = []
        coverage_threashold = float(
            tutil.get_env_var("COVERAGE_THRESHOLD", 0.1))
        for sector_def in parse_area_file(AREA_DEF):
            logger.debug("Checking coverage for %s", sector_def.area_id)
            coverage = overpass.area_coverage(sector_def)
            logger.debug("{} coverage: {}".format(sector_def.area_id,
                                                  coverage))
            if coverage > coverage_threashold:
                sectors.append(sector_def)
        return sectors
예제 #3
0
def _granule_covers_region(granule_metadata, region):
    granule_pass = Pass(_get_platform_name(granule_metadata),
                        granule_metadata["start_time"],
                        granule_metadata["end_time"],
                        instrument=_get_sensor(granule_metadata))
    coverage = granule_pass.area_coverage(region)
    if coverage > 0:
        coverage_str = f"is overlapping region {region.description:s} by fraction {coverage:.5f}"
        _log_overlap_message(granule_metadata, coverage_str)
        return True
    return False
예제 #4
0
 def _predict(self, granule_metadata, step):
     gr_time = granule_metadata["start_time"]
     while True:
         gr_time += step
         gr_pass = Pass(_get_platform_name(granule_metadata),
                        gr_time,
                        gr_time + self.granule_duration,
                        instrument=_get_sensor(granule_metadata))
         if not gr_pass.area_coverage(self.region) > 0:
             break
         self.planned_granule_times.add(gr_time)
예제 #5
0
def granule_inside_area(start_time,
                        end_time,
                        platform_name,
                        instrument,
                        area_def,
                        thr_area_coverage,
                        tle_file=None):
    """Check if a satellite data granule is over area interest, using the start and
    end times from the filename

    """

    try:
        metop = Orbital(platform_name, tle_file)
    except KeyError:
        LOG.exception(
            'Failed getting orbital data for {0}'.format(platform_name))
        LOG.critical(
            'Cannot determine orbit! Probably TLE file problems...\n' +
            'Granule will be set to be inside area of interest disregarding')
        return True

    tle1 = metop.tle.line1
    tle2 = metop.tle.line2

    mypass = Pass(platform_name,
                  start_time,
                  end_time,
                  instrument=instrument,
                  tle1=tle1,
                  tle2=tle2)
    acov = mypass.area_coverage(area_def)
    LOG.debug("Granule coverage of area %s: %f", area_def.area_id, acov)

    is_inside = (acov > thr_area_coverage)

    if is_inside:
        from pyresample.boundary import AreaDefBoundary
        from trollsched.drawing import save_fig
        area_boundary = AreaDefBoundary(area_def, frequency=100)
        area_boundary = area_boundary.contour_poly
        save_fig(mypass, poly=area_boundary, directory='/tmp')

    return
예제 #6
0
    def test_swath_coverage(self):

        # NOAA-19 AVHRR:
        tstart = datetime.strptime('20181016 03:54:13', '%Y%m%d %H:%M:%S')
        tend = datetime.strptime('20181016 03:55:13', '%Y%m%d %H:%M:%S')

        overp = Pass('NOAA-19',
                     tstart,
                     tend,
                     orb=self.n19orb,
                     instrument='avhrr')

        cov = overp.area_coverage(self.euron1)
        self.assertEqual(cov, 0)

        overp = Pass('NOAA-19',
                     tstart,
                     tend,
                     orb=self.n19orb,
                     instrument='avhrr',
                     frequency=80)

        cov = overp.area_coverage(self.euron1)
        self.assertEqual(cov, 0)

        tstart = datetime.strptime('20181016 04:00:00', '%Y%m%d %H:%M:%S')
        tend = datetime.strptime('20181016 04:01:00', '%Y%m%d %H:%M:%S')

        overp = Pass('NOAA-19',
                     tstart,
                     tend,
                     orb=self.n19orb,
                     instrument='avhrr')

        cov = overp.area_coverage(self.euron1)
        self.assertAlmostEqual(cov, 0.103526, 5)

        overp = Pass('NOAA-19',
                     tstart,
                     tend,
                     orb=self.n19orb,
                     instrument='avhrr',
                     frequency=100)

        cov = overp.area_coverage(self.euron1)
        self.assertAlmostEqual(cov, 0.103526, 5)

        overp = Pass('NOAA-19',
                     tstart,
                     tend,
                     orb=self.n19orb,
                     instrument='avhrr/3',
                     frequency=133)

        cov = overp.area_coverage(self.euron1)
        self.assertAlmostEqual(cov, 0.103526, 5)

        overp = Pass('NOAA-19',
                     tstart,
                     tend,
                     orb=self.n19orb,
                     instrument='avhrr',
                     frequency=300)

        cov = overp.area_coverage(self.euron1)
        self.assertAlmostEqual(cov, 0.103526, 5)

        # ASCAT and AVHRR on Metop-B:
        tstart = datetime.strptime("2019-01-02T10:19:39", "%Y-%m-%dT%H:%M:%S")
        tend = tstart + timedelta(seconds=180)
        tle1 = '1 38771U 12049A   19002.35527803  .00000000  00000+0  21253-4 0 00017'
        tle2 = '2 38771  98.7284  63.8171 0002025  96.0390 346.4075 14.21477776326431'

        mypass = Pass('Metop-B',
                      tstart,
                      tend,
                      instrument='ascat',
                      tle1=tle1,
                      tle2=tle2)
        cov = mypass.area_coverage(self.euron1)
        self.assertAlmostEqual(cov, 0.322812, 5)

        mypass = Pass('Metop-B',
                      tstart,
                      tend,
                      instrument='avhrr',
                      tle1=tle1,
                      tle2=tle2)
        cov = mypass.area_coverage(self.euron1)
        self.assertAlmostEqual(cov, 0.357324, 5)

        tstart = datetime.strptime("2019-01-05T01:01:45", "%Y-%m-%dT%H:%M:%S")
        tend = tstart + timedelta(seconds=60 * 15.5)

        tle1 = '1 43010U 17072A   18363.54078832 -.00000045  00000-0 -79715-6 0  9999'
        tle2 = '2 43010  98.6971 300.6571 0001567 143.5989 216.5282 14.19710974 58158'

        mypass = Pass('FENGYUN 3D',
                      tstart,
                      tend,
                      instrument='mersi2',
                      tle1=tle1,
                      tle2=tle2)
        cov = mypass.area_coverage(self.euron1)

        self.assertAlmostEqual(cov, 0.786836, 5)
예제 #7
0
def get_scene_coverage(platform_name, start_time, end_time, sensor, area_id):
    """Get scene area coverage in percentages."""
    overpass = Pass(platform_name, start_time, end_time, instrument=sensor)
    area_def = get_area_def(area_id)

    return 100 * overpass.area_coverage(area_def)
예제 #8
0
    def collect(self, granule_metadata):
        """ 
            Parameters:

                granule_metadata : metadata

        """

        # Check if input data is being waited for

        if "tle_platform_name" in granule_metadata:
            platform = granule_metadata['tle_platform_name']
        else:
            platform = granule_metadata['platform_name']

        start_time = granule_metadata['start_time']
        if ("end_time" not in granule_metadata
                and self.granule_duration is not None):
            granule_metadata["end_time"] = (granule_metadata["start_time"] +
                                            self.granule_duration)

        end_time = granule_metadata['end_time']

        if start_time > end_time:
            old_end_time = end_time
            end_date = start_time.date()
            if end_time.time() < start_time.time():
                end_date += timedelta(days=1)
            end_time = datetime.combine(end_date, end_time.time())
            LOG.debug('Adjusted end time from %s to %s.', old_end_time,
                      end_time)

        granule_metadata['end_time'] = end_time

        LOG.debug("Adding area ID to metadata: %s", str(self.region.area_id))
        granule_metadata['collection_area_id'] = self.region.area_id

        self.last_file_added = False
        for ptime in self.planned_granule_times:
            if abs(start_time - ptime) < timedelta(seconds=3) and \
               ptime not in self.granule_times:
                self.granule_times.add(ptime)
                self.granules.append(granule_metadata)
                self.last_file_added = True
                LOG.info("Added %s (%s) granule to area %s", platform,
                         str(start_time), self.region.area_id)
                # If last granule return swath and cleanup
                # if self.granule_times == self.planned_granule_times:
                if self.is_swath_complete():
                    LOG.info("Collection finished for area: %s",
                             str(self.region.area_id))
                    return self.finish()
                else:
                    try:
                        new_timeout = (max(self.planned_granule_times -
                                           self.granule_times) +
                                       self.granule_duration + self.timeliness)
                    except ValueError:
                        LOG.error("Calculation of new timeout failed, "
                                  "keeping previous timeout.")
                        LOG.error("Planned: %s", self.planned_granule_times)
                        LOG.error("Received: %s", self.granule_times)
                        return

                    if new_timeout < self.timeout:
                        self.timeout = new_timeout
                        LOG.info("Adjusted timeout: %s",
                                 self.timeout.isoformat())

                    return

        # Get corners from input data

        if self.granule_duration is None:
            self.granule_duration = end_time - start_time
            LOG.debug("Estimated granule duration to %s",
                      str(self.granule_duration))

        LOG.info("Platform name %s and sensor %s: Start and end times = %s %s",
                 str(platform), str(granule_metadata["sensor"]),
                 start_time.strftime('%Y%m%d %H:%M:%S'),
                 end_time.strftime('%Y%m%d %H:%M:%S'))

        self.sensor = granule_metadata["sensor"]
        if isinstance(self.sensor, list):
            self.sensor = self.sensor[0]
        granule_pass = Pass(platform,
                            start_time,
                            end_time,
                            instrument=self.sensor)

        # If file is within region, make pass prediction to know what to wait
        # for
        if granule_pass.area_coverage(self.region) > 0:
            self.granule_times.add(start_time)
            self.granules.append(granule_metadata)
            self.last_file_added = True

            # Computation of the predicted granules within the region

            if not self.planned_granule_times:
                self.planned_granule_times.add(start_time)
                LOG.info("Added %s (%s) granule to area %s", platform,
                         str(start_time), self.region.area_id)
                LOG.debug("Predicting granules covering %s",
                          self.region.area_id)
                gr_time = start_time
                while True:
                    gr_time += self.granule_duration
                    gr_pass = Pass(platform,
                                   gr_time,
                                   gr_time + self.granule_duration,
                                   instrument=self.sensor)
                    if not gr_pass.area_coverage(self.region) > 0:
                        break
                    self.planned_granule_times.add(gr_time)

                gr_time = start_time
                while True:
                    gr_time -= self.granule_duration
                    gr_pass = Pass(platform,
                                   gr_time,
                                   gr_time + self.granule_duration,
                                   instrument=self.sensor)
                    if not gr_pass.area_coverage(self.region) > 0:
                        break
                    self.planned_granule_times.add(gr_time)

                LOG.info("Planned granules for %s: %s", self.region.name,
                         str(sorted(self.planned_granule_times)))
                self.timeout = (max(self.planned_granule_times) +
                                self.granule_duration + self.timeliness)
                LOG.info("Planned timeout for %s: %s", self.region.name,
                         self.timeout.isoformat())

        else:
            try:
                LOG.debug("Granule %s is not overlapping %s",
                          granule_metadata["uri"], self.region.name)
            except KeyError:
                try:
                    LOG.debug(
                        "Granule with start and end times = %s  %s  "
                        "is not overlapping %s",
                        str(granule_metadata["start_time"]),
                        str(granule_metadata["end_time"]),
                        str(self.region.name))
                except KeyError:
                    LOG.debug("Failed printing debug info...")
                    LOG.debug("Keys in granule_metadata = %s",
                              str(granule_metadata.keys()))

        # If last granule return swath and cleanup
        if self.is_swath_complete():
            LOG.debug("Collection finished for area: %s",
                      str(self.region.area_id))
            return self.finish()
    def collect(self, granule_metadata):
        """ 
            Parameters:

                granule_metadata : metadata 

        """

        # Check if input data is being waited for

        platform = granule_metadata['platform_name']

        start_time = granule_metadata['start_time']
        end_time = granule_metadata['end_time']

        for ptime in self.planned_granule_times:
            if abs(start_time - ptime) < timedelta(seconds=3):
                self.granule_times.add(ptime)
                self.granules.append(granule_metadata)
                LOG.info("Added %s (%s) granule to area %s",
                         platform,
                         str(start_time),
                         self.region.area_id)
                # If last granule return swath and cleanup
                if self.granule_times == self.planned_granule_times:
                    LOG.info("Collection finished for area: " +
                             str(self.region.area_id))
                    return self.finish()
                else:
                    return

        # Get corners from input data

        if self.granule_duration is None:
            self.granule_duration = end_time - start_time
            LOG.debug("Estimated granule duration to " +
                      str(self.granule_duration))

        granule_pass = Pass(platform, start_time, end_time,
                            instrument=granule_metadata["sensor"])

        # If file is within region, make pass prediction to know what to wait
        # for
        if granule_pass.area_coverage(self.region) > 0:
            self.granule_times.add(start_time)
            self.granules.append(granule_metadata)

            # Computation of the predicted granules within the region

            if not self.planned_granule_times:
                self.planned_granule_times.add(start_time)
                LOG.info("Added %s (%s) granule to area %s",
                         platform,
                         str(start_time),
                         self.region.area_id)
                LOG.debug(
                    "Predicting granules covering " + self.region.area_id)
                gr_time = start_time
                while True:
                    gr_time += self.granule_duration
                    gr_pass = Pass(platform, gr_time,
                                   gr_time + self.granule_duration,
                                   instrument=granule_metadata["sensor"])
                    if not gr_pass.area_coverage(self.region) > 0:
                        break
                    self.planned_granule_times.add(gr_time)

                gr_time = start_time
                while True:
                    gr_time -= self.granule_duration
                    gr_pass = Pass(platform, gr_time,
                                   gr_time + self.granule_duration,
                                   instrument=granule_metadata["sensor"])
                    if not gr_pass.area_coverage(self.region) > 0:
                        break
                    self.planned_granule_times.add(gr_time)

                LOG.info(
                    "Planned granules: " + str(sorted(self.planned_granule_times)))
                self.timeout = (max(self.planned_granule_times)
                                + self.granule_duration
                                + self.timeliness)
                LOG.info("Planned timeout: " + self.timeout.isoformat())
        else:
            try:
                LOG.debug("Granule %s is not overlapping %s",
                          granule_metadata["uri"], self.region.name)
            except KeyError:
                try:
                    LOG.debug("Granule with start and end times = " +
                              str(granule_metadata["start_time"]) + " " +
                              str(granule_metadata["end_time"]) +
                              "is not overlapping " + str(self.region.name))
                except KeyError:
                    LOG.debug("Failed printing debug info...")
                    LOG.debug("Keys in granule_metadata = " +
                              str(granule_metadata.keys()))

        # If last granule return swath and cleanup
        if (self.granule_times and
                (self.granule_times == self.planned_granule_times)):
            LOG.debug("Collection finished for area: " +
                      str(self.region.area_id))
            return self.finish()
예제 #10
0
    def test_swath_coverage(self):

        # NOAA-19 AVHRR:
        tstart = datetime.strptime('20181016 03:54:13', '%Y%m%d %H:%M:%S')
        tend = datetime.strptime('20181016 03:55:13', '%Y%m%d %H:%M:%S')

        overp = Pass('NOAA-19', tstart, tend, orb=self.n19orb, instrument='avhrr')

        cov = overp.area_coverage(self.euron1)
        self.assertEqual(cov, 0)

        overp = Pass('NOAA-19', tstart, tend, orb=self.n19orb, instrument='avhrr', frequency=80)

        cov = overp.area_coverage(self.euron1)
        self.assertEqual(cov, 0)

        tstart = datetime.strptime('20181016 04:00:00', '%Y%m%d %H:%M:%S')
        tend = datetime.strptime('20181016 04:01:00', '%Y%m%d %H:%M:%S')

        overp = Pass('NOAA-19', tstart, tend, orb=self.n19orb, instrument='avhrr')

        cov = overp.area_coverage(self.euron1)
        self.assertAlmostEqual(cov, 0.103526, 5)

        overp = Pass('NOAA-19', tstart, tend, orb=self.n19orb, instrument='avhrr', frequency=100)

        cov = overp.area_coverage(self.euron1)
        self.assertAlmostEqual(cov, 0.103526, 5)

        overp = Pass('NOAA-19', tstart, tend, orb=self.n19orb, instrument='avhrr/3', frequency=133)

        cov = overp.area_coverage(self.euron1)
        self.assertAlmostEqual(cov, 0.103526, 5)

        overp = Pass('NOAA-19', tstart, tend, orb=self.n19orb, instrument='avhrr', frequency=300)

        cov = overp.area_coverage(self.euron1)
        self.assertAlmostEqual(cov, 0.103526, 5)

        # ASCAT and AVHRR on Metop-B:
        tstart = datetime.strptime("2019-01-02T10:19:39", "%Y-%m-%dT%H:%M:%S")
        tend = tstart + timedelta(seconds=180)
        tle1 = '1 38771U 12049A   19002.35527803  .00000000  00000+0  21253-4 0 00017'
        tle2 = '2 38771  98.7284  63.8171 0002025  96.0390 346.4075 14.21477776326431'

        mypass = Pass('Metop-B', tstart, tend, instrument='ascat', tle1=tle1, tle2=tle2)
        cov = mypass.area_coverage(self.euron1)
        self.assertAlmostEqual(cov, 0.322812, 5)

        mypass = Pass('Metop-B', tstart, tend, instrument='avhrr', tle1=tle1, tle2=tle2)
        cov = mypass.area_coverage(self.euron1)
        self.assertAlmostEqual(cov, 0.357324, 5)

        tstart = datetime.strptime("2019-01-05T01:01:45", "%Y-%m-%dT%H:%M:%S")
        tend = tstart + timedelta(seconds=60*15.5)

        tle1 = '1 43010U 17072A   18363.54078832 -.00000045  00000-0 -79715-6 0  9999'
        tle2 = '2 43010  98.6971 300.6571 0001567 143.5989 216.5282 14.19710974 58158'

        mypass = Pass('FENGYUN 3D', tstart, tend, instrument='mersi2', tle1=tle1, tle2=tle2)
        cov = mypass.area_coverage(self.euron1)

        self.assertAlmostEqual(cov, 0.786836, 5)
예제 #11
0
    #dtobj = datetime(int(sat_pos_time.strftime('%Y')),
    #             int(sat_pos_time.strftime('%m')),
    #             int(sat_pos_time.strftime('%d')),
    #             int(sat_pos_time.strftime('%H')),
    #             int(sat_pos_time.strftime('%M')),
    #             0)
    #print("---")
    #print(orb.get_lonlatalt(dtobj))
    #print("---")

    #lonlat = orb.get_lonlatalt(dtobj)

    #if lonlat[0] >= -10. and lonlat[0] <= 20. and lonlat[1] >= 40 and lonlat[1] <= 60:

    granule_pass = Pass("Metop-"+satname, glbl.start_time, glbl.end_time, instrument=glbl['natural_color'].sensor)
    if granule_pass.area_coverage(europe) > 0 :
       print("Region over Switzerland, making CCS4 domain...")
       #local_data = glbl.resample("ccs4large")
       local_data = glbl.resample(europe)
       local_data.save_dataset('night_fog', outDir+"METOP-"+satname+"_fog-europe_"+st+".jpg")
       local_data.save_dataset('natural_color', outDir+"METOP-"+satname+"_overview-europe_"+st+".jpg")
       cw.add_coastlines_to_file(outDir+"METOP-"+satname+"_fog-europe_"+st+".jpg", europe, resolution='l', level=1, outline=(255, 255, 255))
       cw.add_coastlines_to_file(outDir+"METOP-"+satname+"_overview-europe_"+st+".jpg", europe, resolution='l', level=1, outline=(255, 255, 255))
       cw.add_borders_to_file(outDir+"METOP-"+satname+"_fog-europe_"+st+".jpg", europe, outline=(255, 255, 255),resolution='i')
       cw.add_borders_to_file(outDir+"METOP-"+satname+"_overview-europe_"+st+".jpg", europe, outline=(255, 255, 255),resolution='i')
       if os.path.getsize(outDir+"METOP-"+satname+"_fog-europe_"+st+".jpg") < 170000:
           os.remove(outDir+"METOP-"+satname+"_fog-europe_"+st+".jpg")
       if os.path.getsize(outDir+"METOP-"+satname+"_overview-europe_"+st+".jpg") < 170000:
           os.remove(outDir+"METOP-"+satname+"_overview-europe_"+st+".jpg")

    print("Making world map...")