This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This project uses uv as the modern Python package manager. Key commands:
# Install uv if not already installed
curl -LsSf https://astral.sh/uv/install.sh | sh
# Create virtual environment and install all dependencies
uv sync --dev# Run all tests
uv run pytest
# Run tests with coverage
uv run pytest --cov=intensity_normalization --cov-report=html
# Run specific test file
uv run pytest tests/test_normalizers.py
# Run specific test
uv run pytest tests/test_normalizers.py::TestFCMNormalizer::test_fcm_basic# Format code
uv run ruff format src/intensity_normalization/
# Lint code
uv run ruff check src/intensity_normalization/
# Fix linting issues automatically
uv run ruff check --fix src/intensity_normalization/
# Type checking
uv run mypy src/intensity_normalization/# Build package
uv buildThe codebase follows Clean Architecture principles with clear separation of concerns:
- protocols.py: Core interfaces (
ImageProtocol,BaseNormalizer,PopulationNormalizer) - models.py: Value objects (
NormalizationConfig,Modality,TissueType) - exceptions.py: Domain-specific exceptions
- images.py: Universal image adapter supporting both numpy arrays and nibabel images
- io.py: File I/O operations for loading/saving images
- individual/: Single-image methods (FCM, Z-score, KDE, WhiteStripe)
- population/: Multi-image methods (Nyúl, LSQ)
- normalization.py: Orchestration logic via
NormalizationService - validation.py: Input validation services
Command-line interface for the intensity-normalize command.
-
Protocol-Based Design: Uses Python protocols for flexibility - any object implementing
ImageProtocolcan be normalized. -
Service Pattern:
NormalizationServiceorchestrates normalization operations, handling both individual and population methods. -
Factory Pattern: Normalizers are created via registry pattern in
NormalizationService. -
Method Categories:
- Individual methods: Fit and transform each image independently
- Population methods: Fit on multiple images, then transform each
- Create normalizer in appropriate directory (
individual/orpopulation/) - Inherit from
BaseNormalizerorPopulationNormalizer - Implement
fit()andtransform()methods - Register in
NORMALIZER_REGISTRYinservices/normalization.py - Add to exports in
__init__.py - Add tests in
tests/test_normalizers.py
- Population methods (
nyul,lsq) require multiple images for fitting - The
ImageProtocolallows seamless support for numpy arrays and nibabel images - Always preserve image metadata when transforming (use
image.with_data()) - Masks are optional but recommended for better normalization results
- The CLI automatically generates output filenames if not specified