copyGeoCoding issues in SNAP 10+ (Merge operator crashes after GeoTIFF export)

I’m trying to apply geocoding to a TIFF file based on an existing Sentinel-1 product, export it as a GeoTIFF, and later merge it with the original product. This workflow used to work with SNAP ≤ 9, but in SNAP 10, 11, and 12 the behavior has changed. FYI, the product bands are in radar coordinates.

Here’s a minimal example of what I’m doing:

# Open and prepare product (read, split, apply orbit, deburst, subset)
product = ProductIO.readProduct('S1A_IW_SLC__1SDV_20230804T050511_20230804T050538_049721_05FA95_8BED.zip')

# Despeckle and save result to tiff file
# (run CNN) 

# Open tif, copy geocoding, write to geotiff
ds = gdal.Open('input.tif')
nda = ds.ReadAsArray()
nda = nda.astype('float32')
height = nda.shape[0]
width = nda.shape[1]

product_new = Product('titleI', 'title', width, height)
bandname_despeckled = 'Intensity_fcnn_VV'
band = product_new.addBand(bandname_despeckled, ProductData.TYPE_FLOAT32)
ProductUtils.copyGeoCoding(product, product_new)  # FUNDAMENTAL, else cannot merge with source product (copy geocoding from source product)
writer = ProductIO.getProductWriter('GeoTIFF')
product_new.setProductWriter(writer)
product_new.writeHeader('output.tif')
band.writePixels(0, 0, width, height, nda)

# Read geotiff
product_new = ProductIO.readProduct('output.tif')

# Merge products
parameters = HashMap()
sources = HashMap()
sources.put('masterProduct', product)
sources.put('sourceProducts', product_new)
p = GPF.createProduct('Merge', parameters, sources)

Observed behavior in SNAP ≥ 10:

  • Reading the GeoTIFF produces warnings:
Warning: TIFFFetchNormalTag: Incorrect count for "GeoTiePoints"; tag ignored
Warning: PROJ: proj_create_from_database ... contains DATABASE.LAYOUT.VERSION.MINOR = 2 whereas a number >= 6 is expected
  • Merging fails:
INFO: org.esa.snap.core.datamodel.Product: first scan line left corner ... not equal to ...
RuntimeError: org.esa.snap.core.gpf.OperatorException: Product [sourceProducts] is not compatible to master product.
  • details about the original and new product geocoding
=== ORIGINAL product ===
size (w,h): 4253 1241
bands: ['i_IW2_VH', 'q_IW2_VH', 'Intensity_IW2_VH', 'i_IW2_VV', 'q_IW2_VV', 'Intensity_IW2_VV']
corners: {'UL': (15.1121484251098, 37.811124450757156), 'UR': (14.917135617563586, 37.83882302330232), 'LL': (15.079239369564279, 37.65753273616408), 'LR': (14.893348167244312, 37.684014540704936)}
xres, yres: -4.3455124998814654e-05 -0.00012359915817228284
CRS WKT (first 200 chars):
GEOGCS["WGS84(DD)",    DATUM["WGS84",      SPHEROID["WGS84", 6378137.0, 298.257223563]],    PRIMEM["Greenwich", 0.0],    UNIT["degree", 0.017453292519943295],    AXIS["Geodetic longitude", EAST],    A

=== NEW product ===
size (w,h): 4253 1241
bands: ['band_1']
corners: {'UL': (0.0, -0.0), 'UR': (4252.0, -0.0), 'LL': (0.0, -1240.0), 'LR': (4252.0, -1240.0)}
xres, yres: 1.0 -1.0
CRS WKT (first 200 chars):
GEOGCS["WGS 84",    DATUM["World Geodetic System 1984",      SPHEROID["WGS 84", 6378137.0, 298.257223563]],    PRIMEM["Greenwich", 0.0],    UNIT["degree", 0.017453292519943295],    AXIS["Longitude", E

Questions:

  • Has the behavior of ProductUtils.copyGeoCoding changed in SNAP ≥ 10?
  • Is there a recommended workflow to copy geocoding so that products can be merged successfully?

Any guidance or examples would be greatly appreciated.

Thank you!