def test_calc_sector_total_impact(self): """Test running total impact calculations.""" sup = SupplyChain() sup.read_wiod16(year='test', range_rows=(5, 117), range_cols=(4, 116), col_iso3=2, col_sectors=1) # Tropical cyclone over Florida and Caribbean hazard = Hazard('TC') hazard.read_mat(HAZ_TEST_MAT) # Read demo entity values # Set the entity default file to the demo one exp = Exposures() exp.read_hdf5(EXP_DEMO_H5) exp.check() exp.gdf.region_id = 840 #assign right id for USA exp.assign_centroids(hazard) impf_tc = IFTropCyclone() impf_tc.set_emanuel_usa() impf_set = ImpactFuncSet() impf_set.append(impf_tc) impf_set.check() sup.calc_sector_direct_impact(hazard, exp, impf_set) sup.calc_indirect_impact(io_approach='ghosh') sup.calc_total_impact() self.assertAlmostEqual((sup.years.shape[0], sup.mriot_data.shape[0]), sup.total_impact.shape) self.assertAlmostEqual((sup.mriot_data.shape[0], ), sup.total_aai_agg.shape)
def test_cutoff_hazard_pass(self): """Test _cutoff_hazard_damage""" meas = MeasureSet() meas.read_mat(ENT_TEST_MAT) act_1 = meas.get_measure(name='Seawall')[0] haz = Hazard('TC') haz.read_mat(HAZ_TEST_MAT) exp = Exposures() exp.read_mat(ENT_TEST_MAT) exp.gdf.rename(columns={'if_': 'if_TC'}, inplace=True) exp.check() imp_set = ImpactFuncSet() imp_set.read_mat(ENT_TEST_MAT) new_haz = act_1._cutoff_hazard_damage(exp, imp_set, haz) self.assertFalse(id(new_haz) == id(haz)) pos_no_null = np.array([6249, 7697, 9134, 13500, 13199, 5944, 9052, 9050, 2429, 5139, 9053, 7102, 4096, 1070, 5948, 1076, 5947, 7432, 5949, 11694, 5484, 6246, 12147, 778, 3326, 7199, 12498, 11698, 6245, 5327, 4819, 8677, 5970, 7101, 779, 3894, 9051, 5976, 3329, 5978, 4282, 11697, 7193, 5351, 7310, 7478, 5489, 5526, 7194, 4283, 7191, 5328, 4812, 5528, 5527, 5488, 7475, 5529, 776, 5758, 4811, 6223, 7479, 7470, 5480, 5325, 7477, 7318, 7317, 11696, 7313, 13165, 6221]) all_haz = np.arange(haz.intensity.shape[0]) all_haz[pos_no_null] = -1 pos_null = np.argwhere(all_haz > 0).reshape(-1) for i_ev in pos_null: self.assertEqual(new_haz.intensity[i_ev, :].max(), 0)
def _change_all_exposures(self, exposures): """Change exposures to provided exposures_set. Parameters: exposures (Exposures): exposures instance Returns: Exposures """ if isinstance(self.exposures_set, str) and self.exposures_set == NULL_STR: return exposures if isinstance(self.exposures_set, str): LOGGER.debug('Setting new exposures %s', self.exposures_set) new_exp = Exposures() new_exp.read_hdf5(self.exposures_set) new_exp.check() elif isinstance(self.exposures_set, Exposures): LOGGER.debug('Setting new exposures. ') new_exp = copy.deepcopy(self.exposures_set) new_exp.check() else: LOGGER.error('Wrong input exposures.') raise ValueError if not np.array_equal(np.unique(exposures.latitude.values), np.unique(new_exp.latitude.values)) or \ not np.array_equal(np.unique(exposures.longitude.values), np.unique(new_exp.longitude.values)): LOGGER.warning('Exposures locations have changed.') return new_exp
def test_error_logs_wrong_crs(self): """Ambiguous crs definition""" expo = good_exposures() expo.set_geometry_points() # sets crs to 4326 # all good _expo = Exposures(expo.gdf, meta={'crs': 4326}, crs=DEF_CRS) with self.assertRaises(ValueError) as cm: _expo = Exposures(expo.gdf, meta={'crs': 4230}, crs=4326) self.assertIn( "Inconsistent CRS definition, crs and meta arguments don't match", str(cm.exception)) with self.assertRaises(ValueError) as cm: _expo = Exposures(expo.gdf, meta={'crs': 4230}) self.assertIn( "Inconsistent CRS definition, data doesn't match meta or crs argument", str(cm.exception)) with self.assertRaises(ValueError) as cm: _expo = Exposures(expo.gdf, crs='epsg:4230') self.assertIn( "Inconsistent CRS definition, data doesn't match meta or crs argument", str(cm.exception)) _expo = Exposures(expo.gdf) _expo.meta['crs'] = 'epsg:4230' with self.assertRaises(ValueError) as cm: _expo.check() self.assertIn( "Inconsistent CRS definition, gdf (EPSG:4326) attribute doesn't match " "meta (epsg:4230) attribute.", str(cm.exception))
def _build_exp(self): eai_exp = Exposures() eai_exp['value'] = self.eai_exp eai_exp['latitude'] = self.coord_exp[:, 0] eai_exp['longitude'] = self.coord_exp[:, 1] eai_exp.crs = self.crs eai_exp.value_unit = self.unit eai_exp.check() return eai_exp
def test_read_template_pass(self): """Wrong exposures definition""" df = pd.read_excel(ENT_TEMPLATE_XLS) exp_df = Exposures(df) # set metadata exp_df.ref_year = 2020 exp_df.tag = Tag(ENT_TEMPLATE_XLS, 'ENT_TEMPLATE_XLS') exp_df.value_unit = 'XSD' exp_df.check()
def test_io_hdf5_pass(self): """write and read hdf5""" exp_df = Exposures(pd.read_excel(ENT_TEMPLATE_XLS), crs="epsg:32632") exp_df.set_geometry_points() exp_df.check() # set metadata exp_df.ref_year = 2020 exp_df.tag = Tag(ENT_TEMPLATE_XLS, 'ENT_TEMPLATE_XLS') exp_df.value_unit = 'XSD' file_name = DATA_DIR.joinpath('test_hdf5_exp.h5') # pd.errors.PerformanceWarning should be suppressed. Therefore, make sure that # PerformanceWarning would result in test failure here import warnings with warnings.catch_warnings(): warnings.simplefilter("error", category=pd.errors.PerformanceWarning) exp_df.write_hdf5(file_name) exp_read = Exposures.from_hdf5(file_name) self.assertEqual(exp_df.ref_year, exp_read.ref_year) self.assertEqual(exp_df.value_unit, exp_read.value_unit) self.assertDictEqual(exp_df.meta, exp_read.meta) self.assertTrue(u_coord.equal_crs(exp_df.crs, exp_read.crs)) self.assertTrue(u_coord.equal_crs(exp_df.gdf.crs, exp_read.gdf.crs)) self.assertEqual(exp_df.tag.file_name, exp_read.tag.file_name) self.assertEqual(exp_df.tag.description, exp_read.tag.description) np.testing.assert_array_equal(exp_df.gdf.latitude.values, exp_read.gdf.latitude.values) np.testing.assert_array_equal(exp_df.gdf.longitude.values, exp_read.gdf.longitude.values) np.testing.assert_array_equal(exp_df.gdf.value.values, exp_read.gdf.value.values) np.testing.assert_array_equal(exp_df.gdf.deductible.values, exp_read.gdf.deductible.values) np.testing.assert_array_equal(exp_df.gdf.cover.values, exp_read.gdf.cover.values) np.testing.assert_array_equal(exp_df.gdf.region_id.values, exp_read.gdf.region_id.values) np.testing.assert_array_equal(exp_df.gdf.category_id.values, exp_read.gdf.category_id.values) np.testing.assert_array_equal(exp_df.gdf.impf_TC.values, exp_read.gdf.impf_TC.values) np.testing.assert_array_equal(exp_df.gdf.centr_TC.values, exp_read.gdf.centr_TC.values) np.testing.assert_array_equal(exp_df.gdf.impf_FL.values, exp_read.gdf.impf_FL.values) np.testing.assert_array_equal(exp_df.gdf.centr_FL.values, exp_read.gdf.centr_FL.values) for point_df, point_read in zip(exp_df.gdf.geometry.values, exp_read.gdf.geometry.values): self.assertEqual(point_df.x, point_read.x) self.assertEqual(point_df.y, point_read.y)
def test_assign_raster_same_pass(self): """Test assign_centroids with raster hazard""" exp = Exposures() exp.set_from_raster(HAZ_DEMO_FL, window=Window(10, 20, 50, 60)) exp.check() haz = Hazard('FL') haz.set_raster([HAZ_DEMO_FL], window=Window(10, 20, 50, 60)) exp.assign_centroids(haz) np.testing.assert_array_equal(exp.gdf[INDICATOR_CENTR + 'FL'].values, np.arange(haz.centroids.size, dtype=int))
def test_io_hdf5_pass(self): """write and read hdf5""" exp_df = Exposures(pd.read_excel(ENT_TEMPLATE_XLS)) exp_df.set_geometry_points() exp_df.check() # set metadata exp_df.ref_year = 2020 exp_df.tag = Tag(ENT_TEMPLATE_XLS, 'ENT_TEMPLATE_XLS') exp_df.value_unit = 'XSD' file_name = DATA_DIR.joinpath('test_hdf5_exp.h5') exp_df.write_hdf5(file_name) exp_read = Exposures() exp_read.read_hdf5(file_name) self.assertEqual(exp_df.ref_year, exp_read.ref_year) self.assertEqual(exp_df.value_unit, exp_read.value_unit) self.assertEqual(exp_df.crs, exp_read.crs) self.assertEqual(exp_df.tag.file_name, exp_read.tag.file_name) self.assertEqual(exp_df.tag.description, exp_read.tag.description) self.assertTrue( np.array_equal(exp_df.gdf.latitude.values, exp_read.gdf.latitude.values)) self.assertTrue( np.array_equal(exp_df.gdf.longitude.values, exp_read.gdf.longitude.values)) self.assertTrue( np.array_equal(exp_df.gdf.value.values, exp_read.gdf.value.values)) self.assertTrue( np.array_equal(exp_df.gdf.deductible.values, exp_read.gdf.deductible.values)) self.assertTrue( np.array_equal(exp_df.gdf.cover.values, exp_read.gdf.cover.values)) self.assertTrue( np.array_equal(exp_df.gdf.region_id.values, exp_read.gdf.region_id.values)) self.assertTrue( np.array_equal(exp_df.gdf.category_id.values, exp_read.gdf.category_id.values)) self.assertTrue( np.array_equal(exp_df.gdf.if_TC.values, exp_read.gdf.if_TC.values)) self.assertTrue( np.array_equal(exp_df.gdf.centr_TC.values, exp_read.gdf.centr_TC.values)) self.assertTrue( np.array_equal(exp_df.gdf.if_FL.values, exp_read.gdf.if_FL.values)) self.assertTrue( np.array_equal(exp_df.gdf.centr_FL.values, exp_read.gdf.centr_FL.values)) for point_df, point_read in zip(exp_df.gdf.geometry.values, exp_read.gdf.geometry.values): self.assertEqual(point_df.x, point_read.x) self.assertEqual(point_df.y, point_read.y)
def test_ctx_osm_pass(self): """ Test basemap function using osm images """ myexp = Exposures() myexp['latitude'] = np.array([30, 40, 50]) myexp['longitude'] = np.array([0, 0, 0]) myexp['value'] = np.array([1, 1, 1]) myexp.check() try: myexp.plot_basemap(url=ctx.sources.OSM_A) except urllib.error.HTTPError: self.assertEqual(1, 0)
def test_exposures_value_pass(self): """Plot exposures values.""" myexp = pd.read_excel(ENT_DEMO_TODAY) myexp = Exposures(myexp) myexp.check() myexp.tag.description = 'demo_today' myax = myexp.plot_hexbin() self.assertIn('demo_today', myax.get_title()) myexp.tag.description = '' myax = myexp.plot_hexbin() self.assertIn('', myax.get_title())
def test_add_sea_pass(self): """Test add_sea function with fake data.""" exp = Exposures() exp.gdf['value'] = np.arange(0, 1.0e6, 1.0e5) min_lat, max_lat = 27.5, 30 min_lon, max_lon = -18, -12 exp.gdf['latitude'] = np.linspace(min_lat, max_lat, 10) exp.gdf['longitude'] = np.linspace(min_lon, max_lon, 10) exp.gdf['region_id'] = np.ones(10) exp.gdf['if_TC'] = np.ones(10) exp.ref_year = 2015 exp.value_unit = 'XSD' exp.check() sea_coast = 100 sea_res_km = 50 sea_res = (sea_coast, sea_res_km) exp_sea = add_sea(exp, sea_res) exp_sea.check() sea_coast /= ONE_LAT_KM sea_res_km /= ONE_LAT_KM min_lat = min_lat - sea_coast max_lat = max_lat + sea_coast min_lon = min_lon - sea_coast max_lon = max_lon + sea_coast self.assertEqual(np.min(exp_sea.gdf.latitude), min_lat) self.assertEqual(np.min(exp_sea.gdf.longitude), min_lon) self.assertTrue( np.array_equal(exp_sea.gdf.value.values[:10], np.arange(0, 1.0e6, 1.0e5))) self.assertEqual(exp_sea.ref_year, exp.ref_year) self.assertEqual(exp_sea.value_unit, exp.value_unit) on_sea_lat = exp_sea.gdf.latitude.values[11:] on_sea_lon = exp_sea.gdf.longitude.values[11:] res_on_sea = coord_on_land(on_sea_lat, on_sea_lon) res_on_sea = ~res_on_sea self.assertTrue(np.all(res_on_sea)) dist = DistanceMetric.get_metric('haversine') self.assertAlmostEqual( dist.pairwise([ [ exp_sea.gdf.longitude.values[-1], exp_sea.gdf.latitude.values[-1] ], [ exp_sea.gdf.longitude.values[-2], exp_sea.gdf.latitude.values[-2] ], ])[0][1], sea_res_km)
def test_assign_large_hazard_subset_pass(self): """Test assign_centroids with raster hazard""" exp = Exposures() exp.set_from_raster(HAZ_DEMO_FL, window=Window(10, 20, 50, 60)) exp.gdf.latitude[[0, 1]] = exp.gdf.latitude[[1, 0]] exp.gdf.longitude[[0, 1]] = exp.gdf.longitude[[1, 0]] exp.check() haz = Hazard('FL') haz.set_raster([HAZ_DEMO_FL]) haz.raster_to_vector() exp.assign_centroids(haz) assigned_centroids = haz.centroids.select( sel_cen=exp.gdf[INDICATOR_CENTR + 'FL'].values) np.testing.assert_array_equal(assigned_centroids.lat, exp.gdf.latitude) np.testing.assert_array_equal(assigned_centroids.lon, exp.gdf.longitude)
def test_read_raster_pass(self): """set_from_raster""" exp = Exposures() exp.set_from_raster(HAZ_DEMO_FL, window=Window(10, 20, 50, 60)) exp.check() self.assertTrue(u_coord.equal_crs(exp.crs, DEF_CRS)) self.assertAlmostEqual(exp.gdf['latitude'].max(), 10.248220966978932 - 0.009000000000000341 / 2) self.assertAlmostEqual( exp.gdf['latitude'].min(), 10.248220966978932 - 0.009000000000000341 / 2 - 59 * 0.009000000000000341) self.assertAlmostEqual(exp.gdf['longitude'].min(), -69.2471495969998 + 0.009000000000000341 / 2) self.assertAlmostEqual( exp.gdf['longitude'].max(), -69.2471495969998 + 0.009000000000000341 / 2 + 49 * 0.009000000000000341) self.assertEqual(len(exp.gdf), 60 * 50) self.assertAlmostEqual( exp.gdf.value.values.reshape((60, 50))[25, 12], 0.056825936)
def _change_all_exposures(self, exposures): """ Change exposures to provided exposures_set. Parameters ---------- exposures : climada.entity.Exposures exposures instance Returns ------- new_exp : climada.entity.Exposures() Exposures """ if isinstance(self.exposures_set, str) and self.exposures_set == NULL_STR: return exposures if isinstance(self.exposures_set, (str, Path)): LOGGER.debug('Setting new exposures %s', self.exposures_set) new_exp = Exposures() new_exp.read_hdf5(self.exposures_set) new_exp.check() elif isinstance(self.exposures_set, Exposures): LOGGER.debug('Setting new exposures. ') new_exp = self.exposures_set.copy(deep=True) new_exp.check() else: raise ValueError( f'{self.exposures_set} is neither a string nor an Exposures object' ) if not np.array_equal(np.unique(exposures.gdf.latitude.values), np.unique(new_exp.gdf.latitude.values)) or \ not np.array_equal(np.unique(exposures.gdf.longitude.values), np.unique(new_exp.gdf.longitude.values)): LOGGER.warning('Exposures locations have changed.') return new_exp
def _change_all_exposures(self, exposures): """Change exposures to provided exposures_set. Parameters: exposures (Exposures): exposures instance Returns: Exposures """ if self.exposures_set == NULL_STR: return exposures LOGGER.debug('Setting new exposures %s', self.exposures_set) new_exp = Exposures() new_exp.read_hdf5(self.exposures_set) new_exp.check() if exposures.shape[0] != new_exp.shape[0] or \ not np.array_equal(exposures.latitude.values, new_exp.latitude.values) or \ not np.array_equal(exposures.longitude.values, new_exp.longitude.values): LOGGER.warning('Exposures locations have changed.') return new_exp
def test_info_logs_pass(self): """Correct exposures definition""" with self.assertLogs('climada.entity.exposures.base', level='INFO') as cm: expo = good_exposures() expo.check() self.assertIn('meta set to default value', cm.output[0]) self.assertIn('tag set to default value', cm.output[1]) self.assertIn('ref_year set to default value', cm.output[2]) self.assertIn('value_unit set to default value', cm.output[3]) self.assertIn('crs set to default value', cm.output[4]) self.assertIn('cover not set', cm.output[5]) self.assertIn('geometry not set', cm.output[6]) self.assertTrue(expo.crs is not None) self.assertTrue(expo.gdf.crs is not None) with self.assertLogs('climada.entity.exposures.base', level='INFO') as cm: expo2 = Exposures(expo.gdf, meta={'crs': 4230}) expo2.check() self.assertEqual(expo.crs, expo2.crs) self.assertTrue( any(['ignored and overwritten' in line for line in cm.output]))
def test_cutoff_hazard_region_pass(self): """Test _cutoff_hazard_damage in specific region""" meas = MeasureSet() meas.read_mat(ENT_TEST_MAT) act_1 = meas.get_measure(name='Seawall')[0] act_1.exp_region_id = [1] haz = Hazard('TC') haz.read_mat(HAZ_TEST_MAT) exp = Exposures() exp.read_mat(ENT_TEST_MAT) exp['region_id'] = np.zeros(exp.shape[0]) exp.region_id.values[10:] = 1 exp.check() imp_set = ImpactFuncSet() imp_set.read_mat(ENT_TEST_MAT) new_haz = act_1._cutoff_hazard_damage(exp, imp_set, haz) self.assertFalse(id(new_haz) == id(haz)) pos_no_null = np.array([ 6249, 7697, 9134, 13500, 13199, 5944, 9052, 9050, 2429, 5139, 9053, 7102, 4096, 1070, 5948, 1076, 5947, 7432, 5949, 11694, 5484, 6246, 12147, 778, 3326, 7199, 12498, 11698, 6245, 5327, 4819, 8677, 5970, 7101, 779, 3894, 9051, 5976, 3329, 5978, 4282, 11697, 7193, 5351, 7310, 7478, 5489, 5526, 7194, 4283, 7191, 5328, 4812, 5528, 5527, 5488, 7475, 5529, 776, 5758, 4811, 6223, 7479, 7470, 5480, 5325, 7477, 7318, 7317, 11696, 7313, 13165, 6221 ]) all_haz = np.arange(haz.intensity.shape[0]) all_haz[pos_no_null] = -1 pos_null = np.argwhere(all_haz > 0).reshape(-1) centr_null = np.unique(exp.centr_[exp.region_id == 0]) for i_ev in pos_null: self.assertEqual(new_haz.intensity[i_ev, centr_null].max(), 0)
def test_filter_exposures_pass(self): """Test _filter_exposures method with -1""" meas = Measure() meas.exp_region_id = 3 meas.haz_type = 'TC' exp = Exposures() exp.read_mat(ENT_TEST_MAT) exp.rename(columns={'if_':'if_TC', 'centr_':'centr_TC'}, inplace=True) exp['region_id'] = np.ones(exp.shape[0]) exp.region_id.values[:exp.shape[0]//2] = 3 exp.check() imp_set = ImpactFuncSet() imp_set.read_mat(ENT_TEST_MAT) haz = Hazard('TC') haz.read_mat(HAZ_TEST_MAT) new_exp = copy.deepcopy(exp) new_exp['value'] *= 3 new_exp['if_TC'].values[:20] = 2 new_exp['if_TC'].values[20:40] = 3 new_exp['if_TC'].values[40:] = 1 new_ifs = copy.deepcopy(imp_set) new_ifs.get_func('TC')[1].intensity += 1 ref_ifs = copy.deepcopy(new_ifs) new_haz = copy.deepcopy(haz) new_haz.intensity *= 4 res_exp, res_ifs, res_haz = meas._filter_exposures(exp, imp_set, haz, new_exp, new_ifs, new_haz) # unchanged exposures self.assertEqual(res_exp.ref_year, exp.ref_year) self.assertEqual(res_exp.value_unit, exp.value_unit) self.assertEqual(res_exp.tag.file_name, exp.tag.file_name) self.assertEqual(res_exp.tag.description, exp.tag.description) self.assertTrue(np.array_equal(res_exp.value.values[exp.shape[0]//2:], new_exp.value.values[:exp.shape[0]//2])) self.assertTrue(np.array_equal(res_exp.region_id.values[exp.shape[0]//2:], np.ones(exp.shape[0]//2)*3)) self.assertTrue(np.array_equal(res_exp.if_TC.values[exp.shape[0]//2:], new_exp.if_TC.values[:exp.shape[0]//2])) self.assertTrue(np.array_equal(res_exp.latitude.values[exp.shape[0]//2:], new_exp.latitude.values[:exp.shape[0]//2])) self.assertTrue(np.array_equal(res_exp.longitude.values[exp.shape[0]//2:], new_exp.longitude.values[:exp.shape[0]//2])) # changed exposures self.assertTrue(np.array_equal(res_exp.value.values[:exp.shape[0]//2], exp.value.values[exp.shape[0]//2:])) self.assertTrue(np.array_equal(res_exp.region_id.values[:exp.shape[0]//2], np.ones(exp.shape[0]//2))) self.assertTrue(np.array_equal(res_exp.if_TC.values[:exp.shape[0]//2], exp.if_TC.values[exp.shape[0]//2:])) self.assertTrue(np.array_equal(res_exp.latitude.values[:exp.shape[0]//2], exp.latitude.values[exp.shape[0]//2:])) self.assertTrue(np.array_equal(res_exp.longitude.values[:exp.shape[0]//2], exp.longitude.values[exp.shape[0]//2:])) # unchanged impact functions self.assertEqual(list(res_ifs.get_func().keys()), [meas.haz_type]) self.assertEqual(res_ifs.get_func()[meas.haz_type][1].id, imp_set.get_func()[meas.haz_type][1].id) self.assertTrue(np.array_equal(res_ifs.get_func()[meas.haz_type][1].intensity, imp_set.get_func()[meas.haz_type][1].intensity)) self.assertEqual(res_ifs.get_func()[meas.haz_type][3].id, imp_set.get_func()[meas.haz_type][3].id) self.assertTrue(np.array_equal(res_ifs.get_func()[meas.haz_type][3].intensity, imp_set.get_func()[meas.haz_type][3].intensity)) # changed impact functions self.assertTrue(np.array_equal(res_ifs.get_func()[meas.haz_type][1+IF_ID_FACT].intensity, ref_ifs.get_func()[meas.haz_type][1].intensity)) self.assertTrue(np.array_equal(res_ifs.get_func()[meas.haz_type][1+IF_ID_FACT].paa, ref_ifs.get_func()[meas.haz_type][1].paa)) self.assertTrue(np.array_equal(res_ifs.get_func()[meas.haz_type][1+IF_ID_FACT].mdd, ref_ifs.get_func()[meas.haz_type][1].mdd)) self.assertTrue(np.array_equal(res_ifs.get_func()[meas.haz_type][3+IF_ID_FACT].intensity, ref_ifs.get_func()[meas.haz_type][3].intensity)) self.assertTrue(np.array_equal(res_ifs.get_func()[meas.haz_type][3+IF_ID_FACT].paa, ref_ifs.get_func()[meas.haz_type][3].paa)) self.assertTrue(np.array_equal(res_ifs.get_func()[meas.haz_type][3+IF_ID_FACT].mdd, ref_ifs.get_func()[meas.haz_type][3].mdd)) # unchanged hazard self.assertTrue(np.array_equal(res_haz.intensity[:, :36].todense(), haz.intensity[:, :36].todense())) self.assertTrue(np.array_equal(res_haz.intensity[:, 37:46].todense(), haz.intensity[:, 37:46].todense())) self.assertTrue(np.array_equal(res_haz.intensity[:, 47:].todense(), haz.intensity[:, 47:].todense())) # changed hazard self.assertTrue(np.array_equal(res_haz.intensity[[36, 46]].todense(), new_haz.intensity[[36, 46]].todense()))
class Entity(object): """Collects exposures, impact functions, measures and discount rates. Default values set when empty constructor. Attributes: exposures (Exposures): exposures impact_funcs (ImpactFucs): impact functions measures (MeasureSet): measures disc_rates (DiscRates): discount rates def_file (str): Default file from configuration file """ def __init__(self): """ Empty initializator """ self.exposures = Exposures() self.disc_rates = DiscRates() self.impact_funcs = ImpactFuncSet() self.measures = MeasureSet() def read_mat(self, file_name, description=''): """Read MATLAB file of climada. Parameters: file_name (str, optional): file name(s) or folder name containing the files to read description (str or list(str), optional): one description of the data or a description of each data file Raises: ValueError """ self.exposures = Exposures() self.exposures.read_mat(file_name) self.disc_rates = DiscRates() self.disc_rates.read_mat(file_name, description) self.impact_funcs = ImpactFuncSet() self.impact_funcs.read_mat(file_name, description) self.measures = MeasureSet() self.measures.read_mat(file_name, description) def read_excel(self, file_name, description=''): """Read csv or xls or xlsx file following climada's template. Parameters: file_name (str, optional): file name(s) or folder name containing the files to read description (str or list(str), optional): one description of the data or a description of each data file Raises: ValueError """ self.exposures = Exposures(pd.read_excel(file_name)) self.exposures.tag = Tag() self.exposures.tag.file_name = file_name self.exposures.tag.description = description self.disc_rates = DiscRates() self.disc_rates.read_excel(file_name, description) self.impact_funcs = ImpactFuncSet() self.impact_funcs.read_excel(file_name, description) self.measures = MeasureSet() self.measures.read_excel(file_name, description) def write_excel(self, file_name): """ Write excel file following template. """ self.exposures.to_excel(file_name) self.impact_funcs.write_excel(file_name) self.measures.write_excel(file_name) self.disc_rates.write_excel(file_name) def check(self): """Check instance attributes. Raises: ValueError """ self.disc_rates.check() self.exposures.check() self.impact_funcs.check() self.measures.check() def __setattr__(self, name, value): """Check input type before set""" if name == "exposures": if not isinstance(value, Exposures): LOGGER.error("Input value is not (sub)class of Exposures.") raise ValueError elif name == "impact_funcs": if not isinstance(value, ImpactFuncSet): LOGGER.error("Input value is not (sub)class of ImpactFuncSet.") raise ValueError elif name == "measures": if not isinstance(value, MeasureSet): LOGGER.error("Input value is not (sub)class of MeasureSet.") raise ValueError elif name == "disc_rates": if not isinstance(value, DiscRates): LOGGER.error("Input value is not (sub)class of DiscRates.") raise ValueError super().__setattr__(name, value) def __str__(self): return 'Exposures: \n' + self.exposures.tag.__str__() + \ '\nDiscRates: \n' + self.disc_rates.tag.__str__() + \ '\nImpactFuncSet: \n' + self.impact_funcs.tag.__str__() + \ '\nMeasureSet: \n' + self.measures.tag.__str__() __repr__ = __str__
def calc_sector_direct_impact(self, hazard, exposure, imp_fun_set, selected_subsec="service"): """Calculate direct impacts. Parameters: ---------- hazard : Hazard Hazard object for impact calculation. exposure : Exposures Exposures object for impact calculation. For WIOD tables, exposure.region_id must be country names following ISO3 codes. imp_fun_set : ImpactFuncSet Set of impact functions. selected_subsec : str or list Positions of the selected sectors. These positions can be either defined by the user by passing a list of values, or by using built-in sectors' aggregations for the WIOD data passing a string with possible values being "service", "manufacturing", "agriculture" or "mining". Default is "service". """ if isinstance(selected_subsec, str): built_in_subsec_pos = {'service': range(26, 56), 'manufacturing': range(4, 23), 'agriculture': range(0, 1), 'mining': range(3, 4)} selected_subsec = built_in_subsec_pos[selected_subsec] dates = [ dt.datetime.strptime(date, "%Y-%m-%d") for date in hazard.get_event_date() ] self.years = np.unique([date.year for date in dates]) unique_exp_regid = exposure.gdf.region_id.unique() self.direct_impact = np.zeros(shape=(len(self.years), len(self.mriot_reg_names)*len(self.sectors))) self.reg_dir_imp = [] for exp_regid in unique_exp_regid: reg_exp = Exposures(exposure.gdf[exposure.gdf.region_id == exp_regid]) reg_exp.check() # Normalize exposure total_reg_value = reg_exp.gdf['value'].sum() reg_exp.gdf['value'] /= total_reg_value # Calc impact for country imp = Impact() imp.calc(reg_exp, imp_fun_set, hazard) imp_year_set = np.array(list(imp.calc_impact_year_set(imp).values())) mriot_reg_name = self._map_exp_to_mriot(exp_regid, self.mriot_type) self.reg_dir_imp.append(mriot_reg_name) subsec_reg_pos = np.array(selected_subsec) + self.reg_pos[mriot_reg_name][0] subsec_reg_prod = self.mriot_data[subsec_reg_pos].sum(axis=1) imp_year_set = np.repeat(imp_year_set, len(selected_subsec) ).reshape(len(self.years), len(selected_subsec)) direct_impact_reg = np.multiply(imp_year_set, subsec_reg_prod) # Sum needed below in case of many ROWs, which are aggregated into # one country as per WIOD table. self.direct_impact[:, subsec_reg_pos] += direct_impact_reg.astype(np.float32) # average impact across years self.direct_aai_agg = self.direct_impact.mean(axis=0)
def calc_sector_direct_impact(self): """Test running direct impact calculations.""" sup = SupplyChain() sup.read_wiod16(year='test', range_rows=(5, 117), range_cols=(4, 116), col_iso3=2, col_sectors=1) # Tropical cyclone over Florida and Caribbean hazard = Hazard('TC') hazard.read_mat(HAZ_TEST_MAT) # Read demo entity values # Set the entity default file to the demo one exp = Exposures() exp.read_hdf5(EXP_DEMO_H5) exp.check() exp.gdf.region_id = 840 #assign right id for USA exp.assign_centroids(hazard) impf_tc = IFTropCyclone() impf_tc.set_emanuel_usa() impf_set = ImpactFuncSet() impf_set.append(impf_tc) impf_set.check() subsecs = list(range(10)) + list(range(15, 25)) sup.calc_sector_direct_impact(hazard, exp, impf_set, selected_subsec=subsecs) self.assertAlmostEqual((sup.years.shape[0], sup.mriot_data.shape[0]), sup.direct_impact.shape) self.assertAlmostEqual(sup.direct_impact.sum(), sup.direct_impact[:, sup.reg_pos['USA']].sum(), places=3) self.assertAlmostEqual((sup.mriot_data.shape[0], ), sup.direct_aai_agg.shape) self.assertAlmostEqual(sup.direct_aai_agg.sum(), sup.direct_aai_agg[sup.reg_pos['USA']].sum(), places=3) self.assertAlmostEqual(sup.reg_dir_imp[0], 'USA') self.assertAlmostEqual(sup.direct_impact.sum(), sup.direct_impact[:, subsecs].sum(), places=3) self.assertAlmostEqual(sup.direct_aai_agg.sum(), sup.direct_aai_agg[subsecs].sum(), places=3) sup.calc_sector_direct_impact(hazard, exp, impf_set, selected_subsec='manufacturing') self.assertAlmostEqual((sup.years.shape[0], sup.mriot_data.shape[0]), sup.direct_impact.shape) self.assertAlmostEqual(sup.direct_impact.sum(), sup.direct_impact[:, sup.reg_pos['USA']].sum(), places=3) self.assertAlmostEqual((sup.mriot_data.shape[0], ), sup.direct_aai_agg.shape) self.assertAlmostEqual(sup.direct_aai_agg.sum(), sup.direct_aai_agg[sup.reg_pos['USA']].sum(), places=3) self.assertAlmostEqual(sup.reg_dir_imp[0], 'USA') self.assertAlmostEqual(sup.direct_impact.sum(), sup.direct_impact[:, range(4, 23)].sum(), places=3) self.assertAlmostEqual(sup.direct_aai_agg.sum(), sup.direct_aai_agg[range(4, 23)].sum(), places=3) sup.calc_sector_direct_impact(hazard, exp, impf_set, selected_subsec='agriculture') self.assertAlmostEqual((sup.years.shape[0], sup.mriot_data.shape[0]), sup.direct_impact.shape) self.assertAlmostEqual(sup.direct_impact.sum(), sup.direct_impact[:, sup.reg_pos['USA']].sum(), places=3) self.assertAlmostEqual((sup.mriot_data.shape[0], ), sup.direct_aai_agg.shape) self.assertAlmostEqual(sup.direct_aai_agg.sum(), sup.direct_aai_agg[sup.reg_pos['USA']].sum(), places=3) self.assertAlmostEqual(sup.direct_impact.sum(), sup.direct_impact[:, range(0, 1)].sum(), places=3) self.assertAlmostEqual(sup.direct_aai_agg.sum(), sup.direct_aai_agg[range(0, 1)].sum(), places=3) sup.calc_sector_direct_impact(hazard, exp, impf_set, selected_subsec='mining') self.assertAlmostEqual((sup.years.shape[0], sup.mriot_data.shape[0]), sup.direct_impact.shape) self.assertAlmostEqual(sup.direct_impact.sum(), sup.direct_impact[:, sup.reg_pos['USA']].sum(), places=3) self.assertAlmostEqual((sup.mriot_data.shape[0], ), sup.direct_aai_agg.shape) self.assertAlmostEqual(sup.direct_aai_agg.sum(), sup.direct_aai_agg[sup.reg_pos['USA']].sum(), places=3) self.assertAlmostEqual(sup.direct_impact.sum(), sup.direct_impact[:, range(3, 4)].sum(), places=3) self.assertAlmostEqual(sup.direct_aai_agg.sum(), sup.direct_aai_agg[range(3, 4)].sum(), places=3) sup.calc_sector_direct_impact(hazard, exp, impf_set, selected_subsec='service') self.assertAlmostEqual((sup.years.shape[0], sup.mriot_data.shape[0]), sup.direct_impact.shape) self.assertAlmostEqual(sup.direct_impact.sum(), sup.direct_impact[:, sup.reg_pos['USA']].sum(), places=3) self.assertAlmostEqual((sup.mriot_data.shape[0], ), sup.direct_aai_agg.shape) self.assertAlmostEqual(sup.direct_aai_agg.sum(), sup.direct_aai_agg[sup.reg_pos['USA']].sum(), places=3) self.assertAlmostEqual(sup.direct_impact.sum(), sup.direct_impact[:, range(26, 56)].sum(), places=3) self.assertAlmostEqual(sup.direct_aai_agg.sum(), sup.direct_aai_agg[range(26, 56)].sum(), places=3)
def test_filter_exposures_pass(self): """Test _filter_exposures method with two values""" meas = Measure() meas.exp_region_id = [3, 4] meas.haz_type = 'TC' exp = Exposures() exp.read_mat(ENT_TEST_MAT) exp.gdf.rename(columns={'if_': 'if_TC', 'centr_': 'centr_TC'}, inplace=True) exp.gdf['region_id'] = np.ones(exp.gdf.shape[0]) exp.gdf.region_id.values[:exp.gdf.shape[0] // 2] = 3 exp.gdf.region_id[0] = 4 exp.check() imp_set = ImpactFuncSet() imp_set.read_mat(ENT_TEST_MAT) haz = Hazard('TC') haz.read_mat(HAZ_TEST_MAT) exp.assign_centroids(haz) new_exp = copy.deepcopy(exp) new_exp.gdf['value'] *= 3 new_exp.gdf['if_TC'].values[:20] = 2 new_exp.gdf['if_TC'].values[20:40] = 3 new_exp.gdf['if_TC'].values[40:] = 1 new_ifs = copy.deepcopy(imp_set) new_ifs.get_func('TC')[1].intensity += 1 ref_ifs = copy.deepcopy(new_ifs) new_haz = copy.deepcopy(haz) new_haz.intensity *= 4 res_exp, res_ifs, res_haz = meas._filter_exposures(exp, imp_set, haz, new_exp.copy(deep=True), new_ifs, new_haz) # unchanged meta data self.assertEqual(res_exp.ref_year, exp.ref_year) self.assertEqual(res_exp.value_unit, exp.value_unit) self.assertEqual(res_exp.tag.file_name, exp.tag.file_name) self.assertEqual(res_exp.tag.description, exp.tag.description) self.assertEqual(res_exp.crs, exp.crs) self.assertEqual(res_exp.gdf.crs, exp.gdf.crs) # regions (that is just input data, no need for testing, but it makes the changed and unchanged parts obious) self.assertTrue(np.array_equal(res_exp.gdf.region_id.values[0], 4)) self.assertTrue(np.array_equal(res_exp.gdf.region_id.values[1:25], np.ones(24) * 3)) self.assertTrue(np.array_equal(res_exp.gdf.region_id.values[25:], np.ones(25))) # changed exposures self.assertTrue(np.array_equal(res_exp.gdf.value.values[:25], new_exp.gdf.value.values[:25])) self.assertTrue(np.all(np.not_equal(res_exp.gdf.value.values[:25], exp.gdf.value.values[:25]))) self.assertTrue(np.all(np.not_equal(res_exp.gdf.if_TC.values[:25], new_exp.gdf.if_TC.values[:25]))) self.assertTrue(np.array_equal(res_exp.gdf.latitude.values[:25], new_exp.gdf.latitude.values[:25])) self.assertTrue(np.array_equal(res_exp.gdf.longitude.values[:25], new_exp.gdf.longitude.values[:25])) # unchanged exposures self.assertTrue(np.array_equal(res_exp.gdf.value.values[25:], exp.gdf.value.values[25:])) self.assertTrue(np.all(np.not_equal(res_exp.gdf.value.values[25:], new_exp.gdf.value.values[25:]))) self.assertTrue(np.array_equal(res_exp.gdf.if_TC.values[25:], exp.gdf.if_TC.values[25:])) self.assertTrue(np.array_equal(res_exp.gdf.latitude.values[25:], exp.gdf.latitude.values[25:])) self.assertTrue(np.array_equal(res_exp.gdf.longitude.values[25:], exp.gdf.longitude.values[25:])) # unchanged impact functions self.assertEqual(list(res_ifs.get_func().keys()), [meas.haz_type]) self.assertEqual(res_ifs.get_func()[meas.haz_type][1].id, imp_set.get_func()[meas.haz_type][1].id) self.assertTrue(np.array_equal(res_ifs.get_func()[meas.haz_type][1].intensity, imp_set.get_func()[meas.haz_type][1].intensity)) self.assertEqual(res_ifs.get_func()[meas.haz_type][3].id, imp_set.get_func()[meas.haz_type][3].id) self.assertTrue(np.array_equal(res_ifs.get_func()[meas.haz_type][3].intensity, imp_set.get_func()[meas.haz_type][3].intensity)) # changed impact functions self.assertTrue(np.array_equal(res_ifs.get_func()[meas.haz_type][1 + IF_ID_FACT].intensity, ref_ifs.get_func()[meas.haz_type][1].intensity)) self.assertTrue(np.array_equal(res_ifs.get_func()[meas.haz_type][1 + IF_ID_FACT].paa, ref_ifs.get_func()[meas.haz_type][1].paa)) self.assertTrue(np.array_equal(res_ifs.get_func()[meas.haz_type][1 + IF_ID_FACT].mdd, ref_ifs.get_func()[meas.haz_type][1].mdd)) self.assertTrue(np.array_equal(res_ifs.get_func()[meas.haz_type][3 + IF_ID_FACT].intensity, ref_ifs.get_func()[meas.haz_type][3].intensity)) self.assertTrue(np.array_equal(res_ifs.get_func()[meas.haz_type][3 + IF_ID_FACT].paa, ref_ifs.get_func()[meas.haz_type][3].paa)) self.assertTrue(np.array_equal(res_ifs.get_func()[meas.haz_type][3 + IF_ID_FACT].mdd, ref_ifs.get_func()[meas.haz_type][3].mdd)) # unchanged hazard self.assertTrue(np.array_equal(res_haz.intensity[:, :36].toarray(), haz.intensity[:, :36].toarray())) self.assertTrue(np.array_equal(res_haz.intensity[:, 37:46].toarray(), haz.intensity[:, 37:46].toarray())) self.assertTrue(np.array_equal(res_haz.intensity[:, 47:].toarray(), haz.intensity[:, 47:].toarray())) # changed hazard self.assertTrue(np.array_equal(res_haz.intensity[[36, 46]].toarray(), new_haz.intensity[[36, 46]].toarray()))
class Entity(object): """Collects exposures, impact functions, measures and discount rates. Default values set when empty constructor. Attributes ---------- exposures : Exposures exposures impact_funcs : ImpactFucs impact functions measures : MeasureSet measures disc_rates : DiscRates discount rates def_file : str Default file from configuration file """ def __init__(self, exposures=None, disc_rates=None, impact_func_set=None, measure_set=None): """ Initialize entity Parameters ---------- exposures : climada.entity.Exposures, optional Exposures of the entity. The default is None (empty Exposures()). disc_rates : climada.entity.DiscRates, optional Disc rates of the entity. The default is None (empty DiscRates()). impact_func_set : climada.entity.ImpactFuncSet, optional The impact function set. The default is None (empty ImpactFuncSet()). measure_set : climada.entity.Measures, optional The measures. The default is None (empty MeasuresSet(). """ self.exposures = Exposures() if exposures is None else exposures self.disc_rates = DiscRates() if disc_rates is None else disc_rates self.impact_funcs = ImpactFuncSet( ) if impact_func_set is None else impact_func_set self.measures = MeasureSet() if measure_set is None else measure_set @classmethod def from_mat(cls, file_name, description=''): """Read MATLAB file of climada. Parameters ---------- file_name : str, optional file name(s) or folder name containing the files to read description : str or list(str), optional one description of the data or a description of each data file Returns ------- ent : climada.entity.Entity The entity from matlab file """ return cls(exposures=Exposures.from_mat(file_name), disc_rates=DiscRates.from_mat(file_name, description), impact_func_set=ImpactFuncSet.from_mat( file_name, description), measure_set=MeasureSet.from_mat(file_name, description)) def read_mat(self, *args, **kwargs): """This function is deprecated, use Entity.from_mat instead.""" LOGGER.warning("The use of Entity.read_mat is deprecated." "Use Entity.from_mat instead.") self.__dict__ = Entity.from_mat(*args, **kwargs).__dict__ @classmethod def from_excel(cls, file_name, description=''): """Read csv or xls or xlsx file following climada's template. Parameters ---------- file_name : str, optional file name(s) or folder name containing the files to read description : str or list(str), optional one description of the data or a description of each data file Returns ------- ent : climada.entity.Entity The entity from excel file """ exp = Exposures(pd.read_excel(file_name)) exp.tag = Tag() exp.tag.file_name = str(file_name) exp.tag.description = description dr = DiscRates.from_excel(file_name, description) impf_set = ImpactFuncSet.from_excel(file_name, description) meas_set = MeasureSet.from_excel(file_name, description) return cls(exposures=exp, disc_rates=dr, impact_func_set=impf_set, measure_set=meas_set) def read_excel(self, *args, **kwargs): """This function is deprecated, use Entity.from_excel instead.""" LOGGER.warning("The use of Entity.read_excel is deprecated." "Use Entity.from_excel instead.") self.__dict__ = Entity.from_excel(*args, **kwargs).__dict__ def write_excel(self, file_name): """Write excel file following template.""" self.exposures.gdf.to_excel(file_name) self.impact_funcs.write_excel(file_name) self.measures.write_excel(file_name) self.disc_rates.write_excel(file_name) def check(self): """Check instance attributes. Raises ------ ValueError """ self.disc_rates.check() self.exposures.check() self.impact_funcs.check() self.measures.check() def __setattr__(self, name, value): """Check input type before set""" if name == "exposures": if not isinstance(value, Exposures): raise ValueError("Input value is not (sub)class of Exposures.") elif name == "impact_funcs": if not isinstance(value, ImpactFuncSet): raise ValueError( "Input value is not (sub)class of ImpactFuncSet.") elif name == "measures": if not isinstance(value, MeasureSet): raise ValueError( "Input value is not (sub)class of MeasureSet.") elif name == "disc_rates": if not isinstance(value, DiscRates): raise ValueError("Input value is not (sub)class of DiscRates.") super().__setattr__(name, value) def __str__(self): return 'Exposures: \n' + self.exposures.tag.__str__() + \ '\nDiscRates: \n' + self.disc_rates.tag.__str__() + \ '\nImpactFuncSet: \n' + self.impact_funcs.tag.__str__() + \ '\nMeasureSet: \n' + self.measures.tag.__str__() __repr__ = __str__