Пример #1
0
 def test_last_year_pass(self):
     """ Test last_year """
     ordinal_date = [dt.datetime.toordinal(dt.datetime(2018, 4, 6)),
                     dt.datetime.toordinal(dt.datetime(1918, 4, 6)),
                     dt.datetime.toordinal(dt.datetime(2019, 1, 1))]
     self.assertEqual(u_dt.last_year(ordinal_date), 2019)
     self.assertEqual(u_dt.last_year(np.array(ordinal_date)), 2019)
Пример #2
0
    def generate_prob_storms(self,
                             reg_id=528,
                             spatial_shift=4,
                             ssi_args={},
                             **kwargs):
        """ Generates a new hazard set with one original and 29 probabilistic
        storms per historic storm. This represents a partial implementation of
        the Monte-Carlo method described in section 2.2 of Schwierz et al.
        (2010), doi:10.1007/s10584-009-9712-1.
        It omits the rotation of the storm footprints, as well as the pseudo-
        random alterations to the intensity.

        In a first step, the original intensity and five additional intensities
        are saved to an array. In a second step, those 6 possible intensity
        levels are shifted by n raster pixels into each direction (N/S/E/W).

        Caveats:
            - Memory safety is an issue; trial with the entire dataset resulted
              in 60GB of swap memory being used...
            - Can only use numeric region_id for country selection
            - Drops event names as provided by WISC

        Parameters:
            region_id (int, list of ints, or None): iso_n3 code of the
                countries we want the generated hazard set to be returned for.
            spatial_shift (int): amount of raster pixels to shift by
            ssi_args (dict): A dictionary of arguments passed to calc_ssi
            **kwargs: keyword arguments passed on to self._hist2prob()

        Returns:
            new_haz (StormEurope): A new hazard set for the given country.
                Centroid attributes are preserved. self.orig attribute is set
                to True for original storms (event_id ending in 00). Also
                contains a ssi_prob attribute,
        """
        # bool vector selecting the targeted centroids
        if reg_id is not None:
            if self.centroids.region_id.size == 0:
                self.centroids.set_region_id()
            if not isinstance(reg_id, list):
                reg_id = [reg_id]
            sel_cen = np.isin(self.centroids.region_id, reg_id)

        else:  # shifting truncates valid centroids
            sel_cen = np.zeros(self.centroids.shape_grid, bool)
            sel_cen[spatial_shift:-spatial_shift,
                    spatial_shift:-spatial_shift] = True
            sel_cen = sel_cen.reshape(self.centroids.size)

        # init probabilistic array
        n_out = N_PROB_EVENTS * self.size
        intensity_prob = sparse.lil_matrix((n_out, np.count_nonzero(sel_cen)))
        ssi = np.zeros(n_out)

        LOGGER.info('Commencing probabilistic calculations')
        for index, intensity1d in enumerate(self.intensity):
            # indices for return matrix
            start = index * N_PROB_EVENTS
            end = (index + 1) * N_PROB_EVENTS

            intensity_prob[start:end, :], ssi[start:end] =\
                self._hist2prob(
                    intensity1d,
                    sel_cen,
                    spatial_shift,
                    ssi_args,
                    **kwargs,
                )

        LOGGER.info('Generating new StormEurope instance')
        new_haz = StormEurope()
        new_haz.intensity = sparse.csr_matrix(intensity_prob)
        new_haz.ssi_full_area = ssi

        # don't use synthetic dates; just repeat the historic dates
        new_haz.date = np.repeat(self.date, N_PROB_EVENTS)

        # subsetting centroids
        new_haz.centroids = self.centroids.select(sel_cen=sel_cen)

        # construct new event ids
        base = np.repeat((self.event_id * 100), N_PROB_EVENTS)
        synth_id = np.tile(np.arange(N_PROB_EVENTS), self.size)
        new_haz.event_id = base + synth_id

        # frequency still based on the historic number of years
        new_haz.frequency = np.divide(np.ones_like(
            new_haz.event_id), (last_year(self.date) - first_year(self.date)))

        self.tag = TagHazard(
            HAZ_TYPE,
            'Hazard set not saved by default',
            description='WISC probabilistic hazard set using Schwierz et al.')

        new_haz.fraction = new_haz.intensity.copy().tocsr()
        new_haz.fraction.data.fill(1)
        new_haz.orig = (new_haz.event_id % 100 == 0)
        new_haz.check()

        return new_haz
Пример #3
0
    def read_footprints(self,
                        path,
                        description=None,
                        ref_raster=None,
                        centroids=None,
                        files_omit='fp_era20c_1990012515_701_0.nc'):
        """ Clear instance and read WISC footprints into it. Read Assumes that
        all footprints have the same coordinates as the first file listed/first
        file in dir.

        Parameters:
            path (str, list(str)): A location in the filesystem. Either a
                path to a single netCDF WISC footprint, or a folder
                containing only footprints, or a globbing pattern to one or
                more footprints.
            description (str, optional): description of the events, defaults
                to 'WISC historical hazard set'
            ref_raster (str, optional): Reference netCDF file from which to
                construct a new barebones Centroids instance. Defaults to
                the first file in path.
            centroids (Centroids, optional): A Centroids struct, overriding
                ref_raster
            files_omit (str, list(str), optional): List of files to omit;
                defaults to one duplicate storm present in the WISC set as
                of 2018-09-10.
        """

        self.clear()

        file_names = get_file_names(path)

        if ref_raster is not None and centroids is not None:
            LOGGER.warning('Overriding ref_raster with centroids')

        if centroids is not None:
            pass
        elif ref_raster is not None:
            centroids = self._centroids_from_nc(ref_raster)
        elif ref_raster is None:
            centroids = self._centroids_from_nc(file_names[0])

        if isinstance(files_omit, str):
            files_omit = [files_omit]

        LOGGER.info('Commencing to iterate over netCDF files.')

        for file_name in file_names:
            if any(fo in file_name for fo in files_omit):
                LOGGER.info("Omitting file %s", file_name)
                continue
            new_haz = self._read_one_nc(file_name, centroids)
            if new_haz is not None:
                self.append(new_haz)

        self.event_id = np.arange(1, len(self.event_id) + 1)
        self.frequency = np.divide(np.ones_like(
            self.date), (last_year(self.date) - first_year(self.date)))

        self.tag = TagHazard(HAZ_TYPE,
                             'Hazard set not saved by default',
                             description='WISC historical hazard set.')
        if description is not None:
            self.tag.description = description
Пример #4
0
    def from_footprints(cls,
                        path,
                        description=None,
                        ref_raster=None,
                        centroids=None,
                        files_omit='fp_era20c_1990012515_701_0.nc',
                        combine_threshold=None,
                        intensity_thres=None):
        """Create new StormEurope object from WISC footprints.

        Assumes that all footprints have the same coordinates as the first file listed/first
        file in dir.

        Parameters
        ----------
        path : str, list(str)
            A location in the filesystem. Either a
            path to a single netCDF WISC footprint, or a folder
            containing only footprints, or a globbing pattern to one or
            more footprints.
        description : str, optional
            description of the events, defaults
            to 'WISC historical hazard set'
        ref_raster : str, optional
            Reference netCDF file from which to
            construct a new barebones Centroids instance. Defaults to
            the first file in path.
        centroids : Centroids, optional
            A Centroids struct, overriding
            ref_raster
        files_omit : str, list(str), optional
            List of files to omit;
            defaults to one duplicate storm present in the WISC set as
            of 2018-09-10.
        combine_threshold : int, optional
            threshold for combining events
            in number of days. if the difference of the dates (self.date)
            of two events is smaller or equal to this threshold, the two
            events are combined into one.
            Default is None, Advised for WISC is 2
        intensity_thres : float, optional
            Intensity threshold for storage in m/s. Default: class attribute
            StormEurope.intensity_thres (same as used by WISC SSI calculations)

        Returns
        -------
        haz : StormEurope
            StormEurope object with data from WISC footprints.
        """
        intensity_thres = cls.intensity_thres if intensity_thres is None else intensity_thres
        file_names = get_file_names(path)

        if ref_raster is not None and centroids is not None:
            LOGGER.warning('Overriding ref_raster with centroids')

        if centroids is not None:
            pass
        elif ref_raster is not None:
            centroids = cls._centroids_from_nc(ref_raster)
        elif ref_raster is None:
            centroids = cls._centroids_from_nc(file_names[0])

        if isinstance(files_omit, str):
            files_omit = [files_omit]

        LOGGER.info('Commencing to iterate over netCDF files.')

        haz = cls()
        for file_name in file_names:
            if any(fo in file_name for fo in files_omit):
                LOGGER.info("Omitting file %s", file_name)
                continue
            new_haz = cls._read_one_nc(file_name, centroids, intensity_thres)
            if new_haz is not None:
                haz.append(new_haz)

        haz.event_id = np.arange(1, len(haz.event_id) + 1)
        haz.frequency = np.divide(
            np.ones_like(haz.date),
            np.max([(last_year(haz.date) - first_year(haz.date)), 1]))

        haz.tag = TagHazard(HAZ_TYPE,
                            'Hazard set not saved by default',
                            description='WISC historical hazard set.')
        if description is not None:
            haz.tag.description = description

        if combine_threshold is not None:
            LOGGER.info('Combining events with small difference in date.')
            difference_date = np.diff(haz.date)
            for event_id_i in haz.event_id[np.append(
                    difference_date <= combine_threshold, False)]:
                event_ids = [event_id_i, event_id_i + 1]
                haz._combine_events(event_ids)
        return haz