image1

SWOT L2 KaRIn LR Ocean Data Products

This tutorial will introduce you to some sample SWOT L2 KaRIn LR data products and show you how to download these data from AVISO and perform basic plots using Python related libraries.

Tutorial Objectives

  • Present SWOT sample L2 KaRIn LR data products (Basic version)

  • Show you how to find and visualize SWOT Sea Level Anomaly (SLA) data sets from AVISO FTP server

  • Download SWOT KaRIn (2D swaths) data

Import + code

[25]:
# Install Cartopy with mamba to avoid discrepancies
# ! mamba install -q -c conda-forge cartopy
[26]:
import requests
import numpy as np
import xarray as xr

import os
import ftplib
from getpass import getpass
import cartopy.crs as ccrs
import cartopy.feature as cft
import cartopy.mpl.geoaxes as cmplgeo
import cartopy.mpl.gridliner as cmplgrid
import matplotlib.pyplot as plt
# %matplotlib inline
[27]:
def ftp_data_access(ftp_path, filename, username=None, password=None, local_filepath=None):
    # Set up FTP server details
    ftpAVISO = 'ftp-access.aviso.altimetry.fr'

    try:
        # Prompt for username and password
        if not username:
            username = input("Enter username for AVISO: ")
        if not password:
            password = getpass(prompt=f"Enter password for {username}: ")

        # 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():
                if not local_filepath: local_filepath = input("Enter the local directory to save the file: ")
                return download_file_from_ftp(ftp, filename, local_filepath)
            else:
                print(f"File {filename} does not exist in the directory.")
    except ftplib.error_perm as e:
        print(f"FTP error: {e}")
    except Exception as e:
        print(f"Error: {e}")

def download_file_from_ftp(ftp, filename, target_directory):
    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 {local_filepath}")
            return local_filepath
    except Exception as e:
        print(f"Error downloading {filename}: {e}")

Parameters

Define a local filepath to download files

[28]:
local_filepath='/tmp'

Authentication parameters

Enter your AVISO+ credentials

[29]:
username = input("Enter username:")
Enter username: cyril.germineaud@cnes.fr
[30]:
password = getpass(f"Enter password for {username}:")
Enter password for cyril.germineaud@cnes.fr: ········

FTP download

[31]:
# Define directories
ftp_path_basic = '/swot_products/l2_karin/l2_lr_ssh/PGC0/Basic/cycle_007/'
filename_basic = 'SWOT_L2_LR_SSH_Basic_007_317_20231204T170132_20231204T175300_PGC0_01.nc'

# FTP download
half_orbit_basic = ftp_data_access(ftp_path_basic, filename_basic, username, password, local_filepath)
half_orbit_basic
Connection Established 220 192.168.10.119 FTP server ready
Downloaded SWOT_L2_LR_SSH_Basic_007_317_20231204T170132_20231204T175300_PGC0_01.nc to /tmp/SWOT_L2_LR_SSH_Basic_007_317_20231204T170132_20231204T175300_PGC0_01.nc
[31]:
'/tmp/SWOT_L2_LR_SSH_Basic_007_317_20231204T170132_20231204T175300_PGC0_01.nc'

Select regional boundaries

[32]:
localbox = [233, 239, 35, 42] # California

Discover SWOT L2 KaRIn Ocean Basic product

Basic product content

This product contains two versions of SLA (ssha in the datasets) with different wet troposhere and sea state bias (SSB) corrections: - ssha_karin relies more on observations (e.g., wet tropo corrected using radiometer data) - ssha_karin_2 relies more on model for corrections (e.g., wet tropo corrected using ECMWF model)

[33]:
ds_basic =  xr.open_dataset(half_orbit_basic)
[v for v in ds_basic.variables]
[33]:
['time',
 'time_tai',
 'latitude',
 'longitude',
 'ssh_karin',
 'ssh_karin_qual',
 'ssh_karin_uncert',
 'ssha_karin',
 'ssha_karin_qual',
 'ssh_karin_2',
 'ssh_karin_2_qual',
 'ssha_karin_2',
 'ssha_karin_2_qual',
 'num_pt_avg',
 'distance_to_coast',
 'heading_to_coast',
 'ancillary_surface_classification_flag',
 'dynamic_ice_flag',
 'rain_flag',
 'rad_surface_type_flag',
 'mean_sea_surface_cnescls',
 'mean_sea_surface_cnescls_uncert',
 'geoid',
 'internal_tide_hret',
 'height_cor_xover',
 'height_cor_xover_qual']
[34]:
# Select data over the region
lolasubset = (
(ds_basic.longitude > localbox[0]) &
(ds_basic.longitude < localbox[1]) &
(ds_basic.latitude > localbox[2]) &
(ds_basic.latitude < localbox[3]))
#
ds_basic_sub = ds_basic.where(lolasubset, drop=True)
ds_basic_sub = ds_basic_sub.assign_coords(longitude=(((ds_basic_sub.longitude + 180) % 360) - 180))

Application of Crossover Calibration Correction (XOverCal or xover)

To get corrected SSHA, user must apply the xover as follows: - ssha_karin_corrected = ssha_karin + height_cor_xover - ssha_karin_2_corrected = ssha_karin_2 + height_cor_xover

[35]:
ds_basic_sub['ssha_karin_corrected'] = ds_basic_sub.ssha_karin + ds_basic_sub.height_cor_xover
ds_basic_sub['ssha_karin_2_corrected'] = ds_basic_sub.ssha_karin_2 + ds_basic_sub.height_cor_xover
ds_basic_sub
[35]:
<xarray.Dataset> Size: 6MB
Dimensions:                                (num_lines: 414, num_pixels: 69,
                                            num_sides: 2)
Coordinates:
    latitude                               (num_lines, num_pixels) float64 229kB ...
    longitude                              (num_lines, num_pixels) float64 229kB ...
Dimensions without coordinates: num_lines, num_pixels, num_sides
Data variables: (12/26)
    time                                   (num_lines, num_pixels) datetime64[ns] 229kB ...
    time_tai                               (num_lines, num_pixels) datetime64[ns] 229kB ...
    ssh_karin                              (num_lines, num_pixels) float64 229kB ...
    ssh_karin_qual                         (num_lines, num_pixels) float64 229kB ...
    ssh_karin_uncert                       (num_lines, num_pixels) float64 229kB ...
    ssha_karin                             (num_lines, num_pixels) float64 229kB ...
    ...                                     ...
    geoid                                  (num_lines, num_pixels) float64 229kB ...
    internal_tide_hret                     (num_lines, num_pixels) float64 229kB ...
    height_cor_xover                       (num_lines, num_pixels) float64 229kB ...
    height_cor_xover_qual                  (num_lines, num_pixels) float32 114kB ...
    ssha_karin_corrected                   (num_lines, num_pixels) float64 229kB ...
    ssha_karin_2_corrected                 (num_lines, num_pixels) float64 229kB ...
Attributes: (12/62)
    Conventions:                                   CF-1.7
    title:                                         Level 2 Low Rate Sea Surfa...
    institution:                                   JPL
    source:                                        Ka-band radar interferometer
    history:                                       2024-04-03T10:59:55Z : Cre...
    platform:                                      SWOT
    ...                                            ...
    ellipsoid_semi_major_axis:                     6378137.0
    ellipsoid_flattening:                          0.0033528106647474805
    good_ocean_data_percent:                       65.90908627485365
    ssha_variance:                                 0.23576802674130506
    references:                                    V1.2.1
    equator_longitude:                             -130.51

Mask invalid data

[36]:
ds_basic_sub["ssha_karin_corrected"] = ds_basic_sub.ssha_karin_corrected.where(ds_basic_sub.ancillary_surface_classification_flag==0)
ds_basic_sub["ssha_karin_corrected"] = ds_basic_sub.ssha_karin_corrected.where(ds_basic_sub.ssha_karin_qual==0)

[37]:
ds_basic_sub["ssha_karin_2_corrected"] = ds_basic_sub.ssha_karin_2_corrected.where(ds_basic_sub.ancillary_surface_classification_flag==0)
ds_basic_sub["ssha_karin_2_corrected"] = ds_basic_sub.ssha_karin_2_corrected.where(ds_basic_sub.ssha_karin_2_qual==0)

Output visualisation: basic SLA plots

Let’s visualise SWOT KaRIn LR data using cartopy

[38]:
# set figure
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(21, 12), subplot_kw=dict(projection=ccrs.PlateCarree()))
ax1.set_extent(localbox)
ax2.set_extent(localbox)
plot_kwargs = dict(
    x="longitude",
    y="latitude",
    cmap="Spectral_r",
    vmin=-0.2,
    vmax=0.2,
    cbar_kwargs={"shrink": 0.3},)

# SWOT KaRIn SLA plots
ds_basic_sub.ssha_karin_corrected.plot.pcolormesh(ax=ax1, **plot_kwargs)
ds_basic_sub.ssha_karin_2_corrected.plot.pcolormesh(ax=ax2, **plot_kwargs)
#
ax1.gridlines(draw_labels=True)
ax1.coastlines()
ax2.gridlines(draw_labels=True)
ax2.coastlines()
ax2.gridlines()
[38]:
<cartopy.mpl.gridliner.Gridliner at 0x306452350>
../_images/SWOT-Oceanography_ex_swot_l2_basic_startup_aviso_ftp_27_1.png