Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
c07f9c9
Exempt examples/ from docstring and line-length lint rules
edyoshikun Apr 24, 2026
89a0b82
Port VS_model_inference demos from main into applications/cytoland
edyoshikun Apr 24, 2026
0a9aab3
Port dlmbl_exercise tutorial from main into applications/cytoland
edyoshikun Apr 24, 2026
7bf9a4b
Extend examples/ lint exemption to cover E402 and F821
edyoshikun Apr 24, 2026
08f5979
Port vcp_tutorials from main into applications/cytoland
edyoshikun Apr 24, 2026
2dbbac5
Document ported examples in cytoland README
edyoshikun Apr 24, 2026
c8542e1
Port phase_contrast tutorial from main into applications/cytoland
edyoshikun Apr 24, 2026
e3b27aa
Teach PyTorch Lightning in the dlmbl exercise
edyoshikun Apr 24, 2026
c5cfe6a
Sharpen dlmbl exercise teaching material
edyoshikun Apr 24, 2026
6b156d3
Apply 2025 DL@MBL feedback to dlmbl exercise
edyoshikun Apr 24, 2026
63d96a1
Migrate dlmbl setup from conda to uv
edyoshikun Apr 24, 2026
8bd4ea9
Replace SSIM with microSSIM in dlmbl exercise
edyoshikun Apr 24, 2026
34af4f1
Point dlmbl exercise to zarrv3 datasets
edyoshikun May 1, 2026
4453627
Rename dlmbl_exercise to dl-course-exercise
edyoshikun May 1, 2026
f5ce816
Split dl-course-exercise setup into TA and student scripts
edyoshikun May 1, 2026
2eae363
Bump dl-course-exercise to Python 3.13 and viscy>=0.5.0a0
edyoshikun May 1, 2026
15b6f16
Polish dl-course-exercise solution.py
edyoshikun May 1, 2026
7dbdaa6
Polish prose in dl-course-exercise solution.py
edyoshikun May 1, 2026
ae01b60
Port Task 2.5 (fluorescence -> phase) from DL@Janelia exercise
edyoshikun May 1, 2026
1f92f92
Potential fix for pull request finding
edyoshikun May 18, 2026
5fc1d7c
Potential fix for pull request finding
edyoshikun May 18, 2026
52b969e
Potential fix for pull request finding
edyoshikun May 18, 2026
bc71142
Potential fix for pull request finding
edyoshikun May 18, 2026
26be25e
Potential fix for pull request finding
edyoshikun May 18, 2026
7bbe987
Potential fix for pull request finding
edyoshikun May 18, 2026
dc5a855
Potential fix for pull request finding
edyoshikun May 18, 2026
3f772ec
Potential fix for pull request finding
edyoshikun May 18, 2026
c5d0eb9
Potential fix for pull request finding
edyoshikun May 18, 2026
22d9549
Potential fix for pull request finding
edyoshikun May 18, 2026
7df7457
Potential fix for pull request finding
edyoshikun May 18, 2026
891cd4e
Potential fix for pull request finding
edyoshikun May 18, 2026
1ffb236
Potential fix for pull request finding
edyoshikun May 18, 2026
acae30b
Potential fix for pull request finding
edyoshikun May 18, 2026
a738d94
Potential fix for pull request finding
edyoshikun May 18, 2026
1ca6fa1
Potential fix for pull request finding
edyoshikun May 18, 2026
968c720
Potential fix for pull request finding
edyoshikun May 18, 2026
5dd202f
Potential fix for pull request finding
edyoshikun May 18, 2026
83dfa24
Potential fix for pull request finding
edyoshikun May 18, 2026
0a0933d
Potential fix for pull request finding
edyoshikun May 18, 2026
f1794d7
Apply suggestions from code review
edyoshikun May 18, 2026
3a12a95
Apply suggestions from code review
edyoshikun May 18, 2026
830170a
demos: remove invalid `architecture` kwarg from HCSDataModule calls
edyoshikun May 18, 2026
84662fe
demo_vscyto_w_ttas: apply precomputed FOV stats normalization
edyoshikun May 18, 2026
7c10bdf
phase_contrast setup: resolve cytoland path from script location
edyoshikun May 18, 2026
119c301
phase_contrast solution: drop unused trainer, make GPU placement expl…
edyoshikun May 18, 2026
8e089b0
dl-course solution: fix DATA_ROOT semantics, TTA ordering, GPU loads
edyoshikun May 18, 2026
0698483
dl-course README: recommend solution.ipynb path first, warn about tas…
edyoshikun May 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions applications/cytoland/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,22 @@ data:
class_path: viscy_data.hcs.HCSDataModule
```

## Tutorials and demos

Scripts and tutorials live under [`examples/`](./examples/):

| Folder | What it demonstrates |
|--------|----------------------|
| [`examples/VS_model_inference/`](./examples/VS_model_inference/) | Python API inference demos for VSCyto2D, VSCyto3D, VSNeuromast, and TTA-augmented sliding-window prediction |
| [`examples/vcp_tutorials/`](./examples/vcp_tutorials/) | Virtual Cell Platform quick-start and organism-specific walkthroughs (HEK293T, neuromast) |
| [`examples/dl-course-exercise/`](./examples/dl-course-exercise/) | Image-translation course exercise (training from scratch + evaluation) — used at DL@MBL and DL@Janelia |
Comment thread
edyoshikun marked this conversation as resolved.
Resolved
| [`examples/phase_contrast/`](./examples/phase_contrast/) | Phase-contrast tutorial and demo workflows |
| [`examples/configs/`](./examples/configs/) | YAML configs for `viscy fit` / `viscy predict` across models (VSCyto2D/3D, VSNeuromast, FNet3D, dynacell) |

All demo scripts are written as jupytext-style percent-cell `.py` files.
Regenerate paired `.ipynb` notebooks with `jupytext --to ipynb solution.py`
if you prefer the notebook UI.
Comment thread
edyoshikun marked this conversation as resolved.
Resolved

## Models

| Model | Input | Output | Architecture |
Expand Down
146 changes: 146 additions & 0 deletions applications/cytoland/examples/VS_model_inference/demo_vscyto2d.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# %% [markdown]
"""
# 2D Virtual Staining of A549 Cells
---
## Prediction using the VSCyto2D to predict nuclei and plasma membrane from phase.
This example shows how to virtually stain A549 cells using the _VSCyto2D_ model.
The model is trained to predict the membrane and nuclei channels from the phase channel.
"""

# %% Imports and paths
from pathlib import Path

from iohub import open_ome_zarr
from plot import plot_vs_n_fluor

# Cytoland and VisCy modular classes for the trainer and model
from cytoland.engine import FcmaeUNet
from viscy_data.hcs import HCSDataModule
from viscy_transforms import NormalizeSampled
from viscy_utils.callbacks import HCSPredictionWriter
from viscy_utils.trainer import VisCyTrainer

# %% [markdown] tags=[]
#
# <div class="alert alert-block alert-info">
#
# # Download the dataset and checkpoints for the VSCyto2D model
#
# - Download the VSCyto2D test dataset and model checkpoint from here: <br>
# https://public.czbiohub.org/comp.micro/viscy
# - Update the `input_data_path` and `model_ckpt_path` variables with the path to the downloaded files.
# - Select a FOV (i.e 0/0/0).
# - Set an output path for the predictions.
#
# </div>

# %%
# TODO: Set download paths
root_dir = Path("")
# TODO: modify the path to the downloaded dataset
input_data_path = root_dir / "VSCyto2D/test/a549_hoechst_cellmask_test.zarr"
# TODO: modify the path to the downloaded checkpoint
model_ckpt_path = "/epoch=399-step=23200.ckpt"
# TODO: modify the path
# Zarr store to save the predictions
output_path = root_dir / "./a549_prediction.zarr"
# TODO: Choose an FOV
fov = "0/0/0"

input_data_path = input_data_path / fov

# %%
# Create the VSCyto2D network

# Reduce the batch size if encountering out-of-memory errors
BATCH_SIZE = 8
# NOTE: Set the number of workers to 0 for Windows and macOS
# since multiprocessing only works with a
# `if __name__ == '__main__':` guard.
# On Linux, set it to the number of CPU cores to maximize performance.
NUM_WORKERS = 0
phase_channel_name = "Phase3D"

# %%[markdown]
"""
For this example we will use the following parameters:
For more information on the VSCyto2D model,
see ``viscy.unet.networks.fcmae``
([source code](https://github.com/mehta-lab/VisCy/blob/main/viscy/unet/networks/fcmae.py))
for configuration details.
"""
# %%
# Setup the data module.
data_module = HCSDataModule(
data_path=input_data_path,
source_channel=phase_channel_name,
target_channel=["Nuclei", "Membrane"],
z_window_size=1,
split_ratio=0.8,
batch_size=BATCH_SIZE,
num_workers=NUM_WORKERS,
normalizations=[
NormalizeSampled(
[phase_channel_name],
level="fov_statistics",
subtrahend="median",
divisor="iqr",
)
],
)
data_module.prepare_data()
data_module.setup(stage="predict")
# %%
# Setup the model.
# Dictionary that specifies key parameters of the model.
config_VSCyto2D = {
"in_channels": 1,
"out_channels": 2,
"encoder_blocks": [3, 3, 9, 3],
"dims": [96, 192, 384, 768],
"decoder_conv_blocks": 2,
"stem_kernel_size": [1, 2, 2],
"in_stack_depth": 1,
"pretraining": False,
}

model_VSCyto2D = FcmaeUNet.load_from_checkpoint(model_ckpt_path, model_config=config_VSCyto2D)
model_VSCyto2D.eval()

# %%
# Setup the Trainer
trainer = VisCyTrainer(
accelerator="gpu",
callbacks=[HCSPredictionWriter(output_path)],
)

# Start the predictions
trainer.predict(
model=model_VSCyto2D,
datamodule=data_module,
return_predictions=False,
)

# %%
# Open the output_zarr store and inspect the output
# Show the individual channels and the fused in a 1x3 plot
output_path = Path(output_path) / fov

# %%
# Open the predicted data
vs_store = open_ome_zarr(output_path, mode="r")
# Get the 2D images
vs_nucleus = vs_store[0][0, 0, 0] # (t,c,z,y,x)
vs_membrane = vs_store[0][0, 1, 0] # (t,c,z,y,x)
# Open the experimental fluorescence
fluor_store = open_ome_zarr(input_data_path, mode="r")
# Get the 2D images
# NOTE: Channel indices hardcoded for this dataset
fluor_nucleus = fluor_store[0][0, 1, 0] # (t,c,z,y,x)
fluor_membrane = fluor_store[0][0, 2, 0] # (t,c,z,y,x)

# Plot
plot_vs_n_fluor(vs_nucleus, vs_membrane, fluor_nucleus, fluor_membrane)

vs_store.close()
fluor_store.close()
158 changes: 158 additions & 0 deletions applications/cytoland/examples/VS_model_inference/demo_vscyto3d.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
# %% [markdown]
"""
# 3D Virtual Staining of HEK293T Cells
---
## Prediction using the VSCyto3D to predict nuclei and membrane from phase.
This example shows how to virtually stain HEK293T cells using the _VSCyto3D_ model.
The model is trained to predict the membrane and nuclei channels from the phase channel.
"""

# %% Imports and paths
from pathlib import Path

from iohub import open_ome_zarr
from plot import plot_vs_n_fluor

# Cytoland and VisCy modular classes for the trainer and model
from cytoland.engine import VSUNet
from viscy_data.hcs import HCSDataModule
from viscy_transforms import NormalizeSampled
from viscy_utils.callbacks import HCSPredictionWriter
from viscy_utils.trainer import VisCyTrainer

# %% [markdown]
"""
## Data and Model Paths

The dataset and model checkpoint files need to be downloaded before running this example.
"""

# %% [markdown] tags=[]
#
# <div class="alert alert-block alert-info">
#
# # Download the dataset and checkpoints VSCyto3D
#
# - Download the VSCyto3D test dataset and model checkpoint from here: <br>
# https://public.czbiohub.org/comp.micro/viscy
# - Update the `input_data_path` and `model_ckpt_path` variables with the path to the downloaded files.
# - Select a FOV (i.e plate/0/0).
# - Set an output path for the predictions.
#
# </div>
# %%
# TODO: modify the path to the downloaded dataset
input_data_path = "/no_pertubation_Phase1e-3_Denconv_Nuc8e-4_Mem8e-4_pad15_bg50.zarr"

# TODO: modify the path to the downloaded checkpoint
model_ckpt_path = "/epoch=48-step=18130.ckpt"

# TODO: modify the path
# Zarr store to save the predictions
output_path = "./hek_prediction_3d.zarr"

# TODO: Choose an FOV
# FOV of interest
fov = "plate/0/0"

input_data_path = Path(input_data_path) / fov

# %%
# Create the VSCyto3D model

# Reduce the batch size if encountering out-of-memory errors
BATCH_SIZE = 2
# NOTE: Set the number of workers to 0 for Windows and macOS
# since multiprocessing only works with a
# `if __name__ == '__main__':` guard.
# On Linux, set it to the number of CPU cores to maximize performance.
NUM_WORKERS = 0
phase_channel_name = "Phase3D"

# %%[markdown]
"""
For this example we will use the following parameters:
### For more information on the VSCyto3D model:
See ``viscy.unet.networks.unext2``
([source code](https://github.com/mehta-lab/VisCy/blob/main/viscy/unet/networks/unext2.py))
for configuration details.
"""
# %%
# Setup the data module.
data_module = HCSDataModule(
data_path=input_data_path,
source_channel=phase_channel_name,
target_channel=["Nuclei", "Membrane"],
z_window_size=5,
split_ratio=0.8,
batch_size=BATCH_SIZE,
num_workers=NUM_WORKERS,
normalizations=[
NormalizeSampled(
[phase_channel_name],
level="fov_statistics",
subtrahend="median",
divisor="iqr",
)
],
)
data_module.prepare_data()
data_module.setup(stage="predict")
# %%
# Setup the model.
# Dictionary that specifies key parameters of the model.
config_VSCyto3D = {
"in_channels": 1,
"out_channels": 2,
"in_stack_depth": 5,
"backbone": "convnextv2_tiny",
"stem_kernel_size": (5, 4, 4),
"decoder_mode": "pixelshuffle",
"head_expansion_ratio": 4,
"head_pool": True,
}

model_VSCyto3D = VSUNet.load_from_checkpoint(model_ckpt_path, architecture="UNeXt2", model_config=config_VSCyto3D)
model_VSCyto3D.eval()

# %%
# Setup the Trainer
trainer = VisCyTrainer(
accelerator="gpu",
callbacks=[HCSPredictionWriter(output_path)],
)

# Start the predictions
trainer.predict(
model=model_VSCyto3D,
datamodule=data_module,
return_predictions=False,
)

# %%
# Open the output_zarr store and inspect the output
# Show the individual channels and the fused in a 1x3 plot
output_path = Path(output_path) / fov

# %%
# Open the predicted data
vs_store = open_ome_zarr(output_path, mode="r")
T, C, Z, Y, X = vs_store.data.shape

# Get a z-slice
z_slice = Z // 2 # NOTE: using the middle slice of the stack. Change as needed.
vs_nucleus = vs_store[0][0, 0, z_slice] # (t,c,z,y,x)
vs_membrane = vs_store[0][0, 1, z_slice] # (t,c,z,y,x)
# Open the experimental fluorescence
fluor_store = open_ome_zarr(input_data_path, mode="r")
# Get the 2D images
# NOTE: Channel indices hardcoded for this dataset
fluor_nucleus = fluor_store[0][0, 2, z_slice] # (t,c,z,y,x)
fluor_membrane = fluor_store[0][0, 1, z_slice] # (t,c,z,y,x)

# Plot
plot_vs_n_fluor(vs_nucleus, vs_membrane, fluor_nucleus, fluor_membrane)

# Close stores
vs_store.close()
fluor_store.close()
Loading