nipreps / sdcflows

Susceptibility Distortion Correction (SDC) workflows for EPI MR schemes
https://www.nipreps.org/sdcflows
Apache License 2.0
30 stars 24 forks source link

SDCflows standalone example #392

Closed SRSteinkamp closed 7 months ago

SRSteinkamp commented 10 months ago

What would you like changed/added and why?

Dear all,

I think for some users (me) it might be useful to have an example of how to use sdcflows as a standalone.

This might be especially due to my ignorance of nipype, but I think it would be very helpful to have an example script or snippet of how to run sdcflows in practice.

For example, it is a bit unclear for me how to proceed after using the find_estimator functions on a dataset.

Cheers Simon

Do you have any interest in helping improve the documentation?

Yes

Do you have any suggestions for the new documents?

No response

effigies commented 9 months ago

Thanks for your patience. This one got away from us. Right now there is no standalone mode, the main purpose is for use in fMRIPrep, dMRIPrep and ASLPrep.

I can try to sketch out a bit...

Once you have estimators, you can use estimator.get_workflow() to get a nipype workflow. You can find the kinds of workflow that will be created here: https://github.com/nipreps/sdcflows/tree/master/sdcflows/workflows/fit

Then you need to understand the mode of operation:

We have multiple ways of computing a fieldmap:

1) Pepolar: (dir1, dir2) -> b-spline estimate -> field -> voxel shift map 2) Phasediff/fieldmap: field estimate -> field -> voxel shift map 3) SyN-SDC: (epi, anat) -> voxel shift map

The voxel shift map is a brittle representation, and the direct field estimate potentially contains high frequency spatial noise. We therefore have shifted to the following method:

  • Fit 1) Pepolar: (dir1, dir2) -> b-spline estimate 2) Phasediff/fieldmap: field estimate -> field -> b-spline estimate 3) SyN-SDC: (epi, anat) -> voxel shift map -> field -> b-spline estimate
  • Apply
    • b-spline estimate -> field -> voxel shift map

So the workflows you get out of estimator.get_workflow() are the fit stage. For application, you need to register your fieldmap to your target data (https://github.com/nipreps/sdcflows/blob/master/sdcflows/workflows/apply/registration.py) and then unwarp (https://github.com/nipreps/sdcflows/blob/master/sdcflows/workflows/apply/correction.py).

To see how this fits together, here's how we use it in fMRIPrep: We find the estimators we need and create a workflow that fits all of them:

https://github.com/nipreps/fmriprep/blob/2e1ee97f579a6936ab8bcd25ef7f13a8c7afad65/fmriprep/workflows/base.py#L248-L351

That workflow has as its outputs a common set of things for each fieldmap that we connect to the functional preprocessing workflow:

https://github.com/nipreps/fmriprep/blob/2e1ee97f579a6936ab8bcd25ef7f13a8c7afad65/fmriprep/workflows/base.py#L390-L402

We then select the fieldmap we want for our particular BOLD file, coregister and unwarp the reference here:

https://github.com/nipreps/fmriprep/blob/2e1ee97f579a6936ab8bcd25ef7f13a8c7afad65/fmriprep/workflows/bold/fit.py#L341-L423

This is all a bit more complicated than a script that needs to cover fewer cases would be. But hopefully this points you in the right direction. It would be good eventually to make a standalone CLI for fit and apply.

SRSteinkamp commented 9 months ago

Thank you so much for the detailed response :) !