Google Earth Engine: Understanding Landsat 7 Collection 2 QA_PIXEL, bitwiseAnd() for cloud mask

cloud covergoogle-earth-enginegoogle-earth-engine-javascript-apilandsatlandsat-7

I want to see how the new Landsat 7 Collection 2 (C2, 'LANDSAT/LE07/C02/T1_L2') differs from Collection 1 (C1). I have created an adequate Landsat 7 C1 composite since GEE provides a cloud mask function but does not for L7 C2.

Have I understood the bitwise concepts correctly for my own cloud mask? The resulting image is patchy, is this because C2 has better cloud identification so more clouds, haze and shadows are removed?

Additionally:
My image is super dark, I've played around with min max and gamma, but still looks dark.

Shareable link (hopefully sharing configured correctly): https://code.earthengine.google.com/5b109a17b9027d14ad5ed8aba364859c

Alternatively, code below:

// script aim:
// create cloud free composite with L7 Collection 2

// GEE supplied cloud mask for L7 Collection 1
var cloudMaskL457 = function(image) {
  var qa = image.select('pixel_qa');
  // If the cloud bit (5) is set and the cloud confidence (7) is high
  // or the cloud shadow bit is set (3), then it's a bad pixel.
  var cloud = qa.bitwiseAnd(1 << 5)
          .and(qa.bitwiseAnd(1 << 7))
          .or(qa.bitwiseAnd(1 << 3))
  // Remove edge pixels that don't occur in all bands
  var mask2 = image.mask().reduce(ee.Reducer.min());
  return image.updateMask(cloud.not()).updateMask(mask2);
};


// cloud mask I am trying to write for L7 Collection 2
var cloudMaskC2L7 = function(image) {
  var dilatedCloud = (1 << 1)
  var cloud = (1 << 3)
  var cloudShadow = (1 << 4)
  var qa = image.select('QA_PIXEL');
  var mask = qa.bitwiseAnd(dilatedCloud)
    .and(qa.bitwiseAnd(cloud))
    .or(qa.bitwiseAnd(cloudShadow))
  // var mask = qa.bitwiseAnd(dilatedCloud).eq(0).and(
  //   qa.bitwiseAnd(cloud).eq(0)).and(qa.bitwiseAnd(cloudShadow).eq(0))
  var mask2 = image.mask().reduce(ee.Reducer.min());
  return image.updateMask(mask.not()).updateMask(mask2);
}


var landsat7C1 = ee.ImageCollection('LANDSAT/LE07/C01/T1_SR')
  .filterBounds(geometry)
  .filterDate('1999-01-01', '2000-12-31')
  .map(cloudMaskL457)
  .aside(print)
  .min()
  .clip(geometry)


var landsat7C2 = ee.ImageCollection('LANDSAT/LE07/C02/T1_L2')
  .filterBounds(geometry)
  .filterDate('1999-01-01', '2000-12-31')
  .map(cloudMaskC2L7)
  .aside(print)
  .min()
  .clip(geometry)


var L7C1params = {
  bands: ['B3', 'B2', 'B1'],
  min: 0,
  max: 3000,
  gamma: 1.4
}

var L7C2params = {
  bands: ['SR_B3', 'SR_B2', 'SR_B1'],
  min: 5000,
  max: 50000,
  gamma: 2
}


Map.addLayer(landsat7C2, L7C2params, 'landsat 7 Collection 2 1999 - 2000 cloud masked')
Map.addLayer(landsat7C1, L7C1params, 'landsat 7 Collection 1 1999 - 2000 cloud masked')

Best Answer

Bits 1, 3, and 4 look correct, according to the User's Guide, but you haven't scaled the data appropriately. The scaling factors are different for C2.

https://www.usgs.gov/core-science-systems/nli/landsat/landsat-collection-2-level-2-science-products