I'm trying to map the maximal amount of days without rain using the TRMM dataset in Google Earth Engine. I'm doing this by iterating over the collection and if no rain has fallen, one gets added to the cell (code below). When rain has fallen the value gets multiplied by 0 so the "counter" is reset. Then I would like to store each result of each iteration in a Image collection and then select the maximum value to get the longest consecutive dry period.
But that is the theory. When I put this in a script I get an error while adding the image of one iteration to a list.
Does anyone know why this is and how this can be solved?
Code:
var list = [];
function drylength(current, previous){
var mask = current.remap([0], [1], 0,"precipitation").rename('precipitation');
var sum = mask.add(previous).multiply(mask);
list.push(sum);
return sum;
}
var dataset = TRMM
.filterDate("2015-01-01","2015-02-01")
.sort('system:time_start:');
var totalPrecipitation = dataset.iterate(drylength, dataset.max()
.remap([0], [0], 0, "precipitation")
.rename('precipitation'));
print(list);
print(totalPrecipitation);
Map.addLayer(ee.Image(totalPrecipitation), imageVisParam);
Furthermore it appears only 3 items are stored in the list which makes me assume the iteration is more complex than a literal iteration where all images are calculated one by one?
Here is an image of the error:
Errors written if image is not visible or for search engines:
Failed to decode JSON.
Error: Field 'value' of object '{"type":"ArgumentRef","value":null}' is missing or null.
Object: {"type":"ArgumentRef","value":null}.
and:
Unknown variable references: [_MAPPING_VAR_0_0, _MAPPING_VAR_0_1].
Best Answer
You've got some of the idea.
In Earth Engine, your JavaScript code is, by default, not at all involved in the substantial computation. Instead, it is executed to construct a data structure representing the desired computation (in JSON), which is then sent to the Earth Engine servers to be run.
Therefore, any client-side function in
map
oriterate
is not called for every item in the collection, but once to get that representation. (Or in this case, three times because you have three separate server calls: twoprint
s and aMap.addLayer
.)The documentation for
map
mentions this, but I see the documentation foriterate
doesn't.So, you cannot expect the code you have written, which modifies a variable from inside the function supplied to
iterate
, to be useful. It does not collect the actual data, but only the placeholders that are meant to be used byiterate
(hence names like_MAPPING_VAR_0_0
).Instead, what you must do is put the data you want to generate in the iterated value. In this case, this is easy to do — just return the accumulated list, and when you want the previous image take the last element of the list. So, I think this is what you wanted to do:
(Disclaimer: I have only modified the code so that it runs successfully, not checked whether the outputs are scientifically reasonable.)