Well the behaviour described above seems not to be always respected somehow:
sometimes it completes the stacking in a total time equal to the sum of each single band stacking time;
some other times it takes so much more time (usually for the last band);
sometimes it even takes a lot of time for doing only a stack of 1 single band…
These cases always using the same files.
I don’t know why this behaviour, I don’t think that my CPU or RAM usage was affecting the results so much but I can’t be sure about it.
Anyway this is the code I did for stacking (for anyone who might want to use it as well)
def stack(InputFold=None, OutputFold = None, bnames = None):
'''stack(InputFold = None,OutputFold = None, bnames = None) makes you select an input directory InputFold and creates a time stack with all the ".dim" files in that directory.
One stacked product is created for each band in bnames (The band is required to be presented in all the files in the InputFold).
The new products are stored in the output directory OutputFold.
If no OutputFold is given, the function will create it in the same parent directory of the InputFold directory, and will name it by appending '_STACK' to the InputFold name.
In addition to the bands at different times, for each product 2 bands with LAT and LON values per pixel are created.'''
import os
import snappy
import re
from snappy import HashMap, ProductIO, GPF, jpy, Product, ProductUtils
import glob
import tkinter as tk
from tkinter import filedialog
import time
import sys
if InputFold is None:
root=tk.Tk()
root.call('wm', 'attributes', '.', '-topmost', '1')
root.withdraw();
InputFold = tk.filedialog.askdirectory(parent=root,initialdir = r'E:\Users\Davide_Marchegiani\SoilMoisture')
if OutputFold is None:
OutputFold = InputFold + '_STACK'
os.makedirs(OutputFold,exist_ok=True)
print('Begin algorithm...')
sys.stdout.flush()
st=time.time()
files_list=glob.glob(InputFold+'\*.dim')
files_list=sorted(files_list,key=lambda x: os.path.split(x)[1][4:])
#Initialize snappy
HashMap = jpy.get_type('java.util.HashMap')
#Get snappy operators
GPF.getDefaultInstance().getOperatorSpiRegistry().loadOperatorSpis()
ind1= [m.start() for m in re.finditer('_',os.path.split(files_list[0])[1])]
ind2= [m.start() for m in re.finditer('_',os.path.split(files_list[-1])[1])]
#Differentiate between S1 and S2
if os.path.split(files_list[0])[1][1] is '1':
date_start = os.path.split(files_list[0])[1][ind1[3]+1:ind1[3]+9]
date_end = os.path.split(files_list[-1])[1][ind2[3]+1:ind2[3]+9]
elif os.path.split(files_list[0])[1][1] is '2':
date_start = os.path.split(files_list[0])[1][ind1[1]+1:ind1[1]+9]
date_end = os.path.split(files_list[-1])[1][ind2[1]+1:ind2[1]+9]
#==============================================================================
# CREATE NUMBER OF PRODUCTS EQUAL TO len(bnames)
#==============================================================================
source = ProductIO.readProduct(os.path.join(InputFold,files_list[0]))
if bnames is None:
bnames = source.getBandNames()
elif type(bnames) is str:
bnames=[bnames]
width=source.getSceneRasterWidth()
height=source.getSceneRasterHeight()
writer = ProductIO.getProductWriter('BEAM-DIMAP')
products = jpy.array('org.esa.snap.core.datamodel.Product',len(bnames))
for i in range(len(bnames)):
products[i] = Product(bnames[i]+'_Stack_'+date_start+'_'+date_end, source.getProductType(), width, height)
snappy.ProductUtils.copyGeoCoding(source, products[i])
products[i].setProductWriter(writer)
#==============================================================================
# LOOP OVER THE FILES
#==============================================================================
print('Stacking the bands...')
sys.stdout.flush()
for file in files_list:
ind= [m.start() for m in re.finditer('_',os.path.split(file)[1])]
#Differentiate between S1 and S2
if os.path.split(files_list[0])[1][1] is '1':
date = os.path.split(file)[1][ind[3]+1:ind[3]+9]
elif os.path.split(files_list[0])[1][1] is '2':
date = os.path.split(file)[1][ind[1]+1:ind[1]+9]
# OPEN FILES
source = ProductIO.readProduct(file)
# ADD THE SELECTED BANDS TO THE PRODUCTS CREATED
for i in range(len(bnames)):
ProductUtils.copyBand(bnames[i],source,bnames[i]+'_'+date,products[i],True)
#==============================================================================
# ADD LAT and LON BANDS TO THE PRODUCTS
#==============================================================================
# # THIS PART HAS BEEN COMMENTED BECAUSE IT SEEMS NOT TO WORK AS IT SHOULD.
# # ADDING THE LAT AND LON BANDS FROM GUI BANDMATHS WORKS FINE.
#
#
# print('Adding LON and LAT bands...')
# sys.stdout.flush()
# BandDescriptor = jpy.get_type('org.esa.snap.core.gpf.common.BandMathsOp$BandDescriptor')
#
# #Latitude Band
# lat = BandDescriptor()
# lat.name = 'Lat'
# lat.type = 'float64'
# lat.expression = 'LAT'
# #Longitude Band
# lon = BandDescriptor()
# lon.name = 'Lon'
# lon.type = 'float64'
# lon.expression = 'LON'
#
# newBands = jpy.array('org.esa.snap.core.gpf.common.BandMathsOp$BandDescriptor', 2)
# newBands[0] = lat
# newBands[1] = lon
# #Compute BANDMATHS Operator
# parameters = HashMap()
# parameters.put('targetBands', newBands)
# prod1 = GPF.createProduct('BandMaths', parameters, source)
# #Get new bands and add to the Products created
# for prod in products:
# ProductUtils.copyBand('Latitude',prod1,prod,True)
# ProductUtils.copyBand('Longitude',prod1,prod,True)
#==============================================================================
# WRITE PRODUCTS TO FILE
#==============================================================================
for prod in products:
print('Writing product "{}"...'.format(prod.getName()))
sys.stdout.flush()
time.sleep(.1)
ProductIO.writeProduct(prod,os.path.join(OutputFold,os.path.split(files_list[-1])[1][1:ind[3]]+'_'+prod.getName()), 'BEAM-DIMAP')
print('Product "{}" wrote! - t = {:.2f}s'.format(prod.getName(),time.time()-st))
print('Done! - t = {:.2f}s'.format(time.time()-st))
If you can find any problems related to time consume let me know, thank you!