From 8655d20fdaa9849ab154b7e7733f2c7ce5e6a972 Mon Sep 17 00:00:00 2001 From: Jeroen Dries Date: Thu, 22 May 2025 15:36:56 +0200 Subject: [PATCH 1/2] template for sen2like --- .../benchmark_scenarios/sen2like.json | 31 ++++ .../eodc/sen2like/openeo_udp/README.md | 15 ++ .../eodc/sen2like/openeo_udp/generate.py | 61 +++++++ .../eodc/sen2like/openeo_udp/sen2like.json | 159 ++++++++++++++++++ .../eodc/sen2like/records/sen2like.json | 105 ++++++++++++ 5 files changed, 371 insertions(+) create mode 100644 algorithm_catalog/eodc/sen2like/benchmark_scenarios/sen2like.json create mode 100644 algorithm_catalog/eodc/sen2like/openeo_udp/README.md create mode 100644 algorithm_catalog/eodc/sen2like/openeo_udp/generate.py create mode 100644 algorithm_catalog/eodc/sen2like/openeo_udp/sen2like.json create mode 100644 algorithm_catalog/eodc/sen2like/records/sen2like.json diff --git a/algorithm_catalog/eodc/sen2like/benchmark_scenarios/sen2like.json b/algorithm_catalog/eodc/sen2like/benchmark_scenarios/sen2like.json new file mode 100644 index 0000000..1d3a1cf --- /dev/null +++ b/algorithm_catalog/eodc/sen2like/benchmark_scenarios/sen2like.json @@ -0,0 +1,31 @@ +[ + { + "id": "sen2like", + "type": "openeo", + "description": "Sen2like test", + "backend": "openeo.cloud", + "process_graph": { + "pvfarm": { + "process_id": "sen2like", + "namespace": "...", + "arguments": { + "bbox": { + "east": 16.414, + "north": 48.008, + "south": 47.962, + "west": 16.342 + }, + "temporal_extent": [ + "2023-05-01", + "2023-05-30" + ] + }, + "result": true + } + }, + "reference_data": { + }, + "reference_options": { + } + } +] \ No newline at end of file diff --git a/algorithm_catalog/eodc/sen2like/openeo_udp/README.md b/algorithm_catalog/eodc/sen2like/openeo_udp/README.md new file mode 100644 index 0000000..4926602 --- /dev/null +++ b/algorithm_catalog/eodc/sen2like/openeo_udp/README.md @@ -0,0 +1,15 @@ +# Sen2like + +The Sen2Like processor was developed by ESA as part of the EU Copernicus program. It creates Sentinel-2 like harmonized (Level-2H) or fused (Level-2F) surface reflectances by harmonizing Sentinel-2 and Landsat 8/Landsat 9 to increase the temporal revisits. Based on the resulting L2F product, multiple indices can be computed, such as the NDVI and LAI. The fusion also involves the upscaling of Landsat 8/Landsat 9 data to Sentinel-2 resolution. With the new L2F data higher time-series resolution vegetation indices (such as NDVI, LAI, FAPAR, FCOVER) can be calculated. + +### Methodology + + + +### Quality + + + +### Links + +- [RD1] openEO platform Sen2like documentation https://docs.openeo.cloud/usecases/ard/sen2like \ No newline at end of file diff --git a/algorithm_catalog/eodc/sen2like/openeo_udp/generate.py b/algorithm_catalog/eodc/sen2like/openeo_udp/generate.py new file mode 100644 index 0000000..9fe99fa --- /dev/null +++ b/algorithm_catalog/eodc/sen2like/openeo_udp/generate.py @@ -0,0 +1,61 @@ +import json +from pathlib import Path + +import openeo +from openeo.api.process import Parameter +from openeo.rest._datacube import THIS +from openeo.rest.udp import build_process_dict + +def generate(): + connection = openeo.connect("openeo.cloud").authenticate_oidc() + + spatial_extent = Parameter.spatial_extent( + name="spatial_extent", + description="Limits the data to process to the specified bounding box or polygons.\\n\\nFor raster data, the process loads the pixel into the data cube if the point at the pixel center intersects with the bounding box or any of the polygons (as defined in the Simple Features standard by the OGC).\\nFor vector data, the process loads the geometry into the data cube if the geometry is fully within the bounding box or any of the polygons (as defined in the Simple Features standard by the OGC). Empty geometries may only be in the data cube if no spatial extent has been provided.\\n\\nEmpty geometries are ignored.\\nSet this parameter to null to set no limit for the spatial extent." + ) + + temporal_extent = Parameter.temporal_interval( + name="temporal_extent", + description="Temporal extent specified as two-element array with start and end date/date-time." + ) + + collection = 'SENTINEL2_L1C' + bands = ["B02", "B03", "B04", "B05", "B06", "B07", "B08", "B8A", "B11", "B12"] + + s2_l1c = connection.load_collection( + collection, + spatial_extent=spatial_extent, + temporal_extent=temporal_extent, + bands=bands) + + sen2like = s2_l1c.process('sen2like', { + 'data': THIS, + 'target_product': 'L2F', + 'export_original_files': True, + 'cloud_cover': 50}) + + returns = { + "description": "A data cube with the newly computed values.\n\nAll dimensions stay the same, except for the dimensions specified in corresponding parameters. There are three cases how the dimensions can change:\n\n1. The source dimension is the target dimension:\n - The (number of) dimensions remain unchanged as the source dimension is the target dimension.\n - The source dimension properties name and type remain unchanged.\n - The dimension labels, the reference system and the resolution are preserved only if the number of values in the source dimension is equal to the number of values computed by the process. Otherwise, all other dimension properties change as defined in the list below.\n2. The source dimension is not the target dimension. The target dimension exists with a single label only:\n - The number of dimensions decreases by one as the source dimension is 'dropped' and the target dimension is filled with the processed data that originates from the source dimension.\n - The target dimension properties name and type remain unchanged. All other dimension properties change as defined in the list below.\n3. The source dimension is not the target dimension and the latter does not exist:\n - The number of dimensions remain unchanged, but the source dimension is replaced with the target dimension.\n - The target dimension has the specified name and the type other. All other dimension properties are set as defined in the list below.\n\nUnless otherwise stated above, for the given (target) dimension the following applies:\n\n- the number of dimension labels is equal to the number of values computed by the process,\n- the dimension labels are incrementing integers starting from zero,\n- the resolution changes, and\n- the reference system is undefined.", + "schema": { + "type": "object", + "subtype": "datacube" + } + } + + return build_process_dict( + process_graph=sen2like, + process_id="sen2like", + summary="Computes a harmonzed Sentinel-2 and Landsat timeseries.", + description=(Path(__file__).parent / "README.md").read_text(), + parameters=[ + spatial_extent, + temporal_extent + ], + returns=returns, + categories=["sentinel-2", "ARD"] + ) + + +if __name__ == "__main__": + with open("sen2like.json", "w") as f: + json.dump(generate(), f, indent=2) \ No newline at end of file diff --git a/algorithm_catalog/eodc/sen2like/openeo_udp/sen2like.json b/algorithm_catalog/eodc/sen2like/openeo_udp/sen2like.json new file mode 100644 index 0000000..1f6b5f0 --- /dev/null +++ b/algorithm_catalog/eodc/sen2like/openeo_udp/sen2like.json @@ -0,0 +1,159 @@ +{ + "process_graph": { + "loadcollection1": { + "process_id": "load_collection", + "arguments": { + "bands": [ + "B02", + "B03", + "B04", + "B05", + "B06", + "B07", + "B08", + "B8A", + "B11", + "B12" + ], + "id": "SENTINEL2_L1C", + "spatial_extent": { + "from_parameter": "spatial_extent" + }, + "temporal_extent": { + "from_parameter": "temporal_extent" + } + } + }, + "sen2like1": { + "process_id": "sen2like", + "arguments": { + "cloud_cover": 50, + "data": { + "from_node": "loadcollection1" + }, + "export_original_files": true, + "target_product": "L2F" + }, + "result": true + } + }, + "id": "sen2like", + "description": "# Sen2like\n\nThe Sen2Like processor was developed by ESA as part of the EU Copernicus program. It creates Sentinel-2 like harmonized (Level-2H) or fused (Level-2F) surface reflectances by harmonizing Sentinel-2 and Landsat 8/Landsat 9 to increase the temporal revisits. Based on the resulting L2F product, multiple indices can be computed, such as the NDVI and LAI. The fusion also involves the upscaling of Landsat 8/Landsat 9 data to Sentinel-2 resolution. With the new L2F data higher time-series resolution vegetation indices (such as NDVI, LAI, FAPAR, FCOVER) can be calculated.\n\n### Methodology\n\n\n\n### Quality\n\n\n\n### Links\n\n- [RD1] openEO platform Sen2like documentation https://docs.openeo.cloud/usecases/ard/sen2like", + "parameters": [ + { + "name": "spatial_extent", + "description": "Limits the data to process to the specified bounding box or polygons.\\n\\nFor raster data, the process loads the pixel into the data cube if the point at the pixel center intersects with the bounding box or any of the polygons (as defined in the Simple Features standard by the OGC).\\nFor vector data, the process loads the geometry into the data cube if the geometry is fully within the bounding box or any of the polygons (as defined in the Simple Features standard by the OGC). Empty geometries may only be in the data cube if no spatial extent has been provided.\\n\\nEmpty geometries are ignored.\\nSet this parameter to null to set no limit for the spatial extent.", + "schema": [ + { + "title": "Bounding Box", + "type": "object", + "subtype": "bounding-box", + "required": [ + "west", + "south", + "east", + "north" + ], + "properties": { + "west": { + "description": "West (lower left corner, coordinate axis 1).", + "type": "number" + }, + "south": { + "description": "South (lower left corner, coordinate axis 2).", + "type": "number" + }, + "east": { + "description": "East (upper right corner, coordinate axis 1).", + "type": "number" + }, + "north": { + "description": "North (upper right corner, coordinate axis 2).", + "type": "number" + }, + "base": { + "description": "Base (optional, lower left corner, coordinate axis 3).", + "type": [ + "number", + "null" + ], + "default": null + }, + "height": { + "description": "Height (optional, upper right corner, coordinate axis 3).", + "type": [ + "number", + "null" + ], + "default": null + }, + "crs": { + "description": "Coordinate reference system of the extent, specified as as [EPSG code](http://www.epsg-registry.org/) or [WKT2 CRS string](http://docs.opengeospatial.org/is/18-010r7/18-010r7.html). Defaults to `4326` (EPSG code 4326) unless the client explicitly requests a different coordinate reference system.", + "anyOf": [ + { + "title": "EPSG Code", + "type": "integer", + "subtype": "epsg-code", + "minimum": 1000, + "examples": [ + 3857 + ] + }, + { + "title": "WKT2", + "type": "string", + "subtype": "wkt2-definition" + } + ], + "default": 4326 + } + } + }, + { + "title": "Vector data cube", + "description": "Limits the data cube to the bounding box of the given geometries in the vector data cube. For raster data, all pixels inside the bounding box that do not intersect with any of the polygons will be set to no data (`null`). Empty geometries are ignored.", + "type": "object", + "subtype": "datacube", + "dimensions": [ + { + "type": "geometry" + } + ] + }, + { + "title": "No filter", + "description": "Don't filter spatially. All data is included in the data cube.", + "type": "null" + } + ] + }, + { + "name": "temporal_extent", + "description": "Temporal extent specified as two-element array with start and end date/date-time.", + "schema": { + "type": "array", + "subtype": "temporal-interval", + "uniqueItems": true, + "minItems": 2, + "maxItems": 2, + "items": { + "anyOf": [ + { + "type": "string", + "subtype": "date-time", + "format": "date-time" + }, + { + "type": "string", + "subtype": "date", + "format": "date" + }, + { + "type": "null" + } + ] + } + } + } + ] +} \ No newline at end of file diff --git a/algorithm_catalog/eodc/sen2like/records/sen2like.json b/algorithm_catalog/eodc/sen2like/records/sen2like.json new file mode 100644 index 0000000..10259e1 --- /dev/null +++ b/algorithm_catalog/eodc/sen2like/records/sen2like.json @@ -0,0 +1,105 @@ +{ + "id": "sen2like", + "type": "Feature", + "conformsTo": [ + "http://www.opengis.net/spec/ogcapi-records-1/1.0/req/record-core", + "https://apex.esa.int/core/openeo-udp" + ], + "geometry": null, + "properties": { + "created": "2025-05-22T00:00:00Z", + "updated": "2025-05-22T00:00:00Z", + "type": "service", + "title": "Harmonized Landsat/Sentinel-2 ARD", + "description": "# Sen2like\n\nThe Sen2Like processor was developed by ESA as part of the EU Copernicus program. It creates Sentinel-2 like harmonized (Level-2H) or fused (Level-2F) surface reflectances by harmonizing Sentinel-2 and Landsat 8/Landsat 9 to increase the temporal revisits. Based on the resulting L2F product, multiple indices can be computed, such as the NDVI and LAI. The fusion also involves the upscaling of Landsat 8/Landsat 9 data to Sentinel-2 resolution. With the new L2F data higher time-series resolution vegetation indices (such as NDVI, LAI, FAPAR, FCOVER) can be calculated.\n\n### Methodology\n\n\n\n### Quality\n\n\n\n### Links\n\n- [RD1] openEO platform Sen2like documentation https://docs.openeo.cloud/usecases/ard/sen2like", + "cost_estimate": 0.01, + "cost_unit": "platform credits per km\u00b2", + "keywords": [ + "sentinel-2", + "landsat-8", + "ard" + ], + "language": { + "code": "en-US", + "name": "English (United States)" + }, + "languages": [ + { + "code": "en-US", + "name": "English (United States)" + } + ], + "contacts": [ + { + "name": "...", + "position": "Researcher", + "organization": "EODC", + "links": [ + { + "href": "https://www.eodc.eu/", + "title": "EODC Website", + "rel": "about", + "type": "text/html" + }, + { + "href": "https://github.com/...", + "title": "GitHub", + "rel": "about", + "type": "text/html" + } + ], + "contactInstructions": "Contact via EODC", + "roles": [ + "principal investigator", + "processor" + ] + } + ], + "themes": [ + { + "concepts": [ + { + "id": "Sentinel-2 MSI" + } + ], + "scheme": "https://gcmd.earthdata.nasa.gov/kms/concepts/concept_scheme/sciencekeywords" + } + ], + "formats": [ + { + "name": "GeoTIFF" + }, + { + "name": "netCDF" + } + ], + "license": "CC-BY-4.0" + }, + "linkTemplates": [], + "links": [ + { + "rel": "application", + "type": "application/vnd.openeo+json;type=process", + "title": "openEO Process Definition", + "href": "https://raw.githubusercontent.com/ESA-APEx/apex_algorithms/.../eodc/sen2like/openeo_udp/sen2like.json" + }, + { + "rel": "code", + "type": "text/html", + "title": "Sen2like git source repository", + "href": "https://github.com/senbox-org/sen2like" + }, + { + "rel": "service", + "type": "application/json", + "title": "openEO platform", + "href": "https://openeo.cloud" + }, + { + "rel": "cite-as", + "type": "text/html", + "title": "S. Saunier, J. Louis, V. Debaecker et al., \"Sen2like, A Tool To Generate Sentinel-2 Harmonised Surface Reflectance Products - First Results with Landsat-8,\" IGARSS 2019 - 2019 IEEE International Geoscience and Remote Sensing Symposium, Yokohama, Japan, 2019, pp. 5650-5653", + "href": "https://doi.org/10.1109/IGARSS.2019.8899213" + } + ] +} From 83b90e51e4b15de315f13d6947c65bb94bbf6992 Mon Sep 17 00:00:00 2001 From: Jeroen Dries Date: Thu, 22 May 2025 15:38:41 +0200 Subject: [PATCH 2/2] fix namespace --- .../eodc/sen2like/benchmark_scenarios/sen2like.json | 2 +- algorithm_catalog/eodc/sen2like/records/sen2like.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/algorithm_catalog/eodc/sen2like/benchmark_scenarios/sen2like.json b/algorithm_catalog/eodc/sen2like/benchmark_scenarios/sen2like.json index 1d3a1cf..1f830a0 100644 --- a/algorithm_catalog/eodc/sen2like/benchmark_scenarios/sen2like.json +++ b/algorithm_catalog/eodc/sen2like/benchmark_scenarios/sen2like.json @@ -7,7 +7,7 @@ "process_graph": { "pvfarm": { "process_id": "sen2like", - "namespace": "...", + "namespace": "https://raw.githubusercontent.com/ESA-APEx/apex_algorithms/refs/heads/sen2like/algorithm_catalog/eodc/sen2like/openeo_udp/sen2like.json", "arguments": { "bbox": { "east": 16.414, diff --git a/algorithm_catalog/eodc/sen2like/records/sen2like.json b/algorithm_catalog/eodc/sen2like/records/sen2like.json index 10259e1..53cedc8 100644 --- a/algorithm_catalog/eodc/sen2like/records/sen2like.json +++ b/algorithm_catalog/eodc/sen2like/records/sen2like.json @@ -81,7 +81,7 @@ "rel": "application", "type": "application/vnd.openeo+json;type=process", "title": "openEO Process Definition", - "href": "https://raw.githubusercontent.com/ESA-APEx/apex_algorithms/.../eodc/sen2like/openeo_udp/sen2like.json" + "href": "https://raw.githubusercontent.com/ESA-APEx/apex_algorithms/refs/heads/sen2like/algorithm_catalog/eodc/sen2like/openeo_udp/sen2like.json" }, { "rel": "code",