0

I want to know how to multiply every single image of a collection against its respective coefficient allocated in a list. It means to multiply the image 5 with the element 5, image 6 with element 6, and so on...

This is part of my code:

// COLLECTION
    var sentinel2 = ee.ImageCollection('COPERNICUS/S2_SR')
    .filterBounds(aoi)
    .filterDate('2019-01-01', '2019-12-31')
    .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 30))
    .map(rescale).map(cloudMask)
    .select('B[1-7]');

// List of zenith angles
var zenith_list = ee.Array(sentinel2.aggregate_array('MEAN_SOLAR_ZENITH_ANGLE'))

// Apply equation:
// ((0.0000006)*(zenith^3)) - ((0.0002)*(zenith^2)) + ((0.0006)*zenith) + 0.9975
var pow3 = zenith_list.pow(3)
var pow2 = zenith_list.pow(2)
var part1 = pow3.multiply(6e-7)
var part2 = pow2.multiply(2e-4)
var part3 = zenith_list.multiply(6e-4)
var equation = part1.subtract(part2).add(part3).add(0.9975)

// Calculate the difference between the calculated reflectance proportion and the reference
var reference = ee.Number(0.7071);
var delta = equation.subtract(reference).abs()

This is the part that I don't know if I'm doing right:

// Normalize every band reflectance of the imagery
var normal = sentinel2.map(function(img){
    var image = ee.Image(img).multiply(delta)//.toFloat()
  return image.copyProperties(img, img.propertyNames());
})
print('Normalized Imagery:',normal)

Then I want to create a chart using the new image collection, but I'm getting the following error:

"Error generating chart: Input must be a scalar number."

// Create an image time series chart.
var chart = ui.Chart.image.series({
  imageCollection: ee.ImageCollection(normal),
  region: aoi,
  reducer: ee.Reducer.mean(),
  scale: 1000
});

print('Chart',chart)

This is the link of my code if you want to check it out: https://code.earthengine.google.com/98a1194fa641ed8a7dde0f2166424313

Thank you.

UPDATE:

Everything works well when I multiply the collection by a single number, instead of the list of numbers.

In the first case, the band data type produced is "double ∈". But, for the second case, the bands are "double, 1 dimension". I think that my list of numbers is an array, which is converting the data type of the image collection after the multiplication... how can I fix this?

SOLUTION:

I already came up with a solution to this issue. My list of numbers was an array-type one, so I added .toList() to convert it to a list-type. Then, I apply the following function to multiply each image by its respective factor in the list (this function was tweaked from the solution provided to the shared post by hami kelvin):

//Convert array to list
delta = delta.toList();

// Combine into a list of elements containing an image and a scaling factor.
var MAX_ELEMENTS = 1000;
var zippedList = sentinel2.toList(MAX_ELEMENTS).zip(delta);

// Map a function over the list to scale each image.
var scaledCollection = ee.ImageCollection.fromImages(
  zippedList.map(function (list) {
    list = ee.List(list);
    var img = ee.Image(_list.get(0));
    var scale = list.getNumber(1);
    var scaledImage = img.multiply(scale);
    scaledImage = scaledImage.double() // Set the data type, so the collection is consistent.
    return scaledImage.copyProperties(img, img.propertyNames()); 
  })
);

Note that I added .copyProperties to conserve the properties of every image in the collection after the computation and then create a chart.

Thanks to everyone that replied to this thread.

2
1

Your code should work, if you put the equation into the map function. And get the MEAN_SOLAR_ZENITH_ANGLE for every image you map over.

// Normalize every band reflectance of the imagery
var normal = sentinel2.map(function(img){
  var zenith = img.getNumber('MEAN_SOLAR_ZENITH_ANGLE')

  // Apply equation:
  // ((0.0000006)*(zenith^3)) - ((0.0002)*(zenith^2)) + ((0.0006)*zenith) + 0.9975
  var pow3 = zenith.pow(3)
  var pow2 = zenith.pow(2)
  var part1 = pow3.multiply(6e-7)
  var part2 = pow2.multiply(2e-4)
  var part3 = zenith.multiply(6e-4)
  var equation = part1.subtract(part2).add(part3).add(0.9975)

  // Calculate the difference between the calculated reflectance proportion and the reference
  var reference = ee.Number(0.7071);
  var delta = equation.subtract(reference).abs()

  var image = ee.Image(img).multiply(delta)//.toFloat()
  return image.copyProperties(img, img.propertyNames());
})
print('Normalized Imagery:',normal)
4
  • Thanks for clarifying my doubts. But, when I want to create a chart is showing an error, any solution for that? – Luis Lizcano Jun 3 '20 at 12:01
  • I added an update to my question – Luis Lizcano Jun 3 '20 at 13:21
  • Just a comment: My code is displaying the chart perfectly. Also, the solution you edited in your post is NOT working as intended. In your solution you are always multiplying with the same number from the list. Check out my version here, it's much better to do it this way: code.earthengine.google.com/395facadd631d3627a2f7c325de925f6 – JonasV Jun 3 '20 at 20:05
  • Jonas- Thank you for your message. That is also a great approach. Both methods are suitable and work fine I guess it can vary slightly from what we need to evaluate. This is the link comparing both methods and showing same results: code.earthengine.google.com/8cc5c62a6eab5d73c08ec8e232324337 – Luis Lizcano Jun 9 '20 at 16:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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