Skip to content

Commit 68549d8

Browse files
Merge branch 'develop' into feature/density_tracks
2 parents 1f84c40 + 35274ac commit 68549d8

26 files changed

+505
-149
lines changed

.zenodo.json

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
{
2+
"creators": [
3+
{
4+
"name": "Gabriela Aznar Siguan",
5+
"affiliation": "MeteoSwiss"
6+
},
7+
{
8+
"name": "David N. Bresch",
9+
"affiliation": "ETH Z\u00fcrich"
10+
},
11+
{
12+
"name": "Samuel Eberenz",
13+
"affiliation": "ETH Z\u00fcrich"
14+
},
15+
{
16+
"name": "Jan Hartman",
17+
"affiliation": "CelsiusPro"
18+
},
19+
{
20+
"name": "Marine Perus",
21+
"affiliation": "CelsiusPro"
22+
},
23+
{
24+
"name": "Thomas R\u00f6\u00f6sli"
25+
},
26+
{
27+
"name": "Dario Stocker"
28+
},
29+
{
30+
"name": "Veronica Bozzini"
31+
},
32+
{
33+
"name": "Carmen B. Steinmann"
34+
},
35+
{
36+
"name": "Evelyn M\u00fchlhofer",
37+
"affiliation": "MeteoSwiss"
38+
},
39+
{
40+
"name": "Rachel Bungerer"
41+
},
42+
{
43+
"name": "Inga J. Sauer"
44+
},
45+
{
46+
"name": "Samuel L\u00fcthi",
47+
"affiliation": "ETH Z\u00fcrich"
48+
},
49+
{
50+
"name": "Pui Man (Mannie) Kam",
51+
"affiliation": "ETH Z\u00fcrich"
52+
},
53+
{
54+
"name": "Simona Meiler",
55+
"affiliation": "ETH Z\u00fcrich"
56+
},
57+
{
58+
"name": "Alessio Ciullo",
59+
"affiliation": "ETH Z\u00fcrich"
60+
},
61+
{
62+
"name": "Thomas Vogt",
63+
"affiliation": "Potsdam Institute for Climate Impact Research"
64+
},
65+
{
66+
"name": "Benoit P. Guillod",
67+
"affiliation": "CLIMADA Technologies"
68+
},
69+
{
70+
"name": "Chahan M. Kropf",
71+
"affiliation": "ETH Z\u00fcrich"
72+
},
73+
{
74+
"name": "Emanuel Schmid",
75+
"affiliation": "ETH Z\u00fcrich"
76+
},
77+
{
78+
"name": "Chris Fairless",
79+
"affiliation": "CelsiusPro"
80+
},
81+
{
82+
"name": "Jan W\u00fcthrich"
83+
},
84+
{
85+
"name": "Z\u00e9lie Stalhandske",
86+
"affiliation": "ETH Z\u00fcrich"
87+
},
88+
{
89+
"name": "Yue Yu"
90+
},
91+
{
92+
"name": "Lukas Riedel",
93+
"affiliation": "ETH Z\u00fcrich"
94+
},
95+
{
96+
"name": "Raphael Portmann",
97+
"affiliation": "Agroscope"
98+
},
99+
{
100+
"name": "Nicolas Colombi",
101+
"affiliation": "ETH Z\u00fcrich"
102+
},
103+
{
104+
"name": "Leonie Villiger"
105+
},
106+
{
107+
"name": "Timo Schmid"
108+
},
109+
{
110+
"name": "Luca Severino"
111+
},
112+
{
113+
"name": "Samuel Juhel",
114+
"affiliation": "ETH Z\u00fcrich"
115+
},
116+
{
117+
"name": "Valentin Gebhart"
118+
}
119+
]
120+
}

AUTHORS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
* Emanuel Schmid
2424
* Chris Fairless
2525
* Jan Wüthrich
26-
* Zélie Standhanske
26+
* Zélie Stalhandske
2727
* Yue Yu
2828
* Lukas Riedel
2929
* Raphael Portmann

CHANGELOG.md

Lines changed: 60 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,58 @@ Code freeze date: YYYY-MM-DD
1212

1313
### Added
1414

15-
-`climada.hazard.tc_tracks.compute_track_density` function, `climada.util.coordinates.compute_grid_cell_area`
16-
function, `climada.hazard.plot.plot_track_density` function [#1003](https://github.com/CLIMADA-project/climada_python/pull/1003)
15+
### Changed
16+
17+
### Fixed
18+
19+
### Deprecated
20+
21+
### Removed
22+
23+
## 6.0.0
24+
25+
Release date: 2025-03-03
26+
27+
### Dependency Changes
28+
29+
Added:
30+
31+
- `osm-flex` >=1.1
32+
33+
Updated:
34+
35+
- `cartopy` >=0.23 → >=0.24
36+
- `cfgrib` >=0.9.9,<0.9.10 &rarr; >=0.9
37+
- `dask` >=2024.2,<2024.3 &rarr; >=2025.2
38+
- `eccodes` >=2.27,<2.28 &rarr; >=2.40
39+
- `gdal` >=3.6 &rarr; >=3.10
40+
- `geopandas` >=0.14 &rarr; >=0.14,<1.0
41+
- `h5py` >=3.8 &rarr; >=3.12
42+
- `haversine` >=2.8 &rarr; >=2.9
43+
- `matplotlib-base` >=3.9 &rarr; >=3.10
44+
- `netcdf4` >=1.6 &rarr; >=1.7
45+
- `numba` >=0.60 &rarr; >=0.61
46+
- `pillow` =9.4 &rarr; =11.1
47+
- `pyproj` >=3.5 &rarr; >=3.7
48+
- `pytables` >=3.7 &rarr; >=3.10
49+
- `python` =3.9 &rarr; =3.11
50+
- `rasterio` >=1.3 &rarr; >=1.4
51+
- `scikit-learn` >=1.5 &rarr; >=1.6
52+
- `scipy` >=1.13 &rarr; >=1.14,<1.15
53+
- `tqdm` >=4.66 &rarr; >=4.67
54+
- `xarray` >=2024.6 &rarr; >=2025.1
55+
- `xlsxwriter` >=3.1 &rarr; >=3.2
56+
57+
Removed:
58+
59+
- `pyepsg`
60+
61+
### Added
62+
63+
-`climada.hazard.tc_tracks.compute_track_density` function, `climada.hazard.tc_tracks.compute_genesis_density` function,
64+
`climada.util.coordinates.compute_grid_cell_area` function, `climada.util.coordinates.compute_grid_cell_area_validation` function,
65+
`climada.hazard.tc_tracks.normalize_hist` function, `climada.hazard.plot.plot_track_density` function
66+
[#1003](https://github.com/CLIMADA-project/climada_python/pull/1003)
1767
-`climada.hazard.tc_tracks.TCTracks.from_FAST` function, add Australia basin (AU) [#993](https://github.com/CLIMADA-project/climada_python/pull/993)
1868
- Add `osm-flex` package to CLIMADA core [#981](https://github.com/CLIMADA-project/climada_python/pull/981)
1969
- `doc.tutorial.climada_entity_Exposures_osm.ipynb` tutorial explaining how to use `osm-flex`with CLIMADA
@@ -42,14 +92,16 @@ function, `climada.hazard.plot.plot_track_density` function [#1003](https://git
4292
- In `climada.util.plot.geo_im_from_array`, NaNs are plotted in gray while cells with no centroid are not plotted [#929](https://github.com/CLIMADA-project/climada_python/pull/929)
4393
- Renamed `climada.util.plot.subplots_from_gdf` to `climada.util.plot.plot_from_gdf` [#929](https://github.com/CLIMADA-project/climada_python/pull/929)
4494
- `Hazard.local_exceedance_inten`, `Hazard.local_return_period`, and `Impact.local_exceedance_imp` call the corresponding new functions and a deprecation warning is added [#918](https://github.com/CLIMADA-project/climada_python/pull/918). Some inconsistencies in the previous versions are removed and the default method is changed. To reconstruct results from the previous versions, use CLIMADA v5.0.0 or less.
95+
- elements of `event_name` are now explicitly converted to `str` in `from_raster`, `from_xarray_raster`, `from_excel` and `from_csv`. [#951](https://github.com/CLIMADA-project/climada_python/pull/951), [#910](https://github.com/CLIMADA-project/climada_python/issues/910)
96+
- `event_id` and `event_name` are now explicitly converted to respectively a `np.ndarray` (`event_id`), a `list` (`event_name`) in readers. [#951](https://github.com/CLIMADA-project/climada_python/pull/951), [#950](https://github.com/CLIMADA-project/climada_python/issues/950)
4597
- Exposures complete overhaul. Notably
46-
- the _geometry_ column of the inherent `GeoDataFrame` is set up at initialization
47-
- latitude and longitude column are no longer present there (the according arrays can be retrieved as properties of the Exposures object: `exp.latitude` instead of `exp.gdf.latitude.values`).
48-
- `Exposures.gdf` has been renamed to `Exposures.data` (it still works though, as it is a property now pointing to the latter)
49-
- the `check` method does not add a default "IMPF_" column to the GeoDataFrame anymore
98+
- the _geometry_ column of the inherent `GeoDataFrame` is set up at initialization
99+
- latitude and longitude column are no longer present there (the according arrays can be retrieved as properties of the Exposures object: `exp.latitude` instead of `exp.gdf.latitude.values`).
100+
- `Exposures.gdf` has been renamed to `Exposures.data` (it still works though, as it is a property now pointing to the latter)
101+
- the `check` method does not add a default "IMPF_" column to the GeoDataFrame anymore
50102
- Updated IBTrACS version from v4.0 to v4.1 ([#976](https://github.com/CLIMADA-project/climada_python/pull/976)
51-
- Fix xarray future warning in TCTracks for .dims to .sizes
52-
- Fix hazard.concatenate type test for pathos pools
103+
- Fix xarray future warning in TCTracks for .dims to .sizes
104+
- Fix hazard.concatenate type test for pathos pools
53105

54106
### Fixed
55107

@@ -68,8 +120,6 @@ function, `climada.hazard.plot.plot_track_density` function [#1003](https://git
68120
- `climada.engine.impact.Impact.local_exceedance_imp` method
69121
- `climada.engine.impact.Impact.plot_rp_imp` method
70122

71-
### Removed
72-
73123
## 5.0.0
74124

75125
Release date: 2024-07-19

climada/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "5.0.1-dev"
1+
__version__ = "6.0.1-dev"

climada/engine/impact.py

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import pandas as pd
4242
import xlsxwriter
4343
from deprecation import deprecated
44+
from pandas.api.types import is_string_dtype
4445
from pyproj import CRS as pyprojCRS
4546
from rasterio.crs import CRS as rasterioCRS # pylint: disable=no-name-in-module
4647
from scipy import sparse
@@ -50,7 +51,6 @@
5051
import climada.util.dates_times as u_dt
5152
import climada.util.interpolation as u_interp
5253
import climada.util.plot as u_plot
53-
from climada import CONFIG
5454
from climada.entity import Exposures
5555
from climada.util.constants import CMAP_IMPACT, DEF_CRS, DEF_FREQ_UNIT
5656
from climada.util.select import get_attributes_with_matching_dimension
@@ -107,8 +107,8 @@ def __init__(
107107
crs=DEF_CRS,
108108
eai_exp=None,
109109
at_event=None,
110-
tot_value=0.,
111-
aai_agg=0.,
110+
tot_value=0.0,
111+
aai_agg=0.0,
112112
unit="",
113113
imp_mat=None,
114114
haz_type="",
@@ -216,8 +216,8 @@ def calc(
216216
"The use of Impact().calc() is deprecated."
217217
" Use ImpactCalc().impact() instead."
218218
)
219-
from climada.engine.impact_calc import (
220-
ImpactCalc, # pylint: disable=import-outside-toplevel
219+
from climada.engine.impact_calc import ( # pylint: disable=import-outside-toplevel
220+
ImpactCalc,
221221
)
222222

223223
impcalc = ImpactCalc(exposures, impact_funcs, hazard)
@@ -1191,6 +1191,8 @@ def write_csv(self, file_name):
11911191
file_name : str
11921192
absolute path of the file
11931193
"""
1194+
if not all((isinstance(val, str) for val in self.event_name)):
1195+
raise TypeError("'event_name' must be a list of strings")
11941196
LOGGER.info("Writing %s", file_name)
11951197
with open(file_name, "w", encoding="utf-8") as imp_file:
11961198
imp_wr = csv.writer(imp_file)
@@ -1239,6 +1241,8 @@ def write_excel(self, file_name):
12391241
file_name : str
12401242
absolute path of the file
12411243
"""
1244+
if not all((isinstance(val, str) for val in self.event_name)):
1245+
raise TypeError("'event_name' must be a list of strings")
12421246
LOGGER.info("Writing %s", file_name)
12431247

12441248
def write_col(i_col, imp_ws, xls_data):
@@ -1453,7 +1457,13 @@ def from_csv(cls, file_name):
14531457
imp.aai_agg = imp_df["aai_agg"][0]
14541458
imp.event_id = imp_df["event_id"][~np.isnan(imp_df["event_id"])].values
14551459
num_ev = imp.event_id.size
1456-
imp.event_name = imp_df["event_name"][:num_ev].values.tolist()
1460+
event_names = imp_df["event_name"][:num_ev]
1461+
if not is_string_dtype(event_names):
1462+
warnings.warn(
1463+
"Some event names are not str will be converted to str.", UserWarning
1464+
)
1465+
event_names = event_names.astype(str)
1466+
imp.event_name = event_names.values.tolist()
14571467
imp.date = imp_df["event_date"][:num_ev].values
14581468
imp.at_event = imp_df["at_event"][:num_ev].values
14591469
imp.frequency = imp_df["event_frequency"][:num_ev].values
@@ -1475,7 +1485,7 @@ def from_csv(cls, file_name):
14751485
def read_csv(self, *args, **kwargs):
14761486
"""This function is deprecated, use Impact.from_csv instead."""
14771487
LOGGER.warning(
1478-
"The use of Impact.read_csv is deprecated." "Use Impact.from_csv instead."
1488+
"The use of Impact.read_csv is deprecated. Use Impact.from_csv instead."
14791489
)
14801490
self.__dict__ = Impact.from_csv(*args, **kwargs).__dict__
14811491

@@ -1494,28 +1504,32 @@ def from_excel(cls, file_name):
14941504
Impact from excel file
14951505
"""
14961506
LOGGER.info("Reading %s", file_name)
1497-
dfr = pd.read_excel(file_name)
1498-
imp = cls(haz_type=str(dfr["haz_type"][0]))
1499-
1500-
imp.unit = dfr["unit"][0]
1501-
imp.tot_value = dfr["tot_value"][0]
1502-
imp.aai_agg = dfr["aai_agg"][0]
1507+
imp_df = pd.read_excel(file_name)
1508+
imp = cls(haz_type=str(imp_df["haz_type"][0]))
15031509

1504-
imp.event_id = dfr["event_id"][~np.isnan(dfr["event_id"].values)].values
1505-
imp.event_name = dfr["event_name"][: imp.event_id.size].values
1506-
imp.date = dfr["event_date"][: imp.event_id.size].values
1507-
imp.frequency = dfr["event_frequency"][: imp.event_id.size].values
1510+
imp.unit = imp_df["unit"][0]
1511+
imp.tot_value = imp_df["tot_value"][0]
1512+
imp.aai_agg = imp_df["aai_agg"][0]
1513+
imp.event_id = imp_df["event_id"][~np.isnan(imp_df["event_id"].values)].values
1514+
event_names = imp_df["event_name"][~np.isnan(imp_df["event_id"].values)]
1515+
if not is_string_dtype(event_names):
1516+
warnings.warn(
1517+
"Some event names are not str will be converted to str", UserWarning
1518+
)
1519+
event_names = event_names.astype(str)
1520+
imp.event_name = event_names.values
1521+
imp.date = imp_df["event_date"][: imp.event_id.size].values
1522+
imp.frequency = imp_df["event_frequency"][: imp.event_id.size].values
15081523
imp.frequency_unit = (
1509-
dfr["frequency_unit"][0] if "frequency_unit" in dfr else DEF_FREQ_UNIT
1524+
imp_df["frequency_unit"][0] if "frequency_unit" in imp_df else DEF_FREQ_UNIT
15101525
)
1511-
imp.at_event = dfr["at_event"][: imp.event_id.size].values
1512-
1513-
imp.eai_exp = dfr["eai_exp"][~np.isnan(dfr["eai_exp"].values)].values
1526+
imp.at_event = imp_df["at_event"][: imp.event_id.size].values
1527+
imp.eai_exp = imp_df["eai_exp"][~np.isnan(imp_df["eai_exp"].values)].values
15141528
imp.coord_exp = np.zeros((imp.eai_exp.size, 2))
1515-
imp.coord_exp[:, 0] = dfr["exp_lat"].values[: imp.eai_exp.size]
1516-
imp.coord_exp[:, 1] = dfr["exp_lon"].values[: imp.eai_exp.size]
1529+
imp.coord_exp[:, 0] = imp_df["exp_lat"].values[: imp.eai_exp.size]
1530+
imp.coord_exp[:, 1] = imp_df["exp_lon"].values[: imp.eai_exp.size]
15171531
try:
1518-
imp.crs = u_coord.to_csr_user_input(dfr["exp_crs"].values[0])
1532+
imp.crs = u_coord.to_csr_user_input(imp_df["exp_crs"].values[0])
15191533
except AttributeError:
15201534
imp.crs = DEF_CRS
15211535

@@ -1679,8 +1693,8 @@ def video_direct_impact(
16791693
-------
16801694
list of Impact
16811695
"""
1682-
from climada.engine.impact_calc import (
1683-
ImpactCalc, # pylint: disable=import-outside-toplevel
1696+
from climada.engine.impact_calc import ( # pylint: disable=import-outside-toplevel
1697+
ImpactCalc,
16841698
)
16851699

16861700
if args_exp is None:

climada/engine/test/test_impact.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ def test_from_eih_pass(self):
106106
self.assertEqual(imp.frequency_unit, HAZ.frequency_unit)
107107
self.assertEqual(imp.tot_value, tot_value)
108108
np.testing.assert_array_almost_equal(imp.event_id, HAZ.event_id)
109-
np.testing.assert_array_almost_equal(imp.event_name, HAZ.event_name)
109+
np.testing.assert_array_equal(imp.event_name, HAZ.event_name)
110110
np.testing.assert_array_almost_equal(imp.date, HAZ.date)
111111
np.testing.assert_array_almost_equal(imp.frequency, HAZ.frequency)
112112
np.testing.assert_array_almost_equal(imp.eai_exp, fake_eai_exp)

climada/engine/test/test_impact_calc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ def test_empty_impact(self):
297297

298298
def test_single_event_impact(self):
299299
"""Check impact for single event"""
300-
haz = HAZ.select([1])
300+
haz = HAZ.select(event_id=[1])
301301
icalc = ImpactCalc(ENT.exposures, ENT.impact_funcs, haz)
302302
impact = icalc.impact()
303303
aai_agg = 0.0

0 commit comments

Comments
 (0)