Cloud mask
Cloud mask
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
Filters:

 User Services
 Posts: 294
 Joined: Mon Sep 30, 2019 8:33 am America/New_York
 Has thanked: 3 times
Re: Cloud mask
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://atmosphereimager.gsfc.nasa.gov/sites/default/files/ModAtmo/CMUSERSGUIDE_0.pdf
For other Cloud Mask product documents visit:
https://atmosphereimager.gsfc.nasa.gov/products/cloudmask/documentation
https://atmosphereimager.gsfc.nasa.gov/sites/default/files/ModAtmo/CMUSERSGUIDE_0.pdf
For other Cloud Mask product documents visit:
https://atmosphereimager.gsfc.nasa.gov/products/cloudmask/documentation
Regards,
LAADS User Services
To receive news from LAADS DAAC direct to your inbox, email laadsdaacjoin@lists.nasa.gov with “subscribe” in the subject line.
LAADS User Services
To receive news from LAADS DAAC direct to your inbox, email laadsdaacjoin@lists.nasa.gov with “subscribe” in the subject line.
Re: Cloud mask
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?
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?

 Posts: 12
 Joined: Wed Apr 13, 2022 11:58 am America/New_York
Re: Cloud mask
Here is the example of using quality filtering in python from LPDAAC tutorial:
https://lpdaac.usgs.gov/resources/elearning/workingdailynasaviirssurfacereflectancedata/
Also, see if you can use a LPDAAC toolbox:
https://git.earthdata.nasa.gov/projects/LPDUR/repos/arcgismodisviirspythontoolbox/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/elearning/gettingstartedmodisv6surfacereflectancedatapart3interpretingqualityinformation/
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.
https://lpdaac.usgs.gov/resources/elearning/workingdailynasaviirssurfacereflectancedata/
Also, see if you can use a LPDAAC toolbox:
https://git.earthdata.nasa.gov/projects/LPDUR/repos/arcgismodisviirspythontoolbox/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/elearning/gettingstartedmodisv6surfacereflectancedatapart3interpretingqualityinformation/
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.