Skip to content

EnMAP

This notebook requires the cloudsen12_models package

pip install georeader-spaceml cloudsen12_models fsspec

# cloudsen12_models is not a georeader dependency (it depends on georeader),
# so install it in the running kernel.
%pip install cloudsen12_models
Requirement already satisfied: cloudsen12_models in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (1.0.1)
Requirement already satisfied: georeader-spaceml>=1.4 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from cloudsen12_models) (2.3.0)
Requirement already satisfied: huggingface-hub>=0.25 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from cloudsen12_models) (1.17.0)
Requirement already satisfied: numpy>=1 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from cloudsen12_models) (2.4.6)
Requirement already satisfied: rasterio>=1 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from cloudsen12_models) (1.4.4)
Requirement already satisfied: requests>=2 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from cloudsen12_models) (2.34.2)
Requirement already satisfied: segmentation-models-pytorch>=0.3 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from cloudsen12_models) (0.5.0)
Requirement already satisfied: torch>=2 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from cloudsen12_models) (2.12.0)
Requirement already satisfied: tqdm>=4 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from cloudsen12_models) (4.67.3)

Requirement already satisfied: geopandas>=1 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from georeader-spaceml>=1.4->cloudsen12_models) (1.1.3)
Requirement already satisfied: mercantile>=1 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from georeader-spaceml>=1.4->cloudsen12_models) (1.2.1)
Requirement already satisfied: shapely>=2 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from georeader-spaceml>=1.4->cloudsen12_models) (2.1.2)
Requirement already satisfied: pyogrio>=0.7.2 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from geopandas>=1->georeader-spaceml>=1.4->cloudsen12_models) (0.12.1)
Requirement already satisfied: packaging in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from geopandas>=1->georeader-spaceml>=1.4->cloudsen12_models) (26.2)
Requirement already satisfied: pandas>=2.0.0 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from geopandas>=1->georeader-spaceml>=1.4->cloudsen12_models) (3.0.3)
Requirement already satisfied: pyproj>=3.5.0 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from geopandas>=1->georeader-spaceml>=1.4->cloudsen12_models) (3.7.2)
Requirement already satisfied: click>=8.4.0 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from huggingface-hub>=0.25->cloudsen12_models) (8.4.1)
Requirement already satisfied: filelock>=3.10.0 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from huggingface-hub>=0.25->cloudsen12_models) (3.29.0)
Requirement already satisfied: fsspec>=2023.5.0 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from huggingface-hub>=0.25->cloudsen12_models) (2025.12.0)
Requirement already satisfied: hf-xet<2.0.0,>=1.4.3 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from huggingface-hub>=0.25->cloudsen12_models) (1.5.0)
Requirement already satisfied: httpx<1,>=0.23.0 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from huggingface-hub>=0.25->cloudsen12_models) (0.28.1)
Requirement already satisfied: pyyaml>=5.1 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from huggingface-hub>=0.25->cloudsen12_models) (6.0.3)
Requirement already satisfied: typer<0.26.0,>=0.20.0 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from huggingface-hub>=0.25->cloudsen12_models) (0.25.1)
Requirement already satisfied: typing-extensions>=4.1.0 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from huggingface-hub>=0.25->cloudsen12_models) (4.15.0)

Requirement already satisfied: anyio in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from httpx<1,>=0.23.0->huggingface-hub>=0.25->cloudsen12_models) (4.13.0)
Requirement already satisfied: certifi in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from httpx<1,>=0.23.0->huggingface-hub>=0.25->cloudsen12_models) (2026.5.20)
Requirement already satisfied: httpcore==1.* in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from httpx<1,>=0.23.0->huggingface-hub>=0.25->cloudsen12_models) (1.0.9)
Requirement already satisfied: idna in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from httpx<1,>=0.23.0->huggingface-hub>=0.25->cloudsen12_models) (3.17)
Requirement already satisfied: h11>=0.16 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from httpcore==1.*->httpx<1,>=0.23.0->huggingface-hub>=0.25->cloudsen12_models) (0.16.0)
Requirement already satisfied: shellingham>=1.3.0 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from typer<0.26.0,>=0.20.0->huggingface-hub>=0.25->cloudsen12_models) (1.5.4)
Requirement already satisfied: rich>=13.8.0 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from typer<0.26.0,>=0.20.0->huggingface-hub>=0.25->cloudsen12_models) (15.0.0)
Requirement already satisfied: annotated-doc>=0.0.2 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from typer<0.26.0,>=0.20.0->huggingface-hub>=0.25->cloudsen12_models) (0.0.4)

Requirement already satisfied: python-dateutil>=2.8.2 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from pandas>=2.0.0->geopandas>=1->georeader-spaceml>=1.4->cloudsen12_models) (2.9.0.post0)
Requirement already satisfied: six>=1.5 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from python-dateutil>=2.8.2->pandas>=2.0.0->geopandas>=1->georeader-spaceml>=1.4->cloudsen12_models) (1.17.0)

Requirement already satisfied: affine in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from rasterio>=1->cloudsen12_models) (2.4.0)
Requirement already satisfied: attrs in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from rasterio>=1->cloudsen12_models) (26.1.0)
Requirement already satisfied: cligj>=0.5 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from rasterio>=1->cloudsen12_models) (0.7.2)
Requirement already satisfied: click-plugins in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from rasterio>=1->cloudsen12_models) (1.1.1.2)
Requirement already satisfied: pyparsing in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from rasterio>=1->cloudsen12_models) (3.3.2)
Requirement already satisfied: charset_normalizer<4,>=2 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from requests>=2->cloudsen12_models) (3.4.7)
Requirement already satisfied: urllib3<3,>=1.26 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from requests>=2->cloudsen12_models) (2.7.0)
Requirement already satisfied: markdown-it-py>=2.2.0 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from rich>=13.8.0->typer<0.26.0,>=0.20.0->huggingface-hub>=0.25->cloudsen12_models) (4.2.0)
Requirement already satisfied: pygments<3.0.0,>=2.13.0 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from rich>=13.8.0->typer<0.26.0,>=0.20.0->huggingface-hub>=0.25->cloudsen12_models) (2.20.0)

Requirement already satisfied: mdurl~=0.1 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from markdown-it-py>=2.2.0->rich>=13.8.0->typer<0.26.0,>=0.20.0->huggingface-hub>=0.25->cloudsen12_models) (0.1.2)
Requirement already satisfied: pillow>=8 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from segmentation-models-pytorch>=0.3->cloudsen12_models) (12.2.0)
Requirement already satisfied: safetensors>=0.3.1 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from segmentation-models-pytorch>=0.3->cloudsen12_models) (0.7.0)
Requirement already satisfied: timm>=0.9 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from segmentation-models-pytorch>=0.3->cloudsen12_models) (1.0.27)
Requirement already satisfied: torchvision>=0.9 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from segmentation-models-pytorch>=0.3->cloudsen12_models) (0.27.0)

Requirement already satisfied: setuptools<82 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from torch>=2->cloudsen12_models) (81.0.0)
Requirement already satisfied: sympy>=1.13.3 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from torch>=2->cloudsen12_models) (1.14.0)
Requirement already satisfied: networkx>=2.5.1 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from torch>=2->cloudsen12_models) (3.6)
Requirement already satisfied: jinja2 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from torch>=2->cloudsen12_models) (3.1.6)
Requirement already satisfied: cuda-toolkit==13.0.2 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from cuda-toolkit[cudart,cufft,cufile,cupti,curand,cusolver,cusparse,nvjitlink,nvrtc,nvtx]==13.0.2; platform_system == "Linux"->torch>=2->cloudsen12_models) (13.0.2)
Requirement already satisfied: nvidia-cublas<=13.1.1.3,>=13.1.0.3 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from torch>=2->cloudsen12_models) (13.1.1.3)
Requirement already satisfied: cuda-bindings<14,>=13.0.3 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from torch>=2->cloudsen12_models) (13.3.1)
Requirement already satisfied: nvidia-cudnn-cu13==9.20.0.48 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from torch>=2->cloudsen12_models) (9.20.0.48)
Requirement already satisfied: nvidia-cusparselt-cu13==0.8.1 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from torch>=2->cloudsen12_models) (0.8.1)
Requirement already satisfied: nvidia-nccl-cu13==2.29.7 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from torch>=2->cloudsen12_models) (2.29.7)
Requirement already satisfied: nvidia-nvshmem-cu13==3.4.5 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from torch>=2->cloudsen12_models) (3.4.5)
Requirement already satisfied: triton==3.7.0 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from torch>=2->cloudsen12_models) (3.7.0)

Requirement already satisfied: nvidia-cuda-runtime==13.0.96.* in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from cuda-toolkit[cudart,cufft,cufile,cupti,curand,cusolver,cusparse,nvjitlink,nvrtc,nvtx]==13.0.2; platform_system == "Linux"->torch>=2->cloudsen12_models) (13.0.96)
Requirement already satisfied: nvidia-cufft==12.0.0.61.* in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from cuda-toolkit[cudart,cufft,cufile,cupti,curand,cusolver,cusparse,nvjitlink,nvrtc,nvtx]==13.0.2; platform_system == "Linux"->torch>=2->cloudsen12_models) (12.0.0.61)
Requirement already satisfied: nvidia-cufile==1.15.1.6.* in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from cuda-toolkit[cudart,cufft,cufile,cupti,curand,cusolver,cusparse,nvjitlink,nvrtc,nvtx]==13.0.2; platform_system == "Linux"->torch>=2->cloudsen12_models) (1.15.1.6)
Requirement already satisfied: nvidia-cuda-cupti==13.0.85.* in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from cuda-toolkit[cudart,cufft,cufile,cupti,curand,cusolver,cusparse,nvjitlink,nvrtc,nvtx]==13.0.2; platform_system == "Linux"->torch>=2->cloudsen12_models) (13.0.85)
Requirement already satisfied: nvidia-curand==10.4.0.35.* in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from cuda-toolkit[cudart,cufft,cufile,cupti,curand,cusolver,cusparse,nvjitlink,nvrtc,nvtx]==13.0.2; platform_system == "Linux"->torch>=2->cloudsen12_models) (10.4.0.35)
Requirement already satisfied: nvidia-cusolver==12.0.4.66.* in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from cuda-toolkit[cudart,cufft,cufile,cupti,curand,cusolver,cusparse,nvjitlink,nvrtc,nvtx]==13.0.2; platform_system == "Linux"->torch>=2->cloudsen12_models) (12.0.4.66)
Requirement already satisfied: nvidia-cusparse==12.6.3.3.* in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from cuda-toolkit[cudart,cufft,cufile,cupti,curand,cusolver,cusparse,nvjitlink,nvrtc,nvtx]==13.0.2; platform_system == "Linux"->torch>=2->cloudsen12_models) (12.6.3.3)

Requirement already satisfied: nvidia-nvjitlink==13.0.88.* in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from cuda-toolkit[cudart,cufft,cufile,cupti,curand,cusolver,cusparse,nvjitlink,nvrtc,nvtx]==13.0.2; platform_system == "Linux"->torch>=2->cloudsen12_models) (13.0.88)
Requirement already satisfied: nvidia-cuda-nvrtc==13.0.88.* in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from cuda-toolkit[cudart,cufft,cufile,cupti,curand,cusolver,cusparse,nvjitlink,nvrtc,nvtx]==13.0.2; platform_system == "Linux"->torch>=2->cloudsen12_models) (13.0.88)
Requirement already satisfied: nvidia-nvtx==13.0.85.* in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from cuda-toolkit[cudart,cufft,cufile,cupti,curand,cusolver,cusparse,nvjitlink,nvrtc,nvtx]==13.0.2; platform_system == "Linux"->torch>=2->cloudsen12_models) (13.0.85)
Requirement already satisfied: cuda-pathfinder>=1.4.2 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from cuda-bindings<14,>=13.0.3->torch>=2->cloudsen12_models) (1.5.5)

Requirement already satisfied: mpmath<1.4,>=1.1.0 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from sympy>=1.13.3->torch>=2->cloudsen12_models) (1.3.0)

Requirement already satisfied: MarkupSafe>=2.0 in /home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages (from jinja2->torch>=2->cloudsen12_models) (3.0.3)


[notice] A new release of pip is available: 26.1.1 -> 26.1.2
[notice] To update, run: pip install --upgrade pip

Note: you may need to restart the kernel to use updated packages.

import os
from pathlib import Path

from georeader.readers import enmap
from cloudsen12_models import cloudsen12
from georeader import plot

# Resolve the repo-level examples/ folder (works regardless of where the notebook runs from).
EXAMPLES_DIR = next(
    (p / "examples" for p in [Path.cwd(), *Path.cwd().parents] if (p / "examples").is_dir()),
    Path("examples"),
)

# EnMAP L1B tile used by this notebook. If it is not already in examples/,
# download it from the Azure container. Provide these as environment
# variables (or CI secrets); see examples/README.md.
SAS_TOKEN = os.environ.get("SAS_TOKEN", "")
AZURE_STORAGE_ACCOUNT = os.environ.get("AZURE_STORAGE_ACCOUNT", "")
CONTAINER = os.environ.get("CONTAINER_NAME", "")

tile = "ENMAP01-____L1B-DT0000074101_20240511T080843Z_001_V010402_20240514T093550Z"
folder_dest_tile = EXAMPLES_DIR / "EnMAP" / tile
xml_file = os.fspath(folder_dest_tile / f"{tile}-METADATA.XML")

PRODUCT_FOLDERS = {
    "SPECTRAL_IMAGE_SWIR": "swir",
    "SPECTRAL_IMAGE_VNIR": "vnir",
    "QL_QUALITY_CLOUDSHADOW": "ql/cloudshadow",
    "QL_PIXELMASK_SWIR": "ql/pixelmask_swir",
    "QL_QUALITY_CIRRUS": "ql/cirrus",
    "QL_QUALITY_SNOW": "ql/snow",
    "QL_PIXELMASK_VNIR": "ql/pixelmask_vnir",
    "QL_QUALITY_TESTFLAGS_SWIR": "ql/testflags_swir",
    "QL_QUALITY_HAZE": "ql/haze",
    "QL_QUALITY_TESTFLAGS_VNIR": "ql/testflags_vnir",
    "QL_QUALITY_CLASSES": "ql/classes",
    "QL_SWIR": "ql/swir",
    "QL_QUALITY_CLOUD": "ql/cloud",
    "QL_VNIR": "ql/vnir",
}

if not os.path.exists(xml_file):
    import adlfs
    fs = adlfs.AzureBlobFileSystem(
        account_name=AZURE_STORAGE_ACCOUNT, sas_token=SAS_TOKEN, container=CONTAINER
    )
    os.makedirs(folder_dest_tile, exist_ok=True)

    path_metadata = f"az://{CONTAINER}/EnMAP/metadata/{tile}.xml"
    if not fs.exists(path_metadata):
        raise FileNotFoundError(f"File {path_metadata} does not exist")
    fs.get(path_metadata, xml_file)

    for extension, folder in PRODUCT_FOLDERS.items():
        path = f"az://{CONTAINER}/EnMAP/{folder}/{tile}.tif"
        path_dst = os.fspath(folder_dest_tile / f"{tile}-{extension}.TIF")
        if os.path.exists(path_dst):
            continue
        if not fs.exists(path):
            print(f"File {path} not found, skipping")
            continue
        print(f"Downloading {path} ...")
        fs.get(path, path_dst)

enmap_reader = enmap.EnMAP(xml_file, by_folder=False)
enmap_reader

        File: /home/gonzalo/git/georeader/examples/EnMAP/ENMAP01-____L1B-DT0000074101_20240511T080843Z_001_V010402_20240514T093550Z/ENMAP01-____L1B-DT0000074101_20240511T080843Z_001_V010402_20240514T093550Z-METADATA.XML
        Bounds: (47.42948365009492, 29.213144376313977, 47.8031320641908, 29.53032430940031)
        Time: 2024-05-11 08:08:43.855554+00:00
        Spatial shape (height, width): (1024, 1000)
        VNIR Range: (np.float64(411.42039), np.float64(1003.9755)) nbands: 91 
        SWIR Range: (np.float64(892.78475), np.float64(2452.4581000000003)) nbands: 133
        
%%time

rgb = enmap_reader.load_rgb(apply_rpcs=False)
plot.show(rgb)
CPU times: user 211 ms, sys: 79.3 ms, total: 291 ms
Wall time: 312 ms

/home/gonzalo/git/georeader/georeader/reflectance.py:584: UserWarning: 'where' used without 'out', expect unitialized memory in output. If this is intentional, use out=None.
  response = np.divide(response, response.sum(axis=0), where=response.sum(axis=0) > 0)# (N, K)
/home/gonzalo/git/georeader/georeader/plot.py:133: UserWarning: The transform is not rectilinear. The x and y ticks and the scale bar are not going to be correct. To discard this warning use: warnings.filterwarnings('ignore', message='The transform is not rectilinear.')
  warnings.warn("The transform is not rectilinear. The x and y ticks and the scale bar are not going to be correct."

<Axes: >
No description has been provided for this image
from georeader.readers import S2_SAFE_reader

srf = S2_SAFE_reader.read_srf("S2A")
srf
/home/gonzalo/git/georeader/.venv/lib/python3.12/site-packages/openpyxl/worksheet/_reader.py:329: UserWarning: Unknown extension is not supported and will be removed
  warn(msg)

B01 B02 B03 B04 B05 B06 B07 B08 B8A B09 B10 B11 B12
SR_WL
412 0.001776 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.000000
413 0.004073 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.000000
414 0.003626 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.000000
415 0.003515 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.000000
416 0.005729 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.000000
... ... ... ... ... ... ... ... ... ... ... ... ... ...
2316 0.000000 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.010984
2317 0.000000 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.007360
2318 0.000000 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.006491
2319 0.000000 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.004697
2320 0.000000 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.002059

877 rows Ă— 13 columns

%%time

# Load swir in enmap_reader.units (i.e. radiance units)
swir = enmap_reader.load_product("SPECTRAL_IMAGE_SWIR")
CPU times: user 4.42 s, sys: 2.37 s, total: 6.78 s
Wall time: 6.82 s

from georeader import reflectance

bands_s2_swir = ["B09","B10","B11","B12"]
s2bandsswir = reflectance.transform_to_srf(swir, 
                                           srf[bands_s2_swir],
                                           wavelengths_hyperspectral=enmap_reader.wl_center["swir"],
                                           as_reflectance=True,
                                           observation_date_corr_factor=enmap_reader.observation_date_correction_factor,
                                           verbose=True,
                                           units=enmap_reader.units)

s2bandsswir
2026-06-01 17:11:14(0/4) Processing band B09
2026-06-01 17:11:14  Loading 4 bands
2026-06-01 17:11:14  bands loaded, computing tensor
2026-06-01 17:11:14(1/4) Processing band B10
2026-06-01 17:11:14  Loading 5 bands
2026-06-01 17:11:14  bands loaded, computing tensor
2026-06-01 17:11:14(2/4) Processing band B11
2026-06-01 17:11:14  Loading 13 bands
2026-06-01 17:11:14  bands loaded, computing tensor
2026-06-01 17:11:14(3/4) Processing band B12
2026-06-01 17:11:14  Loading 30 bands

2026-06-01 17:11:14    bands loaded, computing tensor

 
         Transform: | 0.00,-0.00, 47.50|
|-0.00,-0.00, 29.53|
| 0.00, 0.00, 1.00|
         Shape: (4, 1024, 1000)
         Resolution: (0.0003069912745516993, 0.0002759618727434178)
         Bounds: (47.42948365009492, 29.213144376313977, 47.8031320641908, 29.53032430940031)
         CRS: EPSG:4326
         fill_value_default: 0.0
        
import matplotlib.pyplot as plt

fig, ax =plt.subplots(2,2,figsize=(12,5), tight_layout=True)
ax =ax.flatten()

for i,b in enumerate(bands_s2_swir):
    ax[i].hist(s2bandsswir.values[i].ravel())
    ax[i].set_title(b)
No description has been provided for this image
vnir = enmap_reader.load_product("SPECTRAL_IMAGE_VNIR")
bands_s2_vnir = ["B01","B02","B03","B04","B05","B06","B07","B08","B8A"]
s2bandsvnir = reflectance.transform_to_srf(vnir, 
                                           srf[bands_s2_vnir],
                                           wavelengths_hyperspectral=enmap_reader.wl_center["vnir"],
                                           as_reflectance=True,
                                           observation_date_corr_factor=enmap_reader.observation_date_correction_factor,
                                           verbose=True,
                                           extrapolate=True,
                                           units=enmap_reader.units)
s2bandsvnir
2026-06-01 17:11:21(0/9) Processing band B01
2026-06-01 17:11:21  Loading 8 bands
2026-06-01 17:11:21  bands loaded, computing tensor
2026-06-01 17:11:21(1/9) Processing band B02
2026-06-01 17:11:21  Loading 18 bands
2026-06-01 17:11:21  bands loaded, computing tensor

2026-06-01 17:11:22(2/9) Processing band B03
2026-06-01 17:11:22  Loading 9 bands
2026-06-01 17:11:22  bands loaded, computing tensor
2026-06-01 17:11:22(3/9) Processing band B04
2026-06-01 17:11:22  Loading 7 bands
2026-06-01 17:11:22  bands loaded, computing tensor
2026-06-01 17:11:22(4/9) Processing band B05
2026-06-01 17:11:22  Loading 4 bands
2026-06-01 17:11:22  bands loaded, computing tensor
2026-06-01 17:11:22(5/9) Processing band B06

2026-06-01 17:11:22    Loading 4 bands
2026-06-01 17:11:22  bands loaded, computing tensor
2026-06-01 17:11:22(6/9) Processing band B07
2026-06-01 17:11:22  Loading 4 bands
2026-06-01 17:11:22  bands loaded, computing tensor
2026-06-01 17:11:22(7/9) Processing band B08
2026-06-01 17:11:22  Loading 20 bands
2026-06-01 17:11:22  bands loaded, computing tensor

2026-06-01 17:11:22(8/9) Processing band B8A
2026-06-01 17:11:22  Loading 6 bands
2026-06-01 17:11:22  bands loaded, computing tensor

 
         Transform: | 0.00,-0.00, 47.50|
|-0.00,-0.00, 29.53|
| 0.00, 0.00, 1.00|
         Shape: (9, 1024, 1000)
         Resolution: (0.0003069912745516993, 0.0002759618727434178)
         Bounds: (47.42948365009492, 29.213144376313977, 47.8031320641908, 29.53032430940031)
         CRS: EPSG:4326
         fill_value_default: 0.0
        
fig, ax =plt.subplots(4,2,figsize=(12,10), tight_layout=True)
ax =ax.flatten()

for i,b in enumerate(bands_s2_vnir[:-1]):
    ax[i].hist(s2bandsvnir.values[i].ravel())
    ax[i].set_title(b)
No description has been provided for this image
rgb_s2 = s2bandsvnir.isel({"band": [3,2,1]})
plot.show(rgb_s2)
/home/gonzalo/git/georeader/georeader/plot.py:133: UserWarning: The transform is not rectilinear. The x and y ticks and the scale bar are not going to be correct. To discard this warning use: warnings.filterwarnings('ignore', message='The transform is not rectilinear.')
  warnings.warn("The transform is not rectilinear. The x and y ticks and the scale bar are not going to be correct."

<Axes: >
No description has been provided for this image
from georeader.geotensor import GeoTensor
import numpy as np
s2_image = GeoTensor(np.concatenate([s2bandsvnir.values, s2bandsswir.values],axis=0),
                     transform=s2bandsswir.transform, crs=s2bandsswir.crs, 
                     fill_value_default=s2bandsswir.fill_value_default)
s2_image
 
         Transform: | 0.00,-0.00, 47.50|
|-0.00,-0.00, 29.53|
| 0.00, 0.00, 1.00|
         Shape: (13, 1024, 1000)
         Resolution: (0.0003069912745516993, 0.0002759618727434178)
         Bounds: (47.42948365009492, 29.213144376313977, 47.8031320641908, 29.53032430940031)
         CRS: EPSG:4326
         fill_value_default: 0.0
        
swir_nir_red = (s2_image.isel({"band": [S2_SAFE_reader.BANDS_S2_L1C.index(b) for b in ["B11", "B08", "B04"]]}) / .45).clip(0,1)

plot.show(swir_nir_red)
<Axes: >
No description has been provided for this image
model_4bands = cloudsen12.load_model_by_name(name="dtacs4bands", weights_folder="cloudsen12_models")
cloudmask = model_4bands.predict(s2_image.isel({"band": [S2_SAFE_reader.BANDS_S2_L1C.index(b) for b in model_4bands.bands]}))

fig, ax = plt.subplots(1,2,figsize=(14,5),sharey=True, tight_layout=True)

plot.show(swir_nir_red,ax=ax[0])
cloudsen12.plot_cloudSEN12mask(cloudmask, ax=ax[1])
<Axes: >
No description has been provided for this image
model = cloudsen12.load_model_by_name(name="UNetMobV2_V2", weights_folder="cloudsen12_models")
cloudmask = model.predict(s2_image)

fig, ax = plt.subplots(1,2,figsize=(14,5),sharey=True, tight_layout=True)

plot.show(swir_nir_red,ax=ax[0])
cloudsen12.plot_cloudSEN12mask(cloudmask, ax=ax[1])
<Axes: >
No description has been provided for this image

Licence

The cloudsen12_models package is published under a GNU Lesser GPL v3 licence

The CloudSEN12 database and all pre-trained models are released under a Creative Commons non-commercial licence. For using the models in comercial pipelines written consent by the authors must be provided.

georeader tutorials and notebooks are released under a Creative Commons non-commercial licence.

If you find this work useful please cite:

@article{aybar_cloudsen12_2024,
    title = {{CloudSEN12}+: {The} largest dataset of expert-labeled pixels for cloud and cloud shadow detection in {Sentinel}-2},
    issn = {2352-3409},
    url = {https://www.sciencedirect.com/science/article/pii/S2352340924008163},
    doi = {10.1016/j.dib.2024.110852},
    journal = {Data in Brief},
    author = {Aybar, Cesar and Bautista, Lesly and Montero, David and Contreras, Julio and Ayala, Daryl and Prudencio, Fernando and Loja, Jhomira and Ysuhuaylas, Luis and Herrera, Fernando and Gonzales, Karen and Valladares, Jeanett and Flores, Lucy A. and Mamani, Evelin and Quiñonez, Maria and Fajardo, Rai and Espinoza, Wendy and Limas, Antonio and Yali, Roy and Alcántara, Alejandro and Leyva, Martin and Loayza-Muro, Rau´l and Willems, Bram and Mateo-García, Gonzalo and Gómez-Chova, Luis},
    month = aug,
    year = {2024},
    pages = {110852},
}