Extract valid mask for sentinel 1

I am confused how to extract a valid mask for sentinel 1 acquisitions. Looking into the forum, I see it should exist a method readValidMask… What I do is the following:

from snappy import ProductIO

file_name = 'S1B_IW_GRDH_1SSH_20171023T121033_20171023T121058_007956_00E0E1_2C5C.SAFE.zip'
source = ProductIO.readProduct(file_name)

However the method does not exist. How can I load a valid pixel mask, that I can later mask out no data pixels?

I think the S1 data has valid mask by default. It should mask out the no-data values (=0).

You can get the mask data by:

source.getBand('Amplitude_VH').readValidMask(0, 0, w, h, data)

You can also ask if it is defined at all:

source.getBand('Amplitude_VH').isValidMaskUsed()

Or you can get the mask expression:

source.getBand('Amplitude_VH').getValidMaskExpression()

If you want to define your own mask you can add masks to the product:

source.addMask('name', 'expression', 'description', Color.YELLOW, transparency)

You can also load shapefiles and use them as mask.

Many thanks marpet that helped me to move quite a bit. Just for code completeness for future users I provide a working example and how to define the data array that we want to populate.

source = ProductIO.readProduct(filename)
w = source.getSceneRasterWidth()
h = source.getSceneRasterHeight()

band = source.getBand('Amplitude_HH')

mask = band.readValidMask(0,0,w,h,np.zeros(shape=(w,h), dtype=np.uint8)) 

At this point mask is a two dimensional array w x h.

I tried to do the same thing to get the actual data

Band = ProductData.createInstance(np.zeros((w, h), np.float32))
band.readRasterData(0,0,w,h,Band)

for some reason it seamed that I needed to instantiate my empty array with the ProductData.createInstance method.

Now if I use Band.getElems() that returns a vector instead of an array. How can I retrieve the actual data array (or convert from the vector to the appropriate 2D array)?

1 Like

Actually is very simple to form an array by using

array.reshape(w,h)

I though that there was a complicate way how the array was represented as a vector…
I still though have the feeling that I miss something. The mask looks a bit weird. Here is the code and the images I got.
Method: I warped an ESA sentinel1 sar file and named it out.tif. I opened the non-warped and retrieved the valid mask. I then save the mask as geotiff including georeference from the warped file.

hhfile = 'S1B_EW_GRDM_1SDH_20171025T115426_20171025T115530_007985_00E1BF_9E58.SAFE/measurement/out.tif'
source = ProductIO.readProduct(filename)
w = source.getSceneRasterWidth()
h = source.getSceneRasterHeight()
band = source.getBand('Amplitude_HH')
mask = band.readValidMask(0,0,h,w,np.zeros(shape=(h,w), dtype=np.uint8))    

outfile = 'mask.tiff'
ds = gdal.Open(hhfile)
driver = gdal.GetDriverByName("GTiff")
outdata = driver.Create(outfile, w, h, 1, gdal.GDT_UInt16)
outdata.SetGeoTransform(ds.GetGeoTransform())
outdata.SetProjection(ds.GetProjection())
outdata.GetRasterBand(1).WriteArray(mask)
outdata.FlushCache() 
ds=None


Shouldn’t we expect that invalid pixels denoted as 0s, would be mainly around the image where the background noise (black areas of the sar image) is?

1 Like