Esempio n. 1
0
    def set_from_tracks(self,
                        tracks,
                        centroids=None,
                        dist_degree=3,
                        description=''):
        """Computes rainfield from tracks based on the RCLIPER model.
        Parallel process.
        Parameters:
            tracks (TCTracks): tracks of events
            centroids (Centroids, optional): Centroids where to model TC.
                Default: global centroids.
            disr_degree (int): distance (in degrees) from node within which
                               the rainfield is processed (default 3 deg,~300km)
            description (str, optional): description of the events

        """
        num_tracks = tracks.size
        if centroids is None:
            centroids = Centroids.from_base_grid(res_as=360, land=True)

        if not centroids.coord.size:
            centroids.set_meta_to_lat_lon()

        LOGGER.info('Mapping %s tracks to %s centroids.', str(tracks.size),
                    str(centroids.size))
        if self.pool:
            chunksize = min(num_tracks // self.pool.ncpus, 1000)
            tc_haz = self.pool.map(self._set_from_track,
                                   tracks.data,
                                   itertools.repeat(centroids, num_tracks),
                                   itertools.repeat(dist_degree, num_tracks),
                                   itertools.repeat(self.intensity_thres,
                                                    num_tracks),
                                   chunksize=chunksize)
        else:
            tc_haz = list()
            for track in tracks.data:
                tc_haz.append(
                    self._set_from_track(track,
                                         centroids,
                                         dist_degree=dist_degree,
                                         intensity=self.intensity_thres))
        LOGGER.debug('Append events.')
        self.concatenate(tc_haz)
        LOGGER.debug('Compute frequency.')
        TropCyclone.frequency_from_tracks(self, tracks.data)
        self.tag.description = description
Esempio n. 2
0
    def test_base_grid(self):
        """Read new centroids using from_base_grid, then select by extent."""
        centroids = Centroids.from_base_grid(land=True, res_as=150)
        self.assertEqual(centroids.lat.size, 8858035)
        self.assertTrue(np.all(np.diff(centroids.lat) <= 0))

        count_sandwich = np.sum(centroids.region_id == 239)
        self.assertEqual(count_sandwich, 321)

        count_sgi = centroids.select(
            reg_id=239,
            extent=(-39, -34.7, -55.5, -53.6)  # south georgia island
        ).size
        self.assertEqual(count_sgi, 296)

        # test negative latitudinal orientation by testing that northern hemisphere (Russia)
        # is listed before southern hemisphere (South Africa)
        russia_max_idx = (centroids.region_id == 643).nonzero()[0].max()
        safrica_min_idx = (centroids.region_id == 710).nonzero()[0].min()
        self.assertTrue(russia_max_idx < safrica_min_idx)
Esempio n. 3
0
    def set_from_tracks(self,
                        tracks,
                        centroids=None,
                        description='',
                        model='H08',
                        ignore_distance_to_coast=False,
                        store_windfields=False,
                        metric="equirect"):
        """
        Clear and fill with windfields from specified tracks.

        This function sets the `TropCyclone.intensity` attribute to contain, for each centroid,
        the maximum wind speed (1-minute sustained winds at 10 meters above ground) experienced
        over the whole period of each TC event in m/s. The wind speed is set to 0 if it doesn't
        exceed the threshold in `TropCyclone.intensity_thres`.

        The `TropCyclone.category` attribute is set to the value of the `category`-attribute
        of each of the given track data sets.

        The `TropCyclone.basin` attribute is set to the genesis basin for each event, which
        is the first value of the `basin`-variable in each of the given track data sets.

        Optionally, the time dependent, vectorial winds can be stored using the `store_windfields`
        function parameter (see below).

        Parameters
        ----------
        tracks : TCTracks
            Tracks of storm events.
        centroids : Centroids, optional
            Centroids where to model TC. Default: global centroids at 360 arc-seconds resolution.
        description : str, optional
            Description of the event set. Default: "".
        model : str, optional
            Parametric wind field model to use: one of "H1980" (the prominent Holland 1980 model),
            "H08" (Holland 1980 with b-value from Holland 2008), or "H10" (Holland et al. 2010).
            Default: "H08".
        ignore_distance_to_coast : boolean, optional
            If True, centroids far from coast are not ignored. Default: False.
        store_windfields : boolean, optional
            If True, the Hazard object gets a list `windfields` of sparse matrices. For each track,
            the full velocity vectors at each centroid and track position are stored in a sparse
            matrix of shape (npositions,  ncentroids * 2) that can be reshaped to a full ndarray
            of shape (npositions, ncentroids, 2). Default: False.
        metric : str, optional
            Specify an approximation method to use for earth distances:
            * "equirect": Distance according to sinusoidal projection. Fast, but inaccurate for
              large distances and high latitudes.
            * "geosphere": Exact spherical distance. Much more accurate at all distances, but slow.
            Default: "equirect".

        Raises
        ------
        ValueError
        """
        num_tracks = tracks.size
        if centroids is None:
            centroids = Centroids.from_base_grid(res_as=360, land=False)

        if not centroids.coord.size:
            centroids.set_meta_to_lat_lon()

        if ignore_distance_to_coast:
            # Select centroids with lat < 61
            coastal_idx = (np.abs(centroids.lat) < 61).nonzero()[0]
        else:
            # Select centroids which are inside INLAND_MAX_DIST_KM and lat < 61
            if not centroids.dist_coast.size:
                centroids.set_dist_coast()
            coastal_idx = ((centroids.dist_coast < INLAND_MAX_DIST_KM * 1000)
                           & (np.abs(centroids.lat) < 61)).nonzero()[0]

        # Restrict to coastal centroids within reach of any of the tracks
        t_lon_min, t_lat_min, t_lon_max, t_lat_max = tracks.get_bounds(
            deg_buffer=CENTR_NODE_MAX_DIST_DEG)
        t_mid_lon = 0.5 * (t_lon_min + t_lon_max)
        coastal_centroids = centroids.coord[coastal_idx]
        u_coord.lon_normalize(coastal_centroids[:, 1], center=t_mid_lon)
        coastal_idx = coastal_idx[((t_lon_min <= coastal_centroids[:, 1])
                                   & (coastal_centroids[:, 1] <= t_lon_max)
                                   & (t_lat_min <= coastal_centroids[:, 0])
                                   & (coastal_centroids[:, 0] <= t_lat_max))]

        LOGGER.info('Mapping %s tracks to %s coastal centroids.',
                    str(tracks.size), str(coastal_idx.size))
        if self.pool:
            chunksize = min(num_tracks // self.pool.ncpus, 1000)
            tc_haz = self.pool.map(self._tc_from_track,
                                   tracks.data,
                                   itertools.repeat(centroids, num_tracks),
                                   itertools.repeat(coastal_idx, num_tracks),
                                   itertools.repeat(model, num_tracks),
                                   itertools.repeat(store_windfields,
                                                    num_tracks),
                                   itertools.repeat(metric, num_tracks),
                                   chunksize=chunksize)
        else:
            last_perc = 0
            tc_haz = []
            for track in tracks.data:
                perc = 100 * len(tc_haz) / len(tracks.data)
                if perc - last_perc >= 10:
                    LOGGER.info("Progress: %d%%", perc)
                    last_perc = perc
                self.append(
                    self._tc_from_track(track,
                                        centroids,
                                        coastal_idx,
                                        model=model,
                                        store_windfields=store_windfields,
                                        metric=metric))
            if last_perc < 100:
                LOGGER.info("Progress: 100%")
        LOGGER.debug('Compute frequency.')
        self.frequency_from_tracks(tracks.data)
        self.tag.description = description
Esempio n. 4
0
    def set_from_tracks(self,
                        tracks,
                        centroids=None,
                        description='',
                        model='H08',
                        ignore_distance_to_coast=False,
                        store_windfields=False):
        """Clear and fill with windfields from specified tracks.

        Parameters:
            tracks (TCTracks): tracks of events
            centroids (Centroids, optional): Centroids where to model TC.
                Default: global centroids.
            description (str, optional): description of the events
            model (str, optional): model to compute gust. Default Holland2008.
            ignore_distance_to_coast (boolean, optional): if True, centroids
                far from coast are not ignored. Default False
            store_windfields (boolean, optional): If True, the Hazard object
                gets a list `windfields` of sparse matrices. For each track,
                the full velocity vectors at each centroid and track position
                are stored in a sparse matrix of shape
                (npositions,  ncentroids * 2), that can be reshaped to a full
                ndarray of shape (npositions, ncentroids, 2). Default: False.

        Raises:
            ValueError
        """
        num_tracks = tracks.size
        if centroids is None:
            centroids = Centroids.from_base_grid(res_as=360, land=False)

        if not centroids.coord.size:
            centroids.set_meta_to_lat_lon()

        if ignore_distance_to_coast:
            # Select centroids with lat < 61
            coastal_idx = (np.abs(centroids.lat) < 61).nonzero()[0]
        else:
            # Select centroids which are inside INLAND_MAX_DIST_KM and lat < 61
            if not centroids.dist_coast.size:
                centroids.set_dist_coast()
            coastal_idx = ((centroids.dist_coast < INLAND_MAX_DIST_KM * 1000)
                           & (np.abs(centroids.lat) < 61)).nonzero()[0]

        LOGGER.info('Mapping %s tracks to %s centroids.', str(tracks.size),
                    str(coastal_idx.size))
        if self.pool:
            chunksize = min(num_tracks // self.pool.ncpus, 1000)
            tc_haz = self.pool.map(self._tc_from_track,
                                   tracks.data,
                                   itertools.repeat(centroids, num_tracks),
                                   itertools.repeat(coastal_idx, num_tracks),
                                   itertools.repeat(model, num_tracks),
                                   itertools.repeat(store_windfields,
                                                    num_tracks),
                                   chunksize=chunksize)
        else:
            last_perc = 0
            tc_haz = []
            for track in tracks.data:
                perc = 100 * len(tc_haz) / len(tracks.data)
                if perc - last_perc >= 10:
                    LOGGER.info("Progress: %d%%", perc)
                    last_perc = perc
                tc_haz.append(
                    self._tc_from_track(track,
                                        centroids,
                                        coastal_idx,
                                        model=model,
                                        store_windfields=store_windfields))
        LOGGER.debug('Append events.')
        self.concatenate(tc_haz)
        LOGGER.debug('Compute frequency.')
        self.frequency_from_tracks(tracks.data)
        self.tag.description = description
Esempio n. 5
0
    def set_from_tracks(self, tracks, centroids=None, description='',
                        model='H08', ignore_distance_to_coast=False,
                        store_windfields=False, metric="equirect"):
        """Clear and fill with windfields from specified tracks.

        Parameters
        ----------
        tracks : TCTracks
            Tracks of storm events.
        centroids : Centroids, optional
            Centroids where to model TC. Default: global centroids at 360 arc-seconds resolution.
        description : str, optional
            Description of the event set. Default: "".
        model : str, optional
            Model to compute gust. Currently only 'H08' is supported for the one implemented in
            `_stat_holland` according to Greg Holland. Default: "H08".
        ignore_distance_to_coast : boolean, optional
            If True, centroids far from coast are not ignored. Default: False.
        store_windfields : boolean, optional
            If True, the Hazard object gets a list `windfields` of sparse matrices. For each track,
            the full velocity vectors at each centroid and track position are stored in a sparse
            matrix of shape (npositions,  ncentroids * 2) that can be reshaped to a full ndarray
            of shape (npositions, ncentroids, 2). Default: False.
        metric : str, optional
            Specify an approximation method to use for earth distances:
            * "equirect": Distance according to sinusoidal projection. Fast, but inaccurate for
              large distances and high latitudes.
            * "geosphere": Exact spherical distance. Much more accurate at all distances, but slow.
            Default: "equirect".

        Raises
        ------
        ValueError
        """
        num_tracks = tracks.size
        if centroids is None:
            centroids = Centroids.from_base_grid(res_as=360, land=False)

        if not centroids.coord.size:
            centroids.set_meta_to_lat_lon()

        if ignore_distance_to_coast:
            # Select centroids with lat < 61
            coastal_idx = (np.abs(centroids.lat) < 61).nonzero()[0]
        else:
            # Select centroids which are inside INLAND_MAX_DIST_KM and lat < 61
            if not centroids.dist_coast.size:
                centroids.set_dist_coast()
            coastal_idx = ((centroids.dist_coast < INLAND_MAX_DIST_KM * 1000)
                           & (np.abs(centroids.lat) < 61)).nonzero()[0]

        # Restrict to coastal centroids within reach of any of the tracks
        t_lon_min, t_lat_min, t_lon_max, t_lat_max = tracks.get_bounds(
            deg_buffer=CENTR_NODE_MAX_DIST_DEG)
        t_mid_lon = 0.5 * (t_lon_min + t_lon_max)
        coastal_centroids = centroids.coord[coastal_idx]
        u_coord.lon_normalize(coastal_centroids[:, 1], center=t_mid_lon)
        coastal_idx = coastal_idx[((t_lon_min <= coastal_centroids[:, 1])
                                   & (coastal_centroids[:, 1] <= t_lon_max)
                                   & (t_lat_min <= coastal_centroids[:, 0])
                                   & (coastal_centroids[:, 0] <= t_lat_max))]

        LOGGER.info('Mapping %s tracks to %s coastal centroids.', str(tracks.size),
                    str(coastal_idx.size))
        if self.pool:
            chunksize = min(num_tracks // self.pool.ncpus, 1000)
            tc_haz = self.pool.map(
                self._tc_from_track, tracks.data,
                itertools.repeat(centroids, num_tracks),
                itertools.repeat(coastal_idx, num_tracks),
                itertools.repeat(model, num_tracks),
                itertools.repeat(store_windfields, num_tracks),
                itertools.repeat(metric, num_tracks),
                chunksize=chunksize)
        else:
            last_perc = 0
            tc_haz = []
            for track in tracks.data:
                perc = 100 * len(tc_haz) / len(tracks.data)
                if perc - last_perc >= 10:
                    LOGGER.info("Progress: %d%%", perc)
                    last_perc = perc
                tc_haz.append(
                    self._tc_from_track(track, centroids, coastal_idx,
                                        model=model, store_windfields=store_windfields,
                                        metric=metric))
            if last_perc < 100:
                LOGGER.info("Progress: 100%")
        LOGGER.debug('Append events.')
        self.concatenate(tc_haz)
        LOGGER.debug('Compute frequency.')
        self.frequency_from_tracks(tracks.data)
        self.tag.description = description