Skip to content

Commit 366feb5

Browse files
committed
Merge branch 'develop' into feature/tutorial-review-impact-calculation
2 parents 75db94b + 6613632 commit 366feb5

31 files changed

+3425
-706
lines changed

.github/scripts/prepare_release.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
44
The following preparation steps are executed:
55
6-
- update version numbers in _version.py and setup.py
6+
- update version numbers in _version.py and pyproject.toml
77
- purge the "Unreleased" section of CHANGELOG.md and rename it to the new version number
88
99
All changes are immediately commited to the repository.
@@ -117,10 +117,10 @@ def update_version(nvn):
117117
return update_file(file_with_version, regex, nvn)
118118

119119

120-
def update_setup(new_version_number):
121-
"""Update the setup.py file"""
122-
file_with_version = "setup.py"
123-
regex = r"(^\s+version\s*=\s*[\'\"]).*([\'\"]\s*,\s*$)"
120+
def update_pyproject(new_version_number):
121+
"""Update the pyproject.toml file"""
122+
file_with_version = "pyproject.toml"
123+
regex = r"(^version\s*=\s*[\'\"]).*([\'\"]\s*$)"
124124
return update_file(file_with_version, regex, new_version_number)
125125

126126

@@ -211,7 +211,7 @@ def prepare_new_release(level):
211211
raise
212212
new_version_number = bump_version_number(last_version_number, level)
213213

214-
update_setup(new_version_number).gitadd()
214+
update_pyproject(new_version_number).gitadd()
215215
update_version(new_version_number).gitadd()
216216
update_changelog(new_version_number).gitadd()
217217

.github/scripts/setup_devbranch.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
44
The following preparation steps are executed:
55
6-
- update version numbers in _version.py and setup.py: append a -dev suffix
6+
- update version numbers in _version.py and pyproject.toml: append a -dev suffix
77
- insert a vanilla "unreleased" section on top of CHANGELOG.md
88
99
The changes are not commited to the repository. This is dealt with in the bash script
@@ -75,10 +75,10 @@ def update_version(nvn):
7575
return update_file(file_with_version, regex, nvn)
7676

7777

78-
def update_setup(new_version_number):
79-
"""Update the setup.py file"""
80-
file_with_version = "setup.py"
81-
regex = r"(^\s+version\s*=\s*[\'\"]).*([\'\"]\s*,\s*$)"
78+
def update_pyproject(new_version_number):
79+
"""Update the pyproject.toml file"""
80+
file_with_version = "pyproject.toml"
81+
regex = r"(^version\s*=\s*[\'\"]).*([\'\"]\s*$)"
8282
return update_file(file_with_version, regex, new_version_number)
8383

8484

@@ -110,7 +110,7 @@ def setup_devbranch():
110110
semver[-1] = f"{int(semver[-1]) + 1}-dev"
111111
dev_version = ".".join(semver)
112112

113-
update_setup(dev_version)
113+
update_pyproject(dev_version)
114114
update_version(dev_version)
115115
update_changelog()
116116

.github/scripts/setup_devbranch.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@ git checkout develop
1010
git pull
1111

1212
git checkout origin/main \
13-
setup.py \
13+
pyproject.toml \
1414
CHANGELOG.md \
1515
*/_version.py
1616

1717
release=`python .github/scripts/setup_devbranch.py`
1818

1919
git add \
20-
setup.py \
20+
pyproject.toml \
2121
CHANGELOG.md \
2222
*/_version.py
2323

.github/workflows/make-release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# This workflow will create a new release from main
22

33
# the new version number is the old one increased by 1 in the given level [major, minor, patch]
4-
# first, some files are modified (_version.py, setup.py and CHANGELOG.md
4+
# first, some files are modified (_version.py, pyproject.toml and CHANGELOG.md
55
# then, a new release is created on GitHub, tagged with v[new version number]
66

77
name: Create a new release

.github/workflows/postrelease-setup-devbranch.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# This workflow will re-initialize the develop branch after a release was published
22

3-
# the version number of setup.py and _version.py will be taken from main, but have a "-dev" appendix
3+
# the version number of pyproject.toml and _version.py will be taken from main, but have a "-dev" appendix
44
# the CHANGELOG.md file will be updated and have a vanila "Unreleased" section
55

66
name: Post-release develop setup

.readthedocs.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,3 @@ python:
2525

2626
formats:
2727
- pdf
28-
29-
sphinx:
30-
configuration: doc/conf.py

CHANGELOG.md

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,30 @@ Code freeze date: YYYY-MM-DD
1212

1313
Added:
1414

15+
- `bayesian-optimization` >=1.5,<2.0
16+
- `deprecation` >=2.1
1517
- `fiona` >=1.10
18+
- `peewee` >=3.17
19+
- `pyarrow` >=20.0
1620

1721
Updated:
1822

19-
- `geopandas` >=0.14,<1.0 → >=0.14
20-
- `pandas` >=2.1,<2.2 → >=2.1
23+
- `bayesian-optimization` =1.5 &rarr; nan
24+
- `bottleneck` >=1.4 &rarr; >=1.5
25+
- `dask` >=2025.2 &rarr; >=2025.5
26+
- `deprecation` =2.1 &rarr; nan
27+
- `eccodes` >=2.40 &rarr; >=2.41
28+
- `geopandas` >=0.14,<1.0 &rarr; >=0.14
29+
- `h5py` >=3.12 &rarr; >=3.13
30+
- `openpyxl` >=3.1 &rarr; >=3.0
31+
- `pandas` >=2.1,<2.2 &rarr; >=2.1
32+
- `peewee` =3.17 &rarr; nan
33+
- `pillow` =11.1 &rarr; =11.3
34+
- `rtree` >=1.3,<1.4 &rarr; >=1.3
35+
- `scikit-learn` >=1.6 &rarr; >=1.7
36+
- `scipy` >=1.14,<1.15 &rarr; >=1.14
37+
- `sparse` >=0.15 &rarr; >=0.17
38+
- `xarray` >=2025.1 &rarr; >=2025.6
2139

2240
Removed:
2341

@@ -30,8 +48,11 @@ Removed:
3048
- 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)
3149
- 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)
3250
- `ImpactFunc` and `ImpactFuncSet` now support equality comparisons via `==` [#1027](https://github.com/CLIMADA-project/climada_python/pull/1027)
51+
- Calibration of impact function ensembles in `climada.util.calibrate` [#1048](https://github.com/CLIMADA-project/climada_python/pull/1048)
52+
- Added optional `attrs` parameter to `Exposures.from_raster` method to set additional object properties through the method's `Exposures.__init__` call.
3353

3454
### Changed
55+
3556
- 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).
3657
- 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)
3758
- 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)
@@ -43,8 +64,10 @@ geographic coordinates as input (e.g. `util.coordinates.dist_to_coast`, `util.co
4364
- 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)
4465
- `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)
4566
- The online documentation has been completely overhauled, now uses PyData theme: [#977](https://github.com/CLIMADA-project/climada_python/pull/977)
67+
- `Input` to impact function calibration tasks now supports adding weights to the data [#1048](https://github.com/CLIMADA-project/climada_python/pull/1048)
4668
- 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)
4769
- 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)
70+
- `util.coordinates.get_resolution` always returns positive values, regardless of how the input coordinates' order [#1080](https://github.com/CLIMADA-project/climada_python/pull/1080).
4871

4972
### Fixed
5073

climada/engine/unsequa/calc_base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,7 @@ def _calc_sens_df(method, problem_sa, sensitivity_kwargs, param_labels, X, unc_d
605605
).ravel()
606606
sens_second_order_dict[submetric_name] = sens_second_order
607607

608-
sens_first_order_df = pd.DataFrame(sens_first_order_dict, dtype=np.number)
608+
sens_first_order_df = pd.DataFrame(sens_first_order_dict, dtype=float)
609609

610610
if not sens_first_order_df.empty:
611611
si_names_first_order, param_names_first_order = _si_param_first(

climada/entity/exposures/base.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,7 @@ def from_raster(
723723
width=None,
724724
height=None,
725725
resampling=Resampling.nearest,
726+
attrs=None,
726727
):
727728
"""Read raster data and set latitude, longitude, value and meta
728729
@@ -750,11 +751,15 @@ def from_raster(
750751
resampling : rasterio.warp,.Resampling optional
751752
resampling
752753
function used for reprojection to dst_crs
754+
attrs : dict
755+
dictionary of kwargs passed to the resulting Exposures.__init__
753756
754757
returns
755758
--------
756759
Exposures
757760
"""
761+
attrs = attrs or {}
762+
758763
meta, value = u_coord.read_raster(
759764
file_name,
760765
[band],
@@ -781,6 +786,7 @@ def from_raster(
781786
},
782787
meta=meta,
783788
crs=meta["crs"],
789+
**attrs,
784790
)
785791

786792
def plot_scatter(

climada/entity/exposures/litpop/gpw_population.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
import numpy as np
2525
import rasterio
26+
from affine import Affine
2627

2728
from climada import CONFIG
2829
from climada.util.constants import SYSTEM_DIR
@@ -171,3 +172,53 @@ def get_gpw_file_path(gpw_version, reference_year, data_dir=None, verbose=True):
171172
f" different folder. The data can be downloaded from {sedac_browse_url}, e.g.,"
172173
f" {sedac_file_url} (Free NASA Earthdata login required)."
173174
)
175+
176+
177+
def grid_aligned_with_gpw(reference_year, gpw_version, res_arcsec, data_dir=SYSTEM_DIR):
178+
"""
179+
Defines a grid based on population metadata.
180+
181+
Parameters
182+
----------
183+
reference_year : int
184+
The reference year for population and nightlight data.
185+
gpw_version : int
186+
Version number of GPW population data.
187+
res_arcsec : int or None
188+
Desired resolution in arcseconds. If None, aligns to population grid.
189+
data_dir : str
190+
Path to input data directory.
191+
192+
Returns
193+
-------
194+
grid : dict
195+
A dictionary containing grid metadata, following the raster grid
196+
specification.
197+
"""
198+
res_deg = res_arcsec / 3600
199+
200+
file_path = get_gpw_file_path(
201+
gpw_version, reference_year, data_dir=data_dir, verbose=False
202+
)
203+
with rasterio.open(file_path, "r") as src:
204+
global_crs = src.crs
205+
gpw_transform = src.transform
206+
# Align grid resolution with GPW dataset
207+
aligned_lon_min = -180 + (round((gpw_transform[2] - (-180)) / res_deg) * res_deg)
208+
aligned_lat_max = 90 - (round((90 - gpw_transform[5]) / res_deg) * res_deg)
209+
210+
global_transform = Affine(res_deg, 0, aligned_lon_min, 0, -res_deg, aligned_lat_max)
211+
212+
global_width = round(360 / res_deg)
213+
global_height = round(180 / res_deg)
214+
215+
# Define the target grid using the computed values
216+
return {
217+
"driver": "GTiff",
218+
"dtype": "float32",
219+
"nodata": None,
220+
"crs": global_crs,
221+
"width": global_width,
222+
"height": global_height,
223+
"transform": global_transform,
224+
}

0 commit comments

Comments
 (0)