Example #1
0
 def test_get_landfall_idx(self):
     """Test identification of landfalls"""
     tr_ds = xr.Dataset()
     datetimes = list()
     for h in range(0, 24, 3):
         datetimes.append(dt(2000, 1, 1, h))
     tr_ds.coords['time'] = ('time', datetimes)
     # no landfall
     tr_ds['on_land'] = np.repeat(np.array([False]), 8)
     sea_land_idx, land_sea_idx = tc._get_landfall_idx(tr_ds)
     self.assertEqual([len(sea_land_idx), len(land_sea_idx)], [0,0])
     # single landfall
     tr_ds['on_land'] = np.array([False, False, True, True, True, False, False, False])
     sea_land_idx, land_sea_idx = tc._get_landfall_idx(tr_ds)
     self.assertEqual([len(sea_land_idx), len(land_sea_idx)], [1,1])
     self.assertEqual([sea_land_idx, land_sea_idx], [2, 5])
     # single landfall from starting point
     tr_ds['on_land'] = np.array([True, True, True, True, True, False, False, False])
     sea_land_idx, land_sea_idx = tc._get_landfall_idx(tr_ds)
     self.assertEqual([len(sea_land_idx), len(land_sea_idx)], [0,0])
     sea_land_idx, land_sea_idx = tc._get_landfall_idx(tr_ds, include_starting_landfall=True)
     self.assertEqual([sea_land_idx, land_sea_idx], [0, 5])
     # two landfalls
     tr_ds['on_land'] = np.array([False, True, True, False, False, False, True, True])
     sea_land_idx, land_sea_idx = tc._get_landfall_idx(tr_ds)
     self.assertEqual([len(sea_land_idx), len(land_sea_idx)], [2,2])
     self.assertEqual(sea_land_idx.tolist(), [1,6])
     self.assertEqual(land_sea_idx.tolist(), [3,8])
     # two landfalls, starting on land
     tr_ds['on_land'] = np.array([True, True, False, False, True, True, False, False])
     sea_land_idx, land_sea_idx = tc._get_landfall_idx(tr_ds)
     self.assertEqual([sea_land_idx, land_sea_idx], [4, 6])
     sea_land_idx, land_sea_idx = tc._get_landfall_idx(tr_ds, include_starting_landfall=True)
     self.assertEqual(sea_land_idx.tolist(), [0,4])
     self.assertEqual(land_sea_idx.tolist(), [2,6])
    def test_decay_end_ocean(self):
        """Test decay is applied after landfall if the track ends over the ocean"""
        tracks_synth_nodecay_example = tc.TCTracks()
        # this track was generated without applying landfall decay
        # (i.e. with decay=False in tc_synth.calc_perturbed_trajectories)
        tracks_synth_nodecay_example.read_netcdf(TEST_TRACK_DECAY_END_OCEAN)

        # apply landfall decay
        extent = tracks_synth_nodecay_example.get_extent()
        land_geom = climada.util.coordinates.get_land_geometry(extent=extent,
                                                               resolution=10)
        tracks_synth_nodecay_example.data = tc_synth._apply_land_decay(
            tracks_synth_nodecay_example.data, tc_synth.LANDFALL_DECAY_V,
            tc_synth.LANDFALL_DECAY_P, land_geom)
        track = tracks_synth_nodecay_example.data[0]

        # read its corresponding historical track
        track_hist = tc.TCTracks()
        track_hist.read_netcdf(TEST_TRACK_DECAY_END_OCEAN_HIST)
        track_hist = track_hist.data[0]

        # Part 1: is landfall applied after going back to the ocean?
        # get that last strip over the ocean
        lf_idx = tc._get_landfall_idx(track)
        last_lf_idx = lf_idx[-1][1]
        # only suitable if track ends over the ocean
        self.assertTrue(last_lf_idx < track.time.size - 2,
                        'This test should be re-written, data not suitable')
        # check pressure and wind values
        p_hist_end = track_hist.central_pressure.values[last_lf_idx:]
        p_synth_end = track.central_pressure.values[last_lf_idx:]
        self.assertTrue(np.all(p_synth_end > p_hist_end))
        v_hist_end = track_hist.max_sustained_wind.values[last_lf_idx:]
        v_synth_end = track.max_sustained_wind.values[last_lf_idx:]
        self.assertTrue(np.all(v_synth_end < v_hist_end))

        # Part 2: is landfall applied in all landfalls?
        p_hist_lf = np.concatenate([
            track_hist.central_pressure.values[lfs:lfe]
            for lfs, lfe in zip(*lf_idx)
        ])
        p_synth_lf = np.concatenate([
            track.central_pressure.values[lfs:lfe] for lfs, lfe in zip(*lf_idx)
        ])
        v_hist_lf = np.concatenate([
            track_hist.max_sustained_wind.values[lfs:lfe]
            for lfs, lfe in zip(*lf_idx)
        ])
        v_synth_lf = np.concatenate([
            track.max_sustained_wind.values[lfs:lfe]
            for lfs, lfe in zip(*lf_idx)
        ])
        self.assertTrue(np.all(p_synth_lf > p_hist_lf))
        self.assertTrue(np.all(v_synth_lf < v_hist_lf))
        self.assertTrue(
            np.all(track.central_pressure.values <=
                   track.environmental_pressure.values))
    def test_decay_penv_gt_pcen(self):
        """Test decay is applied if penv at end of landfall < pcen just before landfall"""
        tracks_synth_nodecay_example = tc.TCTracks()
        # this track was generated without applying landfall decay
        # (i.e. with decay=False in tc_synth.calc_perturbed_trajectories)
        tracks_synth_nodecay_example.read_netcdf(TEST_TRACK_DECAY_PENV_GT_PCEN)

        # apply landfall decay
        extent = tracks_synth_nodecay_example.get_extent()
        land_geom = climada.util.coordinates.get_land_geometry(extent=extent,
                                                               resolution=10)
        tracks_synth_nodecay_example.data = tc_synth._apply_land_decay(
            tracks_synth_nodecay_example.data, tc_synth.LANDFALL_DECAY_V,
            tc_synth.LANDFALL_DECAY_P, land_geom)
        track = tracks_synth_nodecay_example.data[0]

        # read its corresponding historical track
        track_hist = tc.TCTracks()
        track_hist.read_netcdf(TEST_TRACK_DECAY_PENV_GT_PCEN_HIST)
        track_hist = track_hist.data[0]

        # Part 1: is landfall applied after going back to the ocean?
        # get that last strip over the ocean
        lf_idx = tc._get_landfall_idx(track)
        start_lf_idx, end_lf_idx = lf_idx[0][0], lf_idx[1][0]

        # check pressure and wind values
        p_hist_end = track_hist.central_pressure.values[end_lf_idx:]
        p_synth_end = track.central_pressure.values[end_lf_idx:]
        self.assertTrue(np.all(p_synth_end > p_hist_end))
        v_hist_end = track_hist.max_sustained_wind.values[end_lf_idx:]
        v_synth_end = track.max_sustained_wind.values[end_lf_idx:]
        self.assertTrue(np.all(v_synth_end < v_hist_end))

        # Part 2: is landfall applied in all landfalls?

        # central pressure
        p_hist_lf = track_hist.central_pressure.values[start_lf_idx:end_lf_idx]
        p_synth_lf = track.central_pressure.values[start_lf_idx:end_lf_idx]
        # central pressure should be higher in synth than hist; unless it was set to p_env
        self.assertTrue(
            np.all(
                np.logical_or(
                    p_synth_lf > p_hist_lf, p_synth_lf == track.
                    environmental_pressure.values[start_lf_idx:end_lf_idx])))
        # but for this track is should be higher towards the end
        self.assertTrue(np.any(p_synth_lf > p_hist_lf))
        self.assertTrue(np.all(p_synth_lf >= p_hist_lf))

        # wind speed
        v_hist_lf = track_hist.max_sustained_wind.values[
            start_lf_idx:end_lf_idx]
        v_synth_lf = track.max_sustained_wind.values[start_lf_idx:end_lf_idx]
        # wind should decrease over time for that landfall
        v_before_lf = track_hist.max_sustained_wind.values[start_lf_idx - 1]
        self.assertTrue(np.all(v_synth_lf[1:] < v_before_lf))
        # and wind speed should be lower in synth than hist at the end of and after this landfall
        self.assertTrue(
            np.all(track.max_sustained_wind.values[end_lf_idx:] <
                   track_hist.max_sustained_wind.values[end_lf_idx:]))
        # finally, central minus env pressure cannot increase during this landfall
        p_env_lf = track.central_pressure.values[start_lf_idx:end_lf_idx]
        self.assertTrue(np.all(np.diff(p_env_lf - p_synth_lf) <= 0))