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_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)))
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))