Example #1
0
    def make_forest(self):
        """Output an nipy forest structure to represent the ROI hierarchy.

        """
        if self.k == 0:
            return None
        G = Forest(self.k, self.parents)
        return G
Example #2
0
    def reduce_to_leaves(self, rid=''):
        """create a  new set of rois which are only the leaves of self
        """
        isleaf = Forest(self.k, self.parents).isleaf()
        label = self.label.copy()
        label[isleaf[self.label] == 0] = -1
        k = np.sum(isleaf.astype(np.int))
        if self.k == 0:
            return HierarchicalROI(self.domain, label, np.array([]), rid)

        parents = np.arange(k)
        nroi = HierarchicalROI(self.domain, label, parents, rid)

        # now copy the features
        fids = self.features.keys()
        for fid in fids:
            df = [self.features[fid][k] for k in range(self.k) if isleaf[k]]
            nroi.set_feature(fid, df)
        return nroi
Example #3
0
 def select(self, valid, rid='', no_empty_label=True):
     """
     Remove the rois for which valid==0 and update the hierarchy accordingly
     Note that auto=True automatically
     """
     SubDomains.select(self, valid, rid, True, no_empty_label)
     if np.sum(valid) == 0:
         self.parents = np.array([])
     else:
         self.parents = Forest(len(self.parents), self.parents).subforest(
             valid.astype(np.bool)).parents.astype(np.int)
Example #4
0
File: hroi.py Project: Hiccup/nipy
    def select(self, valid, rid='', no_empty_label=True):
        """Remove rois for which valid == 0 and update
           the hierarchy accordingly.

        Parameters
        ----------
        valid: boolean array of shape(self.k)
          Array defining which regions must be merged.
          If valid[i] == False, the i_th region is discarded.

        (fixme: what does this refers to?)
        Note that auto=True automatically

        """
        SubDomains.select(self, valid, rid, True, no_empty_label)
        if np.sum(valid) == 0:
            self.parents = np.array([])
        else:
            self.parents = Forest(len(self.parents), self.parents).subforest(
                valid.astype(np.bool)).parents.astype(np.int)
Example #5
0
    def select_roi(self, id_list):
        """Returns an instance of HROI with only the subset of chosen ROIs.

        The hierarchy is set accordingly.

        Parameters
        ----------
        id_list: list of id (any hashable type)
          The id of the ROI to be kept in the structure.

        """
        valid = np.asarray([int(i in id_list) for i in self.get_id()])
        if np.size(id_list) == 0:
            # handle the case of an empty selection
            new_parents = np.array([])
            self = HierarchicalROI(self.domain, -np.ones(self.label.size),
                                   np.array([]))
        else:
            # get new parents
            new_parents = Forest(self.k, self.parents).subforest(
                valid.astype(np.bool)).parents.astype(np.int)
        SubDomains.select_roi(self, id_list)
        self.parents = new_parents
        self.recompute_labels()
Example #6
0
File: hroi.py Project: Hiccup/nipy
class HierarchicalROI(SubDomains):
    """Class that handles hierarchical ROIs
    """

    def __init__(self, domain, label, parents, rid=''):
        """Building the HierarchicalROI
        """
        self.parents = np.ravel(parents).astype(np.int)
        SubDomains.__init__(self, domain, label, rid)

    def select(self, valid, rid='', no_empty_label=True):
        """Remove rois for which valid == 0 and update
           the hierarchy accordingly.

        Parameters
        ----------
        valid: boolean array of shape(self.k)
          Array defining which regions must be merged.
          If valid[i] == False, the i_th region is discarded.

        (fixme: what does this refers to?)
        Note that auto=True automatically

        """
        SubDomains.select(self, valid, rid, True, no_empty_label)
        if np.sum(valid) == 0:
            self.parents = np.array([])
        else:
            self.parents = Forest(len(self.parents), self.parents).subforest(
                valid.astype(np.bool)).parents.astype(np.int)

    def make_graph(self):
        """Output an fff.graph structure to represent the ROI hierarchy

        """
        if self.k == 0:
            return None
        weights = np.ones(self.k)
        edges = (np.vstack((np.arange(self.k), self.parents))).T
        return WeightedGraph(self.k, edges, weights)

    def make_forest(self):
        """Output an fff.forest structure to represent the ROI hierarchy

        """
        if self.k == 0:
            return None
        G = Forest(self.k, self.parents)
        return G

    def merge_ascending(self, valid):
        """Remove the non-valid ROIs by including them in
        their parents when it exists.

        Parameters
        ----------
        valid: boolean array of shape(self.k)
          Array defining which regions must be merged.
          If valid[i] == False, the i_th region is merged in its parent.

        Note
        ----
        If valid[k]==0 and self.parents[k]==k, k is not removed

        """
        if np.size(valid) != self.k:
            raise ValueError("not the correct dimension for valid")
        if self.k == 0:
            return
        order = self.make_forest().reorder_from_leaves_to_roots()
        for j in order:
            if valid[j] == 0:
                fj = self.parents[j]
                if fj != j:
                    self.parents[self.parents == j] = fj
                    self.label[self.label == j] = fj
                    fids = self.features.keys()
                    for fid in fids:
                        dfj = self.features[fid][fj]
                        dj = self.features[fid][j]
                        if len(dfj.shape) == 1:
                            dfj = dfj.reshape((-1, 1))
                        if len(dj.shape) == 1:
                            dj = dj.reshape((-1, 1))
                        self.features[fid][fj] = np.concatenate(
                            (np.ravel(dfj), np.ravel(dj)))
                else:
                    valid[j] = 1

        self.select(valid)

    def merge_descending(self, methods=None):
        """ Remove the items with only one son by including them in their son

        Parameters
        ----------
        methods indicates the way possible features are dealt with
        (not implemented yet)

        Caveat
        ------
        if roi_features have been defined, they will be removed
        """
        if self.k == 0:
            return

        valid = np.ones(self.k).astype('bool')
        order = self.make_forest().reorder_from_leaves_to_roots()[:: - 1]
        for j in order:
            i = np.nonzero(self.parents == j)
            i = i[0]
            if np.sum(i != j) == 1:
                i = int(i[i != j])
                self.parents[i] = self.parents[j]
                self.label[self.label == j] = i
                valid[j] = 0
                fids = self.features.keys()
                for fid in fids:
                    di = self.features[fid][i]
                    dj = self.features[fid][j]
                    self.features[fid][i] = np.concatenate(
                        (np.ravel(di), np.ravel(dj)))

        # finally remove  the non-valid items
        self.select(valid)

    def get_parents(self):
        return self.parents

    def get_k(self):
        return self.k

    def isleaf(self):
        """
        """
        if self.k == 0:
            return np.array([])
        return Forest(self.k, self.parents).isleaf()

    def reduce_to_leaves(self, rid=''):
        """Create a  new set of rois which are only the leaves of self

        """
        if self.k == 0:
            return HierarchicalROI(
                self.domain, -np.ones(self.domain.size), np.array([]), rid)
        isleaf = Forest(self.k, self.parents).isleaf()
        label = self.label.copy()
        label[isleaf[self.label] == 0] = -1
        k = np.sum(isleaf.astype(np.int))

        parents = np.arange(k)
        nroi = HierarchicalROI(self.domain, label, parents, rid)

        # now copy the features
        fids = self.features.keys()
        for fid in fids:
            df = [self.features[fid][k] for k in range(self.k) if isleaf[k]]
            nroi.set_feature(fid, df)
        return nroi

    def copy(self, rid=''):
        """ Returns a copy of self. self.domain is not copied.
        """
        cp = make_hroi_from_subdomain(SubDomains.copy(self, rid),
                                      self.parents.copy())
        return cp

    def representative_feature(self, fid, method='mean'):
        """Compute an ROI-level feature given the discrete features

        Parameters
        ----------
        fid: str,
          The discrete feature under consideration.
        method: str,
          The assessment method. Values can be:
          - 'mean' (default)
          - 'min'
          - 'max'
          - 'cumulated mean'
          - 'median'
          - 'weighted mean'

        Returns
        -------
        The computed roi-feature is returned

        """
        if method not in['min', 'max', 'mean', 'cumulated mean', 'median',
                         'weighted mean']:
            raise  ValueError('unknown method')
        if method == 'cumulated mean':
            data = self.features[fid]
            d0 = data[0]
            if np.size(d0) == np.shape(d0)[0]:
                np.reshape(d0, (np.size(d0), 1))
            fdim = d0.shape[1]
            ldata = np.zeros((self.k, fdim))
            for k in range(self.k):
                dk = self.make_forest().get_descendents(k)
                card = np.sum(self.get_size()[dk])
                for ch in dk:
                    ldata[k] += np.sum(data[ch], 0)
                ldata[k] /= card
            self.set_roi_feature(fid, ldata)
        else:
            ldata = SubDomains.representative_feature(self, fid, method)

        return ldata