Skip to main content

euler

euler-loading

One PyTorch Dataset across arbitrarily many data modalities — matched by ID, not by filename luck.

PyPI Python versions License: MIT CI


Multi-modal datasets arrive as separate directory trees — RGB here, depth there, segmentation in a zip, calibration somewhere above it all. Keeping them in step usually means a pile of fragile path arithmetic.

euler-loading replaces that. Each modality is indexed by ds-crawler, and euler-loading intersects the file IDs across modalities so every sample holds exactly one file per modality. Hierarchical files such as per-scene calibration are matched by their position in the tree and shared across the samples below them.

flowchart LR
    A["rgb/"] --> X
    B["depth/"] --> X
    C["segmentation.zip"] --> X
    X(["intersect file IDs"]) --> S["sample dict<br/>rgb · depth · segmentation<br/>id · full_id · meta · attributes"]
    D["calib.json<br/><i>hierarchical</i>"] -.->|"matched by tree position"| S

It never interprets file contents. It resolves which file to load and hands the path — or an in-memory buffer, for zip-backed modalities — to a loader function, which you supply or let euler-loading resolve from the dataset's dataset-head.json contract.

Install

pip install "euler-loading[gpu]"

Requires Python 3.9+. The [gpu] extra pulls in PyTorch for the tensor loaders; without it the package still works using the CPU (NumPy) loaders.

For Synscapes EXR depth files, install euler-loading[synscapes] (NumPy) or euler-loading[gpu,synscapes] (tensors). See the Synscapes loaders for formats and usage.

Quick start

from euler_loading import Modality, MultiModalDataset
from euler_loading.loaders.gpu import vkitti2

dataset = MultiModalDataset(
    modalities={
        "rgb":   Modality("/data/vkitti2/rgb",   loader=vkitti2.rgb,   split="train"),
        "depth": Modality("/data/vkitti2/depth", loader=vkitti2.depth, split="train"),
    },
    hierarchical_modalities={
        "intrinsics": Modality("/data/vkitti2/textgt", loader=vkitti2.read_intrinsics),
    },
)

sample = dataset[0]
sample["rgb"]         # torch.Tensor (3, H, W) float32 in [0, 1]
sample["depth"]       # torch.Tensor (1, H, W) float32, metres
sample["intrinsics"]  # {file_id: (3, 3) tensor} for every calib file above this sample
sample["id"]          # leaf file ID, shared across modalities
sample["full_id"]     # full hierarchical path, e.g. "/Scene01/Camera_0/00000"

Drop it straight into a DataLoader — it is a standard torch.utils.data.Dataset:

loader = DataLoader(dataset, batch_size=16, num_workers=4, pin_memory=True)

Automatic loader resolution

Omit loader= and euler-loading resolves the loader declared by that modality's ds-crawler dataset contract:

dataset = MultiModalDataset(
    modalities={
        "rgb": Modality("/data/vkitti2/rgb", split="train"),
    },
)

The modality root must contain .ds_crawler/dataset-head.json (or the scoped equivalent) with a named euler_loading entry in its addons object. A minimal RGB contract looks like this:

{
  "contract": {
    "kind": "dataset_head",
    "version": "1.0"
  },
  "dataset": {
    "id": "vkitti2_rgb",
    "name": "Virtual KITTI 2 RGB"
  },
  "modality": {
    "key": "rgb",
    "meta": {
      "range": [0, 255]
    }
  },
  "addons": {
    "euler_loading": {
      "version": "1.0",
      "loader": "vkitti2",
      "function": "rgb"
    }
  }
}

loader selects a built-in loader module and function selects the callable inside it. Automatic resolution uses the GPU variant; pass a loader explicitly when you want the CPU variant or a custom callable. See Automatic loader resolution for the full contract and writer rules.

What you get

ID intersection Every sample has exactly one file per modality. Unmatched files are reported, not silently dropped.
Hierarchical modalities Per-scene or per-sequence calibration is matched by tree position and cached, with deepest-file-wins inheritance.
Zip-native Point a modality at a .zip and files are read from the archive without extraction. One handle per worker.
Splits Modality(path, split="train") overlays a ds-crawler inline split on the canonical index.
Scoped metadata Several logical modalities can share one physical root or archive via metadata_scope.
Loader resolution Loaders and writers resolve from the dataset-head.json addons.euler_loading contract, so datasets describe how to read themselves.
Writing back Resolved writers put inference outputs back in dataset-native formats, re-indexable with matching IDs.
Spatial preprocessing SamplePreprocessor resizes and crops consistently across images, depth, masks, ray maps and intrinsics.

Built-in loaders

Every dataset module exists in two variants: loaders.gpu.* returns torch.Tensor in CHW layout, loaders.cpu.* returns numpy.ndarray in HWC. All of them accept both filesystem paths and in-memory buffers.

Module Dataset Modalities
vkitti2 Virtual KITTI 2 rgb, depth, class/instance segmentation, scene flow, sky mask, intrinsics, extrinsics
muses MUSES rgb, reference rgb, semantic & panoptic segmentation, sky mask, lidar point cloud, sparse depth, calibration
real_drive_sim Real Drive Sim rgb, depth, class segmentation, sky mask, calibration, intrinsics, extrinsics
princeton_dense Princeton DENSE / SeeingThroughFog rgb, rccb, sparse depth, intrinsics, extrinsics
generic_dense_depth any — inferred from file extension rgb, depth, sky mask, intrinsics
generic any — .npy / .npz modalities points 3d, maps, segmentation, spherical maps, SH coefficients, …

Full inventory with shapes, dtypes and units: docs/loaders.md. The machine-readable version is loaders.json.

Documentation

Guide Covers
Dataset & modalities Modality and MultiModalDataset reference, the sample dict, splits, scoped metadata, zip archives, layout-aware loading
Loaders & writers The loader contract, automatic resolution, per-file attributes, the full built-in inventory
Preprocessing & transforms Cross-modal transforms, SamplePreprocessor, calibration-aware resize and crop
Writing outputs Writing predictions back in dataset-native formats and re-indexing them
Examples Runnable scripts against real datasets

Development

git clone https://github.com/d-rothen/euler-loading.git
cd euler-loading
pip install -e ".[gpu,dev]"
pytest

See CONTRIBUTING.md for the loader-authoring workflow and release process.

License

MIT © Daniel Rothenpieler

See Phase 2 materialization for the opt-in captured spatial workflow (2.24.0, unreleased).

Metadata

Release files for euler-loading 2.25.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for euler-loading 2.25.0
File Size Uploaded
euler_loading-2.25.0.tar.gz 152.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for euler-loading 2.25.0
File Interpreter ABI Platform
euler_loading-2.25.0-py3-none-any.whl Python 3 none any Details

Total release size: 268.4 kB

Release files / euler_loading-2.25.0.tar.gz

Download URL euler_loading-2.25.0.tar.gz
Size 152.0 kB
Tags Source
SHA-256 checksum
How to use checksums
45077479721b7884f31144b4ddb253839a082d02070a7cbaa2e79247787b1da2
BLAKE2b-256 checksum
How to use checksums
210963be3fd1bd61b9bca8356686ffdf126bcfd456a5402270adefe25dfcdb80
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.13 {"installer":{"name":"uv","version":"0.12.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / euler_loading-2.25.0-py3-none-any.whl

Download URL euler_loading-2.25.0-py3-none-any.whl
Size 116.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a66e27f5536f6e537e625c87a00265e7247bff1a7e5b68216b4a86ce7045e2e2
BLAKE2b-256 checksum
How to use checksums
e68f30d297214f83b75fa5110d4ca414fcb5a1f5594257a3935464606fbcaf52
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.13 {"installer":{"name":"uv","version":"0.12.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

2.25.0 This release

2 release files

2.21.0

2 release files

2.20.0

2 release files

2.19.1

2 release files

2.19.0

2 release files

2.18.0

2 release files

2.17.0

2 release files

2.14.0

2 release files

2.12.0

2 release files

2.9.0

2 release files

2.8.0

2 release files

2.7.0

2 release files

2.6.0

2 release files

2.5.0

2 release files

2.4.0

2 release files

2.3.0

2 release files

2.2.2

2 release files

2.2.1

2 release files

2.2.0

2 release files

2.1.0

2 release files

2.0.0

2 release files

1.3.0

2 release files

1.2.0

2 release files

1.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page