Skip to content

Commit

Permalink
Add LST Backward Average script (#333)
Browse files Browse the repository at this point in the history
* Initial setup LST Backwar Average scripts and docs

* Create and update color ramp in one command

---------

Co-authored-by: Amber Mulder <amber.mulder@planet.com>
  • Loading branch information
AmberMulder and AmberMulderPlanet authored Nov 5, 2024
1 parent ba2159c commit 59d4b9d
Show file tree
Hide file tree
Showing 4 changed files with 193 additions and 0 deletions.
1 change: 1 addition & 0 deletions planetary-variables/land-surface-temperature/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ Planet's LST product provides near real-time measurements twice a day at 1:30 an

- [Land Surface Temperature Visualization]({% link planetary-variables/land-surface-temperature/land-surface-temperature-visualization/index.md %})
- [Land Surface Temperature Anomaly]({% link planetary-variables/land-surface-temperature/land-surface-temperature-anomaly/index.md %})
- [Land Surface Temperature Backward Average]({% link planetary-variables/land-surface-temperature/land-surface-temperature-backward-average/index.md %})
- [Land Surface Temperature Quality Flags]({% link planetary-variables/land-surface-temperature/land-surface-temperature-quality-flags/index.md %})
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
title: Land Surface Temperature Backward Average
grand_parent: Planetary Variables
parent: Land Surface Temperature
layout: script
nav_exclude: false
scripts:
- [Visualization, script.js]
- [Raw Values, raw.js]
examples:
- zoom: '11'
lat: '44.8398'
lng: '-0.5294'
datasetId: '8d977093-cf9e-4351-8159-90f2522c29c1'
fromTime: '2022-12-01T00:00:00.000Z'
toTime: '2022-12-30T23:59:59.999Z'
platform:
- EOB
evalscripturl: https://custom-scripts.sentinel-hub.com/custom-scripts/planetary-variables/land-surface-temperature/land-surface-temperature-backward-average/script.js
additionalQueryParams:
- - themeId
- PLANET_SANDBOX
---
## General description
The Land Surface Temperature Backward Average is a method to reduce data gaps and measurement noise in the Land Surface Temperature (LST) data. Depending on the requirements, we can choose a lookback period, for example 20 days. The 20-day backward average of LST for day n is the average of LST over the 20 days preceding day n. We compute the backward average using all available measurements within this 20-day period, and therefore, we do have a valid value for every day, except in case of prolonged data unavailability, such as during long frost and snow periods.

## Why it is useful
The Land Surface Temperature Backward Average is suitable for applications where long-term temperatures are more relevant than daily fluctuations. The moving average operation reduces day-to-day variations and in the resulting time series, seasonal and longer-term changes can be easily detected. It can be used for monitoring drought risk, yield forecasting and analysis of climate change.

## Useful links
- [Product specifications](https://planet.widen.net/s/tltwk6hnps)
- [Data sheet](https://planet.widen.net/s/ttvp2rvwzd)
- [Sentinel Hub documentation about Land Surface Temperature](https://docs.sentinel-hub.com/api/latest/data/planetary-variables/land-surface-temp/)
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//VERSION=3

// LST has two observations per day: 1h30 and 13h30 solar local time

const date = "2022-12-31"; // The date for which the backward average is calculated
const nDays = 20; // The number of days to load data for
const scaleFactor = 100; // The scale factor for the SWC values
const sensing_time = "0130"; // Observation time: "0130" or "1330" or ""
const variable = "LST"; // Variable of interest: "LST" or "LST_MaskedPixels"

function setup() {
return {
input: [variable, "dataMask"],
output: { bands: 1, sampleType: "FLOAT32" },
mosaicking: "TILE",
};
}

// Select files based on sensing time (0130 or 1330) and within the last nDays
function preProcessScenes(collections) {
var calculationDate = new Date(date);
collections.scenes.tiles = collections.scenes.tiles.filter(function (tile) {
var tileDate = new Date(tile.date);
return (
tile.dataPath.includes("T" + sensing_time) &&
tileDate.getTime() >= calculationDate.getTime() - nDays * 24 * 3600 * 1000
);
});
return collections;
}

function get_mean_lst_value(samples) {
// Get the sum of all LST values
let n_valid_dates = 0;
let sum = 0;
for (let i = 0; i < samples.length; i++) {
if (samples[i].dataMask) {
sum += samples[i].LST / scaleFactor;
n_valid_dates += 1;
}
}

// Calculate the mean LST value
let mean_lst_value = NaN;
if (n_valid_dates > 0) {
mean_lst_value = sum / n_valid_dates;
}

return mean_lst_value;
}

function evaluatePixel(samples) {
// When there are no dates, return no data
if (samples.length == 0) return [NaN];

// Calculate mean LST value
const mean_lst_val = get_mean_lst_value(samples);

return [mean_lst_val];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
//VERSION=3

// Set defaultVis to false to scale and set color_min and color_max values.
// LST has two observations per day: 1h30 and 13h30 solar local time

const date = "2022-12-31"; // The date for which the backward average is calculated
const nDays = 20; // The number of days to load data for
const scaleFactor = 100; // The scale factor for the SWC values
const color_min = 260; // The minimum value of the colormap.
const color_max = 280; // The maximum value of the colormap.
const sensing_time = "0130"; // Observation time: "0130" or "1330" or ""
const variable = "LST"; // Variable of interest: "LST" or "LST_MaskedPixels"

function setup() {
return {
input: [variable, "dataMask"],
output: { id: "default", bands: 4 },
mosaicking: "TILE",
};
}

// Select files based on sensing time (0130 or 1330) and within the last nDays
function preProcessScenes(collections) {
var calculationDate = new Date(date);
collections.scenes.tiles = collections.scenes.tiles.filter(function (tile) {
var tileDate = new Date(tile.date);
return (
tile.dataPath.includes("T" + sensing_time) &&
tileDate.getTime() >= calculationDate.getTime() - nDays * 24 * 3600 * 1000
);
});
return collections;
}

function get_mean_lst_value(samples) {
// Get the sum of all LST values
let n_valid_dates = 0;
let sum = 0;
for (let i = 0; i < samples.length; i++) {
if (samples[i].dataMask) {
sum += samples[i].LST / scaleFactor;
n_valid_dates += 1;
}
}

// Calculate the mean LST value
let mean_lst_value = NaN;
if (n_valid_dates > 0) {
mean_lst_value = sum / n_valid_dates;
}

return mean_lst_value;
}

// Create color ramp 250 - 340 (full range)
const cmap = [
[263, 0x000004],
[266, 0x06051a],
[270, 0x140e36],
[274, 0x251255],
[278, 0x3b0f70],
[282, 0x51127c],
[286, 0x641a80],
[289, 0x782281],
[293, 0x8c2981],
[297, 0xa1307e],
[301, 0xb73779],
[305, 0xca3e72],
[309, 0xde4968],
[313, 0xed5a5f],
[316, 0xf7705c],
[320, 0xfc8961],
[324, 0xfe9f6d],
[328, 0xfeb77e],
[332, 0xfecf92],
[336, 0xfde7a9],
[340, 0xfcfdbf],
];

// Initialize the ColorRamp
const visualizer = new ColorRampVisualizer(cmap, color_min, color_max);

function evaluatePixel(samples) {
// When there are no dates, return no data
if (samples.length == 0) return [NaN, NaN, NaN, 0];

// Calculate mean LST value
const mean_lst_val = get_mean_lst_value(samples);

// Set opacity to 0 if there is no valid data
let opacity = 1;
if (isNaN(mean_lst_val)) {
opacity = 0;
}

// Apply colormap
imgVals = visualizer.process(mean_lst_val);
return [...imgVals, opacity];
}

0 comments on commit 59d4b9d

Please sign in to comment.