Skip to content

[Option Appraisal Module] [Package 1: Measures] Split 3: Adds new base Measure class - #1279

Draft
spjuhel wants to merge 60 commits into
developfrom
feature/option-appraisal-new-measure-base
Draft

spjuhel wants to merge 60 commits into
developfrom
feature/option-appraisal-new-measure-base

Conversation

@spjuhel

@spjuhel spjuhel commented Apr 8, 2026

Copy link
Copy Markdown
Collaborator

Changes proposed in this PR:

This PR brings the basis of the refactored Measure class, using closures (functions that return a function) to define the effects of a measure.

Important points:

  • Effects are separated by effects on Exposures, effects on Impfset, and on Hazard
  • The closures need to accept keyword arguments to enable effects that rely on something else than what the effect is applied on (i.e. year, other part of risk, etc...)
  • We always pass the Exposures, Impfset and Hazard objects as kwargs to the closures by default
  • We pass user-defined function through an allow_kwargs to make sure closures always accept kwargs.
  • Measure instances optionally have a _config attribute that contains a MeasureConfig if the measure was defined from such an object (and is therefore serializable).

PR Author Checklist

PR Reviewer Checklist

spjuhel added 30 commits April 7, 2026 09:34

@ValentinGebhart ValentinGebhart left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new implementation of the measures looks super cool :) I think it is much cleaner and user-friendly to before! I just commented whenever something was unclear to me. I haven't had time to check the working of the functions with actual data yet , e.g. for some consistency checks.

The only one more conceptual question I have is if you have to work with the (hidden) base_exposure, base_hazard, base_impfunc handling, but maybe I have not understood yet why these can be useful. Happy to discuss!

Note that I first read the tutorial without knowing the code to just check if I understand the usage. Some of the comments there might not be there know after I read the code :)

Comment thread doc/user-guide/climada_measures.ipynb Outdated
Comment thread doc/user-guide/climada_measures.ipynb Outdated
Comment thread doc/user-guide/climada_measures.ipynb
Comment thread doc/user-guide/climada_measures.ipynb Outdated
Comment thread doc/user-guide/climada_measures.ipynb Outdated
Comment thread climada/entity/measures/measure.py Outdated
Comment thread climada/entity/measures/measure.py Outdated
Comment thread climada/entity/measures/measure.py Outdated
Comment thread climada/entity/measures/measure.py Outdated
Comment thread climada/entity/measures/test/test_measure.py
@spjuhel

spjuhel commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator Author

This new implementation of the measures looks super cool :) I think it is much cleaner and user-friendly to before! I just commented whenever something was unclear to me. I haven't had time to check the working of the functions with actual data yet , e.g. for some consistency checks.

The only one more conceptual question I have is if you have to work with the (hidden) base_exposure, base_hazard, base_impfunc handling, but maybe I have not understood yet why these can be useful. Happy to discuss!

Note that I first read the tutorial without knowing the code to just check if I understand the usage. Some of the comments there might not be there know after I read the code :)

Thanks for these comments.

Answering the conceptual question about the base_X arguments. (see also #1279 (comment)):

The idea comes from the fact that I assume there is a whole range of adaptation options effect on Hazard|Exposures|Impfset where you have to use some information in your base exposures, hazard or impfset.

But it is a bit "advanced" to write for instance (ellipsed/simplified):

def my_effect_on_exposures(exposures, req_hazard):
    indices = req_hazard > 10
    exposures.gdf.loc[indices,"value"] *= 0.98
    
measure_a = Measure(..., exposure_change=my_effect_on_exposures)

exp, impf, haz = measure.apply(exp, impf, haz, kwarg_exposures = {req_hazard: haz}) # That part is slightly scary

By always providing base_Hazard|Exposures|Impfset, you can "simplify":

def my_effect_on_exposures(exposures, base_hazard): # note that the name need to be base_hazard!
    indices = base_hazard > 10
    exposures.gdf.loc[indices,"value"] *= 0.98
    
measure_a = Measure(..., exposure_change=my_effect_on_exposures)

exp, impf, haz = measure.apply(exp, impf, haz) # Scary kwargs are gone!

On this small example it may seem not much, but if the three effects all rely on the three components then it is way more relevant.

I agree the current explanations in the docs might be improved ;D

Comment thread climada/entity/measures/measure.py Outdated
Comment thread climada/entity/measures/measure.py Outdated
Comment thread climada/entity/measures/measure.py
Comment thread climada/entity/measures/measure.py Outdated
Comment thread climada/entity/measures/measure.py
spjuhel and others added 9 commits October 14, 2026 17:30
Co-authored-by: Samuel Juhel <10011382+spjuhel@users.noreply.github.com>
commit 45f8885
Merge: 6ba1f6f 720b31d
Author: spjuhel <pro@sjuhel.org>
Date:   Wed Oct 14 17:14:18 2026 +0200

    Merge branch 'feature/option-appraisal-costincome' of github.com:CLIMADA-project/climada_python into feature/option-appraisal-costincome

commit 6ba1f6f
Author: spjuhel <pro@sjuhel.org>
Date:   Wed Oct 14 17:13:25 2026 +0200

    fixes tests

commit d2d891f
Author: spjuhel <pro@sjuhel.org>
Date:   Wed Oct 14 17:10:24 2026 +0200

    other minor fixes

commit bf7fb2e
Author: spjuhel <pro@sjuhel.org>
Date:   Wed Oct 14 16:50:52 2026 +0200

    Fixes some linter issues, removes datetime

commit b5da6bf
Author: spjuhel <pro@sjuhel.org>
Date:   Wed Oct 14 16:13:40 2026 +0200

    Tuple -> tuple

commit 720b31d
Merge: d5778d9 c0fcc8d
Author: emanuel-schmid <schmide@ethz.ch>
Date:   Wed Sep 23 17:57:36 2026 +0200

    Merge branch 'develop' into feature/option-appraisal-costincome

commit c0fcc8d
Author: Lukas Riedel <34276446+peanutfun@users.noreply.github.com>
Date:   Tue Sep 22 16:13:26 2026 +0200

    Fix exposure coordinate extraction for `CalcDeltaImpact` (#1304)

    * Use final exposure for centroid coords

    * Fix querying exposure coords in CalcDeltaImpact

    ---------

    Co-authored-by: emanuel-schmid <schmide@ethz.ch>

commit b158053
Author: Lukas Riedel <34276446+peanutfun@users.noreply.github.com>
Date:   Tue Sep 15 16:49:20 2026 +0200

    Trigger pipeline for pull requests (#1318)

    * Trigger pipeline for pull requests and pushes to main, develop, releases.
    * Add info on approving workflow runs to CONTRIBUTING.md

commit dea46fa
Author: emanuel-schmid <schmide@ethz.ch>
Date:   Fri Sep 4 11:03:56 2026 +0200

    pin rasterio to 1.4

commit 4f4a1bd
Author: emanuel-schmid <schmide@ethz.ch>
Date:   Thu Sep 3 19:33:41 2026 +0200

    remove noaa nightlight test

commit 697e8d6
Author: EnvDroneSense <thomas.remote.sensing@outlook.com>
Date:   Wed Sep 2 14:56:20 2026 +0200

    Compute forecast quantiles block-wise to bound memory (#1313)

    Add `sparse_quantile_axis0` to densify sparse matrices blockwise
    before computing the column quantiles.

    ---------

    Co-authored-by: Lukas Riedel <34276446+peanutfun@users.noreply.github.com>

commit 9efa386
Author: emanuel-schmid <schmide@ethz.ch>
Date:   Fri Aug 28 17:42:20 2026 +0200

    fix damage

commit 05481fd
Author: Lukas Riedel <34276446+peanutfun@users.noreply.github.com>
Date:   Fri Aug 28 16:27:33 2026 +0200

    Upgrade GitHub Actions and Python versions (#1281)

    * Upgrade actions and Python versions

    Python 3.11 to 3.13.

    * Upgrade Python version in pyproject.toml

    * docs: Update supported versions

    * pin pandas

    ---------

    Co-authored-by: emanuel-schmid <schmide@ethz.ch>

commit 6b921e3
Merge: 6c7e3c8 bd6b09a
Author: emanuel-schmid <schmide@ethz.ch>
Date:   Fri Aug 28 13:40:30 2026 +0200

    Merge branch 'develop' of github.com:CLIMADA-project/climada_python into develop

commit bd6b09a
Author: ankurmahiwal118028 <mahiinfo10@gmail.com>
Date:   Fri Aug 28 17:08:07 2026 +0530

    Fix #814: raise clear error for empty Hazard in ImpactCalc.impact (#1290)

    * Raise clear error for empty Hazard in ImpactCalc.impact

    Computing impact with a Hazard containing zero events previously
    crashed deep inside ``np.array_split`` with the obscure message
    "number sections must be larger than 0". This adds an early guard
    in ``ImpactCalc.impact`` that raises a ``ValueError`` with a clear
    explanation when ``self.hazard.size == 0``.

    Closes #814

    * Update climada/engine/test/test_impact_calc.py

    Co-authored-by: Lukas Riedel <34276446+peanutfun@users.noreply.github.com>

    ---------

    Co-authored-by: Samuel Juhel <10011382+spjuhel@users.noreply.github.com>
    Co-authored-by: Emanuel Schmid <51439563+emanuel-schmid@users.noreply.github.com>
    Co-authored-by: Lukas Riedel <34276446+peanutfun@users.noreply.github.com>

commit 6c7e3c8
Merge: 54d100c ca00465
Author: emanuel-schmid <schmide@ethz.ch>
Date:   Fri Aug 28 13:33:06 2026 +0200

    Merge branch 'develop' of github.com:CLIMADA-project/climada_python into develop

commit ca00465
Author: Emanuel Schmid <51439563+emanuel-schmid@users.noreply.github.com>
Date:   Fri Aug 28 13:32:17 2026 +0200

    fix future warning: H is deprecated (#1307)

    * use h (H is deprecated)

    * add comment to affine pin

commit a694663
Author: Emanuel Schmid <51439563+emanuel-schmid@users.noreply.github.com>
Date:   Fri Aug 28 13:31:06 2026 +0200

    fix fiona deprecation warning (#1308)

    * remove obsolete DEF_CRS_FIONA

    * add comment to affine pin

commit 54d100c
Merge: 5b03edb d2af313
Author: emanuel-schmid <schmide@ethz.ch>
Date:   Fri Aug 28 13:05:56 2026 +0200

    Merge branch 'develop' of github.com:CLIMADA-project/climada_python into develop

commit d2af313
Author: Giovanni Cozzolongo <79092266+giovannicozzolongo@users.noreply.github.com>
Date:   Thu Aug 20 11:24:41 2026 +0200

    Read forecast dates from xarray (#1310)

    Preserve explicitly mapped date variables in
    HazardForecast.from_xarray_raster.

commit 5b03edb
Author: emanuel-schmid <schmide@ethz.ch>
Date:   Wed Aug 19 11:02:31 2026 +0200

    add comment to affine pin

commit 80a2975
Author: emanuel-schmid <schmide@ethz.ch>
Date:   Wed Aug 19 10:36:03 2026 +0200

    dependencies: pin affine to 2.4

commit 8100a31
Author: Lukas Riedel <34276446+peanutfun@users.noreply.github.com>
Date:   Wed Jul 15 12:18:41 2026 +0200

    Use Zenodo for downloading distance to coastline dataset (#1301)

commit cf0aa86
Author: Lukas Riedel <34276446+peanutfun@users.noreply.github.com>
Date:   Mon Jul 13 16:22:25 2026 +0200

    Handle 0-dim arrays being passed to ordinal converter (#1300)

commit 222a6e5
Author: emanuel-schmid <schmide@ethz.ch>
Date:   Fri Jun 19 16:11:18 2026 +0200

    pin matplotlib to 3.10

commit 5d0a985
Author: Lukas Riedel <34276446+peanutfun@users.noreply.github.com>
Date:   Wed Jun 17 11:23:05 2026 +0200

    Update installation guide (#1296)

    * Fix formatting errors.
    * Move switching branches to FAQ.
    * Fix some links.

commit d5778d9
Merge: a56dcc6 7094124
Author: spjuhel <pro@sjuhel.org>
Date:   Wed Jun 10 15:13:21 2026 +0200

    Merge remote-tracking branch 'origin/develop' into feature/option-appraisal-costincome

commit 7094124
Author: Lukas Riedel <34276446+peanutfun@users.noreply.github.com>
Date:   Wed Jun 10 11:55:53 2026 +0200

    Fix README links and update structure (#1101)

    * Fix README links and structure
    * Improve petals description

    ---------

    Co-authored-by: emanuel-schmid <schmide@ethz.ch>
    Co-authored-by: Chahan M. Kropf <chahan.kropf@usys.ethz.ch>
    Co-authored-by: Lukas Riedel <34276446+peanutfun@users.noreply.github.com>

commit a1e7107
Author: Lukas Riedel <34276446+peanutfun@users.noreply.github.com>
Date:   Wed Jun 10 11:31:14 2026 +0200

    Add forecast classes (#1115)

    * Add HazardForecast and ImpactForecast classes.
    * Add tests.
    * Add new forecast tutorial.

    ---------

    Co-authored-by: Evelyn Mühlhofer <42063186+Evelyn-M@users.noreply.github.com>
    Co-authored-by: Luca Severino <91593121+luseverin@users.noreply.github.com>
    Co-authored-by: Valentin Gebhart <60438839+ValentinGebhart@users.noreply.github.com>
    Co-authored-by: Chahan M. Kropf <chahan.kropf@usys.ethz.ch>
    Co-authored-by: Chahan Kropf <chahan.kropf@posteo.com>
    Co-authored-by: elianekobler <138141646+elianekobler@users.noreply.github.com>

commit a56dcc6
Author: spjuhel <pro@sjuhel.org>
Date:   Wed Jun 10 09:50:52 2026 +0200

    removes tests for removed method

commit 7e30183
Merge: dd9c738 a99b10b
Author: spjuhel <pro@sjuhel.org>
Date:   Wed Jun 10 09:36:03 2026 +0200

    Merge remote-tracking branch 'origin/develop' into feature/option-appraisal-costincome

commit a99b10b
Merge: 805e2da aae360f
Author: Samuel Juhel <10011382+spjuhel@users.noreply.github.com>
Date:   Wed Jun 10 09:33:31 2026 +0200

    MeasureConfig dataclasses

    [Option Appraisal Module] [Package 1: Measures] Split 1: Adds `MeasureConfig` dataclasses for serializable measure configuration.

commit aae360f
Merge: 92990e4 a423c78
Author: spjuhel <pro@sjuhel.org>
Date:   Wed Jun 10 09:12:00 2026 +0200

    Merge remote-tracking branch 'origin/develop' into feature/option-appraisal-dataclasses

commit 805e2da
Author: Emanuel Schmid <51439563+emanuel-schmid@users.noreply.github.com>
Date:   Mon Jun 8 16:08:27 2026 +0200

    Docs/pixi installation (#1295)

    * first draft

    * improvments

    * notice about windows

    * make installation instructions more concise, add comments

    * layout corrections

    * improve section order

commit dd9c738
Author: spjuhel <pro@sjuhel.org>
Date:   Fri May 29 11:59:34 2026 +0200

    Adds test for custom cost incomes and cash flow computation

commit f191980
Merge: d09d18f a423c78
Author: spjuhel <pro@sjuhel.org>
Date:   Fri May 29 10:11:15 2026 +0200

    Merge remote-tracking branch 'origin/develop' into feature/option-appraisal-costincome

commit 92990e4
Merge: 8a4d13b 5ae3f7f
Author: spjuhel <pro@sjuhel.org>
Date:   Fri May 29 10:10:34 2026 +0200

    Merge remote-tracking branch 'origin/develop' into feature/option-appraisal-dataclasses

commit 8a4d13b
Author: spjuhel <pro@sjuhel.org>
Date:   Fri May 29 10:10:06 2026 +0200

    updates notebook outputs

commit 6ef99a2
Author: spjuhel <pro@sjuhel.org>
Date:   Fri May 29 10:09:14 2026 +0200

    Updates custom cash flow values

commit d09d18f
Author: spjuhel <pro@sjuhel.org>
Date:   Fri May 29 10:01:30 2026 +0200

    Removes method not in use

commit 3165652
Author: spjuhel <pro@sjuhel.org>
Date:   Fri May 29 09:57:37 2026 +0200

    Removes double checks

commit dc29f9b
Author: spjuhel <pro@sjuhel.org>
Date:   Thu May 28 16:55:16 2026 +0200

    Implement somes comments from Vale

commit ee1e854
Author: spjuhel <pro@sjuhel.org>
Date:   Thu May 28 16:06:58 2026 +0200

    idem

commit 1264c8e
Author: spjuhel <pro@sjuhel.org>
Date:   Thu May 28 15:59:51 2026 +0200

    Implements comments from Vale

commit 991562d
Author: Valentin Gebhart <valentin.gebhart@usys.ethz.ch>
Date:   Fri May 22 08:15:13 2026 +0200

    some typos and rephrasing

commit 3e8c51a
Merge: 044b7f4 3133447
Author: spjuhel <pro@sjuhel.org>
Date:   Wed May 13 14:47:26 2026 +0200

    Merge remote-tracking branch 'origin/develop' into feature/option-appraisal-costincome

commit 044b7f4
Merge: 2ee944b 2b19cf8
Author: spjuhel <pro@sjuhel.org>
Date:   Wed May 13 14:43:27 2026 +0200

    Merge branch 'develop' into feature/option-appraisal-costincome

commit 7803112
Merge: 0423a6f 3133447
Author: spjuhel <pro@sjuhel.org>
Date:   Wed May 13 14:27:52 2026 +0200

    Merge remote-tracking branch 'origin/develop' into feature/option-appraisal-dataclasses
@spjuhel

spjuhel commented Oct 15, 2026

Copy link
Copy Markdown
Collaborator Author

@ValentinGebhart : I think I addressed all remaining comments, and I've added a few more advanced examples to the guide. (Of course we can extend even more, but I think that's enough for now)

@chahank, @emanuel-schmid @peanutfun Can you have a quick code-owner look?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants