1

I want to download images from NASA's Black Marble nighttime light (NTL) using Google Earth Engine. The product can be found here. Before downloading them I need to check the pixel's quality using the QF Cloud Mask. More specifically, from the table under the Bitmask for QF_Cloud_Mask I need:

  1. Bit 0: Day/Night: 0: Night
  2. Bits 1-3: Land/Water Background: 1: Land no Desert
  3. Bits 4-5: Cloud Mask Quality: 3: High
  4. Bits 6-7: Cloud Detection Results & Confidence Indicator: 0: Confident Clear
  5. Bit 8: Shadow Detected: 0: No
  6. Bit 9: Cirrus Detection (IR) (BTM15 - BTM16): 0: No cloud
  7. Bit 10: Snow/Ice Surface: 0: No Snow/Ice

From the Mandatory_Quality_Flag Class Table:

  • 0 High-quality, Persistent nighttime lights

From the Snow_Flag Class Table:

  • 0 No Snow/Ice

Based on the above information, I did:

// Here I'm trying to set the Bits according to table 'Bitmask for QF_Cloud_Mask'
var mask_vnpa2_img = function(image) {
  var LandWaterBackground = (1 << 3);
  var CloudMaskQuality = (3 << 5);
  var CloudDetectionResultsConfidenceIndicator = (0 << 7);
  var ShadowDetected = (0 << 8);
  var CirrusDetection = (0 << 9);
  var SnowIceSurface = (0 << 10);

  // Get the pixel QA band
  var qa = image.select('QF_Cloud_Mask');

  var mask = qa
    .bitwiseAnd(LandWaterBackground).eq(0)
    .and(qa.bitwiseAnd(CloudMaskQuality).eq(0))
    .and(qa.bitwiseAnd(CloudDetectionResultsConfidenceIndicator).eq(0))
    .and(qa.bitwiseAnd(ShadowDetected).eq(0))
    .and(qa.bitwiseAnd(CirrusDetection).eq(0))
    .and(qa.bitwiseAnd(SnowIceSurface).eq(0));

  // Mask image with clouds and shadows
  return image.updateMask(mask);
};

var dataset = ee.ImageCollection('NOAA/VIIRS/001/VNP46A2').filter(
  ee.Filter.date('2018-06-01', '2018-06-30'));

// Bidirectional Reflectance Distribution Function (BRDF)
var brdf = dataset.select('DNB_BRDF_Corrected_NTL');
var brdfVis = {
  min: 0,
  max: 100,
  palette: ['black', 'purple', 'cyan', 'green', 'yellow', 'red', 'white'],
};

Map.setCenter(-79.4, 43.1, 8);
// Day/Night Band (DNB)
// NightTime Light (NTL)
Map.addLayer(brdf, brdfVis, 'DNB_BRDF_Corrected_NTL');

If I remove the code from line 1 to 24 and plot the results I don't see any difference meaning that the QA mask I applied isn't correct. Here is the table (shp) I am using.

How can I apply the QA mask to the collection before I export the image?

1 Answer 1

1

Maybe you messed up the bit fiddling? I've got a little utility function that I always use, so I don't have to think about it every time:

var mask_vnpa2_img = function(image) {
  var qa = image.select('QF_Cloud_Mask');
  var landWaterBackground = bitwiseExtract(qa, 1, 3)
  var cloudMaskQuality = bitwiseExtract(qa, 4, 5)
  var cloudDetectionResultsConfidenceIndicator = bitwiseExtract(qa, 6, 7)
  var shadowDetected = bitwiseExtract(qa, 8)
  var cirrusDetection = bitwiseExtract(qa, 9)
  var snowIceSurface = bitwiseExtract(qa, 10)

  var mask = ee.Image(1)
    .and(landWaterBackground.eq(1)) // Land no Desert
    .and(cloudMaskQuality.eq(3)) // High
    .and(cloudDetectionResultsConfidenceIndicator.eq(0)) // Confident Clear
    .and(shadowDetected.eq(0)) // No
    .and(cirrusDetection.eq(0)) // No cloud
    .and(snowIceSurface.eq(0)) // No Snow/Ice
    
  return image.updateMask(mask);
}


function bitwiseExtract(value, fromBit, toBit) {
  if (toBit === undefined)
    toBit = fromBit
  var maskSize = ee.Number(1).add(toBit).subtract(fromBit)
  var mask = ee.Number(1).leftShift(maskSize).subtract(1)
  return value.rightShift(fromBit).bitwiseAnd(mask)
}

https://code.earthengine.google.com/a7be3d668841043a7d0daa9de406d0b7

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.