0

I am about to calculate Chorophyll-a in the water bodies in one region, as I outlined above. I have created a mask, with water=1, land=0(transparent). And I want to calculate quality formula (NDCI, refer to normalized difference chl-a index) over the mask I created in the last step. Here are my code.

function maskS2clouds(image) {
       var qa = image.select('QA60')
        var cloudBitMask = 1 << 10;
        var cirrusBitMask = 1 << 11;
 var mask = qa.bitwiseAnd(cloudBitMask).eq(0).and(
         qa.bitwiseAnd(cirrusBitMask).eq(0))
 return image.updateMask(mask).divide(10000)
  .select("B.*")
  .copyProperties(image, ["system:time_start"])
   }

  var tiles = ['29UNV']
   var collection = ee.ImageCollection("COPERNICUS/S2_SR")
   .filterDate('2020-01-01', '2020-12-31')
    .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20))
   .filter(ee.Filter.inList('MGRS_TILE', tiles))
   print(collection)
   var minmin = collection.map(maskS2clouds)
   print(minmin)
    var calndwi = function(image){
     //water mask
     var NDWI = image.normalizedDifference(['B3', 'B8']).rename('NDWI');
     return image.addBands(NDWI).updateMask(NDWI.gt(0));
    };
   print(minmin.map(calndwi));
  //Add NDWI to the clipped image collection
   var withNDWI = minmin.map(calndwi).select('NDWI');
   print("NDWI collection", withNDWI);
  var bb = withNDWI.first();
  Map.addLayer(bb,{},'ss');
   var addNDCI = function(image) {
  var ndci = image.normalizedDifference(['B5', 'B4']).rename('NDCI');
    return image.addBands(ndci);
   };
   var withNDCI = minmin.map(addNDCI).select('NDCI');
   print("NDCI collection", withNDCI);
   var MASK = function(image) {
  var mask = bb.mask(image);
     return image.addBands(mask);
   };
  var maskk = withNDCI.map(MASK).select('mask');
  print(maskk)**

and it give me the bug like ImageCollection (Error) Error in map(ID=20200106T114451_20200106T114531_T29UNV):Image.select: Pattern 'mask' did not match any bands.what should I do? thanks a million

1 Answers1

0

The maskk object does not contain any bands named mask, because your MASK function does not create or add any bands with that name.

What your code does, as you've currently written it, is this:

   var MASK = function(image) {
  // Apply a mask over the 'bb' image.
  var mask = bb.mask(image);
     // return 'image' (which was the 'mask' parameter above), 
     // with ALL bands from the object 'mask', which is now a 'masked' version of bb. 
     // since mask = bb.mask(image), all the bands from bb will be added. 
     return image.addBands(mask);
   };

var maskk = withNDCI
  // Map the 'MASK' function over the 'withNDCI' collection
  .map(MASK)
  // Attempt to select a band named 'mask' (which does not exist).
  .select('mask');

I'm not sure what you're looking for when you try to select the mask 'band' - I assume what you want is the masked NCDI image. That's essentially what you have already - but the band names of the 'maskk' object are "NDWI" and "NDCI", since it is derived from the bb, and those are the bands that bb contains. There is no band named "mask".

Anson Call
  • 146
  • 1
  • 7
  • Hi, I just want to get the information only from water (that's way I calculated NDWI before),and calculated NDCI from image collection (with my criteria set before, cloud coverage<20%, and there are 14 images in the year of 2020 for Sentinel) only on the water pixels (water mask I created from last step with NDWI). Thanks a lot for your help. Maybe it's not right for me to use 'mask'? I have checked earth engine catalog before, image1.mask(image2), any pixels in image2 with value=0 will also be set transparent, I just don't know which approach should I use. – minyan zhao Jul 13 '22 at 10:19
  • Ah, I see what is happening. You are trying to mask your NCDI image with an image that's *clipped to the extent of water*. What you need is a *mask that covers the whole ROI, with 1s over water and 0s over land.* The fix is in the link: https://code.earthengine.google.com/bc7c3bd8420c4dfd7d4f6d3a0d19da59 – Anson Call Jul 14 '22 at 16:51
  • Hi thanks a lot and it works! I have one more question with your answer---the 'mask' function as outlined in GEE catalog, mask is 'The mask of an image is set using a call like image1.mask(image2). This call takes the values of image2 and makes them the mask of image1. ((Any pixels in image2 that have the value 0 will be made transparent in image1 )).' so if i mask ndci with the water area--'bb.mask(ndci)', ndci is the image2 as describe in GEE catalog, will it made the pixels in NDCI with the value of 0 becomes transparent? Thank you. – minyan zhao Jul 15 '22 at 10:40
  • If you run ```bb.mask(ndci)```, the function will return a masked version of ```bb``` (i.e. the ```bb``` image, but transparent in all the areas where ```ndci``` is 0). If you run ```ndci.mask(bb)```, the function will return a masked version of ```ndci``` (in other words, the ```ndci``` image, but transparent in all the areas where ``bb`` is 0. If you just want ```ndci``` in the areas where ```ndci``` is greater than zero (in other words, ```ndci``` masked by itself), you can try ```ndci.mask(ndci.gt(0))``` - I think that should do it. – Anson Call Jul 16 '22 at 12:40