def load_example_fmri_dataset(name="1slice", literal=False): """Load minimal fMRI dataset that is shipped with PyMVPA.""" from mvpa2.datasets.sources.openfmri import OpenFMRIDataset from mvpa2.datasets.mri import fmri_dataset from mvpa2.misc.io import SampleAttributes basedir = op.join(pymvpa_dataroot, "haxby2001") mask = { "1slice": op.join(pymvpa_dataroot, "mask.nii.gz"), "25mm": op.join(basedir, "sub001", "masks", "25mm", "brain.nii.gz"), }[name] if literal: model = 1 subj = 1 openfmri = OpenFMRIDataset(basedir) ds = openfmri.get_model_bold_dataset(model, subj, flavor=name, mask=mask, noinfolabel="rest") # re-imagine the global time_coords of a concatenated time series # this is only for the purpose of keeping the example data in the # exact same shape as it has always been. in absolute terms this makes no # sense as there is no continuous time in this dataset ds.sa["run_time_coords"] = ds.sa.time_coords ds.sa["time_coords"] = np.arange(len(ds)) * 2.5 else: if name == "25mm": raise ValueError("The 25mm dataset is no longer available with " "numerical labels") attr = SampleAttributes(op.join(pymvpa_dataroot, "attributes.txt")) ds = fmri_dataset( samples=op.join(pymvpa_dataroot, "bold.nii.gz"), targets=attr.targets, chunks=attr.chunks, mask=mask ) return ds
def load_example_fmri_dataset(name='1slice', literal=False): """Load minimal fMRI dataset that is shipped with PyMVPA.""" from mvpa2.datasets.sources.openfmri import OpenFMRIDataset from mvpa2.datasets.mri import fmri_dataset from mvpa2.misc.io import SampleAttributes basedir = pathjoin(pymvpa_dataroot, 'haxby2001') mask = {'1slice': pathjoin(pymvpa_dataroot, 'mask.nii.gz'), '25mm': pathjoin(basedir, 'sub001', 'masks', '25mm', 'brain.nii.gz')}[name] if literal: model = 1 subj = 1 openfmri = OpenFMRIDataset(basedir) ds = openfmri.get_model_bold_dataset(model, subj, flavor=name, mask=mask, noinfolabel='rest') # re-imagine the global time_coords of a concatenated time series # this is only for the purpose of keeping the example data in the # exact same shape as it has always been. in absolute terms this makes no # sense as there is no continuous time in this dataset ds.sa['run_time_coords'] = ds.sa.time_coords ds.sa['time_coords'] = np.arange(len(ds)) * 2.5 else: if name == '25mm': raise ValueError("The 25mm dataset is no longer available with " "numerical labels") attr = SampleAttributes(pathjoin(pymvpa_dataroot, 'attributes.txt')) ds = fmri_dataset(samples=pathjoin(pymvpa_dataroot, 'bold.nii.gz'), targets=attr.targets, chunks=attr.chunks, mask=mask) return ds
def load_example_fmri_dataset(name='1slice', literal=False): """Load minimal fMRI dataset that is shipped with PyMVPA.""" from mvpa2.datasets.eventrelated import events2sample_attr from mvpa2.datasets.sources.openfmri import OpenFMRIDataset from mvpa2.datasets.mri import fmri_dataset from mvpa2.misc.io import SampleAttributes basedir = os.path.join(pymvpa_dataroot, 'openfmri') mask = {'1slice': os.path.join(pymvpa_dataroot, 'mask.nii.gz'), '25mm': os.path.join(basedir, 'sub001', 'masks', '25mm', 'brain.nii.gz')}[name] if literal: model = 1 subj = 1 openfmri = OpenFMRIDataset(basedir) ds = openfmri.get_model_bold_dataset(model, subj, flavor=name, mask=mask, noinfolabel='rest') # re-imagine the global time_coords of a concatenated time series # this is only for the purpose of keeping the example data in the # exact same shape as it has always been. in absolute terms this makes no # sense as there is no continuous time in this dataset ds.sa['run_time_coords'] = ds.sa.time_coords ds.sa['time_coords'] = np.arange(len(ds)) * 2.5 else: if name == '25mm': raise ValueError("The 25mm dataset is no longer available with " "numerical labels") attr = SampleAttributes(os.path.join(pymvpa_dataroot, 'attributes.txt')) ds = fmri_dataset(samples=os.path.join(pymvpa_dataroot, 'bold.nii.gz'), targets=attr.targets, chunks=attr.chunks, mask=mask) return ds
def load_datadb_tutorial_data(path=os.path.join( pymvpa_datadbroot, 'tutorial_data', 'tutorial_data', 'data'), roi='brain', add_fa=None): """Loads the block-design demo dataset from PyMVPA dataset DB. Parameters ---------- path : str Path of the directory containing the dataset files. roi : str or int or tuple or None Region Of Interest to be used for masking the dataset. If a string is given a corresponding mask image from the demo dataset will be used (mask_<str>.nii.gz). If an int value is given, the corresponding ROI is determined from the atlas image (mask_hoc.nii.gz). If a tuple is provided it may contain int values that a processed as explained before, but the union of a ROIs is taken to produce the final mask. If None, no masking is performed. add_fa : dict Passed on to the dataset creator function (see fmri_dataset() for more information). """ import nibabel as nb from mvpa2.datasets.sources.openfmri import OpenFMRIDataset task = model = subj = 1 dhandle = OpenFMRIDataset(path) maskpath = os.path.join(path, 'sub001', 'masks', 'orig') if roi is None: mask = None elif isinstance(roi, str): mask = os.path.join(maskpath, roi + '.nii.gz') elif isinstance(roi, int): nimg = nb.load(os.path.join(maskpath, 'hoc.nii.gz')) tmpmask = nimg.get_data() == roi mask = nb.Nifti1Image(tmpmask.astype(int), nimg.get_affine(), nimg.get_header()) elif isinstance(roi, tuple) or isinstance(roi, list): nimg = nb.load(os.path.join(maskpath, 'hoc.nii.gz')) if externals.versions['nibabel'] >= '1.2': img_shape = nimg.shape else: img_shape = nimg.get_shape() tmpmask = np.zeros(img_shape, dtype='bool') for r in roi: tmpmask = np.logical_or(tmpmask, nimg.get_data() == r) mask = nb.Nifti1Image(tmpmask.astype(int), nimg.get_affine(), nimg.get_header()) elif isinstance(roi, nb.Nifti1Image): mask=roi else: raise ValueError("Got something as mask that I cannot handle.") ds = dhandle.get_model_bold_dataset(model, subj, mask=mask, add_fa=add_fa, noinfolabel='rest') # fixup time_coords to make the impression of a continuous time series # this is only necessary until we have changed the tutorial to # show/encourage run-wise processing ds.sa['time_coords'] = np.linspace(0, (len(ds) * 2.5), len(ds) + 1)[:-1] return ds
def create_betas_per_trial_with_pymvpa_roni(study_path, subj, conf, mask_name, flavor, TR): dhandle = OpenFMRIDataset(study_path) model = 1 task = 1 # Do this for other tasks as well. not only the first mask_fname = _opj(study_path, "sub{:0>3d}".format(subj), "masks", conf.mvpa_tasks[0], "{}.nii.gz".format(mask_name)) print mask_fname run_datasets = [] for run_id in dhandle.get_task_bold_run_ids(task)[subj]: if type(run_id) == str: continue # all_events = dhandle.get_bold_run_model(model, subj, run_id) all_events = get_bold_run_model(dhandle, 2, subj, run_id) run_events = [] i = 0 for event in all_events: if event["task"] == task: event["condition"] = "{}-{}".format(event["condition"], event["id"]) run_events.append(event) i += 1 # load BOLD data for this run (with masking); add 0-based chunk ID run_ds = dhandle.get_bold_run_dataset(subj, task, run_id, flavor=flavor, chunks=run_id - 1, mask=mask_fname) # convert event info into a sample attribute and assign as 'targets' run_ds.sa.time_coords = run_ds.sa.time_indices * TR run_ds.sa["targets"] = events2sample_attr(run_events, run_ds.sa.time_coords, noinfolabel="rest") # additional time series preprocessing can go here poly_detrend(run_ds, polyord=1, chunks_attr="chunks") zscore(run_ds, chunks_attr="chunks", param_est=("targets", ["rest"]), dtype="float32") glm_dataset = fit_event_hrf_model(run_ds, run_events, time_attr="time_coords", condition_attr="condition") glm_dataset.sa["targets"] = [x[: x.find("-")] for x in glm_dataset.sa.condition] glm_dataset.sa["id"] = [x[x.find("-") + 1 :] for x in glm_dataset.sa.condition] glm_dataset.sa.condition = glm_dataset.sa["targets"] glm_dataset.sa["chunks"] = [run_id - 1] * len(glm_dataset.samples) # If a trial was dropped (the subject pressed on a button) than the counter trial from the # other condition should also be dropped for pair in conf.conditions_to_compare: cond_bool = np.array([c in pair for c in glm_dataset.sa["condition"]]) sub_dataset = glm_dataset[cond_bool] c = Counter(sub_dataset.sa.id) for value in c: if c[value] < 2: id_bool = np.array([value in cond_id for cond_id in glm_dataset.sa["id"]]) glm_dataset = glm_dataset[np.bitwise_not(np.logical_and(id_bool, cond_bool))] run_datasets.append(glm_dataset) return vstack(run_datasets, 0)
def create_betas_per_run_with_pymvpa(study_path, subj, conf, mask_name, flavor): of = OpenFMRIDataset(study_path) mask_fname = _opj(study_path, "sub{:0>3d}".format(subj), "masks", conf.mvpa_tasks[0], "{}.nii.gz".format(mask_name)) ds = of.get_model_bold_dataset( model_id=1, subj_id=subj, flavor=flavor, mask=mask_fname, # preproc_img=smooth, preproc_ds=detrend, modelfx=fit_event_hrf_model, time_attr="time_coords", condition_attr="condition", ) return ds
def test_openfmri_dataset(): of = OpenFMRIDataset(os.path.join(pymvpa_dataroot, 'openfmri')) sub_ids = of.get_subj_ids() assert_equal(sub_ids, [1, 'phantom']) assert_equal(of.get_scan_properties(), {'TR': '2.5'}) tasks = of.get_task_descriptions() assert_equal(tasks, {1: 'object viewing'}) task = tasks.keys()[0] run_ids = of.get_bold_run_ids(sub_ids[0], task) assert_equal(run_ids, range(1, 13)) task_runs = of.get_task_bold_run_ids(task) assert_equal(task_runs, {1: range(1, 13)}) orig_attrs = SampleAttributes(os.path.join(pymvpa_dataroot, 'attributes_literal.txt')) for subj, runs in task_runs.iteritems(): for run in runs: # load single run ds = of.get_bold_run_dataset(subj, task, run, flavor='1slice', mask=os.path.join(pymvpa_dataroot, 'mask.nii.gz'), add_sa='bold_moest.txt') # basic shape assert_equal(len(ds), 121) assert_equal(ds.nfeatures, 530) # functional mapper assert_equal(ds.O.shape, (121, 40, 20, 1)) # additional attributes present moest = of.get_bold_run_motion_estimates(subj, task, run) for i in range(6): moest_attr = 'bold_moest.txt_%i' % (i,) assert_true(moest_attr in ds.sa) assert_array_equal(moest[:,i], ds.sa[moest_attr].value) # check conversion of model into sample attribute events = of.get_bold_run_model(subj, task, run) targets = events2sample_attr(events, ds.sa.time_coords, noinfolabel='rest') assert_array_equal( orig_attrs['targets'][(run - 1) * 121: run * len(ds)], targets) assert_equal(ds.sa['subj'][0], subj) # more basic access motion = of.get_task_bold_attributes(1, 'bold_moest.txt', np.loadtxt) assert_equal(len(motion), 12) # one per run # one per subject, per volume, 6 estimates assert_equal([m.shape for m in motion], [(1, 121, 6)] * 12)
def make_ds(sub, datapath, flavor): of = OpenFMRIDataset(datapath) ds = of.get_model_bold_dataset( model_id=1, subj_id=sub, #ds = of.get_bold_run_dataset(1,1,1, flavor=flavor, mask=_opj( datapath, 'sub%.3i' % sub, 'masks', 'task001_run001', 'grey.nii.gz'), #preproc_img=smooth, #preproc_ds = detrend, #modelfx=fit_event_hrf_model, time_attr='time_coords', condition_attr='condition') for i in np.unique(ds.chunks)[5:]: detrend(ds[ds.chunks == i])
def make_ds(sub, datapath, flavor): of = OpenFMRIDataset(datapath) ds = of.get_model_bold_dataset( model_id=1, subj_id=sub, flavor=flavor, mask=_opj(datapath, 'sub%.3i' % sub, 'masks', 'task001_run001', 'grey.nii.gz'), #preproc_img=smooth, preproc_ds=detrend, modelfx=fit_event_hrf_model, time_attr='time_coords', condition_attr='condition') ds14 = ds[np.array([c in ['G1', 'G4'] for c in ds.sa['condition']])] ds23 = ds[np.array([c in ['G2', 'G3'] for c in ds.sa['condition']])] result_dir = _opj(datapath, 'mvpa', 'ds', flavor) if not os.path.isdir(result_dir): os.makedirs(result_dir) print "{:0>3d}-ds14 {},{}".format(sub, ds14.shape, ds14.sa.condition) print "{:0>3d}-ds23 {},{}".format(sub, ds23.shape, ds23.sa.condition) h5save(_opj(result_dir, 'sub%.3i_14_hrf.hdf5' % sub), ds14) h5save(_opj(result_dir, 'sub%.3i_23_hrf.hdf5' % sub), ds23)
def make_ds(sub, datapath, flavor): of = OpenFMRIDataset(datapath) ds = of.get_model_bold_dataset( model_id=1, subj_id=sub, flavor=flavor, mask=_opj(datapath, "sub%.3i" % sub, "masks", "task001_run001", "grey.nii.gz"), # preproc_img=smooth, preproc_ds=detrend, modelfx=fit_event_hrf_model, time_attr="time_coords", condition_attr="condition", ) ds14 = ds[np.array([c in ["G1", "G4"] for c in ds.sa["condition"]])] ds23 = ds[np.array([c in ["G2", "G3"] for c in ds.sa["condition"]])] result_dir = _opj(datapath, "mvpa", "ds", flavor) if not os.path.isdir(result_dir): os.makedirs(result_dir) print "{:0>3d}-ds14 {},{}".format(sub, ds14.shape, ds14.sa.condition) print "{:0>3d}-ds23 {},{}".format(sub, ds23.shape, ds23.sa.condition) h5save(_opj(result_dir, "sub%.3i_14_hrf.hdf5" % sub), ds14) h5save(_opj(result_dir, "sub%.3i_23_hrf.hdf5" % sub), ds23)
def create_betas_per_trial_with_pymvpa(study_path, subj, conf, mask_name, flavor, TR): dhandle = OpenFMRIDataset(study_path) model = 1 task = 1 # Do this for other tasks as well. not only the first mask_fname = _opj(study_path, "sub{:0>3d}".format(subj), "masks", conf.mvpa_tasks[0], "{}.nii.gz".format(mask_name)) print mask_fname run_datasets = [] for run_id in dhandle.get_task_bold_run_ids(task)[subj]: if type(run_id) == str: continue all_events = dhandle.get_bold_run_model(model, subj, run_id) run_events = [] i = 0 for event in all_events: if event["task"] == task: event["condition"] = "{}-{}".format(event["condition"], i) run_events.append(event) i += 1 # load BOLD data for this run (with masking); add 0-based chunk ID run_ds = dhandle.get_bold_run_dataset(subj, task, run_id, flavor=flavor, chunks=run_id - 1, mask=mask_fname) # convert event info into a sample attribute and assign as 'targets' run_ds.sa.time_coords = run_ds.sa.time_indices * TR print run_id run_ds.sa["targets"] = events2sample_attr(run_events, run_ds.sa.time_coords, noinfolabel="rest") # additional time series preprocessing can go here poly_detrend(run_ds, polyord=1, chunks_attr="chunks") zscore(run_ds, chunks_attr="chunks", param_est=("targets", ["rest"]), dtype="float32") glm_dataset = fit_event_hrf_model(run_ds, run_events, time_attr="time_coords", condition_attr="condition") glm_dataset.sa["targets"] = [x[: x.find("-")] for x in glm_dataset.sa.condition] glm_dataset.sa.condition = glm_dataset.sa["targets"] glm_dataset.sa["chunks"] = [run_id - 1] * len(glm_dataset.samples) run_datasets.append(glm_dataset) return vstack(run_datasets, 0)
def load_tutorial_data(path=None, roi='brain', add_fa=None, flavor=None): """Loads the block-design demo dataset from PyMVPA dataset DB. Parameters ---------- path : str, optional Path to the directory with the extracted content of the tutorial data package. This is only necessary for accessing the full resolution data. The ``1slice``, and ``25mm`` flavors are shipped with PyMVPA itself, and the path argument is ignored for them. This function also honors the MVPA_LOCATION_TUTORIAL_DATA environment variable, and the respective configuration setting. roi : str or int or tuple or None, optional Region Of Interest to be used for masking the dataset. If a string is given a corresponding mask image from the demo dataset will be used (mask_<str>.nii.gz). If an int value is given, the corresponding ROI is determined from the atlas image (mask_hoc.nii.gz). If a tuple is provided it may contain int values that a processed as explained before, but the union of a ROIs is taken to produce the final mask. If None, no masking is performed. add_fa : dict, optional Passed on to the dataset creator function (see fmri_dataset() for more information). flavor: str, optional Resolution flavor of the data to load. By default, the data is loaded in its original resolution. The PyMVPA source distribution contains a '25mm' flavor that has been downsampled to a very coarse resolution and can be used for quick test execution. Likewise a ``1slice`` flavor is available that contents a full-resultion single-slice subset of the dataset. """ if path is None: if flavor in ('1slice', '25mm'): # we know that this part is there path = op.join(pymvpa_dataroot) else: # check config for info, pretend it is in the working dir otherwise path = mvpa2.cfg.get('location', 'tutorial data', default=op.curdir) # we need the haxby2001 portion of the tutorial data path = op.join(path, 'haxby2001') import nibabel as nb from mvpa2.datasets.sources.openfmri import OpenFMRIDataset model = subj = 1 dhandle = OpenFMRIDataset(path) if flavor is None: maskpath = op.join(path, 'sub001', 'masks', 'orig') else: maskpath = op.join(path, 'sub001', 'masks', flavor) if roi is None: mask = None elif isinstance(roi, str): mask = op.join(maskpath, roi + '.nii.gz') elif isinstance(roi, int): nimg = nb.load(op.join(maskpath, 'hoc.nii.gz')) tmpmask = nimg.get_data() == roi mask = nb.Nifti1Image(tmpmask.astype(int), nimg.get_affine(), nimg.get_header()) elif isinstance(roi, tuple) or isinstance(roi, list): nimg = nb.load(op.join(maskpath, 'hoc.nii.gz')) if externals.versions['nibabel'] >= '1.2': img_shape = nimg.shape else: img_shape = nimg.get_shape() tmpmask = np.zeros(img_shape, dtype='bool') for r in roi: tmpmask = np.logical_or(tmpmask, nimg.get_data() == r) mask = nb.Nifti1Image(tmpmask.astype(int), nimg.get_affine(), nimg.get_header()) elif isinstance(roi, nb.Nifti1Image): mask = roi else: raise ValueError("Got something as mask that I cannot handle.") ds = dhandle.get_model_bold_dataset(model, subj, flavor=flavor, mask=mask, add_fa=add_fa, noinfolabel='rest') # fixup time_coords to make the impression of a continuous time series # this is only necessary until we have changed the tutorial to # show/encourage run-wise processing ds.sa['time_coords'] = np.linspace(0, (len(ds) * 2.5), len(ds) + 1)[:-1] return ds
def run(args): import numpy as np import pylab as pl from mvpa2.datasets.sources.openfmri import OpenFMRIDataset from mvpa2.misc.plot import timeseries_boxplot, concat_ts_boxplot_stats from mvpa2.misc.stats import compute_ts_boxplot_stats from mvpa2.base import verbose of = OpenFMRIDataset(args.path) data = of.get_task_bold_attributes(args.task, args.estimate_fname, np.loadtxt, exclude_subjs=args.exclude_subjs) segment_sizes = [len(d[d.keys()[0]]) for d in data] if args.relative is not None: # recode per-subject estimates wrt their particular reference ref = { subj: d[args.relative[1]] for subj, d in data[args.relative[0]].iteritems() } for d in data: for subj in d: if subj in d: d[subj] -= ref[subj] print subj, d[subj].mean() # collapse all data into a per-run (subj x vol x estimate) array data = [np.array(d.values()) for d in data] # figure setup pl.figure(figsize=(12, 5)) ax = pl.subplot(211) plt_props = { 'translation': 'estimate L2-norm in mm', 'rotation': 'estimate L2-norm in deg' } def bxplot(stats, label): stats = concat_ts_boxplot_stats(stats) # XXX need some way to expose whether there were missing subjects and # report proper IDs -- for now resort to whining verbose( 0, "List of outlier time series follows (if any) [note, subject IDs are enumarations and may differ from dataset subject IDs in case of missing subjects]" ) for i, run in enumerate([ np.where(np.sum(np.logical_not(o.mask), axis=0)) for o in stats[1] ]): sids = run[0] if len(sids): verbose(0, "%s r%.3i: %s" % (label, i + 1, [s + 1 for s in sids])) timeseries_boxplot(stats[0]['median'], mean=stats[0]['mean'], std=stats[0]['std'], n=stats[0]['n'], min=stats[0]['min'], max=stats[0]['max'], p25=stats[0]['p25'], p75=stats[0]['p75'], outlierd=stats[1], segment_sizes=segment_sizes) pl.title(label) xp, xl = pl.xticks() pl.xticks(xp, ['' for i in xl]) pl.xlim((0, len(stats[0]['n']))) pl.ylabel(plt_props[label]) if args.rad2deg and args.estimate_order == 'rottrans': convfunc = np.rad2deg else: convfunc = lambda x: x # first three columns run_stats = [ compute_ts_boxplot_stats(convfunc(d[..., :3]), outlier_abs_minthresh=args.outlier_minthresh, outlier_thresh=args.outlier_stdthresh, aggfx=np.linalg.norm, greedy_outlier=True) for d in data ] ax = pl.subplot(211) if args.estimate_order == 'transrot': bxplot(run_stats, 'translation') else: bxplot(run_stats, 'rotation') # last three columns if args.rad2deg and args.estimate_order == 'transrot': convfunc = np.rad2deg else: convfunc = lambda x: x run_stats = [ compute_ts_boxplot_stats(convfunc(d[..., 3:]), outlier_abs_minthresh=args.outlier_minthresh, outlier_thresh=args.outlier_stdthresh, aggfx=np.linalg.norm, greedy_outlier=True) for d in data ] ax = pl.subplot(212) if args.estimate_order == 'rottrans': bxplot(run_stats, 'translation') else: bxplot(run_stats, 'rotation') pl.xlabel('time in fMRI volumes') if args.savefig is None: pl.show() else: pl.savefig(args.savefig)
#!/usr/bin/python import sys from os.path import join as _opj from mvpa2.datasets.sources.openfmri import OpenFMRIDataset from mvpa2.datasets.eventrelated import fit_event_hrf_model from mvpa2.base.hdf5 import h5save from nilearn.image import smooth_img import nibabel as nb datapath = 'BASEDIR' of = OpenFMRIDataset(datapath) sub = int(sys.argv[1]) + 1 def smooth(img): # we need to preserve the original header because the smoothing function # f***s the TR up nimg = smooth_img(img, fwhm=2.0) return nb.Nifti1Image(nimg.get_data(), img.get_affine(), header=img.get_header()) ds = of.get_model_bold_dataset( model_id=1, subj_id=sub, flavor='dico_bold7Tp1_to_subjbold7Tp1', # full brain
def run(args): import numpy as np import pylab as pl from mvpa2.datasets.sources.openfmri import OpenFMRIDataset from mvpa2.misc.plot import timeseries_boxplot, concat_ts_boxplot_stats from mvpa2.misc.stats import compute_ts_boxplot_stats from mvpa2.base import verbose of = OpenFMRIDataset(args.path) data = of.get_task_bold_attributes( args.task, args.estimate_fname, np.loadtxt, exclude_subjs=args.exclude_subjs) segment_sizes = [len(d[d.keys()[0]]) for d in data] if not args.relative is None: # recode per-subject estimates wrt their particular reference ref = {subj: d[args.relative[1]] for subj, d in data[args.relative[0]].iteritems()} for d in data: for subj in d: if subj in d: d[subj] -= ref[subj] print subj, d[subj].mean() # collapse all data into a per-run (subj x vol x estimate) array data = [np.array(d.values()) for d in data] # figure setup pl.figure(figsize=(12, 5)) ax = pl.subplot(211) plt_props = { 'translation': 'estimate L2-norm in mm', 'rotation': 'estimate L2-norm in deg' } def bxplot(stats, label): stats = concat_ts_boxplot_stats(stats) # XXX need some way to expose whether there were missing subjects and # report proper IDs -- for now resort to whining verbose(0, "List of outlier time series follows (if any) [note, subject IDs are enumarations and may differ from dataset subject IDs in case of missing subjects]") for i, run in enumerate([np.where(np.sum(np.logical_not(o.mask), axis=0)) for o in stats[1]]): sids = run[0] if len(sids): verbose(0, "%s r%.3i: %s" % (label, i + 1, [s + 1 for s in sids])) timeseries_boxplot(stats[0]['median'], mean=stats[0]['mean'], std=stats[0]['std'], n=stats[0]['n'], min=stats[0]['min'], max=stats[0]['max'], p25=stats[0]['p25'], p75=stats[0]['p75'], outlierd=stats[1], segment_sizes=segment_sizes) pl.title(label) xp, xl = pl.xticks() pl.xticks(xp, ['' for i in xl]) pl.xlim((0, len(stats[0]['n']))) pl.ylabel(plt_props[label]) if args.rad2deg and args.estimate_order == 'rottrans': convfunc = np.rad2deg else: convfunc = lambda x: x # first three columns run_stats = [compute_ts_boxplot_stats( convfunc(d[...,:3]), outlier_abs_minthresh=args.outlier_minthresh, outlier_thresh=args.outlier_stdthresh, aggfx=np.linalg.norm, greedy_outlier=True) for d in data] ax = pl.subplot(211) if args.estimate_order == 'transrot': bxplot(run_stats, 'translation') else: bxplot(run_stats, 'rotation') # last three columns if args.rad2deg and args.estimate_order == 'transrot': convfunc = np.rad2deg else: convfunc = lambda x: x run_stats = [compute_ts_boxplot_stats( convfunc(d[...,3:]), outlier_abs_minthresh=args.outlier_minthresh, outlier_thresh=args.outlier_stdthresh, aggfx=np.linalg.norm, greedy_outlier=True) for d in data] ax = pl.subplot(212) if args.estimate_order == 'rottrans': bxplot(run_stats, 'translation') else: bxplot(run_stats, 'rotation') pl.xlabel('time in fMRI volumes') if args.savefig is None: pl.show() else: pl.savefig(args.savefig)
def run(args): from mvpa2.base.hdf5 import h5save ds = None vol_attr = dict() if args.add_vol_attr is not None: # XXX add a way to use the mapper of an existing dataset to # add a volume attribute without having to load the entire # mri data again vol_attr = dict(args.add_vol_attr) if not len(args.add_vol_attr) == len(vol_attr): warning("--vol-attr option with duplicate attribute name: " "check arguments!") verbose(2, "Prepare to add volumetric feature attributes: %s" % vol_attr) if args.txt_data is not None: verbose(1, "Load data from TXT file '%s'" % args.txt_data) samples = _load_from_txt(args.txt_data) ds = Dataset(samples) elif args.npy_data is not None: verbose(1, "Load data from NPY file '%s'" % args.npy_data) samples = _load_from_npy(args.npy_data) ds = Dataset(samples) elif args.mri_data is not None: verbose(1, "Load data from MRI image(s) %s" % args.mri_data) from mvpa2.datasets.mri import fmri_dataset ds = fmri_dataset(args.mri_data, mask=args.mask, add_fa=vol_attr) elif args.openfmri_modelbold is not None: verbose(1, "Load data from OpenFMRI model specification %s" % args.openfmri_modelbold) if not len(args.openfmri_modelbold[3]): args.openfmri_modelbold[3] = None # load openfmri dataset from mvpa2.datasets.sources.openfmri import OpenFMRIDataset of = OpenFMRIDataset(args.openfmri_modelbold[0]) ds = of.get_model_bold_dataset( int(args.openfmri_modelbold[1]), int(args.openfmri_modelbold[2]), flavor=args.openfmri_modelbold[3], mask=args.mask, add_fa=vol_attr, add_sa=args.add_fsl_mcpar, ) if ds is None: if args.data is None: raise RuntimeError("no data source specific") else: ds = hdf2ds(args.data)[0] else: if args.data is not None: verbose(1, "ignoring dataset input in favor of other data source -- remove either one to disambiguate") # act on all attribute options ds = process_common_dsattr_opts(ds, args) if args.openfmri_modelbold is None and args.add_fsl_mcpar is not None: from mvpa2.misc.fsl.base import McFlirtParams mc_par = McFlirtParams(args.add_fsl_mcpar) for param in mc_par: verbose(2, "Add motion regressor as sample attribute '%s'" % ("mc_" + param)) ds.sa["mc_" + param] = mc_par[param] verbose(3, "Dataset summary %s" % (ds.summary())) # and store outfilename = args.output if not outfilename.endswith(".hdf5"): outfilename += ".hdf5" verbose(1, "Save dataset to '%s'" % outfilename) h5save(outfilename, ds, mkdir=True, compression=args.hdf5_compression)
def load_tutorial_data(path=None, roi="brain", add_fa=None, flavor=None): """Loads the block-design demo dataset from PyMVPA dataset DB. Parameters ---------- path : str, optional Path to the directory with the extracted content of the tutorial data package. This is only necessary for accessing the full resolution data. The ``1slice``, and ``25mm`` flavors are shipped with PyMVPA itself, and the path argument is ignored for them. This function also honors the MVPA_LOCATION_TUTORIAL_DATA environment variable, and the respective configuration setting. roi : str or int or tuple or None, optional Region Of Interest to be used for masking the dataset. If a string is given a corresponding mask image from the demo dataset will be used (mask_<str>.nii.gz). If an int value is given, the corresponding ROI is determined from the atlas image (mask_hoc.nii.gz). If a tuple is provided it may contain int values that a processed as explained before, but the union of a ROIs is taken to produce the final mask. If None, no masking is performed. add_fa : dict, optional Passed on to the dataset creator function (see fmri_dataset() for more information). flavor: str, optional Resolution flavor of the data to load. By default, the data is loaded in its original resolution. The PyMVPA source distribution contains a '25mm' flavor that has been downsampled to a very coarse resolution and can be used for quick test execution. Likewise a ``1slice`` flavor is available that contents a full-resultion single-slice subset of the dataset. """ if path is None: if flavor in ("1slice", "25mm"): # we know that this part is there path = op.join(pymvpa_dataroot) else: # check config for info, pretend it is in the working dir otherwise path = mvpa2.cfg.get("location", "tutorial data", default=op.curdir) # we need the haxby2001 portion of the tutorial data path = op.join(path, "haxby2001") import nibabel as nb from mvpa2.datasets.sources.openfmri import OpenFMRIDataset model = subj = 1 dhandle = OpenFMRIDataset(path) if flavor is None: maskpath = op.join(path, "sub001", "masks", "orig") else: maskpath = op.join(path, "sub001", "masks", flavor) if roi is None: mask = None elif isinstance(roi, str): mask = op.join(maskpath, roi + ".nii.gz") elif isinstance(roi, int): nimg = nb.load(op.join(maskpath, "hoc.nii.gz")) tmpmask = nimg.get_data() == roi mask = nb.Nifti1Image(tmpmask.astype(int), nimg.get_affine(), nimg.get_header()) elif isinstance(roi, tuple) or isinstance(roi, list): nimg = nb.load(op.join(maskpath, "hoc.nii.gz")) if externals.versions["nibabel"] >= "1.2": img_shape = nimg.shape else: img_shape = nimg.get_shape() tmpmask = np.zeros(img_shape, dtype="bool") for r in roi: tmpmask = np.logical_or(tmpmask, nimg.get_data() == r) mask = nb.Nifti1Image(tmpmask.astype(int), nimg.get_affine(), nimg.get_header()) elif isinstance(roi, nb.Nifti1Image): mask = roi else: raise ValueError("Got something as mask that I cannot handle.") ds = dhandle.get_model_bold_dataset(model, subj, flavor=flavor, mask=mask, add_fa=add_fa, noinfolabel="rest") # fixup time_coords to make the impression of a continuous time series # this is only necessary until we have changed the tutorial to # show/encourage run-wise processing ds.sa["time_coords"] = np.linspace(0, (len(ds) * 2.5), len(ds) + 1)[:-1] return ds
#!/usr/bin/python import sys from os.path import join as _opj from mvpa2.datasets.sources.openfmri import OpenFMRIDataset from mvpa2.datasets.eventrelated import fit_event_hrf_model from mvpa2.base.hdf5 import h5save from nilearn.image import smooth_img import nibabel as nb datapath = 'BASEDIR' of = OpenFMRIDataset(datapath) sub = int(sys.argv[1]) + 1 def smooth(img): # we need to preserve the original header because the smoothing function # f***s the TR up nimg = smooth_img(img, fwhm=2.0) return nb.Nifti1Image(nimg.get_data(), img.get_affine(), header=img.get_header()) ds = of.get_model_bold_dataset( model_id=1, subj_id=sub, flavor='dico_bold7Tp1_to_subjbold7Tp1', # full brain mask=_opj( datapath, 'sub%.3i' % sub, 'templates', 'bold7Tp1',
def run(args): from mvpa2.base.hdf5 import h5save ds = None vol_attr = dict() if args.add_vol_attr is not None: # XXX add a way to use the mapper of an existing dataset to # add a volume attribute without having to load the entire # mri data again vol_attr = dict(args.add_vol_attr) if not len(args.add_vol_attr) == len(vol_attr): warning("--vol-attr option with duplicate attribute name: " "check arguments!") verbose(2, "Prepare to add volumetric feature attributes: %s" % vol_attr) if args.txt_data is not None: verbose(1, "Load data from TXT file '%s'" % args.txt_data) samples = _load_from_txt(args.txt_data) ds = Dataset(samples) elif args.npy_data is not None: verbose(1, "Load data from NPY file '%s'" % args.npy_data) samples = _load_from_npy(args.npy_data) ds = Dataset(samples) elif args.mri_data is not None: verbose(1, "Load data from MRI image(s) %s" % args.mri_data) from mvpa2.datasets.mri import fmri_dataset ds = fmri_dataset(args.mri_data, mask=args.mask, add_fa=vol_attr) elif args.openfmri_modelbold is not None: verbose( 1, "Load data from OpenFMRI model specification %s" % args.openfmri_modelbold) if not len(args.openfmri_modelbold[3]): args.openfmri_modelbold[3] = None # load openfmri dataset from mvpa2.datasets.sources.openfmri import OpenFMRIDataset of = OpenFMRIDataset(args.openfmri_modelbold[0]) ds = of.get_model_bold_dataset(int(args.openfmri_modelbold[1]), int(args.openfmri_modelbold[2]), flavor=args.openfmri_modelbold[3], mask=args.mask, add_fa=vol_attr, add_sa=args.add_fsl_mcpar) if ds is None: if args.data is None: raise RuntimeError('no data source specific') else: ds = hdf2ds(args.data)[0] else: if args.data is not None: verbose( 1, 'ignoring dataset input in favor of other data source -- remove either one to disambiguate' ) # act on all attribute options ds = process_common_dsattr_opts(ds, args) if args.openfmri_modelbold is None and args.add_fsl_mcpar is not None: from mvpa2.misc.fsl.base import McFlirtParams mc_par = McFlirtParams(args.add_fsl_mcpar) for param in mc_par: verbose( 2, "Add motion regressor as sample attribute '%s'" % ('mc_' + param)) ds.sa['mc_' + param] = mc_par[param] verbose(3, "Dataset summary %s" % (ds.summary())) # and store outfilename = args.output if not outfilename.endswith('.hdf5'): outfilename += '.hdf5' verbose(1, "Save dataset to '%s'" % outfilename) h5save(outfilename, ds, mkdir=True, compression=args.hdf5_compression)
def run(args): import numpy as np import pylab as pl from mvpa2.datasets.sources.openfmri import OpenFMRIDataset from mvpa2.misc.plot import timeseries_boxplot, concat_ts_boxplot_stats from mvpa2.misc.stats import compute_ts_boxplot_stats of = OpenFMRIDataset(args.path) data = of.get_task_bold_attributes( args.task, args.estimate_fname, np.loadtxt, exclude_subjs=args.exclude_subjs) segment_sizes = [len(d[0]) for d in data] # figure setup pl.figure(figsize=(12, 5)) ax = pl.subplot(211) # translation run_stats = [compute_ts_boxplot_stats( d[...,:3], outlier_abs_minthresh=args.outlier_minthresh, outlier_thresh=args.outlier_stdthresh, aggfx=np.linalg.norm, greedy_outlier=True) for d in data] stats = concat_ts_boxplot_stats(run_stats) timeseries_boxplot(stats[0]['median'], mean=stats[0]['mean'], std=stats[0]['std'], n=stats[0]['n'], min=stats[0]['min'], max=stats[0]['max'], p25=stats[0]['p25'], p75=stats[0]['p75'], outlierd=stats[1], segment_sizes=segment_sizes) pl.title('translation') xp, xl = pl.xticks() pl.xticks(xp, ['' for i in xl]) pl.xlim((0, len(stats[0]['n']))) #pl.ylim((0,7)) pl.ylabel('estimate L2-norm in mm') # rotation ax = pl.subplot(212) run_stats = [compute_ts_boxplot_stats( d[...,3:], outlier_abs_minthresh=args.outlier_minthresh, outlier_thresh=args.outlier_stdthresh, aggfx=np.linalg.norm, greedy_outlier=True) for d in data] stats = concat_ts_boxplot_stats(run_stats) timeseries_boxplot(stats[0]['median'], mean=stats[0]['mean'], std=stats[0]['std'], n=stats[0]['n'], min=stats[0]['min'], max=stats[0]['max'], p25=stats[0]['p25'], p75=stats[0]['p75'], outlierd=stats[1], segment_sizes=segment_sizes) pl.xlim((0, len(stats[0]['n']))) #pl.ylim((0,5)) pl.title('rotation') pl.ylabel('estimate L2-norm in deg') pl.xlabel('time in fMRI volumes') if args.savefig is None: pl.show() else: pl.savefig(args.safefig)