def test_setDescendantTipProperty(self): """setDescendantTipProperty should set correct property and value""" leaf_dict = {'d':2, 'e':1, 'g':6, 'h':7} means_dict = leaf_dict.copy() means_dict.update({'f':6, 'c':3, 'b':3, 'a':4}) stdevs_dict = {'d':0, 'e':0, 'g':0, 'f':0, 'c':stdev([2,1,6]), \ 'b':stdev([2,1,6]), 'h':0, 'a':stdev([2,1,6,7])} def set_leaf_f(node): return leaf_dict[node.Data] r = self.TreeRoot r.setDescendantTipProperty(set_leaf_f, 'x') for node in r.traverse(): self.assertEqual(node.xMean, means_dict[node.Data]) self.assertFloatEqual(node.xStdev, stdevs_dict[node.Data])
def setDescendantTipProperty(self,f,prop_name='Trait',force_recalc=False): """Sets n.propMean, n.propStdev) of f(node) for all nodes in self. These correspond to T_i and S_i respectively in AOT, Ackerley 2004. Example usage: (a) You have a dict mapping leaf -> property: leaf_f = lambda node: d[node.Data] (b) You have the property stored in leaf.prop_xyz: leaf_f = lambda node: node.prop_xyz tree.setDescendantTipProperty(leaf_f, 'MyProp') will set on each node n.MyPropMean and n.MyPropStdev. """ for node in self.traverse(self_before=False, self_after=True): if force_recalc or not hasattr(node, 'DescendantTips'): node.setDescendantTips() values = map(f, node.DescendantTips) setattr(node, prop_name+'Mean', mean(values)) if len(values) > 1: std = stdev(values) else: std = 0 setattr(node, prop_name+'Stdev', std)