Page 1 of 1

Cloud mask

Posted: Tue May 17, 2022 3:01 pm America/New_York
by shivyansh
How can I get cloud mask from MODIS DATA. When I download MOD35_L2 dataset, it turns out to have multiple band in it. I am finding it difficult to get a binary cloud mask from Modis data. Please guide me

Re: Cloud mask

Posted: Wed May 18, 2022 1:24 pm America/New_York
by LAADS_UserServices_M
The MOD35_L2 product does not contain a ready to use binary cloud mask. It contains a "Cloud_Mask" Scientific Data Set (SDS) which is represented in a 6 byte (48 bit) array. Individual bits or groups of bits are set to denote various cloud conditions and characteristics for that pixel. To find out what this product is, how to use it, and to get details on individual Cloud Mask bit flags, see the Cloud Mask Users Guide at:
https://atmosphere-imager.gsfc.nasa.gov/sites/default/files/ModAtmo/CMUSERSGUIDE_0.pdf
For other Cloud Mask product documents visit:
https://atmosphere-imager.gsfc.nasa.gov/products/cloud-mask/documentation

Re: Cloud mask

Posted: Thu May 26, 2022 6:33 am America/New_York
by shivyansh
I have gone through the CMUSERGUIDE, and figured out that the first bit of 48 bit array denotes cloud or no cloud and is important to get a binary cloud image.
But how can we generate it?
Where can we find a ready to use binary cloud?
If not, how can we create a binary cloud mask?

Re: Cloud mask

Posted: Thu May 26, 2022 10:03 am America/New_York
by rapsodia86
Here is the example of using quality filtering in python from LPDAAC tutorial:
https://lpdaac.usgs.gov/resources/e-learning/working-daily-nasa-viirs-surface-reflectance-data/
Also, see if you can use a LPDAAC toolbox:
https://git.earthdata.nasa.gov/projects/LPDUR/repos/arcgis-modis-viirs-python-toolbox/browse

LPDAAC has produced also a video about quality/cloud bit reading (I know it is different product, but the idea is the same): https://lpdaac.usgs.gov/resources/e-learning/getting-started-modis-v6-surface-reflectance-data-part-3-interpreting-quality-information/

If you are not familiar with python, here is an R function that allows to read and condition on bit values.
get_mask <- function(band_data,bit_pos, bit_len, value, cumulative){
bitlen <- strtoi(strrep(1,bit_len),base = 2)
bitlen
pos_value <- bitwShiftL(bitlen,bit_pos)
pos_value
if (is.character(value)){
value <- strtoi(value,base = 2)
}
con_value = bitwShiftL(value,bit_pos) #N*(2^i)
if (cumulative=="GE"){
msk <- bitwAnd(band_data,pos_value) >= con_value}
if (cumulative=="EQ"){
msk <- bitwAnd(band_data,pos_value) == con_value}
if (cumulative=="LE"){
msk <- bitwAnd(band_data,pos_value) <= con_value}
return(as.integer(msk))
}

#band_data :is your tiff raster
#bit_pos :where the bit starts [from column BIT FIELD in user guide]
#bit_len :how many bits
#value :what decimal value you want from those bits above [from column RESULTS in user guide]
#cumulative :if it is going to be greater equal/lower equal/equal of your expected value
library(raster)
rcfile <-raster(YOURFILE)
qa_mk0 <- calc(rcfile, fun=function(x){get_mask(x,0, 1, 1, "EQ")} ) #it takes 1 bit that starts at 0 position, and check if its value (that can be 0 or 1) is equal to 1. If yes that you get 1, if not then you get 0.
qa_mk1 <- calc(rcfile, fun=function(x){get_mask(x,1, 2, 0, "EQ")} ) #it takes 2 bits that start at 1 position, and check if its value (that can be from 0 to 3) is equal to 0. If yes that you get 1, if not then you get 0.
#at the end, you can combine all produced masks for the final one.