def setup_func_small_tree(): """ Setup function for Horton-Strahler number testing """ global test_trees global test_stats #0 - Only soma tree test_trees.append( btmorph.STree2().read_SWC_tree_from_file("tests/soma_only.swc")) #1 - Wiki test tree test_trees.append(btmorph.STree2().read_SWC_tree_from_file( "tests/horton-strahler_test_wiki_3pointsoma.swc")) test_stats = btmorph.BTStats(test_trees[1])
def plotPCA(fn="tests/moto_1_outputted.swc"): tree = btmorph.STree2().read_SWC_tree_from_file(fn) tree.write_SWC_tree_to_file('tmpTree_3d.swc') tree2d = pca_project_tree(tree) tree2d.write_SWC_tree_to_file('tmpTree_2d.swc') plot_3D_SWC('tmpTree_3d.swc') plot_3D_SWC('tmpTree_2d.swc')
def filter_and_save_SWC(destination,filter,types=list(range(10)),prefix="_filtered"): """ Removes points from a SWC structure and saves the new SWC to a file. Can be used to remove unwanted structures that are identifiable by \ the type-field in the SWC description. Specification of (standard) \ SWC type fields can be found `here <http://www.neuronland.org/NLMorphologyConverter/MorphologyFormats/SWC/Spec.html>`_. To select the basal dendrites only, use the argument `types=[1,3]`:\ 1 to select the soma and 3 for the basal dendrites themselves. Parameters ----------- destination : string string with the location of where to find the SWC files. types : list of int types that are to be remained in the SWC file. """ # change to a directory of choice for I/O pwd = os.getcwd() os.chdir(destination) # load morphologies and initialize statistics all_f = glob.glob(filter) for f in all_f: print(("processing file: ",f)) temp_tree = btmorph.STree2() temp_tree.read_SWC_tree_from_file(f,types=types) outN = f.split(".swc")[0]+prefix+".swc" temp_tree.write_SWC_tree_to_file(outN) os.chdir(pwd)
def pca_project_tree(tree): """ Returns a tree which is a projection of the original tree on the plane of most variance Parameters ---------- tree : :class:`btmorph.btstructs2.STree2` A tree Returns -------- tree : :class:`btmorph.btstructs2.STree2` New flattened tree """ nodes = tree.get_nodes() N = len(nodes) coords = [n.content['p3d'].xyz for n in nodes] points = np.transpose(coords) coeff, score, latent = _pca(points.T) score[2, :] = [0] * N newp = np.transpose(score) # Move soma to origin translate = score[:, 0] for i in range(0, N): nodes[i].content['p3d'].xyz = newp[i] - translate import time fmt = '%Y_%b_%d_%H_%M_%S' now = time.strftime(fmt) tree.write_SWC_tree_to_file('tmpTree_3d_' + now + '.swc') tree = btmorph.STree2().read_SWC_tree_from_file('tmpTree_3d_' + now + '.swc') import os os.remove('tmpTree_3d_' + now + '.swc') return tree
def fracLac_2d(fn='tmpTree_2d.swc'): tree = btmorph.STree2().read_SWC_tree_from_file(fn) stats = btmorph.BTStats(tree) voxvol = max(stats.total_dimension()) / 512.0 rng = map(lambda i: voxvol * i, range(1, 8)) print fn for i in rng: print('VoxelSize:', i) print stats.fractal_dimension_lacunarity(i)
def standard_lacunarity(): """ Test if lacunarity method is working properly """ tree = btmorph.STree2().read_SWC_tree_from_file( "tests/moto_1_outputted.swc") stats = btmorph.BTStats(tree) for vD in range(5, 40, 5): lac, fd = stats.fractal_dimension_lacunarity(vD) print("Voxel size:", vD, "tree Lac=", lac, "tree fd=", fd)
def test_0_load_swc(): """ Test whether SWC files are correctly loaded """ global swc_tree swc_tree = btmorph.STree2() swc_tree.read_SWC_tree_from_file(test_file_name) all_nodes = swc_tree.get_nodes() print 'len(all_nodes)', len(all_nodes) assert (len(all_nodes) == 562)
def test_load_swc_mcs2(): ''' Test whether SWC files with multiple-cylinder soma format are read correctly (ri05) ''' print "\n" swc_tree = btmorph.STree2() swc_tree.read_SWC_tree_from_file('tests/soma_types/ri05.CNG.swc') all_nodes1 = swc_tree.get_nodes() print '\nlen(swc_tree1)', len(all_nodes1) assert (len(all_nodes1) == 8970) assert (503 < btmorph.BTStats(swc_tree).approx_soma() < 504)
def test_load_swc(): ''' Test whether SWC files are correctly loaded ''' swc_tree = btmorph.STree2() swc_tree.read_SWC_tree_from_file('tests/v_e_moto1.CNG.swc') all_nodes1 = swc_tree.get_nodes() print '\nlen(swc_tree1)', len(all_nodes1) assert (len(all_nodes1) == 562)
def setup_func_small_tree_lac(): """ Setup function for tree initialization and loading """ global test_trees global test_stats #0 - Only soma tree #test_trees.append(btmorph.STree2().read_SWC_tree_from_file("tests/soma_only.swc")) #1 - Wiki test tree moto_1_outputted #test_trees.append(btmorph.STree2().read_SWC_tree_from_file("tests/horton-strahler_test_wiki_3pointsoma.swc")) test_trees.append( btmorph.STree2().read_SWC_tree_from_file("tests/moto_1_outputted.swc")) test_stats = [btmorph.BTStats(test_trees[0])]
def write_main_branches(self, path, neuronName, class_number): trees = [] if self._tree.root != None: for node in self._tree.root.children: if len(node.children) > 0 & node.index != 2: tmp_tree = btmorph.STree2() tmp_tree.root = copy.copy(self._tree.root) tmp_tree.root.children = [node] trees.append(tmp_tree) file_num = 1 for sub_tree in trees: # print (len(sub_tree.root.children)) # sub_tree_name="./"+path+"/"+neuronName+"_branch" # if not os.path.exists(sub_tree_name): # os.makedirs(sub_tree_name) # sub_tree_name="./"+path+"/"+neuronName+"_branch" store_path = "./main_branches/" + path if not os.path.exists(store_path): os.makedirs(store_path) # n=sub_tree.other_write_SWC_tree_to_file(str(store_path) + '/' + str(class_number) + '__' + neuronName + '_' + str(file_num) + '.swc') # if len(sub_tree.get_nodes()) > 1: # # print(str(sub_tree_name)+str(class_number)+'__'+neuronName+'_'+ # # new_file_name+'.swc') n = sub_tree.other_write_SWC_tree_to_file( str(store_path) + '/' + str(class_number) + '__' + neuronName + '_' + str(file_num) + '.swc') # else: # sub_tree = None file_num += 1 # copyfile(path+"/"+neuronName , sub_tree_name+'/'+neuronName) return trees
def loaddata(path): swc_tree = btmorph.STree2() swc_tree.read_SWC_tree_from_file(path) stats = btmorph.BTStats(swc_tree) return swc_tree, stats
new_directory = "tests/" + str(sys.argv[2] + "_" + str(slice_size)) class_number = (dictionary[sys.argv[1]]) from_level = 0 to_level = 5 counter = 0 for i in range(from_level, to_level): # runs until the final level slice_begin = i slice_end = i + slice_size new_file_name = str(slice_begin) print(str(slice_begin) + '-' + str(slice_end)) for fileName in os.listdir(directory): #for each file in the directory if fileName.endswith(".swc"): counter += 1 swc_tree = btmorph.STree2() filePath = str(directory) + '/' + str(fileName) types = [1, 3, 4, 5, 6, 7] # the 2 is omited because we are not using axons swc_tree.read_SWC_tree_from_file(filePath, types) stats = btmorph.BTStats(swc_tree) stats.set_level_to_tree() # print ("tree level"+ str(swc_tree.max_height)) tree_height = swc_tree.max_height print str(fileName) + " " + str(tree_height) if tree_height < 0: print(" -> processing " + str(fileName)) print("OUT OF RANGE") else: try: swc_tree = stats.write_subtree_by_slice_range(
def perform_1D_population_analysis(destination, filter="*.swc", depth="Y", bar=[200, 200, 200], post_name=None, max_n=None): """ Wrapper function to perform a complete analysis of a population of neuronal morphologies stored in SWC format (and three-point soma). Computes the following features: - # bifurcations - # terminals - # stems - total length - total volume - total surface - max centrifugal order - inter bifurcation length - terminal segment length - euclidean distance between terminal tips and soma - path legth between terminal tips and soma For each feature a list is created with all values collected from all morphologies. These vectors are saved as python Pickle objects. At the same time a histogram is generated to display the data. Parameters ----------- destination : string string with the location of where to find the SWC files. filter : string filter to select SWC files. Default is "*.swc". See `glob <https://docs.python.org/2/library/glob.html>`_ documentation for more advanced filters depth : string Dimension that indicates "depth"/distance from top. Default is "Y"; NeuroMac generated files use "Z". bar : array of float Include a scale-bar with the specified dimensions max_n : int To perform the analysis on a subset of morphologies specify a \ number. Default is None and all morphologies will be taken \ into account. post_name : string string appended to the file name when saving. Default None """ # change to a directory of choice for I/O pwd = os.getcwd() os.chdir(destination) # load morphologies and initialize statistics all_f = glob.glob(filter) if not max_n == None: all_f = all_f[:max_n] swc_trees = {} individual_stats = {} for f in all_f: print "f: ", f cell_name = f.split(filter)[0] temp_tree = btmorph.STree2() temp_tree.read_SWC_tree_from_file(f) swc_trees[cell_name] = temp_tree temp_stats = btmorph.BTStats(temp_tree) individual_stats[cell_name] = temp_stats plt.clf() btmorph.plot_2D_SWC(f, outN=cell_name + "_2D.pdf", align=True, depth=depth, show_axis=True) #btmorph.true_2D_projections_equal(f,outN=f.split(".swc")[0]+"_projections.pdf",depth=depth,bar=bar) plt.close() """ 1D features, without dependencies on other quantities Both global (1 per neuron) and local (N per neuron) features""" one_d_stats = {} # bulk statistics of global features funcs = ["total_length","no_bifurcations","no_terminals","no_stems",\ "total_volume","total_surface"] for cell_name in individual_stats: for func in funcs: method = getattr(individual_stats[cell_name], func) ret = method() if isinstance(ret, tuple): ret = ret[0] if func in one_d_stats: one_d_stats[func].append(ret) else: one_d_stats[func] = [] one_d_stats[func].append(ret) # extract the max order for cell_name in individual_stats: max_order = 0 for node in swc_trees[cell_name].get_nodes(): order = individual_stats[cell_name].order_of_node(node) if order > max_order: max_order = order if "max_order" in one_d_stats: one_d_stats["max_order"].append(max_order) else: one_d_stats["max_order"] = [] one_d_stats["max_order"].append(max_order) # extract the "inter-bifurcation segment length" for cell_name in individual_stats: bif_nodes = individual_stats[cell_name]._bif_points for node in bif_nodes: L = individual_stats[cell_name].get_segment_pathlength(node) if "inter_bif_L" in one_d_stats: one_d_stats["inter_bif_L"].append(L) else: one_d_stats["inter_bif_L"] = [] one_d_stats["inter_bif_L"].append(L) # extract the terminal segment lengths # extract the path length / euclidean distance to terminal tips for cell_name in individual_stats: term_nodes = individual_stats[cell_name]._end_points for node in term_nodes: L = individual_stats[cell_name].get_segment_pathlength(node) path_L = individual_stats[cell_name].get_pathlength_to_root(node) eucl_L = individual_stats[cell_name].get_Euclidean_length_to_root( node) if "term_L" in one_d_stats: one_d_stats["term_L"].append(L) else: one_d_stats["term_L"] = [] one_d_stats["term_L"].append(L) if "term_path_L" in one_d_stats: one_d_stats["term_path_L"].append(path_L) else: one_d_stats["term_path_L"] = [] one_d_stats["term_path_L"].append(path_L) if "term_eucl_L" in one_d_stats: one_d_stats["term_eucl_L"].append(eucl_L) else: one_d_stats["term_eucl_L"] = [] one_d_stats["term_eucl_L"].append(eucl_L) for func in one_d_stats: plt.figure(0) plt.clf() plt.hist(one_d_stats[func]) plt.xlabel(func) plt.ylabel("#") if post_name == None: plt.savefig("pop_1D_" + func + "_hist.pdf") p_name = "pop_1D_" + func + "_raw.pkl" else: plt.savefig("pop_1D_" + func + "_hist" + post_name + ".pdf") p_name = "pop_1D_" + func + "_raw" + post_name + ".pkl" pickle.dump(one_d_stats[func], open(p_name, "w")) # and change back to the original directory where the command was given os.chdir(pwd)
def perform_2D_analysis(destination, filter="*.swc", max_n=None): """ Wrapper function to perform an analysis of the vector features of one neuronal morphology (in the SWC format and with 3-point soma) For both the terminal points and the branching points the following features are recorded - Order of the node - degree of the node - Euclidean distance to the soma - path length to the soma - pathlength of the segment (coming in to a node) - Euclidean distance of the segment (coming in the a node) - branch angle amplitude [branch points only] Two text files are generated, for terminal and branching points. Each row corresponds to a node (point) and the six columns correspond to the features above. Parameters ----------- destination : string string with the location of where to find the SWC files. """ # change to a directory of choice for I/O os.chdir(destination) # load morphologies and initialize statistics all_f = glob.glob(filter) if not max_n == None: all_f = all_f[:max_n] swc_trees = {} individual_stats = {} for f in all_f: print(("f: ", f)) cell_name = f.split(filter)[0] temp_tree = btmorph.STree2() temp_tree.read_SWC_tree_from_file(f) swc_trees[cell_name] = temp_tree temp_stats = btmorph.BTStats(temp_tree) individual_stats[cell_name] = temp_stats """ 2D features calculated per neuron and for the whole population. For each bifurcation and terminal point, the following features \ at that location will be recorded: order, degree, asymmetry_index, \ path length, euclidean distance,(bifurcation angle, local)""" for cell_name in individual_stats: print(("analyzing cell %s" % cell_name)) bif_nodes = individual_stats[cell_name]._bif_points term_nodes = individual_stats[cell_name]._end_points term_to_write = "" for node in term_nodes: O,D,ED,PL,SPL,SED= \ _get_node_features(individual_stats[cell_name],node,term=True) term_to_write += "%0.2f\t%0.2f\t%0.2f\t%0.2f\t%0.2f\t%0.2f\n" % ( O, D, ED, PL, SPL, SED) term_writer = open(cell_name + "_terms_multivariate.txt", "w") term_writer.write(term_to_write) term_writer.flush() term_writer.close() bif_to_write = "" for node in bif_nodes: O,D,ED,PL,SPL,SED,PA,AMP= \ _get_node_features(individual_stats[cell_name],node) bif_to_write += "%0.2f\t%0.2f\t%0.2f\t%0.2f\t%0.2f\t%0.2f\t%0.2f\t%0.2f\n" % ( O, D, ED, PL, SPL, SED, PA, AMP) bif_writer = open(cell_name + "_bifs_multivariate.txt", "w") bif_writer.write(bif_to_write) bif_writer.flush() bif_writer.close()
def plot_dendrogram(file_name, transform='plain', shift=0, c='k', radius=True, rm=20000.0, ra=200, outN=None): """ Generate a dendrogram from an SWC file. The SWC has to be formatted with a "three point soma" Parameters ----------- file_name : string File name of the SWC file to plots transform : string Either 'plain' or 'lambda'. Plain means no transform while 'lambda' performs an elecotrtonic transform shift : float Offset in the x-direction c : string Color ('r','g', 'b', ...) radius : boolean Plot a wire (False) dendrogram or one with the thickness of the processes (True) rm : float Membrane resistance. Only needed when transform = 'lambda' rm : float Axial resistance. Only needed when transform = 'lambda' outN : string File name of the output file. Extension of this file sets the file type """ global C, RM, RA, max_width, max_height # n.a.s.t.y. swc_tree = btmorph.STree2() swc_tree = swc_tree.read_SWC_tree_from_file(file_name) RM = rm RA = ra C = c max_height = 0 max_width = 0 plt.clf() print('Going to build the dendrogram. This might take a while...') ttt = time.time() _expand_dendrogram(swc_tree.root, swc_tree, shift, 0, radius=radius, transform=transform) if (transform == 'plain'): plt.ylabel('L (micron)') elif (transform == 'lambda'): plt.ylabel('L (lambda)') print(((time.time() - ttt), ' later the dendrogram was finished. ')) print(('max_widht=%f, max_height=%f' % (max_width, max_height))) x_bound = (max_width / 2.0) + (0.1 * max_width) max_y_bound = max_height + 0.1 * max_height plt.axis([-1.0 * x_bound, x_bound, -0.1 * max_height, max_y_bound]) plt.plot([x_bound, x_bound], [0, 100], 'k', linewidth=5) # 250 for MN, 100 for granule frame1 = plt.gca() frame1.axes.get_xaxis().set_visible(False) frame1.axes.get_yaxis().set_visible(False) plt.show() if (outN != None): plt.savefig(outN)