def test_swath_boundary(self): tstart = datetime(2018, 10, 16, 2, 48, 29) tend = datetime(2018, 10, 16, 3, 2, 38) overp = Pass('NOAA-20', tstart, tend, orb=self.n20orb, instrument='viirs') overp_boundary = SwathBoundary(overp) cont = overp_boundary.contour() assertNumpyArraysEqual(cont[0], LONS1) assertNumpyArraysEqual(cont[1], LATS1) tstart = datetime(2018, 10, 16, 4, 29, 4) tend = datetime(2018, 10, 16, 4, 30, 29, 400000) overp = Pass('NOAA-20', tstart, tend, orb=self.n20orb, instrument='viirs') overp_boundary = SwathBoundary(overp, frequency=200) cont = overp_boundary.contour() assertNumpyArraysEqual(cont[0], LONS2) assertNumpyArraysEqual(cont[1], LATS2) # NOAA-19 AVHRR: 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') overp_boundary = SwathBoundary(overp, frequency=500) cont = overp_boundary.contour() assertNumpyArraysEqual(cont[0], LONS3) assertNumpyArraysEqual(cont[1], LATS3) overp = Pass('NOAA-19', tstart, tend, orb=self.n19orb, instrument='avhrr/3') overp_boundary = SwathBoundary(overp, frequency=500) cont = overp_boundary.contour() assertNumpyArraysEqual(cont[0], LONS3) assertNumpyArraysEqual(cont[1], LATS3) overp = Pass('NOAA-19', tstart, tend, orb=self.n19orb, instrument='avhrr-3') overp_boundary = SwathBoundary(overp, frequency=500) cont = overp_boundary.contour() assertNumpyArraysEqual(cont[0], LONS3) assertNumpyArraysEqual(cont[1], LATS3)
def get_terra_aqua_passes(passes, utctime, forward, sat, passlist, satorb, aqua_terra_dumps): """Get the Terra/Aqua passes, taking care that Terra and Aqua do not have direct broadcast when there are global dumps passes: The dictionary of satellite passes which is being built utctime: The start time (datetime object) forward: The number of hours ahead for which we will get the coming passes sat: The Satellite platform considered passlist: List of Pass objects satorb: Orbital instance for the actual satellite and tles considered aqua_terra_dumps: True or False or the actual URL to get info on Terra/Aqua dumps. If True, the default URL will be used. If False or None, no dump info will be considered. """ instrument = 'modis' 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, orb=satorb, uptime=uptime, instrument=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, orb=satorb, uptime=uptime, instrument=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, orb=satorb, uptime=uptime, instrument=instrument) for rtime, ftime, uptime in passlist_pf if rtime < ftime ] aqua_passes = [ Pass(sat, rtime, ftime, orb=satorb, uptime=uptime, instrument=instrument) for rtime, ftime, uptime in passlist if rtime < ftime ] dumps = get_aqua_terra_dumps(utctime - timedelta(minutes=30), utctime + timedelta(hours=forward + 0.5), satorb, sat, aqua_terra_dumps) # 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[sat.name] = [] 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[sat.name].append(overpass) return
def boundary(self, value): self._boundary = SwathBoundary(self, frequency=self.frequency)
def boundary(self): if not self._boundary: self._boundary = SwathBoundary(self, frequency=self.frequency) return self._boundary
def test_swath_boundary(self): tstart = datetime(2018, 10, 16, 2, 48, 29) tend = datetime(2018, 10, 16, 3, 2, 38) overp = Pass('NOAA-20', tstart, tend, orb=self.n20orb, instrument='viirs') overp_boundary = SwathBoundary(overp) cont = overp_boundary.contour() assertNumpyArraysEqual(cont[0], LONS1) assertNumpyArraysEqual(cont[1], LATS1) tstart = datetime(2018, 10, 16, 4, 29, 4) tend = datetime(2018, 10, 16, 4, 30, 29, 400000) overp = Pass('NOAA-20', tstart, tend, orb=self.n20orb, instrument='viirs') overp_boundary = SwathBoundary(overp, frequency=200) cont = overp_boundary.contour() assertNumpyArraysEqual(cont[0], LONS2) assertNumpyArraysEqual(cont[1], LATS2) # NOAA-19 AVHRR: 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') overp_boundary = SwathBoundary(overp, frequency=500) cont = overp_boundary.contour() assertNumpyArraysEqual(cont[0], LONS3) assertNumpyArraysEqual(cont[1], LATS3) overp = Pass('NOAA-19', tstart, tend, orb=self.n19orb, instrument='avhrr/3') overp_boundary = SwathBoundary(overp, frequency=500) cont = overp_boundary.contour() assertNumpyArraysEqual(cont[0], LONS3) assertNumpyArraysEqual(cont[1], LATS3) overp = Pass('NOAA-19', tstart, tend, orb=self.n19orb, instrument='avhrr-3') overp_boundary = SwathBoundary(overp, frequency=500) cont = overp_boundary.contour() assertNumpyArraysEqual(cont[0], LONS3) assertNumpyArraysEqual(cont[1], LATS3)