8. Précipitation Maximale Probable (PMP)

La Précipitation Maximale Probable (PMP) est la quantité théorique maximale de précipitations qui pourrait se produire à un endroit spécifique dans un laps de temps donné, en tenant compte des conditions météorologiques les plus extrêmes. La PMP est un paramètre critique en hydrologie, en particulier pour la conception d’infrastructures telles que les barrages, réservoirs et systèmes de drainage.

Il existe plusieurs méthodes pour calculer la PMP, chacune variant en complexité et en fonction du type de données utilisées. La méthode actuellement implémentée dans xHydro est basée sur l’approche décrite par Clavet-Gaumont et al. (2017). Cette méthode consiste à maximiser l’eau précipitable sur un emplacement donné, ce qui fait référence à la quantité totale de vapeur d’eau dans l’atmosphère qui pourrait être potentiellement convertie en précipitations dans des conditions idéales. En maximisant cette valeur, la méthode estime la précipitation maximale qui pourrait théoriquement se produire à cet endroit.

[1]:
from pathlib import Path

import hvplot.xarray
import matplotlib.pyplot as plt
import numpy as np
import pooch
import xarray as xr
import xclim

import xhydro as xh
from xhydro.testing.helpers import deveraux
ERROR 1: PROJ: proj_create_from_database: Open of /home/docs/checkouts/readthedocs.org/user_builds/xhydro-fr/conda/latest/share/proj failed

8.1. Acquisition des données

L’acquisition des données climatiques est hors de la portée de xHydro. Cependant, quelques exemples de comment obtenir et gérer de telles données sont fournis dans les Notebooks Opérations SIG et Exemple de cas d’application. Pour ce Notebook, nous allons utiliser un jeu de données test composé de 2 ans et de 9 points de grille issus des données du modèle climatique CanESM5. Dans une application réelle, il serait préférable d’avoir autant d’années de données que possible.

Pour effectuer l’analyse, certaines variables climatiques sont nécessaires.

  • Variables au pas de temps quotidien:

    • pr → Flux de précipitations

    • snw → Équivalent en eau de neige

    • hus → Humidité spécifique pour plusieurs niveaux de pression

    • zg → Hauteur géopotentielle pour plusieurs niveaux de pression

  • Variables de champ fixe:

    • orog → Altitude de la surface

Dans les régions froides, il peut être nécessaire de diviser les précipitations totales en composantes de pluie et de neige. De nombreux modèles climatiques fournissent déjà ces données séparément. Cependant, si ces données ne sont pas directement disponibles, des librairies comme xclim peuvent approximer la division en utilisant les données de précipitations et de température.

[2]:
from pathlib import Path

import xhydro as xh

path_day_zip = deveraux().fetch(
    "pmp/CMIP.CCCma.CanESM5.historical.r1i1p1f1.day.gn.zarr.zip",
    pooch.Unzip(),
)
ds_day = xr.open_zarr(Path(path_day_zip[0]).parents[0])

path_fx_zip = deveraux().fetch(
    "pmp/CMIP.CCCma.CanESM5.historical.r1i1p1f1.fx.gn.zarr.zip",
    pooch.Unzip(),
)
ds_fx = xr.open_zarr(Path(path_fx_zip[0]).parents[0])

# There are a few issues with attributes in this dataset that we need to address
ds_day["pr"].attrs = {"units": "mm", "long_name": "precipitation"}
ds_day["prsn"].attrs = {"units": "mm", "long_name": "snowfall"}
ds_day["rf"].attrs = {"units": "mm", "long_name": "rainfall"}

# Combine both datasets
ds = ds_day.convert_calendar("standard")
ds["orog"] = ds_fx["orog"]
ds
[2]:
<xarray.Dataset> Size: 643kB
Dimensions:      (time: 730, plev: 8, y: 3, x: 3)
Coordinates:
    height       float64 8B ...
  * plev         (plev) float64 64B 1e+05 8.5e+04 7e+04 ... 1e+04 5e+03 1e+03
  * time         (time) datetime64[ns] 6kB 2010-01-01T12:00:00 ... 2011-12-31...
  * x            (x) float64 24B 281.2 284.1 286.9
  * y            (y) float64 24B 43.25 46.04 48.84
Data variables:
    hus          (time, plev, y, x) float32 210kB dask.array<chunksize=(214, 8, 3, 3), meta=np.ndarray>
    lat_bounds   (y) float64 24B dask.array<chunksize=(3,), meta=np.ndarray>
    lon_bounds   (x) float64 24B dask.array<chunksize=(3,), meta=np.ndarray>
    pr           (time, y, x) float64 53kB dask.array<chunksize=(730, 3, 3), meta=np.ndarray>
    prsn         (time, y, x) float64 53kB dask.array<chunksize=(730, 3, 3), meta=np.ndarray>
    rf           (time, y, x) float64 53kB dask.array<chunksize=(730, 3, 3), meta=np.ndarray>
    snw          (time, y, x) float32 26kB dask.array<chunksize=(730, 3, 3), meta=np.ndarray>
    tas          (time, y, x) float32 26kB dask.array<chunksize=(730, 3, 3), meta=np.ndarray>
    time_bounds  (time) object 6kB dask.array<chunksize=(730,), meta=np.ndarray>
    zg           (time, plev, y, x) float32 210kB dask.array<chunksize=(239, 8, 3, 3), meta=np.ndarray>
    orog         (y, x) float32 36B dask.array<chunksize=(3, 3), meta=np.ndarray>
Attributes: (12/56)
    CCCma_model_hash:            3dedf95315d603326fde4f5340dc0519d80d10c0
    CCCma_parent_runid:          rc3-pictrl
    CCCma_pycmor_hash:           33c30511acc319a98240633965a04ca99c26427e
    CCCma_runid:                 rc3.1-his01
    Conventions:                 CF-1.7 CMIP-6.2
    YMDH_branch_time_in_child:   1850:01:01:00
    ...                          ...
    title:                       CanESM5 output prepared for CMIP6
    tracking_id:                 hdl:21.14100/d0a84c86-7fb1-4de4-8837-574504c...
    variable_id:                 hus
    variant_label:               r1i1p1f1
    version:                     v20190429
    version_id:                  v20190429

8.2. Calcul de la PMP

La méthode décrite par Clavet-Gaumont et al. (2017) suit ces étapes :

  1. Identification des grands événements de précipitation:
    La première étape consiste à identifier les grands événements de précipitation qui seront maximisés. Cela se fait en filtrant les événements en fonction d’un seuil spécifié.
  2. Calcul de l’eau précipitable mensuelle de récurrence 100 ans :
    L’étape suivante consiste à calculer l’eau précipitable de récurrence 100 ans sur une base mensuelle en utilisant la distribution des Valeurs Extrêmes Généralisées (GEV), avec un plafond maximum de 20 % supérieur à la valeur observée la plus grande.
  3. Maximisation des précipitations pendant les événements:
    Dans cette étape, les événements de précipitation sont maximisés en fonction du rapport entre l’eau précipitable mensuelle de récurrence 100 ans et l’eau précipitable pendant les grands événements de précipitation. Dans les régions sans neige, c’est le résultat final.
  4. Séparation saisonnière dans les régions froides:
    Dans les régions froides, les résultats sont séparés en saisons (par exemple, printemps, été) pour tenir compte de la neige lors du calcul des Crues Maximales Probables (CMP).

Cette méthode fournit une approche complète pour estimer la PMP, en tenant compte à la fois des variations de température et de précipitations à travers différentes régions et saisons.

8.2.1. Grands événements de précipitation

La première étape pour calculer la Précipitation Maximale Probable (PMP) consiste à filtrer les données de précipitation pour ne retenir que les événements qui dépassent un certain seuil. Ces grands événements de précipitation seront maximisés dans les étapes suivantes. La fonction xh.indicators.pmp.major_precipitation_events peut être utilisée à cette fin. Elle offre également l’option de sommer les précipitations sur un nombre spécifié de jours, ce qui peut aider à agréger les événements de tempête. Pour les données 2D, comme dans cet exemple, chaque point de grille est traité indépendamment.

Dans cet exemple, nous allons filtrer les 10 % des tempêtes les plus intenses pour éviter de surévaluer les événements de précipitation plus petits pendant le processus de maximisation. De plus, nous nous concentrerons sur les précipitations liquides (rf) plutôt que sur les précipitations totales (pr) afin d’exclure les tempêtes de neige.

Help on function major_precipitation_events in module xhydro.indicators.pmp:

major_precipitation_events(da: xarray.core.dataarray.DataArray, *, windows: list[int], quantile: float = 0.9)
    Get precipitation events that exceed a given quantile for a given time step accumulation. Based on Clavet-Gaumont et al. (2017).

    Parameters
    ----------
    da : xr.DataArray
        DataArray containing the precipitation values.
    windows : list of int
        List of the number of time steps to accumulate precipitation.
    quantile : float
        Threshold that limits the events to those that exceed this quantile. Defaults to 0.9.

    Returns
    -------
    xr.DataArray
        Masked DataArray containing the major precipitation events.

    Notes
    -----
    https://doi.org/10.1016/j.ejrh.2017.07.003

[4]:
precipitation_events = xh.indicators.pmp.major_precipitation_events(
    ds.rf, windows=[1], quantile=0.9
)

ds.rf.isel(x=1, y=1).hvplot() * precipitation_events.isel(
    x=1, y=1, window=0
).hvplot.scatter(color="red")
[4]:

8.2.2. Eau précipitable quotidienne

AVERTISSEMENT

Cette étape doit être évitée si possible, car elle consiste à approximer l’eau précipitable à partir de l’intégrale de l’humidité spécifique et sera fortement sensible au nombre de niveaux de pression utilisés. Si disponible, les utilisateurs sont fortement encouragés à utiliser une variable ou une combinaison de variables qui représentent directement l’eau précipitable.

L’eau précipitable peut être estimée en utilisant xhydro.indicators.pmp.precipitable_water pour intégrer la colonne verticale de l’humidité. Ce processus nécessite des données d’humidité spécifique, de hauteur géopotentielle et d’altitude. La valeur résultante représente la quantité totale de vapeur d’eau qui pourrait être précipitée de l’atmosphère sous des conditions idéales.

Help on function precipitable_water in module xhydro.indicators.pmp:

precipitable_water(*, hus: xarray.core.dataarray.DataArray, zg: xarray.core.dataarray.DataArray, orog: xarray.core.dataarray.DataArray, windows: list[int] | None = None, beta_func: bool = True, add_pre_lay: bool = False)
    Compute precipitable water based on Clavet-Gaumont et al. (2017) and Rousseau et al (2014).

    Parameters
    ----------
    hus : xr.DataArray
        Specific humidity. Must have a pressure level (plev) dimension.
    zg : xr.DataArray
        Geopotential height. Must have a pressure level (plev) dimension.
    orog : xr.DataArray
        Surface altitude.
    windows : list of int, optional
        Duration of the event in time steps. Defaults to [1].
        Note that an additional time step will be added to the window size to account for antecedent conditions.
    beta_func : bool, optional
        If True, use the beta function proposed by Boer (1982) to get the pressure layers above the topography.
        If False, the surface altitude is used as the lower boundary of the atmosphere assuming that the surface altitude
        and the geopotential height are virtually identical at low altitudes.
    add_pre_lay : bool, optional
        If True, add the pressure layer between the surface and the lowest pressure level (e.g., at sea level).
        If False, only the pressure layers between the lowest and highest pressure level are considered.

    Returns
    -------
    xr.DataArray
        Precipitable water.

    Notes
    -----
    1) The precipitable water of an event is defined as the maximum precipitable water found during the entire duration of the event,
    extending up to one time step before the start of the event. Thus, the rolling operation made using `windows` is a maximum, not a sum.

    2) beta_func = True and add_pre_lay = False follow Clavet-Gaumont et al. (2017) and Rousseau et al (2014).

    3) https://doi.org/10.1016/j.ejrh.2017.07.003
       https://doi.org/10.1016/j.jhydrol.2014.10.053
       https://doi.org/10.1175/1520-0493(1982)110<1801:DEIIC>2.0.CO;2

[6]:
pw = xh.indicators.pmp.precipitable_water(
    hus=ds.hus,
    zg=ds.zg,
    orog=ds.orog,
    windows=[1],
    add_pre_lay=False,
)

pw.isel(x=1, y=1, window=0).hvplot()
[6]:

8.2.3. Eau précipitable mensuelle de récurrence 100 ans

Selon Clavet-Gaumont et al. (2017), l’eau précipitable mensuelle de récurrence 100 ans doit être calculée en utilisant la distribution des Valeurs Extrêmes Généralisées (GEV). La valeur doit être limitée à un maximum de 20 % supérieur à la valeur maximale observée de l’eau précipitable pour un mois donné. Cette approche garantit que l’événement estimé sur 100 ans est réaliste et contraint par les données observées.

Pour calculer cela, vous pouvez utiliser la fonction xh.indicators.pmp.precipitable_water_100y. Si vous utilisez rebuild_time, la sortie aura le même axe temporel que les données d’origine.

Help on function precipitable_water_100y in module xhydro.indicators.pmp:

precipitable_water_100y(pw: xarray.core.dataarray.DataArray, *, dist: str, method: str, mf: float = 0.2, rebuild_time: bool = True)
    Compute the 100-year return period of precipitable water for each month. Based on Clavet-Gaumont et al. (2017).

    Parameters
    ----------
    pw : xr.DataArray
        DataArray containing the precipitable water.
    dist : str
        Probability distributions.
    method : {"ML" or "MLE", "MM", "PWM", "APP"}
        Fitting method, either maximum likelihood (ML or MLE), method of moments (MM) or approximate method (APP).
        Can also be the probability weighted moments (PWM), also called L-Moments, if a compatible `dist` object is passed.
    mf : float
        Maximum majoration factor of the 100-year event compared to the maximum of the timeseries.
        Used as an upper limit for the frequency analysis.
    rebuild_time : bool
        Whether or not to reconstruct a timeseries with the same time dimensions as `pw`.

    Returns
    -------
    xr.DataArray
        Precipitable water for a 100-year return period.

    Notes
    -----
    https://doi.org/10.1016/j.ejrh.2017.07.003

[8]:
pw100 = xh.indicators.pmp.precipitable_water_100y(
    pw.sel(window=1).chunk(dict(time=-1)),
    dist="genextreme",
    method="ML",
    mf=0.2,
    rebuild_time=True,
).compute()

pw.isel(x=1, y=1, window=0).hvplot() * pw100.isel(x=1, y=1).hvplot()
[8]:

8.2.4. Précipitations maximisées

INFO

Cette étape suit la méthodologie décrite dans Clavet-Gaumont et al., 2017. Elle est appelée « Maximisation des précipitations », cependant, elle applique effectivement un rapport basé sur l’eau précipitable mensuelle de récurrence 100 ans. Si un événement historique a dépassé cette valeur—comme cela a été observé pour janvier 2011—le résultat peut en réalité réduire les précipitations, plutôt que de les augmenter.

Grâce aux informations recueillies jusqu’à présent, nous pouvons maintenant procéder à la maximisation des événements de précipitation. Bien que xHydro ne fournisse pas de fonction explicite pour cette étape, cela peut être accompli en suivant ces étapes :

  1. Calculer le rapport : Tout d’abord, calculez le rapport entre l’eau précipitable mensuelle de récurrence 100 ans et l’eau précipitable pendant les grands événements de précipitation.

  2. Appliquer le rapport : Ensuite, appliquez ce rapport aux valeurs de précipitations elles-mêmes pour maximiser les événements de précipitation en conséquence.

Ce processus ajuste les événements de précipitation en fonction de l’eau précipitable de récurrence 100 ans, fournissant une estimation des précipitations maximales possibles.

[9]:
# Precipitable water on the day of the major precipitation events.
pw_events = pw.where(precipitation_events > 0)
ratio = pw100 / pw_events

# Apply the ratio onto precipitation itself
precipitation_max = ratio * precipitation_events
precipitation_max.name = "maximized_precipitation"

ds.rf.isel(x=1, y=1).hvplot() * precipitation_max.isel(
    x=1, y=1, window=0
).hvplot.scatter(color="red")
[9]:

8.2.5. Masque saisonnier

Dans les régions froides, le calcul des Crues Maximales Probables (CMP) implique souvent des scénarios qui combinent à la fois les précipitations et le manteau neigeux. Par conséquent, les valeurs de PMP peuvent devoir être séparées en deux catégories : pluie-sur-neige (c’est-à-dire, « printemps ») et précipitations sans neige (c’est-à-dire, « été »).

Cela peut être facilement calculé en utilisant xhydro.indicators.pmp.compute_spring_and_summer_mask, qui définit les dates de début et de fin du printemps, de l’été et de l’hiver en fonction de la présence de neige au sol, selon les critères suivants :

  1. Hiver :

    • Début de l’hiver : Le premier jour après lequel il y a au moins 14 jours consécutifs avec de la neige au sol.

    • Fin de l’hiver : Le dernier jour avec de la neige au sol, suivi d’au moins 45 jours consécutifs sans neige.

  2. Printemps :

    • Début du printemps : 60 jours avant la fin de l’hiver.

    • Fin du printemps : 30 jours après la fin de l’hiver.

  3. Été :

    • La période estivale est définie comme la période entre les hivers. Cette période n’est pas influencée par le fait qu’elle tombe pendant l’été ou l’automne traditionnels, mais marque simplement l’intervalle entre les saisons de neige.

Help on function compute_spring_and_summer_mask in module xhydro.indicators.pmp:

compute_spring_and_summer_mask(snw: xarray.core.dataarray.DataArray, *, thresh: str = '1 cm', window_wint_start: int = 14, window_wint_end: int = 45, spr_start: int = 60, spr_end: int = 30, freq: str = 'YS-JUL')
    Create a mask that defines the spring and summer seasons based on the snow water equivalent.

    Parameters
    ----------
    snw : xarray.DataArray
        Snow water equivalent. Must be a length (e.g. "mm") or a mass (e.g. "kg m-2").
    thresh : Quantified
        Threshold snow thickness to define the start and end of winter.
    window_wint_start : int
        Minimum number of days with snow depth above or equal to threshold to define the start of winter.
    window_wint_end : int
        Maximum number of days with snow depth below or equal to threshold to define the end of winter.
    spr_start : int
        Number of days before the end of winter to define the start of spring.
    spr_end : int
        Number of days after the end of winter to define the end of spring.
    freq : str
        Frequency of the time axis (annual frequency). Defaults to "YS-JUL".

    Returns
    -------
    xr.Dataset
        Dataset with two DataArrays (mask_spring and mask_summer), with values of 1 where the
        spring and summer criteria are met and 0 where they are not.

[11]:
mask = xh.indicators.pmp.compute_spring_and_summer_mask(
    ds.snw,
    thresh="1 cm",
    window_wint_end=14,  # Since the dataset used does not have a lot of snow, we need to be more lenient
    freq="YS-SEP",
)

mask
[11]:
<xarray.Dataset> Size: 111kB
Dimensions:      (time: 730, y: 3, x: 3)
Coordinates:
    height       float64 8B 2.0
  * time         (time) datetime64[ns] 6kB 2010-01-01T12:00:00 ... 2011-12-31...
  * y            (y) float64 24B 43.25 46.04 48.84
  * x            (x) float64 24B 281.2 284.1 286.9
Data variables:
    mask_spring  (time, y, x) float64 53kB dask.array<chunksize=(365, 3, 3), meta=np.ndarray>
    mask_summer  (time, y, x) float64 53kB dask.array<chunksize=(365, 3, 3), meta=np.ndarray>
[12]:
xclim.core.units.convert_units_to(
    ds.isel(x=1, y=1).snw, "cm", context="hydro"
).hvplot() * (mask.mask_spring.isel(x=1, y=1) * 10).hvplot() * (
    mask.mask_summer.isel(x=1, y=1) * 8
).hvplot()
[12]:

8.2.6. PMP finale

La PMP finale est obtenue en trouvant la valeur maximale sur la dimension time. Dans notre cas, puisque nous avons calculé un masque saisonnier, nous pouvons affiner les résultats en une PMP pour le printemps et l’été.

[13]:
pmp_spring = (precipitation_max * mask.mask_spring).max("time").compute()
pmp_summer = (precipitation_max * mask.mask_summer).max("time").compute()
[14]:
plt.subplots(1, 2, figsize=[12, 5])

ax = plt.subplot(1, 2, 1)
pmp_spring.sel(window=1).plot(vmin=30, vmax=100)
plt.title("Spring PMP")

ax = plt.subplot(1, 2, 2)
pmp_summer.sel(window=1).plot(vmin=30, vmax=100)
plt.title("Summer PMP")
[14]:
Text(0.5, 1.0, 'Summer PMP')
../_images/notebooks_pmp_21_1.png

8.3. PMP avec configurations de tempêtes agrégées

Dans certains cas, il peut être préférable d’éviter de traiter chaque point de grille indépendamment. À la place, les tempêtes peuvent être agrégées en utilisant différentes configurations pour fournir une estimation plus représentative à l’échelle régionale. Ces configurations permettent une moyenne spatiale des événements de tempête, ce qui peut aider à réduire la variabilité entre les points de grille et fournir des résultats plus fiables.

Différentes configurations d’agrégation sont discutées dans Clavet-Gaumont et al. (2017) et ont été implémentées dans xHydro sous la fonction xhydro.indicators.pmp.spatial_average_storm_configurations.

Notez que l’eau précipitable doit d’abord être calculée de manière distribuée puis moyennée spatialement pour obtenir l’eau précipitable agrégée.

Help on function spatial_average_storm_configurations in module xhydro.indicators.pmp:

spatial_average_storm_configurations(da, *, radius)
    Compute the spatial average for different storm configurations proposed by Clavet-Gaumont et al. (2017).

    Parameters
    ----------
    da : xr.DataArray
        DataArray containing the precipitation values.
    radius : float
        Maximum radius of the storm.

    Returns
    -------
    xr.DataSet
        DataSet containing the spatial averages for all the storm configurations. The y and x coordinates indicate
        the location of the storm. This location is determined by n//2, where n is the total number of cells for
        both the rows and columns in the configuration, and // represents floor division.

    Notes
    -----
    https://doi.org/10.1016/j.ejrh.2017.07.003.

[16]:
ds_agg = []
for variable in ["rf", "pw", "snw"]:
    if variable == "pw":
        ds_agg.extend(
            [xh.indicators.pmp.spatial_average_storm_configurations(pw, radius=3)]
        )
    else:
        ds_agg.extend(
            [
                xh.indicators.pmp.spatial_average_storm_configurations(
                    ds[variable], radius=3
                )
            ]
        )
ds_agg = xr.merge(ds_agg).chunk(dict(time=-1))

# The aggreagtion creates NaN values for snow, so we'll restrict the domain
ds_agg = ds_agg.isel(y=slice(0, -1), x=slice(0, -1))

ds_agg
[16]:
<xarray.Dataset> Size: 497kB
Dimensions:             (conf: 7, y: 2, x: 2, time: 730, window: 1)
Coordinates:
  * conf                (conf) object 56B '2.1' '2.2' '3.1' ... '3.4' '4.1'
  * y                   (y) float64 16B 43.25 46.04
  * x                   (x) float64 16B 281.2 284.1
  * time                (time) datetime64[ns] 6kB 2010-01-01T12:00:00 ... 201...
    height              float64 8B 2.0
  * window              (window) int64 8B 1
Data variables:
    rf                  (conf, time, y, x) float64 164kB dask.array<chunksize=(1, 730, 1, 1), meta=np.ndarray>
    precipitable_water  (conf, window, time, y, x) float64 164kB dask.array<chunksize=(1, 1, 730, 1, 1), meta=np.ndarray>
    snw                 (conf, time, y, x) float64 164kB dask.array<chunksize=(1, 730, 1, 1), meta=np.ndarray>
Attributes:
    units:    mm

Après avoir appliqué l’agrégation des tempêtes, les étapes suivantes restent les mêmes qu’auparavant, suivant le processus standard de calcul da le PMP.

[17]:
pe_agg = xh.indicators.pmp.major_precipitation_events(
    ds_agg.rf, windows=[1], quantile=0.9
)

pw100_agg = xh.indicators.pmp.precipitable_water_100y(
    ds_agg.sel(window=1).precipitable_water, dist="genextreme", method="ML", mf=0.2
)

# Maximization
pw_events_agg = ds_agg.precipitable_water.where(pe_agg > 0)
r_agg = pw100_agg / pw_events_agg

pmax_agg = r_agg * pe_agg

# Season mask
mask_agg = xh.indicators.pmp.compute_spring_and_summer_mask(
    ds_agg.snw,
    thresh="1 cm",
    window_wint_start=14,
    window_wint_end=14,
    spr_start=60,
    spr_end=30,
    freq="YS-SEP",
)

pmp_spring_agg = pmax_agg * mask_agg.mask_spring
pmp_summer_agg = pmax_agg * mask_agg.mask_summer

pmp_summer_agg
[17]:
<xarray.DataArray (conf: 7, y: 2, x: 2, time: 730, window: 1)> Size: 164kB
dask.array<mul, shape=(7, 2, 2, 730, 1), dtype=float64, chunksize=(1, 1, 1, 24, 1), chunktype=numpy.ndarray>
Coordinates:
  * conf      (conf) object 56B '2.1' '2.2' '3.1' '3.2' '3.3' '3.4' '4.1'
  * y         (y) float64 16B 43.25 46.04
  * x         (x) float64 16B 281.2 284.1
  * time      (time) datetime64[ns] 6kB 2010-01-01T12:00:00 ... 2011-12-31T12...
    height    float64 8B 2.0
  * window    (window) int64 8B 1
    quantile  float64 8B 0.9

Auparavant, la PMP finale pour chaque saison était obtenue en prenant la valeur maximale sur la dimension time. Dans cette approche mise à jour, nous pouvons désormais prendre la valeur maximale à la fois sur les dimensions time et conf, en utilisant nos multiples configurations de tempêtes.

[18]:
# Final results
pmp_spring_agg = pmp_spring_agg.max(dim=["time", "conf"])
pmp_summer_agg = pmp_summer_agg.max(dim=["time", "conf"])

pmp_summer_agg
[18]:
<xarray.DataArray (y: 2, x: 2, window: 1)> Size: 32B
dask.array<_nanmax_skip-aggregate, shape=(2, 2, 1), dtype=float64, chunksize=(1, 1, 1), chunktype=numpy.ndarray>
Coordinates:
  * y         (y) float64 16B 43.25 46.04
  * x         (x) float64 16B 281.2 284.1
    height    float64 8B 2.0
  * window    (window) int64 8B 1
    quantile  float64 8B 0.9
[19]:
# Compare results for the central grid cell
print(
    f"Grid-cell summer PMP: {np.round(pmp_summer.isel(x=1, y=1, window=0).values, 1)} mm"
)
print(
    f"Aggregated summer PMP: {np.round(pmp_summer_agg.isel(x=1, y=1, window=0).values, 1)} mm"
)
Grid-cell summer PMP: 78.7 mm
Aggregated summer PMP: 67.7 mm