def test_make_copy(): tree_copy = make_copy(REF_TREE3) # assert that the two trees have the same values # first by total nodes nt.assert_true(len(list(ipreorder(tree_copy))) == len(list(ipreorder(REF_TREE3)))) # then node by node for val1, val2 in izip(val_iter(ipreorder(tree_copy)), val_iter(ipreorder(REF_TREE3))): nt.assert_true(all(val1 == val2)) # assert that the tree values do not have the same identity for val1, val2 in izip(val_iter(ipreorder(tree_copy)), val_iter(ipreorder(REF_TREE3))): nt.assert_false(val1 is val2) # create a deepcopy of the original tree for validation validation_tree = deepcopy(REF_TREE3) # modify copied tree tree_copy.value[0:3] = np.array([1000.0, 1000.0, -1000.0]) tree_copy.children[0].add_child(Tree(np.array([0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0]))) # check if anything changed in REF_TREE3 with respect to the validation deepcopy nt.assert_true(len(list(ipreorder(validation_tree))) == len(list(ipreorder(REF_TREE3)))) for val1, val2 in izip(val_iter(ipreorder(REF_TREE3)), val_iter(ipreorder(validation_tree))): nt.assert_true(all(val1 == val2))
def _evaluate(tr1, tr2, comp_func): for v1, v2 in izip(val_iter(ipreorder(tr1)), val_iter(ipreorder(tr2))): #print "v1 : ", v1[:COLS.R] #print "v2 : ", v2[:COLS.R] #print "-" * 10 nt.assert_true(comp_func(v1[:COLS.R], v2[:COLS.R]))
def test_preorder_iteration(): nt.ok_( list(val_iter(ipreorder(REF_TREE))) == [0, 11, 111, 112, 12, 121, 1211, 12111, 12112, 122]) nt.ok_(list(val_iter(ipreorder(REF_TREE.children[0]))) == [11, 111, 112]) nt.ok_( list(val_iter(ipreorder(REF_TREE.children[1]))) == [12, 121, 1211, 12111, 12112, 122])
def test_iter_points(self): ref_point_radii = [] for t in self.neuron.neurites: ref_point_radii.extend(p[COLS.R] for p in val_iter(ipreorder(t))) rads = [r for r in self.neuron.iter_points(lambda p: p[COLS.R])] nt.assert_true(np.all(ref_point_radii == rads))
def test_copy(): soma = neuron.make_soma([[0, 0, 0, 1, 1, 1, -1]]) nrn1 = neuron.Neuron(soma, [TREE], name="Rabbit of Caerbannog") nrn2 = nrn1.copy() # check if two neurons are identical # somata nt.assert_true(isinstance(nrn2.soma, type(nrn1.soma))) nt.assert_true(nrn1.soma.radius == nrn2.soma.radius) for v1, v2 in izip(nrn1.soma.iter(), nrn2.soma.iter()): nt.assert_true(np.allclose(v1, v2)) # neurites for neu1, neu2 in izip(nrn1.neurites, nrn2.neurites): nt.assert_true(isinstance(neu2, type(neu1))) for v1, v2 in izip(val_iter(ipreorder(neu1)), val_iter(ipreorder(neu2))): nt.assert_true(np.allclose(v1, v2)) # check if the ids are different # somata nt.assert_true( nrn1.soma is not nrn2.soma) # neurites for neu1, neu2 in izip(nrn1.neurites, nrn2.neurites): nt.assert_true(neu1 is not neu2) # check if changes are propagated between neurons nrn2.soma.radius = 10. nt.assert_false(nrn1.soma.radius == nrn2.soma.radius) # neurites for neu1, neu2 in izip(nrn1.neurites, nrn2.neurites): for v1, v2 in izip(val_iter(ipreorder(neu1)), val_iter(ipreorder(neu2))): v2 = np.array([-1000., -1000., -1000., 1000., -100., -100., -100.]) nt.assert_false(any(v1 == v2))
def find_tree_type(tree): """ Calculates the 'mean' type of the tree. Accepted tree types are: 'undefined', 'axon', 'basal', 'apical' The 'mean' tree type is defined as the type that is shared between at least 51% of the tree's points. Returns: The type of the tree """ tree_types = tuple(TreeType) types = [node[COLS.TYPE] for node in tr.val_iter(tr.ipreorder(tree))] types = [node[COLS.TYPE] for node in tr.val_iter(tr.ipreorder(tree))] return tree_types[int(np.median(types))]
def test_deep_iteration(): root = t = Tree(0) for i in range(1, sys.getrecursionlimit() + 2): child = Tree(i) t.add_child(child) t = child list(ipreorder(root)) list(ipostorder(root)) list(iupstream(t))
def _check_trees(trees): for t in trees: nt.ok_(len(list(tree.ileaf(t))) == 11) nt.ok_(len(list(tree.iforking_point(t))) == 10) nt.ok_(len(list(tree.ipreorder(t))) == 211) nt.ok_(len(list(tree.ipostorder(t))) == 211) nt.ok_(len(list(tree.isegment(t))) == 210) leaves = [l for l in tree.ileaf(t)] # path length from each leaf to root node. branch_order = [21, 31, 41, 51, 61, 71, 81, 91, 101, 111, 111] for i, l in enumerate(leaves): nt.ok_(len(list(tree.iupstream(l))) == branch_order[i])
def _total_rectangles(tree): ''' Calculate the total number of segments that are required for the dendrogram. There is a vertical line for each segment and two horizontal line at each branching point ''' def f(children): '''Calculates number of lines needed for the children of a node ''' return 2 * len(children) if len(children) != 1 else 1 return sum(f(node.children) for node in ipreorder(tree))
def nonzero_neurite_radii(neuron, threshold=0.0): '''Check presence of neurite points with radius not above threshold Arguments: neuron: Neuron object whose segments will be tested threshold: value above which a radius is considered to be non-zero Return: list of IDs of zero-radius points ''' ids = [[i[COLS.ID] for i in val_iter(ipreorder(t)) if i[COLS.R] <= threshold] for t in neuron.neurites] return [i for i in chain(*ids)]
def nonzero_neurite_radii(neuron, threshold=0.0): '''Check presence of neurite points with radius not above threshold Arguments: neuron: Neuron object whose segments will be tested threshold: value above which a radius is considered to be non-zero Return: list of IDs of zero-radius points ''' ids = [[ i[COLS.ID] for i in val_iter(ipreorder(t)) if i[COLS.R] <= threshold ] for t in neuron.neurites] return [i for i in chain(*ids)]
def get_bounding_box(tree): """ Returns: The boundaries of the tree in three dimensions: [[xmin, ymin, zmin], [xmax, ymax, zmax]] """ min_xyz, max_xyz = (np.array([np.inf, np.inf, np.inf]), np.array([np.NINF, np.NINF, np.NINF])) for p in val_iter(tr.ipreorder(tree)): min_xyz = np.minimum(p[: COLS.R], min_xyz) max_xyz = np.maximum(p[: COLS.R], max_xyz) return np.array([min_xyz, max_xyz])
def get_bounding_box(tree): """ Returns: The boundaries of the tree in three dimensions: [[xmin, ymin, zmin], [xmax, ymax, zmax]] """ min_xyz, max_xyz = (np.array([np.inf, np.inf, np.inf]), np.array([np.NINF, np.NINF, np.NINF])) for p in val_iter(tr.ipreorder(tree)): min_xyz = np.minimum(p[:COLS.R], min_xyz) max_xyz = np.maximum(p[:COLS.R], max_xyz) return np.array([min_xyz, max_xyz])
def is_monotonic(tree, tol): '''Check if tree is monotonic, i.e. if each child has smaller or equal diameters from its parent Arguments: tree : tree object tol: numerical precision ''' for node in ipreorder(tree): if node.parent is not None: if node.value[COLS.R] > node.parent.value[COLS.R] + tol: return False return True
def _affineTransformTree(tree, A, t, origin=None): ''' Apply an affine transform on your tree by applying a linear transform A (e.g. rotation) and a non-linear transform t (translation) Input: A : 3x3 transformation matrix t : 3x1 translation array tree : tree object origin : the point with respect of which the rotation is applied. If None then the x,y,z of the root node is assumed to be the origin. ''' # if no origin is specified, the position from the root node # becomes the origin if origin is None: origin = tree.value[:COLS.R] for value in val_iter(ipreorder(tree)): _affineTransformPoint(value, A, t, origin)
def principal_direction_extent(tree): '''Calculate the extent of a tree, that is the maximum distance between the projections on the principal directions of the covariance matrix of the x,y,z points of the nodes of the tree. Input tree : a tree object Returns extents : the extents for each of the eigenvectors of the cov matrix eigs : eigenvalues of the covariance matrix eigv : respective eigenvectors of the covariance matrix ''' # extract the x,y,z coordinates of all the points in the tree points = np.array([value[COLS.X: COLS.R]for value in val_iter(ipreorder(tree))]) # center the points around 0.0 points -= np.mean(points, axis=0) # principal components _, eigv = pca(points) extent = np.zeros(3) for i in range(eigv.shape[1]): # orthogonal projection onto the direction of the v component scalar_projs = np.sort(np.array([np.dot(p, eigv[:, i]) for p in points])) extent[i] = scalar_projs[-1] if scalar_projs[0] < 0.: extent -= scalar_projs[0] return extent
def test_preorder_iteration(): nt.ok_(list(val_iter(ipreorder(REF_TREE))) == [0, 11, 111, 112, 12, 121, 1211, 12111, 12112, 122]) nt.ok_(list(val_iter(ipreorder(REF_TREE.children[0]))) == [11, 111, 112]) nt.ok_(list(val_iter(ipreorder(REF_TREE.children[1]))) == [12, 121, 1211, 12111, 12112, 122])
def _max_recursion_depth(obj): ''' Estimate recursion depth, which is defined as the number of nodes in a tree ''' neurites = obj.neurites if hasattr(obj, 'neurites') else [obj] return max(sum(1 for _ in ipreorder(neu)) for neu in neurites)
def _make_monotonic(neuron): for neurite in neuron.neurites: for node in ipreorder(neurite): if node.parent is not None: node.value[COLS.R] = node.parent.value[COLS.R] / 2.
if __name__ == '__main__': filename = 'test_data/swc/Neuron.swc' rd = load_data(filename) init_seg_ids = get_initial_segment_ids(rd) trees = [make_tree(rd, sg) for sg in init_seg_ids] soma = neuron.make_soma([rd.get_row(si) for si in get_soma_ids(rd)]) for tr in trees: for p in point_iter(tree.ipreorder(tr)): print p print 'Initial segment IDs:', init_seg_ids nrn = neuron.Neuron(soma, trees) print 'Neuron soma raw data', [r for r in nrn.soma.iter()] print 'Neuron soma points', [as_point(p) for p in nrn.soma.iter()] print 'Neuron tree init points, types' for tt in nrn.neurites: print tt.value[COLS.ID], tt.value[COLS.TYPE] print 'Making neuron 2' nrn2 = make_neuron(rd)
def _make_flat(neuron): for neurite in neuron.neurites: for node in ipreorder(neurite): if node.parent is not None: node.value[COLS.Z] = 0.
if __name__ == '__main__': filename = 'test_data/swc/Neuron.swc' rd = load_data(filename) init_seg_ids = get_initial_segment_ids(rd) trees = [make_tree(rd, sg) for sg in init_seg_ids] soma = neuron.make_soma([rd.get_row(si) for si in get_soma_ids(rd)]) for tr in trees: for p in point_iter(tree.ipreorder(tr)): LOG.debug(p) LOG.info('Initial segment IDs: %s', init_seg_ids) nrn = neuron.Neuron(soma, trees) LOG.info('Neuron soma raw data % s', [r for r in nrn.soma.iter()]) LOG.info('Neuron soma points %s', [as_point(p) for p in nrn.soma.iter()]) LOG.info('Neuron tree init points, types') for tt in nrn.neurites: LOG.info('%s, %s', tt.value[COLS.ID], tt.value[COLS.TYPE]) LOG.info('Making neuron 2')
def _max_diameter(tree): '''Find max diameter in tree ''' return 2. * max(node.value[COLS.R] for node in ipreorder(tree))