Beispiel #1
0
    def __init__(self, samples=None, mask=None, **kwargs):
        """
        :Parameters:
          mask: ndarray
            the chosen features equal the non-zero mask elements.
        """
        # might contain the default mapper
        mapper = None

        # need if clause here as N.array(None) != None
        if not samples is None:
            # XXX should be asanyarray? but then smth segfaults on unittests
            samples = N.asarray(samples)
            mapper = DenseArrayMapper(mask=mask,
                                      shape=samples.shape[1:])

        if not mapper is None:
            if samples is None:
                raise ValueError, \
                      "Constructor of MaskedDataset requires both a samples " \
                      "array and a mask if one of both is provided."
            # init base class -- MappedDataset takes care of all the forward
            # mapping stuff
            MappedDataset.__init__(
                self,
                samples=samples,
                mapper=mapper,
                **(kwargs))
        else:
            MappedDataset.__init__(self, **(kwargs))
Beispiel #2
0
    def __init__(self, samples=None, dsattr=None,
                 t0=None, dt=None, channelids=None, **kwargs):
        """Initialize ChannelDataset.

        :Parameters:
          samples: ndarray
            Three-dimensional array: (samples x channels x timepoints).
          t0: float
            Reference time of the first timepoint. Can be used to preserve
            information about the onset of some stimulation. Preferably in
            seconds.
          dt: float
            Temporal distance between two timepoints. Has to be given in
            seconds. Otherwise `samplingrate` property will not return
            `Hz`.
          channelids: list
            List of channel names.
        """
        # if dsattr is none, set it to an empty dict
        if dsattr is None:
            dsattr = {}

        # check samples
        if not samples is None and len(samples.shape) != 3:
                raise ValueError, \
                  "ChannelDataset takes 3D array as samples."

        # charge dataset properties
        # but only if some value
        if (not dt is None) or not dsattr.has_key('ch_dt'):
            dsattr['ch_dt'] = dt
        if (not channelids is None) or not dsattr.has_key('ch_ids'):
            dsattr['ch_ids'] = channelids
        if (not t0 is None) or not dsattr.has_key('ch_t0'):
            dsattr['ch_t0'] = t0

        # come up with mapper if fresh samples were provided
        if not samples is None:
            mapper = MaskMapper(N.ones(samples.shape[1:], dtype='bool'))
        else:
            # Doesn't make difference at the moment, but might come 'handy'?
            mapper = dsattr.get('mapper', None)

        # init dataset
        MappedDataset.__init__(self,
                               samples=samples,
                               mapper=mapper,
                               dsattr=dsattr,
                               **(kwargs))
Beispiel #3
0
    def __init__(self, samples=None, events=None, mask=None, bcshape=None,
                 dametric=None, **kwargs):
        """
        :Parameters:
          samples: ndarray
            'Raw' input data from which boxcar-shaped samples will be extracted.
          events: sequence of `Event` instances
            Both an events `onset` and `duration` are assumed to be provided
            as #samples. The boxlength will be determined by the maximum
            duration of all events.
          mask: boolean array
            Only features corresponding to non-zero mask elements will be
            considered for the final dataset. The mask shape either has to match
            the shape of the generated boxcar-samples, or the shape of the 'raw'
            input samples. In the latter case, the mask is automatically
            expanded to cover the whole boxcar. If no mask is provided, a
            full mask will be constructed automatically.
          bcshape: tuple
            Shape of the boxcar samples generated by the embedded boxcar mapper.
            If not provided this is determined automatically. However, this
            required an extra mapping step.
          dametric: Metric
            Custom metric to be used by the embedded DenseArrayMapper.
          **kwargs
            All additional arguments are passed to the base class.
        """
        # check if we are in copy constructor mode
        if events is None:
            MappedDataset.__init__(self, samples=samples, **kwargs)
            return

        #
        # otherwise we really want to freshly prepare a dataset
        #

        # loop over events and extract all meaningful information to charge
        # a boxcar mapper
        startpoints = [e['onset'] for e in events]
        try:
            durations = [e['duration'] for e in events]
        except KeyError:
            raise ValueError, "Each event must have a `duration`!"

        # we need a regular array, so all events must have a common
        # boxlength
        boxlength = max(durations)
        if __debug__:
            if not max(durations) == min(durations):
                warning('Boxcar mapper will use maximum boxlength (%i) of all '
                        'provided Events.'% boxlength)

        # now look for stuff we need for the dataset itself
        try:
            labels = [e['label'] for e in events]
        except KeyError:
            raise ValueError, "Each event must have a `label`!"
        # chunks are optional
        chunks = [e['chunk'] for e in events if e.has_key('chunk')]
        if not len(chunks):
            chunks = None

        # optional stuff
        # extract additional features for each event
        extrafeatures = [e['features'] 
                            for e in events if e.has_key('features')]

        # sanity check for extra features
        if len(extrafeatures):
            if len(extrafeatures) == len(startpoints):
                try:
                    # will fail if varying number of features per event
                    extrafeatures = N.asanyarray(extrafeatures)
                except ValueError:
                    raise ValueError, \
                          'Unequal number of extra features per event'
            else:
                raise ValueError, \
                      'Each event has to provide to same number of extra ' \
                      'features.'
        else:
            extrafeatures = None

        # now build the mapper
        # we know the properties of the boxcar mapper, so now use it
        # to determine its output size unless it is already provided
        bcmapper = BoxcarMapper(startpoints, boxlength)

        # determine array mapper input shape, as a fail-safe procedure
        # in case no mask provided, and to check the mask sanity if we have one
        if bcshape is None:
            # map the data and look at the shape of the first sample
            # to determine the properties of the array mapper
            bcshape = bcmapper(samples)[0].shape

        # expand the mask if necessary (ie. if provided in raw sample space and
        # not in boxcar space
        if not mask is None:
            if len(mask.shape) < len(bcshape)-1:
                # complement needed dimensions
                mshape = mask.shape
                missing_dims = len(bcshape) - 1 - len(mshape)
                mask = mask.reshape((1,)*missing_dims + mshape)
            if len(mask.shape) == len(bcshape) - 1:
                # replicate per each boxcar elemenet
                mask = N.array([mask] * bcshape[0])

        # now we can build the array mapper, using the optionally provided
        # custom metric
        amapper = DenseArrayMapper(mask=mask, shape=bcshape, metric=dametric)

        # now compose the full mapper for the main samples
        mapper = ChainMapper([bcmapper, amapper])

        # if we have extra features, we need to combine them with the rest
        if not extrafeatures is None:
            # first half for main samples, second half simple mask mapper
            # for unstructured additional features
            mapper = CombinedMapper(
                        (mapper,
                         MaskMapper(mask=N.ones(extrafeatures.shape[1]))))

            # add extra features to the samples
            samples = (samples, extrafeatures)

        # finally init baseclass
        MappedDataset.__init__(self,
                               samples=samples,
                               labels=labels,
                               chunks=chunks,
                               mapper=mapper,
                               **kwargs)
Beispiel #4
0
    def __init__(self, samples=None, mask=None, dsattr=None,
                 enforce_dim=4, **kwargs):
        """
        :Parameters:
          samples: str | NiftiImage
            Filename of a NIfTI image or a `NiftiImage` instance.
          mask: str | NiftiImage | ndarray
            Filename of a NIfTI image or a `NiftiImage` instance or an ndarray
            of appropriate shape.
          enforce_dim : int or None
            If not None, it is the dimensionality of the data to be enforced,
            commonly 4D for the data, and 3D for the mask in case of fMRI.
        """
        # if in copy constructor mode
        if not dsattr is None and dsattr.has_key('mapper'):
            MappedDataset.__init__(self,
                                   samples=samples,
                                   dsattr=dsattr,
                                   **kwargs)
            return

        #
        # the following code only deals with contructing fresh datasets from
        # scratch
        #

        # load the samples
        niftisamples = getNiftiFromAnySource(samples, ensure=True,
                                             enforce_dim=enforce_dim)
        samples = niftisamples.data

        # do not put the whole NiftiImage in the dict as this will most
        # likely be deepcopy'ed at some point and ensuring data integrity
        # of the complex Python-C-Swig hybrid might be a tricky task.
        # Only storing the header dict should achieve the same and is more
        # memory efficient and even simpler
        dsattr = {'niftihdr': niftisamples.header}


        # figure out what the mask is, but onyl handle known cases, the rest
        # goes directly into the mapper which maybe knows more
        niftimask = getNiftiFromAnySource(mask)
        if niftimask is None:
            pass
        elif isinstance(niftimask, N.ndarray):
            mask = niftimask
        else:
            mask = getNiftiData(niftimask)

        # build an appropriate mapper that knows about the metrics of the NIfTI
        # data
        # NiftiDataset uses a DescreteMetric with cartesian
        # distance and element size from the NIfTI header

        # 'voxdim' is (x,y,z) while 'samples' are (t,z,y,x)
        elementsize = [i for i in reversed(niftisamples.voxdim)]
        mapper = DenseArrayMapper(mask=mask, shape=samples.shape[1:],
                    metric=DescreteMetric(elementsize=elementsize,
                                          distance_function=cartesianDistance))

        MappedDataset.__init__(self,
                               samples=samples,
                               mapper=mapper,
                               dsattr=dsattr,
                               **kwargs)