def test_gust_from_track(self): """ Test gust_from_track function. Compare to MATLAB reference. """ tc_track = TCTracks() tc_track.read_processed_ibtracs_csv(TEST_TRACK_SHORT) tc_track.equal_timestep() intensity = tc.gust_from_track(tc_track.data[0], CENT_CLB, model='H08') self.assertTrue(isinstance(intensity, sparse.csr.csr_matrix)) self.assertEqual(intensity.shape, (1, 1656093)) self.assertEqual(np.nonzero(intensity)[0].size, 7) self.assertEqual(intensity[0, 1630273], 0) self.assertAlmostEqual(intensity[0, 1630272], 18.505998796740347, 5) self.assertTrue(np.isclose(18.505998796740347, intensity[0, 1630272])) self.assertAlmostEqual(intensity[0, 1630393], 18.511077471450232, 6) self.assertTrue(np.isclose(18.511077471450232, intensity[0, 1630393])) self.assertAlmostEqual(intensity[0, 1630514], 18.297250626663271, 5) self.assertTrue(np.isclose(18.297250626663271, intensity[0, 1630514])) self.assertAlmostEqual(intensity[0, 1630635], 17.733240401598668, 6) self.assertTrue(np.isclose(17.733240401598668, intensity[0, 1630635])) self.assertAlmostEqual(intensity[0, 1630877], 17.525880201507256, 6) self.assertTrue(np.isclose(17.525880201507256, intensity[0, 1630877]))
def test_read_pass(self): """Read a tropical cyclone.""" tc_track = TCTracks() tc_track.read_processed_ibtracs_csv(TEST_TRACK) self.assertEqual(tc_track.data[0].time.size, 38) self.assertEqual(tc_track.data[0].lon[11], -39.60) self.assertEqual(tc_track.data[0].lat[23], 14.10) self.assertEqual(tc_track.data[0].time_step[7], 6) self.assertEqual(np.max(tc_track.data[0].radius_max_wind), 0) self.assertEqual(np.min(tc_track.data[0].radius_max_wind), 0) self.assertEqual(tc_track.data[0].max_sustained_wind[21], 55) self.assertEqual(tc_track.data[0].central_pressure[29], 969.76880) self.assertEqual(np.max(tc_track.data[0].environmental_pressure), 1010) self.assertEqual(np.min(tc_track.data[0].environmental_pressure), 1010) self.assertEqual(tc_track.data[0].time.dt.year[13], 1951) self.assertEqual(tc_track.data[0].time.dt.month[26], 9) self.assertEqual(tc_track.data[0].time.dt.day[7], 29) self.assertEqual(tc_track.data[0].max_sustained_wind_unit, 'kn') self.assertEqual(tc_track.data[0].central_pressure_unit, 'mb') self.assertEqual(tc_track.data[0].orig_event_flag, 1) self.assertEqual(tc_track.data[0].name, '1951239N12334') self.assertEqual(tc_track.data[0].sid, '1951239N12334') self.assertEqual(tc_track.data[0].id_no, 1951239012334) self.assertEqual(tc_track.data[0].data_provider, 'hurdat_atl') self.assertTrue(np.isnan(tc_track.data[0].basin)) self.assertEqual(tc_track.data[0].id_no, 1951239012334) self.assertEqual(tc_track.data[0].category, 1)
def test_set_one_file_pass(self): """Test set function set_from_tracks with one input.""" tc_track = TCTracks() tc_track.read_processed_ibtracs_csv(TEST_TRACK_SHORT) tc_haz = TCRain() tc_haz.set_from_tracks(tc_track, CENTR_TEST_BRB) tc_haz.check() self.assertEqual(tc_haz.tag.haz_type, 'TR') self.assertEqual(tc_haz.tag.description, '') self.assertEqual(tc_haz.tag.file_name, 'IBTrACS: 1951239N12334') self.assertEqual(tc_haz.units, 'mm') self.assertEqual(tc_haz.centroids.size, 296) self.assertEqual(tc_haz.event_id.size, 1) self.assertEqual(tc_haz.event_id[0], 1) self.assertEqual(tc_haz.event_name, ['1951239N12334']) self.assertEqual(tc_haz.category, tc_track.data[0].category) self.assertEqual(tc_haz.basin[0], "NA") self.assertIsInstance(tc_haz.basin, list) self.assertIsInstance(tc_haz.category, np.ndarray) self.assertTrue(np.array_equal(tc_haz.frequency, np.array([1]))) self.assertTrue(isinstance(tc_haz.intensity, sparse.csr.csr_matrix)) self.assertTrue(isinstance(tc_haz.fraction, sparse.csr.csr_matrix)) self.assertEqual(tc_haz.intensity.shape, (1, 296)) self.assertEqual(tc_haz.fraction.shape, (1, 296)) self.assertEqual(tc_haz.fraction.nonzero()[0].size, 0) self.assertEqual(tc_haz.intensity.nonzero()[0].size, 0)
def test_decay_values_andrew_pass(self): """ Test _decay_values with central pressure function.""" tc_track = TCTracks() tc_track.read_processed_ibtracs_csv(TC_ANDREW_FL) s_rel = False land_geom = tc._calc_land_geom(tc_track.data) tc._track_land_params(tc_track.data[0], land_geom) v_lf, p_lf, x_val = tc._decay_values(tc_track.data[0], land_geom, s_rel) ss_category = 6 s_cell_1 = 1*[1.0149413347244263] s_cell_2 = 8*[1.047120451927185] s_cell = s_cell_1 + s_cell_2 p_vs_lf_time_relative = [1.0149413020277482, 1.018848167539267, 1.037696335078534, \ 1.0418848167539267, 1.043979057591623, 1.0450261780104713, \ 1.0460732984293193, 1.0471204188481675, 1.0471204188481675] self.assertEqual(list(p_lf.keys()), [ss_category]) self.assertEqual(p_lf[ss_category][0], array.array('f', s_cell)) self.assertEqual(p_lf[ss_category][1], array.array('f', p_vs_lf_time_relative)) v_vs_lf_time_relative = [0.8846153846153846, 0.6666666666666666, 0.4166666666666667, \ 0.2916666666666667, 0.250000000000000, 0.250000000000000, \ 0.20833333333333334, 0.16666666666666666, 0.16666666666666666] self.assertEqual(list(v_lf.keys()), [ss_category]) self.assertEqual(v_lf[ss_category], array.array('f', v_vs_lf_time_relative)) x_val_ref = np.array([95.9512939453125, 53.624916076660156, 143.09530639648438, 225.0262908935547, 312.5832824707031, 427.43109130859375, 570.1857299804688, 750.3827514648438, 1020.5431518554688]) self.assertEqual(list(x_val.keys()), [ss_category]) self.assertTrue(np.allclose(x_val[ss_category], x_val_ref))
def test_set_one_pass(self): """Test _hazard_from_track function.""" tc_track = TCTracks() tc_track.read_processed_ibtracs_csv(TEST_TRACK_SHORT) tc_track.equal_timestep() coastal_centr = tc.coastal_centr_idx(CENT_CLB) tc_haz = TropCyclone._tc_from_track(tc_track.data[0], CENT_CLB, coastal_centr) self.assertEqual(tc_haz.tag.haz_type, 'TC') self.assertEqual(tc_haz.tag.description, '') self.assertEqual(tc_haz.tag.file_name, 'IBTrACS: 1951239N12334') self.assertEqual(tc_haz.units, 'm/s') self.assertEqual(tc_haz.centroids.size, 1656093) self.assertEqual(tc_haz.event_id.size, 1) self.assertEqual(tc_haz.date.size, 1) self.assertEqual(dt.datetime.fromordinal(tc_haz.date[0]).year, 1951) self.assertEqual(dt.datetime.fromordinal(tc_haz.date[0]).month, 8) self.assertEqual(dt.datetime.fromordinal(tc_haz.date[0]).day, 27) self.assertEqual(tc_haz.event_id[0], 1) self.assertEqual(tc_haz.event_name, ['1951239N12334']) self.assertTrue(np.array_equal(tc_haz.frequency, np.array([1]))) self.assertTrue(isinstance(tc_haz.intensity, sparse.csr.csr_matrix)) self.assertTrue(isinstance(tc_haz.fraction, sparse.csr.csr_matrix)) self.assertEqual(tc_haz.intensity.shape, (1, 1656093)) self.assertEqual(tc_haz.fraction.shape, (1, 1656093)) self.assertAlmostEqual(tc_haz.intensity[0, 1630393], 18.511077471450232, 6) self.assertEqual(tc_haz.intensity[0, 1630394], 0) self.assertEqual(tc_haz.fraction[0, 1630393], 1) self.assertEqual(tc_haz.fraction[0, 1630394], 0) self.assertEqual(tc_haz.fraction.nonzero()[0].size, 7) self.assertEqual(tc_haz.intensity.nonzero()[0].size, 7)
def test_set_one_file_pass(self): """ Test set function set_from_tracks with one input.""" pool = Pool() tc_track = TCTracks(pool) tc_track.read_processed_ibtracs_csv(TEST_TRACK) tc_track.calc_random_walk() tc_track.equal_timestep() tc_haz = TropCyclone(pool) tc_haz.set_from_tracks(tc_track, CENTR_TEST_BRB) tc_haz.check() pool.close() pool.join() self.assertEqual(tc_haz.tag.haz_type, 'TC') self.assertEqual(tc_haz.tag.description, '') self.assertEqual(tc_haz.units, 'm/s') self.assertEqual(tc_haz.centroids.size, 296) self.assertEqual(tc_haz.event_id.size, 10) self.assertTrue(isinstance(tc_haz.intensity, sparse.csr.csr_matrix)) self.assertTrue(isinstance(tc_haz.fraction, sparse.csr.csr_matrix)) self.assertEqual(tc_haz.intensity.shape, (10, 296)) self.assertEqual(tc_haz.fraction.shape, (10, 296))
def test_two_files_pass(self): """Test set function set_from_tracks with two ibtracs.""" tc_track = TCTracks() tc_track.read_processed_ibtracs_csv( [TEST_TRACK_SHORT, TEST_TRACK_SHORT]) tc_haz = TCRain() tc_haz.set_from_tracks(tc_track, CENTR_TEST_BRB) tc_haz.remove_duplicates() tc_haz.check() self.assertEqual(tc_haz.tag.haz_type, 'TR') self.assertEqual(tc_haz.tag.description, '') self.assertEqual(tc_haz.tag.file_name, ['IBTrACS: 1951239N12334', 'IBTrACS: 1951239N12334']) self.assertEqual(tc_haz.units, 'mm') self.assertEqual(tc_haz.centroids.size, 296) self.assertEqual(tc_haz.event_id.size, 1) self.assertEqual(tc_haz.event_id[0], 1) self.assertEqual(tc_haz.event_name, ['1951239N12334']) self.assertTrue(np.array_equal(tc_haz.frequency, np.array([1]))) self.assertTrue(np.array_equal(tc_haz.orig, np.array([True]))) self.assertTrue(isinstance(tc_haz.intensity, sparse.csr.csr_matrix)) self.assertTrue(isinstance(tc_haz.fraction, sparse.csr.csr_matrix)) self.assertEqual(tc_haz.intensity.shape, (1, 296)) self.assertEqual(tc_haz.fraction.shape, (1, 296)) self.assertEqual(tc_haz.fraction.nonzero()[0].size, 0) self.assertEqual(tc_haz.intensity.nonzero()[0].size, 0)
def test_random_no_landfall_pass(self): """ Test calc_random_walk with decay and no historical tracks with landfall """ tc_track = TCTracks() tc_track.read_processed_ibtracs_csv(TEST_TRACK_SHORT) with self.assertLogs('climada.hazard.tc_tracks', level='INFO') as cm: tc_track.calc_random_walk() self.assertIn('No historical track with landfall.', cm.output[1])
def test_interp_track_pass(self): """ Interpolate track to min_time_step. Compare to MATLAB reference.""" tc_track = TCTracks() tc_track.read_processed_ibtracs_csv(TEST_TRACK) tc_track.equal_timestep(time_step_h=1) self.assertEqual(tc_track.data[0].time.size, 223) self.assertAlmostEqual(tc_track.data[0].lon.values[11], -27.426151640151684) self.assertAlmostEqual(tc_track.data[0].lat[23], 12.300006169591480) self.assertEqual(tc_track.data[0].time_step[7], 1) self.assertEqual(np.max(tc_track.data[0].radius_max_wind), 0) self.assertEqual(np.min(tc_track.data[0].radius_max_wind), 0) self.assertEqual(tc_track.data[0].max_sustained_wind[21], 25) self.assertAlmostEqual(tc_track.data[0].central_pressure.values[29], 1.005409300000005e+03) self.assertEqual(np.max(tc_track.data[0].environmental_pressure), 1010) self.assertEqual(np.min(tc_track.data[0].environmental_pressure), 1010) self.assertEqual(tc_track.data[0]['time.year'][13], 1951) self.assertEqual(tc_track.data[0]['time.month'][26], 8) self.assertEqual(tc_track.data[0]['time.day'][7], 27) self.assertEqual(tc_track.data[0].max_sustained_wind_unit, 'kn') self.assertEqual(tc_track.data[0].central_pressure_unit, 'mb') self.assertEqual(tc_track.data[0].orig_event_flag, 1) self.assertEqual(tc_track.data[0].name, '1951239N12334') self.assertEqual(tc_track.data[0].data_provider, 'hurdat_atl') self.assertTrue(np.isnan(tc_track.data[0].basin)) self.assertEqual(tc_track.data[0].id_no, 1951239012334) self.assertEqual(tc_track.data[0].category, 1)
def test_set_one_pass(self): """Test _set_from_track function.""" tc_track = TCTracks() tc_track.read_processed_ibtracs_csv(TEST_TRACK) tc_track.equal_timestep() tc_haz = TCRain._set_from_track(tc_track.data[0], CENTR_TEST_BRB) self.assertEqual(tc_haz.tag.haz_type, 'TR') self.assertEqual(tc_haz.tag.description, '') self.assertEqual(tc_haz.tag.file_name, 'IBTrACS: 1951239N12334') self.assertEqual(tc_haz.units, 'mm') self.assertEqual(tc_haz.centroids.size, 296) self.assertEqual(tc_haz.event_id.size, 1) self.assertEqual(tc_haz.date.size, 1) self.assertEqual(dt.datetime.fromordinal(tc_haz.date[0]).year, 1951) self.assertEqual(dt.datetime.fromordinal(tc_haz.date[0]).month, 8) self.assertEqual(dt.datetime.fromordinal(tc_haz.date[0]).day, 27) self.assertEqual(tc_haz.event_id[0], 1) self.assertEqual(tc_haz.event_name, ['1951239N12334']) self.assertTrue(np.array_equal(tc_haz.frequency, np.array([1]))) self.assertTrue(isinstance(tc_haz.intensity, sparse.csr.csr_matrix)) self.assertTrue(isinstance(tc_haz.fraction, sparse.csr.csr_matrix)) self.assertEqual(tc_haz.intensity.shape, (1, 296)) self.assertEqual(tc_haz.fraction.shape, (1, 296)) self.assertAlmostEqual(tc_haz.intensity[0, 100], 99.7160586771286, 6) self.assertAlmostEqual(tc_haz.intensity[0, 260], 33.2087621869295) self.assertEqual(tc_haz.fraction[0, 100], 1) self.assertEqual(tc_haz.fraction[0, 260], 1) self.assertEqual(tc_haz.fraction.nonzero()[0].size, 296) self.assertEqual(tc_haz.intensity.nonzero()[0].size, 296)
def test_set_one_pass(self): """Test _tc_from_track function.""" intensity_idx = [0, 1, 2, 3, 80, 100, 120, 200, 220, 250, 260, 295] intensity_values = { "geosphere": [25.60794285, 26.90906280, 28.26649026, 25.54076797, 31.21986961, 36.17171808, 21.11408573, 28.01457948, 32.65349378, 31.34027741, 0, 40.27362679], "equirect": [25.60778909, 26.90887264, 28.26624642, 25.54092386, 31.21941738, 36.16596567, 21.11399856, 28.01452136, 32.65076804, 31.33884098, 0, 40.27002104] } # the values for the two metrics should agree up to first digit at least for i, val in enumerate(intensity_values["geosphere"]): self.assertAlmostEqual(intensity_values["equirect"][i], val, 1) tc_track = TCTracks() tc_track.read_processed_ibtracs_csv(TEST_TRACK) tc_track.equal_timestep() tc_track.data = tc_track.data[:1] for metric in ["equirect", "geosphere"]: tc_haz = TropCyclone() tc_haz.set_from_tracks(tc_track, centroids=CENTR_TEST_BRB, model='H08', store_windfields=True, metric=metric) self.assertEqual(tc_haz.tag.haz_type, 'TC') self.assertEqual(tc_haz.tag.description, '') self.assertEqual(tc_haz.tag.file_name, 'Name: 1951239N12334') self.assertEqual(tc_haz.units, 'm/s') self.assertEqual(tc_haz.centroids.size, 296) self.assertEqual(tc_haz.event_id.size, 1) self.assertEqual(tc_haz.date.size, 1) self.assertEqual(dt.datetime.fromordinal(tc_haz.date[0]).year, 1951) self.assertEqual(dt.datetime.fromordinal(tc_haz.date[0]).month, 8) self.assertEqual(dt.datetime.fromordinal(tc_haz.date[0]).day, 27) self.assertEqual(tc_haz.event_id[0], 1) self.assertEqual(tc_haz.event_name, ['1951239N12334']) self.assertTrue(np.array_equal(tc_haz.frequency, np.array([1]))) self.assertTrue(isinstance(tc_haz.fraction, sparse.csr.csr_matrix)) self.assertEqual(tc_haz.fraction.shape, (1, 296)) self.assertEqual(tc_haz.fraction[0, 100], 1) self.assertEqual(tc_haz.fraction[0, 260], 0) self.assertEqual(tc_haz.fraction.nonzero()[0].size, 280) self.assertTrue(isinstance(tc_haz.intensity, sparse.csr.csr_matrix)) self.assertEqual(tc_haz.intensity.shape, (1, 296)) self.assertEqual(np.nonzero(tc_haz.intensity)[0].size, 280) for idx, val in zip(intensity_idx, intensity_values[metric]): if val == 0: self.assertEqual(tc_haz.intensity[0, idx], 0) else: self.assertAlmostEqual(tc_haz.intensity[0, idx], val) windfields = tc_haz.windfields[0].toarray() windfields = windfields.reshape(windfields.shape[0], -1, 2) windfield_norms = np.linalg.norm(windfields, axis=-1).max(axis=0) intensity = tc_haz.intensity.toarray()[0, :] msk = (intensity > 0) np.testing.assert_array_equal(windfield_norms[msk], intensity[msk])
def test_vang_sym(self): """ Test _vang_sym function. Compare to MATLAB reference. """ ureg = UnitRegistry() i_node = 1 tc_track = TCTracks() tc_track.read_processed_ibtracs_csv(TEST_TRACK) tc_track.equal_timestep() tc_track.data[0]['radius_max_wind'] = ( 'time', tc._extra_rad_max_wind(tc_track.data[0].central_pressure.values, tc_track.data[0].radius_max_wind.values, ureg)) r_arr = np.array([ 286.4938638337190, 290.5930935802884, 295.0271327746536, 299.7811253637995, 296.8484825705515, 274.9892882245964 ]) v_trans = 5.2429431910897559 v_ang = tc._vang_sym( tc_track.data[0].environmental_pressure.values[i_node], tc_track.data[0].central_pressure.values[i_node - 1:i_node + 1], tc_track.data[0].lat.values[i_node], tc_track.data[0].time_step.values[i_node], tc_track.data[0].radius_max_wind.values[i_node], r_arr, v_trans, model=0) to_kn = (1 * ureg.meter / ureg.second).to(ureg.knot).magnitude self.assertEqual(v_ang.size, 6) self.assertAlmostEqual(v_ang[0] * to_kn, 10.774196807905097) self.assertAlmostEqual(v_ang[1] * to_kn, 10.591725180482094) self.assertAlmostEqual(v_ang[2] * to_kn, 10.398212766600055) self.assertAlmostEqual(v_ang[3] * to_kn, 10.195108683240084) self.assertAlmostEqual(v_ang[4] * to_kn, 10.319869893291429) self.assertAlmostEqual(v_ang[5] * to_kn, 11.305188714213809)
def test_windfield(self): """ Test _windfield function. Compare to MATLAB reference. """ ureg = UnitRegistry() tc_track = TCTracks() tc_track.read_processed_ibtracs_csv(TEST_TRACK) tc_track.equal_timestep() tc_track.data[0]['radius_max_wind'] = ( 'time', tc._extra_rad_max_wind(tc_track.data[0].central_pressure.values, tc_track.data[0].radius_max_wind.values, ureg)) coast_centr = tc.coastal_centr_idx(CENTR_TEST_BRB) wind = tc._windfield(tc_track.data[0], CENTR_TEST_BRB.coord, coast_centr, model=0) to_kn = (1 * ureg.meter / ureg.second).to(ureg.knot).magnitude self.assertEqual(wind.shape, (CENTR_TEST_BRB.size, )) wind = wind[coast_centr] self.assertEqual(np.nonzero(wind)[0].size, 280) self.assertAlmostEqual(wind[0] * to_kn, 51.16153933277889) self.assertAlmostEqual(wind[80] * to_kn, 64.15891933409763) self.assertAlmostEqual(wind[120] * to_kn, 41.43819201370903) self.assertAlmostEqual(wind[200] * to_kn, 57.28814245245439) self.assertAlmostEqual(wind[220] * to_kn, 69.62477194818004)
def test_vtrans_correct(self): """ Test _vtrans_correct function. Compare to MATLAB reference.""" ureg = UnitRegistry() i_node = 1 tc_track = TCTracks() tc_track.read_processed_ibtracs_csv(TEST_TRACK) tc_track.equal_timestep() tc_track.data[0]['radius_max_wind'] = ( 'time', tc._extra_rad_max_wind(tc_track.data[0].central_pressure.values, tc_track.data[0].radius_max_wind.values, ureg)) r_arr = np.array([ 286.4938638337190, 290.5930935802884, 295.0271327746536, 299.7811253637995, 296.8484825705515, 274.9892882245964 ]) v_trans_corr = tc._vtrans_correct( tc_track.data[0].lat.values[i_node:i_node + 2], tc_track.data[0].lon.values[i_node:i_node + 2], tc_track.data[0].radius_max_wind.values[i_node], CENTR_TEST_BRB.coord[:6, :], r_arr) to_kn = (1 * ureg.meter / ureg.second).to(ureg.knot).magnitude v_trans = 10.191466256012880 / to_kn v_trans_corr *= v_trans self.assertEqual(v_trans_corr.size, 6) self.assertAlmostEqual(v_trans_corr[0] * to_kn, 0.06547673730228235) self.assertAlmostEqual(v_trans_corr[1] * to_kn, 0.07106877437273672) self.assertAlmostEqual(v_trans_corr[2] * to_kn, 0.07641714650288109) self.assertAlmostEqual(v_trans_corr[3] * to_kn, 0.0627289214278824) self.assertAlmostEqual(v_trans_corr[4] * to_kn, 0.0697427233582331) self.assertAlmostEqual(v_trans_corr[5] * to_kn, 0.06855335593983322)
def test_vtrans_correct(self): """ Test _vtrans_correct function. Compare to MATLAB reference.""" ureg = UnitRegistry() i_node = 1 tc_track = TCTracks() tc_track.read_processed_ibtracs_csv(TEST_TRACK) tc_track.equal_timestep() tc_track.data[0]['radius_max_wind'] = ('time', tc._extra_rad_max_wind( tc_track.data[0].central_pressure.values, tc_track.data[0].radius_max_wind.values, ureg)) coast_centr = tc.coastal_centr_idx(CENT_CLB) new_centr = CENT_CLB.coord[coast_centr] r_arr = np.array([286.4938638337190, 290.5930935802884, 295.0271327746536, 299.7811253637995, 296.8484825705515, 274.9892882245964]) close_centr = np.array([400381, 400382, 400383, 400384, 401110, 1019665]) - 1 v_trans_corr = tc._vtrans_correct( tc_track.data[0].lat.values[i_node:i_node+2], tc_track.data[0].lon.values[i_node:i_node+2], tc_track.data[0].radius_max_wind.values[i_node], new_centr[close_centr, :], r_arr) to_kn = (1* ureg.meter / ureg.second).to(ureg.knot).magnitude v_trans = 10.191466256012880 / to_kn v_trans_corr *= v_trans self.assertEqual(v_trans_corr.size, 6) self.assertAlmostEqual(v_trans_corr[0] * to_kn, 2.490082696506720) self.assertAlmostEqual(v_trans_corr[1] * to_kn, 2.418324821762491) self.assertAlmostEqual(v_trans_corr[2] * to_kn, 2.344175399115656) self.assertAlmostEqual(v_trans_corr[3] * to_kn, 2.268434724527058) self.assertAlmostEqual(v_trans_corr[4] * to_kn, 2.416654031976129) self.assertAlmostEqual(v_trans_corr[5] * to_kn, -1.394485527059995)
def test_calc_decay_no_landfall_pass(self): """ Test _calc_land_decay with no historical tracks with landfall """ tc_track = TCTracks() tc_track.read_processed_ibtracs_csv(TEST_TRACK_SHORT) land_geom = tc._calc_land_geom(tc_track.data) tc._track_land_params(tc_track.data[0], land_geom) with self.assertLogs('climada.hazard.tc_tracks', level='INFO') as cm: tc_track._calc_land_decay(land_geom) self.assertIn('No historical track with landfall.', cm.output[0])
def test_set_one_pass(self): """Test _tc_from_track function.""" tc_track = TCTracks() tc_track.read_processed_ibtracs_csv(TEST_TRACK) tc_track.equal_timestep() tc_track.data = tc_track.data[:1] tc_haz = TropCyclone() tc_haz.set_from_tracks(tc_track, centroids=CENTR_TEST_BRB, model='H08', store_windfields=True) self.assertEqual(tc_haz.tag.haz_type, 'TC') self.assertEqual(tc_haz.tag.description, '') self.assertEqual(tc_haz.tag.file_name, 'Name: 1951239N12334') self.assertEqual(tc_haz.units, 'm/s') self.assertEqual(tc_haz.centroids.size, 296) self.assertEqual(tc_haz.event_id.size, 1) self.assertEqual(tc_haz.date.size, 1) self.assertEqual(dt.datetime.fromordinal(tc_haz.date[0]).year, 1951) self.assertEqual(dt.datetime.fromordinal(tc_haz.date[0]).month, 8) self.assertEqual(dt.datetime.fromordinal(tc_haz.date[0]).day, 27) self.assertEqual(tc_haz.event_id[0], 1) self.assertEqual(tc_haz.event_name, ['1951239N12334']) self.assertTrue(np.array_equal(tc_haz.frequency, np.array([1]))) self.assertTrue(isinstance(tc_haz.fraction, sparse.csr.csr_matrix)) self.assertEqual(tc_haz.fraction.shape, (1, 296)) self.assertEqual(tc_haz.fraction[0, 100], 1) self.assertEqual(tc_haz.fraction[0, 260], 0) self.assertEqual(tc_haz.fraction.nonzero()[0].size, 280) self.assertTrue(isinstance(tc_haz.intensity, sparse.csr.csr_matrix)) self.assertEqual(tc_haz.intensity.shape, (1, 296)) self.assertEqual(np.nonzero(tc_haz.intensity)[0].size, 280) self.assertEqual(tc_haz.intensity[0, 260], 0) self.assertAlmostEqual(tc_haz.intensity[0, 1], 27.08333002) self.assertAlmostEqual(tc_haz.intensity[0, 2], 28.46008202) self.assertAlmostEqual(tc_haz.intensity[0, 3], 25.70445069) self.assertAlmostEqual(tc_haz.intensity[0, 100], 36.45564037) self.assertAlmostEqual(tc_haz.intensity[0, 250], 31.60115745) self.assertAlmostEqual(tc_haz.intensity[0, 295], 40.62433745) to_kn = (1.0 * ureg.meter / ureg.second).to(ureg.knot).magnitude wind = tc_haz.intensity.toarray()[0, :] self.assertAlmostEqual(wind[0] * to_kn, 50.08492156) self.assertAlmostEqual(wind[80] * to_kn, 61.13812028) self.assertAlmostEqual(wind[120] * to_kn, 41.26159439) self.assertAlmostEqual(wind[200] * to_kn, 54.85572160) self.assertAlmostEqual(wind[220] * to_kn, 63.99749424) windfields = tc_haz.windfields[0].toarray() windfields = windfields.reshape(windfields.shape[0], -1, 2) windfield_norms = np.linalg.norm(windfields, axis=-1).max(axis=0) intensity = tc_haz.intensity.toarray()[0, :] msk = (intensity > 0) self.assertTrue(np.allclose(windfield_norms[msk], intensity[msk]))
def test_get_track_pass(self): """ Test get_track.""" tc_track = TCTracks() tc_track.read_processed_ibtracs_csv(TEST_TRACK_SHORT) self.assertIsInstance(tc_track.get_track(), xr.Dataset) self.assertIsInstance(tc_track.get_track('1951239N12334'), xr.Dataset) tc_track_bis = TCTracks() tc_track_bis.read_processed_ibtracs_csv(TEST_TRACK_SHORT) tc_track.append(tc_track_bis) self.assertIsInstance(tc_track.get_track(), list) self.assertIsInstance(tc_track.get_track('1951239N12334'), xr.Dataset)
def test_rainfield_from_track_pass(self): """Test _rainfield_from_track function. Compare to MATLAB reference.""" tc_track = TCTracks() tc_track.read_processed_ibtracs_csv(TEST_TRACK) tc_track.equal_timestep() rainfall = rainfield_from_track(tc_track.data[0], CENTR_TEST_BRB) rainfall = np.round(rainfall, decimals=9) self.assertAlmostEqual(rainfall[0, 0], 66.801702386) self.assertAlmostEqual(rainfall[0, 130], 43.290917792) self.assertAlmostEqual(rainfall[0, 200], 76.315923838)
def test_interp_origin_inv_pass(self): """ Interpolate track to min_time_step crossing lat origin """ tc_track = TCTracks() tc_track.read_processed_ibtracs_csv(TEST_TRACK) tc_track.data[0].lon.values = np.array([ 167.207761, 168.1, 168.936535, 169.728947, 170.5, 171.257176, 171.946822, 172.5, 172.871797, 173.113396, 173.3, 173.496375, 173.725522, 174., 174.331591, 174.728961, 175.2, 175.747632, 176.354929, 177., 177.66677, 178.362433, 179.1, 179.885288, -179.304661, -178.5, -177.726442, -176.991938, -176.3, -175.653595, -175.053513, -174.5, -173.992511, -173.527342, -173.1, -172.705991, -172.340823, -172. ]) tc_track.data[0].lon.values = -tc_track.data[0].lon.values tc_track.data[0].lat.values = np.array([ 40.196053, 40.6, 40.930215, 41.215674, 41.5, 41.816354, 42.156065, 42.5, 42.833998, 43.16377, 43.5, 43.847656, 44.188854, 44.5, 44.764269, 44.991925, 45.2, 45.402675, 45.602707, 45.8, 45.995402, 46.193543, 46.4, 46.615718, 46.82312, 47., 47.130616, 47.225088, 47.3, 47.369224, 47.435786, 47.5, 47.562858, 47.628064, 47.7, 47.783047, 47.881586, 48. ]) tc_track.equal_timestep(time_step_h=1) self.assertEqual(tc_track.data[0].time.size, 223) self.assertAlmostEqual(tc_track.data[0].lon.values[0], -167.207761) self.assertAlmostEqual(tc_track.data[0].lon.values[-1], 172) self.assertAlmostEqual(tc_track.data[0].lon.values[137], -179.75187272) self.assertAlmostEqual(tc_track.data[0].lon.values[138], -179.885288) self.assertAlmostEqual(tc_track.data[0].lon.values[139], 179.98060885) self.assertAlmostEqual(tc_track.data[0].lon.values[140], 179.84595743) self.assertAlmostEqual(tc_track.data[0].lat.values[0], 40.196053) self.assertAlmostEqual(tc_track.data[0].lat.values[-1], 48.) self.assertEqual(tc_track.data[0].time_step[7], 1) self.assertEqual(np.max(tc_track.data[0].radius_max_wind), 0) self.assertEqual(np.min(tc_track.data[0].radius_max_wind), 0) self.assertEqual(tc_track.data[0].max_sustained_wind[21], 25) self.assertAlmostEqual(tc_track.data[0].central_pressure.values[29], 1.005409300000005e+03) self.assertEqual(np.max(tc_track.data[0].environmental_pressure), 1010) self.assertEqual(np.min(tc_track.data[0].environmental_pressure), 1010) self.assertEqual(tc_track.data[0]['time.year'][13], 1951) self.assertEqual(tc_track.data[0]['time.month'][26], 8) self.assertEqual(tc_track.data[0]['time.day'][7], 27) self.assertEqual(tc_track.data[0].max_sustained_wind_unit, 'kn') self.assertEqual(tc_track.data[0].central_pressure_unit, 'mb') self.assertEqual(tc_track.data[0].orig_event_flag, 1) self.assertEqual(tc_track.data[0].name, '1951239N12334') self.assertEqual(tc_track.data[0].data_provider, 'hurdat_atl') self.assertTrue(np.isnan(tc_track.data[0].basin)) self.assertEqual(tc_track.data[0].id_no, 1951239012334) self.assertEqual(tc_track.data[0].category, 1)
def test_random_walk_decay_pass(self): """Test land decay is called from calc_random_walk.""" tc_track = TCTracks() tc_track.read_processed_ibtracs_csv(TC_ANDREW_FL) ens_size=2 with self.assertLogs('climada.hazard.tc_tracks', level='DEBUG') as cm: tc_track.calc_random_walk(ens_size, seed=25, decay=True) self.assertIn('No historical track of category Tropical Depression with landfall.', cm.output[1]) self.assertIn('Decay parameters from category Hurrican Cat. 4 taken.', cm.output[2]) self.assertIn('No historical track of category Hurrican Cat. 1 with landfall.', cm.output[3]) self.assertIn('Decay parameters from category Hurrican Cat. 4 taken.', cm.output[4]) self.assertIn('No historical track of category Hurrican Cat. 3 with landfall. Decay parameters from category Hurrican Cat. 4 taken.', cm.output[5]) self.assertIn('No historical track of category Hurrican Cat. 5 with landfall.', cm.output[6])
def test_calc_orig_lf(self): """ Test _calc_orig_lf for andrew tropical cyclone.""" tc_track = TCTracks() tc_track.read_processed_ibtracs_csv(TC_ANDREW_FL) track = tc_track.get_track() track['on_land'] = ('time', coord_on_land(track.lat.values, track.lon.values)) sea_land_idx = np.where(np.diff(track.on_land.astype(int)) == 1)[0] orig_lf = tc._calc_orig_lf(track, sea_land_idx) self.assertEqual(orig_lf.shape, (sea_land_idx.size, 2)) self.assertTrue(np.array_equal(orig_lf[0], np.array([25.5, -80.25]))) self.assertTrue(np.array_equal(orig_lf[1], np.array([29.65, -91.5])))
def test_apply_decay_no_landfall_pass(self): """ Test _apply_land_decay with no historical tracks with landfall """ tc_track = TCTracks() tc_track.read_processed_ibtracs_csv(TEST_TRACK_SHORT) land_geom = tc._calc_land_geom(tc_track.data) 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_track._apply_land_decay(dict(), dict(), land_geom) self.assertTrue(np.array_equal(tc_track.data[0].max_sustained_wind.values, tc_ref.max_sustained_wind.values)) self.assertTrue(np.array_equal(tc_track.data[0].central_pressure.values, tc_ref.central_pressure.values)) self.assertTrue(np.array_equal(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_vtrans_pass(self): """ Test _vtrans function. Compare to MATLAB reference.""" ureg = UnitRegistry() i_node = 1 tc_track = TCTracks() tc_track.read_processed_ibtracs_csv(TEST_TRACK) tc_track.equal_timestep() v_trans = tc._vtrans(tc_track.data[0].lat.values, tc_track.data[0].lon.values, tc_track.data[0].time_step.values, ureg) to_kn = (1* ureg.meter / ureg.second).to(ureg.knot).magnitude self.assertEqual(v_trans.size, tc_track.data[0].time.size-1) self.assertAlmostEqual(v_trans[i_node-1]*to_kn, 10.191466256012880)
def test_vtrans_pass(self): """Test _vtrans function. Compare to MATLAB reference.""" tc_track = TCTracks() tc_track.read_processed_ibtracs_csv(TEST_TRACK) tc_track.equal_timestep() v_trans, _ = _vtrans( tc_track.data[0].lat.values, tc_track.data[0].lon.values, tc_track.data[0].time_step.values) to_kn = (1.0 * ureg.meter / ureg.second).to(ureg.knot).magnitude self.assertEqual(v_trans.size, tc_track.data[0].time.size) self.assertEqual(v_trans[0], 0) self.assertAlmostEqual(v_trans[1] * to_kn, 10.191466246)
def test_read_and_tc_fail(self): """ Append Hazard and Tropical Cyclone. Fail because of missing category in hazard. """ tc_track = TCTracks() tc_track.read_processed_ibtracs_csv(TEST_TRACK_SHORT) tc_haz1 = TropCyclone() tc_haz1.read_mat(HAZ_TEST_MAT) tc_haz2 = TropCyclone() tc_haz2.set_from_tracks(tc_track, CENTR_TEST_BRB) tc_haz2.append(tc_haz1) self.assertEqual(tc_haz2.intensity.shape, (14451, 396)) with self.assertRaises(ValueError): tc_haz2.check()
def test_calc_land_decay_pass(self): """ Test _calc_land_decay with environmental pressure function.""" tc_track = TCTracks() tc_track.read_processed_ibtracs_csv(TC_ANDREW_FL) land_geom = tc._calc_land_geom(tc_track.data) tc._track_land_params(tc_track.data[0], land_geom) v_rel, p_rel = tc_track._calc_land_decay(land_geom) self.assertEqual(7, len(v_rel)) for i, val in enumerate(v_rel.values()): self.assertAlmostEqual(val, 0.0038894834) self.assertTrue(i + 1 in v_rel.keys()) self.assertEqual(7, len(p_rel)) for i, val in enumerate(p_rel.values()): self.assertAlmostEqual(val[0], 1.0598491) self.assertAlmostEqual(val[1], 0.0041949237) self.assertTrue(i + 1 in p_rel.keys())
def test_extra_rad_max_wind_pass(self): """ Test _extra_rad_max_wind function. Compare to MATLAB reference.""" ureg = UnitRegistry() tc_track = TCTracks() tc_track.read_processed_ibtracs_csv(TEST_TRACK) tc_track.equal_timestep() rad_max_wind = tc._extra_rad_max_wind(tc_track.data[0].central_pressure.values, tc_track.data[0].radius_max_wind.values, ureg) self.assertEqual(rad_max_wind[0], 75.536713749999905) self.assertAlmostEqual(rad_max_wind[10], 75.592659583328057) self.assertAlmostEqual(rad_max_wind[128], 46.686527832605236) self.assertEqual(rad_max_wind[129], 46.089211533333405) self.assertAlmostEqual(rad_max_wind[130], 45.672274889277276) self.assertEqual(rad_max_wind[189], 45.132715266666672) self.assertAlmostEqual(rad_max_wind[190], 45.979603999211285) self.assertAlmostEqual(rad_max_wind[191], 47.287173876478825) self.assertEqual(rad_max_wind[192], 48.875090249999985) self.assertAlmostEqual(rad_max_wind[200], 59.975901084074955)
def test_dist_since_lf_pass(self): """ Test _dist_since_lf for andrew tropical cyclone.""" tc_track = TCTracks() tc_track.read_processed_ibtracs_csv(TC_ANDREW_FL) track = tc_track.get_track() track['on_land'] = ('time', coord_on_land(track.lat.values, track.lon.values)) track['dist_since_lf'] = ('time', tc._dist_since_lf(track)) self.assertTrue(np.all(np.isnan(track.dist_since_lf.values[track.on_land == False]))) self.assertEqual(track.dist_since_lf.values[track.on_land == False].size, 38) self.assertTrue(track.dist_since_lf.values[-1] > dist_to_coast(track.lat.values[-1], track.lon.values[-1])/1000) self.assertEqual(1020.5431562223974, track['dist_since_lf'].values[-1]) # check distances on land always increase, in second landfall dist_on_land = track.dist_since_lf.values[track.on_land] self.assertTrue(np.all(np.diff(dist_on_land)[1:] > 0))
def test_gust_from_track(self): """ Test gust_from_track function. Compare to MATLAB reference. """ tc_track = TCTracks() tc_track.read_processed_ibtracs_csv(TEST_TRACK) tc_track.equal_timestep() intensity = tc.gust_from_track(tc_track.data[0], CENTR_TEST_BRB, model='H08') self.assertTrue(isinstance(intensity, sparse.csr.csr_matrix)) self.assertEqual(intensity.shape, (1, 296)) self.assertEqual(np.nonzero(intensity)[0].size, 280) self.assertEqual(intensity[0, 260], 0) self.assertAlmostEqual(intensity[0, 1], 27.835686180065114) self.assertAlmostEqual(intensity[0, 2], 29.46862830056694) self.assertAlmostEqual(intensity[0, 3], 26.36829914594632) self.assertAlmostEqual(intensity[0, 100], 38.84863159321016) self.assertAlmostEqual(intensity[0, 250], 34.26311998266044) self.assertAlmostEqual(intensity[0, 295], 44.273964728810924)