diff --git a/fsl/data/featimage.py b/fsl/data/featimage.py index 3186b7ad462c89fccefbc5fb061ec3fd1a1ecdff..4f9e1385fac73497d63aac7c2d47b4c6094bf150 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 9b725bb2d123e628051996c88be033bb61480dc8..88b186ee28d75cdab4fab2d584fc0f33dc42af46 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 e010a8c1835b81669960e187c76a187efe7b4917..8d87e72434bdbe4958a341f8a97a5dc28d0c432a 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 0fb5530e4a623cc2dd5739b0a7f5992c31b4a621..f9d231c4eb066bb389d39c03835a605c888f6bc6 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 88ebb52eb3a25a8f9370e6d55ff6c479d025edf5..90f31c76acc87720a8109e28ee103430893a0682 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)