From 0abbd119685dff4292f8adfc5b0275296247c654 Mon Sep 17 00:00:00 2001 From: Paul McCarthy <pauld.mccarthy@gmail.com> Date: Thu, 9 Jul 2015 16:15:43 +0100 Subject: [PATCH] Real EV names (as specified in design.fsf) are used --- fsl/data/featimage.py | 53 ++++++++++++++++++- fsl/data/strings.py | 2 +- .../controls/timeseriescontrolpanel.py | 12 ++--- fsl/fslview/controls/timeserieslistpanel.py | 8 +-- fsl/fslview/views/timeseriespanel.py | 7 +-- 5 files changed, 68 insertions(+), 14 deletions(-) diff --git a/fsl/data/featimage.py b/fsl/data/featimage.py index 3186b7ad4..4f9e1385f 100644 --- a/fsl/data/featimage.py +++ b/fsl/data/featimage.py @@ -109,7 +109,10 @@ def loadDesignFsf(designfsf): tkns = line.split(None, 2) - settings[tkns[1].strip()] = tkns[2] + key = tkns[1].strip() + val = tkns[2].strip().strip("'").strip('"') + + settings[key] = val return settings @@ -154,6 +157,7 @@ class FEATImage(fslimage.Image): self.__contrastNames = names self.__contrasts = cons self.__settings = settings + self.__evNames = self.__getEVNames() self.__residuals = None self.__pes = [None] * self.numEVs() @@ -163,6 +167,49 @@ class FEATImage(fslimage.Image): self.name = '{}.feat: {}'.format( self.__analysisName, self.name) + + def __getEVNames(self): + + numEVs = self.numEVs() + + titleKeys = filter( + lambda s: s.startswith('fmri(evtitle'), + self.__settings.keys()) + + derivKeys = filter( + lambda s: s.startswith('fmri(deriv_yn'), + self.__settings.keys()) + + evnames = [] + + for titleKey, derivKey in zip(titleKeys, derivKeys): + + # Figure out the ev number from + # the design.fsf key - skip over + # 'fmri(evtitle' (an offset of 12) + evnum = int(titleKey[12:-1]) + + # Sanity check - the evnum + # for the deriv_yn key matches + # that for the evtitle key + if evnum != int(derivKey[13:-1]): + raise RuntimeError('design.fsf seem to be corrupt') + + title = self.__settings[titleKey] + deriv = self.__settings[derivKey] + + if deriv == '0': + evnames.append(title) + else: + evnames.append(title) + evnames.append('{} - {}'.format(title, 'temporal derivative')) + + if len(evnames) != numEVs: + raise RuntimeError('The number of EVs in design.fsf does not ' + 'match the number of EVs in design.mat') + + return evnames + def getAnalysisName(self): return self.__analysisName @@ -179,6 +226,10 @@ class FEATImage(fslimage.Image): def numEVs(self): return self.__design.shape[1] + + def evNames(self): + return list(self.__evNames) + def numContrasts(self): return len(self.__contrasts) diff --git a/fsl/data/strings.py b/fsl/data/strings.py index 9b725bb2d..88b186ee2 100644 --- a/fsl/data/strings.py +++ b/fsl/data/strings.py @@ -439,7 +439,7 @@ choices = TypeDict({ 'HistogramPanel.histType.probability' : 'Probability', 'HistogramPanel.histType.count' : 'Count', - 'TimeSeriesPanel.plotMode.normal' : 'Normal', + 'TimeSeriesPanel.plotMode.normal' : 'Normal - no scaling/offsets', 'TimeSeriesPanel.plotMode.demean' : 'Demeaned', 'TimeSeriesPanel.plotMode.normalise' : 'Normalised', 'TimeSeriesPanel.plotMode.percentChange' : 'Percent changed', diff --git a/fsl/fslview/controls/timeseriescontrolpanel.py b/fsl/fslview/controls/timeseriescontrolpanel.py index e010a8c18..8d87e7243 100644 --- a/fsl/fslview/controls/timeseriescontrolpanel.py +++ b/fsl/fslview/controls/timeseriescontrolpanel.py @@ -231,19 +231,19 @@ class TimeSeriesControlPanel(fslpanel.FSLViewPanel): for i, ev in enumerate(evs): - evName = 'EV{}'.format(i + 1) + evName = ts.overlay.evNames()[i] self.__widgets.AddWidget( ev, - displayName=strings.properties[ts, 'plotEVs'].format(i + 1, - evName), + displayName=strings.properties[ts, 'plotEVs'].format( + i + 1, evName), groupName='currentFEATSettings') for i, pe in enumerate(pes): - evName = 'EV{}'.format(i + 1) + evName = ts.overlay.evNames()[i] self.__widgets.AddWidget( pe, - displayName=strings.properties[ts, 'plotPEFits'].format(i + 1, - evName), + displayName=strings.properties[ts, 'plotPEFits'].format( + i + 1, evName), groupName='currentFEATSettings') copeNames = overlay.contrastNames() diff --git a/fsl/fslview/controls/timeserieslistpanel.py b/fsl/fslview/controls/timeserieslistpanel.py index 0fb5530e4..f9d231c4e 100644 --- a/fsl/fslview/controls/timeserieslistpanel.py +++ b/fsl/fslview/controls/timeserieslistpanel.py @@ -117,10 +117,12 @@ class TimeSeriesListPanel(fslpanel.FSLViewPanel): return '{} ({})'.format( parentTs.label, strings.labels[modelTs]) + elif isinstance(modelTs, tsp.FEATEVTimeSeries): - return '{} ({})'.format( - parentTs.label, - 'EV') + return '{} EV{} ({})'.format( + modelTs.overlay.name, + modelTs.idx + 1, + modelTs.overlay.evNames()[modelTs.idx]) label = '{} ({})'.format( parentTs.label, diff --git a/fsl/fslview/views/timeseriespanel.py b/fsl/fslview/views/timeseriespanel.py index 88ebb52eb..90f31c76a 100644 --- a/fsl/fslview/views/timeseriespanel.py +++ b/fsl/fslview/views/timeseriespanel.py @@ -343,13 +343,14 @@ class FEATReducedTimeSeries(TimeSeries): data = self.overlay.reducedData(self.coords, self.contrast, False) return TimeSeries.getData(self, ydata=data) + class FEATEVTimeSeries(TimeSeries): - def __init__(self, tsPanel, overlay, coords, ev): + def __init__(self, tsPanel, overlay, coords, idx): TimeSeries.__init__(self, tsPanel, overlay, coords) - self.ev = ev + self.idx = idx def getData(self): - data = self.overlay.getDesign()[:, self.ev] + data = self.overlay.getDesign()[:, self.idx] return TimeSeries.getData(self, ydata=data) -- GitLab