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))
Example #2
0
    def test_apply_decay_no_landfall_pass(self):
        """Test _apply_land_decay with no historical tracks with landfall"""
        tc_track = tc.TCTracks()
        tc_track.read_processed_ibtracs_csv(TEST_TRACK_SHORT)
        extent = tc_track.get_extent()
        land_geom = climada.util.coordinates.get_land_geometry(
            extent=extent, resolution=10
        )
        tc.track_land_params(tc_track.data[0], land_geom)
        tc_track.data[0]['orig_event_flag'] = False
        tc_ref = tc_track.data[0].copy()
        tc_synth._apply_land_decay(tc_track.data, dict(), dict(), land_geom)

        self.assertTrue(np.allclose(tc_track.data[0].max_sustained_wind.values,
                                    tc_ref.max_sustained_wind.values))
        self.assertTrue(np.allclose(tc_track.data[0].central_pressure.values,
                                    tc_ref.central_pressure.values))
        self.assertTrue(np.allclose(tc_track.data[0].environmental_pressure.values,
                                    tc_ref.environmental_pressure.values))
        self.assertTrue(np.all(np.isnan(tc_track.data[0].dist_since_lf.values)))
Example #3
0
    def test_apply_decay_pass(self):
        """Test _apply_land_decay against MATLAB reference."""
        v_rel = {
            6: 0.0038950967656296597,
            1: 0.0038950967656296597,
            2: 0.0038950967656296597,
            3: 0.0038950967656296597,
            4: 0.0038950967656296597,
            5: 0.0038950967656296597,
            7: 0.0038950967656296597
        }

        p_rel = {
            6: (1.0499941, 0.007978940084158488),
            1: (1.0499941, 0.007978940084158488),
            2: (1.0499941, 0.007978940084158488),
            3: (1.0499941, 0.007978940084158488),
            4: (1.0499941, 0.007978940084158488),
            5: (1.0499941, 0.007978940084158488),
            7: (1.0499941, 0.007978940084158488)
        }

        tc_track = tc.TCTracks()
        tc_track.read_processed_ibtracs_csv(TC_ANDREW_FL)
        tc_track.data[0]['orig_event_flag'] = False
        extent = tc_track.get_extent()
        land_geom = climada.util.coordinates.get_land_geometry(
            extent=extent, resolution=10
        )
        tc.track_land_params(tc_track.data[0], land_geom)
        tc_synth._apply_land_decay(tc_track.data, v_rel, p_rel, land_geom,
                                   s_rel=True, check_plot=False)

        p_ref = np.array([
            1.010000000000000, 1.009000000000000, 1.008000000000000,
            1.006000000000000, 1.003000000000000, 1.002000000000000,
            1.001000000000000, 1.000000000000000, 1.000000000000000,
            1.001000000000000, 1.002000000000000, 1.005000000000000,
            1.007000000000000, 1.010000000000000, 1.010000000000000,
            1.010000000000000, 1.010000000000000, 1.010000000000000,
            1.010000000000000, 1.007000000000000, 1.004000000000000,
            1.000000000000000, 0.994000000000000, 0.981000000000000,
            0.969000000000000, 0.961000000000000, 0.947000000000000,
            0.933000000000000, 0.922000000000000, 0.930000000000000,
            0.937000000000000, 0.951000000000000, 0.947000000000000,
            0.943000000000000, 0.948000000000000, 0.946000000000000,
            0.941000000000000, 0.937000000000000, 0.955000000000000,
            0.9741457117, 0.99244068917, 1.00086729492, 1.00545853355,
            1.00818354609, 1.00941850023, 1.00986192053, 1.00998400565
        ]) * 1e3

        self.assertTrue(np.allclose(p_ref, tc_track.data[0].central_pressure.values))

        v_ref = np.array([
            0.250000000000000, 0.300000000000000, 0.300000000000000,
            0.350000000000000, 0.350000000000000, 0.400000000000000,
            0.450000000000000, 0.450000000000000, 0.450000000000000,
            0.450000000000000, 0.450000000000000, 0.450000000000000,
            0.450000000000000, 0.400000000000000, 0.400000000000000,
            0.400000000000000, 0.400000000000000, 0.450000000000000,
            0.450000000000000, 0.500000000000000, 0.500000000000000,
            0.550000000000000, 0.650000000000000, 0.800000000000000,
            0.950000000000000, 1.100000000000000, 1.300000000000000,
            1.450000000000000, 1.500000000000000, 1.250000000000000,
            1.300000000000000, 1.150000000000000, 1.150000000000000,
            1.150000000000000, 1.150000000000000, 1.200000000000000,
            1.250000000000000, 1.250000000000000, 1.200000000000000,
            0.9737967353, 0.687255951, 0.4994850556, 0.3551480462, 0.2270548036,
            0.1302099557, 0.0645385918, 0.0225325851
        ]) * 1e2

        self.assertTrue(np.allclose(v_ref, tc_track.data[0].max_sustained_wind.values))

        cat_ref = tc.set_category(tc_track.data[0].max_sustained_wind.values,
                                  tc_track.data[0].max_sustained_wind_unit)
        self.assertEqual(cat_ref, tc_track.data[0].category)
    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))