@yibeichan/claude-skills 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +98 -0
- package/cli.js +272 -0
- package/install.py +240 -0
- package/package.json +44 -0
- package/skills/bidsapp-nidm-standards/SKILL.md +202 -0
- package/skills/bidsapp-nidm-standards/references/babs_config.md +20 -0
- package/skills/bidsapp-nidm-standards/references/cli_arguments.md +76 -0
- package/skills/bidsapp-nidm-standards/references/container_patterns.md +53 -0
- package/skills/bidsapp-nidm-standards/references/nidm_integration.md +403 -0
- package/skills/bidsapp-nidm-standards/references/repo_structure.md +121 -0
- package/skills/bidsapp-nidm-standards/references/testing_patterns.md +82 -0
- package/skills/dicom2fmriprep/SKILL.md +377 -0
- package/skills/dicom2fmriprep/evals/evals.json +26 -0
- package/skills/dicom2fmriprep/references/babs-details.md +407 -0
- package/skills/dicom2fmriprep/references/fmriprep-details.md +250 -0
- package/skills/dicom2fmriprep/references/heudiconv-details.md +243 -0
- package/skills/fmri-ssm/SKILL.md +317 -0
- package/skills/fmri-ssm/references/code_templates.md +1570 -0
- package/skills/fmri-ssm/references/downstream_analysis.md +680 -0
- package/skills/fmri-ssm/references/group_inference.md +608 -0
- package/skills/fmri-ssm/references/hrf_modeling.md +447 -0
- package/skills/fmri-ssm/references/model_catalog.md +436 -0
- package/skills/fmri-ssm/references/paradigm_guide.md +406 -0
- package/skills/fmri-ssm/references/preprocessing.md +614 -0
- package/skills/fmri-ssm.zip +0 -0
- package/skills/neuroimaging-qc/SKILL.md +203 -0
- package/skills/neuroimaging-qc/references/eeg_qc.md +400 -0
- package/skills/neuroimaging-qc/references/fmri_qc.md +343 -0
- package/skills/neuroimaging-qc/references/fnirs_qc.md +430 -0
- package/skills/neuroimaging-qc/references/structural_qc.md +454 -0
- package/skills/neuroimaging-qc/scripts/parse_fmriprep_confounds.py +153 -0
- package/skills/neuroimaging-qc/scripts/parse_mriqc.py +114 -0
- package/skills/neuroimaging-qc/scripts/qc_report.py +295 -0
- package/skills/scientific-writer/SKILL.md +202 -0
- package/skills/scientific-writer/references/citation_styles.md +163 -0
- package/skills/scientific-writer/references/field_conventions.md +245 -0
- package/skills/scientific-writer/references/figures_tables.md +225 -0
- package/skills/scientific-writer/references/reporting_guidelines.md +225 -0
- package/skills.json +54 -0
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dicom2fmriprep
|
|
3
|
+
description: Generate scripts for the full fMRI preprocessing pipeline from raw DICOM files through BIDS conversion (heudiconv) to fMRIPrep, including HPC/SLURM execution via BABS. Use this skill whenever someone needs to preprocess fMRI data, convert DICOMs to BIDS, write heudiconv heuristics, run fMRIPrep on a cluster, set up BABS projects, fix BIDS validation errors, or generate any scripts related to the DICOM-to-fMRIPrep pipeline.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# fMRI DICOM-to-fMRIPrep Pipeline
|
|
7
|
+
|
|
8
|
+
This skill helps users generate scripts for the complete fMRI preprocessing pipeline:
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
Raw DICOMs → heudiconv (BIDS conversion) → BIDS validation → fMRIPrep → preprocessed data
|
|
12
|
+
↑
|
|
13
|
+
(optionally via BABS on HPC)
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## When to Use This Skill
|
|
17
|
+
|
|
18
|
+
- Converting unsorted DICOM files to BIDS format
|
|
19
|
+
- Writing heudiconv heuristic files from scratch
|
|
20
|
+
- Fixing BIDS validation errors
|
|
21
|
+
- Running fMRIPrep (locally or on HPC with Singularity)
|
|
22
|
+
- Setting up BABS projects for large-scale fMRIPrep on SLURM clusters
|
|
23
|
+
- Generating SLURM submission scripts for neuroimaging pipelines
|
|
24
|
+
|
|
25
|
+
## Pipeline Overview
|
|
26
|
+
|
|
27
|
+
### Step 1: DICOM to BIDS with heudiconv
|
|
28
|
+
|
|
29
|
+
heudiconv wraps dcm2niix and handles the full conversion from DICOMs to a BIDS-compliant dataset. The process has two passes:
|
|
30
|
+
|
|
31
|
+
**Pass 1 — Reconnaissance** (discover what's in the DICOMs):
|
|
32
|
+
```bash
|
|
33
|
+
heudiconv \
|
|
34
|
+
--files /path/to/dicoms/{subject}/*/*/*.dcm \
|
|
35
|
+
-o /path/to/bids_output \
|
|
36
|
+
-f convertall \
|
|
37
|
+
-s SUBJECT_ID \
|
|
38
|
+
-c none
|
|
39
|
+
```
|
|
40
|
+
This produces `.heudiconv/{subject}/info/dicominfo.tsv` — a table of every DICOM series with metadata (dimensions, TR, protocol name, etc.). The user needs this to write their heuristic.
|
|
41
|
+
|
|
42
|
+
**Pass 2 — Convert** (apply the heuristic):
|
|
43
|
+
```bash
|
|
44
|
+
heudiconv \
|
|
45
|
+
--files /path/to/dicoms/{subject}/*/*/*.dcm \
|
|
46
|
+
-o /path/to/bids_output \
|
|
47
|
+
-f /path/to/heuristic.py \
|
|
48
|
+
-s SUBJECT_ID \
|
|
49
|
+
-ss SESSION_LABEL \
|
|
50
|
+
-c dcm2niix -b --minmeta --overwrite
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
#### Writing a Heuristic File
|
|
54
|
+
|
|
55
|
+
The heuristic maps DICOM series to BIDS filenames. Always ask the user to share their `dicominfo.tsv` first — it tells you exactly what series exist and how to match them.
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
import os
|
|
59
|
+
|
|
60
|
+
def create_key(template, outtype=('nii.gz',), annotation_classes=None):
|
|
61
|
+
if template is None or not template:
|
|
62
|
+
raise ValueError("Template must be a valid format string")
|
|
63
|
+
return (template, outtype, annotation_classes)
|
|
64
|
+
|
|
65
|
+
def infotodict(seqinfo):
|
|
66
|
+
"""Map DICOM series to BIDS filenames based on series metadata."""
|
|
67
|
+
|
|
68
|
+
# Define BIDS keys — adjust paths based on what the dataset contains
|
|
69
|
+
t1w = create_key('sub-{subject}/{session}/anat/sub-{subject}_{session}_T1w')
|
|
70
|
+
func_rest = create_key(
|
|
71
|
+
'sub-{subject}/{session}/func/sub-{subject}_{session}_task-rest_run-{item:02d}_bold'
|
|
72
|
+
)
|
|
73
|
+
func_task = create_key(
|
|
74
|
+
'sub-{subject}/{session}/func/sub-{subject}_{session}_task-TASKNAME_run-{item:02d}_bold'
|
|
75
|
+
)
|
|
76
|
+
fmap_ap = create_key('sub-{subject}/{session}/fmap/sub-{subject}_{session}_dir-AP_epi')
|
|
77
|
+
fmap_pa = create_key('sub-{subject}/{session}/fmap/sub-{subject}_{session}_dir-PA_epi')
|
|
78
|
+
dwi = create_key('sub-{subject}/{session}/dwi/sub-{subject}_{session}_dir-AP_dwi')
|
|
79
|
+
|
|
80
|
+
info = {t1w: [], func_rest: [], func_task: [], fmap_ap: [], fmap_pa: [], dwi: []}
|
|
81
|
+
|
|
82
|
+
for s in seqinfo:
|
|
83
|
+
# Filter out motion-corrected and derived series
|
|
84
|
+
if s.is_motion_corrected or s.is_derived:
|
|
85
|
+
continue
|
|
86
|
+
|
|
87
|
+
# Match by protocol_name, dimensions, TR — adapt to your scanner's naming
|
|
88
|
+
if 'mprage' in s.protocol_name.lower() and s.dim3 >= 160:
|
|
89
|
+
info[t1w].append(s.series_id)
|
|
90
|
+
elif 'rest' in s.protocol_name.lower() and s.dim4 > 50:
|
|
91
|
+
info[func_rest].append(s.series_id)
|
|
92
|
+
elif 'task' in s.protocol_name.lower() and s.dim4 > 50:
|
|
93
|
+
info[func_task].append(s.series_id)
|
|
94
|
+
elif 'distortion' in s.protocol_name.lower() and 'AP' in s.protocol_name:
|
|
95
|
+
info[fmap_ap] = [s.series_id]
|
|
96
|
+
elif 'distortion' in s.protocol_name.lower() and 'PA' in s.protocol_name:
|
|
97
|
+
info[fmap_pa] = [s.series_id]
|
|
98
|
+
elif 'dti' in s.protocol_name.lower() or 'dwi' in s.protocol_name.lower():
|
|
99
|
+
info[dwi].append(s.series_id)
|
|
100
|
+
|
|
101
|
+
return info
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Key matching fields from `seqinfo`**: `protocol_name`, `series_description`, `sequence_name`, `dim1`-`dim4`, `TR`, `TE`, `image_type`, `is_motion_corrected`, `is_derived`.
|
|
105
|
+
|
|
106
|
+
**Important heuristic rules:**
|
|
107
|
+
- Use `.append()` for series that may have multiple runs (BOLD, DWI)
|
|
108
|
+
- Use `= [s.series_id]` for single-occurrence series (T1w, fieldmaps)
|
|
109
|
+
- Always filter `is_motion_corrected` and `is_derived` for functional data
|
|
110
|
+
- Use `.lower()` on protocol names — scanner naming is inconsistent
|
|
111
|
+
- For single-session studies, omit `{session}` from templates entirely
|
|
112
|
+
|
|
113
|
+
For the complete SeqInfo field reference and advanced patterns (multi-echo, IntendedFor population, ReproIn), see `references/heudiconv-details.md`.
|
|
114
|
+
|
|
115
|
+
### Step 2: BIDS Validation
|
|
116
|
+
|
|
117
|
+
After conversion, validate the dataset. Present the user with options:
|
|
118
|
+
|
|
119
|
+
**Option A — CLI validator** (recommended for scripted workflows):
|
|
120
|
+
```bash
|
|
121
|
+
# Install
|
|
122
|
+
npm install -g bids-validator
|
|
123
|
+
# or: pip install bids-validator
|
|
124
|
+
|
|
125
|
+
# Run
|
|
126
|
+
bids-validator /path/to/bids_dataset
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**Option B — Web validator** (good for quick checks, no install):
|
|
130
|
+
Direct users to https://bids-standard.github.io/bids-validator/
|
|
131
|
+
|
|
132
|
+
**Common BIDS fixes the skill should help generate scripts for:**
|
|
133
|
+
- Missing `dataset_description.json` → generate it
|
|
134
|
+
- Misnamed files → rename script
|
|
135
|
+
- Missing sidecar JSON fields (e.g., `TaskName` for func, `IntendedFor` for fieldmaps) → patch script
|
|
136
|
+
- Extra files that aren't BIDS-compliant → add to `.bidsignore`
|
|
137
|
+
|
|
138
|
+
### Step 3: fMRIPrep
|
|
139
|
+
|
|
140
|
+
#### Running Locally with Singularity
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# Build the image (do this once)
|
|
144
|
+
singularity build /path/to/fmriprep-<VERSION>.sif docker://nipreps/fmriprep:<VERSION>
|
|
145
|
+
|
|
146
|
+
# Pre-fetch TemplateFlow templates (required for offline HPC nodes)
|
|
147
|
+
export TEMPLATEFLOW_HOME=/path/to/templateflow
|
|
148
|
+
python -c "
|
|
149
|
+
from templateflow.api import get
|
|
150
|
+
get(['MNI152NLin2009cAsym', 'MNI152NLin6Asym', 'OASIS30ANTs', 'fsaverage', 'fsaverage5', 'fsaverage6', 'fsLR'])
|
|
151
|
+
"
|
|
152
|
+
|
|
153
|
+
# Run fMRIPrep
|
|
154
|
+
export SINGULARITYENV_FS_LICENSE=$HOME/.freesurfer.txt
|
|
155
|
+
export SINGULARITYENV_TEMPLATEFLOW_HOME="/templateflow"
|
|
156
|
+
|
|
157
|
+
singularity run --cleanenv \
|
|
158
|
+
-B ${BIDS_DIR}:/data:ro \
|
|
159
|
+
-B ${OUTPUT_DIR}:/out \
|
|
160
|
+
-B ${WORK_DIR}:/work \
|
|
161
|
+
-B ${TEMPLATEFLOW_HOME}:/templateflow \
|
|
162
|
+
/path/to/fmriprep-<VERSION>.sif \
|
|
163
|
+
/data /out participant \
|
|
164
|
+
--participant-label ${SUBJECT} \
|
|
165
|
+
-w /work \
|
|
166
|
+
--output-spaces MNI152NLin2009cAsym:res-2 \
|
|
167
|
+
--fs-license-file /opt/freesurfer/license.txt \
|
|
168
|
+
--nthreads ${SLURM_CPUS_PER_TASK:-8} \
|
|
169
|
+
--omp-nthreads 8 \
|
|
170
|
+
--mem_mb 30000 \
|
|
171
|
+
--skip-bids-validation \
|
|
172
|
+
--notrack
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
#### Commonly Forgotten Flags
|
|
176
|
+
|
|
177
|
+
Always ask the user about these and help them decide:
|
|
178
|
+
|
|
179
|
+
| Flag | What it does | When to use |
|
|
180
|
+
|------|-------------|-------------|
|
|
181
|
+
| `--output-spaces` | Where to resample results | Always specify explicitly. Common: `MNI152NLin2009cAsym:res-2`. Add `MNI152NLin6Asym:res-2` if ICA-AROMA needed later |
|
|
182
|
+
| `--fs-license-file` | FreeSurfer license path | Always required. Free from https://surfer.nmr.mgh.harvard.edu/registration.html |
|
|
183
|
+
| `--fs-no-reconall` | Skip FreeSurfer surfaces | Saves hours; use when surfaces aren't needed |
|
|
184
|
+
| `--cifti-output 91k` | Output CIFTI dense timeseries | For HCP-style surface+volume analyses |
|
|
185
|
+
| `--dummy-scans N` | Discard initial volumes | When auto-detection isn't appropriate |
|
|
186
|
+
| `--fd-spike-threshold` | Motion outlier threshold | Default 0.5mm; stricter = 0.2mm |
|
|
187
|
+
| `--use-syn-sdc warn` | Fieldmap-less distortion correction | When no fieldmaps available |
|
|
188
|
+
| `--ignore fieldmaps` | Skip fieldmap correction | When fieldmaps are bad/unusable |
|
|
189
|
+
| `--anat-only` | Only anatomical processing | For running FreeSurfer first, then func later |
|
|
190
|
+
| `--low-mem` | Reduce memory at cost of disk I/O | When memory-constrained |
|
|
191
|
+
|
|
192
|
+
#### Resource Guidelines
|
|
193
|
+
|
|
194
|
+
| Scenario | CPUs | Memory | Walltime | Disk (work) |
|
|
195
|
+
|----------|------|--------|----------|-------------|
|
|
196
|
+
| With FreeSurfer | 4-8 | 30 GB | 12-24h | 15-30 GB/sub |
|
|
197
|
+
| Without FreeSurfer | 4-8 | 16 GB | 1-4h | 5-15 GB/sub |
|
|
198
|
+
| Anat-only | 2-4 | 12 GB | 6-16h | 10-20 GB/sub |
|
|
199
|
+
|
|
200
|
+
For detailed fMRIPrep flags, troubleshooting, and output structure, see `references/fmriprep-details.md`.
|
|
201
|
+
|
|
202
|
+
### Step 4 (Optional): Large-Scale Processing with BABS
|
|
203
|
+
|
|
204
|
+
BABS (BIDS App Bootstrap) automates large-scale fMRIPrep runs on SLURM clusters with DataLad-based provenance tracking.
|
|
205
|
+
|
|
206
|
+
#### BABS Workflow
|
|
207
|
+
|
|
208
|
+
```
|
|
209
|
+
1. Prepare inputs (BIDS as DataLad dataset + Singularity container as DataLad dataset)
|
|
210
|
+
2. Write configuration YAML
|
|
211
|
+
3. babs init → creates project
|
|
212
|
+
4. babs check-setup --job-test → verify everything works
|
|
213
|
+
5. babs submit --count N → submit jobs
|
|
214
|
+
6. babs status → monitor
|
|
215
|
+
7. babs merge → collect results
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
#### Preparing Inputs
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
# 1. Make BIDS dataset a DataLad dataset (if not already)
|
|
222
|
+
cd /path/to/bids_dataset
|
|
223
|
+
datalad create -f -D "My BIDS dataset" .
|
|
224
|
+
|
|
225
|
+
# 2. Create container DataLad dataset
|
|
226
|
+
singularity build fmriprep-24.1.1.sif docker://nipreps/fmriprep:24.1.1
|
|
227
|
+
datalad create -D "fMRIPrep container" fmriprep-container
|
|
228
|
+
cd fmriprep-container
|
|
229
|
+
datalad containers-add --url /full/path/to/fmriprep-24.1.1.sif fmriprep-24-1-1
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
#### Configuration YAML
|
|
233
|
+
|
|
234
|
+
Help the user fill in this template by asking about their cluster setup:
|
|
235
|
+
|
|
236
|
+
```yaml
|
|
237
|
+
input_datasets:
|
|
238
|
+
BIDS:
|
|
239
|
+
required_files:
|
|
240
|
+
- "func/*_bold.nii*"
|
|
241
|
+
- "anat/*_T1w.nii*"
|
|
242
|
+
is_zipped: false
|
|
243
|
+
origin_url: "/path/to/bids_datalad_dataset"
|
|
244
|
+
path_in_babs: inputs/data/BIDS
|
|
245
|
+
|
|
246
|
+
cluster_resources:
|
|
247
|
+
interpreting_shell: "/bin/bash"
|
|
248
|
+
hard_memory_limit: 32G
|
|
249
|
+
temporary_disk_space: 200G
|
|
250
|
+
number_of_cpus: "6"
|
|
251
|
+
hard_runtime_limit: "24:00:00"
|
|
252
|
+
customized_text: |
|
|
253
|
+
#SBATCH -p YOUR_PARTITION
|
|
254
|
+
#SBATCH --nodes=1
|
|
255
|
+
#SBATCH --ntasks=1
|
|
256
|
+
|
|
257
|
+
script_preamble: |
|
|
258
|
+
source "${CONDA_PREFIX}"/bin/activate babs
|
|
259
|
+
module load singularity
|
|
260
|
+
|
|
261
|
+
job_compute_space: "${TMPDIR}"
|
|
262
|
+
|
|
263
|
+
singularity_args:
|
|
264
|
+
- --cleanenv
|
|
265
|
+
|
|
266
|
+
bids_app_args:
|
|
267
|
+
$SUBJECT_SELECTION_FLAG: "--participant-label"
|
|
268
|
+
-w: "$BABS_TMPDIR"
|
|
269
|
+
--fs-license-file: "/path/to/license.txt"
|
|
270
|
+
--output-spaces: "MNI152NLin2009cAsym:res-2"
|
|
271
|
+
--force-bbr: ""
|
|
272
|
+
--n_cpus: "6"
|
|
273
|
+
--mem-mb: "30000"
|
|
274
|
+
--skip-bids-validation: ""
|
|
275
|
+
--notrack: ""
|
|
276
|
+
|
|
277
|
+
zip_foldernames:
|
|
278
|
+
fmriprep: "24-1-1"
|
|
279
|
+
freesurfer: "24-1-1"
|
|
280
|
+
|
|
281
|
+
alert_log_messages:
|
|
282
|
+
stdout:
|
|
283
|
+
- "fMRIPrep failed"
|
|
284
|
+
- "Cannot allocate memory"
|
|
285
|
+
- "Excessive topologic defect encountered"
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
**When asking the user about cluster config, help them decide:**
|
|
289
|
+
- **Partition**: ask what's available on their cluster (`sinfo -s`)
|
|
290
|
+
- **Memory**: 32G is safe default; 16G if `--fs-no-reconall`
|
|
291
|
+
- **CPUs**: 4-8 is typical; diminishing returns beyond 16
|
|
292
|
+
- **Walltime**: 24h with FreeSurfer, 6h without
|
|
293
|
+
- **Temp disk**: 200G is generous; 100G usually enough
|
|
294
|
+
- **Modules**: what module system they use (`module avail singularity`)
|
|
295
|
+
|
|
296
|
+
#### Running BABS
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
# Initialize project
|
|
300
|
+
babs init \
|
|
301
|
+
--container_ds /path/to/fmriprep-container \
|
|
302
|
+
--container_name fmriprep-24-1-1 \
|
|
303
|
+
--container_config /path/to/config.yaml \
|
|
304
|
+
--processing_level subject \
|
|
305
|
+
--queue slurm \
|
|
306
|
+
/path/to/my_babs_project
|
|
307
|
+
|
|
308
|
+
# Verify setup (always do this first!)
|
|
309
|
+
babs check-setup /path/to/my_babs_project --job-test
|
|
310
|
+
|
|
311
|
+
# Submit jobs (start small to verify)
|
|
312
|
+
babs submit /path/to/my_babs_project --count 2
|
|
313
|
+
|
|
314
|
+
# Check status
|
|
315
|
+
babs status /path/to/my_babs_project
|
|
316
|
+
|
|
317
|
+
# Once all jobs succeed, merge results
|
|
318
|
+
babs merge /path/to/my_babs_project
|
|
319
|
+
|
|
320
|
+
# Clone output for downstream use
|
|
321
|
+
datalad clone \
|
|
322
|
+
ria+file:///path/to/my_babs_project/output_ria#~data \
|
|
323
|
+
my_fmriprep_outputs
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
For the full BABS YAML reference, advanced configurations (anat-only + ingressed FreeSurfer workflow, multi-session handling), see `references/babs-details.md`.
|
|
327
|
+
|
|
328
|
+
## Guiding New Users
|
|
329
|
+
|
|
330
|
+
Many users will be new to this pipeline. Don't assume they know the tools — walk them through it step by step. Start every interaction by understanding where they are:
|
|
331
|
+
|
|
332
|
+
1. **Assess their starting point**: Ask what they have (raw DICOMs? already in BIDS? already ran fMRIPrep but need HPC scaling?). Don't dump the whole pipeline on someone who only needs one step.
|
|
333
|
+
2. **Gather their data details before generating anything**:
|
|
334
|
+
- How are the DICOMs organized? (flat directory, by subject, by session?)
|
|
335
|
+
- What scanner and modalities? (Siemens/GE/Philips, T1w, BOLD, fieldmaps, DWI?)
|
|
336
|
+
- How many subjects and sessions?
|
|
337
|
+
- Where will they run fMRIPrep — local machine or HPC cluster?
|
|
338
|
+
- If HPC: what scheduler (SLURM), what partitions, what's their scratch space?
|
|
339
|
+
3. **Explain each step as you go**: Briefly tell them *why* each step matters (e.g., "heudiconv's first pass doesn't convert anything — it just catalogs your DICOM series so we can write the mapping rules"). Users who understand the reasoning can troubleshoot on their own later.
|
|
340
|
+
4. **Generate one stage at a time**: Don't produce all scripts at once. Generate the heudiconv heuristic first, have them run the reconnaissance pass, share the `dicominfo.tsv`, then refine the heuristic together. Move to BIDS validation only after conversion works.
|
|
341
|
+
5. **Offer to explain unfamiliar concepts**: Terms like "BIDS", "heuristic file", "DataLad dataset", "RIA store" may be new. Define them naturally when they first come up.
|
|
342
|
+
|
|
343
|
+
## Generating Scripts
|
|
344
|
+
|
|
345
|
+
When generating scripts, follow these principles:
|
|
346
|
+
|
|
347
|
+
1. **Generate modular scripts**: separate scripts for each pipeline stage so users can run/debug independently
|
|
348
|
+
2. **Include error handling**: check for missing files, validate outputs
|
|
349
|
+
3. **Add comments**: explain what each section does, especially heudiconv matching logic
|
|
350
|
+
4. **Make paths configurable**: use variables at the top of scripts, not hardcoded paths
|
|
351
|
+
5. **Support both bash and Python**: generate whichever the user prefers
|
|
352
|
+
|
|
353
|
+
### Recommended script structure:
|
|
354
|
+
```
|
|
355
|
+
scripts/
|
|
356
|
+
├── 01_dicom_to_bids.sh # heudiconv conversion
|
|
357
|
+
├── heuristic.py # heudiconv heuristic file
|
|
358
|
+
├── 02_validate_bids.sh # BIDS validation + fixes
|
|
359
|
+
├── 03_run_fmriprep.sh # fMRIPrep (local) or BABS setup
|
|
360
|
+
└── 04_check_outputs.sh # verify fMRIPrep outputs
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
## Common Pitfalls
|
|
364
|
+
|
|
365
|
+
- **Not filtering MoCo series**: Siemens scanners duplicate BOLD as motion-corrected series. Always check `is_motion_corrected`.
|
|
366
|
+
- **Missing `--minmeta` in heudiconv**: Without it, JSON sidecars balloon with dcmstack metadata.
|
|
367
|
+
- **TemplateFlow on offline nodes**: Pre-fetch templates on the login node before submitting jobs.
|
|
368
|
+
- **FreeSurfer license**: Forgetting to set it up is the #1 fMRIPrep failure. Always verify the path.
|
|
369
|
+
- **Mixing fMRIPrep versions**: Process the entire dataset with one version. Don't mix.
|
|
370
|
+
- **Not running `babs check-setup --job-test`**: Always test before bulk submission.
|
|
371
|
+
- **Killing `babs submit`**: Never interrupt it mid-run — job IDs won't be captured.
|
|
372
|
+
|
|
373
|
+
## References
|
|
374
|
+
|
|
375
|
+
- `references/heudiconv-details.md` — Full SeqInfo fields, advanced heuristic patterns, multi-echo, IntendedFor
|
|
376
|
+
- `references/fmriprep-details.md` — Complete flag reference, output structure, confounds, troubleshooting
|
|
377
|
+
- `references/babs-details.md` — Full YAML schema, advanced workflows (anat-only + ingressed-fs), consuming results
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "fmri-dicom-to-fmriprep",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": 0,
|
|
6
|
+
"name": "heudiconv-heuristic",
|
|
7
|
+
"prompt": "I have a bunch of unsorted DICOMs from a Siemens scanner with T1w MPRAGE (176 slices), resting-state fMRI (300 volumes, TR=2s), and AP/PA spin-echo fieldmaps. The DICOMs are in /data/raw_dicoms/ organized by subject folders like S001, S002 etc. Help me write scripts to convert them to BIDS format using heudiconv. I need the heuristic.py file and a bash script to run the conversion for all subjects.",
|
|
8
|
+
"expected_output": "A heuristic.py with correct create_key/infotodict matching the described sequences, and a bash script running heudiconv two-pass workflow",
|
|
9
|
+
"files": []
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"id": 1,
|
|
13
|
+
"name": "babs-setup",
|
|
14
|
+
"prompt": "I need to run fMRIPrep 24.1.1 on 200 subjects on our SLURM cluster. We have Singularity available via 'module load singularity/3.8'. Our cluster has partitions 'normal' (max 24h) and 'long' (max 72h). Scratch space is at /scratch/$USER. The BIDS dataset is already a DataLad dataset at /project/data/bids_datalad. I want MNI152NLin2009cAsym:res-2 output space and CIFTI output. Can you help me set up BABS for this?",
|
|
15
|
+
"expected_output": "Step-by-step instructions including: building Singularity image, creating container DataLad dataset, BABS config YAML with correct cluster resources, and babs init/check-setup/submit commands",
|
|
16
|
+
"files": []
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": 2,
|
|
20
|
+
"name": "bids-fix",
|
|
21
|
+
"prompt": "My BIDS dataset at /data/bids_study fails validation. The errors are: (1) TaskName is missing from all func JSON sidecars, the task is 'rest', (2) IntendedFor is not set on the fieldmap JSON files - the fieldmaps are in fmap/ and should point to the bold runs in func/, and (3) there are some .DS_Store files scattered around. Generate a Python script to fix all of these issues.",
|
|
22
|
+
"expected_output": "A Python script that adds TaskName to func sidecars, sets IntendedFor in fmap sidecars pointing to BOLD files, adds .DS_Store to .bidsignore, and optionally removes .DS_Store files",
|
|
23
|
+
"files": []
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
}
|