Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 54 additions & 26 deletions qap/qap_workflows.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ def qap_gather_header_info(workflow, resource_pool, config, name="_",
gather_header.inputs.in_file = resource_pool["functional_scan"]
gather_header.inputs.type = data_type


out_dir = os.path.join(config['output_directory'], "derivatives",
config["run_name"], config["subject_id"],
config["session_id"])
Expand Down Expand Up @@ -612,8 +613,14 @@ def qap_anatomical_spatial_workflow(workflow, resource_pool, config, name="_",
resource_pool['anatomical_csf_mask']

if config.get('write_report', False):
qa_out_dir = os.path.join(config['output_directory'], config["run_name"], "QA")
out_mosaic = os.path.join(qa_out_dir, "%s_%s_%s_mosaic.png"
% (config["subject_id"], config["session_id"],
config["scan_id"]))
plot = pe.Node(PlotMosaic(), name='plot_mosaic%s' % name)
plot.inputs.subject = config['subject_id']
plot.inputs.out_file = out_mosaic


metadata = [config['session_id'], config['scan_id']]
if 'site_name' in config.keys():
Expand All @@ -631,6 +638,7 @@ def qap_anatomical_spatial_workflow(workflow, resource_pool, config, name="_",
resource_pool['mean_epi_mosaic'] = (plot, 'out_file')
resource_pool['qap_mosaic'] = (plot, 'out_file')


out_dir = os.path.join(config['output_directory'], "derivatives",
config["run_name"], config["subject_id"],
config["session_id"])
Expand Down Expand Up @@ -873,6 +881,7 @@ def run_everything_qap_anatomical_spatial(
return workflow, workflow.base_dir



def qap_functional_workflow(workflow, resource_pool, config, name="_"):
"""Build and run a Nipype workflow to calculate the QAP functional
temporal quality measures.
Expand Down Expand Up @@ -938,7 +947,7 @@ def qap_functional_workflow(workflow, resource_pool, config, name="_"):
qap_functional_spatial, global_signal_time_series
from qap_utils import write_json
from temporal_qc import fd_jenkinson
from qap.viz.interfaces import PlotMosaic, PlotFD
from qap.viz.interfaces import PlotMosaic, GrayPlot

def _getfirst(inlist):
if isinstance(inlist, list):
Expand Down Expand Up @@ -1069,18 +1078,52 @@ def _getfirst(inlist):
output_names=["output"], function=global_signal_time_series),
name="global_signal_time_series%s" % name)

qa_out_dir = os.path.join(config['output_directory'], config["run_name"], "QA")

if config.get('write_report', False):
metadata = [config['session_id'], config['scan_id']]
if 'site_name' in config.keys():
metadata.append(config['site_name'])

out_fd = os.path.join(qa_out_dir, "%s_%s_%s_timeseries_measures.png"
% (config["subject_id"], config["session_id"],
config["scan_id"]))

def pick_dvars(qa, dict_id):
print qa[dict_id]
dvars = qa[dict_id]['Standardized DVARS']
return dvars

grayplot = pe.Node(GrayPlot(), name='grayplot%s' % name)
grayplot.inputs.subject = config['subject_id']
grayplot.inputs.out_file = out_fd
id_string = "%s %s %s" % (config["subject_id"], config["session_id"], config["scan_id"])
grayplot.inputs.metadata = [id_string]
workflow.connect(fd, 'out_file', grayplot, 'meanfd_file')
dict_id = "%s %s %s"%(config["subject_id"], config["session_id"],config["scan_id"])
workflow.connect(temporal, ('qa', pick_dvars, dict_id), grayplot, 'dvars')
workflow.connect(gs_ts, 'output', grayplot, 'global_signal')
resource_pool['qap_fd'] = (grayplot, 'out_file')

# func reorient (timeseries) -> QAP func temp
if len(resource_pool['func_reorient']) == 2:
node, out_file = resource_pool['func_reorient']
workflow.connect(node, out_file, temporal, 'func_timeseries')
workflow.connect(node, out_file, gs_ts, 'functional_file')

if config.get('write_report', False):
workflow.connect(node, out_file, grayplot, 'func_file')

else:
from qap_utils import check_input_resources
check_input_resources(resource_pool, 'func_reorient')
input_file = resource_pool['func_reorient']
temporal.inputs.func_timeseries = input_file
gs_ts.inputs.functional_file = input_file

if config.get('write_report', False):
grayplot.inputs.func_file = input_file

# func mean (one volume) -> QAP func temp
if len(resource_pool['mean_functional']) == 2:
node, out_file = resource_pool['mean_functional']
Expand All @@ -1095,9 +1138,16 @@ def _getfirst(inlist):
if len(resource_pool['functional_brain_mask']) == 2:
node, out_file = resource_pool['functional_brain_mask']
workflow.connect(node, out_file, temporal, 'func_brain_mask')

if config.get('write_report', False):
workflow.connect(node, out_file, grayplot, 'mask_file')

else:
temporal.inputs.func_brain_mask = \
resource_pool['functional_brain_mask']

if config.get('write_report', False):
grayplot.inputs.mask_file = resource_pool['functional_brain_mask']

# inverted functional brain mask -> QAP func temp
if len(resource_pool['inverted_functional_brain_mask']) == 2:
Expand All @@ -1107,28 +1157,18 @@ def _getfirst(inlist):
temporal.inputs.bg_func_brain_mask = \
resource_pool['inverted_functional_brain_mask']


# temporal STD -> QAP func temp
if isinstance(resource_pool['SFS'], tuple):
node, out_file = resource_pool['SFS']
workflow.connect(node, out_file, temporal, 'sfs')
else:
temporal.inputs.sfs = resource_pool['SFS']

# Write mosaic and FD plot
if config['write_report']:
metadata = [config['session_id'], config['scan_id']]
if 'site_name' in config.keys():
metadata.append(config['site_name'])

fdplot = pe.Node(PlotFD(), name='plot_fd%s' % name)
fdplot.inputs.subject = config['subject_id']
fdplot.inputs.metadata = metadata
workflow.connect(fd, 'out_file', fdplot, 'in_file')
resource_pool['qap_fd'] = (fdplot, 'out_file')

out_dir = os.path.join(config['output_directory'], "derivatives",
config["run_name"], config["subject_id"],
config["session_id"])

out_json = os.path.join(out_dir, "%s_%s_%s_qap-functional.json"
% (config["subject_id"], config["session_id"],
config["scan_id"]))
Expand Down Expand Up @@ -1171,22 +1211,10 @@ def _getfirst(inlist):
workflow.connect(temporal, 'qa', qa_to_json, 'output_dict')
resource_pool['QA_func'] = qa_out_json


id_string = "%s %s %s" % (config["subject_id"], config["session_id"],
config["scan_id"])

if config['write_report']:
metadata = [config['session_id'], config['scan_id']]
if 'site_name' in config.keys():
metadata.append(config['site_name'])

fdplot = pe.Node(PlotFD(), name='plot_fd%s' % name)
fdplot.inputs.subject = config['subject_id']
fdplot.inputs.metadata = [id_string]
workflow.connect(fd, 'out_file', fdplot, 'meanfd_file')
workflow.connect(temporal, 'qa', fdplot, 'dvars')
workflow.connect(gs_ts, 'output', fdplot, 'global_signal')
resource_pool['qap_fd'] = (fdplot, 'out_file')

return workflow, resource_pool


Expand Down
3 changes: 2 additions & 1 deletion qap/qap_workflows_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ def global_signal_time_series(functional_file):
# maybe numpy can do it in one line
for i in range(time):
output[i] = func[:,:,:,i].mean()
return output
output = (output - min(output))/(max(output) - min(output))
return output.tolist()


def convert_allineate_xfm(mat_list):
Expand Down
4 changes: 2 additions & 2 deletions qap/viz/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
# vi: set ft=python sts=4 ts=4 sw=4 et:

from reports import *
from plotting import plot_measures, plot_mosaic, plot_all, plot_fd
#import individual_report
from plotting import plot_measures, plot_mosaic, plot_all, grayplot

28 changes: 14 additions & 14 deletions qap/viz/interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
BaseInterfaceInputSpec, isdefined,
DynamicTraitedSpec, Undefined)

from .plotting import (plot_mosaic, plot_fd)
from .plotting import (plot_mosaic, grayplot)

from nipype import logging
iflogger = logging.getLogger('interface')
Expand Down Expand Up @@ -80,37 +80,37 @@ def _list_outputs(self):
return outputs


class PlotFDInputSpec(BaseInterfaceInputSpec):
class GrayPlotInputSpec(BaseInterfaceInputSpec):
func_file = File(exists=True, mandatory=True, desc='functional file to be plotted in gray plot')
mask_file = File(exists=True, mandatory=True, desc='file for mask functional data')
meanfd_file = File(exists=True, mandatory=True, desc='mean fd file to be plotted')
dvars = traits.Dict(mandatory=True, desc='dvars float array be plotted')
dvars = traits.List(traits.Float, mandatory=True, desc='dvars float array be plotted')
global_signal = traits.List(traits.Float, mandatory=True, desc='global signal to be plotted')
metadata = traits.List(traits.Str, mandatory=True, desc='additional metadata')
title = traits.Str('Mean FD, DVARS ad global Signal', usedefault=True,
title = traits.Str('Timeseries Plot', usedefault=True,
desc='modality name to be prepended')
subject = traits.Str(desc='Subject id')
dpi = traits.Int(300, usedefault=True, desc='Desired DPI of figure')
out_file = File('fd.png', usedefault=True, desc='output file name')
out_file = File('grayplot.png', usedefault=True, desc='output file name')


class PlotFDOutputSpec(TraitedSpec):
out_file = File(exists=True, desc='output pdf file')

class GrayPlotOutputSpec(TraitedSpec):
out_file = File(exists=True, desc='output png file')

class PlotFD(BaseInterface):

class GrayPlot(BaseInterface):
"""
Plots the frame displacement of a dataset
"""
input_spec = PlotFDInputSpec
output_spec = PlotFDOutputSpec
input_spec = GrayPlotInputSpec
output_spec = GrayPlotOutputSpec

def _run_interface(self, runtime):
title = self.inputs.title
if isdefined(self.inputs.subject):
title += ', subject %s' % self.inputs.subject
title += ', %s' % self.inputs.subject
fig = grayplot(self.inputs.func_file, self.inputs.mask_file, self.inputs.meanfd_file, self.inputs.dvars, self.inputs.global_signal, self.inputs.metadata, title=title)

fig = plot_fd(self.inputs.meanfd_file, self.inputs.dvars,
self.inputs.global_signal, self.inputs.metadata)

fig.savefig(self.inputs.out_file, dpi=float(self.inputs.dpi))

Expand Down
Loading