V3 sentinel 2A removal cloud slow image loading

Hi all,

I use script to remove cloud in Sentinel 2A for 1 month ago but the images don’t display.
Could you tell me why and how to fix it? Thank you
//VERSION=3

function setup() {
return {
input: [{
bands: [
“B04”,
“B03”,
“B02”,
“SCL”
],
units: “DN”
}],
output: {
bands: 3,
sampleType: SampleType.UINT8
},
mosaicking: “ORBIT”
}
}
function filterScenes (scenes, inputMetadata) {
return scenes.filter(function (scene) {
return scene.date.getTime()>=(inputMetadata.to.getTime()-2312436001000);
});
}
function getValue(values) {
values.sort( function(a,b) {return a - b;} );
return getFirstQuartile(values);
}

function getFirstQuartile(sortedValues) {
var index = Math.floor(sortedValues.length / 4);
return sortedValues[index];
}
function getDarkestPixel(sortedValues) {
return sortedValues[0]; // darkest pixel
}
function validate (samples) {
var scl = samples.SCL;

if (scl === 3) { // SC_CLOUD_SHADOW
return false;
} else if (scl === 9) { // SC_CLOUD_HIGH_PROBA
return false;
} else if (scl === 8) { // SC_CLOUD_MEDIUM_PROBA
return false;
} else if (scl === 7) { // SC_CLOUD_LOW_PROBA / UNCLASSIFIED
// return false;
} else if (scl === 10) { // SC_THIN_CIRRUS
return false;
} else if (scl === 11) { // SC_SNOW_ICE
return false;
} else if (scl === 1) { // SC_SATURATED_DEFECTIVE
return false;
} else if (scl === 2) { // SC_DARK_FEATURE_SHADOW
// return false;
}
return true;
}

function evaluatePixel(samples, scenes) {
var clo_b02 = []; var clo_b03 = []; var clo_b04 = [];
var clo_b02_invalid = []; var clo_b03_invalid = []; var clo_b04_invalid = [];
var a = 0; var a_invalid = 0;

for (var i = 0; i < samples.length; i++) {
var sample = samples[i];
if (sample.B02 > 0 && sample.B03 > 0 && sample.B04 > 0) {
var isValid = validate(sample);

  if (isValid) {
    clo_b02[a] = sample.B02;
    clo_b03[a] = sample.B03;
    clo_b04[a] = sample.B04;
    a = a + 1;
  } else {
    clo_b02_invalid[a_invalid] = sample.B02;
    clo_b03_invalid[a_invalid] = sample.B03;
    clo_b04_invalid[a_invalid] = sample.B04;
    a_invalid = a_invalid + 1;
  }
}

}

var rValue;
var gValue;
var bValue;
if (a > 0) {
rValue = getValue(clo_b04);
gValue = getValue(clo_b03);
bValue = getValue(clo_b02);
} else if (a_invalid > 0) {
rValue = getValue(clo_b04_invalid);
gValue = getValue(clo_b03_invalid);
bValue = getValue(clo_b02_invalid);
} else {
rValue = 0;
gValue = 0;
bValue = 0;
}
return [rValue/100002552.5, gValue/100002552.5, bValue/100002552.5]
}

Dear Hoang,

your script had a couple of mistakes, which prevented it from working.

  • You used incorrect quotation marks around the bands and DN in your function setup(). You used ”, while " should be used.
  • sampleType: SampleType.UINT8 isn’t the correct format for specifying sampleType. In V3, it should be sampleType: "UINT8".
  • In your return statement, you had return [rValue/100002552.5, gValue/100002552.5, bValue/100002552.5], which looks like you tried to divide it by 10000, 255 and 2.5 at the same time, returning a number much too large. I found that dividing by 10 works best for this script.
  • In your function filterScenes(scenes, inputMetadata), you had 2312436001000 instead of 2*31*24*3600*1000. The time units in Javascript are in milliseconds. So when you specified 2312436001000, you did not specify that you want 2 months, 31 days, and so on, but that you want 2312436001000 milliseconds, which is some 72 years. This is why, after fixing other mistakes, your script took a long time to load; it took into account all the data as far back in time as it could get (of course there is no 72 years of data for S2), which is years. When we write * between the numbers, we then multply them, which for 2*31*24*3600*1000 comes to be 5356800000 miliseconds, which is 2 months, as we want. This is why you should always add *, to make it possible for you to specify the timerange, unless you calculate the milliseconds for your timerange and insert them instead.

Please find the corrected script below, and view it in EO Browser.

//VERSION=3
function setup() {
    return {
        input: [{
            bands: [
                "B04",
                "B03",
                "B02",
                "SCL"
            ],
            units: "DN"
        }],
        output: {
            bands: 3,
            sampleType: "UINT8"
        },
        mosaicking: "ORBIT"
    }
}

function filterScenes(scenes, inputMetadata) {
    return scenes.filter(function(scene) {
        return scene.date.getTime() >= (inputMetadata.to.getTime() - 2 * 31 * 24 * 3600 * 1000);
    });
}

function getValue(values) {
    values.sort(function(a, b) {
        return a - b;
    });
    return getFirstQuartile(values);
}

function getFirstQuartile(sortedValues) {
    var index = Math.floor(sortedValues.length / 4);
    return sortedValues[index];
}

function getDarkestPixel(sortedValues) {
    return sortedValues[0]; // darkest pixel
}

function validate(samples) {
    var scl = samples.SCL;

    if (scl === 3) { // SC_CLOUD_SHADOW
        return false;
    } else if (scl === 9) { // SC_CLOUD_HIGH_PROBA
        return false;
    } else if (scl === 8) { // SC_CLOUD_MEDIUM_PROBA
        return false;
    } else if (scl === 7) { // SC_CLOUD_LOW_PROBA / UNCLASSIFIED
        //return false;
    } else if (scl === 10) { // SC_THIN_CIRRUS
        return false;
    } else if (scl === 11) { // SC_SNOW_ICE
        return false;
    } else if (scl === 1) { // SC_SATURATED_DEFECTIVE
        return false;
    } else if (scl === 2) { // SC_DARK_FEATURE_SHADOW
        //return false;
    }
    return true;
}

function evaluatePixel(samples, scenes) {
    var clo_b02 = [];
    var clo_b03 = [];
    var clo_b04 = [];
    var clo_b02_invalid = [];
    var clo_b03_invalid = [];
    var clo_b04_invalid = [];
    var a = 0;
    var a_invalid = 0;

    for (var i = 0; i < samples.length; i++) {
        var sample = samples[i];
        if (sample.B02 > 0 && sample.B03 > 0 && sample.B04 > 0) {
            var isValid = validate(sample);

            if (isValid) {
                clo_b02[a] = sample.B02;
                clo_b03[a] = sample.B03;
                clo_b04[a] = sample.B04;
                a = a + 1;
            } else {
                clo_b02_invalid[a_invalid] = sample.B02;
                clo_b03_invalid[a_invalid] = sample.B03;
                clo_b04_invalid[a_invalid] = sample.B04;
                a_invalid = a_invalid + 1;
            }
        }
    }

    var rValue;
    var gValue;
    var bValue;
    if (a > 0) {
        rValue = getValue(clo_b04);
        gValue = getValue(clo_b03);
        bValue = getValue(clo_b02);
    } else if (a_invalid > 0) {
        rValue = getValue(clo_b04_invalid);
        gValue = getValue(clo_b03_invalid);
        bValue = getValue(clo_b02_invalid);
    } else {
        rValue = 0;
        gValue = 0;
        bValue = 0;
    }
    return [rValue / 10, gValue / 10, bValue / 10]
}

Best,
Monja

Thank you so much Monja.
I have a question about units miliseconds.
Example : 2 * 31 * 24 * 3600 * 1000
2: 2 months ago, right?
If I make mosaic 1 years ago (12 months ago), it means miliseconds: 12 * 31 * 24 * 3600 * 1000, right?

Thank you