def test_fraction_on_land(self):
        """Test _fraction_on_land helper function."""
        res_deg = 10 / (60 * 60)
        bounds = (-149.54, -23.42, -149.40, -23.33)
        lat = np.arange(bounds[1] + 0.5 * res_deg, bounds[3], res_deg)
        lon = np.arange(bounds[0] + 0.5 * res_deg, bounds[2], res_deg)
        shape = (lat.size, lon.size)
        lon, lat = [ar.ravel() for ar in np.meshgrid(lon, lat)]
        centroids = Centroids()
        centroids.set_lat_lon(lat, lon)
        centroids.set_dist_coast(signed=True, precomputed=True)

        dem_bounds = (bounds[0] - 1, bounds[1] - 1, bounds[2] + 1, bounds[3] + 1)
        dem_res = 3 / (60 * 60)
        with tmp_artifical_topo(dem_bounds, dem_res) as topo_path:
            fraction = _fraction_on_land(centroids, topo_path)
        fraction = fraction.reshape(shape)
        dist_coast = centroids.dist_coast.reshape(shape)

        # check valid range and order of magnitude
        self.assertTrue(np.all((fraction >= 0) & (fraction <= 1)))
        np.testing.assert_array_equal(fraction[dist_coast > 1000], 0)
        np.testing.assert_array_equal(fraction[dist_coast < -1000], 1)

        # check individual known pixel values
        self.assertAlmostEqual(fraction[24, 10], 0.0)
        self.assertAlmostEqual(fraction[22, 11], 0.21)
        self.assertAlmostEqual(fraction[22, 12], 0.93)
        self.assertAlmostEqual(fraction[21, 14], 1.0)
Beispiel #2
0
    def centroids(self, latlon=None, res_as=360):
        """Return centroids in this region

        Parameters
        ----------
        latlon : pair (lat, lon), optional
            Latitude and longitude of centroids.
            If not given, values are taken from CLIMADA's base grid (see `res_as`).
        res_as : int, optional
            One of 150 or 360. When `latlon` is not given, choose coordinates from centroids
            according to CLIMADA's base grid of given resolution in arc-seconds. Default: 360.

        Returns
        -------
        centroids : climada.hazard.Centroids object
        """
        if latlon is None:
            centroids = Centroids.from_base_grid(res_as=res_as)
            centroids.set_meta_to_lat_lon()
            lat, lon = centroids.lat, centroids.lon
        else:
            lat, lon = latlon
            centroids = Centroids()
            centroids.set_lat_lon(lat, lon)
        msk = shapely.vectorized.contains(self.shape, lon, lat)
        centroids = centroids.select(sel_cen=msk)
        centroids.id = np.arange(centroids.lon.shape[0])
        return centroids
def calc_tc(expo_dict, tracks, data_dir, pool):
    """ Compute tropical cyclone events from tracks at every island group,
    if not contained in data_dir. """
    try:
        abs_path = os.path.join(data_dir, 'tc_isl.p')
        with open(abs_path, 'rb') as f:
            tc_dict = pickle.load(f)
        print('Loaded tc_isl:', len(tc_dict))
    except FileNotFoundError:
        all_isl = BlackMarble(pd.concat(list(expo_dict.values())))

        centr = Centroids()
        centr.set_lat_lon(all_isl.latitude.values, all_isl.longitude.values)
        centr.region_id = all_isl.region_id.values
        centr.check()

        tc = TropCyclone(pool)
        tc.set_from_tracks(tracks, centr)

        tc_dict = dict()
        for ent_iso, ent_val in expo_dict.items():
            reg_id = np.unique(ent_val.region_id)[0]
            tc_dict[ent_iso] = tc.select(reg_id=reg_id)

        save(os.path.join(data_dir, 'tc_isl.p'), tc_dict)

    return tc_dict
Beispiel #4
0
def irma_tc(exp, data_irma):
    centr = Centroids()
    centr.set_lat_lon(exp.latitude.values, exp.longitude.values)

    tc_irma = TropCyclone()
    data_irma.equal_timestep(0.1)
    tc_irma.set_from_tracks(data_irma, centr)

    return tc_irma
    def __init__(self, bounds, res_deg):
        """Read distance to coast values from raster file for later use.

        Parameters
        ----------
        bounds : tuple (lon_min, lat_min, lon_max, lat_max)
            Coordinates of bounding box
        res_deg : float
            Resolution in degrees
        """
        lat = np.arange(bounds[3] - 0.5 * res_deg, bounds[1], -res_deg)
        lon = np.arange(bounds[0] + 0.5 * res_deg, bounds[2], res_deg)
        self.shape = (lat.size, lon.size)
        self.transform = rasterio.Affine(res_deg, 0, bounds[0], 0, -res_deg, bounds[3])
        centroids = Centroids()
        centroids.set_lat_lon(*[ar.ravel() for ar in np.meshgrid(lon, lat)][::-1])
        centroids.set_dist_coast(signed=True, precomputed=True)
        self.dist_coast = centroids.dist_coast
    def test_surge_from_track(self):
        """Test TCSurgeBathtub.from_tc_winds function."""
        # similar to IBTrACS 2010029S12177 (OLI, 2010) hitting Tubuai, but much stronger
        track = xr.Dataset({
            'radius_max_wind': ('time', [15., 15, 15, 15, 15, 17, 20, 20]),
            'radius_oci': ('time', [202., 202, 202, 202, 202, 202, 202, 202]),
            'max_sustained_wind': ('time', [155., 147, 140, 135, 130, 122, 115, 116]),
            'central_pressure': ('time', [894., 901, 906, 909, 913, 918, 924, 925]),
            'environmental_pressure': ('time', np.full((8,), 1004.0, dtype=np.float64)),
            'time_step': ('time', np.full((8,), 3.0, dtype=np.float64)),
        }, coords={
            'time': np.arange('2010-02-05T09:00', '2010-02-06T09:00',
                              np.timedelta64(3, 'h'), dtype='datetime64[h]'),
            'lat': ('time', [-24.33, -25.54, -24.79, -24.05,
                             -23.35, -22.7, -22.07, -21.50]),
            'lon': ('time', [-147.27, -148.0, -148.51, -148.95,
                             -149.41, -149.85, -150.27, -150.56]),
        }, attrs={
            'max_sustained_wind_unit': 'kn',
            'central_pressure_unit': 'mb',
            'name': 'test',
            'sid': '2010029S12177_test',
            'orig_event_flag': True,
            'data_provider': 'unit_test',
            'basin': 'SP',
            'id_no': 0,
            'category': 4,
        })
        tc_track = TCTracks()
        tc_track.data = [track]
        tc_track.equal_timestep(time_step_h=1)

        res_deg = 10 / (60 * 60)
        bounds = (-149.54, -23.42, -149.40, -23.33)
        lat = np.arange(bounds[1] + 0.5 * res_deg, bounds[3], res_deg)
        lon = np.arange(bounds[0] + 0.5 * res_deg, bounds[2], res_deg)
        shape = (lat.size, lon.size)
        lon, lat = [ar.ravel() for ar in np.meshgrid(lon, lat)]
        centroids = Centroids()
        centroids.set_lat_lon(lat, lon)
        centroids.set_dist_coast(signed=True, precomputed=True)

        wind_haz = TropCyclone()
        wind_haz.set_from_tracks(tc_track, centroids=centroids)

        dem_bounds = (bounds[0] - 1, bounds[1] - 1, bounds[2] + 1, bounds[3] + 1)
        dem_res = 3 / (60 * 60)
        with tmp_artifical_topo(dem_bounds, dem_res) as topo_path:
            for slr in [0, 0.5, 1.5]:
                surge_haz = TCSurgeBathtub.from_tc_winds(wind_haz, topo_path,
                                                         add_sea_level_rise=slr)
                inten = surge_haz.intensity.toarray().reshape(shape)
                fraction = surge_haz.fraction.toarray().reshape(shape)

                # check valid range and order of magnitude
                np.testing.assert_array_equal(inten >= 0, True)
                np.testing.assert_array_equal(inten <= 10, True)
                np.testing.assert_array_equal((fraction >= 0) & (fraction <= 1), True)
                np.testing.assert_array_equal(inten[fraction == 0], 0)

                # check individual known pixel values
                self.assertAlmostEqual(inten[9, 31], max(-0.391 + slr, 0), places=2)
                self.assertAlmostEqual(inten[14, 34] - slr, 3.637, places=2)