Skip to content

Commit ba2159c

Browse files
AmberMulderAmberMulderPlanetJonas Viehweger
authored
Add SWC and LST quality flags scripts and docs (#332)
* Initial setup SWC quality flags scripts and docs * Fix invalid date in example * Add initial setup LST quality flags scripts * Add documentation on SWC quality flags scripts * Add documentation on LST quality flags scripts * Auto-formatting scripts --------- Co-authored-by: Amber Mulder <[email protected]> Co-authored-by: Jonas Viehweger <[email protected]>
1 parent 5de3c9d commit ba2159c

File tree

11 files changed

+275
-1
lines changed

11 files changed

+275
-1
lines changed

planetary-variables/land-surface-temperature/index.md

+1
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ Planet's LST product provides near real-time measurements twice a day at 1:30 an
1313

1414
- [Land Surface Temperature Visualization]({% link planetary-variables/land-surface-temperature/land-surface-temperature-visualization/index.md %})
1515
- [Land Surface Temperature Anomaly]({% link planetary-variables/land-surface-temperature/land-surface-temperature-anomaly/index.md %})
16+
- [Land Surface Temperature Quality Flags]({% link planetary-variables/land-surface-temperature/land-surface-temperature-quality-flags/index.md %})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
---
2+
title: Land Surface Temperature Quality Flags
3+
grand_parent: Planetary Variables
4+
parent: Land Surface Temperature
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: '44.8398'
13+
lng: '-0.5294'
14+
datasetId: '8d977093-cf9e-4351-8159-90f2522c29c1'
15+
fromTime: '2022-04-26T00:00:00.000Z'
16+
toTime: '2022-04-26T23:59:59.999Z'
17+
platform:
18+
- EOB
19+
evalscripturl: https://custom-scripts.sentinel-hub.com/custom-scripts/planetary-variables/land-surface-temperature/land-surface-temperature-quality-flags/script.js
20+
additionalQueryParams:
21+
- - themeId
22+
- PLANET_SANDBOX
23+
---
24+
## General description
25+
Land Surface Temperature (LST) products include [quality flag assets](https://developers.planet.com/docs/planetary-variables/land-surface-temperature-technical-specification/#quality-flags) that provide quality metadata for each pixel using a bitwise flag system. These flags help identify the reliability of the LST values for each pixel. Here we show how these quality flags can be easily displayed using custom scripts. For a complete list of all possible quality flags and their corresponding bits, please refer to [these tables](https://developers.planet.com/docs/planetary-variables/land-surface-temperature-technical-specification/#quality-flags).
26+
27+
## Notes on usage
28+
Users can customize the script by adding the bit numbers corresponding to the quality flag(s) of interest to the `bits_to_check` list within the script. By default, the provided scripts are set to check all critical flags (indicating unreliable data, with corresponding LST pixels set to the no data value), but this can be updated to include or exclude specific flags as needed.
29+
30+
Planet’s LST product provides near real-time measurements twice a day at 1:30 and 13:30 solar local time. The `sensing_time` variable in the scripts can be used to select the sensing time of interest
31+
32+
The provided Visualization script highlights pixels for which specific quality flags of interest are set. This allows users to visually inspect areas of concern or interest.
33+
34+
The Raw Values script retrieves a binary raster where:
35+
36+
- `1` indicates pixels for which the quality flag(s) of interest are set
37+
- `0` indicates pixels where the quality flag(s) of interest are not set
38+
39+
## Description of representative images
40+
The 'Open water' (bit 15\) quality flag in Flevoland, The Netherlands, on 2022-12-31.
41+
42+
![The water quality flag](fig/qf_lst_100m_water_netherlands_2022-12-31.png)
43+
44+
## Useful links
45+
- [Product specifications](https://planet.widen.net/s/tltwk6hnps)
46+
- [Data sheet](https://planet.widen.net/s/ttvp2rvwzd)
47+
- [Sentinel Hub documentation about Land Surface Temperature](https://docs.sentinel-hub.com/api/latest/data/planetary-variables/land-surface-temp/)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//VERSION=3
2+
3+
const bits_to_check = [8, 9, 11, 13, 14, 15]; // Bits to check if they are set
4+
const sensing_time = "0130"; // "0130" or "1330" or ""
5+
6+
function setup() {
7+
return {
8+
input: ["QF", "dataMask"],
9+
output: { bands: 1, sampleType: "UINT8" },
10+
mosaicking: "TILE",
11+
};
12+
}
13+
14+
//Select files based on sensing time (0130 or 1330)
15+
function preProcessScenes(collections) {
16+
collections.scenes.tiles = collections.scenes.tiles.filter(function (tile) {
17+
return tile.dataPath.includes("T" + sensing_time);
18+
});
19+
collections.scenes.tiles.sort((a, b) => new Date(b.date) - new Date(a.date));
20+
return collections;
21+
}
22+
23+
function areBitsSet(qf) {
24+
// Check if the bits are set
25+
for (let idx in bits_to_check) {
26+
const bit = 1 << (bits_to_check[idx] - 1);
27+
if ((qf & bit) !== 0) {
28+
return true;
29+
}
30+
}
31+
return false;
32+
}
33+
34+
function evaluatePixel(sample) {
35+
// When there are no dates, return no data
36+
if (sample.length == 0) return [NaN];
37+
38+
// Return NaN for no data pixels
39+
if (sample[0].dataMask == 0) {
40+
return [NaN];
41+
}
42+
43+
// Check if the bits are set
44+
const bit_set = areBitsSet(sample[0].QF);
45+
46+
return [bit_set ? 1 : 0];
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//VERSION=3
2+
3+
const bits_to_check = [8, 9, 11, 13, 14, 15]; // Bits to check if they are set
4+
const sensing_time = "0130"; // "0130" or "1330" or ""
5+
6+
function setup() {
7+
return {
8+
input: ["QF", "dataMask"],
9+
output: { id: "default", bands: 4 },
10+
mosaicking: "TILE",
11+
};
12+
}
13+
14+
//Select files based on sensing time (0130 or 1330)
15+
function preProcessScenes(collections) {
16+
collections.scenes.tiles = collections.scenes.tiles.filter(function (tile) {
17+
return tile.dataPath.includes("T" + sensing_time);
18+
});
19+
collections.scenes.tiles.sort((a, b) => new Date(b.date) - new Date(a.date));
20+
return collections;
21+
}
22+
23+
function areBitsSet(qf) {
24+
// Check if the bits are set
25+
for (let idx in bits_to_check) {
26+
const bit = 1 << (bits_to_check[idx] - 1);
27+
if ((qf & bit) !== 0) {
28+
return true;
29+
}
30+
}
31+
return false;
32+
}
33+
34+
function evaluatePixel(sample) {
35+
// When there are no dates, return no data
36+
if (sample.length == 0) return [NaN, NaN, NaN, 0];
37+
38+
// Return NaN for no data pixels
39+
if (sample[0].dataMask == 0) {
40+
return [NaN, NaN, NaN, 0];
41+
}
42+
43+
// Check if the bits are set
44+
const bit_set = areBitsSet(sample[0].QF);
45+
46+
// Ensure only flagged pixels are displayed
47+
let opacity = 0;
48+
let imgVals = [1, 0, 0];
49+
if (bit_set) {
50+
opacity = 0.5;
51+
}
52+
53+
return [...imgVals, opacity];
54+
}

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ 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 %})
17+
- [Soil Water Content Backward Average]({% link planetary-variables/soil-water-content/soil-water-content-backward-average/index.md %})
18+
- [Soil Water Content Quality Flags]({% link planetary-variables/soil-water-content/soil-water-content-quality-flags/index.md %})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
---
2+
title: Soil Water Content Quality Flags
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: '44.8398'
13+
lng: '-0.5294'
14+
datasetId: '65f7e4fb-a27a-4fae-8d79-06a59d7e6ede'
15+
fromTime: '2022-04-26T00:00:00.000Z'
16+
toTime: '2022-04-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-quality-flags/script.js
20+
additionalQueryParams:
21+
- - themeId
22+
- PLANET_SANDBOX
23+
---
24+
## General description
25+
Soil Water Content (SWC) products include [quality flag assets](https://developers.planet.com/docs/planetary-variables/soil-water-content-technical-specification/#quality-flags) that provide quality metadata for each pixel using a bitwise flag system. These flags help identify the reliability of the SWC values for each pixel. Here we show how these quality flags can be easily displayed using custom scripts. For a complete list of all possible quality flags and their corresponding bits, please refer to [these tables](https://developers.planet.com/docs/planetary-variables/soil-water-content-technical-specification/#quality-flags).
26+
27+
## Notes on usage
28+
Users can customize the script by adding the bit numbers corresponding to the quality flag(s) of interest to the `bits_to_check` list within the script. By default, the provided scripts are set to check all critical flags (indicating unreliable data, with corresponding SWC pixels set to the no data value), but this can be updated to include or exclude specific flags as needed.
29+
30+
The provided Visualization script highlights pixels for which specific quality flags of interest are set. This allows users to visually inspect areas of concern or interest.
31+
32+
The Raw Values script retrieves a binary raster where:
33+
34+
- `1` indicates pixels for which the quality flag(s) of interest are set
35+
- `0` indicates pixels where the quality flag(s) of interest are not set
36+
37+
## Description of representative images
38+
The 'Open water' (bit 15\) quality flag in Bordeaux, France, on 2022-04-26.
39+
40+
![The water quality flag](fig/qf_swc_100m_water_bordeaux_2022-04-26.png)
41+
42+
43+
The 'Possible frozen soil' (bit 7) and 'Frozen soil' (bit 8) quality flags in Alberta, Canada, on 2022-12-23.
44+
45+
![Possibly (frozen) quality flags](fig/qf_swc_100m_frozen_and_possibly_frozen_alberta_2022-12-23.png)
46+
47+
48+
## Useful links
49+
- [SWC Technical specifications](https://developers.planet.com/docs/planetary-variables/soil-water-content-technical-specification/)
50+
- [SWC Data sheet](https://planet.widen.net/s/cv7bfjhhd5)
51+
- [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,33 @@
1+
//VERSION=3
2+
3+
const bits_to_check = [6, 8, 9, 10, 11, 12, 13, 14, 15, 16]; // Bits to check if they are set
4+
5+
function setup() {
6+
return {
7+
input: ["QF", "dataMask"],
8+
output: { bands: 1, sampleType: "UINT8" },
9+
};
10+
}
11+
12+
function areBitsSet(qf) {
13+
// Check if the bits are set
14+
for (let idx in bits_to_check) {
15+
const bit = 1 << (bits_to_check[idx] - 1);
16+
if ((qf & bit) !== 0) {
17+
return true;
18+
}
19+
}
20+
return false;
21+
}
22+
23+
function evaluatePixel(sample) {
24+
// Return NaN for no data pixels
25+
if (sample.dataMask == 0) {
26+
return [NaN];
27+
}
28+
29+
// Check if the bits are set
30+
const bit_set = areBitsSet(sample.QF);
31+
32+
return [bit_set ? 1 : 0];
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//VERSION=3
2+
3+
const bits_to_check = [6, 8, 9, 10, 11, 12, 13, 14, 15, 16]; // Bits to check if they are set
4+
5+
function setup() {
6+
return {
7+
input: ["QF", "dataMask"],
8+
output: { id: "default", bands: 4 },
9+
};
10+
}
11+
12+
function areBitsSet(qf) {
13+
// Check if the bits are set
14+
for (let idx in bits_to_check) {
15+
const bit = 1 << (bits_to_check[idx] - 1);
16+
if ((qf & bit) !== 0) {
17+
return true;
18+
}
19+
}
20+
return false;
21+
}
22+
23+
function evaluatePixel(sample) {
24+
// Return NaN for no data pixels
25+
if (sample.dataMask == 0) {
26+
return [NaN, NaN, NaN, 0];
27+
}
28+
29+
// Check if the bits are set
30+
const bit_set = areBitsSet(sample.QF);
31+
32+
// Ensure only flagged pixels are displayed
33+
let opacity = 0;
34+
let imgVals = [1, 0, 0];
35+
if (bit_set) {
36+
opacity = 0.5;
37+
}
38+
39+
return [...imgVals, opacity];
40+
}

0 commit comments

Comments
 (0)