From cd80a80feb33f50bbebc30a3f1d95b5aec8a57d2 Mon Sep 17 00:00:00 2001 From: Paul Castillo Date: Thu, 21 May 2026 07:46:13 +0000 Subject: [PATCH 01/13] implementation of absolute path for inputs and outputs in Docker + read me update --- sen2vm-notebook/README_Notebooks.md | 52 +++++++++-- sen2vm-notebook/src/notebook.ipynb | 136 ++++++++++++++++------------ 2 files changed, 122 insertions(+), 66 deletions(-) diff --git a/sen2vm-notebook/README_Notebooks.md b/sen2vm-notebook/README_Notebooks.md index 78c56020..652dfa57 100644 --- a/sen2vm-notebook/README_Notebooks.md +++ b/sen2vm-notebook/README_Notebooks.md @@ -32,7 +32,7 @@ Actually, this notebook can generate an inverse grid but can not use it to apply * Required data: * **Sentinel-2 L1B product** : /DATASTRIP and /GRANULE. - * **DEM files** placed in the appropriate directory + * **DEM files** ## Mandatory Directory Structure @@ -40,16 +40,48 @@ Actually, this notebook can generate an inverse grid but can not use it to apply WORKDIR │ ├── DATA/ -│ ├── DEM/ # Put your DEM files here -| ├── GEOID/ # Put your GEOID files here (Optional) -│ └── / # Place the full L1B product here -| ├── DATASTRIP # Required -| ├── GRANULE # Required -| └── ... +│ └── GEOID/ # Put your GEOID files here (Optional) └── ... ``` -If the GEOID folder is empty, the notebopok will automaticaly use the geoid provided by sen2vm-core +## Inputs + +Several inputs are needed : +-L1B S2 product under EUP.SAFE format : +```bash + / + ├── DATASTRIP # Required + ├── GRANULE # Required + ├── S2*OPER_MTD_SAFL1B_PDMC*.xml #Required + └── ... +``` +-Digital Elevation Model (DEM) +-GIPP (if the path given in the notebook cell n°1 is empty (i.e ""), GIPP can be donwloaded and cloned from the GIT in /WORKSPACE/DATA + +Thanks to recent updates, input data can now be handled in two different ways: + +Using absolute paths (recommended) : +You can directly provide full paths to your data (L1B, DEM, GIPP), wherever they are located on your system. +This avoids copying large datasets and allows more flexibility. + +Using the default WORKDIR/DATA structure : +Alternatively, you can place all inputs inside the WORKDIR/DATA directory. + +## Directory Structure after execution +```bash +WORKDIR +│ +├── DATA/ +│ ├── bulletin*.txt # IERS prediction of earth exploration (downloaded by the cell n°3) +│ └── GEOID +│ +├── output/ # output after orthorectification and mosaic (.tif) +│ ├── GDAL_OUTPUT_ORTHO +│ └── GDAL_OUTPUT_MOSAIC +│ +├── src/ # contains a .sh used to run in the gdal docker generated by the notebook +└── UserConf # contains .txt config files generated by the notebook +``` ## Python Environment Setup @@ -71,8 +103,10 @@ In the first cell of the notebook: * The working directory * The L1B product + * The GIPP directory * The output directory - + * The DEM directory + 2. Adjust configuration parameters for: * Sen2VM diff --git a/sen2vm-notebook/src/notebook.ipynb b/sen2vm-notebook/src/notebook.ipynb index 8cd94e73..141b495a 100644 --- a/sen2vm-notebook/src/notebook.ipynb +++ b/sen2vm-notebook/src/notebook.ipynb @@ -2,16 +2,16 @@ "cells": [ { "cell_type": "markdown", - "id": "e8bbfd73", + "id": "8e5ed8d8-c718-4f80-a220-464bbc67c748", "metadata": {}, "source": [ - "# === USER CONFIGURATION ===\n" + "# === USER CONFIGURATION ===" ] }, { "cell_type": "code", - "execution_count": null, - "id": "3be1da11", + "execution_count": 1, + "id": "2b816cd9-5254-452b-bced-2943eb6b7aec", "metadata": {}, "outputs": [], "source": [ @@ -26,14 +26,21 @@ "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "\n", "# Path to downloaded product\n", - "PATH_L1B_DATA = \"PATH/TO/L1B/PRODUCT\"\n", + "PATH_L1B_DATA = \"PATH/TO/L1B_PRODUCT\"\n", + "\n", + "# Path to GIPP directory\n", + "PATH_GIPP = \"PATH/TO/GIPP\"\n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", - "# /!\\/!\\/!\\ CAREFUL, for now PATH_L1B_DATA shall be inside WORKID/DATA and respect the one described in README_Notebooks.md\n", + "# /!\\/!\\/!\\ If the \"PATH_GIPP is empty (i.e = \"\"), you may execute the cell \"# GIPP database download (Optional)\", so the gipp can be cloned \n", + "# cloned from git, they will be put in /WORKDIR/DATA/sen2vm-gipp-database\n", + "# Please note that this current notebook will search for a subfolder with mission S2[A/B/C] inside the GIPP folder\n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "\n", - "# Output folder chosen by the user\n", - "INVERSE_OUTPUT_FOLDER = \"PATH/TO/OUTPUT/FOLDER\" # Used only if GRID_MODE = \"inverse\"\n", + "# Path to DEM directory\n", + "PATH_DEM = \"PATH/TO/DEM\"\n", "\n", + "# Output folder chosen by the user\n", + "INVERSE_OUTPUT_FOLDER = \"PATH/TO/OUTPUT_FOLDER\" # where the exits are donwloaded\n", "\n", "# === SEN2VM OPTIONS ===\n", "\n", @@ -42,12 +49,12 @@ "# /!\\/!\\/!\\ CAREFUL, for now only direct shall be used with a full product (no missing granules)\n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "\n", - "UTM_EPSG = 32636 # UTM zone EPSG code for the ROI\n", + "UTM_EPSG = 32628 # UTM zone EPSG code for the ROI\n", "LOCATION = {\n", - " \"ul_x\": 210000, \n", - " \"ul_y\": 3504541, \n", - " \"lr_x\": 436397, \n", - " \"lr_y\": 3296817 \n", + " \"ul_x\": 281719,\n", + " \"ul_y\": 3640370,\n", + " \"lr_x\": 336222,\n", + " \"lr_y\": 3611287\n", "}\n", "\n", "# Grid step in pixels for sen2vm grid generation \n", @@ -59,14 +66,12 @@ " \"60m_bands\": 1 # Grid step: ~DEM90/2 = 45m/60m ≈ 1 pixel (one point every 1 pixel at 60m, or 2 is also fine)\n", "}\n", "\n", - "\n", "# === GDAL ORTHO OPTIONS ===\n", "\n", "ORTHO_SETTINGS = {\n", - " \"keep_bands\": [\"B03\"], # list of bands to keep for orthorectification\n", - " \"keep_detectors\": [\"11\",\"10\"] # list of the detectors to keep \n", - "}\n", - " \n" + " \"keep_bands\": [\"B02\"], # list of bands to keep for orthorectification\n", + " \"keep_detectors\": [\"01\",\"02\",\"03\",\"04\",\"05\",\"06\",\"07\",\"08\",\"09\",\"10\",\"11\",\"12\"] # list of the detectors to keep \n", + "}\n" ] }, { @@ -86,6 +91,7 @@ "source": [ "# === GIPPs ===\n", "# This step is optional if the Database was already downloaded or if you want to use your own GIPP\n", + "# If the PATH_GIPP isn't equal to \"\", this cell won't work, if PATH_GIPP= \"\", this cell will clone the git GIPP folder inside WORKDIR/DATA\n", "# Please note that this current notebook will search for a subfolder with mission S2[A/B/C] inside the GIPP folder\n", "\n", "import os\n", @@ -93,7 +99,11 @@ "import tarfile\n", "import re\n", "from datetime import datetime\n", + "import sys\n", "\n", + "if len(PATH_GIPP) != 0:\n", + " print(\"Stopping because PATH_GIPP is not empty\")\n", + " sys.exit(0)\n", "\n", "gipp_dir = os.path.join(WORKDIR, \"DATA\") \n", "os.makedirs(gipp_dir, exist_ok=True) \n", @@ -103,21 +113,20 @@ "# =====================================================================\n", "\n", "gipp_repo_name = \"sen2vm-gipp-database\"\n", - "gipp_repo_path = os.path.join(gipp_dir, gipp_repo_name)\n", + "PATH_GIPP = os.path.join(gipp_dir, gipp_repo_name)\n", "\n", "# Delete repository if exists\n", - "if os.path.exists(gipp_repo_path):\n", - " print(f\"Removing existing repository: {gipp_repo_path}\")\n", - " shutil.rmtree(gipp_repo_path)\n", + "if os.path.exists(PATH_GIPP):\n", + " print(f\"Removing existing repository: {PATH_GIPP}\")\n", + " shutil.rmtree(PATH_GIPP)\n", "\n", "# Clone repository fresh\n", "print(\"Cloning sen2vm-gipp-database...\")\n", - "!git clone https://github.com/sen2vm/sen2vm-gipp-database.git {gipp_repo_path}\n", + "!git clone https://github.com/sen2vm/sen2vm-gipp-database.git {PATH_GIPP}\n", "print(\"Clone complete.\\n\")\n", "\n", - "\n", - "\n", - "print(\"GIPP processing finished successfully.\")\n" + "print(\"GIPP processing finished successfully.\")\n", + "print(\"GIPP donwloaded in :\", PATH_GIPP)\n" ] }, { @@ -310,11 +319,9 @@ "# 2. Docker paths inside /workspace\n", "# =====================================================\n", "\n", - "safe_name = os.path.basename(PATH_L1B_DATA)\n", - "\n", - "docker_l1b = f\"/workspace/DATA/{safe_name}\"\n", - "docker_dem = \"/workspace/DATA/DEM\"\n", - "docker_gipp = f\"/workspace/DATA/sen2vm-gipp-database/{mission}\"\n", + "docker_l1b = \"/data/L1B\"\n", + "docker_dem = \"/data/DEM\"\n", + "docker_gipp = f\"/data/GIPP/{mission}\"\n", "\n", "# =====================================================\n", "# 3. Geoid management\n", @@ -552,6 +559,9 @@ "cmd_run = [\n", " \"docker\", \"run\",\n", " \"--rm\",\n", + " \"-v\", f\"{PATH_L1B_DATA}:/data/L1B\",\n", + " \"-v\", f\"{PATH_DEM}:/data/DEM\",\n", + " \"-v\", f\"{PATH_GIPP}:/data/GIPP\",\n", " \"-v\", f\"{WORKDIR}:/workspace\", \n", " \"sen2vm\",\n", " \"-c\", config_inside,\n", @@ -560,20 +570,17 @@ "\n", "print(\"Running Docker container...\\n\")\n", "print(\"Command:\", \" \".join(cmd_run), \"\\n\")\n", - "\n", "subprocess.run(cmd_run, check=True)\n", - "\n", "print(\"\\nDocker execution complete.\\n\")\n", "\n", "# =====================================================\n", "# 3. REMOVE DOCKER IMAGE\n", "# =====================================================\n", - "\n", + "\"\"\"\n", "print(\"Removing Docker image 'sen2vm'...\")\n", - "\n", "subprocess.run([\"docker\", \"rmi\", \"-f\", \"sen2vm\"], check=True)\n", - "\n", - "print(\"Docker image removed.\\n\")" + "print(\"Docker image removed.\\n\")\n", + "\"\"\"\n" ] }, { @@ -581,7 +588,7 @@ "id": "e54044d2", "metadata": {}, "source": [ - "# Generate Orthorectification images" + " # Generate Orthorectification images" ] }, { @@ -598,6 +605,14 @@ "import re\n", "\n", "# =====================================================\n", + "# SAFETY CHECKS\n", + "# =====================================================\n", + "assert os.path.exists(PATH_L1B_DATA), \"L1B path missing\"\n", + "\n", + "os.makedirs(INVERSE_OUTPUT_FOLDER, exist_ok=True)\n", + "assert os.path.exists(INVERSE_OUTPUT_FOLDER), \"Output folder missing\"\n", + "\n", + "# =====================================================\n", "# Locate product name\n", "# =====================================================\n", "product = os.path.basename(os.path.normpath(PATH_L1B_DATA))\n", @@ -678,10 +693,10 @@ "# =====================================================\n", "# Output directories\n", "# =====================================================\n", - "OUTDIR = os.path.join(WORKDIR, \"DATA\", \"GDAL_OUTPUT_ORTHO\")\n", - "os.makedirs(OUTDIR, exist_ok=True)\n", + "os.makedirs(os.path.join(INVERSE_OUTPUT_FOLDER, \"GDAL_OUTPUT_ORTHO\"), exist_ok=True)\n", + "os.makedirs(os.path.join(INVERSE_OUTPUT_FOLDER, \"GDAL_OUTPUT_MOSAIC\"), exist_ok=True)\n", "\n", - "OUTDIR_DOCKER = \"/workspace/DATA/GDAL_OUTPUT_ORTHO\"\n", + "print(\"Output folder:\", INVERSE_OUTPUT_FOLDER)\n", "\n", "# =====================================================\n", "# Build GDAL docker\n", @@ -733,10 +748,10 @@ " f.write(f\"\"\"#!/bin/bash\n", "set +e\n", "\n", - "cd /workspace/DATA/{product}\n", + "cd /data/L1B\n", "\n", - "OUT_ORTHO=\"/workspace/DATA/GDAL_OUTPUT_ORTHO\"\n", - "OUT_MOSAIC=\"/workspace/DATA/GDAL_OUTPUT_MOSAIC\"\n", + "OUT_ORTHO=\"/output/GDAL_OUTPUT_ORTHO\"\n", + "OUT_MOSAIC=\"/output/GDAL_OUTPUT_MOSAIC\"\n", "\n", "mkdir -p \"$OUT_ORTHO\"\n", "mkdir -p \"$OUT_MOSAIC\"\n", @@ -771,15 +786,14 @@ "echo \"=== ORTHORECTIFICATION ===\"\n", "\n", "for VRT in {vrt_array}; do\n", - " BASENAME=\"$VRT\"\n", - " OUT=\"$OUT_ORTHO/${{BASENAME}}_ortho.tif\"\n", - "\n", + " OUT=\"$OUT_ORTHO/${{VRT}}_ortho.tif\"\n", + " \n", " echo \"----------------------------------------\"\n", " echo \"Processing VRT: $VRT\"\n", " echo \"----------------------------------------\"\n", "\n", " rm -f \"$OUT\"\n", - "\n", + " \n", " # Get resolution for this band (Issue #61)\n", " RESOLUTION=$(get_band_resolution \"$VRT\")\n", " echo \"Band resolution: $RESOLUTION m\"\n", @@ -796,8 +810,6 @@ " -co COMPRESS=LZW \\\\\n", " -co TILED=YES \\\\\n", " -overwrite\n", - "\n", - " echo \"\"\n", "done\n", "\n", "echo \"\"\n", @@ -808,16 +820,15 @@ " echo \"----------------------------------------\"\n", " echo \"Creating mosaic for band: $BAND\"\n", " echo \"----------------------------------------\"\n", - "\n", - " INPUT_FILES=($(ls $OUT_ORTHO/*_${{BAND}}_ortho.tif 2>/dev/null))\n", + " \n", + " INPUT_FILES=($OUT_ORTHO/*_${{BAND}}_ortho.tif)\n", "\n", " if [ ${{#INPUT_FILES[@]}} -eq 0 ]; then\n", " echo \"No ortho images found for band $BAND\"\n", " continue\n", " fi\n", - "\n", " OUTPUT=\"$OUT_MOSAIC/ORTHO_mosaic_${{BAND}}.tif\"\n", - "\n", + " \n", " # Use gdal_merge.py instead of gdalwarp to avoid double resampling \n", " # All ortho images should have the same resolution and geometry\n", " # No resampling needed, just assembly\n", @@ -839,7 +850,6 @@ "\"\"\")\n", "\n", "os.chmod(gdal_script_path, 0o755)\n", - "print(\"Generated:\", gdal_script_path)\n", "\n", "# =====================================================\n", "# Run GDAL docker\n", @@ -849,7 +859,9 @@ "cmd_run = [\n", " \"docker\", \"run\",\n", " \"--rm\",\n", + " \"-v\", f\"{PATH_L1B_DATA}:/data/L1B\",\n", " \"-v\", f\"{WORKDIR}:/workspace\",\n", + " \"-v\", f\"{INVERSE_OUTPUT_FOLDER}:/output\",\n", " \"gdal-latest\",\n", " \"/workspace/src/gdal_ortho.sh\"\n", "]\n", @@ -858,13 +870,23 @@ "subprocess.run(cmd_run, check=True)\n", "print(\"\\nGDAL ortho + mosaic complete.\\n\")\n", "\n", + "\"\"\"\n", "# =====================================================\n", "# Cleanup docker image\n", "# =====================================================\n", "print(\"Removing gdal-latest image...\\n\")\n", "subprocess.run([\"docker\", \"rmi\", \"-f\", \"gdal-latest\"], check=True)\n", - "print(\"GDAL image removed.\\n\")\n" + "print(\"GDAL image removed.\\n\")\n", + "\"\"\"" ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "257b2ddd-8b9d-4c21-9233-0223c2a8b7d0", + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { @@ -883,7 +905,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.11" + "version": "3.13.11" } }, "nbformat": 4, From eecd79b9d43a2dbff30629f36a5c5f6077c3a40f Mon Sep 17 00:00:00 2001 From: Paul Castillo Date: Fri, 22 May 2026 11:39:06 +0000 Subject: [PATCH 02/13] Apply review comments : update of the README, separate notebook for static inputs --- sen2vm-notebook/README_Notebooks.md | 80 ++++--- .../src/inputs-download-notebook.ipynb | 152 +++++++++++++ sen2vm-notebook/src/notebook.ipynb | 212 +++++++----------- 3 files changed, 284 insertions(+), 160 deletions(-) create mode 100644 sen2vm-notebook/src/inputs-download-notebook.ipynb diff --git a/sen2vm-notebook/README_Notebooks.md b/sen2vm-notebook/README_Notebooks.md index 652dfa57..31e53631 100644 --- a/sen2vm-notebook/README_Notebooks.md +++ b/sen2vm-notebook/README_Notebooks.md @@ -16,6 +16,15 @@ # Sen2VM Notebook Processing Workflow This repository provides a complete workflow to run **Sen2VM** inside Docker and generate orthorectified and mosaicked outputs from Sentinel-2 L1B data. + +Two notebooks are provided: + +* **inputs-download-notebook.ipynb** + Downloads all required input data (GEOID and GIPP) from the Git repository. + +* **notebook.ipynb** + Runs Sen2VM using the downloaded inputs, along with the IERS file and L1B product, to produce orthorectified and mosaicked images. + The project is designed and tested on **Linux**. It may not work reliably on **Windows**. Actually, this notebook can generate an inverse grid but can not use it to apply the orthorectification. @@ -36,18 +45,12 @@ Actually, this notebook can generate an inverse grid but can not use it to apply ## Mandatory Directory Structure -```bash -WORKDIR -│ -├── DATA/ -│ └── GEOID/ # Put your GEOID files here (Optional) -└── ... -``` +Only a `WORKDIR` folder is required. All outputs, as well as intermediate files generated during execution, will be stored there. ## Inputs Several inputs are needed : --L1B S2 product under EUP.SAFE format : +* L1B S2 product under EUP.SAFE format : ```bash / ├── DATASTRIP # Required @@ -55,25 +58,21 @@ Several inputs are needed : ├── S2*OPER_MTD_SAFL1B_PDMC*.xml #Required └── ... ``` --Digital Elevation Model (DEM) --GIPP (if the path given in the notebook cell n°1 is empty (i.e ""), GIPP can be donwloaded and cloned from the GIT in /WORKSPACE/DATA +* Digital Elevation Model (DEM) + +* IERS (prediction of Earth orientation, IERS can be donwloaded using **notebook.ipynb** (cell number 2)) -Thanks to recent updates, input data can now be handled in two different ways: +* GIPP (GIPP can be downloaded from the GIT repositery using **inputs-download-notebook.ipynb**) -Using absolute paths (recommended) : -You can directly provide full paths to your data (L1B, DEM, GIPP), wherever they are located on your system. -This avoids copying large datasets and allows more flexibility. +* GEOID (GEOID can also be downloaded from the GIT repositery using **inputs-download-notebook.ipynb** ) -Using the default WORKDIR/DATA structure : -Alternatively, you can place all inputs inside the WORKDIR/DATA directory. +Thanks to a recent update (#issue 56), now the differents inputs path are absolute path. ## Directory Structure after execution ```bash WORKDIR │ -├── DATA/ -│ ├── bulletin*.txt # IERS prediction of earth exploration (downloaded by the cell n°3) -│ └── GEOID +├── bulletin*.txt # IERS prediction of earth exploration (downloaded by the cell n°3) │ ├── output/ # output after orthorectification and mosaic (.tif) │ ├── GDAL_OUTPUT_ORTHO @@ -95,39 +94,58 @@ pip install -r requirements.txt Select the virtual environment kernel in your Jupyter session. -## Notebook Configuration +## Notebooks Configuration -In the first cell of the notebook: +In **inputs-download-notebook.ipynb** : +In the first cell of the notebook : -1. Set the path to: +1. Set the paths to: + + * The directory where you want the GIPP files to be downloaded + * The directory where you want the GEOID files to be downloaded + +In **notebook.ipynb** : +In the first cell of the notebook : + +1. Set the absolute paths to: * The working directory * The L1B product * The GIPP directory - * The output directory + * The GEOID directory * The DEM directory + * The output directory + * The IERS file (if you do not have the IERS file, put `""`, and one will be automatically ed to the working directory) 2. Adjust configuration parameters for: * Sen2VM * Orthorectification settings + +3. Specify whether the docker images should be removed ## Processing Steps -Execute the notebook cell by cell in the following order: +If you do not have your own GIPP and GEOID files, or if they are not already downloaded, +execute the **inputs-download-notebook.ipynb** cell by cell in the following order : -1. Variable definitions +1. Path definitions 2. Clone `sen2vm-gipp`, and manage GIPP assets -3. Automatic download of the IERS bulletin -4. Generation of `config.json` in: `/WORKDIR/UserConf` -5. Generation of `params.json` in: `/WORKDIR/UserConf` -6. Execution of sen2vm inside Docker -7. Generation of a `.sh` script, then execution inside a second Docker container running the latest GDAL: +3. Copy `Geoid` folder from `"*/sen2vm-core/src/test/resources/DEM_GEOID"` + +Then, execute the **notebook.ipynb** cell by cell : + +1. Variable and path definitions +2. Automatic download of the IERS bulletin if none is provided by the user +3. Generation of `config.json` in: `/WORKDIR/UserConf` +4. Generation of `params.json` in: `/WORKDIR/UserConf` +5. Execution of sen2vm inside Docker +6. Generation of a `.sh` script, then execution inside a second Docker container running the latest GDAL: * Orthorectification by band * Mosaicking -Docker images are automatically cleaned up after each execution. +Docker images can be removed or kept depending on the value of `REMOVE_DOCKER_IMAGE` in step 1. ## Execution diff --git a/sen2vm-notebook/src/inputs-download-notebook.ipynb b/sen2vm-notebook/src/inputs-download-notebook.ipynb new file mode 100644 index 00000000..48b6f870 --- /dev/null +++ b/sen2vm-notebook/src/inputs-download-notebook.ipynb @@ -0,0 +1,152 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e71d30a3-b1dc-48f9-b7a0-1ee82f8cc775", + "metadata": {}, + "source": [ + "# === USER CONFIGURATION ===" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "0d377684-c4b1-4faa-a16f-02d7c8a58105", + "metadata": {}, + "outputs": [], + "source": [ + "#In this cell, you may indicate where you want the inputs to be donwloaded\n", + "\n", + "# Path where to put the GIPP directory\n", + "PATH_TO_GIPP = \"PATH/WHERE/TO/PUT/GIPP\"\n", + "\n", + "# Path where to put the GEOID directory\n", + "PATH_TO_GEOID = \"PATH/WHERE/TO/PUT/GEOID\"" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "93bc15d2-9c05-4cc2-82e5-3533e1bbcfd0", + "metadata": {}, + "outputs": [], + "source": [ + "# GIPP database download" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "52f77292-b1d3-42cd-817f-24b9bea7e520", + "metadata": {}, + "outputs": [], + "source": [ + "# === GIPPs ===\n", + "# This step is optional if the Database was already downloaded or if you want to use your own GIPP,\n", + "# It will donwload from GITHUB the directory sen2vm-gipp-database at PATH_GIPP\n", + "\n", + "import os\n", + "import shutil\n", + "import tarfile\n", + "import re\n", + "from datetime import datetime\n", + "import sys\n", + "\n", + "if not os.path.exists(PATH_TO_GIPP):\n", + " print(\"The folder where you want to download the GIPP is missing\")\n", + " sys.exit() \n", + "\n", + "# =====================================================================\n", + "# 1) CLONE sen2vm-gipp-database\n", + "# =====================================================================\n", + "\n", + "gipp_repo_name = \"sen2vm-gipp-database\"\n", + "PATH_GIPP = os.path.join(PATH_TO_GIPP, gipp_repo_name)\n", + "\n", + "# Delete repository if exists\n", + "if os.path.exists(PATH_GIPP):\n", + " print(f\"Removing existing repository: {PATH_GIPP}\")\n", + " shutil.rmtree(PATH_GIPP)\n", + "\n", + "# Clone repository fresh\n", + "print(\"Cloning sen2vm-gipp-database...\")\n", + "!git clone https://github.com/sen2vm/sen2vm-gipp-database.git {PATH_GIPP}\n", + "print(\"Clone complete.\\n\")\n", + "\n", + "print(\"GIPP processing finished successfully.\")\n", + "print(\"GIPP donwloaded in :\", PATH_GIPP)\n" + ] + }, + { + "cell_type": "markdown", + "id": "0e8b2d6d-5e67-4145-aa04-42d99671d36b", + "metadata": {}, + "source": [ + "# GEOID folder copy from github" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c781bbdc-3aa7-48d1-9284-5f5c507ed265", + "metadata": {}, + "outputs": [], + "source": [ + "# === GEOID ===\n", + "# This step is optional if the GEOID are already copied, or if you want to you use your own GEOID,\n", + "# It will copy the folder GEOID from \"*/sen2vm-core/src/test/resources/DEM_GEOID\" to PATH_TO_GEOID\n", + "\n", + "import os\n", + "import sys\n", + "import shutil\n", + "\n", + "if not os.path.exists(PATH_TO_GEOID):\n", + " print(\"The folder where you want to download the GEOID is missing\")\n", + " sys.exit() \n", + "\n", + "GEOID_DIR = os.path.join(PATH_TO_GEOID, \"GEOID\")\n", + "\n", + "if os.path.exists(GEOID_DIR):\n", + " shutil.rmtree(GEOID_DIR)\n", + "\n", + "os.makedirs(GEOID_DIR)\n", + "\n", + "# Notebook location (NOT relative to CWD)\n", + "notebook_dir = os.getcwd()\n", + "\n", + "# Relative path to DEM_GEOID from notebook\n", + "internal_geoid_dir = os.path.abspath(os.path.join(\n", + " notebook_dir,\n", + " \"..\", \"..\", \"src\", \"test\", \"resources\", \"DEM_GEOID\"\n", + "))\n", + "\n", + "for f in os.listdir(internal_geoid_dir):\n", + " src = os.path.join(internal_geoid_dir, f)\n", + " dst = os.path.join(GEOID_DIR, f)\n", + " shutil.copy(src, dst)\n", + "print(\"Done copying\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.11" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/sen2vm-notebook/src/notebook.ipynb b/sen2vm-notebook/src/notebook.ipynb index 141b495a..4ef98bce 100644 --- a/sen2vm-notebook/src/notebook.ipynb +++ b/sen2vm-notebook/src/notebook.ipynb @@ -21,9 +21,6 @@ "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "\n", "WORKDIR = \"PATH/TO/WORKDIR\" # Working directory for sen2vm processing\n", - "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", - "# /!\\/!\\/!\\ CAREFUL, the structure of the WORKDIR shall respect the one described in README_Notebooks.md\n", - "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "\n", "# Path to downloaded product\n", "PATH_L1B_DATA = \"PATH/TO/L1B_PRODUCT\"\n", @@ -31,16 +28,31 @@ "# Path to GIPP directory\n", "PATH_GIPP = \"PATH/TO/GIPP\"\n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", - "# /!\\/!\\/!\\ If the \"PATH_GIPP is empty (i.e = \"\"), you may execute the cell \"# GIPP database download (Optional)\", so the gipp can be cloned \n", - "# cloned from git, they will be put in /WORKDIR/DATA/sen2vm-gipp-database\n", - "# Please note that this current notebook will search for a subfolder with mission S2[A/B/C] inside the GIPP folder\n", + "# /!\\/!\\/!\\ If you do not have your own GIPP folder, you may use the inputs-download-notebook to download it, then you may indicate the path were you \n", + "# /!\\/!\\/!\\ downloaded it here in PATH_GIPP\n", + "# /!\\/!\\/!\\ If you have your own GIPP folder, please note that this current notebook will search for a subfolder with mission S2[A/B/C] inside the GIPP folder\n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "\n", - "# Path to DEM directory\n", + "# Path to DEM directory \n", "PATH_DEM = \"PATH/TO/DEM\"\n", "\n", + "# Path to GEOID directory\n", + "PATH_GEOID = \"PATH/TO/GEOID\"\n", + "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", + "# /!\\/!\\/!\\ If you do not have your own GEOID folder, you may use the inputs-download-notebook to download it, then you may indicate the path were you\n", + "# /!\\/!\\/!\\ downloaded it here in \n", + "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", + "\n", + "# Path to IERS file\n", + "PATH_IERS = \"PATH/TO/IERS_FILE\"\n", + "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", + "# /!\\/!\\/!\\ If you do not have your own IERS, you may let this path empy (i.e. \"\") and execute the cell number 2 named #IERS Download\n", + "# /!\\/!\\/!\\ In this case, the IERS will be downloaded in the WORKDIR\n", + "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", + "\n", "# Output folder chosen by the user\n", - "INVERSE_OUTPUT_FOLDER = \"PATH/TO/OUTPUT_FOLDER\" # where the exits are donwloaded\n", + "OUTPUT_FOLDER = \"PATH/TO/OUTPUT_FOLDER\" # where the exits are donwloaded\n", + "\n", "\n", "# === SEN2VM OPTIONS ===\n", "\n", @@ -71,62 +83,21 @@ "ORTHO_SETTINGS = {\n", " \"keep_bands\": [\"B02\"], # list of bands to keep for orthorectification\n", " \"keep_detectors\": [\"01\",\"02\",\"03\",\"04\",\"05\",\"06\",\"07\",\"08\",\"09\",\"10\",\"11\",\"12\"] # list of the detectors to keep \n", - "}\n" - ] - }, - { - "cell_type": "markdown", - "id": "c9e95184", - "metadata": {}, - "source": [ - "# GIPP database download (Optional)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a4e410c1", - "metadata": {}, - "outputs": [], - "source": [ - "# === GIPPs ===\n", - "# This step is optional if the Database was already downloaded or if you want to use your own GIPP\n", - "# If the PATH_GIPP isn't equal to \"\", this cell won't work, if PATH_GIPP= \"\", this cell will clone the git GIPP folder inside WORKDIR/DATA\n", - "# Please note that this current notebook will search for a subfolder with mission S2[A/B/C] inside the GIPP folder\n", - "\n", - "import os\n", - "import shutil\n", - "import tarfile\n", - "import re\n", - "from datetime import datetime\n", - "import sys\n", - "\n", - "if len(PATH_GIPP) != 0:\n", - " print(\"Stopping because PATH_GIPP is not empty\")\n", - " sys.exit(0)\n", - "\n", - "gipp_dir = os.path.join(WORKDIR, \"DATA\") \n", - "os.makedirs(gipp_dir, exist_ok=True) \n", - "\n", - "# =====================================================================\n", - "# 1) CLONE sen2vm-gipp-database\n", - "# =====================================================================\n", - "\n", - "gipp_repo_name = \"sen2vm-gipp-database\"\n", - "PATH_GIPP = os.path.join(gipp_dir, gipp_repo_name)\n", - "\n", - "# Delete repository if exists\n", - "if os.path.exists(PATH_GIPP):\n", - " print(f\"Removing existing repository: {PATH_GIPP}\")\n", - " shutil.rmtree(PATH_GIPP)\n", + "}\n", "\n", - "# Clone repository fresh\n", - "print(\"Cloning sen2vm-gipp-database...\")\n", - "!git clone https://github.com/sen2vm/sen2vm-gipp-database.git {PATH_GIPP}\n", - "print(\"Clone complete.\\n\")\n", "\n", - "print(\"GIPP processing finished successfully.\")\n", - "print(\"GIPP donwloaded in :\", PATH_GIPP)\n" + "# === Docker Options ===\n", + "# Building Docker images may take several minutes.\n", + "# By setting REMOVE_DOCKER_IMAGE = False, the images are kept,\n", + "# which significantly speeds up subsequent executions.\n", + "#\n", + "# However, Docker images use disk space (~4 GB in this case).\n", + "#\n", + "# Docker images can be manually removed using:\n", + "# docker images\n", + "# docker rmi \n", + "#\n", + "REMOVE_DOCKER_IMAGE = False # True = remove Docker images after execution" ] }, { @@ -134,7 +105,7 @@ "id": "63f616a3", "metadata": {}, "source": [ - "# IERS Download (optionnal)" + "# IERS Download" ] }, { @@ -145,36 +116,38 @@ "outputs": [], "source": [ "# === DOWNLOAD IERS ===\n", - "\n", "import os\n", "import re\n", "import requests\n", "from datetime import datetime\n", "\n", - "DATA_DIR = os.path.join(WORKDIR, \"DATA\")\n", + "if len(PATH_IERS) != 0: #Safety in case the PATH_IERS isn't empty\n", + " print(\"Stopping because PATH_IERS is not empty\")\n", + " sys.exit(0)\n", "\n", - "if not os.path.exists(DATA_DIR):\n", - " raise RuntimeError(f\"DATA directory not found: {DATA_DIR}\")\n", + "if not os.path.exists(WORKDIR):\n", + " raise RuntimeError(f\"WORKDIR directory not found: {WORKDIR}\")\n", "\n", - "print(\"Bulletin output directory:\", DATA_DIR)\n", + "print(\"Bulletin output directory:\", WORKDIR)\n", "\n", + "PATH_IERS = WORKDIR # then our file will be there\n", "# =====================================================================\n", - "# 0. REMOVE EXISTING IERS BULLETINS\n", + "# REMOVE EXISTING IERS BULLETINS\n", "# =====================================================================\n", "\n", - "for f in os.listdir(DATA_DIR):\n", + "for f in os.listdir(WORKDIR):\n", " if f.startswith(\"bulletina-\") and f.endswith(\".txt\"):\n", - " os.remove(os.path.join(DATA_DIR, f))\n", + " os.remove(os.path.join(WORKDIR, f))\n", " print(\"Removed old bulletin A:\", f)\n", "\n", " if f.startswith(\"bulletinb-\") and f.endswith(\".txt\"):\n", - " os.remove(os.path.join(DATA_DIR, f))\n", + " os.remove(os.path.join(WORKDIR, f))\n", " print(\"Removed old bulletin B:\", f)\n", "\n", "print(\"Cleanup of old bulletins complete.\\n\")\n", "\n", "# =====================================================================\n", - "# 2. EXTRACT PRODUCT DATE (FROM DATASTRIP)\n", + "# EXTRACT PRODUCT DATE (FROM DATASTRIP)\n", "# =====================================================================\n", "\n", "datastrip_dir = os.path.join(PATH_L1B_DATA, \"DATASTRIP\")\n", @@ -244,7 +217,7 @@ "\n", " if response.status_code == 200:\n", " print(\"Bulletin found:\", index_str)\n", - " dest_file = os.path.join(DATA_DIR, f\"bulletina-{roman_year}-{index_str}.txt\")\n", + " dest_file = os.path.join(WORKDIR, f\"bulletina-{roman_year}-{index_str}.txt\")\n", " found = True\n", " break\n", "\n", @@ -288,10 +261,8 @@ "\n", "print(\"UserConf directory:\", USERCONF_DIR)\n", "\n", - "GEOID_DIR = os.path.join(WORKDIR, \"DATA\", \"GEOID\")\n", - "os.makedirs(GEOID_DIR, exist_ok=True)\n", "\n", - "print(\"Geoid directory:\", GEOID_DIR)\n", + "print(\"Geoid directory:\", PATH_GEOID)\n", "\n", "# =====================================================\n", "# 1. Extract mission from DATASTRIP\n", @@ -327,47 +298,29 @@ "# 3. Geoid management\n", "# =====================================================\n", "\n", - "# Notebook location (NOT relative to CWD)\n", - "notebook_dir = os.getcwd()\n", - "\n", - "# Relative path to DEM_GEOID from notebook\n", - "internal_geoid_dir = os.path.abspath(os.path.join(\n", - " notebook_dir,\n", - " \"..\", \"..\", \"src\", \"test\", \"resources\", \"DEM_GEOID\"\n", - "))\n", - "\n", - "# If WORKDIR/DATA/GEOID is empty -> copy internal files\n", - "if len(os.listdir(GEOID_DIR)) == 0:\n", - " print(\"GEOID directory is empty -> copying default geoid files...\")\n", - " for f in os.listdir(internal_geoid_dir):\n", - " src = os.path.join(internal_geoid_dir, f)\n", - " dst = os.path.join(GEOID_DIR, f)\n", - " shutil.copy(src, dst)\n", - "\n", - "# Detect .gtx inside GEOID_DIR\n", - "geoid_files = [f for f in os.listdir(GEOID_DIR) if f.lower().endswith(\".gtx\")]\n", + "# Detect .gtx inside PATH_GEOID\n", + "geoid_files = [f for f in os.listdir(PATH_GEOID) if f.lower().endswith(\".gtx\")]\n", "if len(geoid_files) == 0:\n", - " raise RuntimeError(\"No .gtx geoid file found in WORKDIR/DATA/GEOID.\")\n", + " raise RuntimeError(\"No .gtx geoid file found in PATH_GEOID.\")\n", "\n", - "docker_geoid = f\"/workspace/DATA/GEOID/{geoid_files[0]}\"\n", + "docker_geoid = f\"/data/GEOID/{geoid_files[0]}\"\n", "\n", "# =====================================================\n", "# 4. Locate IERS bulletin on host\n", "# =====================================================\n", "\n", - "DATA_DIR = os.path.join(WORKDIR, \"DATA\")\n", "iers_host = None\n", "\n", - "for f in os.listdir(DATA_DIR):\n", + "for f in os.listdir(PATH_IERS):\n", " if f.startswith(\"bulletin\"):\n", - " iers_host = os.path.join(DATA_DIR, f)\n", + " iers_host = os.path.join(PATH_IERS, f)\n", " break\n", "\n", "if iers_host is None:\n", - " raise RuntimeError(\"IERS bulletin not found inside WORKDIR/DATA directory.\")\n", - "\n", - "docker_iers = \"/workspace/DATA/\" + os.path.basename(iers_host)\n", + " raise RuntimeError(\"IERS bulletin not found inside PATH_IERS directory.\")\n", "\n", + "docker_iers = f\"/data/IERS/{os.path.basename(iers_host)}\"\n", + "print(docker_iers)\n", "# =====================================================\n", "# 5. Build config dictionary\n", "# =====================================================\n", @@ -527,6 +480,8 @@ "import os\n", "import subprocess\n", "\n", + "# Notebook location (NOT relative to CWD)\n", + "notebook_dir = os.getcwd()\n", "\n", "dockerfile_dir = os.path.abspath(os.path.join(\n", " notebook_dir,\n", @@ -562,7 +517,9 @@ " \"-v\", f\"{PATH_L1B_DATA}:/data/L1B\",\n", " \"-v\", f\"{PATH_DEM}:/data/DEM\",\n", " \"-v\", f\"{PATH_GIPP}:/data/GIPP\",\n", - " \"-v\", f\"{WORKDIR}:/workspace\", \n", + " \"-v\", f\"{PATH_GEOID}:/data/GEOID\",\n", + " \"-v\", f\"{PATH_IERS}:/data/IERS\",\n", + " \"-v\", f\"{WORKDIR}:/workspace\",\n", " \"sen2vm\",\n", " \"-c\", config_inside,\n", " \"-p\", params_inside\n", @@ -576,11 +533,13 @@ "# =====================================================\n", "# 3. REMOVE DOCKER IMAGE\n", "# =====================================================\n", - "\"\"\"\n", - "print(\"Removing Docker image 'sen2vm'...\")\n", - "subprocess.run([\"docker\", \"rmi\", \"-f\", \"sen2vm\"], check=True)\n", - "print(\"Docker image removed.\\n\")\n", - "\"\"\"\n" + "if REMOVE_DOCKER_IMAGE:\n", + " print(\"Removing Docker image 'sen2vm'...\")\n", + " subprocess.run([\"docker\", \"rmi\", \"-f\", \"sen2vm\"], check=True)\n", + " print(\"Docker images removed.\\n\")\n", + "else:\n", + " print(\"Docker images kept.\\n\")\n", + "\n" ] }, { @@ -609,8 +568,8 @@ "# =====================================================\n", "assert os.path.exists(PATH_L1B_DATA), \"L1B path missing\"\n", "\n", - "os.makedirs(INVERSE_OUTPUT_FOLDER, exist_ok=True)\n", - "assert os.path.exists(INVERSE_OUTPUT_FOLDER), \"Output folder missing\"\n", + "os.makedirs(OUTPUT_FOLDER, exist_ok=True)\n", + "assert os.path.exists(OUTPUT_FOLDER), \"Output folder missing\"\n", "\n", "# =====================================================\n", "# Locate product name\n", @@ -693,10 +652,10 @@ "# =====================================================\n", "# Output directories\n", "# =====================================================\n", - "os.makedirs(os.path.join(INVERSE_OUTPUT_FOLDER, \"GDAL_OUTPUT_ORTHO\"), exist_ok=True)\n", - "os.makedirs(os.path.join(INVERSE_OUTPUT_FOLDER, \"GDAL_OUTPUT_MOSAIC\"), exist_ok=True)\n", + "os.makedirs(os.path.join(OUTPUT_FOLDER, \"GDAL_OUTPUT_ORTHO\"), exist_ok=True)\n", + "os.makedirs(os.path.join(OUTPUT_FOLDER, \"GDAL_OUTPUT_MOSAIC\"), exist_ok=True)\n", "\n", - "print(\"Output folder:\", INVERSE_OUTPUT_FOLDER)\n", + "print(\"Output folder:\", OUTPUT_FOLDER)\n", "\n", "# =====================================================\n", "# Build GDAL docker\n", @@ -861,7 +820,7 @@ " \"--rm\",\n", " \"-v\", f\"{PATH_L1B_DATA}:/data/L1B\",\n", " \"-v\", f\"{WORKDIR}:/workspace\",\n", - " \"-v\", f\"{INVERSE_OUTPUT_FOLDER}:/output\",\n", + " \"-v\", f\"{OUTPUT_FOLDER}:/output\",\n", " \"gdal-latest\",\n", " \"/workspace/src/gdal_ortho.sh\"\n", "]\n", @@ -870,23 +829,18 @@ "subprocess.run(cmd_run, check=True)\n", "print(\"\\nGDAL ortho + mosaic complete.\\n\")\n", "\n", - "\"\"\"\n", + "\n", "# =====================================================\n", "# Cleanup docker image\n", "# =====================================================\n", - "print(\"Removing gdal-latest image...\\n\")\n", - "subprocess.run([\"docker\", \"rmi\", \"-f\", \"gdal-latest\"], check=True)\n", - "print(\"GDAL image removed.\\n\")\n", - "\"\"\"" + "\n", + "if REMOVE_DOCKER_IMAGE:\n", + " print(\"Removing gdal-latest image...\\n\")\n", + " subprocess.run([\"docker\", \"rmi\", \"-f\", \"gdal-latest\"], check=True)\n", + " print(\"GDAL image removed.\\n\")\n", + "else:\n", + " print(\"Docker images kept (faster next run, ~4 GB disk usage).\\n\")" ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "257b2ddd-8b9d-4c21-9233-0223c2a8b7d0", - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { From 6067ad4a094a8507da873e2f91b0aa3a0690e5e0 Mon Sep 17 00:00:00 2001 From: Paul Castillo Date: Fri, 12 Jun 2026 08:58:28 +0000 Subject: [PATCH 03/13] grid direct & inverse --- sen2vm-notebook/README_Notebooks.md | 54 +- ...ebook.ipynb => notebook-direct-grid.ipynb} | 83 +- .../src/notebook-inverse-grid.ipynb | 894 ++++++++++++++++++ 3 files changed, 959 insertions(+), 72 deletions(-) rename sen2vm-notebook/src/{notebook.ipynb => notebook-direct-grid.ipynb} (94%) create mode 100644 sen2vm-notebook/src/notebook-inverse-grid.ipynb diff --git a/sen2vm-notebook/README_Notebooks.md b/sen2vm-notebook/README_Notebooks.md index 31e53631..d025e905 100644 --- a/sen2vm-notebook/README_Notebooks.md +++ b/sen2vm-notebook/README_Notebooks.md @@ -17,16 +17,18 @@ This repository provides a complete workflow to run **Sen2VM** inside Docker and generate orthorectified and mosaicked outputs from Sentinel-2 L1B data. -Two notebooks are provided: +Three notebooks are provided: * **inputs-download-notebook.ipynb** Downloads all required input data (GEOID and GIPP) from the Git repository. -* **notebook.ipynb** - Runs Sen2VM using the downloaded inputs, along with the IERS file and L1B product, to produce orthorectified and mosaicked images. +* **notebook-direct-grid.ipynb** + Runs Sen2VM with the **direct** mode, using the downloaded inputs, along with the IERS file and L1B product, to produce orthorectified and mosaicked images. + +* **notebook-inverse-grid.ipynb** + Runs Sen2VM with the **inverse** mode, using the downloaded inputs, along with the IERS file and L1B product, to produce orthorectified and mosaicked images. The project is designed and tested on **Linux**. It may not work reliably on **Windows**. -Actually, this notebook can generate an inverse grid but can not use it to apply the orthorectification. ## Prerequisites @@ -34,7 +36,10 @@ Actually, this notebook can generate an inverse grid but can not use it to apply * **Python 3.x** * **the full sen2vm-notebook folder shall be present:** - * notebook.ipynb + * inputs-download-notebook.ipynb + * `notebook-direct-grid.ipynb + * `notebook-inverse-grid.ipynb + * requirements.txt * gdal-latest folder @@ -75,10 +80,17 @@ WORKDIR ├── bulletin*.txt # IERS prediction of earth exploration (downloaded by the cell n°3) │ ├── output/ # output after orthorectification and mosaic (.tif) -│ ├── GDAL_OUTPUT_ORTHO -│ └── GDAL_OUTPUT_MOSAIC +│ ├── DIRECT +│ │ ├─ GDAL_OUTPUT_ORTHO # .tif orthorectified, one for each band and detector +│ │ └─ GDAL_OUTPUT_MOSAIC # .tif orthorectified and merged by band, one for each band +│ └── INVERSE +│ ├─ INVERSE_GRID # inverse gelocation grid, generated by sen2vm, these grids encode the transformation between sensor geometry and map geometry +│ ├─ raw # contains the raw L1B images extracted per detector and per band, expressed in the sensor geometry (i.e., before any orthorectification or map projection) +│ ├─ otb_no_georef # contains images resampled using OTB with the inverse grids. The data are projected onto a regular grid but are not yet fully georeferenced +│ ├─ output_georef # contains the final orthorectificatied and georeferenced images +│ └─ mosaic # contains mosaicked images generated per spectral band by merging all detector-level orthorectified images │ -├── src/ # contains a .sh used to run in the gdal docker generated by the notebook +├── src/ # contains a .sh used to run in the gdal docker generated by the notebook └── UserConf # contains .txt config files generated by the notebook ``` @@ -104,7 +116,7 @@ In the first cell of the notebook : * The directory where you want the GIPP files to be downloaded * The directory where you want the GEOID files to be downloaded -In **notebook.ipynb** : +In **notebook-direct-grid.ipynb** or in **notebook-inverse-grid.ipynb** : In the first cell of the notebook : 1. Set the absolute paths to: @@ -114,9 +126,9 @@ In the first cell of the notebook : * The GIPP directory * The GEOID directory * The DEM directory - * The output directory * The IERS file (if you do not have the IERS file, put `""`, and one will be automatically ed to the working directory) - + * NB : The output directory will be created in the working directory + 2. Adjust configuration parameters for: * Sen2VM @@ -133,7 +145,7 @@ execute the **inputs-download-notebook.ipynb** cell by cell in the following ord 2. Clone `sen2vm-gipp`, and manage GIPP assets 3. Copy `Geoid` folder from `"*/sen2vm-core/src/test/resources/DEM_GEOID"` -Then, execute the **notebook.ipynb** cell by cell : +Then if you want to use the direct grids, which may be longer, execute the **notebook-direct-grid.ipynb** cell by cell : 1. Variable and path definitions 2. Automatic download of the IERS bulletin if none is provided by the user @@ -142,11 +154,23 @@ Then, execute the **notebook.ipynb** cell by cell : 5. Execution of sen2vm inside Docker 6. Generation of a `.sh` script, then execution inside a second Docker container running the latest GDAL: - * Orthorectification by band - * Mosaicking + * Orthorectification by band that generate images in `WORKDIR/DIRECT/GDAL_OUTPUT_ORTHO` + * Mosaicking by band that generate an image in `WORKDIR/DIRECT/GDAL_OUTPUT_MOSAIC` + + +If you want to use the inverse grids, execute the **notebook-inverse-grid.ipynb** cell by cell : -Docker images can be removed or kept depending on the value of `REMOVE_DOCKER_IMAGE` in step 1. +1. Variable and path definitions +2. Automatic download of the IERS bulletin if none is provided by the user +3. Generation of `config.json` in: `/WORKDIR/UserConf` +4. Generation of `params.json` in: `/WORKDIR/UserConf` +5. Execution of sen2vm inside Docker to generate the inverse grids in `WORKDIR/output/INVERSE/INVERSE_GRID` +6. Orthorectification using OTB inside a docker then mosaicking using GDAL : + + * Orthorectification by band + * Mosaicking +Docker images can be removed or kept depending on the value of `REMOVE_DOCKER_IMAGE` in step 1. ## Execution Run all notebook cells sequentially. diff --git a/sen2vm-notebook/src/notebook.ipynb b/sen2vm-notebook/src/notebook-direct-grid.ipynb similarity index 94% rename from sen2vm-notebook/src/notebook.ipynb rename to sen2vm-notebook/src/notebook-direct-grid.ipynb index 4ef98bce..7fd5c2c6 100644 --- a/sen2vm-notebook/src/notebook.ipynb +++ b/sen2vm-notebook/src/notebook-direct-grid.ipynb @@ -10,7 +10,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "2b816cd9-5254-452b-bced-2943eb6b7aec", "metadata": {}, "outputs": [], @@ -50,23 +50,16 @@ "# /!\\/!\\/!\\ In this case, the IERS will be downloaded in the WORKDIR\n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "\n", - "# Output folder chosen by the user\n", - "OUTPUT_FOLDER = \"PATH/TO/OUTPUT_FOLDER\" # where the exits are donwloaded\n", - "\n", + "# The output folder is put in the WORKDIR\n", + "OUTPUT_FOLDER = WORKDIR + \"/output/DIRECT\"\n", "\n", "# === SEN2VM OPTIONS ===\n", - "\n", - "GRID_MODE = \"direct\" # direct or inverse\n", - "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", - "# /!\\/!\\/!\\ CAREFUL, for now only direct shall be used with a full product (no missing granules)\n", - "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", - "\n", "UTM_EPSG = 32628 # UTM zone EPSG code for the ROI\n", "LOCATION = {\n", - " \"ul_x\": 281719,\n", - " \"ul_y\": 3640370,\n", - " \"lr_x\": 336222,\n", - " \"lr_y\": 3611287\n", + " \"ul_x\": 283910,\n", + " \"ul_y\": 3641660,\n", + " \"lr_x\": 354280,\n", + " \"lr_y\": 3608316.0\n", "}\n", "\n", "# Grid step in pixels for sen2vm grid generation \n", @@ -75,17 +68,16 @@ "STEPS = {\n", " \"10m_bands\": 4.5, # Grid step: ~DEM90/2 = 45m/10m = 4.5 pixels (one point every 4.5 pixels at 10m)\n", " \"20m_bands\": 2.25, # Grid step: ~DEM90/2 = 45m/20m = 2.25 pixels (one point every 2.25 pixels at 20m)\n", - " \"60m_bands\": 1 # Grid step: ~DEM90/2 = 45m/60m ≈ 1 pixel (one point every 1 pixel at 60m, or 2 is also fine)\n", + " \"60m_bands\": 1.0 # Grid step: ~DEM90/2 = 45m/60m ≈ 1 pixel (one point every 1 pixel at 60m, or 2 is also fine)\n", "}\n", "\n", "# === GDAL ORTHO OPTIONS ===\n", "\n", "ORTHO_SETTINGS = {\n", - " \"keep_bands\": [\"B02\"], # list of bands to keep for orthorectification\n", + " \"keep_bands\": [\"B02\",\"B03\"], # list of bands to keep for orthorectification\n", " \"keep_detectors\": [\"01\",\"02\",\"03\",\"04\",\"05\",\"06\",\"07\",\"08\",\"09\",\"10\",\"11\",\"12\"] # list of the detectors to keep \n", "}\n", "\n", - "\n", "# === Docker Options ===\n", "# Building Docker images may take several minutes.\n", "# By setting REMOVE_DOCKER_IMAGE = False, the images are kept,\n", @@ -119,6 +111,7 @@ "import os\n", "import re\n", "import requests\n", + "import sys\n", "from datetime import datetime\n", "\n", "if len(PATH_IERS) != 0: #Safety in case the PATH_IERS isn't empty\n", @@ -145,7 +138,6 @@ " print(\"Removed old bulletin B:\", f)\n", "\n", "print(\"Cleanup of old bulletins complete.\\n\")\n", - "\n", "# =====================================================================\n", "# EXTRACT PRODUCT DATE (FROM DATASTRIP)\n", "# =====================================================================\n", @@ -175,7 +167,6 @@ "product_date = datetime(year, month, day)\n", "\n", "print(\"Product date extracted from DATASTRIP:\", product_date.date(), \"\\n\")\n", - "\n", "# =====================================================================\n", "# Roman conversion \n", "# =====================================================================\n", @@ -192,13 +183,10 @@ " res += s\n", " n -= v\n", " return res\n", - "\n", - "\n", "# =====================================================================\n", "# Bulletin A\n", "# =====================================================================\n", "\n", - "\n", "roman_year = int_to_roman(year - 1987)\n", "doy = product_date.timetuple().tm_yday\n", "index = (doy - 1) // 7 + 1\n", @@ -229,7 +217,7 @@ "with open(dest_file, \"wb\") as f:\n", " f.write(response.content)\n", "\n", - "print(\"Downloaded:\", dest_file)\n" + "print(\"Downloaded:\", dest_file)" ] }, { @@ -255,13 +243,10 @@ "import shutil\n", "from numpy import double\n", "\n", - "\n", "USERCONF_DIR = os.path.join(WORKDIR, \"UserConf\")\n", "os.makedirs(USERCONF_DIR, exist_ok=True)\n", "\n", "print(\"UserConf directory:\", USERCONF_DIR)\n", - "\n", - "\n", "print(\"Geoid directory:\", PATH_GEOID)\n", "\n", "# =====================================================\n", @@ -284,8 +269,6 @@ " raise RuntimeError(\"Cannot extract mission (S2A/S2B/S2C) from DATASTRIP name.\")\n", "\n", "mission = match.group(1)\n", - "\n", - "\n", "# =====================================================\n", "# 2. Docker paths inside /workspace\n", "# =====================================================\n", @@ -293,7 +276,6 @@ "docker_l1b = \"/data/L1B\"\n", "docker_dem = \"/data/DEM\"\n", "docker_gipp = f\"/data/GIPP/{mission}\"\n", - "\n", "# =====================================================\n", "# 3. Geoid management\n", "# =====================================================\n", @@ -304,7 +286,6 @@ " raise RuntimeError(\"No .gtx geoid file found in PATH_GEOID.\")\n", "\n", "docker_geoid = f\"/data/GEOID/{geoid_files[0]}\"\n", - "\n", "# =====================================================\n", "# 4. Locate IERS bulletin on host\n", "# =====================================================\n", @@ -333,7 +314,7 @@ " \"dem\": docker_dem,\n", " \"geoid\": docker_geoid,\n", " \"iers\": docker_iers,\n", - " \"operation\": GRID_MODE,\n", + " \"operation\": \"direct\",\n", " \"deactivate_available_refining\": False,\n", " \"steps\": {\n", " \"10m_bands\": STEPS[\"10m_bands\"],\n", @@ -342,18 +323,6 @@ " },\n", " \"export_alt\": True\n", "}\n", - "\n", - "# Add inverse block only if needed\n", - "if GRID_MODE == \"inverse\":\n", - " config[\"inverse_location_additional_info\"] = {\n", - " \"ul_x\": double(LOCATION[\"ul_x\"]),\n", - " \"ul_y\": double(LOCATION[\"ul_y\"]),\n", - " \"lr_x\": double(LOCATION[\"lr_x\"]),\n", - " \"lr_y\": double(LOCATION[\"lr_y\"]),\n", - " \"referential\": f\"EPSG:{UTM_EPSG}\",\n", - " \"output_folder\": \"/workspace/DATA/Output\"\n", - " }\n", - "\n", "# =====================================================\n", "# Save config.json\n", "# =====================================================\n", @@ -364,7 +333,7 @@ " json.dump(config, f, indent=4)\n", "\n", "print(\"Configuration file generated:\")\n", - "print(config_path)\n" + "print(config_path)" ] }, { @@ -384,10 +353,10 @@ "os.makedirs(USERCONF_DIR, exist_ok=True)\n", "\n", "print(\"UserConf directory:\", USERCONF_DIR)\n", - "\n", "# =====================================================\n", "# Locate GRANULE folders\n", "# =====================================================\n", + "\n", "GR_TARGET_DIR = os.path.join(PATH_L1B_DATA, \"GRANULE\")\n", "\n", "if not os.path.exists(GR_TARGET_DIR):\n", @@ -400,10 +369,10 @@ "]\n", "\n", "print(\"Found\", len(granule_folders), \"granule folders.\")\n", - "\n", "# =====================================================\n", "# Extract detectors and bands from JP2\n", "# =====================================================\n", + "\n", "detectors = set()\n", "bands = set()\n", "\n", @@ -426,7 +395,6 @@ "\n", "print(\"Detected detectors:\", detectors)\n", "print(\"Detected bands:\", bands)\n", - "\n", "# =====================================================\n", "# Write params.json\n", "# =====================================================\n", @@ -457,7 +425,7 @@ "\n", "print(\"params.json written to:\", params_path)\n", "print(f\" - Detectors: {params['detectors']}\")\n", - "print(f\" - Bands: {params['bands']}\")\n" + "print(f\" - Bands: {params['bands']}\")" ] }, { @@ -490,13 +458,11 @@ "\n", "config_inside = \"/workspace/UserConf/config.json\"\n", "params_inside = \"/workspace/UserConf/params.json\"\n", - "\n", "# =====================================================\n", "# 1. BUILD DOCKER IMAGE\n", "# =====================================================\n", "\n", "print(f\"Building Docker image 'sen2vm' from: {dockerfile_dir}\")\n", - "\n", "cmd_build = [\n", " \"docker\", \"build\",\n", " \"-t\", \"sen2vm\",\n", @@ -506,7 +472,6 @@ "print(\"Command:\", \" \".join(cmd_build), \"\\n\")\n", "subprocess.run(cmd_build, check=True)\n", "print(\"Docker image built successfully.\\n\")\n", - "\n", "# =====================================================\n", "# 2. RUN SEN2VM CONTAINER\n", "# =====================================================\n", @@ -529,17 +494,16 @@ "print(\"Command:\", \" \".join(cmd_run), \"\\n\")\n", "subprocess.run(cmd_run, check=True)\n", "print(\"\\nDocker execution complete.\\n\")\n", - "\n", "# =====================================================\n", "# 3. REMOVE DOCKER IMAGE\n", "# =====================================================\n", + "\n", "if REMOVE_DOCKER_IMAGE:\n", " print(\"Removing Docker image 'sen2vm'...\")\n", " subprocess.run([\"docker\", \"rmi\", \"-f\", \"sen2vm\"], check=True)\n", " print(\"Docker images removed.\\n\")\n", "else:\n", - " print(\"Docker images kept.\\n\")\n", - "\n" + " print(\"Docker images kept.\\n\")" ] }, { @@ -567,7 +531,6 @@ "# SAFETY CHECKS\n", "# =====================================================\n", "assert os.path.exists(PATH_L1B_DATA), \"L1B path missing\"\n", - "\n", "os.makedirs(OUTPUT_FOLDER, exist_ok=True)\n", "assert os.path.exists(OUTPUT_FOLDER), \"Output folder missing\"\n", "\n", @@ -828,8 +791,6 @@ "print(\"Command:\", \" \".join(cmd_run), \"\\n\")\n", "subprocess.run(cmd_run, check=True)\n", "print(\"\\nGDAL ortho + mosaic complete.\\n\")\n", - "\n", - "\n", "# =====================================================\n", "# Cleanup docker image\n", "# =====================================================\n", @@ -841,6 +802,14 @@ "else:\n", " print(\"Docker images kept (faster next run, ~4 GB disk usage).\\n\")" ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9ceb746c-6830-4bef-ab52-16d463fa12c8", + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { diff --git a/sen2vm-notebook/src/notebook-inverse-grid.ipynb b/sen2vm-notebook/src/notebook-inverse-grid.ipynb new file mode 100644 index 00000000..0fe11948 --- /dev/null +++ b/sen2vm-notebook/src/notebook-inverse-grid.ipynb @@ -0,0 +1,894 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "8e5ed8d8-c718-4f80-a220-464bbc67c748", + "metadata": {}, + "source": [ + "# === USER CONFIGURATION ===" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2b816cd9-5254-452b-bced-2943eb6b7aec", + "metadata": {}, + "outputs": [], + "source": [ + "# # === USER CONFIGURATION ===\n", + "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", + "# /!\\/!\\/!\\ CAREFUL, please read the README_Notebooks.md file before\n", + "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", + "\n", + "WORKDIR = \"PATH/TO/WORKDIR\" # Working directory for sen2vm processing\n", + "\n", + "# Path to downloaded product\n", + "PATH_L1B_DATA = \"PATH/TO/L1B_PRODUCT\"\n", + "\n", + "# Path to GIPP directory\n", + "PATH_GIPP = \"PATH/TO/GIPP\"\n", + "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", + "# /!\\/!\\/!\\ If you do not have your own GIPP folder, you may use the inputs-download-notebook to download it, then you may indicate the path were you \n", + "# /!\\/!\\/!\\ downloaded it here in PATH_GIPP\n", + "# /!\\/!\\/!\\ If you have your own GIPP folder, please note that this current notebook will search for a subfolder with mission S2[A/B/C] inside the GIPP folder\n", + "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", + "\n", + "# Path to DEM directory \n", + "PATH_DEM = \"PATH/TO/DEM\"\n", + "\n", + "# Path to GEOID directory\n", + "PATH_GEOID = \"PATH/TO/GEOID\"\n", + "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", + "# /!\\/!\\/!\\ If you do not have your own GEOID folder, you may use the inputs-download-notebook to download it, then you may indicate the path were you\n", + "# /!\\/!\\/!\\ downloaded it here in \n", + "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", + "\n", + "# Path to IERS file\n", + "PATH_IERS = \"PATH/TO/IERS_FILE\"\n", + "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", + "# /!\\/!\\/!\\ If you do not have your own IERS, you may let this path empy (i.e. \"\") and execute the cell number 2 named #IERS Download\n", + "# /!\\/!\\/!\\ In this case, the IERS will be downloaded in the WORKDIR\n", + "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", + "\n", + "# The output folder is put in the WORKDIR\n", + "OUTPUT_FOLDER = WORKDIR + \"/output/INVERSE\"\n", + "\n", + "# === SEN2VM OPTIONS ===\n", + "UTM_EPSG = 32628 # UTM zone EPSG code for the ROI\n", + "LOCATION = {\n", + " \"ul_x\": 283910,\n", + " \"ul_y\": 3641660,\n", + " \"lr_x\": 354280,\n", + " \"lr_y\": 3608316.0\n", + "}\n", + "\n", + "# Grid step in pixels for sen2vm grid generation \n", + "# These values represent the grid step in pixels, it's the pixel in the detector geometry, typically DEM resolution\n", + "# For S2 with DEM90, this gives approximately: 45m\n", + "STEPS = {\n", + " \"10m_bands\": 45, \n", + " \"20m_bands\": 45, \n", + " \"60m_bands\": 45\n", + "}\n", + "\n", + "# === GDAL ORTHO OPTIONS ===\n", + "\n", + "ORTHO_SETTINGS = {\n", + " \"keep_bands\": [\"B02\"], # list of bands to keep for orthorectification\n", + " \"keep_detectors\": [\"01\",\"02\",\"03\",\"04\",\"05\",\"06\",\"07\",\"08\",\"09\",\"10\",\"11\",\"12\"] # list of the detectors to keep \n", + "}\n", + "\n", + "# === Docker Options ===\n", + "# By setting REMOVE_DOCKER_IMAGE = False, the images are kept,\n", + "# which significantly speeds up subsequent executions.\n", + "#\n", + "# However, Docker images use disk space (~4 GB in this case).\n", + "#\n", + "# Docker images can be manually removed using:\n", + "# docker images\n", + "# docker rmi \n", + "#\n", + "REMOVE_DOCKER_IMAGE = False # True = remove Docker images after execution" + ] + }, + { + "cell_type": "markdown", + "id": "63f616a3", + "metadata": {}, + "source": [ + "# IERS Download" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8ec4d6f6", + "metadata": {}, + "outputs": [], + "source": [ + "# === DOWNLOAD IERS ===\n", + "import os\n", + "import re\n", + "import requests\n", + "import sys\n", + "from datetime import datetime\n", + "\n", + "if len(PATH_IERS) != 0: #Safety in case the PATH_IERS isn't empty\n", + " print(\"Stopping because PATH_IERS is not empty\")\n", + " sys.exit(0)\n", + "\n", + "if not os.path.exists(WORKDIR):\n", + " raise RuntimeError(f\"WORKDIR directory not found: {WORKDIR}\")\n", + "\n", + "print(\"Bulletin output directory:\", WORKDIR)\n", + "\n", + "PATH_IERS = WORKDIR # then our file will be there\n", + "# =====================================================================\n", + "# REMOVE EXISTING IERS BULLETINS\n", + "# =====================================================================\n", + "\n", + "for f in os.listdir(WORKDIR):\n", + " if f.startswith(\"bulletina-\") and f.endswith(\".txt\"):\n", + " os.remove(os.path.join(WORKDIR, f))\n", + " print(\"Removed old bulletin A:\", f)\n", + "\n", + " if f.startswith(\"bulletinb-\") and f.endswith(\".txt\"):\n", + " os.remove(os.path.join(WORKDIR, f))\n", + " print(\"Removed old bulletin B:\", f)\n", + "\n", + "print(\"Cleanup of old bulletins complete.\\n\")\n", + "# =====================================================================\n", + "# EXTRACT PRODUCT DATE (FROM DATASTRIP)\n", + "# =====================================================================\n", + "\n", + "datastrip_dir = os.path.join(PATH_L1B_DATA, \"DATASTRIP\")\n", + "\n", + "if not os.path.isdir(datastrip_dir):\n", + " raise RuntimeError(f\"DATASTRIP directory not found: {datastrip_dir}\")\n", + "\n", + "datastrip_entries = os.listdir(datastrip_dir)\n", + "if not datastrip_entries:\n", + " raise RuntimeError(f\"No DATASTRIP found in: {datastrip_dir}\")\n", + "\n", + "# Take the first DATASTRIP product\n", + "datastrip_name = datastrip_entries[0]\n", + "\n", + "match = re.search(r\"_S(\\d{8})T\\d{6}_\", datastrip_name)\n", + "if not match:\n", + " raise RuntimeError(\"Could not extract product date from DATASTRIP name.\")\n", + "\n", + "product_date_str = match.group(1)\n", + "\n", + "year = int(product_date_str[:4])\n", + "month = int(product_date_str[4:6])\n", + "day = int(product_date_str[6:8])\n", + "\n", + "product_date = datetime(year, month, day)\n", + "\n", + "print(\"Product date extracted from DATASTRIP:\", product_date.date(), \"\\n\")\n", + "# =====================================================================\n", + "# Roman conversion \n", + "# =====================================================================\n", + "\n", + "def int_to_roman(n):\n", + " vals = [\n", + " (1000, 'm'), (900, 'cm'), (500, 'd'), (400, 'cd'),\n", + " (100, 'c'), (90, 'xc'), (50, 'l'), (40, 'xl'),\n", + " (10, 'x'), (9, 'ix'), (5, 'v'), (4, 'iv'), (1, 'i')\n", + " ]\n", + " res = \"\"\n", + " for v, s in vals:\n", + " while n >= v:\n", + " res += s\n", + " n -= v\n", + " return res\n", + "# =====================================================================\n", + "# Bulletin A\n", + "# =====================================================================\n", + "\n", + "roman_year = int_to_roman(year - 1987)\n", + "doy = product_date.timetuple().tm_yday\n", + "index = (doy - 1) // 7 + 1\n", + "\n", + "print(f\"Bulletin A Roman year: {roman_year}\")\n", + "print(f\"Initial weekly index: {index}\\n\")\n", + "\n", + "found = False\n", + "\n", + "while index > 0:\n", + " index_str = f\"{index:03d}\"\n", + " url = f\"https://datacenter.iers.org/data/6/bulletina-{roman_year}-{index_str}.txt\"\n", + " print(\"Trying bulletin:\", url)\n", + "\n", + " response = requests.get(url)\n", + "\n", + " if response.status_code == 200:\n", + " print(\"Bulletin found:\", index_str)\n", + " dest_file = os.path.join(WORKDIR, f\"bulletina-{roman_year}-{index_str}.txt\")\n", + " found = True\n", + " break\n", + "\n", + " index -= 1\n", + "\n", + "if not found:\n", + " raise RuntimeError(\"No Bulletin A available for current or previous weeks.\")\n", + "\n", + "with open(dest_file, \"wb\") as f:\n", + " f.write(response.content)\n", + "\n", + "print(\"Downloaded:\", dest_file)" + ] + }, + { + "cell_type": "markdown", + "id": "9e85608d", + "metadata": {}, + "source": [ + "# Sen2VM configuration" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "276592b5", + "metadata": {}, + "outputs": [], + "source": [ + "# === GENERATE CONFIG.JSON ===\n", + "\n", + "import os\n", + "import json\n", + "import re\n", + "import shutil\n", + "from numpy import double\n", + "\n", + "USERCONF_DIR = os.path.join(WORKDIR, \"UserConf\")\n", + "os.makedirs(USERCONF_DIR, exist_ok=True)\n", + "\n", + "print(\"UserConf directory:\", USERCONF_DIR)\n", + "\n", + "print(\"Geoid directory:\", PATH_GEOID)\n", + "# =====================================================\n", + "# 1. Extract mission from DATASTRIP\n", + "# =====================================================\n", + "\n", + "datastrip_dir = os.path.join(PATH_L1B_DATA, \"DATASTRIP\")\n", + "\n", + "if not os.path.isdir(datastrip_dir):\n", + " raise RuntimeError(f\"DATASTRIP directory not found: {datastrip_dir}\")\n", + "\n", + "datastrip_entries = os.listdir(datastrip_dir)\n", + "if not datastrip_entries:\n", + " raise RuntimeError(f\"No DATASTRIP found in: {datastrip_dir}\")\n", + "\n", + "datastrip_name = datastrip_entries[0]\n", + "\n", + "match = re.match(r\"(S2[A-C])_OPER_\", datastrip_name)\n", + "if not match:\n", + " raise RuntimeError(\"Cannot extract mission (S2A/S2B/S2C) from DATASTRIP name.\")\n", + "\n", + "mission = match.group(1)\n", + "# =====================================================\n", + "# 2. Docker paths inside /workspace\n", + "# =====================================================\n", + "\n", + "docker_l1b = \"/data/L1B\"\n", + "docker_dem = \"/data/DEM\"\n", + "docker_gipp = f\"/data/GIPP/{mission}\"\n", + "# =====================================================\n", + "# 3. Geoid management\n", + "# =====================================================\n", + "\n", + "# Detect .gtx inside PATH_GEOID\n", + "geoid_files = [f for f in os.listdir(PATH_GEOID) if f.lower().endswith(\".gtx\")]\n", + "if len(geoid_files) == 0:\n", + " raise RuntimeError(\"No .gtx geoid file found in PATH_GEOID.\")\n", + "\n", + "docker_geoid = f\"/data/GEOID/{geoid_files[0]}\"\n", + "# =====================================================\n", + "# 4. Locate IERS bulletin on host\n", + "# =====================================================\n", + "\n", + "iers_host = None\n", + "\n", + "for f in os.listdir(PATH_IERS):\n", + " if f.startswith(\"bulletin\"):\n", + " iers_host = os.path.join(PATH_IERS, f)\n", + " break\n", + "\n", + "if iers_host is None:\n", + " raise RuntimeError(\"IERS bulletin not found inside PATH_IERS directory.\")\n", + "\n", + "docker_iers = f\"/data/IERS/{os.path.basename(iers_host)}\"\n", + "print(docker_iers)\n", + "# =====================================================\n", + "# 5. Build config dictionary\n", + "# =====================================================\n", + "\n", + "config = {\n", + " \"l1b_product\": docker_l1b,\n", + " \"gipp_folder\": docker_gipp,\n", + " \"auto_gipp_selection\": True,\n", + " \"grids_overwriting\": True,\n", + " \"dem\": docker_dem,\n", + " \"geoid\": docker_geoid,\n", + " \"iers\": docker_iers,\n", + " \"operation\": \"inverse\",\n", + " \"deactivate_available_refining\": False,\n", + " \"steps\": {\n", + " \"10m_bands\": STEPS[\"10m_bands\"],\n", + " \"20m_bands\": STEPS[\"20m_bands\"],\n", + " \"60m_bands\": STEPS[\"60m_bands\"]\n", + " },\n", + " \"export_alt\": True\n", + "}\n", + "\n", + "config[\"inverse_location_additional_info\"] = {\n", + " \"ul_x\": double(LOCATION[\"ul_x\"]),\n", + " \"ul_y\": double(LOCATION[\"ul_y\"]),\n", + " \"lr_x\": double(LOCATION[\"lr_x\"]),\n", + " \"lr_y\": double(LOCATION[\"lr_y\"]),\n", + " \"referential\": f\"EPSG:{UTM_EPSG}\",\n", + " \"output_folder\": \"/workspace/output/INVERSE/INVERSE_GRID\"\n", + "}\n", + "# =====================================================\n", + "# Save config.json\n", + "# =====================================================\n", + "\n", + "config_path = os.path.join(USERCONF_DIR, \"config.json\")\n", + "\n", + "with open(config_path, \"w\") as f:\n", + " json.dump(config, f, indent=4)\n", + "\n", + "print(\"Configuration file generated:\")\n", + "print(config_path)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "23b1da25", + "metadata": {}, + "outputs": [], + "source": [ + "# === GENERATE PARAMS.JSON ===\n", + "\n", + "import os\n", + "import json\n", + "import re\n", + "\n", + "USERCONF_DIR = os.path.join(WORKDIR, \"UserConf\")\n", + "os.makedirs(USERCONF_DIR, exist_ok=True)\n", + "\n", + "print(\"UserConf directory:\", USERCONF_DIR)\n", + "\n", + "# =====================================================\n", + "# Locate GRANULE folders\n", + "# =====================================================\n", + "\n", + "GR_TARGET_DIR = os.path.join(PATH_L1B_DATA, \"GRANULE\")\n", + "\n", + "if not os.path.exists(GR_TARGET_DIR):\n", + " raise RuntimeError(\"GRANULE directory not found inside L1B SAFE.\")\n", + "\n", + "granule_folders = [\n", + " os.path.join(GR_TARGET_DIR, d)\n", + " for d in os.listdir(GR_TARGET_DIR)\n", + " if os.path.isdir(os.path.join(GR_TARGET_DIR, d))\n", + "]\n", + "\n", + "print(\"Found\", len(granule_folders), \"granule folders.\")\n", + "# =====================================================\n", + "# Extract detectors and bands from JP2\n", + "# =====================================================\n", + "\n", + "detectors = set()\n", + "bands = set()\n", + "\n", + "pattern = r\"_D(\\d+)_B(\\d{1,2}[A]?)\\.jp2$\"\n", + "\n", + "for granule in granule_folders:\n", + " img_data_dir = os.path.join(granule, \"IMG_DATA\")\n", + "\n", + " if not os.path.isdir(img_data_dir):\n", + " continue\n", + "\n", + " for fname in os.listdir(img_data_dir):\n", + " match = re.search(pattern, fname)\n", + " if match:\n", + " detectors.add(match.group(1))\n", + " bands.add(f\"B{match.group(2)}\")\n", + "\n", + "detectors = sorted(detectors)\n", + "bands = sorted(bands)\n", + "\n", + "print(\"Detected detectors:\", detectors)\n", + "print(\"Detected bands:\", bands)\n", + "# =====================================================\n", + "# Write params.json\n", + "# =====================================================\n", + "\n", + "# Validate keep_detectors: must be a non-empty list (user requirement)\n", + "if not isinstance(ORTHO_SETTINGS.get(\"keep_detectors\"), list) or len(ORTHO_SETTINGS[\"keep_detectors\"]) == 0:\n", + " raise RuntimeError(\"ORTHO_SETTINGS['keep_detectors'] must be a non-empty list of detector ids (e.g. ['01','02']).\")\n", + "\n", + "# Filter detectors to only include those selected by the user\n", + "keep_detectors_list = ORTHO_SETTINGS[\"keep_detectors\"]\n", + "selected_detectors = [d for d in keep_detectors_list if d in detectors]\n", + "\n", + "# Validate that all requested detectors exist\n", + "missing_detectors = [d for d in keep_detectors_list if d not in detectors]\n", + "if missing_detectors:\n", + " raise RuntimeError(f\"Some requested detectors are not available in the product: {missing_detectors}. Available detectors: {detectors}\")\n", + "\n", + "# Only include selected detectors and bands in params.json\n", + "params = {\n", + " \"detectors\": sorted(selected_detectors),\n", + " \"bands\": sorted(ORTHO_SETTINGS[\"keep_bands\"])\n", + "}\n", + "\n", + "params_path = os.path.join(USERCONF_DIR, \"params.json\")\n", + "\n", + "with open(params_path, \"w\") as f:\n", + " json.dump(params, f, indent=4)\n", + "\n", + "print(\"params.json written to:\", params_path)\n", + "print(f\" - Detectors: {params['detectors']}\")\n", + "print(f\" - Bands: {params['bands']}\")" + ] + }, + { + "cell_type": "markdown", + "id": "ec6f67fe", + "metadata": {}, + "source": [ + "# Sen2VM run" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "572bd72a", + "metadata": {}, + "outputs": [], + "source": [ + "# === RUN SEN2VM (Docker: BUILD + RUN + CLEAN) ===\n", + "\n", + "import os\n", + "import subprocess\n", + "\n", + "# Notebook location (NOT relative to CWD)\n", + "notebook_dir = os.getcwd()\n", + "\n", + "dockerfile_dir = os.path.abspath(os.path.join(\n", + " notebook_dir,\n", + " \"..\", \"..\"\n", + "))\n", + "\n", + "config_inside = \"/workspace/UserConf/config.json\"\n", + "params_inside = \"/workspace/UserConf/params.json\"\n", + "\n", + "os.makedirs(\n", + " os.path.join(WORKDIR, \"output\", \"INVERSE\", \"INVERSE_GRID\"),\n", + " exist_ok=True\n", + ")\n", + "# =====================================================\n", + "# 1. BUILD DOCKER IMAGE\n", + "# =====================================================\n", + "\n", + "print(f\"Building Docker image 'sen2vm' from: {dockerfile_dir}\")\n", + "cmd_build = [\n", + " \"docker\", \"build\",\n", + " \"-t\", \"sen2vm\",\n", + " dockerfile_dir\n", + "]\n", + "\n", + "print(\"Command:\", \" \".join(cmd_build), \"\\n\")\n", + "subprocess.run(cmd_build, check=True)\n", + "print(\"Docker image built successfully.\\n\")\n", + "# =====================================================\n", + "# 2. RUN SEN2VM CONTAINER\n", + "# =====================================================\n", + "\n", + "cmd_run = [\n", + " \"docker\", \"run\",\n", + " \"--rm\",\n", + " \"-v\", f\"{PATH_L1B_DATA}:/data/L1B\",\n", + " \"-v\", f\"{PATH_DEM}:/data/DEM\",\n", + " \"-v\", f\"{PATH_GIPP}:/data/GIPP\",\n", + " \"-v\", f\"{PATH_GEOID}:/data/GEOID\",\n", + " \"-v\", f\"{PATH_IERS}:/data/IERS\",\n", + " \"-v\", f\"{WORKDIR}:/workspace\",\n", + " \"sen2vm\",\n", + " \"-c\", config_inside,\n", + " \"-p\", params_inside\n", + "]\n", + "\n", + "print(\"Running Docker container...\\n\")\n", + "print(\"Command:\", \" \".join(cmd_run), \"\\n\")\n", + "subprocess.run(cmd_run, check=True)\n", + "print(\"\\nDocker execution complete.\\n\")\n", + "# =====================================================\n", + "# 3. REMOVE DOCKER IMAGE\n", + "# =====================================================\n", + "if REMOVE_DOCKER_IMAGE:\n", + " print(\"Removing Docker image 'sen2vm'...\")\n", + " subprocess.run([\"docker\", \"rmi\", \"-f\", \"sen2vm\"], check=True)\n", + " print(\"Docker images removed.\\n\")\n", + "else:\n", + " print(\"Docker images kept.\\n\")" + ] + }, + { + "cell_type": "markdown", + "id": "e54044d2", + "metadata": {}, + "source": [ + " # Generate Orthorectification images" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "61ebba54-43f0-4d39-9589-40c87609f70e", + "metadata": {}, + "outputs": [], + "source": [ + "# =====================================================\n", + "# INVERSE\n", + "# =====================================================\n", + "import os\n", + "import subprocess\n", + "import glob\n", + "import json\n", + "import re\n", + "\n", + "# =====================================================\n", + "# SAFETY CHECKS\n", + "# =====================================================\n", + "assert os.path.exists(PATH_L1B_DATA), \"L1B path missing\"\n", + "os.makedirs(OUTPUT_FOLDER, exist_ok=True)\n", + "assert os.path.exists(OUTPUT_FOLDER), \"Output folder missing\"\n", + "\n", + "# =====================================================\n", + "# OUTPUT FOLDERS\n", + "# =====================================================\n", + "RAW_DIR = os.path.join(OUTPUT_FOLDER, \"raw\")\n", + "OTB_DIR = os.path.join(OUTPUT_FOLDER, \"otb_no_georef\")\n", + "GEOREF_DIR = os.path.join(OUTPUT_FOLDER, \"output_georef\")\n", + "MOSAIC_DIR = os.path.join(OUTPUT_FOLDER, \"mosaic\")\n", + "os.makedirs(RAW_DIR, exist_ok=True)\n", + "os.makedirs(OTB_DIR, exist_ok=True)\n", + "os.makedirs(GEOREF_DIR, exist_ok=True)\n", + "os.makedirs(MOSAIC_DIR, exist_ok=True)\n", + "\n", + "# =====================================================\n", + "# Locate product name\n", + "# =====================================================\n", + "product = os.path.basename(os.path.normpath(PATH_L1B_DATA))\n", + "print(\"Product:\", product)\n", + "\n", + "# =====================================================\n", + "# Locate XML\n", + "# =====================================================\n", + "xml_list = glob.glob(\n", + " os.path.join(\n", + " PATH_L1B_DATA,\n", + " \"S2*_MTD_*.xml\"\n", + " )\n", + ")\n", + "\n", + "if len(xml_list) == 0:\n", + " raise RuntimeError(\"No DATASTRIP MTD XML found\")\n", + "\n", + "xml_path = xml_list[0]\n", + "xml_name = os.path.basename(xml_path)\n", + "print(\"Using XML:\", xml_path)\n", + "\n", + "# =====================================================\n", + "# Read params.json\n", + "# =====================================================\n", + "params_path = os.path.join(WORKDIR, \"UserConf\", \"params.json\")\n", + "if not os.path.exists(params_path):\n", + " raise RuntimeError(f\"params.json not found at {params_path}\")\n", + "\n", + "with open(params_path, \"r\") as f:\n", + " params = json.load(f)\n", + "\n", + "selected_bands = params.get(\"bands\", [])\n", + "selected_detectors = params.get(\"detectors\", [])\n", + "print(\"Bands:\", selected_bands)\n", + "print(\"Detectors:\", selected_detectors)\n", + "\n", + "# =====================================================\n", + "# Build GDAL Docker\n", + "# =====================================================\n", + "notebook_dir = os.path.dirname(os.getcwd())\n", + "dockerfile_dir = os.path.abspath(os.path.join(\n", + " notebook_dir,\n", + " \"src\",\n", + " \"gdal-latest\"\n", + "))\n", + "print(\"\\n=== BUILDING GDAL CONTAINER ===\\n\")\n", + "\n", + "cmd_build = [\n", + " \"docker\", \"build\",\n", + " \"--platform=linux/amd64\",\n", + " \"-t\", \"gdal-latest\",\n", + " dockerfile_dir\n", + "]\n", + "\n", + "print(\"Command:\")\n", + "print(\" \".join(cmd_build))\n", + "subprocess.run(cmd_build, check=True)\n", + "print(\"\\nGDAL image built successfully.\\n\")\n", + "\n", + "# =====================================================\n", + "# Locate inverse grids\n", + "# =====================================================\n", + "INV_FOLDER = os.path.join(OUTPUT_FOLDER, \"INVERSE_GRID\")\n", + "if not os.path.exists(INV_FOLDER):\n", + " raise RuntimeError(f\"Inverse folder not found: {INV_FOLDER}\")\n", + " \n", + "inv_grid_list = glob.glob(\n", + " os.path.join(INV_FOLDER, \"*.tif\")\n", + ")\n", + "if len(inv_grid_list) == 0:\n", + " raise RuntimeError(\"No inverse grids found\")\n", + "print(f\"\\nFound {len(inv_grid_list)} inverse grids:\\n\")\n", + "\n", + "for g in inv_grid_list:\n", + " print(\" \", os.path.basename(g))\n", + "\n", + "# =====================================================\n", + "# Process all inverse grids\n", + "# =====================================================\n", + "for inv_grid_path in inv_grid_list:\n", + " test_grid = os.path.basename(inv_grid_path)\n", + " print(\"\\n=================================================\")\n", + " print(\"Processing:\", test_grid)\n", + " print(\"=================================================\")\n", + "\n", + " # =================================================\n", + " # Parse detector / band\n", + " # =================================================\n", + " match = re.search(r\"_D(\\d+)_B(\\d{1,2}[A]?)\", test_grid)\n", + " if not match:\n", + " print(\"Could not parse detector/band\")\n", + " continue\n", + "\n", + " detector = match.group(1)\n", + " band = f\"B{match.group(2)}\"\n", + "\n", + " print(\"Detector:\", detector)\n", + " print(\"Band:\", band)\n", + "\n", + " # =================================================\n", + " # Build subdataset dynamically\n", + " # =================================================\n", + " subdataset = test_grid.replace(\"INV_L1B\", \"GEO_L1B\")\n", + " subdataset = subdataset.replace(\".tif\", \"\")\n", + " print(\"Subdataset:\", subdataset)\n", + " \n", + " # =================================================\n", + " # Determine resolution\n", + " # =================================================\n", + " if band in [\"B02\", \"B03\", \"B04\", \"B08\"]:\n", + " resolution = 10\n", + " elif band in [\"B05\", \"B06\", \"B07\", \"B8A\", \"B11\", \"B12\"]:\n", + " resolution = 20\n", + " elif band in [\"B01\", \"B09\", \"B10\"]:\n", + " resolution = 60\n", + " else:\n", + " resolution = 10\n", + " \n", + " print(\"Resolution:\", resolution)\n", + " \n", + " # =================================================\n", + " # Compute output size\n", + " # =================================================\n", + " width = int(\n", + " (LOCATION[\"lr_x\"] - LOCATION[\"ul_x\"]) / resolution\n", + " )\n", + " height = int(\n", + " (LOCATION[\"ul_y\"] - LOCATION[\"lr_y\"]) / resolution\n", + " )\n", + " print(\"Width :\", width)\n", + " print(\"Height:\", height)\n", + "\n", + " # =================================================\n", + " # File paths\n", + " # =================================================\n", + " raw_name = f\"raw_D{detector}_{band}.tif\"\n", + " ortho_name = f\"ortho_D{detector}_{band}.tif\"\n", + " georef_name = f\"ortho_D{detector}_{band}_georef.tif\"\n", + " \n", + " # =================================================\n", + " # Extract raw detector image\n", + " # =================================================\n", + " cmd_extract = [\n", + " \"docker\", \"run\",\n", + " \"--rm\",\n", + " \"-v\", f\"{PATH_L1B_DATA}:/data/L1B\",\n", + " \"-v\", f\"{OUTPUT_FOLDER}:/output\",\n", + " \"gdal-latest\",\n", + " \"-c\",\n", + " f'''\n", + " gdal_translate \\\n", + " \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/{xml_name}:{subdataset}\" \\\n", + " \"/output/raw/{raw_name}\"\n", + " '''\n", + " ]\n", + " print(\"\\n=== EXTRACTION ===\\n\")\n", + " print(\" \".join(cmd_extract))\n", + "\n", + " subprocess.run(cmd_extract, check=True)\n", + " \n", + " # Half-pixel correction (OTB bug fix)\n", + " corrected_ulx = LOCATION[\"ul_x\"] + resolution / 2\n", + " corrected_uly = LOCATION[\"ul_y\"] - resolution / 2\n", + "\n", + " # =================================================\n", + " # OTB resampling\n", + " # =================================================\n", + " cmd_otb = [\n", + " \"docker\", \"run\",\n", + " \"--rm\",\n", + " \"-v\", f\"{OUTPUT_FOLDER}:/output\",\n", + " \"orfeotoolbox/otb:9.0.0\",\n", + " \"otbcli_GridBasedImageResampling\",\n", + " \"-io.in\",\n", + " f\"/output/raw/{raw_name}\",\n", + " \"-io.out\",\n", + " f\"/output/otb_no_georef/{ortho_name}\",\n", + " \"-grid.in\",\n", + " f\"/output/INVERSE_GRID/{test_grid}\",\n", + " \"-grid.type\",\n", + " \"loc\",\n", + " \"-out.ulx\",\n", + " str(corrected_ulx),\n", + " \"-out.uly\",\n", + " str(corrected_uly),\n", + " \"-out.spacingx\",\n", + " str(resolution),\n", + " \"-out.spacingy\",\n", + " str(-resolution),\n", + " \"-out.sizex\",\n", + " str(width),\n", + " \"-out.sizey\",\n", + " str(height)\n", + " ]\n", + "\n", + " print(\"\\n=== OTB RESAMPLING ===\\n\")\n", + " print(\" \".join(cmd_otb))\n", + "\n", + " try:\n", + " subprocess.run(cmd_otb, check=True)\n", + " print(\"OTB success\")\n", + " \n", + " except subprocess.CalledProcessError:\n", + " print(\"OTB failed (outside grid) → skipping\")\n", + " continue\n", + "\n", + " # ==================a===============================\n", + " # Add georeferencing to correct otb missing one\n", + " # =================================================\n", + " cmd_georef = [\n", + " \"docker\", \"run\",\n", + " \"--rm\",\n", + " \"-v\", f\"{OUTPUT_FOLDER}:/output\",\n", + " \"gdal-latest\",\n", + " \"-c\",\n", + " f'''\n", + " gdal_translate \\\n", + " -a_srs EPSG:{UTM_EPSG} \\\n", + " /output/otb_no_georef/{ortho_name} \\\n", + " /output/output_georef/{georef_name}\n", + " '''\n", + " ]\n", + "\n", + " print(\"\\n=== ADD GEOREF ===\\n\")\n", + " print(\" \".join(cmd_georef))\n", + " subprocess.run(cmd_georef, check=True)\n", + " print(\"\\nFinished:\", georef_name)\n", + "\n", + "# =====================================================\n", + "# Mosaic\n", + "# =====================================================\n", + "print(\"\\n=== MOSAIC CREATION ===\\n\")\n", + "bands = set()\n", + "for f in glob.glob(os.path.join(GEOREF_DIR, \"*.tif\")):\n", + " match = re.search(r\"_B(\\d{2}[A]?)\", f)\n", + " if match:\n", + " bands.add(f\"B{match.group(1)}\")\n", + "print(\"Bands detected:\", bands)\n", + "\n", + "for band in bands:\n", + "\n", + " print(\"\\n----------------------------------------\")\n", + " print(\"Creating mosaic for band:\", band)\n", + " print(\"----------------------------------------\")\n", + " # fichiers correspondant à la bande\n", + " input_files = glob.glob(\n", + " os.path.join(GEOREF_DIR, f\"*_{band}_georef.tif\")\n", + " )\n", + " if len(input_files) == 0:\n", + " print(\"No ortho images found for band\", band)\n", + " continue\n", + " input_files = sorted(input_files)\n", + " \n", + " output_path = os.path.join(\n", + " MOSAIC_DIR,\n", + " f\"ORTHO_mosaic_{band}.tif\"\n", + " )\n", + " print(\"Found\", len(input_files), \"files\")\n", + " for f in input_files:\n", + " print(\" \", os.path.basename(f))\n", + " \n", + " gdal_cmd = \"gdal_merge.py \" \\\n", + " f\"-o /output/mosaic/ORTHO_mosaic_{band}.tif \" \\\n", + " \"-of GTiff \" \\\n", + " \"-co COMPRESS=LZW \" \\\n", + " \"-co TILED=YES \" \\\n", + " \"-ot UInt16 \" \\\n", + " \"-n 0 -a_nodata 0 \"\n", + "\n", + " for f in input_files:\n", + " fname = os.path.basename(f)\n", + " gdal_cmd += f\"/output/output_georef/{fname} \"\n", + "\n", + " cmd_mosaic = [\n", + " \"docker\", \"run\",\n", + " \"--rm\",\n", + " \"-v\", f\"{OUTPUT_FOLDER}:/output\",\n", + " \"gdal-latest\",\n", + " \"-c\",\n", + " gdal_cmd\n", + " ]\n", + "\n", + " print(\"\\nRunning mosaic:\\n\", gdal_cmd)\n", + " subprocess.run(cmd_mosaic, check=True)\n", + " print(\"Mosaic written →\", output_path)\n", + "\n", + "# =====================================================\n", + "# Cleanup docker image\n", + "# =====================================================\n", + "if REMOVE_DOCKER_IMAGE:\n", + " print(\"Removing gdal-latest image...\\n\")\n", + " subprocess.run([\"docker\", \"rmi\", \"-f\", \"gdal-latest\"], check=True)\n", + " print(\"GDAL image removed.\\n\")\n", + "else:\n", + " print(\"Docker images kept (faster next run, ~4 GB disk usage).\\n\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b281ab9e-0afd-4ef9-8ca0-0f4d368c7cb3", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.11" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From c3b978137b8b5091e4941594c3bb454d7ced4ffb Mon Sep 17 00:00:00 2001 From: Paul Castillo Date: Fri, 26 Jun 2026 12:24:02 +0000 Subject: [PATCH 04/13] Switch to OTB for direct grid --- .../src/notebook-direct-grid-otb.ipynb | 1411 +++++++++++++++++ .../src/notebook-direct-grid.ipynb | 435 ++++- .../src/notebook-inverse-grid.ipynb | 845 +++++++++- sen2vm-notebook/src/requirements.txt | 2 + 4 files changed, 2652 insertions(+), 41 deletions(-) create mode 100644 sen2vm-notebook/src/notebook-direct-grid-otb.ipynb diff --git a/sen2vm-notebook/src/notebook-direct-grid-otb.ipynb b/sen2vm-notebook/src/notebook-direct-grid-otb.ipynb new file mode 100644 index 00000000..a0df851b --- /dev/null +++ b/sen2vm-notebook/src/notebook-direct-grid-otb.ipynb @@ -0,0 +1,1411 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "8e5ed8d8-c718-4f80-a220-464bbc67c748", + "metadata": {}, + "source": [ + "# === USER CONFIGURATION ===" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "2b816cd9-5254-452b-bced-2943eb6b7aec", + "metadata": {}, + "outputs": [], + "source": [ + "# # === USER CONFIGURATION ===\n", + "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", + "# /!\\/!\\/!\\ CAREFUL, please read the README_Notebooks.md file before\n", + "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", + "\n", + "WORKDIR = \"/home/pcastillo/sen2vm/WORKDIR\" # Working directory for sen2vm processing\n", + "\n", + "# Path to downloaded product\n", + "PATH_L1B_DATA = \"/home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE\"\n", + "\n", + "# Path to GIPP directory\n", + "PATH_GIPP = \"/home/pcastillo/sen2vm/WORKDIR/GIPP\"\n", + "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", + "# /!\\/!\\/!\\ If you do not have your own GIPP folder, you may use the inputs-download-notebook to download it, then you may indicate the path were you \n", + "# /!\\/!\\/!\\ downloaded it here in PATH_GIPP\n", + "# /!\\/!\\/!\\ If you have your own GIPP folder, please note that this current notebook will search for a subfolder with mission S2[A/B/C] inside the GIPP folder\n", + "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", + "\n", + "# Path to DEM directory \n", + "PATH_DEM = \"/home/pcastillo/sen2vm/WORKDIR/DEM\"\n", + "\n", + "# Path to GEOID directory\n", + "PATH_GEOID = \"/home/pcastillo/sen2vm/WORKDIR/GEOID\"\n", + "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", + "# /!\\/!\\/!\\ If you do not have your own GEOID folder, you may use the inputs-download-notebook to download it, then you may indicate the path were you\n", + "# /!\\/!\\/!\\ downloaded it here in \n", + "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", + "\n", + "# Path to IERS file\n", + "PATH_IERS = \"/home/pcastillo/sen2vm/WORKDIR\"\n", + "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", + "# /!\\/!\\/!\\ If you do not have your own IERS, you may let this path empy (i.e. \"\") and execute the cell number 2 named #IERS Download\n", + "# /!\\/!\\/!\\ In this case, the IERS will be downloaded in the WORKDIR\n", + "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", + "\n", + "# The output folder is put in the WORKDIR\n", + "OUTPUT_FOLDER = WORKDIR + \"/output/DIRECT_otb\"\n", + "\n", + "# === SEN2VM OPTIONS ===\n", + "UTM_EPSG = 32628 # UTM zone EPSG code for the ROI\n", + "LOCATION = {\n", + " \"ul_x\": 283910,\n", + " \"ul_y\": 3641660,\n", + " \"lr_x\": 354280,\n", + " \"lr_y\": 3608316.0\n", + "}\n", + "\n", + "# Grid step in pixels for sen2vm grid generation \n", + "# These values represent the grid step in pixels, typically DEM resolution / 2\n", + "# For S2 with DEM90, this gives approximately: 45m/10m=4.5, 45m/20m=2.25, 45m/60m≈1\n", + "STEPS = {\n", + " \"10m_bands\": 4.5, # Grid step: ~DEM90/2 = 45m/10m = 4.5 pixels (one point every 4.5 pixels at 10m)\n", + " \"20m_bands\": 2.25, # Grid step: ~DEM90/2 = 45m/20m = 2.25 pixels (one point every 2.25 pixels at 20m)\n", + " \"60m_bands\": 1.0 # Grid step: ~DEM90/2 = 45m/60m ≈ 1 pixel (one point every 1 pixel at 60m, or 2 is also fine)\n", + "}\n", + "\n", + "# === GDAL ORTHO OPTIONS ===\n", + "\n", + "ORTHO_SETTINGS = {\n", + " \"keep_bands\": [\"B02\"], # list of bands to keep for orthorectification\n", + " \"keep_detectors\": [\"07\",\"08\",\"09\",\"10\",\"11\"] # list of the detectors to keep \n", + "}\n", + "\n", + "# === Docker Options ===\n", + "# Building Docker images may take several minutes.\n", + "# By setting REMOVE_DOCKER_IMAGE = False, the images are kept,\n", + "# which significantly speeds up subsequent executions.\n", + "#\n", + "# However, Docker images use disk space (~4 GB in this case).\n", + "#\n", + "# Docker images can be manually removed using:\n", + "# docker images\n", + "# docker rmi \n", + "#\n", + "REMOVE_DOCKER_IMAGE = False # True = remove Docker images after execution" + ] + }, + { + "cell_type": "markdown", + "id": "63f616a3", + "metadata": {}, + "source": [ + "# IERS Download" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "8ec4d6f6", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Stopping because PATH_IERS is not empty\n" + ] + }, + { + "ename": "SystemExit", + "evalue": "0", + "output_type": "error", + "traceback": [ + "An exception has occurred, use %tb to see the full traceback.\n", + "\u001b[31mSystemExit\u001b[39m\u001b[31m:\u001b[39m 0\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/pcastillo/sen2vm/sen2vm-core/sen2vm-notebook/src/.venv/lib/python3.13/site-packages/IPython/core/interactiveshell.py:3709: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.\n", + " warn(\"To exit: use 'exit', 'quit', or Ctrl-D.\", stacklevel=1)\n" + ] + } + ], + "source": [ + "# === DOWNLOAD IERS ===\n", + "import os\n", + "import re\n", + "import requests\n", + "import sys\n", + "from datetime import datetime\n", + "\n", + "if len(PATH_IERS) != 0: #Safety in case the PATH_IERS isn't empty\n", + " print(\"Stopping because PATH_IERS is not empty\")\n", + " sys.exit(0)\n", + "\n", + "if not os.path.exists(WORKDIR):\n", + " raise RuntimeError(f\"WORKDIR directory not found: {WORKDIR}\")\n", + "\n", + "print(\"Bulletin output directory:\", WORKDIR)\n", + "\n", + "PATH_IERS = WORKDIR # then our file will be there\n", + "# =====================================================================\n", + "# REMOVE EXISTING IERS BULLETINS\n", + "# =====================================================================\n", + "\n", + "for f in os.listdir(WORKDIR):\n", + " if f.startswith(\"bulletina-\") and f.endswith(\".txt\"):\n", + " os.remove(os.path.join(WORKDIR, f))\n", + " print(\"Removed old bulletin A:\", f)\n", + "\n", + " if f.startswith(\"bulletinb-\") and f.endswith(\".txt\"):\n", + " os.remove(os.path.join(WORKDIR, f))\n", + " print(\"Removed old bulletin B:\", f)\n", + "\n", + "print(\"Cleanup of old bulletins complete.\\n\")\n", + "# =====================================================================\n", + "# EXTRACT PRODUCT DATE (FROM DATASTRIP)\n", + "# =====================================================================\n", + "\n", + "datastrip_dir = os.path.join(PATH_L1B_DATA, \"DATASTRIP\")\n", + "\n", + "if not os.path.isdir(datastrip_dir):\n", + " raise RuntimeError(f\"DATASTRIP directory not found: {datastrip_dir}\")\n", + "\n", + "datastrip_entries = os.listdir(datastrip_dir)\n", + "if not datastrip_entries:\n", + " raise RuntimeError(f\"No DATASTRIP found in: {datastrip_dir}\")\n", + "\n", + "# Take the first DATASTRIP product\n", + "datastrip_name = datastrip_entries[0]\n", + "\n", + "match = re.search(r\"_S(\\d{8})T\\d{6}_\", datastrip_name)\n", + "if not match:\n", + " raise RuntimeError(\"Could not extract product date from DATASTRIP name.\")\n", + "\n", + "product_date_str = match.group(1)\n", + "\n", + "year = int(product_date_str[:4])\n", + "month = int(product_date_str[4:6])\n", + "day = int(product_date_str[6:8])\n", + "\n", + "product_date = datetime(year, month, day)\n", + "\n", + "print(\"Product date extracted from DATASTRIP:\", product_date.date(), \"\\n\")\n", + "# =====================================================================\n", + "# Roman conversion \n", + "# =====================================================================\n", + "\n", + "def int_to_roman(n):\n", + " vals = [\n", + " (1000, 'm'), (900, 'cm'), (500, 'd'), (400, 'cd'),\n", + " (100, 'c'), (90, 'xc'), (50, 'l'), (40, 'xl'),\n", + " (10, 'x'), (9, 'ix'), (5, 'v'), (4, 'iv'), (1, 'i')\n", + " ]\n", + " res = \"\"\n", + " for v, s in vals:\n", + " while n >= v:\n", + " res += s\n", + " n -= v\n", + " return res\n", + "# =====================================================================\n", + "# Bulletin A\n", + "# =====================================================================\n", + "\n", + "roman_year = int_to_roman(year - 1987)\n", + "doy = product_date.timetuple().tm_yday\n", + "index = (doy - 1) // 7 + 1\n", + "\n", + "print(f\"Bulletin A Roman year: {roman_year}\")\n", + "print(f\"Initial weekly index: {index}\\n\")\n", + "\n", + "found = False\n", + "\n", + "while index > 0:\n", + " index_str = f\"{index:03d}\"\n", + " url = f\"https://datacenter.iers.org/data/6/bulletina-{roman_year}-{index_str}.txt\"\n", + " print(\"Trying bulletin:\", url)\n", + "\n", + " response = requests.get(url)\n", + "\n", + " if response.status_code == 200:\n", + " print(\"Bulletin found:\", index_str)\n", + " dest_file = os.path.join(WORKDIR, f\"bulletina-{roman_year}-{index_str}.txt\")\n", + " found = True\n", + " break\n", + "\n", + " index -= 1\n", + "\n", + "if not found:\n", + " raise RuntimeError(\"No Bulletin A available for current or previous weeks.\")\n", + "\n", + "with open(dest_file, \"wb\") as f:\n", + " f.write(response.content)\n", + "\n", + "print(\"Downloaded:\", dest_file)" + ] + }, + { + "cell_type": "markdown", + "id": "9e85608d", + "metadata": {}, + "source": [ + "# Sen2VM configuration" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "276592b5", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "UserConf directory: /home/pcastillo/sen2vm/WORKDIR/UserConf\n", + "Geoid directory: /home/pcastillo/sen2vm/WORKDIR/GEOID\n", + "/data/IERS/bulletina-xxxvii-042.txt\n", + "Configuration file generated:\n", + "/home/pcastillo/sen2vm/WORKDIR/UserConf/config.json\n" + ] + } + ], + "source": [ + "# === GENERATE CONFIG.JSON ===\n", + "\n", + "import os\n", + "import json\n", + "import re\n", + "import shutil\n", + "from numpy import double\n", + "\n", + "USERCONF_DIR = os.path.join(WORKDIR, \"UserConf\")\n", + "os.makedirs(USERCONF_DIR, exist_ok=True)\n", + "\n", + "print(\"UserConf directory:\", USERCONF_DIR)\n", + "print(\"Geoid directory:\", PATH_GEOID)\n", + "\n", + "# =====================================================\n", + "# 1. Extract mission from DATASTRIP\n", + "# =====================================================\n", + "\n", + "datastrip_dir = os.path.join(PATH_L1B_DATA, \"DATASTRIP\")\n", + "\n", + "if not os.path.isdir(datastrip_dir):\n", + " raise RuntimeError(f\"DATASTRIP directory not found: {datastrip_dir}\")\n", + "\n", + "datastrip_entries = os.listdir(datastrip_dir)\n", + "if not datastrip_entries:\n", + " raise RuntimeError(f\"No DATASTRIP found in: {datastrip_dir}\")\n", + "\n", + "datastrip_name = datastrip_entries[0]\n", + "\n", + "match = re.match(r\"(S2[A-C])_OPER_\", datastrip_name)\n", + "if not match:\n", + " raise RuntimeError(\"Cannot extract mission (S2A/S2B/S2C) from DATASTRIP name.\")\n", + "\n", + "mission = match.group(1)\n", + "# =====================================================\n", + "# 2. Docker paths inside /workspace\n", + "# =====================================================\n", + "\n", + "docker_l1b = \"/data/L1B\"\n", + "docker_dem = \"/data/DEM\"\n", + "docker_gipp = f\"/data/GIPP/{mission}\"\n", + "# =====================================================\n", + "# 3. Geoid management\n", + "# =====================================================\n", + "\n", + "# Detect .gtx inside PATH_GEOID\n", + "geoid_files = [f for f in os.listdir(PATH_GEOID) if f.lower().endswith(\".gtx\")]\n", + "if len(geoid_files) == 0:\n", + " raise RuntimeError(\"No .gtx geoid file found in PATH_GEOID.\")\n", + "\n", + "docker_geoid = f\"/data/GEOID/{geoid_files[0]}\"\n", + "# =====================================================\n", + "# 4. Locate IERS bulletin on host\n", + "# =====================================================\n", + "\n", + "iers_host = None\n", + "\n", + "for f in os.listdir(PATH_IERS):\n", + " if f.startswith(\"bulletin\"):\n", + " iers_host = os.path.join(PATH_IERS, f)\n", + " break\n", + "\n", + "if iers_host is None:\n", + " raise RuntimeError(\"IERS bulletin not found inside PATH_IERS directory.\")\n", + "\n", + "docker_iers = f\"/data/IERS/{os.path.basename(iers_host)}\"\n", + "print(docker_iers)\n", + "# =====================================================\n", + "# 5. Build config dictionary\n", + "# =====================================================\n", + "\n", + "config = {\n", + " \"l1b_product\": docker_l1b,\n", + " \"gipp_folder\": docker_gipp,\n", + " \"auto_gipp_selection\": True,\n", + " \"grids_overwriting\": True,\n", + " \"dem\": docker_dem,\n", + " \"geoid\": docker_geoid,\n", + " \"iers\": docker_iers,\n", + " \"operation\": \"direct\",\n", + " \"deactivate_available_refining\": False,\n", + " \"steps\": {\n", + " \"10m_bands\": STEPS[\"10m_bands\"],\n", + " \"20m_bands\": STEPS[\"20m_bands\"],\n", + " \"60m_bands\": STEPS[\"60m_bands\"]\n", + " },\n", + " \"export_alt\": True\n", + "}\n", + "# =====================================================\n", + "# Save config.json\n", + "# =====================================================\n", + "\n", + "config_path = os.path.join(USERCONF_DIR, \"config.json\")\n", + "\n", + "with open(config_path, \"w\") as f:\n", + " json.dump(config, f, indent=4)\n", + "\n", + "print(\"Configuration file generated:\")\n", + "print(config_path)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "23b1da25", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "UserConf directory: /home/pcastillo/sen2vm/WORKDIR/UserConf\n", + "Found 60 granule folders.\n", + "Detected detectors: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12']\n", + "Detected bands: ['B01', 'B02', 'B03', 'B04', 'B05', 'B06', 'B07', 'B08', 'B09', 'B10', 'B11', 'B12', 'B8A']\n", + "params.json written to: /home/pcastillo/sen2vm/WORKDIR/UserConf/params.json\n", + " - Detectors: ['07', '08', '09', '10', '11']\n", + " - Bands: ['B02']\n" + ] + } + ], + "source": [ + "# === GENERATE PARAMS.JSON ===\n", + "\n", + "import os\n", + "import json\n", + "import re\n", + "\n", + "USERCONF_DIR = os.path.join(WORKDIR, \"UserConf\")\n", + "os.makedirs(USERCONF_DIR, exist_ok=True)\n", + "\n", + "print(\"UserConf directory:\", USERCONF_DIR)\n", + "# =====================================================\n", + "# Locate GRANULE folders\n", + "# =====================================================\n", + "\n", + "GR_TARGET_DIR = os.path.join(PATH_L1B_DATA, \"GRANULE\")\n", + "\n", + "if not os.path.exists(GR_TARGET_DIR):\n", + " raise RuntimeError(\"GRANULE directory not found inside L1B SAFE.\")\n", + "\n", + "granule_folders = [\n", + " os.path.join(GR_TARGET_DIR, d)\n", + " for d in os.listdir(GR_TARGET_DIR)\n", + " if os.path.isdir(os.path.join(GR_TARGET_DIR, d))\n", + "]\n", + "\n", + "print(\"Found\", len(granule_folders), \"granule folders.\")\n", + "# =====================================================\n", + "# Extract detectors and bands from JP2\n", + "# =====================================================\n", + "\n", + "detectors = set()\n", + "bands = set()\n", + "\n", + "pattern = r\"_D(\\d+)_B(\\d{1,2}[A]?)\\.jp2$\"\n", + "\n", + "for granule in granule_folders:\n", + " img_data_dir = os.path.join(granule, \"IMG_DATA\")\n", + "\n", + " if not os.path.isdir(img_data_dir):\n", + " continue\n", + "\n", + " for fname in os.listdir(img_data_dir):\n", + " match = re.search(pattern, fname)\n", + " if match:\n", + " detectors.add(match.group(1))\n", + " bands.add(f\"B{match.group(2)}\")\n", + "\n", + "detectors = sorted(detectors)\n", + "bands = sorted(bands)\n", + "\n", + "print(\"Detected detectors:\", detectors)\n", + "print(\"Detected bands:\", bands)\n", + "# =====================================================\n", + "# Write params.json\n", + "# =====================================================\n", + "\n", + "# Validate keep_detectors: must be a non-empty list (user requirement)\n", + "if not isinstance(ORTHO_SETTINGS.get(\"keep_detectors\"), list) or len(ORTHO_SETTINGS[\"keep_detectors\"]) == 0:\n", + " raise RuntimeError(\"ORTHO_SETTINGS['keep_detectors'] must be a non-empty list of detector ids (e.g. ['01','02']).\")\n", + "\n", + "# Filter detectors to only include those selected by the user\n", + "keep_detectors_list = ORTHO_SETTINGS[\"keep_detectors\"]\n", + "selected_detectors = [d for d in keep_detectors_list if d in detectors]\n", + "\n", + "# Validate that all requested detectors exist\n", + "missing_detectors = [d for d in keep_detectors_list if d not in detectors]\n", + "if missing_detectors:\n", + " raise RuntimeError(f\"Some requested detectors are not available in the product: {missing_detectors}. Available detectors: {detectors}\")\n", + "\n", + "# Only include selected detectors and bands in params.json\n", + "params = {\n", + " \"detectors\": sorted(selected_detectors),\n", + " \"bands\": sorted(ORTHO_SETTINGS[\"keep_bands\"])\n", + "}\n", + "\n", + "params_path = os.path.join(USERCONF_DIR, \"params.json\")\n", + "\n", + "with open(params_path, \"w\") as f:\n", + " json.dump(params, f, indent=4)\n", + "\n", + "print(\"params.json written to:\", params_path)\n", + "print(f\" - Detectors: {params['detectors']}\")\n", + "print(f\" - Bands: {params['bands']}\")" + ] + }, + { + "cell_type": "markdown", + "id": "ec6f67fe", + "metadata": {}, + "source": [ + "# Sen2VM run" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "572bd72a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Building Docker image 'sen2vm' from: /home/pcastillo/sen2vm/sen2vm-core\n", + "Command: docker build -t sen2vm /home/pcastillo/sen2vm/sen2vm-core \n", + "\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "DEPRECATED: The legacy builder is deprecated and will be removed in a future release.\n", + " Install the buildx component to build images with BuildKit:\n", + " https://docs.docker.com/go/buildx/\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Sending build context to Docker daemon 1.718GB\n", + "Step 1/5 : FROM ghcr.io/sen2vm/sen2vm-build-env:latest AS launcher\n", + " ---> a5369801b500\n", + "Step 2/5 : ENV SEN2VM_VERSION=1.1.4\n", + " ---> Using cache\n", + " ---> 14de44fa18ab\n", + "Step 3/5 : WORKDIR /Sen2vm\n", + " ---> Using cache\n", + " ---> b4079a1b81e1\n", + "Step 4/5 : RUN curl -L -o sen2vm-core.jar https://github.com/sen2vm/sen2vm-core/releases/download/${SEN2VM_VERSION}/sen2vm-core-${SEN2VM_VERSION}.jar\n", + " ---> Using cache\n", + " ---> 01c51fc5d7d7\n", + "Step 5/5 : ENTRYPOINT [\"java\", \"-jar\",\"sen2vm-core.jar\"]\n", + " ---> Using cache\n", + " ---> 5be1977daa50\n", + "Successfully built 5be1977daa50\n", + "Successfully tagged sen2vm:latest\n", + "Docker image built successfully.\n", + "\n", + "Running Docker container...\n", + "\n", + "Command: docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/DEM:/data/DEM -v /home/pcastillo/sen2vm/WORKDIR/GIPP:/data/GIPP -v /home/pcastillo/sen2vm/WORKDIR/GEOID:/data/GEOID -v /home/pcastillo/sen2vm/WORKDIR:/data/IERS -v /home/pcastillo/sen2vm/WORKDIR:/workspace sen2vm -c /workspace/UserConf/config.json -p /workspace/UserConf/params.json \n", + "\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2026-06-26 09:03:26 [INFO ] Start Sen2VM \n", + "2026-06-26 09:03:27 [INFO ] Parsing file /workspace/UserConf/config.json \n", + "2026-06-26 09:03:27 [INFO ] Reading IERS file at: /data/IERS/bulletina-xxxvii-042.txt \n", + "2026-06-26 09:03:27 [INFO ] Parsing file /workspace/UserConf/params.json \n", + "2026-06-26 09:03:27 [INFO ] Detectors list: [DETECTOR_7, DETECTOR_8, DETECTOR_9, DETECTOR_10, DETECTOR_11] \n", + "2026-06-26 09:03:27 [INFO ] Bands list: [BAND_2] \n", + "2026-06-26 09:03:27 [INFO ] Find the following datastrip metadata file: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/S2B_OPER_MTD_L1B_DS_2BPS_20241019T153411_S20241019T120215.xml \n", + "2026-06-26 09:03:28 [INFO ] Initializing: copy of the Orekit-data: /Sen2vm/orekit-data \n", + "2026-06-26 09:03:28 [INFO ] Orekit-data: /Sen2vm/orekit-data \n", + "2026-06-26 09:03:35 [INFO ] Get through GIPP folder: /data/GIPP/S2B \n", + "2026-06-26 09:03:35 [INFO ] Read blind pixel file: /data/GIPP/S2B/S2B_OPER_GIP_BLINDP_MPC__20170221T000000_V20170101T000000_21000101T000000_B00.xml \n", + "2026-06-26 09:03:35 [INFO ] Read spacecraft model file: /data/GIPP/S2B/S2B_OPER_GIP_SPAMOD_MPC__20231122T110035_V20231123T000000_21000101T000000_B00.xml \n", + "2026-06-26 09:03:35 [INFO ] Read viewingDirection file: /data/GIPP/S2B/S2B_OPER_GIP_VIEDIR_MPC__20170512T114736_V20170322T000000_21000101T000000_B02.xml \n", + "2026-06-26 09:03:36 [INFO ] setAndProcessDataStrip listOfFiles/data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11 \n", + "2026-06-26 09:03:36 [INFO ] Datastrip S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11 \n", + "2026-06-26 09:03:36 [INFO ] \n", + "2026-06-26 09:03:36 [INFO ] Starting grids generation \n", + "2026-06-26 09:03:36 [INFO ] \n", + "2026-06-26 09:03:36 [INFO ] ############### \n", + "2026-06-26 09:03:36 [INFO ] ### BAND 2 ### \n", + "2026-06-26 09:03:36 [INFO ] ############### \n", + "2026-06-26 09:03:36 [INFO ] Grid resolution: 4.5 \n", + "2026-06-26 09:03:36 [INFO ] Band resolution: 10.0 \n", + "2026-06-26 09:03:36 [INFO ] \n", + "2026-06-26 09:03:36 [INFO ] ### DET 07 (BAND 2) ### \n", + "2026-06-26 09:03:36 [INFO ] Grid information: ConvOffset: (0.5, 0.5); Step: (4.5, 4.5); Start: (0, 0); Size: (11520, 2552) \n", + "2026-06-26 09:03:52 [INFO ] Granule: 4608 -> 6912 \n", + "2026-06-26 09:03:52 [INFO ] Grid start: 1024 (4606.25) -> Grid end: 1536 (6910.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 09:03:52 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120228_D07_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120228_D07_B02.tif \n", + "2026-06-26 09:03:52 [INFO ] Granule: 2304 -> 4608 \n", + "2026-06-26 09:03:52 [INFO ] Grid start: 512 (2302.25) -> Grid end: 1024 (4606.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 09:03:52 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120225_D07_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120225_D07_B02.tif \n", + "2026-06-26 09:03:52 [INFO ] Granule: 9216 -> 11520 \n", + "2026-06-26 09:03:52 [INFO ] Grid start: 2048 (9214.25) -> Grid end: 2560 (11518.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 09:03:52 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120235_D07_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120235_D07_B02.tif \n", + "2026-06-26 09:03:52 [INFO ] Granule: 0 -> 2304 \n", + "2026-06-26 09:03:52 [INFO ] Grid start: 0 (-1.75) -> Grid end: 512 (2302.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 09:03:52 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120221_D07_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120221_D07_B02.tif \n", + "2026-06-26 09:03:52 [INFO ] Granule: 6912 -> 9216 \n", + "2026-06-26 09:03:52 [INFO ] Grid start: 1536 (6910.25) -> Grid end: 2048 (9214.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 09:03:52 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120232_D07_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120232_D07_B02.tif \n", + "2026-06-26 09:03:52 [INFO ] VRT saved in: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02.vrt \n", + "2026-06-26 09:03:52 [INFO ] \n", + "2026-06-26 09:03:52 [INFO ] ### DET 08 (BAND 2) ### \n", + "2026-06-26 09:03:52 [INFO ] Grid information: ConvOffset: (0.5, 0.5); Step: (4.5, 4.5); Start: (0, 0); Size: (11520, 2552) \n", + "2026-06-26 09:04:07 [INFO ] Granule: 2304 -> 4608 \n", + "2026-06-26 09:04:07 [INFO ] Grid start: 512 (2302.25) -> Grid end: 1024 (4606.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 09:04:08 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120221_D08_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120221_D08_B02.tif \n", + "2026-06-26 09:04:08 [INFO ] Granule: 4608 -> 6912 \n", + "2026-06-26 09:04:08 [INFO ] Grid start: 1024 (4606.25) -> Grid end: 1536 (6910.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 09:04:08 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120224_D08_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120224_D08_B02.tif \n", + "2026-06-26 09:04:08 [INFO ] Granule: 6912 -> 9216 \n", + "2026-06-26 09:04:08 [INFO ] Grid start: 1536 (6910.25) -> Grid end: 2048 (9214.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 09:04:08 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120228_D08_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120228_D08_B02.tif \n", + "2026-06-26 09:04:08 [INFO ] Granule: 9216 -> 11520 \n", + "2026-06-26 09:04:08 [INFO ] Grid start: 2048 (9214.25) -> Grid end: 2560 (11518.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 09:04:08 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120231_D08_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120231_D08_B02.tif \n", + "2026-06-26 09:04:08 [INFO ] Granule: 0 -> 2304 \n", + "2026-06-26 09:04:08 [INFO ] Grid start: 0 (-1.75) -> Grid end: 512 (2302.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 09:04:08 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120217_D08_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120217_D08_B02.tif \n", + "2026-06-26 09:04:08 [INFO ] VRT saved in: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02.vrt \n", + "2026-06-26 09:04:08 [INFO ] \n", + "2026-06-26 09:04:08 [INFO ] ### DET 09 (BAND 2) ### \n", + "2026-06-26 09:04:08 [INFO ] Grid information: ConvOffset: (0.5, 0.5); Step: (4.5, 4.5); Start: (0, 0); Size: (11520, 2552) \n", + "2026-06-26 09:04:25 [INFO ] Granule: 4608 -> 6912 \n", + "2026-06-26 09:04:25 [INFO ] Grid start: 1024 (4606.25) -> Grid end: 1536 (6910.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 09:04:25 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120228_D09_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120228_D09_B02.tif \n", + "2026-06-26 09:04:25 [INFO ] Granule: 6912 -> 9216 \n", + "2026-06-26 09:04:25 [INFO ] Grid start: 1536 (6910.25) -> Grid end: 2048 (9214.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 09:04:25 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120232_D09_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120232_D09_B02.tif \n", + "2026-06-26 09:04:25 [INFO ] Granule: 2304 -> 4608 \n", + "2026-06-26 09:04:25 [INFO ] Grid start: 512 (2302.25) -> Grid end: 1024 (4606.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 09:04:25 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120225_D09_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120225_D09_B02.tif \n", + "2026-06-26 09:04:25 [INFO ] Granule: 9216 -> 11520 \n", + "2026-06-26 09:04:25 [INFO ] Grid start: 2048 (9214.25) -> Grid end: 2560 (11518.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 09:04:25 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120235_D09_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120235_D09_B02.tif \n", + "2026-06-26 09:04:25 [INFO ] Granule: 0 -> 2304 \n", + "2026-06-26 09:04:25 [INFO ] Grid start: 0 (-1.75) -> Grid end: 512 (2302.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 09:04:25 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120221_D09_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120221_D09_B02.tif \n", + "2026-06-26 09:04:25 [INFO ] VRT saved in: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02.vrt \n", + "2026-06-26 09:04:25 [INFO ] \n", + "2026-06-26 09:04:25 [INFO ] ### DET 10 (BAND 2) ### \n", + "2026-06-26 09:04:25 [INFO ] Grid information: ConvOffset: (0.5, 0.5); Step: (4.5, 4.5); Start: (0, 0); Size: (11520, 2552) \n", + "2026-06-26 09:04:43 [INFO ] Granule: 4608 -> 6912 \n", + "2026-06-26 09:04:43 [INFO ] Grid start: 1024 (4606.25) -> Grid end: 1536 (6910.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 09:04:43 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120224_D10_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120224_D10_B02.tif \n", + "2026-06-26 09:04:43 [INFO ] Granule: 0 -> 2304 \n", + "2026-06-26 09:04:43 [INFO ] Grid start: 0 (-1.75) -> Grid end: 512 (2302.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 09:04:43 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120217_D10_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120217_D10_B02.tif \n", + "2026-06-26 09:04:43 [INFO ] Granule: 2304 -> 4608 \n", + "2026-06-26 09:04:43 [INFO ] Grid start: 512 (2302.25) -> Grid end: 1024 (4606.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 09:04:43 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120221_D10_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120221_D10_B02.tif \n", + "2026-06-26 09:04:43 [INFO ] Granule: 9216 -> 11520 \n", + "2026-06-26 09:04:43 [INFO ] Grid start: 2048 (9214.25) -> Grid end: 2560 (11518.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 09:04:43 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120231_D10_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120231_D10_B02.tif \n", + "2026-06-26 09:04:43 [INFO ] Granule: 6912 -> 9216 \n", + "2026-06-26 09:04:43 [INFO ] Grid start: 1536 (6910.25) -> Grid end: 2048 (9214.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 09:04:43 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120228_D10_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120228_D10_B02.tif \n", + "2026-06-26 09:04:43 [INFO ] VRT saved in: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02.vrt \n", + "2026-06-26 09:04:43 [INFO ] \n", + "2026-06-26 09:04:43 [INFO ] ### DET 11 (BAND 2) ### \n", + "2026-06-26 09:04:43 [INFO ] Grid information: ConvOffset: (0.5, 0.5); Step: (4.5, 4.5); Start: (0, 0); Size: (11520, 2552) \n", + "2026-06-26 09:05:01 [INFO ] Granule: 0 -> 2304 \n", + "2026-06-26 09:05:01 [INFO ] Grid start: 0 (-1.75) -> Grid end: 512 (2302.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 09:05:01 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120221_D11_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120221_D11_B02.tif \n", + "2026-06-26 09:05:01 [INFO ] Granule: 9216 -> 11520 \n", + "2026-06-26 09:05:01 [INFO ] Grid start: 2048 (9214.25) -> Grid end: 2560 (11518.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 09:05:01 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120235_D11_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120235_D11_B02.tif \n", + "2026-06-26 09:05:01 [INFO ] Granule: 4608 -> 6912 \n", + "2026-06-26 09:05:01 [INFO ] Grid start: 1024 (4606.25) -> Grid end: 1536 (6910.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 09:05:01 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120228_D11_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120228_D11_B02.tif \n", + "2026-06-26 09:05:01 [INFO ] Granule: 2304 -> 4608 \n", + "2026-06-26 09:05:01 [INFO ] Grid start: 512 (2302.25) -> Grid end: 1024 (4606.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 09:05:01 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120225_D11_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120225_D11_B02.tif \n", + "2026-06-26 09:05:01 [INFO ] Granule: 6912 -> 9216 \n", + "2026-06-26 09:05:01 [INFO ] Grid start: 1536 (6910.25) -> Grid end: 2048 (9214.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 09:05:01 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120232_D11_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120232_D11_B02.tif \n", + "2026-06-26 09:05:01 [INFO ] VRT saved in: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02.vrt \n", + "2026-06-26 09:05:01 [INFO ] Find the following datastrip metadata file: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/S2B_OPER_MTD_L1B_DS_2BPS_20241019T153411_S20241019T120215.xml \n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Docker execution complete.\n", + "\n", + "Docker images kept.\n", + "\n" + ] + } + ], + "source": [ + "# === RUN SEN2VM (Docker: BUILD + RUN + CLEAN) ===\n", + "\n", + "import os\n", + "import subprocess\n", + "# Notebook location (NOT relative to CWD)\n", + "notebook_dir = os.getcwd()\n", + "dockerfile_dir = os.path.abspath(os.path.join(\n", + " notebook_dir,\n", + " \"..\", \"..\"\n", + "))\n", + "\n", + "config_inside = \"/workspace/UserConf/config.json\"\n", + "params_inside = \"/workspace/UserConf/params.json\"\n", + "# =====================================================\n", + "# 1. BUILD DOCKER IMAGE\n", + "# =====================================================\n", + "\n", + "print(f\"Building Docker image 'sen2vm' from: {dockerfile_dir}\")\n", + "cmd_build = [\n", + " \"docker\", \"build\",\n", + " \"-t\", \"sen2vm\",\n", + " dockerfile_dir\n", + "]\n", + "print(\"Command:\", \" \".join(cmd_build), \"\\n\")\n", + "subprocess.run(cmd_build, check=True)\n", + "print(\"Docker image built successfully.\\n\")\n", + "# =====================================================\n", + "# 2. RUN SEN2VM CONTAINER\n", + "# =====================================================\n", + "\n", + "cmd_run = [\n", + " \"docker\", \"run\",\n", + " \"--rm\",\n", + " \"-v\", f\"{PATH_L1B_DATA}:/data/L1B\",\n", + " \"-v\", f\"{PATH_DEM}:/data/DEM\",\n", + " \"-v\", f\"{PATH_GIPP}:/data/GIPP\",\n", + " \"-v\", f\"{PATH_GEOID}:/data/GEOID\",\n", + " \"-v\", f\"{PATH_IERS}:/data/IERS\",\n", + " \"-v\", f\"{WORKDIR}:/workspace\",\n", + " \"sen2vm\",\n", + " \"-c\", config_inside,\n", + " \"-p\", params_inside\n", + "]\n", + "print(\"Running Docker container...\\n\")\n", + "print(\"Command:\", \" \".join(cmd_run), \"\\n\")\n", + "subprocess.run(cmd_run, check=True)\n", + "print(\"\\nDocker execution complete.\\n\")\n", + "# =====================================================\n", + "# 3. REMOVE DOCKER IMAGE\n", + "# =====================================================\n", + "\n", + "if REMOVE_DOCKER_IMAGE:\n", + " print(\"Removing Docker image 'sen2vm'...\")\n", + " subprocess.run([\"docker\", \"rmi\", \"-f\", \"sen2vm\"], check=True)\n", + " print(\"Docker images removed.\\n\")\n", + "else:\n", + " print(\"Docker images kept.\\n\")" + ] + }, + { + "cell_type": "markdown", + "id": "e54044d2", + "metadata": {}, + "source": [ + " # Generate Orthorectification images" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "a091ccaf", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/home/pcastillo/sen2vm/sen2vm-core/assets/scripts\n", + "Using XML: /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml\n", + "Bands from params.json: ['B02']\n", + "Detectors from params.json: ['07', '08', '09', '10', '11']\n", + "Total direct grids found: 5\n", + "✓ Keep S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02 (Detector=07, Band=B02)\n", + "✓ Keep S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02 (Detector=10, Band=B02)\n", + "✓ Keep S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02 (Detector=08, Band=B02)\n", + "✓ Keep S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02 (Detector=11, Band=B02)\n", + "✓ Keep S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02 (Detector=09, Band=B02)\n", + "\n", + "Filtered direct grids: 5\n", + "\n", + "========================================\n", + "Generating inverse grid\n", + "Direct : /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02.vrt\n", + "Inverse: /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb/INVERSE_GRID/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02.tif\n", + "========================================\n", + "resolution 10\n", + "\n", + "========================================\n", + "Generating inverse grid\n", + "Direct : /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02.vrt\n", + "Inverse: /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb/INVERSE_GRID/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02.tif\n", + "========================================\n", + "resolution 10\n", + "\n", + "========================================\n", + "Generating inverse grid\n", + "Direct : /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02.vrt\n", + "Inverse: /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb/INVERSE_GRID/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02.tif\n", + "========================================\n", + "resolution 10\n", + "\n", + "========================================\n", + "Generating inverse grid\n", + "Direct : /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02.vrt\n", + "Inverse: /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb/INVERSE_GRID/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02.tif\n", + "========================================\n", + "resolution 10\n", + "\n", + "========================================\n", + "Generating inverse grid\n", + "Direct : /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02.vrt\n", + "Inverse: /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb/INVERSE_GRID/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02.tif\n", + "========================================\n", + "resolution 10\n", + "\n", + "=================================================\n", + "Processing: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02.tif\n", + "=================================================\n", + "Detector: 07\n", + "Band: B02\n", + "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02\n", + "Resolution: 10\n", + "Width : 7037\n", + "Height: 3334\n", + "\n", + "=== EXTRACTION ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb:/output gdal-latest -c \n", + " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02\" \"/output/raw/raw_D07_B02.tif\"\n", + " \n", + "Input file size is 2552, 11520\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "=== OTB RESAMPLING ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D07_B02.tif -io.out /output/otb_no_georef/ortho_D07_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", + "2026-06-26 09:08:39 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", + "2026-06-26 09:08:39 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", + "2026-06-26 09:08:39 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", + "2026-06-26 09:08:39 (INFO): Loading metadata from official product\n", + "2026-06-26 09:08:39 (INFO): Loading metadata from official product\n", + "2026-06-26 09:08:39 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:08:39 (FATAL) GridBasedImageResampling: Requested region is (at least partially) outside the largest possible region of the displacement field.\n", + "OTB failed (outside grid) → skipping\n", + "\n", + "=================================================\n", + "Processing: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02.tif\n", + "=================================================\n", + "Detector: 10\n", + "Band: B02\n", + "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02\n", + "Resolution: 10\n", + "Width : 7037\n", + "Height: 3334\n", + "\n", + "=== EXTRACTION ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb:/output gdal-latest -c \n", + " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02\" \"/output/raw/raw_D10_B02.tif\"\n", + " \n", + "Input file size is 2552, 11520\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "=== OTB RESAMPLING ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D10_B02.tif -io.out /output/otb_no_georef/ortho_D10_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", + "2026-06-26 09:08:44 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", + "2026-06-26 09:08:44 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", + "2026-06-26 09:08:44 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", + "2026-06-26 09:08:44 (INFO): Loading metadata from official product\n", + "2026-06-26 09:08:44 (INFO): Loading metadata from official product\n", + "2026-06-26 09:08:44 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:08:44 (INFO): Estimated memory for full processing: 1110.09MB (avail.: 256 MB), optimal image partitioning: 5 blocks\n", + "2026-06-26 09:08:44 (INFO): File /output/otb_no_georef/ortho_D10_B02.tif will be written in 6 blocks of 7037x556 pixels\n", + "Writing /output/otb_no_georef/ortho_D10_B02.tif...: 100% [**************************************************] (4s)\n", + "OTB success\n", + "\n", + "=== ADD GEOREF ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb:/output gdal-latest -c \n", + " gdal_translate -a_srs EPSG:32628 /output/otb_no_georef/ortho_D10_B02.tif /output/output_georef/ortho_D10_B02_georef.tif\n", + " \n", + "Input file size is 7037, 3334\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "Finished: ortho_D10_B02_georef.tif\n", + "\n", + "=================================================\n", + "Processing: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02.tif\n", + "=================================================\n", + "Detector: 08\n", + "Band: B02\n", + "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02\n", + "Resolution: 10\n", + "Width : 7037\n", + "Height: 3334\n", + "\n", + "=== EXTRACTION ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb:/output gdal-latest -c \n", + " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02\" \"/output/raw/raw_D08_B02.tif\"\n", + " \n", + "Input file size is 2552, 11520\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "=== OTB RESAMPLING ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D08_B02.tif -io.out /output/otb_no_georef/ortho_D08_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", + "2026-06-26 09:08:54 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", + "2026-06-26 09:08:54 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", + "2026-06-26 09:08:54 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", + "2026-06-26 09:08:54 (INFO): Loading metadata from official product\n", + "2026-06-26 09:08:54 (INFO): Loading metadata from official product\n", + "2026-06-26 09:08:54 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:08:54 (INFO): Estimated memory for full processing: 1110.09MB (avail.: 256 MB), optimal image partitioning: 5 blocks\n", + "2026-06-26 09:08:54 (INFO): File /output/otb_no_georef/ortho_D08_B02.tif will be written in 6 blocks of 7037x556 pixels\n", + "Writing /output/otb_no_georef/ortho_D08_B02.tif...: 100% [**************************************************] (4s)\n", + "OTB success\n", + "\n", + "=== ADD GEOREF ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb:/output gdal-latest -c \n", + " gdal_translate -a_srs EPSG:32628 /output/otb_no_georef/ortho_D08_B02.tif /output/output_georef/ortho_D08_B02_georef.tif\n", + " \n", + "Input file size is 7037, 3334\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "Finished: ortho_D08_B02_georef.tif\n", + "\n", + "=================================================\n", + "Processing: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02.tif\n", + "=================================================\n", + "Detector: 11\n", + "Band: B02\n", + "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02\n", + "Resolution: 10\n", + "Width : 7037\n", + "Height: 3334\n", + "\n", + "=== EXTRACTION ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb:/output gdal-latest -c \n", + " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02\" \"/output/raw/raw_D11_B02.tif\"\n", + " \n", + "Input file size is 2552, 11520\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "=== OTB RESAMPLING ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D11_B02.tif -io.out /output/otb_no_georef/ortho_D11_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", + "2026-06-26 09:09:04 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", + "2026-06-26 09:09:04 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", + "2026-06-26 09:09:04 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", + "2026-06-26 09:09:04 (INFO): Loading metadata from official product\n", + "2026-06-26 09:09:04 (INFO): Loading metadata from official product\n", + "2026-06-26 09:09:04 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:09:04 (FATAL) GridBasedImageResampling: Requested region is (at least partially) outside the largest possible region of the displacement field.\n", + "OTB failed (outside grid) → skipping\n", + "\n", + "=================================================\n", + "Processing: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02.tif\n", + "=================================================\n", + "Detector: 09\n", + "Band: B02\n", + "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02\n", + "Resolution: 10\n", + "Width : 7037\n", + "Height: 3334\n", + "\n", + "=== EXTRACTION ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb:/output gdal-latest -c \n", + " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02\" \"/output/raw/raw_D09_B02.tif\"\n", + " \n", + "Input file size is 2552, 11520\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "=== OTB RESAMPLING ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D09_B02.tif -io.out /output/otb_no_georef/ortho_D09_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", + "2026-06-26 09:09:08 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", + "2026-06-26 09:09:08 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", + "2026-06-26 09:09:08 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", + "2026-06-26 09:09:08 (INFO): Loading metadata from official product\n", + "2026-06-26 09:09:08 (INFO): Loading metadata from official product\n", + "2026-06-26 09:09:08 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:09:08 (INFO): Estimated memory for full processing: 1246.6MB (avail.: 256 MB), optimal image partitioning: 5 blocks\n", + "2026-06-26 09:09:08 (INFO): File /output/otb_no_georef/ortho_D09_B02.tif will be written in 6 blocks of 7037x556 pixels\n", + "Writing /output/otb_no_georef/ortho_D09_B02.tif...: 100% [**************************************************] (5s)\n", + "OTB success\n", + "\n", + "=== ADD GEOREF ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb:/output gdal-latest -c \n", + " gdal_translate -a_srs EPSG:32628 /output/otb_no_georef/ortho_D09_B02.tif /output/output_georef/ortho_D09_B02_georef.tif\n", + " \n", + "Input file size is 7037, 3334\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "Finished: ortho_D09_B02_georef.tif\n", + "\n", + "=== MOSAIC CREATION ===\n", + "\n", + "Bands detected: {'B02'}\n", + "\n", + "----------------------------------------\n", + "Creating mosaic for band: B02\n", + "----------------------------------------\n", + "Found 3 files\n", + " ortho_D08_B02_georef.tif\n", + " ortho_D09_B02_georef.tif\n", + " ortho_D10_B02_georef.tif\n", + "\n", + "Running mosaic:\n", + " gdal_merge.py -o /output/mosaic/ORTHO_mosaic_B02.tif -of GTiff -co COMPRESS=LZW -co TILED=YES -ot UInt16 -n 0 -a_nodata 0 /output/output_georef/ortho_D08_B02_georef.tif /output/output_georef/ortho_D09_B02_georef.tif /output/output_georef/ortho_D10_B02_georef.tif \n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "Mosaic written → /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb/mosaic/ORTHO_mosaic_B02.tif\n", + "Docker images kept (faster next run, ~4 GB disk usage).\n", + "\n" + ] + } + ], + "source": [ + "import os\n", + "import subprocess\n", + "import glob\n", + "import json\n", + "import re\n", + "\n", + "# =====================================================\n", + "# Import of sen2vm_invloc_from_dir_loc_grid\n", + "# =====================================================\n", + "import sys\n", + "from pathlib import Path\n", + "sys.path.append(\n", + " str(Path(\"../../assets/scripts\").resolve())\n", + ")\n", + "\n", + "from sen2vm_invloc_from_dir_loc_grid import (\n", + " sen2vm_invloc_from_dir_loc_grid\n", + ")\n", + "print(Path(\"../../assets/scripts\").resolve())\n", + "\n", + "# =====================================================\n", + "# SAFETY CHECKS\n", + "# =====================================================\n", + "assert os.path.exists(PATH_L1B_DATA), \"L1B path missing\"\n", + "os.makedirs(OUTPUT_FOLDER, exist_ok=True)\n", + "assert os.path.exists(OUTPUT_FOLDER), \"Output folder missing\"\n", + "\n", + "# =====================================================\n", + "# Locate product name\n", + "# =====================================================\n", + "product = os.path.basename(os.path.normpath(PATH_L1B_DATA))\n", + "\n", + "# =====================================================\n", + "# Locate XML\n", + "# =====================================================\n", + "xml_list = glob.glob(\n", + " os.path.join(\n", + " PATH_L1B_DATA,\n", + " \"S2*_MTD_*.xml\"\n", + " )\n", + ")\n", + "if len(xml_list) == 0:\n", + " raise RuntimeError(\"No DATASTRIP MTD XML found\")\n", + "\n", + "xml_path = xml_list[0]\n", + "xml_name = os.path.basename(xml_path)\n", + "\n", + "# XML path inside docker (relative, after cd)\n", + "xml_docker = f\"./{xml_name}\"\n", + "\n", + "print(\"Using XML:\", xml_path)\n", + "\n", + "# =====================================================\n", + "# Read params.json to get selected bands and detectors\n", + "# =====================================================\n", + "params_path = os.path.join(WORKDIR, \"UserConf\", \"params.json\")\n", + "if not os.path.exists(params_path):\n", + " raise RuntimeError(f\"params.json not found at {params_path}\")\n", + "\n", + "with open(params_path, \"r\") as f:\n", + " params = json.load(f)\n", + "\n", + "selected_bands = params.get(\"bands\", [])\n", + "selected_detectors = params.get(\"detectors\", [])\n", + "\n", + "print(f\"Bands from params.json: {selected_bands}\")\n", + "print(f\"Detectors from params.json: {selected_detectors}\")\n", + "# =====================================================\n", + "# Create output folders\n", + "# =====================================================\n", + "\n", + "RAW_DIR = os.path.join(OUTPUT_FOLDER, \"raw\")\n", + "OTB_DIR = os.path.join(OUTPUT_FOLDER, \"otb_no_georef\")\n", + "GEOREF_DIR = os.path.join(OUTPUT_FOLDER, \"output_georef\")\n", + "MOSAIC_DIR = os.path.join(OUTPUT_FOLDER, \"mosaic\")\n", + "os.makedirs(os.path.join(OUTPUT_FOLDER, \"INVERSE_GRID\"), exist_ok=True)\n", + "os.makedirs(RAW_DIR, exist_ok=True)\n", + "os.makedirs(OTB_DIR, exist_ok=True)\n", + "os.makedirs(GEOREF_DIR, exist_ok=True)\n", + "os.makedirs(MOSAIC_DIR, exist_ok=True)\n", + "\n", + "# =====================================================\n", + "# Locate and filter direct grids\n", + "# =====================================================\n", + "\n", + "grid_pattern = r\"_D(\\d+)_B(\\d{1,2}[A]?)\"\n", + "direct_grids = []\n", + "all_grids = glob.glob(\n", + " os.path.join(\n", + " PATH_L1B_DATA,\n", + " \"DATASTRIP\",\n", + " \"S2*\",\n", + " \"GEO_DATA\",\n", + " \"*.vrt\"\n", + " )\n", + ")\n", + "print(f\"Total direct grids found: {len(all_grids)}\")\n", + "\n", + "for grid in all_grids:\n", + " grid_name = Path(grid).stem\n", + " match = re.search(grid_pattern, grid_name)\n", + " if not match:\n", + " continue\n", + " detector = match.group(1)\n", + " band = f\"B{match.group(2)}\"\n", + " if detector in selected_detectors and band in selected_bands:\n", + " direct_grids.append(grid)\n", + " print(\n", + " f\"✓ Keep {grid_name} \"\n", + " f\"(Detector={detector}, Band={band})\"\n", + " )\n", + "print(f\"\\nFiltered direct grids: {len(direct_grids)}\")\n", + "# =====================================================\n", + "# Create inverse grids\n", + "# =====================================================\n", + "\n", + "inverse_grid_list = []\n", + "\n", + "for direct_grid in direct_grids:\n", + " grid_name = Path(direct_grid).stem\n", + " match = re.search(grid_pattern, grid_name)\n", + " detector = match.group(1)\n", + " band = f\"B{match.group(2)}\"\n", + " \n", + " if band in [\"B02\", \"B03\", \"B04\", \"B08\"]:\n", + " resolution = 10\n", + " elif band in [\"B05\", \"B06\", \"B07\", \"B8A\", \"B11\", \"B12\"]:\n", + " resolution = 20\n", + " elif band in [\"B01\", \"B09\", \"B10\"]:\n", + " resolution = 60\n", + " else:\n", + " resolution = 10\n", + " inverse_grid = os.path.join(\n", + " OUTPUT_FOLDER,\n", + " \"INVERSE_GRID\",\n", + " f\"{grid_name}.tif\"\n", + " )\n", + " print(\"\\n========================================\")\n", + " print(\"Generating inverse grid\")\n", + " print(\"Direct :\", direct_grid)\n", + " print(\"Inverse:\", inverse_grid)\n", + " print(\"========================================\")\n", + "\n", + " sen2vm_invloc_from_dir_loc_grid(\n", + " grid=direct_grid,\n", + " resolution=resolution,\n", + " out_file=inverse_grid,\n", + " epsg=UTM_EPSG\n", + " )\n", + " inverse_grid_list.append(inverse_grid)\n", + "\n", + "# =====================================================\n", + "# Process all inverse grids\n", + "# =====================================================\n", + "for inv_grid_path in inverse_grid_list:\n", + " test_grid = os.path.basename(inv_grid_path)\n", + " print(\"\\n=================================================\")\n", + " print(\"Processing:\", test_grid)\n", + " print(\"=================================================\")\n", + "\n", + " # =================================================\n", + " # Parse detector / band\n", + " # =================================================\n", + " match = re.search(r\"_D(\\d+)_B(\\d{1,2}[A]?)\", test_grid)\n", + " if not match:\n", + " print(\"Could not parse detector/band\")\n", + " continue\n", + "\n", + " detector = match.group(1)\n", + " band = f\"B{match.group(2)}\"\n", + "\n", + " print(\"Detector:\", detector)\n", + " print(\"Band:\", band)\n", + "\n", + " # =================================================\n", + " # Build subdataset dynamically\n", + " # =================================================\n", + " subdataset = test_grid.replace(\".tif\", \"\")\n", + " print(\"Subdataset:\", subdataset)\n", + " \n", + " # =================================================\n", + " # Determine resolution\n", + " # =================================================\n", + " if band in [\"B02\", \"B03\", \"B04\", \"B08\"]:\n", + " resolution = 10\n", + " elif band in [\"B05\", \"B06\", \"B07\", \"B8A\", \"B11\", \"B12\"]:\n", + " resolution = 20\n", + " elif band in [\"B01\", \"B09\", \"B10\"]:\n", + " resolution = 60\n", + " else:\n", + " resolution = 10\n", + " \n", + " print(\"Resolution:\", resolution)\n", + " \n", + " # =================================================\n", + " # Compute output size\n", + " # =================================================\n", + " width = int(\n", + " (LOCATION[\"lr_x\"] - LOCATION[\"ul_x\"]) / resolution\n", + " )\n", + " height = int(\n", + " (LOCATION[\"ul_y\"] - LOCATION[\"lr_y\"]) / resolution\n", + " )\n", + " print(\"Width :\", width)\n", + " print(\"Height:\", height)\n", + "\n", + " # =================================================\n", + " # File paths\n", + " # =================================================\n", + " raw_name = f\"raw_D{detector}_{band}.tif\"\n", + " ortho_name = f\"ortho_D{detector}_{band}.tif\"\n", + " georef_name = f\"ortho_D{detector}_{band}_georef.tif\"\n", + " \n", + " # =================================================\n", + " # Extract raw detector image\n", + " # =================================================\n", + " cmd_extract = [\n", + " \"docker\", \"run\",\n", + " \"--rm\",\n", + " \"-v\", f\"{PATH_L1B_DATA}:/data/L1B\",\n", + " \"-v\", f\"{OUTPUT_FOLDER}:/output\",\n", + " \"gdal-latest\",\n", + " \"-c\",\n", + " f'''\n", + " gdal_translate \\\n", + " \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/{xml_name}:{subdataset}\" \\\n", + " \"/output/raw/{raw_name}\"\n", + " '''\n", + " ]\n", + " print(\"\\n=== EXTRACTION ===\\n\")\n", + " print(\" \".join(cmd_extract))\n", + "\n", + " subprocess.run(cmd_extract, check=True)\n", + " \n", + " # Half-pixel correction (OTB bug fix)\n", + " corrected_ulx = LOCATION[\"ul_x\"] + resolution / 2\n", + " corrected_uly = LOCATION[\"ul_y\"] - resolution / 2\n", + "\n", + " # =================================================\n", + " # OTB resampling\n", + " # =================================================\n", + " cmd_otb = [\n", + " \"docker\", \"run\",\n", + " \"--rm\",\n", + " \"-v\", f\"{OUTPUT_FOLDER}:/output\",\n", + " \"orfeotoolbox/otb:9.0.0\",\n", + " \"otbcli_GridBasedImageResampling\",\n", + " \"-io.in\",\n", + " f\"/output/raw/{raw_name}\",\n", + " \"-io.out\",\n", + " f\"/output/otb_no_georef/{ortho_name}\",\n", + " \"-grid.in\",\n", + " f\"/output/INVERSE_GRID/{test_grid}\",\n", + " \"-grid.type\",\n", + " \"loc\",\n", + " \"-out.ulx\",\n", + " str(corrected_ulx),\n", + " \"-out.uly\",\n", + " str(corrected_uly),\n", + " \"-out.spacingx\",\n", + " str(resolution),\n", + " \"-out.spacingy\",\n", + " str(-resolution),\n", + " \"-out.sizex\",\n", + " str(width),\n", + " \"-out.sizey\",\n", + " str(height)\n", + " ]\n", + "\n", + " print(\"\\n=== OTB RESAMPLING ===\\n\")\n", + " print(\" \".join(cmd_otb))\n", + "\n", + " try:\n", + " subprocess.run(cmd_otb, check=True)\n", + " print(\"OTB success\")\n", + " \n", + " except subprocess.CalledProcessError:\n", + " print(\"OTB failed (outside grid) → skipping\")\n", + " continue\n", + "\n", + " # ==================a===============================\n", + " # Add georeferencing to correct otb missing one\n", + " # =================================================\n", + " cmd_georef = [\n", + " \"docker\", \"run\",\n", + " \"--rm\",\n", + " \"-v\", f\"{OUTPUT_FOLDER}:/output\",\n", + " \"gdal-latest\",\n", + " \"-c\",\n", + " f'''\n", + " gdal_translate \\\n", + " -a_srs EPSG:{UTM_EPSG} \\\n", + " /output/otb_no_georef/{ortho_name} \\\n", + " /output/output_georef/{georef_name}\n", + " '''\n", + " ]\n", + "\n", + " print(\"\\n=== ADD GEOREF ===\\n\")\n", + " print(\" \".join(cmd_georef))\n", + " subprocess.run(cmd_georef, check=True)\n", + " print(\"\\nFinished:\", georef_name)\n", + "\n", + "# =====================================================\n", + "# Mosaic\n", + "# =====================================================\n", + "print(\"\\n=== MOSAIC CREATION ===\\n\")\n", + "bands = set()\n", + "for f in glob.glob(os.path.join(GEOREF_DIR, \"*.tif\")):\n", + " match = re.search(r\"_B(\\d{2}[A]?)\", f)\n", + " if match:\n", + " bands.add(f\"B{match.group(1)}\")\n", + "print(\"Bands detected:\", bands)\n", + "\n", + "for band in bands:\n", + "\n", + " print(\"\\n----------------------------------------\")\n", + " print(\"Creating mosaic for band:\", band)\n", + " print(\"----------------------------------------\")\n", + " # fichiers correspondant à la bande\n", + " input_files = glob.glob(\n", + " os.path.join(GEOREF_DIR, f\"*_{band}_georef.tif\")\n", + " )\n", + " if len(input_files) == 0:\n", + " print(\"No ortho images found for band\", band)\n", + " continue\n", + " input_files = sorted(input_files)\n", + " \n", + " output_path = os.path.join(\n", + " MOSAIC_DIR,\n", + " f\"ORTHO_mosaic_{band}.tif\"\n", + " )\n", + " print(\"Found\", len(input_files), \"files\")\n", + " for f in input_files:\n", + " print(\" \", os.path.basename(f))\n", + " \n", + " gdal_cmd = \"gdal_merge.py \" \\\n", + " f\"-o /output/mosaic/ORTHO_mosaic_{band}.tif \" \\\n", + " \"-of GTiff \" \\\n", + " \"-co COMPRESS=LZW \" \\\n", + " \"-co TILED=YES \" \\\n", + " \"-ot UInt16 \" \\\n", + " \"-n 0 -a_nodata 0 \"\n", + "\n", + " for f in input_files:\n", + " fname = os.path.basename(f)\n", + " gdal_cmd += f\"/output/output_georef/{fname} \"\n", + "\n", + " cmd_mosaic = [\n", + " \"docker\", \"run\",\n", + " \"--rm\",\n", + " \"-v\", f\"{OUTPUT_FOLDER}:/output\",\n", + " \"gdal-latest\",\n", + " \"-c\",\n", + " gdal_cmd\n", + " ]\n", + "\n", + " print(\"\\nRunning mosaic:\\n\", gdal_cmd)\n", + " subprocess.run(cmd_mosaic, check=True)\n", + " print(\"Mosaic written →\", output_path)\n", + "\n", + "# =====================================================\n", + "# Cleanup docker image\n", + "# =====================================================\n", + "if REMOVE_DOCKER_IMAGE:\n", + " print(\"Removing gdal-latest image...\\n\")\n", + " subprocess.run([\"docker\", \"rmi\", \"-f\", \"gdal-latest\"], check=True)\n", + " print(\"GDAL image removed.\\n\")\n", + "else:\n", + " print(\"Docker images kept (faster next run, ~4 GB disk usage).\\n\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f3f9c566-f0ba-42fa-872e-333f9f41b851", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.11" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/sen2vm-notebook/src/notebook-direct-grid.ipynb b/sen2vm-notebook/src/notebook-direct-grid.ipynb index 7fd5c2c6..8c1460a7 100644 --- a/sen2vm-notebook/src/notebook-direct-grid.ipynb +++ b/sen2vm-notebook/src/notebook-direct-grid.ipynb @@ -10,7 +10,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "id": "2b816cd9-5254-452b-bced-2943eb6b7aec", "metadata": {}, "outputs": [], @@ -20,13 +20,13 @@ "# /!\\/!\\/!\\ CAREFUL, please read the README_Notebooks.md file before\n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "\n", - "WORKDIR = \"PATH/TO/WORKDIR\" # Working directory for sen2vm processing\n", + "WORKDIR = \"/home/pcastillo/sen2vm/WORKDIR\" # Working directory for sen2vm processing\n", "\n", "# Path to downloaded product\n", - "PATH_L1B_DATA = \"PATH/TO/L1B_PRODUCT\"\n", + "PATH_L1B_DATA = \"/home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE\"\n", "\n", "# Path to GIPP directory\n", - "PATH_GIPP = \"PATH/TO/GIPP\"\n", + "PATH_GIPP = \"/home/pcastillo/sen2vm/WORKDIR/GIPP\"\n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "# /!\\/!\\/!\\ If you do not have your own GIPP folder, you may use the inputs-download-notebook to download it, then you may indicate the path were you \n", "# /!\\/!\\/!\\ downloaded it here in PATH_GIPP\n", @@ -34,24 +34,24 @@ "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "\n", "# Path to DEM directory \n", - "PATH_DEM = \"PATH/TO/DEM\"\n", + "PATH_DEM = \"/home/pcastillo/sen2vm/WORKDIR/DEM\"\n", "\n", "# Path to GEOID directory\n", - "PATH_GEOID = \"PATH/TO/GEOID\"\n", + "PATH_GEOID = \"/home/pcastillo/sen2vm/WORKDIR/GEOID\"\n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "# /!\\/!\\/!\\ If you do not have your own GEOID folder, you may use the inputs-download-notebook to download it, then you may indicate the path were you\n", "# /!\\/!\\/!\\ downloaded it here in \n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "\n", "# Path to IERS file\n", - "PATH_IERS = \"PATH/TO/IERS_FILE\"\n", + "PATH_IERS = \"\"\n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "# /!\\/!\\/!\\ If you do not have your own IERS, you may let this path empy (i.e. \"\") and execute the cell number 2 named #IERS Download\n", "# /!\\/!\\/!\\ In this case, the IERS will be downloaded in the WORKDIR\n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "\n", "# The output folder is put in the WORKDIR\n", - "OUTPUT_FOLDER = WORKDIR + \"/output/DIRECT\"\n", + "OUTPUT_FOLDER = WORKDIR + \"/output/DIRECT_gdal\"\n", "\n", "# === SEN2VM OPTIONS ===\n", "UTM_EPSG = 32628 # UTM zone EPSG code for the ROI\n", @@ -74,8 +74,8 @@ "# === GDAL ORTHO OPTIONS ===\n", "\n", "ORTHO_SETTINGS = {\n", - " \"keep_bands\": [\"B02\",\"B03\"], # list of bands to keep for orthorectification\n", - " \"keep_detectors\": [\"01\",\"02\",\"03\",\"04\",\"05\",\"06\",\"07\",\"08\",\"09\",\"10\",\"11\",\"12\"] # list of the detectors to keep \n", + " \"keep_bands\": [\"B02\"], # list of bands to keep for orthorectification\n", + " \"keep_detectors\": [\"07\",\"08\",\"09\",\"10\",\"11\"] # list of the detectors to keep \n", "}\n", "\n", "# === Docker Options ===\n", @@ -102,10 +102,28 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "id": "8ec4d6f6", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Bulletin output directory: /home/pcastillo/sen2vm/WORKDIR\n", + "Cleanup of old bulletins complete.\n", + "\n", + "Product date extracted from DATASTRIP: 2024-10-19 \n", + "\n", + "Bulletin A Roman year: xxxvii\n", + "Initial weekly index: 42\n", + "\n", + "Trying bulletin: https://datacenter.iers.org/data/6/bulletina-xxxvii-042.txt\n", + "Bulletin found: 042\n", + "Downloaded: /home/pcastillo/sen2vm/WORKDIR/bulletina-xxxvii-042.txt\n" + ] + } + ], "source": [ "# === DOWNLOAD IERS ===\n", "import os\n", @@ -230,10 +248,22 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "id": "276592b5", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "UserConf directory: /home/pcastillo/sen2vm/WORKDIR/UserConf\n", + "Geoid directory: /home/pcastillo/sen2vm/WORKDIR/GEOID\n", + "/data/IERS/bulletina-xxxvii-042.txt\n", + "Configuration file generated:\n", + "/home/pcastillo/sen2vm/WORKDIR/UserConf/config.json\n" + ] + } + ], "source": [ "# === GENERATE CONFIG.JSON ===\n", "\n", @@ -338,10 +368,24 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "id": "23b1da25", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "UserConf directory: /home/pcastillo/sen2vm/WORKDIR/UserConf\n", + "Found 60 granule folders.\n", + "Detected detectors: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12']\n", + "Detected bands: ['B01', 'B02', 'B03', 'B04', 'B05', 'B06', 'B07', 'B08', 'B09', 'B10', 'B11', 'B12', 'B8A']\n", + "params.json written to: /home/pcastillo/sen2vm/WORKDIR/UserConf/params.json\n", + " - Detectors: ['07', '08', '09', '10', '11']\n", + " - Bands: ['B02']\n" + ] + } + ], "source": [ "# === GENERATE PARAMS.JSON ===\n", "\n", @@ -438,10 +482,195 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "id": "572bd72a", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Building Docker image 'sen2vm' from: /home/pcastillo/sen2vm/sen2vm-core\n", + "Command: docker build -t sen2vm /home/pcastillo/sen2vm/sen2vm-core \n", + "\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "DEPRECATED: The legacy builder is deprecated and will be removed in a future release.\n", + " Install the buildx component to build images with BuildKit:\n", + " https://docs.docker.com/go/buildx/\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Sending build context to Docker daemon 1.718GB\n", + "Step 1/5 : FROM ghcr.io/sen2vm/sen2vm-build-env:latest AS launcher\n", + " ---> a5369801b500\n", + "Step 2/5 : ENV SEN2VM_VERSION=1.1.4\n", + " ---> Using cache\n", + " ---> 14de44fa18ab\n", + "Step 3/5 : WORKDIR /Sen2vm\n", + " ---> Using cache\n", + " ---> b4079a1b81e1\n", + "Step 4/5 : RUN curl -L -o sen2vm-core.jar https://github.com/sen2vm/sen2vm-core/releases/download/${SEN2VM_VERSION}/sen2vm-core-${SEN2VM_VERSION}.jar\n", + " ---> Using cache\n", + " ---> 01c51fc5d7d7\n", + "Step 5/5 : ENTRYPOINT [\"java\", \"-jar\",\"sen2vm-core.jar\"]\n", + " ---> Using cache\n", + " ---> 5be1977daa50\n", + "Successfully built 5be1977daa50\n", + "Successfully tagged sen2vm:latest\n", + "Docker image built successfully.\n", + "\n", + "Running Docker container...\n", + "\n", + "Command: docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/DEM:/data/DEM -v /home/pcastillo/sen2vm/WORKDIR/GIPP:/data/GIPP -v /home/pcastillo/sen2vm/WORKDIR/GEOID:/data/GEOID -v /home/pcastillo/sen2vm/WORKDIR:/data/IERS -v /home/pcastillo/sen2vm/WORKDIR:/workspace sen2vm -c /workspace/UserConf/config.json -p /workspace/UserConf/params.json \n", + "\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2026-06-26 08:55:17 [INFO ] Start Sen2VM \n", + "2026-06-26 08:55:17 [INFO ] Parsing file /workspace/UserConf/config.json \n", + "2026-06-26 08:55:17 [INFO ] Reading IERS file at: /data/IERS/bulletina-xxxvii-042.txt \n", + "2026-06-26 08:55:17 [INFO ] Parsing file /workspace/UserConf/params.json \n", + "2026-06-26 08:55:17 [INFO ] Detectors list: [DETECTOR_7, DETECTOR_8, DETECTOR_9, DETECTOR_10, DETECTOR_11] \n", + "2026-06-26 08:55:17 [INFO ] Bands list: [BAND_2] \n", + "2026-06-26 08:55:17 [INFO ] Find the following datastrip metadata file: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/S2B_OPER_MTD_L1B_DS_2BPS_20241019T153411_S20241019T120215.xml \n", + "2026-06-26 08:55:18 [INFO ] Initializing: copy of the Orekit-data: /Sen2vm/orekit-data \n", + "2026-06-26 08:55:18 [INFO ] Orekit-data: /Sen2vm/orekit-data \n", + "2026-06-26 08:55:25 [INFO ] Get through GIPP folder: /data/GIPP/S2B \n", + "2026-06-26 08:55:26 [INFO ] Read blind pixel file: /data/GIPP/S2B/S2B_OPER_GIP_BLINDP_MPC__20170221T000000_V20170101T000000_21000101T000000_B00.xml \n", + "2026-06-26 08:55:26 [INFO ] Read spacecraft model file: /data/GIPP/S2B/S2B_OPER_GIP_SPAMOD_MPC__20231122T110035_V20231123T000000_21000101T000000_B00.xml \n", + "2026-06-26 08:55:26 [INFO ] Read viewingDirection file: /data/GIPP/S2B/S2B_OPER_GIP_VIEDIR_MPC__20170512T114736_V20170322T000000_21000101T000000_B02.xml \n", + "2026-06-26 08:55:26 [INFO ] setAndProcessDataStrip listOfFiles/data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11 \n", + "2026-06-26 08:55:26 [INFO ] Datastrip S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11 \n", + "2026-06-26 08:55:27 [INFO ] \n", + "2026-06-26 08:55:27 [INFO ] Starting grids generation \n", + "2026-06-26 08:55:27 [INFO ] \n", + "2026-06-26 08:55:27 [INFO ] ############### \n", + "2026-06-26 08:55:27 [INFO ] ### BAND 2 ### \n", + "2026-06-26 08:55:27 [INFO ] ############### \n", + "2026-06-26 08:55:27 [INFO ] Grid resolution: 4.5 \n", + "2026-06-26 08:55:27 [INFO ] Band resolution: 10.0 \n", + "2026-06-26 08:55:27 [INFO ] \n", + "2026-06-26 08:55:27 [INFO ] ### DET 07 (BAND 2) ### \n", + "2026-06-26 08:55:27 [INFO ] Grid information: ConvOffset: (0.5, 0.5); Step: (4.5, 4.5); Start: (0, 0); Size: (11520, 2552) \n", + "2026-06-26 08:55:42 [INFO ] Granule: 4608 -> 6912 \n", + "2026-06-26 08:55:42 [INFO ] Grid start: 1024 (4606.25) -> Grid end: 1536 (6910.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 08:55:42 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120228_D07_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120228_D07_B02.tif \n", + "2026-06-26 08:55:42 [INFO ] Granule: 2304 -> 4608 \n", + "2026-06-26 08:55:42 [INFO ] Grid start: 512 (2302.25) -> Grid end: 1024 (4606.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 08:55:42 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120225_D07_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120225_D07_B02.tif \n", + "2026-06-26 08:55:42 [INFO ] Granule: 9216 -> 11520 \n", + "2026-06-26 08:55:42 [INFO ] Grid start: 2048 (9214.25) -> Grid end: 2560 (11518.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 08:55:42 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120235_D07_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120235_D07_B02.tif \n", + "2026-06-26 08:55:42 [INFO ] Granule: 0 -> 2304 \n", + "2026-06-26 08:55:42 [INFO ] Grid start: 0 (-1.75) -> Grid end: 512 (2302.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 08:55:42 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120221_D07_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120221_D07_B02.tif \n", + "2026-06-26 08:55:42 [INFO ] Granule: 6912 -> 9216 \n", + "2026-06-26 08:55:42 [INFO ] Grid start: 1536 (6910.25) -> Grid end: 2048 (9214.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 08:55:42 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120232_D07_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120232_D07_B02.tif \n", + "2026-06-26 08:55:42 [INFO ] VRT saved in: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02.vrt \n", + "2026-06-26 08:55:42 [INFO ] \n", + "2026-06-26 08:55:42 [INFO ] ### DET 08 (BAND 2) ### \n", + "2026-06-26 08:55:42 [INFO ] Grid information: ConvOffset: (0.5, 0.5); Step: (4.5, 4.5); Start: (0, 0); Size: (11520, 2552) \n", + "2026-06-26 08:55:58 [INFO ] Granule: 2304 -> 4608 \n", + "2026-06-26 08:55:58 [INFO ] Grid start: 512 (2302.25) -> Grid end: 1024 (4606.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 08:55:58 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120221_D08_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120221_D08_B02.tif \n", + "2026-06-26 08:55:58 [INFO ] Granule: 4608 -> 6912 \n", + "2026-06-26 08:55:58 [INFO ] Grid start: 1024 (4606.25) -> Grid end: 1536 (6910.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 08:55:58 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120224_D08_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120224_D08_B02.tif \n", + "2026-06-26 08:55:58 [INFO ] Granule: 6912 -> 9216 \n", + "2026-06-26 08:55:58 [INFO ] Grid start: 1536 (6910.25) -> Grid end: 2048 (9214.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 08:55:58 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120228_D08_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120228_D08_B02.tif \n", + "2026-06-26 08:55:58 [INFO ] Granule: 9216 -> 11520 \n", + "2026-06-26 08:55:58 [INFO ] Grid start: 2048 (9214.25) -> Grid end: 2560 (11518.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 08:55:58 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120231_D08_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120231_D08_B02.tif \n", + "2026-06-26 08:55:58 [INFO ] Granule: 0 -> 2304 \n", + "2026-06-26 08:55:58 [INFO ] Grid start: 0 (-1.75) -> Grid end: 512 (2302.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 08:55:58 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120217_D08_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120217_D08_B02.tif \n", + "2026-06-26 08:55:58 [INFO ] VRT saved in: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02.vrt \n", + "2026-06-26 08:55:58 [INFO ] \n", + "2026-06-26 08:55:58 [INFO ] ### DET 09 (BAND 2) ### \n", + "2026-06-26 08:55:58 [INFO ] Grid information: ConvOffset: (0.5, 0.5); Step: (4.5, 4.5); Start: (0, 0); Size: (11520, 2552) \n", + "2026-06-26 08:56:14 [INFO ] Granule: 4608 -> 6912 \n", + "2026-06-26 08:56:14 [INFO ] Grid start: 1024 (4606.25) -> Grid end: 1536 (6910.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 08:56:14 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120228_D09_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120228_D09_B02.tif \n", + "2026-06-26 08:56:14 [INFO ] Granule: 6912 -> 9216 \n", + "2026-06-26 08:56:14 [INFO ] Grid start: 1536 (6910.25) -> Grid end: 2048 (9214.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 08:56:14 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120232_D09_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120232_D09_B02.tif \n", + "2026-06-26 08:56:14 [INFO ] Granule: 2304 -> 4608 \n", + "2026-06-26 08:56:14 [INFO ] Grid start: 512 (2302.25) -> Grid end: 1024 (4606.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 08:56:14 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120225_D09_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120225_D09_B02.tif \n", + "2026-06-26 08:56:14 [INFO ] Granule: 9216 -> 11520 \n", + "2026-06-26 08:56:14 [INFO ] Grid start: 2048 (9214.25) -> Grid end: 2560 (11518.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 08:56:14 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120235_D09_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120235_D09_B02.tif \n", + "2026-06-26 08:56:14 [INFO ] Granule: 0 -> 2304 \n", + "2026-06-26 08:56:14 [INFO ] Grid start: 0 (-1.75) -> Grid end: 512 (2302.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 08:56:14 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120221_D09_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120221_D09_B02.tif \n", + "2026-06-26 08:56:14 [INFO ] VRT saved in: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02.vrt \n", + "2026-06-26 08:56:14 [INFO ] \n", + "2026-06-26 08:56:14 [INFO ] ### DET 10 (BAND 2) ### \n", + "2026-06-26 08:56:14 [INFO ] Grid information: ConvOffset: (0.5, 0.5); Step: (4.5, 4.5); Start: (0, 0); Size: (11520, 2552) \n", + "2026-06-26 08:56:30 [INFO ] Granule: 4608 -> 6912 \n", + "2026-06-26 08:56:30 [INFO ] Grid start: 1024 (4606.25) -> Grid end: 1536 (6910.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 08:56:30 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120224_D10_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120224_D10_B02.tif \n", + "2026-06-26 08:56:30 [INFO ] Granule: 0 -> 2304 \n", + "2026-06-26 08:56:30 [INFO ] Grid start: 0 (-1.75) -> Grid end: 512 (2302.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 08:56:31 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120217_D10_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120217_D10_B02.tif \n", + "2026-06-26 08:56:31 [INFO ] Granule: 2304 -> 4608 \n", + "2026-06-26 08:56:31 [INFO ] Grid start: 512 (2302.25) -> Grid end: 1024 (4606.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 08:56:31 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120221_D10_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120221_D10_B02.tif \n", + "2026-06-26 08:56:31 [INFO ] Granule: 9216 -> 11520 \n", + "2026-06-26 08:56:31 [INFO ] Grid start: 2048 (9214.25) -> Grid end: 2560 (11518.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 08:56:31 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120231_D10_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120231_D10_B02.tif \n", + "2026-06-26 08:56:31 [INFO ] Granule: 6912 -> 9216 \n", + "2026-06-26 08:56:31 [INFO ] Grid start: 1536 (6910.25) -> Grid end: 2048 (9214.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 08:56:31 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120228_D10_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120228_D10_B02.tif \n", + "2026-06-26 08:56:31 [INFO ] VRT saved in: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02.vrt \n", + "2026-06-26 08:56:31 [INFO ] \n", + "2026-06-26 08:56:31 [INFO ] ### DET 11 (BAND 2) ### \n", + "2026-06-26 08:56:31 [INFO ] Grid information: ConvOffset: (0.5, 0.5); Step: (4.5, 4.5); Start: (0, 0); Size: (11520, 2552) \n", + "2026-06-26 08:56:48 [INFO ] Granule: 0 -> 2304 \n", + "2026-06-26 08:56:48 [INFO ] Grid start: 0 (-1.75) -> Grid end: 512 (2302.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 08:56:48 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120221_D11_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120221_D11_B02.tif \n", + "2026-06-26 08:56:48 [INFO ] Granule: 9216 -> 11520 \n", + "2026-06-26 08:56:48 [INFO ] Grid start: 2048 (9214.25) -> Grid end: 2560 (11518.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 08:56:48 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120235_D11_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120235_D11_B02.tif \n", + "2026-06-26 08:56:48 [INFO ] Granule: 4608 -> 6912 \n", + "2026-06-26 08:56:48 [INFO ] Grid start: 1024 (4606.25) -> Grid end: 1536 (6910.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 08:56:48 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120228_D11_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120228_D11_B02.tif \n", + "2026-06-26 08:56:48 [INFO ] Granule: 2304 -> 4608 \n", + "2026-06-26 08:56:48 [INFO ] Grid start: 512 (2302.25) -> Grid end: 1024 (4606.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 08:56:48 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120225_D11_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120225_D11_B02.tif \n", + "2026-06-26 08:56:48 [INFO ] Granule: 6912 -> 9216 \n", + "2026-06-26 08:56:48 [INFO ] Grid start: 1536 (6910.25) -> Grid end: 2048 (9214.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", + "2026-06-26 08:56:48 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120232_D11_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120232_D11_B02.tif \n", + "2026-06-26 08:56:48 [INFO ] VRT saved in: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02.vrt \n", + "2026-06-26 08:56:48 [INFO ] Find the following datastrip metadata file: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/S2B_OPER_MTD_L1B_DS_2BPS_20241019T153411_S20241019T120215.xml \n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Docker execution complete.\n", + "\n", + "Docker images kept.\n", + "\n" + ] + } + ], "source": [ "# === RUN SEN2VM (Docker: BUILD + RUN + CLEAN) ===\n", "\n", @@ -516,10 +745,174 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "id": "a091ccaf", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Using XML: /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml\n", + "Bands from params.json: ['B02']\n", + "Detectors from params.json: ['07', '08', '09', '10', '11']\n", + "Total VRT files found: 5\n", + " ✓ Keep: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02 (detector=07, band=B02)\n", + " ✓ Keep: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02 (detector=10, band=B02)\n", + " ✓ Keep: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02 (detector=08, band=B02)\n", + " ✓ Keep: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02 (detector=11, band=B02)\n", + " ✓ Keep: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02 (detector=09, band=B02)\n", + "\n", + "Filtered VRTs to process: 5\n", + "VRT list: ['S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02', 'S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02', 'S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02', 'S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02', 'S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02']\n", + "Output folder: /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_gdal\n", + "\n", + "=== BUILDING GDAL LATEST CONTAINER ===\n", + "\n", + "Command: docker build --platform=linux/amd64 -t gdal-latest /home/pcastillo/sen2vm/sen2vm-core/sen2vm-notebook/src/gdal-latest \n", + "\n", + "Sending build context to Docker daemon 3.072kB\n", + "Step 1/10 : FROM ubuntu:22.04\n", + " ---> 962f6cadeae0\n", + "Step 2/10 : ENV DEBIAN_FRONTEND=noninteractive\n", + " ---> Using cache\n", + " ---> e6e9ea6fb1e0\n", + "Step 3/10 : RUN apt-get update && apt-get install -y build-essential git cmake pkg-config curl wget zip libcurl4-openssl-dev libproj-dev proj-bin libgeos-dev libsqlite3-dev libtiff-dev libjpeg-dev libpng-dev libzstd-dev liblzma-dev libopenjp2-7-dev libboost-dev python3 python3-pip python3-dev python3-numpy swig ninja-build libhdf5-dev libnetcdf-dev libpq-dev libxml2-dev\n", + " ---> Using cache\n", + " ---> bd1e25e4a887\n", + "Step 4/10 : RUN git clone https://github.com/rouault/gdal.git /gdal && cd /gdal && git fetch --tags && LATEST_TAG=$(git describe --tags `git rev-list --tags --max-count=1`) && echo \"Using GDAL sentinel2_geoloc_missing_granules\" && git checkout sentinel2_geoloc_missing_granules\n", + " ---> Using cache\n", + " ---> bfeced2e5339\n", + "Step 5/10 : RUN mkdir /gdal/build\n", + " ---> Using cache\n", + " ---> b16c40868e8e\n", + "Step 6/10 : RUN cd /gdal/build && cmake .. -GNinja -DCMAKE_BUILD_TYPE=Release -DBUILD_PYTHON_BINDINGS=ON -DGDAL_USE_OPENJPEG=ON -DGDAL_USE_TIFF_INTERNAL=ON -DGDAL_USE_GEOTIFF_INTERNAL=ON -DGDAL_USE_JPEG_INTERNAL=ON\n", + " ---> Using cache\n", + " ---> 06435d37867a\n", + "Step 7/10 : RUN cd /gdal/build && ninja && ninja install\n", + " ---> Using cache\n", + " ---> c502c440c76b\n", + "Step 8/10 : RUN ldconfig\n", + " ---> Using cache\n", + " ---> e0f05073c6a4\n", + "Step 9/10 : RUN gdalinfo --version\n", + " ---> Using cache\n", + " ---> de5dd366334c\n", + "Step 10/10 : ENTRYPOINT [\"/bin/bash\"]\n", + " ---> Using cache\n", + " ---> 33cca57541bf\n", + "Successfully built 33cca57541bf\n", + "Successfully tagged gdal-latest:latest\n", + "GDAL image built successfully.\n", + "\n", + "\n", + "=== GENERATING GDAL SCRIPT ===\n", + "VRTs to process: 5\n", + " - S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02\n", + " - S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02\n", + " - S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02\n", + " - S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02\n", + " - S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02\n", + "\n", + "=== RUNNING GDAL PROCESSING ===\n", + "\n", + "Command: docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR:/workspace -v /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_gdal:/output gdal-latest /workspace/src/gdal_ortho.sh \n", + "\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "DEPRECATED: The legacy builder is deprecated and will be removed in a future release.\n", + " Install the buildx component to build images with BuildKit:\n", + " https://docs.docker.com/go/buildx/\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== ORTHORECTIFICATION ===\n", + "----------------------------------------\n", + "Processing VRT: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02\n", + "----------------------------------------\n", + "Band resolution: 10 m\n", + "Creating output file that is 7037P x 3334L.\n", + "Processing S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02 [1/1] : 0...10...20...30...40...50...60...70...80...90...100 - done in 00:00:10.\n", + "----------------------------------------\n", + "Processing VRT: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02\n", + "----------------------------------------\n", + "Band resolution: 10 m\n", + "Creating output file that is 7037P x 3334L.\n", + "Processing S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02 [1/1] : 0" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Warning 1: Too many points (529 out of 529) failed to transform, unable to compute output bounds.\n", + "Warning 1: Unable to compute source region for output window 0,0,3328,3334, skipping.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "...10...20...30...40...50...60...70...80...90...100 - done in 00:00:10.\n", + "----------------------------------------\n", + "Processing VRT: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02\n", + "----------------------------------------\n", + "Band resolution: 10 m\n", + "Creating output file that is 7037P x 3334L.\n", + "Processing S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02 [1/1] : 0" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Warning 1: Too many points (529 out of 529) failed to transform, unable to compute output bounds.\n", + "Warning 1: Unable to compute source region for output window 3328,0,3709,3334, skipping.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "...10...20...30...40...50...60...70...80...90...100 - done in 00:00:09.\n", + "----------------------------------------\n", + "Processing VRT: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02\n", + "----------------------------------------\n", + "Band resolution: 10 m\n", + "Creating output file that is 7037P x 3334L.\n", + "Processing S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02 [1/1] : 0...10...20...30...40...50...60...70...80...90...100 - done in 00:00:10.\n", + "----------------------------------------\n", + "Processing VRT: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02\n", + "----------------------------------------\n", + "Band resolution: 10 m\n", + "Creating output file that is 7037P x 3334L.\n", + "Processing S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02 [1/1] : 0...10...20...30...40...50...60...70...80...90...100 - done in 00:00:15.\n", + "\n", + "=== MOSAIC GENERATION ===\n", + "\n", + "----------------------------------------\n", + "Creating mosaic for band: B02\n", + "----------------------------------------\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + " Mosaic written -> /output/GDAL_OUTPUT_MOSAIC/ORTHO_mosaic_B02.tif\n", + "\n", + "=== GDAL processing complete ===\n", + "\n", + "GDAL ortho + mosaic complete.\n", + "\n", + "Docker images kept (faster next run, ~4 GB disk usage).\n", + "\n" + ] + } + ], "source": [ "import os\n", "import subprocess\n", @@ -806,7 +1199,7 @@ { "cell_type": "code", "execution_count": null, - "id": "9ceb746c-6830-4bef-ab52-16d463fa12c8", + "id": "838b73c6-4666-4492-8882-be899a53b2da", "metadata": {}, "outputs": [], "source": [] diff --git a/sen2vm-notebook/src/notebook-inverse-grid.ipynb b/sen2vm-notebook/src/notebook-inverse-grid.ipynb index 0fe11948..efc74de6 100644 --- a/sen2vm-notebook/src/notebook-inverse-grid.ipynb +++ b/sen2vm-notebook/src/notebook-inverse-grid.ipynb @@ -10,7 +10,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "2b816cd9-5254-452b-bced-2943eb6b7aec", "metadata": {}, "outputs": [], @@ -20,13 +20,13 @@ "# /!\\/!\\/!\\ CAREFUL, please read the README_Notebooks.md file before\n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "\n", - "WORKDIR = \"PATH/TO/WORKDIR\" # Working directory for sen2vm processing\n", + "WORKDIR = \"/home/pcastillo/sen2vm/WORKDIR\" # Working directory for sen2vm processing\n", "\n", "# Path to downloaded product\n", - "PATH_L1B_DATA = \"PATH/TO/L1B_PRODUCT\"\n", + "PATH_L1B_DATA = \"/home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE\"\n", "\n", "# Path to GIPP directory\n", - "PATH_GIPP = \"PATH/TO/GIPP\"\n", + "PATH_GIPP = \"/home/pcastillo/sen2vm/WORKDIR/GIPP\"\n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "# /!\\/!\\/!\\ If you do not have your own GIPP folder, you may use the inputs-download-notebook to download it, then you may indicate the path were you \n", "# /!\\/!\\/!\\ downloaded it here in PATH_GIPP\n", @@ -34,17 +34,17 @@ "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "\n", "# Path to DEM directory \n", - "PATH_DEM = \"PATH/TO/DEM\"\n", + "PATH_DEM = \"/home/pcastillo/sen2vm/WORKDIR/DEM\"\n", "\n", "# Path to GEOID directory\n", - "PATH_GEOID = \"PATH/TO/GEOID\"\n", + "PATH_GEOID = \"/home/pcastillo/sen2vm/WORKDIR/GEOID\"\n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "# /!\\/!\\/!\\ If you do not have your own GEOID folder, you may use the inputs-download-notebook to download it, then you may indicate the path were you\n", "# /!\\/!\\/!\\ downloaded it here in \n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "\n", "# Path to IERS file\n", - "PATH_IERS = \"PATH/TO/IERS_FILE\"\n", + "PATH_IERS = \"/home/pcastillo/sen2vm/WORKDIR\"\n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "# /!\\/!\\/!\\ If you do not have your own IERS, you may let this path empy (i.e. \"\") and execute the cell number 2 named #IERS Download\n", "# /!\\/!\\/!\\ In this case, the IERS will be downloaded in the WORKDIR\n", @@ -101,10 +101,35 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "8ec4d6f6", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Stopping because PATH_IERS is not empty\n" + ] + }, + { + "ename": "SystemExit", + "evalue": "0", + "output_type": "error", + "traceback": [ + "An exception has occurred, use %tb to see the full traceback.\n", + "\u001b[31mSystemExit\u001b[39m\u001b[31m:\u001b[39m 0\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/pcastillo/sen2vm/sen2vm-core/sen2vm-notebook/src/.venv/lib/python3.13/site-packages/IPython/core/interactiveshell.py:3709: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.\n", + " warn(\"To exit: use 'exit', 'quit', or Ctrl-D.\", stacklevel=1)\n" + ] + } + ], "source": [ "# === DOWNLOAD IERS ===\n", "import os\n", @@ -229,10 +254,22 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "276592b5", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "UserConf directory: /home/pcastillo/sen2vm/WORKDIR/UserConf\n", + "Geoid directory: /home/pcastillo/sen2vm/WORKDIR/GEOID\n", + "/data/IERS/bulletina-xxxvii-042.txt\n", + "Configuration file generated:\n", + "/home/pcastillo/sen2vm/WORKDIR/UserConf/config.json\n" + ] + } + ], "source": [ "# === GENERATE CONFIG.JSON ===\n", "\n", @@ -346,10 +383,24 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "23b1da25", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "UserConf directory: /home/pcastillo/sen2vm/WORKDIR/UserConf\n", + "Found 60 granule folders.\n", + "Detected detectors: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12']\n", + "Detected bands: ['B01', 'B02', 'B03', 'B04', 'B05', 'B06', 'B07', 'B08', 'B09', 'B10', 'B11', 'B12', 'B8A']\n", + "params.json written to: /home/pcastillo/sen2vm/WORKDIR/UserConf/params.json\n", + " - Detectors: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12']\n", + " - Bands: ['B02']\n" + ] + } + ], "source": [ "# === GENERATE PARAMS.JSON ===\n", "\n", @@ -447,10 +498,161 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "id": "572bd72a", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Building Docker image 'sen2vm' from: /home/pcastillo/sen2vm/sen2vm-core\n", + "Command: docker build -t sen2vm /home/pcastillo/sen2vm/sen2vm-core \n", + "\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "DEPRECATED: The legacy builder is deprecated and will be removed in a future release.\n", + " Install the buildx component to build images with BuildKit:\n", + " https://docs.docker.com/go/buildx/\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Sending build context to Docker daemon 1.718GB\n", + "Step 1/5 : FROM ghcr.io/sen2vm/sen2vm-build-env:latest AS launcher\n", + " ---> a5369801b500\n", + "Step 2/5 : ENV SEN2VM_VERSION=1.1.4\n", + " ---> Using cache\n", + " ---> 14de44fa18ab\n", + "Step 3/5 : WORKDIR /Sen2vm\n", + " ---> Using cache\n", + " ---> b4079a1b81e1\n", + "Step 4/5 : RUN curl -L -o sen2vm-core.jar https://github.com/sen2vm/sen2vm-core/releases/download/${SEN2VM_VERSION}/sen2vm-core-${SEN2VM_VERSION}.jar\n", + " ---> Using cache\n", + " ---> 01c51fc5d7d7\n", + "Step 5/5 : ENTRYPOINT [\"java\", \"-jar\",\"sen2vm-core.jar\"]\n", + " ---> Using cache\n", + " ---> 5be1977daa50\n", + "Successfully built 5be1977daa50\n", + "Successfully tagged sen2vm:latest\n", + "Docker image built successfully.\n", + "\n", + "Running Docker container...\n", + "\n", + "Command: docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/DEM:/data/DEM -v /home/pcastillo/sen2vm/WORKDIR/GIPP:/data/GIPP -v /home/pcastillo/sen2vm/WORKDIR/GEOID:/data/GEOID -v /home/pcastillo/sen2vm/WORKDIR:/data/IERS -v /home/pcastillo/sen2vm/WORKDIR:/workspace sen2vm -c /workspace/UserConf/config.json -p /workspace/UserConf/params.json \n", + "\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2026-06-26 09:12:56 [INFO ] Start Sen2VM \n", + "2026-06-26 09:12:57 [INFO ] Parsing file /workspace/UserConf/config.json \n", + "2026-06-26 09:12:57 [INFO ] Reading IERS file at: /data/IERS/bulletina-xxxvii-042.txt \n", + "2026-06-26 09:12:57 [INFO ] Parsing file /workspace/UserConf/params.json \n", + "2026-06-26 09:12:57 [INFO ] Detectors list: [DETECTOR_1, DETECTOR_2, DETECTOR_3, DETECTOR_4, DETECTOR_5, DETECTOR_6, DETECTOR_7, DETECTOR_8, DETECTOR_9, DETECTOR_10, DETECTOR_11, DETECTOR_12] \n", + "2026-06-26 09:12:57 [INFO ] Bands list: [BAND_2] \n", + "2026-06-26 09:12:57 [INFO ] Find the following datastrip metadata file: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/S2B_OPER_MTD_L1B_DS_2BPS_20241019T153411_S20241019T120215.xml \n", + "2026-06-26 09:12:58 [INFO ] Initializing: copy of the Orekit-data: /Sen2vm/orekit-data \n", + "2026-06-26 09:12:58 [INFO ] Orekit-data: /Sen2vm/orekit-data \n", + "2026-06-26 09:13:05 [INFO ] Get through GIPP folder: /data/GIPP/S2B \n", + "2026-06-26 09:13:05 [INFO ] Read blind pixel file: /data/GIPP/S2B/S2B_OPER_GIP_BLINDP_MPC__20170221T000000_V20170101T000000_21000101T000000_B00.xml \n", + "2026-06-26 09:13:05 [INFO ] Read spacecraft model file: /data/GIPP/S2B/S2B_OPER_GIP_SPAMOD_MPC__20231122T110035_V20231123T000000_21000101T000000_B00.xml \n", + "2026-06-26 09:13:05 [INFO ] Read viewingDirection file: /data/GIPP/S2B/S2B_OPER_GIP_VIEDIR_MPC__20170512T114736_V20170322T000000_21000101T000000_B02.xml \n", + "2026-06-26 09:13:06 [INFO ] setAndProcessDataStrip listOfFiles/data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11 \n", + "2026-06-26 09:13:06 [INFO ] Datastrip S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11 \n", + "2026-06-26 09:13:06 [INFO ] EGSG read from configuration file (for inverse location): EPSG:32628 \n", + "2026-06-26 09:13:06 [INFO ] \n", + "2026-06-26 09:13:06 [INFO ] Starting grids generation \n", + "2026-06-26 09:13:06 [INFO ] \n", + "2026-06-26 09:13:06 [INFO ] ############### \n", + "2026-06-26 09:13:06 [INFO ] ### BAND 2 ### \n", + "2026-06-26 09:13:06 [INFO ] ############### \n", + "2026-06-26 09:13:06 [INFO ] Grid resolution: 45.0 \n", + "2026-06-26 09:13:06 [INFO ] Band resolution: 10.0 \n", + "2026-06-26 09:13:06 [INFO ] \n", + "2026-06-26 09:13:06 [INFO ] ### DET 01 (BAND 2) ### \n", + "2026-06-26 09:13:06 [INFO ] # Grid information \n", + "2026-06-26 09:13:06 [INFO ] Step: (-45.0, 45.0); UL: (3641682.5, 283887.5) LR: (3608292.5, 354312.5) \n", + "2026-06-26 09:13:22 [INFO ] Granule grid saved in: /workspace/output/INVERSE/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D01_B02.tif \n", + "2026-06-26 09:13:22 [INFO ] \n", + "2026-06-26 09:13:22 [INFO ] ### DET 02 (BAND 2) ### \n", + "2026-06-26 09:13:22 [INFO ] # Grid information \n", + "2026-06-26 09:13:22 [INFO ] Step: (-45.0, 45.0); UL: (3641682.5, 283887.5) LR: (3608292.5, 354312.5) \n", + "2026-06-26 09:13:38 [INFO ] Granule grid saved in: /workspace/output/INVERSE/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D02_B02.tif \n", + "2026-06-26 09:13:38 [INFO ] \n", + "2026-06-26 09:13:38 [INFO ] ### DET 03 (BAND 2) ### \n", + "2026-06-26 09:13:38 [INFO ] # Grid information \n", + "2026-06-26 09:13:38 [INFO ] Step: (-45.0, 45.0); UL: (3641682.5, 283887.5) LR: (3608292.5, 354312.5) \n", + "2026-06-26 09:13:53 [INFO ] Granule grid saved in: /workspace/output/INVERSE/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D03_B02.tif \n", + "2026-06-26 09:13:53 [INFO ] \n", + "2026-06-26 09:13:53 [INFO ] ### DET 04 (BAND 2) ### \n", + "2026-06-26 09:13:53 [INFO ] # Grid information \n", + "2026-06-26 09:13:53 [INFO ] Step: (-45.0, 45.0); UL: (3641682.5, 283887.5) LR: (3608292.5, 354312.5) \n", + "2026-06-26 09:14:09 [INFO ] Granule grid saved in: /workspace/output/INVERSE/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D04_B02.tif \n", + "2026-06-26 09:14:09 [INFO ] \n", + "2026-06-26 09:14:09 [INFO ] ### DET 05 (BAND 2) ### \n", + "2026-06-26 09:14:09 [INFO ] # Grid information \n", + "2026-06-26 09:14:09 [INFO ] Step: (-45.0, 45.0); UL: (3641682.5, 283887.5) LR: (3608292.5, 354312.5) \n", + "2026-06-26 09:14:24 [INFO ] Granule grid saved in: /workspace/output/INVERSE/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D05_B02.tif \n", + "2026-06-26 09:14:24 [INFO ] \n", + "2026-06-26 09:14:24 [INFO ] ### DET 06 (BAND 2) ### \n", + "2026-06-26 09:14:24 [INFO ] # Grid information \n", + "2026-06-26 09:14:24 [INFO ] Step: (-45.0, 45.0); UL: (3641682.5, 283887.5) LR: (3608292.5, 354312.5) \n", + "2026-06-26 09:14:40 [INFO ] Granule grid saved in: /workspace/output/INVERSE/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D06_B02.tif \n", + "2026-06-26 09:14:40 [INFO ] \n", + "2026-06-26 09:14:40 [INFO ] ### DET 07 (BAND 2) ### \n", + "2026-06-26 09:14:40 [INFO ] # Grid information \n", + "2026-06-26 09:14:40 [INFO ] Step: (-45.0, 45.0); UL: (3641682.5, 283887.5) LR: (3608292.5, 354312.5) \n", + "2026-06-26 09:14:56 [INFO ] Granule grid saved in: /workspace/output/INVERSE/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02.tif \n", + "2026-06-26 09:14:56 [INFO ] \n", + "2026-06-26 09:14:56 [INFO ] ### DET 08 (BAND 2) ### \n", + "2026-06-26 09:14:56 [INFO ] # Grid information \n", + "2026-06-26 09:14:56 [INFO ] Step: (-45.0, 45.0); UL: (3641682.5, 283887.5) LR: (3608292.5, 354312.5) \n", + "2026-06-26 09:15:13 [INFO ] Granule grid saved in: /workspace/output/INVERSE/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02.tif \n", + "2026-06-26 09:15:13 [INFO ] \n", + "2026-06-26 09:15:13 [INFO ] ### DET 09 (BAND 2) ### \n", + "2026-06-26 09:15:13 [INFO ] # Grid information \n", + "2026-06-26 09:15:13 [INFO ] Step: (-45.0, 45.0); UL: (3641682.5, 283887.5) LR: (3608292.5, 354312.5) \n", + "2026-06-26 09:15:30 [INFO ] Granule grid saved in: /workspace/output/INVERSE/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02.tif \n", + "2026-06-26 09:15:30 [INFO ] \n", + "2026-06-26 09:15:30 [INFO ] ### DET 10 (BAND 2) ### \n", + "2026-06-26 09:15:30 [INFO ] # Grid information \n", + "2026-06-26 09:15:30 [INFO ] Step: (-45.0, 45.0); UL: (3641682.5, 283887.5) LR: (3608292.5, 354312.5) \n", + "2026-06-26 09:15:48 [INFO ] Granule grid saved in: /workspace/output/INVERSE/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02.tif \n", + "2026-06-26 09:15:48 [INFO ] \n", + "2026-06-26 09:15:48 [INFO ] ### DET 11 (BAND 2) ### \n", + "2026-06-26 09:15:48 [INFO ] # Grid information \n", + "2026-06-26 09:15:48 [INFO ] Step: (-45.0, 45.0); UL: (3641682.5, 283887.5) LR: (3608292.5, 354312.5) \n", + "2026-06-26 09:16:04 [INFO ] Granule grid saved in: /workspace/output/INVERSE/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02.tif \n", + "2026-06-26 09:16:04 [INFO ] \n", + "2026-06-26 09:16:04 [INFO ] ### DET 12 (BAND 2) ### \n", + "2026-06-26 09:16:04 [INFO ] # Grid information \n", + "2026-06-26 09:16:04 [INFO ] Step: (-45.0, 45.0); UL: (3641682.5, 283887.5) LR: (3608292.5, 354312.5) \n", + "2026-06-26 09:16:19 [INFO ] Granule grid saved in: /workspace/output/INVERSE/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D12_B02.tif \n", + "2026-06-26 09:16:19 [INFO ] Find the following datastrip metadata file: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/S2B_OPER_MTD_L1B_DS_2BPS_20241019T153411_S20241019T120215.xml \n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Docker execution complete.\n", + "\n", + "Docker images kept.\n", + "\n" + ] + } + ], "source": [ "# === RUN SEN2VM (Docker: BUILD + RUN + CLEAN) ===\n", "\n", @@ -529,10 +731,612 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "id": "61ebba54-43f0-4d39-9589-40c87609f70e", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Product: S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE\n", + "Using XML: /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml\n", + "Bands from params.json: ['B02']\n", + "Detectors from params.json: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12']\n", + "\n", + "=== BUILDING GDAL CONTAINER ===\n", + "\n", + "Command:\n", + "docker build --platform=linux/amd64 -t gdal-latest /home/pcastillo/sen2vm/sen2vm-core/sen2vm-notebook/src/gdal-latest\n", + "Sending build context to Docker daemon 3.072kB\n", + "Step 1/10 : FROM ubuntu:22.04\n", + " ---> 962f6cadeae0\n", + "Step 2/10 : ENV DEBIAN_FRONTEND=noninteractive\n", + " ---> Using cache\n", + " ---> e6e9ea6fb1e0\n", + "Step 3/10 : RUN apt-get update && apt-get install -y build-essential git cmake pkg-config curl wget zip libcurl4-openssl-dev libproj-dev proj-bin libgeos-dev libsqlite3-dev libtiff-dev libjpeg-dev libpng-dev libzstd-dev liblzma-dev libopenjp2-7-dev libboost-dev python3 python3-pip python3-dev python3-numpy swig ninja-build libhdf5-dev libnetcdf-dev libpq-dev libxml2-dev\n", + " ---> Using cache\n", + " ---> bd1e25e4a887\n", + "Step 4/10 : RUN git clone https://github.com/rouault/gdal.git /gdal && cd /gdal && git fetch --tags && LATEST_TAG=$(git describe --tags `git rev-list --tags --max-count=1`) && echo \"Using GDAL sentinel2_geoloc_missing_granules\" && git checkout sentinel2_geoloc_missing_granules\n", + " ---> Using cache\n", + " ---> bfeced2e5339\n", + "Step 5/10 : RUN mkdir /gdal/build\n", + " ---> Using cache\n", + " ---> b16c40868e8e\n", + "Step 6/10 : RUN cd /gdal/build && cmake .. -GNinja -DCMAKE_BUILD_TYPE=Release -DBUILD_PYTHON_BINDINGS=ON -DGDAL_USE_OPENJPEG=ON -DGDAL_USE_TIFF_INTERNAL=ON -DGDAL_USE_GEOTIFF_INTERNAL=ON -DGDAL_USE_JPEG_INTERNAL=ON\n", + " ---> Using cache\n", + " ---> 06435d37867a\n", + "Step 7/10 : RUN cd /gdal/build && ninja && ninja install\n", + " ---> Using cache\n", + " ---> c502c440c76b\n", + "Step 8/10 : RUN ldconfig\n", + " ---> Using cache\n", + " ---> e0f05073c6a4\n", + "Step 9/10 : RUN gdalinfo --version\n", + " ---> Using cache\n", + " ---> de5dd366334c\n", + "Step 10/10 : ENTRYPOINT [\"/bin/bash\"]\n", + " ---> Using cache\n", + " ---> 33cca57541bf\n", + "Successfully built 33cca57541bf\n", + "Successfully tagged gdal-latest:latest\n", + "\n", + "GDAL image built successfully.\n", + "\n", + "\n", + "Found 12 inverse grids:\n", + "\n", + " S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D12_B02.tif\n", + " S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02.tif\n", + " S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D06_B02.tif\n", + " S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02.tif\n", + " S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02.tif\n", + " S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02.tif\n", + " S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D05_B02.tif\n", + " S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D01_B02.tif\n", + " S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D03_B02.tif\n", + " S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D04_B02.tif\n", + " S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02.tif\n", + " S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D02_B02.tif\n", + "\n", + "=================================================\n", + "Processing: S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D12_B02.tif\n", + "=================================================\n", + "Detector: 12\n", + "Band: B02\n", + "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D12_B02\n", + "Resolution: 10\n", + "Width : 7037\n", + "Height: 3334\n", + "\n", + "=== EXTRACTION ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", + " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D12_B02\" \"/output/raw/raw_D12_B02.tif\"\n", + " \n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "DEPRECATED: The legacy builder is deprecated and will be removed in a future release.\n", + " Install the buildx component to build images with BuildKit:\n", + " https://docs.docker.com/go/buildx/\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Input file size is 2552, 11520\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "=== OTB RESAMPLING ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D12_B02.tif -io.out /output/otb_no_georef/ortho_D12_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D12_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", + "2026-06-26 09:16:25 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", + "2026-06-26 09:16:25 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", + "2026-06-26 09:16:25 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", + "2026-06-26 09:16:25 (INFO): Loading metadata from official product\n", + "2026-06-26 09:16:25 (INFO): Loading metadata from official product\n", + "2026-06-26 09:16:25 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:16:25 (INFO): Estimated memory for full processing: 234.894MB (avail.: 256 MB), optimal image partitioning: 1 blocks\n", + "2026-06-26 09:16:25 (INFO): File /output/otb_no_georef/ortho_D12_B02.tif will be written in 1 blocks of 7037x3334 pixels\n", + "Writing /output/otb_no_georef/ortho_D12_B02.tif...: 100% [**************************************************] (0s)\n", + "OTB success\n", + "\n", + "=== ADD GEOREF ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", + " gdal_translate -a_srs EPSG:32628 /output/otb_no_georef/ortho_D12_B02.tif /output/output_georef/ortho_D12_B02_georef.tif\n", + " \n", + "Input file size is 7037, 3334\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "Finished: ortho_D12_B02_georef.tif\n", + "\n", + "=================================================\n", + "Processing: S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02.tif\n", + "=================================================\n", + "Detector: 09\n", + "Band: B02\n", + "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02\n", + "Resolution: 10\n", + "Width : 7037\n", + "Height: 3334\n", + "\n", + "=== EXTRACTION ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", + " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02\" \"/output/raw/raw_D09_B02.tif\"\n", + " \n", + "Input file size is 2552, 11520\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "=== OTB RESAMPLING ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D09_B02.tif -io.out /output/otb_no_georef/ortho_D09_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", + "2026-06-26 09:16:30 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", + "2026-06-26 09:16:30 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", + "2026-06-26 09:16:30 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", + "2026-06-26 09:16:30 (INFO): Loading metadata from official product\n", + "2026-06-26 09:16:30 (INFO): Loading metadata from official product\n", + "2026-06-26 09:16:30 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:16:30 (INFO): Estimated memory for full processing: 390.826MB (avail.: 256 MB), optimal image partitioning: 2 blocks\n", + "2026-06-26 09:16:30 (INFO): File /output/otb_no_georef/ortho_D09_B02.tif will be written in 3 blocks of 7037x1112 pixels\n", + "Writing /output/otb_no_georef/ortho_D09_B02.tif...: 100% [**************************************************] (3s)\n", + "OTB success\n", + "\n", + "=== ADD GEOREF ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", + " gdal_translate -a_srs EPSG:32628 /output/otb_no_georef/ortho_D09_B02.tif /output/output_georef/ortho_D09_B02_georef.tif\n", + " \n", + "Input file size is 7037, 3334\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "Finished: ortho_D09_B02_georef.tif\n", + "\n", + "=================================================\n", + "Processing: S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D06_B02.tif\n", + "=================================================\n", + "Detector: 06\n", + "Band: B02\n", + "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D06_B02\n", + "Resolution: 10\n", + "Width : 7037\n", + "Height: 3334\n", + "\n", + "=== EXTRACTION ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", + " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D06_B02\" \"/output/raw/raw_D06_B02.tif\"\n", + " \n", + "Input file size is 2552, 11520\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "=== OTB RESAMPLING ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D06_B02.tif -io.out /output/otb_no_georef/ortho_D06_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D06_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", + "2026-06-26 09:16:39 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", + "2026-06-26 09:16:39 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", + "2026-06-26 09:16:39 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", + "2026-06-26 09:16:39 (INFO): Loading metadata from official product\n", + "2026-06-26 09:16:39 (INFO): Loading metadata from official product\n", + "2026-06-26 09:16:39 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:16:39 (INFO): Estimated memory for full processing: 234.894MB (avail.: 256 MB), optimal image partitioning: 1 blocks\n", + "2026-06-26 09:16:39 (INFO): File /output/otb_no_georef/ortho_D06_B02.tif will be written in 1 blocks of 7037x3334 pixels\n", + "Writing /output/otb_no_georef/ortho_D06_B02.tif...: 100% [**************************************************] (0s)\n", + "OTB success\n", + "\n", + "=== ADD GEOREF ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", + " gdal_translate -a_srs EPSG:32628 /output/otb_no_georef/ortho_D06_B02.tif /output/output_georef/ortho_D06_B02_georef.tif\n", + " \n", + "Input file size is 7037, 3334\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "Finished: ortho_D06_B02_georef.tif\n", + "\n", + "=================================================\n", + "Processing: S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02.tif\n", + "=================================================\n", + "Detector: 11\n", + "Band: B02\n", + "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02\n", + "Resolution: 10\n", + "Width : 7037\n", + "Height: 3334\n", + "\n", + "=== EXTRACTION ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", + " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02\" \"/output/raw/raw_D11_B02.tif\"\n", + " \n", + "Input file size is 2552, 11520\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "=== OTB RESAMPLING ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D11_B02.tif -io.out /output/otb_no_georef/ortho_D11_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", + "2026-06-26 09:16:44 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", + "2026-06-26 09:16:44 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", + "2026-06-26 09:16:44 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", + "2026-06-26 09:16:44 (INFO): Loading metadata from official product\n", + "2026-06-26 09:16:44 (INFO): Loading metadata from official product\n", + "2026-06-26 09:16:44 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:16:44 (INFO): Estimated memory for full processing: 234.894MB (avail.: 256 MB), optimal image partitioning: 1 blocks\n", + "2026-06-26 09:16:44 (INFO): File /output/otb_no_georef/ortho_D11_B02.tif will be written in 1 blocks of 7037x3334 pixels\n", + "Writing /output/otb_no_georef/ortho_D11_B02.tif...: 100% [**************************************************] (1s)\n", + "OTB success\n", + "\n", + "=== ADD GEOREF ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", + " gdal_translate -a_srs EPSG:32628 /output/otb_no_georef/ortho_D11_B02.tif /output/output_georef/ortho_D11_B02_georef.tif\n", + " \n", + "Input file size is 7037, 3334\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "Finished: ortho_D11_B02_georef.tif\n", + "\n", + "=================================================\n", + "Processing: S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02.tif\n", + "=================================================\n", + "Detector: 08\n", + "Band: B02\n", + "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02\n", + "Resolution: 10\n", + "Width : 7037\n", + "Height: 3334\n", + "\n", + "=== EXTRACTION ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", + " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02\" \"/output/raw/raw_D08_B02.tif\"\n", + " \n", + "Input file size is 2552, 11520\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "=== OTB RESAMPLING ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D08_B02.tif -io.out /output/otb_no_georef/ortho_D08_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", + "2026-06-26 09:16:51 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", + "2026-06-26 09:16:51 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", + "2026-06-26 09:16:51 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", + "2026-06-26 09:16:51 (INFO): Loading metadata from official product\n", + "2026-06-26 09:16:51 (INFO): Loading metadata from official product\n", + "2026-06-26 09:16:51 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:16:51 (INFO): Estimated memory for full processing: 234.894MB (avail.: 256 MB), optimal image partitioning: 1 blocks\n", + "2026-06-26 09:16:51 (INFO): File /output/otb_no_georef/ortho_D08_B02.tif will be written in 1 blocks of 7037x3334 pixels\n", + "Writing /output/otb_no_georef/ortho_D08_B02.tif...: 100% [**************************************************] (2s)\n", + "OTB success\n", + "\n", + "=== ADD GEOREF ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", + " gdal_translate -a_srs EPSG:32628 /output/otb_no_georef/ortho_D08_B02.tif /output/output_georef/ortho_D08_B02_georef.tif\n", + " \n", + "Input file size is 7037, 3334\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "Finished: ortho_D08_B02_georef.tif\n", + "\n", + "=================================================\n", + "Processing: S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02.tif\n", + "=================================================\n", + "Detector: 07\n", + "Band: B02\n", + "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02\n", + "Resolution: 10\n", + "Width : 7037\n", + "Height: 3334\n", + "\n", + "=== EXTRACTION ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", + " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02\" \"/output/raw/raw_D07_B02.tif\"\n", + " \n", + "Input file size is 2552, 11520\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "=== OTB RESAMPLING ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D07_B02.tif -io.out /output/otb_no_georef/ortho_D07_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", + "2026-06-26 09:16:59 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", + "2026-06-26 09:16:59 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", + "2026-06-26 09:16:59 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", + "2026-06-26 09:16:59 (INFO): Loading metadata from official product\n", + "2026-06-26 09:16:59 (INFO): Loading metadata from official product\n", + "2026-06-26 09:16:59 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:16:59 (INFO): Estimated memory for full processing: 234.894MB (avail.: 256 MB), optimal image partitioning: 1 blocks\n", + "2026-06-26 09:16:59 (INFO): File /output/otb_no_georef/ortho_D07_B02.tif will be written in 1 blocks of 7037x3334 pixels\n", + "Writing /output/otb_no_georef/ortho_D07_B02.tif...: 100% [**************************************************] (1s)\n", + "OTB success\n", + "\n", + "=== ADD GEOREF ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", + " gdal_translate -a_srs EPSG:32628 /output/otb_no_georef/ortho_D07_B02.tif /output/output_georef/ortho_D07_B02_georef.tif\n", + " \n", + "Input file size is 7037, 3334\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "Finished: ortho_D07_B02_georef.tif\n", + "\n", + "=================================================\n", + "Processing: S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D05_B02.tif\n", + "=================================================\n", + "Detector: 05\n", + "Band: B02\n", + "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D05_B02\n", + "Resolution: 10\n", + "Width : 7037\n", + "Height: 3334\n", + "\n", + "=== EXTRACTION ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", + " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D05_B02\" \"/output/raw/raw_D05_B02.tif\"\n", + " \n", + "Input file size is 2552, 11520\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "=== OTB RESAMPLING ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D05_B02.tif -io.out /output/otb_no_georef/ortho_D05_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D05_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", + "2026-06-26 09:17:06 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", + "2026-06-26 09:17:06 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", + "2026-06-26 09:17:06 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", + "2026-06-26 09:17:06 (INFO): Loading metadata from official product\n", + "2026-06-26 09:17:06 (INFO): Loading metadata from official product\n", + "2026-06-26 09:17:06 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:17:06 (INFO): Estimated memory for full processing: 234.894MB (avail.: 256 MB), optimal image partitioning: 1 blocks\n", + "2026-06-26 09:17:06 (INFO): File /output/otb_no_georef/ortho_D05_B02.tif will be written in 1 blocks of 7037x3334 pixels\n", + "Writing /output/otb_no_georef/ortho_D05_B02.tif...: 100% [**************************************************] (0s)\n", + "OTB success\n", + "\n", + "=== ADD GEOREF ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", + " gdal_translate -a_srs EPSG:32628 /output/otb_no_georef/ortho_D05_B02.tif /output/output_georef/ortho_D05_B02_georef.tif\n", + " \n", + "Input file size is 7037, 3334\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "Finished: ortho_D05_B02_georef.tif\n", + "\n", + "=================================================\n", + "Processing: S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D01_B02.tif\n", + "=================================================\n", + "Detector: 01\n", + "Band: B02\n", + "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D01_B02\n", + "Resolution: 10\n", + "Width : 7037\n", + "Height: 3334\n", + "\n", + "=== EXTRACTION ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", + " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D01_B02\" \"/output/raw/raw_D01_B02.tif\"\n", + " \n", + "Input file size is 2552, 11520\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "=== OTB RESAMPLING ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D01_B02.tif -io.out /output/otb_no_georef/ortho_D01_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D01_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", + "2026-06-26 09:17:11 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", + "2026-06-26 09:17:11 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", + "2026-06-26 09:17:11 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", + "2026-06-26 09:17:11 (INFO): Loading metadata from official product\n", + "2026-06-26 09:17:11 (INFO): Loading metadata from official product\n", + "2026-06-26 09:17:11 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:17:11 (INFO): Estimated memory for full processing: 234.894MB (avail.: 256 MB), optimal image partitioning: 1 blocks\n", + "2026-06-26 09:17:11 (INFO): File /output/otb_no_georef/ortho_D01_B02.tif will be written in 1 blocks of 7037x3334 pixels\n", + "Writing /output/otb_no_georef/ortho_D01_B02.tif...: 100% [**************************************************] (0s)\n", + "OTB success\n", + "\n", + "=== ADD GEOREF ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", + " gdal_translate -a_srs EPSG:32628 /output/otb_no_georef/ortho_D01_B02.tif /output/output_georef/ortho_D01_B02_georef.tif\n", + " \n", + "Input file size is 7037, 3334\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "Finished: ortho_D01_B02_georef.tif\n", + "\n", + "=================================================\n", + "Processing: S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D03_B02.tif\n", + "=================================================\n", + "Detector: 03\n", + "Band: B02\n", + "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D03_B02\n", + "Resolution: 10\n", + "Width : 7037\n", + "Height: 3334\n", + "\n", + "=== EXTRACTION ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", + " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D03_B02\" \"/output/raw/raw_D03_B02.tif\"\n", + " \n", + "Input file size is 2552, 11520\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "=== OTB RESAMPLING ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D03_B02.tif -io.out /output/otb_no_georef/ortho_D03_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D03_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", + "2026-06-26 09:17:17 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", + "2026-06-26 09:17:17 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", + "2026-06-26 09:17:17 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", + "2026-06-26 09:17:17 (INFO): Loading metadata from official product\n", + "2026-06-26 09:17:17 (INFO): Loading metadata from official product\n", + "2026-06-26 09:17:17 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:17:17 (INFO): Estimated memory for full processing: 234.894MB (avail.: 256 MB), optimal image partitioning: 1 blocks\n", + "2026-06-26 09:17:17 (INFO): File /output/otb_no_georef/ortho_D03_B02.tif will be written in 1 blocks of 7037x3334 pixels\n", + "Writing /output/otb_no_georef/ortho_D03_B02.tif...: 100% [**************************************************] (0s)\n", + "OTB success\n", + "\n", + "=== ADD GEOREF ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", + " gdal_translate -a_srs EPSG:32628 /output/otb_no_georef/ortho_D03_B02.tif /output/output_georef/ortho_D03_B02_georef.tif\n", + " \n", + "Input file size is 7037, 3334\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "Finished: ortho_D03_B02_georef.tif\n", + "\n", + "=================================================\n", + "Processing: S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D04_B02.tif\n", + "=================================================\n", + "Detector: 04\n", + "Band: B02\n", + "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D04_B02\n", + "Resolution: 10\n", + "Width : 7037\n", + "Height: 3334\n", + "\n", + "=== EXTRACTION ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", + " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D04_B02\" \"/output/raw/raw_D04_B02.tif\"\n", + " \n", + "Input file size is 2552, 11520\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "=== OTB RESAMPLING ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D04_B02.tif -io.out /output/otb_no_georef/ortho_D04_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D04_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", + "2026-06-26 09:17:23 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", + "2026-06-26 09:17:23 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", + "2026-06-26 09:17:23 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", + "2026-06-26 09:17:23 (INFO): Loading metadata from official product\n", + "2026-06-26 09:17:23 (INFO): Loading metadata from official product\n", + "2026-06-26 09:17:23 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:17:23 (INFO): Estimated memory for full processing: 234.894MB (avail.: 256 MB), optimal image partitioning: 1 blocks\n", + "2026-06-26 09:17:23 (INFO): File /output/otb_no_georef/ortho_D04_B02.tif will be written in 1 blocks of 7037x3334 pixels\n", + "Writing /output/otb_no_georef/ortho_D04_B02.tif...: 100% [**************************************************] (0s)\n", + "OTB success\n", + "\n", + "=== ADD GEOREF ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", + " gdal_translate -a_srs EPSG:32628 /output/otb_no_georef/ortho_D04_B02.tif /output/output_georef/ortho_D04_B02_georef.tif\n", + " \n", + "Input file size is 7037, 3334\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "Finished: ortho_D04_B02_georef.tif\n", + "\n", + "=================================================\n", + "Processing: S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02.tif\n", + "=================================================\n", + "Detector: 10\n", + "Band: B02\n", + "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02\n", + "Resolution: 10\n", + "Width : 7037\n", + "Height: 3334\n", + "\n", + "=== EXTRACTION ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", + " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02\" \"/output/raw/raw_D10_B02.tif\"\n", + " \n", + "Input file size is 2552, 11520\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "=== OTB RESAMPLING ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D10_B02.tif -io.out /output/otb_no_georef/ortho_D10_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", + "2026-06-26 09:17:29 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", + "2026-06-26 09:17:29 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", + "2026-06-26 09:17:29 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", + "2026-06-26 09:17:29 (INFO): Loading metadata from official product\n", + "2026-06-26 09:17:29 (INFO): Loading metadata from official product\n", + "2026-06-26 09:17:29 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:17:29 (INFO): Estimated memory for full processing: 234.894MB (avail.: 256 MB), optimal image partitioning: 1 blocks\n", + "2026-06-26 09:17:29 (INFO): File /output/otb_no_georef/ortho_D10_B02.tif will be written in 1 blocks of 7037x3334 pixels\n", + "Writing /output/otb_no_georef/ortho_D10_B02.tif...: 100% [**************************************************] (2s)\n", + "OTB success\n", + "\n", + "=== ADD GEOREF ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", + " gdal_translate -a_srs EPSG:32628 /output/otb_no_georef/ortho_D10_B02.tif /output/output_georef/ortho_D10_B02_georef.tif\n", + " \n", + "Input file size is 7037, 3334\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "Finished: ortho_D10_B02_georef.tif\n", + "\n", + "=================================================\n", + "Processing: S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D02_B02.tif\n", + "=================================================\n", + "Detector: 02\n", + "Band: B02\n", + "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D02_B02\n", + "Resolution: 10\n", + "Width : 7037\n", + "Height: 3334\n", + "\n", + "=== EXTRACTION ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", + " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D02_B02\" \"/output/raw/raw_D02_B02.tif\"\n", + " \n", + "Input file size is 2552, 11520\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "=== OTB RESAMPLING ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D02_B02.tif -io.out /output/otb_no_georef/ortho_D02_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D02_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", + "2026-06-26 09:17:37 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", + "2026-06-26 09:17:37 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", + "2026-06-26 09:17:37 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", + "2026-06-26 09:17:37 (INFO): Loading metadata from official product\n", + "2026-06-26 09:17:37 (INFO): Loading metadata from official product\n", + "2026-06-26 09:17:37 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:17:37 (INFO): Estimated memory for full processing: 234.894MB (avail.: 256 MB), optimal image partitioning: 1 blocks\n", + "2026-06-26 09:17:37 (INFO): File /output/otb_no_georef/ortho_D02_B02.tif will be written in 1 blocks of 7037x3334 pixels\n", + "Writing /output/otb_no_georef/ortho_D02_B02.tif...: 100% [**************************************************] (0s)\n", + "OTB success\n", + "\n", + "=== ADD GEOREF ===\n", + "\n", + "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", + " gdal_translate -a_srs EPSG:32628 /output/otb_no_georef/ortho_D02_B02.tif /output/output_georef/ortho_D02_B02_georef.tif\n", + " \n", + "Input file size is 7037, 3334\n", + "0...10...20...30...40...50...60...70...80...90...100 - done.\n", + "\n", + "Finished: ortho_D02_B02_georef.tif\n", + "\n", + "=== MOSAIC CREATION ===\n", + "\n", + "Bands detected: {'B02'}\n", + "\n", + "----------------------------------------\n", + "Creating mosaic for band: B02\n", + "----------------------------------------\n", + "Found 12 files\n", + " ortho_D01_B02_georef.tif\n", + " ortho_D02_B02_georef.tif\n", + " ortho_D03_B02_georef.tif\n", + " ortho_D04_B02_georef.tif\n", + " ortho_D05_B02_georef.tif\n", + " ortho_D06_B02_georef.tif\n", + " ortho_D07_B02_georef.tif\n", + " ortho_D08_B02_georef.tif\n", + " ortho_D09_B02_georef.tif\n", + " ortho_D10_B02_georef.tif\n", + " ortho_D11_B02_georef.tif\n", + " ortho_D12_B02_georef.tif\n", + "\n", + "Running mosaic:\n", + " gdal_merge.py -o /output/mosaic/ORTHO_mosaic_B02.tif -of GTiff -co COMPRESS=LZW -co TILED=YES -ot UInt16 -n 0 -a_nodata 0 /output/output_georef/ortho_D01_B02_georef.tif /output/output_georef/ortho_D02_B02_georef.tif /output/output_georef/ortho_D03_B02_georef.tif /output/output_georef/ortho_D04_B02_georef.tif /output/output_georef/ortho_D05_B02_georef.tif /output/output_georef/ortho_D06_B02_georef.tif /output/output_georef/ortho_D07_B02_georef.tif /output/output_georef/ortho_D08_B02_georef.tif /output/output_georef/ortho_D09_B02_georef.tif /output/output_georef/ortho_D10_B02_georef.tif /output/output_georef/ortho_D11_B02_georef.tif /output/output_georef/ortho_D12_B02_georef.tif \n", + "0...10...20...30...40...50...60...70...80...90...100 - done in 00:00:09.\n", + "Mosaic written → /home/pcastillo/sen2vm/WORKDIR/output/INVERSE/mosaic/ORTHO_mosaic_B02.tif\n", + "Docker images kept (faster next run, ~4 GB disk usage).\n", + "\n" + ] + } + ], "source": [ "# =====================================================\n", "# INVERSE\n", @@ -586,7 +1390,7 @@ "print(\"Using XML:\", xml_path)\n", "\n", "# =====================================================\n", - "# Read params.json\n", + "# Read params.json to get selected bands and detectors\n", "# =====================================================\n", "params_path = os.path.join(WORKDIR, \"UserConf\", \"params.json\")\n", "if not os.path.exists(params_path):\n", @@ -597,8 +1401,9 @@ "\n", "selected_bands = params.get(\"bands\", [])\n", "selected_detectors = params.get(\"detectors\", [])\n", - "print(\"Bands:\", selected_bands)\n", - "print(\"Detectors:\", selected_detectors)\n", + "\n", + "print(f\"Bands from params.json: {selected_bands}\")\n", + "print(f\"Detectors from params.json: {selected_detectors}\")\n", "\n", "# =====================================================\n", "# Build GDAL Docker\n", diff --git a/sen2vm-notebook/src/requirements.txt b/sen2vm-notebook/src/requirements.txt index b8115cf4..d81a89d0 100644 --- a/sen2vm-notebook/src/requirements.txt +++ b/sen2vm-notebook/src/requirements.txt @@ -34,9 +34,11 @@ python-dateutil==2.9.0.post0 pyzmq==27.1.0 rasterio==1.4.3 requests==2.32.5 +scipy six==1.17.0 stack-data==0.6.3 tornado==6.5.2 traitlets==5.14.3 urllib3==2.6.1 +utm==0.8.1 wcwidth==0.2.14 From 6d845f4e2236d3ab143adcc49b14edf6ca2a4af7 Mon Sep 17 00:00:00 2001 From: Paul Castillo Date: Fri, 26 Jun 2026 13:02:14 +0000 Subject: [PATCH 05/13] direct otb, cleaning the notebooks --- .../src/notebook-direct-grid-otb.ipynb | 522 +---------- .../src/notebook-direct-grid.ipynb | 427 +-------- .../src/notebook-inverse-grid.ipynb | 836 +----------------- 3 files changed, 49 insertions(+), 1736 deletions(-) diff --git a/sen2vm-notebook/src/notebook-direct-grid-otb.ipynb b/sen2vm-notebook/src/notebook-direct-grid-otb.ipynb index a0df851b..95383bad 100644 --- a/sen2vm-notebook/src/notebook-direct-grid-otb.ipynb +++ b/sen2vm-notebook/src/notebook-direct-grid-otb.ipynb @@ -20,13 +20,13 @@ "# /!\\/!\\/!\\ CAREFUL, please read the README_Notebooks.md file before\n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "\n", - "WORKDIR = \"/home/pcastillo/sen2vm/WORKDIR\" # Working directory for sen2vm processing\n", + "WORKDIR = \"PATH/TO/WORKDIR\" # Working directory for sen2vm processing\n", "\n", "# Path to downloaded product\n", - "PATH_L1B_DATA = \"/home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE\"\n", + "PATH_L1B_DATA = \"PATH/TO/L1B_PRODUCT\"\n", "\n", "# Path to GIPP directory\n", - "PATH_GIPP = \"/home/pcastillo/sen2vm/WORKDIR/GIPP\"\n", + "PATH_GIPP = \"PATH/TO/GIPP\"\n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "# /!\\/!\\/!\\ If you do not have your own GIPP folder, you may use the inputs-download-notebook to download it, then you may indicate the path were you \n", "# /!\\/!\\/!\\ downloaded it here in PATH_GIPP\n", @@ -34,17 +34,17 @@ "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "\n", "# Path to DEM directory \n", - "PATH_DEM = \"/home/pcastillo/sen2vm/WORKDIR/DEM\"\n", + "PATH_DEM = \"PATH/TO/DEM\"\n", "\n", "# Path to GEOID directory\n", - "PATH_GEOID = \"/home/pcastillo/sen2vm/WORKDIR/GEOID\"\n", + "PATH_GEOID = \"PATH/TO/GEOID\"\n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "# /!\\/!\\/!\\ If you do not have your own GEOID folder, you may use the inputs-download-notebook to download it, then you may indicate the path were you\n", "# /!\\/!\\/!\\ downloaded it here in \n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "\n", "# Path to IERS file\n", - "PATH_IERS = \"/home/pcastillo/sen2vm/WORKDIR\"\n", + "PATH_IERS = \"PATH/TO/IERS_FILE\"\n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "# /!\\/!\\/!\\ If you do not have your own IERS, you may let this path empy (i.e. \"\") and execute the cell number 2 named #IERS Download\n", "# /!\\/!\\/!\\ In this case, the IERS will be downloaded in the WORKDIR\n", @@ -102,35 +102,10 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "8ec4d6f6", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Stopping because PATH_IERS is not empty\n" - ] - }, - { - "ename": "SystemExit", - "evalue": "0", - "output_type": "error", - "traceback": [ - "An exception has occurred, use %tb to see the full traceback.\n", - "\u001b[31mSystemExit\u001b[39m\u001b[31m:\u001b[39m 0\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/pcastillo/sen2vm/sen2vm-core/sen2vm-notebook/src/.venv/lib/python3.13/site-packages/IPython/core/interactiveshell.py:3709: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.\n", - " warn(\"To exit: use 'exit', 'quit', or Ctrl-D.\", stacklevel=1)\n" - ] - } - ], + "outputs": [], "source": [ "# === DOWNLOAD IERS ===\n", "import os\n", @@ -255,22 +230,10 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "id": "276592b5", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "UserConf directory: /home/pcastillo/sen2vm/WORKDIR/UserConf\n", - "Geoid directory: /home/pcastillo/sen2vm/WORKDIR/GEOID\n", - "/data/IERS/bulletina-xxxvii-042.txt\n", - "Configuration file generated:\n", - "/home/pcastillo/sen2vm/WORKDIR/UserConf/config.json\n" - ] - } - ], + "outputs": [], "source": [ "# === GENERATE CONFIG.JSON ===\n", "\n", @@ -375,24 +338,10 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "id": "23b1da25", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "UserConf directory: /home/pcastillo/sen2vm/WORKDIR/UserConf\n", - "Found 60 granule folders.\n", - "Detected detectors: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12']\n", - "Detected bands: ['B01', 'B02', 'B03', 'B04', 'B05', 'B06', 'B07', 'B08', 'B09', 'B10', 'B11', 'B12', 'B8A']\n", - "params.json written to: /home/pcastillo/sen2vm/WORKDIR/UserConf/params.json\n", - " - Detectors: ['07', '08', '09', '10', '11']\n", - " - Bands: ['B02']\n" - ] - } - ], + "outputs": [], "source": [ "# === GENERATE PARAMS.JSON ===\n", "\n", @@ -489,195 +438,10 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "id": "572bd72a", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Building Docker image 'sen2vm' from: /home/pcastillo/sen2vm/sen2vm-core\n", - "Command: docker build -t sen2vm /home/pcastillo/sen2vm/sen2vm-core \n", - "\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "DEPRECATED: The legacy builder is deprecated and will be removed in a future release.\n", - " Install the buildx component to build images with BuildKit:\n", - " https://docs.docker.com/go/buildx/\n", - "\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Sending build context to Docker daemon 1.718GB\n", - "Step 1/5 : FROM ghcr.io/sen2vm/sen2vm-build-env:latest AS launcher\n", - " ---> a5369801b500\n", - "Step 2/5 : ENV SEN2VM_VERSION=1.1.4\n", - " ---> Using cache\n", - " ---> 14de44fa18ab\n", - "Step 3/5 : WORKDIR /Sen2vm\n", - " ---> Using cache\n", - " ---> b4079a1b81e1\n", - "Step 4/5 : RUN curl -L -o sen2vm-core.jar https://github.com/sen2vm/sen2vm-core/releases/download/${SEN2VM_VERSION}/sen2vm-core-${SEN2VM_VERSION}.jar\n", - " ---> Using cache\n", - " ---> 01c51fc5d7d7\n", - "Step 5/5 : ENTRYPOINT [\"java\", \"-jar\",\"sen2vm-core.jar\"]\n", - " ---> Using cache\n", - " ---> 5be1977daa50\n", - "Successfully built 5be1977daa50\n", - "Successfully tagged sen2vm:latest\n", - "Docker image built successfully.\n", - "\n", - "Running Docker container...\n", - "\n", - "Command: docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/DEM:/data/DEM -v /home/pcastillo/sen2vm/WORKDIR/GIPP:/data/GIPP -v /home/pcastillo/sen2vm/WORKDIR/GEOID:/data/GEOID -v /home/pcastillo/sen2vm/WORKDIR:/data/IERS -v /home/pcastillo/sen2vm/WORKDIR:/workspace sen2vm -c /workspace/UserConf/config.json -p /workspace/UserConf/params.json \n", - "\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2026-06-26 09:03:26 [INFO ] Start Sen2VM \n", - "2026-06-26 09:03:27 [INFO ] Parsing file /workspace/UserConf/config.json \n", - "2026-06-26 09:03:27 [INFO ] Reading IERS file at: /data/IERS/bulletina-xxxvii-042.txt \n", - "2026-06-26 09:03:27 [INFO ] Parsing file /workspace/UserConf/params.json \n", - "2026-06-26 09:03:27 [INFO ] Detectors list: [DETECTOR_7, DETECTOR_8, DETECTOR_9, DETECTOR_10, DETECTOR_11] \n", - "2026-06-26 09:03:27 [INFO ] Bands list: [BAND_2] \n", - "2026-06-26 09:03:27 [INFO ] Find the following datastrip metadata file: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/S2B_OPER_MTD_L1B_DS_2BPS_20241019T153411_S20241019T120215.xml \n", - "2026-06-26 09:03:28 [INFO ] Initializing: copy of the Orekit-data: /Sen2vm/orekit-data \n", - "2026-06-26 09:03:28 [INFO ] Orekit-data: /Sen2vm/orekit-data \n", - "2026-06-26 09:03:35 [INFO ] Get through GIPP folder: /data/GIPP/S2B \n", - "2026-06-26 09:03:35 [INFO ] Read blind pixel file: /data/GIPP/S2B/S2B_OPER_GIP_BLINDP_MPC__20170221T000000_V20170101T000000_21000101T000000_B00.xml \n", - "2026-06-26 09:03:35 [INFO ] Read spacecraft model file: /data/GIPP/S2B/S2B_OPER_GIP_SPAMOD_MPC__20231122T110035_V20231123T000000_21000101T000000_B00.xml \n", - "2026-06-26 09:03:35 [INFO ] Read viewingDirection file: /data/GIPP/S2B/S2B_OPER_GIP_VIEDIR_MPC__20170512T114736_V20170322T000000_21000101T000000_B02.xml \n", - "2026-06-26 09:03:36 [INFO ] setAndProcessDataStrip listOfFiles/data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11 \n", - "2026-06-26 09:03:36 [INFO ] Datastrip S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11 \n", - "2026-06-26 09:03:36 [INFO ] \n", - "2026-06-26 09:03:36 [INFO ] Starting grids generation \n", - "2026-06-26 09:03:36 [INFO ] \n", - "2026-06-26 09:03:36 [INFO ] ############### \n", - "2026-06-26 09:03:36 [INFO ] ### BAND 2 ### \n", - "2026-06-26 09:03:36 [INFO ] ############### \n", - "2026-06-26 09:03:36 [INFO ] Grid resolution: 4.5 \n", - "2026-06-26 09:03:36 [INFO ] Band resolution: 10.0 \n", - "2026-06-26 09:03:36 [INFO ] \n", - "2026-06-26 09:03:36 [INFO ] ### DET 07 (BAND 2) ### \n", - "2026-06-26 09:03:36 [INFO ] Grid information: ConvOffset: (0.5, 0.5); Step: (4.5, 4.5); Start: (0, 0); Size: (11520, 2552) \n", - "2026-06-26 09:03:52 [INFO ] Granule: 4608 -> 6912 \n", - "2026-06-26 09:03:52 [INFO ] Grid start: 1024 (4606.25) -> Grid end: 1536 (6910.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 09:03:52 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120228_D07_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120228_D07_B02.tif \n", - "2026-06-26 09:03:52 [INFO ] Granule: 2304 -> 4608 \n", - "2026-06-26 09:03:52 [INFO ] Grid start: 512 (2302.25) -> Grid end: 1024 (4606.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 09:03:52 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120225_D07_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120225_D07_B02.tif \n", - "2026-06-26 09:03:52 [INFO ] Granule: 9216 -> 11520 \n", - "2026-06-26 09:03:52 [INFO ] Grid start: 2048 (9214.25) -> Grid end: 2560 (11518.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 09:03:52 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120235_D07_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120235_D07_B02.tif \n", - "2026-06-26 09:03:52 [INFO ] Granule: 0 -> 2304 \n", - "2026-06-26 09:03:52 [INFO ] Grid start: 0 (-1.75) -> Grid end: 512 (2302.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 09:03:52 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120221_D07_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120221_D07_B02.tif \n", - "2026-06-26 09:03:52 [INFO ] Granule: 6912 -> 9216 \n", - "2026-06-26 09:03:52 [INFO ] Grid start: 1536 (6910.25) -> Grid end: 2048 (9214.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 09:03:52 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120232_D07_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120232_D07_B02.tif \n", - "2026-06-26 09:03:52 [INFO ] VRT saved in: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02.vrt \n", - "2026-06-26 09:03:52 [INFO ] \n", - "2026-06-26 09:03:52 [INFO ] ### DET 08 (BAND 2) ### \n", - "2026-06-26 09:03:52 [INFO ] Grid information: ConvOffset: (0.5, 0.5); Step: (4.5, 4.5); Start: (0, 0); Size: (11520, 2552) \n", - "2026-06-26 09:04:07 [INFO ] Granule: 2304 -> 4608 \n", - "2026-06-26 09:04:07 [INFO ] Grid start: 512 (2302.25) -> Grid end: 1024 (4606.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 09:04:08 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120221_D08_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120221_D08_B02.tif \n", - "2026-06-26 09:04:08 [INFO ] Granule: 4608 -> 6912 \n", - "2026-06-26 09:04:08 [INFO ] Grid start: 1024 (4606.25) -> Grid end: 1536 (6910.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 09:04:08 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120224_D08_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120224_D08_B02.tif \n", - "2026-06-26 09:04:08 [INFO ] Granule: 6912 -> 9216 \n", - "2026-06-26 09:04:08 [INFO ] Grid start: 1536 (6910.25) -> Grid end: 2048 (9214.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 09:04:08 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120228_D08_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120228_D08_B02.tif \n", - "2026-06-26 09:04:08 [INFO ] Granule: 9216 -> 11520 \n", - "2026-06-26 09:04:08 [INFO ] Grid start: 2048 (9214.25) -> Grid end: 2560 (11518.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 09:04:08 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120231_D08_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120231_D08_B02.tif \n", - "2026-06-26 09:04:08 [INFO ] Granule: 0 -> 2304 \n", - "2026-06-26 09:04:08 [INFO ] Grid start: 0 (-1.75) -> Grid end: 512 (2302.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 09:04:08 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120217_D08_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120217_D08_B02.tif \n", - "2026-06-26 09:04:08 [INFO ] VRT saved in: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02.vrt \n", - "2026-06-26 09:04:08 [INFO ] \n", - "2026-06-26 09:04:08 [INFO ] ### DET 09 (BAND 2) ### \n", - "2026-06-26 09:04:08 [INFO ] Grid information: ConvOffset: (0.5, 0.5); Step: (4.5, 4.5); Start: (0, 0); Size: (11520, 2552) \n", - "2026-06-26 09:04:25 [INFO ] Granule: 4608 -> 6912 \n", - "2026-06-26 09:04:25 [INFO ] Grid start: 1024 (4606.25) -> Grid end: 1536 (6910.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 09:04:25 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120228_D09_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120228_D09_B02.tif \n", - "2026-06-26 09:04:25 [INFO ] Granule: 6912 -> 9216 \n", - "2026-06-26 09:04:25 [INFO ] Grid start: 1536 (6910.25) -> Grid end: 2048 (9214.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 09:04:25 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120232_D09_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120232_D09_B02.tif \n", - "2026-06-26 09:04:25 [INFO ] Granule: 2304 -> 4608 \n", - "2026-06-26 09:04:25 [INFO ] Grid start: 512 (2302.25) -> Grid end: 1024 (4606.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 09:04:25 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120225_D09_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120225_D09_B02.tif \n", - "2026-06-26 09:04:25 [INFO ] Granule: 9216 -> 11520 \n", - "2026-06-26 09:04:25 [INFO ] Grid start: 2048 (9214.25) -> Grid end: 2560 (11518.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 09:04:25 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120235_D09_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120235_D09_B02.tif \n", - "2026-06-26 09:04:25 [INFO ] Granule: 0 -> 2304 \n", - "2026-06-26 09:04:25 [INFO ] Grid start: 0 (-1.75) -> Grid end: 512 (2302.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 09:04:25 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120221_D09_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120221_D09_B02.tif \n", - "2026-06-26 09:04:25 [INFO ] VRT saved in: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02.vrt \n", - "2026-06-26 09:04:25 [INFO ] \n", - "2026-06-26 09:04:25 [INFO ] ### DET 10 (BAND 2) ### \n", - "2026-06-26 09:04:25 [INFO ] Grid information: ConvOffset: (0.5, 0.5); Step: (4.5, 4.5); Start: (0, 0); Size: (11520, 2552) \n", - "2026-06-26 09:04:43 [INFO ] Granule: 4608 -> 6912 \n", - "2026-06-26 09:04:43 [INFO ] Grid start: 1024 (4606.25) -> Grid end: 1536 (6910.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 09:04:43 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120224_D10_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120224_D10_B02.tif \n", - "2026-06-26 09:04:43 [INFO ] Granule: 0 -> 2304 \n", - "2026-06-26 09:04:43 [INFO ] Grid start: 0 (-1.75) -> Grid end: 512 (2302.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 09:04:43 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120217_D10_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120217_D10_B02.tif \n", - "2026-06-26 09:04:43 [INFO ] Granule: 2304 -> 4608 \n", - "2026-06-26 09:04:43 [INFO ] Grid start: 512 (2302.25) -> Grid end: 1024 (4606.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 09:04:43 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120221_D10_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120221_D10_B02.tif \n", - "2026-06-26 09:04:43 [INFO ] Granule: 9216 -> 11520 \n", - "2026-06-26 09:04:43 [INFO ] Grid start: 2048 (9214.25) -> Grid end: 2560 (11518.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 09:04:43 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120231_D10_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120231_D10_B02.tif \n", - "2026-06-26 09:04:43 [INFO ] Granule: 6912 -> 9216 \n", - "2026-06-26 09:04:43 [INFO ] Grid start: 1536 (6910.25) -> Grid end: 2048 (9214.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 09:04:43 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120228_D10_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120228_D10_B02.tif \n", - "2026-06-26 09:04:43 [INFO ] VRT saved in: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02.vrt \n", - "2026-06-26 09:04:43 [INFO ] \n", - "2026-06-26 09:04:43 [INFO ] ### DET 11 (BAND 2) ### \n", - "2026-06-26 09:04:43 [INFO ] Grid information: ConvOffset: (0.5, 0.5); Step: (4.5, 4.5); Start: (0, 0); Size: (11520, 2552) \n", - "2026-06-26 09:05:01 [INFO ] Granule: 0 -> 2304 \n", - "2026-06-26 09:05:01 [INFO ] Grid start: 0 (-1.75) -> Grid end: 512 (2302.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 09:05:01 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120221_D11_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120221_D11_B02.tif \n", - "2026-06-26 09:05:01 [INFO ] Granule: 9216 -> 11520 \n", - "2026-06-26 09:05:01 [INFO ] Grid start: 2048 (9214.25) -> Grid end: 2560 (11518.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 09:05:01 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120235_D11_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120235_D11_B02.tif \n", - "2026-06-26 09:05:01 [INFO ] Granule: 4608 -> 6912 \n", - "2026-06-26 09:05:01 [INFO ] Grid start: 1024 (4606.25) -> Grid end: 1536 (6910.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 09:05:01 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120228_D11_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120228_D11_B02.tif \n", - "2026-06-26 09:05:01 [INFO ] Granule: 2304 -> 4608 \n", - "2026-06-26 09:05:01 [INFO ] Grid start: 512 (2302.25) -> Grid end: 1024 (4606.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 09:05:01 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120225_D11_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120225_D11_B02.tif \n", - "2026-06-26 09:05:01 [INFO ] Granule: 6912 -> 9216 \n", - "2026-06-26 09:05:01 [INFO ] Grid start: 1536 (6910.25) -> Grid end: 2048 (9214.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 09:05:01 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120232_D11_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120232_D11_B02.tif \n", - "2026-06-26 09:05:01 [INFO ] VRT saved in: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02.vrt \n", - "2026-06-26 09:05:01 [INFO ] Find the following datastrip metadata file: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/S2B_OPER_MTD_L1B_DS_2BPS_20241019T153411_S20241019T120215.xml \n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "Docker execution complete.\n", - "\n", - "Docker images kept.\n", - "\n" - ] - } - ], + "outputs": [], "source": [ "# === RUN SEN2VM (Docker: BUILD + RUN + CLEAN) ===\n", "\n", @@ -748,264 +512,10 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "id": "a091ccaf", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/home/pcastillo/sen2vm/sen2vm-core/assets/scripts\n", - "Using XML: /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml\n", - "Bands from params.json: ['B02']\n", - "Detectors from params.json: ['07', '08', '09', '10', '11']\n", - "Total direct grids found: 5\n", - "✓ Keep S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02 (Detector=07, Band=B02)\n", - "✓ Keep S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02 (Detector=10, Band=B02)\n", - "✓ Keep S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02 (Detector=08, Band=B02)\n", - "✓ Keep S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02 (Detector=11, Band=B02)\n", - "✓ Keep S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02 (Detector=09, Band=B02)\n", - "\n", - "Filtered direct grids: 5\n", - "\n", - "========================================\n", - "Generating inverse grid\n", - "Direct : /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02.vrt\n", - "Inverse: /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb/INVERSE_GRID/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02.tif\n", - "========================================\n", - "resolution 10\n", - "\n", - "========================================\n", - "Generating inverse grid\n", - "Direct : /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02.vrt\n", - "Inverse: /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb/INVERSE_GRID/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02.tif\n", - "========================================\n", - "resolution 10\n", - "\n", - "========================================\n", - "Generating inverse grid\n", - "Direct : /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02.vrt\n", - "Inverse: /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb/INVERSE_GRID/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02.tif\n", - "========================================\n", - "resolution 10\n", - "\n", - "========================================\n", - "Generating inverse grid\n", - "Direct : /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02.vrt\n", - "Inverse: /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb/INVERSE_GRID/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02.tif\n", - "========================================\n", - "resolution 10\n", - "\n", - "========================================\n", - "Generating inverse grid\n", - "Direct : /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02.vrt\n", - "Inverse: /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb/INVERSE_GRID/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02.tif\n", - "========================================\n", - "resolution 10\n", - "\n", - "=================================================\n", - "Processing: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02.tif\n", - "=================================================\n", - "Detector: 07\n", - "Band: B02\n", - "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02\n", - "Resolution: 10\n", - "Width : 7037\n", - "Height: 3334\n", - "\n", - "=== EXTRACTION ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb:/output gdal-latest -c \n", - " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02\" \"/output/raw/raw_D07_B02.tif\"\n", - " \n", - "Input file size is 2552, 11520\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "=== OTB RESAMPLING ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D07_B02.tif -io.out /output/otb_no_georef/ortho_D07_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", - "2026-06-26 09:08:39 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", - "2026-06-26 09:08:39 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", - "2026-06-26 09:08:39 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", - "2026-06-26 09:08:39 (INFO): Loading metadata from official product\n", - "2026-06-26 09:08:39 (INFO): Loading metadata from official product\n", - "2026-06-26 09:08:39 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:08:39 (FATAL) GridBasedImageResampling: Requested region is (at least partially) outside the largest possible region of the displacement field.\n", - "OTB failed (outside grid) → skipping\n", - "\n", - "=================================================\n", - "Processing: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02.tif\n", - "=================================================\n", - "Detector: 10\n", - "Band: B02\n", - "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02\n", - "Resolution: 10\n", - "Width : 7037\n", - "Height: 3334\n", - "\n", - "=== EXTRACTION ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb:/output gdal-latest -c \n", - " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02\" \"/output/raw/raw_D10_B02.tif\"\n", - " \n", - "Input file size is 2552, 11520\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "=== OTB RESAMPLING ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D10_B02.tif -io.out /output/otb_no_georef/ortho_D10_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", - "2026-06-26 09:08:44 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", - "2026-06-26 09:08:44 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", - "2026-06-26 09:08:44 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", - "2026-06-26 09:08:44 (INFO): Loading metadata from official product\n", - "2026-06-26 09:08:44 (INFO): Loading metadata from official product\n", - "2026-06-26 09:08:44 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:08:44 (INFO): Estimated memory for full processing: 1110.09MB (avail.: 256 MB), optimal image partitioning: 5 blocks\n", - "2026-06-26 09:08:44 (INFO): File /output/otb_no_georef/ortho_D10_B02.tif will be written in 6 blocks of 7037x556 pixels\n", - "Writing /output/otb_no_georef/ortho_D10_B02.tif...: 100% [**************************************************] (4s)\n", - "OTB success\n", - "\n", - "=== ADD GEOREF ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb:/output gdal-latest -c \n", - " gdal_translate -a_srs EPSG:32628 /output/otb_no_georef/ortho_D10_B02.tif /output/output_georef/ortho_D10_B02_georef.tif\n", - " \n", - "Input file size is 7037, 3334\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "Finished: ortho_D10_B02_georef.tif\n", - "\n", - "=================================================\n", - "Processing: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02.tif\n", - "=================================================\n", - "Detector: 08\n", - "Band: B02\n", - "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02\n", - "Resolution: 10\n", - "Width : 7037\n", - "Height: 3334\n", - "\n", - "=== EXTRACTION ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb:/output gdal-latest -c \n", - " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02\" \"/output/raw/raw_D08_B02.tif\"\n", - " \n", - "Input file size is 2552, 11520\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "=== OTB RESAMPLING ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D08_B02.tif -io.out /output/otb_no_georef/ortho_D08_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", - "2026-06-26 09:08:54 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", - "2026-06-26 09:08:54 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", - "2026-06-26 09:08:54 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", - "2026-06-26 09:08:54 (INFO): Loading metadata from official product\n", - "2026-06-26 09:08:54 (INFO): Loading metadata from official product\n", - "2026-06-26 09:08:54 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:08:54 (INFO): Estimated memory for full processing: 1110.09MB (avail.: 256 MB), optimal image partitioning: 5 blocks\n", - "2026-06-26 09:08:54 (INFO): File /output/otb_no_georef/ortho_D08_B02.tif will be written in 6 blocks of 7037x556 pixels\n", - "Writing /output/otb_no_georef/ortho_D08_B02.tif...: 100% [**************************************************] (4s)\n", - "OTB success\n", - "\n", - "=== ADD GEOREF ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb:/output gdal-latest -c \n", - " gdal_translate -a_srs EPSG:32628 /output/otb_no_georef/ortho_D08_B02.tif /output/output_georef/ortho_D08_B02_georef.tif\n", - " \n", - "Input file size is 7037, 3334\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "Finished: ortho_D08_B02_georef.tif\n", - "\n", - "=================================================\n", - "Processing: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02.tif\n", - "=================================================\n", - "Detector: 11\n", - "Band: B02\n", - "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02\n", - "Resolution: 10\n", - "Width : 7037\n", - "Height: 3334\n", - "\n", - "=== EXTRACTION ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb:/output gdal-latest -c \n", - " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02\" \"/output/raw/raw_D11_B02.tif\"\n", - " \n", - "Input file size is 2552, 11520\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "=== OTB RESAMPLING ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D11_B02.tif -io.out /output/otb_no_georef/ortho_D11_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", - "2026-06-26 09:09:04 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", - "2026-06-26 09:09:04 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", - "2026-06-26 09:09:04 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", - "2026-06-26 09:09:04 (INFO): Loading metadata from official product\n", - "2026-06-26 09:09:04 (INFO): Loading metadata from official product\n", - "2026-06-26 09:09:04 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:09:04 (FATAL) GridBasedImageResampling: Requested region is (at least partially) outside the largest possible region of the displacement field.\n", - "OTB failed (outside grid) → skipping\n", - "\n", - "=================================================\n", - "Processing: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02.tif\n", - "=================================================\n", - "Detector: 09\n", - "Band: B02\n", - "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02\n", - "Resolution: 10\n", - "Width : 7037\n", - "Height: 3334\n", - "\n", - "=== EXTRACTION ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb:/output gdal-latest -c \n", - " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02\" \"/output/raw/raw_D09_B02.tif\"\n", - " \n", - "Input file size is 2552, 11520\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "=== OTB RESAMPLING ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D09_B02.tif -io.out /output/otb_no_georef/ortho_D09_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", - "2026-06-26 09:09:08 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", - "2026-06-26 09:09:08 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", - "2026-06-26 09:09:08 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", - "2026-06-26 09:09:08 (INFO): Loading metadata from official product\n", - "2026-06-26 09:09:08 (INFO): Loading metadata from official product\n", - "2026-06-26 09:09:08 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:09:08 (INFO): Estimated memory for full processing: 1246.6MB (avail.: 256 MB), optimal image partitioning: 5 blocks\n", - "2026-06-26 09:09:08 (INFO): File /output/otb_no_georef/ortho_D09_B02.tif will be written in 6 blocks of 7037x556 pixels\n", - "Writing /output/otb_no_georef/ortho_D09_B02.tif...: 100% [**************************************************] (5s)\n", - "OTB success\n", - "\n", - "=== ADD GEOREF ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb:/output gdal-latest -c \n", - " gdal_translate -a_srs EPSG:32628 /output/otb_no_georef/ortho_D09_B02.tif /output/output_georef/ortho_D09_B02_georef.tif\n", - " \n", - "Input file size is 7037, 3334\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "Finished: ortho_D09_B02_georef.tif\n", - "\n", - "=== MOSAIC CREATION ===\n", - "\n", - "Bands detected: {'B02'}\n", - "\n", - "----------------------------------------\n", - "Creating mosaic for band: B02\n", - "----------------------------------------\n", - "Found 3 files\n", - " ortho_D08_B02_georef.tif\n", - " ortho_D09_B02_georef.tif\n", - " ortho_D10_B02_georef.tif\n", - "\n", - "Running mosaic:\n", - " gdal_merge.py -o /output/mosaic/ORTHO_mosaic_B02.tif -of GTiff -co COMPRESS=LZW -co TILED=YES -ot UInt16 -n 0 -a_nodata 0 /output/output_georef/ortho_D08_B02_georef.tif /output/output_georef/ortho_D09_B02_georef.tif /output/output_georef/ortho_D10_B02_georef.tif \n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "Mosaic written → /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_otb/mosaic/ORTHO_mosaic_B02.tif\n", - "Docker images kept (faster next run, ~4 GB disk usage).\n", - "\n" - ] - } - ], + "outputs": [], "source": [ "import os\n", "import subprocess\n", diff --git a/sen2vm-notebook/src/notebook-direct-grid.ipynb b/sen2vm-notebook/src/notebook-direct-grid.ipynb index 8c1460a7..152cff0a 100644 --- a/sen2vm-notebook/src/notebook-direct-grid.ipynb +++ b/sen2vm-notebook/src/notebook-direct-grid.ipynb @@ -10,7 +10,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 1, "id": "2b816cd9-5254-452b-bced-2943eb6b7aec", "metadata": {}, "outputs": [], @@ -20,13 +20,13 @@ "# /!\\/!\\/!\\ CAREFUL, please read the README_Notebooks.md file before\n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "\n", - "WORKDIR = \"/home/pcastillo/sen2vm/WORKDIR\" # Working directory for sen2vm processing\n", + "WORKDIR = \"PATH/TO/WORKDIR\" # Working directory for sen2vm processing\n", "\n", "# Path to downloaded product\n", - "PATH_L1B_DATA = \"/home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE\"\n", + "PATH_L1B_DATA = \"PATH/TO/L1B_PRODUCT\"\n", "\n", "# Path to GIPP directory\n", - "PATH_GIPP = \"/home/pcastillo/sen2vm/WORKDIR/GIPP\"\n", + "PATH_GIPP = \"PATH/TO/GIPP\"\n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "# /!\\/!\\/!\\ If you do not have your own GIPP folder, you may use the inputs-download-notebook to download it, then you may indicate the path were you \n", "# /!\\/!\\/!\\ downloaded it here in PATH_GIPP\n", @@ -34,17 +34,17 @@ "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "\n", "# Path to DEM directory \n", - "PATH_DEM = \"/home/pcastillo/sen2vm/WORKDIR/DEM\"\n", + "PATH_DEM = \"PATH/TO/DEM\"\n", "\n", "# Path to GEOID directory\n", - "PATH_GEOID = \"/home/pcastillo/sen2vm/WORKDIR/GEOID\"\n", + "PATH_GEOID = \"PATH/TO/GEOID\"\n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "# /!\\/!\\/!\\ If you do not have your own GEOID folder, you may use the inputs-download-notebook to download it, then you may indicate the path were you\n", "# /!\\/!\\/!\\ downloaded it here in \n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "\n", "# Path to IERS file\n", - "PATH_IERS = \"\"\n", + "PATH_IERS = \"PATH/TO/IERS_FILE\"\n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "# /!\\/!\\/!\\ If you do not have your own IERS, you may let this path empy (i.e. \"\") and execute the cell number 2 named #IERS Download\n", "# /!\\/!\\/!\\ In this case, the IERS will be downloaded in the WORKDIR\n", @@ -102,28 +102,10 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "id": "8ec4d6f6", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Bulletin output directory: /home/pcastillo/sen2vm/WORKDIR\n", - "Cleanup of old bulletins complete.\n", - "\n", - "Product date extracted from DATASTRIP: 2024-10-19 \n", - "\n", - "Bulletin A Roman year: xxxvii\n", - "Initial weekly index: 42\n", - "\n", - "Trying bulletin: https://datacenter.iers.org/data/6/bulletina-xxxvii-042.txt\n", - "Bulletin found: 042\n", - "Downloaded: /home/pcastillo/sen2vm/WORKDIR/bulletina-xxxvii-042.txt\n" - ] - } - ], + "outputs": [], "source": [ "# === DOWNLOAD IERS ===\n", "import os\n", @@ -248,22 +230,10 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "id": "276592b5", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "UserConf directory: /home/pcastillo/sen2vm/WORKDIR/UserConf\n", - "Geoid directory: /home/pcastillo/sen2vm/WORKDIR/GEOID\n", - "/data/IERS/bulletina-xxxvii-042.txt\n", - "Configuration file generated:\n", - "/home/pcastillo/sen2vm/WORKDIR/UserConf/config.json\n" - ] - } - ], + "outputs": [], "source": [ "# === GENERATE CONFIG.JSON ===\n", "\n", @@ -368,24 +338,10 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "id": "23b1da25", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "UserConf directory: /home/pcastillo/sen2vm/WORKDIR/UserConf\n", - "Found 60 granule folders.\n", - "Detected detectors: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12']\n", - "Detected bands: ['B01', 'B02', 'B03', 'B04', 'B05', 'B06', 'B07', 'B08', 'B09', 'B10', 'B11', 'B12', 'B8A']\n", - "params.json written to: /home/pcastillo/sen2vm/WORKDIR/UserConf/params.json\n", - " - Detectors: ['07', '08', '09', '10', '11']\n", - " - Bands: ['B02']\n" - ] - } - ], + "outputs": [], "source": [ "# === GENERATE PARAMS.JSON ===\n", "\n", @@ -482,195 +438,10 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "id": "572bd72a", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Building Docker image 'sen2vm' from: /home/pcastillo/sen2vm/sen2vm-core\n", - "Command: docker build -t sen2vm /home/pcastillo/sen2vm/sen2vm-core \n", - "\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "DEPRECATED: The legacy builder is deprecated and will be removed in a future release.\n", - " Install the buildx component to build images with BuildKit:\n", - " https://docs.docker.com/go/buildx/\n", - "\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Sending build context to Docker daemon 1.718GB\n", - "Step 1/5 : FROM ghcr.io/sen2vm/sen2vm-build-env:latest AS launcher\n", - " ---> a5369801b500\n", - "Step 2/5 : ENV SEN2VM_VERSION=1.1.4\n", - " ---> Using cache\n", - " ---> 14de44fa18ab\n", - "Step 3/5 : WORKDIR /Sen2vm\n", - " ---> Using cache\n", - " ---> b4079a1b81e1\n", - "Step 4/5 : RUN curl -L -o sen2vm-core.jar https://github.com/sen2vm/sen2vm-core/releases/download/${SEN2VM_VERSION}/sen2vm-core-${SEN2VM_VERSION}.jar\n", - " ---> Using cache\n", - " ---> 01c51fc5d7d7\n", - "Step 5/5 : ENTRYPOINT [\"java\", \"-jar\",\"sen2vm-core.jar\"]\n", - " ---> Using cache\n", - " ---> 5be1977daa50\n", - "Successfully built 5be1977daa50\n", - "Successfully tagged sen2vm:latest\n", - "Docker image built successfully.\n", - "\n", - "Running Docker container...\n", - "\n", - "Command: docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/DEM:/data/DEM -v /home/pcastillo/sen2vm/WORKDIR/GIPP:/data/GIPP -v /home/pcastillo/sen2vm/WORKDIR/GEOID:/data/GEOID -v /home/pcastillo/sen2vm/WORKDIR:/data/IERS -v /home/pcastillo/sen2vm/WORKDIR:/workspace sen2vm -c /workspace/UserConf/config.json -p /workspace/UserConf/params.json \n", - "\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2026-06-26 08:55:17 [INFO ] Start Sen2VM \n", - "2026-06-26 08:55:17 [INFO ] Parsing file /workspace/UserConf/config.json \n", - "2026-06-26 08:55:17 [INFO ] Reading IERS file at: /data/IERS/bulletina-xxxvii-042.txt \n", - "2026-06-26 08:55:17 [INFO ] Parsing file /workspace/UserConf/params.json \n", - "2026-06-26 08:55:17 [INFO ] Detectors list: [DETECTOR_7, DETECTOR_8, DETECTOR_9, DETECTOR_10, DETECTOR_11] \n", - "2026-06-26 08:55:17 [INFO ] Bands list: [BAND_2] \n", - "2026-06-26 08:55:17 [INFO ] Find the following datastrip metadata file: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/S2B_OPER_MTD_L1B_DS_2BPS_20241019T153411_S20241019T120215.xml \n", - "2026-06-26 08:55:18 [INFO ] Initializing: copy of the Orekit-data: /Sen2vm/orekit-data \n", - "2026-06-26 08:55:18 [INFO ] Orekit-data: /Sen2vm/orekit-data \n", - "2026-06-26 08:55:25 [INFO ] Get through GIPP folder: /data/GIPP/S2B \n", - "2026-06-26 08:55:26 [INFO ] Read blind pixel file: /data/GIPP/S2B/S2B_OPER_GIP_BLINDP_MPC__20170221T000000_V20170101T000000_21000101T000000_B00.xml \n", - "2026-06-26 08:55:26 [INFO ] Read spacecraft model file: /data/GIPP/S2B/S2B_OPER_GIP_SPAMOD_MPC__20231122T110035_V20231123T000000_21000101T000000_B00.xml \n", - "2026-06-26 08:55:26 [INFO ] Read viewingDirection file: /data/GIPP/S2B/S2B_OPER_GIP_VIEDIR_MPC__20170512T114736_V20170322T000000_21000101T000000_B02.xml \n", - "2026-06-26 08:55:26 [INFO ] setAndProcessDataStrip listOfFiles/data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11 \n", - "2026-06-26 08:55:26 [INFO ] Datastrip S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11 \n", - "2026-06-26 08:55:27 [INFO ] \n", - "2026-06-26 08:55:27 [INFO ] Starting grids generation \n", - "2026-06-26 08:55:27 [INFO ] \n", - "2026-06-26 08:55:27 [INFO ] ############### \n", - "2026-06-26 08:55:27 [INFO ] ### BAND 2 ### \n", - "2026-06-26 08:55:27 [INFO ] ############### \n", - "2026-06-26 08:55:27 [INFO ] Grid resolution: 4.5 \n", - "2026-06-26 08:55:27 [INFO ] Band resolution: 10.0 \n", - "2026-06-26 08:55:27 [INFO ] \n", - "2026-06-26 08:55:27 [INFO ] ### DET 07 (BAND 2) ### \n", - "2026-06-26 08:55:27 [INFO ] Grid information: ConvOffset: (0.5, 0.5); Step: (4.5, 4.5); Start: (0, 0); Size: (11520, 2552) \n", - "2026-06-26 08:55:42 [INFO ] Granule: 4608 -> 6912 \n", - "2026-06-26 08:55:42 [INFO ] Grid start: 1024 (4606.25) -> Grid end: 1536 (6910.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 08:55:42 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120228_D07_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120228_D07_B02.tif \n", - "2026-06-26 08:55:42 [INFO ] Granule: 2304 -> 4608 \n", - "2026-06-26 08:55:42 [INFO ] Grid start: 512 (2302.25) -> Grid end: 1024 (4606.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 08:55:42 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120225_D07_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120225_D07_B02.tif \n", - "2026-06-26 08:55:42 [INFO ] Granule: 9216 -> 11520 \n", - "2026-06-26 08:55:42 [INFO ] Grid start: 2048 (9214.25) -> Grid end: 2560 (11518.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 08:55:42 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120235_D07_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120235_D07_B02.tif \n", - "2026-06-26 08:55:42 [INFO ] Granule: 0 -> 2304 \n", - "2026-06-26 08:55:42 [INFO ] Grid start: 0 (-1.75) -> Grid end: 512 (2302.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 08:55:42 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120221_D07_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120221_D07_B02.tif \n", - "2026-06-26 08:55:42 [INFO ] Granule: 6912 -> 9216 \n", - "2026-06-26 08:55:42 [INFO ] Grid start: 1536 (6910.25) -> Grid end: 2048 (9214.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 08:55:42 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120232_D07_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120232_D07_B02.tif \n", - "2026-06-26 08:55:42 [INFO ] VRT saved in: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02.vrt \n", - "2026-06-26 08:55:42 [INFO ] \n", - "2026-06-26 08:55:42 [INFO ] ### DET 08 (BAND 2) ### \n", - "2026-06-26 08:55:42 [INFO ] Grid information: ConvOffset: (0.5, 0.5); Step: (4.5, 4.5); Start: (0, 0); Size: (11520, 2552) \n", - "2026-06-26 08:55:58 [INFO ] Granule: 2304 -> 4608 \n", - "2026-06-26 08:55:58 [INFO ] Grid start: 512 (2302.25) -> Grid end: 1024 (4606.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 08:55:58 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120221_D08_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120221_D08_B02.tif \n", - "2026-06-26 08:55:58 [INFO ] Granule: 4608 -> 6912 \n", - "2026-06-26 08:55:58 [INFO ] Grid start: 1024 (4606.25) -> Grid end: 1536 (6910.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 08:55:58 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120224_D08_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120224_D08_B02.tif \n", - "2026-06-26 08:55:58 [INFO ] Granule: 6912 -> 9216 \n", - "2026-06-26 08:55:58 [INFO ] Grid start: 1536 (6910.25) -> Grid end: 2048 (9214.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 08:55:58 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120228_D08_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120228_D08_B02.tif \n", - "2026-06-26 08:55:58 [INFO ] Granule: 9216 -> 11520 \n", - "2026-06-26 08:55:58 [INFO ] Grid start: 2048 (9214.25) -> Grid end: 2560 (11518.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 08:55:58 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120231_D08_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120231_D08_B02.tif \n", - "2026-06-26 08:55:58 [INFO ] Granule: 0 -> 2304 \n", - "2026-06-26 08:55:58 [INFO ] Grid start: 0 (-1.75) -> Grid end: 512 (2302.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 08:55:58 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120217_D08_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120217_D08_B02.tif \n", - "2026-06-26 08:55:58 [INFO ] VRT saved in: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02.vrt \n", - "2026-06-26 08:55:58 [INFO ] \n", - "2026-06-26 08:55:58 [INFO ] ### DET 09 (BAND 2) ### \n", - "2026-06-26 08:55:58 [INFO ] Grid information: ConvOffset: (0.5, 0.5); Step: (4.5, 4.5); Start: (0, 0); Size: (11520, 2552) \n", - "2026-06-26 08:56:14 [INFO ] Granule: 4608 -> 6912 \n", - "2026-06-26 08:56:14 [INFO ] Grid start: 1024 (4606.25) -> Grid end: 1536 (6910.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 08:56:14 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120228_D09_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120228_D09_B02.tif \n", - "2026-06-26 08:56:14 [INFO ] Granule: 6912 -> 9216 \n", - "2026-06-26 08:56:14 [INFO ] Grid start: 1536 (6910.25) -> Grid end: 2048 (9214.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 08:56:14 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120232_D09_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120232_D09_B02.tif \n", - "2026-06-26 08:56:14 [INFO ] Granule: 2304 -> 4608 \n", - "2026-06-26 08:56:14 [INFO ] Grid start: 512 (2302.25) -> Grid end: 1024 (4606.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 08:56:14 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120225_D09_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120225_D09_B02.tif \n", - "2026-06-26 08:56:14 [INFO ] Granule: 9216 -> 11520 \n", - "2026-06-26 08:56:14 [INFO ] Grid start: 2048 (9214.25) -> Grid end: 2560 (11518.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 08:56:14 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120235_D09_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120235_D09_B02.tif \n", - "2026-06-26 08:56:14 [INFO ] Granule: 0 -> 2304 \n", - "2026-06-26 08:56:14 [INFO ] Grid start: 0 (-1.75) -> Grid end: 512 (2302.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 08:56:14 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120221_D09_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120221_D09_B02.tif \n", - "2026-06-26 08:56:14 [INFO ] VRT saved in: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02.vrt \n", - "2026-06-26 08:56:14 [INFO ] \n", - "2026-06-26 08:56:14 [INFO ] ### DET 10 (BAND 2) ### \n", - "2026-06-26 08:56:14 [INFO ] Grid information: ConvOffset: (0.5, 0.5); Step: (4.5, 4.5); Start: (0, 0); Size: (11520, 2552) \n", - "2026-06-26 08:56:30 [INFO ] Granule: 4608 -> 6912 \n", - "2026-06-26 08:56:30 [INFO ] Grid start: 1024 (4606.25) -> Grid end: 1536 (6910.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 08:56:30 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120224_D10_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120224_D10_B02.tif \n", - "2026-06-26 08:56:30 [INFO ] Granule: 0 -> 2304 \n", - "2026-06-26 08:56:30 [INFO ] Grid start: 0 (-1.75) -> Grid end: 512 (2302.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 08:56:31 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120217_D10_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120217_D10_B02.tif \n", - "2026-06-26 08:56:31 [INFO ] Granule: 2304 -> 4608 \n", - "2026-06-26 08:56:31 [INFO ] Grid start: 512 (2302.25) -> Grid end: 1024 (4606.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 08:56:31 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120221_D10_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120221_D10_B02.tif \n", - "2026-06-26 08:56:31 [INFO ] Granule: 9216 -> 11520 \n", - "2026-06-26 08:56:31 [INFO ] Grid start: 2048 (9214.25) -> Grid end: 2560 (11518.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 08:56:31 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120231_D10_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120231_D10_B02.tif \n", - "2026-06-26 08:56:31 [INFO ] Granule: 6912 -> 9216 \n", - "2026-06-26 08:56:31 [INFO ] Grid start: 1536 (6910.25) -> Grid end: 2048 (9214.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 08:56:31 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120228_D10_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120228_D10_B02.tif \n", - "2026-06-26 08:56:31 [INFO ] VRT saved in: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02.vrt \n", - "2026-06-26 08:56:31 [INFO ] \n", - "2026-06-26 08:56:31 [INFO ] ### DET 11 (BAND 2) ### \n", - "2026-06-26 08:56:31 [INFO ] Grid information: ConvOffset: (0.5, 0.5); Step: (4.5, 4.5); Start: (0, 0); Size: (11520, 2552) \n", - "2026-06-26 08:56:48 [INFO ] Granule: 0 -> 2304 \n", - "2026-06-26 08:56:48 [INFO ] Grid start: 0 (-1.75) -> Grid end: 512 (2302.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 08:56:48 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120221_D11_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120221_D11_B02.tif \n", - "2026-06-26 08:56:48 [INFO ] Granule: 9216 -> 11520 \n", - "2026-06-26 08:56:48 [INFO ] Grid start: 2048 (9214.25) -> Grid end: 2560 (11518.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 08:56:48 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120235_D11_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120235_D11_B02.tif \n", - "2026-06-26 08:56:48 [INFO ] Granule: 4608 -> 6912 \n", - "2026-06-26 08:56:48 [INFO ] Grid start: 1024 (4606.25) -> Grid end: 1536 (6910.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 08:56:48 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120228_D11_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120228_D11_B02.tif \n", - "2026-06-26 08:56:48 [INFO ] Granule: 2304 -> 4608 \n", - "2026-06-26 08:56:48 [INFO ] Grid start: 512 (2302.25) -> Grid end: 1024 (4606.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 08:56:48 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120225_D11_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120225_D11_B02.tif \n", - "2026-06-26 08:56:48 [INFO ] Granule: 6912 -> 9216 \n", - "2026-06-26 08:56:48 [INFO ] Grid start: 1536 (6910.25) -> Grid end: 2048 (9214.25) // Line Offset: -1.75 Pixel Offset: -1.75 \n", - "2026-06-26 08:56:48 [INFO ] Granule grid saved in: /data/L1B/GRANULE/S2B_OPER_MSI_L1B_GR_2BPS_20241019T153411_S20241019T120232_D11_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_GR_2BPS_20241019T153411_S20241019T120232_D11_B02.tif \n", - "2026-06-26 08:56:48 [INFO ] VRT saved in: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/GEO_DATA/S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02.vrt \n", - "2026-06-26 08:56:48 [INFO ] Find the following datastrip metadata file: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/S2B_OPER_MTD_L1B_DS_2BPS_20241019T153411_S20241019T120215.xml \n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "Docker execution complete.\n", - "\n", - "Docker images kept.\n", - "\n" - ] - } - ], + "outputs": [], "source": [ "# === RUN SEN2VM (Docker: BUILD + RUN + CLEAN) ===\n", "\n", @@ -745,174 +516,10 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "id": "a091ccaf", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Using XML: /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml\n", - "Bands from params.json: ['B02']\n", - "Detectors from params.json: ['07', '08', '09', '10', '11']\n", - "Total VRT files found: 5\n", - " ✓ Keep: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02 (detector=07, band=B02)\n", - " ✓ Keep: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02 (detector=10, band=B02)\n", - " ✓ Keep: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02 (detector=08, band=B02)\n", - " ✓ Keep: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02 (detector=11, band=B02)\n", - " ✓ Keep: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02 (detector=09, band=B02)\n", - "\n", - "Filtered VRTs to process: 5\n", - "VRT list: ['S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02', 'S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02', 'S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02', 'S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02', 'S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02']\n", - "Output folder: /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_gdal\n", - "\n", - "=== BUILDING GDAL LATEST CONTAINER ===\n", - "\n", - "Command: docker build --platform=linux/amd64 -t gdal-latest /home/pcastillo/sen2vm/sen2vm-core/sen2vm-notebook/src/gdal-latest \n", - "\n", - "Sending build context to Docker daemon 3.072kB\n", - "Step 1/10 : FROM ubuntu:22.04\n", - " ---> 962f6cadeae0\n", - "Step 2/10 : ENV DEBIAN_FRONTEND=noninteractive\n", - " ---> Using cache\n", - " ---> e6e9ea6fb1e0\n", - "Step 3/10 : RUN apt-get update && apt-get install -y build-essential git cmake pkg-config curl wget zip libcurl4-openssl-dev libproj-dev proj-bin libgeos-dev libsqlite3-dev libtiff-dev libjpeg-dev libpng-dev libzstd-dev liblzma-dev libopenjp2-7-dev libboost-dev python3 python3-pip python3-dev python3-numpy swig ninja-build libhdf5-dev libnetcdf-dev libpq-dev libxml2-dev\n", - " ---> Using cache\n", - " ---> bd1e25e4a887\n", - "Step 4/10 : RUN git clone https://github.com/rouault/gdal.git /gdal && cd /gdal && git fetch --tags && LATEST_TAG=$(git describe --tags `git rev-list --tags --max-count=1`) && echo \"Using GDAL sentinel2_geoloc_missing_granules\" && git checkout sentinel2_geoloc_missing_granules\n", - " ---> Using cache\n", - " ---> bfeced2e5339\n", - "Step 5/10 : RUN mkdir /gdal/build\n", - " ---> Using cache\n", - " ---> b16c40868e8e\n", - "Step 6/10 : RUN cd /gdal/build && cmake .. -GNinja -DCMAKE_BUILD_TYPE=Release -DBUILD_PYTHON_BINDINGS=ON -DGDAL_USE_OPENJPEG=ON -DGDAL_USE_TIFF_INTERNAL=ON -DGDAL_USE_GEOTIFF_INTERNAL=ON -DGDAL_USE_JPEG_INTERNAL=ON\n", - " ---> Using cache\n", - " ---> 06435d37867a\n", - "Step 7/10 : RUN cd /gdal/build && ninja && ninja install\n", - " ---> Using cache\n", - " ---> c502c440c76b\n", - "Step 8/10 : RUN ldconfig\n", - " ---> Using cache\n", - " ---> e0f05073c6a4\n", - "Step 9/10 : RUN gdalinfo --version\n", - " ---> Using cache\n", - " ---> de5dd366334c\n", - "Step 10/10 : ENTRYPOINT [\"/bin/bash\"]\n", - " ---> Using cache\n", - " ---> 33cca57541bf\n", - "Successfully built 33cca57541bf\n", - "Successfully tagged gdal-latest:latest\n", - "GDAL image built successfully.\n", - "\n", - "\n", - "=== GENERATING GDAL SCRIPT ===\n", - "VRTs to process: 5\n", - " - S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02\n", - " - S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02\n", - " - S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02\n", - " - S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02\n", - " - S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02\n", - "\n", - "=== RUNNING GDAL PROCESSING ===\n", - "\n", - "Command: docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR:/workspace -v /home/pcastillo/sen2vm/WORKDIR/output/DIRECT_gdal:/output gdal-latest /workspace/src/gdal_ortho.sh \n", - "\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "DEPRECATED: The legacy builder is deprecated and will be removed in a future release.\n", - " Install the buildx component to build images with BuildKit:\n", - " https://docs.docker.com/go/buildx/\n", - "\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "=== ORTHORECTIFICATION ===\n", - "----------------------------------------\n", - "Processing VRT: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02\n", - "----------------------------------------\n", - "Band resolution: 10 m\n", - "Creating output file that is 7037P x 3334L.\n", - "Processing S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02 [1/1] : 0...10...20...30...40...50...60...70...80...90...100 - done in 00:00:10.\n", - "----------------------------------------\n", - "Processing VRT: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02\n", - "----------------------------------------\n", - "Band resolution: 10 m\n", - "Creating output file that is 7037P x 3334L.\n", - "Processing S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02 [1/1] : 0" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Warning 1: Too many points (529 out of 529) failed to transform, unable to compute output bounds.\n", - "Warning 1: Unable to compute source region for output window 0,0,3328,3334, skipping.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "...10...20...30...40...50...60...70...80...90...100 - done in 00:00:10.\n", - "----------------------------------------\n", - "Processing VRT: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02\n", - "----------------------------------------\n", - "Band resolution: 10 m\n", - "Creating output file that is 7037P x 3334L.\n", - "Processing S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02 [1/1] : 0" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Warning 1: Too many points (529 out of 529) failed to transform, unable to compute output bounds.\n", - "Warning 1: Unable to compute source region for output window 3328,0,3709,3334, skipping.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "...10...20...30...40...50...60...70...80...90...100 - done in 00:00:09.\n", - "----------------------------------------\n", - "Processing VRT: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02\n", - "----------------------------------------\n", - "Band resolution: 10 m\n", - "Creating output file that is 7037P x 3334L.\n", - "Processing S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02 [1/1] : 0...10...20...30...40...50...60...70...80...90...100 - done in 00:00:10.\n", - "----------------------------------------\n", - "Processing VRT: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02\n", - "----------------------------------------\n", - "Band resolution: 10 m\n", - "Creating output file that is 7037P x 3334L.\n", - "Processing S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02 [1/1] : 0...10...20...30...40...50...60...70...80...90...100 - done in 00:00:15.\n", - "\n", - "=== MOSAIC GENERATION ===\n", - "\n", - "----------------------------------------\n", - "Creating mosaic for band: B02\n", - "----------------------------------------\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - " Mosaic written -> /output/GDAL_OUTPUT_MOSAIC/ORTHO_mosaic_B02.tif\n", - "\n", - "=== GDAL processing complete ===\n", - "\n", - "GDAL ortho + mosaic complete.\n", - "\n", - "Docker images kept (faster next run, ~4 GB disk usage).\n", - "\n" - ] - } - ], + "outputs": [], "source": [ "import os\n", "import subprocess\n", diff --git a/sen2vm-notebook/src/notebook-inverse-grid.ipynb b/sen2vm-notebook/src/notebook-inverse-grid.ipynb index efc74de6..10707548 100644 --- a/sen2vm-notebook/src/notebook-inverse-grid.ipynb +++ b/sen2vm-notebook/src/notebook-inverse-grid.ipynb @@ -20,13 +20,13 @@ "# /!\\/!\\/!\\ CAREFUL, please read the README_Notebooks.md file before\n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "\n", - "WORKDIR = \"/home/pcastillo/sen2vm/WORKDIR\" # Working directory for sen2vm processing\n", + "WORKDIR = \"PATH/TO/WORKDIR\" # Working directory for sen2vm processing\n", "\n", "# Path to downloaded product\n", - "PATH_L1B_DATA = \"/home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE\"\n", + "PATH_L1B_DATA = \"PATH/TO/L1B_PRODUCT\"\n", "\n", "# Path to GIPP directory\n", - "PATH_GIPP = \"/home/pcastillo/sen2vm/WORKDIR/GIPP\"\n", + "PATH_GIPP = \"PATH/TO/GIPP\"\n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "# /!\\/!\\/!\\ If you do not have your own GIPP folder, you may use the inputs-download-notebook to download it, then you may indicate the path were you \n", "# /!\\/!\\/!\\ downloaded it here in PATH_GIPP\n", @@ -34,17 +34,17 @@ "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "\n", "# Path to DEM directory \n", - "PATH_DEM = \"/home/pcastillo/sen2vm/WORKDIR/DEM\"\n", + "PATH_DEM = \"PATH/TO/DEM\"\n", "\n", "# Path to GEOID directory\n", - "PATH_GEOID = \"/home/pcastillo/sen2vm/WORKDIR/GEOID\"\n", + "PATH_GEOID = \"PATH/TO/GEOID\"\n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "# /!\\/!\\/!\\ If you do not have your own GEOID folder, you may use the inputs-download-notebook to download it, then you may indicate the path were you\n", "# /!\\/!\\/!\\ downloaded it here in \n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "\n", "# Path to IERS file\n", - "PATH_IERS = \"/home/pcastillo/sen2vm/WORKDIR\"\n", + "PATH_IERS = \"PATH/TO/IERS_FILE\"\n", "# /!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\/!\\\n", "# /!\\/!\\/!\\ If you do not have your own IERS, you may let this path empy (i.e. \"\") and execute the cell number 2 named #IERS Download\n", "# /!\\/!\\/!\\ In this case, the IERS will be downloaded in the WORKDIR\n", @@ -101,35 +101,10 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "8ec4d6f6", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Stopping because PATH_IERS is not empty\n" - ] - }, - { - "ename": "SystemExit", - "evalue": "0", - "output_type": "error", - "traceback": [ - "An exception has occurred, use %tb to see the full traceback.\n", - "\u001b[31mSystemExit\u001b[39m\u001b[31m:\u001b[39m 0\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/pcastillo/sen2vm/sen2vm-core/sen2vm-notebook/src/.venv/lib/python3.13/site-packages/IPython/core/interactiveshell.py:3709: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.\n", - " warn(\"To exit: use 'exit', 'quit', or Ctrl-D.\", stacklevel=1)\n" - ] - } - ], + "outputs": [], "source": [ "# === DOWNLOAD IERS ===\n", "import os\n", @@ -254,22 +229,10 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "id": "276592b5", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "UserConf directory: /home/pcastillo/sen2vm/WORKDIR/UserConf\n", - "Geoid directory: /home/pcastillo/sen2vm/WORKDIR/GEOID\n", - "/data/IERS/bulletina-xxxvii-042.txt\n", - "Configuration file generated:\n", - "/home/pcastillo/sen2vm/WORKDIR/UserConf/config.json\n" - ] - } - ], + "outputs": [], "source": [ "# === GENERATE CONFIG.JSON ===\n", "\n", @@ -383,24 +346,10 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "id": "23b1da25", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "UserConf directory: /home/pcastillo/sen2vm/WORKDIR/UserConf\n", - "Found 60 granule folders.\n", - "Detected detectors: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12']\n", - "Detected bands: ['B01', 'B02', 'B03', 'B04', 'B05', 'B06', 'B07', 'B08', 'B09', 'B10', 'B11', 'B12', 'B8A']\n", - "params.json written to: /home/pcastillo/sen2vm/WORKDIR/UserConf/params.json\n", - " - Detectors: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12']\n", - " - Bands: ['B02']\n" - ] - } - ], + "outputs": [], "source": [ "# === GENERATE PARAMS.JSON ===\n", "\n", @@ -498,161 +447,10 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "id": "572bd72a", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Building Docker image 'sen2vm' from: /home/pcastillo/sen2vm/sen2vm-core\n", - "Command: docker build -t sen2vm /home/pcastillo/sen2vm/sen2vm-core \n", - "\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "DEPRECATED: The legacy builder is deprecated and will be removed in a future release.\n", - " Install the buildx component to build images with BuildKit:\n", - " https://docs.docker.com/go/buildx/\n", - "\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Sending build context to Docker daemon 1.718GB\n", - "Step 1/5 : FROM ghcr.io/sen2vm/sen2vm-build-env:latest AS launcher\n", - " ---> a5369801b500\n", - "Step 2/5 : ENV SEN2VM_VERSION=1.1.4\n", - " ---> Using cache\n", - " ---> 14de44fa18ab\n", - "Step 3/5 : WORKDIR /Sen2vm\n", - " ---> Using cache\n", - " ---> b4079a1b81e1\n", - "Step 4/5 : RUN curl -L -o sen2vm-core.jar https://github.com/sen2vm/sen2vm-core/releases/download/${SEN2VM_VERSION}/sen2vm-core-${SEN2VM_VERSION}.jar\n", - " ---> Using cache\n", - " ---> 01c51fc5d7d7\n", - "Step 5/5 : ENTRYPOINT [\"java\", \"-jar\",\"sen2vm-core.jar\"]\n", - " ---> Using cache\n", - " ---> 5be1977daa50\n", - "Successfully built 5be1977daa50\n", - "Successfully tagged sen2vm:latest\n", - "Docker image built successfully.\n", - "\n", - "Running Docker container...\n", - "\n", - "Command: docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/DEM:/data/DEM -v /home/pcastillo/sen2vm/WORKDIR/GIPP:/data/GIPP -v /home/pcastillo/sen2vm/WORKDIR/GEOID:/data/GEOID -v /home/pcastillo/sen2vm/WORKDIR:/data/IERS -v /home/pcastillo/sen2vm/WORKDIR:/workspace sen2vm -c /workspace/UserConf/config.json -p /workspace/UserConf/params.json \n", - "\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2026-06-26 09:12:56 [INFO ] Start Sen2VM \n", - "2026-06-26 09:12:57 [INFO ] Parsing file /workspace/UserConf/config.json \n", - "2026-06-26 09:12:57 [INFO ] Reading IERS file at: /data/IERS/bulletina-xxxvii-042.txt \n", - "2026-06-26 09:12:57 [INFO ] Parsing file /workspace/UserConf/params.json \n", - "2026-06-26 09:12:57 [INFO ] Detectors list: [DETECTOR_1, DETECTOR_2, DETECTOR_3, DETECTOR_4, DETECTOR_5, DETECTOR_6, DETECTOR_7, DETECTOR_8, DETECTOR_9, DETECTOR_10, DETECTOR_11, DETECTOR_12] \n", - "2026-06-26 09:12:57 [INFO ] Bands list: [BAND_2] \n", - "2026-06-26 09:12:57 [INFO ] Find the following datastrip metadata file: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/S2B_OPER_MTD_L1B_DS_2BPS_20241019T153411_S20241019T120215.xml \n", - "2026-06-26 09:12:58 [INFO ] Initializing: copy of the Orekit-data: /Sen2vm/orekit-data \n", - "2026-06-26 09:12:58 [INFO ] Orekit-data: /Sen2vm/orekit-data \n", - "2026-06-26 09:13:05 [INFO ] Get through GIPP folder: /data/GIPP/S2B \n", - "2026-06-26 09:13:05 [INFO ] Read blind pixel file: /data/GIPP/S2B/S2B_OPER_GIP_BLINDP_MPC__20170221T000000_V20170101T000000_21000101T000000_B00.xml \n", - "2026-06-26 09:13:05 [INFO ] Read spacecraft model file: /data/GIPP/S2B/S2B_OPER_GIP_SPAMOD_MPC__20231122T110035_V20231123T000000_21000101T000000_B00.xml \n", - "2026-06-26 09:13:05 [INFO ] Read viewingDirection file: /data/GIPP/S2B/S2B_OPER_GIP_VIEDIR_MPC__20170512T114736_V20170322T000000_21000101T000000_B02.xml \n", - "2026-06-26 09:13:06 [INFO ] setAndProcessDataStrip listOfFiles/data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11 \n", - "2026-06-26 09:13:06 [INFO ] Datastrip S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11 \n", - "2026-06-26 09:13:06 [INFO ] EGSG read from configuration file (for inverse location): EPSG:32628 \n", - "2026-06-26 09:13:06 [INFO ] \n", - "2026-06-26 09:13:06 [INFO ] Starting grids generation \n", - "2026-06-26 09:13:06 [INFO ] \n", - "2026-06-26 09:13:06 [INFO ] ############### \n", - "2026-06-26 09:13:06 [INFO ] ### BAND 2 ### \n", - "2026-06-26 09:13:06 [INFO ] ############### \n", - "2026-06-26 09:13:06 [INFO ] Grid resolution: 45.0 \n", - "2026-06-26 09:13:06 [INFO ] Band resolution: 10.0 \n", - "2026-06-26 09:13:06 [INFO ] \n", - "2026-06-26 09:13:06 [INFO ] ### DET 01 (BAND 2) ### \n", - "2026-06-26 09:13:06 [INFO ] # Grid information \n", - "2026-06-26 09:13:06 [INFO ] Step: (-45.0, 45.0); UL: (3641682.5, 283887.5) LR: (3608292.5, 354312.5) \n", - "2026-06-26 09:13:22 [INFO ] Granule grid saved in: /workspace/output/INVERSE/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D01_B02.tif \n", - "2026-06-26 09:13:22 [INFO ] \n", - "2026-06-26 09:13:22 [INFO ] ### DET 02 (BAND 2) ### \n", - "2026-06-26 09:13:22 [INFO ] # Grid information \n", - "2026-06-26 09:13:22 [INFO ] Step: (-45.0, 45.0); UL: (3641682.5, 283887.5) LR: (3608292.5, 354312.5) \n", - "2026-06-26 09:13:38 [INFO ] Granule grid saved in: /workspace/output/INVERSE/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D02_B02.tif \n", - "2026-06-26 09:13:38 [INFO ] \n", - "2026-06-26 09:13:38 [INFO ] ### DET 03 (BAND 2) ### \n", - "2026-06-26 09:13:38 [INFO ] # Grid information \n", - "2026-06-26 09:13:38 [INFO ] Step: (-45.0, 45.0); UL: (3641682.5, 283887.5) LR: (3608292.5, 354312.5) \n", - "2026-06-26 09:13:53 [INFO ] Granule grid saved in: /workspace/output/INVERSE/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D03_B02.tif \n", - "2026-06-26 09:13:53 [INFO ] \n", - "2026-06-26 09:13:53 [INFO ] ### DET 04 (BAND 2) ### \n", - "2026-06-26 09:13:53 [INFO ] # Grid information \n", - "2026-06-26 09:13:53 [INFO ] Step: (-45.0, 45.0); UL: (3641682.5, 283887.5) LR: (3608292.5, 354312.5) \n", - "2026-06-26 09:14:09 [INFO ] Granule grid saved in: /workspace/output/INVERSE/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D04_B02.tif \n", - "2026-06-26 09:14:09 [INFO ] \n", - "2026-06-26 09:14:09 [INFO ] ### DET 05 (BAND 2) ### \n", - "2026-06-26 09:14:09 [INFO ] # Grid information \n", - "2026-06-26 09:14:09 [INFO ] Step: (-45.0, 45.0); UL: (3641682.5, 283887.5) LR: (3608292.5, 354312.5) \n", - "2026-06-26 09:14:24 [INFO ] Granule grid saved in: /workspace/output/INVERSE/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D05_B02.tif \n", - "2026-06-26 09:14:24 [INFO ] \n", - "2026-06-26 09:14:24 [INFO ] ### DET 06 (BAND 2) ### \n", - "2026-06-26 09:14:24 [INFO ] # Grid information \n", - "2026-06-26 09:14:24 [INFO ] Step: (-45.0, 45.0); UL: (3641682.5, 283887.5) LR: (3608292.5, 354312.5) \n", - "2026-06-26 09:14:40 [INFO ] Granule grid saved in: /workspace/output/INVERSE/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D06_B02.tif \n", - "2026-06-26 09:14:40 [INFO ] \n", - "2026-06-26 09:14:40 [INFO ] ### DET 07 (BAND 2) ### \n", - "2026-06-26 09:14:40 [INFO ] # Grid information \n", - "2026-06-26 09:14:40 [INFO ] Step: (-45.0, 45.0); UL: (3641682.5, 283887.5) LR: (3608292.5, 354312.5) \n", - "2026-06-26 09:14:56 [INFO ] Granule grid saved in: /workspace/output/INVERSE/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02.tif \n", - "2026-06-26 09:14:56 [INFO ] \n", - "2026-06-26 09:14:56 [INFO ] ### DET 08 (BAND 2) ### \n", - "2026-06-26 09:14:56 [INFO ] # Grid information \n", - "2026-06-26 09:14:56 [INFO ] Step: (-45.0, 45.0); UL: (3641682.5, 283887.5) LR: (3608292.5, 354312.5) \n", - "2026-06-26 09:15:13 [INFO ] Granule grid saved in: /workspace/output/INVERSE/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02.tif \n", - "2026-06-26 09:15:13 [INFO ] \n", - "2026-06-26 09:15:13 [INFO ] ### DET 09 (BAND 2) ### \n", - "2026-06-26 09:15:13 [INFO ] # Grid information \n", - "2026-06-26 09:15:13 [INFO ] Step: (-45.0, 45.0); UL: (3641682.5, 283887.5) LR: (3608292.5, 354312.5) \n", - "2026-06-26 09:15:30 [INFO ] Granule grid saved in: /workspace/output/INVERSE/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02.tif \n", - "2026-06-26 09:15:30 [INFO ] \n", - "2026-06-26 09:15:30 [INFO ] ### DET 10 (BAND 2) ### \n", - "2026-06-26 09:15:30 [INFO ] # Grid information \n", - "2026-06-26 09:15:30 [INFO ] Step: (-45.0, 45.0); UL: (3641682.5, 283887.5) LR: (3608292.5, 354312.5) \n", - "2026-06-26 09:15:48 [INFO ] Granule grid saved in: /workspace/output/INVERSE/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02.tif \n", - "2026-06-26 09:15:48 [INFO ] \n", - "2026-06-26 09:15:48 [INFO ] ### DET 11 (BAND 2) ### \n", - "2026-06-26 09:15:48 [INFO ] # Grid information \n", - "2026-06-26 09:15:48 [INFO ] Step: (-45.0, 45.0); UL: (3641682.5, 283887.5) LR: (3608292.5, 354312.5) \n", - "2026-06-26 09:16:04 [INFO ] Granule grid saved in: /workspace/output/INVERSE/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02.tif \n", - "2026-06-26 09:16:04 [INFO ] \n", - "2026-06-26 09:16:04 [INFO ] ### DET 12 (BAND 2) ### \n", - "2026-06-26 09:16:04 [INFO ] # Grid information \n", - "2026-06-26 09:16:04 [INFO ] Step: (-45.0, 45.0); UL: (3641682.5, 283887.5) LR: (3608292.5, 354312.5) \n", - "2026-06-26 09:16:19 [INFO ] Granule grid saved in: /workspace/output/INVERSE/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D12_B02.tif \n", - "2026-06-26 09:16:19 [INFO ] Find the following datastrip metadata file: /data/L1B/DATASTRIP/S2B_OPER_MSI_L1B_DS_2BPS_20241019T153411_S20241019T120215_N05.11/S2B_OPER_MTD_L1B_DS_2BPS_20241019T153411_S20241019T120215.xml \n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "Docker execution complete.\n", - "\n", - "Docker images kept.\n", - "\n" - ] - } - ], + "outputs": [], "source": [ "# === RUN SEN2VM (Docker: BUILD + RUN + CLEAN) ===\n", "\n", @@ -731,612 +529,10 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "id": "61ebba54-43f0-4d39-9589-40c87609f70e", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Product: S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE\n", - "Using XML: /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml\n", - "Bands from params.json: ['B02']\n", - "Detectors from params.json: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12']\n", - "\n", - "=== BUILDING GDAL CONTAINER ===\n", - "\n", - "Command:\n", - "docker build --platform=linux/amd64 -t gdal-latest /home/pcastillo/sen2vm/sen2vm-core/sen2vm-notebook/src/gdal-latest\n", - "Sending build context to Docker daemon 3.072kB\n", - "Step 1/10 : FROM ubuntu:22.04\n", - " ---> 962f6cadeae0\n", - "Step 2/10 : ENV DEBIAN_FRONTEND=noninteractive\n", - " ---> Using cache\n", - " ---> e6e9ea6fb1e0\n", - "Step 3/10 : RUN apt-get update && apt-get install -y build-essential git cmake pkg-config curl wget zip libcurl4-openssl-dev libproj-dev proj-bin libgeos-dev libsqlite3-dev libtiff-dev libjpeg-dev libpng-dev libzstd-dev liblzma-dev libopenjp2-7-dev libboost-dev python3 python3-pip python3-dev python3-numpy swig ninja-build libhdf5-dev libnetcdf-dev libpq-dev libxml2-dev\n", - " ---> Using cache\n", - " ---> bd1e25e4a887\n", - "Step 4/10 : RUN git clone https://github.com/rouault/gdal.git /gdal && cd /gdal && git fetch --tags && LATEST_TAG=$(git describe --tags `git rev-list --tags --max-count=1`) && echo \"Using GDAL sentinel2_geoloc_missing_granules\" && git checkout sentinel2_geoloc_missing_granules\n", - " ---> Using cache\n", - " ---> bfeced2e5339\n", - "Step 5/10 : RUN mkdir /gdal/build\n", - " ---> Using cache\n", - " ---> b16c40868e8e\n", - "Step 6/10 : RUN cd /gdal/build && cmake .. -GNinja -DCMAKE_BUILD_TYPE=Release -DBUILD_PYTHON_BINDINGS=ON -DGDAL_USE_OPENJPEG=ON -DGDAL_USE_TIFF_INTERNAL=ON -DGDAL_USE_GEOTIFF_INTERNAL=ON -DGDAL_USE_JPEG_INTERNAL=ON\n", - " ---> Using cache\n", - " ---> 06435d37867a\n", - "Step 7/10 : RUN cd /gdal/build && ninja && ninja install\n", - " ---> Using cache\n", - " ---> c502c440c76b\n", - "Step 8/10 : RUN ldconfig\n", - " ---> Using cache\n", - " ---> e0f05073c6a4\n", - "Step 9/10 : RUN gdalinfo --version\n", - " ---> Using cache\n", - " ---> de5dd366334c\n", - "Step 10/10 : ENTRYPOINT [\"/bin/bash\"]\n", - " ---> Using cache\n", - " ---> 33cca57541bf\n", - "Successfully built 33cca57541bf\n", - "Successfully tagged gdal-latest:latest\n", - "\n", - "GDAL image built successfully.\n", - "\n", - "\n", - "Found 12 inverse grids:\n", - "\n", - " S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D12_B02.tif\n", - " S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02.tif\n", - " S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D06_B02.tif\n", - " S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02.tif\n", - " S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02.tif\n", - " S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02.tif\n", - " S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D05_B02.tif\n", - " S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D01_B02.tif\n", - " S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D03_B02.tif\n", - " S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D04_B02.tif\n", - " S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02.tif\n", - " S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D02_B02.tif\n", - "\n", - "=================================================\n", - "Processing: S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D12_B02.tif\n", - "=================================================\n", - "Detector: 12\n", - "Band: B02\n", - "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D12_B02\n", - "Resolution: 10\n", - "Width : 7037\n", - "Height: 3334\n", - "\n", - "=== EXTRACTION ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", - " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D12_B02\" \"/output/raw/raw_D12_B02.tif\"\n", - " \n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "DEPRECATED: The legacy builder is deprecated and will be removed in a future release.\n", - " Install the buildx component to build images with BuildKit:\n", - " https://docs.docker.com/go/buildx/\n", - "\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Input file size is 2552, 11520\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "=== OTB RESAMPLING ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D12_B02.tif -io.out /output/otb_no_georef/ortho_D12_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D12_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", - "2026-06-26 09:16:25 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", - "2026-06-26 09:16:25 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", - "2026-06-26 09:16:25 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", - "2026-06-26 09:16:25 (INFO): Loading metadata from official product\n", - "2026-06-26 09:16:25 (INFO): Loading metadata from official product\n", - "2026-06-26 09:16:25 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:16:25 (INFO): Estimated memory for full processing: 234.894MB (avail.: 256 MB), optimal image partitioning: 1 blocks\n", - "2026-06-26 09:16:25 (INFO): File /output/otb_no_georef/ortho_D12_B02.tif will be written in 1 blocks of 7037x3334 pixels\n", - "Writing /output/otb_no_georef/ortho_D12_B02.tif...: 100% [**************************************************] (0s)\n", - "OTB success\n", - "\n", - "=== ADD GEOREF ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", - " gdal_translate -a_srs EPSG:32628 /output/otb_no_georef/ortho_D12_B02.tif /output/output_georef/ortho_D12_B02_georef.tif\n", - " \n", - "Input file size is 7037, 3334\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "Finished: ortho_D12_B02_georef.tif\n", - "\n", - "=================================================\n", - "Processing: S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02.tif\n", - "=================================================\n", - "Detector: 09\n", - "Band: B02\n", - "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02\n", - "Resolution: 10\n", - "Width : 7037\n", - "Height: 3334\n", - "\n", - "=== EXTRACTION ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", - " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02\" \"/output/raw/raw_D09_B02.tif\"\n", - " \n", - "Input file size is 2552, 11520\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "=== OTB RESAMPLING ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D09_B02.tif -io.out /output/otb_no_georef/ortho_D09_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D09_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", - "2026-06-26 09:16:30 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", - "2026-06-26 09:16:30 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", - "2026-06-26 09:16:30 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", - "2026-06-26 09:16:30 (INFO): Loading metadata from official product\n", - "2026-06-26 09:16:30 (INFO): Loading metadata from official product\n", - "2026-06-26 09:16:30 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:16:30 (INFO): Estimated memory for full processing: 390.826MB (avail.: 256 MB), optimal image partitioning: 2 blocks\n", - "2026-06-26 09:16:30 (INFO): File /output/otb_no_georef/ortho_D09_B02.tif will be written in 3 blocks of 7037x1112 pixels\n", - "Writing /output/otb_no_georef/ortho_D09_B02.tif...: 100% [**************************************************] (3s)\n", - "OTB success\n", - "\n", - "=== ADD GEOREF ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", - " gdal_translate -a_srs EPSG:32628 /output/otb_no_georef/ortho_D09_B02.tif /output/output_georef/ortho_D09_B02_georef.tif\n", - " \n", - "Input file size is 7037, 3334\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "Finished: ortho_D09_B02_georef.tif\n", - "\n", - "=================================================\n", - "Processing: S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D06_B02.tif\n", - "=================================================\n", - "Detector: 06\n", - "Band: B02\n", - "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D06_B02\n", - "Resolution: 10\n", - "Width : 7037\n", - "Height: 3334\n", - "\n", - "=== EXTRACTION ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", - " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D06_B02\" \"/output/raw/raw_D06_B02.tif\"\n", - " \n", - "Input file size is 2552, 11520\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "=== OTB RESAMPLING ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D06_B02.tif -io.out /output/otb_no_georef/ortho_D06_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D06_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", - "2026-06-26 09:16:39 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", - "2026-06-26 09:16:39 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", - "2026-06-26 09:16:39 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", - "2026-06-26 09:16:39 (INFO): Loading metadata from official product\n", - "2026-06-26 09:16:39 (INFO): Loading metadata from official product\n", - "2026-06-26 09:16:39 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:16:39 (INFO): Estimated memory for full processing: 234.894MB (avail.: 256 MB), optimal image partitioning: 1 blocks\n", - "2026-06-26 09:16:39 (INFO): File /output/otb_no_georef/ortho_D06_B02.tif will be written in 1 blocks of 7037x3334 pixels\n", - "Writing /output/otb_no_georef/ortho_D06_B02.tif...: 100% [**************************************************] (0s)\n", - "OTB success\n", - "\n", - "=== ADD GEOREF ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", - " gdal_translate -a_srs EPSG:32628 /output/otb_no_georef/ortho_D06_B02.tif /output/output_georef/ortho_D06_B02_georef.tif\n", - " \n", - "Input file size is 7037, 3334\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "Finished: ortho_D06_B02_georef.tif\n", - "\n", - "=================================================\n", - "Processing: S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02.tif\n", - "=================================================\n", - "Detector: 11\n", - "Band: B02\n", - "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02\n", - "Resolution: 10\n", - "Width : 7037\n", - "Height: 3334\n", - "\n", - "=== EXTRACTION ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", - " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02\" \"/output/raw/raw_D11_B02.tif\"\n", - " \n", - "Input file size is 2552, 11520\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "=== OTB RESAMPLING ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D11_B02.tif -io.out /output/otb_no_georef/ortho_D11_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D11_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", - "2026-06-26 09:16:44 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", - "2026-06-26 09:16:44 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", - "2026-06-26 09:16:44 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", - "2026-06-26 09:16:44 (INFO): Loading metadata from official product\n", - "2026-06-26 09:16:44 (INFO): Loading metadata from official product\n", - "2026-06-26 09:16:44 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:16:44 (INFO): Estimated memory for full processing: 234.894MB (avail.: 256 MB), optimal image partitioning: 1 blocks\n", - "2026-06-26 09:16:44 (INFO): File /output/otb_no_georef/ortho_D11_B02.tif will be written in 1 blocks of 7037x3334 pixels\n", - "Writing /output/otb_no_georef/ortho_D11_B02.tif...: 100% [**************************************************] (1s)\n", - "OTB success\n", - "\n", - "=== ADD GEOREF ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", - " gdal_translate -a_srs EPSG:32628 /output/otb_no_georef/ortho_D11_B02.tif /output/output_georef/ortho_D11_B02_georef.tif\n", - " \n", - "Input file size is 7037, 3334\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "Finished: ortho_D11_B02_georef.tif\n", - "\n", - "=================================================\n", - "Processing: S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02.tif\n", - "=================================================\n", - "Detector: 08\n", - "Band: B02\n", - "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02\n", - "Resolution: 10\n", - "Width : 7037\n", - "Height: 3334\n", - "\n", - "=== EXTRACTION ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", - " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02\" \"/output/raw/raw_D08_B02.tif\"\n", - " \n", - "Input file size is 2552, 11520\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "=== OTB RESAMPLING ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D08_B02.tif -io.out /output/otb_no_georef/ortho_D08_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D08_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", - "2026-06-26 09:16:51 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", - "2026-06-26 09:16:51 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", - "2026-06-26 09:16:51 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", - "2026-06-26 09:16:51 (INFO): Loading metadata from official product\n", - "2026-06-26 09:16:51 (INFO): Loading metadata from official product\n", - "2026-06-26 09:16:51 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:16:51 (INFO): Estimated memory for full processing: 234.894MB (avail.: 256 MB), optimal image partitioning: 1 blocks\n", - "2026-06-26 09:16:51 (INFO): File /output/otb_no_georef/ortho_D08_B02.tif will be written in 1 blocks of 7037x3334 pixels\n", - "Writing /output/otb_no_georef/ortho_D08_B02.tif...: 100% [**************************************************] (2s)\n", - "OTB success\n", - "\n", - "=== ADD GEOREF ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", - " gdal_translate -a_srs EPSG:32628 /output/otb_no_georef/ortho_D08_B02.tif /output/output_georef/ortho_D08_B02_georef.tif\n", - " \n", - "Input file size is 7037, 3334\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "Finished: ortho_D08_B02_georef.tif\n", - "\n", - "=================================================\n", - "Processing: S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02.tif\n", - "=================================================\n", - "Detector: 07\n", - "Band: B02\n", - "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02\n", - "Resolution: 10\n", - "Width : 7037\n", - "Height: 3334\n", - "\n", - "=== EXTRACTION ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", - " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02\" \"/output/raw/raw_D07_B02.tif\"\n", - " \n", - "Input file size is 2552, 11520\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "=== OTB RESAMPLING ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D07_B02.tif -io.out /output/otb_no_georef/ortho_D07_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D07_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", - "2026-06-26 09:16:59 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", - "2026-06-26 09:16:59 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", - "2026-06-26 09:16:59 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", - "2026-06-26 09:16:59 (INFO): Loading metadata from official product\n", - "2026-06-26 09:16:59 (INFO): Loading metadata from official product\n", - "2026-06-26 09:16:59 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:16:59 (INFO): Estimated memory for full processing: 234.894MB (avail.: 256 MB), optimal image partitioning: 1 blocks\n", - "2026-06-26 09:16:59 (INFO): File /output/otb_no_georef/ortho_D07_B02.tif will be written in 1 blocks of 7037x3334 pixels\n", - "Writing /output/otb_no_georef/ortho_D07_B02.tif...: 100% [**************************************************] (1s)\n", - "OTB success\n", - "\n", - "=== ADD GEOREF ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", - " gdal_translate -a_srs EPSG:32628 /output/otb_no_georef/ortho_D07_B02.tif /output/output_georef/ortho_D07_B02_georef.tif\n", - " \n", - "Input file size is 7037, 3334\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "Finished: ortho_D07_B02_georef.tif\n", - "\n", - "=================================================\n", - "Processing: S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D05_B02.tif\n", - "=================================================\n", - "Detector: 05\n", - "Band: B02\n", - "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D05_B02\n", - "Resolution: 10\n", - "Width : 7037\n", - "Height: 3334\n", - "\n", - "=== EXTRACTION ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", - " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D05_B02\" \"/output/raw/raw_D05_B02.tif\"\n", - " \n", - "Input file size is 2552, 11520\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "=== OTB RESAMPLING ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D05_B02.tif -io.out /output/otb_no_georef/ortho_D05_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D05_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", - "2026-06-26 09:17:06 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", - "2026-06-26 09:17:06 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", - "2026-06-26 09:17:06 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", - "2026-06-26 09:17:06 (INFO): Loading metadata from official product\n", - "2026-06-26 09:17:06 (INFO): Loading metadata from official product\n", - "2026-06-26 09:17:06 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:17:06 (INFO): Estimated memory for full processing: 234.894MB (avail.: 256 MB), optimal image partitioning: 1 blocks\n", - "2026-06-26 09:17:06 (INFO): File /output/otb_no_georef/ortho_D05_B02.tif will be written in 1 blocks of 7037x3334 pixels\n", - "Writing /output/otb_no_georef/ortho_D05_B02.tif...: 100% [**************************************************] (0s)\n", - "OTB success\n", - "\n", - "=== ADD GEOREF ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", - " gdal_translate -a_srs EPSG:32628 /output/otb_no_georef/ortho_D05_B02.tif /output/output_georef/ortho_D05_B02_georef.tif\n", - " \n", - "Input file size is 7037, 3334\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "Finished: ortho_D05_B02_georef.tif\n", - "\n", - "=================================================\n", - "Processing: S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D01_B02.tif\n", - "=================================================\n", - "Detector: 01\n", - "Band: B02\n", - "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D01_B02\n", - "Resolution: 10\n", - "Width : 7037\n", - "Height: 3334\n", - "\n", - "=== EXTRACTION ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", - " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D01_B02\" \"/output/raw/raw_D01_B02.tif\"\n", - " \n", - "Input file size is 2552, 11520\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "=== OTB RESAMPLING ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D01_B02.tif -io.out /output/otb_no_georef/ortho_D01_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D01_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", - "2026-06-26 09:17:11 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", - "2026-06-26 09:17:11 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", - "2026-06-26 09:17:11 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", - "2026-06-26 09:17:11 (INFO): Loading metadata from official product\n", - "2026-06-26 09:17:11 (INFO): Loading metadata from official product\n", - "2026-06-26 09:17:11 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:17:11 (INFO): Estimated memory for full processing: 234.894MB (avail.: 256 MB), optimal image partitioning: 1 blocks\n", - "2026-06-26 09:17:11 (INFO): File /output/otb_no_georef/ortho_D01_B02.tif will be written in 1 blocks of 7037x3334 pixels\n", - "Writing /output/otb_no_georef/ortho_D01_B02.tif...: 100% [**************************************************] (0s)\n", - "OTB success\n", - "\n", - "=== ADD GEOREF ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", - " gdal_translate -a_srs EPSG:32628 /output/otb_no_georef/ortho_D01_B02.tif /output/output_georef/ortho_D01_B02_georef.tif\n", - " \n", - "Input file size is 7037, 3334\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "Finished: ortho_D01_B02_georef.tif\n", - "\n", - "=================================================\n", - "Processing: S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D03_B02.tif\n", - "=================================================\n", - "Detector: 03\n", - "Band: B02\n", - "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D03_B02\n", - "Resolution: 10\n", - "Width : 7037\n", - "Height: 3334\n", - "\n", - "=== EXTRACTION ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", - " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D03_B02\" \"/output/raw/raw_D03_B02.tif\"\n", - " \n", - "Input file size is 2552, 11520\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "=== OTB RESAMPLING ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D03_B02.tif -io.out /output/otb_no_georef/ortho_D03_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D03_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", - "2026-06-26 09:17:17 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", - "2026-06-26 09:17:17 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", - "2026-06-26 09:17:17 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", - "2026-06-26 09:17:17 (INFO): Loading metadata from official product\n", - "2026-06-26 09:17:17 (INFO): Loading metadata from official product\n", - "2026-06-26 09:17:17 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:17:17 (INFO): Estimated memory for full processing: 234.894MB (avail.: 256 MB), optimal image partitioning: 1 blocks\n", - "2026-06-26 09:17:17 (INFO): File /output/otb_no_georef/ortho_D03_B02.tif will be written in 1 blocks of 7037x3334 pixels\n", - "Writing /output/otb_no_georef/ortho_D03_B02.tif...: 100% [**************************************************] (0s)\n", - "OTB success\n", - "\n", - "=== ADD GEOREF ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", - " gdal_translate -a_srs EPSG:32628 /output/otb_no_georef/ortho_D03_B02.tif /output/output_georef/ortho_D03_B02_georef.tif\n", - " \n", - "Input file size is 7037, 3334\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "Finished: ortho_D03_B02_georef.tif\n", - "\n", - "=================================================\n", - "Processing: S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D04_B02.tif\n", - "=================================================\n", - "Detector: 04\n", - "Band: B02\n", - "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D04_B02\n", - "Resolution: 10\n", - "Width : 7037\n", - "Height: 3334\n", - "\n", - "=== EXTRACTION ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", - " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D04_B02\" \"/output/raw/raw_D04_B02.tif\"\n", - " \n", - "Input file size is 2552, 11520\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "=== OTB RESAMPLING ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D04_B02.tif -io.out /output/otb_no_georef/ortho_D04_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D04_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", - "2026-06-26 09:17:23 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", - "2026-06-26 09:17:23 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", - "2026-06-26 09:17:23 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", - "2026-06-26 09:17:23 (INFO): Loading metadata from official product\n", - "2026-06-26 09:17:23 (INFO): Loading metadata from official product\n", - "2026-06-26 09:17:23 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:17:23 (INFO): Estimated memory for full processing: 234.894MB (avail.: 256 MB), optimal image partitioning: 1 blocks\n", - "2026-06-26 09:17:23 (INFO): File /output/otb_no_georef/ortho_D04_B02.tif will be written in 1 blocks of 7037x3334 pixels\n", - "Writing /output/otb_no_georef/ortho_D04_B02.tif...: 100% [**************************************************] (0s)\n", - "OTB success\n", - "\n", - "=== ADD GEOREF ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", - " gdal_translate -a_srs EPSG:32628 /output/otb_no_georef/ortho_D04_B02.tif /output/output_georef/ortho_D04_B02_georef.tif\n", - " \n", - "Input file size is 7037, 3334\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "Finished: ortho_D04_B02_georef.tif\n", - "\n", - "=================================================\n", - "Processing: S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02.tif\n", - "=================================================\n", - "Detector: 10\n", - "Band: B02\n", - "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02\n", - "Resolution: 10\n", - "Width : 7037\n", - "Height: 3334\n", - "\n", - "=== EXTRACTION ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", - " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02\" \"/output/raw/raw_D10_B02.tif\"\n", - " \n", - "Input file size is 2552, 11520\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "=== OTB RESAMPLING ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D10_B02.tif -io.out /output/otb_no_georef/ortho_D10_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D10_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", - "2026-06-26 09:17:29 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", - "2026-06-26 09:17:29 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", - "2026-06-26 09:17:29 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", - "2026-06-26 09:17:29 (INFO): Loading metadata from official product\n", - "2026-06-26 09:17:29 (INFO): Loading metadata from official product\n", - "2026-06-26 09:17:29 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:17:29 (INFO): Estimated memory for full processing: 234.894MB (avail.: 256 MB), optimal image partitioning: 1 blocks\n", - "2026-06-26 09:17:29 (INFO): File /output/otb_no_georef/ortho_D10_B02.tif will be written in 1 blocks of 7037x3334 pixels\n", - "Writing /output/otb_no_georef/ortho_D10_B02.tif...: 100% [**************************************************] (2s)\n", - "OTB success\n", - "\n", - "=== ADD GEOREF ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", - " gdal_translate -a_srs EPSG:32628 /output/otb_no_georef/ortho_D10_B02.tif /output/output_georef/ortho_D10_B02_georef.tif\n", - " \n", - "Input file size is 7037, 3334\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "Finished: ortho_D10_B02_georef.tif\n", - "\n", - "=================================================\n", - "Processing: S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D02_B02.tif\n", - "=================================================\n", - "Detector: 02\n", - "Band: B02\n", - "Subdataset: S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D02_B02\n", - "Resolution: 10\n", - "Width : 7037\n", - "Height: 3334\n", - "\n", - "=== EXTRACTION ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/S2B_MSIL1B_20241019T120219_N0511_R023_20241022T154709.SAFE:/data/L1B -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", - " gdal_translate \"SENTINEL2_L1B_WITH_GEOLOC:/data/L1B/S2B_OPER_MTD_SAFL1B_PDMC_20241022T154709_R023_V20241019T120217_20241019T120235.xml:S2B_OPER_GEO_L1B_DS_2BPS_20241019T153411_S20241019T120215_D02_B02\" \"/output/raw/raw_D02_B02.tif\"\n", - " \n", - "Input file size is 2552, 11520\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "=== OTB RESAMPLING ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output orfeotoolbox/otb:9.0.0 otbcli_GridBasedImageResampling -io.in /output/raw/raw_D02_B02.tif -io.out /output/otb_no_georef/ortho_D02_B02.tif -grid.in /output/INVERSE_GRID/S2B_OPER_INV_L1B_DS_2BPS_20241019T153411_S20241019T120215_D02_B02.tif -grid.type loc -out.ulx 283915.0 -out.uly 3641655.0 -out.spacingx 10 -out.spacingy -10 -out.sizex 7037 -out.sizey 3334\n", - "2026-06-26 09:17:37 (INFO) GridBasedImageResampling: Default RAM limit for OTB is 256 MB\n", - "2026-06-26 09:17:37 (INFO) GridBasedImageResampling: GDAL maximum cache size is 799 MB\n", - "2026-06-26 09:17:37 (INFO) GridBasedImageResampling: OTB will use at most 4 threads\n", - "2026-06-26 09:17:37 (INFO): Loading metadata from official product\n", - "2026-06-26 09:17:37 (INFO): Loading metadata from official product\n", - "2026-06-26 09:17:37 (INFO) GridBasedImageResampling: Grid interpreted as a location grid.2026-06-26 09:17:37 (INFO): Estimated memory for full processing: 234.894MB (avail.: 256 MB), optimal image partitioning: 1 blocks\n", - "2026-06-26 09:17:37 (INFO): File /output/otb_no_georef/ortho_D02_B02.tif will be written in 1 blocks of 7037x3334 pixels\n", - "Writing /output/otb_no_georef/ortho_D02_B02.tif...: 100% [**************************************************] (0s)\n", - "OTB success\n", - "\n", - "=== ADD GEOREF ===\n", - "\n", - "docker run --rm -v /home/pcastillo/sen2vm/WORKDIR/output/INVERSE:/output gdal-latest -c \n", - " gdal_translate -a_srs EPSG:32628 /output/otb_no_georef/ortho_D02_B02.tif /output/output_georef/ortho_D02_B02_georef.tif\n", - " \n", - "Input file size is 7037, 3334\n", - "0...10...20...30...40...50...60...70...80...90...100 - done.\n", - "\n", - "Finished: ortho_D02_B02_georef.tif\n", - "\n", - "=== MOSAIC CREATION ===\n", - "\n", - "Bands detected: {'B02'}\n", - "\n", - "----------------------------------------\n", - "Creating mosaic for band: B02\n", - "----------------------------------------\n", - "Found 12 files\n", - " ortho_D01_B02_georef.tif\n", - " ortho_D02_B02_georef.tif\n", - " ortho_D03_B02_georef.tif\n", - " ortho_D04_B02_georef.tif\n", - " ortho_D05_B02_georef.tif\n", - " ortho_D06_B02_georef.tif\n", - " ortho_D07_B02_georef.tif\n", - " ortho_D08_B02_georef.tif\n", - " ortho_D09_B02_georef.tif\n", - " ortho_D10_B02_georef.tif\n", - " ortho_D11_B02_georef.tif\n", - " ortho_D12_B02_georef.tif\n", - "\n", - "Running mosaic:\n", - " gdal_merge.py -o /output/mosaic/ORTHO_mosaic_B02.tif -of GTiff -co COMPRESS=LZW -co TILED=YES -ot UInt16 -n 0 -a_nodata 0 /output/output_georef/ortho_D01_B02_georef.tif /output/output_georef/ortho_D02_B02_georef.tif /output/output_georef/ortho_D03_B02_georef.tif /output/output_georef/ortho_D04_B02_georef.tif /output/output_georef/ortho_D05_B02_georef.tif /output/output_georef/ortho_D06_B02_georef.tif /output/output_georef/ortho_D07_B02_georef.tif /output/output_georef/ortho_D08_B02_georef.tif /output/output_georef/ortho_D09_B02_georef.tif /output/output_georef/ortho_D10_B02_georef.tif /output/output_georef/ortho_D11_B02_georef.tif /output/output_georef/ortho_D12_B02_georef.tif \n", - "0...10...20...30...40...50...60...70...80...90...100 - done in 00:00:09.\n", - "Mosaic written → /home/pcastillo/sen2vm/WORKDIR/output/INVERSE/mosaic/ORTHO_mosaic_B02.tif\n", - "Docker images kept (faster next run, ~4 GB disk usage).\n", - "\n" - ] - } - ], + "outputs": [], "source": [ "# =====================================================\n", "# INVERSE\n", From 9a40b2c8df84966527ae68cd079bed0b77c178c7 Mon Sep 17 00:00:00 2001 From: aburie Date: Wed, 15 Jul 2026 12:22:46 +0200 Subject: [PATCH 06/13] Change step in notebooks + typo + style --- .../src/inputs-download-notebook.ipynb | 10 ++- .../src/notebook-direct-grid-otb.ipynb | 70 +++++++++---------- .../src/notebook-direct-grid.ipynb | 50 ++++++------- .../src/notebook-inverse-grid.ipynb | 68 +++++++++--------- .../sen2vm/input/gipp/GIPPFileManager.java | 4 +- .../java/esa/sen2vm/Sen2VMCheckPointTest.java | 2 +- src/test/java/esa/sen2vm/Utils.java | 6 +- 7 files changed, 104 insertions(+), 106 deletions(-) diff --git a/sen2vm-notebook/src/inputs-download-notebook.ipynb b/sen2vm-notebook/src/inputs-download-notebook.ipynb index 48b6f870..7e20258b 100644 --- a/sen2vm-notebook/src/inputs-download-notebook.ipynb +++ b/sen2vm-notebook/src/inputs-download-notebook.ipynb @@ -25,13 +25,11 @@ ] }, { - "cell_type": "code", - "execution_count": 2, + "cell_type": "markdown", "id": "93bc15d2-9c05-4cc2-82e5-3533e1bbcfd0", "metadata": {}, - "outputs": [], "source": [ - "# GIPP database download" + "# === GIPP database download ===" ] }, { @@ -74,7 +72,7 @@ "print(\"Clone complete.\\n\")\n", "\n", "print(\"GIPP processing finished successfully.\")\n", - "print(\"GIPP donwloaded in :\", PATH_GIPP)\n" + "print(\"GIPP donwloaded in : \", PATH_GIPP)\n" ] }, { @@ -82,7 +80,7 @@ "id": "0e8b2d6d-5e67-4145-aa04-42d99671d36b", "metadata": {}, "source": [ - "# GEOID folder copy from github" + "# === GEOID folder copy from github ===" ] }, { diff --git a/sen2vm-notebook/src/notebook-direct-grid-otb.ipynb b/sen2vm-notebook/src/notebook-direct-grid-otb.ipynb index 95383bad..3675ec9c 100644 --- a/sen2vm-notebook/src/notebook-direct-grid-otb.ipynb +++ b/sen2vm-notebook/src/notebook-direct-grid-otb.ipynb @@ -10,7 +10,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "2b816cd9-5254-452b-bced-2943eb6b7aec", "metadata": {}, "outputs": [], @@ -63,18 +63,18 @@ "}\n", "\n", "# Grid step in pixels for sen2vm grid generation \n", - "# These values represent the grid step in pixels, typically DEM resolution / 2\n", - "# For S2 with DEM90, this gives approximately: 45m/10m=4.5, 45m/20m=2.25, 45m/60m≈1\n", + "# These values represent the grid step in pixels\n", + "# In operation, this step is linked to DEM step which is not constant over the world, pending the Latitude\n", "STEPS = {\n", - " \"10m_bands\": 4.5, # Grid step: ~DEM90/2 = 45m/10m = 4.5 pixels (one point every 4.5 pixels at 10m)\n", - " \"20m_bands\": 2.25, # Grid step: ~DEM90/2 = 45m/20m = 2.25 pixels (one point every 2.25 pixels at 20m)\n", - " \"60m_bands\": 1.0 # Grid step: ~DEM90/2 = 45m/60m ≈ 1 pixel (one point every 1 pixel at 60m, or 2 is also fine)\n", + " \"10m_bands\": 4.5, # Around 45m in operation (pending laittude) with 30m and also 90m DEM\n", + " \"20m_bands\": 4.5, # Around 90m in operation (pending laittude) with 30m and also 90m DEM\n", + " \"60m_bands\": 3.0 # Around 180m in operation (pending laittude) with 30m and also 90m DEM\n", "}\n", "\n", "# === GDAL ORTHO OPTIONS ===\n", "\n", "ORTHO_SETTINGS = {\n", - " \"keep_bands\": [\"B02\"], # list of bands to keep for orthorectification\n", + " \"keep_bands\": [\"B01\", \"B02\", \"B03\", \"B04\", \"B05\", \"B06\", \"B07\", \"B08\", \"B8A\", \"B09\", \"B10\", \"B11\", \"B12\"], # list of bands to keep for orthorectification\n", " \"keep_detectors\": [\"07\",\"08\",\"09\",\"10\",\"11\"] # list of the detectors to keep \n", "}\n", "\n", @@ -114,14 +114,14 @@ "import sys\n", "from datetime import datetime\n", "\n", - "if len(PATH_IERS) != 0: #Safety in case the PATH_IERS isn't empty\n", + "if len(PATH_IERS) != 0: # Safety in case the PATH_IERS isn't empty\n", " print(\"Stopping because PATH_IERS is not empty\")\n", " sys.exit(0)\n", "\n", "if not os.path.exists(WORKDIR):\n", " raise RuntimeError(f\"WORKDIR directory not found: {WORKDIR}\")\n", "\n", - "print(\"Bulletin output directory:\", WORKDIR)\n", + "print(\"Bulletin output directory: \", WORKDIR)\n", "\n", "PATH_IERS = WORKDIR # then our file will be there\n", "# =====================================================================\n", @@ -131,11 +131,11 @@ "for f in os.listdir(WORKDIR):\n", " if f.startswith(\"bulletina-\") and f.endswith(\".txt\"):\n", " os.remove(os.path.join(WORKDIR, f))\n", - " print(\"Removed old bulletin A:\", f)\n", + " print(\"Removed old bulletin A: \", f)\n", "\n", " if f.startswith(\"bulletinb-\") and f.endswith(\".txt\"):\n", " os.remove(os.path.join(WORKDIR, f))\n", - " print(\"Removed old bulletin B:\", f)\n", + " print(\"Removed old bulletin B: \", f)\n", "\n", "print(\"Cleanup of old bulletins complete.\\n\")\n", "# =====================================================================\n", @@ -166,7 +166,7 @@ "\n", "product_date = datetime(year, month, day)\n", "\n", - "print(\"Product date extracted from DATASTRIP:\", product_date.date(), \"\\n\")\n", + "print(\"Product date extracted from DATASTRIP: \", product_date.date(), \"\\n\")\n", "# =====================================================================\n", "# Roman conversion \n", "# =====================================================================\n", @@ -199,12 +199,12 @@ "while index > 0:\n", " index_str = f\"{index:03d}\"\n", " url = f\"https://datacenter.iers.org/data/6/bulletina-{roman_year}-{index_str}.txt\"\n", - " print(\"Trying bulletin:\", url)\n", + " print(\"Trying bulletin: \", url)\n", "\n", " response = requests.get(url)\n", "\n", " if response.status_code == 200:\n", - " print(\"Bulletin found:\", index_str)\n", + " print(\"Bulletin found: \", index_str)\n", " dest_file = os.path.join(WORKDIR, f\"bulletina-{roman_year}-{index_str}.txt\")\n", " found = True\n", " break\n", @@ -217,7 +217,7 @@ "with open(dest_file, \"wb\") as f:\n", " f.write(response.content)\n", "\n", - "print(\"Downloaded:\", dest_file)" + "print(\"Downloaded: \", dest_file)" ] }, { @@ -246,8 +246,8 @@ "USERCONF_DIR = os.path.join(WORKDIR, \"UserConf\")\n", "os.makedirs(USERCONF_DIR, exist_ok=True)\n", "\n", - "print(\"UserConf directory:\", USERCONF_DIR)\n", - "print(\"Geoid directory:\", PATH_GEOID)\n", + "print(\"UserConf directory: \", USERCONF_DIR)\n", + "print(\"Geoid directory: \", PATH_GEOID)\n", "\n", "# =====================================================\n", "# 1. Extract mission from DATASTRIP\n", @@ -332,7 +332,7 @@ "with open(config_path, \"w\") as f:\n", " json.dump(config, f, indent=4)\n", "\n", - "print(\"Configuration file generated:\")\n", + "print(\"Configuration file generated: \")\n", "print(config_path)" ] }, @@ -352,7 +352,7 @@ "USERCONF_DIR = os.path.join(WORKDIR, \"UserConf\")\n", "os.makedirs(USERCONF_DIR, exist_ok=True)\n", "\n", - "print(\"UserConf directory:\", USERCONF_DIR)\n", + "print(\"UserConf directory: \", USERCONF_DIR)\n", "# =====================================================\n", "# Locate GRANULE folders\n", "# =====================================================\n", @@ -393,8 +393,8 @@ "detectors = sorted(detectors)\n", "bands = sorted(bands)\n", "\n", - "print(\"Detected detectors:\", detectors)\n", - "print(\"Detected bands:\", bands)\n", + "print(\"Detected detectors: \", detectors)\n", + "print(\"Detected bands: \", bands)\n", "# =====================================================\n", "# Write params.json\n", "# =====================================================\n", @@ -423,7 +423,7 @@ "with open(params_path, \"w\") as f:\n", " json.dump(params, f, indent=4)\n", "\n", - "print(\"params.json written to:\", params_path)\n", + "print(\"params.json written to: \", params_path)\n", "print(f\" - Detectors: {params['detectors']}\")\n", "print(f\" - Bands: {params['bands']}\")" ] @@ -567,7 +567,7 @@ "# XML path inside docker (relative, after cd)\n", "xml_docker = f\"./{xml_name}\"\n", "\n", - "print(\"Using XML:\", xml_path)\n", + "print(\"Using XML: \", xml_path)\n", "\n", "# =====================================================\n", "# Read params.json to get selected bands and detectors\n", @@ -656,8 +656,8 @@ " )\n", " print(\"\\n========================================\")\n", " print(\"Generating inverse grid\")\n", - " print(\"Direct :\", direct_grid)\n", - " print(\"Inverse:\", inverse_grid)\n", + " print(\"Direct: \", direct_grid)\n", + " print(\"Inverse: \", inverse_grid)\n", " print(\"========================================\")\n", "\n", " sen2vm_invloc_from_dir_loc_grid(\n", @@ -674,7 +674,7 @@ "for inv_grid_path in inverse_grid_list:\n", " test_grid = os.path.basename(inv_grid_path)\n", " print(\"\\n=================================================\")\n", - " print(\"Processing:\", test_grid)\n", + " print(\"Processing: \", test_grid)\n", " print(\"=================================================\")\n", "\n", " # =================================================\n", @@ -688,14 +688,14 @@ " detector = match.group(1)\n", " band = f\"B{match.group(2)}\"\n", "\n", - " print(\"Detector:\", detector)\n", - " print(\"Band:\", band)\n", + " print(\"Detector: \", detector)\n", + " print(\"Band: \", band)\n", "\n", " # =================================================\n", " # Build subdataset dynamically\n", " # =================================================\n", " subdataset = test_grid.replace(\".tif\", \"\")\n", - " print(\"Subdataset:\", subdataset)\n", + " print(\"Subdataset: \", subdataset)\n", " \n", " # =================================================\n", " # Determine resolution\n", @@ -709,7 +709,7 @@ " else:\n", " resolution = 10\n", " \n", - " print(\"Resolution:\", resolution)\n", + " print(\"Resolution: \", resolution)\n", " \n", " # =================================================\n", " # Compute output size\n", @@ -720,8 +720,8 @@ " height = int(\n", " (LOCATION[\"ul_y\"] - LOCATION[\"lr_y\"]) / resolution\n", " )\n", - " print(\"Width :\", width)\n", - " print(\"Height:\", height)\n", + " print(\"Width: \", width)\n", + " print(\"Height: \", height)\n", "\n", " # =================================================\n", " # File paths\n", @@ -817,7 +817,7 @@ " print(\"\\n=== ADD GEOREF ===\\n\")\n", " print(\" \".join(cmd_georef))\n", " subprocess.run(cmd_georef, check=True)\n", - " print(\"\\nFinished:\", georef_name)\n", + " print(\"\\nFinished: \", georef_name)\n", "\n", "# =====================================================\n", "# Mosaic\n", @@ -828,12 +828,12 @@ " match = re.search(r\"_B(\\d{2}[A]?)\", f)\n", " if match:\n", " bands.add(f\"B{match.group(1)}\")\n", - "print(\"Bands detected:\", bands)\n", + "print(\"Bands detected: \", bands)\n", "\n", "for band in bands:\n", "\n", " print(\"\\n----------------------------------------\")\n", - " print(\"Creating mosaic for band:\", band)\n", + " print(\"Creating mosaic for band: \", band)\n", " print(\"----------------------------------------\")\n", " # fichiers correspondant à la bande\n", " input_files = glob.glob(\n", diff --git a/sen2vm-notebook/src/notebook-direct-grid.ipynb b/sen2vm-notebook/src/notebook-direct-grid.ipynb index 152cff0a..5616fdf1 100644 --- a/sen2vm-notebook/src/notebook-direct-grid.ipynb +++ b/sen2vm-notebook/src/notebook-direct-grid.ipynb @@ -10,7 +10,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "2b816cd9-5254-452b-bced-2943eb6b7aec", "metadata": {}, "outputs": [], @@ -63,18 +63,18 @@ "}\n", "\n", "# Grid step in pixels for sen2vm grid generation \n", - "# These values represent the grid step in pixels, typically DEM resolution / 2\n", - "# For S2 with DEM90, this gives approximately: 45m/10m=4.5, 45m/20m=2.25, 45m/60m≈1\n", + "# These values represent the grid step in pixels\n", + "# In operation, this step is linked to DEM step which is not constant over the world, pending the Latitude\n", "STEPS = {\n", - " \"10m_bands\": 4.5, # Grid step: ~DEM90/2 = 45m/10m = 4.5 pixels (one point every 4.5 pixels at 10m)\n", - " \"20m_bands\": 2.25, # Grid step: ~DEM90/2 = 45m/20m = 2.25 pixels (one point every 2.25 pixels at 20m)\n", - " \"60m_bands\": 1.0 # Grid step: ~DEM90/2 = 45m/60m ≈ 1 pixel (one point every 1 pixel at 60m, or 2 is also fine)\n", + " \"10m_bands\": 4.5, # Around 45m in operation (pending laittude) with 30m and also 90m DEM\n", + " \"20m_bands\": 4.5, # Around 90m in operation (pending laittude) with 30m and also 90m DEM\n", + " \"60m_bands\": 3.0 # Around 180m in operation (pending laittude) with 30m and also 90m DEM\n", "}\n", "\n", "# === GDAL ORTHO OPTIONS ===\n", "\n", "ORTHO_SETTINGS = {\n", - " \"keep_bands\": [\"B02\"], # list of bands to keep for orthorectification\n", + " \"keep_bands\": [\"B01\", \"B02\", \"B03\", \"B04\", \"B05\", \"B06\", \"B07\", \"B08\", \"B8A\", \"B09\", \"B10\", \"B11\", \"B12\"], # list of bands to keep for orthorectification\n", " \"keep_detectors\": [\"07\",\"08\",\"09\",\"10\",\"11\"] # list of the detectors to keep \n", "}\n", "\n", @@ -114,14 +114,14 @@ "import sys\n", "from datetime import datetime\n", "\n", - "if len(PATH_IERS) != 0: #Safety in case the PATH_IERS isn't empty\n", + "if len(PATH_IERS) != 0: # Safety in case the PATH_IERS isn't empty\n", " print(\"Stopping because PATH_IERS is not empty\")\n", " sys.exit(0)\n", "\n", "if not os.path.exists(WORKDIR):\n", " raise RuntimeError(f\"WORKDIR directory not found: {WORKDIR}\")\n", "\n", - "print(\"Bulletin output directory:\", WORKDIR)\n", + "print(\"Bulletin output directory: \", WORKDIR)\n", "\n", "PATH_IERS = WORKDIR # then our file will be there\n", "# =====================================================================\n", @@ -131,11 +131,11 @@ "for f in os.listdir(WORKDIR):\n", " if f.startswith(\"bulletina-\") and f.endswith(\".txt\"):\n", " os.remove(os.path.join(WORKDIR, f))\n", - " print(\"Removed old bulletin A:\", f)\n", + " print(\"Removed old bulletin A: \", f)\n", "\n", " if f.startswith(\"bulletinb-\") and f.endswith(\".txt\"):\n", " os.remove(os.path.join(WORKDIR, f))\n", - " print(\"Removed old bulletin B:\", f)\n", + " print(\"Removed old bulletin B: \", f)\n", "\n", "print(\"Cleanup of old bulletins complete.\\n\")\n", "# =====================================================================\n", @@ -166,7 +166,7 @@ "\n", "product_date = datetime(year, month, day)\n", "\n", - "print(\"Product date extracted from DATASTRIP:\", product_date.date(), \"\\n\")\n", + "print(\"Product date extracted from DATASTRIP: \", product_date.date(), \"\\n\")\n", "# =====================================================================\n", "# Roman conversion \n", "# =====================================================================\n", @@ -199,12 +199,12 @@ "while index > 0:\n", " index_str = f\"{index:03d}\"\n", " url = f\"https://datacenter.iers.org/data/6/bulletina-{roman_year}-{index_str}.txt\"\n", - " print(\"Trying bulletin:\", url)\n", + " print(\"Trying bulletin: \", url)\n", "\n", " response = requests.get(url)\n", "\n", " if response.status_code == 200:\n", - " print(\"Bulletin found:\", index_str)\n", + " print(\"Bulletin found: \", index_str)\n", " dest_file = os.path.join(WORKDIR, f\"bulletina-{roman_year}-{index_str}.txt\")\n", " found = True\n", " break\n", @@ -217,7 +217,7 @@ "with open(dest_file, \"wb\") as f:\n", " f.write(response.content)\n", "\n", - "print(\"Downloaded:\", dest_file)" + "print(\"Downloaded: \", dest_file)" ] }, { @@ -246,8 +246,8 @@ "USERCONF_DIR = os.path.join(WORKDIR, \"UserConf\")\n", "os.makedirs(USERCONF_DIR, exist_ok=True)\n", "\n", - "print(\"UserConf directory:\", USERCONF_DIR)\n", - "print(\"Geoid directory:\", PATH_GEOID)\n", + "print(\"UserConf directory: \", USERCONF_DIR)\n", + "print(\"Geoid directory: \", PATH_GEOID)\n", "\n", "# =====================================================\n", "# 1. Extract mission from DATASTRIP\n", @@ -332,7 +332,7 @@ "with open(config_path, \"w\") as f:\n", " json.dump(config, f, indent=4)\n", "\n", - "print(\"Configuration file generated:\")\n", + "print(\"Configuration file generated: \")\n", "print(config_path)" ] }, @@ -352,7 +352,7 @@ "USERCONF_DIR = os.path.join(WORKDIR, \"UserConf\")\n", "os.makedirs(USERCONF_DIR, exist_ok=True)\n", "\n", - "print(\"UserConf directory:\", USERCONF_DIR)\n", + "print(\"UserConf directory: \", USERCONF_DIR)\n", "# =====================================================\n", "# Locate GRANULE folders\n", "# =====================================================\n", @@ -368,7 +368,7 @@ " if os.path.isdir(os.path.join(GR_TARGET_DIR, d))\n", "]\n", "\n", - "print(\"Found\", len(granule_folders), \"granule folders.\")\n", + "print(\"Found \", len(granule_folders), \" granule folders.\")\n", "# =====================================================\n", "# Extract detectors and bands from JP2\n", "# =====================================================\n", @@ -393,8 +393,8 @@ "detectors = sorted(detectors)\n", "bands = sorted(bands)\n", "\n", - "print(\"Detected detectors:\", detectors)\n", - "print(\"Detected bands:\", bands)\n", + "print(\"Detected detectors: \", detectors)\n", + "print(\"Detected bands: \", bands)\n", "# =====================================================\n", "# Write params.json\n", "# =====================================================\n", @@ -423,7 +423,7 @@ "with open(params_path, \"w\") as f:\n", " json.dump(params, f, indent=4)\n", "\n", - "print(\"params.json written to:\", params_path)\n", + "print(\"params.json written to: \", params_path)\n", "print(f\" - Detectors: {params['detectors']}\")\n", "print(f\" - Bands: {params['bands']}\")" ] @@ -558,7 +558,7 @@ "# XML path inside docker (relative, after cd)\n", "xml_docker = f\"./{xml_name}\"\n", "\n", - "print(\"Using XML:\", xml_path)\n", + "print(\"Using XML: \", xml_path)\n", "\n", "# =====================================================\n", "# Read params.json to get selected bands and detectors\n", @@ -618,7 +618,7 @@ "os.makedirs(os.path.join(OUTPUT_FOLDER, \"GDAL_OUTPUT_ORTHO\"), exist_ok=True)\n", "os.makedirs(os.path.join(OUTPUT_FOLDER, \"GDAL_OUTPUT_MOSAIC\"), exist_ok=True)\n", "\n", - "print(\"Output folder:\", OUTPUT_FOLDER)\n", + "print(\"Output folder: \", OUTPUT_FOLDER)\n", "\n", "# =====================================================\n", "# Build GDAL docker\n", diff --git a/sen2vm-notebook/src/notebook-inverse-grid.ipynb b/sen2vm-notebook/src/notebook-inverse-grid.ipynb index 10707548..a15a1a2c 100644 --- a/sen2vm-notebook/src/notebook-inverse-grid.ipynb +++ b/sen2vm-notebook/src/notebook-inverse-grid.ipynb @@ -10,7 +10,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "2b816cd9-5254-452b-bced-2943eb6b7aec", "metadata": {}, "outputs": [], @@ -63,18 +63,18 @@ "}\n", "\n", "# Grid step in pixels for sen2vm grid generation \n", - "# These values represent the grid step in pixels, it's the pixel in the detector geometry, typically DEM resolution\n", - "# For S2 with DEM90, this gives approximately: 45m\n", + "# These values represent the grid step in pixels, it's the pixel in the detector geometry\n", + "# In operation, this step is linked to DEM step which is not constant over the world, pending the Latitude\n", "STEPS = {\n", - " \"10m_bands\": 45, \n", - " \"20m_bands\": 45, \n", - " \"60m_bands\": 45\n", + " \"10m_bands\": 45, # Around 45m in operation (pending laittude) with 30m and also 90m DEM\n", + " \"20m_bands\": 90, # Around 90m in operation (pending laittude) with 30m and also 90m DEM\n", + " \"60m_bands\": 180 # Around 180m in operation (pending laittude) with 30m and also 90m DEM\n", "}\n", "\n", "# === GDAL ORTHO OPTIONS ===\n", "\n", "ORTHO_SETTINGS = {\n", - " \"keep_bands\": [\"B02\"], # list of bands to keep for orthorectification\n", + " \"keep_bands\": [\"B01\", \"B02\", \"B03\", \"B04\", \"B05\", \"B06\", \"B07\", \"B08\", \"B8A\", \"B09\", \"B10\", \"B11\", \"B12\"], # list of bands to keep for orthorectification\n", " \"keep_detectors\": [\"01\",\"02\",\"03\",\"04\",\"05\",\"06\",\"07\",\"08\",\"09\",\"10\",\"11\",\"12\"] # list of the detectors to keep \n", "}\n", "\n", @@ -113,14 +113,14 @@ "import sys\n", "from datetime import datetime\n", "\n", - "if len(PATH_IERS) != 0: #Safety in case the PATH_IERS isn't empty\n", + "if len(PATH_IERS) != 0: # Safety in case the PATH_IERS isn't empty\n", " print(\"Stopping because PATH_IERS is not empty\")\n", " sys.exit(0)\n", "\n", "if not os.path.exists(WORKDIR):\n", " raise RuntimeError(f\"WORKDIR directory not found: {WORKDIR}\")\n", "\n", - "print(\"Bulletin output directory:\", WORKDIR)\n", + "print(\"Bulletin output directory: \", WORKDIR)\n", "\n", "PATH_IERS = WORKDIR # then our file will be there\n", "# =====================================================================\n", @@ -130,11 +130,11 @@ "for f in os.listdir(WORKDIR):\n", " if f.startswith(\"bulletina-\") and f.endswith(\".txt\"):\n", " os.remove(os.path.join(WORKDIR, f))\n", - " print(\"Removed old bulletin A:\", f)\n", + " print(\"Removed old bulletin A: \", f)\n", "\n", " if f.startswith(\"bulletinb-\") and f.endswith(\".txt\"):\n", " os.remove(os.path.join(WORKDIR, f))\n", - " print(\"Removed old bulletin B:\", f)\n", + " print(\"Removed old bulletin B: \", f)\n", "\n", "print(\"Cleanup of old bulletins complete.\\n\")\n", "# =====================================================================\n", @@ -165,7 +165,7 @@ "\n", "product_date = datetime(year, month, day)\n", "\n", - "print(\"Product date extracted from DATASTRIP:\", product_date.date(), \"\\n\")\n", + "print(\"Product date extracted from DATASTRIP: \", product_date.date(), \"\\n\")\n", "# =====================================================================\n", "# Roman conversion \n", "# =====================================================================\n", @@ -198,12 +198,12 @@ "while index > 0:\n", " index_str = f\"{index:03d}\"\n", " url = f\"https://datacenter.iers.org/data/6/bulletina-{roman_year}-{index_str}.txt\"\n", - " print(\"Trying bulletin:\", url)\n", + " print(\"Trying bulletin: \", url)\n", "\n", " response = requests.get(url)\n", "\n", " if response.status_code == 200:\n", - " print(\"Bulletin found:\", index_str)\n", + " print(\"Bulletin found: \", index_str)\n", " dest_file = os.path.join(WORKDIR, f\"bulletina-{roman_year}-{index_str}.txt\")\n", " found = True\n", " break\n", @@ -216,7 +216,7 @@ "with open(dest_file, \"wb\") as f:\n", " f.write(response.content)\n", "\n", - "print(\"Downloaded:\", dest_file)" + "print(\"Downloaded: \", dest_file)" ] }, { @@ -245,9 +245,9 @@ "USERCONF_DIR = os.path.join(WORKDIR, \"UserConf\")\n", "os.makedirs(USERCONF_DIR, exist_ok=True)\n", "\n", - "print(\"UserConf directory:\", USERCONF_DIR)\n", + "print(\"UserConf directory: \", USERCONF_DIR)\n", "\n", - "print(\"Geoid directory:\", PATH_GEOID)\n", + "print(\"Geoid directory: \", PATH_GEOID)\n", "# =====================================================\n", "# 1. Extract mission from DATASTRIP\n", "# =====================================================\n", @@ -340,7 +340,7 @@ "with open(config_path, \"w\") as f:\n", " json.dump(config, f, indent=4)\n", "\n", - "print(\"Configuration file generated:\")\n", + "print(\"Configuration file generated: \")\n", "print(config_path)" ] }, @@ -360,7 +360,7 @@ "USERCONF_DIR = os.path.join(WORKDIR, \"UserConf\")\n", "os.makedirs(USERCONF_DIR, exist_ok=True)\n", "\n", - "print(\"UserConf directory:\", USERCONF_DIR)\n", + "print(\"UserConf directory: \", USERCONF_DIR)\n", "\n", "# =====================================================\n", "# Locate GRANULE folders\n", @@ -402,8 +402,8 @@ "detectors = sorted(detectors)\n", "bands = sorted(bands)\n", "\n", - "print(\"Detected detectors:\", detectors)\n", - "print(\"Detected bands:\", bands)\n", + "print(\"Detected detectors: \", detectors)\n", + "print(\"Detected bands: \", bands)\n", "# =====================================================\n", "# Write params.json\n", "# =====================================================\n", @@ -432,7 +432,7 @@ "with open(params_path, \"w\") as f:\n", " json.dump(params, f, indent=4)\n", "\n", - "print(\"params.json written to:\", params_path)\n", + "print(\"params.json written to: \", params_path)\n", "print(f\" - Detectors: {params['detectors']}\")\n", "print(f\" - Bands: {params['bands']}\")" ] @@ -566,7 +566,7 @@ "# Locate product name\n", "# =====================================================\n", "product = os.path.basename(os.path.normpath(PATH_L1B_DATA))\n", - "print(\"Product:\", product)\n", + "print(\"Product: \", product)\n", "\n", "# =====================================================\n", "# Locate XML\n", @@ -583,7 +583,7 @@ "\n", "xml_path = xml_list[0]\n", "xml_name = os.path.basename(xml_path)\n", - "print(\"Using XML:\", xml_path)\n", + "print(\"Using XML: \", xml_path)\n", "\n", "# =====================================================\n", "# Read params.json to get selected bands and detectors\n", @@ -647,7 +647,7 @@ "for inv_grid_path in inv_grid_list:\n", " test_grid = os.path.basename(inv_grid_path)\n", " print(\"\\n=================================================\")\n", - " print(\"Processing:\", test_grid)\n", + " print(\"Processing: \", test_grid)\n", " print(\"=================================================\")\n", "\n", " # =================================================\n", @@ -661,15 +661,15 @@ " detector = match.group(1)\n", " band = f\"B{match.group(2)}\"\n", "\n", - " print(\"Detector:\", detector)\n", - " print(\"Band:\", band)\n", + " print(\"Detector: \", detector)\n", + " print(\"Band: \", band)\n", "\n", " # =================================================\n", " # Build subdataset dynamically\n", " # =================================================\n", " subdataset = test_grid.replace(\"INV_L1B\", \"GEO_L1B\")\n", " subdataset = subdataset.replace(\".tif\", \"\")\n", - " print(\"Subdataset:\", subdataset)\n", + " print(\"Subdataset: \", subdataset)\n", " \n", " # =================================================\n", " # Determine resolution\n", @@ -683,7 +683,7 @@ " else:\n", " resolution = 10\n", " \n", - " print(\"Resolution:\", resolution)\n", + " print(\"Resolution: \", resolution)\n", " \n", " # =================================================\n", " # Compute output size\n", @@ -694,8 +694,8 @@ " height = int(\n", " (LOCATION[\"ul_y\"] - LOCATION[\"lr_y\"]) / resolution\n", " )\n", - " print(\"Width :\", width)\n", - " print(\"Height:\", height)\n", + " print(\"Width : \", width)\n", + " print(\"Height: \", height)\n", "\n", " # =================================================\n", " # File paths\n", @@ -791,7 +791,7 @@ " print(\"\\n=== ADD GEOREF ===\\n\")\n", " print(\" \".join(cmd_georef))\n", " subprocess.run(cmd_georef, check=True)\n", - " print(\"\\nFinished:\", georef_name)\n", + " print(\"\\nFinished: \", georef_name)\n", "\n", "# =====================================================\n", "# Mosaic\n", @@ -802,12 +802,12 @@ " match = re.search(r\"_B(\\d{2}[A]?)\", f)\n", " if match:\n", " bands.add(f\"B{match.group(1)}\")\n", - "print(\"Bands detected:\", bands)\n", + "print(\"Bands detected: \", bands)\n", "\n", "for band in bands:\n", "\n", " print(\"\\n----------------------------------------\")\n", - " print(\"Creating mosaic for band:\", band)\n", + " print(\"Creating mosaic for band: \", band)\n", " print(\"----------------------------------------\")\n", " # fichiers correspondant à la bande\n", " input_files = glob.glob(\n", diff --git a/src/main/java/esa/sen2vm/input/gipp/GIPPFileManager.java b/src/main/java/esa/sen2vm/input/gipp/GIPPFileManager.java index ca847d78..6f52c332 100644 --- a/src/main/java/esa/sen2vm/input/gipp/GIPPFileManager.java +++ b/src/main/java/esa/sen2vm/input/gipp/GIPPFileManager.java @@ -219,7 +219,7 @@ public FileVisitResult visitFile(Path filePath, BasicFileAttributes attrs) { } catch(IOException e) { - LOGGER.warning("The targz extraction of GIPP has failed:"+file.toString()); + LOGGER.warning("The targz extraction of GIPP has failed: "+file.toString()); e.printStackTrace(); } } @@ -260,7 +260,7 @@ public static File findGippFile(Path root, String dirNameRegex, List gip final List results = findGippFiles(root, dirNameRegex, gippList, fileNameRegex, validExtensions); if(results.size()==0) { - throw new Sen2VMException("The directory must be contains keyword:"+fileNameRegex); + throw new Sen2VMException("The directory must be contains keyword: "+fileNameRegex); } else if(results.size()>1) { diff --git a/src/test/java/esa/sen2vm/Sen2VMCheckPointTest.java b/src/test/java/esa/sen2vm/Sen2VMCheckPointTest.java index 8f6a995c..87a41780 100644 --- a/src/test/java/esa/sen2vm/Sen2VMCheckPointTest.java +++ b/src/test/java/esa/sen2vm/Sen2VMCheckPointTest.java @@ -151,7 +151,7 @@ public void geoTimeFirstLine() LineSensor lineSensor = ruggedManager.getLineSensor("B01/D01"); String date = lineSensor.getDate(0.5).toString(TimeScalesFactory.getGPS()); - LOGGER.info("date line 0.5:" + date); + LOGGER.info("date line 0.5: " + date); assertEquals(date, "2020-08-16T12:02:45.812731"); } catch ( SXGeoException e ) { diff --git a/src/test/java/esa/sen2vm/Utils.java b/src/test/java/esa/sen2vm/Utils.java index ef057842..5c1066e0 100644 --- a/src/test/java/esa/sen2vm/Utils.java +++ b/src/test/java/esa/sen2vm/Utils.java @@ -77,9 +77,9 @@ public static void verifyStepDirectLoc(String configFilepath, int step) throws S double res = BandInfo.getBandInfoFromIndex(b).getPixelHeight(); Dataset ds = gdal.Open(grid.getPath()); double[] transform = ds.GetGeoTransform(); - System.out.println("transform:" + String.valueOf(transform[1])); - System.out.println("res:" + String.valueOf(res)); - System.out.println("step:" + String.valueOf(step)); + System.out.println("transform: " + String.valueOf(transform[1])); + System.out.println("res: " + String.valueOf(res)); + System.out.println("step: " + String.valueOf(step)); assertEquals(transform[1] * (res / 10), step); assertEquals(transform[5] * (res / 10), step); From c8b773f26eeba6a5f5c698153cf3da3a77de701d Mon Sep 17 00:00:00 2001 From: aburie Date: Wed, 15 Jul 2026 14:05:53 +0200 Subject: [PATCH 07/13] Style --- sen2vm-notebook/README_Notebooks.md | 24 +++++++++---------- .../java/esa/sen2vm/Sen2VMDirectTest.java | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/sen2vm-notebook/README_Notebooks.md b/sen2vm-notebook/README_Notebooks.md index d025e905..5c0edb0e 100644 --- a/sen2vm-notebook/README_Notebooks.md +++ b/sen2vm-notebook/README_Notebooks.md @@ -45,7 +45,7 @@ The project is designed and tested on **Linux**. It may not work reliably on **W * Required data: - * **Sentinel-2 L1B product** : /DATASTRIP and /GRANULE. + * **Sentinel-2 L1B product**: /DATASTRIP and /GRANULE. * **DEM files** ## Mandatory Directory Structure @@ -54,8 +54,8 @@ Only a `WORKDIR` folder is required. All outputs, as well as intermediate files ## Inputs -Several inputs are needed : -* L1B S2 product under EUP.SAFE format : +Several inputs are needed: +* L1B S2 product under EUP.SAFE format: ```bash / ├── DATASTRIP # Required @@ -96,7 +96,7 @@ WORKDIR ## Python Environment Setup -In the notebook directory create your venv : +In the notebook directory create your venv: ```bash python3 -m venv .venv @@ -108,16 +108,16 @@ Select the virtual environment kernel in your Jupyter session. ## Notebooks Configuration -In **inputs-download-notebook.ipynb** : -In the first cell of the notebook : +In **inputs-download-notebook.ipynb**: +In the first cell of the notebook: 1. Set the paths to: * The directory where you want the GIPP files to be downloaded * The directory where you want the GEOID files to be downloaded -In **notebook-direct-grid.ipynb** or in **notebook-inverse-grid.ipynb** : -In the first cell of the notebook : +In **notebook-direct-grid.ipynb** or in **notebook-inverse-grid.ipynb**: +In the first cell of the notebook: 1. Set the absolute paths to: @@ -139,13 +139,13 @@ In the first cell of the notebook : ## Processing Steps If you do not have your own GIPP and GEOID files, or if they are not already downloaded, -execute the **inputs-download-notebook.ipynb** cell by cell in the following order : +execute the **inputs-download-notebook.ipynb** cell by cell in the following order: 1. Path definitions 2. Clone `sen2vm-gipp`, and manage GIPP assets 3. Copy `Geoid` folder from `"*/sen2vm-core/src/test/resources/DEM_GEOID"` -Then if you want to use the direct grids, which may be longer, execute the **notebook-direct-grid.ipynb** cell by cell : +Then if you want to use the direct grids, which may be longer, execute the **notebook-direct-grid.ipynb** cell by cell: 1. Variable and path definitions 2. Automatic download of the IERS bulletin if none is provided by the user @@ -158,14 +158,14 @@ Then if you want to use the direct grids, which may be longer, execute the **no * Mosaicking by band that generate an image in `WORKDIR/DIRECT/GDAL_OUTPUT_MOSAIC` -If you want to use the inverse grids, execute the **notebook-inverse-grid.ipynb** cell by cell : +If you want to use the inverse grids, execute the **notebook-inverse-grid.ipynb** cell by cell: 1. Variable and path definitions 2. Automatic download of the IERS bulletin if none is provided by the user 3. Generation of `config.json` in: `/WORKDIR/UserConf` 4. Generation of `params.json` in: `/WORKDIR/UserConf` 5. Execution of sen2vm inside Docker to generate the inverse grids in `WORKDIR/output/INVERSE/INVERSE_GRID` -6. Orthorectification using OTB inside a docker then mosaicking using GDAL : +6. Orthorectification using OTB inside a docker then mosaicking using GDAL: * Orthorectification by band * Mosaicking diff --git a/src/test/java/esa/sen2vm/Sen2VMDirectTest.java b/src/test/java/esa/sen2vm/Sen2VMDirectTest.java index c29ffb77..b7eb8650 100644 --- a/src/test/java/esa/sen2vm/Sen2VMDirectTest.java +++ b/src/test/java/esa/sen2vm/Sen2VMDirectTest.java @@ -143,7 +143,7 @@ public void testAutoSelectTarGipp() String config = Config.configAutoGippSelection(configTmpDirect, GIPP_2, true, outputDir); String param = Config.changeParams(paramTmp, detectors, bands, outputDir); String[] args = {"-c", config, "-p", param}; - LOGGER.info("config:"+config); + LOGGER.info("config: "+config); Sen2VM.main(args); Utils.verifyDirectLoc(config, refDir + "/" + nameTest); } catch (Sen2VMException e) { @@ -186,7 +186,7 @@ public void testAutoSelectWithMissingGipp() String config = Config.configAutoGippSelection(configTmpDirect, GIPP_2, true, outputDir); String param = Config.changeParams(paramTmp, detectors, bands, outputDir); String[] args = {"-c", config, "-p", param}; - LOGGER.info("config:"+config); + LOGGER.info("config: "+config); Sen2VM.main(args); Utils.verifyDirectLoc(config, refDir + "/" + nameTest); } catch (Sen2VMException e) { From 32f19502d07e09fd64b7bb80234de17274eaeb5e Mon Sep 17 00:00:00 2001 From: aburie Date: Wed, 15 Jul 2026 14:08:02 +0200 Subject: [PATCH 08/13] Style --- sen2vm-notebook/src/inputs-download-notebook.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sen2vm-notebook/src/inputs-download-notebook.ipynb b/sen2vm-notebook/src/inputs-download-notebook.ipynb index 7e20258b..cb5327b8 100644 --- a/sen2vm-notebook/src/inputs-download-notebook.ipynb +++ b/sen2vm-notebook/src/inputs-download-notebook.ipynb @@ -72,7 +72,7 @@ "print(\"Clone complete.\\n\")\n", "\n", "print(\"GIPP processing finished successfully.\")\n", - "print(\"GIPP donwloaded in : \", PATH_GIPP)\n" + "print(\"GIPP downloaded in: \", PATH_GIPP)\n" ] }, { From 6ba560c771785d00b13d359e73eae978767708a9 Mon Sep 17 00:00:00 2001 From: Paul Castillo Date: Wed, 15 Jul 2026 15:38:08 +0000 Subject: [PATCH 09/13] update of README.md --- sen2vm-notebook/README_Notebooks.md | 41 ++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/sen2vm-notebook/README_Notebooks.md b/sen2vm-notebook/README_Notebooks.md index 5c0edb0e..a33fa456 100644 --- a/sen2vm-notebook/README_Notebooks.md +++ b/sen2vm-notebook/README_Notebooks.md @@ -17,13 +17,16 @@ This repository provides a complete workflow to run **Sen2VM** inside Docker and generate orthorectified and mosaicked outputs from Sentinel-2 L1B data. -Three notebooks are provided: +Four notebooks are provided: * **inputs-download-notebook.ipynb** Downloads all required input data (GEOID and GIPP) from the Git repository. * **notebook-direct-grid.ipynb** - Runs Sen2VM with the **direct** mode, using the downloaded inputs, along with the IERS file and L1B product, to produce orthorectified and mosaicked images. + Runs Sen2VM with the **direct** mode, using the downloaded inputs, along with the IERS file and L1B product, to produce orthorectified and mosaicked images using gdal functions. + +* **notebook-direct-grid-otb.ipynb** + Runs Sen2vm with the **direct** mode, using the downloaded inputs, along with the IERS file and L1B product, to product orthorectified and mosaicked imaged using otb functions. * **notebook-inverse-grid.ipynb** Runs Sen2VM with the **inverse** mode, using the downloaded inputs, along with the IERS file and L1B product, to produce orthorectified and mosaicked images. @@ -80,9 +83,15 @@ WORKDIR ├── bulletin*.txt # IERS prediction of earth exploration (downloaded by the cell n°3) │ ├── output/ # output after orthorectification and mosaic (.tif) -│ ├── DIRECT +│ ├── DIRECT_gdal │ │ ├─ GDAL_OUTPUT_ORTHO # .tif orthorectified, one for each band and detector │ │ └─ GDAL_OUTPUT_MOSAIC # .tif orthorectified and merged by band, one for each band +│ ├── DIRECT_otb +│ │ ├─ INVERSE_GRID # inverse gelocation grid, generated by sen2vm, these grids encode the transformation between sensor geometry and map geometry +│ │ ├─ raw # contains the raw L1B images extracted per detector and per band, expressed in the sensor geometry (i.e., before any orthorectification or map projection) +│ │ ├─ otb_no_georef # contains images resampled using OTB with the inverse grids. The data are projected onto a regular grid but are not yet fully georeferenced +│ │ ├─ output_georef # contains the final orthorectificatied and georeferenced images +│ │ └─ mosaic # contains mosaicked images generated per spectral band by merging all detector-level orthorectified │ └── INVERSE │ ├─ INVERSE_GRID # inverse gelocation grid, generated by sen2vm, these grids encode the transformation between sensor geometry and map geometry │ ├─ raw # contains the raw L1B images extracted per detector and per band, expressed in the sensor geometry (i.e., before any orthorectification or map projection) @@ -116,7 +125,7 @@ In the first cell of the notebook: * The directory where you want the GIPP files to be downloaded * The directory where you want the GEOID files to be downloaded -In **notebook-direct-grid.ipynb** or in **notebook-inverse-grid.ipynb**: +In **notebook-direct-grid.ipynb** or **notebook-direct-grid-otb.ipynb** or **notebook-inverse-grid.ipynb**: In the first cell of the notebook: 1. Set the absolute paths to: @@ -143,20 +152,34 @@ execute the **inputs-download-notebook.ipynb** cell by cell in the following ord 1. Path definitions 2. Clone `sen2vm-gipp`, and manage GIPP assets -3. Copy `Geoid` folder from `"*/sen2vm-core/src/test/resources/DEM_GEOID"` +3. Copy `Geoid` folder from `"/sen2vm-core/src/test/resources/DEM_GEOID"` -Then if you want to use the direct grids, which may be longer, execute the **notebook-direct-grid.ipynb** cell by cell: +Then if you want to use the direct grids with gdal functions only, execute the **notebook-direct-grid.ipynb** cell by cell: 1. Variable and path definitions 2. Automatic download of the IERS bulletin if none is provided by the user 3. Generation of `config.json` in: `/WORKDIR/UserConf` 4. Generation of `params.json` in: `/WORKDIR/UserConf` -5. Execution of sen2vm inside Docker +5. Execution of sen2vm inside Docker to generatre the direct grids 6. Generation of a `.sh` script, then execution inside a second Docker container running the latest GDAL: - * Orthorectification by band that generate images in `WORKDIR/DIRECT/GDAL_OUTPUT_ORTHO` - * Mosaicking by band that generate an image in `WORKDIR/DIRECT/GDAL_OUTPUT_MOSAIC` + * Orthorectification by band that generate images in `WORKDIR/DIRECT/GDAL_OUTPUT_ORTHO` using the function **gdalwarp** + * Mosaicking by band that generate an image in `WORKDIR/DIRECT/GDAL_OUTPUT_MOSAIC` using the function **gdalmerge.py** +If you want to use the direct grids with otb functions for the orthorectification, execute the **notebook-direct-grid-otb.ipynb** cell by cell + +1. Variable and path definitions +2. Automatic download of the IERS bulletin if none is provided by the user +3. Generation of `config.json` in: `/WORKDIR/UserConf` +4. Generation of `params.json` in: `/WORKDIR/UserConf` +5. Execution of sen2vm inside Docker to generate the direct grids +6. Generation of inverse grids in `WORKDIR/output/INVERSE/INVERSE_GRID` from the direct direct grids using **sen2vminvlocfromdirlocgrid** +7. Orthorectification using OTB inside a docker then mosaicking using GDAL: + + * Orthorectification by band + * Mosaicking + +Docker images can be removed or kept depending on the value of `REMOVE_DOCKER_IMAGE` in step 1. If you want to use the inverse grids, execute the **notebook-inverse-grid.ipynb** cell by cell: From b9344b2cd24cf24d370dfa7f7d460b3669734bc5 Mon Sep 17 00:00:00 2001 From: paul-csgroup0411 Date: Wed, 15 Jul 2026 17:54:44 +0200 Subject: [PATCH 10/13] Update README_Notebooks.md --- sen2vm-notebook/README_Notebooks.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/sen2vm-notebook/README_Notebooks.md b/sen2vm-notebook/README_Notebooks.md index a33fa456..6e9ba052 100644 --- a/sen2vm-notebook/README_Notebooks.md +++ b/sen2vm-notebook/README_Notebooks.md @@ -25,10 +25,10 @@ Four notebooks are provided: * **notebook-direct-grid.ipynb** Runs Sen2VM with the **direct** mode, using the downloaded inputs, along with the IERS file and L1B product, to produce orthorectified and mosaicked images using gdal functions. -* **notebook-direct-grid-otb.ipynb** - Runs Sen2vm with the **direct** mode, using the downloaded inputs, along with the IERS file and L1B product, to product orthorectified and mosaicked imaged using otb functions. +* **notebook-direct-grid-otb.ipynb** + Runs Sen2vm with the **direct** mode, using the downloaded inputs, along with the IERS file and L1B product, to product orthorectified and mosaicked images using otb functions. -* **notebook-inverse-grid.ipynb** +* **notebook-inverse-grid.ipynb** Runs Sen2VM with the **inverse** mode, using the downloaded inputs, along with the IERS file and L1B product, to produce orthorectified and mosaicked images. The project is designed and tested on **Linux**. It may not work reliably on **Windows**. @@ -40,8 +40,9 @@ The project is designed and tested on **Linux**. It may not work reliably on **W * **the full sen2vm-notebook folder shall be present:** * inputs-download-notebook.ipynb - * `notebook-direct-grid.ipynb - * `notebook-inverse-grid.ipynb + * notebook-direct-grid.ipynb + * notebook-direct-grid-otb.ipynb + * notebook-inverse-grid.ipynb * requirements.txt * gdal-latest folder @@ -87,7 +88,7 @@ WORKDIR │ │ ├─ GDAL_OUTPUT_ORTHO # .tif orthorectified, one for each band and detector │ │ └─ GDAL_OUTPUT_MOSAIC # .tif orthorectified and merged by band, one for each band │ ├── DIRECT_otb -│ │ ├─ INVERSE_GRID # inverse gelocation grid, generated by sen2vm, these grids encode the transformation between sensor geometry and map geometry +│ │ ├─ INVERSE_GRID # inverse gelocation grid, generated from direct grids by sen2vminvlocfromdirlocgrid.py, these grids encode the transformation between sensor geometry and map geometry │ │ ├─ raw # contains the raw L1B images extracted per detector and per band, expressed in the sensor geometry (i.e., before any orthorectification or map projection) │ │ ├─ otb_no_georef # contains images resampled using OTB with the inverse grids. The data are projected onto a regular grid but are not yet fully georeferenced │ │ ├─ output_georef # contains the final orthorectificatied and georeferenced images @@ -166,7 +167,7 @@ Then if you want to use the direct grids with gdal functions only, execute the * Orthorectification by band that generate images in `WORKDIR/DIRECT/GDAL_OUTPUT_ORTHO` using the function **gdalwarp** * Mosaicking by band that generate an image in `WORKDIR/DIRECT/GDAL_OUTPUT_MOSAIC` using the function **gdalmerge.py** -If you want to use the direct grids with otb functions for the orthorectification, execute the **notebook-direct-grid-otb.ipynb** cell by cell +If you want to use the direct grids with otb functions for the orthorectification, execute the **notebook-direct-grid-otb.ipynb** cell by cell: 1. Variable and path definitions 2. Automatic download of the IERS bulletin if none is provided by the user From 2949e700f7cb91297562d5a61d37406dac73354c Mon Sep 17 00:00:00 2001 From: aburie Date: Thu, 16 Jul 2026 09:53:18 +0200 Subject: [PATCH 11/13] Merge of main, update doc to prepare PR into a rc2 --- CHANGELOG.md | 12 +++++++++--- Dockerfile | 2 +- pom.xml | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c7fcff62..f77fbb80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Sen2VM Release history -## Merged in main +## Merged in main (1.3.0.rc2) ### Main feature @@ -12,11 +12,17 @@ * Feature: - * + * Handle mosaic DEM (multiple square degrees): #62 * Doc: - * + * Notebooks improvements: + + * Separate static input download in a dedicated notebook (#56) + * Allow more flexible input structure with separated input locations (#56) + * Creation of a Notebook for Inverse location (#54) + * Allow using OTB instead of gdal in direct location Notebook (through a new notebook) + ## 1.2.0 (2026-05-04) diff --git a/Dockerfile b/Dockerfile index 8bc7ccff..63c98c84 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM ghcr.io/sen2vm/sen2vm-build-env:latest AS launcher -ENV SEN2VM_VERSION=1.3.0.rc1 +ENV SEN2VM_VERSION=1.3.0.rc2 WORKDIR /Sen2vm diff --git a/pom.xml b/pom.xml index dc7155ff..e9152b8a 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ esa.sen2vm sen2vm-core - 1.3.0.rc1 + 1.3.0.rc2 sen2vm-core https://github.com/sen2vm/sen2vm-core From b2254994e1b0bd1fba516ae6b709df873d3009b7 Mon Sep 17 00:00:00 2001 From: aburie Date: Thu, 16 Jul 2026 11:35:33 +0200 Subject: [PATCH 12/13] Update IERS definition --- sen2vm-notebook/src/notebook-direct-grid-otb.ipynb | 14 +++++++++----- sen2vm-notebook/src/notebook-direct-grid.ipynb | 14 +++++++++----- sen2vm-notebook/src/notebook-inverse-grid.ipynb | 14 +++++++++----- .../esa/sen2vm/input/gipp/GIPPFileManager.java | 5 +++-- 4 files changed, 30 insertions(+), 17 deletions(-) diff --git a/sen2vm-notebook/src/notebook-direct-grid-otb.ipynb b/sen2vm-notebook/src/notebook-direct-grid-otb.ipynb index 3675ec9c..d1415522 100644 --- a/sen2vm-notebook/src/notebook-direct-grid-otb.ipynb +++ b/sen2vm-notebook/src/notebook-direct-grid-otb.ipynb @@ -292,16 +292,20 @@ "\n", "iers_host = None\n", "\n", - "for f in os.listdir(PATH_IERS):\n", - " if f.startswith(\"bulletin\"):\n", - " iers_host = os.path.join(PATH_IERS, f)\n", - " break\n", + "if os.path.isfile(PATH_IERS):\n", + " iers_host = PATH_IERS\n", + " PATH_IERS = os.path.dirname(PATH_IERS)\n", + "elif os.path.isdir(PATH_IERS):\n", + " for f in os.listdir(PATH_IERS):\n", + " if f.startswith(\"bulletin\"):\n", + " iers_host = os.path.join(PATH_IERS, f)\n", + " break\n", "\n", "if iers_host is None:\n", " raise RuntimeError(\"IERS bulletin not found inside PATH_IERS directory.\")\n", "\n", "docker_iers = f\"/data/IERS/{os.path.basename(iers_host)}\"\n", - "print(docker_iers)\n", + "print(\"IERS: \", docker_iers)\n", "# =====================================================\n", "# 5. Build config dictionary\n", "# =====================================================\n", diff --git a/sen2vm-notebook/src/notebook-direct-grid.ipynb b/sen2vm-notebook/src/notebook-direct-grid.ipynb index 5616fdf1..675c3e13 100644 --- a/sen2vm-notebook/src/notebook-direct-grid.ipynb +++ b/sen2vm-notebook/src/notebook-direct-grid.ipynb @@ -292,16 +292,20 @@ "\n", "iers_host = None\n", "\n", - "for f in os.listdir(PATH_IERS):\n", - " if f.startswith(\"bulletin\"):\n", - " iers_host = os.path.join(PATH_IERS, f)\n", - " break\n", + "if os.path.isfile(PATH_IERS):\n", + " iers_host = PATH_IERS\n", + " PATH_IERS = os.path.dirname(PATH_IERS)\n", + "elif os.path.isdir(PATH_IERS):\n", + " for f in os.listdir(PATH_IERS):\n", + " if f.startswith(\"bulletin\"):\n", + " iers_host = os.path.join(PATH_IERS, f)\n", + " break\n", "\n", "if iers_host is None:\n", " raise RuntimeError(\"IERS bulletin not found inside PATH_IERS directory.\")\n", "\n", "docker_iers = f\"/data/IERS/{os.path.basename(iers_host)}\"\n", - "print(docker_iers)\n", + "print(\"IERS: \", docker_iers)\n", "# =====================================================\n", "# 5. Build config dictionary\n", "# =====================================================\n", diff --git a/sen2vm-notebook/src/notebook-inverse-grid.ipynb b/sen2vm-notebook/src/notebook-inverse-grid.ipynb index a15a1a2c..733aab9f 100644 --- a/sen2vm-notebook/src/notebook-inverse-grid.ipynb +++ b/sen2vm-notebook/src/notebook-inverse-grid.ipynb @@ -291,16 +291,20 @@ "\n", "iers_host = None\n", "\n", - "for f in os.listdir(PATH_IERS):\n", - " if f.startswith(\"bulletin\"):\n", - " iers_host = os.path.join(PATH_IERS, f)\n", - " break\n", + "if os.path.isfile(PATH_IERS):\n", + " iers_host = PATH_IERS\n", + " PATH_IERS = os.path.dirname(PATH_IERS)\n", + "elif os.path.isdir(PATH_IERS):\n", + " for f in os.listdir(PATH_IERS):\n", + " if f.startswith(\"bulletin\"):\n", + " iers_host = os.path.join(PATH_IERS, f)\n", + " break\n", "\n", "if iers_host is None:\n", " raise RuntimeError(\"IERS bulletin not found inside PATH_IERS directory.\")\n", "\n", "docker_iers = f\"/data/IERS/{os.path.basename(iers_host)}\"\n", - "print(docker_iers)\n", + "print(\"IERS: \", docker_iers)\n", "# =====================================================\n", "# 5. Build config dictionary\n", "# =====================================================\n", diff --git a/src/main/java/esa/sen2vm/input/gipp/GIPPFileManager.java b/src/main/java/esa/sen2vm/input/gipp/GIPPFileManager.java index efcc6172..b814dad3 100644 --- a/src/main/java/esa/sen2vm/input/gipp/GIPPFileManager.java +++ b/src/main/java/esa/sen2vm/input/gipp/GIPPFileManager.java @@ -97,8 +97,9 @@ public static List findGippFiles(Path root, String dirNameRegex, List searchGIPFilesFromRegex(Path root, String dirNameRegex, String fileNameRegex, List validExtensions) throws IOException { - final Pattern dirPattern = Pattern.compile(dirNameRegex); + public static List searchGIPFilesFromRegex(Path root, String dirNameRegex, String fileNameRegex, List validExtensions) throws IOException + { + final Pattern dirPattern = Pattern.compile(dirNameRegex); final Pattern filePattern = Pattern.compile(fileNameRegex); final List results = new ArrayList<>(); // Stack indicating whether we are currently in a qualified subtree From 617f9df0f9ae4b3926f50b5284542f3a268043d1 Mon Sep 17 00:00:00 2001 From: aburie Date: Thu, 16 Jul 2026 16:19:22 +0200 Subject: [PATCH 13/13] Correct Inverse to allow modifying output_path and allow IERS to be a file --- sen2vm-notebook/src/notebook-direct-grid-otb.ipynb | 2 +- sen2vm-notebook/src/notebook-direct-grid.ipynb | 2 +- sen2vm-notebook/src/notebook-inverse-grid.ipynb | 7 ++++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/sen2vm-notebook/src/notebook-direct-grid-otb.ipynb b/sen2vm-notebook/src/notebook-direct-grid-otb.ipynb index d1415522..fbafa227 100644 --- a/sen2vm-notebook/src/notebook-direct-grid-otb.ipynb +++ b/sen2vm-notebook/src/notebook-direct-grid-otb.ipynb @@ -511,7 +511,7 @@ "id": "e54044d2", "metadata": {}, "source": [ - " # Generate Orthorectification images" + "# Generate Orthorectification images" ] }, { diff --git a/sen2vm-notebook/src/notebook-direct-grid.ipynb b/sen2vm-notebook/src/notebook-direct-grid.ipynb index 675c3e13..14431f3f 100644 --- a/sen2vm-notebook/src/notebook-direct-grid.ipynb +++ b/sen2vm-notebook/src/notebook-direct-grid.ipynb @@ -515,7 +515,7 @@ "id": "e54044d2", "metadata": {}, "source": [ - " # Generate Orthorectification images" + "# Generate Orthorectification images" ] }, { diff --git a/sen2vm-notebook/src/notebook-inverse-grid.ipynb b/sen2vm-notebook/src/notebook-inverse-grid.ipynb index 733aab9f..de748503 100644 --- a/sen2vm-notebook/src/notebook-inverse-grid.ipynb +++ b/sen2vm-notebook/src/notebook-inverse-grid.ipynb @@ -333,7 +333,7 @@ " \"lr_x\": double(LOCATION[\"lr_x\"]),\n", " \"lr_y\": double(LOCATION[\"lr_y\"]),\n", " \"referential\": f\"EPSG:{UTM_EPSG}\",\n", - " \"output_folder\": \"/workspace/output/INVERSE/INVERSE_GRID\"\n", + " \"output_folder\": \"/output/INVERSE_GRID\"\n", "}\n", "# =====================================================\n", "# Save config.json\n", @@ -473,7 +473,7 @@ "params_inside = \"/workspace/UserConf/params.json\"\n", "\n", "os.makedirs(\n", - " os.path.join(WORKDIR, \"output\", \"INVERSE\", \"INVERSE_GRID\"),\n", + " os.path.join(OUTPUT_FOLDER, \"INVERSE_GRID\"),\n", " exist_ok=True\n", ")\n", "# =====================================================\n", @@ -503,6 +503,7 @@ " \"-v\", f\"{PATH_GEOID}:/data/GEOID\",\n", " \"-v\", f\"{PATH_IERS}:/data/IERS\",\n", " \"-v\", f\"{WORKDIR}:/workspace\",\n", + " \"-v\", f\"{OUTPUT_FOLDER}:/output\",\n", " \"sen2vm\",\n", " \"-c\", config_inside,\n", " \"-p\", params_inside\n", @@ -528,7 +529,7 @@ "id": "e54044d2", "metadata": {}, "source": [ - " # Generate Orthorectification images" + "# Generate Orthorectification images" ] }, {