Template script for running qsiprep then qsirecon?

Summary of what happened:

Now that qsiprep and qsirecon are split, what are the expected arguments to each so that qsirecon sees the outputs from qsiprep? I tried

qsiprep /bids /output participant

which creates /output/sub-XXXX/ses-YYYY/dwi/

But if I then try:
qsirecon /bids /output participant

Command used (and if a helper script was used, a link to the helper script or the command generated):

apptainer exec --cleanenv --containall \
    -B /mydata/bids:/bids:ro -B /mydata/output:/output -B /mydata/qsiprep_work:/work -B /mydata/scripts:/scripts:ro \
    -B /mydata/templateflow:/opt/templateflow --env TEMPLATEFLOW_HOME=/opt/templateflow \
    -B ${FREESURFER_HOME}:/opt/freesurfer:ro --env FREESURFER_HOME=/opt/freesurfer \
    /mydata/qsiprep-1.0.2.sif \
  qsiprep /bids /output participant \
    --output-resolution 1.5 \
    --pepolar-method TOPUP \
    --hmc-model eddy \
    --distortion-group-merge average \
    --fs-license-file /scripts/freesurfer_license.txt \
    --write-graph --stop-on-first-crash --verbose --resource-monitor \
    --nthreads 40 --omp-nthreads 40  \
    -w /work

apptainer exec --cleanenv --containall \
    -B /mydata/bids:/bids:ro -B /mydata/output:/output -B /mydata/qsirecon_work:/work -B /mydata/scripts:/scripts:ro \
    -B /mydata/templateflow:/opt/templateflow --env TEMPLATEFLOW_HOME=/opt/templateflow \
    -B ${FREESURFER_HOME}:/opt/freesurfer:ro --env FREESURFER_HOME=/opt/freesurfer \
    /mydata/qsirecon-1.0.0.sif \
  qsirecon /bids /output participant \
    --output-resolution 1.5 \
    --input-type qsiprep \
    --recon-spec /scripts/mrtrix_multishell_msmt_noACT.yaml \
    --fs-subjects-dir /output/derivatives/freesurfer \
    --fs-license-file /scripts/freesurfer_license.txt \
    --write-graph --stop-on-first-crash --verbose --notrack --resource-monitor \
    --nthreads 40 --omp-nthreads 40  \
    -w /work

Version:

this is qsiprep 1.0.2 and qsireceon 1.0.0

Environment (Docker, Singularity / Apptainer, custom installation):

Apptainer

Data formatted according to a validatable standard? Please provide the output of the validator:

PASTE VALIDATOR OUTPUT HERE

Relevant log outputs (up to 20 lines):

It starts up but says:

251119-19:32:33,186 nipype.workflow IMPORTANT:
	 Building QSIRecon's workflow:
           * BIDS dataset path: /bids.
           * Participant list: ['XXXXX'].
           * Run identifier: 20251119-193223_3906bf66-4913-4abc-a356-b7aef16cd597.
           * Pre-run FreeSurfer's SUBJECTS_DIR: /output/derivatives/freesurfer.
251119-19:32:34,511 nipype.workflow INFO:
	 No dwi files found for XXXXX
251119-19:32:34,783 nipype.workflow INFO:
	 QSIRecon workflow graph with 0 nodes built successfully.
....
251119-19:32:43,739 nipype.workflow CRITICAL:
	 QSIRecon failed: Graph has no nodes or edges
251119-19:32:43,778 nipype.utils WARNING:
	 DatasetType key not in /bids/dataset_description.json. Assuming 'derivative'.
251119-19:32:43,788 cli INFO:
	 QSIRecon pipeline suffixes: ['MRtrix3_act-None']
251119-19:32:44,264 nipype.utils WARNING:
	 DatasetType key not in /bids/dataset_description.json. Assuming 'derivative'.

and exits without doing anything

Screenshots / relevant information:


Hi @kjamison,

You need to feed in the QSIPrep outputs for QSIRecon’s first positional argument. Also, we do not recommend using the act-None pipeline unless you do not have anatomical data, just a heads up.

Best,
Steven

Thanks for the quick reply!

So what exactly would that call look like? I ran through a couple of variations I thought might work but got various errors each time. Since these two pipelines are intended to be run in sequence, there must be some expected format and I think a precise example running one then the other would be very helpful for users.

(And yes I’m just using that recon-spec as a stand-in while I figure out how to get it running)

Hi @kjamison,

Can you edit your post to add what you have for code now so I can adapt it? The documentation already has this in it as an example (Quick Start — qsirecon 1.1.2.dev21+g3b8865e2b documentation):

Finally, you’ll need to craft a command to set up your QSIRecon run. Suppose you’re in a directory where there are some qsiprep results in inputs/qsiprep. You’d like to save QSIRecon outputs in results. You have access to 8 cpus. To run the from qsirecon-latest.sif you could use:

apptainer run \
    --containall \
    --writable-tmpfs \
    -B "${PWD}" \
    "${QSIRECON_IMG}" \
    "${PWD}/inputs/qsiprep" \
    "${PWD}/results/qsirecon" \
    participant \
    -w "${PWD}/work" \
    --nthreads 8 \
    --omp-nthreads 8 \
    --recon-spec dsi_studio_autotrack \
    -v -v

Best,
Steven

I edited to include my commands.

I saw that in the docs, but it doesn’t include the actual call to qsiprep that would provide the expected directory structure.

HI @kjamison,

There shouldn’t be any special consideration when running QSIPrep, it automatically outputs the expected directory structure. In your second command just input /output/qsiprep as the first positional argument (what you currently have as /bids).

Also, --cleanenv is redundant when you have --containall. We also recommend adding --writable-tmpfs to the apptainer run preamble, it makes some plotting functions work better on HPCs.

Best,
Steven

Not a special consideration, but the qsirecon path arguments depend on the qsiprep path arguments

In this case the confusion is that qsiprep does not create /output/qsiprep/sub-XXXX. It creates /output/sub-XXXX. If I do:

qsiprep /bids /output ...
qsirecon /output /output/qsirecon ...

it works!

The example for qsiprep says:
qsiprep data/bids_root/ out/ participant -w work/

And the initial example for qsirecon says

apptainer run --containall --writable-tmpfs \
    -B "${PWD}" \
   qsiprep-latest.sif 
    "${PWD}/inputs/qsiprep" \
    "${PWD}/results/qsirecon" ...```

It would be very helpful if instead the qsiprep and qsirecon docs started with something more aligned, like:

qsiprep data/bids_root output/qsiprep participant -w work/

or

apptainer run  --containall --writable-tmpfs \
    -B ${PWD} \
    qsiprep-latest.sif \
    ${PWD}/data/bids_root \
    ${PWD}/output/qsiprep ...

and then the qsirecon is accordingly:

qsirecon output/qsiprep output/qsirecon participant -w work/

or

apptainer run  --containall --writable-tmpfs \
    -B ${PWD} \
    qsirecon-latest.sif \
    ${PWD}/output/qsiprep \
    ${PWD}/output/qsirecon ...

Ah right, yah qsiprep/recon no longer hard codes the output directory name, so people can be flexible in naming (e.g., name it outputs/qsiprep_{version} if they wanted to).