-
Paul McCarthy authoredPaul McCarthy authored
test_melodicimage.py 5.67 KiB
#!/usr/bin/env python
#
# test_melodicimage.py -
#
# Author: Paul McCarthy <pauldmccarthy@gmail.com>
#
from __future__ import division
import os.path as op
import numpy as np
import nibabel as nib
import pytest
import tests
import fsl.data.image as fslimage
import fsl.data.melodicimage as meli
import fsl.data.melodicanalysis as mela
def _create_dummy_melodic_analysis(basedir,
shape4D=(10, 10, 10, 10),
timepoints=20,
tr=2,
with_data=True,
with_reportfile=True,
with_meanfile=True,
ic_prefix='melodic_IC'):
tldir = op.join(basedir, 'toplevel.ica')
meldir = op.join(tldir, 'analysis.ica')
datafile = op.join(tldir, 'filtered_func_data.nii.gz')
reportfile = op.join(tldir, 'report.html')
meanfile = op.join(meldir, 'mean.nii.gz')
icfile = op.join(meldir, '{}.nii.gz'.format(ic_prefix))
mixfile = op.join(meldir, 'melodic_mix')
ftmixfile = op.join(meldir, 'melodic_FTmix')
# Create stub files, and the directory structure
tests.make_dummy_files([icfile, mixfile, ftmixfile])
nics = shape4D[-1]
icimg = np.zeros(shape4D)
for ic in range(nics):
icimg[..., ic] = ic
# rows=timepoints
# coluumns=ICs
mixdata = np.zeros((timepoints, nics))
# rows=frequencies
# columns=ICs
if timepoints % 2: nfreqs = int(np.ceil(timepoints / 2.0))
else: nfreqs = timepoints // 2
ftmixdata = np.zeros((nfreqs, nics))
for ic in range(nics):
mixdata[ :, ic] = ic
ftmixdata[:, ic] = ic
np.savetxt(mixfile, mixdata)
np.savetxt(ftmixfile, ftmixdata)
fslimage.Image(icimg).save(icfile)
if with_data:
dataimg = np.zeros(list(shape4D[:3]) + [timepoints])
for t in range(timepoints):
dataimg[..., t] = t
hdr = nib.nifti1.Nifti1Header()
hdr['pixdim'][4] = tr
img = fslimage.Image(dataimg, header=hdr, xform=np.eye(4))
img.save(datafile)
if with_reportfile:
tests.make_dummy_file(reportfile)
if with_meanfile:
nvoxels = np.prod(shape4D[:3])
data = np.arange(0, nvoxels).reshape(shape4D[:3])
fslimage.Image(data).save(meanfile)
return meldir
def test_MelodicImage_create():
# non existent
with pytest.raises(Exception):
meli.MelodicImage('badfile')
# bad file
paths = ['analysis.ica/melodic_IC.nii.gz',
'analysis.ica/melodic_mix',
'analysis.ica/melodic_FTmix']
paths = [op.join(*p.split('/')) for p in paths]
with tests.testdir(paths) as testdir:
path = op.join(testdir, 'analysis.ica', 'melodic_IC.nii.gz')
with pytest.raises(Exception):
meli.MelodicImage(path)
for ic_prefix in ['melodic_IC', 'melodic_oIC']:
with tests.testdir() as testdir:
meldir = _create_dummy_melodic_analysis(testdir,
ic_prefix=ic_prefix)
icfile = op.join(meldir, '{}.nii.gz'.format(ic_prefix))
icfilenosuf = op.join(meldir, ic_prefix)
# Should be able to specify the
# melodic dir, or the IC image
i = meli.MelodicImage(meldir)
i = meli.MelodicImage(icfile)
i = meli.MelodicImage(icfilenosuf)
i = None
def test_MelodicImage_atts():
with tests.testdir() as testdir:
meldir = _create_dummy_melodic_analysis(testdir)
img = meli.MelodicImage(meldir)
assert img.shape == (10, 10, 10, 10)
assert img.pixdim == ( 1, 1, 1, 1)
assert np.all(img.voxToWorldMat == np.eye(4))
assert img.numComponents() == 10
assert img.getMelodicDir() == meldir
assert img.getReportFile() == mela.getReportFile(meldir)
assert img.getTopLevelAnalysisDir() == mela.getTopLevelAnalysisDir(meldir)
assert img.getDataFile() == mela.getDataFile(meldir)
assert img.getMeanFile() == mela.getMeanFile(meldir)
img = None
def test_MelodicImage_componentData():
with tests.testdir() as testdir:
meldir = _create_dummy_melodic_analysis(testdir)
img = meli.MelodicImage(meldir)
nics = img.numComponents()
expectTS = mela.getComponentTimeSeries( meldir)
expectPS = mela.getComponentPowerSpectra(meldir)
for ic in range(nics):
assert np.all(img.getComponentTimeSeries( ic) == expectTS[:, ic])
assert np.all(img.getComponentPowerSpectrum(ic) == expectPS[:, ic])
img = None
def test_MelodicImage_tr():
# If data file not present, tr should default to 1.0
with tests.testdir() as testdir:
meldir = _create_dummy_melodic_analysis(testdir, with_data=False)
img = meli.MelodicImage(meldir)
assert img.tr == 1
img = None
# Otherwise, it should be set to the datafile tr
with tests.testdir() as testdir:
meldir = _create_dummy_melodic_analysis(testdir, tr=5)
img = meli.MelodicImage(meldir)
assert img.tr == 5
img = None
# The TR can be updated
with tests.testdir() as testdir:
cbCalled = [False]
def trChanged(*a):
cbCalled[0] = True
meldir = _create_dummy_melodic_analysis(testdir, with_data=False)
img = meli.MelodicImage(meldir)
img.register('cbname', trChanged, topic='tr')
img.tr = 8
assert cbCalled[0]
assert img.tr == 8
img = None