Add viscy-phenotyping package for image-based feature extraction#410
Open
Soorya19Pradeep wants to merge 2 commits intodynadtwfrom
Open
Add viscy-phenotyping package for image-based feature extraction#410Soorya19Pradeep wants to merge 2 commits intodynadtwfrom
Soorya19Pradeep wants to merge 2 commits intodynadtwfrom
Conversation
Introduces a new sub-package with CLI commands for computing Spearman correlation features between DynaCLR PCs and computed image features: - compute-features: extracts per-cell morphology and texture features - write-header: initialises shared CSV before SLURM array jobs - list-fovs: enumerates FOVs in an OME-Zarr store - merge-features: concatenates per-FOV CSVs Nuclear label channel is now resolved by name from the tracking zarr (nuclear_label_channel in features.yml) rather than relying on np.squeeze over the label array. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds four CellProfiler measurement groups computed per cell patch: - cp_sizeshape_features: MeasureObjectSizeShape (78 features, mask-only, prefix cp_) - cp_intensity_features: MeasureObjectIntensity (21 features, per channel) - cp_texture_features: MeasureTexture/Haralick (52 features, per channel) - cp_granularity_features: MeasureGranularity (16 features, per channel) Texture images are min-max normalised to [0, 1] before passing to cp_measure to satisfy skimage.img_as_ubyte's float range requirement. Total features per cell per channel increases from ~84 to ~241. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds a new viscy-phenotyping workspace package that computes per-cell, per-timepoint image-derived features (custom + CellProfiler-style via cp-measure) and provides a Click CLI to run feature extraction over OME-Zarr datasets / tracking outputs for downstream correlation with DynaCLR PCs.
Changes:
- Introduces
viscy-phenotypingPython package with feature modules and a single-cell feature orchestrator. - Adds a
viscy-phenotypingCLI with commands to list FOVs, write CSV headers, compute per-FOV/all-FOV features, and merge per-FOV CSV outputs. - Adds unit tests and reference documentation (feature catalog + design notes) for the new package.
Reviewed changes
Copilot reviewed 17 out of 19 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
uv.lock |
Adds the new workspace member and locks new dependencies (cp-measure, centrosome, mahotas, etc.). |
packages/viscy-phenotyping/tests/profiler_test.py |
Tests for individual feature modules plus the compute_cell_features orchestrator. |
packages/viscy-phenotyping/tests/features_test.py |
Tests for extract_nuclear_morphology on 2D/3D label images. |
packages/viscy-phenotyping/src/viscy_phenotyping/profiler.py |
Orchestrates per-cell feature computation across channels and feature groups. |
packages/viscy-phenotyping/src/viscy_phenotyping/io.py |
Implements patch cropping utility used by the CLI pipeline. |
packages/viscy-phenotyping/src/viscy_phenotyping/features.py |
Implements nuclear morphology extraction from label images (2D/3D). |
packages/viscy-phenotyping/src/viscy_phenotyping/features_texture.py |
Implements intensity statistics + GLCM/LBP texture features. |
packages/viscy-phenotyping/src/viscy_phenotyping/features_structure.py |
Implements edge density, connected-components, and skeleton-based structure features. |
packages/viscy-phenotyping/src/viscy_phenotyping/features_shape.py |
Implements nuclear shape/circularity + Fourier shape descriptors. |
packages/viscy-phenotyping/src/viscy_phenotyping/features_radial.py |
Implements radial distribution and concentric ring uniformity features. |
packages/viscy-phenotyping/src/viscy_phenotyping/features_gradient.py |
Implements gradient/sharpness features and nucleus-vs-background contrast. |
packages/viscy-phenotyping/src/viscy_phenotyping/features_density.py |
Implements spot/density + granularity spectrum features. |
packages/viscy-phenotyping/src/viscy_phenotyping/features_cp_measure.py |
Wraps cp-measure feature groups (intensity/size-shape/texture/granularity). |
packages/viscy-phenotyping/src/viscy_phenotyping/cli.py |
Adds Click CLI entrypoints for feature extraction workflows. |
packages/viscy-phenotyping/src/viscy_phenotyping/__init__.py |
Exposes main library entrypoints (compute_cell_features, extract_nuclear_morphology). |
packages/viscy-phenotyping/README.md |
Package README referenced by packaging metadata (currently empty). |
packages/viscy-phenotyping/pyproject.toml |
Defines the new package, dependencies, and CLI entrypoint. |
packages/viscy-phenotyping/FEATURES.md |
Feature reference documentation for outputs and naming conventions. |
packages/viscy-phenotyping/DESIGN.md |
Design notes describing intended workflows (incl. SLURM parallelism pattern). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+61
to
+66
| prev_sum = baseline | ||
| for r in range(1, _N_GRANULARITY_SCALES + 1): | ||
| opened = opening(img_uint8, disk(r)) | ||
| curr_sum = float(opened.sum()) | ||
| out[f"granularity_{r}"] = float((prev_sum - curr_sum) / baseline) | ||
| prev_sum = curr_sum |
| csv_files = list((tracks_path / fov_name).glob("*.csv")) | ||
| if not csv_files: | ||
| _logger.warning("No tracking CSV found for %s — skipping.", fov_name) | ||
| return pd.DataFrame() |
Comment on lines
+26
to
+29
| yh, xh = patch_yx[0] // 2, patch_yx[1] // 2 | ||
| yc = min(max(y, yh), H - yh) | ||
| xc = min(max(x, xh), W - xh) | ||
| return array[..., yc - yh : yc + yh, xc - xh : xc + xh] |
| [project] | ||
| name = "viscy-phenotyping" | ||
| description = "Image-based phenotyping via nuclear morphology for VisCy" | ||
| readme = "README.md" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Introduces a new sub-package with CLI commands for computing Spearman correlation features between DynaCLR PCs and computed image features:
Nuclear label channel is now resolved by name from the tracking zarr (nuclear_label_channel in features.yml) rather than relying on np.squeeze over the label array.