1

I am trying to apply a distance function to a collection of masked images, but am receiving a "Parameter 'index' is required" error. I've found answers for other "Parameter 'xyz' is required/missing" errors but nothing for 'index'.

The function works when I input independent years (e.g. '7' or '12') but not when applied to over the list of years. It seems like there is some trouble indexing each image after applying the function but I'm not sure why. I've tried setting the system index (set("system:index", y)) within the function but still no luck. I've even tried nesting functions instead of having two arguments within one function, but the same error shows up. I'm by no means a GGE expert so please let me know if I'm missing something easy!

Here is the code for the non-nested function modified to an 'ImageCollection' for generalizability:

// List of last two digits of years 2000-2016 to call from a list of 17 tree cover images (1 from each
// year)

var years = ee.List.sequence(0,16);

// function to calculate distance (for each image in an Image Collection) from each masked pixel to 
// nearest unmasked pixel

function distance(coll, y) {
  var list = coll.toList(years.size()); // converting to list to call by indexed number
  var non_tc = ee.Image(list.get(Math.round(y))).lte(0);   // using 'round' to convert floats to integers
  var tc = ee.Image(list.get(Math.round(y))).gt(0);
  var dist = non_tc.cumulativeCost({
                      source: tc,
                      maxDistance: 10000
    });
  return dist
    .set('year', y);
}

// When applied to one year, it works fine:
var test12 = distance(ImageCollection, 12);

// When I try to apply it to all years, I get the error:
var dist_coll = distance(ImageCollection, years);
print('dist_coll', dist_coll);

Here's another version of the function using "map", which returns the same error:

function distance1(coll) {
  var list = coll.toList(years.size());
  var non_tc = ee.Image(list.get(Math.round(yeears))).lte(0);
  var tc = ee.Image(list.get(Math.round(years))).gt(0);
  var dist = non_tc.cumulativeCost({
                      source: tc,
                      maxDistance: 10000
    });
  return dist
    .set('year', y);
}

var dist_coll1 = years.map(distance1(ImageCollection));
print('dist_coll1', dist_coll1);

And trying to nest functions, with the same result:

var distance2 = function(coll) {
  var dist = function(y) {
       var list = coll.toList(years.size());
       var non_tc = ee.Image(list.get(Math.round(y))).lte(0);
       var tc = ee.Image(list.get(Math.round(y))).gt(0);
       var cost = non_tc.cumulativeCost({
                        source: tc,
                        maxDistance: 10000});
          return cost
            .set('year', y);
      };
   return coll.map(dist);
};

var dist_coll2 = years.map(distance2(ImageCollection));
print('dist coll2', dist_coll2);

2 Answers 2

0

I think you misinterpreted the use of function in this lines:

// When applied to one year, it works fine:
var test12 = distance(ImageCollection, 12);

It means that you are calculating cumulative cost for an image with id equal 12; not for a group of them equivalent a year. So, variable year is a total number of images in complete list (not a specific year). So, I assumed MODIS/006/MOD09GA as ImageCollection variable in your code (where it was arbitrarily selected 'sur_refl_b01' band for estimating cost) and following date range '2019-06-01', '2019-06-30' (29 images in this Image Collection). Complete code (with several modifications; including Gorelick's suggestion) looks as follows:

var ImageCollection = ee.ImageCollection('MODIS/006/MOD09GA')
        .select('sur_refl_b01')
        .filterDate('2019-06-01', '2019-06-30');

print(ImageCollection);

// List of last two digits of years 2000-2016 to call from a list of 17 tree cover images (1 from each
// year)

var imageNumbers = ee.List.sequence(0, ImageCollection.size().subtract(1));

print("Image Number", imageNumbers);

// function to calculate distance (for each image in an Image Collection) from each masked pixel to 
// nearest unmasked pixel

function distance(coll, y) {
  var list = coll.toList(imageNumbers.size()); // converting to list to call by indexed number
  var non_tc = ee.Image(list.get(y)).lte(0);   // using 'round' to convert floats to integers
  var tc = ee.Image(list.get(y)).gt(0);
  var dist = non_tc.cumulativeCost({
                      source: tc,
                      maxDistance: 10000
    });

  return dist
    .set('id_number', y);
}

// Mapping now imageNumbers list (not years), it works fine:
var cumCostImages = imageNumbers.map(function(ele){

  return distance(ImageCollection, ele);

});

print("Cumulative Cost Images", cumCostImages);

After running above code in GEE code editor, I got result of following image (without any "Parameter 'index' is required" error). It can be observed cumulative_cost default number for band of first image and id_number as property.

enter image description here

1
  • Many thanks for the help with the function @xunilk, that worked! I was putting the list of year #s into the function instead of mapping it for the first example (explains the Math.round() issue) and had the function order wrong in others. I did still get the "Parameter 'index' is required" error before cleaning up other parts of the script, so there must've been something else causing the error. I'm still working to reproduce it to understand the cause of that specific error message and will comment again when I've figured it out. Regardless, thanks for the response and clear example.
    – Jay Schoen
    Apr 5, 2021 at 12:42
0

You cannot use Math.round on a computed value. Math.round is a browser function that happens immediately; the list (and the values in it) don't even exist until everything gets to the server.

However, you don't even need the Math.round at all. The sequence only contains integers.

1
  • Thank you for getting back @Noel! For some reason when I don't use the Math.round(), I get the error: "List.get, argument 'index': Invalid type. Expected type: Integer. Actual type: List<Float>. Actual value: [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0]." Not sure why they are floats instead of integers, but the the Math.round() seemed to take care of that. Any idea what the "Parameter index is required" error might be from?
    – Jay Schoen
    Apr 3, 2021 at 16:32

Your Answer

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