Google Earth Engine – Calculating Equation from Two Collection Images

google-earth-enginegoogle-earth-engine-javascript-apiimage

I've got stuck when I'm trying to calculate MNDISI with MODIS. FYI, to calculate MNDISI, that should use LST collection image and SR collection image, so I'm trying to combine MODIS Surface Reflectance (MODIS/006/MOD11A1) and MODIS LST (MODIS/006/MOD09GA).

But I've got an error with the command:

Number (Error) reduce.mean: Error in map(ID=2020_01_01): Image.select:
Pattern 'LST_Day_1km' did not match any bands.

var jawa = ee.FeatureCollection("projects/ee-tugasakhirkkh/assets/Daerah_Penelitian");
Map.centerObject(jawa,7);

//Define Research Time
  var start = ee.Date('2020-01-01');
  var end = ee.Date('2020-12-31');
  
//Convert Kelvin to Celcius
  function celcius(img){
    return img.multiply(0.02).subtract(273.15)
              .copyProperties(img,['system:time_start']);
  }
//LST Terra MODIS 
  var terra_kelvin = ee.ImageCollection('MODIS/006/MOD11A1')
                       .select('LST_Day_1km')
                       .filterDate(start,end);
  var terra_LST = terra_kelvin.map(celcius);
  print(terra_LST);
  
var modisProjection = terra_LST.first().projection();
print('MODIS LST Projection:', modisProjection.nominalScale());

//Downsetting Function
function reduceres(image){
  return image.reduceResolution({
    reducer : ee.Reducer.mean(),
    maxPixels : 1024
  })
  .reproject({
    crs : modisProjection
  });
}

//MNDISI Function
function MNDISIModis(a){
  var green = a.select('sur_refl_b04'); 
  var swir = a.select('sur_refl_b05');
  var nir = a.select('sur_refl_b02');
  var b = 3;
  var lst = a.select('LST_Day_1km');
  var mndwi = (green.subtract(swir)).divide(green.add(swir)).rename('mndwi');
  var mndisi = (lst.subtract((mndwi.add(nir).add(swir)).divide(b))).divide(lst.add((mndwi.add(nir).add(swir)).divide(b))).rename('mndisi');
  return a.addBands(mndisi).copyProperties(a,['system:time_start']);
}

//MNDISI Terra
var terra_SR = ee.ImageCollection("MODIS/006/MOD09GA")
                .filterDate(start,end)
                .map(MNDISIModis)
                .map(reduceres)
                .map(function(img){
                        return img.addBands(terra_LST.filter(ee.Filter.eq('system:index',img.get('system:index'))))
                     })
    
var terraMNDISI = terra_SR.select('MNDISI').mean();
var terraMNDISI_clip = terraMNDISI.clip(jawa);

//Check the Resolution
var terra_proj = terraMNDISI_clip.projection();
print('MODIS MNDISI Projection:', terra_proj.nominalScale());

var param = {
  min: -1.0,
  max: 1.0,
  palette: [
    'FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718', '74A901',
    '66A000', '529400', '3E8601', '207401', '056201', '004C00', '023B01',
    '012E01', '011D01', '011301'
  ],
};

Map.addLayer(terraMNDISI_clip,param,'Average MNDISI in 2020');

//Create Legend
//CreatePalette
function makeColorBarParams(palette) {
  return {
    bbox: [0, 0, 1, 0.1],
    dimensions: '200x20',
    format: 'png',
    min: 0,
    max: 1,
    palette: palette,
  };
}

//Create ColorBar
var colorBar = ui.Thumbnail({
  image: ee.Image.pixelLonLat().select(0),
  params: makeColorBarParams(param.palette),
  style: {stretch: 'vertical', margin: '0px 8px', maxHeight: '24px'},
});

//Create Panels
var legendLabels = ui.Panel({
  widgets: [
    ui.Label(param.min, {margin: '4px 5px', textAlign: 'left'}),
    ui.Label(param.max, {margin: '4px 170px', textAlign: 'right'})
  ],
  layout: ui.Panel.Layout.flow('horizontal')
});

var legendTitle = ui.Label({
  value: 'Average MNDISI in 2020',
  style: {fontWeight: 'bold'}
});

//Show Legend
var legendPanel = ui.Panel([legendTitle, colorBar, legendLabels]);
Map.add(legendPanel);

I haven't found any related reference to help solve my problem and tried with other combinations but still can't solve the problem.

Best Answer

The problem is functions order. First, you add LST band, then you compute MNDISI.

Also, this chunk won't work:

.map(function(img){
    return img.addBands(terra_LST.filter(ee.Filter.eq('system:index',img.get('system:index'))))
    })

You are mapping addBands() function trying to add bands from an ee.ImageCollection, it should be ee.Image type. No worries, .first() does the trick.

I recommend you to include addBands() in MNDISI calculation, as:

//MNDISI Function
function MNDISIModis(a){
  var green = a.select('sur_refl_b04'); 
  var swir = a.select('sur_refl_b05');
  var nir = a.select('sur_refl_b02');
  var b = 3;
  var lst = terra_LST.filter(ee.Filter.eq('system:index',a.get('system:index'))).first().select('LST_Day_1km');
  var mndwi = (green.subtract(swir)).divide(green.add(swir)).rename('mndwi');
  var mndisi = (lst.subtract((mndwi.add(nir).add(swir)).divide(b))).divide(lst.add((mndwi.add(nir).add(swir)).divide(b))).rename('mndisi');
  return a.addBands(mndisi).copyProperties(a,['system:time_start']);
}
Related Question