Google Earth Engine – Using Landsat 5 EVI in GEE

evigoogle-earth-enginelandsat

I used this script for Landsat 8 and it worked fine, I've changed the band info for Landsat 5 but now I get this error:

ImageCollection (Error)
Error in map(ID=0):
Image.select: Pattern 'B4' did not match any bands.

Where am I going wrong?

// Import landsat imagery. Create function to cloud mask from 
// the pixel_qa band of Landsat 5 SR data. 
// Bits 3 and 5 are cloud shadow and cloud, respectively.

var imageCollection = ee.ImageCollection('LANDSAT/LT05/C01/T1_SR')
  .filterBounds(AOI);
   
function maskL8sr(imageCollection) {
  var cloudShadowBitMask = 1 << 3;
  var cloudsBitMask = 1 << 5;
   
  var qa = imageCollection.select('pixel_qa');

  var mask = qa.bitwiseAnd(cloudShadowBitMask).eq(0)
      .and(qa.bitwiseAnd(cloudsBitMask).eq(0));

  return imageCollection.updateMask(mask).divide(10000)
      .select("B[0-9]*")
      .copyProperties(imageCollection, ["system:time_start"]);
}

var stepList = ee.List.sequence(2000,2012);
 
var filterCollection = stepList.map(function(year){
  var startDate = ee.Date.fromYMD(year,3,1);
  var endDate = ee.Date.fromYMD(year,5,31);
  var composite_i = imageCollection.filterDate(startDate, endDate)
                        .map(maskL8sr)
                        .median()
                        .set('system:time_start',startDate);
  return composite_i;
});

print(filterCollection)
var yearlyComposites = ee.ImageCollection(filterCollection);
print(yearlyComposites, 'Masked and Filtered Composites');
 

 // Add Enhanced Vegetation Index to a function and apply it.
 // EVI = 2.5 * ((NIR - Red) / (NIR + 6 * Red – 7.5 * Blue + 1))
 function evi(img){
   var eviImg = img.select(['B4','B3','B1'],['nir','red','blue']);
   eviImg = eviImg.expression(
     '(2.5 * ((NIR - RED)) / (NIR + 6 * RED - 7.5 * BLUE + 1))', {
       'NIR': eviImg.select('nir'),
       'RED': eviImg.select('red'),
       'BLUE': eviImg.select('blue')
     }).rename('EVI');
   return img.addBands(eviImg);
 }
 
 yearlyComposites = yearlyComposites.map(function(image){
   return evi(image);
 });
 
 print(yearlyComposites, 'With EVI as Band');

Best Answer

Your stepList.map(...) function is returning some images with no bands (and therefore no band names B4, B3, B2 that the evi function is looking for).

enter image description here

Here I have added a valid property to each image in the collection based on whether it has bands, then filter the collection on that property.

// Import landsat imagery. Create function to cloud mask from 
// the pixel_qa band of Landsat 5 SR data. 
// Bits 3 and 5 are cloud shadow and cloud, respectively.

var imageCollection = ee.ImageCollection('LANDSAT/LT05/C01/T1_SR')
  .filterBounds(AOI);
   
function maskL8sr(imageCollection) {
  var cloudShadowBitMask = 1 << 3;
  var cloudsBitMask = 1 << 5;
   
  var qa = imageCollection.select('pixel_qa');

  var mask = qa.bitwiseAnd(cloudShadowBitMask).eq(0)
      .and(qa.bitwiseAnd(cloudsBitMask).eq(0));

  return imageCollection.updateMask(mask).divide(10000)
      .select("B[0-9]*")
      .copyProperties(imageCollection, ["system:time_start"]);
}

// cloud masking outside the stepList.map() function for efficiency
var imageCollectionMasked = imageCollection.map(maskL8sr);

var stepList = ee.List.sequence(2000,2012);
 
var filterCollection = stepList.map(function(year){
  var startDate = ee.Date.fromYMD(year,3,1);
  var endDate = ee.Date.fromYMD(year,5,31);
  var composite_i = imageCollectionMasked.filterDate(startDate, endDate)
                        .median()
                        .set('system:time_start', startDate);
  
  // add a 'valid' property of 1 if image has bands and 0 if image has no bands
  // it works because a populated list is evaluated as true and an empty list is evaluated as false
  composite_i = ee.Algorithms.If(composite_i.bandNames(), composite_i.set('valid', 1), composite_i.set('valid', 0))
  
  return composite_i;
});


// make an image collection from list of images
var yearlyComposites = ee.ImageCollection(filterCollection);

// filter only valid images
yearlyComposites = yearlyComposites.filterMetadata('valid', 'equals', 1);

print(yearlyComposites, 'Masked and Filtered Composites');
 

 // Add Enhanced Vegetation Index to a function and apply it.
 // EVI = 2.5 * ((NIR - Red) / (NIR + 6 * Red – 7.5 * Blue + 1))
 function evi(img){
   var eviImg = img.select(['B4','B3','B1'],['nir','red','blue']);
   eviImg = eviImg.expression(
     '(2.5 * ((NIR - RED)) / (NIR + 6 * RED - 7.5 * BLUE + 1))', {
       'NIR': eviImg.select('nir'),
       'RED': eviImg.select('red'),
       'BLUE': eviImg.select('blue')
     }).rename('EVI');
   return img.addBands(eviImg);
 }
 
 yearlyComposites = yearlyComposites.map(function(image){
   return evi(image);
 });
 
 print(yearlyComposites, 'With EVI as Band');
Related Question