Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions spimquant/config/snakebids.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pybids_inputs:
- sample
- acquisition
- staining
- extension
mri:
filters:
suffix: 'T2w'
Expand Down
43 changes: 41 additions & 2 deletions spimquant/workflow/Snakefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@ from itertools import combinations as _combinations, product as _product
import pandas as _pd
from zarrnii import ZarrNii
from snakemake.utils import format
from snakebids import bids, generate_inputs, get_wildcard_constraints, set_bids_spec
from snakebids import (
BidsComponent,
BidsDataset,
bids,
generate_inputs,
get_wildcard_constraints,
set_bids_spec,
)
import snakebids

# update v15 spec to add template entity
Expand Down Expand Up @@ -58,6 +65,38 @@ inputs = generate_inputs(
)


# The spim component is generated with `extension` as a wildcard so that one
# path template covers datasets mixing image formats (e.g. .ims files alongside
# .ome.zarr stores). Rules resolve each scan's concrete image path through
# spim_input(); the component exposed to the rest of the workflow has the
# extension stripped so it cannot leak into derived output templates.
spim_raw = inputs["spim"]

_spim_key_wildcards = [w for w in spim_raw.zip_lists if w != "extension"]
_spim_path_lookup = {
tuple(spim_raw.zip_lists[w][i] for w in _spim_key_wildcards): path
for i, path in enumerate(spim_raw.expand())
}


def spim_input(wildcards):
"""Concrete raw image path (whatever its extension) for a job's wildcards."""
return _spim_path_lookup[tuple(getattr(wildcards, w) for w in _spim_key_wildcards)]

Comment on lines +75 to +85

inputs = BidsDataset(
{
**inputs,
"spim": BidsComponent(
name=spim_raw.name,
path=spim_raw.path.replace("{extension}", ""),
zip_lists={w: spim_raw.zip_lists[w] for w in _spim_key_wildcards},
),
},
layout=inputs.layout,
)


if "mri" in inputs:
suffixes = inputs["mri"].entities["suffix"]
if len(suffixes) == 1:
Expand All @@ -81,7 +120,7 @@ include: "rules/common.smk"
# prepopulate json sidecar metadata for every spim input
spim_json_overrides = {
str(spim_path): get_spim_json_overrides(spim_path)
for spim_path in inputs["spim"].expand()
for spim_path in spim_raw.expand()
}
zarrnii_cli_kwargs = {}

Expand Down
2 changes: 1 addition & 1 deletion spimquant/workflow/rules/common.smk
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def get_stains_all_subjects(ignore_stains=None):
ignore_set = set(ignore_stains) if ignore_stains else set()

stain_sets = []
for zarr in inputs["spim"].expand():
for zarr in spim_raw.expand():
channels = set(get_spim_channels(zarr))
# Remove ignored stains
channels = channels - ignore_set
Expand Down
2 changes: 1 addition & 1 deletion spimquant/workflow/rules/counts.smk
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
rule counts_per_voxel:
"""Calculate counts per voxel based on points"""
input:
ref_spim=inputs["spim"].path,
ref_spim=spim_input,
regionprops_parquet=bids(
root=root,
datatype="tabular",
Expand Down
2 changes: 1 addition & 1 deletion spimquant/workflow/rules/import.smk
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ rule get_downsampled_nii:
based on configuration.
"""
input:
spim=inputs["spim"].path,
spim=spim_input,
params:
zarrnii_kwargs=zarrnii_in_kwargs,
output:
Expand Down
4 changes: 2 additions & 2 deletions spimquant/workflow/rules/patches.smk
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ rule create_spim_patches:
but level in the dseg input is the (downsampled) registration_level.
"""
input:
spim=inputs["spim"].path,
spim=spim_input,
dseg=bids(
root=root,
datatype="parc",
Expand Down Expand Up @@ -192,7 +192,7 @@ rule create_imaris_crops:
to_imaris() function. Level defaults to 0 for high-resolution output.
"""
input:
spim=inputs["spim"].path,
spim=spim_input,
dseg=bids(
root=root,
datatype="parc",
Expand Down
4 changes: 2 additions & 2 deletions spimquant/workflow/rules/plaques.smk
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ rule run_lantern_plaques:
changed downstream without re-running inference.
"""
input:
spim=inputs["spim"].path,
spim=spim_input,
models=expand(
"resources/models/lantern-ki3-abeta/fold{fold}/seg_model.pt",
fold=range(config["plaque_n_folds"]),
Expand Down Expand Up @@ -108,7 +108,7 @@ rule binarize_lantern_plaques:
suffix="probseg.{ext}",
**inputs["spim"].wildcards,
),
spim=inputs["spim"].path,
spim=spim_input,
params:
zarrnii_kwargs=zarrnii_in_kwargs,
n_folds=config["plaque_n_folds"],
Expand Down
14 changes: 7 additions & 7 deletions spimquant/workflow/rules/qc.smk
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ cumulative distribution, and a summary-statistics panel including the
saturation/clip fraction (percentage of voxels at the maximum bin).
"""
input:
spim=inputs["spim"].path,
spim=spim_input,
output:
png=bids(
root=root,
Expand Down Expand Up @@ -83,7 +83,7 @@ overlay, and a max-intensity projection column for each orientation.
Aspect ratio is corrected using voxel spacings from ``ZarrNii.get_zooms()``.
"""
input:
spim=inputs["spim"].path,
spim=spim_input,
mask=bids_oz_in(
root=root,
datatype="seg",
Expand Down Expand Up @@ -122,7 +122,7 @@ vessel binary mask. Loads data via ZarrNii with ``downsample_near_isotropic``
for isotropic display and physically correct aspect ratio.
"""
input:
spim=inputs["spim"].path,
spim=spim_input,
mask=bids_oz_in(
root=root,
datatype="vessels",
Expand Down Expand Up @@ -181,7 +181,7 @@ one without (``desc-{desc}nomask_roimontage.png``).
if _use_n4_bg
else {}
),
spim=inputs["spim"].path,
spim=spim_input,
mask=bids_oz_in(
root=root,
datatype="seg",
Expand Down Expand Up @@ -268,7 +268,7 @@ and one without (``desc-{desc}nomask_vesselroimontage.png``).
if _use_n4_bg
else {}
),
spim=inputs["spim"].path,
spim=spim_input,
mask=bids_oz_in(
root=root,
datatype="vessels",
Expand Down Expand Up @@ -660,7 +660,7 @@ Inputs are the aggregated (all-stain) regionprops parquet in template space
parcellation for atlas-label lookup.
"""
input:
spim=inputs["spim"].path,
spim=spim_input,
instance_parquet=bids(
root=root,
datatype="tabular",
Expand Down Expand Up @@ -730,7 +730,7 @@ two colocalized objects (subject-space ``pos_coloc_x/y/z``), with a circle
marker drawn at the average radius of the pair.
"""
input:
spim=inputs["spim"].path,
spim=spim_input,
instance_parquet=bids(
root=root,
datatype="tabular",
Expand Down
4 changes: 2 additions & 2 deletions spimquant/workflow/rules/segmentation.smk
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Outputs include:
rule gaussian_biasfield:
"""simple bias field correction with gaussian"""
input:
spim=inputs["spim"].path,
spim=spim_input,
output:
corrected=temp(
bids_oz_out(
Expand Down Expand Up @@ -204,7 +204,7 @@ rule n4_pre_quant_tune:
rule n4_biasfield:
"""N4 bias field correction with antspyx"""
input:
spim=inputs["spim"].path,
spim=spim_input,
biasfield=bids(
root=root,
datatype="micr",
Expand Down
12 changes: 6 additions & 6 deletions spimquant/workflow/rules/templatereg.smk
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ rule resample_labels_to_zarr:
dseg=bids(root=root, template="{template}", desc="LR", suffix="dseg.nii.gz"),
label_tsv=bids(root=root, template="{template}", desc="LR", suffix="dseg.tsv"),
xfm_ras=rules.affine_reg.output.xfm_ras,
zarr_zip=inputs["spim"].path,
zarr_zip=spim_input,
params:
level_to_resample_to=0,
max_downsampling_layers=config["ome_zarr"]["max_downsampling_layers"],
Expand Down Expand Up @@ -420,7 +420,7 @@ rule resample_labels_to_zarr:

rule affine_zarr_to_template_nii:
input:
ome_zarr=inputs["spim"].path,
ome_zarr=spim_input,
xfm_ras=rules.affine_reg.output.xfm_ras,
ref_nii=get_template_for_reg,
params:
Expand All @@ -445,7 +445,7 @@ rule affine_zarr_to_template_nii:

rule affine_zarr_to_template_ome_zarr:
input:
ome_zarr=inputs["spim"].path,
ome_zarr=spim_input,
xfm_ras=rules.affine_reg.output.xfm_ras,
ref_nii=get_template_for_reg,
params:
Expand Down Expand Up @@ -474,7 +474,7 @@ rule deform_zarr_to_template_nii:
xfm_composite=rules.compose_subject_to_template_warp.output.xfm_composite,
ref_nii=get_template_for_reg,
params:
ome_zarr=inputs["spim"].path,
ome_zarr=spim_input,
flo_opts={"level": 2}, #downsampling level to use (TODO: set this automatically based on ref resolution?)
do_downsample=True, #whether to perform further downsampling before transforming
downsample_opts={"along_z": 4}, #could also be determined automatically
Expand All @@ -499,7 +499,7 @@ rule deform_zarr_to_template_nii:

rule deform_to_template_nii_zoomed:
input:
ome_zarr=inputs["spim"].path,
ome_zarr=spim_input,
xfm_composite=rules.compose_subject_to_template_warp.output.xfm_composite,
ref_nii=get_template_for_reg,
params:
Expand Down Expand Up @@ -612,7 +612,7 @@ rule deform_template_dseg_to_subject_nii:
""" this rule needs updating - use atlas/seg wildcard and proper script
rule deform_transform_labels_to_subj:
input:
ref_ome_zarr=inputs["spim"].path,
ref_ome_zarr=spim_input,
xfm_ras=rules.affine_reg.output.xfm_ras,
invwarp_nii=rules.deform_reg.output.invwarp,
flo_nii=bids(
Expand Down
2 changes: 1 addition & 1 deletion spimquant/workflow/rules/vessels.smk
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ rule import_vesselfm_model:

rule run_vesselfm:
input:
spim=inputs["spim"].path,
spim=spim_input,
model_path="resources/models/vesselfm.pt",
params:
zarrnii_kwargs=zarrnii_in_kwargs,
Expand Down