-
Notifications
You must be signed in to change notification settings - Fork 132
Add functions to compute, plot, store the local hazard exceedence intensity and RP maps (new branch) #898
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
Add functions to compute, plot, store the local hazard exceedence intensity and RP maps (new branch) #898
Changes from 6 commits
1e91def
e7a5913
81dc151
f5c3d4e
c588124
0711526
1b29f1f
24ba039
d79b670
f228918
5198646
fe99121
8dc544f
8b0d482
acddaa3
0e50ebe
7f61c52
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -44,7 +44,7 @@ | |
LOGGER = logging.getLogger(__name__) | ||
|
||
|
||
class Hazard(HazardIO, HazardPlot): | ||
""" | ||
Contains events of some hazard type defined at centroids. Loads from | ||
files with format defined in FILE_EXT. | ||
|
@@ -450,6 +450,46 @@ | |
LOGGER.debug('Resetting event_id.') | ||
self.event_id = np.arange(1, self.event_id.size + 1) | ||
|
||
def local_return_period(self, threshold_intensities): | ||
"""Compute local return periods for given hazard intensities. | ||
|
||
Parameters | ||
---------- | ||
threshold_intensities : np.array | ||
Hazard intensities to consider. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I find the name There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what about "test_intensities"? I agree, I'll update the docstrings There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hmmm I think the word |
||
|
||
Returns | ||
------- | ||
return_periods : np.array | ||
Array containing computed local return periods for given hazard intensities. | ||
""" | ||
# Ensure threshold_intensities is a numpy array | ||
threshold_intensities = np.array(threshold_intensities) | ||
|
||
num_cen = self.intensity.shape[1] | ||
return_periods = np.zeros((len(threshold_intensities), num_cen)) # Adjusted for 2D structure | ||
ValentinGebhart marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
# Process each centroid in chunks as in local_exceedance_inten | ||
cen_step = CONFIG.max_matrix_size.int() // self.intensity.shape[0] | ||
ValentinGebhart marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if not cen_step: | ||
raise ValueError('Increase max_matrix_size configuration parameter to >' | ||
f'{self.intensity.shape[0]}') | ||
|
||
chk = -1 | ||
for chk in range(int(num_cen / cen_step)): | ||
self._loc_return_period( | ||
threshold_intensities, | ||
self.intensity[:, chk * cen_step:(chk + 1) * cen_step].toarray(), | ||
return_periods[:, chk * cen_step:(chk + 1) * cen_step]) | ||
|
||
if (chk + 1) * cen_step < num_cen: # Check if there's a remainder | ||
self._loc_return_period( | ||
threshold_intensities, | ||
self.intensity[:, (chk + 1) * cen_step:].toarray(), | ||
return_periods[:, (chk + 1) * cen_step:]) | ||
ValentinGebhart marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
return return_periods | ||
|
||
def get_event_id(self, event_name): | ||
"""Get an event id from its name. Several events might have the same | ||
name. | ||
|
@@ -613,6 +653,44 @@ | |
exc_inten[:, cen_idx] = self._cen_return_inten( | ||
inten_sort[:, cen_idx], freq_sort[:, cen_idx], | ||
self.intensity_thres, return_periods) | ||
|
||
def _loc_return_period(self, threshold_intensities, inten, return_periods): | ||
"""Compute local return periods for given hazard intensities for a specific chunk of data. | ||
ValentinGebhart marked this conversation as resolved.
Show resolved
Hide resolved
ValentinGebhart marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Parameters | ||
---------- | ||
threshold_intensities: np.array | ||
Given hazard intensities for which to calculate return periods. | ||
inten: np.array | ||
The intensity array for a specific chunk of data. | ||
ValentinGebhart marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return_periods: np.array | ||
Array to store computed return periods for the given hazard intensities. | ||
""" | ||
# Assuming inten is sorted and calculating cumulative frequency | ||
sort_pos = np.argsort(inten, axis=0)[::-1, :] | ||
ValentinGebhart marked this conversation as resolved.
Show resolved
Hide resolved
|
||
inten_sort = inten[sort_pos, np.arange(inten.shape[1])] | ||
freq_sort = self.frequency[sort_pos] | ||
np.cumsum(freq_sort, axis=0, out=freq_sort) | ||
ValentinGebhart marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
for cen_idx in range(inten.shape[1]): | ||
sorted_inten_cen = inten_sort[:, cen_idx] | ||
cum_freq_cen = freq_sort[:, cen_idx] | ||
|
||
for i, intensity in enumerate(threshold_intensities): | ||
# Find the first occurrence where the intensity is less than the sorted intensities | ||
exceedance_index = np.searchsorted(sorted_inten_cen[::-1], intensity, side='right') | ||
|
||
# Calculate exceedance probability | ||
if exceedance_index < len(cum_freq_cen): | ||
exceedance_probability = cum_freq_cen[-exceedance_index - 1] | ||
else: | ||
exceedance_probability = 0 # Or set a default minimal probability | ||
|
||
# Calculate and store return period | ||
if exceedance_probability > 0: | ||
return_periods[i, cen_idx] = 1 / exceedance_probability | ||
else: | ||
return_periods[i, cen_idx] = np.nan | ||
|
||
def _check_events(self): | ||
"""Check that all attributes but centroids contain consistent data. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,9 +19,11 @@ | |
Define Hazard Plotting Methods. | ||
""" | ||
|
||
import geopandas as gpd | ||
import numpy as np | ||
import matplotlib.pyplot as plt | ||
|
||
import climada.util.coordinates as u_coord | ||
import climada.util.plot as u_plot | ||
|
||
|
||
|
@@ -65,6 +67,37 @@ | |
colbar_name, title, smooth=smooth, axes=axis, | ||
figsize=figsize, adapt_fontsize=adapt_fontsize, **kwargs) | ||
return axis, inten_stats | ||
|
||
def plot_local_rp(self, threshold_intensities, smooth=True, axis=None, figsize=(9, 13), adapt_fontsize=True, cmap = 'viridis_r', **kwargs): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Formatting. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So, if a user wants to adapt the say color map, they must recompute the return periods every time? This seems rather inefficient. Would it not make sense to be able to pass the return periods to this function? Something like
Then, if return_periods is none, compute them. Else, use the return periods to make the graph. Maybe throw a warning if the threshold_itnensities are not in the gdf. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sorry, I forgot to remove this function. The functionality is now in |
||
"""Plot hazard local return periods for given hazard intensities. | ||
|
||
Parameters | ||
---------- | ||
threshold_intensities: np.array | ||
Hazard intensities to consider for calculating return periods. | ||
smooth: bool, optional | ||
Smooth plot to plot.RESOLUTION x plot.RESOLUTION. | ||
axis: matplotlib.axes._subplots.AxesSubplot, optional | ||
Axis to use. | ||
figsize: tuple, optional | ||
Figure size for plt.subplots. | ||
kwargs: optional | ||
Arguments for pcolormesh matplotlib function used in event plots. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some parameters are missing. |
||
|
||
Returns | ||
------- | ||
axis: matplotlib.axes._subplots.AxesSubplot | ||
Matplotlib axis with the plot. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Incomplete. |
||
""" | ||
return_periods = self.local_return_period(threshold_intensities) | ||
colbar_name = 'Return Period (years)' | ||
title = list() | ||
for haz_int in threshold_intensities: | ||
title.append('Intensity: ' + f'{haz_int} {self.units}') | ||
axis = u_plot.geo_im_from_array(return_periods, self.centroids.coord, | ||
colbar_name, title, smooth=smooth, axes=axis, | ||
figsize=figsize, adapt_fontsize=adapt_fontsize, cmap=cmap, **kwargs) | ||
return axis, return_periods | ||
|
||
def plot_intensity(self, event=None, centr=None, smooth=True, axis=None, adapt_fontsize=True, | ||
**kwargs): | ||
|
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.
It would be good to have a clear explanation here of what this method is doing. How are the local return periods computed? Interpolation? Fitting?