-
Notifications
You must be signed in to change notification settings - Fork 151
Risk Trajectory Split 4 : Non-interpolated (Static) trajectories #1200
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
spjuhel
wants to merge
47
commits into
develop
Choose a base branch
from
feature/static-risk-traj
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+2,632
−0
Open
Changes from all commits
Commits
Show all changes
47 commits
Select commit
Hold shift + click to select a range
a734bfa
cherrypick from risk_traj
spjuhel 6147507
Merge branch 'feature/interpolation-strategies' into feature/static-r…
spjuhel 245d13c
Merge branch 'feature/impact-computation-strategies' into feature/sta…
spjuhel 40f37b0
cherry pick, renaming
spjuhel 50ab78b
cherry picks __init__
spjuhel c0e5e55
Merge branch 'feature/impact-computation-strategies' into feature/sta…
spjuhel 6be5e6c
namespace fixes
spjuhel 0e99117
cherry picks dataframe handling
spjuhel dd63bf4
Introduces on/off option for caching
spjuhel a6932e8
removes redondant code
spjuhel 49e1cad
Clarifies docstring
spjuhel cc74d4a
Cherry picks tests
spjuhel 6bf3416
Initial data
spjuhel d44f377
Merge branch 'feature/common_test_fixtures' into feature/static-risk-…
spjuhel 7ec7db1
cleanups test
spjuhel 7349bc7
cleansup
spjuhel 2708f9a
Merge branch 'feature/common_test_fixtures' into feature/static-risk-…
spjuhel e01c330
Pylint compliance
spjuhel 1ec88bf
Fixes type hints
spjuhel 1511994
Merge branch 'feature/snapshots' into feature/static-risk-traj
spjuhel 595fb55
Merge branch 'feature/impact-computation-strategies' into feature/sta…
spjuhel 183783f
API references files
spjuhel 3a262c8
Merge branch 'feature/snapshots' into feature/static-risk-traj
spjuhel 3902daa
Merge branch 'feature/impact-computation-strategies' into feature/sta…
spjuhel ca8ca6e
Wrong merge somewhere pbly
spjuhel 46e089a
cleanup from wrong merge
spjuhel a9ebdb5
fixes type hint annoyance
spjuhel e69794f
Shifts tests to pytest
spjuhel 8941528
cleanup in tests
spjuhel 7e21455
Merge branch 'feature/snapshots' into feature/static-risk-traj
spjuhel 7a58d5b
Changes remaining test to pytest
spjuhel 7c818d7
Fixes inconsistencies with all_groups_name
spjuhel e83b768
idid for tests
spjuhel dea5796
Fixes from integration tests
spjuhel 5f96532
Merge branch 'feature/impact-computation-strategies' into feature/sta…
spjuhel bb08305
Fix discount rates
spjuhel 7b71918
Merge remote-tracking branch 'origin/develop' into feature/static-ris…
spjuhel ff12adf
Merge branch 'develop' into feature/static-risk-traj
spjuhel 8436fc4
Merge branch 'feature/snapshots' into feature/static-risk-traj
spjuhel 6b2b243
Merge branch 'feature/impact-computation-strategies' into feature/sta…
spjuhel 5dc47ce
Merge remote-tracking branch 'origin/develop' into feature/static-ris…
spjuhel e55a481
Updates tests
spjuhel 7a73c87
Implements Chahan's comments
spjuhel bcbdcd2
Fixes tests
spjuhel 5a04b1c
Merge remote-tracking branch 'origin/develop' into feature/static-ris…
spjuhel bf3dd58
Adds conftest, makes test more tractable
spjuhel 152f594
adds test for dataframe handling
spjuhel File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,205 @@ | ||
| """ | ||
| This file is part of CLIMADA. | ||
|
|
||
| Copyright (C) 2017 ETH Zurich, CLIMADA contributors listed in AUTHORS. | ||
|
|
||
| CLIMADA is free software: you can redistribute it and/or modify it under the | ||
| terms of the GNU General Public License as published by the Free | ||
| Software Foundation, version 3. | ||
|
|
||
| CLIMADA is distributed in the hope that it will be useful, but WITHOUT ANY | ||
| WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A | ||
| PARTICULAR PURPOSE. See the GNU General Public License for more details. | ||
|
|
||
| You should have received a copy of the GNU General Public License along | ||
| with CLIMADA. If not, see <https://www.gnu.org/licenses/>. | ||
| --- | ||
|
|
||
| A set of reusable objects for testing purpose. | ||
|
|
||
| The objective of this file is to provide minimalistic, understandable and consistent | ||
| default objects for unit and integration testing. | ||
|
|
||
| """ | ||
|
|
||
| import geopandas as gpd | ||
| import numpy as np | ||
| from scipy.sparse import csr_matrix | ||
| from shapely.geometry import Point | ||
|
|
||
| from climada.entity import Exposures, ImpactFunc, ImpactFuncSet | ||
| from climada.hazard import Centroids, Hazard | ||
| from climada.trajectories.snapshot import Snapshot | ||
|
|
||
| # --------------------------------------------------------------------------- | ||
| # Coordinate system and metadata | ||
| # --------------------------------------------------------------------------- | ||
| CRS_WGS84 = "EPSG:4326" | ||
|
|
||
| # --------------------------------------------------------------------------- | ||
| # Exposure attributes | ||
| # --------------------------------------------------------------------------- | ||
| EXP_DESC = "Test exposure dataset" | ||
| EXP_DESC_LATLON = "Test exposure dataset (lat/lon)" | ||
| EXPOSURE_REF_YEAR = 2020 | ||
| EXPOSURE_VALUE_UNIT = "USD" | ||
| VALUES = np.array([0, 1000, 2000, 3000]) | ||
| REGIONS = np.array(["A", "A", "B", "B"]) | ||
| CATEGORIES = np.array([1, 1, 2, 1]) | ||
|
|
||
| # Exposure coordinates | ||
| EXP_LONS = np.array([4, 4.5, 4, 4.5]) | ||
| EXP_LATS = np.array([45, 45, 45.5, 45.5]) | ||
|
|
||
| # --------------------------------------------------------------------------- | ||
| # Hazard definition | ||
| # --------------------------------------------------------------------------- | ||
| HAZARD_TYPE = "TEST_HAZARD_TYPE" | ||
| HAZARD_UNIT = "TEST_HAZARD_UNIT" | ||
|
|
||
| # Hazard centroid positions | ||
| HAZ_JITTER = 0.1 # To test centroid matching | ||
| HAZ_LONS = EXP_LONS + HAZ_JITTER | ||
| HAZ_LATS = EXP_LATS + HAZ_JITTER | ||
|
|
||
| # Hazard events | ||
| EVENT_IDS = np.array([1, 2, 3, 4]) | ||
| EVENT_NAMES = ["ev1", "ev2", "ev3", "ev4"] | ||
| DATES = np.array([1, 2, 3, 4]) | ||
|
|
||
| # Frequency are choosen so that they cumulate nicely | ||
| # to correspond to 100, 50, and 20y return periods (for impacts) | ||
| FREQUENCY = np.array([0.1, 0.03, 0.01, 0.01]) | ||
| FREQUENCY_UNIT = "1/year" | ||
|
|
||
| # Hazard maximum intensity | ||
| # 100 to match 0 to 100% idea | ||
| # also in line with linear 1:1 impact function | ||
| # for easy mental calculus | ||
| HAZARD_MAX_INTENSITY = 100 | ||
|
|
||
| # --------------------------------------------------------------------------- | ||
| # Impact function | ||
| # --------------------------------------------------------------------------- | ||
| IMPF_ID = 1 | ||
| IMPF_NAME = "IMPF_1" | ||
|
|
||
| # --------------------------------------------------------------------------- | ||
| # Future years | ||
| # --------------------------------------------------------------------------- | ||
| EXPOSURE_FUTURE_YEAR = 2040 | ||
|
|
||
|
|
||
| def reusable_minimal_exposures( | ||
| values=VALUES, | ||
| regions=REGIONS, | ||
| group_id=None, | ||
| lon=EXP_LONS, | ||
| lat=EXP_LATS, | ||
| crs=CRS_WGS84, | ||
| desc=EXP_DESC, | ||
| ref_year=EXPOSURE_REF_YEAR, | ||
| value_unit=EXPOSURE_VALUE_UNIT, | ||
| assign_impf=IMPF_ID, | ||
| increase_value_factor=1, | ||
| ) -> Exposures: | ||
| data = gpd.GeoDataFrame( | ||
| { | ||
| "value": values * increase_value_factor, | ||
| "region_id": regions, | ||
| f"impf_{HAZARD_TYPE}": assign_impf, | ||
| "geometry": [Point(lon, lat) for lon, lat in zip(lon, lat)], | ||
| }, | ||
| crs=crs, | ||
| ) | ||
| if group_id is not None: | ||
| data["group_id"] = group_id | ||
| return Exposures( | ||
| data=data, | ||
| description=desc, | ||
| ref_year=ref_year, | ||
| value_unit=value_unit, | ||
| ) | ||
|
|
||
|
|
||
| def reusable_intensity_mat(max_intensity=HAZARD_MAX_INTENSITY): | ||
| # Choosen such that: | ||
| # - 1st event has 0 intensity | ||
| # - 2nd event has max intensity in first exposure point (defaulting to 0 value) | ||
| # - 3rd event has 1/2* of max intensity in second centroid | ||
| # - 4th event has 1/4* of max intensity everywhere | ||
| # *: So that you can double intensity of the hazard and expect double impacts | ||
| return csr_matrix( | ||
| [ | ||
| [0, 0, 0, 0], | ||
| [max_intensity, 0, 0, 0], | ||
| [0, max_intensity / 2, 0, 0], | ||
| [ | ||
| max_intensity / 4, | ||
| max_intensity / 4, | ||
| max_intensity / 4, | ||
| max_intensity / 4, | ||
| ], | ||
spjuhel marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ] | ||
| ) | ||
|
|
||
|
|
||
| def reusable_minimal_hazard( | ||
| haz_type=HAZARD_TYPE, | ||
| units=HAZARD_UNIT, | ||
| lat=HAZ_LATS, | ||
| lon=HAZ_LONS, | ||
| crs=CRS_WGS84, | ||
| event_id=EVENT_IDS, | ||
| event_name=EVENT_NAMES, | ||
| date=DATES, | ||
| frequency=FREQUENCY, | ||
| frequency_unit=FREQUENCY_UNIT, | ||
| intensity=None, | ||
| intensity_factor=1, | ||
| ) -> Hazard: | ||
| intensity = reusable_intensity_mat() if intensity is None else intensity | ||
| intensity *= intensity_factor | ||
| return Hazard( | ||
| haz_type=haz_type, | ||
| units=units, | ||
| centroids=Centroids(lat=lat, lon=lon, crs=crs), | ||
| event_id=event_id, | ||
| event_name=event_name, | ||
| date=date, | ||
| frequency=frequency, | ||
| frequency_unit=frequency_unit, | ||
| intensity=intensity, | ||
| ) | ||
|
|
||
|
|
||
| def reusable_minimal_impfset( | ||
| hazard=None, name=IMPF_NAME, impf_id=IMPF_ID, max_intensity=HAZARD_MAX_INTENSITY | ||
| ): | ||
| hazard = reusable_minimal_hazard() if hazard is None else hazard | ||
| return ImpactFuncSet( | ||
| [ | ||
| ImpactFunc( | ||
| haz_type=hazard.haz_type, | ||
| intensity_unit=hazard.units, | ||
| name=name, | ||
| intensity=np.array([0, max_intensity / 2, max_intensity]), | ||
| mdd=np.array([0, 0.5, 1]), | ||
| paa=np.array([1, 1, 1]), | ||
| id=impf_id, | ||
| ) | ||
| ] | ||
| ) | ||
|
|
||
|
|
||
| def reusable_snapshot( | ||
| hazard_intensity_increase_factor=1, | ||
| exposure_value_increase_factor=1, | ||
| date=EXPOSURE_REF_YEAR, | ||
| ): | ||
| exposures = reusable_minimal_exposures( | ||
| increase_value_factor=exposure_value_increase_factor | ||
| ) | ||
| hazard = reusable_minimal_hazard(intensity_factor=hazard_intensity_increase_factor) | ||
| impfset = reusable_minimal_impfset() | ||
| return Snapshot(exposure=exposures, hazard=hazard, impfset=impfset, date=str(date)) | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What would happen with negative intensities? Probably easy to test using a negative intensity factor. Although then the reusable impact function set would need adjustments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that is beyond the scope of this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmmm when could this be done? Because negative intensities are valid in CLIMADA, and it would be quite problematic to break this without good reason.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll have a look.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, sorry I got confused actually, my initial comment on "this is beyond this PR" applies.
This PR has absolutely no impact on how negative intensities are handled by CLIMADA, it will work the same as before, we did not modify anything related to impact computation here, everything is just a wrapper.
I do have to check if interpolation cause problems with negative value (but that's split 5 not this one).
What also might change something is the option appraisal refactoring (next big project in line) which does change the
measuremodule, and hopefully fixes the problem mentioned by Chris in #1257.