Ejemplo n.º 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."""
    if area_def.proj_dict.get('proj') == 'geos':
        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)) < 90:
            return 1.0
        else:
            return 0.0
    else:
        daylight_area = daylight.area()
        total_area = cut_area_poly.area()
        return daylight_area / total_area
Ejemplo n.º 2
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)
Ejemplo n.º 3
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
Ejemplo n.º 4
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
Ejemplo n.º 5
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
Ejemplo n.º 6
0
    def __init__(self, overpass, scan_step=50, frequency=200):
        # compute area covered by pass

        Boundary.__init__(self)

        self.overpass = overpass
        self.orb = overpass.orb

        # compute sides

        scanlength_seconds = ((overpass.falltime - overpass.risetime).seconds +
                              (overpass.falltime - overpass.risetime).microseconds / 1000000.0)

        logger.debug("Instrument = %s", self.overpass.instrument)
        if self.overpass.instrument == 'viirs':
            sec_scan_duration = 1.779166667
            along_scan_reduce_factor = 1
        elif self.overpass.instrument.startswith("avhrr"):
            sec_scan_duration = 1./6.
            along_scan_reduce_factor = 0.1
        elif self.overpass.instrument == 'ascat':
            sec_scan_duration = 3.74747474747
            along_scan_reduce_factor = 1
            # Overwrite the scan step
            scan_step = 1
        else:
            # Assume AVHRR!
            logmsg = ("Instrument scan duration not known. Setting it to AVHRR. Instrument: ")
            logger.info(logmsg + "%s", str(self.overpass.instrument))
            sec_scan_duration = 1./6.
            along_scan_reduce_factor = 0.1

        # From pass length in seconds and the seconds for one scan derive the number of scans in the swath:
        scans_nb = scanlength_seconds/sec_scan_duration * along_scan_reduce_factor
        # Devide by the scan step to a reduced number of scans:
        scans_nb = np.floor(scans_nb/scan_step)
        scans_nb = int(max(scans_nb, 1))

        sides_lons, sides_lats = self.get_instrument_points(self.overpass,
                                                            overpass.risetime,
                                                            scans_nb,
                                                            np.array([0, self.overpass.number_of_fovs-1]),
                                                            scan_step=scan_step)

        side_shape = sides_lons[::-1, 0].shape[0]
        nmod = 1
        if side_shape != scans_nb:
            nmod = side_shape // scans_nb
            logger.debug('Number of scan lines (%d) does not match number of scans (%d)',
                         side_shape, scans_nb)
            logger.info('Take every %d th element on the sides...', nmod)

        self.left_lons = sides_lons[::-1, 0][::nmod]
        self.left_lats = sides_lats[::-1, 0][::nmod]
        self.right_lons = sides_lons[:, 1][::nmod]
        self.right_lats = sides_lats[:, 1][::nmod]

        # compute bottom
        maxval = self.overpass.number_of_fovs
        rest = maxval % frequency
        mid_range = np.arange(rest / 2, maxval, frequency)
        if mid_range[0] == 0:
            start_idx = 1
        else:
            start_idx = 0

        reduced = np.hstack([0, mid_range[start_idx::], maxval - 1]).astype('int')

        lons, lats = self.get_instrument_points(self.overpass,
                                                overpass.falltime,
                                                1,
                                                reduced)

        self.bottom_lons = lons[0][::-1]
        self.bottom_lats = lats[0][::-1]

        # compute top
        lons, lats = self.get_instrument_points(self.overpass,
                                                overpass.risetime,
                                                1,
                                                reduced)

        self.top_lons = lons[0]
        self.top_lats = lats[0]
Ejemplo n.º 7
0
    def __init__(self, overpass, scan_step=50, frequency=200):
        # compute area covered by pass

        Boundary.__init__(self)

        self.overpass = overpass
        self.orb = overpass.orb

        # compute sides

        scanlength_seconds = (
            (overpass.falltime - overpass.risetime).seconds +
            (overpass.falltime - overpass.risetime).microseconds / 1000000.0)

        logger.debug("Instrument = %s", self.overpass.instrument)
        if self.overpass.instrument == 'viirs':
            sec_scan_duration = 1.779166667
            along_scan_reduce_factor = 1
        elif self.overpass.instrument.startswith("avhrr"):
            sec_scan_duration = 1. / 6.
            along_scan_reduce_factor = 0.1
        elif self.overpass.instrument == 'ascat':
            sec_scan_duration = 3.74747474747
            along_scan_reduce_factor = 1
            # Overwrite the scan step
            scan_step = 1
        elif self.overpass.instrument == 'mhs':
            sec_scan_duration = 8 / 3.
            along_scan_reduce_factor = 1
            # Overwrite the scan step
            scan_step = 1
        elif self.overpass.instrument == 'atms':
            sec_scan_duration = 8 / 3.
            along_scan_reduce_factor = 1
            # Overwrite the scan step
            scan_step = 1
        elif self.overpass.instrument == 'mwhs-2':
            sec_scan_duration = 8 / 3.
            along_scan_reduce_factor = 1
            # Overwrite the scan step
            scan_step = 1
        else:
            # Assume AVHRR!
            logmsg = (
                "Instrument scan duration not known. Setting it to AVHRR. Instrument: "
            )
            logger.info(logmsg + "%s", str(self.overpass.instrument))
            sec_scan_duration = 1. / 6.
            along_scan_reduce_factor = 0.1

        # From pass length in seconds and the seconds for one scan derive the number of scans in the swath:
        scans_nb = scanlength_seconds / sec_scan_duration * along_scan_reduce_factor
        # Devide by the scan step to a reduced number of scans:
        scans_nb = np.floor(scans_nb / scan_step)
        scans_nb = int(max(scans_nb, 1))

        sides_lons, sides_lats = self.get_instrument_points(
            self.overpass,
            overpass.risetime,
            scans_nb,
            np.array([0, self.overpass.number_of_fovs - 1]),
            scan_step=scan_step)

        side_shape = sides_lons[::-1, 0].shape[0]
        nmod = 1
        if side_shape != scans_nb:
            nmod = side_shape // scans_nb
            logger.debug(
                'Number of scan lines (%d) does not match number of scans (%d)',
                side_shape, scans_nb)
            logger.info('Take every %d th element on the sides...', nmod)

        self.left_lons = sides_lons[::-1, 0][::nmod]
        self.left_lats = sides_lats[::-1, 0][::nmod]
        self.right_lons = sides_lons[:, 1][::nmod]
        self.right_lats = sides_lats[:, 1][::nmod]

        # compute bottom
        maxval = self.overpass.number_of_fovs
        rest = maxval % frequency
        mid_range = np.arange(rest / 2, maxval, frequency)
        if mid_range[0] == 0:
            start_idx = 1
        else:
            start_idx = 0

        reduced = np.hstack([0, mid_range[start_idx::],
                             maxval - 1]).astype('int')

        lons, lats = self.get_instrument_points(self.overpass,
                                                overpass.falltime, 1, reduced)

        self.bottom_lons = lons[0][::-1]
        self.bottom_lats = lats[0][::-1]

        # compute top
        lons, lats = self.get_instrument_points(self.overpass,
                                                overpass.risetime, 1, reduced)

        self.top_lons = lons[0]
        self.top_lats = lats[0]