Calibration with the Snappy API - the outputs don't seem to contain data

Hi, I have been trying to apply the Calibration operator to ALOS-2 PALSAR-2 data that I have in beam-dim format. My code runs through, but I think the product being output is empty as an image can’t be displayed for the radiometrically corrected bands. Could you please advise me as to where I’m going wrong with the following code? I am able to successfully run this within the user interface for a single band, using the menu options: Radar → Radiometric → Calibrate, but I will have to automate the process to apply to all data.

p = ProductIO.readProduct(C_files[0])

band_names = p.getBandNames()
bands = list(band_names)
print (bands)

products = []

# looping through the band names and creating the output radiometrically calibrated product
for band_name in band_names:
    parameters = HashMap()
    parameters.put('sourceBands', band_name)
    parameters.put('outputSigmaBand', True) 
    parameters.put('outputImageScaleInDb', True)
    
    #operator = GPF.createOperator('Calibration')
    #operator.setParameter('outputImageInDb', True)
    #product = operator.apply(p)
    #products.append(p)
    products.append(GPF.createProduct('Calibration',parameters,p))

# getting the width and height of the first product in the sequence
width = products[0].getSceneRasterWidth()
height = products[0].getSceneRasterHeight()

# an empty product for the merged sigma bands
merged_product_s = Product('MERGED_PRODUCT', 'MERGED_TYPE', width, height)

# now looping through the list of band names and corrected products
for i in range(len(band_names)):
    band_name = band_names[i]
    print (i, band_name)
    product = products[i]
    
    # the products output bands
    bands = product.getBands()
    
    for band in bands:
        band.setName('HH_sigma0' + band_name[-10:])
        merged_product_s.addBand(band)
        
# writing the merged product
ProductIO.writeProduct(merged_product_s,Out_dir + 'test.dim','BEAM-DIMAP')

On further investigation, the calibrate operator works well, and I can output each band as a new beam-dim file. However there seems to be an issue when setting the band names to something new, and then merging the bands. The output BEAM-DIM file contains the new band names, but not the underlying data. Is it possible I’m missing a step somewhere in my code when re-assigning the band name, that would allow for the product data to be included?

When I skip the step of renaming the bands, the code works and I can view the output calibrated images, but the bands are not merged in their original order - the merging process adds an _{band number} subscript for each band that would otherwise have the same name. This would be fine if they were in the original order, as I could then rename them after, but I can’t tell which date goes with each of the newly output bands. Is there a way to maintain the original band order when using band merge, or would each individual band have to be specified in the list passed to BandMerge?

This was the code I used:

%%time

from snappy import HashMap, GPF, Product, ProductIO, ProductUtils

p = ProductIO.readProduct(C_files[0])
band_names = p.getBandNames()
bands = list(band_names)
print (bands)


# an array for the radiometrically corrected outputs
rc = []
#for j in range(len(band_names)):
for j in range(len(bands)):
    print ("Applying calibration for: " , bands[j])

    parameters = HashMap()
    parameters.put('createGammaBand', True)
    parameters.put('outputSigmaBand', True) 
    parameters.put('outputGammaBand', True)
    parameters.put('outputImageScaleInDb', True)
    parameters.put('sourceBands', bands[j])
    # applying radiometric correction to each band
    rc.append(GPF.createProduct('Calibration', parameters, p))


# new band names for the sigma0 outputs
output_bands_s = [rc[j].getBandAt(0).getName() + bands[j][-10:] for j in range(len(rc))]

# new band names for the gamma0 outputs
output_bands_g = [rc[j].getBandAt(1).getName() + bands[j][-10:] for j in range(len(rc))]

#print (output_bands_s)
#print (output_bands_g)

# changing the band names for the calibrated product (includes both gamma0 and sigma0)
for i in range(len(output_bands_s)):

    # the products output bands
    band_name_s = rc[i].getBandAt(0).getName()
    band_name_g = rc[i].getBandAt(1).getName()
   
    # setting the bands to their new names
    rc[i].getBand('Sigma0_HH_db').setName(output_bands_s[i])
    rc[i].getBand('Gamma0_HH_db').setName(output_bands_g[i])


# sigma merged product
parameters = HashMap()
#parameters.put('includes',r_corrected)
#sourceProducts = HashMap()
#sourceProducts.put('masterProduct',r_corrected[0])
#sourceProducts.put('slaveProduct',r_corrected[1:])

merged_product = GPF.createProduct('BandMerge', parameters, (rc))

options = {'memory':True}  

# Writing the merged product
ProductIO.writeProduct(merged_product, Out_dir + 'Cal_HH_area1', 'BEAM-DIMAP')

When you calibrate all bands at once the order should stay the same. The BandMerge adds the bands in the order of source products. At least, according to a quick look I had at the implementation.

@jun_lu @lveci Can you have a look at this?
Thanks

The calibrate function doesn’t currently work to calibrate all bands at once on either the SNAP platform or when using snappy as the output bands have the same name, e.g., Sigma0_HH_db for all bands, so they all get overwritten, except for one. To compensate for this I’m trying to calibrate each band (representing a different image date) individually, append the calibrated output to an array, and then set the band name to the original band name + the calibrated output band name (e.g., 20201110_Sigma0_HH_db).

The individual calibrated outputs look good, but I will have to merge them into a single BEAM-DIM file, and I’m still having issues with both the re-naming step (the renaming works, but the image data is lost) and the merging step - the bands are not merged in the original order, even though that is how they are passed to the BandMerge operator.

I fixed this by printing the calibration outputs for each image to file, then reading them in and changing the band names to something unique to each image (e.g., Sigma0_HH_29Mar2020_01 for the master image). I think the issue must be with storing the image data in memory.

1 Like