@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,407 @@
|
|
|
1
|
+
# BABS Detailed Reference
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
- [Full YAML Configuration Schema](#full-yaml-configuration-schema)
|
|
5
|
+
- [Advanced Workflows](#advanced-workflows)
|
|
6
|
+
- [CLI Command Reference](#cli-command-reference)
|
|
7
|
+
- [Consuming Results](#consuming-results)
|
|
8
|
+
- [Troubleshooting](#troubleshooting)
|
|
9
|
+
|
|
10
|
+
## Full YAML Configuration Schema
|
|
11
|
+
|
|
12
|
+
### `input_datasets`
|
|
13
|
+
|
|
14
|
+
```yaml
|
|
15
|
+
input_datasets:
|
|
16
|
+
DATASET_NAME: # User-chosen key (e.g., "BIDS", "FreeSurfer")
|
|
17
|
+
required_files: # Glob patterns — subjects missing these are skipped
|
|
18
|
+
- "func/*_bold.nii*"
|
|
19
|
+
- "anat/*_T1w.nii*"
|
|
20
|
+
is_zipped: false # true for zipped derivative inputs
|
|
21
|
+
origin_url: "/path/to/datalad/dataset"
|
|
22
|
+
path_in_babs: inputs/data/BIDS
|
|
23
|
+
# For zipped inputs only:
|
|
24
|
+
unzipped_path_containing_subject_dirs: "freesurfer"
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The **first listed dataset** becomes the positional BIDS input argument to the container.
|
|
28
|
+
|
|
29
|
+
### `cluster_resources`
|
|
30
|
+
|
|
31
|
+
| Key | SLURM Translation | Example |
|
|
32
|
+
|-----|-------------------|---------|
|
|
33
|
+
| `interpreting_shell` | `#!VALUE` | `/bin/bash` or `/bin/bash -l` |
|
|
34
|
+
| `hard_memory_limit` | `#SBATCH --mem=VALUE` | `32G` |
|
|
35
|
+
| `temporary_disk_space` | `#SBATCH --tmp=VALUE` | `200G` |
|
|
36
|
+
| `number_of_cpus` | `#SBATCH --cpus-per-task=VALUE` | `"6"` |
|
|
37
|
+
| `hard_runtime_limit` | `#SBATCH --time=VALUE` | `"24:00:00"` |
|
|
38
|
+
| `customized_text` | Copied verbatim | See below |
|
|
39
|
+
|
|
40
|
+
```yaml
|
|
41
|
+
cluster_resources:
|
|
42
|
+
interpreting_shell: "/bin/bash"
|
|
43
|
+
hard_memory_limit: 32G
|
|
44
|
+
temporary_disk_space: 200G
|
|
45
|
+
number_of_cpus: "6"
|
|
46
|
+
hard_runtime_limit: "24:00:00"
|
|
47
|
+
customized_text: |
|
|
48
|
+
#SBATCH -p all
|
|
49
|
+
#SBATCH --nodes=1
|
|
50
|
+
#SBATCH --ntasks=1
|
|
51
|
+
#SBATCH --propagate=NONE
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### `script_preamble`
|
|
55
|
+
|
|
56
|
+
Bash commands run before the container. Use `|` for multiline. Do NOT quote commands.
|
|
57
|
+
|
|
58
|
+
```yaml
|
|
59
|
+
script_preamble: |
|
|
60
|
+
source "${CONDA_PREFIX}"/bin/activate babs
|
|
61
|
+
module load singularity
|
|
62
|
+
export TEMPLATEFLOW_HOME=/shared/templateflow
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### `job_compute_space`
|
|
66
|
+
|
|
67
|
+
Ephemeral scratch directory. Should auto-clean after job finishes.
|
|
68
|
+
|
|
69
|
+
```yaml
|
|
70
|
+
job_compute_space: "${TMPDIR}"
|
|
71
|
+
# Or a specific path:
|
|
72
|
+
job_compute_space: "/scratch/${USER}/babs_tmp"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### `singularity_args`
|
|
76
|
+
|
|
77
|
+
```yaml
|
|
78
|
+
singularity_args:
|
|
79
|
+
- --cleanenv
|
|
80
|
+
- --writable-tmpfs
|
|
81
|
+
# Add --nv for GPU workloads
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### `bids_app_args`
|
|
85
|
+
|
|
86
|
+
```yaml
|
|
87
|
+
bids_app_args:
|
|
88
|
+
$SUBJECT_SELECTION_FLAG: "--participant-label" # BABS special variable
|
|
89
|
+
-w: "$BABS_TMPDIR" # BABS placeholder for temp workspace
|
|
90
|
+
--fs-license-file: "/path/to/license.txt" # Auto-bound into container
|
|
91
|
+
--output-spaces: "MNI152NLin2009cAsym:res-2"
|
|
92
|
+
--force-bbr: "" # Flag without value (empty string, Null, or NULL)
|
|
93
|
+
--cifti-output: "91k"
|
|
94
|
+
--n_cpus: "6" # Quote numeric values
|
|
95
|
+
--mem-mb: "30000"
|
|
96
|
+
--skip-bids-validation: ""
|
|
97
|
+
--notrack: ""
|
|
98
|
+
-v: '-v' # Double verbose: -v -v
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Rules:**
|
|
102
|
+
- Do NOT include `--participant-label` or `--bids-filter-file` directly — BABS handles these via `$SUBJECT_SELECTION_FLAG`
|
|
103
|
+
- Use `$BABS_TMPDIR` for working directory (`-w`)
|
|
104
|
+
- Use `$SLURM_CPUS_PER_TASK` as env var in script_preamble if needed
|
|
105
|
+
- BABS auto-adds `--bids-filter-file` for fMRIPrep with multi-session data
|
|
106
|
+
- FreeSurfer license path is auto-bound into container at `/SGLR/FREESURFER_HOME/license.txt`
|
|
107
|
+
- BABS handles `$TEMPLATEFLOW_HOME` if the env var is set when running `babs init`
|
|
108
|
+
|
|
109
|
+
### `zip_foldernames`
|
|
110
|
+
|
|
111
|
+
Controls how outputs are zipped per subject. Version string becomes part of the zip filename.
|
|
112
|
+
|
|
113
|
+
**Legacy output layout** (fMRIPrep < 21.0):
|
|
114
|
+
```yaml
|
|
115
|
+
zip_foldernames:
|
|
116
|
+
fmriprep: "24-1-1" # → sub-XX_fmriprep-24-1-1.zip
|
|
117
|
+
freesurfer: "24-1-1" # → sub-XX_freesurfer-24-1-1.zip
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**BIDS output layout** (fMRIPrep >= 21.0, with `all_results_in_one_zip`):
|
|
121
|
+
```yaml
|
|
122
|
+
all_results_in_one_zip: true
|
|
123
|
+
zip_foldernames:
|
|
124
|
+
fmriprep_anat: "24-1-1" # Single zip with everything
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
When `all_results_in_one_zip: true`, only ONE foldername is allowed.
|
|
128
|
+
|
|
129
|
+
### `imported_files` (optional)
|
|
130
|
+
|
|
131
|
+
Copy external files into the DataLad dataset (useful for custom config files):
|
|
132
|
+
|
|
133
|
+
```yaml
|
|
134
|
+
imported_files:
|
|
135
|
+
- original_path: "/path/to/custom_config.yaml"
|
|
136
|
+
analysis_path: "code/custom_config.yaml"
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### `alert_log_messages` (optional)
|
|
140
|
+
|
|
141
|
+
Patterns to flag in failed job logs:
|
|
142
|
+
|
|
143
|
+
```yaml
|
|
144
|
+
alert_log_messages:
|
|
145
|
+
stdout:
|
|
146
|
+
- "fMRIPrep failed"
|
|
147
|
+
- "Cannot allocate memory"
|
|
148
|
+
- "Excessive topologic defect encountered"
|
|
149
|
+
- "mris_curvature_stats: Could not open file"
|
|
150
|
+
- "Numerical result out of range"
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Advanced Workflows
|
|
154
|
+
|
|
155
|
+
### Anat-Only + Ingressed FreeSurfer (Two-Stage Pipeline)
|
|
156
|
+
|
|
157
|
+
For large datasets, split fMRIPrep into two stages to optimize resources:
|
|
158
|
+
|
|
159
|
+
**Stage 1: Anat-only** (long walltime, low CPU)
|
|
160
|
+
|
|
161
|
+
```yaml
|
|
162
|
+
input_datasets:
|
|
163
|
+
BIDS:
|
|
164
|
+
required_files:
|
|
165
|
+
- "anat/*_T1w.nii*"
|
|
166
|
+
is_zipped: false
|
|
167
|
+
origin_url: "/path/to/bids"
|
|
168
|
+
path_in_babs: inputs/data/BIDS
|
|
169
|
+
|
|
170
|
+
cluster_resources:
|
|
171
|
+
interpreting_shell: "/bin/bash"
|
|
172
|
+
hard_memory_limit: 12G
|
|
173
|
+
number_of_cpus: "2"
|
|
174
|
+
hard_runtime_limit: "24:00:00"
|
|
175
|
+
customized_text: |
|
|
176
|
+
#SBATCH -p long
|
|
177
|
+
#SBATCH --nodes=1
|
|
178
|
+
|
|
179
|
+
bids_app_args:
|
|
180
|
+
$SUBJECT_SELECTION_FLAG: "--participant-label"
|
|
181
|
+
-w: "$BABS_TMPDIR"
|
|
182
|
+
--anat-only: ""
|
|
183
|
+
--fs-license-file: "/path/to/license.txt"
|
|
184
|
+
--output-spaces: "MNI152NLin2009cAsym:res-2"
|
|
185
|
+
--notrack: ""
|
|
186
|
+
|
|
187
|
+
all_results_in_one_zip: true
|
|
188
|
+
zip_foldernames:
|
|
189
|
+
fmriprep_anat: "24-1-1"
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
**Stage 2: Func with ingressed FreeSurfer** (shorter walltime, more CPU)
|
|
193
|
+
|
|
194
|
+
```yaml
|
|
195
|
+
input_datasets:
|
|
196
|
+
BIDS:
|
|
197
|
+
required_files:
|
|
198
|
+
- "func/*_bold.nii*"
|
|
199
|
+
- "anat/*_T1w.nii*"
|
|
200
|
+
is_zipped: false
|
|
201
|
+
origin_url: "/path/to/bids"
|
|
202
|
+
path_in_babs: inputs/data/BIDS
|
|
203
|
+
FreeSurfer:
|
|
204
|
+
required_files:
|
|
205
|
+
- "*fmriprep_anat*.zip"
|
|
206
|
+
is_zipped: true
|
|
207
|
+
origin_url: "/path/to/stage1_babs_project/output_ria"
|
|
208
|
+
unzipped_path_containing_subject_dirs: "fmriprep_anat"
|
|
209
|
+
path_in_babs: inputs/data/freesurfer
|
|
210
|
+
|
|
211
|
+
cluster_resources:
|
|
212
|
+
interpreting_shell: "/bin/bash"
|
|
213
|
+
hard_memory_limit: 30G
|
|
214
|
+
number_of_cpus: "6"
|
|
215
|
+
hard_runtime_limit: "8:00:00"
|
|
216
|
+
customized_text: |
|
|
217
|
+
#SBATCH -p normal
|
|
218
|
+
#SBATCH --nodes=1
|
|
219
|
+
|
|
220
|
+
bids_app_args:
|
|
221
|
+
$SUBJECT_SELECTION_FLAG: "--participant-label"
|
|
222
|
+
-w: "$BABS_TMPDIR"
|
|
223
|
+
--fs-subjects-dir: "inputs/data/freesurfer/freesurfer"
|
|
224
|
+
--fs-license-file: "/path/to/license.txt"
|
|
225
|
+
--output-spaces: "MNI152NLin2009cAsym:res-2"
|
|
226
|
+
--force-bbr: ""
|
|
227
|
+
--n_cpus: "6"
|
|
228
|
+
--mem-mb: "28000"
|
|
229
|
+
--notrack: ""
|
|
230
|
+
|
|
231
|
+
all_results_in_one_zip: true
|
|
232
|
+
zip_foldernames:
|
|
233
|
+
fmriprep_func: "24-1-1"
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Multi-Session Processing
|
|
237
|
+
|
|
238
|
+
For multi-session data, use `--processing_level session` in `babs init`. BABS will:
|
|
239
|
+
- Process each session independently
|
|
240
|
+
- Auto-generate `--bids-filter-file` for fMRIPrep
|
|
241
|
+
- Create per-session output zips
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
babs init \
|
|
245
|
+
--container_ds /path/to/fmriprep-container \
|
|
246
|
+
--container_name fmriprep-24-1-1 \
|
|
247
|
+
--container_config config.yaml \
|
|
248
|
+
--processing_level session \
|
|
249
|
+
--queue slurm \
|
|
250
|
+
/path/to/my_babs_project
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Filtering Subjects
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
# Via CSV file during init
|
|
257
|
+
babs init ... --list_sub_file subjects.csv
|
|
258
|
+
|
|
259
|
+
# CSV format (subject-level):
|
|
260
|
+
# sub_id
|
|
261
|
+
# sub-01
|
|
262
|
+
# sub-02
|
|
263
|
+
|
|
264
|
+
# CSV format (session-level):
|
|
265
|
+
# sub_id,ses_id
|
|
266
|
+
# sub-01,ses-01
|
|
267
|
+
# sub-01,ses-02
|
|
268
|
+
|
|
269
|
+
# Via --select during submit
|
|
270
|
+
babs submit --select sub-01 ses-01 --select sub-02 ses-01
|
|
271
|
+
|
|
272
|
+
# Via inclusion file during submit
|
|
273
|
+
babs submit --inclusion-file my_subjects.csv
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Throttling Jobs
|
|
277
|
+
|
|
278
|
+
Limit simultaneous SLURM array tasks to avoid overwhelming the cluster:
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
babs init ... --throttle 10 # Max 10 concurrent jobs
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
## CLI Command Reference
|
|
285
|
+
|
|
286
|
+
### `babs init`
|
|
287
|
+
```bash
|
|
288
|
+
babs init \
|
|
289
|
+
--container_ds PATH \
|
|
290
|
+
--container_name NAME \
|
|
291
|
+
--container_config YAML \
|
|
292
|
+
--processing_level {subject,session} \
|
|
293
|
+
--queue slurm \
|
|
294
|
+
[--list_sub_file CSV] \
|
|
295
|
+
[--keep_if_failed] \
|
|
296
|
+
[--throttle N] \
|
|
297
|
+
PROJECT_ROOT
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### `babs check-setup`
|
|
301
|
+
```bash
|
|
302
|
+
babs check-setup [PROJECT_ROOT] [--job-test]
|
|
303
|
+
```
|
|
304
|
+
Always run with `--job-test` before bulk submission.
|
|
305
|
+
|
|
306
|
+
### `babs submit`
|
|
307
|
+
```bash
|
|
308
|
+
babs submit [PROJECT_ROOT] \
|
|
309
|
+
[--count N] \
|
|
310
|
+
[--select SUB [SES]] \
|
|
311
|
+
[--inclusion-file CSV] \
|
|
312
|
+
[--skip-running-jobs]
|
|
313
|
+
```
|
|
314
|
+
`--count`, `--select`, and `--inclusion-file` are mutually exclusive.
|
|
315
|
+
|
|
316
|
+
**WARNING**: Never kill `babs submit` while running.
|
|
317
|
+
|
|
318
|
+
### `babs status`
|
|
319
|
+
```bash
|
|
320
|
+
babs status [PROJECT_ROOT]
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### `babs merge`
|
|
324
|
+
```bash
|
|
325
|
+
babs merge [PROJECT_ROOT] [--chunk-size 2000]
|
|
326
|
+
```
|
|
327
|
+
If merge fails, manually remove `merge_ds/` before retrying.
|
|
328
|
+
|
|
329
|
+
### `babs sync-code`
|
|
330
|
+
```bash
|
|
331
|
+
babs sync-code [PROJECT_ROOT] [-m "message"]
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### `babs update-input-data`
|
|
335
|
+
```bash
|
|
336
|
+
babs update-input-data [PROJECT_ROOT] [--dataset-name BIDS]
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
## Consuming Results
|
|
340
|
+
|
|
341
|
+
After `babs merge`:
|
|
342
|
+
|
|
343
|
+
```bash
|
|
344
|
+
# Clone the output dataset
|
|
345
|
+
datalad clone \
|
|
346
|
+
ria+file:///absolute/path/to/my_babs_project/output_ria#~data \
|
|
347
|
+
my_outputs
|
|
348
|
+
|
|
349
|
+
cd my_outputs
|
|
350
|
+
|
|
351
|
+
# Get specific subject's results
|
|
352
|
+
datalad get sub-01_fmriprep-24-1-1.zip
|
|
353
|
+
unzip sub-01_fmriprep-24-1-1.zip
|
|
354
|
+
|
|
355
|
+
# Get all results
|
|
356
|
+
datalad get .
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### Project Structure After Init
|
|
360
|
+
|
|
361
|
+
```
|
|
362
|
+
my_babs_project/
|
|
363
|
+
├── analysis/
|
|
364
|
+
│ ├── code/
|
|
365
|
+
│ │ ├── participant_job.sh # Generated SLURM script
|
|
366
|
+
│ │ └── processing_inclusion.csv
|
|
367
|
+
│ ├── inputs/
|
|
368
|
+
│ │ └── data/
|
|
369
|
+
│ │ └── BIDS/ # Cloned input dataset
|
|
370
|
+
│ └── containers/
|
|
371
|
+
│ └── fmriprep-24-1-1.sif
|
|
372
|
+
└── output_ria/ # RIA store for results
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
## Troubleshooting
|
|
376
|
+
|
|
377
|
+
### `babs init` fails
|
|
378
|
+
- Check all paths are absolute
|
|
379
|
+
- Verify container DataLad dataset was created correctly
|
|
380
|
+
- Use `--keep_if_failed` and run `babs check-setup` to diagnose
|
|
381
|
+
|
|
382
|
+
### `babs check-setup --job-test` fails
|
|
383
|
+
- Check `script_preamble` — are modules available?
|
|
384
|
+
- Verify Singularity/Apptainer is loadable
|
|
385
|
+
- Check SLURM partition exists (`sinfo -s`)
|
|
386
|
+
- Check FreeSurfer license path
|
|
387
|
+
- Look at the job log in `analysis/logs/`
|
|
388
|
+
|
|
389
|
+
### Jobs fail immediately
|
|
390
|
+
- Check `cluster_resources` — enough memory/time?
|
|
391
|
+
- Verify `job_compute_space` exists and is writable
|
|
392
|
+
- Check `singularity_args` — `--cleanenv` is usually needed
|
|
393
|
+
|
|
394
|
+
### `babs merge` fails
|
|
395
|
+
- Remove `merge_ds/` directory and retry
|
|
396
|
+
- Check that successful jobs actually completed (not just submitted)
|
|
397
|
+
- Try with `--chunk-size 500` for very large datasets
|
|
398
|
+
|
|
399
|
+
### DataLad issues
|
|
400
|
+
```bash
|
|
401
|
+
# If input dataset isn't a DataLad dataset:
|
|
402
|
+
cd /path/to/bids
|
|
403
|
+
datalad create -f -D "BIDS dataset" .
|
|
404
|
+
|
|
405
|
+
# If container dataset has issues:
|
|
406
|
+
datalad containers-list # verify container is registered
|
|
407
|
+
```
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
# fMRIPrep Detailed Reference
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
- [Complete Flag Reference](#complete-flag-reference)
|
|
5
|
+
- [Output Structure](#output-structure)
|
|
6
|
+
- [Confounds Reference](#confounds-reference)
|
|
7
|
+
- [SLURM Script Template](#slurm-script-template)
|
|
8
|
+
- [Troubleshooting](#troubleshooting)
|
|
9
|
+
|
|
10
|
+
## Complete Flag Reference
|
|
11
|
+
|
|
12
|
+
### Input/Output
|
|
13
|
+
| Flag | Description |
|
|
14
|
+
|------|-------------|
|
|
15
|
+
| `bids_dir` | Positional: path to BIDS dataset |
|
|
16
|
+
| `output_dir` | Positional: path for derivatives |
|
|
17
|
+
| `analysis_level` | `participant` (subject-level) |
|
|
18
|
+
| `--participant-label` | Subject IDs without `sub-` prefix |
|
|
19
|
+
| `--task-id` | Process only specific task |
|
|
20
|
+
| `--bids-filter-file` | JSON for custom BIDS input filtering |
|
|
21
|
+
| `-w, --work-dir` | Working directory (keep for crash recovery) |
|
|
22
|
+
| `--skip-bids-validation` | Skip BIDS validation (use only after manual validation) |
|
|
23
|
+
|
|
24
|
+
### Output Spaces
|
|
25
|
+
| Flag | Description |
|
|
26
|
+
|------|-------------|
|
|
27
|
+
| `--output-spaces` | Space-delimited list of output spaces |
|
|
28
|
+
|
|
29
|
+
Common spaces:
|
|
30
|
+
- `MNI152NLin2009cAsym` — Default volumetric template (most common)
|
|
31
|
+
- `MNI152NLin2009cAsym:res-2` — Same, at 2mm resolution
|
|
32
|
+
- `MNI152NLin6Asym:res-2` — FSL's MNI (required for ICA-AROMA post-processing)
|
|
33
|
+
- `fsaverage` / `fsaverage5` / `fsaverage6` — FreeSurfer surface spaces
|
|
34
|
+
- `fsnative` — Subject's native surface
|
|
35
|
+
- `T1w` — Subject's native anatomical space
|
|
36
|
+
|
|
37
|
+
### FreeSurfer
|
|
38
|
+
| Flag | Description |
|
|
39
|
+
|------|-------------|
|
|
40
|
+
| `--fs-license-file` | Path to FreeSurfer license.txt |
|
|
41
|
+
| `--fs-no-reconall` | Skip FreeSurfer surface reconstruction (saves hours) |
|
|
42
|
+
| `--fs-subjects-dir` | Reuse existing FreeSurfer recon-all output |
|
|
43
|
+
|
|
44
|
+
### Distortion Correction
|
|
45
|
+
| Flag | Description |
|
|
46
|
+
|------|-------------|
|
|
47
|
+
| `--ignore fieldmaps` | Skip fieldmap-based SDC |
|
|
48
|
+
| `--use-syn-sdc warn` | Enable fieldmap-less SyN SDC as fallback |
|
|
49
|
+
| `--force-syn-sdc` | Force SyN SDC even with fieldmaps |
|
|
50
|
+
|
|
51
|
+
### Skull Stripping
|
|
52
|
+
| Flag | Description |
|
|
53
|
+
|------|-------------|
|
|
54
|
+
| `--skull-strip-template` | Template for brain extraction (default: `OASIS30ANTs`) |
|
|
55
|
+
| `--skull-strip-t1w` | `auto`, `skip`, or `force` (default: `force`) |
|
|
56
|
+
| `--skull-strip-fixed-seed` | Reproducible skull stripping |
|
|
57
|
+
|
|
58
|
+
### Resource Control
|
|
59
|
+
| Flag | Description |
|
|
60
|
+
|------|-------------|
|
|
61
|
+
| `--nthreads` / `--nprocs` / `--n-cpus` | Max total threads |
|
|
62
|
+
| `--omp-nthreads` | Max threads per process |
|
|
63
|
+
| `--mem-mb` / `--mem` | Memory limit in MB |
|
|
64
|
+
| `--low-mem` | Trade disk I/O for lower memory usage |
|
|
65
|
+
|
|
66
|
+
### Quality & Scans
|
|
67
|
+
| Flag | Description |
|
|
68
|
+
|------|-------------|
|
|
69
|
+
| `--dummy-scans N` | Override auto non-steady-state detection |
|
|
70
|
+
| `--fd-spike-threshold` | FD threshold for motion outliers (default: 0.5mm) |
|
|
71
|
+
| `--dvars-spike-threshold` | DVARS outlier threshold (default: 1.5) |
|
|
72
|
+
| `--bold2anat-dof` | BOLD-to-T1w registration DOF: 6, 9, or 12 (default: 6) |
|
|
73
|
+
|
|
74
|
+
### Other
|
|
75
|
+
| Flag | Description |
|
|
76
|
+
|------|-------------|
|
|
77
|
+
| `--cifti-output 91k` | Output CIFTI dense timeseries |
|
|
78
|
+
| `--anat-only` | Only anatomical workflows |
|
|
79
|
+
| `--random-seed N` | For reproducibility |
|
|
80
|
+
| `--notrack` | Disable usage tracking |
|
|
81
|
+
| `--force-bbr` | Force boundary-based registration |
|
|
82
|
+
| `--ignore slicetiming` | Skip slice timing correction |
|
|
83
|
+
|
|
84
|
+
**Note:** `--use-aroma` was removed in fMRIPrep 23.1.0. Use [fmripost-aroma](https://github.com/nipreps/fmripost-aroma) instead.
|
|
85
|
+
|
|
86
|
+
## Output Structure
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
<output_dir>/
|
|
90
|
+
├── dataset_description.json
|
|
91
|
+
├── sub-<label>.html # Visual QC report (open in browser!)
|
|
92
|
+
├── sub-<label>/
|
|
93
|
+
│ ├── anat/
|
|
94
|
+
│ │ ├── *_desc-preproc_T1w.nii.gz # Preprocessed T1w
|
|
95
|
+
│ │ ├── *_desc-brain_mask.nii.gz # Brain mask
|
|
96
|
+
│ │ ├── *_dseg.nii.gz # Tissue segmentation
|
|
97
|
+
│ │ ├── *_label-{CSF,GM,WM}_probseg.nii.gz # Probability maps
|
|
98
|
+
│ │ ├── *_from-MNI*_to-T1w_xfm.h5 # MNI→native transform
|
|
99
|
+
│ │ ├── *_from-T1w_to-MNI*_xfm.h5 # Native→MNI transform
|
|
100
|
+
│ │ └── *_hemi-{L,R}_{pial,white,midthickness}.surf.gii # Surfaces
|
|
101
|
+
│ └── func/
|
|
102
|
+
│ ├── *_space-<space>_desc-preproc_bold.nii.gz # Preprocessed BOLD
|
|
103
|
+
│ ├── *_space-<space>_desc-brain_mask.nii.gz # BOLD brain mask
|
|
104
|
+
│ ├── *_desc-confounds_timeseries.tsv # Confounds
|
|
105
|
+
│ ├── *_desc-confounds_timeseries.json # Confounds metadata
|
|
106
|
+
│ ├── *_from-boldref_to-T1w_xfm.txt # BOLD→T1w transform
|
|
107
|
+
│ ├── *_bold.dtseries.nii # CIFTI (if --cifti-output)
|
|
108
|
+
│ └── *_space-T1w_desc-aparcaseg_dseg.nii.gz # Parcellation in BOLD space
|
|
109
|
+
└── sourcedata/
|
|
110
|
+
└── freesurfer/ # FreeSurfer recon-all output
|
|
111
|
+
└── sub-<label>/
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Confounds Reference
|
|
115
|
+
|
|
116
|
+
The `*_desc-confounds_timeseries.tsv` contains:
|
|
117
|
+
|
|
118
|
+
### Motion Parameters
|
|
119
|
+
- `trans_x`, `trans_y`, `trans_z` — Translation (mm)
|
|
120
|
+
- `rot_x`, `rot_y`, `rot_z` — Rotation (radians)
|
|
121
|
+
- Each has `_derivative1`, `_power2`, `_derivative1_power2` variants (24-parameter expansion)
|
|
122
|
+
|
|
123
|
+
### Global Signals
|
|
124
|
+
- `csf`, `white_matter`, `global_signal` (+ derivative/power variants)
|
|
125
|
+
|
|
126
|
+
### Quality Metrics
|
|
127
|
+
- `framewise_displacement` — Head motion summary (mm)
|
|
128
|
+
- `rmsd` — Root mean squared deviation
|
|
129
|
+
- `dvars`, `std_dvars` — Intensity change metrics
|
|
130
|
+
|
|
131
|
+
### Noise Components
|
|
132
|
+
- `a_comp_cor_XX` — Anatomical CompCor components
|
|
133
|
+
- `t_comp_cor_XX` — Temporal CompCor components
|
|
134
|
+
- `cosine_XX` — High-pass filter (DCT basis set)
|
|
135
|
+
|
|
136
|
+
### Outlier Indicators
|
|
137
|
+
- `non_steady_state_outlier_XX` — Initial volume flags
|
|
138
|
+
- `motion_outlier_XX` — Spike regressors for high-motion volumes
|
|
139
|
+
|
|
140
|
+
### Recommended Confound Strategies
|
|
141
|
+
- **Minimal**: 6 motion parameters + FD
|
|
142
|
+
- **Standard**: 24 motion parameters + aCompCor (top 5) + cosines
|
|
143
|
+
- **Aggressive**: 24 motion + aCompCor + spike regressors + global signal
|
|
144
|
+
|
|
145
|
+
## SLURM Script Template
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
#!/bin/bash
|
|
149
|
+
#SBATCH --job-name=fmriprep
|
|
150
|
+
#SBATCH --time=24:00:00
|
|
151
|
+
#SBATCH --cpus-per-task=8
|
|
152
|
+
#SBATCH --mem=32G
|
|
153
|
+
#SBATCH --tmp=200G
|
|
154
|
+
#SBATCH --output=log/fmriprep-%A-%a.out
|
|
155
|
+
#SBATCH --error=log/fmriprep-%A-%a.err
|
|
156
|
+
|
|
157
|
+
# ---- Configuration ----
|
|
158
|
+
BIDS_DIR="/path/to/bids"
|
|
159
|
+
OUTPUT_DIR="/path/to/output"
|
|
160
|
+
WORK_DIR="/tmp/fmriprep_work_${SLURM_ARRAY_TASK_ID}"
|
|
161
|
+
FMRIPREP_SIF="/path/to/fmriprep-24.1.1.sif"
|
|
162
|
+
TEMPLATEFLOW_HOME="$HOME/.cache/templateflow"
|
|
163
|
+
FS_LICENSE="$HOME/.freesurfer.txt"
|
|
164
|
+
|
|
165
|
+
# ---- Setup ----
|
|
166
|
+
mkdir -p ${WORK_DIR} ${OUTPUT_DIR} log
|
|
167
|
+
|
|
168
|
+
export SINGULARITYENV_FS_LICENSE=${FS_LICENSE}
|
|
169
|
+
export SINGULARITYENV_TEMPLATEFLOW_HOME="/templateflow"
|
|
170
|
+
|
|
171
|
+
# Get subject ID from participants.tsv using array index
|
|
172
|
+
SUBJECT=$(sed -n -E "$((${SLURM_ARRAY_TASK_ID} + 1))s/sub-(\S*)\>.*/\1/gp" \
|
|
173
|
+
${BIDS_DIR}/participants.tsv)
|
|
174
|
+
|
|
175
|
+
echo "Processing sub-${SUBJECT} on $(hostname) at $(date)"
|
|
176
|
+
|
|
177
|
+
# ---- Run fMRIPrep ----
|
|
178
|
+
singularity run --cleanenv \
|
|
179
|
+
-B ${BIDS_DIR}:/data:ro \
|
|
180
|
+
-B ${OUTPUT_DIR}:/out \
|
|
181
|
+
-B ${WORK_DIR}:/work \
|
|
182
|
+
-B ${TEMPLATEFLOW_HOME}:/templateflow \
|
|
183
|
+
${FMRIPREP_SIF} \
|
|
184
|
+
/data /out participant \
|
|
185
|
+
--participant-label ${SUBJECT} \
|
|
186
|
+
-w /work \
|
|
187
|
+
--output-spaces MNI152NLin2009cAsym:res-2 \
|
|
188
|
+
--fs-license-file /opt/freesurfer/license.txt \
|
|
189
|
+
--nthreads ${SLURM_CPUS_PER_TASK} \
|
|
190
|
+
--omp-nthreads $(( SLURM_CPUS_PER_TASK - 1 )) \
|
|
191
|
+
--mem_mb 30000 \
|
|
192
|
+
--skip-bids-validation \
|
|
193
|
+
--notrack
|
|
194
|
+
|
|
195
|
+
EXIT_CODE=$?
|
|
196
|
+
|
|
197
|
+
# ---- Cleanup ----
|
|
198
|
+
rm -rf ${WORK_DIR}
|
|
199
|
+
|
|
200
|
+
echo "Finished sub-${SUBJECT} with exit code ${EXIT_CODE} at $(date)"
|
|
201
|
+
exit ${EXIT_CODE}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Submit: `sbatch --array=1-N fmriprep.slurm` where N = number of subjects.
|
|
205
|
+
|
|
206
|
+
## Troubleshooting
|
|
207
|
+
|
|
208
|
+
### "recon-all is already running"
|
|
209
|
+
Stale lock files from a crashed run. Remove them:
|
|
210
|
+
```bash
|
|
211
|
+
rm <fs-subjects-dir>/sub-*/scripts/IsRunning.*
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### fMRIPrep hangs or freezes
|
|
215
|
+
Usually a memory issue. Try:
|
|
216
|
+
- Increase `--mem-mb`
|
|
217
|
+
- Use `--low-mem`
|
|
218
|
+
- Reduce `--omp-nthreads`
|
|
219
|
+
|
|
220
|
+
### "insufficient length of BOLD data"
|
|
221
|
+
Too few volumes after discarding non-steady-state frames:
|
|
222
|
+
- Use `--dummy-scans 0` to override
|
|
223
|
+
- Or `--ignore slicetiming`
|
|
224
|
+
- Check if the run is just too short
|
|
225
|
+
|
|
226
|
+
### TemplateFlow download failures on HPC
|
|
227
|
+
Compute nodes often lack internet. Pre-fetch on login node:
|
|
228
|
+
```bash
|
|
229
|
+
export TEMPLATEFLOW_HOME=/shared/templateflow
|
|
230
|
+
python -c "from templateflow.api import get; get(['MNI152NLin2009cAsym', 'MNI152NLin6Asym', 'OASIS30ANTs', 'fsaverage'])"
|
|
231
|
+
```
|
|
232
|
+
Then bind-mount in Singularity.
|
|
233
|
+
|
|
234
|
+
### Out of memory
|
|
235
|
+
- Increase SLURM `--mem`
|
|
236
|
+
- Use `--low-mem` flag
|
|
237
|
+
- Use `--fs-no-reconall` if surfaces aren't needed
|
|
238
|
+
- Reduce `--omp-nthreads`
|
|
239
|
+
|
|
240
|
+
### Race conditions with parallel runs
|
|
241
|
+
Never run multiple fMRIPrep instances writing to the same output directory simultaneously. Use one subject per container instance (SLURM array jobs handle this).
|
|
242
|
+
|
|
243
|
+
### Crash recovery
|
|
244
|
+
fMRIPrep can resume if the working directory (`-w`) is preserved. Rerun the exact same command.
|
|
245
|
+
|
|
246
|
+
### QC before fMRIPrep
|
|
247
|
+
Run MRIQC first to catch bad data before spending hours on fMRIPrep:
|
|
248
|
+
```bash
|
|
249
|
+
singularity run mriqc.sif /data /out participant --participant-label ${SUBJECT}
|
|
250
|
+
```
|