This notebook demonstrates the Algal Bloom use case from the Open Science Persistent Demonstrator (OSPD) using the openEO Web Editor, which is connected to the openEO Google Earth Engine implementation:
Connecting to the service
Open the following URL in your browser: https://editor.openeo.org/?server=https%3A%2F%2Fearthengine.openeo.org
It will open the openEO Web Editor and connect automatically the openEO API for Google Earth Engine.
You can log in using either your own Google Account, but it needs to have access to Google Earth Engine. Choose the authentication method “Google” in this case.
If you can’t connect using your Google Account, you can request demo credentials for the “Internal” authentication method at the following email address: openeo.psc@uni-muenster.de.
Exploring the service
After the login procedure, you’ll see an interface where you have a list of Collections, Processes and File Formats on the left. On the middle/right side you see the model builder on the top and your data on the bottom (data processing, web services, custom processes and files).
Use the left side to look through the Collections, Processes and Export File Formats.
A core concept in openEO is “datacubes”. It is recommended to make yourself aware of how openEO datacubes work before proceeding. Read the Introduction to Datacubes for more details.
Creating a workflow
In this demo we’ll be creating and running the worflow for the Algal Bloom usecase. For this usecase we’ll be using:
- Collection:
COPERNICUS/S2_SR_HARMONIZED(implicitly uses the openEO processload_collection) - Processes:
reduce_dimensionand various mathematical processes such asmean,divide, etc. - Export File Format:
GTIFF(GeoTiff, implicitly uses the openEO processsave_result)
The following workflow will be created:

Loading a datacube
Start by drag & dropping the COPERNICUS/S2_SR_HARMONIZED collection/datacube into the model builder:
Then click the small “paper with pencil” button to edit the parameters of the process.

Select the spatial extent (AOI), the temporal extent and the bands.
For the spatial extent, you could provide the following GeoJSON. Choose the type “GeoJSON” (instead of “Bounding Box”) and then select the “Code” tab in the Editor to be able to paste the following GeoJSON:
{
"type": "Polygon",
"coordinates": [
[
[-7.664532, 38.543869],
[-7.689248, 38.141037],
[-7.159228, 38.151837],
[-7.115289, 38.554609],
[-7.664532, 38.543869]
]
]
}
Switch back to the map to visualize the GeoJSON.
As temporal extent use the following two values:
2019-06-27 00:00:002019-07-04 00:00:00
For the bands, select the type “Array” instead of “No filter”. Add three more entries by clicking the “+ Add” button three times. In the four fields select the Bands B1, B2, B3 and B4 respecitvely.
Submit the form and you’ll see the process parameter being updated in the model builder.
Reducing the temporal dimension
If there’s any overlap on the temporal dimension (there should be none, but we want to make sure), we want to compute the mean value over time. Additionally, the Sentinel-2 collection is made available as “digital numbers” and not as surface reflectance yet. To convert from digital numbers we need to divide the values by 10000. We’ll do both in the following reduce operation.
Find the reduce_dimension process, drag & drop it into the model builder. Connect the return value of the “COPERNICUS/S2_SR_HARMONIZED” box with the data paramter of the “reduce_dimension” box. Afterwards, edit the parameters with the “paper with pencil” button again.
You need to change two parameters:
- reducer:
- Add the process
mean - Connect the
databox and thedataparameter of themeanprocess, which effectively passes the individual timeseries per pixel and abn into the mean calculation - Add the
divideprocess, connect themeanreturn value and thexparameter of thedivideprocess - Edit the parameters of the
meanprocess - Set
yto10000 - Submit the form
- Add the process
- dimension: Set to
twhich is the name of the temporal dimension
Afterwards, submit the form.

Computing the density of cyanobacteria
We want to compute the density of cyanobacteria based on the available bands now. The formula is:

Drag & drop the reduce_dimension process once more into the model builder. Connect the return value of the first “reduce_dimension” box with the data paramter of the newly created “reduce_dimension” box. Afterwards, edit the parameters with the “paper with pencil” button.
We’d need to create the formula above with openEO processes now. That is a rather annoying process due to the number of processes you need to create and connect. Due to that the Web Editor offers a simpler way to insert formulas. Click the “√x” button (tooltip: “Insert/Edit Formula”) and paste the following Web Editor formula into the text field:
115530*(($B3*$B4)/$B2)^2.38
Click “Insert” and this will convert the formula into a model.
Finally, set the dimension parameter to bands which is the name of the bands dimension which we’ll reduce/work on and submit the form.

Choosing a file format
The last step for this computation is to choose a file format to save the results in.
Find the save_result process, drag & drop it into the model builder. Connect the return value of the most recently created “reduce_dimension” box with the data paramter of the “save_result” box. Afterwards, edit the parameters with the “paper with pencil” button again.
Provide the following for the parameters:
- Format: “GeoTiff – GTIFF”
- Options:
- Name of the exported assets and files:
- Type “String”
- Value:
cyanobacteria
- Additional STAC metadata to be added to the exported asset:
- Type “Object”
- Value (paste into the “Code” tab):
{ "raster:bands": [ { "statistics": { "minimum": 0, "maximum": 100 } } ] }
- EPSG Code to reproject the images to:
- Type “Epsg Code”
- Value: “32629: WGS 84 / UTM zone 29N”
- Name of the exported assets and files:

Computing the concentration of chlorophyll a
We want to compute the concentration of chlorophyll a now. The formula is:
Follow the same steps as in “Computing the density of cyanobacteria” and “Choosing a file format”, but use the following Web Editor formula instead:
4.26*($B3/$B1)^3.94
Connect the newly created reduce_dimension box, parameter data, with the reduce_dimension box for the dimension t.
For save_result use the following parameters:
name:chlorophyll_a- In the metadata statistics use the maximum value
200
Computing the turbidity
We want to compute the turbidity now. The formula is:
Follow the same steps as in “Computing the density of cyanobacteria” and “Choosing a file format”, but use the following Web Editor formula instead:
8.93*($B3/$B1)-6.39
Connect the newly created reduce_dimension box, parameter data, with the reduce_dimension box for the dimension t.
For save_result use the following parameters:
name:turbidity- In the metadata statistics use the maximum value
30
Executing the workflow
The final workflow should look similar to the following image:

You can now create a batch job to compute the results.
Click “+ Create Batch Job” in the “Data Processing” tab.
You’ll be asked to provide a title and some additional data, but except for the title non is relevant here. You can provide for example OSPD Algal Bloom usecase as title. Submit the form and a new batch job will be created, which will show up in the Data Processing table.
Click the “play” button (tooltip: “Start Processing”) to start processing.
After some seconds you should get a confirmation that the batch job has been computed successfully and you can visualize or download the results.
- Click the “eye” button (tooltip: “View results”) to open the results in individual tabs.
- Click the “download” button to see a list of computed files and click “Download GeoTIFF image” to download the files. Here can also click “Show on Map” to add the images to an existing map, which might be interesting to compare results.
- Click the “i” button (tooltip: “Details”) to see the full job details, including the results and processing worflow. You can share the workflow with others and they can run the same workflow, which makes it easy to reproduce the results. Depending on the availability of the data, you might also be able to run this workflow on another openEO backend and compare the results across different processing platforms.

Comparing results
To compare results that have been generated with other services (e.g. openEO or OGC API – Processes), you can add other results to the map we opened before:
- Click the small image/photo icon on the top right part of the map.
- Paste the URL to the cloud-optimized GeoTiff or STAC Item / Collection into the textfield with the label “Internet Adress”.
- Select the corresponding file format if not selected automatically. Either Cloud-optimized GeoTiff (common for OGC API – Processes) or STAC Item / Collection (common for openEO).
- Click the “Add layer” button
Note:
The EO Application Package used for the Algal Bloom usecase in the OSPD project output non-cloud-optimized (i.e. regular) GeoTiffs by default. Due to memory constraints in the browsers, we can’t visualize those files in the Web Editor. You explicitly need to request cloud-optimized GeoTiffs from the service to be able to use the visualization functionality.

The image should appear on the map. A slider will show up for comparison. You can also customite the visualization in the bottom left corner by providing different minimum and maximum values. In the layer switcher you can adjust the opacity. Hovering over the images will give the values for all images shown. You can also click them to show them on a chart.
See the following examples where examples from Google Earth Engine and openEO Platform are compared:
Appendix: The full workflow
This is the openEO process as JSON for completeness. You can copy paste it into the model builder (“Code” tab) if you don’t want to follow the steps above or encountered any issues during the creation of the workflow.
{
"process_graph": {
"load1": {
"process_id": "load_collection",
"arguments": {
"id": "COPERNICUS/S2_SR_HARMONIZED",
"spatial_extent": {
"type": "Polygon",
"coordinates": [
[
[
-7.664532,
38.543869
],
[
-7.689248,
38.141037
],
[
-7.159228,
38.151837
],
[
-7.115289,
38.554609
],
[
-7.664532,
38.543869
]
]
]
},
"temporal_extent": [
"2019-06-27T00:00:00Z",
"2019-07-04T00:00:00Z"
],
"bands": [
"B1",
"B2",
"B3",
"B4"
]
}
},
"reduce2": {
"process_id": "reduce_dimension",
"arguments": {
"data": {
"from_node": "load1"
},
"reducer": {
"process_graph": {
"divide1": {
"process_id": "divide",
"arguments": {
"x": {
"from_node": "mean1"
},
"y": 10000
},
"result": true
},
"mean1": {
"process_id": "mean",
"arguments": {
"data": {
"from_parameter": "data"
}
}
}
}
},
"dimension": "t"
}
},
"reduce1": {
"process_id": "reduce_dimension",
"arguments": {
"data": {
"from_node": "reduce2"
},
"dimension": "bands",
"reducer": {
"process_graph": {
"il4c7j4lr": {
"process_id": "array_element",
"arguments": {
"data": {
"from_parameter": "data"
},
"label": "B2"
}
},
"qj6u3oylh": {
"process_id": "array_element",
"arguments": {
"data": {
"from_parameter": "data"
},
"label": "B3"
}
},
"ud7qocqmh": {
"process_id": "array_element",
"arguments": {
"data": {
"from_parameter": "data"
},
"label": "B4"
}
},
"xidmp3qla": {
"process_id": "multiply",
"arguments": {
"x": {
"from_node": "qj6u3oylh"
},
"y": {
"from_node": "ud7qocqmh"
}
}
},
"2du071v7s": {
"process_id": "divide",
"arguments": {
"x": {
"from_node": "xidmp3qla"
},
"y": {
"from_node": "il4c7j4lr"
}
}
},
"4ckks9uzi": {
"process_id": "power",
"arguments": {
"base": {
"from_node": "2du071v7s"
},
"p": 2.38
}
},
"nnxuedpgo": {
"process_id": "multiply",
"arguments": {
"x": 115530,
"y": {
"from_node": "4ckks9uzi"
}
},
"result": true
}
}
}
},
"description": "Density of cyanobacteria"
},
"reduce4": {
"process_id": "reduce_dimension",
"arguments": {
"data": {
"from_node": "reduce2"
},
"dimension": "bands",
"reducer": {
"process_graph": {
"wkvqxkkbz": {
"process_id": "array_element",
"arguments": {
"data": {
"from_parameter": "data"
},
"label": "B3"
}
},
"y2t8gkl32": {
"process_id": "array_element",
"arguments": {
"data": {
"from_parameter": "data"
},
"label": "B1"
}
},
"k5qpt74bj": {
"process_id": "divide",
"arguments": {
"x": {
"from_node": "wkvqxkkbz"
},
"y": {
"from_node": "y2t8gkl32"
}
}
},
"kvjizj4da": {
"process_id": "power",
"arguments": {
"base": {
"from_node": "k5qpt74bj"
},
"p": 3.94
}
},
"6w3dqkcrd": {
"process_id": "multiply",
"arguments": {
"x": 4.26,
"y": {
"from_node": "kvjizj4da"
}
},
"result": true
}
}
}
},
"description": "Concentration of Chlorophyll a"
},
"reduce6": {
"process_id": "reduce_dimension",
"arguments": {
"data": {
"from_node": "reduce2"
},
"dimension": "bands",
"reducer": {
"process_graph": {
"crvn2egum": {
"process_id": "array_element",
"arguments": {
"data": {
"from_parameter": "data"
},
"label": "B3"
}
},
"v9pckltcm": {
"process_id": "array_element",
"arguments": {
"data": {
"from_parameter": "data"
},
"label": "B1"
}
},
"zm849zdxq": {
"process_id": "divide",
"arguments": {
"x": {
"from_node": "crvn2egum"
},
"y": {
"from_node": "v9pckltcm"
}
}
},
"lq08asl75": {
"process_id": "multiply",
"arguments": {
"x": 8.93,
"y": {
"from_node": "zm849zdxq"
}
}
},
"otg5lfkdw": {
"process_id": "subtract",
"arguments": {
"x": {
"from_node": "lq08asl75"
},
"y": 6.39
},
"result": true
}
}
}
},
"description": "Turbidity"
},
"save3": {
"process_id": "save_result",
"arguments": {
"data": {
"from_node": "reduce1"
},
"format": "GTIFF",
"options": {
"name": "cyanobacteria",
"metadata": {
"raster:bands": [
{
"statistics": {
"minimum": 0,
"maximum": 100
}
}
]
},
"epsgCode": 32629
}
},
"description": "Density of cyanobacteria",
"result": true
},
"save5": {
"process_id": "save_result",
"arguments": {
"data": {
"from_node": "reduce4"
},
"format": "GTIFF",
"options": {
"name": "chlorophyll_a",
"metadata": {
"raster:bands": [
{
"statistics": {
"minimum": 0,
"maximum": 200
}
}
]
},
"epsgCode": 32629
}
},
"description": "Concentration of Chlorophyll a"
},
"save7": {
"process_id": "save_result",
"arguments": {
"data": {
"from_node": "reduce6"
},
"format": "GTIFF",
"options": {
"name": "turbidity",
"metadata": {
"raster:bands": [
{
"statistics": {
"minimum": 0,
"maximum": 30
}
}
]
},
"epsgCode": 32629
}
},
"description": "Turbidity"
}
}
}
Return now to Lesson 6 of Module 5 of the OSPD Training Course