Skip to content

GeoTIFF-BigTIFF output from Terrain-Correction writes border pixels as 0 instead of NoData #11

@crdmacedo

Description

@crdmacedo

When processing Sentinel-1 GRD data with SNAP (via snappy / GPF), the GeoTIFF-BigTIFF output generated after Terrain-Correction contains zero-valued pixels at image borders, where NoData or NaN values are expected.

This occurs even when attempting to define NoData explicitly (via SetNoDataValue or BandMaths).
This behavior affects products and makes it difficult to distinguish between physically valid zero backscatter or invalid / out-of-swath pixels.

Is there a recommended way to force NoData (-9999, float32) propagation to GeoTIFF outputs after Terrain-Correction? Or is this a known limitation/bug in the GeoTIFF writer for floating-point products?

Minimal reproducible example:

`
from esa_snappy import ProductIO, HashMap, GPF
import os

proj = 'WGS84(DD)'

def do_apply_orbit_file(source):
parameters = HashMap()
parameters.put('Apply-Orbit-File', True)
return GPF.createProduct('Apply-Orbit-File', parameters, source)

def do_remove_grd_border_noise(source):
return GPF.createProduct('Remove-GRD-Border-Noise', HashMap(), source)

def do_thermal_noise_removal(source):
parameters = HashMap()
parameters.put('removeThermalNoise', True)
return GPF.createProduct('ThermalNoiseRemoval', parameters, source)

def do_calibration(source):
parameters = HashMap()
parameters.put('outputSigmaBand', False)
parameters.put('outputBetaBand', True)
return GPF.createProduct("Calibration", parameters, source)

def do_terrain_flattening(source):
parameters = HashMap()
parameters.put('demName', 'Copernicus 30m Global DEM')
parameters.put('nodataValueAtSea', False)
return GPF.createProduct("Terrain-Flattening", parameters, source)

def do_terrain_correction(source, proj):
parameters = HashMap()
parameters.put('demName', 'Copernicus 30m Global DEM')
parameters.put('mapProjection', proj)
parameters.put('nodataValueAtSea', False)
parameters.put('saveSelectedSourceBand', True)
parameters.put('saveLocalIncidenceAngle', True)
return GPF.createProduct('Terrain-Correction', parameters, source)

def do_subset_band(source, band_name):
parameters = HashMap()
parameters.put('sourceBands', band_name)
return GPF.createProduct('Subset', parameters, source)

path = './data_s1/GRD/S1A_IW_GRDH_1SDV_20250704T094105_20250704T094130_059932_0771DC_011E.SAFE'
outpath = './s1_preprocessed/GRD'
os.makedirs(outpath, exist_ok=True)

product = ProductIO.readProduct(os.path.join(path, 'manifest.safe'))

applyorbit = do_apply_orbit_file(product)
removebordernoise = do_remove_grd_border_noise(applyorbit)
thermalnoiseremoval = do_thermal_noise_removal(removebordernoise)
calibration = do_calibration(thermalnoiseremoval)
terrainflattening = do_terrain_flattening(calibration)
rtc = do_terrain_correction(terrainflattening, proj)

gamma0_vv = do_subset_band(rtc, 'Gamma0_VV')

output = os.path.join(outpath, 'gamma0VV_RTC')
ProductIO.writeProduct(gamma0_vv, output, 'GeoTIFF-BigTIFF')
`

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions