Download Swot from AVISO
This notebook explains how to explore and retrieve available SWOT LR data from AVISO’s THREDDS Data Server and FTP Server, presented here.
L2 data can be explored at: https://tds.aviso.altimetry.fr/thredds/L2/L2-SWOT-DATA/L2-SWOT.html
L3 data can be explored at: https://tds.aviso.altimetry.fr/thredds/catalog/dataset-l3-swot-karin-nadir-validated/l3_lr_ssh/catalog.html
Tutorial Objectives
Discover Aviso’s Thredds Data Server catalogue
Download files through HTTP and FTP
Download data subset through Opendap
Import + code
[1]:
import os
import re
from getpass import getpass
import requests as rq
import ftplib
import xarray as xr
from xarray.backends import PydapDataStore
[2]:
def _get_filename_from_cd(cd):
""" Get filename from content-disposition """
if not cd:
return None
fname = re.findall('filename="(.+)"', cd)
if len(fname) == 0:
return None
return fname[0]
def http_download_file(dataset_url:str, output_path:str):
response = rq.get(dataset_url, auth=(username, password))
filename = _get_filename_from_cd(response.headers['content-disposition'])
file_path = os.path.join(output_path, filename)
open(file_path, 'wb').write(response.content)
return file_path
def _download_file(ftp:str, filename:str, target_directory:str):
try:
local_filepath = os.path.join(target_directory, filename)
with open(local_filepath, 'wb') as file:
ftp.retrbinary('RETR %s' % filename, file.write)
print(f"Downloaded {filename} to {target_directory}")
return local_filepath
except Exception as e:
print(f"Error downloading {filename}: {e}")
def ftp_download_file(ftp_path:str, filename:str, output_path:str):
# Set up FTP server details
ftpAVISO = 'ftp-access.aviso.altimetry.fr'
try:
# Logging into FTP server using provided credentials
with ftplib.FTP(ftpAVISO) as ftp:
ftp.login(username, password)
ftp.cwd(ftp_path)
print(f"Connection Established {ftp.getwelcome()}")
# Check if the file exists in the directory
if filename in ftp.nlst():
return _download_file(ftp, filename, output_path)
else:
print(f"File {filename} does not exist in the directory {ftp}.")
except ftplib.error_perm as e:
print(f"FTP error: {e}")
except Exception as e:
print(f"Error: {e}")
def open_opendap_dataset(dataset_url):
session = rq.Session()
session.auth = (username, password)
store = PydapDataStore.open(dataset_url, session=session, timeout=300, user_charset='UTF-8')
return xr.open_dataset(store)
Parameters
Define output folder to save results
[3]:
output_dir = "downloads"
Authentication parameters
Enter your AVISO+ credentials
[ ]:
password = getpass(f"Enter password for {username}:")
[ ]:
username = input("Enter username:")
Download files through HTTP
To find the data you want to download, you can explore the Swot LR L2 or Swot LR L3 catalogues.
Copy the FileServer url to download data through HTTP :
Swot LR L2 data
[5]:
l2_dataset_url = "https://tds.aviso.altimetry.fr/thredds/fileServer/dataset-l2-swot-karin-lr-ssh-pre-validated/PIC0/Basic/cycle_014/SWOT_L2_LR_SSH_Basic_014_001_20240417T111950_20240417T121118_PIC0_01.nc"
[6]:
l2_file = http_download_file(l2_dataset_url, output_dir)
l2_file
[6]:
'downloads/SWOT_L2_LR_SSH_Basic_014_001_20240417T111950_20240417T121118_PIC0_01.nc'
Swot LR L3 data
[7]:
l3_dataset_url = "https://tds.aviso.altimetry.fr/thredds/fileServer/dataset-l3-swot-karin-nadir-pre-validated/l3_lr_ssh/v1_0/Basic/cycle_014/SWOT_L3_LR_SSH_Basic_014_001_20240417T111950_20240417T121116_v1.0.nc"
[8]:
l3_file = http_download_file(l3_dataset_url, output_dir)
l3_file
[8]:
'downloads/SWOT_L3_LR_SSH_Basic_014_001_20240417T111950_20240417T121116_v1.0.nc'
Download files through FTP
Files available through FTP follow the same file tree as in the THREDDS Data Server.
Data |
FTP starting point |
Browsing files URL |
---|---|---|
Swot LR L2 |
/swot_products/l2_karin/l2_lr_ssh |
|
Swot LR L3 |
/swot_products/l3_karin_nadir/l3_lr_ssh |
Swot LR L2 data
[9]:
l2_ftp_path = '/swot_products/l2_karin/l2_lr_ssh/PGC0/WindWave/cycle_001/'
l2_ftp_file = 'SWOT_L2_LR_SSH_WindWave_001_155_20230726T173636_20230726T182805_PGC0_01.nc'
[10]:
l2_file = ftp_download_file(l2_ftp_path, l2_ftp_file, output_dir)
l2_file
Connection Established 220 192.168.10.119 FTP server ready
Downloaded SWOT_L2_LR_SSH_WindWave_001_155_20230726T173636_20230726T182805_PGC0_01.nc to downloads
[10]:
'downloads/SWOT_L2_LR_SSH_WindWave_001_155_20230726T173636_20230726T182805_PGC0_01.nc'
Swot LR L3 data
[11]:
l3_ftp_path = '/swot_products/l3_karin_nadir/l3_lr_ssh/v1_0/Basic/cycle_011/'
l3_ftp_file = 'SWOT_L3_LR_SSH_Basic_011_550_20240305T114902_20240305T124029_v1.0.nc'
[12]:
l3_file = ftp_download_file(l3_ftp_path, l3_ftp_file, output_dir)
l3_file
Connection Established 220 192.168.10.119 FTP server ready
Downloaded SWOT_L3_LR_SSH_Basic_011_550_20240305T114902_20240305T124029_v1.0.nc to downloads
[12]:
'downloads/SWOT_L3_LR_SSH_Basic_011_550_20240305T114902_20240305T124029_v1.0.nc'
Load subset via OPeNDAP
To find the data you want to subset, you can explore the Swot LR L2 or Swot LR L3 catalogues.
Copy the OPeNDAP url to subset data through Opendap :
Swot LR L2 data
[13]:
l2_dataset_url = "https://tds.aviso.altimetry.fr/thredds/dodsC/dataset-l2-swot-karin-lr-ssh-pre-validated/PIC0/Basic/cycle_014/SWOT_L2_LR_SSH_Basic_014_001_20240417T111950_20240417T121118_PIC0_01.nc"
[14]:
l2_dataset = open_opendap_dataset(l2_dataset_url)
l2_dataset
[14]:
<xarray.Dataset> Dimensions: (num_lines: 9866, num_pixels: 69, num_sides: 2) Coordinates: latitude (num_lines, num_pixels) float64 ... longitude (num_lines, num_pixels) float64 ... Dimensions without coordinates: num_lines, num_pixels, num_sides Data variables: (12/24) time (num_lines) datetime64[ns] ... time_tai (num_lines) datetime64[ns] ... ssh_karin (num_lines, num_pixels) float64 ... ssh_karin_qual (num_lines, num_pixels) float64 ... ssh_karin_uncert (num_lines, num_pixels) float32 ... ssha_karin (num_lines, num_pixels) float64 ... ... ... mean_sea_surface_cnescls (num_lines, num_pixels) float64 ... mean_sea_surface_cnescls_uncert (num_lines, num_pixels) float32 ... geoid (num_lines, num_pixels) float64 ... internal_tide_hret (num_lines, num_pixels) float32 ... height_cor_xover (num_lines, num_pixels) float64 ... height_cor_xover_qual (num_lines, num_pixels) float32 ... Attributes: (12/63) Conventions: CF-1.7 title: Level 2 Low Rate Sea Surfa... institution: CNES source: Ka-band radar interferometer history: 2024-04-19T22:01:03Z : Cre... platform: SWOT ... ... ellipsoid_flattening: 0.0033528106647474805 good_ocean_data_percent: 63.07686914249655 ssha_variance: 1.1479401224317318 _NCProperties: version=2,netcdf=4.9.2,hdf... references: V1.2.1 equator_longitude: 0.17
Select variables
[15]:
variables = ['time', 'ssha_karin_2', 'mean_sea_surface_cnescls']
[16]:
ds = l2_dataset[variables]
ds
[16]:
<xarray.Dataset> Dimensions: (num_lines: 9866, num_pixels: 69) Coordinates: latitude (num_lines, num_pixels) float64 ... longitude (num_lines, num_pixels) float64 ... Dimensions without coordinates: num_lines, num_pixels Data variables: time (num_lines) datetime64[ns] ... ssha_karin_2 (num_lines, num_pixels) float64 ... mean_sea_surface_cnescls (num_lines, num_pixels) float64 ... Attributes: (12/63) Conventions: CF-1.7 title: Level 2 Low Rate Sea Surfa... institution: CNES source: Ka-band radar interferometer history: 2024-04-19T22:01:03Z : Cre... platform: SWOT ... ... ellipsoid_flattening: 0.0033528106647474805 good_ocean_data_percent: 63.07686914249655 ssha_variance: 1.1479401224317318 _NCProperties: version=2,netcdf=4.9.2,hdf... references: V1.2.1 equator_longitude: 0.17
Select lines
Select lines to load
[17]:
idx_first, idx_last = 5000, 6000
[18]:
ds = xr.merge([ds[var][idx_first:idx_last] for var in variables])
[19]:
ds.load()
[19]:
<xarray.Dataset> Dimensions: (num_lines: 1000, num_pixels: 69) Coordinates: latitude (num_lines, num_pixels) float64 1.297 ... 18.96 longitude (num_lines, num_pixels) float64 359.7 ... 3.747 Dimensions without coordinates: num_lines, num_pixels Data variables: time (num_lines) datetime64[ns] 2024-04-17T11:45:57.... ssha_karin_2 (num_lines, num_pixels) float64 nan -2.287 ... nan mean_sea_surface_cnescls (num_lines, num_pixels) float64 17.35 ... 25.86 Attributes: long_name: time in UTC standard_name: time tai_utc_difference: 37.0 leap_second: 0000-00-00T00:00:00Z comment: Time of measurement in seconds in the UTC time scale... _ChunkSizes: 9866
Swot LR L3 data
[20]:
l3_dataset_url = "https://tds.aviso.altimetry.fr/thredds/dodsC/dataset-l3-swot-karin-nadir-pre-validated/l3_lr_ssh/v1_0/Basic/cycle_014/SWOT_L3_LR_SSH_Basic_014_350_20240429T223450_20240429T232617_v1.0.nc"
[21]:
l3_dataset = open_opendap_dataset(l3_dataset_url)
l3_dataset
[21]:
<xarray.Dataset> Dimensions: (num_lines: 9860, num_pixels: 69, num_nadir: 2095) Coordinates: latitude (num_lines, num_pixels) float64 ... longitude (num_lines, num_pixels) float64 ... Dimensions without coordinates: num_lines, num_pixels, num_nadir Data variables: time (num_lines) datetime64[ns] ... mdt (num_lines, num_pixels) float64 ... ssha (num_lines, num_pixels) float64 ... ssha_noiseless (num_lines, num_pixels) float64 ... i_num_line (num_nadir) int16 ... i_num_pixel (num_nadir) int8 ... Attributes: (12/43) Conventions: CF-1.7 Metadata_Conventions: Unidata Dataset Discovery v1.0 cdm_data_type: Swath comment: Sea Surface Height measured by Altimetry data_used: SWOT KaRIn L2_LR_SSH PIC0 (NASA/CNES). D... doi: https://doi.org/10.24400/527896/A01-2023... ... ... time_coverage_end: 2024-04-29T23:26:17Z geospatial_lat_min: -78.271903 geospatial_lat_max: 78.272068 geospatial_lon_min: 0.000145 geospatial_lon_max: 359.999524 _NCProperties: version=2,netcdf=4.9.2,hdf5=1.14.1
Select variables
[22]:
variables = ['time', 'ssha']
[23]:
ds = l3_dataset[variables]
ds
[23]:
<xarray.Dataset> Dimensions: (num_lines: 9860, num_pixels: 69) Coordinates: latitude (num_lines, num_pixels) float64 ... longitude (num_lines, num_pixels) float64 ... Dimensions without coordinates: num_lines, num_pixels Data variables: time (num_lines) datetime64[ns] ... ssha (num_lines, num_pixels) float64 ... Attributes: (12/43) Conventions: CF-1.7 Metadata_Conventions: Unidata Dataset Discovery v1.0 cdm_data_type: Swath comment: Sea Surface Height measured by Altimetry data_used: SWOT KaRIn L2_LR_SSH PIC0 (NASA/CNES). D... doi: https://doi.org/10.24400/527896/A01-2023... ... ... time_coverage_end: 2024-04-29T23:26:17Z geospatial_lat_min: -78.271903 geospatial_lat_max: 78.272068 geospatial_lon_min: 0.000145 geospatial_lon_max: 359.999524 _NCProperties: version=2,netcdf=4.9.2,hdf5=1.14.1
Select lines
Select lines to load
[24]:
idx_first, idx_last = 5000, 6000
[25]:
ds = xr.merge([ds[var][idx_first:idx_last] for var in variables])
[26]:
ds.load()
[26]:
<xarray.Dataset> Dimensions: (num_lines: 1000, num_pixels: 69) Coordinates: latitude (num_lines, num_pixels) float64 -1.155 -1.157 ... -19.19 -19.2 longitude (num_lines, num_pixels) float64 343.1 343.1 343.1 ... 344.6 344.6 Dimensions without coordinates: num_lines, num_pixels Data variables: time (num_lines) datetime64[ns] 2024-04-29T23:00:53.917956864 ... 2... ssha (num_lines, num_pixels) float64 nan nan nan nan ... nan nan nan Attributes: comment: Time of measurement in seconds in the UTC time scale... leap_second: 0000-00-00T00:00:00Z long_name: time in UTC standard_name: time tai_utc_difference: 37.0 _ChunkSizes: 9860
Store subset to NetCDF file
[ ]:
ds.to_netcdf(os.path.join(output_dir, 'dataset.nc'))