1

I am working on a new version of the bfast monitor algorithm in Google Earth Engine. See the code of the original algorithm on Github. The function bfastMonitor() takes user-defined parameters and applies some parameter checks before starting actual calculations. When the user-defined parameter settings are incompatible with the algorithm, an error should be raised.

During the parameter check, two types of if statements are made: statements that only check the parameter boundaries and raise an error at incompatible values, and statements that check and rewrite the contents of a parameter and raise an error at incompatible values. For the sake of the focus of this question, I will consider only the latter one.

Obviously, in a conventional coding paradigm, if-statements can be used to do this parameter check, however, using if-statements goes against the client-server model of GEE.

Consider the period parameter, which can only be 2,4,6,8, or 10. This parameter code used to index a list later in the code (line 459 on Github), where a period-value of 4 means that the list should be indexed at position 1, for instance.

Currently the implementation looks like this, using if-statements:

period = period||10

if (period == 2) {
   period  = 0;
} else if (period  == 4){
   period  = 1;
}else if (period  == 6){
   period  = 2;
}else if (period  == 8){
   period  = 3;
}else if (period  == 10){
   period  = 4;
}else {
  alert("Error: for period parameter, we only have 2, 4, 6, 8,10. Choose one of these values");
}

Later on, the period parameter is used a form like this (from Github):

var exampleList = ee.List([0.001, 0.002, 0.003, 0.004, 0.005]);
var exampleValue = exampleList[period]; 

The code could be rewritten easily to get rid of the if-statements, like this for instance:

var period = ee.Number(6);
var periodDict = ee.Dictionary({
  '2':0,
  '4':1,
  '6':2,
  '8':3,
  '10':4,
});
var exampleList = ee.List([0.001, 0.002, 0.003, 0.004, 0.005]);
var exampleValue = exampleList.get(periodDict.get(period.format()));

But then I don't know how to retain the opportunity to throw an error when the value for period is out of bounds.

How can I check the parameters of a function in Google Earth Engine and throw errors while avoiding if-statements?

saQuist
  • 416
  • 7
  • 19
  • The best way to handle this depends on _where the parameter came from_ (what data source, what code provided it) and what you're doing with it. Can you [edit] your question to say more about that? The right answer might be to use `if` anyway, or something else. – Kevin Reid May 05 '21 at 19:48
  • Hi @KevinReid, thank you for your comment, I have expanded the question now, I hope this helps. – saQuist May 06 '21 at 09:49

1 Answers1

1

There is nothing at all wrong with using a JavaScript if statement when it works. The advice you linked is about using ee.Algorithms.If which is unfortunately often inefficient — that's completely unrelated. The usual problem with a JavaScript if is when you're trying to use it on a server-side value that hasn't been computed yet.

But in your case, it looks like you want to validate a user-provided parameter. if is a perfectly fine way to do this.

I'll suggest one improvement: instead of using alert("error message");, use throw new Error:

  throw new Error("For period parameter, we only have 2, 4, 6, 8,10. Choose one of these values");

This has two advantages:

  • It doesn't pop a dialog that the user must interact with before fixing the problem, but just results in an error message in the usual place, the Code Editor's Console.
  • It will stop the rest of the code from executing, which alert() doesn't.
Kevin Reid
  • 37,492
  • 13
  • 80
  • 108
  • Thank you for clarifying both the proper contexts of if-statements, as well as the difference between `throw` and `alert`! – saQuist May 06 '21 at 18:09