Cyclobs user manual

How to get/use data from https://cyclobs.ifremer.fr

Notebook installation

conda create -n cyclobs python=3 cartopy nodejs

conda activate cyclobs

pip install xarray geoviews pandas rioxarray tqdm ipywidgets jupyterlab

jupyter labextension install @pyviz/jupyterlab_pyviz

jupyter labextension install @jupyter-widgets/jupyterlab-manager

wget https://gitlab.ifremer.fr/cyclobs/user_manual/-/raw/master/user_manual.ipynb

jupyter lab

In [1]:
#import matplotlib 
#%matplotlib inline 
import geoviews as gv
import holoviews as hv
import geoviews.feature as gf
gv.extension('bokeh','matplotlib')
hv.extension('bokeh','matplotlib')
import pandas as pd
import xarray as xr
import rasterio as rio
import rioxarray # geospatial extension for xarray
import os
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy
from tqdm.auto import tqdm
import numpy as np
from operator import mul


download_path="/tmp/cyclobs"
os.makedirs(download_path,exist_ok = True)
In [2]:
# FIXME : year=2018 will help to select HECTOR in 2018
# FIXME : date format is MM-DD-YYYY
# FIXME : adding 'VMAX' to includeCols give 'INTERNAL SERVER ERROR'
# FIXME : check if all arguments are valids
# FIXME : add includeCols=all

request_url="https://cyclobs.ifremer.fr/app/api/getData?Cyclone%20name=HECTOR&startdate=01-01-2018&stopdate=12-31-2018&instrument=C-Band%20SAR&includeCols=Cyclone%20name,File%20path,Instrument,Mission,SID,Basins"
df_request = pd.read_csv(request_url)

# FIXME : avoid %20 in url

# FIXME : Cyclone%20name not handled (all cyclones returned)
df_request = df_request[df_request["Cyclone name"] == "HECTOR"]

# FIXME :  "Instrument" not handled (all instruments returned) 
df_request = df_request[df_request["Instrument"] == "C-Band Synthetic Aperture Radar"].reset_index(drop=True)

# FIXME  : rename 'File path' to 'url' or 'File url' in upstream
df_request.rename(columns={"File path": "url"},inplace=True)


# FIXME : _gd instead of _sw by default
df_request['url'] = df_request['url'].map(lambda x : x.replace("_sw","_gd"))

# add download path
df_request['path'] = df_request['url'].map(lambda x : os.path.join(download_path,os.path.basename(x)))

# coloc
df_request=df_request[['20180807' in x for x in df_request['path']] ].reset_index(drop=True)

df_request
Out[2]:
Cyclone name url Instrument Mission SID Basins path
0 HECTOR https://cyclobs.ifremer.fr/static/sarwing_data... C-Band Synthetic Aperture Radar RADARSAT-2 ep102018 NWP;NEP /tmp/cyclobs/rs2--owi-cm-20180807t154512-20180...
1 HECTOR https://cyclobs.ifremer.fr/static/sarwing_data... C-Band Synthetic Aperture Radar SENTINEL-1 A ep102018 NEP;NWP /tmp/cyclobs/s1a-ew-owi-cm-20180807t154302-201...
In [3]:
# download 'url' to 'path' with wget, and read files
projection=ccrs.Mercator()
#projection=ccrs.PlateCarree()
datasets = []
for idx,entry in tqdm(df_request.iterrows(),total=df_request.shape[0]):
    ret = os.system('cd %s ; wget -N  %s' % (os.path.dirname(entry['path']),entry['url']))
    # FIXME : rename 'X' and 'Y' to 'x' and 'y'
    if ret == 0 : 
        #ds = rioxarray.open_rasterio(entry['path'])#.rename({'X' : 'x', 'Y':'y'})
        ds = xr.open_dataset(entry['path'])
        #datasets.append(ds)
        datasets.append( ds.rio.reproject(projection.proj4_params))
        
    else:
        datasets.append(None) # error fetching file
df_request['dataset'] = datasets

In [50]:
ds_rs2 = df_request['dataset'].iloc[0]

# reproject s1 on rs2. s1 outside rs2 will be nan
ds_s1  = df_request['dataset'].iloc[1].rio.reproject_match(ds_rs2['wind_speed'])
ds_rs2 = ds_rs2.rio.reproject_match(ds_s1['wind_speed'])




da_s1 = ds_s1['wind_speed'].squeeze()[::5,::5]
da_rs2 = ds_rs2['wind_speed'].squeeze()[::5,::5]

# mask non -intersting
mask = np.isnan(da_s1.values) | np.isnan(da_rs2.values)
da_rs2.values[mask ] = np.nan
da_s1.values[mask ] = np.nan

#ds_coloc= xr.combine_by_coords([ds_rs2,ds_s1]).stack(xx=('x', 'y'))
#ds_coloc
coastline=gf.coastline.opts(projection=projection)

ds = hv.Dataset((da_rs2.x, da_rs2.y, da_rs2.values, da_s1.values), ['x', 'y'], ['rs2', 's1'])

# two Image
plots = [hv.Image(ds, vdims=vdim)  for vdim in ds.vdims]
plots.append(hv.Scatter(ds, 'rs2', 's1'))

layout=hv.Layout(plots)

np.warnings.filterwarnings('ignore')

hv.selection.link_selections(layout,unselected_color='#505050', unselected_alpha=0.05).opts(hv.opts.Image(tools=[ 'box_select'],cmap='jet'),hv.opts.Scatter(tools=['box_select'],nonselection_color='grey',nonselection_alpha=0.05))
Out[50]: