|
| 1 | +# Copilot Instructions for multiscale-spatial-image |
| 2 | + |
| 3 | +## Project Overview |
| 4 | + |
| 5 | +This library generates multiscale, chunked, multi-dimensional spatial image data |
| 6 | +structures serializable to OME-NGFF format. It's built on Xarray DataTree with |
| 7 | +spatial-image Dataset nodes, creating image pyramids for visualization and |
| 8 | +analysis. |
| 9 | + |
| 10 | +## Core Architecture |
| 11 | + |
| 12 | +### Key Components |
| 13 | + |
| 14 | +- **MultiscaleSpatialImage**: Xarray DataTree accessor |
| 15 | + (`@register_datatree_accessor("msi")`) providing NGFF-compatible multiscale |
| 16 | + operations |
| 17 | +- **to_multiscale()**: Main entry point for creating pyramids with configurable |
| 18 | + downsampling methods |
| 19 | +- **Methods enum**: Defines downsampling algorithms (XARRAY*COARSEN, ITK*_, |
| 20 | + DASK*IMAGE*_) |
| 21 | +- **Operations module**: Provides dataset operations that skip non-dimensional |
| 22 | + nodes |
| 23 | + |
| 24 | +### Data Structure Pattern |
| 25 | + |
| 26 | +```python |
| 27 | +# DataTree structure: /scale0, /scale1, /scale2, etc. |
| 28 | +# Each scale contains Dataset with same variable name as input |
| 29 | +multiscale = to_multiscale(image, [2, 4]) # Creates 3 scales total |
| 30 | +multiscale['scale0'].ds # Original resolution |
| 31 | +multiscale['scale1'].ds # 2x downsampled |
| 32 | +multiscale['scale2'].ds # 8x downsampled (2*4) |
| 33 | +``` |
| 34 | + |
| 35 | +### Zarr Integration Patterns |
| 36 | + |
| 37 | +- **Always use `dimension_separator='/'`** for NGFF compliance |
| 38 | +- Support both Zarr v2 (DirectoryStore) and v3 (LocalStore) with fallback |
| 39 | + pattern in `_data.py` |
| 40 | +- NGFF metadata automatically added in `to_zarr()` method with coordinate |
| 41 | + transformations |
| 42 | + |
| 43 | +## Development Workflows |
| 44 | + |
| 45 | +### Environment Management (Pixi-based) |
| 46 | + |
| 47 | +```bash |
| 48 | +pixi install -a # Install all environments |
| 49 | +pixi run -e test test # Run unit tests |
| 50 | +pixi run test-notebooks # Test example notebooks |
| 51 | +pixi shell # Activate development shell |
| 52 | +``` |
| 53 | + |
| 54 | +### Testing Patterns |
| 55 | + |
| 56 | +- **Baseline comparison testing**: Use `verify_against_baseline()` for image |
| 57 | + output validation |
| 58 | +- **Test data**: IPFS-hosted via pooch, SHA256-verified downloads |
| 59 | +- **Notebook testing**: nbmake integration tests all examples |
| 60 | +- **Multiple backends**: Tests run against ITK, dask-image, and xarray methods |
| 61 | + |
| 62 | +### Adding Test Data |
| 63 | + |
| 64 | +```python |
| 65 | +# Temporary add this line to generate new baseline: |
| 66 | +store_new_image(dataset_name, baseline_name, multiscale) |
| 67 | +# Remove after running tests, then update data.tar.gz and SHA256 in _data.py |
| 68 | +``` |
| 69 | + |
| 70 | +## Critical Patterns |
| 71 | + |
| 72 | +### Dimension Handling |
| 73 | + |
| 74 | +- **skip_non_dimension_nodes decorator**: Essential for operations on DataTree |
| 75 | + root nodes without dimensions |
| 76 | +- **Default chunking**: Uses 64 for 3D (with 'z'), 256 for 2D, 1 for 't' |
| 77 | + dimension |
| 78 | +- **Coordinate transforms**: Scale and translation automatically computed from |
| 79 | + coordinate spacing |
| 80 | + |
| 81 | +### Multi-Backend Support |
| 82 | + |
| 83 | +```python |
| 84 | +# Pattern for optional dependencies |
| 85 | +try: |
| 86 | + from zarr.storage import DirectoryStore # Zarr v2 |
| 87 | +except ImportError: |
| 88 | + from zarr.storage import LocalStore # Zarr v3 |
| 89 | +``` |
| 90 | + |
| 91 | +### Downsampling Method Dispatch |
| 92 | + |
| 93 | +- Each method in `to_multiscale/` subdirectory follows `_downsample_{method}` |
| 94 | + naming |
| 95 | +- Methods handle chunking alignment via `_align_chunks()` helper |
| 96 | +- Scale factors can be uniform int or per-dimension dict: |
| 97 | + `[2, {'x': 2, 'y': 4}]` |
| 98 | + |
| 99 | +## Integration Points |
| 100 | + |
| 101 | +### External Dependencies |
| 102 | + |
| 103 | +- **spatial-image**: Base SpatialImage input type |
| 104 | +- **xarray-datatree**: Core DataTree functionality |
| 105 | +- **OME-NGFF**: Metadata standard compliance via `multiscales` attribute |
| 106 | +- **Optional**: ITK (medical imaging), dask-image (distributed), pyimagej |
| 107 | + |
| 108 | +### File Patterns |
| 109 | + |
| 110 | +- `multiscale_spatial_image.py`: Core accessor class with to_zarr() and |
| 111 | + operations |
| 112 | +- `to_multiscale/`: Downsampling method implementations |
| 113 | +- `operations/`: Dataset operations with dimension-aware decorators |
| 114 | +- `examples/`: Jupyter notebooks demonstrating usage patterns |
| 115 | + |
| 116 | +## Key Conventions |
| 117 | + |
| 118 | +- Use `promote_attrs=True` when converting DataArrays to Datasets to preserve |
| 119 | + metadata |
| 120 | +- Coordinate names follow spatial conventions: 't' (time), 'c' (channel), |
| 121 | + 'x'/'y'/'z' (space) |
| 122 | +- Error handling validates scale factors against current image dimensions before |
| 123 | + processing |
| 124 | +- NGFF axes metadata includes type classification (time/channel/space) and |
| 125 | + optional units |
0 commit comments