Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Output Checks Configuration

The output checks system serves two purposes:

  1. --resume: before submitting each task’s SLURM array job, the pipeline checks which subjects already have valid outputs and silently excludes them from the submission. Checks are scoped to the tasks you explicitly request on the command line; tasks not included in the current invocation are not evaluated, even if they are configured in the YAML or have failed previously.

  2. neuropipe check-outputs: a standalone command that runs the same checks on demand and saves a CSV report.

Both use the same YAML configuration file.

Configuration File Location

config/results_check/{project}_checks.yaml

The file is named after your project (same as your {project}_config.yaml). For example, project branchbranch_checks.yaml.

Generate a blank template with the CLI or the GUI:

neuropipe generate-checks branch

Or open the Results Check Config tab in the GUI and click New.

After generating, edit the file to add your task checks, then save it back via the GUI Save button or directly on disk.

If the file doesn’t exist when you run --resume, a warning is printed and all subjects are submitted for every task:

Warning: Output checks config not found: .../branch_checks.yaml
         Create 'branch_checks.yaml' in .../results_check to enable resume.

File Structure

# Each top-level key is a task name (must match config.yaml exactly)
task_name:
  output_path: "{work_dir}/path/to/{prefix}{subject}/ses-{session}/"

  # Check type 1: specific files must exist
  required_files:
    - pattern: "filename_or_glob"
      min_size_kb: 500        # optional

  # Check type 2: file count within expected ± tolerance
  count_check:
    label:                    # arbitrary label for this check
      pattern: "*.nii.gz"
      expected_count: 4
      tolerance: 1

Both check types are optional and can be combined freely within one task.

Path Placeholders

The output_path and pattern fields support these placeholders:

PlaceholderExpands toExample
{work_dir}Project work/output directory root/data/work/branch
{subject}Subject ID without prefix001
{prefix}Subject directory prefixsub-
{session}Session label01

output_path is the base directory. Patterns are joined to it with os.path.join before globbing, so they are relative to output_path.

Check Type: required_files

Each entry in the list must resolve to at least one existing file.

volume:
  output_path: "{work_dir}/AFNI_derivatives/{prefix}{subject}/ses-{session}/sswarp2/T1_results"
  required_files:
    - pattern: "QC_anatSS.{prefix}{subject}.jpg"
      min_size_kb: 50

Logic:

  1. The pattern is expanded with {subject}, {prefix}, {session} placeholders.

  2. The expanded pattern is globbed against output_path/pattern (recursive glob supported with **).

  3. If no files match → FAIL (file not found).

  4. If min_size_kb is set and all matching files are smaller than the threshold → FAIL (file exists but too small).

  5. Otherwise → PASS.

Plain strings (without min_size_kb) are also accepted:

required_files:
  - "sub-{subject}*.html"           # shorthand — no size check
  - pattern: "stats+tlrc.HEAD"
    min_size_kb: 1000               # with size check

Check Type: count_check

Validates that a glob matches a specific number of files, within a tolerance.

recon:
  output_path: "{work_dir}/BIDS/sub-{subject}/ses-{session}/"
  count_check:
    anat:
      pattern: "anat/*.nii.gz"
      expected_count: 1
      tolerance: 0
    rest:
      pattern: "func/*rest*.nii.gz"
      expected_count: 2
      tolerance: 1
    fmap:
      pattern: "fmap/*.nii.gz"
      expected_count: 4
      tolerance: 1

Logic:

The label (e.g. anat, rest, fmap) is arbitrary; it appears in the CSV report as check_type: count_check:anat.

Full Example: Real Project Checks

This is the checks file used by the BRANCH study:

View full example config branch_checks.yaml
# Prep
recon:
  output_path: "{work_dir}/BIDS/sub-{subject}/ses-{session}/"
  count_check:
    anat:
      pattern: "anat/*.nii.gz"
      expected_count: 1
      tolerance: 0
    fmap:
      pattern: "fmap/*.nii.gz"
      expected_count: 4
      tolerance: 1
    rest:
      pattern: "func/*rest*.nii.gz"
      expected_count: 2
      tolerance: 1
    kidvid:
      pattern: "func/*kidvid*.nii.gz"
      expected_count: 1
      tolerance: 0
    cards:
      pattern: "func/*cards*.nii.gz"
      expected_count: 1
      tolerance: 0
    dwi:
      pattern: "dwi/*.nii.gz"
      expected_count: 1
      tolerance: 0

# Intermed
volume:
  output_path: "{work_dir}/AFNI_derivatives/{prefix}{subject}/ses-{session}/sswarp2/T1_results"
  required_files:
    - pattern: "QC_anatSS.{prefix}{subject}.jpg"
      min_size_kb: 50

# Resting-state fMRI
rest_preprocess:
  output_path: "{work_dir}/BIDS_derivatives/fmriprep/"
  required_files:
    - pattern: "sub-{subject}*.html"
      min_size_kb: 500

rest_post:
  output_path: "{work_dir}/BIDS_derivatives/xcpd/sub-{subject}/ses-{session}"
  required_files:
    - pattern: "sub-{subject}*.html"
      min_size_kb: 200

# Task fMRI
cards_preprocess:
  output_path: "{work_dir}/AFNI_derivatives/{prefix}{subject}/ses-{session}/cards_output/{prefix}{subject}.results/QC_{prefix}{subject}"
  required_files:
    - pattern: "index.html"
      min_size_kb: 50

kidvid_preprocess:
  output_path: "{work_dir}/AFNI_derivatives/{prefix}{subject}/ses-{session}/kidvid_output/{prefix}{subject}.results/QC_{prefix}{subject}"
  required_files:
    - pattern: "index.html"
      min_size_kb: 50

# DWI
dwi_preprocess:
  output_path: "{work_dir}/BIDS_derivatives/qsiprep"
  required_files:
    - pattern: "sub-{subject}*.html"
      min_size_kb: 200

dwi_post:
  output_path: "{work_dir}/BIDS_derivatives/qsirecon"
  required_files:
    - pattern: "sub-{subject}*.html"
      min_size_kb: 200

# Quality control
mriqc_preprocess:
  output_path: "{work_dir}/quality_control/mriqc"
  required_files:
    - pattern: "sub-{subject}*.html"
      min_size_kb: 100

mriqc_post:
  output_path: "{work_dir}/quality_control/mriqc"
  required_files:
    - pattern: "group_*.html"
      min_size_kb: 50

How a Subject’s Status Is Determined

A subject is COMPLETE for a task if and only if every check item in that task’s config returns PASS. A single failure in any check marks the subject as pending.

subject 001 on task rest_preprocess:
  required_files[0]: sub-001*.html  → PASS (file exists, 620 KB ≥ 500 KB)
  → ALL PASS → subject is COMPLETE → excluded from --resume submission

subject 002 on task rest_preprocess:
  required_files[0]: sub-002*.html  → FAIL (file not found)
  → ANY FAIL → subject is PENDING → included in --resume submission

If a task has no entry in the checks YAML, get_completed_subjects returns an empty list (no one is considered complete), so get_pending_subjects returns all subjects: everyone is treated as pending and the full subject list is submitted. A warning is printed. The resume flag has no effect for that task.

neuropipe check-outputs Command

Run checks independently of a pipeline submission:

neuropipe check-outputs \
  --project my_study \
  --work /data/work \
  --config-dir /data/config \
  --subjects 001,002,003,004,005

Optional filters

# Check only specific tasks
neuropipe check-outputs \
  --project my_study \
  --work /data/work \
  --config-dir /data/config \
  --subjects 001,002,003 \
  --task rest_preprocess

# Point to a non-default checks file
neuropipe check-outputs \
  --project my_study \
  --work /data/work \
  --config-dir /data/config \
  --subjects 001,002,003 \
  --checks-dir /path/to/custom/checks/

Output

The command prints a terminal summary and saves a full CSV report:

[check-outputs] Issues found:
  rest_preprocess: 002, 004
  volume: 004

The CSV is written to {work_dir}/check_results_{timestamp}.csv with one row per check item:

ColumnDescription
taskTask name
subjectSubject ID
sessionSession label
check_typerequired_files or count_check:{label}
patternThe glob pattern that was evaluated
expectedexists, exists + ≥N KB, or N±tolerance
actualNumber of files found
statusPASS or FAIL – reason

Example output (3 subjects, 2 tasks):

tasksubjectsessioncheck_typepatternexpectedactualstatus
rest_preprocess00101required_filessub-{subject}*.htmlexists + ≥500 KB1PASS
rest_preprocess00201required_filessub-{subject}*.htmlexists + ≥500 KB0FAIL – file not found
rest_preprocess00301required_filessub-{subject}*.htmlexists + ≥500 KB1FAIL – file exists but too small (< 500 KB)
recon00101count_check:anatanat/*.nii.gz1±01PASS
recon00101count_check:fmapfmap/*.nii.gz4±14PASS
recon00201count_check:anatanat/*.nii.gz1±01PASS
recon00201count_check:fmapfmap/*.nii.gz4±12FAIL – too few files on fmap (got 2, expected 4±1)
recon00301count_check:anatanat/*.nii.gz1±01PASS
recon00301count_check:fmapfmap/*.nii.gz4±15PASS

The terminal summary only shows which subjects failed, not why. Open the CSV for the per-check detail.

Tips

Using ** for recursive search:

required_files:
  - pattern: "**/sub-{subject}*space-T1w_boldref.nii.gz"

Checking a directory exists (not just a file):
Check for a file that is always present inside the directory, e.g. a report HTML or a known output file.

Debugging a failing check:
Run check-outputs and open the CSV. The pattern and actual columns show exactly what was globbed and how many files were found. Resolve the output_path manually on the HPC to verify the path is correct:

ls /data/work/my_study/BIDS_derivatives/fmriprep/sub-002*.html