Skip to content

Commit 4ac3050

Browse files
edyoshikunclaude
andauthored
Modularizing the model's folder (#365)
* add planning roadmap * docs: start milestone v1.1 Models * docs: define milestone v1.1 requirements * docs: create milestone v1.1 roadmap (5 phases) * docs(package-scaffold-shared-components): research phase domain * docs(06): create phase plan - package scaffold and shared components * feat(06-01): create viscy-models package scaffold - Add pyproject.toml with hatchling build, torch/timm/monai/numpy deps - Create src layout with _components, unet, contrastive, vae subpackages - Add PEP 561 py.typed marker - Add test scaffolding with device fixture Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(06-01): register viscy-models in workspace - Add viscy-models to root dependencies and uv sources - Update lockfile with timm and viscy-models dependencies - Verified: uv sync, import, and pytest collection all succeed Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs(06-01): complete package scaffold plan - Add 06-01-SUMMARY.md with execution results - Update STATE.md with position, metrics, and decisions Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(06-02): extract shared components into _components/ module - stems.py: UNeXt2Stem, StemDepthtoChannels from v0.3.3 unext2.py - heads.py: PixelToVoxelHead, UnsqueezeHead, PixelToVoxelShuffleHead - blocks.py: icnr_init, _get_convnext_stage, UNeXt2UpStage, UNeXt2Decoder - __init__.py: re-exports all 8 public components - Zero imports from unet/, vae/, or contrastive/ - All attribute names preserved for state dict compatibility * feat(06-03): migrate ConvBlock2D and ConvBlock3D to unet/_layers/ - Copy ConvBlock2D from v0.3.3 source to snake_case file - Copy ConvBlock3D from v0.3.3 source to snake_case file - Preserve register_modules/add_module pattern for state dict key compatibility - Update _layers/__init__.py with public re-exports - Fix docstring formatting for ruff D-series compliance * test(06-03): add tests for ConvBlock2D and ConvBlock3D - 6 tests for ConvBlock2D: forward pass, state dict keys, residual, filter steps, instance norm - 4 tests for ConvBlock3D: forward pass, state dict keys, dropout registration, layer order - All 10 tests verify shape, naming patterns, and module registration * test(06-02): add forward-pass tests for all _components - test_stems.py: UNeXt2Stem shape, StemDepthtoChannels shape + mismatch error - test_heads.py: PixelToVoxelHead, UnsqueezeHead, PixelToVoxelShuffleHead shapes - test_blocks.py: icnr_init, _get_convnext_stage, UNeXt2UpStage, UNeXt2Decoder - 10 tests total, all passing on CPU * docs(06-03): complete UNet ConvBlock layers plan - SUMMARY.md with migration details and self-check - STATE.md updated: phase 6 plan 3/3, decisions recorded * docs(06-02): complete shared components extraction plan - SUMMARY.md documents 8 extracted components with 10 tests - STATE.md updated with decisions from 06-02 execution * docs(phase-6): complete phase execution and verification Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs(07-core-unet-models): research phase domain * docs(07): create phase plan for core UNet models * feat(07-01): migrate UNeXt2 model class to viscy-models - Copy UNeXt2 class (~70 lines) from monolithic unext2.py - Update imports to use viscy_models._components (stems, heads, blocks) - Preserve all attribute names for state dict compatibility - Export UNeXt2 from viscy_models.unet public API Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * test(07-01): add 6 UNeXt2 forward-pass tests and fix deconv tuple bug - Add tests: default, small backbone, multichannel, diff stack depths, deconv, stem validation - Fix deconv decoder tuple bug in UNeXt2UpStage (trailing comma created tuple not module) - Mark deconv test xfail: original code has channel mismatch in deconv forward path - All 26 tests pass (25 passed, 1 xfailed) with no regressions Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs(07-01): complete UNeXt2 migration plan - Add 07-01-SUMMARY.md with execution results and deviation documentation - Update STATE.md: phase 7, plan 1/2 complete, new decisions logged Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(07-02): migrate FullyConvolutionalMAE to viscy-models - Copy FCMAE and all helper classes/functions to unet/fcmae.py - Replace old viscy imports with viscy_models._components imports - Remove duplicated PixelToVoxelShuffleHead (import from _components.heads) - Fix mutable list defaults to tuples (encoder_blocks, dims) - Export both UNeXt2 and FullyConvolutionalMAE from unet/__init__.py * test(07-02): migrate 11 FCMAE tests to viscy-models - Copy all 11 test functions with zero logic changes - Update imports from viscy.unet.networks.fcmae to viscy_models.unet.fcmae - Import PixelToVoxelShuffleHead from viscy_models._components.heads - All 37 tests pass across full suite (no regressions) * docs(07-02): complete FCMAE migration plan (Phase 7 complete) - Add 07-02-SUMMARY.md with execution results - Update STATE.md: Phase 7 complete, 12 plans total, decisions logged * docs(phase-7): complete phase execution and verification Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs(phase-8): research representation models migration * docs(08): create phase plan for representation models * feat(08-02): migrate BetaVae25D and BetaVaeMonai to viscy-models - Add BetaVae25D with VaeUpStage, VaeEncoder, VaeDecoder helpers - Add BetaVaeMonai wrapping MONAI VarAutoEncoder - Fix VaeDecoder mutable list defaults to tuples (COMPAT-02) - Change VaeEncoder pretrained default to False - Preserve all attribute names for state dict compatibility Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(08-01): migrate ContrastiveEncoder and ResNet3dEncoder to viscy-models - Add ContrastiveEncoder with convnext/resnet50 backbone support via timm - Add ResNet3dEncoder with MONAI ResNetFeatures backend - Fix ResNet50 bug: use encoder.num_features instead of encoder.head.fc.in_features - Add pretrained parameter (default False) for pure nn.Module semantics - Preserve state dict attribute names (stem, encoder, projection) - Share projection_mlp utility between both encoder classes * test(08-01): add 5 forward-pass tests for contrastive models - 3 tests for ContrastiveEncoder: convnext_tiny, resnet50, custom stem - 2 tests for ResNet3dEncoder: resnet18, resnet10 - Verify embedding and projection output shapes - ResNet50 test uses in_stack_depth=10 for valid stem channel alignment * test(08-02): add forward-pass tests for BetaVae25D and BetaVaeMonai - 2 BetaVae25D tests: resnet50 and convnext_tiny backbones - 2 BetaVaeMonai tests: 2D and 3D spatial configurations - Verify SimpleNamespace output with recon_x, mean, logvar, z - Fix ResNet50 expected spatial dims (64x64 not 128x128) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs(08-01): complete contrastive model migration plan - Add 08-01-SUMMARY.md with execution results - Update STATE.md to Phase 8, plan 1/2 * docs(08-02): complete VAE migration plan (Phase 8 complete) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs(phase-8): complete phase execution and verification Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs(09): research legacy UNet models migration * docs(09): create phase plan for legacy UNet models * feat(09-01): migrate Unet2d and Unet25d to viscy-models - Copy Unet2d from v0.3.3 with import path update to viscy_models.unet._layers - Copy Unet25d from v0.3.3 with import path update to viscy_models.unet._layers - Fix mutable default num_filters=[] to num_filters=() in both models - Add module docstrings and __all__ exports - Update unet/__init__.py to export all 4 models (UNeXt2, FCMAE, Unet2d, Unet25d) - Preserve register_modules/add_module pattern for state dict compatibility - All 45 existing tests still pass Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * test(09-01): add pytest tests for Unet2d and Unet25d - 12 tests for Unet2d: default forward, variable depth, multichannel, residual, task mode, dropout, state dict keys, custom num_filters - 11 tests for Unet25d: default Z-compression, preserved depth, variable depth, multichannel, residual, task mode, state dict keys with skip_conv_layer, custom filters - Fix list(num_filters) conversion in both models for tuple default compatibility - Total test suite: 68 passed, 1 xfailed, 0 failures Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs(09-01): complete legacy UNet migration plan - SUMMARY.md with task commits, deviations, and self-check - STATE.md updated to Phase 9 complete (15 plans total) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs(phase-9): complete phase execution and verification Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs(10): create phase plan for public API and CI integration * feat(10-01): add top-level re-exports for all 8 model classes - Import UNeXt2, FullyConvolutionalMAE, Unet2d, Unet25d from unet subpackage - Import ContrastiveEncoder, ResNet3dEncoder from contrastive subpackage - Import BetaVae25D, BetaVaeMonai from vae subpackage - Update __all__ with all 8 classes in alphabetical order Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * test(10-01): add state dict key compatibility regression tests - 24 tests covering all 8 migrated model architectures - Each model tested for parameter count, top-level prefixes, and sentinel keys - Guards COMPAT-01: state dict keys must match for checkpoint loading - Tests import from top-level viscy_models package (validates public API) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore(10-01): add viscy-models to CI test matrix - Add package dimension to test matrix (viscy-transforms, viscy-models) - Use cross-platform --cov=src/ instead of named package coverage - Matrix now produces 18 jobs (3 OS x 3 Python x 2 packages) - check job automatically aggregates all test results via alls-green Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs(10-01): complete public API & CI integration plan (v1.1 milestone complete) - Add 10-01-SUMMARY.md with execution results - Update STATE.md: phase 10 complete, v1.1 milestone done, 100% progress Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs(phase-10): complete phase execution and verification (v1.1 milestone complete) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor: consolidate ConvBlock2D/3D into _components Move conv_block_2d.py and conv_block_3d.py from unet/_layers/ to _components/ alongside all other shared building blocks. All reusable layers now live in one place. unet/_layers/ retained as backward- compatible re-export shim. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * remove the _layers * update the readme * update the main readme * fix description in toml * changing ruff formatting , dosctrings and imports * renaming folder to components * updatet planning docs * update to components * numpy docstring * add claude.md and contributing.md --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 12b0279 commit 4ac3050

113 files changed

Lines changed: 18145 additions & 65 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/test.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,14 @@ concurrency:
1212

1313
jobs:
1414
test:
15-
name: Test (Python ${{ matrix.python-version }}, ${{ matrix.os }})
15+
name: Test (${{ matrix.package }}, Python ${{ matrix.python-version }}, ${{ matrix.os }})
1616
runs-on: ${{ matrix.os }}
1717
strategy:
1818
fail-fast: true
1919
matrix:
2020
os: [ubuntu-latest, macos-latest, windows-latest]
2121
python-version: ["3.11", "3.12", "3.13"]
22+
package: [viscy-transforms, viscy-models]
2223

2324
steps:
2425
- name: Checkout repository
@@ -33,11 +34,11 @@ jobs:
3334

3435
- name: Install dependencies
3536
run: uv sync --frozen --all-extras --dev
36-
working-directory: packages/viscy-transforms
37+
working-directory: packages/${{ matrix.package }}
3738

3839
- name: Run tests with coverage
39-
run: uv run --frozen pytest --cov=viscy_transforms --cov-report=term-missing
40-
working-directory: packages/viscy-transforms
40+
run: uv run --frozen pytest --cov=src/ --cov-report=term-missing
41+
working-directory: packages/${{ matrix.package }}
4142

4243
check:
4344
name: All tests pass

.planning/MILESTONES.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Milestones: VisCy Modularization
2+
3+
## v1.0 — Transforms & Monorepo Skeleton
4+
5+
**Shipped:** 2026-01-29
6+
**Phases:** 1–5 (4 executed, 1 deferred)
7+
8+
**What shipped:**
9+
- uv workspace scaffolding with `packages/` directory
10+
- `viscy-transforms` package extracted with src layout
11+
- Clean import paths: `from viscy_transforms import X`
12+
- hatchling + uv-dynamic-versioning build system
13+
- All 16 transform modules migrated with full test suite
14+
- CI/CD: 9-job test matrix (3 OS x 3 Python) + lint workflow
15+
- prek hooks with ruff formatting
16+
17+
**Deferred:**
18+
- Phase 4: Documentation (Zensical + GitHub Pages)
19+
20+
**Last phase:** 5

.planning/PROJECT.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# VisCy Modularization
2+
3+
## What This Is
4+
5+
Restructuring VisCy from a monolithic package into a uv workspace monorepo. This enables reusing transforms, dataloaders, and models in downstream projects without requiring the entire VisCy package as a dependency. The second milestone extracts `viscy-models` as an independent package containing all 8 network architectures as pure nn.Modules, organized by function (unet/, vae/, contrastive/) with shared components factored into a `components/` module.
6+
7+
## Core Value
8+
9+
**Independent, reusable subpackages with clean import paths.** Users can `pip install viscy-models` and use `from viscy_models import UNeXt2` without pulling in the entire VisCy ecosystem.
10+
11+
## Current Milestone: v1.1 Models
12+
13+
**Goal:** Extract all network architectures into `viscy-models` as pure nn.Modules with comprehensive test coverage.
14+
15+
**Target features:**
16+
- `viscy-models` package with 8 architectures organized by function (unet/, vae/, contrastive/)
17+
- Shared components extracted to `components/` (stems, heads, decoder blocks)
18+
- Full test coverage: migrate existing + write new for UNeXt2, ContrastiveEncoder, BetaVAE
19+
- Independent of viscy-transforms and lightning (torch/timm/monai deps only)
20+
- State dict key compatibility preserved for checkpoint loading
21+
22+
## Requirements
23+
24+
### Validated
25+
26+
- ✓ uv workspace scaffolding with `packages/` directory structure — v1.0
27+
-`viscy-transforms` package extracted with src layout — v1.0
28+
- ✓ Import path: `from viscy_transforms import X` (clean break) — v1.0
29+
- ✓ hatchling build backend with uv-dynamic-versioning — v1.0
30+
- ✓ All existing transform tests passing in new structure — v1.0
31+
- ✓ CI updated for monorepo structure — v1.0
32+
33+
### Active
34+
35+
- [ ] `viscy-models` package with src layout and function-based organization
36+
- [ ] All 8 architectures migrated: UNeXt2, FCMAE, ContrastiveEncoder, ResNet3dEncoder, BetaVae25D, BetaVaeMonai, Unet2d, Unet25d
37+
- [ ] Shared components extracted to `components/` (stems, heads, blocks)
38+
- [ ] Full test coverage: existing tests migrated + new tests for untested models
39+
- [ ] Import path: `from viscy_models import UNeXt2` (clean break)
40+
- [ ] State dict key compatibility preserved
41+
- [ ] CI includes viscy-models in test matrix
42+
43+
### Out of Scope
44+
45+
- Hydra/BaseModel registry infrastructure — deferred to future `viscy-hydra` package
46+
- BaseModelMeta metaclass — deferred to future `viscy-hydra` package
47+
- Extracting data packages (viscy-data) — future milestone
48+
- Application-level LightningModules — move to applications/ in future milestone
49+
- Backward-compatible imports — not maintaining
50+
- Documentation (Zensical + GitHub Pages) — deferred from v1.0
51+
52+
## Context
53+
54+
**Design doc:** https://github.com/mehta-lab/VisCy/issues/353
55+
56+
**Reference implementations:**
57+
- flowbench BaseModel: `/home/eduardo.hirata/repos/flowbench/src/models/base_model.py` (future reference for viscy-hydra)
58+
- lightning-hydra-template: https://github.com/ashleve/lightning-hydra-template (future reference)
59+
- iohub pyproject.toml: modern hatchling + uv-dynamic-versioning pattern
60+
61+
**Current state (post v1.0):**
62+
- uv workspace with `viscy-transforms` at `packages/viscy-transforms/`
63+
- Root `viscy` umbrella package with dynamic versioning
64+
- Models in monolithic `viscy/unet/networks/` and `viscy/representation/`
65+
- 14+ shared components in unext2.py used by fcmae, contrastive, vae
66+
- No tests for UNeXt2, ContrastiveEncoder, or BetaVAE
67+
68+
**Architecture vision:**
69+
- `viscy-models`: Pure nn.Module architectures (this milestone)
70+
- `viscy-hydra`: BaseModel, BaseModelMeta, Hydra config utilities (future milestone)
71+
- Applications (Cytoland, DynaCLR): LightningModules composing models with training logic (future milestone)
72+
73+
## Constraints
74+
75+
- **Package naming**: `viscy-models` (hyphen) as package name, `viscy_models` (underscore) as import
76+
- **Python version**: >=3.11 (matching current VisCy)
77+
- **Build system**: hatchling with uv-dynamic-versioning (following viscy-transforms pattern)
78+
- **Layout**: src layout required (`packages/viscy-models/src/viscy_models/`)
79+
- **Independence**: viscy-models must NOT depend on viscy-transforms or lightning
80+
- **Dependencies**: torch, timm, monai, numpy only
81+
- **Tooling**: uv only, no pip/setuptools for package management
82+
83+
## Key Decisions
84+
85+
| Decision | Rationale | Outcome |
86+
|----------|-----------|---------|
87+
| Clean break on imports | Simpler architecture, no re-export complexity | ✓ Good |
88+
| hatchling over setuptools | Modern, faster, better uv integration | ✓ Good |
89+
| src layout | Prevents import confusion during development | ✓ Good |
90+
| Tests inside packages | Isolated testing, `uv run --package` workflow | ✓ Good |
91+
| Pure nn.Module in viscy-models | No Lightning/Hydra coupling; maximum reusability | — Pending |
92+
| Hydra infra in separate package | Keeps model package lightweight; Hydra optional for consumers | — Pending |
93+
| Function-based grouping (unet/, vae/, contrastive/) | Clean organization for 8+ models with shared components | — Pending |
94+
| viscy-models independent of viscy-transforms | Keep packages loosely coupled | — Pending |
95+
96+
---
97+
*Last updated: 2026-02-12 after requirements definition*

.planning/REQUIREMENTS.md

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
# Requirements: VisCy Modularization
2+
3+
**Defined:** 2025-01-27
4+
**Core Value:** Independent, reusable subpackages with clean import paths
5+
6+
## v1.0 Requirements (Complete)
7+
8+
### Workspace Foundation
9+
10+
- [x] **WORK-00**: Clean slate setup - wipe repo keeping only LICENSE, CITATION.cff, .gitignore
11+
- [x] **WORK-01**: Virtual workspace root with `[tool.uv.workspace]` and `members = ["packages/*"]`
12+
- [x] **WORK-02**: Shared lockfile (`uv.lock`) at repository root
13+
- [x] **WORK-03**: Python version floor (>=3.11) enforced in root pyproject.toml
14+
- [x] **WORK-04**: Pre-commit hooks configured (ruff, ty) for local development
15+
- [x] **WORK-05**: Shared pytest configuration in root pyproject.toml
16+
17+
### Package Structure
18+
19+
- [x] **PKG-01**: src layout for viscy-transforms (`packages/viscy-transforms/src/viscy_transforms/`)
20+
- [x] **PKG-02**: Package pyproject.toml with hatchling build backend
21+
- [x] **PKG-03**: uv-dynamic-versioning configured for git-based versioning
22+
- [x] **PKG-04**: Package README.md with installation and usage instructions
23+
24+
### Code Migration
25+
26+
- [x] **MIG-01**: All transform modules migrated from `viscy/transforms/` to package
27+
- [x] **MIG-02**: All transform tests migrated from `tests/transforms/` to `packages/viscy-transforms/tests/`
28+
- [x] **MIG-03**: Import path updated to `from viscy_transforms import X`
29+
- [x] **MIG-04**: All migrated tests passing with `uv run --package viscy-transforms pytest`
30+
- [x] **MIG-05**: Original `viscy/transforms/` directory removed
31+
32+
### CI/CD
33+
34+
- [x] **CI-01**: GitHub Actions workflow for testing viscy-transforms package
35+
- [x] **CI-03**: Matrix testing across Python 3.11, 3.12, 3.13
36+
- [x] **CI-04**: Linting via prek (uvx prek) in CI workflows
37+
38+
## v1.1 Requirements
39+
40+
Requirements for milestone v1.1 (Models). Each maps to roadmap phases.
41+
42+
### Models -- Package Infrastructure
43+
44+
- [x] **MPKG-01**: Package directory `packages/viscy-models/` with src layout (`src/viscy_models/`)
45+
- [x] **MPKG-02**: pyproject.toml with hatchling, uv-dynamic-versioning, torch/timm/monai/numpy dependencies
46+
- [x] **MPKG-03**: `uv sync --package viscy-models` succeeds in workspace
47+
- [x] **MPKG-04**: `components/` module with stems.py, heads.py, blocks.py extracted from shared code
48+
49+
### Models -- UNet Architectures
50+
51+
- [x] **UNET-01**: UNeXt2 migrated to `unet/unext2.py` with shared component imports updated
52+
- [x] **UNET-02**: FullyConvolutionalMAE migrated to `unet/fcmae.py`
53+
- [x] **UNET-03**: Unet2d migrated to `unet/unet2d.py` (renamed from PascalCase)
54+
- [x] **UNET-04**: Unet25d migrated to `unet/unet25d.py` (renamed from PascalCase)
55+
- [x] **UNET-05**: ConvBlock2D/3D migrated to `unet/_layers/` (renamed from PascalCase)
56+
- [x] **UNET-06**: Forward-pass tests for UNeXt2 (NEW -- currently missing)
57+
- [x] **UNET-07**: FCMAE tests migrated from existing test suite
58+
- [x] **UNET-08**: Unet2d/Unet25d tests migrated and converted from unittest to pytest
59+
60+
### Models -- Variational Autoencoders
61+
62+
- [x] **VAE-01**: BetaVae25D migrated to `vae/beta_vae_25d.py`
63+
- [x] **VAE-02**: BetaVaeMonai migrated to `vae/beta_vae_monai.py`
64+
- [x] **VAE-03**: Forward-pass tests for both VAE models (NEW -- currently missing)
65+
66+
### Models -- Contrastive Learning
67+
68+
- [x] **CONT-01**: ContrastiveEncoder migrated to `contrastive/encoder.py`
69+
- [x] **CONT-02**: ResNet3dEncoder migrated to `contrastive/resnet3d.py`
70+
- [x] **CONT-03**: Forward-pass tests for contrastive models (NEW -- currently missing)
71+
72+
### Models -- Public API & CI
73+
74+
- [x] **API-01**: `from viscy_models import UNeXt2` works for all 8 model classes
75+
- [x] **API-02**: `uv run --package viscy-models pytest` passes all tests
76+
- [x] **API-03**: CI test matrix updated to include viscy-models
77+
- [x] **API-04**: Root pyproject.toml updated with viscy-models workspace dependency
78+
79+
### Models -- Compatibility
80+
81+
- [x] **COMPAT-01**: State dict keys preserved identically for all migrated models
82+
- [x] **COMPAT-02**: Mutable default arguments fixed to tuples in model constructors
83+
84+
## Future Requirements
85+
86+
Deferred to future milestones. Tracked but not in current roadmap.
87+
88+
### Hydra Integration (future viscy-hydra package)
89+
90+
- **HYDRA-01**: BaseModelMeta metaclass or `__init_subclass__` registry for model discovery
91+
- **HYDRA-02**: BaseModel(LightningModule) base class with auto Hydra instantiation
92+
- **HYDRA-03**: Hydra ConfigStore integration (optional dependency)
93+
- **HYDRA-04**: `get_model("unext2")` factory function for name-based lookup
94+
95+
### Applications (future milestone)
96+
97+
- **APP-01**: applications/DynaCLR with ContrastiveModule LightningModule
98+
- **APP-02**: applications/Cytoland with VSUNet/FcmaeUNet LightningModules
99+
100+
### Documentation (deferred from v1.0)
101+
102+
- **DOC-01**: Zensical configuration (`zensical.toml`) at repository root
103+
- **DOC-02**: Documentation site structure with navigation
104+
- **DOC-03**: API reference auto-generated from docstrings
105+
- **DOC-04**: GitHub Pages deployment
106+
107+
## Out of Scope
108+
109+
Explicitly excluded. Documented to prevent scope creep.
110+
111+
| Feature | Reason |
112+
|---------|--------|
113+
| Hydra/BaseModel registry in viscy-models | Deferred to separate viscy-hydra package |
114+
| LightningModule wrappers | Training logic stays in applications/ |
115+
| Backward-compatible imports | Clean break approach |
116+
| viscy-data extraction | Separate milestone |
117+
| Documentation (Zensical) | Deferred from v1.0 |
118+
| ONNX/TorchScript export | VAE models return SimpleNamespace, incompatible |
119+
120+
## Traceability
121+
122+
Which phases cover which requirements. Updated during roadmap creation.
123+
124+
### v1.0 Traceability
125+
126+
| Requirement | Phase | Status |
127+
|-------------|-------|--------|
128+
| WORK-00 | Phase 1 | Complete |
129+
| WORK-01 | Phase 1 | Complete |
130+
| WORK-02 | Phase 1 | Complete |
131+
| WORK-03 | Phase 1 | Complete |
132+
| WORK-04 | Phase 1 | Complete |
133+
| WORK-05 | Phase 1 | Complete |
134+
| PKG-01 | Phase 2 | Complete |
135+
| PKG-02 | Phase 2 | Complete |
136+
| PKG-03 | Phase 2 | Complete |
137+
| PKG-04 | Phase 2 | Complete |
138+
| MIG-01 | Phase 3 | Complete |
139+
| MIG-02 | Phase 3 | Complete |
140+
| MIG-03 | Phase 3 | Complete |
141+
| MIG-04 | Phase 3 | Complete |
142+
| MIG-05 | Phase 3 | Complete |
143+
| CI-01 | Phase 5 | Complete |
144+
| CI-03 | Phase 5 | Complete |
145+
| CI-04 | Phase 5 | Complete |
146+
147+
### v1.1 Traceability
148+
149+
| Requirement | Phase | Status |
150+
|-------------|-------|--------|
151+
| MPKG-01 | Phase 6 | Complete |
152+
| MPKG-02 | Phase 6 | Complete |
153+
| MPKG-03 | Phase 6 | Complete |
154+
| MPKG-04 | Phase 6 | Complete |
155+
| UNET-05 | Phase 6 | Complete |
156+
| COMPAT-02 | Phases 7-9 | Complete |
157+
| UNET-01 | Phase 7 | Complete |
158+
| UNET-02 | Phase 7 | Complete |
159+
| UNET-06 | Phase 7 | Complete |
160+
| UNET-07 | Phase 7 | Complete |
161+
| CONT-01 | Phase 8 | Complete |
162+
| CONT-02 | Phase 8 | Complete |
163+
| CONT-03 | Phase 8 | Complete |
164+
| VAE-01 | Phase 8 | Complete |
165+
| VAE-02 | Phase 8 | Complete |
166+
| VAE-03 | Phase 8 | Complete |
167+
| UNET-03 | Phase 9 | Complete |
168+
| UNET-04 | Phase 9 | Complete |
169+
| UNET-08 | Phase 9 | Complete |
170+
| API-01 | Phase 10 | Complete |
171+
| API-02 | Phase 10 | Complete |
172+
| API-03 | Phase 10 | Complete |
173+
| API-04 | Phase 10 | Complete |
174+
| COMPAT-01 | Phase 10 | Complete |
175+
176+
**Coverage:**
177+
- v1.0 requirements: 18 total, 18 mapped (complete)
178+
- v1.1 requirements: 24 total, 24 mapped
179+
- Unmapped: 0
180+
181+
---
182+
*Requirements defined: 2025-01-27*
183+
*Last updated: 2026-02-12 after v1.1 roadmap creation*

0 commit comments

Comments
 (0)