Skip to content

Commit

Permalink
[ENH] Update pyafq; add pyafq full test (#533)
Browse files Browse the repository at this point in the history
  • Loading branch information
36000 committed Mar 10, 2023
1 parent b6e3867 commit 8080311
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 34 deletions.
23 changes: 20 additions & 3 deletions .circleci/PyAFQReconTests.sh
Expand Up @@ -26,8 +26,8 @@ EDDY_CFG=${TESTDIR}/data/eddy_config.json
export FS_LICENSE=${TESTDIR}/data/license.txt


# Test pyAFQ_full
TESTNAME=pyafq_input_trk_test
# Test pyafq_tractometry
TESTNAME=pyafq_tractometry_test
setup_dir ${TESTDIR}/${TESTNAME}
TEMPDIR=${TESTDIR}/${TESTNAME}/work
OUTPUT_DIR=${TESTDIR}/${TESTNAME}/derivatives
Expand All @@ -38,6 +38,23 @@ ${QSIPREP_CMD} \
-w ${TEMPDIR} \
--recon-input ${BIDS_INPUT_DIR} \
--sloppy \
--recon-spec pyafq_input_trk \
--recon-spec pyafq_tractometry \
--recon-only \
-vv


# Test mrtrix_multishell_msmt_pyafq_tractometry
TESTNAME=mrtrix_multishell_msmt_pyafq_tractometry_test
setup_dir ${TESTDIR}/${TESTNAME}
TEMPDIR=${TESTDIR}/${TESTNAME}/work
OUTPUT_DIR=${TESTDIR}/${TESTNAME}/derivatives
BIDS_INPUT_DIR=${TESTDIR}/data/multishell_output/qsiprep
QSIPREP_CMD=$(run_qsiprep_cmd ${BIDS_INPUT_DIR} ${OUTPUT_DIR})

${QSIPREP_CMD} \
-w ${TEMPDIR} \
--recon-input ${BIDS_INPUT_DIR} \
--sloppy \
--recon-spec mrtrix_multishell_msmt_pyafq_tractometry \
--recon-only \
-vv
10 changes: 6 additions & 4 deletions docs/reconstruction.rst
Expand Up @@ -288,7 +288,7 @@ used for tractography with no T1w-based anatomical constraints.

.. _pyafq:

``pyafq``
``pyafq_tractometry``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

This workflow uses the AFQ [Yeatman2012]_ implemented in Python [Kruper2021]_ to recognize
Expand All @@ -297,11 +297,13 @@ those pathways. See the `pyAFQ documentation <https://yeatmanlab.github.io/pyAFQ

.. _pyafq_input_trk:

``pyafq_input_trk``
``mrtrix_multishell_msmt_pyafq_tractometry``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Identical to :ref:`pyafq` except that tractography generated using another reconstruciton pipeline
(such as MRTrix3), instead of using pyAFQ's default DIPY tractography.
Identical to :ref:`pyafq` except that tractography generated using IFOD2 from MRTrix3,
instead of using pyAFQ's default DIPY tractography.
This can also be used as an example for how to import tractographies from other
reconstruciton pipelines to pyAFQ.


.. _amico_noddi:
Expand Down
@@ -1,7 +1,7 @@
{
"description": "Use pyAFQ to perform the Tractometry pipeline, with tractography from qsiprep",
"space": "T1w",
"name": "pyAFQ_import_trk",
"name": "mrtrix_multishell_msmt_pyafq_tractometry",
"atlases": [],
"nodes": [
{
Expand Down Expand Up @@ -41,13 +41,14 @@
}
},
{
"name": "pyAFQ_full",
"name": "pyafq_tractometry",
"software": "pyAFQ",
"action": "pyAFQ_full",
"action": "pyafq_tractometry",
"input": "track_ifod2",
"output_suffix": "PYAFQ_FULL_ET",
"output_suffix": "PYAFQ_TRACTOMETRY_ET",
"parameters": {
"use_external_tracking": true,
"export": "all",
"directions": "prob",
"max_angle": 30.0,
"sphere": "",
Expand All @@ -59,8 +60,8 @@
"stop_mask": "",
"stop_threshold": 0,
"step_size": 0.5,
"min_length": 10,
"max_length": 1000,
"min_length": 50,
"max_length": 250,
"odf_model": "CSD",
"tracker": "local",
"nb_points": false,
Expand Down Expand Up @@ -89,7 +90,7 @@
"save_intermediates": "",
"n_points": 100,
"clean_rounds": 5,
"distance_threshold": 5,
"distance_threshold": 3,
"length_threshold": 4,
"min_sl": 20,
"stat": "mean",
Expand Down
@@ -1,17 +1,18 @@
{
"description": "Use pyAFQ to perform the full Tractometry pipeline",
"space": "T1w",
"name": "pyAFQ_full",
"name": "pyafq_tractometry",
"atlases": [],
"nodes": [
{
"name": "pyAFQ_full",
"name": "pyafq_tractometry",
"software": "pyAFQ",
"action": "pyAFQ_full",
"action": "pyafq_tractometry",
"input": "qsiprep",
"output_suffix": "PYAFQ_FULL",
"output_suffix": "PYAFQ_TRACTOMETRY",
"parameters": {
"use_external_tracking": false,
"export": "all",
"directions": "prob",
"max_angle": 30.0,
"sphere": "",
Expand All @@ -23,8 +24,8 @@
"stop_mask": "",
"stop_threshold": 0,
"step_size": 0.5,
"min_length": 10,
"max_length": 1000,
"min_length": 50,
"max_length": 250,
"odf_model": "CSD",
"tracker": "local",
"nb_points": false,
Expand Down Expand Up @@ -53,7 +54,7 @@
"save_intermediates": "",
"n_points": 100,
"clean_rounds": 5,
"distance_threshold": 5,
"distance_threshold": 3,
"length_threshold": 4,
"min_sl": 20,
"stat": "mean",
Expand Down
19 changes: 8 additions & 11 deletions qsiprep/interfaces/pyafq.py
Expand Up @@ -56,8 +56,6 @@ def _run_interface(self, runtime):
newpath=shim_dir)
mask_file = fname_presuffix(self.inputs.mask_file,
newpath=shim_dir)
tck_file = fname_presuffix(self.inputs.tck_file,
newpath=shim_dir)
itk_file = fname_presuffix(self.inputs.itk_file,
newpath=shim_dir)
os.symlink(self.inputs.bval_file, bval_file)
Expand All @@ -69,6 +67,8 @@ def _run_interface(self, runtime):
kwargs = self.inputs.kwargs

if self.inputs.tck_file and isdefined(self.inputs.tck_file):
tck_file = fname_presuffix(self.inputs.tck_file,
newpath=shim_dir)
os.symlink(self.inputs.tck_file, tck_file)
else:
tck_file = None
Expand All @@ -77,16 +77,13 @@ def _run_interface(self, runtime):

if tck_file is None:
tck_file = kwargs['import_tract']
else:
kwargs.pop('import_tract', None)
kwargs.pop('import_tract', None)
if brain_mask_definition is None:
brain_mask_definition = kwargs['brain_mask_definition']
else:
kwargs.pop('brain_mask_definition', None)
if itk_map is None:
itk_map = kwargs['mapping_definition']
else:
kwargs.pop('mapping_definition', None)
kwargs.pop('brain_mask_definition', None)
# if itk_map is None: # Use pyAFQ internal mapping
# itk_map = kwargs['mapping_definition']
# kwargs.pop('mapping_definition', None)

if 'parallel_segmentation' in kwargs:
if 'n_jobs' not in kwargs['parallel_segmentation']\
Expand All @@ -102,7 +99,7 @@ def _run_interface(self, runtime):
dwi_file, bval_file, bvec_file, output_dir,
import_tract=tck_file,
brain_mask_definition=brain_mask_definition,
mapping_definition=itk_map,
# mapping_definition=itk_map,
**kwargs)
myafq.export("profiles")

Expand Down
2 changes: 1 addition & 1 deletion qsiprep/workflows/recon/build_workflow.py
Expand Up @@ -212,7 +212,7 @@ def workflow_from_spec(omp_nthreads, available_anatomical_data, node_spec,
return init_amico_noddi_fit_wf(**kwargs)

elif software == "pyAFQ":
if node_spec["action"] == "pyAFQ_full":
if node_spec["action"] == "pyafq_tractometry":
return init_pyafq_wf(**kwargs)

# qsiprep operations
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Expand Up @@ -54,7 +54,7 @@ install_requires =
scikit-learn >=0.20.2
scikit-image
SimpleITK
pyAFQ >= 0.12
pyAFQ >= 1.0.1
test_requires =
coverage
codecov
Expand Down

0 comments on commit 8080311

Please sign in to comment.