Skip to content

Commit

Permalink
Fix many things.
Browse files Browse the repository at this point in the history
  • Loading branch information
tsalo committed Nov 21, 2023
1 parent 560e052 commit 6fbc653
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 34 deletions.
7 changes: 4 additions & 3 deletions aslprep/interfaces/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@
"""Nipype interfaces for aslprep."""
from aslprep.interfaces.bids import DerivativesDataSink
from aslprep.interfaces.confounds import GatherConfounds
from aslprep.interfaces.plotting import ASLSummary, CBFSummary, CBFtsSummary
from aslprep.interfaces.reports import AboutSummary, FunctionalSummary, SubjectSummary
from aslprep.interfaces.plotting import ASLCarpetPlot, CBFSummaryPlot, CBFtsSummary
from aslprep.interfaces.reports import AboutSummary, CBFSummary, FunctionalSummary, SubjectSummary

__all__ = [
"SubjectSummary",
"FunctionalSummary",
"AboutSummary",
"GatherConfounds",
"ASLSummary",
"ASLCarpetPlot",
"CBFSummary",
"CBFSummaryPlot",
"CBFtsSummary",
"DerivativesDataSink",
]
24 changes: 13 additions & 11 deletions aslprep/interfaces/plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from aslprep.utils.plotting import CBFPlot, CBFtsPlot, fMRIPlot


class _ASLSummaryInputSpec(BaseInterfaceInputSpec):
class _ASLCarpetPlotInputSpec(BaseInterfaceInputSpec):
in_nifti = File(exists=True, mandatory=True, desc="input BOLD (4D NIfTI file)")
in_cifti = File(exists=True, desc="input BOLD (CIFTI dense timeseries)")
in_segm = File(exists=True, desc="volumetric segmentation corresponding to in_nifti")
Expand All @@ -36,15 +36,17 @@ class _ASLSummaryInputSpec(BaseInterfaceInputSpec):
drop_trs = traits.Int(0, usedefault=True, desc="dummy scans")


class _ASLSummaryOutputSpec(TraitedSpec):
class _ASLCarpetPlotOutputSpec(TraitedSpec):
out_file = File(exists=True, desc="written file path")


class ASLSummary(SimpleInterface):
"""Copy the x-form matrices from `hdr_file` to `out_file`."""
class ASLCarpetPlot(SimpleInterface):
"""Create a combined carpet/line plot for ASL time series data.
input_spec = _ASLSummaryInputSpec
output_spec = _ASLSummaryOutputSpec
Copy the x-form matrices from `hdr_file` to `out_file`."""

input_spec = _ASLCarpetPlotInputSpec
output_spec = _ASLCarpetPlotOutputSpec

def _run_interface(self, runtime):
self._results["out_file"] = fname_presuffix(
Expand Down Expand Up @@ -125,25 +127,25 @@ def _run_interface(self, runtime):
return runtime


class _CBFSummaryInputSpec(BaseInterfaceInputSpec):
class _CBFSummaryPlotInputSpec(BaseInterfaceInputSpec):
cbf = File(exists=True, mandatory=True, desc="")
label = traits.Str(exists=True, mandatory=True, desc="label")
vmax = traits.Int(exists=True, default_value=90, mandatory=True, desc="max value of asl")
ref_vol = File(exists=True, mandatory=True, desc="")


class _CBFSummaryOutputSpec(TraitedSpec):
class _CBFSummaryPlotOutputSpec(TraitedSpec):
out_file = File(exists=True, desc="written file path")


class CBFSummary(SimpleInterface):
class CBFSummaryPlot(SimpleInterface):
"""Prepare an CBF summary plot for the report.
This plot restricts CBF values to -20 (if there are negative values) or 0 (if not) to 100.
"""

input_spec = _CBFSummaryInputSpec
output_spec = _CBFSummaryOutputSpec
input_spec = _CBFSummaryPlotInputSpec
output_spec = _CBFSummaryPlotOutputSpec

def _run_interface(self, runtime):
self._results["out_file"] = fname_presuffix(
Expand Down
45 changes: 36 additions & 9 deletions aslprep/interfaces/reports.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@
\t\t\t<li>Phase-encoding (PE) direction: {pedir}</li>
\t\t\t<li>Susceptibility distortion correction: {sdc}</li>
\t\t\t<li>Registration: {registration}</li>
\t\t</ul>
"""

QC_TEMPLATE = """\t\t<h3 class="elem-title">QC Summary</h3>
\t\t<ul class="elem-desc">
\t\t\t<li>Confounds collected: {confounds}</li>
\t\t\t<li>Motion summary measures: {motionparam}</li>
\t\t\t<li>Coregistration quality: {coregindex}</li>
Expand Down Expand Up @@ -206,6 +212,35 @@ def _generate_segment(self):

pedir = get_world_pedir(self.inputs.orientation, self.inputs.pe_direction)

if self.inputs.pe_direction is None:
pedir = "MISSING - Assuming Anterior-Posterior"
else:
pedir = {"i": "Left-Right", "j": "Anterior-Posterior"}[self.inputs.pe_direction[0]]

# the number of dummy scans was specified by the user and
# it is not equal to the number detected by the algorithm

# the number of dummy scans was not specified by the user

return FUNCTIONAL_TEMPLATE.format(
pedir=pedir,
sdc=self.inputs.distortion_correction,
registration=reg,
tr=self.inputs.tr,
)


class _CBFSummaryInputSpec(BaseInterfaceInputSpec):
confounds_file = File(exists=True, mandatory=False, desc="Confounds file")
qc_file = File(exists=True, desc="qc file")


class CBFSummary(SummaryInterface):
"""A summary of a functional run, with QC measures included."""

input_spec = _CBFSummaryInputSpec

def _generate_segment(self):
qcfile = pd.read_csv(self.inputs.qc_file)
motionparam = f"FD : {round(qcfile['FD'][0], 4)}, rmsd: {round(qcfile['rmsd'][0], 4)} "
coregindex = (
Expand Down Expand Up @@ -239,10 +274,6 @@ def _generate_segment(self):
f"basil: {round(qcfile['NEG_BASIL_PERC'][0], 2)}, "
f"pvc: {round(qcfile['NEG_PVC_PERC'][0], 2)} "
)
if self.inputs.pe_direction is None:
pedir = "MISSING - Assuming Anterior-Posterior"
else:
pedir = {"i": "Left-Right", "j": "Anterior-Posterior"}[self.inputs.pe_direction[0]]

if isdefined(self.inputs.confounds_file):
with open(self.inputs.confounds_file) as cfh:
Expand All @@ -254,12 +285,8 @@ def _generate_segment(self):

# the number of dummy scans was not specified by the user

return FUNCTIONAL_TEMPLATE.format(
pedir=pedir,
sdc=self.inputs.distortion_correction,
registration=reg,
return QC_TEMPLATE.format(
confounds=re.sub(r"[\t ]+", ", ", conflist),
tr=self.inputs.tr,
motionparam=motionparam,
qei=qei,
coregindex=coregindex,
Expand Down
4 changes: 4 additions & 0 deletions aslprep/workflows/asl/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -722,9 +722,13 @@ def init_asl_preproc_wf(
("t1w_dseg", "inputnode.t1w_dseg"),
("mni2009c2anat_xfm", "inputnode.std2anat_xfm"),
]),
(asl_confounds_wf, plot_cbf_wf, [
("outputnode.confounds_file", "inputnode.confounds_file"),
]),
(cbf_wf, plot_cbf_wf, [
("outputnode.score_outlier_index", "inputnode.score_outlier_index"),
]),
(cbf_qc_wf, plot_cbf_wf, [("outputnode.qc_file", "inputnode.qc_file")]),
(asl_fit_wf, plot_cbf_wf, [
("outputnode.coreg_aslref", "inputnode.aslref"),
("outputnode.aslref2anat_xfm", "inputnode.aslref2anat_xfm"),
Expand Down
4 changes: 2 additions & 2 deletions aslprep/workflows/asl/confounds.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from templateflow.api import get as get_template

from aslprep.config import DEFAULT_MEMORY_MIN_GB
from aslprep.interfaces import ASLSummary, DerivativesDataSink, GatherConfounds
from aslprep.interfaces import ASLCarpetPlot, DerivativesDataSink, GatherConfounds
from aslprep.interfaces.ants import ApplyTransforms


Expand Down Expand Up @@ -375,7 +375,7 @@ def init_carpetplot_wf(

# Carpetplot and confounds plot
conf_plot = pe.Node(
ASLSummary(
ASLCarpetPlot(
tr=metadata["RepetitionTime"],
confounds_list=confounds_list,
),
Expand Down
7 changes: 5 additions & 2 deletions aslprep/workflows/asl/fit.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ def init_asl_fit_wf(
)

reduce_asl_file = pe.Node(
ReduceASLFiles(),
ReduceASLFiles(metadata=metadata),
name="reduce_asl_file",
)
# fmt:off
Expand Down Expand Up @@ -401,7 +401,10 @@ def init_asl_fit_wf(
# fmt:off
workflow.connect([
(hmcref_buffer, asl_hmc_wf, [("aslref", "inputnode.raw_ref_image")]),
(reduce_asl_file, asl_hmc_wf, [("asl_file", "inputnode.asl_file")]),
(reduce_asl_file, asl_hmc_wf, [
("asl_file", "inputnode.asl_file"),
("aslcontext", "inputnode.aslcontext"),
]),
(asl_hmc_wf, ds_hmc_wf, [("outputnode.xforms", "inputnode.xforms")]),
(asl_hmc_wf, hmc_buffer, [
("outputnode.xforms", "hmc_xforms"),
Expand Down
30 changes: 23 additions & 7 deletions aslprep/workflows/asl/plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
from aslprep.interfaces import DerivativesDataSink
from aslprep.interfaces.ants import ApplyTransforms
from aslprep.interfaces.confounds import GatherCBFConfounds
from aslprep.interfaces.plotting import CBFByTissueTypePlot, CBFSummary
from aslprep.interfaces.plotting import CBFByTissueTypePlot, CBFSummaryPlot
from aslprep.interfaces.reports import CBFSummary
from aslprep.utils.misc import _select_last_in_list
from aslprep.workflows.asl.confounds import init_carpetplot_wf

Expand Down Expand Up @@ -49,6 +50,8 @@ def init_plot_cbf_wf(
"t1w_dseg",
"aslref2anat_xfm",
"std2anat_xfm",
"confounds_file",
"qc_file",
# If plot_timeseries is True
"crown_mask",
"acompcor_masks",
Expand All @@ -68,11 +71,24 @@ def init_plot_cbf_wf(
"mean_cbf_gm_basil",
"mean_cbf_wm_basil", # unused
"att_basil", # unused
]
],
),
name="inputnode",
)

summary = pe.Node(
CBFSummary(),
name="summary",
mem_gb=config.DEFAULT_MEMORY_MIN_GB,
run_without_submitting=True,
)
workflow.connect([
(inputnode, summary, [
("confounds_file", "confounds_file"),
("qc_file", "qc_file"),
])
]) # fmt:skip

# Warp dseg file from T1w space to ASL reference space
warp_t1w_dseg_to_aslref = pe.Node(
ApplyTransforms(
Expand Down Expand Up @@ -168,7 +184,7 @@ def init_plot_cbf_wf(
])
# fmt:on

cbf_summary = pe.Node(CBFSummary(label="cbf", vmax=100), name="cbf_summary", mem_gb=1)
cbf_summary = pe.Node(CBFSummaryPlot(label="cbf", vmax=100), name="cbf_summary", mem_gb=1)

# fmt:off
workflow.connect([
Expand Down Expand Up @@ -211,7 +227,7 @@ def init_plot_cbf_wf(

if scorescrub:
score_summary = pe.Node(
CBFSummary(label="score", vmax=100),
CBFSummaryPlot(label="score", vmax=100),
name="score_summary",
mem_gb=1,
)
Expand Down Expand Up @@ -260,7 +276,7 @@ def init_plot_cbf_wf(
# fmt:on

scrub_summary = pe.Node(
CBFSummary(label="scrub", vmax=100),
CBFSummaryPlot(label="scrub", vmax=100),
name="scrub_summary",
mem_gb=1,
)
Expand Down Expand Up @@ -310,7 +326,7 @@ def init_plot_cbf_wf(

if basil:
basil_summary = pe.Node(
CBFSummary(label="basil", vmax=100),
CBFSummaryPlot(label="basil", vmax=100),
name="basil_summary",
mem_gb=1,
)
Expand Down Expand Up @@ -359,7 +375,7 @@ def init_plot_cbf_wf(
# fmt:on

pvc_summary = pe.Node(
CBFSummary(label="pvc", vmax=120),
CBFSummaryPlot(label="pvc", vmax=120),
name="pvc_summary",
mem_gb=1,
)
Expand Down

0 comments on commit 6fbc653

Please sign in to comment.