Skip to content

Commit

Permalink
Merge branch 'develop' into pre-commit-configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
peanutfun committed Aug 9, 2024
2 parents 0eedb4d + 994fd6d commit f8558bf
Show file tree
Hide file tree
Showing 55 changed files with 10,046 additions and 1,904 deletions.
2 changes: 2 additions & 0 deletions AUTHORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@
* Raphael Portmann
* Nicolas Colombi
* Leonie Villiger
* Timo Schmid
* Kam Lam Yeung
* Sarah Hülsen
* Timo Schmid
* Luca Severino
* Samuel Juhel
* Valentin Gebhart
50 changes: 50 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,73 @@ Code freeze date: YYYY-MM-DD

### Added

### Changed

### Fixed

### Deprecated

### Removed

## 5.0.0

Release date: 2024-07-19

### Dependency Changes

Added:

- `bayesian-optimization`
- `seaborn` >=0.13

Updated:

- `bottleneck` >=1.3 → >=1.4
- `cartopy` >=0.22 → >=0.23
- `contextily` >=1.5 → >=1.6
- `dask` >=2024.1,<2024.3 &rarr; >=2024.2,<2024.3
- `matplotlib-base` >=3.8 &rarr; >=3.9
- `numba` >=0.59 &rarr; >=0.60
- `numexpr` >=2.9 &rarr; >=2.10
- `pint` >=0.23 &rarr; >=0.24
- `pycountry` >=22.3 &rarr; >=24.6
- `requests` >=2.31 &rarr; >=2.32
- `salib` >=1.4 &rarr; >=1.5
- `scikit-learn` >=1.4 &rarr; >=1.5
- `scipy` >=1.12 &rarr; >=1.13
- `xarray` >=2024.2 &rarr; >=2024.6

### Added

- GitHub actions workflow for CLIMADA Petals compatibility tests [#855](https://github.com/CLIMADA-project/climada_python/pull/855)
- `climada.util.calibrate` module for calibrating impact functions [#692](https://github.com/CLIMADA-project/climada_python/pull/692)

### Changed

- Use Geopandas GeoDataFrame.plot() for centroids plotting function [896](https://github.com/CLIMADA-project/climada_python/pull/896)
- Update SALib sensitivity and sampling methods from newest version (SALib 1.4.7) [#828](https://github.com/CLIMADA-project/climada_python/issues/828)
- Allow for computation of relative and absolute delta impacts in `CalcDeltaClimate`
- Remove content tables and make minor improvements (fix typos and readability) in
CLIMADA tutorials. [#872](https://github.com/CLIMADA-project/climada_python/pull/872)
- Centroids complete overhaul. Most function should be backward compatible. Internal data is stored in a geodataframe attribute. Raster are now stored as points, and the meta attribute is removed. Several methds were deprecated or removed. [#787](https://github.com/CLIMADA-project/climada_python/pull/787)
- Improved error messages produced by `ImpactCalc.impact()` in case impact function in the exposures is not found in impf_set [#863](https://github.com/CLIMADA-project/climada_python/pull/863)
- Update the Holland et al. 2010 TC windfield model and introduce `model_kwargs` parameter to adjust model parameters [#846](https://github.com/CLIMADA-project/climada_python/pull/846)
- Changed module structure: `climada.hazard.Hazard` has been split into the modules `base`, `io` and `plot` [#871](https://github.com/CLIMADA-project/climada_python/pull/871)
- Ensure `csr_matrix` stored in `climada.hazard.Hazard` have consistent data format and store no explicit zeros when initializing `ImpactCalc` [#893](https://github.com/CLIMADA-project/climada_python/pull/893)
- `Impact.from_hdf5` now calls `str` on `event_name` data that is not strings, and issue a warning then [#894](https://github.com/CLIMADA-project/climada_python/pull/894)
- `Impact.write_hdf5` now throws an error if `event_name` is does not contain strings exclusively [#894](https://github.com/CLIMADA-project/climada_python/pull/894)
- Split `climada.hazard.trop_cyclone` module into smaller submodules without affecting module usage [#911](https://github.com/CLIMADA-project/climada_python/pull/911)

### Fixed

- Avoid an issue where a Hazard subselection would have a fraction matrix with only zeros as entries by throwing an error [#866](https://github.com/CLIMADA-project/climada_python/pull/866)
- Allow downgrading the Python bugfix version to improve environment compatibility [#900](https://github.com/CLIMADA-project/climada_python/pull/900)
- Fix broken links in `CONTRIBUTING.md` [#900](https://github.com/CLIMADA-project/climada_python/pull/900)
- When writing `TCTracks` to NetCDF, only apply compression to `float` or `int` data types. This fixes a downstream issue, see [climada_petals#135](https://github.com/CLIMADA-project/climada_petals/issues/135) [#911](https://github.com/CLIMADA-project/climada_python/pull/911)

### Added

- Method `Hazard.check_matrices` for bringing the stored CSR matrices into "canonical format" [#893](https://github.com/CLIMADA-project/climada_python/pull/893)
- Generic s-shaped impact function via `ImpactFunc.from_poly_s_shape` [#878](https://github.com/CLIMADA-project/climada_python/pull/878)
- climada.hazard.centroids.centr.Centroids.get_area_pixel
- climada.hazard.centroids.centr.Centroids.get_dist_coast
Expand All @@ -50,6 +99,7 @@ CLIMADA tutorials. [#872](https://github.com/CLIMADA-project/climada_python/pull
- climada.hazard.centroids.centr.Centroids.empty_geometry_points
- climada.hazard.centroids.centr.Centroids.set_meta_to_lat_lon
- climada.hazard.centroids.centr.Centroids.set_lat_lon_to_meta
- `scheduler` parameter in `climada.util.coordinates.set_df_geometry_points`, as dask is not used anymore, leaving all calculation to shapely [#912](https://github.com/CLIMADA-project/climada_python/pull/912)

### Removed

Expand Down
13 changes: 7 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Please contact the [lead developers](https://wcr.ethz.ch/research/climada.html)

## Minimal Steps to Contribute

Before you start, please have a look at our [Developer Guide][devguide].
Before you start, please have a look at our Developer Guide section in the [CLIMADA Docs][docs].

To contribute follow these steps:

Expand Down Expand Up @@ -65,21 +65,22 @@ To contribute follow these steps:
## Resources
The CLIMADA documentation provides a [Developer Guide][devguide].
The [CLIMADA documentation][docs] provides several Developer Guides.
Here's a selection of the commonly required information:

* How to use Git and GitHub for CLIMADA development: [Development and Git and CLIMADA](https://climada-python.readthedocs.io/en/latest/guide/Guide_Git_Development.html)
* Coding instructions for CLIMADA: [Python Dos and Don'ts](https://climada-python.readthedocs.io/en/latest/guide/Guide_PythonDos-n-Donts.html), [Performance Tips](https://climada-python.readthedocs.io/en/latest/guide/Guide_Py_Performance.html), [CLIMADA Conventions](https://climada-python.readthedocs.io/en/latest/guide/Guide_Miscellaneous.html)
* How to execute tests in CLIMADA: [Testing and Continuous Integration][testing]
* Coding instructions for CLIMADA: [Python Dos and Don'ts](https://climada-python.readthedocs.io/en/latest/guide/Guide_PythonDos-n-Donts.html), [Performance Tips](https://climada-python.readthedocs.io/en/latest/guide/Guide_Py_Performance.html), [CLIMADA Conventions](https://climada-python.readthedocs.io/en/latest/guide/Guide_CLIMADA_conventions.html)
* How to execute tests in CLIMADA: [Testing][testing] and [Continuous Integration](https://climada-python.readthedocs.io/en/latest/guide/Guide_continuous_integration_GitHub_actions.html)
## Pull Requests
After developing a new feature, fixing a bug, or updating the tutorials, you can create a [pull request](https://docs.github.com/en/pull-requests) to have your changes reviewed and then merged into the CLIMADA code base.
To ensure that your pull request can be reviewed quickly and easily, please have a look at the _Resources_ above before opening a pull request.
In particular, please check out the [Pull Request instructions](https://climada-python.readthedocs.io/en/latest/guide/Guide_Git_Development.html#Pull-requests).
In particular, please check out the [Pull Request instructions](https://climada-python.readthedocs.io/en/latest/guide/Guide_Git_Development.html#pull-requests).
We provide a description template for pull requests that helps you provide the essential information for reviewers.
It also contains a checklist for both pull request authors and reviewers to guide the review process.
[docs]: https://climada-python.readthedocs.io/en/latest/
[devguide]: https://climada-python.readthedocs.io/en/latest/#developer-guide
[testing]: https://climada-python.readthedocs.io/en/latest/guide/Guide_Continuous_Integration_and_Testing.html
[testing]: https://climada-python.readthedocs.io/en/latest/guide/Guide_Testing.html
2 changes: 1 addition & 1 deletion climada/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '4.1.2-dev'
__version__ = '5.0.1-dev'
2 changes: 1 addition & 1 deletion climada/conf/climada.conf
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
"cache_db": "{local_data.system}/.downloads.db",
"cache_enabled": true,
"cache_dir": "{local_data.system}/.apicache",
"supported_hazard_types": ["river_flood", "tropical_cyclone", "storm_europe", "relative_cropyield", "wildfire", "earthquake", "flood", "hail"],
"supported_hazard_types": ["river_flood", "tropical_cyclone", "storm_europe", "relative_cropyield", "wildfire", "earthquake", "flood", "hail", "aqueduct_coastal_flood"],
"supported_exposures_types": ["litpop", "crop_production", "ssp_population", "crops"]
}
}
26 changes: 18 additions & 8 deletions climada/engine/impact.py
Original file line number Diff line number Diff line change
Expand Up @@ -937,11 +937,6 @@ def write_hdf5(self, file_path: Union[str, Path], dense_imp_mat: bool=False):
The impact matrix can be stored in a sparse or dense format.
Notes
-----
This writer does not support attributes with variable types. Please make sure
that ``event_name`` is a list of equally-typed values, e.g., all ``str``.
Parameters
----------
file_path : str or Path
Expand All @@ -950,6 +945,11 @@ def write_hdf5(self, file_path: Union[str, Path], dense_imp_mat: bool=False):
If ``True``, write the impact matrix as dense matrix that can be more easily
interpreted by common H5 file readers but takes up (vastly) more space.
Defaults to ``False``.
Raises
------
TypeError
If :py:attr:`event_name` does not contain strings exclusively.
"""
# Define writers for all types (will be filled later)
type_writers = dict()
Expand Down Expand Up @@ -983,7 +983,7 @@ def write(group: h5py.Group, name: str, value: Any):

def _str_type_helper(values: Collection):
"""Return string datatype if we assume 'values' contains strings"""
if isinstance(next(iter(values)), str):
if all((isinstance(val, str) for val in values)):
return h5py.string_dtype()
return None

Expand Down Expand Up @@ -1037,6 +1037,8 @@ def write_csr(group, name, value):
# Now write all attributes
# NOTE: Remove leading underscore to write '_tot_value' as regular attribute
for name, value in self.__dict__.items():
if name == "event_name" and _str_type_helper(value) is None:
raise TypeError("'event_name' must be a list of strings")
write(file, name.lstrip("_"), value)

def write_sparse_csr(self, file_name):
Expand Down Expand Up @@ -1240,10 +1242,18 @@ def from_hdf5(cls, file_path: Union[str, Path]):
).intersection(file.keys())
kwargs.update({attr: file[attr][:] for attr in array_attrs})

# Special handling for 'event_name' because it's a list of strings
# Special handling for 'event_name' because it should be a list of strings
if "event_name" in file:
# pylint: disable=no-member
kwargs["event_name"] = list(file["event_name"].asstr()[:])
try:
event_name = file["event_name"].asstr()[:]
except TypeError:
LOGGER.warning(
"'event_name' is not stored as strings. Trying to decode "
"values with 'str()' instead."
)
event_name = map(str, file["event_name"][:])
kwargs["event_name"] = list(event_name)

# Create the impact object
return cls(**kwargs)
Expand Down
4 changes: 4 additions & 0 deletions climada/engine/impact_calc.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ def __init__(self,
The dimension of the imp_mat variable must be compatible with the
exposures and hazard objects.
This will call :py:meth:`climada.hazard.base.Hazard.check_matrices`.
Parameters
----------
exposures : climada.entity.Exposures
Expand All @@ -61,6 +63,8 @@ def __init__(self,
self.exposures = exposures
self.impfset = impfset
self.hazard = hazard
self.hazard.check_matrices()

# exposures index to use for matrix reconstruction
self._orig_exp_idx = np.arange(self.exposures.gdf.shape[0])

Expand Down
19 changes: 15 additions & 4 deletions climada/engine/test/test_impact.py
Original file line number Diff line number Diff line change
Expand Up @@ -779,7 +779,8 @@ def test_select_event_identity_pass(self):
ent.exposures.assign_centroids(hazard)

# Compute the impact over the whole exposures
imp = ImpactCalc(ent.exposures, ent.impact_funcs, hazard).impact(save_mat=True, assign_centroids=False)
imp = ImpactCalc(ent.exposures, ent.impact_funcs, hazard).impact(
save_mat=True, assign_centroids=False)

sel_imp = imp.select(event_ids=imp.event_id,
event_names=imp.event_name,
Expand Down Expand Up @@ -1019,10 +1020,11 @@ def test_write_hdf5_without_imp_mat(self):

def test_write_hdf5_type_fail(self):
"""Test that writing attributes with varying types results in an error"""
self.impact.event_name = [1, "a", 1.0, "b", "c", "d"]
with self.assertRaises(TypeError) as cm:
self.impact.event_name = ["a", 1, 1.0, "b", "c", "d"]
with self.assertRaisesRegex(
TypeError, "'event_name' must be a list of strings"
):
self.impact.write_hdf5(self.filepath)
self.assertIn("No conversion path for dtype", str(cm.exception))

def test_cycle_hdf5(self):
"""Test writing and reading the same object"""
Expand Down Expand Up @@ -1120,6 +1122,15 @@ def test_read_hdf5_full(self):
impact = Impact.from_hdf5(self.filepath)
npt.assert_array_equal(impact.imp_mat.toarray(), [[0, 1, 2], [3, 0, 0]])

# Check with non-string event_name
event_name = [1.2, 2]
with h5py.File(self.filepath, "r+") as file:
del file["event_name"]
file.create_dataset("event_name", data=event_name)
with self.assertLogs("climada.engine.impact", "WARNING") as cm:
impact = Impact.from_hdf5(self.filepath)
self.assertIn("'event_name' is not stored as strings", cm.output[0])
self.assertListEqual(impact.event_name, ["1.2", "2.0"])

# Execute Tests
if __name__ == "__main__":
Expand Down
10 changes: 10 additions & 0 deletions climada/engine/test/test_impact_calc.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,16 @@ def test_init(self):
np.testing.assert_array_equal(HAZ.event_id, icalc.hazard.event_id)
np.testing.assert_array_equal(HAZ.event_name, icalc.hazard.event_name)

# Test check matrices
hazard = deepcopy(HAZ)
hazard.intensity[0, hazard.intensity.indices[0]] = 0
hazard.fraction = sparse.csr_matrix(np.ones((1, 1)))
with self.assertRaisesRegex(
ValueError, "Intensity and fraction matrices must have the same shape"
):
ImpactCalc(ENT.exposures, ENT.impact_funcs, hazard)
self.assertEqual(hazard.intensity.nnz, HAZ.intensity.nnz - 1) # was pruned

def test_metrics(self):
"""Test methods to get impact metrics"""
mat = sparse.csr_matrix(np.array(
Expand Down
Loading

0 comments on commit f8558bf

Please sign in to comment.