Rainfall Model#

import warnings
warnings.filterwarnings('ignore')
import os
import os.path as op
import sys

import matplotlib.pyplot as plt
import xarray as xr
import pandas as pd
import numpy as np
import geopandas as gpd
import utm
sys.path.insert(0, os.path.join(os.path.abspath(''), '..','..', '..' ))

from bluemath.rainfall_forecast.rainfall_forecast import *
from bluemath.rainfall_forecast.graffiti_rain import *
Warning: cannot import cf-json, install "metocean" dependencies for full functionality
# database
p_data = r'/media/administrador/HD2/SamoaTonga/data'
site, site_, nm = 'Savaii', 'savaii', 'sp'
p_site = op.join(p_data, site)

p_deliv = op.join(p_site, 'd09_rainfall_forecast')
p_figs = op.join(p_deliv, 'figs')

#Basins path
p_basins = op.join(p_deliv, 'basins', nm + '_db' +  '_fixed.shp')

#Som fitting
p_som_fit = os.path.join(p_deliv, 'som_fit_30x30_4d.nc')

#Parameters from classification
p_params_fit = os.path.join(p_deliv, 'params_fit_30x30_4d_clust.nc')

#Historical track
n = 166
p_hist_track = os.path.join(p_deliv,'sp_{0}.nc'.format(n))
times_sel = [150, 385] #Times to cut that specific track to our area

#output files
p_rain_out = os.path.join(p_deliv,'rain_sp_{0}.nc'.format(n))

# make data folders
for f in [p_deliv, p_figs]:
    if not op.isdir(f):
        os.makedirs(f)
#Parameters

area_interest = [[187.11, 187.89],[-13.89, -13.38]] #savaii
discretization = 0.05 #local grid discretization
bas_raw = gpd.read_file(p_basins)

Regional Scale#

A model to estimate rainfall caused by the action of tropical cyclones (TCs) according to atmospheric, geographical, and oceanic variables has been developed. For this purpose, three databases have been used: precipitation measured by satellite GPM mission with half-hourly temporal resolution and 0.1° of spatial resolution, TCs historical tracks from IBTrACS and sea surface temperature (SST) from the NOAA OI SST V2 High Resolution Dataset with daily data at 0.25° spatial resolution.

The model assumes a circular shape of the TC influence area and defines the precipitation clustered in 900 groups following a Self-Organizing Maps (SOM) algorithm as a function of:

  • TC track minimum pressure

  • TC track sea surface temperature

  • TC track latitude

  • \(\Delta\)SST : difference in sea surface temperature between the current day and the previous day averaged in an circular area of radius equal to 200 km from the TC track
    For each of the 900 clusters, the mean precipitacion over the radius dimension is calculated, and the curves are shown below.

from IPython.display import Image
Image('./resources/Rainfall_SOM.png', width=1000)    
../_images/01_Rainfall_Model_9_0.png

Load needed files#

To run the model, we need to load the data corresponding to the SOM clustering (som_fit dataset) and the parameters associated to each of the 900 clusters (params_fit dataset).

som_fit = xr.open_dataset(p_som_fit)
params_fit = xr.open_dataset(p_params_fit)

Rainfall footprint#

For a historical TC track:

tco = xr.open_dataset(p_hist_track)
tc = process_tc_file(tco)
TC: AMOS, starting day 2016-04-17
#We can select the dates we are interested in
tc = tc.isel(date_time=slice(times_sel[0], times_sel[1]))

Plot TC track

The track is coloured according to the minimum pressure value

fig_tc = Plot_track(tc, figsize=[20,10], cmap='jet_r', m_size=10)
../_images/01_Rainfall_Model_19_0.png

Obtain rainfall fields

interp=1 #interp: 1:activate / 0:deactivate 
interp_factor=1 #multiply by interp_factor the number of points along the track, in this case we already have the data each half hour in the TCs database
min_points=5 #minimum points to consider TC track and process it
tc_r = Generate_Rain_TC_4D(tc, som_fit, params_fit, interp, interp_factor, min_points)
time step 209

Once the model is constructed, from any TC track with its corresponding values of SST, latitude, minimum pressure and \(\Delta\)SST, a precipitation field from the closest cluster can be assigned to each position of the TC track.

Plot rain field

rmax = 20
figsize = [25,12]
fig_rf = plot_rain_fields(tc,tc_r,figsize,rmax)
../_images/01_Rainfall_Model_25_0.png

Total storm rainfall#

Here we grid the results into a regular grid with the resolution given below (discretization), to obtain the resultant rainfall grid in mm/hr associated to each temporal moment.
Then we aggregate the results to obtain the resultant rainfall footprint for all the storm.

Obtain the grid for each temporal moment

discretization = 0.5
l_ds = tc_grid(tc_r,discretization)
time step 209
#Dataset containing for each temporal moment the resultant rainfall grid
dst = xr.concat(l_ds,dim='time')

#Dataset with the resultant rainfall footprint for all the TC duration
dss = dst.sum(dim='time')*0.5

dss.to_netcdf(p_rain_out)

By aggregating the rainfall at each point of the region, the rainfall SWATH for the duration of the storm can be obtained

fig_total_storm_tc = tc_total_rain(tc, dss, figsize=[25,12])
../_images/01_Rainfall_Model_32_0.png

Local Scale#

Define area of interest and gris parameters

area_interest_l = [[area_interest[0][0]-discretization*3, area_interest[0][1]+discretization*3],[area_interest[1][0]-discretization*3, area_interest[1][1]+discretization*3]] #upolu

l_ds_area = tc_grid(tc_r,discretization, area=area_interest_l)
dst_area = xr.concat(l_ds_area,dim='time')
dss_area = dst_area.sum(dim='time')*0.5
time step 209
dst_area = dst_area.interp(lon=np.arange(dss_area.lon[0], dss_area.lon[-1], 0.01), lat=np.arange(dss_area.lat[0], dss_area.lat[-1], 0.01), method='linear')
dst_area = dst_area.sel(lon=slice(area_interest[0][0], area_interest[0][1]), lat=slice(area_interest[1][0], area_interest[1][1]))
dss_area = dss_area.interp(lon=np.arange(dss_area.lon[0], dss_area.lon[-1], 0.01), lat=np.arange(dss_area.lat[0], dss_area.lat[-1], 0.01), method='linear')
dss_area = dss_area.sel(lon=slice(area_interest[0][0], area_interest[0][1]), lat=slice(area_interest[1][0], area_interest[1][1]))
dst_area
<xarray.Dataset>
Dimensions:      (lat: 51, lon: 78, time: 210)
Coordinates:
  * lon          (lon) float64 187.1 187.1 187.1 187.1 ... 187.9 187.9 187.9
  * lat          (lat) float64 -13.88 -13.87 -13.86 ... -13.4 -13.39 -13.38
Dimensions without coordinates: time
Data variables:
    rain         (time, lat, lon) float64 nan nan nan nan ... nan nan nan nan
    cell_counts  (time, lat, lon) float64 nan nan nan nan ... nan nan nan nan

Basins discretization#

The discretization of the island in its watersheds have been carried out by means of QGIS, an open-source cross-platform desktop geographic information system (GIS) application that supports viewing, editing, and analysis of geospatial data. From the 5m resolution digital elevation model, a number of basins have been obtained, as in the following figure:

basins = Obtain_Basins(bas_raw, site)
Plot_Basins(basins)
../_images/01_Rainfall_Model_39_0.png

Rain in the different basins#

For each of the different basins, the rainfall has been downscaled and averaged in order to include an spatial rainfall constant throughout the basin.

x_utm, y_utm = tc_total_rain_site(tc,  dss_area, figsize=[25,12], basins=basins)#, vmax=970)
../_images/01_Rainfall_Model_42_0.png
dss_area['X_UTM'] = (('lon'), x_utm)
dss_area['Y_UTM'] = (('lat'), y_utm)
dss_area
<xarray.Dataset>
Dimensions:      (lat: 51, lon: 78)
Coordinates:
  * lon          (lon) float64 187.1 187.1 187.1 187.1 ... 187.9 187.9 187.9
  * lat          (lat) float64 -13.88 -13.87 -13.86 ... -13.4 -13.39 -13.38
Data variables:
    rain         (lat, lon) float64 217.3 217.6 218.0 ... 251.8 251.9 252.0
    cell_counts  (lat, lon) float64 9.815e+03 9.845e+03 ... 1.376e+04 1.373e+04
    X_UTM        (lon) float64 2.968e+05 2.979e+05 ... 3.79e+05 3.801e+05
    Y_UTM        (lat) float64 8.465e+06 8.466e+06 ... 8.519e+06 8.52e+06
x_utm, y_utm, INFO = tc_total_rain_site(tc, dss_area, figsize=[25,12], rain=0, basins=basins, points=1)#, vmax=970)
../_images/01_Rainfall_Model_44_0.png

Hyetograph for each basin#

The rainfall over time has been then obtained for each of the following basins, as it will be the input of the flooding model.

D_5 = Plot_Rain_Hyetograph_Basins(dst_area, dss_area, basins, INFO, site, thr_plot=1, thr=5)
D_5.to_netcdf(os.path.join(p_deliv, 'Rain_Real_Basins_' + site + '_Tc_' + str(tc.name.values) + '_sp' + str(n) + '.nc'))
../_images/01_Rainfall_Model_47_0.png ../_images/01_Rainfall_Model_47_1.png