Skip to content

Commit

Permalink
Add swc backward average script (#331)
Browse files Browse the repository at this point in the history
* Add initial setup SWC backward average

* Add SWC Backward Average to index page

* Remove abundant ;

* Ensure average is also returned when there is no data for the last day

* Ensure average is also returned when there is no data for the last day and created opacity mask from calculated average pixels

* Make constants out of returned mean swc values

* Add documentation on SWC backward average

* Add SWC docs link and update examples of short-term fluctuations

* Return one NaN when no data

Co-authored-by: Jonas <[email protected]>

* Avoid the use of mapping

* Auto-formatting, added back FLOAT32 output

---------

Co-authored-by: Amber Mulder <[email protected]>
Co-authored-by: Jonas <[email protected]>
Co-authored-by: Jonas Viehweger <[email protected]>
  • Loading branch information
4 people authored Oct 28, 2024
1 parent 999afca commit 5de3c9d
Show file tree
Hide file tree
Showing 4 changed files with 185 additions and 0 deletions.
1 change: 1 addition & 0 deletions planetary-variables/soil-water-content/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ Planet's SWC product provides near-daily measurements at spatial resolutions of
- [Soil Water Content Visualization]({% link planetary-variables/soil-water-content/soil-water-content-visualization/index.md %})
- [Soil Water Content Anomaly]({% link planetary-variables/soil-water-content/soil-water-content-anomaly/index.md %})
- [Derived Root-Zone Soil Water Content]({% link planetary-variables/soil-water-content/derived-root-zone-soil-water-content/index.md %})
- [Soil Water Content Backward Average]({% link planetary-variables/soil-water-content/soil-water-content-backward-average/index.md %})
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
title: Soil Water Content Backward Average
grand_parent: Planetary Variables
parent: Soil Water Content
layout: script
nav_exclude: false
scripts:
- [Visualization, script.js]
- [Raw Values, raw.js]
examples:
- zoom: '11'
lat: '41.1921'
lng: '-93.845'
datasetId: '65f7e4fb-a27a-4fae-8d79-06a59d7e6ede'
fromTime: '2022-05-01T00:00:00.000Z'
toTime: '2022-05-26T23:59:59.999Z'
platform:
- EOB
evalscripturl: https://custom-scripts.sentinel-hub.com/custom-scripts/planetary-variables/soil-water-content/soil-water-content-backward-average/script.js
additionalQueryParams:
- - themeId
- PLANET_SANDBOX
---
## General description
The Soil Water Content Backward Average is a method to reduce data gaps and measurement noise in the Soil Water Content (SWC) data. Depending on the requirements, we can choose a lookback period, for example 20 days. The 20-day backward average of SWC for day n is the average of SWC 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
Our [Soil Water Content](https://custom-scripts.sentinel-hub.com/planetary-variables/soil-water-content/soil-water-content-visualization/) provides a great reflection of the immediate soil conditions. However, daily measurements often exhibit short-term fluctuations due to for example rainfall events and evaporation. The Soil Water Content Backward Average is suitable for applications where long-term soil moisture conditions 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
- [SWC Technical specifications](https://developers.planet.com/docs/planetary-variables/soil-water-content-technical-specification/)
- [SWC Data sheet](https://planet.widen.net/s/cv7bfjhhd5)
- [Sentinel Hub documentation about Soil Water Content](https://docs.sentinel-hub.com/api/latest/data/planetary-variables/soil-water-content/)
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//VERSION=3

const nDays = 20; // The number of days to load data for
const scaleFactor = 1000; // The scale factor for the SWC values

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

function preProcessScenes(collections) {
collections.scenes.orbits = collections.scenes.orbits.filter(function (
orbit
) {
var orbitDateFrom = new Date(orbit.dateFrom);
// Select all images within the last nDays
return (
orbitDateFrom.getTime() >=
collections.to.getTime() - nDays * 24 * 3600 * 1000
);
});
return collections;
}

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

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

return mean_swc_value;
}

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

// Calculate mean SWC value
const mean_swc_val = get_mean_swc_value(samples);

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

const nDays = 20; // The number of days to load data for
const scaleFactor = 1000; // The scale factor for the SWC values
const vmin = 0.0; // The minimum value of the colormap
const vmax = 0.4; // The maximum value of the colormap

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

function preProcessScenes(collections) {
collections.scenes.orbits = collections.scenes.orbits.filter(function (
orbit
) {
var orbitDateFrom = new Date(orbit.dateFrom);
// Select all images within the last nDays
return (
orbitDateFrom.getTime() >=
collections.to.getTime() - nDays * 24 * 3600 * 1000
);
});
return collections;
}

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

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

return mean_swc_value;
}

const cmap = [
[0.0, 0xfff7ea],
[0.05, 0xfaedda],
[0.1, 0xede4cb],
[0.15, 0xdedcbd],
[0.2, 0xced3af],
[0.25, 0xbdcba3],
[0.3, 0xaac398],
[0.35, 0x96bc90],
[0.4, 0x80b48a],
[0.45, 0x68ac86],
[0.5, 0x4da484],
[0.55, 0x269c83],
[0.6, 0x009383],
[0.65, 0x008a85],
[0.7, 0x008186],
[0.75, 0x007788],
[0.8, 0x006d8a],
[0.85, 0x00618c],
[0.9, 0x00558d],
[0.95, 0x00478f],
[1.0, 0x003492],
];

// Prepare colormap based on provided min and max values
const visualizer = new ColorRampVisualizer(cmap, vmin, vmax);

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

// Calculate mean SWC value
const mean_swc_val = get_mean_swc_value(samples);

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

// Apply colormap
imgVals = visualizer.process(mean_swc_val);

return [...imgVals, opacity];
}

0 comments on commit 5de3c9d

Please sign in to comment.