Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 50 additions & 2 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e .[dev]
pip install -e .[dev,bl733,desy_p03]

- name: Lint with flake8
run: |
Expand Down Expand Up @@ -63,7 +63,7 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e .[dev]
pip install -e .[dev,bl733,desy_p03]

- name: Run tests with pytest
run: |
Expand Down Expand Up @@ -121,3 +121,51 @@ jobs:
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max

build-and-push-desy:
needs: [lint, test]
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata (tags, labels) for DESY Docker image
id: meta-desy
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
flavor: |
suffix=-desy,onlatest=true
tags: |
type=ref,event=branch
type=ref,event=pr
type=ref,event=tag
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=raw,value=latest,enable={{is_default_branch}}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Build and push DESY Docker image
uses: docker/build-push-action@v5
with:
context: .
file: ./Containerfile.desy
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta-desy.outputs.tags }}
labels: ${{ steps.meta-desy.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
14 changes: 14 additions & 0 deletions Containerfile.desy
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FROM ghcr.io/bluesky/tiled:0.2.15 AS base

# uv is a statically-linked Rust binary — no shared-library mprotect call,
# so it works under rootless Podman where `pip` (glibc RELRO) fails.
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv

USER app
ENV PATH=/app/bin:$PATH
ENV PYTHONPATH=/app/src:/tiled_deploy/config

COPY --chown=app:app pyproject.toml README.md ./
COPY --chown=app:app src/ ./src/
RUN uv pip install --python /app/bin/python --no-cache ".[desy_p03]"
COPY --chown=app:app scripts/ ./scripts/
20,398 changes: 10,235 additions & 10,163 deletions pixi.lock

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions pixi.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ platforms = ["linux-64", "osx-64", "osx-arm64", "linux-aarch64"]
[environments]
default = { features = ["bl733"] }
dev = { features = ["bl733", "dev"] }
desy-p03 = { features = ["desy_p03", "dev"] }

[dependencies]
python = "3.13.*"
Expand All @@ -20,6 +21,9 @@ zarr = "*"
numpy = "*"
pandas = "*"

[pypi-dependencies]
splash_tiled = { path = ".", editable = true }

[feature.dev.dependencies]
mypy = "*"
ipython = "*"
Expand All @@ -35,10 +39,16 @@ pytest-asyncio = "*"
[feature.bl733.dependencies]
fabio = "*"

[feature.desy_p03.dependencies]
fabio = "*"
h5py = "*"
ndindex = "*"

[tasks]
test = "pytest --cov=splash_tiled --cov-report=term-missing"
test_user_office = "pytest -m user_office"
test_integration = "pytest tests/test_user_office_integration.py -v"
lint = "flake8 src tests && black --check src tests && isort --check-only src tests && mypy src"
format = "black src tests && isort src tests"
precommit = "pre-commit run --all-files"
access = "access"
5 changes: 5 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ tiled-all = [
bl733 = [
"fabio",
]
desy_p03 = [
"fabio",
"h5py",
"ndindex",
]
dev = [
"flake8",
"black",
Expand Down
Empty file.
Empty file.
Empty file.
70 changes: 70 additions & 0 deletions src/splash_tiled/external/desy_p03/adapters/cbf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import logging
from typing import Any, Optional

import fabio
from tiled.adapters.array import ArrayAdapter
from tiled.adapters.utils import init_adapter_from_catalog
from tiled.catalog.orm import Node
from tiled.structures.array import ArrayStructure
from tiled.structures.core import Spec, StructureFamily
from tiled.structures.data_source import DataSource
from tiled.type_aliases import JSON
from tiled.utils import path_from_uri

logger = logging.getLogger(__name__)
LOADING_MESSAGE = "Loading CBF file produced at DESY beamline P03: %s"


class CBFAdapter(ArrayAdapter):
structure_family = StructureFamily.array

def __init__(
self,
data_uri: str,
structure: Optional[ArrayStructure] = None,
metadata: Optional[JSON] = None,
specs: Optional[list[Spec]] = None,
**kwargs: Optional[Any],
) -> None:
"""Adapter for `.cbf` detector image files (e.g. Dectris Eiger/Pilatus) at DESY beamline P03."""
filepath = path_from_uri(data_uri)
logger.debug(LOADING_MESSAGE, filepath)

with fabio.open(filepath) as cbf_file:
array = cbf_file.data
metadata_cbf = dict(cbf_file.header)

metadata = {
**(metadata or {}),
**metadata_cbf,
}

cbf_spec = Spec("desy-p03-cbf", version="1.0")
specs = list(specs or [])
if cbf_spec not in specs:
specs.append(cbf_spec)
super().__init__(
array=array,
structure=structure or ArrayStructure.from_array(array),
metadata=metadata,
specs=specs,
**kwargs,
)

@classmethod
def from_catalog(
cls,
data_source: DataSource,
node: Node,
/,
**kwargs: Optional[Any],
) -> "CBFAdapter":
return init_adapter_from_catalog(cls, data_source, node, **kwargs)

@classmethod
def from_uris(
cls,
data_uri: str,
**kwargs: Optional[Any],
) -> "CBFAdapter":
return cls(data_uri, **kwargs)
Loading
Loading