-
Notifications
You must be signed in to change notification settings - Fork 299
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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]>
- Loading branch information
1 parent
999afca
commit 5de3c9d
Showing
4 changed files
with
185 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
...etary-variables/soil-water-content/soil-water-content-backward-average/index.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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/) |
56 changes: 56 additions & 0 deletions
56
planetary-variables/soil-water-content/soil-water-content-backward-average/raw.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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]; | ||
} |
94 changes: 94 additions & 0 deletions
94
planetary-variables/soil-water-content/soil-water-content-backward-average/script.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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]; | ||
} |