From c0bfb136f6b423f3661ddb49de7cdde6dbd6ad23 Mon Sep 17 00:00:00 2001 From: emanuel-schmid Date: Thu, 13 Jul 2023 13:46:45 +0200 Subject: [PATCH 01/19] exposures.base: remove tag from Exposures --- climada/entity/entity_def.py | 2 - climada/entity/exposures/base.py | 51 +++++++++++----------- climada/entity/exposures/test/test_base.py | 11 ----- climada/entity/test/test_entity.py | 9 +--- 4 files changed, 28 insertions(+), 45 deletions(-) diff --git a/climada/entity/entity_def.py b/climada/entity/entity_def.py index b908d5709..2ae14d7f5 100755 --- a/climada/entity/entity_def.py +++ b/climada/entity/entity_def.py @@ -25,7 +25,6 @@ from typing import Optional import pandas as pd -from climada.util.tag import Tag from climada.entity.impact_funcs.impact_func_set import ImpactFuncSet from climada.entity.disc_rates.base import DiscRates from climada.entity.measures.measure_set import MeasureSet @@ -125,7 +124,6 @@ def from_excel(cls, file_name, description=''): """ exp = Exposures(pd.read_excel(file_name)) - exp.tag = Tag(file_name=file_name, description=description) dr = DiscRates.from_excel(file_name) impf_set = ImpactFuncSet.from_excel(file_name) diff --git a/climada/entity/exposures/base.py b/climada/entity/exposures/base.py index 904612f77..721aed996 100644 --- a/climada/entity/exposures/base.py +++ b/climada/entity/exposures/base.py @@ -37,7 +37,6 @@ import cartopy.crs as ccrs from climada.hazard import Hazard -from climada.util.tag import Tag import climada.util.hdf5_handler as u_hdf5 from climada.util.constants import ONE_LAT_KM, DEF_CRS, CMAP_RASTER import climada.util.coordinates as u_coord @@ -84,8 +83,6 @@ class Exposures(): Attributes ---------- - tag : climada.util.tag.Tag - metada - information about the source data ref_year : int metada - reference year value_unit : str @@ -121,7 +118,7 @@ class Exposures(): TC. There might be different hazards defined: centr_TC, centr_FL, ... Computed in method assign_centroids(). """ - _metadata = ['tag', 'ref_year', 'value_unit', 'meta'] + _metadata = ['ref_year', 'value_unit', 'meta'] vars_oblig = ['value', 'latitude', 'longitude'] """Name of the variables needed to compute the impact.""" @@ -142,7 +139,7 @@ def crs(self): # In case of gdf without geometry, empty or before set_geometry_points was called return self.meta.get('crs') - def __init__(self, *args, meta=None, tag=None, ref_year=DEF_REF_YEAR, + def __init__(self, *args, meta=None, ref_year=DEF_REF_YEAR, value_unit=DEF_VALUE_UNIT, crs=None, **kwargs): """Creates an Exposures object from a GeoDataFrame @@ -154,8 +151,6 @@ def __init__(self, *args, meta=None, tag=None, ref_year=DEF_REF_YEAR, Named arguments of the GeoDataFrame constructor, additionally meta : dict, optional Metadata dictionary. Default: {} (empty dictionary) - tag : climada.entity.exposures.tag.Tag, optional - Exposures tag. Defaults to the entry of the same name in `meta` or an empty Tag object. ref_year : int, optional Reference Year. Defaults to the entry of the same name in `meta` or 2018. value_unit : str, optional @@ -168,7 +163,6 @@ def __init__(self, *args, meta=None, tag=None, ref_year=DEF_REF_YEAR, self.meta = {} if meta is None else meta if not isinstance(self.meta, dict): raise ValueError("meta must be a dictionary") - self.tag = self.meta.get('tag', Tag()) if tag is None else tag self.ref_year = self.meta.get('ref_year', DEF_REF_YEAR) if ref_year is None else ref_year self.value_unit = (self.meta.get('value_unit', DEF_VALUE_UNIT) if value_unit is None else value_unit) @@ -500,7 +494,6 @@ def from_raster(cls, file_name, band=1, src_crs=None, window=None, Exposures """ exp = cls() - exp.tag = Tag(file_name=file_name) meta, value = u_coord.read_raster(file_name, [band], src_crs, window, geometry, dst_crs, transform, width, height, resampling) @@ -520,7 +513,7 @@ def from_raster(cls, file_name, band=1, src_crs=None, window=None, def plot_scatter(self, mask=None, ignore_zero=False, pop_name=True, buffer=0.0, extend='neither', axis=None, figsize=(9, 13), - adapt_fontsize=True, **kwargs): + adapt_fontsize=True, title="", **kwargs): """Plot exposures geometry's value sum scattered over Earth's map. The plot will we projected according to the current crs. @@ -545,17 +538,17 @@ def plot_scatter(self, mask=None, ignore_zero=False, pop_name=True, adapt_fontsize : bool, optional If set to true, the size of the fonts will be adapted to the size of the figure. Otherwise the default matplotlib font size is used. Default is True. + title : str, optional + a title for the plot kwargs : optional arguments for scatter matplotlib function, e.g. - cmap='Greys'. Default: 'Wistia' + cmap='Greys' Returns ------- cartopy.mpl.geoaxes.GeoAxesSubplot """ crs_epsg, _ = u_plot.get_transformation(self.crs) - title = "\n".join(self.tag.description) - cbar_label = f'Value ({self.value_unit})' if mask is None: mask = np.ones((self.gdf.shape[0],), dtype=bool) if ignore_zero: @@ -565,8 +558,12 @@ def plot_scatter(self, mask=None, ignore_zero=False, pop_name=True, value = self.gdf.value[mask][pos_vals].values coord = np.stack([self.gdf.latitude[mask][pos_vals].values, self.gdf.longitude[mask][pos_vals].values], axis=1) - return u_plot.geo_scatter_from_array(value, coord, cbar_label, title, - pop_name, buffer, extend, + return u_plot.geo_scatter_from_array(value, coord, + cbar_label=f'Value ({self.value_unit})', + title=title, + pop_name=pop_name, + buffer=buffer, + extend=extend, proj=crs_epsg, axes=axis, figsize=figsize, @@ -575,7 +572,7 @@ def plot_scatter(self, mask=None, ignore_zero=False, pop_name=True, def plot_hexbin(self, mask=None, ignore_zero=False, pop_name=True, buffer=0.0, extend='neither', axis=None, figsize=(9, 13), - adapt_fontsize=True, **kwargs): + adapt_fontsize=True, title="", **kwargs): """Plot exposures geometry's value sum binned over Earth's map. An other function for the bins can be set through the key reduce_C_function. The plot will we projected according to the current crs. @@ -604,6 +601,8 @@ def plot_hexbin(self, mask=None, ignore_zero=False, pop_name=True, If set to true, the size of the fonts will be adapted to the size of the figure. Otherwise the default matplotlib font size is used. Default is True. + title : str, optional + a title for the plot kwargs : optional arguments for hexbin matplotlib function, e.g. `reduce_C_function=np.average`. @@ -614,8 +613,6 @@ def plot_hexbin(self, mask=None, ignore_zero=False, pop_name=True, cartopy.mpl.geoaxes.GeoAxesSubplot """ crs_epsg, _ = u_plot.get_transformation(self.crs) - title = "\n".join(self.tag.description) - cbar_label = f'Value ({self.value_unit})' if 'reduce_C_function' not in kwargs: kwargs['reduce_C_function'] = np.sum if mask is None: @@ -627,9 +624,16 @@ def plot_hexbin(self, mask=None, ignore_zero=False, pop_name=True, value = self.gdf.value[mask][pos_vals].values coord = np.stack([self.gdf.latitude[mask][pos_vals].values, self.gdf.longitude[mask][pos_vals].values], axis=1) - return u_plot.geo_bin_from_array(value, coord, cbar_label, title, - pop_name, buffer, extend, proj=crs_epsg, - axes=axis, figsize=figsize, adapt_fontsize=adapt_fontsize, + return u_plot.geo_bin_from_array(value, coord, + cbar_label=f'Value ({self.value_unit})', + title=title, + pop_name=pop_name, + buffer=buffer, + extend=extend, + proj=crs_epsg, + axes=axis, + figsize=figsize, + adapt_fontsize=adapt_fontsize, **kwargs) def plot_raster(self, res=None, raster_res=None, save_tiff=None, @@ -1156,8 +1160,7 @@ def add_sea(exposures, sea_res, scheduler=None): crs=exposures.crs, ref_year=exposures.ref_year, value_unit=exposures.value_unit, - meta=exposures.meta, - tag=exposures.tag + meta=exposures.meta ) @@ -1216,5 +1219,3 @@ def _read_mat_metadata(exposures, data, file_name, var_names): file_name, data[var_names['var_name']['uni']][0][0]) except KeyError: exposures.value_unit = DEF_VALUE_UNIT - - exposures.tag = Tag(file_name) diff --git a/climada/entity/exposures/test/test_base.py b/climada/entity/exposures/test/test_base.py index 7c0ddf346..ee022284e 100644 --- a/climada/entity/exposures/test/test_base.py +++ b/climada/entity/exposures/test/test_base.py @@ -31,7 +31,6 @@ from climada.entity.exposures.base import Exposures, INDICATOR_IMPF, \ INDICATOR_CENTR, add_sea, DEF_REF_YEAR, DEF_VALUE_UNIT from climada.entity import LitPop -from climada.util.tag import Tag from climada.hazard.base import Hazard, Centroids from climada.util.constants import ENT_TEMPLATE_XLS, ONE_LAT_KM, DEF_CRS, HAZ_DEMO_FL import climada.util.coordinates as u_coord @@ -294,7 +293,6 @@ def test_read_template_pass(self): 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() @@ -305,7 +303,6 @@ def test_io_hdf5_pass(self): 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') @@ -324,8 +321,6 @@ def test_io_hdf5_pass(self): 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) @@ -433,8 +428,6 @@ def test_copy_pass(self): self.assertTrue(u_coord.equal_crs(exp_copy.crs, exp.crs)) self.assertEqual(exp_copy.ref_year, exp.ref_year) self.assertEqual(exp_copy.value_unit, exp.value_unit) - self.assertEqual(exp_copy.tag.description, exp.tag.description) - self.assertEqual(exp_copy.tag.file_name, exp.tag.file_name) np.testing.assert_array_equal(exp_copy.gdf.latitude.values, exp.gdf.latitude.values) np.testing.assert_array_equal(exp_copy.gdf.longitude.values, exp.gdf.longitude.values) @@ -448,8 +441,6 @@ def test_to_crs_inplace_pass(self): self.assertTrue(u_coord.equal_crs(exp.crs, 'epsg:3395')) self.assertEqual(exp.ref_year, DEF_REF_YEAR) self.assertEqual(exp.value_unit, DEF_VALUE_UNIT) - self.assertEqual(exp.tag.description, []) - self.assertEqual(exp.tag.file_name, []) def test_to_crs_pass(self): """Test to_crs function copy.""" @@ -462,8 +453,6 @@ def test_to_crs_pass(self): self.assertTrue(u_coord.equal_crs(exp_tr.crs, 'epsg:3395')) self.assertEqual(exp_tr.ref_year, DEF_REF_YEAR) self.assertEqual(exp_tr.value_unit, DEF_VALUE_UNIT) - self.assertEqual(exp_tr.tag.description, []) - self.assertEqual(exp_tr.tag.file_name, []) def test_constructor_pass(self): """Test initialization with input GeoDataFrame""" diff --git a/climada/entity/test/test_entity.py b/climada/entity/test/test_entity.py index c1f4e01fb..51eb277f6 100644 --- a/climada/entity/test/test_entity.py +++ b/climada/entity/test/test_entity.py @@ -58,15 +58,10 @@ def test_default_pass(self): def test_from_mat(self): """Read entity from mat file produced by climada.""" entity_mat = Entity.from_mat(ENT_TEST_MAT) - self.assertEqual(entity_mat.exposures.tag.file_name, [str(ENT_TEST_MAT)]) + self.assertIsInstance(entity_mat.exposures, Exposures) self.assertIsInstance(entity_mat.disc_rates, DiscRates) self.assertIsInstance(entity_mat.measures, MeasureSet) - self.assertTrue(isinstance(entity_mat.impact_funcs, ImpactFuncSet)) - - def test_from_excel(self): - """Read entity from an xls file following the template.""" - entity_xls = Entity.from_excel(ENT_TEMPLATE_XLS) - self.assertEqual(entity_xls.exposures.tag.file_name, [str(ENT_TEMPLATE_XLS)]) + self.assertIsInstance(entity_mat.impact_funcs, ImpactFuncSet) class TestCheck(unittest.TestCase): From a83c98c8b5a782eaec62d84d70df06eddf5650ac Mon Sep 17 00:00:00 2001 From: emanuel-schmid Date: Thu, 13 Jul 2023 13:57:10 +0200 Subject: [PATCH 02/19] doc: remove tag from Exposures tutorial --- doc/tutorial/climada_entity_Exposures.ipynb | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/doc/tutorial/climada_entity_Exposures.ipynb b/doc/tutorial/climada_entity_Exposures.ipynb index b4cb3adb0..731a534c7 100644 --- a/doc/tutorial/climada_entity_Exposures.ipynb +++ b/doc/tutorial/climada_entity_Exposures.ipynb @@ -78,7 +78,6 @@ "| Metadata variables | Data Type | Description |\n", "| :-------------------- | :------------ | :------------------------------------------------------------------------------------- |\n", "| `crs` | str or int | coordinate reference system, see GeoDataFrame.crs |\n", - "| `tag` | Tag | information about the source data |\n", "| `ref_year` | int | reference year |\n", "| `value_unit` | str | unit of the exposures' values |\n", "| `meta` | dict | dictionary containing corresponding raster properties (if any):
width, height, crs and transform must be present at least (transform needs to contain upper left corner!).
Exposures might not contain all the points of the corresponding raster. |\n" @@ -212,8 +211,6 @@ "text": [ "\n", "\u001b[1;03;30;30mexp looks like:\u001b[0m\n", - "tag: File: \n", - " Description: \n", "ref_year: 2018\n", "value_unit: USD\n", "meta: {'crs': 'EPSG:4326'}\n", @@ -347,8 +344,6 @@ "text": [ "\n", "\u001b[1;03;30;30mexp_gpd looks like:\u001b[0m\n", - "tag: File: \n", - " Description: \n", "ref_year: 2018\n", "value_unit: USD\n", "meta: {'crs': \n", @@ -1656,7 +1651,7 @@ "\n", "## Write (Save) Exposures\n", "\n", - "Exposures can be saved in any format available for `GeoDataFrame` (see fiona.supported_drivers) and `DataFrame` ([pandas IO tools](https://pandas.pydata.org/pandas-docs/stable/io.html)). Take into account that in many of these formats the metadata (e.g. variables `ref_year`, `value_unit` and `tag`) will not be saved. Use instead the format hdf5 provided by `Exposures` methods `write_hdf5()` and `from_hdf5()` to handle all the data." + "Exposures can be saved in any format available for `GeoDataFrame` (see fiona.supported_drivers) and `DataFrame` ([pandas IO tools](https://pandas.pydata.org/pandas-docs/stable/io.html)). Take into account that in many of these formats the metadata (e.g. variables `ref_year` and `value_unit`) will not be saved. Use instead the format hdf5 provided by `Exposures` methods `write_hdf5()` and `from_hdf5()` to handle all the data." ] }, { From e2fa3f4ebe0be3d310e60c196003fb73f3564ce9 Mon Sep 17 00:00:00 2001 From: emanuel-schmid Date: Thu, 13 Jul 2023 14:09:33 +0200 Subject: [PATCH 03/19] Entity: no more __str__ overriding --- climada/entity/entity_def.py | 5 ----- climada/entity/test/test_entity.py | 18 ------------------ 2 files changed, 23 deletions(-) diff --git a/climada/entity/entity_def.py b/climada/entity/entity_def.py index 2ae14d7f5..990221f56 100755 --- a/climada/entity/entity_def.py +++ b/climada/entity/entity_def.py @@ -176,8 +176,3 @@ def __setattr__(self, name, value): 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__() - - __repr__ = __str__ diff --git a/climada/entity/test/test_entity.py b/climada/entity/test/test_entity.py index 51eb277f6..54ab7aa72 100644 --- a/climada/entity/test/test_entity.py +++ b/climada/entity/test/test_entity.py @@ -105,24 +105,6 @@ def test_wrongDisc_fail(self): self.assertIn('DiscRates', str(cm.exception)) -class TestStringRepr(unittest.TestCase): - """Test the representation dunder methods of Entity""" - def setUp(self): - self.entity = Entity() - self.entity.exposures.tag.description = ["foo", "bar"] - - def test_str(self): - """Test Entity.__str__""" - out = str(self.entity) - self.assertIn("Exposures", out) - self.assertIn("Description: foo + bar", out) - - def test_repr(self): - """Test Entity.__repr__""" - out = repr(self.entity) - self.assertIn("Exposures", out) - self.assertIn("Description: foo + bar", out) - # Execute Tests if __name__ == "__main__": TESTS = unittest.TestLoader().loadTestsFromTestCase(TestReader) From a240c6844774d3b396c4c59b1106d7039f876243 Mon Sep 17 00:00:00 2001 From: emanuel-schmid Date: Fri, 14 Jul 2023 11:22:44 +0200 Subject: [PATCH 04/19] remove tag from Exposures --- climada/entity/exposures/base.py | 10 ++++++---- climada/entity/exposures/test/test_mat.py | 1 - climada/entity/measures/test/test_base.py | 6 ------ 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/climada/entity/exposures/base.py b/climada/entity/exposures/base.py index 721aed996..567690ae8 100644 --- a/climada/entity/exposures/base.py +++ b/climada/entity/exposures/base.py @@ -558,8 +558,9 @@ def plot_scatter(self, mask=None, ignore_zero=False, pop_name=True, value = self.gdf.value[mask][pos_vals].values coord = np.stack([self.gdf.latitude[mask][pos_vals].values, self.gdf.longitude[mask][pos_vals].values], axis=1) - return u_plot.geo_scatter_from_array(value, coord, - cbar_label=f'Value ({self.value_unit})', + return u_plot.geo_scatter_from_array(array_sub=value, + geo_coord=coord, + var_name=f'Value ({self.value_unit})', title=title, pop_name=pop_name, buffer=buffer, @@ -624,8 +625,9 @@ def plot_hexbin(self, mask=None, ignore_zero=False, pop_name=True, value = self.gdf.value[mask][pos_vals].values coord = np.stack([self.gdf.latitude[mask][pos_vals].values, self.gdf.longitude[mask][pos_vals].values], axis=1) - return u_plot.geo_bin_from_array(value, coord, - cbar_label=f'Value ({self.value_unit})', + return u_plot.geo_bin_from_array(array_sub=value, + geo_coord=coord, + var_name=f'Value ({self.value_unit})', title=title, pop_name=pop_name, buffer=buffer, diff --git a/climada/entity/exposures/test/test_mat.py b/climada/entity/exposures/test/test_mat.py index 20ca26cdd..a4b30bab3 100644 --- a/climada/entity/exposures/test/test_mat.py +++ b/climada/entity/exposures/test/test_mat.py @@ -78,7 +78,6 @@ def test_read_demo_pass(self): self.assertEqual(expo.ref_year, 2016) self.assertEqual(expo.value_unit, 'USD') - self.assertEqual(expo.tag.file_name, [str(ENT_TEST_MAT)]) class TestObligatories(unittest.TestCase): """Test reading exposures obligatory values.""" diff --git a/climada/entity/measures/test/test_base.py b/climada/entity/measures/test/test_base.py index 7b6d7b399..1c32a1c8e 100644 --- a/climada/entity/measures/test/test_base.py +++ b/climada/entity/measures/test/test_base.py @@ -165,8 +165,6 @@ def test_change_exposures_impf_pass(self): self.assertEqual(new_exp.ref_year, exp.ref_year) self.assertEqual(new_exp.value_unit, exp.value_unit) - self.assertEqual(new_exp.tag.file_name, exp.tag.file_name) - self.assertEqual(new_exp.tag.description, exp.tag.description) self.assertTrue(np.array_equal(new_exp.gdf.value.values, exp.gdf.value.values)) self.assertTrue(np.array_equal(new_exp.gdf.latitude.values, exp.gdf.latitude.values)) self.assertTrue(np.array_equal(new_exp.gdf.longitude.values, exp.gdf.longitude.values)) @@ -204,8 +202,6 @@ def test_change_all_exposures_pass(self): self.assertEqual(new_exp.ref_year, ref_exp.ref_year) self.assertEqual(new_exp.value_unit, ref_exp.value_unit) - self.assertEqual(new_exp.tag.file_name, ref_exp.tag.file_name) - self.assertEqual(new_exp.tag.description, ref_exp.tag.description) self.assertTrue(np.array_equal(new_exp.gdf.value.values, ref_exp.gdf.value.values)) self.assertTrue(np.array_equal(new_exp.gdf.latitude.values, ref_exp.gdf.latitude.values)) self.assertTrue(np.array_equal(new_exp.gdf.longitude.values, ref_exp.gdf.longitude.values)) @@ -271,8 +267,6 @@ def test_filter_exposures_pass(self): # 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.assertTrue(u_coord.equal_crs(res_exp.crs, exp.crs)) self.assertFalse(hasattr(exp.gdf, "crs")) self.assertFalse(hasattr(res_exp.gdf, "crs")) From 8c578a92f28995c42b92f3437160f24584fe85cc Mon Sep 17 00:00:00 2001 From: emanuel-schmid Date: Fri, 14 Jul 2023 12:22:40 +0200 Subject: [PATCH 05/19] remove dead code --- climada/engine/forecast.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/climada/engine/forecast.py b/climada/engine/forecast.py index 6549b5fe4..7299a65ee 100644 --- a/climada/engine/forecast.py +++ b/climada/engine/forecast.py @@ -1064,18 +1064,6 @@ def _plot_warn( polygon_file_crs, self._impact[haz_ind].crs, always_xy=True ) # checking the decision dict and define the corresponding functions - if not ( - isinstance(decision_dict["probability_aggregation"], float) - & isinstance(decision_dict["area_aggregation"], float) - ): - ValueError( - " If decision_level is 'exposure_point'," - + "parameters probability_aggregation and " - + "area_aggregation of " - + "Forecast.plot_warn_map() must both be " - + "floats between [0..1]. Which each " - + "specify quantiles." - ) decision_dict_functions = decision_dict.copy() for aggregation in decision_dict: if isinstance(decision_dict[aggregation], float): From 474ef1ee2e48439db767574738e3ebe9f6c2321a Mon Sep 17 00:00:00 2001 From: emanuel-schmid Date: Fri, 14 Jul 2023 14:13:34 +0200 Subject: [PATCH 06/19] cosmetics --- doc/tutorial/1_main_climada.ipynb | 62 +++----- doc/tutorial/climada_entity_LitPop.ipynb | 186 ----------------------- 2 files changed, 23 insertions(+), 225 deletions(-) diff --git a/doc/tutorial/1_main_climada.ipynb b/doc/tutorial/1_main_climada.ipynb index 8e6ca9d6a..465165d48 100644 --- a/doc/tutorial/1_main_climada.ipynb +++ b/doc/tutorial/1_main_climada.ipynb @@ -165,7 +165,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 1, "metadata": { "ExecuteTime": { "end_time": "2022-03-09T16:14:07.505695Z", @@ -256,7 +256,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "metadata": {}, "outputs": [ { @@ -291,7 +291,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -329,7 +329,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -369,7 +369,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 6, "metadata": { "ExecuteTime": { "end_time": "2022-03-09T16:16:32.680624Z", @@ -403,7 +403,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -432,7 +432,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -507,7 +507,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -603,7 +603,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -637,7 +637,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -653,7 +653,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -704,7 +704,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 13, "metadata": {}, "outputs": [], "source": [ @@ -746,7 +746,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 14, "metadata": {}, "outputs": [ { @@ -755,7 +755,7 @@ "Text(0.5, 1.0, 'TC: Modified impact function')" ] }, - "execution_count": 11, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" }, @@ -801,7 +801,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 15, "metadata": {}, "outputs": [ { @@ -846,7 +846,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 16, "metadata": {}, "outputs": [ { @@ -910,7 +910,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 17, "metadata": {}, "outputs": [ { @@ -954,24 +954,8 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 18, "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'Optional' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/var/folders/r5/6rbkr9r16mg86237m11wqn500000gn/T/ipykernel_65266/1555313014.py\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mfrom\u001b[0m \u001b[0mclimada\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mentity\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mEntity\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;32m~/Documents/Climada/climada_python/climada/entity/__init__.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0;34m.\u001b[0m\u001b[0mdisc_rates\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 25\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0;34m.\u001b[0m\u001b[0mmeasures\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 26\u001b[0;31m \u001b[0;32mfrom\u001b[0m \u001b[0;34m.\u001b[0m\u001b[0mentity_def\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;32m~/Documents/Climada/climada_python/climada/entity/entity_def.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 33\u001b[0m \u001b[0mLOGGER\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlogging\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgetLogger\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0m__name__\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 34\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 35\u001b[0;31m \u001b[0;32mclass\u001b[0m \u001b[0mEntity\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 36\u001b[0m \"\"\"Collects exposures, impact functions, measures and discount rates.\n\u001b[1;32m 37\u001b[0m \u001b[0mDefault\u001b[0m \u001b[0mvalues\u001b[0m \u001b[0mset\u001b[0m \u001b[0mwhen\u001b[0m \u001b[0mempty\u001b[0m \u001b[0mconstructor\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/Documents/Climada/climada_python/climada/entity/entity_def.py\u001b[0m in \u001b[0;36mEntity\u001b[0;34m()\u001b[0m\n\u001b[1;32m 53\u001b[0m def __init__(\n\u001b[1;32m 54\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 55\u001b[0;31m \u001b[0mexposures\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mOptional\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mExposures\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 56\u001b[0m \u001b[0mdisc_rates\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mOptional\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mDiscRates\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 57\u001b[0m \u001b[0mimpact_func_set\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mOptional\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mImpactFuncSet\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mNameError\u001b[0m: name 'Optional' is not defined" - ] - } - ], "source": [ "from climada.entity import Entity\n", "\n", @@ -1015,7 +999,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 19, "metadata": {}, "outputs": [ { @@ -1044,7 +1028,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 20, "metadata": {}, "outputs": [ { @@ -1083,7 +1067,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 21, "metadata": {}, "outputs": [ { @@ -1125,7 +1109,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 22, "metadata": {}, "outputs": [], "source": [ @@ -1165,7 +1149,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 23, "metadata": {}, "outputs": [ { diff --git a/doc/tutorial/climada_entity_LitPop.ipynb b/doc/tutorial/climada_entity_LitPop.ipynb index d3872275c..f41885ced 100644 --- a/doc/tutorial/climada_entity_LitPop.ipynb +++ b/doc/tutorial/climada_entity_LitPop.ipynb @@ -458,17 +458,6 @@ "Florida index: 20\n" ] }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "$CONDA_PREFIX/lib/python3.8/site-packages/pyproj/crs/crs.py:68: FutureWarning: '+init=:' syntax is deprecated. ':' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6\n", - " return _prepare_from_string(\" \".join(pjargs))\n", - "$CLIMADA_SRC/climada/util/coordinates.py:1129: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", - "\n", - " countries['area'] = countries.geometry.area\n" - ] - }, { "name": "stdout", "output_type": "stream", @@ -536,17 +525,6 @@ "execution_count": 7, "metadata": {}, "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "$CONDA_PREFIX/lib/python3.8/site-packages/pyproj/crs/crs.py:68: FutureWarning: '+init=:' syntax is deprecated. ':' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6\n", - " return _prepare_from_string(\" \".join(pjargs))\n", - "$CLIMADA_SRC/climada/util/coordinates.py:1129: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", - "\n", - " countries['area'] = countries.geometry.area\n" - ] - }, { "name": "stdout", "output_type": "stream", @@ -603,17 +581,6 @@ "execution_count": 8, "metadata": {}, "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "$CONDA_PREFIX/lib/python3.8/site-packages/pyproj/crs/crs.py:68: FutureWarning: '+init=:' syntax is deprecated. ':' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6\n", - " return _prepare_from_string(\" \".join(pjargs))\n", - "$CLIMADA_SRC/climada/util/coordinates.py:1129: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", - "\n", - " countries['area'] = countries.geometry.area\n" - ] - }, { "name": "stdout", "output_type": "stream", @@ -627,17 +594,6 @@ "\n" ] }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "$CONDA_PREFIX/lib/python3.8/site-packages/pyproj/crs/crs.py:68: FutureWarning: '+init=:' syntax is deprecated. ':' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6\n", - " return _prepare_from_string(\" \".join(pjargs))\n", - "$CLIMADA_SRC/climada/util/coordinates.py:1129: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", - "\n", - " countries['area'] = countries.geometry.area\n" - ] - }, { "name": "stdout", "output_type": "stream", @@ -760,154 +716,12 @@ "2021-10-19 17:04:31,363 - climada.entity.exposures.litpop.gpw_population - WARNING - Reference year: 2018. Using nearest available year for GPW data: 2020\n" ] }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "$CONDA_PREFIX/lib/python3.8/site-packages/pyproj/crs/crs.py:68: FutureWarning: '+init=:' syntax is deprecated. ':' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6\n", - " return _prepare_from_string(\" \".join(pjargs))\n", - "$CLIMADA_SRC/climada/util/coordinates.py:1129: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", - "\n", - " countries['area'] = countries.geometry.area\n", - "$CONDA_PREFIX/lib/python3.8/site-packages/pyproj/crs/crs.py:68: FutureWarning: '+init=:' syntax is deprecated. ':' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6\n", - " return _prepare_from_string(\" \".join(pjargs))\n", - "$CLIMADA_SRC/climada/util/coordinates.py:1129: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", - "\n", - " countries['area'] = countries.geometry.area\n", - "$CONDA_PREFIX/lib/python3.8/site-packages/pyproj/crs/crs.py:68: FutureWarning: '+init=:' syntax is deprecated. ':' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6\n", - " return _prepare_from_string(\" \".join(pjargs))\n", - "$CLIMADA_SRC/climada/util/coordinates.py:1129: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", - "\n", - " countries['area'] = countries.geometry.area\n", - "$CONDA_PREFIX/lib/python3.8/site-packages/pyproj/crs/crs.py:68: FutureWarning: '+init=:' syntax is deprecated. ':' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6\n", - " return _prepare_from_string(\" \".join(pjargs))\n", - "$CLIMADA_SRC/climada/util/coordinates.py:1129: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", - "\n", - " countries['area'] = countries.geometry.area\n", - "$CONDA_PREFIX/lib/python3.8/site-packages/pyproj/crs/crs.py:68: FutureWarning: '+init=:' syntax is deprecated. ':' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6\n", - " return _prepare_from_string(\" \".join(pjargs))\n", - "$CLIMADA_SRC/climada/util/coordinates.py:1129: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", - "\n", - " countries['area'] = countries.geometry.area\n", - "$CONDA_PREFIX/lib/python3.8/site-packages/pyproj/crs/crs.py:68: FutureWarning: '+init=:' syntax is deprecated. ':' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6\n", - " return _prepare_from_string(\" \".join(pjargs))\n", - "$CLIMADA_SRC/climada/util/coordinates.py:1129: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", - "\n", - " countries['area'] = countries.geometry.area\n", - "$CONDA_PREFIX/lib/python3.8/site-packages/pyproj/crs/crs.py:68: FutureWarning: '+init=:' syntax is deprecated. ':' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6\n", - " return _prepare_from_string(\" \".join(pjargs))\n", - "$CLIMADA_SRC/climada/util/coordinates.py:1129: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", - "\n", - " countries['area'] = countries.geometry.area\n", - "$CONDA_PREFIX/lib/python3.8/site-packages/pyproj/crs/crs.py:68: FutureWarning: '+init=:' syntax is deprecated. ':' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6\n", - " return _prepare_from_string(\" \".join(pjargs))\n", - "$CLIMADA_SRC/climada/util/coordinates.py:1129: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", - "\n", - " countries['area'] = countries.geometry.area\n", - "$CONDA_PREFIX/lib/python3.8/site-packages/pyproj/crs/crs.py:68: FutureWarning: '+init=:' syntax is deprecated. ':' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6\n", - " return _prepare_from_string(\" \".join(pjargs))\n", - "$CLIMADA_SRC/climada/util/coordinates.py:1129: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", - "\n", - " countries['area'] = countries.geometry.area\n", - "$CONDA_PREFIX/lib/python3.8/site-packages/pyproj/crs/crs.py:68: FutureWarning: '+init=:' syntax is deprecated. ':' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6\n", - " return _prepare_from_string(\" \".join(pjargs))\n", - "$CLIMADA_SRC/climada/util/coordinates.py:1129: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", - "\n", - " countries['area'] = countries.geometry.area\n", - "$CONDA_PREFIX/lib/python3.8/site-packages/pyproj/crs/crs.py:68: FutureWarning: '+init=:' syntax is deprecated. ':' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6\n", - " return _prepare_from_string(\" \".join(pjargs))\n", - "$CLIMADA_SRC/climada/util/coordinates.py:1129: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", - "\n", - " countries['area'] = countries.geometry.area\n", - "$CONDA_PREFIX/lib/python3.8/site-packages/pyproj/crs/crs.py:68: FutureWarning: '+init=:' syntax is deprecated. ':' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6\n", - " return _prepare_from_string(\" \".join(pjargs))\n", - "$CLIMADA_SRC/climada/util/coordinates.py:1129: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", - "\n", - " countries['area'] = countries.geometry.area\n", - "$CONDA_PREFIX/lib/python3.8/site-packages/pyproj/crs/crs.py:68: FutureWarning: '+init=:' syntax is deprecated. ':' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6\n", - " return _prepare_from_string(\" \".join(pjargs))\n", - "$CLIMADA_SRC/climada/util/coordinates.py:1129: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", - "\n", - " countries['area'] = countries.geometry.area\n", - "$CONDA_PREFIX/lib/python3.8/site-packages/pyproj/crs/crs.py:68: FutureWarning: '+init=:' syntax is deprecated. ':' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6\n", - " return _prepare_from_string(\" \".join(pjargs))\n", - "$CLIMADA_SRC/climada/util/coordinates.py:1129: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", - "\n", - " countries['area'] = countries.geometry.area\n", - "$CONDA_PREFIX/lib/python3.8/site-packages/pyproj/crs/crs.py:68: FutureWarning: '+init=:' syntax is deprecated. ':' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6\n", - " return _prepare_from_string(\" \".join(pjargs))\n", - "$CLIMADA_SRC/climada/util/coordinates.py:1129: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", - "\n", - " countries['area'] = countries.geometry.area\n", - "$CONDA_PREFIX/lib/python3.8/site-packages/pyproj/crs/crs.py:68: FutureWarning: '+init=:' syntax is deprecated. ':' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6\n", - " return _prepare_from_string(\" \".join(pjargs))\n", - "$CLIMADA_SRC/climada/util/coordinates.py:1129: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", - "\n", - " countries['area'] = countries.geometry.area\n", - "$CONDA_PREFIX/lib/python3.8/site-packages/pyproj/crs/crs.py:68: FutureWarning: '+init=:' syntax is deprecated. ':' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6\n", - " return _prepare_from_string(\" \".join(pjargs))\n", - "$CLIMADA_SRC/climada/util/coordinates.py:1129: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", - "\n", - " countries['area'] = countries.geometry.area\n", - "$CONDA_PREFIX/lib/python3.8/site-packages/pyproj/crs/crs.py:68: FutureWarning: '+init=:' syntax is deprecated. ':' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6\n", - " return _prepare_from_string(\" \".join(pjargs))\n", - "$CLIMADA_SRC/climada/util/coordinates.py:1129: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", - "\n", - " countries['area'] = countries.geometry.area\n", - "$CONDA_PREFIX/lib/python3.8/site-packages/pyproj/crs/crs.py:68: FutureWarning: '+init=:' syntax is deprecated. ':' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6\n", - " return _prepare_from_string(\" \".join(pjargs))\n", - "$CLIMADA_SRC/climada/util/coordinates.py:1129: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", - "\n", - " countries['area'] = countries.geometry.area\n", - "$CONDA_PREFIX/lib/python3.8/site-packages/pyproj/crs/crs.py:68: FutureWarning: '+init=:' syntax is deprecated. ':' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6\n", - " return _prepare_from_string(\" \".join(pjargs))\n", - "$CLIMADA_SRC/climada/util/coordinates.py:1129: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", - "\n", - " countries['area'] = countries.geometry.area\n", - "$CONDA_PREFIX/lib/python3.8/site-packages/pyproj/crs/crs.py:68: FutureWarning: '+init=:' syntax is deprecated. ':' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6\n", - " return _prepare_from_string(\" \".join(pjargs))\n", - "$CLIMADA_SRC/climada/util/coordinates.py:1129: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", - "\n", - " countries['area'] = countries.geometry.area\n", - "$CONDA_PREFIX/lib/python3.8/site-packages/pyproj/crs/crs.py:68: FutureWarning: '+init=:' syntax is deprecated. ':' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6\n", - " return _prepare_from_string(\" \".join(pjargs))\n", - "$CLIMADA_SRC/climada/util/coordinates.py:1129: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", - "\n", - " countries['area'] = countries.geometry.area\n", - "$CONDA_PREFIX/lib/python3.8/site-packages/pyproj/crs/crs.py:68: FutureWarning: '+init=:' syntax is deprecated. ':' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6\n", - " return _prepare_from_string(\" \".join(pjargs))\n", - "$CLIMADA_SRC/climada/util/coordinates.py:1129: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", - "\n", - " countries['area'] = countries.geometry.area\n", - "$CONDA_PREFIX/lib/python3.8/site-packages/pyproj/crs/crs.py:68: FutureWarning: '+init=:' syntax is deprecated. ':' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6\n", - " return _prepare_from_string(\" \".join(pjargs))\n", - "$CLIMADA_SRC/climada/util/coordinates.py:1129: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", - "\n", - " countries['area'] = countries.geometry.area\n", - "$CONDA_PREFIX/lib/python3.8/site-packages/pyproj/crs/crs.py:68: FutureWarning: '+init=:' syntax is deprecated. ':' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6\n", - " return _prepare_from_string(\" \".join(pjargs))\n", - "$CLIMADA_SRC/climada/util/coordinates.py:1129: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", - "\n", - " countries['area'] = countries.geometry.area\n", - "$CONDA_PREFIX/lib/python3.8/site-packages/pyproj/crs/crs.py:68: FutureWarning: '+init=:' syntax is deprecated. ':' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6\n", - " return _prepare_from_string(\" \".join(pjargs))\n" - ] - }, { "name": "stdout", "output_type": "stream", "text": [ "Done.\n" ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "$CLIMADA_SRC/climada/util/coordinates.py:1129: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", - "\n", - " countries['area'] = countries.geometry.area\n" - ] } ], "source": [ From 7b0a770dad099674d4379da95ed711648dd315f9 Mon Sep 17 00:00:00 2001 From: emanuel-schmid Date: Fri, 14 Jul 2023 16:17:09 +0200 Subject: [PATCH 07/19] LitPop remove tag, replaced by novel _metadata attribute `description` Overriding plot_scatter and plot_hexbin to keep custom plot titles unchanged --- climada/entity/exposures/litpop/litpop.py | 68 ++++++++++++++--------- 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/climada/entity/exposures/litpop/litpop.py b/climada/entity/exposures/litpop/litpop.py index 8fe0509f2..2337aac94 100644 --- a/climada/entity/exposures/litpop/litpop.py +++ b/climada/entity/exposures/litpop/litpop.py @@ -29,7 +29,6 @@ import climada.util.coordinates as u_coord import climada.util.finance as u_fin -from climada.util.tag import Tag from climada.entity.exposures.litpop import nightlight as nl_util from climada.entity.exposures.litpop import gpw_population as pop_util from climada.entity.exposures.base import Exposures, INDICATOR_IMPF, DEF_REF_YEAR @@ -65,8 +64,11 @@ class LitPop(Exposures): gpw_version : int, optional Version number of GPW population data, e.g. 11 for v4.11. The default is defined in GPW_VERSION. + description : str, optional + Summary of how the object has been created, set in ``from_shape``, ``from_countries`` + and ``from_shape_and_countries``. """ - _metadata = Exposures._metadata + ['exponents', 'fin_mode', 'gpw_version'] + _metadata = Exposures._metadata + ['exponents', 'fin_mode', 'gpw_version', 'description'] def set_countries(self, *args, **kwargs): """This function is deprecated, use LitPop.from_countries instead.""" @@ -81,7 +83,7 @@ def from_countries(cls, countries, res_arcsec=30, exponents=(1,1), data_dir=SYSTEM_DIR): """Init new LitPop exposure object for a list of countries (admin 0). - Sets attributes `ref_year`, `tag`, `crs`, `value`, `geometry`, `meta`, + Sets attributes `ref_year`, `crs`, `value`, `geometry`, `meta`, `value_unit`, `exponents`,`fin_mode`, `gpw_version`, and `admin1_calc`. Parameters @@ -183,19 +185,19 @@ def from_countries(cls, countries, res_arcsec=30, exponents=(1,1), LOGGER.warning('Some countries could not be identified and are ignored: ' '%s. Litpop only initiated for: %s', countries_out, countries_in) - tag = Tag(description=f'LitPop Exposure for {countries_in} at {res_arcsec} as, ' - f'year: {reference_year}, financial mode: {fin_mode}, ' - f'exp: {exponents}, admin1_calc: {admin1_calc}') + description = (f'LitPop Exposure for {countries_in} at {res_arcsec} as,' + f' year: {reference_year}, financial mode: {fin_mode},' + f' exp: {exponents}, admin1_calc: {admin1_calc}') exp = cls( data=Exposures.concat(litpop_list).gdf, crs=litpop_list[0].crs, ref_year=reference_year, - tag=tag, value_unit=get_value_unit(fin_mode), - exponents = exponents, - gpw_version = gpw_version, - fin_mode = fin_mode, + exponents=exponents, + gpw_version=gpw_version, + fin_mode=fin_mode, + description=description ) try: @@ -429,9 +431,9 @@ def from_shape_and_countries(cls, shape, countries, res_arcsec=30, exponents=(1, else: raise NotImplementedError('Not implemented for `shape` of type {type(shape)}') - exp.tag.append(Tag(description=f'LitPop Exposure for custom shape in {countries} at ' - f'{res_arcsec} as, year: {reference_year}, financial mode: ' - f'{fin_mode}, exp: {exponents}, admin1_calc: {admin1_calc}')) + exp.description = (f'LitPop Exposure for custom shape in {countries} at' + f' {res_arcsec} as, year: {reference_year}, financial mode:' + f' {fin_mode}, exp: {exponents}, admin1_calc: {admin1_calc}') exp.set_gdf(gdf.reset_index()) try: @@ -473,7 +475,7 @@ def from_shape( """init LitPop exposure object for a custom shape. Requires user input regarding the total value to be disaggregated. - Sets attributes `ref_year`, `tag`, `crs`, `value`, `geometry`, `meta`, + Sets attributes `ref_year`, `crs`, `value`, `geometry`, `meta`, `value_unit`, `exponents`,`fin_mode`, `gpw_version`, and `admin1_calc`. This method can be used to initiated LitPop Exposure for sub-national @@ -542,21 +544,21 @@ def from_shape( elif total_value is not None: raise TypeError("total_value must be int, float or None.") - tag = Tag(description = f'LitPop Exposure for custom shape at {res_arcsec} as, ' \ - f'year: {reference_year}, exp: {exponents}') + description = (f'LitPop Exposure for custom shape at {res_arcsec} as,' + f' year: {reference_year}, exp: {exponents}') litpop_gdf[INDICATOR_IMPF] = 1 exp = cls( - data=litpop_gdf, - crs=litpop_gdf.crs, - ref_year=reference_year, - tag=tag, - value_unit=value_unit, - exponents = exponents, - gpw_version = gpw_version, - fin_mode = None, - ) + data=litpop_gdf, + crs=litpop_gdf.crs, + ref_year=reference_year, + value_unit=value_unit, + exponents=exponents, + gpw_version=gpw_version, + fin_mode=None, + description=description + ) if min(len(exp.gdf.latitude.unique()), len(exp.gdf.longitude.unique())) > 1: #if exp.gdf.shape[0] > 1 and len(exp.gdf.latitude.unique()) > 1: @@ -661,6 +663,22 @@ def _from_country(country, res_arcsec=30, exponents=(1,1), fin_mode=None, exp.gdf[INDICATOR_IMPF] = 1 return exp + def plot_hexbin(self, *args, **kwargs): + """Overriding ``Exposures.plot_hexbin``. + Sets the object's ``description`` attribute as plot title. + """ + if self.description and 'title' not in kwargs: + kwargs['title'] = self.description + return super().plot_hexbin(*args, **kwargs) + + def plot_scatter(self, *args, **kwargs): + """Overriding ``Exposures.plot_scatter``. + Sets the object's ``description`` attribute as plot title. + """ + if self.description and 'title' not in kwargs: + kwargs['title'] = self.description + return super().plot_scatter(*args, **kwargs) + # Alias method names for backward compatibility: set_country = set_countries From 6e2ac6241051827863122d9c86613b0724cb69ed Mon Sep 17 00:00:00 2001 From: emanuel-schmid Date: Fri, 14 Jul 2023 16:29:20 +0200 Subject: [PATCH 08/19] PEP8 --- climada/entity/entity_def.py | 6 +++--- climada/entity/exposures/base.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/climada/entity/entity_def.py b/climada/entity/entity_def.py index 990221f56..542ca2992 100755 --- a/climada/entity/entity_def.py +++ b/climada/entity/entity_def.py @@ -105,7 +105,7 @@ def read_mat(self, *args, **kwargs): self.__dict__ = Entity.from_mat(*args, **kwargs).__dict__ @classmethod - def from_excel(cls, file_name, description=''): + def from_excel(cls, file_name): """Read csv or xls or xlsx file following climada's template. Parameters @@ -125,13 +125,13 @@ def from_excel(cls, file_name, description=''): exp = Exposures(pd.read_excel(file_name)) - dr = DiscRates.from_excel(file_name) + disc_rates = DiscRates.from_excel(file_name) impf_set = ImpactFuncSet.from_excel(file_name) meas_set = MeasureSet.from_excel(file_name) return cls( exposures=exp, - disc_rates=dr, + disc_rates=disc_rates, impact_func_set=impf_set, measure_set=meas_set, ) diff --git a/climada/entity/exposures/base.py b/climada/entity/exposures/base.py index 567690ae8..ef7db376f 100644 --- a/climada/entity/exposures/base.py +++ b/climada/entity/exposures/base.py @@ -626,7 +626,7 @@ def plot_hexbin(self, mask=None, ignore_zero=False, pop_name=True, coord = np.stack([self.gdf.latitude[mask][pos_vals].values, self.gdf.longitude[mask][pos_vals].values], axis=1) return u_plot.geo_bin_from_array(array_sub=value, - geo_coord=coord, + geo_coord=coord, var_name=f'Value ({self.value_unit})', title=title, pop_name=pop_name, From 6d4f4e02d1b8f84cb732a79f0b06a84a159cd6f3 Mon Sep 17 00:00:00 2001 From: emanuel-schmid Date: Fri, 14 Jul 2023 16:56:19 +0200 Subject: [PATCH 09/19] reaction to out of the blue failing of readthedocs to build --- requirements/env_docs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements/env_docs.yml b/requirements/env_docs.yml index 9a6ae5e25..1a2096fc9 100644 --- a/requirements/env_docs.yml +++ b/requirements/env_docs.yml @@ -326,6 +326,7 @@ dependencies: - deprecation==2.1.0 - descartes==1.1.0 - docutils==0.17.1 + - earthengine-api - isort==5.12.0 - lazy-object-proxy==1.9.0 - markdown-it-py==2.1.0 From 37949bf3532336becc7649a01d0f93108815750a Mon Sep 17 00:00:00 2001 From: emanuel-schmid Date: Fri, 4 Aug 2023 17:31:42 +0200 Subject: [PATCH 10/19] adjust readthedocs environment --- requirements/env_docs.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements/env_docs.yml b/requirements/env_docs.yml index 1a2096fc9..9a6ae5e25 100644 --- a/requirements/env_docs.yml +++ b/requirements/env_docs.yml @@ -326,7 +326,6 @@ dependencies: - deprecation==2.1.0 - descartes==1.1.0 - docutils==0.17.1 - - earthengine-api - isort==5.12.0 - lazy-object-proxy==1.9.0 - markdown-it-py==2.1.0 From 57463c296352786604382fb708ae19cb313fa062 Mon Sep 17 00:00:00 2001 From: emanuel-schmid Date: Sat, 5 Aug 2023 18:53:07 +0200 Subject: [PATCH 11/19] add output secction to prevent readthedocs from buildiing --- doc/tutorial/1_main_climada.ipynb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/tutorial/1_main_climada.ipynb b/doc/tutorial/1_main_climada.ipynb index 465165d48..c8a8b269d 100644 --- a/doc/tutorial/1_main_climada.ipynb +++ b/doc/tutorial/1_main_climada.ipynb @@ -956,6 +956,8 @@ "cell_type": "code", "execution_count": 18, "metadata": {}, + "outputs": [ + ], "source": [ "from climada.entity import Entity\n", "\n", From bded4bb8e279ac6f3d846a5382394f9a80732fbd Mon Sep 17 00:00:00 2001 From: emanuel-schmid Date: Mon, 7 Aug 2023 10:49:39 +0200 Subject: [PATCH 12/19] changelog updated --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 80908618e..4eecd9a27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -74,6 +74,7 @@ Removed: - `Centroids.set_raster_from_pix_bounds` [#721](https://github.com/CLIMADA-project/climada_python/pull/721) - `requirements/env_developer.yml` environment specs. Use 'extra' requirements when installing the Python package instead [#712](https://github.com/CLIMADA-project/climada_python/pull/712) - `Impact.tag` attribute. This change is not backwards-compatible with respect to the files written and read by the `Impact` class [#743](https://github.com/CLIMADA-project/climada_python/pull/743) +- `Exposures.tag` attribute. This change is not backwards-compatible with respect to the files written and read by the `Exposures` class [#756](https://github.com/CLIMADA-project/climada_python/pull/756) ## v3.3.2 From 6add533f75d59734f25012401b6e22e0e46bcdc6 Mon Sep 17 00:00:00 2001 From: emanuel-schmid Date: Mon, 7 Aug 2023 11:01:30 +0200 Subject: [PATCH 13/19] chanchangelog updated --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4eecd9a27..0b1b3bbd0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ Removed: - Added method `Exposures.centroids_total_value` to replace the functionality of `Exposures.affected_total_value`. This method is temporary and deprecated. [#702](https://github.com/CLIMADA-project/climada_python/pull/702) - New method `climada.util.api_client.Client.purge_cache`: utility function to remove outdated files from the local file system to free disk space. ([#737](https://github.com/CLIMADA-project/climada_python/pull/737)) +- New attribute `climada.entity.exposures.LitPop.description`: used for setting the title in plots from plotting mathods `plot_hexbin` and `plot_scatter`. [#756](https://github.com/CLIMADA-project/climada_python/pull/756) ### Changed From ff75e23305cd74f189f89c684286a4a53e8222ef Mon Sep 17 00:00:00 2001 From: emanuel-schmid Date: Fri, 11 Aug 2023 11:39:00 +0200 Subject: [PATCH 14/19] Make description an attribute of Exposures, not just LitPop crop_production, black_marble and spam_agrar also depend on it --- CHANGELOG.md | 3 ++- climada/entity/exposures/base.py | 26 +++++++++++++++------ climada/entity/exposures/litpop/litpop.py | 21 +---------------- climada/entity/exposures/test/test_base.py | 4 ++++ climada/entity/measures/test/test_base.py | 3 +++ doc/tutorial/climada_entity_Exposures.ipynb | 1 + 6 files changed, 30 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b1b3bbd0..31834b0c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,7 +30,7 @@ Removed: - Added method `Exposures.centroids_total_value` to replace the functionality of `Exposures.affected_total_value`. This method is temporary and deprecated. [#702](https://github.com/CLIMADA-project/climada_python/pull/702) - New method `climada.util.api_client.Client.purge_cache`: utility function to remove outdated files from the local file system to free disk space. ([#737](https://github.com/CLIMADA-project/climada_python/pull/737)) -- New attribute `climada.entity.exposures.LitPop.description`: used for setting the title in plots from plotting mathods `plot_hexbin` and `plot_scatter`. [#756](https://github.com/CLIMADA-project/climada_python/pull/756) +- New attribute `climada.entity.exposures.Exposures.description`: used for setting the default title in plots from plotting mathods `plot_hexbin` and `plot_scatter`. [#756](https://github.com/CLIMADA-project/climada_python/pull/756) ### Changed @@ -58,6 +58,7 @@ Removed: - `list_dataset_infos` from `climada.util.api_client.Client`: the `properties` argument, a `dict`, can now have `None` as values. Before, only strings and lists of strings were allowed. Setting a particular property to `None` triggers a search for datasets where this property is not assigned. [#752](https://github.com/CLIMADA-project/climada_python/pull/752) - Reduce memory requirements of `TropCyclone.from_tracks` [#749](https://github.com/CLIMADA-project/climada_python/pull/749) - Support for different wind speed and pressure units in `TCTracks` when running `TropCyclone.from_tracks` [#749](https://github.com/CLIMADA-project/climada_python/pull/749) +- The title of plots created by the `Exposures` methods `plot_hexbin` and `plot_scatter` can be set as a method argument. [#756](https://github.com/CLIMADA-project/climada_python/pull/756) ### Fixed diff --git a/climada/entity/exposures/base.py b/climada/entity/exposures/base.py index ef7db376f..7031bd592 100644 --- a/climada/entity/exposures/base.py +++ b/climada/entity/exposures/base.py @@ -83,6 +83,8 @@ class Exposures(): Attributes ---------- + description : str + metadata - description of content and origin of the data ref_year : int metada - reference year value_unit : str @@ -118,7 +120,7 @@ class Exposures(): TC. There might be different hazards defined: centr_TC, centr_FL, ... Computed in method assign_centroids(). """ - _metadata = ['ref_year', 'value_unit', 'meta'] + _metadata = ['description', 'ref_year', 'value_unit', 'meta'] vars_oblig = ['value', 'latitude', 'longitude'] """Name of the variables needed to compute the impact.""" @@ -139,7 +141,7 @@ def crs(self): # In case of gdf without geometry, empty or before set_geometry_points was called return self.meta.get('crs') - def __init__(self, *args, meta=None, ref_year=DEF_REF_YEAR, + def __init__(self, *args, meta=None, description=None, ref_year=DEF_REF_YEAR, value_unit=DEF_VALUE_UNIT, crs=None, **kwargs): """Creates an Exposures object from a GeoDataFrame @@ -151,6 +153,8 @@ def __init__(self, *args, meta=None, ref_year=DEF_REF_YEAR, Named arguments of the GeoDataFrame constructor, additionally meta : dict, optional Metadata dictionary. Default: {} (empty dictionary) + description : str, optional + Default: None ref_year : int, optional Reference Year. Defaults to the entry of the same name in `meta` or 2018. value_unit : str, optional @@ -163,6 +167,7 @@ def __init__(self, *args, meta=None, ref_year=DEF_REF_YEAR, self.meta = {} if meta is None else meta if not isinstance(self.meta, dict): raise ValueError("meta must be a dictionary") + self.description = self.meta.get('description') if description is None else description self.ref_year = self.meta.get('ref_year', DEF_REF_YEAR) if ref_year is None else ref_year self.value_unit = (self.meta.get('value_unit', DEF_VALUE_UNIT) if value_unit is None else value_unit) @@ -513,7 +518,7 @@ def from_raster(cls, file_name, band=1, src_crs=None, window=None, def plot_scatter(self, mask=None, ignore_zero=False, pop_name=True, buffer=0.0, extend='neither', axis=None, figsize=(9, 13), - adapt_fontsize=True, title="", **kwargs): + adapt_fontsize=True, title=None, **kwargs): """Plot exposures geometry's value sum scattered over Earth's map. The plot will we projected according to the current crs. @@ -539,7 +544,7 @@ def plot_scatter(self, mask=None, ignore_zero=False, pop_name=True, If set to true, the size of the fonts will be adapted to the size of the figure. Otherwise the default matplotlib font size is used. Default is True. title : str, optional - a title for the plot + a title for the plot. If not set `self.description` is used. kwargs : optional arguments for scatter matplotlib function, e.g. cmap='Greys' @@ -549,6 +554,8 @@ def plot_scatter(self, mask=None, ignore_zero=False, pop_name=True, cartopy.mpl.geoaxes.GeoAxesSubplot """ crs_epsg, _ = u_plot.get_transformation(self.crs) + title = (self.description.strip() if isinstance(self.description, str) else "" + ) if title is None else title if mask is None: mask = np.ones((self.gdf.shape[0],), dtype=bool) if ignore_zero: @@ -573,7 +580,7 @@ def plot_scatter(self, mask=None, ignore_zero=False, pop_name=True, def plot_hexbin(self, mask=None, ignore_zero=False, pop_name=True, buffer=0.0, extend='neither', axis=None, figsize=(9, 13), - adapt_fontsize=True, title="", **kwargs): + adapt_fontsize=True, title=None, **kwargs): """Plot exposures geometry's value sum binned over Earth's map. An other function for the bins can be set through the key reduce_C_function. The plot will we projected according to the current crs. @@ -603,7 +610,7 @@ def plot_hexbin(self, mask=None, ignore_zero=False, pop_name=True, Otherwise the default matplotlib font size is used. Default is True. title : str, optional - a title for the plot + a title for the plot. If not set `self.description` is used. kwargs : optional arguments for hexbin matplotlib function, e.g. `reduce_C_function=np.average`. @@ -614,6 +621,8 @@ def plot_hexbin(self, mask=None, ignore_zero=False, pop_name=True, cartopy.mpl.geoaxes.GeoAxesSubplot """ crs_epsg, _ = u_plot.get_transformation(self.crs) + title = (self.description.strip() if isinstance(self.description, str) else "" + ) if title is None else title if 'reduce_C_function' not in kwargs: kwargs['reduce_C_function'] = np.sum if mask is None: @@ -847,6 +856,8 @@ def from_hdf5(cls, file_name): for key, val in metadata.items(): if key in type(exp)._metadata: # pylint: disable=protected-access setattr(exp, key, val) + if key == 'tag': # for backwards compatitbility with climada <= 3.x + exp.description = getattr(val, 'description', None) return exp def read_mat(self, *args, **kwargs): @@ -1162,7 +1173,8 @@ def add_sea(exposures, sea_res, scheduler=None): crs=exposures.crs, ref_year=exposures.ref_year, value_unit=exposures.value_unit, - meta=exposures.meta + meta=exposures.meta, + description=exposures.description, ) diff --git a/climada/entity/exposures/litpop/litpop.py b/climada/entity/exposures/litpop/litpop.py index 2337aac94..c60de6da8 100644 --- a/climada/entity/exposures/litpop/litpop.py +++ b/climada/entity/exposures/litpop/litpop.py @@ -64,11 +64,8 @@ class LitPop(Exposures): gpw_version : int, optional Version number of GPW population data, e.g. 11 for v4.11. The default is defined in GPW_VERSION. - description : str, optional - Summary of how the object has been created, set in ``from_shape``, ``from_countries`` - and ``from_shape_and_countries``. """ - _metadata = Exposures._metadata + ['exponents', 'fin_mode', 'gpw_version', 'description'] + _metadata = Exposures._metadata + ['exponents', 'fin_mode', 'gpw_version'] def set_countries(self, *args, **kwargs): """This function is deprecated, use LitPop.from_countries instead.""" @@ -663,22 +660,6 @@ def _from_country(country, res_arcsec=30, exponents=(1,1), fin_mode=None, exp.gdf[INDICATOR_IMPF] = 1 return exp - def plot_hexbin(self, *args, **kwargs): - """Overriding ``Exposures.plot_hexbin``. - Sets the object's ``description`` attribute as plot title. - """ - if self.description and 'title' not in kwargs: - kwargs['title'] = self.description - return super().plot_hexbin(*args, **kwargs) - - def plot_scatter(self, *args, **kwargs): - """Overriding ``Exposures.plot_scatter``. - Sets the object's ``description`` attribute as plot title. - """ - if self.description and 'title' not in kwargs: - kwargs['title'] = self.description - return super().plot_scatter(*args, **kwargs) - # Alias method names for backward compatibility: set_country = set_countries diff --git a/climada/entity/exposures/test/test_base.py b/climada/entity/exposures/test/test_base.py index ee022284e..79f0f5110 100644 --- a/climada/entity/exposures/test/test_base.py +++ b/climada/entity/exposures/test/test_base.py @@ -321,6 +321,7 @@ def test_io_hdf5_pass(self): 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.description, exp_read.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) @@ -428,6 +429,7 @@ def test_copy_pass(self): self.assertTrue(u_coord.equal_crs(exp_copy.crs, exp.crs)) self.assertEqual(exp_copy.ref_year, exp.ref_year) self.assertEqual(exp_copy.value_unit, exp.value_unit) + self.assertEqual(exp_copy.description, exp.description) np.testing.assert_array_equal(exp_copy.gdf.latitude.values, exp.gdf.latitude.values) np.testing.assert_array_equal(exp_copy.gdf.longitude.values, exp.gdf.longitude.values) @@ -441,6 +443,7 @@ def test_to_crs_inplace_pass(self): self.assertTrue(u_coord.equal_crs(exp.crs, 'epsg:3395')) self.assertEqual(exp.ref_year, DEF_REF_YEAR) self.assertEqual(exp.value_unit, DEF_VALUE_UNIT) + self.assertEqual(exp.description, None) def test_to_crs_pass(self): """Test to_crs function copy.""" @@ -453,6 +456,7 @@ def test_to_crs_pass(self): self.assertTrue(u_coord.equal_crs(exp_tr.crs, 'epsg:3395')) self.assertEqual(exp_tr.ref_year, DEF_REF_YEAR) self.assertEqual(exp_tr.value_unit, DEF_VALUE_UNIT) + self.assertEqual(exp_tr.description, None) def test_constructor_pass(self): """Test initialization with input GeoDataFrame""" diff --git a/climada/entity/measures/test/test_base.py b/climada/entity/measures/test/test_base.py index 1c32a1c8e..b9aec847f 100644 --- a/climada/entity/measures/test/test_base.py +++ b/climada/entity/measures/test/test_base.py @@ -165,6 +165,7 @@ def test_change_exposures_impf_pass(self): self.assertEqual(new_exp.ref_year, exp.ref_year) self.assertEqual(new_exp.value_unit, exp.value_unit) + self.assertEqual(new_exp.description, exp.description) self.assertTrue(np.array_equal(new_exp.gdf.value.values, exp.gdf.value.values)) self.assertTrue(np.array_equal(new_exp.gdf.latitude.values, exp.gdf.latitude.values)) self.assertTrue(np.array_equal(new_exp.gdf.longitude.values, exp.gdf.longitude.values)) @@ -202,6 +203,7 @@ def test_change_all_exposures_pass(self): self.assertEqual(new_exp.ref_year, ref_exp.ref_year) self.assertEqual(new_exp.value_unit, ref_exp.value_unit) + self.assertEqual(new_exp.description, ref_exp.description) self.assertTrue(np.array_equal(new_exp.gdf.value.values, ref_exp.gdf.value.values)) self.assertTrue(np.array_equal(new_exp.gdf.latitude.values, ref_exp.gdf.latitude.values)) self.assertTrue(np.array_equal(new_exp.gdf.longitude.values, ref_exp.gdf.longitude.values)) @@ -267,6 +269,7 @@ def test_filter_exposures_pass(self): # 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.description, exp.description) self.assertTrue(u_coord.equal_crs(res_exp.crs, exp.crs)) self.assertFalse(hasattr(exp.gdf, "crs")) self.assertFalse(hasattr(res_exp.gdf, "crs")) diff --git a/doc/tutorial/climada_entity_Exposures.ipynb b/doc/tutorial/climada_entity_Exposures.ipynb index 731a534c7..c2c3990dc 100644 --- a/doc/tutorial/climada_entity_Exposures.ipynb +++ b/doc/tutorial/climada_entity_Exposures.ipynb @@ -78,6 +78,7 @@ "| Metadata variables | Data Type | Description |\n", "| :-------------------- | :------------ | :------------------------------------------------------------------------------------- |\n", "| `crs` | str or int | coordinate reference system, see
GeoDataFrame.crs |\n", + "| `description` | str | describing origin and content of the exposures data |\n", "| `ref_year` | int | reference year |\n", "| `value_unit` | str | unit of the exposures' values |\n", "| `meta` | dict | dictionary containing corresponding raster properties (if any):
width, height, crs and transform must be present at least (transform needs to contain upper left corner!).
Exposures might not contain all the points of the corresponding raster. |\n" From 08a671c39678181d71f92328823fd5a848753ec7 Mon Sep 17 00:00:00 2001 From: emanuel-schmid Date: Wed, 30 Aug 2023 12:56:18 +0200 Subject: [PATCH 15/19] exposures.plots: skip standard title formatting --- climada/entity/exposures/base.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/climada/entity/exposures/base.py b/climada/entity/exposures/base.py index 7031bd592..0ea81220d 100644 --- a/climada/entity/exposures/base.py +++ b/climada/entity/exposures/base.py @@ -554,8 +554,8 @@ def plot_scatter(self, mask=None, ignore_zero=False, pop_name=True, cartopy.mpl.geoaxes.GeoAxesSubplot """ crs_epsg, _ = u_plot.get_transformation(self.crs) - title = (self.description.strip() if isinstance(self.description, str) else "" - ) if title is None else title + if title is None: + title = self.description if mask is None: mask = np.ones((self.gdf.shape[0],), dtype=bool) if ignore_zero: @@ -621,8 +621,8 @@ def plot_hexbin(self, mask=None, ignore_zero=False, pop_name=True, cartopy.mpl.geoaxes.GeoAxesSubplot """ crs_epsg, _ = u_plot.get_transformation(self.crs) - title = (self.description.strip() if isinstance(self.description, str) else "" - ) if title is None else title + if title is None: + title = self.description if 'reduce_C_function' not in kwargs: kwargs['reduce_C_function'] = np.sum if mask is None: From 314948d06de54361ccb315f136752160aa442931 Mon Sep 17 00:00:00 2001 From: emanuel-schmid Date: Wed, 30 Aug 2023 12:58:31 +0200 Subject: [PATCH 16/19] forcast: revert dead code removal --- climada/engine/forecast.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/climada/engine/forecast.py b/climada/engine/forecast.py index 75d3c00dd..02d470b62 100644 --- a/climada/engine/forecast.py +++ b/climada/engine/forecast.py @@ -1079,6 +1079,18 @@ def _plot_warn( polygon_file_crs, self._impact[haz_ind].crs, always_xy=True ) # checking the decision dict and define the corresponding functions + if not ( + isinstance(decision_dict["probability_aggregation"], float) + & isinstance(decision_dict["area_aggregation"], float) + ): + ValueError( + " If decision_level is 'exposure_point'," + + "parameters probability_aggregation and " + + "area_aggregation of " + + "Forecast.plot_warn_map() must both be " + + "floats between [0..1]. Which each " + + "specify quantiles." + ) decision_dict_functions = decision_dict.copy() for aggregation in decision_dict: if isinstance(decision_dict[aggregation], float): From 39535028020491e0693bdb87baf0fbc68ba59598 Mon Sep 17 00:00:00 2001 From: emanuel-schmid Date: Wed, 30 Aug 2023 13:53:10 +0200 Subject: [PATCH 17/19] exposures.base.plots: title must not be None --- climada/entity/exposures/base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/climada/entity/exposures/base.py b/climada/entity/exposures/base.py index 0ea81220d..aee6494fd 100644 --- a/climada/entity/exposures/base.py +++ b/climada/entity/exposures/base.py @@ -555,7 +555,7 @@ def plot_scatter(self, mask=None, ignore_zero=False, pop_name=True, """ crs_epsg, _ = u_plot.get_transformation(self.crs) if title is None: - title = self.description + title = self.description or "" if mask is None: mask = np.ones((self.gdf.shape[0],), dtype=bool) if ignore_zero: @@ -622,7 +622,7 @@ def plot_hexbin(self, mask=None, ignore_zero=False, pop_name=True, """ crs_epsg, _ = u_plot.get_transformation(self.crs) if title is None: - title = self.description + title = self.description or "" if 'reduce_C_function' not in kwargs: kwargs['reduce_C_function'] = np.sum if mask is None: From 49de034be7f970f6a52c2304b94c4096ae684930 Mon Sep 17 00:00:00 2001 From: emanuel-schmid Date: Wed, 30 Aug 2023 16:02:41 +0200 Subject: [PATCH 18/19] remove remaining traces of Exposures.tag --- climada/entity/exposures/base.py | 3 ++- climada/test/test_api_client.py | 12 ++++-------- climada/test/test_litpop_integr.py | 6 +++--- climada/test/test_plot.py | 9 ++++----- doc/tutorial/climada_entity_DiscRates.ipynb | 3 +-- 5 files changed, 14 insertions(+), 19 deletions(-) diff --git a/climada/entity/exposures/base.py b/climada/entity/exposures/base.py index aee6494fd..0f12cfc86 100644 --- a/climada/entity/exposures/base.py +++ b/climada/entity/exposures/base.py @@ -857,7 +857,8 @@ def from_hdf5(cls, file_name): if key in type(exp)._metadata: # pylint: disable=protected-access setattr(exp, key, val) if key == 'tag': # for backwards compatitbility with climada <= 3.x - exp.description = getattr(val, 'description', None) + descriptions = [u_hdf5.to_string(x) for x in getattr(val, 'description', [])] + exp.description = "\n".join(descriptions) if descriptions else None return exp def read_mat(self, *args, **kwargs): diff --git a/climada/test/test_api_client.py b/climada/test/test_api_client.py index 2d9f5352d..9e8b11141 100644 --- a/climada/test/test_api_client.py +++ b/climada/test/test_api_client.py @@ -149,10 +149,8 @@ def test_get_exposures(self): dump_dir=DATA_DIR) self.assertEqual(len(exposures.gdf), 5782) self.assertEqual(np.unique(exposures.gdf.region_id), 40) - self.assertEqual(exposures.tag.description, - ["LitPop Exposure for ['AUT'] at 150 as, year: 2018, financial mode: pop, exp: [0, 1], admin1_calc: False"]) - self.assertEqual(exposures.tag.file_name, - []) + self.assertEqual(exposures.description, + "LitPop Exposure for ['AUT'] at 150 as, year: 2018, financial mode: pop, exp: [0, 1], admin1_calc: False") def test_get_exposures_fails(self): client = Client() @@ -205,10 +203,8 @@ def test_get_litpop(self): litpop = client.get_litpop(country='LUX', version='v1', dump_dir=DATA_DIR) self.assertEqual(len(litpop.gdf), 188) self.assertEqual(np.unique(litpop.gdf.region_id), 442) - self.assertEqual(litpop.tag.description, - ["LitPop Exposure for ['LUX'] at 150 as, year: 2018, financial mode: pc, exp: [1, 1], admin1_calc: False"]) - self.assertEqual(litpop.tag.file_name, - []) + self.assertEqual(litpop.description, + "LitPop Exposure for ['LUX'] at 150 as, year: 2018, financial mode: pc, exp: [1, 1], admin1_calc: False") def test_get_litpop_fail(self): client = Client() diff --git a/climada/test/test_litpop_integr.py b/climada/test/test_litpop_integr.py index f8fb2d989..23f459ee4 100644 --- a/climada/test/test_litpop_integr.py +++ b/climada/test/test_litpop_integr.py @@ -70,9 +70,9 @@ def test_switzerland300_pass(self): # confirm that the total value is equal to GDP * (income_group+1): self.assertAlmostEqual(ent.gdf.value.sum()/gdp('CHE', 2016)[1], (income_group('CHE', 2016)[1] + 1)) - self.assertIn("LitPop Exposure for ['CHE'] at 300 as, year: 2016", ent.tag.description[0]) - self.assertIn('income_group', ent.tag.description[0]) - self.assertIn('1, 1', ent.tag.description[0]) + self.assertIn("LitPop Exposure for ['CHE'] at 300 as, year: 2016", ent.description) + self.assertIn('income_group', ent.description) + self.assertIn('1, 1', ent.description) self.assertTrue(u_coord.equal_crs(ent.crs, 'epsg:4326')) self.assertEqual(ent.meta['width'], 54) self.assertEqual(ent.meta['height'], 23) diff --git a/climada/test/test_plot.py b/climada/test/test_plot.py index f03eebf1f..ea58c8ce7 100644 --- a/climada/test/test_plot.py +++ b/climada/test/test_plot.py @@ -34,7 +34,6 @@ from climada.hazard import Hazard, Centroids from climada.util.constants import HAZ_DEMO_MAT, ENT_DEMO_TODAY, TEST_UNC_OUTPUT_COSTBEN from climada.util.api_client import Client -from climada.util.tag import Tag apiclient = Client() ds = apiclient.get_dataset_info(name=TEST_UNC_OUTPUT_COSTBEN, status='test_dataset') @@ -115,13 +114,13 @@ def test_exposures_value_pass(self): myexp = pd.read_excel(ENT_DEMO_TODAY) myexp = Exposures(myexp) myexp.check() - myexp.tag = Tag(description='demo_today') + myexp.description = 'demo_today' myax = myexp.plot_hexbin() - self.assertIn('demo_today', myax.get_title()) + self.assertEqual('demo_today', myax.get_title()) - myexp.tag = Tag() + myexp.description = None myax = myexp.plot_hexbin() - self.assertNotIn('demo_today', myax.get_title()) + self.assertEqual('', myax.get_title()) myexp.plot_scatter() myexp.plot_basemap() diff --git a/doc/tutorial/climada_entity_DiscRates.ipynb b/doc/tutorial/climada_entity_DiscRates.ipynb index 3337fca5d..3d0e64985 100644 --- a/doc/tutorial/climada_entity_DiscRates.ipynb +++ b/doc/tutorial/climada_entity_DiscRates.ipynb @@ -15,7 +15,6 @@ "\n", "This class contains the discount rates for every year and discounts given values. Its attributes are:\n", "\n", - " * tag (Tag): information about the source data\n", " * years (np.array): years\n", " * rates (np.array): discount rates for each year (between 0 and 1)\n", "\n", @@ -214,7 +213,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.13 | packaged by conda-forge | (default, Mar 25 2022, 06:05:47) \n[Clang 12.0.1 ]" + "version": "3.9.16" }, "latex_envs": { "LaTeX_envs_menu_present": true, From 8ce8cba4f819d18a7b50af99e361891dac9851bb Mon Sep 17 00:00:00 2001 From: emanuel-schmid Date: Wed, 30 Aug 2023 16:04:44 +0200 Subject: [PATCH 19/19] remove remaining traces of Exposures.tag --- doc/tutorial/climada_entity_DiscRates.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tutorial/climada_entity_DiscRates.ipynb b/doc/tutorial/climada_entity_DiscRates.ipynb index 3d0e64985..c88cdc18f 100644 --- a/doc/tutorial/climada_entity_DiscRates.ipynb +++ b/doc/tutorial/climada_entity_DiscRates.ipynb @@ -136,8 +136,8 @@ "\n", "# Fill DataFrame from Excel file\n", "file_name = ENT_TEMPLATE_XLS # provide absolute path of the excel file\n", + "print('Read file:', ENT_TEMPLATE_XLS)\n", "disc = DiscRates.from_excel(file_name)\n", - "print('Read file:', disc.tag.file_name)\n", "disc.plot();" ] },