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
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
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
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)
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
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)
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)
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()
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)
#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...")