0

This is the code that has an error. I don´t know how to fix it.

I am trying to get the albedo values of a range of time: 2001-2018 and just of 4 months of each year, September to December.

var col = ee.ImageCollection('MODIS/006/MCD43A3')
                  .filter(ee.Filter.date('2001-01-01', '2018-12-31'))
                  .filterBounds(geometry).select('Albedo_WSA_shortwave'); 
                   
// Functions to stack colletion series into image bands 

var stackCollection = function(collection) {
  var first = ee.Image(collection.first()).select([]);
  var appendBands = function(image, previous) 
  {return ee.Image(previous).addBands(image);};
  return ee.Image(collection.iterate(appendBands, first));};

// Function to generate mask for each Scene.

var getSceneMask = function(scene) {
  var dateString = ee.Date(scene.get('system:time_start')).format('yyyy-MM-dd');
  var mask = scene.select('Albedo_WSA_shortwave').gt(-9999).updateMask(ee.Image(1)); 
  return mask.rename(dateString);};

//Stacked mask for collection
    
var Maskcol = stackCollection(col.map(getSceneMask));

// Generate a datelist for collection 

var datelist = ee.List(Maskcol.bandNames()).map(function(date){return ee.Date(date).format('yyyy-MM-dd')});

// Stack bands and rename by date  

var WSA_stacked = stackCollection(col.select('Albedo_WSA_shortwave')).multiply(0.001).rename(datelist).clip(geometry);


Map.addLayer(WSA_stacked.select(20), {min:0.0, max:400, gamma:2}); 

print(WSA_stacked);
print(datelist);

// Exportar datos //

Export.image.toDrive({
  image: WSA_stacked.clip(geometry),
  description: 'MODIS_WSA_stacked',
  region: geometry,
  folder: 'ejemplo',
  scale: 500,
  crs: 'EPSG:4326'});
4
  • 1
    Please Edit the question to state, in words, what you are trying to accomplish. Since it reports a memory error, reporting the amount of RAM on your system, and the amount used by the process is strongly recommended. An indication of where in the code the error occurs is also necessary.
    – Vince
    Commented Jun 17, 2020 at 22:01
  • @Vince While I agree that a detailed problem statement is good practice, please note that in google-earth-engine the computation does not execute on the user's computer, and there are no options to vary the amount of RAM available to the server performing the computation — it's “one size fits all".
    – Kevin Reid
    Commented Jun 17, 2020 at 22:40
  • 1
    @val Note that this produces an image with 6569 bands - depending on the size of your geometry, the export could be large and difficult to deal with. What is the end goal - can you process the data further in EE before export - some kind of reduction maybe? Commented Jun 17, 2020 at 22:47
  • I need the values of albedo between 2001 and 2018 for 4 months, (sept-dec) but I don´t know hoy to filter for this dates on each year.
    – val
    Commented Jun 17, 2020 at 23:22

1 Answer 1

3

Your stackCollection function is an inefficient way to go about combining an image collection's bands into an image, and is not needed. You can use the built-in ImageCollection.toBands(), instead. It produces band names of the form "imageId_bandName" so we'll have to reformat the strings, but the image IDs are already the dates, so we don't have to save the system:time_start separately, just change the text format.

var col = ee.ImageCollection('MODIS/006/MCD43A3')
  .filter(ee.Filter.date('2001-01-01', '2018-12-31'))
  .filterBounds(geometry)
  .select('Albedo_WSA_shortwave'); 

var colStacked = col.toBands();

var datelist = colStacked.bandNames().map(function(bandName){
  // Band names from toBands are of the form "imageId_bandName",
  // so in this case they are the date with underscores followed by "_Albedo_WSA_shortwave".
  // Match the underscores, replace them with dashes, and discard the rest.
  return ee.String(bandName).replace("^(\\d+)_(\\d+)_(\\d+)_.*$", "$1-$2-$3");
});

// Or, instead of using the image IDs we can use system:time_start from the
// collection. This computes the same value; use whichever you like.
var datelist2 =
  ee.List(
    col.reduceColumns(ee.Reducer.toList(), ['system:time_start']).get('list'))
  .map(function(timestamp) {
    return ee.Date(timestamp).format('yyyy-MM-dd');
  });

// Stack bands and rename bands by date  
var WSA_stacked = colStacked
  .multiply(0.001)
  .rename(datelist)
  .clip(geometry);

https://code.earthengine.google.com/0bfc7bc140517ffd157e8e9862f23e42

Note that I left out your getSceneMask because the only part of it that was actually used in your script was the band names. If you intended to mask the images, I recommend doing it in a .map() rather than building a separate collection and image and list, i.e. change col rather than the later steps.

I also removed several redundant .select()s — the one in the definition of col is all that is necessary.

2
  • I get lost in this part: return ee.String(bandName).replace("^(\\d+)_(\\d+)_(\\d+)_.*$", "$1-$2-$3"); });
    – val
    Commented Jun 17, 2020 at 23:01
  • @val Reasonable — regular expressions are a great tool but they can be cryptic. I've added an alternative that uses the date formatting like your original code did,
    – Kevin Reid
    Commented Jun 18, 2020 at 3:31

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.