[Option Appraisal Module] [Package 1: Measures] Split 1: Adds MeasureConfig dataclasses for serializable measure configuration.#1276
Conversation
|
Excellent idea! |
Cleans-up, Docstringfies Better to_dict, color parser, and post_inits Removes duplicate docstring
…MADA-project/climada_python into feature/option-appraisal-dataclasses
MeasureConfig dataclasses for serializable measure configuration.MeasureConfig dataclasses for serializable measure configuration.
|
Question: Should measures (defined by Currently, they are specific (thus configs require you to provide I see how you could want modifications of impact function to be for multiple hazards Any opinion on that? |
|
This PR is officially open for review! Review is advised after #1274 is merged. Actual changes to be reviewed are in:
|
Good question. I would then to keep it hazard type specific. But maybe best is to ask core users of the model :). |
peanutfun
left a comment
There was a problem hiding this comment.
I reviewed mostly on a technical level. Very nice code quality overall, nice class structure! I found a few issues. Sorry for the brevity 😬 ✌️
Co-authored-by: Lukas Riedel <34276446+peanutfun@users.noreply.github.com>
…e/option-appraisal-dataclasses
…raisal-dataclasses
|
@ValentinGebhart This has been reviewed on the technical aspects. Can you give a look at the guide here and tell me if its clear enough? Note: The "measure tutorial" link at the end does not work yet and is a placeholder. |
ValentinGebhart
left a comment
There was a problem hiding this comment.
Thanks for this very clear tutorial! I added only a few rephrasings and some comments at points where I thought it was not perfectly clear. However all are only minor things, and I find the explanations very clear about how to define the MeasureConfigs.
| "\n", | ||
| "CLIMADA uses `Measure` objects to model the effects of adaptation measures. `Measure` objects were formerly defined declaratively (via for instance, a shifting or scaling of the hazard intensity or a change of impact function), and are now defined as python functions to enable more flexibility on the possible changes (see the [tutorial on measure objects](measure-tutorial)'). \n", | ||
| "\n", | ||
| "The caveat of defining measure effects as python functions is that it cannot be serialized (written to a file), and also makes reading from a file a challenge.\n", |
There was a problem hiding this comment.
Is it really impossible to save python functions? That means that measures that do not correspond to MeasureConfigs cannot be saved?
| "\n", | ||
| "The caveat of defining measure effects as python functions is that it cannot be serialized (written to a file), and also makes reading from a file a challenge.\n", | ||
| "\n", | ||
| "In order to close that gap, the `measure` module now ships `MeasureConfig` objects, which handle the reading, writing and \"declarative\" defining of `Measure` objects.\n", |
There was a problem hiding this comment.
If I understood correctly, this sounds a bit misleading, as if MeasureConfig handle reading and writing of ALL Measure objects, while actually they can only read and write those that correspond to MeasureConfig objects, right?
Maybe rephrase to
"which can be read from and written to files, and which enable a "declarative" defining of Measure objects."
| "- `ExposuresModifierConfig`: Modifies exposure data (e.g., reassigning IDs or zeroing regions).\n", | ||
| "- `CostIncomeConfig`: Handles the financial aspects, including initial costs and recurring income.\n", | ||
| "\n", | ||
| "Note that everything can be defined and accessed directly from the `MeasureConfig` container, the underlying ones are there to keep things organized.\n", |
There was a problem hiding this comment.
On first reading the meaning was not super clear to me. Maybe rephrase to
"Note that all effects of a MeasureConfig object can be directly defined using the MeasureConfig container, the underlying ones are there to keep things organized.
| "| **Hazard** | `haz_int_mult` | `float` | Multiplier for hazard intensity (default: 1.0). |\n", | ||
| "| | `haz_int_add` | `float` | Additive offset for hazard intensity (default: 0.0). |\n", | ||
| "| | `new_hazard_path` | | Path to an HDF5 file to replace the current hazard. |\n", | ||
| "| | `impact_rp_cutoff` | `float` | Return period (years) threshold; events below this are ignored. |\n", |
There was a problem hiding this comment.
| "| | `impact_rp_cutoff` | `float` | Return period (years) threshold; events below this are ignored. |\n", | |
| "| | `impact_rp_cutoff` | `float` | Return period (years) threshold; events with impacts below this threshold are ignored. |\n", |
| " 0,\n", | ||
| " 25,\n", | ||
| " 78,\n", | ||
| " ], # Sets the value of exposure points with index 0, 25 and 78 to 0.\n", |
There was a problem hiding this comment.
This seems in conflict to what you wrote above. Here it sounds that you set to zero exposure points with specific index values, above it sounds that you set to zero exposure points with specific region_ids ("List of Region IDs where exposure value is set to 0."
| " 0,\n", | ||
| " 25,\n", | ||
| " 78,\n", | ||
| " ], # Sets the value of exposure points with index 0, 25 and 78 to 0.\n", |
There was a problem hiding this comment.
This seems in conflict to what you wrote above. Here it sounds that you set to zero exposure points with specific index values, above it sounds that you set to zero exposure points with specific region_ids ("List of Region IDs where exposure value is set to 0."
| " cost_yearly_growth_rate=0.02,\n", | ||
| " periodic_income=100_000.0,\n", | ||
| " income_yearly_growth_rate=0.03,\n", | ||
| " freq=\"Y\",\n", |
There was a problem hiding this comment.
The freq attribute is not shown in the below print, and it not entirely clear to me what it does. Above, it is written "frequecy of cash flows". That means that if one uses, e.g., freq="2Y", the growth rates etc are still yearly but the the costs and incomes occur only every two years?
| "custom_schedule = [\n", | ||
| " {\"date\": \"2024-01-01\", \"value\": -1000000}, # Initial cost\n", | ||
| " {\"date\": \"2029-01-01\", \"value\": -200000}, # Mid-term overhaul\n", | ||
| " {\"date\": \"2034-01-01\", \"value\": 500000}, # Terminal value\n", |
There was a problem hiding this comment.
Maybe clarify what negative and positive values are, and above cost were given as positive values. I assume here negative values are one-time costs and negative values are one-time incomes?
| "- Applying a cutoff on frequency based on impacts: via `impact_rp_cutoff` (see the note).\n", | ||
| "\n", | ||
| "```{note}\n", | ||
| "Providing a value for `impact_rp_cutoff` \"removes\" (it sets their intensity to 0.) events from the hazard, for which the exceedance frequency (inverse of return period) of impacts is below the given threshold.\n", |
There was a problem hiding this comment.
I was actually wondering about this one: AFAIK you want to have each measure consist of three functions that modify each of the risk components. This parameter however looks like it takes into account all hazard, vulnerability and exposure, as it looks at the impacts per event, which seems a bit confusing with the three function structure. My main question is if this cutoff is applied at the start (computing the impact events to be excluded before applying all other stuff), or at the end (after all other effect were taken into account)?
Changes proposed in this PR:
This PR introduces a new module defining a family of dataclasses that encode adaptation measure parameters in a serializable, declarative form. This is a preparatory step for the broader
Measure/MeasureSetrework.The objective is to retain the possibility to define measures from modifiers in addition to the upcoming system that will use python functions directly, and provide a (better) user interface for this.
no existing code is changed.
New dataclasses:
MeasureConfigtop-level configuration for a single measure, aggregating all modifier configs below.ImpfsetModifierConfigparameters for modifying impact functions (intensity, MDD, PAA scaling, optional replacement)HazardModifierConfigparameters for modifying hazard (intensity scaling, frequency cutoff, optional replacement)ExposuresModifierConfigparameters for modifying exposures (impact function remapping, zeroing regions, optional replacement)CostIncomeConfigserializable representation of cost/income cash flow parametersAll configs inherit from the abstract
_ModifierConfigbase, which provides sharedto_dict/from_dictand a__repr__that highlights non-default fields.MeasureConfigsupports full serialization to/from dict, YAML, and legacy Excel rows (from_row), which will serve as the migration path for the existing file-based I/O inMeasureSet.PR Author Checklist
develop)PR Reviewer Checklist