Skip to content

Commit

Permalink
Merge pull request #193 from chrisfilo/enh/aroma_rpt
Browse files Browse the repository at this point in the history
[RTM] ICA AROM supports
  • Loading branch information
effigies authored Aug 5, 2017
2 parents 841c329 + 3acfea6 commit a1204f0
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 13 deletions.
36 changes: 36 additions & 0 deletions niworkflows/interfaces/segmentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,39 @@ def _post_run_hook(self, runtime):
self._melodic_dir = outputs.out_dir

NIWORKFLOWS_LOG.info('Generating report for MELODIC')


class ICA_AROMAInputSpecRPT(nrc.ReportCapableInputSpec,
fsl.aroma.ICA_AROMAInputSpec):
out_report = File(
'ica_aroma_reportlet.svg', usedefault=True, desc='Filename for the visual'
' report generated '
'by Nipype.')
report_mask = File(desc='Mask used to draw the outline on the reportlet. '
'If not set the mask will be derived from the data.')

class ICA_AROMAOutputSpecRPT(nrc.ReportCapableOutputSpec,
fsl.aroma.ICA_AROMAOutputSpec):
pass


class ICA_AROMARPT(nrc.ReportCapableInterface, fsl.ICA_AROMA):
input_spec = ICA_AROMAInputSpecRPT
output_spec = ICA_AROMAOutputSpecRPT

def _generate_report(self):
from niworkflows.viz.utils import plot_melodic_components
plot_melodic_components(melodic_dir=self.inputs.melodic_dir,
in_file=self.inputs.in_file,
out_file=self.inputs.out_report,
compress=self.inputs.compress_report,
report_mask=self.inputs.report_mask,
noise_components_file=self._noise_components_file
)

def _post_run_hook(self, runtime):
outputs = self.aggregate_outputs(runtime=runtime)
self._noise_components_file = os.path.join(outputs.out_dir,
"classified_motion_ICs.txt")

NIWORKFLOWS_LOG.info('Generating report for ICA AROMA')
52 changes: 39 additions & 13 deletions niworkflows/viz/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,18 +448,24 @@ def compose_view(bg_svgs, fg_svgs, ref=0, out_file='report.svg'):
out_file = op.abspath(out_file)
fig.save(out_file)

# Post processing
with open(out_file, 'r' if PY3 else 'rb') as f:
svg = f.read().split('\n')

# Remove <?xml... line
if svg[0].startswith("<?xml"):
svg = svg[1:]

# Add styles for the flicker animation
if fg_svgs:
with open(out_file, 'r' if PY3 else 'rb') as f:
svg = f.read().split('\n')

svg.insert(2, """<style type="text/css">
@keyframes flickerAnimation%s { 0%% {opacity: 1;} 100%% { opacity: 0; }}
.foreground-svg { animation: 1s ease-in-out 0s alternate none infinite paused flickerAnimation%s;}
.foreground-svg:hover { animation-play-state: running;}
</style>""" % tuple([uuid4()] * 2))
with open(out_file, 'w' if PY3 else 'wb') as f:
f.write('\n'.join(svg))

with open(out_file, 'w' if PY3 else 'wb') as f:
f.write('\n'.join(svg))
return out_file


Expand Down Expand Up @@ -488,7 +494,8 @@ def transform_to_2d(data, max_axis):

def plot_melodic_components(melodic_dir, in_file, tr=None,
out_file='melodic_reportlet.svg',
compress='auto', report_mask=None):
compress='auto', report_mask=None,
noise_components_file=None):
from nilearn.plotting import plot_glass_brain
from nilearn.image import index_img, iter_img
import nibabel as nb
Expand All @@ -497,6 +504,7 @@ def plot_melodic_components(melodic_dir, in_file, tr=None,
import seaborn as sns
from matplotlib.gridspec import GridSpec
import os
import re
from io import StringIO
sns.set_style("white")
current_palette = sns.color_palette()
Expand Down Expand Up @@ -546,13 +554,27 @@ def plot_melodic_components(melodic_dir, in_file, tr=None,
width_ratios=[1, 1, 1, 4, 0.001, 1, 1, 1, 4, ],
height_ratios=[1.1, 1] * n_rows)

if noise_components_file:
with open(noise_components_file) as cf:
noise_components = [int(c) for c in cf.read().split(",")]

for i, img in enumerate(
iter_img(os.path.join(melodic_dir, "melodic_IC.nii.gz"))):

col = i % 2
row = int(i / 2)
l_row = row * 2

if noise_components_file:
if (i + 1) in noise_components:
color_title = color_time = color_power = 'r'
else:
color_title = color_time = color_power = 'g'
else:
color_title = 'k'
color_time = current_palette[0]
color_power = current_palette[1]

data = img.get_data()
for j in range(3):
ax1 = fig.add_subplot(gs[l_row:l_row + 2, j + col * 5])
Expand All @@ -568,29 +590,33 @@ def plot_melodic_components(melodic_dir, in_file, tr=None,
"C%d: Tot. var. expl. %.2g%%" % (i + 1, stats[i, 1]), x=0,
y=1.18, fontsize=7,
horizontalalignment='left',
verticalalignment='top')
verticalalignment='top',
color=color_title)

ax2 = fig.add_subplot(gs[l_row, 3 + col * 5])
ax3 = fig.add_subplot(gs[l_row + 1, 3 + col * 5])

ax2.plot(np.arange(len(timeseries[:, i])) * tr, timeseries[:, i],
linewidth=min(200 / len(timeseries[:, i]), 1.0))
linewidth=min(200 / len(timeseries[:, i]), 1.0),
color=color_time)
ax2.set_xlim([0, len(timeseries[:, i]) * tr])
ax2.axes.get_yaxis().set_visible(False)
ax2.autoscale_view('tight')
ax2.tick_params(axis='both', which='major', pad=0)
sns.despine(left=True, bottom=True)
zed = [tick.label.set_fontsize(6) for tick in
ax2.xaxis.get_major_ticks()]
for tick in ax2.xaxis.get_major_ticks():
tick.label.set_fontsize(6)
tick.label.set_color(color_time)

ax3.plot(f[0:], power[0:, i], color=current_palette[1],
ax3.plot(f[0:], power[0:, i], color=color_power,
linewidth=min(100 / len(power[0:, i]), 1.0))
ax3.set_xlim([f[0], f.max()])
ax3.axes.get_yaxis().set_visible(False)
ax3.autoscale_view('tight')
ax3.tick_params(axis='both', which='major', pad=0)
zed = [tick.label.set_fontsize(6) for tick in
ax3.xaxis.get_major_ticks()]
for tick in ax3.xaxis.get_major_ticks():
tick.label.set_fontsize(6)
tick.label.set_color(color_power)
sns.despine(left=True, bottom=True)

plt.subplots_adjust(hspace=0.5)
Expand Down

0 comments on commit a1204f0

Please sign in to comment.