def test_FEATImage_fit_firstLevel(): featdir = op.join(datadir, '1stlevel_realdata.feat') fi = featimage.FEATImage(featdir) expect = np.array([ 10625.35273455, 10625.35263602, 10625.35248499, 10625.35272602, 10625.35286707, 10625.35237145, 10625.35244999, 10625.35270435, 10625.35272762, 10629.03397661, 10685.36428581, 10658.64633521, 10524.89226543, 10415.61794156, 10373.6671577, 10437.10001383, 10403.88611746, 10226.98548936, 10080.14323091, 10012.89132265, 9936.530395, 9957.92598556, 10090.51140821, 10199.6446317, 10246.67689405, 10261.45133255, 10265.36943466, 10266.22514043, 10266.32736048, 10264.92716455, 10243.05011597, 10245.62798475, 10287.91883737, 10325.38456267, 10341.92299781, 10347.17916861, 10348.58339616, 10348.89634025, 10348.93522057, 10345.25397481, 10288.9236822, 10315.64160242, 10449.39567496, 10558.66999883, 10597.64918744 ]) # bad contrast with pytest.raises(Exception): fi.fit([1, 2, 3, 4, 5, 6, 7], (2, 2, 2)) # bad voxel with pytest.raises(Exception): fi.fit([1, 0, 0, 0], (6, 7, 7)) result = fi.fit([1, 1, 1, 1], (2, 2, 2)) assert np.all(np.isclose(result, expect))
def test_FEATImage_imageAccessors(): for featdir in TEST_ANALYSES.keys(): shape = TEST_ANALYSES[featdir]['shape'] xform = TEST_ANALYSES[featdir]['xform'] with tests.testdir() as testdir: if 'realdata' not in featdir: featdir = tests.make_mock_feat_analysis( op.join(datadir, featdir), testdir, shape, xform) else: featdir = op.join(datadir, featdir) shape4D = shape shape = shape4D[:3] fi = featimage.FEATImage(featdir) nevs = fi.numEVs() ncons = fi.numContrasts() # Testing the FEATImage intenral cache for i in range(2): assert fi.getResiduals().shape == shape4D for ev in range(nevs): assert fi.getPE(ev).shape == shape for con in range(ncons): assert fi.getCOPE(con).shape == shape assert fi.getZStats(con).shape == shape assert fi.getClusterMask(con).shape == shape
def test_FEATImage_fit_higherLevel(): featdir = op.join(datadir, '2ndlevel_realdata.gfeat/cope1.feat') fi = featimage.FEATImage(featdir) expect = np.array([86.37929535, 86.37929535, 86.37929535]) result = fi.fit([1], (5, 5, 5)) assert np.all(np.isclose(result, expect))
def test_FEATImage_nostats(): featdir = op.join(datadir, '1stlevel_nostats.feat') shape = (4, 4, 5, 45) with tests.testdir() as testdir: featdir = tests.make_mock_feat_analysis(featdir, testdir, shape) fi = featimage.FEATImage(featdir) assert fi.getDesign() is None assert fi.numPoints() == 0 assert fi.numEVs() == 0 assert fi.evNames() == [] with pytest.raises(Exception): fi.fit([1, 2, 3], (2, 2, 2)) with pytest.raises(Exception): fi.partialFit([1, 2, 3], (2, 2, 2))
def test_FEATImage_partialFit(): featdir = op.join(datadir, '1stlevel_realdata.feat') fi = featimage.FEATImage(featdir) expect = np.array([ 10476.23185443, 10825.13542716, 10781.15297632, 11032.96902851, 11019.47536463, 10856.61537194, 10463.38391362, 10664.79227954, 10948.11850521, 10712.01568132, 10882.88149773, 10745.65913733, 10590.78057109, 10524.89948148, 10744.82941967, 10422.96359453, 10156.39446402, 10219.8339014, 10115.32145738, 10494.28109315, 10121.89555309, 10165.92560409, 10556.70058668, 10198.67478569, 10045.04934583, 9906.60233353, 10015.75569565, 9864.38786016, 10241.91219554, 10099.08538293, 10444.7826294, 10152.72622847, 10077.09075815, 10128.63320464, 10087.93203101, 10450.29667654, 10207.89144059, 10137.98334586, 10387.09965691, 10194.79436483, 10203.21032619, 10136.1942605, 10128.23728873, 10416.78984136, 10118.51262128 ]) result = fi.partialFit([1, 1, 1, 1], (2, 2, 2)) assert np.all(np.isclose(result, expect))
def test_FEATImage_attributes(): # TEst bad input with pytest.raises(Exception): featimage.FEATImage('baddir') for featdir in TEST_ANALYSES.keys(): shape = TEST_ANALYSES[featdir]['shape'] xform = TEST_ANALYSES[featdir]['xform'] with tests.testdir() as testdir: if 'realdata' not in featdir: featdir = tests.make_mock_feat_analysis(op.join( datadir, featdir), testdir, shape, xform, pes=False, copes=False, zstats=False, residuals=False, clustMasks=False) else: featdir = op.join(datadir, featdir) # Now create a FEATImage. We validate its # attributes against the values returned by # the functions in featdesign/featanalysis. fi = featimage.FEATImage(featdir) settings = featanalysis.loadSettings(featdir) design = featdesign.FEATFSFDesign(featdir, settings) desmat = design.getDesign() evnames = [ev.title for ev in design.getEVs()] contrastnames, contrasts = featanalysis.loadContrasts(featdir) assert np.all(np.isclose(fi.shape, shape)) assert np.all(np.isclose(fi.voxToWorldMat, xform)) assert fi.getFEATDir() == featdir assert fi.getAnalysisName() == op.splitext(op.basename(featdir))[0] assert fi.isFirstLevelAnalysis( ) == featanalysis.isFirstLevelAnalysis(settings) assert fi.getTopLevelAnalysisDir( ) == featanalysis.getTopLevelAnalysisDir(featdir) assert fi.getReportFile() == featanalysis.getReportFile(featdir) assert fi.hasStats() == featanalysis.hasStats(featdir) assert fi.numPoints() == desmat.shape[0] assert fi.numEVs() == desmat.shape[1] assert fi.evNames() == evnames assert fi.numContrasts() == len(contrasts) assert fi.contrastNames() == contrastnames assert fi.contrasts() == contrasts assert np.all(np.isclose(fi.getDesign(), desmat)) assert fi.thresholds() == featanalysis.getThresholds(settings) for ci in range(len(contrasts)): result = fi.clusterResults(ci) expect = featanalysis.loadClusterResults(featdir, settings, ci) assert len(result) == len(expect) assert all([ rc.nvoxels == ec.nvoxels for rc, ec in zip(result, expect) ])
def __selectedOverlayChanged(self, *a): """Called when the :attr:`.DisplayContext.selectedOverlay` changes, and by the :meth:`__overlayListChanged` method. If the newly selected overlay is a :class:`.FEATImage` (or is otherwise associated with a FEAT analysis) which has cluster results, they are loaded in, and displayed on a :class:`.WidgetGrid`. """ prevOverlay = self.__selectedOverlay self.__selectedOverlay = None # No overlays are loaded if len(self.overlayList) == 0: self.__disable(strings.messages[self, 'noOverlays']) return overlay = self.displayCtx.getSelectedOverlay() # Overlay is in-memory if overlay.dataSource is None: self.__disable(strings.messages[self, 'notFEAT']) return featDir = featanalysis.getAnalysisDir(overlay.dataSource) # No FEAT analysis, or not an Image, # can't do anything with that if featDir is None or not isinstance(overlay, fslimage.Nifti): log.debug('Overlay {} is not part of a feat ' 'analysis, or is not Nifti'.format(overlay)) self.__disable(strings.messages[self, 'notFEAT']) return # Selected overlay is either the # same one (maybe the overlay list, # rather than the selected overlay, # changed) or the newly selected # overlay is from the same FEAT # analysis. No need to do anything. if prevOverlay is not None: prevFeatImage = self.__featImages.get(prevOverlay) if prevOverlay is overlay or \ (prevFeatImage is not None and featDir == prevFeatImage.getFEATDir()): log.debug('Overlay {} is already selected.'.format(overlay)) # Make sure the overlay -> FEATImage # mapping is present, and (re-)cache # a reference to the selected overlay. self.__featImages[overlay] = prevFeatImage self.__selectedOverlay = overlay return # We're in business. The newly selected # overlay is a part of a FEAT analysis # which is not currently being displayed. self.__selectedOverlay = overlay # Clear the stat selection combo box. self.__statSelect.Clear() # Get the FEATImage associated with # this overlay, so we can get # information about the FEAT analysis featImage = self.__featImages.get(overlay) if featImage is None: # If the overlay itself is a FEATImage, # then we have nothing to do. if isinstance(overlay, featimage.FEATImage): featImage = overlay else: # The FEATImage might already # be in the overlay list - # let's search for it. for ovl in self.overlayList: if isinstance(ovl, featimage.FEATImage) and \ ovl.getFEATDir() == featDir: featImage = ovl # As a last resort, if the FEATImage is not # in the overlay list, we'll create one. if featImage is None: featImage = featimage.FEATImage(featDir, loadData=False, calcRange=False) self.__featImages[overlay] = featImage log.debug('Identified FEAT analysis associated with overlay ' '{}: {}'.format(overlay, featImage.getFEATDir())) # Get the contrast and cluster # information for the FEAT analysis. display = self.displayCtx.getDisplay(overlay) numCons = featImage.numContrasts() conNames = featImage.contrastNames() try: # clusts is a list of (contrast, clusterList) tuples clusts = [(c, featImage.clusterResults(c)) for c in range(numCons)] clusts = [c for c in clusts if c[1] is not None] # Error parsing the cluster data except Exception as e: log.warning('Error parsing cluster data for ' '{}: {}'.format(featImage.name, str(e)), exc_info=True) self.__disable(strings.messages[self, 'badData']) return # No cluster results exist # for any contrast if len(clusts) == 0: self.__disable(strings.messages[self, 'noClusters']) return # Populate the stat selection combo box for contrast, clusterList in clusts: name = conNames[contrast] name = strings.labels[self, 'clustName'].format(contrast + 1, name) self.__statSelect.Append(name, clusterList) self.__overlayName.SetLabel(display.name) # Refresh the widget grid self.__statSelect.SetSelection(0) self.__statSelected() self.Layout()