Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
163 commits
Select commit Hold shift + click to select a range
078ce21
Improved the styling of components
hpmartins Oct 8, 2025
30fd222
Updated page title, favicon and logo
hpmartins Oct 8, 2025
fa47cae
Removed unused dependencies
hpmartins Oct 8, 2025
ff836df
Disabled third column
hpmartins Oct 15, 2025
6bb2963
Changed column sizes and flow to fit screen
hpmartins Oct 15, 2025
beee4c8
Refactoring Scattering and XPS into modules (1)
hpmartins Oct 22, 2025
d5d874d
Refactoring Scattering and XPS into modules (2)
hpmartins Oct 22, 2025
660d312
feat: integrate Tiled for data selection and enhance scattering funct…
hpmartins Nov 4, 2025
c2c1448
Removed commented-out code
hpmartins Nov 4, 2025
ec32da9
fix: avoid infinite loop when a linecut is added
hpmartins Nov 4, 2025
19edee4
Update folder_url to container_path for clarity
hpmartins Nov 18, 2025
a7fda52
Improve binary extraction and buffer alignment handling
hpmartins Nov 18, 2025
28df36c
Update Docker configuration + uv for backend
hpmartins Nov 19, 2025
754e242
replace lucide-react and react-icons with phosphor-icons
hpmartins Nov 19, 2025
8de541e
commenting out hubapplayout
hpmartins Nov 19, 2025
c50a80e
restyle: sidebar first changes
hpmartins Dec 3, 2025
7072e83
restyle: content + data transformation overlay
hpmartins Dec 3, 2025
484dc7a
restyle: collapsible sidebar and raw data overview
hpmartins Dec 3, 2025
5f16f5b
restyle: moved subtract/divide to a menu
hpmartins Dec 3, 2025
d85867e
restyle: changed title colors
hpmartins Dec 3, 2025
c25d90a
restyle: update layout and font sizes
hpmartins Dec 8, 2025
834793f
refactor: centralize Tiled client management and improve API structure
hpmartins Dec 8, 2025
825bed5
refactor: migrate utility functions to centralized utils module
hpmartins Dec 8, 2025
4beffa8
refactor: add CLI entry point and update project structure/deps
hpmartins Dec 8, 2025
d8b89de
moved to tests folder
hpmartins Dec 8, 2025
1c199bb
refactor: restructure frontend application and update package configu…
hpmartins Dec 9, 2025
d873c5c
feat: added session storage
hpmartins Dec 11, 2025
a62156d
renamed useMultimodal to useScattering
hpmartins Dec 11, 2025
fd59a96
updated favicon
hpmartins Dec 11, 2025
1b0fea5
updated ALS logo + added header on standalone
hpmartins Dec 11, 2025
0579925
removed unused variables / props
hpmartins Dec 11, 2025
401bef5
added mantine notifications
hpmartins Dec 11, 2025
3ff6851
fixed variable name
hpmartins Dec 11, 2025
6bb4220
renamed spectrum to summary, fixed notifications
hpmartins Dec 11, 2025
26c52be
localStorage replaced by sessionStorage
hpmartins Dec 11, 2025
5354c5d
first test for indexeddb for scattering image cache
hpmartins Dec 17, 2025
70f4161
changed some font styles
hpmartins Dec 17, 2025
b2873bc
moved calibration parameters to overlay
hpmartins Dec 17, 2025
b5652b9
changed layout of linecuts + new icons
hpmartins Dec 17, 2025
5c4a68b
refactored UI components; replaced mantine with radix-ui
hpmartins Dec 17, 2025
0b95ecf
removed bidirectional scaleanchor and scaleratio
hpmartins Dec 17, 2025
6067a7c
unified horizontal/vertical fig/widgets into one file for each
hpmartins Dec 17, 2025
ce439fb
renamed Raw Data Overview to Summary
hpmartins Dec 17, 2025
6df8017
removed px
hpmartins Dec 17, 2025
271fc95
replaced msgpack with msgpackr
hpmartins Dec 17, 2025
5523974
added natural sorting for images
hpmartins Dec 17, 2025
29c04a2
changed linecut card and graph labels
hpmartins Dec 18, 2025
8b07670
fetch q-vectors when image size changes, not image itself
hpmartins Dec 19, 2025
2a781a9
caching calculations for all resolutions instead of only orig image
hpmartins Dec 19, 2025
f558a17
attempt at improving loops
hpmartins Dec 19, 2025
4ed74a8
upgraded plotly packages
hpmartins Dec 19, 2025
a171945
moving image selection to scattering data card
hpmartins Dec 19, 2025
4da772c
feat: Add backend image cache, H5Web visualization, and SummaryFig en…
hpmartins Dec 29, 2025
b88e809
refactor(frontend): reorganize component structure and reduce code du…
hpmartins Dec 29, 2025
2f1abf6
refactor(Tooltip): integrate Radix UI for improved tooltip
hpmartins Dec 29, 2025
13ee99e
refactor: reduce bundle size with partial Plotly.js and remove unused…
hpmartins Dec 29, 2025
e7fbb05
updated pyFAI from 2025.3.0 to 2025.12.1
hpmartins Dec 30, 2025
6694a89
refactor: add initial GISAXS support with direct equations
hpmartins Dec 30, 2025
591a4a7
refactor + squeeze to ensure 2D image
hpmartins Jan 7, 2026
2033b91
fix(NumberInput): input handling with local state and formatting
hpmartins Jan 7, 2026
0a9f114
calibration params start as null + warning if not set
hpmartins Jan 7, 2026
2ad2b21
adjusted select to shrink correctly
hpmartins Jan 7, 2026
6fd03af
adjust grid and content padding
hpmartins Jan 7, 2026
06e515f
feat(CalibrationAccordion): add Tiled integration for loading calibra…
hpmartins Jan 8, 2026
b196164
adding z-index for react-tooltip to fix Tiled select
hpmartins Jan 8, 2026
ff787e1
feat(backend): Add batch processing for linecut and azimuthal integra…
hpmartins Jan 8, 2026
7e62a48
feat(frontend): added initial batch processing
hpmartins Jan 8, 2026
1f5e957
added Radix UI Tabs component
hpmartins Jan 10, 2026
cfa51c3
improved batch processing, exporting and visualization
hpmartins Jan 12, 2026
56d6fbc
added fabio as dependency
hpmartins Jan 13, 2026
ea2a4ce
feat: Add mask management
hpmartins Jan 13, 2026
f07a084
added server-side linecut computation with Q-matrix caching
hpmartins Jan 14, 2026
524cf7e
added pre-commit as dev dep
hpmartins Jan 14, 2026
013c3c3
consolidated shared types and removed some unused code
hpmartins Jan 14, 2026
4a9e3a4
removed utility exports
hpmartins Jan 14, 2026
becc280
update pre-commit hooks and add ESLint/Prettier configuration
hpmartins Jan 14, 2026
1177818
replaced button elements with finch Button
hpmartins Jan 14, 2026
d30c659
added mask dimension validation and status handling in upload and loa…
hpmartins Jan 14, 2026
4449250
fix to ensure safe websocket removal on disconnect
hpmartins Jan 14, 2026
9e95789
add @radix-ui/react-toggle-group dependency
hpmartins Jan 14, 2026
f069f5a
add ToggleGroup component
hpmartins Jan 14, 2026
74157b3
replace summary Toggle components with ToggleGroup
hpmartins Jan 14, 2026
9337f03
inverting qy to match inverted image y-axis
hpmartins Jan 14, 2026
95693d8
add maskUri to session persistence
hpmartins Jan 14, 2026
571d130
add toolbar button to toggle between pixel and q-space
hpmartins Jan 15, 2026
f8ba507
fixed max q-value for azimuthal integration
hpmartins Jan 15, 2026
75c00c6
added mask overlay
hpmartins Jan 15, 2026
5064f7f
added first version
hpmartins Jan 15, 2026
2f73e9e
simplified App to use standalone only
hpmartins Jan 16, 2026
6dd0891
add configuration for standalone application
hpmartins Jan 16, 2026
06d015a
update Docker setup
hpmartins Jan 16, 2026
a3ee64f
removed Plotly-based ScatterSubplot component
hpmartins Jan 16, 2026
34bcf78
remove unused clipPolygonToImageBoundaries
hpmartins Jan 16, 2026
184db4f
using original q-space to pixel width functions
hpmartins Jan 16, 2026
5d380b9
refactored h5webscattersubplot component
hpmartins Jan 16, 2026
8d73fb8
changed Batch buttons and constants
hpmartins Jan 16, 2026
c52df10
renamed and clean up files
hpmartins Jan 16, 2026
2957857
linecut widths are limited to max q value
hpmartins Jan 16, 2026
a5e012e
binary search for closest q-value in pixel position calculations
hpmartins Jan 16, 2026
9d1cf3d
vectorized numpy operations
hpmartins Jan 16, 2026
a6ab230
incident angle validation for GISAXS + minor layout change
hpmartins Jan 16, 2026
369a1ed
check for incident angle before submitting
hpmartins Jan 16, 2026
07a6e8e
consolidated q magnitute calculation to one fetch
hpmartins Jan 16, 2026
71545da
Refactor backend to src-layout package structure
hpmartins Jan 17, 2026
4d3debf
remove resolution levels
hpmartins Jan 19, 2026
2209ece
Add GISAXS Q-space support with pyFAI FiberIntegrator
hpmartins Jan 19, 2026
e37c504
Add /api/get-mask endpoint to restore masks from backend cache
hpmartins Jan 19, 2026
25416a6
reset q data / calibration and toggles when experiment changes
hpmartins Jan 19, 2026
514438b
remove old data transformation logic
hpmartins Jan 20, 2026
770ac26
maximized heatmap sizes with y-axis label on left panel only
hpmartins Jan 20, 2026
96a7b3a
Replace Plotly.js with H5Web for all line plot visualizations
hpmartins Jan 20, 2026
2f1b71a
Add zoom/pan synchronization across heatmap panels
hpmartins Jan 20, 2026
55efee8
fix data Map key renumbering when deleting horizontal/vertical linecuts
hpmartins Jan 20, 2026
f20650c
Fix domain widget popup clipping and style toolbar background
hpmartins Jan 20, 2026
58d8287
reformatting whole code
hpmartins Jan 20, 2026
e1b2056
Add SCATTERING_BACKEND_ prefix to env vars and unify port to 4000
hpmartins Jan 20, 2026
bf7235a
revert overflow changes and reposition DomainWidget in toolbar
hpmartins Jan 21, 2026
2c405f4
refactor backend cache with generic LRUCache and improve type safety
hpmartins Jan 21, 2026
6bafa08
cleaning up comments and unused plotly type declaration
hpmartins Jan 21, 2026
043aebf
consolidate/rename duplicated type definitions
hpmartins Jan 21, 2026
4a27b6f
refactor linecut hooks with generic factory pattern
hpmartins Jan 21, 2026
39a381f
add useMemo and React.memo to avoid re-renders
hpmartins Jan 21, 2026
84a4dd3
fix TypeScript strict mode errors and consolidate duplicated types
hpmartins Jan 21, 2026
b18c887
strict linting options
hpmartins Jan 21, 2026
9141c6c
fix: no minimum yMax
hpmartins Jan 21, 2026
e34ca4d
set default showGrid to true
hpmartins Jan 21, 2026
0f308c6
add auto-toggle for Q-space + loading overlay
hpmartins Jan 21, 2026
1d35437
add beam center overlay and toolbar button
hpmartins Jan 21, 2026
48990f7
reorder toolbar buttons and rename states for clarity
hpmartins Jan 21, 2026
5c005df
add snapshot for visualizations
hpmartins Jan 21, 2026
96672b6
add CSV download buttons to linecut figures
hpmartins Jan 21, 2026
32c3783
use domain-clamped values for comparison image
hpmartins Jan 21, 2026
d7e780c
updated
hpmartins Jan 21, 2026
c596cd5
add tooltips and fix button icon alignment
hpmartins Jan 21, 2026
a7b7dcf
fix experiment type change and Q-matrix reset
hpmartins Jan 21, 2026
781f5bd
optimize React hooks
hpmartins Jan 21, 2026
df7ff5c
formatting
hpmartins Jan 21, 2026
e2f0d46
add build-essential for pyFAI installation
hpmartins Jan 27, 2026
c4e0ea1
auto-select first tab with batch results
hpmartins Jan 28, 2026
65a5a17
Done button is now enabled when uploading mask
hpmartins Jan 28, 2026
89e4ad7
dynamic Q slider step size based on actual data spacing
hpmartins Jan 28, 2026
b37aadb
fix: Q value precision in sliders and tooltips
hpmartins Jan 28, 2026
f220d5f
center linecut overlays at center of pixels
hpmartins Jan 28, 2026
1646696
increase max upload size for image uploads
hpmartins Jan 28, 2026
9a231c5
add info tooltip for linecuts
hpmartins Jan 29, 2026
65f0dc7
add frontend unit tests
hpmartins Jan 29, 2026
cb47c98
fix: exclude masked pixels from SAXS linecut width averaging
hpmartins Jan 29, 2026
640bbe0
unify backend logging via Uvicorn's log_config
hpmartins Jan 29, 2026
89af81c
add save-to-Tiled feature for linecut and batch results
hpmartins Jan 29, 2026
a396a32
add dedicated calibration Tiled server + unified infrastructure endpoint
hpmartins Jan 30, 2026
5d1f11d
add prop to enable/disable Tiled calibration loading
hpmartins Jan 30, 2026
00bf909
return Tiled ID and URI from save endpoints, show confirmation popup
hpmartins Jan 30, 2026
5f3ac65
replace infrastructure endpoint with unified health check + overlay
hpmartins Jan 30, 2026
60d25ca
move calibration loading from frontend to backend endpoint
hpmartins Jan 30, 2026
d9fd0d1
added tilt_angle and converted all angles to radians
hpmartins Jan 30, 2026
eb3d313
deduplicate q/chi array computation in azimuthal integration
hpmartins Jan 30, 2026
ada27b8
include enableTiledResults and default props to true
hpmartins Jan 30, 2026
c30d50b
updated with env vars and props
hpmartins Jan 30, 2026
0538990
use pyFAI direct integration for GISAXS linecuts + graph transformations
hpmartins Jan 30, 2026
58646c2
added test notebook
hpmartins Jan 30, 2026
63ac132
add configurable npt for GISAXS pyFAI linecut integration
hpmartins Jan 30, 2026
9e2fc12
fix: restore overflow-hidden on ContentCard to fix image panel resize
hpmartins Jan 30, 2026
819cd40
fix: use consistent q axis labels in GISAXS mode
hpmartins Jan 30, 2026
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
107 changes: 103 additions & 4 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,103 @@
TILED_URI_MASK="http://host.docker.internal:8888/api/v1/metadata/raw/AgB_2024_03_25_10s_2m_mask"
TILED_API_KEY_MASK=<your-unique-tiled-api-key-for-mask>
TILED_URI_IMAGES="http://127.0.0.1:8888/api/v1/metadata/raw/"
TILED_API_KEY_IMAGES=<your-unique-tiled-api-key-for-images>
# =============================================================================
# Required Environment Variables
# =============================================================================
# These must be set before starting the backend server.

# Tiled Server URL
# The base URL for the Tiled data server providing scan data.
SCATTERING_TILED_URL="http://tiled:8888/api/v1"

# Tiled API Key
# Authentication token for accessing the Tiled server.
SCATTERING_TILED_API_KEY="your_api_key_here"

# =============================================================================
# Optional Environment Variables (with defaults)
# =============================================================================
# These have sensible defaults but can be tuned for your environment.

# -----------------------------------------------------------------------------
# Save Results to Tiled (Optional Feature)
# -----------------------------------------------------------------------------
# When set, a "Save to Tiled" button appears in the UI, allowing users to
# save linecut and batch processing results to a writable Tiled container.
# If not set, the feature is disabled and no save buttons are shown.

# URL of the writable Tiled container for saving results.
# Use the metadata path to target a specific container, e.g.:
# http://tiled:8888/api/v1/metadata/results
# Or use the bare API URL to write to the root:
# http://tiled:8888/api/v1
# SCATTERING_TILED_RESULTS_URL="http://tiled:8888/api/v1/metadata/results"

# API key for the results Tiled server.
# SCATTERING_TILED_RESULTS_API_KEY="your_results_api_key_here"

# -----------------------------------------------------------------------------
# Calibration Tiled Server (Optional Feature)
# -----------------------------------------------------------------------------
# When set, calibration parameters and masks can be loaded from a dedicated
# Tiled server. If not set, calibration loading from Tiled is disabled and
# users must enter calibration parameters manually or upload mask files.

# URL of the Tiled server containing calibration data (PONI files and masks).
# SCATTERING_TILED_CALIBRATION_URL="http://tiled-calibration:8888/api/v1"

# API key for the calibration Tiled server.
# SCATTERING_TILED_CALIBRATION_API_KEY="your_calibration_api_key_here"

# -----------------------------------------------------------------------------
# Server Configuration
# -----------------------------------------------------------------------------

# Development mode enables hot reload (default: false)
# Set to true for local development, false for production/Docker.
# SCATTERING_BACKEND_DEVELOPMENT=false

# Backend server host address (default: 0.0.0.0)
# Use 0.0.0.0 to accept connections from any interface.
# SCATTERING_BACKEND_HOST=0.0.0.0

# Backend server port (default: 8000)
# SCATTERING_BACKEND_PORT=8000

# -----------------------------------------------------------------------------
# Cache Configuration
# -----------------------------------------------------------------------------
# Larger cache sizes improve performance but use more memory.
# Each cached image is ~10-50MB depending on detector size.

# Maximum number of processed images to cache (default: 50)
# SCATTERING_BACKEND_CACHE_IMAGE_SIZE=50

# Maximum number of Q-space matrices to cache (default: 20)
# Q-matrices are reused when only linecut parameters change.
# SCATTERING_BACKEND_CACHE_QSPACE_SIZE=20

# Maximum number of GISAXS transforms to cache (default: 20)
# SCATTERING_BACKEND_CACHE_GISAXS_SIZE=20

# Maximum number of masks to cache per cache type (default: 50)
# Applies to both Tiled masks and uploaded masks separately.
# SCATTERING_BACKEND_CACHE_MASK_SIZE=50

# Maximum number of Tiled URI client connections to cache (default: 4)
# SCATTERING_BACKEND_CACHE_TILED_URIS=4

# -----------------------------------------------------------------------------
# Batch Processing Configuration
# -----------------------------------------------------------------------------

# Maximum number of parallel workers for batch processing (default: 16)
# Higher values improve throughput but increase memory usage.
# Recommended: Set to number of CPU cores or slightly higher for I/O-bound work.
# SCATTERING_BACKEND_BATCH_MAX_WORKERS=16

# -----------------------------------------------------------------------------
# Logging Configuration
# -----------------------------------------------------------------------------

# Log level for application logging (default: INFO)
# Valid values: DEBUG, INFO, WARNING, ERROR, CRITICAL
# Use DEBUG for development, INFO or WARNING for production.
# SCATTERING_BACKEND_LOG_LEVEL=INFO
20 changes: 16 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ default_language_version:
python: python3
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
rev: v6.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
Expand All @@ -13,11 +13,11 @@ repos:
- id: check-yaml
- id: debug-statements
- repo: https://github.com/gitguardian/ggshield
rev: v1.25.0
rev: v1.46.0
hooks:
- id: ggshield
language_version: python3
stages: [commit]
stages: [pre-commit]
# Using this mirror lets us use mypyc-compiled black, which is about 2x faster
- repo: https://github.com/psf/black-pre-commit-mirror
rev: 24.2.0
Expand All @@ -28,7 +28,19 @@ repos:
hooks:
- id: flake8
- repo: https://github.com/pycqa/isort
rev: 5.13.2
rev: 7.0.0
hooks:
- id: isort
args: ["--profile", "black"]
- repo: local
hooks:
- id: prettier
name: prettier
entry: npx --prefix frontend prettier --write
language: system
files: ^frontend/.*\.(js|jsx|ts|tsx|css|scss|json)$
- id: eslint
name: eslint
entry: npx --prefix frontend eslint --fix --config frontend/eslint.config.js
language: system
files: ^frontend/.*\.(js|jsx|ts|tsx)$
81 changes: 81 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# XScattering - GISAXS/SAXS Data Analysis

Full-stack scientific application for X-ray scattering data visualization and analysis.

**Stack:** React 18 + TypeScript + Vite | FastAPI + Python 3.13 | Docker Compose

## Features

- **Dual image comparison** with synchronized panning/zooming
- **Linecut extraction** (horizontal, vertical, inclined) in Q-space
- **Azimuthal integration** using pyFAI
- **GISAXS and SAXS modes** with proper Q-space transformations
- **Batch processing** across multiple scans with real-time progress
- **Detector mask support** (upload or load from Tiled)
- **Session persistence** for analysis state

## Quick Start (Docker)

```bash
# 1. Set environment variables
export SCATTERING_TILED_URL="http://your-tiled-server:8000/api/v1"
export SCATTERING_TILED_API_KEY="your-api-key"

# 2. Build and run
docker-compose up --build

# 3. Access at http://localhost:3000
```

## Environment Variables

| Variable | Required | Description |
|----------|----------|-------------|
| `SCATTERING_TILED_URL` | Yes | Tiled server URL (e.g., `http://localhost:8000/api/v1`) |
| `SCATTERING_TILED_API_KEY` | Yes | Tiled API authentication token |
| `SCATTERING_TILED_RESULTS_URL` | No | Writable Tiled URL for saving results (enables "Save to Tiled" buttons) |
| `SCATTERING_TILED_RESULTS_API_KEY` | No | API key for the results Tiled server |
| `SCATTERING_BACKEND_DEVELOPMENT` | No | Enable hot reload (default: `false`) |
| `SCATTERING_BACKEND_HOST` | No | Server bind address (default: `0.0.0.0`) |
| `SCATTERING_BACKEND_PORT` | No | Server port (default: `8000`) |
| `SCATTERING_BACKEND_LOG_LEVEL` | No | Logging level (default: `INFO`) |

See `.env.example` for all available configuration options.

## Development (without Docker)

### Backend

```bash
cd backend
uv sync # Install dependencies
SCATTERING_BACKEND_DEVELOPMENT=true uv run xscattering-backend # Dev server with hot reload
```

### Frontend

```bash
cd frontend
npm install # Install dependencies
npm run dev # Runs on http://localhost:4000
```

## Project Structure

```
├── frontend/ # React app (Vite + TypeScript)
│ └── src/
│ └── components/
│ └── Scattering/ # Main analysis component
├── backend/ # FastAPI server
│ └── src/
│ └── xscattering_backend/
│ ├── routers/ # API endpoints
│ ├── cache/ # LRU caches
│ ├── config/ # Settings and models
│ └── utils/ # Q-space, linecut extraction
├── docker-compose.yml
└── .env.example
```

## License
1 change: 1 addition & 0 deletions backend/.dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ venv/
ENV/
.git
.gitignore
*.ipynb
1 change: 1 addition & 0 deletions backend/.python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.13
30 changes: 21 additions & 9 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,37 @@ FROM python:3.13-slim
# All subsequent commands will be run from this directory
WORKDIR /app

# Copy only the requirements file first
# Install build dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
&& rm -rf /var/lib/apt/lists/*

# Install uv
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/

# Copy dependency files first for better layer caching
# This takes advantage of Docker's layer caching
# If requirements.txt doesn't change, Docker will reuse the cached dependencies
COPY requirements.txt .
# Install Python dependencies specified in requirements.txt
# --no-cache-dir reduces the image size by not storing the pip cache
RUN pip install --no-cache-dir -r requirements.txt
# If pyproject.toml and uv.lock don't change, Docker will reuse the cached dependencies
COPY pyproject.toml uv.lock ./

# Install Python dependencies using uv
# --system installs packages into the system Python rather than creating a virtual environment
# --locked ensures the exact versions from uv.lock are used
# --no-cache reduces the image size by not storing the uv cache
RUN uv sync --no-cache --no-dev

# Copy the rest of the application code
# This step is done after installing dependencies for better caching
# When you change your code but not requirements.txt, only this layer is rebuilt
# When you change your code but not pyproject.toml/uv.lock, only this layer is rebuilt
COPY . .

# Inform Docker that the container will listen on port 8000
# Inform Docker/Podman that the container will listen on port 8000
# This is for documentation - it doesn't actually publish the port
EXPOSE 8000

# Define the command to run the FastAPI application
# uv run executes the command in the environment with installed dependencies
# uvicorn is the ASGI server that will run your FastAPI app
# --host 0.0.0.0 makes the server available to all network interfaces
# --port 8000 specifies the port the server will listen on
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
CMD ["uv", "run", "uvicorn", "xscattering_backend.main:app", "--host", "0.0.0.0", "--port", "8000"]
95 changes: 95 additions & 0 deletions backend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# XScattering Backend

FastAPI backend for SAXS/GISAXS X-ray scattering analysis.

## Requirements

- Python 3.13+
- [uv](https://github.com/astral-sh/uv) package manager

## Setup

```bash
cd backend
uv sync
```

## Configuration

Required environment variables:

| Variable | Description |
|----------|-------------|
| `SCATTERING_TILED_URL` | Tiled data server URL |
| `SCATTERING_TILED_API_KEY` | Tiled API key |

Optional (Tiled services):

| Variable | Description |
|----------|-------------|
| `SCATTERING_TILED_RESULTS_URL` | Writable Tiled container URL for saving analysis results. Feature disabled if unset. |
| `SCATTERING_TILED_RESULTS_API_KEY` | API key for the results Tiled server |
| `SCATTERING_TILED_CALIBRATION_URL` | Tiled server URL for calibration data (PONI files and masks). Feature disabled if unset. |
| `SCATTERING_TILED_CALIBRATION_API_KEY` | API key for the calibration Tiled server |

Optional (server):

| Variable | Default | Description |
|----------|---------|-------------|
| `SCATTERING_BACKEND_DEVELOPMENT` | false | Enable development mode with hot reload |
| `SCATTERING_BACKEND_HOST` | 0.0.0.0 | Server host |
| `SCATTERING_BACKEND_PORT` | 8000 | Server port |
| `SCATTERING_BACKEND_LOG_LEVEL` | INFO | DEBUG/INFO/WARNING/ERROR/CRITICAL |
| `SCATTERING_BACKEND_BATCH_MAX_WORKERS` | 16 | Thread pool size for batch processing |

Optional (cache sizes):

| Variable | Default | Description |
|----------|---------|-------------|
| `SCATTERING_BACKEND_CACHE_IMAGE_SIZE` | 50 | Image cache entries |
| `SCATTERING_BACKEND_CACHE_QSPACE_SIZE` | 20 | Q-matrix cache entries |
| `SCATTERING_BACKEND_CACHE_GISAXS_SIZE` | 20 | GISAXS transform cache entries |
| `SCATTERING_BACKEND_CACHE_MASK_SIZE` | 50 | Mask cache entries (per type) |
| `SCATTERING_BACKEND_CACHE_TILED_URIS` | 4 | Tiled URI client connection cache entries |

## Run

```bash
uv run xscattering-backend
```

Or with uvicorn directly:

```bash
uv run uvicorn xscattering_backend.main:app --reload
```

## Docker

```bash
docker build -t xscattering-backend .
docker run -p 8000:8000 \
-e SCATTERING_TILED_URL=... \
-e SCATTERING_TILED_API_KEY=... \
xscattering-backend
```

## API Endpoints

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/api/health` | GET | Unified health status for all services |
| `/api/summary` | GET | Scan metadata for folder |
| `/api/fetch-scan-image` | GET | Detector image with optional GISAXS transform |
| `/api/q-space` | GET | Q-matrix computation (SAXS) |
| `/api/extract-linecut` | POST | Single linecut extraction |
| `/api/azimuthal-integrator` | GET | 1D azimuthal integration |
| `/api/batch-all` | POST | Parallel batch processing across scans |
| `/api/batch-cancel/{batch_id}` | POST | Cancel an active batch job |
| `/api/get-mask` | GET | Retrieve cached mask data |
| `/api/upload-mask` | POST | Upload a detector mask file |
| `/api/load-mask-from-tiled` | GET | Load a mask from Tiled |
| `/api/load-calibration` | GET | Load calibration parameters and mask from a PONI file in Tiled |
| `/api/save-linecuts` | POST | Save linecut results to Tiled |
| `/api/save-batch-results` | POST | Save batch results to Tiled |
| `/ws/progress` | WS | Real-time progress updates |
Loading