it's the first time I'm working with MODIS data and I am a bit confused about how bits work and how masks are created. After a bit of research I've been able to understand, more or less, how bit filtering works -- using the help found here and MODIS documentation files (1 and 2).
I am using MOD09GA product to create cloud and aerosol free mask data. I built my binary filter based on the information found in the next table (file 2, page 24).
When doing bitwise operations in python and applying the bit filter to the QA band (state_1km), I am not fully sure that what it returns is right, since it generates a mask with 4 integer values (0, 1, 2 and 3) when I was expecting 2 (0 and 1).
I will show this with an example. You can download the .hdf file from here, although you'll need you login credentials.
import gdal
import numpy as np
# Opening MODIS hdf file
modisImage = gdal.Open("data/MOD09GAMOD09GA.A2008001.h10v05.006.2015169041625.hdf")
# Getting subdatasets
subData = modisImage.GetSubDatasets()
data = {}
for fname, name in subData:
newname = name.split("] ")[1]
without_type = newname.split(" (")[0]
print(without_type)
data[without_type] = gdal.Open(fname).ReadAsArray()
# =============================================================================
# # num_observations_1km MODIS_Grid_1km_2D
# # state_1km_1 MODIS_Grid_1km_2D <-- I want this one
# # SensorZenith_1 MODIS_Grid_1km_2D
# # .
# # .
# # .
# # .
# # q_scan_1 MODIS_Grid_500m_2D
# =============================================================================
# now call the desired band
qc = data["state_1km_1 MODIS_Grid_1km_2D"]
Cloud state, cloud shadow and land/water bit masks are returning a mask with the values expected (0 and 1), but when I apply the same approach to the aerosol quantity I can't understand the mask returned.
# Aerosol quantity information is in the Bitshift 6 and Bitmask 0-3 (first and third columns of the table). In this case, I want to return only high quantity aerosol
qcAerosol = (qc >> 6) & 3
# Checking values returned (more than 2 values)
np.unique(qcAerosol) # array([ 0, 1, 2, 3], dtype=uint16)
# Taking a closer look to te values returned
bin(1) # '0b1'
bin(2) # '0b10'
bin(3) # '0b11'
The qcAerosol mask created is the one in the image. As you can see, it has four colors corresponding to each value.
Each value returned in the mask, maps a binary value in the table:
1 corresponds to the bit mask for 'low aerosol quantity'
2 corresponds to the bit mask for 'average aerosol quantity'
3 corresponds to the bit mask for 'high aerosol quantity'
Since I want a 'high aerosol quantity' mask, I need a last step to create one.
qcAerosol[qcAerosol != 3] = 0
qcAerosol[qcAerosol == 3] = 1
Getting the next mask.
Python qcAerosol
However, as I noted above, bitmasks for cloud state, cloud shadow and land/water only return two values, 0 and 1. I think there could be a problem with my approach, therefore my question is raised: When working with MOD09GA product, is supposed QC bitmask for high aerosol quantity to return 4 values?