Predict volume#280
Conversation
|
@ziw-liu, @tayllatheodoro is actively working on this branch to get a prototype ready for Friday. Can you please keep an eye on it and provide quick feedback where needed? Thanks! |
edyoshikun
left a comment
There was a problem hiding this comment.
I still need to test that this runs.
| weights = x.new_zeros((1, 1, Z, 1, 1)) | ||
|
|
||
| pad = getattr(self, "_predict_pad", None) | ||
| if pad is None: |
There was a problem hiding this comment.
Im not sure if this is needed?
Co-authored-by: Ziwen Liu <67518483+ziw-liu@users.noreply.github.com>
Co-authored-by: Ziwen Liu <67518483+ziw-liu@users.noreply.github.com>
|
@edyoshikun @tayllatheodoro @srivarra flagging that we should work on merging this PR. As far as I know, the code works well and we are happy with it. |
now initialized in __init__
- Removed the weights == 0 runtime check - the sliding window logic
guarantees full coverage when iterating range(0, depth, step)
|
@ieivanov @tayllatheodoro @srivarra
Feel free to run any of the demo scripts. This should fix Gav's parallelization issue. |
|
Thanks @edyoshikun! Do you approve this PR? I think it's worth merging it as soon as possible, maybe early next week? We rely on it for autotracker, and it sounds like it may be useful to Gav also. @tayllatheodoro can you look through Ed's last set of changes and also approve the PR? |
|
Tagging @mark-a-potts, as he is working on the OPS optimization and this might be useful. |
Port PR #280 ("Predict volume") functionality to the modular architecture. - Enhance _blend_in in prediction_writer.py to support both torch.Tensor (5D: B,C,Z,Y,X) and np.ndarray (4D: C,Z,Y,X) with unified blending - Add predict_sliding_windows() to AugmentedPredictionVSUNet for in-memory Z-sliding inference with linear feathering blending - Extract _predict_with_tta() helper from predict_step() - Make forward_transforms/inverse_transforms optional (default identity) - Add getattr guard for out_stack_depth (clear error for 2D models) - Add 7 tests: blend_in consistency/edge cases, sliding window shape, invalid input, missing attribute, optional transforms Co-Authored-By: Claude Sonnet 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
* docs: start milestone v1.1 Extract viscy-data
* update the main readme
* docs: complete viscy-data project research
* docs: define milestone v1.1 requirements
* docs: create milestone v1.1 roadmap (4 phases)
* docs(06-package-scaffolding-and-foundation): create phase plan
* feat(06-01): create viscy-data package directory structure with pyproject.toml
- Add pyproject.toml with hatchling build, uv-dynamic-versioning, all base deps
- Declare optional dependency groups: triplet, livecell, mmap, all
- Add PEP 561 py.typed marker and tests/__init__.py
- Configure pattern-prefix for independent versioning
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(06-01): add type definitions and package init with re-exports
- Copy all type definitions from viscy/data/typing.py into _typing.py
- Add INDEX_COLUMNS from viscy/data/triplet.py for shared access
- Update typing_extensions.NotRequired to typing.NotRequired (Python >=3.11)
- Create __init__.py with full re-export of all public types
- Add README.md required by hatchling build
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(06-01): integrate viscy-data as workspace dependency in root pyproject.toml
- Add viscy-data to root dependencies list
- Register viscy-data as workspace source in [tool.uv.sources]
- Verified editable install and full import chain works
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(06-01): complete package scaffolding plan with summary and state update
- Add 06-01-SUMMARY.md documenting viscy-data package creation
- Update STATE.md with plan position, metrics, and decisions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(06-02): extract shared utility functions into _utils.py
- Extract _ensure_channel_list, _search_int_in_str, _collate_samples, _read_norm_meta from hcs.py
- Extract _scatter_channels, _gather_channels, _transform_channel_wise from triplet.py
- Update imports to use viscy_data._typing instead of viscy.data.typing
- Add __all__ listing all 7 utility functions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(06-02): complete utility module extraction plan
- Add 06-02-SUMMARY.md documenting utility extraction
- Update STATE.md: Phase 6 complete, progress 80%
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(phase-6): complete phase execution
* docs(07-code-migration): create phase plan
* feat(07-01): migrate select.py, distributed.py, segmentation.py to viscy-data
- Copy select.py with well/FOV filtering utilities (no internal viscy imports)
- Copy distributed.py with ShardedDistributedSampler (no internal viscy imports)
- Copy segmentation.py with viscy.data.typing -> viscy_data._typing import update
- Add missing docstrings to satisfy ruff D rules
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(07-01): migrate hcs.py to viscy-data with utility import rewiring
- Copy HCSDataModule, SlidingWindowDataset, MaskTestDataset from main
- Replace viscy.data.typing imports with viscy_data._typing
- Remove 4 utility function definitions (now in _utils.py)
- Add import from viscy_data._utils for shared utilities
- Remove unused re and collate_meta_tensor imports
- Add missing docstrings for ruff D compliance
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(07-01): migrate gpu_aug.py to viscy-data with dependency rewiring
- Copy GPUTransformDataModule, CachedOmeZarrDataset, CachedOmeZarrDataModule
- Rewire viscy.data.distributed -> viscy_data.distributed
- Rewire viscy.data.hcs utility imports -> viscy_data._utils
- Rewire viscy.data.select -> viscy_data.select
- Rewire viscy.data.typing -> viscy_data._typing
- Add missing docstrings for ruff D compliance
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(07-01): complete core data module migration plan
- Add 07-01-SUMMARY.md documenting migration of 5 core modules
- Update STATE.md: phase 7 plan 1 of 4, decisions, metrics
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(07-03): migrate mmap_cache.py and ctmc_v1.py to viscy-data
- Rewire all imports from viscy.data to viscy_data prefix
- Add lazy import for tensordict with clear error message
- Add docstrings for ruff D compliance
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(07-03): migrate livecell.py with lazy optional dependency imports
- Rewire imports from viscy.data to viscy_data prefix
- Add lazy imports for pycocotools, tifffile, torchvision
- Add import guards in LiveCellDataset and LiveCellTestDataset __init__
- Add docstrings for ruff D compliance
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(07-03): migrate combined.py as-is with import rewiring
- Rewire viscy.data.distributed to viscy_data.distributed
- Rewire viscy.data.hcs._collate_samples to viscy_data._utils._collate_samples
- Preserve all 6 public classes without structural changes
- Add docstrings for ruff D compliance
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(07-02): migrate cell_classification.py and cell_division_triplet.py
- Rewire imports from viscy.data to viscy_data prefix
- Add lazy import for pandas in cell_classification.py with clear error message
- Import _transform_channel_wise from viscy_data._utils (not triplet.py)
- Import INDEX_COLUMNS and AnnotationColumns from viscy_data._typing
- Add docstrings for ruff D compliance
* docs(07-03): complete optional dependency module migration plan
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(07-02): complete specialized module migration plan
- Add 07-02-SUMMARY.md documenting triplet, classification, and cell division module migration
- Update STATE.md with position, decisions, and metrics
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(07-04): add complete public API exports to viscy_data __init__.py
- Export all 45 public names (17 types, 2 utilities, 26 DataModules/Datasets/enums)
- Eager imports from all 13 modules (lazy guards handled internally by each module)
- Comprehensive __all__ list for IDE autocompletion and star-import support
- Ruff-sorted import ordering passes all lint checks
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(07-04): complete public API exports plan - phase 7 fully done
- 07-04-SUMMARY.md documenting 45 public exports and full package verification
- STATE.md updated: phase 7 complete (4/4 plans), 12 total plans done
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(phase-7): complete code migration execution
* docs(08-test-migration-and-validation): create phase plan
* test(08-01): add conftest.py with HCS OME-Zarr fixtures for viscy-data
- Copy all 6 fixtures and _build_hcs helper from main branch conftest
- Replace legacy np.random.rand with np.random.default_rng (NPY002)
- No viscy import changes needed (only uses third-party libs)
- Provides preprocessed_hcs_dataset, small_hcs_dataset, tracks fixtures
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(08-02): complete smoke tests plan - phase 8 test migration done
- Created 08-02-SUMMARY.md documenting 52 smoke tests for viscy_data
- Updated STATE.md: phase 8 complete, 14 total plans executed
- DATA-TST-02 satisfied: import, __all__, optional dep messages, no legacy namespace
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(08-01): migrate test_hcs, test_triplet, test_select to viscy-data package
- Update imports from viscy.data.X to viscy_data
- Add BatchedCenterSpatialCropd to _utils.py (fixes batch dim handling)
- Fix triplet.py to use BatchedCenterSpatialCropd instead of CenterSpatialCropd
- Add tensorstore to test dependency group for triplet tests
- All 19 tests pass across 3 test files
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(08-01): complete data test migration plan summary
- Create 08-01-SUMMARY.md documenting test migration and bug fixes
- Update STATE.md with BatchedCenterSpatialCropd decision revision
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(phase-8): complete test migration and validation
* docs(09-ci-integration): create phase plan
* feat(09-01): add viscy-data CI test jobs to GitHub Actions workflow
- Add test-data job with 3x3 matrix (3 OS x 3 Python) for viscy-data
- Add test-data-extras job (ubuntu-latest, Python 3.13) for extras validation
- Update check job needs to aggregate all test jobs: test, test-data, test-data-extras
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(09-01): complete CI integration plan
- Add 09-01-SUMMARY.md documenting viscy-data CI jobs
- Update STATE.md: phase 9 complete, v1.0 milestone complete
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(phase-9): complete CI integration - milestone v1.1 done
* chore: complete v1.1 milestone — Extract viscy-data
Delivered: viscy-data package with 15 modules, 45 public exports,
optional dependency groups, 71 tests, and tiered CI.
Archives:
- milestones/v1.1-ROADMAP.md
- milestones/v1.1-REQUIREMENTS.md
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* harmonize the planning between the modular-data and modular-models
* viscy-utils package
* add applications/dynaclr
* update the monorepo uv
* moving files around
* update planning
* docs: start milestone v2.1 DynaCLR Integration Validation
* docs: define milestone v2.1 requirements
* docs: create milestone v2.1 roadmap (2 phases)
* docs(18-training-validation): create phase plan
* feat(18-01): add training integration tests for ContrastiveModule
- Add fast_dev_run tests for TripletMarginLoss and NTXentLoss code paths
- Add parametrized config class_path resolution tests for fit.yml and predict.yml
- Add tensorboard as test dependency for TensorBoardLogger in integration tests
- Fix workspace exclude to skip non-package application directories
- Use 2D-compatible synthetic data shapes (1,1,4,4) for render_images compatibility
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs(18-01): complete training integration tests plan
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs(phase-18): complete phase execution
* docs(19-inference-reproducibility): create phase plan
* chore(19-01): add anndata test dependency and HPC conftest fixtures
- Add anndata to dynacrl test dependency group
- Create conftest.py with HPC path constants, skip markers, and fixtures
- Update uv.lock
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(19-01): add inference reproducibility integration tests
- Create test_inference_reproducibility.py with 2 HPC integration tests
- test_checkpoint_loads_into_modular_contrastive_module (INFER-01)
- test_predict_embeddings_and_exact_match (INFER-02 + INFER-03)
- Fix lazy imports in EmbeddingWriter to avoid unconditional umap import
- Fix anndata nullable string compatibility in write_embedding_dataset
- Tests skip gracefully when HPC paths or GPU unavailable
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(19-01): complete inference reproducibility plan
- Add 19-01-SUMMARY.md with execution results and deviation documentation
- Update STATE.md: Phase 19 complete, v2.1 milestone finished
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: add seed_everything(42) to all integration tests
Ensures reproducibility by seeding all tests consistently.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(phase-19): complete phase execution
* restructure the examples folder and ruff
* update readme.me hallucination
* update the readmes
* - Add `viscy` console script in viscy-utils pointing to
viscy_utils.cli:main
- Add jsonargparse[signatures] dependency for LightningCLI
- Add 4 CLI smoke tests (help, subcommands, fit --help, predict
--help)
- Replace conda/anaconda with uv in SLURM scripts
- Update SLURM scripts to use `viscy fit/predict` instead of old
monolith
* add the CLI for running training and prediction
* default embedding writer to None
* import within the function
* ruff
* dynaclr typo
* rename folder to dynaclr
* add the classifiers here
* docs: start milestone v2.2 Composable Sampling Framework
* docs: define milestone v2.2 requirements
* docs: create milestone v2.2 roadmap (6 phases)
* docs(20): capture phase context
* docs(20): create phase plan for experiment configuration
* test(20-01): add failing tests for ExperimentConfig and ExperimentRegistry
- 19 test cases covering config creation, defaults, channel maps,
validation errors, YAML loading, tau-range conversion, and lookups
- All tests fail with ModuleNotFoundError (module not yet implemented)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(20-01): implement ExperimentConfig and ExperimentRegistry
- ExperimentConfig dataclass with all fields and defaults
- ExperimentRegistry with fail-fast validation at __post_init__:
empty check, duplicate names, source_channel membership,
channel count consistency, interval_minutes positivity,
condition_wells non-empty, data_path existence, zarr channel match
- channel_maps: per-experiment source position -> zarr index mapping
- from_yaml classmethod for YAML config loading
- tau_range_frames for hours-to-frames conversion with warning
- get_experiment lookup by name with KeyError
- All 19 tests pass
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor(20-01): clean up imports and exclude stale dynacrl workspace member
- Fix ruff I001 (import sorting) and F401 (unused import) in test file
- Exclude applications/dynacrl (typo) from uv workspace to unblock builds
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs(20-01): complete ExperimentConfig/ExperimentRegistry plan
- SUMMARY.md with TDD execution results, self-check passed
- STATE.md updated with position, decisions, session continuity
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(20-02): add explicit deps and top-level experiment API exports
- Add iohub>=0.3a2 and pyyaml as explicit dependencies in dynaclr pyproject.toml
- Re-export ExperimentConfig and ExperimentRegistry from dynaclr __init__.py
- Both classes now importable via `from dynaclr import ExperimentConfig, ExperimentRegistry`
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(20-02): add example multi-experiment YAML configuration
- Demonstrate positional channel alignment across 2 experiments
- SEC61 (30min interval, ER) and TOMM20 (15min interval, mito)
- Show condition_wells with infected/uninfected/mock conditions
- Include comments explaining channel alignment and tau_range conversion
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs(20-02): complete package wiring and example config plan
- SUMMARY.md with execution results and self-check
- STATE.md updated: Phase 20 complete, 20/25 phases (80%)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs(phase-20): complete phase execution
Phase 20 Experiment Configuration verified (11/11 must-haves).
ExperimentConfig + ExperimentRegistry with TDD, package wiring, example YAML.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs(21): create phase plan for Cell Index & Lineage
* test(21-01): add failing tests for MultiExperimentIndex
- 17 test cases covering CELL-01 (unified tracks), CELL-02 (lineage), CELL-03 (border clamping)
- All fail with ModuleNotFoundError (dynaclr.index not yet implemented)
- Test fixtures create mini OME-Zarr stores with tracking CSVs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(21-01): implement MultiExperimentIndex with lineage and border clamping
- Unified tracks DataFrame from all experiments with enriched columns
- Lineage reconstruction linking daughters to root ancestor via parent_track_id
- Border clamping: retains border cells with shifted patch origins instead of exclusion
- All 23 tests pass
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor(21-01): fix lint issues and export MultiExperimentIndex
- Remove unused variable (F841) in test_global_track_id_unique_across_experiments
- Use .to_numpy() instead of .values (PD011) in test_exclude_fovs_filter
- Export MultiExperimentIndex from dynaclr __init__.py
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs(21-01): complete MultiExperimentIndex plan summary and state update
- 21-01-SUMMARY.md with full execution documentation
- STATE.md updated for 21-01 completion, decisions, session continuity
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* test(21-02): add failing tests for valid anchors, properties, and summary
- 8 tests for valid_anchors: basic validity, subset check, end-of-track exclusion,
lineage continuity, different tau ranges, empty tracks, gap handling, self-exclusion
- 9 tests for properties/summary: experiment_groups, condition_groups, summary()
- All 17 new tests fail with TypeError (tau_range_hours not yet accepted)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(21-02): implement valid_anchors, experiment_groups, condition_groups, summary
- Add tau_range_hours parameter to MultiExperimentIndex.__init__
- _compute_valid_anchors: per-experiment tau conversion, lineage-based lookup
- experiment_groups/condition_groups properties returning index arrays
- summary() with experiment counts, observation counts, per-experiment breakdowns
- All 40 tests pass (23 existing + 17 new)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs(21-02): complete valid anchors plan
- SUMMARY.md with self-check passed
- STATE.md updated: Phase 21 complete, ready for Phase 22
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs(22): research batch sampling phase domain
* docs(22): create phase plan for batch sampling
* test(22-01): add failing tests for FlexibleBatchSampler
- Experiment-aware batching: single-experiment restriction, all experiments appear
- Condition balancing: 2-condition and 3-condition proportional tests
- Leaky mixing: zero leak, 20% leak injection, no-effect when not experiment-aware
- Small group fallback: no crash, warning emission
- Determinism: same seed/epoch reproduces, set_epoch changes sequence
- Sampler protocol: yields list[int], correct __len__
- DDP partitioning: disjoint interleaved batches across ranks
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(22-01): implement FlexibleBatchSampler with experiment-aware, condition-balanced, leaky mixing
- FlexibleBatchSampler(Sampler[list[int]]) with cascade batch construction
- experiment_aware=True restricts each batch to a single experiment
- condition_balanced=True balances condition representation per batch
- leaky > 0.0 injects cross-experiment samples into restricted batches
- Deterministic via np.random.default_rng(seed + epoch)
- DDP support via interleaved batch partitioning across ranks
- Small group fallback to replacement sampling with logged warning
- Pre-computed group indices at __init__ for O(1) lookup
- Fix lint issues in test file (import sorting, .values -> .to_numpy(), nunique -> len(unique))
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor(22-01): export FlexibleBatchSampler from viscy_data package
- Add FlexibleBatchSampler to viscy_data.__init__.py public API
- Place import in alphabetically correct position for ruff isort compliance
- Add to __all__ exports under Utilities section
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs(22-01): complete FlexibleBatchSampler core plan
- Create 22-01-SUMMARY.md with TDD execution results
- Update STATE.md: plan 01/02 complete, decisions, session continuity
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* test(22-02): add failing tests for temporal enrichment, DDP coverage, validation
- 6 temporal enrichment tests (focal concentration, global_fraction edge cases, validation)
- 5 DDP disjoint coverage tests (interleaving, coverage, epoch reproducibility)
- 3 validation guard tests (missing experiment/condition/hpi columns)
- 2 package import tests (import, __all__)
- All 9 new feature tests fail as expected (RED)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(22-02): implement temporal enrichment, validation guards, DDP coverage
- Add temporal_enrichment, temporal_window_hours, temporal_global_fraction params
- Implement _enrich_temporal: focal/global sampling from experiment pool
- Add column validation guards for experiment/condition/hpi columns
- Conditional precomputation: only groupby columns when feature enabled
- Fix stale smoke test __all__ count (45 -> 46) from Plan 01
- All 35 sampler tests pass, 107 total viscy-data tests pass
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs(22-02): complete temporal enrichment + DDP plan
- 22-02-SUMMARY.md with all metrics, decisions, deviations
- STATE.md advanced to Phase 23, progress 22/25 (88%)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs(phase-22): complete batch sampling phase execution
Phase 22 verified: FlexibleBatchSampler with all 5 SAMP requirements.
5/5 must-haves passed. 35 tests, 107 full suite pass. No regressions.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs(23): create phase plan for Loss & Augmentation
* test(23-01): add failing tests for NTXentHCL
- 12 test cases covering subclass, beta=0 equivalence, hard negatives,
gradients, temperature effect, edge cases, defaults, and CUDA
- All fail with ModuleNotFoundError (dynaclr.loss not yet created)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* test(23-02): add failing tests for ChannelDropout and variable tau sampling
- 11 tests for ChannelDropout: zeros, probability bounds, eval mode, per-sample, dtype, input safety, multi-channel, CUDA
- 7 tests for sample_tau: range, exponential decay, uniform, single value, determinism, return type
* feat(23-02): implement ChannelDropout and variable tau sampling
- ChannelDropout nn.Module: per-sample channel zeroing on (B,C,Z,Y,X) tensors
- sample_tau: exponential decay weighted sampling for temporal offsets
* feat(23-01): implement NTXentHCL with hard-negative concentration
- NTXentHCL subclasses NTXentLoss from pytorch_metric_learning
- beta=0.0 delegates to parent for exact numerical equivalence
- beta>0 applies exp(beta*sim) reweighting on negatives in denominator
- Normalized weights preserve loss magnitude across beta values
- All 11 tests pass (1 CUDA test skipped on macOS)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor(23-02): add ChannelDropout and sample_tau to package exports
- Export ChannelDropout from viscy_data top-level
- Export sample_tau from dynaclr top-level
- Include NTXentHCL export added by linter
* docs(23-02): complete ChannelDropout and tau sampling plan
- Summary with TDD metrics, decisions, self-check
- STATE.md updated for Phase 23 completion
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs(23-01): complete NTXentHCL loss plan
- Created 23-01-SUMMARY.md with TDD execution results
- Updated STATE.md with HCL implementation decisions
- Self-check passed: all artifacts and commits verified
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs(phase-23): complete loss & augmentation phase execution
Phase 23 verified: NTXentHCL (3/3 LOSS reqs), ChannelDropout (AUG-01),
sample_tau (AUG-03). AUG-02 wiring deferred to Phase 24 by design.
30 tests pass across loss, channel_dropout, tau_sampling.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs(24): create phase plan
* test(24-01): add failing tests for MultiExperimentTripletDataset
- 7 test cases covering __getitems__ return format, norm_meta, lineage-aware
positive sampling, division event traversal, channel remapping, predict mode,
and dataset length
- All tests fail with ModuleNotFoundError (RED phase)
* feat(24-01): implement MultiExperimentTripletDataset with lineage-aware sampling
- __getitems__ returns batch dicts with anchor/positive Tensors (B,C,Z,Y,X)
- Lineage-aware positive sampling via pre-built (experiment, lineage_id) lookup
- Division events traversed naturally via shared lineage_id
- Per-experiment channel remapping using registry.channel_maps
- Tensorstore I/O with SLURM-aware context and per-FOV caching
- Predict mode returns anchor + TrackingIndex dicts
- Exponential decay tau sampling with fallback to full range scan
* refactor(24-01): add MultiExperimentTripletDataset to package exports
- Export from dynaclr.__init__ for public API access
* docs(24-01): complete MultiExperimentTripletDataset plan
- SUMMARY.md with TDD commits, decisions, self-check
- STATE.md updated: position 24-01, decisions, session continuity
* update uv
* test(24-02): add failing tests for MultiExperimentDataModule
- 6 test cases covering hyperparameter exposure, experiment-level split,
FlexibleBatchSampler wiring, val dataloader, transforms, ChannelDropout
- RED phase: all tests fail with ModuleNotFoundError
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(24-02): implement MultiExperimentDataModule with experiment-level split
- MultiExperimentDataModule composes FlexibleBatchSampler + Dataset +
ChannelDropout + ThreadDataLoader with collate_fn=lambda x: x
- Train/val split by whole experiments via val_experiments parameter
- All sampling, augmentation, and loss hyperparameters exposed as __init__ params
- on_after_batch_transfer applies normalizations + augmentations + final crop
+ ChannelDropout with proper norm_meta handling for all-None case
- 6 TDD tests passing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor(24-02): add MultiExperimentDataModule to dynaclr package exports
- Import MultiExperimentDataModule from dynaclr.datamodule
- Add to __all__ for top-level importability
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs(24-02): complete MultiExperimentDataModule plan
- Summary with TDD commits, decisions, and deviation documentation
- STATE.md updated: Phase 24 complete, 96% progress, ready for Phase 25
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs(phase-24): complete dataset & datamodule phase execution
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs(25): create phase plan
* docs(phase-25): complete integration phase plan
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(25-01): add end-to-end multi-experiment integration tests
- Create test_multi_experiment_fast_dev_run: 2 experiments with different
channel sets (GFP vs RFP), fast_dev_run with NTXentHCL loss
- Create test_multi_experiment_fast_dev_run_with_all_sampling_axes:
experiment_aware + condition_balanced + temporal_enrichment enabled
- Synthetic data helpers for multi-channel HCS OME-Zarr creation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(25-01): add multi-experiment YAML config and class_path validation test
- Create multi_experiment_fit.yml with MultiExperimentDataModule,
NTXentHCL loss, all sampling axes, generic channel names (ch_0/ch_1)
- Add test_multi_experiment_config_class_paths_resolve validating all
class_path entries in the config resolve to importable Python classes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs(25-01): complete integration plan - milestone v2.2 complete
- Add 25-01-SUMMARY.md documenting end-to-end integration validation
- Update STATE.md: phase 25/25 complete, progress 100%, milestone v2.2 done
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs(phase-25): complete integration phase execution — v2.2 milestone shipped
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* add the smoothness and dynamic range comparison
* add the applications/qc
* bug qc metrics exposing the device
* add batch predict
* adding cli for reduce dimensionality composable
* add example configs for model comparision and smoothness
* add the biological annotations to the zattrs
* adding airtable logic
* harmonize and remove duplication between airtable and qc. moving most things to airtable
* cleanup readme for airtable
* add callback to store embeddings every n epochs and store metadata to the anndata.uns
* fix the apply-linear classifiers to make sure we use the model and version.
* Exclude untracked applications/dynacell from uv workspace
Local debris directory (hydra outputs, pycache) has no pyproject.toml
and breaks uv lock when matched by applications/* glob.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(26): capture phase context
* docs(state): record phase 26 context session
* docs(26): create phase plans
* feat(26-01): extract HCSPredictionWriter to viscy-utils callbacks
- Create prediction_writer.py with HCSPredictionWriter, _pad_shape, _resize_image, _blend_in
- Use TYPE_CHECKING guard for viscy_data imports (HCSDataModule, Sample)
- Add numpy-style docstrings to all functions and class
- Re-export HCSPredictionWriter from callbacks __init__.py
- Fix pre-existing INDEX_COLUMNS -> ULTRACK_INDEX_COLUMNS in embedding_snapshot.py and embedding_writer.py
- Add missing docstrings to embedding_snapshot.py public methods
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(26-01): extract MixedLoss to viscy-utils losses submodule
- Create losses/ submodule with mixed_loss.py containing MixedLoss class
- Uses ms_ssim_25d from viscy_utils.evaluation.metrics internally
- Convert docstrings to numpy-style
- Re-export MixedLoss from losses __init__.py
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(26-01): create translation application scaffold with workspace registration
- Create applications/translation/ with src layout following dynaclr pattern
- Add pyproject.toml with hatchling build, uv-dynamic-versioning, and workspace deps
- Add README.md required by hatchling readme field
- Add __main__.py delegating to viscy_utils.cli.main for LightningCLI entry point
- Add example YAML configs (fit.yml, predict.yml) with HCSPredictionWriter callback
- Create empty tests/__init__.py
- Register viscy-translation in root pyproject.toml workspace sources
- Update uv.lock with new workspace member
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(26-01): complete shared infra extraction + app scaffold plan
- Create 26-01-SUMMARY.md with execution results
- Update STATE.md with plan progress, decisions, session info
- Update ROADMAP.md marking 26-01 as complete
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(26-02): migrate translation engine and evaluation modules
- Copy engine.py with VSUNet, FcmaeUNet, AugmentedPredictionVSUNet, MaskedMSELoss
- Copy evaluation.py with SegmentationMetrics2D
- Update all imports to new package paths (viscy_data, viscy_models, viscy_utils)
- Remove MixedLoss class from engine.py (now imported from viscy_utils.losses)
- Update __init__.py with top-level re-exports
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test(26-02): add translation engine test suite
- Import tests for all public exports (VSUNet, FcmaeUNet, etc.)
- VSUNet init and forward pass smoke tests with synthetic data
- State dict key regression test for checkpoint compatibility
- MixedLoss integration test (from viscy_utils.losses)
- FcmaeUNet init test
- No old import paths grep test
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(26-02): complete engine migration plan
- SUMMARY.md with 2 task commits, 2 auto-fixed deviations
- STATE.md updated: phase 26 complete, 20/25 phases (80%)
- ROADMAP.md updated with plan progress
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test(26): complete UAT - 8 passed, 0 issues
* add the pseudotime evals
* re-structure pseudotime folder
* add the linear classifier evals and restructure folder path
* add evaluations to dynaclr package
* cli and linear classifier init
* fix(translation): address engine and evaluation bugs
- Fix operator precedence bug in evaluation.py boolean condition
- Fix source variable overwritten in AugmentedPredictionVSUNet loop
- Fix unbound return_target in FcmaeUNet.forward_fit_task
- Add weights_only=True to torch.load for security
- Fix mutable default argument model_config: dict = {}
- Simplify redundant Union[nn.Module, MixedLoss] to nn.Module
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(translation): correct example config keys and dependencies
- Fix monitor key loss/val -> loss/validate in fit.yml
- Fix output_path -> output_store param name in predict.yml
- Add lightning>=2.3 as direct dependency
- Remove unused torchvision, pin torchmetrics>=1
- Remove unused SYNTH_OUT_C from conftest
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(viscy-utils): fix prediction_writer indexing and embedding_writer overwrite flag
- Fix numpy indexing in prediction_writer _blend_in broadcast shape
- Fix tuple[int] -> tuple[int, ...] type annotation in _create_image
- Respect overwrite flag in EmbeddingWriter.on_predict_start
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(viscy-utils): correct annotation.py docstring examples
- Fix function name in example: convert_xarray_annotation_to_anndata -> convert
- Fix obsm keys in example: X_PCA/X_UMAP/X_PHATE -> X_pca/X_umap/X_phate
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(viscy-models): prevent Sequence mutation and ZeroDivisionError
- Avoid mutating Sequence input in UNeXt2Decoder.forward
- Add input validation in UNeXt2Stem to prevent ZeroDivisionError
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: address PR review blockers (airtable security, tests, qc cleanup)
- Remove api_key/base_id params from AirtableDatasets.__init__; read
credentials exclusively from env vars with clear ValueError on missing
- Add 59 tests for airtable_utils (database + schemas) with full mocking
- Wrap open_ome_zarr in context manager in qc/annotation.py to prevent
file handle leaks on exceptions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix tests
* add track timing backup, save the aucroc as metric for linear classifier, and fix the overwritting by the linear classifiers.
* fix(viscy-utils): validate every_n_epochs >= 1 in EmbeddingSnapshotCallback
Prevent ZeroDivisionError in _should_collect when every_n_epochs=0.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* consolidate appending column to anndata functionality from reduce dimension and linear classifier
* add DINOv3 to viscy-data
* refactor dynaclr app folder structure
* move losses to viscy-models
* data folder
* porting #360
* rname dino to foundation and support openphenom
* move shells cripts to the configs folder
* fix the import for opephenom
* generalize the qc class
* fix(viscy-data): skip None norm_meta in SlidingWindowDataset collation
Pre-existing bug: when a zarr has no normalization metadata,
sample["norm_meta"] = None was added to the batch dict, causing
default_collate to crash on NoneType. Only add norm_meta when
it is not None.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test(translation): add inference reproducibility test for vscyto3d
Validates refactored FcmaeUNet matches old monolithic code predictions.
Reference generated from main branch on a 512x512 crop of the mehta-lab
VSCyto3D test dataset with fov_statistics normalization.
- test_checkpoint_loads: 0 missing/unexpected state dict keys
- test_predict_and_match_reference: full pipeline (HCSDataModule +
HCSPredictionWriter + VisCyTrainer), Pearson r > 0.999, atol=0.02
HPC-gated: skips when checkpoint/data/reference paths unavailable.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(translation): use self.log_dict instead of self.logger.log_metrics
self.logger.log_metrics() crashes when no logger is attached and
bypasses Lightning's built-in aggregation/sync. Use self.log_dict()
which handles missing loggers and DDP sync correctly.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(dynaclr): avoid CPU pos_weight device mismatch in ClassificationModule
pos_weight=torch.tensor(1.0) as a default argument is created on CPU
at class definition time. When the module is moved to GPU,
BCEWithLogitsLoss errors due to device mismatch. Move the default
into __init__ body so the tensor is created at instantiation time.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(dynaclr): fix typo in create_pseudo_tracks docstring
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* add tqdm as default instead of Rich. Rich doesnt show up on the stdout of slurm jobs until it's done.
* de parallelize and default cosine distance for msd and knn for PHATE.
* make a cli for anndata
* add append to obs cli
* adding a cell index that standardizes and spits out parqet
* add example cell index
* update multiexperiment datamodule
* recipes
* add parquet integration test for multi-experiment training
Adds test_multi_experiment_fast_dev_run_with_parquet which verifies the
full Lightning training loop works when loading from a pre-built cell
index parquet via MultiExperimentDataModule.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* demo slurm code
* obs should use fov_name and track_id and id as UUID
* add marker, task and channels to compute the crossval.
* fix prediction remodeling analysis
* test(translation): add training integration tests for VSUNet and FcmaeUNet
Add 6 fast_dev_run tests validating the forward+backward pass:
- VSUNet with MSELoss and MixedLoss (synthetic data)
- FcmaeUNet pretraining (MaskedMSELoss) and fine-tuning (synthetic data)
- VSUNet and FcmaeUNet with real HCSDataModule/CachedOmeZarrDataModule
Also remove architecture-specific language from package description.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test(translation): add config class_path resolution tests
Validate that all class_path entries in fit.yml and predict.yml resolve
to importable classes, matching the DynaCLR test pattern.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Raw logits are now passed through sigmoid before computing binary_accuracy and
binary_f1_score
* fix the dataset statistics
* add contributing and uv to claude.md
* pydantic >2.0
* - Add `schemas.py` with shared Pydantic data models (FOVRecord, etc.)
- Add `collection.py` for ML training collection definitions
- Rename `hours_post_infection` → `hours_post_perturbation` in `_typing.py`
- Update `cell_index.py` to use `collection_path` and renamed field
- Add corresponding tests for new modules and updated cell index
* uvx precommit
* refactor(viscy-data): replace condition_balanced with stratify_by in sampler
* add norm_meta batching helpers and triplet None guard
* - Apply _radians_to_degrees to shear_range (Kornia expects degrees, calls deg2rad internally)
- Fix docstrings to reflect ZYX input order, facet naming, and unit conventions
- Remove stale timepoint_statistics lookup in _normalize.py
* extend DatasetRecord from FOVRecord in viscy-data schemas; add viscy-data dep
* - ExperimentRegistry backed by Collection for per-experiment channel/norm maps
- MultiExperimentIndex with parallel FOV loading and lineage-aware anchors
- MultiExperimentDataModule with stratify_by, num_workers_index, FOV-level split
- Dataset updates for new pipeline; remove ExperimentConfig from __init__
- Consolidate shared test helpers and constants into conftest.py
* pass batch_size to Lightning metric logging for correct step counts
* update recipes and add sampling-strategies guide; add CLAUDE.md
- Update build-cell-index, train-multi-experiment, troubleshooting recipes
- Add sampling-strategies.md documenting FlexibleBatchSampler axes
- Update README table
- Add CLAUDE.md with data pipeline design principles
* update pseudotime and linear classifier scripts for renamed fields
* add configs
* physical nomrlaiztion and fix to mlp projetion layer for adapter.
* code review fixes: remove _components/, assert→ValueError, docstrings, logging
- Remove duplicate viscy_models/_components/ (all imports already use components/)
- Replace assert with raise ValueError in conv_block_2d/3d.py
- Fix numpy docstrings in viscy_data/_utils.py (_ensure_channel_list, _collate_samples)
- Narrow broad except Exception to (OSError, ValueError) in hcs.py
- Use direct row["parent_track_id"] access in cell_index.py (column guarded above)
- Fix frame interval mode().iloc[0] IndexError risk in pseudotime/metrics.py
- Remove backwards-compat re-exports from qc/config.py
- Add logging + warn on silent AUROC ValueError in linear_classifier.py
- Add exc_info=True to PHATE/PCA warning in embedding_writer.py
- Remove resolved TODO in feature.py
- Add _logger and replace print() with logging in dynaclr/utils.py and qc/qc_metrics.py
- Warn when logger_base path does not exist in dynaclr/utils.py
- Move inline imports to top in test_sampler.py
- Add type hints to stems.py compute_stem_channels()
- Remove redundant num_channels reassignment in beta_vae_25d.py
- Fix prek reference in CLAUDE.md (was pre-commit)
- Fix input_channel comment/value: organelle→marker in example config
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* fix tests: remove test_smoke, update config fields, fix parquet dtype
- Remove packages/viscy-data/tests/test_smoke.py: not a real integration
test (magic __all__ count, source string matching, no functional coverage)
- Update TestLinearClassifierTrainConfig: embedding_model+wandb_project
replaced by embedding_model_name+embedding_model_version in schema
- Fix test_parquet_lineage_preserved: add check_index_type=False to handle
object vs StringDtype difference between legacy and parquet paths
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* rename organelle→marker channel type; fix ArrowString/schema test failures
- Rename "organelle" → "marker" in VALID_CHANNELS, pseudotime plotting,
and test fixtures to match the unified channel type naming
- Fix tests: set pd.options.future.infer_string=False in conftest to prevent
pandas 2.x ArrowStringArray from breaking anndata zarr writer
- Fix test_loss: torch.Generator(device=device) for CUDA compatibility
- Update TestLinearClassifierInferenceConfigOrganelle to new schema
(embedding_model_name/version + models list)
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* add experiment configs and SLURM scripts
- Update example_cell_index.yaml with real dataset paths and rename
hours_post_infection → hours_post_perturbation
- Add collection YAMLs: A549_ZIKV_multiorganelle, A549_bag_of_channels, example
- Add training fit configs for A549_ZIKV_multiorganelle and A549_bag_of_channels
- Add smoothness evaluation SLURM scripts
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* add linear classifier and pseudotime analysis scripts
- generate_classifier_inference.py: generate inference configs + SLURM
script for a model predictions folder
- generate_train_config_from_folder.py: generate training configs from
prediction folders, supports multi-dataset combine
- label_offset_sweep.py: sweep temporal label offsets for infection
classifier to find optimal onset labeling
- infection_death_remodeling.py: correlate infection, death, and
organelle remodeling event timings across tracks
- infection_onset_distribution.py: compute and plot infection onset
distributions from classifier predictions
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* fix test_inference_reproducibility: remove stale reference zarr dependency
Replace comparison against a pre-computed reference zarr (39170 cells,
now stale) with a self-contained determinism test: run inference twice
with the same seed and assert the outputs match within GPU tolerance.
This removes the brittle hardcoded cell count and the reference zarr
that needs to be regenerated whenever the data or pipeline changes.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* feat(translation): add sliding window volume prediction (PR #280 port)
Port PR #280 ("Predict volume") functionality to the modular architecture.
- Enhance _blend_in in prediction_writer.py to support both torch.Tensor
(5D: B,C,Z,Y,X) and np.ndarray (4D: C,Z,Y,X) with unified blending
- Add predict_sliding_windows() to AugmentedPredictionVSUNet for
in-memory Z-sliding inference with linear feathering blending
- Extract _predict_with_tta() helper from predict_step()
- Make forward_transforms/inverse_transforms optional (default identity)
- Add getattr guard for out_stack_depth (clear error for 2D models)
- Add 7 tests: blend_in consistency/edge cases, sliding window shape,
invalid input, missing attribute, optional transforms
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* fix examples and configs: rename organelle→marker channel type, add overwrite=True to EmbeddingWriter
- quickstart.py/ipynb: add overwrite=True to EmbeddingWriter to prevent
FileExistsError on notebook re-run
- cross_validate_example.yaml: channels [phase, sensor, organelle] → [phase, sensor, marker]
- example_linear_classifier_inference.yaml: update W&B artifact names
organelle_state-organelle-* → organelle_state-marker-*
- example_linear_classifier_train.yaml: update comment and example
embedding paths to use marker instead of organelle
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* fix(viscy-models): port UNeXt2Stem validation guards to components/stems.py
Copy the in_stack_depth and out_channels divisibility checks from
_components/stems.py to components/stems.py before the upcoming merge
deletes _components/. Without these guards, invalid parameters cause
a silent ZeroDivisionError.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* remove ed notes
* missing pyarrow in dynaclr install. dpeend on visc-data triplet optional dependency
* fix troubleshooting.md for MultiExperiment setup
* add wandndb as core dependency
* remove the data.log
* fix(monorepo): declare missing deps, fix test infrastructure for root pytest
Dependency fixes (all were missing from pyproject.toml):
- viscy-utils: add wandb, anndata, tensorboard as core deps; remove
redundant optional-dependencies.anndata group
- viscy-data: promote pandas and pyarrow from optional/test to core deps
- viscy-models: add pytorch-metric-learning as core dep
- dynaclr: add statsmodels to eval and test dep groups
Test infrastructure:
- Extract shared test helpers/constants from conftest.py into
helpers.py so tests can import them under --import-mode=importlib
(from conftest import broke when running pytest from repo root)
- Remove pythonpath=["tests"] from dynaclr pyproject.toml (was a
workaround for running from the app dir; root config now handles it)
- Add pythonpath=["applications/dynaclr/tests"] to root pytest config
- Move pd.options.future.infer_string=False into pytest_configure hook
so imports stay at top level (fixes ruff E402)
Bug fixes:
- hcs.py: scope propagate=False to viscy_data.hcs.cache logger instead
of viscy_data parent, which was breaking caplog in downstream tests
- Remove test_small_group_emits_warning: tested log wording not behavior
- Remove test_nan_gene_name_to_ntc: tested pandas fillna not module code
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* docs(dynaclr): add tracking note for anndata ArrowString zarr bug
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* chore: remove tests/__init__.py files (importlib mode doesn't need them)
--import-mode=importlib does not use package-style imports for test
files, so __init__.py in test directories is unnecessary and can cause
import collisions.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* fix(dynaclr): resource leak, None propagation, CSV ambiguity
- Wrap open_ome_zarr() in context managers in index.py and cell_index.py
- Raise RuntimeError in _sample_positives() when no positive found instead of silent self-positive fallback
- Raise FileNotFoundError when tracking CSV is missing (fail fast before training)
- Raise ValueError when multiple CSVs exist in a tracks dir
- Update test_empty_tracks_empty_anchors → test_missing_tracking_csv_raises
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* chore(dynaclr): minor cleanup in inspect_dataloader and test formatting
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* add package and applications folder rules for CLAUDE.md
* context managers rule
* remove __version.py
* delete gsd markdowns
* chore: remove stale applications/dynacell directory
Remove old Hydra output logs and cache files from the defunct dynacell
application. This directory was already excluded from the uv workspace.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Eduardo Hirata-Miyasaki <edhiratam@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Alexandr Kalinin <alxndrkalinin@users.noreply.github.com>
Closes #279
TODO: