Most MODIS QA data (including the Cloud Mask data) are not stored as separate raster bands, where each band is a grid where each cell is one value of one QA data field. Instead, the QA data are concatenated into strings of bits. So instead of having Band 1 be 00
and Band 2 be 11
, they just concatenated them (right-to-left) as 1100
which is a completely different number in decimal.
ENVI doesn't know that the data are concatenated from multiple bit "words", so it converts the entire string of bits into a decimal number. So while ENVI thinks the value of the QA band is 7457
(made up example), in binary it is 1110100100001
which should be split into a series of separate bit words like 11 1010 0 1 000 01
where each word represents a different QA flag. You can test this by looking for areas that are clearly cloudy and converting the decimal QA value to binary and looking at the binary output.
But you probably want to export an entire scene of this QA data to a new raster. There is a way to do this in ENVI. Table 2 of this PDF (here's a mirror since NASA link isn't working) shows the bit "words" that comprise the 48-bit QA band of the MOD35 Cloud Mask data. This table says that the "Cloud Mask" QA flag is bit 0 in the 48-bit string. Assuming that the data are written in big endian format (it is for MODIS land data), bit 0 is the least significant bit at the far right of the binary string. So to summarize, we need to take the far right digit of the binary notation of the QA band, and export it to a new raster.
Using Band Math and ENVI's Bitwise Operators (e.g. AND, OR, NOT, and XOR) we can effectively mask out the other 47 bits. Simply run the Band Math expression b1 and 1
. This will convert values of b1
and 1
to binary, and then run a bitwise AND operation on the two binary values. This proceeds through the bit string digit by digit, outputting 1
where both inputs are 1
, and 0
otherwise. Here's what's happening internally:
7457 = decimal version of example data point
1 1 1 0 1 0 0 1 0 0 0 0 1 = binary version of 7457. Bit of interest in bold.
0 0 0 0 0 0 0 0 0 0 0 0 1 = binary version of 1
0 0 0 0 0 0 0 0 0 0 0 0 1 = output of Band Math operation. 1 AND 1
equals 1
.
If your input was 7458, here's what it would look like internally:
7458 = decimal version of example data point
1 1 1 0 1 0 0 1 0 0 0 1 0 = binary version of 7458. Bit of interest in bold.
0 0 0 0 0 0 0 0 0 0 0 0 1 = binary version of 1
0 0 0 0 0 0 0 0 0 0 0 0 0 = output of Band Math operation. 1 AND 0
equals 0
.
This example is a bit easier because the bit of interest is the least significant bit. If you are trying to read from a bit word in the middle of the bit string, you need to do some division afterwards. Below is an example where I'm interested in the 3rd, 4th, 5th, and 6th bits:
55150 = decimal version of example data point
1 1 0 1 0 1 1 1 0 1 1 0 1 1 1 0 = binary version of 55150. Bits of interest in bold.
0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 = binary value used for AND. 111100
is 60 in decimal notation.
0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 = output of Band Math operation. 1011
is eleven in decimal, but the output of this is 101100
which is forty-four in decimal. We need to chop off the last two binary digits by dividing by 4.
Another way to describe this division step is to use an example from the base-10 world instead of base-2 world. If we wanted to change the number 8700 to 87 we just divide by 100. It's second nature to us, but in a more formal way of describing this operation is dividing by (base ^ number of digits to remove) = (10 ^ 2) = 100. In binary, if we want to convert 101100 to 1011 we need to divide by (base ^ number of digits to remove) = (2 ^ 2) = 4.