Beispiel #1
0
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)
Beispiel #2
0
    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)]
Beispiel #3
0
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
Beispiel #4
0
 def _build_event(onset, duration, combo):
     ev = Event(onset=onset, duration=duration, **combo)
     return ev