Mosaicing Sentinel-2 tiles in snappy

I’m trying to mosaic 2 Sentinel-2 tiles using snappy but when I execute this code:

products = jpy.array('org.esa.snap.core.datamodel.Product', 2)
products[0] = ProductIO.readProduct(sourcePath1)
products[1] = ProductIO.readProduct(sourcePath2)
bnames = products[0].getBandNames()  #Bands are the same for each product
parameters = HashMap()
parameters.put('variables',bnames)        
Mosaic = GPF.createProduct('Mosaic', parameters, products)

I get this error:
RuntimeError: org.esa.snap.core.gpf.OperatorException: Operator ‘MosaicOp’: Value for ‘Variables’ must be of type ‘Variable[]’.

Anybody knows what should I put inside the “variable” parameter?
Thank you!

Variables are not just names of Bands.

You can use gpt to get some more help.

gpt mosaic -h

Or open the mosaic processor in SNAP Desktop, configure it and the save or display the parameters from the file menu.

In snappy you need to do the following:

Variable = jpy.get_type('org.esa.snap.core.gpf.common.MosaicOp.Variable')
vars = jpy.array('org.esa.snap.core.gpf.common.MosaicOp.Variable', 3)
vars[0] = Variable('varName', 'expression')
...

Thank you @marpet for the answer, but when I execute:

Variable = jpy.get_type('org.esa.snap.core.gpf.common.MosaicOp.Variable') 

it gives me the error:
ValueError: Java class ‘org.esa.snap.core.gpf.common.MosaicOp.Variable’ not found
Any suggestions?

Ah, sorry. Because Variable is an inner class it needs to be

Variable = jpy.get_type('org.esa.snap.core.gpf.common.MosaicOp$Variable')

ok, if I execute my code now I get another error:
File “<'ipython-input-86-29d76134b16e>”, line 13, in
Mosaic = GPF.createProduct(‘Mosaic’, parameters, products)
RuntimeError: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0

This is the code snippet:

bandsok = ['B2','B3','B4','B8']
products = jpy.array('org.esa.snap.core.datamodel.Product', 2)
products[0] = ProductIO.readProduct(sourcePath1)
products[1] = ProductIO.readProduct(sourcePath2)
Variable = jpy.get_type('org.esa.snap.core.gpf.common.MosaicOp$Variable')
Vars = jpy.array('org.esa.snap.core.gpf.common.MosaicOp$Variable', len(bandsok))
ii=0
for band in bandsok:
    Vars[ii] = Variable(band, band)
    ii += 1
parameters = HashMap()
parameters.put('variables',Vars)        
Mosaic = GPF.createProduct('Mosaic', parameters, products)

But I have no object with 0 elements or anyway either products or parameters have elements…what’s the problem here?
Thank you very much for your replies.

What are your input products? If they are S2 products, they are multisize products and they cannot be used directly for the Mosaic operator.

In this case, you have two options:

  1. resampling the products previously (it is necessary although you are using only 10m bands)
  2. using the ‘Multi-size Mosaic’ operator instead of ‘Mosaic’
1 Like

Hello @obarrilero, thank you very much for your answer! I thought that by using only 10m bands I could avoid resampling. I understand, do you suggest the first or second option? By resampling a 10m band into 10m pixels I’m supposed to get a nearly (if not completely) identical image right?

EDIT: I chose to resample the images and it now works fine :slight_smile: thank you!

I was using code similar to the upper one by @atteggiani .
My products are just two tiff images, resampled, 750 MB each, with R-G-B channels only.
The I called the code for mosaicing and it was working for about an hour and in the end it gave an error

ProductIO.writeProduct(target_4, ‘D:\Mozaik\mosaicPY’, ‘GeoTIFF-BigTIFF’)
RuntimeError: javax.imageio.IIOException: I/O error writing TIFF file!

The thing is that I ran out of space on my D drive. Unfinished mosaic was as big as 150 GB!!! Still, this was just a test. I planned to do mosaicing for many more images at once.
Any solution to this? Comment?

Hi,
Are you defining the bounds and the pixelSize in your parameters? Perhaps your pixel size is very small for your image…

pixelSize is 10 m, but I haven’t set the bounds. I considered it will be recognized somehow by sanppy. I guess that could be the reason. Now I see that by default BB is quite large area.

Hey all,

I am also trying to create a mosaic of Sentinel-2 images using python, but can’t get it working.
When I try to run the below code I get the error: RuntimeError: org.esa.snap.core.gpf.OperatorException.
It looks like it is not able to run the following line in execfile: exec(compile(scripttext, filename, ‘exec’), glob, loc)

This is my code:

import snappy
import os
from snappy import ProductIO
from snappy import GPF
from snappy import HashMap

# input directory with all products
input_file_dir = 'G:\\S2\\2015_iCOR_combined\\2015_07_06_60m'
# output folder
output_dir = 'G:\\S2\\iCOR_mosaics\\60m' 

parameters = HashMap()
parameters.put('combine', 'OR') 
parameters.put('combine', 'OR')       
parameters.put('resampling', 'Nearest')
parameters.put('crs', 'EPSG:4326' )
parameters.put('westBound', '1.363832199040854')    
parameters.put('northBound', '52.57995161281976')
parameters.put('eastBound', '6.224271638606645')
parameters.put('southBound', '50.25859695650797')
parameters.put('pixelSizeX', 60.0)
parameters.put('pixelSizeY', 60.0)

# creating file with input images 
products = []
for product in os.listdir(input_file_dir):
       products.append(ProductIO.readProduct(os.path.join(input_file_dir, product)))

# creating mosaic
Mosaic = GPF.createProduct('Mosaic', parameters, products)
# Writing output
ProductIO.writeProduct(Mosaic, os.path.join(output_dir, '2015_07_06'), 'BEAM-DIMAP')

products are by my idea correct:
[org.esa.snap.core.datamodel.Product(objectRef=0x000000002E611228), org.esa.snap.core.datamodel.Product(objectRef=0x000000002E611200), org.esa.snap.core.datamodel.Product(objectRef=0x000000002E6111E8), org.esa.snap.core.datamodel.Product(objectRef=0x000000002E6111C0), org.esa.snap.core.datamodel.Product(objectRef=0x000000002E6111B0), org.esa.snap.core.datamodel.Product(objectRef=0x000000002E610EA8)]

I hope someone can help me out with this problem :slight_smile:.

p.s. If I use snap desktop with these images and with similar settings it works correctly.

Hi - were you able to sort out this problem? If so, can you please tell me how you did it?