Skip to content
Merged
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
58 changes: 29 additions & 29 deletions autoafids/config/snakebids.yml
Original file line number Diff line number Diff line change
Expand Up @@ -287,35 +287,35 @@ afids_inference:
afid_01: 'resources/afids_cnn_ckpts/afid-01_epoch-820_mae-0.0002.ckpt'
afid_02: 'resources/afids_cnn_ckpts/afid-02_epoch-964_mae-0.0007.ckpt'
afid_03: 'resources/afids_cnn_ckpts/afid-03_epoch-778_mae-0.0008.ckpt'
afid_04: 'resources/afids_cnn_ckpts/afid-01_epoch-820_mae-0.0002.ckpt' # placeholder
afid_05: 'resources/afids_cnn_ckpts/afid-01_epoch-820_mae-0.0002.ckpt' # placeholder
afid_06: 'resources/afids_cnn_ckpts/afid-01_epoch-820_mae-0.0002.ckpt' # placeholder
afid_07: 'resources/afids_cnn_ckpts/afid-01_epoch-820_mae-0.0002.ckpt' # placeholder
afid_08: 'resources/afids_cnn_ckpts/afid-01_epoch-820_mae-0.0002.ckpt' # placeholder
afid_09: 'resources/afids_cnn_ckpts/afid-01_epoch-820_mae-0.0002.ckpt' # placeholder
afid_10: 'resources/afids_cnn_ckpts/afid-01_epoch-820_mae-0.0002.ckpt' # placeholder
afid_11: 'resources/afids_cnn_ckpts/afid-01_epoch-820_mae-0.0002.ckpt' # placeholder
afid_12: 'resources/afids_cnn_ckpts/afid-01_epoch-820_mae-0.0002.ckpt' # placeholder
afid_13: 'resources/afids_cnn_ckpts/afid-01_epoch-820_mae-0.0002.ckpt' # placeholder
afid_14: 'resources/afids_cnn_ckpts/afid-01_epoch-820_mae-0.0002.ckpt' # placeholder
afid_15: 'resources/afids_cnn_ckpts/afid-01_epoch-820_mae-0.0002.ckpt' # placeholder
afid_16: 'resources/afids_cnn_ckpts/afid-01_epoch-820_mae-0.0002.ckpt' # placeholder
afid_17: 'resources/afids_cnn_ckpts/afid-01_epoch-820_mae-0.0002.ckpt' # placeholder
afid_18: 'resources/afids_cnn_ckpts/afid-01_epoch-820_mae-0.0002.ckpt' # placeholder
afid_19: 'resources/afids_cnn_ckpts/afid-01_epoch-820_mae-0.0002.ckpt' # placeholder
afid_20: 'resources/afids_cnn_ckpts/afid-01_epoch-820_mae-0.0002.ckpt' # placeholder
afid_21: 'resources/afids_cnn_ckpts/afid-01_epoch-820_mae-0.0002.ckpt' # placeholder
afid_22: 'resources/afids_cnn_ckpts/afid-01_epoch-820_mae-0.0002.ckpt' # placeholder
afid_23: 'resources/afids_cnn_ckpts/afid-01_epoch-820_mae-0.0002.ckpt' # placeholder
afid_24: 'resources/afids_cnn_ckpts/afid-01_epoch-820_mae-0.0002.ckpt' # placeholder
afid_25: 'resources/afids_cnn_ckpts/afid-01_epoch-820_mae-0.0002.ckpt' # placeholder
afid_26: 'resources/afids_cnn_ckpts/afid-01_epoch-820_mae-0.0002.ckpt' # placeholder
afid_27: 'resources/afids_cnn_ckpts/afid-01_epoch-820_mae-0.0002.ckpt' # placeholder
afid_28: 'resources/afids_cnn_ckpts/afid-01_epoch-820_mae-0.0002.ckpt' # placeholder
afid_29: 'resources/afids_cnn_ckpts/afid-01_epoch-820_mae-0.0002.ckpt' # placeholder
afid_30: 'resources/afids_cnn_ckpts/afid-01_epoch-820_mae-0.0002.ckpt' # placeholder
afid_31: 'resources/afids_cnn_ckpts/afid-01_epoch-820_mae-0.0002.ckpt' # placeholder
afid_32: 'resources/afids_cnn_ckpts/afid-01_epoch-820_mae-0.0002.ckpt' # placeholder
afid_04: 'resources/afids_cnn_ckpts/afid-04_epoch-529_mae-0.0007.ckpt'
afid_05: 'resources/afids_cnn_ckpts/afid-05_epoch-628_mae-0.0007.ckpt'
afid_06: 'resources/afids_cnn_ckpts/afid-06_epoch-485_mae-0.0009.ckpt'
afid_07: 'resources/afids_cnn_ckpts/afid-07_epoch-599_mae-0.0008.ckpt'
afid_08: 'resources/afids_cnn_ckpts/afid-08_epoch-455_mae-0.0013.ckpt'
afid_09: 'resources/afids_cnn_ckpts/afid-09_epoch-535_mae-0.0010.ckpt'
afid_10: 'resources/afids_cnn_ckpts/afid-10_epoch-431_mae-0.0009.ckpt'
afid_11: 'resources/afids_cnn_ckpts/afid-11_epoch-735_mae-0.0005.ckpt'
afid_12: 'resources/afids_cnn_ckpts/afid-12_epoch-694_mae-0.0007.ckpt'
afid_13: 'resources/afids_cnn_ckpts/afid-13_epoch-763_mae-0.0006.ckpt'
afid_14: 'resources/afids_cnn_ckpts/afid-14_epoch-405_mae-0.0011.ckpt'
afid_15: 'resources/afids_cnn_ckpts/afid-15_epoch-371_mae-0.0013.ckpt'
afid_16: 'resources/afids_cnn_ckpts/afid-16_epoch-454_mae-0.0012.ckpt'
afid_17: 'resources/afids_cnn_ckpts/afid-17_epoch-291_mae-0.0023.ckpt'
afid_18: 'resources/afids_cnn_ckpts/afid-18_epoch-233_mae-0.0016.ckpt'
afid_19: 'resources/afids_cnn_ckpts/afid-19_epoch-626_mae-0.0011.ckpt'
afid_20: 'resources/afids_cnn_ckpts/afid-20_epoch-720_mae-0.0011.ckpt'
afid_21: 'resources/afids_cnn_ckpts/afid-21_epoch-672_mae-0.0009.ckpt'
afid_22: 'resources/afids_cnn_ckpts/afid-22_epoch-647_mae-0.0008.ckpt'
afid_23: 'resources/afids_cnn_ckpts/afid-23_epoch-656_mae-0.0010.ckpt'
afid_24: 'resources/afids_cnn_ckpts/afid-24_epoch-689_mae-0.0007.ckpt'
afid_25: 'resources/afids_cnn_ckpts/afid-25_epoch-513_mae-0.0013.ckpt'
afid_26: 'resources/afids_cnn_ckpts/afid-26_epoch-784_mae-0.0009.ckpt'
afid_27: 'resources/afids_cnn_ckpts/afid-27_epoch-300_mae-0.0014.ckpt'
afid_28: 'resources/afids_cnn_ckpts/afid-28_epoch-351_mae-0.0009.ckpt'
afid_29: 'resources/afids_cnn_ckpts/afid-29_epoch-394_mae-0.0014.ckpt'
afid_30: 'resources/afids_cnn_ckpts/afid-30_epoch-618_mae-0.0012.ckpt'
afid_31: 'resources/afids_cnn_ckpts/afid-31_epoch-573_mae-0.0009.ckpt'
afid_32: 'resources/afids_cnn_ckpts/afid-32_epoch-561_mae-0.0007.ckpt'
patch_size: 64 # cubic patch size in voxels
device: cuda:0 # cpu recommended for parallel mode; cuda:0 for sequential
overlap: 0.5 # sliding-window overlap for --detect_without_prior (0.0–0.75)
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
5 changes: 3 additions & 2 deletions autoafids/workflow/Snakefile
Original file line number Diff line number Diff line change
Expand Up @@ -355,13 +355,16 @@ rule mni2subfids:

# ── Detection mode: choose rules to include ──────────────────────────────
if config.get("detect_mode", "prior") == "nnlm":

# nnLandmark mode: single-pass whole-volume detection
include: "rules/nnlm.smk"

else:
# Legacy CNN modes (prior / noprior)
# If running on GPU, automatically enable sequential inference to avoid spawning 32 parallel jobs
if config.get("afids_inference", {}).get("device") == "cuda:0":
config["enable_sequential_inference"] = True

include: "rules/cnn.smk"


Expand All @@ -377,7 +380,6 @@ if config["LEAD_DBS_DIR"] or config["FMRIPREP_DIR"]:
include: "rules/regqc.smk"



# Select the correct FCSV output descriptor based on inference mode.
# prior → applyfidmodel_gather → desc="afidscnn"
# noprior → applyfidmodel_noprior_gather → desc="afidscnn-noprior"
Expand Down Expand Up @@ -445,4 +447,3 @@ rule all:
else []
),
default_target: True

63 changes: 42 additions & 21 deletions autoafids/workflow/rules/cnn.smk
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# populate the AUTOAFIDS_CACHE_DIR folder as needed


rule download_cnn_model:
params:
url=config["resource_urls"][config["model"]],
Expand All @@ -15,9 +16,11 @@ rule download_cnn_model:
" unzip -q -d {output.unzip_dir} model.zip && "
" rm model.zip"


_AFIDS = [f"{i:02d}" for i in range(1, 33)] # ["01", "02", ..., "32"]

if config.get("enable_sequential_inference", False):

rule applyfidmodel_all:
"""Run 5-patch inference for ALL 32 AFIDs using MNI-registered prior location"""
input:
Expand All @@ -27,7 +30,7 @@ if config.get("enable_sequential_inference", False):
datatype="normalize",
desc=chosen_norm_method,
suffix="T1w.nii.gz",
**inputs[config["modality"]].wildcards
**inputs[config["modality"]].wildcards,
)
if config["modality"] != "T1w"
else bids(
Expand All @@ -36,7 +39,7 @@ if config.get("enable_sequential_inference", False):
desc=chosen_norm_method,
res=config["res"],
suffix="T1w.nii.gz",
**inputs[config["modality"]].wildcards
**inputs[config["modality"]].wildcards,
)
),
prior=bids(
Expand All @@ -55,7 +58,8 @@ if config.get("enable_sequential_inference", False):
afid=afid,
suffix="coord.txt",
**inputs[config["modality"]].wildcards,
) for afid in _AFIDS
)
for afid in _AFIDS
],
probs=[
bids(
Expand All @@ -64,7 +68,8 @@ if config.get("enable_sequential_inference", False):
afid=afid,
suffix="probmap.nii.gz",
**inputs[config["modality"]].wildcards,
) for afid in _AFIDS
)
for afid in _AFIDS
],
fcsv=bids(
root=root,
Expand All @@ -83,14 +88,15 @@ if config.get("enable_sequential_inference", False):
ckpts=lambda wildcards: {
key: str(Path(workflow.basedir).parent / path)
for key, path in config["afids_inference"]["checkpoints"].items()
}
},
threads: 1

conda:
"../envs/pytorch.yaml"
script:
"../scripts/apply_with_prior_all.py"

else:

# ── WITH PRIOR (SINGLE) ──────────────────────────────────────────────────────
rule applyfidmodel_single:
"""Run 5-patch inference for ONE AFID using MNI-registered prior location."""
Expand All @@ -101,7 +107,7 @@ else:
datatype="normalize",
desc=chosen_norm_method,
suffix="T1w.nii.gz",
**inputs[config["modality"]].wildcards
**inputs[config["modality"]].wildcards,
)
if config["modality"] != "T1w"
else bids(
Expand All @@ -110,7 +116,7 @@ else:
desc=chosen_norm_method,
res=config["res"],
suffix="T1w.nii.gz",
**inputs[config["modality"]].wildcards
**inputs[config["modality"]].wildcards,
)
),
prior=bids(
Expand Down Expand Up @@ -148,10 +154,11 @@ else:
params:
ckpt_path=lambda wildcards: str(
Path(workflow.basedir).parent
/ config["afids_inference"]["checkpoints"][f"afid_{int(wildcards.afid):02d}"]
/ config["afids_inference"]["checkpoints"][
f"afid_{int(wildcards.afid):02d}"
]
),
threads: 1

conda:
"../envs/pytorch.yaml"
script:
Expand All @@ -166,7 +173,10 @@ else:
datatype="afids-cnn",
afid="{afid}",
suffix="coord.txt",
**{k: getattr(wildcards, k) for k in inputs[config["modality"]].wildcards},
**{
k: getattr(wildcards, k)
for k in inputs[config["modality"]].wildcards
},
),
afid=_AFIDS,
),
Expand All @@ -190,9 +200,11 @@ else:
script:
"../scripts/gather_afids.py"


# ---------------------------------------------------------------------------

if config.get("enable_sequential_inference", False):

rule applyfidmodel_noprior_all:
"""Whole-volume sliding-window inference for ALL 32 AFIDs (no prior needed)"""
input:
Expand All @@ -202,7 +214,7 @@ if config.get("enable_sequential_inference", False):
datatype="normalize",
desc=chosen_norm_method,
suffix="T1w.nii.gz",
**inputs[config["modality"]].wildcards
**inputs[config["modality"]].wildcards,
)
if config["modality"] != "T1w"
else bids(
Expand All @@ -211,7 +223,7 @@ if config.get("enable_sequential_inference", False):
desc=chosen_norm_method,
res=config["res"],
suffix="T1w.nii.gz",
**inputs[config["modality"]].wildcards
**inputs[config["modality"]].wildcards,
)
),
output:
Expand All @@ -222,7 +234,8 @@ if config.get("enable_sequential_inference", False):
afid=afid,
suffix="coord.txt",
**inputs[config["modality"]].wildcards,
) for afid in _AFIDS
)
for afid in _AFIDS
],
probs=[
bids(
Expand All @@ -231,7 +244,8 @@ if config.get("enable_sequential_inference", False):
afid=afid,
suffix="probmap.nii.gz",
**inputs[config["modality"]].wildcards,
) for afid in _AFIDS
)
for afid in _AFIDS
],
fcsv=bids(
root=root,
Expand All @@ -250,13 +264,15 @@ if config.get("enable_sequential_inference", False):
ckpts=lambda wildcards: {
key: str(Path(workflow.basedir).parent / path)
for key, path in config["afids_inference"]["checkpoints"].items()
}
},
threads: 1
conda:
"../envs/pytorch.yaml"
script:
"../scripts/apply_noprior_all.py"

else:

# ── WITHOUT PRIOR (SINGLE) ──────────────────────────────────────────────────
rule applyfidmodel_noprior_single:
"""Whole-volume sliding-window inference for ONE AFID — no prior needed."""
Expand All @@ -267,7 +283,7 @@ else:
datatype="normalize",
desc=chosen_norm_method,
suffix="T1w.nii.gz",
**inputs[config["modality"]].wildcards
**inputs[config["modality"]].wildcards,
)
if config["modality"] != "T1w"
else bids(
Expand All @@ -276,7 +292,7 @@ else:
desc=chosen_norm_method,
res=config["res"],
suffix="T1w.nii.gz",
**inputs[config["modality"]].wildcards
**inputs[config["modality"]].wildcards,
)
),
output:
Expand Down Expand Up @@ -306,7 +322,9 @@ else:
params:
ckpt_path=lambda wildcards: str(
Path(workflow.basedir).parent
/ config["afids_inference"]["checkpoints"][f"afid_{int(wildcards.afid):02d}"]
/ config["afids_inference"]["checkpoints"][
f"afid_{int(wildcards.afid):02d}"
]
),
threads: 1
conda:
Expand All @@ -323,7 +341,10 @@ else:
datatype="afids-cnn-noprior",
afid="{afid}",
suffix="coord.txt",
**{k: getattr(wildcards, k) for k in inputs[config["modality"]].wildcards},
**{
k: getattr(wildcards, k)
for k in inputs[config["modality"]].wildcards
},
),
afid=_AFIDS,
),
Expand All @@ -345,4 +366,4 @@ else:
conda:
"../envs/pytorch.yaml"
script:
"../scripts/gather_afids.py"
"../scripts/gather_afids.py"
2 changes: 1 addition & 1 deletion autoafids/workflow/rules/nnlm.smk
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ rule nnlm_to_fcsv:
**inputs[config["modality"]].wildcards,
),
params:
fcsv_template=str(Path(workflow.basedir).parent / "resources" / "dummy.fcsv")
fcsv_template=str(Path(workflow.basedir).parent / "resources" / "dummy.fcsv"),
conda:
"../envs/nibabel.yaml"
script:
Expand Down
Loading
Loading