Beispiel #1
0
def _get_sunlight_coverage(area_def, start_time, overpass=None):
    """Get the sunlight coverage of *area_def* at *start_time* as a value between 0 and 1."""
    adp = AreaDefBoundary(area_def, frequency=100).contour_poly
    poly = get_twilight_poly(start_time)
    if overpass is not None:
        ovp = overpass.boundary.contour_poly
        cut_area_poly = adp.intersection(ovp)
    else:
        cut_area_poly = adp

    if cut_area_poly is None:
        if not adp._is_inside(ovp):
            return 0.0
        else:
            # Should already have been taken care of in pyresample.spherical.intersection
            cut_area_poly = adp

    daylight = cut_area_poly.intersection(poly)
    if daylight is None:
        if sun_zenith_angle(start_time, *area_def.get_lonlat(0, 0)) < 90:
            return 1.0
        else:
            return 0.0
    else:
        daylight_area = daylight.area()
        total_area = adp.area()
        return daylight_area / total_area
Beispiel #2
0
    def area_coverage(self, area_of_interest):
        """Get the ratio of coverage (between 0 and 1) of the pass with the area
        of interest.
        """
        try:
            area_boundary = area_of_interest.poly
        except AttributeError:
            area_boundary = AreaDefBoundary(area_of_interest, frequency=100)
            area_boundary = area_boundary.contour_poly

        inter = self.boundary.contour_poly.intersection(area_boundary)

        if inter is None:
            return 0
        return inter.area() / area_boundary.area()
Beispiel #3
0
    def area_coverage(self, area_of_interest):
        """Get the ratio of coverage (between 0 and 1) of the pass with the area
        of interest.
        """
        try:
            area_boundary = area_of_interest.poly
        except AttributeError:
            area_boundary = AreaDefBoundary(area_of_interest, frequency=100)
            area_boundary = area_boundary.contour_poly

        inter = self.boundary.contour_poly.intersection(area_boundary)

        if inter is None:
            return 0
        return inter.area() / area_boundary.area()
Beispiel #4
0
def get_area_slices(data_area, area_to_cover):
    """Compute the slice to read from an *area* based on an *area_to_cover*."""

    if data_area.proj_dict['proj'] != 'geos':
        raise NotImplementedError('Only geos supported')

    # Intersection only required for two different projections
    if area_to_cover.proj_dict['proj'] == data_area.proj_dict['proj']:
        LOGGER.debug('Projections for data and slice areas are'
                     ' identical: {}'.format(area_to_cover.proj_dict['proj']))
        # Get xy coordinates
        llx, lly, urx, ury = area_to_cover.area_extent
        x, y = data_area.get_xy_from_proj_coords([llx, urx], [lly, ury])

        return slice(x[0], x[1] + 1), slice(y[1], y[0] + 1)

    data_boundary = Boundary(*get_geostationary_bounding_box(data_area))

    area_boundary = AreaDefBoundary(area_to_cover, 100)
    intersection = data_boundary.contour_poly.intersection(
        area_boundary.contour_poly)

    x, y = data_area.get_xy_from_lonlat(np.rad2deg(intersection.lon),
                                        np.rad2deg(intersection.lat))

    return slice(min(x), max(x) + 1), slice(min(y), max(y) + 1)
Beispiel #5
0
    def check_file_covers_area(file_handler, check_area):
        """Checks if the file covers the current area.

        If the file doesn't provide any bounding box information or 'area'
        was not provided in `filter_parameters`, the check returns True.
        """
        try:
            gbb = Boundary(*file_handler.get_bounding_box())
        except NotImplementedError as err:
            logger.debug("Bounding box computation not implemented: %s",
                         str(err))
        else:
            abb = AreaDefBoundary(get_area_def(check_area), frequency=1000)

            intersection = gbb.contour_poly.intersection(abb.contour_poly)
            if not intersection:
                return False
        return True
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
Beispiel #7
0
def boundary_for_area(area_def: PRGeometry) -> Boundary:
    """Create Boundary object representing the provided area."""
    if not FIXED_PR and isinstance(area_def, SwathDefinition):
        # TODO: Persist lon/lats if requested
        lons, lats = area_def.get_bbox_lonlats()
        freq = int(area_def.shape[0] * 0.05)
        if hasattr(lons[0], "compute") and da is not None:
            lons, lats = da.compute(lons, lats)
        lons = [lon_side.astype(np.float64) for lon_side in lons]
        lats = [lat_side.astype(np.float64) for lat_side in lats]
        adp = AreaBoundary(*zip(lons, lats))
        adp.decimate(freq)
    elif getattr(area_def, "is_geostationary", False):
        adp = Boundary(
            *get_geostationary_bounding_box(area_def, nb_points=100))
    else:
        freq_fraction = 0.05 if isinstance(area_def, SwathDefinition) else 0.30
        adp = AreaDefBoundary(area_def,
                              frequency=int(area_def.shape[0] * freq_fraction))
    return adp
Beispiel #8
0
def _get_sunlight_coverage(area_def,
                           start_time,
                           sza_threshold=90,
                           overpass=None):
    """Get the sunlight coverage of *area_def* at *start_time* as a value between 0 and 1."""
    if isinstance(area_def, SwathDefinition):
        lons, lats = area_def.get_lonlats()
        freq = int(lons.shape[-1] * 0.10)
        lons, lats = da.compute(lons[::freq, ::freq], lats[::freq, ::freq])
        adp = Boundary(lons.ravel(), lats.ravel()).contour_poly
    elif area_def.is_geostationary:
        adp = Boundary(*get_geostationary_bounding_box(
            area_def, nb_points=100)).contour_poly
    else:
        adp = AreaDefBoundary(area_def, frequency=100).contour_poly
    poly = get_twilight_poly(start_time)
    if overpass is not None:
        ovp = overpass.boundary.contour_poly
        cut_area_poly = adp.intersection(ovp)
    else:
        cut_area_poly = adp

    if cut_area_poly is None:
        if not adp._is_inside(ovp):
            return 0.0
        else:
            # Should already have been taken care of in pyresample.spherical.intersection
            cut_area_poly = adp

    daylight = cut_area_poly.intersection(poly)
    if daylight is None:
        if sun_zenith_angle(start_time, *area_def.get_lonlat(
                0, 0)) < sza_threshold:
            return 1.0
        else:
            return 0.0
    else:
        daylight_area = daylight.area()
        total_area = adp.area()
        return daylight_area / total_area
Beispiel #9
0
    def single_station(self, sched, start_time, tle_file):
        """Calculate passes, graph, and schedule for one station."""

        logger.debug("station: %s coords: %s area: %s scores: %s", self.id,
                     self.coords, self.area.area_id, self.satellites)

        opts = sched.opts
        pattern = sched.patterns
        pattern_args = {
            "station": self.id,
            "output_dir": opts.output_dir,
            "date": start_time.strftime("%Y%m%d"),
            "time": start_time.strftime("%H%M%S")
        }
        if opts.xml:
            pattern_args['mode'] = "request"
        elif opts.report:
            pattern_args['mode'] = "report"

        logger.info("Computing next satellite passes")
        allpasses = get_next_passes(
            self.satellites,
            start_time,
            sched.forward,
            self.coords,
            tle_file,
            aqua_terra_dumps=(sched.dump_url or True
                              if opts.no_aqua_terra_dump else None),
            min_pass=self.min_pass,
            local_horizon=self.local_horizon)
        logger.info("Computation of next overpasses done")

        logger.debug(str(sorted(allpasses, key=lambda x: x.risetime)))

        area_boundary = AreaDefBoundary(self.area, frequency=500)
        self.area.poly = area_boundary.contour_poly

        if opts.plot:
            logger.info("Saving plots to %s",
                        build_filename("dir_plots", pattern, pattern_args))
            from threading import Thread
            image_saver = Thread(target=save_passes,
                                 args=(allpasses, self.area.poly,
                                       build_filename("dir_plots", pattern,
                                                      pattern_args),
                                       sched.plot_parameters,
                                       sched.plot_title))
            image_saver.start()

        if opts.avoid is not None:
            avoid_list = get_passes_from_xml_file(opts.avoid)
        else:
            avoid_list = None

        logger.info("computing best schedule for area %s" % self.area.area_id)
        schedule, (graph,
                   labels) = get_best_sched(allpasses, self.area,
                                            timedelta(seconds=opts.delay),
                                            avoid_list)

        logger.debug(pformat(schedule))
        for opass in schedule:
            opass.rec = True
        logger.info("generating file")

        if opts.scisys:
            generate_sch_file(
                build_filename("file_sci", pattern, pattern_args), allpasses,
                self.coords)

        if opts.meos:
            generate_meos_file(
                build_filename("file_meos", pattern, pattern_args), allpasses,
                self.coords, start_time + timedelta(hours=sched.start),
                True)  # Ie report mode

        if opts.plot:
            logger.info("Waiting for images to be saved...")
            image_saver.join()
            logger.info("Done!")

        if opts.metno_xml:
            generate_metno_xml_file(
                build_filename("file_metno_xml", pattern,
                               pattern_args), allpasses, self.coords,
                start_time + timedelta(hours=sched.start),
                start_time + timedelta(hours=sched.forward), self.id,
                sched.center_id, True)

        if opts.xml or opts.report:
            url = urlparse(opts.output_url or opts.output_dir)
            if opts.xml or opts.report:
                """Allways create xml-file in request-mode"""
                pattern_args['mode'] = "request"
                xmlfile = generate_xml_file(
                    allpasses, start_time + timedelta(hours=sched.start),
                    start_time + timedelta(hours=sched.forward),
                    build_filename("file_xml", pattern, pattern_args), self.id,
                    sched.center_id, False)
                logger.info("Generated " + str(xmlfile))
                send_file(url, xmlfile)
            if opts.report:
                """'If report-mode was set"""
                pattern_args['mode'] = "report"
                xmlfile = generate_xml_file(
                    allpasses, start_time + timedelta(hours=sched.start),
                    start_time + timedelta(hours=sched.forward),
                    build_filename("file_xml", pattern, pattern_args), self.id,
                    sched.center_id, True)
                logger.info("Generated " + str(xmlfile))

        if opts.graph or opts.comb:
            graph.save(build_filename("file_graph", pattern, pattern_args))
            graph.export(
                labels=[str(label) for label in labels],
                filename=build_filename("file_graph", pattern, pattern_args) +
                ".gv")
        if opts.comb:
            import pickle
            ph = open(
                os.path.join(
                    build_filename("dir_output", pattern, pattern_args),
                    "allpasses.%s.pkl" % self.id), "wb")
            pickle.dump(allpasses, ph)
            ph.close()

        return graph, allpasses