Skip to content

Commit 55440a1

Browse files
Merge branch 'develop' into feature/review_api_tutorial
2 parents e9a7585 + b40ea48 commit 55440a1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+4081
-2403
lines changed

.github/pull_request_template.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ This PR fixes #
1919
### PR Reviewer Checklist
2020

2121
- [ ] Read the [Contribution Guide][contrib]
22-
- [ ] [CLIMADA Reviewer Checklist](https://climada-python.readthedocs.io/en/latest/guide/Guide_Reviewer_Checklist.html) passed
22+
- [ ] [CLIMADA Reviewer Checklist](https://climada-python.readthedocs.io/en/latest/development/Guide_Review.html) passed
2323
- [ ] [Tests][testing] passing
2424
- [ ] No new [linter issues][linter]
2525

2626
[contrib]: https://github.com/CLIMADA-project/climada_python/blob/main/CONTRIBUTING.md
27-
[testing]: https://climada-python.readthedocs.io/en/latest/guide/Guide_Continuous_Integration_and_Testing.html
28-
[linter]: https://climada-python.readthedocs.io/en/stable/guide/Guide_Continuous_Integration_and_Testing.html#3.C.--Static-Code-Analysis
27+
[testing]: https://climada-python.readthedocs.io/en/latest/development/Guide_continuous_integration_GitHub_actions.html
28+
[linter]: https://climada-python.readthedocs.io/en/latest/development/Guide_continuous_integration_GitHub_actions.html#static-code-analysis

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ jobs:
4747
-
4848
name: Install CLIMADA
4949
run: |
50-
python -m pip install ".[test]"
50+
python -m pip install "./[dev]"
5151
-
5252
name: Run Unit Tests
5353
run: |

.zenodo.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,9 @@
119119
},
120120
{
121121
"name": "Valentin Gebhart"
122+
},
123+
{
124+
"name": "Dahyann Araya"
122125
}
123126
]
124127
}

AUTHORS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,4 @@
3636
* Luca Severino
3737
* Samuel Juhel
3838
* Valentin Gebhart
39+
* Dahyann Araya

CHANGELOG.md

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,41 @@ Code freeze date: YYYY-MM-DD
1010

1111
### Dependency Changes
1212

13+
Added:
14+
15+
- `fiona` >=1.10
16+
17+
Updated:
18+
19+
- `geopandas` >=0.14,<1.0 → >=0.14
20+
- `pandas` >=2.1,<2.2 → >=2.1
21+
1322
Removed:
1423

1524
- `pandas-datareader`
1625

1726
### Added
27+
1828
- Added optional parameter to `geo_im_from_array`, `plot_from_gdf`, `plot_rp_imp`, `plot_rp_intensity`,
1929
`plot_intensity`, `plot_fraction`, `_event_plot` to mask plotting when regions are too far from data points [#1047](https://github.com/CLIMADA-project/climada_python/pull/1047). To recreate previous plots (no masking), the parameter can be set to None.
2030
- Added instructions to install Climada petals on Euler cluster in `doc.guide.Guide_Euler.ipynb` [#1029](https://github.com/CLIMADA-project/climada_python/pull/1029)
21-
31+
- Added util methods to handle crs coordinates consistently: `is_geo_coords`, `check_if_geo_coords`, `get_crs_unit`, `estimate_matching_threshold`, `degree_to_km`, and `km_to_degree` [#1080](https://github.com/CLIMADA-project/climada_python/pull/1080)
2232
- `ImpactFunc` and `ImpactFuncSet` now support equality comparisons via `==` [#1027](https://github.com/CLIMADA-project/climada_python/pull/1027)
2333

2434
### Changed
35+
- Changed default distance threshold for nearest neighbor matching in `util.coordinates.match_coordinates` from a fixed value of 100km to twice the highest resolution of the coords_to_assign [#1080](https://github.com/CLIMADA-project/climada_python/pull/1080).
2536
- Changed the default mask_distance in `util.plot.geo_im_from_array` to 0.03 to avoid white gaps in gridded hazard data with comparably low resolution (>80 centroids per axis) [#1073](https://github.com/CLIMADA-project/climada_python/pull/1073)
2637
- Increased speed of `util.plot.add_shapes` by avoiding for loops, substantially speeding up `Hazard.plot_intensity` and other functions. [#1073](https://github.com/CLIMADA-project/climada_python/pull/1073)
38+
- Update `util.coordinates.match_centroids`, `util.coordinates.match_coordinates`, so that they also
39+
accept coordinates that are not defined in degree. [#1080](https://github.com/CLIMADA-project/climada_python/pull/1080)
40+
- Implement cheap test to check that input coordinates at least seem geographic for functions that require
41+
geographic coordinates as input (e.g. `util.coordinates.dist_to_coast`, `util.coordinates.coord_on_land`, `util.coordinates.lon_normalize`, `util.coordinates.lon_bounds`). [#1080](https://github.com/CLIMADA-project/climada_python/pull/1080)
2742
- `Hazard.local_exceedance_intensity`, `Hazard.local_return_period` and `Impact.local_exceedance_impact`, `Impact.local_return_period`, using the `climada.util.interpolation` module: New default (no binning), binning on decimals, and faster implementation [#1012](https://github.com/CLIMADA-project/climada_python/pull/1012)
2843
- World Bank indicator data is now downloaded directly from their API via the function `download_world_bank_indicator`, instead of relying on the `pandas-datareader` package [#1033](https://github.com/CLIMADA-project/climada_python/pull/1033)
2944
- `Exposures.write_hdf5` pickles geometry data in WKB format, which is faster and more sustainable. [#1051](https://github.com/CLIMADA-project/climada_python/pull/1051)
3045
- The online documentation has been completely overhauled, now uses PyData theme: [#977](https://github.com/CLIMADA-project/climada_python/pull/977)
46+
- Add `climada.hazard.xarray` module with helper structures for reading Hazard objects from `xarray` data [#1063](https://github.com/CLIMADA-project/climada_python/pull/1063)
47+
- The output of the `impact_yearset` was changed to only contain attributes corresponding to the yearly impact set. The application of the correction factor and the frequency of the resulting yearly impact object are corrected. [#1075](https://github.com/CLIMADA-project/climada_python/pull/1075)
3148

3249
### Fixed
3350

@@ -36,9 +53,13 @@ Removed:
3653

3754
### Deprecated
3855

56+
- `Hazard.from_xarray_raster_file`. Use `Hazard.from_xarray_raster` and pass the file path as `data` argument [#1063](https://github.com/CLIMADA-project/climada_python/pull/1063)
57+
3958
### Removed
4059

4160
- `climada.util.interpolation.round_to_sig_digits` [#1012](https://github.com/CLIMADA-project/climada_python/pull/1012)
61+
- `intensity_thres` of `Hazard`, `StormEurope`, and `TropCyclones` object [#1065](https://github.com/CLIMADA-project/climada_python/pull/1065)
62+
- Deprecated method `climada.hazard.trop_cyclone.trop_cyclone.TropCyclone.set_from_tracks` [#1065](https://github.com/CLIMADA-project/climada_python/pull/1065)
4263

4364
## 6.0.1
4465

@@ -89,8 +110,12 @@ Removed:
89110

90111
### Added
91112

113+
- `climada.entity.impact_funcs.trop_cyclone.ImpfSetTropCyclone.get_impf_id_regions_per_countries` function [#1034](https://github.com/CLIMADA-project/climada_python/pull/1034)
114+
- `climada.hazard.tc_tracks.BasinBoundsStorm` Enum class `climada.hazard.tc_tracks.subset_by_basin` function [#1031](https://github.com/CLIMADA-project/climada_python/pull/1031)
92115
- `climada.hazard.tc_tracks.TCTracks.subset_years` function [#1023](https://github.com/CLIMADA-project/climada_python/pull/1023)
93-
- `climada.hazard.tc_tracks.TCTracks.from_FAST` function, add Australia basin (AU) [#993](https://github.com/CLIMADA-project/climada_python/pull/993)
116+
-`climada.hazard.tc_tracks.compute_track_density` function, `climada.hazard.tc_tracks.compute_genesis_density` function, `climada.hazard.plot.plot_track_density` function
117+
[#1003](https://github.com/CLIMADA-project/climada_python/pull/1003)
118+
-`climada.hazard.tc_tracks.TCTracks.from_FAST` function, add Australia basin (AU) [#993](https://github.com/CLIMADA-project/climada_python/pull/993)
94119
- Add `osm-flex` package to CLIMADA core [#981](https://github.com/CLIMADA-project/climada_python/pull/981)
95120
- `doc.tutorial.climada_entity_Exposures_osm.ipynb` tutorial explaining how to use `osm-flex` with CLIMADA
96121
- `climada.util.coordinates.bounding_box_global` function [#980](https://github.com/CLIMADA-project/climada_python/pull/980)
@@ -208,6 +233,7 @@ CLIMADA tutorials. [#872](https://github.com/CLIMADA-project/climada_python/pull
208233
- `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)
209234
- Split `climada.hazard.trop_cyclone` module into smaller submodules without affecting module usage [#911](https://github.com/CLIMADA-project/climada_python/pull/911)
210235
- `yearly_steps` parameter of `TropCyclone.apply_climate_scenario_knu` has been made explicit [#991](https://github.com/CLIMADA-project/climada_python/pull/991)
236+
- `Hazard.write_hdf5` writes centroids as x,y columns (or as wkb in case of polygons) at a compression level of 9, not as pickled `Shapely` objects anymore, which reduces the size of the files significantly.
211237

212238
### Fixed
213239

climada/engine/impact_calc.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,12 @@ def impact(
9292
Default: True
9393
assign_centroids : bool, optional
9494
indicates whether centroids are assigned to the self.exposures object.
95+
The default centroids assignment uses Euclidean distance and a threshold equal to
96+
twice the highest resolution (smallest distance between any two nearest neighbours)
97+
of the centroids (assuming a regular grid).
98+
Recommendation: assign the centroids directly with control
99+
over the distance metric and the distance threshold using
100+
`exposure.assign_centroids(hazard)`. In this case, set assign_centroids to ``False``.
95101
Centroids assignment is an expensive operation; set this to ``False`` to save
96102
computation time if the hazards' centroids are already assigned to the exposures
97103
object.
@@ -114,10 +120,20 @@ def impact(
114120
>>> imp = impcalc.impact(insured=True)
115121
>>> imp.aai_agg
116122
123+
>>> haz = Hazard.from_hdf5(HAZ_DEMO_H5) # Set hazard
124+
>>> impfset = ImpactFuncSet.from_excel(ENT_TEMPLATE_XLS)
125+
>>> exp = Exposures(pd.read_excel(ENT_TEMPLATE_XLS))
126+
>>> #Adjust threshold and distance to centroids/exposure resolution
127+
>>> exp.assign_centroids(hazard, threshold=1.5, distance='euclidean')
128+
>>> impcalc = ImpactCal(exp, impfset, haz)
129+
>>> imp = impcalc.impact(insured=True, assign_centroids=False)
130+
>>> imp.aai_agg
131+
117132
See also
118133
--------
119134
apply_deductible_to_mat : apply deductible to impact matrix
120135
apply_cover_to_mat : apply cover to impact matrix
136+
climada.entity.exposures.assign_centroids : assign centroids to exposures explicitly
121137
"""
122138
# TODO: consider refactoring, making use of Exposures.hazard_impf
123139
# check for compatibility of exposures and hazard type

climada/engine/impact_data.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -774,7 +774,7 @@ def clean_emdat_df(
774774
df_data["Start Day"] = np.array(day_list, dtype="int")
775775
df_data["Start Year"] = np.array(year_list, dtype="int")
776776
for var in ["Disaster Subtype", "Disaster Type", "Country"]:
777-
df_data[VARNAMES_EMDAT[target_version][var]].fillna("None", inplace=True)
777+
df_data.fillna({VARNAMES_EMDAT[target_version][var]: "None"}, inplace=True)
778778

779779
# (3) Filter by countries, year range, and disaster type
780780
# (3.1) Countries:

climada/engine/test/test_impact_calc.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,28 @@ def test_calc_impact_TC_pass(self):
210210
self.assertAlmostEqual(6.570532945599105e11, impact.tot_value)
211211
self.assertAlmostEqual(6.512201157564421e09 * x, impact.aai_agg, 5)
212212

213+
def test_calc_impact_TC_change_crs_pass(self):
214+
"""Test compute impact"""
215+
crs = "EPSG:4087"
216+
exp = ENT.exposures.copy()
217+
exp.to_crs(crs)
218+
haz = deepcopy(HAZ)
219+
haz.centroids.to_crs(crs)
220+
icalc = ImpactCalc(exp, ENT.impact_funcs, haz)
221+
impact = icalc.impact()
222+
self.assertEqual(icalc.n_events, len(impact.at_event))
223+
self.assertEqual(0, impact.at_event[0])
224+
self.assertEqual(0, impact.at_event[7225])
225+
self.assertAlmostEqual(1.472482938320243e08, impact.at_event[13809], delta=1)
226+
self.assertAlmostEqual(7.076504723057620e10, impact.at_event[12147], delta=1)
227+
self.assertEqual(0, impact.at_event[14449])
228+
self.assertEqual(icalc.n_exp_pnt, len(impact.eai_exp))
229+
self.assertAlmostEqual(1.518553670803242e08, impact.eai_exp[0], delta=1)
230+
self.assertAlmostEqual(1.373490457046383e08, impact.eai_exp[25], 6)
231+
self.assertAlmostEqual(1.066837260150042e08, impact.eai_exp[49], 6)
232+
self.assertAlmostEqual(6.570532945599105e11, impact.tot_value)
233+
self.assertAlmostEqual(6.512201157564421e09, impact.aai_agg, 5)
234+
213235
def test_calc_impact_RF_pass(self):
214236
haz = Hazard.from_hdf5(get_test_file("test_hazard_US_flood_random_locations"))
215237
exp = Exposures.from_hdf5(
@@ -574,10 +596,13 @@ def test_single_exp_zero_mdr(self):
574596
eai_exp = np.array([aai_agg])
575597
at_event = np.array([imp_evt, 0])
576598
exp.set_geometry_points()
599+
exp.assign_centroids(haz, threshold=1)
577600
impf_tc = ImpfTropCyclone.from_emanuel_usa()
578601
impf_set = ImpactFuncSet([impf_tc])
579602
impf_set.check()
580-
imp = ImpactCalc(exp, impf_set, haz).impact(save_mat=True)
603+
imp = ImpactCalc(exp, impf_set, haz).impact(
604+
assign_centroids=False, save_mat=True
605+
)
581606
check_impact(self, imp, haz, exp, aai_agg, eai_exp, at_event, at_event)
582607

583608

climada/engine/unsequa/calc_cost_benefit.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ def _map_costben_calc(
398398
ent_future=ent_fut,
399399
save_imp=False,
400400
assign_centroids=False,
401-
**cost_benefit_kwargs
401+
**cost_benefit_kwargs,
402402
)
403403
# Extract from climada.impact the chosen metrics
404404
uncertainty_values.append(

climada/engine/unsequa/test/test_unsequa.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,7 @@ def test_calc_sensitivity_all_pass(self):
650650
}
651651

652652
def test_sensitivity_method(
653-
exp_unc, impf_unc, haz_unc, sensitivity_method, param_dict
653+
exp_unc, impf_unc, haz_unc, sensitivity_method, param_dict, places
654654
):
655655
"""Function to test each seaprate sensitivity method"""
656656
unc_calc = CalcImpact(exp_unc, impf_unc, haz_unc)
@@ -681,7 +681,7 @@ def test_sensitivity_method(
681681
self.assertAlmostEqual(
682682
param_dict["test_si_value"][0],
683683
unc_data.aai_agg_sens_df["aai_agg"][param_dict["test_si_value"][1]],
684-
places=5,
684+
places=places,
685685
)
686686

687687
self.assertEqual(unc_data.aai_agg_unc_df.size, unc_data.n_samples)
@@ -695,7 +695,12 @@ def test_sensitivity_method(
695695
# loop over each method and do test
696696
for sensitivity_method, method_params in test_dict.items():
697697
test_sensitivity_method(
698-
exp_unc, impf_unc, haz_unc, sensitivity_method, method_params
698+
exp_unc,
699+
impf_unc,
700+
haz_unc,
701+
sensitivity_method,
702+
method_params,
703+
places=2 if sensitivity_method == "rbd_fast" else 5,
699704
)
700705

701706

0 commit comments

Comments
 (0)