Skip to content

Commit 5de3c9d

Browse files
AmberMulderAmberMulderPlanetjonasViehwegerJonas Viehweger
authored
Add swc backward average script (#331)
* 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]>
1 parent 999afca commit 5de3c9d

File tree

4 files changed

+185
-0
lines changed

4 files changed

+185
-0
lines changed

planetary-variables/soil-water-content/index.md

+1
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ Planet's SWC product provides near-daily measurements at spatial resolutions of
1414
- [Soil Water Content Visualization]({% link planetary-variables/soil-water-content/soil-water-content-visualization/index.md %})
1515
- [Soil Water Content Anomaly]({% link planetary-variables/soil-water-content/soil-water-content-anomaly/index.md %})
1616
- [Derived Root-Zone Soil Water Content]({% link planetary-variables/soil-water-content/derived-root-zone-soil-water-content/index.md %})
17+
- [Soil Water Content Backward Average]({% link planetary-variables/soil-water-content/soil-water-content-backward-average/index.md %})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
---
2+
title: Soil Water Content Backward Average
3+
grand_parent: Planetary Variables
4+
parent: Soil Water Content
5+
layout: script
6+
nav_exclude: false
7+
scripts:
8+
- [Visualization, script.js]
9+
- [Raw Values, raw.js]
10+
examples:
11+
- zoom: '11'
12+
lat: '41.1921'
13+
lng: '-93.845'
14+
datasetId: '65f7e4fb-a27a-4fae-8d79-06a59d7e6ede'
15+
fromTime: '2022-05-01T00:00:00.000Z'
16+
toTime: '2022-05-26T23:59:59.999Z'
17+
platform:
18+
- EOB
19+
evalscripturl: https://custom-scripts.sentinel-hub.com/custom-scripts/planetary-variables/soil-water-content/soil-water-content-backward-average/script.js
20+
additionalQueryParams:
21+
- - themeId
22+
- PLANET_SANDBOX
23+
---
24+
## General description
25+
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.
26+
27+
## Why it is useful
28+
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.
29+
30+
31+
## Useful links
32+
- [SWC Technical specifications](https://developers.planet.com/docs/planetary-variables/soil-water-content-technical-specification/)
33+
- [SWC Data sheet](https://planet.widen.net/s/cv7bfjhhd5)
34+
- [Sentinel Hub documentation about Soil Water Content](https://docs.sentinel-hub.com/api/latest/data/planetary-variables/soil-water-content/)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
//VERSION=3
2+
3+
const nDays = 20; // The number of days to load data for
4+
const scaleFactor = 1000; // The scale factor for the SWC values
5+
6+
function setup() {
7+
return {
8+
input: ["SWC", "dataMask"],
9+
output: { bands: 1, sampleType: "FLOAT32" },
10+
mosaicking: "ORBIT",
11+
};
12+
}
13+
14+
function preProcessScenes(collections) {
15+
collections.scenes.orbits = collections.scenes.orbits.filter(function (
16+
orbit
17+
) {
18+
var orbitDateFrom = new Date(orbit.dateFrom);
19+
// Select all images within the last nDays
20+
return (
21+
orbitDateFrom.getTime() >=
22+
collections.to.getTime() - nDays * 24 * 3600 * 1000
23+
);
24+
});
25+
return collections;
26+
}
27+
28+
function get_mean_swc_value(samples) {
29+
// Get the sum of all SWC values
30+
let n_valid_dates = 0;
31+
let sum = 0;
32+
for (let i = 0; i < samples.length; i++) {
33+
if (samples[i].dataMask) {
34+
sum += samples[i].SWC / scaleFactor;
35+
n_valid_dates += 1;
36+
}
37+
}
38+
39+
// Calculate the mean SWC value
40+
let mean_swc_value = NaN;
41+
if (n_valid_dates > 0) {
42+
mean_swc_value = sum / n_valid_dates;
43+
}
44+
45+
return mean_swc_value;
46+
}
47+
48+
function evaluatePixel(samples) {
49+
// When there are no dates, return no data
50+
if (samples.length == 0) return [NaN];
51+
52+
// Calculate mean SWC value
53+
const mean_swc_val = get_mean_swc_value(samples);
54+
55+
return [mean_swc_val];
56+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
//VERSION=3
2+
3+
const nDays = 20; // The number of days to load data for
4+
const scaleFactor = 1000; // The scale factor for the SWC values
5+
const vmin = 0.0; // The minimum value of the colormap
6+
const vmax = 0.4; // The maximum value of the colormap
7+
8+
function setup() {
9+
return {
10+
input: ["SWC", "dataMask"],
11+
output: { id: "default", bands: 4 },
12+
mosaicking: "ORBIT",
13+
};
14+
}
15+
16+
function preProcessScenes(collections) {
17+
collections.scenes.orbits = collections.scenes.orbits.filter(function (
18+
orbit
19+
) {
20+
var orbitDateFrom = new Date(orbit.dateFrom);
21+
// Select all images within the last nDays
22+
return (
23+
orbitDateFrom.getTime() >=
24+
collections.to.getTime() - nDays * 24 * 3600 * 1000
25+
);
26+
});
27+
return collections;
28+
}
29+
30+
function get_mean_swc_value(samples) {
31+
// Get the sum of all SWC values
32+
let n_valid_dates = 0;
33+
let sum = 0;
34+
for (let i = 0; i < samples.length; i++) {
35+
if (samples[i].dataMask) {
36+
sum += samples[i].SWC / scaleFactor;
37+
n_valid_dates += 1;
38+
}
39+
}
40+
41+
// Calculate the mean SWC value
42+
let mean_swc_value = NaN;
43+
if (n_valid_dates > 0) {
44+
mean_swc_value = sum / n_valid_dates;
45+
}
46+
47+
return mean_swc_value;
48+
}
49+
50+
const cmap = [
51+
[0.0, 0xfff7ea],
52+
[0.05, 0xfaedda],
53+
[0.1, 0xede4cb],
54+
[0.15, 0xdedcbd],
55+
[0.2, 0xced3af],
56+
[0.25, 0xbdcba3],
57+
[0.3, 0xaac398],
58+
[0.35, 0x96bc90],
59+
[0.4, 0x80b48a],
60+
[0.45, 0x68ac86],
61+
[0.5, 0x4da484],
62+
[0.55, 0x269c83],
63+
[0.6, 0x009383],
64+
[0.65, 0x008a85],
65+
[0.7, 0x008186],
66+
[0.75, 0x007788],
67+
[0.8, 0x006d8a],
68+
[0.85, 0x00618c],
69+
[0.9, 0x00558d],
70+
[0.95, 0x00478f],
71+
[1.0, 0x003492],
72+
];
73+
74+
// Prepare colormap based on provided min and max values
75+
const visualizer = new ColorRampVisualizer(cmap, vmin, vmax);
76+
77+
function evaluatePixel(samples) {
78+
// When there are no dates, return no data
79+
if (samples.length == 0) return [NaN, NaN, NaN, 0];
80+
81+
// Calculate mean SWC value
82+
const mean_swc_val = get_mean_swc_value(samples);
83+
84+
// Set opacity to 0 if there is no valid data
85+
let opacity = 1;
86+
if (isNaN(mean_swc_val)) {
87+
opacity = 0;
88+
}
89+
90+
// Apply colormap
91+
imgVals = visualizer.process(mean_swc_val);
92+
93+
return [...imgVals, opacity];
94+
}

0 commit comments

Comments
 (0)