SAR example
Contents
SAR example#
Let’s use EOReader with SAR data.
Warning: SAR data is processed with SNAP, so be sure to have it installed and that GPT
is in your path.
Imports#
import os
import logging
import matplotlib.pyplot as plt
# EOReader
from eoreader.reader import Reader
from eoreader.bands import VV, HH, VV_DSPK, HH_DSPK, HILLSHADE, SLOPE, to_str
from eoreader.env_vars import DEM_PATH
Create logger#
# Create logger
logger = logging.getLogger("eoreader")
logger.setLevel(logging.INFO)
# create console handler and set level to debug
ch = logging.StreamHandler()
ch.setLevel(logging.INFO)
# create formatter
formatter = logging.Formatter('%(message)s')
# add formatter to ch
ch.setFormatter(formatter)
# add ch to logger
logger.addHandler(ch)
Open the COSMO-SkyMed product#
Please be aware that:
EOReader will orthorectify your SAR data to get UTM tiles.
complex data is not handled as is, EOReader will convert them to ground range.
# First of all, we need some VHR data, let's use some COSMO-SkyMed data
path = os.path.join("/home", "data", "DATA", "PRODS", "COSMO", "1st_GEN", "1001512-735097")
# Open your product
prod = Reader().open(path, remove_tmp=True)
prod
eoreader.CskProduct 'CSKS4_DGM_B_HI_09_HH_RA_FF_20201008224018_20201008224025'
Attributes:
condensed_name: 20201008T224018_CSK_HH_HI_DGM
path: /home/data/DATA/PRODS/COSMO/1st_GEN/1001512-735097
constellation: COSMO-SkyMed
sensor type: SAR
product type: DGM
default resolution: 5.0
acquisition datetime: 2020-10-08T22:40:18.446381
band mapping:
HH: HH
HH_DSPK: HH_DSPK
needs extraction: True
orbit direction: ASCENDING
# Plot the quicklook
prod.plot()
/opt/conda/lib/python3.10/site-packages/rasterio/__init__.py:277: NotGeoreferencedWarning: Dataset has no geotransform, gcps, or rpcs. The identity matrix will be returned.
dataset = DatasetReader(path, driver=driver, sharing=sharing, **kwargs)
/opt/conda/lib/python3.10/site-packages/rioxarray/_io.py:924: NotGeoreferencedWarning: Dataset has no geotransform, gcps, or rpcs. The identity matrix will be returned.
warnings.warn(str(rio_warning.message), type(rio_warning.message)) # type: ignore
/opt/conda/lib/python3.10/site-packages/rasterio/__init__.py:287: NotGeoreferencedWarning: The given matrix is equal to Affine.identity or its flipped counterpart. GDAL may ignore this matrix and save no geotransform without raising an error. This behavior is somewhat driver-specific.
dataset = writer(
Warning 1: /tmp/tmp76e5z02s/tmp_20201008T224018_CSK_HH_HI_DGM/20201008T224018_CSK_HH_HI_DGM_QLK.tif: Metadata exceeding 32000 bytes cannot be written into GeoTIFF. Transferred to PAM instead.

# Get the band information
prod.bands
eoreader.SarBand 'HH'
Attributes:
id: HH
eoreader_name: HH
gsd (m): 5.0
asset_role: intensity
eoreader.SarBand 'HH_DSPK'
Attributes:
id: HH_DSPK
eoreader_name: HH_DSPK
gsd (m): 5.0
asset_role: intensity
# Print some data
print(f"Acquisition datetime: {prod.datetime}")
print(f"Condensed name: {prod.condensed_name}")
# Open here some more interesting geographical data: extent and footprint
extent = prod.extent()
footprint = prod.footprint()
base = extent.plot(color='cyan', edgecolor='black')
footprint.plot(ax=base, color='blue', edgecolor='black', alpha=0.5)
Acquisition datetime: 2020-10-08 22:40:18.446381
Condensed name: 20201008T224018_CSK_HH_HI_DGM
Executing processing graph
....10%....20%....30%....40%....50%....60%....70%....80%....90% done.
/opt/conda/lib/python3.10/site-packages/rasterio/__init__.py:277: NotGeoreferencedWarning: Dataset has no geotransform, gcps, or rpcs. The identity matrix will be returned.
dataset = DatasetReader(path, driver=driver, sharing=sharing, **kwargs)
<AxesSubplot: >

For SAR data, the footprint needs the orthorectified data !
For that, SNAP uses its own DEM, but you can change it when positionning the EOREADER_SNAP_DEM_NAME
environment variable.
Available DEMs are:
ACE2_5Min
ACE30
ASTER 1sec GDEM
Copernicus 30m Global DEM
Copernicus 90m Global DEM
GETASSE30
(by default)SRTM 1Sec HGT
SRTM 3Sec
External DEM
Warning:
If External DEM
is set, you must specify the DEM you want by positioning the EOREADER_DEM_PATH
to a DEM that can be read by SNAP.
Load bands#
# Set the DEM
os.environ[DEM_PATH] = os.path.join("/home", "data", "DS2", "BASES_DE_DONNEES", "GLOBAL", "COPDEM_30m", "COPDEM_30m.vrt")
# Select some bands you wish to load without knowing if they exist
bands = [VV, HH, VV_DSPK, HH_DSPK, HILLSHADE, SLOPE]
# Only keep those selected
ok_bands = [band for band in bands if prod.has_band(band)]
# This product does not have VV band and HILLSHADE band cannot be computed from SAR band
print(to_str(ok_bands))
['HH', 'HH_DSPK', 'SLOPE']
# Load those bands as a dict of xarray.DataArray, with a 20m resolution
band_dict = prod.load(ok_bands, resolution=20.)
band_dict[HH]
Executing processing graph
first_line_time metadata value is null
last_line_time metadata value is null
...10%...21%...32%...43%...54%...65%...76%...87%. done.
<xarray.DataArray 'HH' (band: 1, y: 2473, x: 2688)> array([[[nan, nan, nan, ..., nan, nan, nan], [nan, nan, nan, ..., nan, nan, nan], [nan, nan, nan, ..., nan, nan, nan], ..., [nan, nan, nan, ..., nan, nan, nan], [nan, nan, nan, ..., nan, nan, nan], [nan, nan, nan, ..., nan, nan, nan]]], dtype=float32) Coordinates: * x (x) float64 2.058e+05 2.059e+05 ... 2.596e+05 2.596e+05 * y (y) float64 1.746e+06 1.746e+06 ... 1.697e+06 1.697e+06 * band (band) int64 1 spatial_ref int64 0 Attributes: AREA_OR_POINT: Area bands: 1 Band_1: Sigma0_HH_db band_names: Sigma0_HH_db byte_order: 1 coordinate_system_string: PROJCS["WGS 84 / UTM zone 49N", GEOGCS["WGS 84... data_gain_values: 1.0 data_offset_values: 0.0 data_type: 4 description: HIMAGE - Unit: intensity_db file_type: ENVI Standard header_offset: 0 interleave: bsq lines: 9893 long_name: HH samples: 10752 scale_factor: 1.0 add_offset: 0.0 constellation: COSMO-SkyMed constellation_id: CSK product_path: /home/data/DATA/PRODS/COSMO/1st_GEN/1001512-73... product_name: CSKS4_DGM_B_HI_09_HH_RA_FF_20201008224018_2020... product_filename: 1001512-735097 instrument: SAR-2000 product_type: DGM acquisition_date: 20201008T224018 condensed_name: 20201008T224018_CSK_HH_HI_DGM orbit_direction: ASCENDING
This can lead the Terrain Correction
step to create large nodata area when projecting on a DEM.
If it happens, you can set the keyword SAR_INTERP_NA
to True
when loading or stacking SAR data to fill these area with interpolated data.
from eoreader.keywords import SAR_INTERP_NA
band_dict = prod.load(
ok_bands,
resolution=20.,
**{SAR_INTERP_NA: True}
)
# Plot a subsampled version
band_dict[SLOPE][:, ::10, ::10].plot()
<matplotlib.collections.QuadMesh at 0x7ff8763bbfa0>

Stack some data#
# You can also stack those bands
stack = prod.stack(ok_bands)
stack
<xarray.DataArray 'HH_HH_DSPK_SLOPE' (z: 3, y: 9893, x: 10752)> array([[[ nan, nan, nan, ..., nan, nan, nan], [ nan, nan, nan, ..., nan, nan, nan], [ nan, nan, nan, ..., nan, nan, nan], ..., [ nan, nan, nan, ..., nan, nan, nan], [ nan, nan, nan, ..., nan, nan, nan], [ nan, nan, nan, ..., nan, nan, nan]], [[ nan, nan, nan, ..., nan, nan, nan], [ nan, nan, nan, ..., nan, nan, nan], [ nan, nan, nan, ..., nan, nan, nan], ... [ nan, nan, nan, ..., nan, nan, nan], [ nan, nan, nan, ..., nan, nan, nan], [ nan, nan, nan, ..., nan, nan, nan]], [[ 0.23764595, 0.23764595, 0.23764595, ..., 0. , 0. , 0. ], [ 0.23764595, 0.23764595, 0.23764595, ..., 0. , 0. , 0. ], [ 0.23764595, 0.23764595, 0.23764595, ..., 0. , 0. , 0. ], ..., [16.46719 , 16.46719 , 16.46719 , ..., 0.08529702, 0.08529702, 0.08529702], [16.46719 , 16.46719 , 16.46719 , ..., 0.08529702, 0.08529702, 0.08529702], [16.81581 , 16.81581 , 16.81581 , ..., 0.0906441 , 0.0906441 , 0.0906441 ]]], dtype=float32) Coordinates: * x (x) float64 2.058e+05 2.058e+05 ... 2.596e+05 2.596e+05 * y (y) float64 1.746e+06 1.746e+06 ... 1.697e+06 1.697e+06 spatial_ref int64 0 * z (z) object MultiIndex * variable (z) object 'HH' 'HH_DSPK' 'SLOPE' * band (z) int64 1 1 1 Attributes: long_name: HH HH_DSPK SLOPE constellation: COSMO-SkyMed constellation_id: CSK product_path: /home/data/DATA/PRODS/COSMO/1st_GEN/1001512-735097 product_name: CSKS4_DGM_B_HI_09_HH_RA_FF_20201008224018_20201008224025 product_filename: 1001512-735097 instrument: SAR-2000 product_type: DGM acquisition_date: 20201008T224018 condensed_name: 20201008T224018_CSK_HH_HI_DGM orbit_direction: ASCENDING
# Plot a subsampled version
nrows = len(stack)
fig, axes = plt.subplots(nrows=nrows, figsize=(3 * nrows, 6 * nrows), subplot_kw={"box_aspect": 1})
for i in range(nrows):
stack[i, ::10, ::10].plot(x="x", y="y", ax=axes[i])
