def __call__(self, data ): if self.nlevels == None: raise NotImplementedError("incomplete implementation of %s" % str(self)) labels = DataTree.getPaths( data ) debug( "transform: started with paths: %s" % labels) assert len(labels) >= self.nlevels, "expected at least %i levels - got %i" % (self.nlevels, len(labels)) paths = list(itertools.product( *labels[:-self.nlevels] )) for path in paths: work = DataTree.getLeaf( data, path ) if not work: continue new_data = self.transform( work, path ) if new_data: if path: DataTree.setLeaf( data, path, new_data ) else: # set new root data = new_data else: warn( "no data at %s - removing branch" % str(path)) DataTree.removeLeaf( data, path ) debug( "transform: finished with paths: %s" % DataTree.getPaths( data )) return data
def __call__(self, data, path ): '''iterate over leaves/branches in data structure. This method will call the :meth:`render` method for each leaf/branch at level :attr:`nlevels`. ''' if self.nlevels == None: raise NotImplementedError("incomplete implementation of %s" % str(self)) result = ResultBlocks( title = path2str(path) ) labels = DataTree.getPaths( data ) if len(labels) < self.nlevels: self.warn( "at %s: expected at least %i levels - got %i: %s" %\ (str(path), self.nlevels, len(labels), str(labels)) ) result.append( EmptyResultBlock( title = path2str(path) ) ) return result paths = list(itertools.product( *labels[:-self.nlevels] )) for p in paths: work = DataTree.getLeaf( data, p ) if not work: continue try: result.extend( self.render( work, path + p ) ) except: self.warn("exeception raised in rendering for path: %s" % str(path+p)) raise return result
def transform(self,data,path): from rpy2.robjects import r as R paths, lengths, values = [],[],[] labels = DataTree.getPaths(data) paths = list(itertools.product( *labels[:-1])) for path in paths: work = DataTree.getLeaf(data, path) try: lengths.append(len(work[self.pval])) values.extend(work[self.pval]) except TypeError: lengths.append(0) values.append(work[self.pval]) padj = R["p.adjust"](values, method = self.method) padj = [x for x in padj] for path in paths: num = lengths.pop(0) if num > 0: new_values = padj[0:num] padj = padj[num:] else: new_values = padj[0] padj = padj[1:] if path: work = odict(DataTree.getLeaf(data,path)) work["P-adjust"] = new_values DataTree.setLeaf(data,path,work) else: data["P-adjust"] = new_values return data
def render(self): """supply the :class:`Renderer.Renderer` with the data to render. The data supplied will depend on the ``groupby`` option. return resultblocks """ self.debug("%s: rendering data started for %i items" % (self, len(self.data))) results = ResultBlocks(title="main") # get number of levels required by renderer try: renderer_nlevels = self.renderer.nlevels except AttributeError: renderer_nlevels = 0 data_paths = DataTree.getPaths(self.data) nlevels = len(data_paths) group_level = self.group_level self.debug( "%s: rendering data started. levels=%i, required levels>=%i, group_level=%i, data_paths=%s" % (self, nlevels, renderer_nlevels, group_level, str(data_paths)[:100]) ) if nlevels < renderer_nlevels: # add some dummy levels if levels is not enough d = self.data for x in range(renderer_nlevels - nlevels): d = odict((("all", d),)) results.append(self.renderer(d, path=("all",))) elif group_level < 0 or renderer_nlevels < 0: # no grouping results.append(self.renderer(self.data, path=())) else: # group at level group_level paths = list(itertools.product(*data_paths[: group_level + 1])) for path in paths: work = DataTree.getLeaf(self.data, path) if not work: continue try: results.append(self.renderer(work, path=path)) except: results.append(ResultBlocks(Utils.buildException("rendering"))) if len(results) == 0: self.warn("tracker returned no data.") raise ValueError("tracker returned no data.") self.debug("%s: rendering data finished with %i blocks" % (self.tracker, len(results))) return results
def prune(self): """prune data tree. Remove all empty leaves. Remove all levels from the data tree that are superfluous, i.e. levels that contain only a single label all labels in the hierarchy below are the same. Ignore both the first and last level for this analyis. """ # remove all empty leaves DataTree.removeEmptyLeaves(self.data) # prune superfluous levels data_paths = DataTree.getPaths(self.data) nlevels = len(data_paths) # get number of levels required by renderer try: renderer_nlevels = self.renderer.nlevels except AttributeError: renderer_nlevels = 0 # do not prune for renderers that want all data if renderer_nlevels < 0: return levels_to_prune = [] for level in range(1, nlevels - 1): # check for single label in level if len(data_paths[level]) == 1: label = data_paths[level][0] prefixes = DataTree.getPrefixes(self.data, level) keep = False for prefix in prefixes: leaves = DataTree.getLeaf(self.data, prefix) if len(leaves) > 1 or label not in leaves: keep = True break if not keep: levels_to_prune.append((level, label)) levels_to_prune.reverse() # only prune to the minimum of levels required by renderer at most # levels_to_prune = levels_to_prune[:nlevels - renderer_nlevels] for level, label in levels_to_prune: self.debug("pruning level %i from data tree: label='%s'" % (level, label)) DataTree.removeLevel(self.data, level)