I am currently implementing a processor for SNAP in Python.
At the beginning of my computations I cut the source product (as not all data is relevant) and I also want to add a new band with additional data.
The additional data is loaded as tiff and converted to a numpy array. It has the same dimensions as the sub_product
Without knowing the complete code you have written, but you should not write product within an operator. This is something you should leave to the framework. Also I think you should not use the subset operator in your operator.
Just process what you get and let it up to the user to subset the region.
The user can use a graph to set up a processing chain.
I guess the ref_image is some ancillary data. How to deal with it depends where it comes from and how it should be used.
In general, I think, it would be good to read it as a second product. And then use ProductUtils.copyband(âŚ)
I am trying to save a numpy array as a new band in a product, without having to write a temporary DIM file.
Indeed, my current workflow is: 1) export bands of a Sentinel-1 product as numpy arrays, 2) perform operations on these using numpy, 3) save the resulting array in a DIM file (following snappy_ndvi.py), 4) open this new DIM file with snappy + merge it with the original product (using the âMergeâ operator), and 5) geocode the product (using the âBack-Geocodingâ operator).
I have been trying to avoid having to write a temporary DIM file, but without any success. The following code results in an empty band (Error âjava.lang.NullPointerExceptionâ). The variable D is a numpy array which I want to save as a new band.
from snappy import ProductData
from snappy import ProductIO
height, width = D.shape
targetBand = p.addBand('newBand', ProductData.TYPE_FLOAT32)
writer = ProductIO.getProductWriter('BEAM-DIMAP')
p.setProductWriter(writer)
for y in range(height):
print("processing line {}/{}".format(y, height))
d = D[y,:]
#targetBand.writePixels(0, y, width, 1, d) #writePixels writes values to disk and by passes the band/product
targetBand.setPixels(0, y, width, 1, d)
Could you please point at what I am doing wrong? Many thanks in advance!
If you set the pixels you are not writing them out - they are only in memory. However, I guess you have already tried the writePixels line above that? Did you add the line p.closeIO() after writing to the band?
A NullPointerException is not the same as an empty band. Can you tell in which line the exception occurs and maybe even what object is null/None there?
If you want to stick to the code you already have, you could call the operators from your code (see snappy_subset.py for an example where the Subset Op is used). You would then use your setPixels()-line from above to add the data to your bands and set your Product p as input to the next operator.
Finally, you donât need the MergeOp then, as you can simply copy bands using ProductUtils.copyBand(sourceBandName, sourceProduct, targetProduct, True). And I recommend calling ProductUtils.copyProductNodes(sourceProduct, targetProduct) after that.
Thanks TonioF for your help, and sorry for getting back to you so late.
Regarding the first part of your comment:
when using âsetPixelâ, the exception (java.lang.NullPointerException) occurs during the loop, at the first attempt to execute âtargetBand.setPixels(0, y, width, 1, d)â
when using âwritePixelsâ, the loop executes entirely without any error, it is only when I try to read this new band that the exception occurs (java.lang.NullPointerException): b = p.getBand(ânewBandâ); b.readPixels(0, 0, w, h, ânewBandâ)
I have never tried writing an operator, but I will try that as you suggest that it is a better strategy. Iâll post the result in case I succeed!