def test_er_nifti_dataset_mapping(): """Some mapping testing -- more tests is better """ # z,y,x sample_size = (4, 3, 2) # t,z,y,x samples = np.arange(120).reshape((5, ) + sample_size) dsmask = np.arange(24).reshape(sample_size) % 2 import nibabel tds = fmri_dataset(nibabel.Nifti1Image(samples.T, None), mask=nibabel.Nifti1Image(dsmask.T, None)) ds = eventrelated_dataset(tds, events=[ Event(onset=0, duration=2, label=1, chunk=1, features=[1000, 1001]), Event(onset=1, duration=2, label=2, chunk=1, features=[2000, 2001]) ]) nfeatures = tds.nfeatures mask = np.zeros(dsmask.shape, dtype='bool') mask[0, 0, 0] = mask[1, 0, 1] = mask[0, 0, 1] = 1 fmask = ds.a.mapper.forward1(mask.T) # select using mask in volume and all features in the other part ds_sel = ds[:, fmask] # now tests assert_array_equal(mask.reshape(24).nonzero()[0], [0, 1, 7]) # two events, 2 orig features at 2 timepoints assert_equal(ds_sel.samples.shape, (2, 4)) assert_array_equal(ds_sel.sa.features, [[1000, 1001], [2000, 2001]]) assert_array_equal(ds_sel.samples, [[1, 7, 25, 31], [25, 31, 49, 55]]) # reproducability assert_array_equal(ds_sel.samples, ds_sel.a.mapper.forward(np.rollaxis(samples.T, -1))) # reverse-mapping rmapped = ds_sel.a.mapper.reverse1(np.arange(10, 14)) assert_equal(np.rollaxis(rmapped, 0, 4).T.shape, (2, ) + sample_size) expected = np.zeros((2, ) + sample_size, dtype='int') expected[0, 0, 0, 1] = 10 expected[0, 1, 0, 1] = 11 expected[1, 0, 0, 1] = 12 expected[1, 1, 0, 1] = 13 assert_array_equal(np.rollaxis(rmapped, 0, 4).T, expected)
def to_events(self, **kwargs): """Convert into a list of `Event` instances. Parameters ---------- kwargs Any keyword arugment provided would be replicated, through all the entries. Useful to specify label or even a chunk """ return \ [Event(onset=self['onsets'][i], duration=self['durations'][i], features=[self['intensities'][i]], **kwargs) for i in range(self.nevs)]
def simple_hrf_dataset(events=None, hrf_gen=lambda t: double_gamma_hrf(t) - single_gamma_hrf(t, 0.8, 1, 0.05), fir_length=15, nsamples=None, tr=2.0, tres=1, baseline=800.0, signal_level=1, noise='normal', noise_level=1, resampling='scipy'): """ events: list of Events or ndarray of onsets for simple(r) designs """ if events is None: events = [1, 20, 25, 50, 60, 90, 92, 140] if isinstance(events, np.ndarray) or not isinstance(events[0], dict): events = [Event(onset=o) for o in events] else: assert (isinstance(events, list)) for e in events: assert (isinstance(e, dict)) # play fmri # full-blown HRF with initial dip and undershoot ;-) hrf_x = np.arange(0, float(fir_length) * tres, tres) if isinstance(hrf_gen, np.ndarray): # just accept provided HRF and only verify size match assert (len(hrf_x) == len(hrf_gen)) hrf = hrf_gen else: # actually generate it hrf = hrf_gen(hrf_x) if not nsamples: # estimate number of samples needed if not provided max_onset = max([e['onset'] for e in events]) nsamples = int(max_onset / tres + len(hrf_x) * 1.5) # come up with an experimental design fast_er = np.zeros(nsamples) for e in events: on = int(e['onset'] / float(tres)) off = int((e['onset'] + e.get('duration', 1.)) / float(tres)) if off == on: off += 1 # so we have at least 1 point assert (range(on, off)) fast_er[on:off] = e.get('intensity', 1) # high resolution model of the convolved regressor model_hr = np.convolve(fast_er, hrf)[:nsamples] # downsample the regressor to fMRI resolution if resampling == 'scipy': from scipy import signal model_lr = signal.resample(model_hr, int(tres * nsamples / tr), window='ham') elif resampling == 'naive': if tr % tres != 0.0: raise ValueError("You must use resample='scipy' since your TR=%.2g" " is not multiple of tres=%.2g" % (tr, tres)) if tr < tres: raise ValueError("You must use resample='scipy' since your TR=%.2g" " is less than tres=%.2g" % (tr, tres)) step = int(tr // tres) model_lr = model_hr[::step] else: raise ValueError("resampling can only be 'scipy' or 'naive'. Got %r" % resampling) # generate artifical fMRI data: two voxels one is noise, one has # something wsignal = baseline + model_lr * signal_level nsignal = np.ones(wsignal.shape) * baseline # build design matrix: bold-regressor and constant design = np.array([model_lr, np.repeat(1, len(model_lr))]).T # two 'voxel' dataset ds = dataset_wizard(samples=np.array((wsignal, nsignal)).T, targets=1) ds.a['baseline'] = baseline ds.a['tr'] = tr ds.sa['design'] = design ds.fa['signal_level'] = [signal_level, False] if noise == 'autocorrelated': # this one seems to be quite unstable and can provide really # funky noise at times noise = autocorrelated_noise(ds, 1 / tr, 1 / (2 * tr), lfnl=noise_level, hfnl=noise_level, add_baseline=False) elif noise == 'normal': noise = np.random.randn(*ds.shape) * noise_level else: raise ValueError(noise) ds.sa['noise'] = noise ds.samples += noise return ds
def _build_event(onset, duration, combo): ev = Event(onset=onset, duration=duration, **combo) return ev