This program reads a set of neuron hoc files from a given directory and spits out a tabular comparison of each neuron's cable properties; these properties include the number of branch points, total cable length, mean path length, and overall tortuosity.
First, here are the required imports:
In [1]:
    
# Required for system access (utilized below)
import sys
# Required for os access (utilized below)
import os
sys.path.append(os.path.join(os.path.dirname(os.getcwd()),
                             'dependencies'))
# Required to interpret hoc files
from neuron_readExportedGeometry import *
# Required for efficient calculation of mean and standard deviation
import numpy as np
# Required to display and save data in tabular/graphical form
import matplotlib.pyplot as plt
    
Next, load up a set of neuron hoc files within a directory as a list of geo objects:
In [2]:
    
# Specify a directory full of hoc files
directory = '/home/cosmo/marderlab/test/'
# Convert the given directory into a list of hoc files
hocs = [(directory + h) for h in os.listdir(directory)]
# Convert the list of hoc files into a list of geo objects
geos = [demoReadsilent(h) for h in hocs]
    
    
Now that we have our list of geo objects ready to go, let's make a parallel list of names:
In [3]:
    
# Loop through the filenames in directory and split off irrelevant
# information
names = [h.split('_s')[0].split('_f')[0].split('.h')[0].split('_r')[0] for h in os.listdir(directory)]
names
    
    Out[3]:
Next up, let's make a parallel list containing the number of branch points present in each neuron:
In [4]:
    
# Count the number of branches, which is equivalent to the number of
# branch points 
branchpoints = [len(g.branches) for g in geos]
branchpoints
    
    Out[4]:
Now, let's make another parallel list containing the total cable length of each neuron:
In [5]:
    
# More detailed documentation for this code can be found in cable-length-calculator.ipynb
cablelengths = [] # Initialize a list of cablelengths
for geo in geos:
    tips, ends = geo.getTips() # Store all the tip segments in a list, "tips"
                               # Also store the associated ends in "ends"
    find = PathDistanceFinder(geo, geo.soma) # Set up a PDF object for the
                                             # given geo object, anchored at
                                             # the soma
    paths = [find.pathTo(seg) for seg in tips] # List of all paths
    counted = [] # Initialize a list for keeping track of which segments have
                 # already been measured
    cablelength = 0 # Initialize a running total of cable length
    for path in paths: # Sort through each path
        pruned = [seg for seg in path if seg not in counted] # Limit the paths
                                                             # we work with to
                                                             # those which have
                                                             # not already been
                                                             # measured
        forfind = PathDistanceFinder(geo, pruned[0]) # Initialize a PDF
                                                     # anchored at the earliest
                                                     # unmeasured segment
        cablelength += forfind.distanceTo(pruned[-1]) # Add the distance
                                                      # between the anchor and
                                                      # the tip segment to the
                                                      # running total
        for seg in pruned: # Add all of the measured segments to "counted"
            counted.append(seg)
    cablelengths.append(cablelength)
cablelengths
    
    
    Out[5]:
Next, let's make yet another parallel list containing the mean path length of each neuron:
In [6]:
    
# Loops through geos and calculates the mean path length for each neuron
plmeans = [np.mean(g.getProperties()[0]['Path Length']) for g in geos]
plmeans
    
    
    
    Out[6]:
Now, let's make a parallel list containing the standard deviation in path length for each neuron:
In [7]:
    
# Loops through geos and calculates the standard deviation in path
# length for each neuron
plstds = [np.std(g.getProperties()[0]['Path Length']) for g in geos]
plstds
    
    
    
    Out[7]:
Next up, let's make another parallel list containing the mean tortuosity of each neuron:
In [8]:
    
# Loops through geos and calculates the mean tortuosity for each neuron
tortmeans = [np.mean(g.getProperties()[0]['Tortuosity']) for g in geos]
tortmeans
    
    
    
    Out[8]:
Now, let's make yet another parallel list containing the standard deviation in tortuosity for each neuron:
In [9]:
    
# Loops through geos and calculates the standard deviation in tortuosity
# for each neuron
tortstds = [np.std(g.getProperties()[0]['Tortuosity']) for g in geos]
tortstds
    
    
    
    Out[9]:
In [10]:
    
filename = 'Test.txt'
f = open(filename, 'w')
props = ['Neuron ID', 'Branches', 'Total Cable Length (um)',
         'Mean Path Length (um)', 'Path Length Standard Deviation',
         'Mean Tortuosity', 'Tortuosity Standard Deviation']
tablebar = \
'+---------------------------------------------------------------------------------+'
f.write('\n' + tablebar + '\n')
f.write('|{0:<26}|{1:<22}|{2:<31}|'.format(props[0], props[1],
                                           props[2]) + '\n')
f.write(tablebar + '\n')
for n in range(len(geos)):
    f.write('|{0:<26}|{1:<22}|{2:<31}|'.format(names[n],branchpoints[n],
                                               cablelengths[n]) + '\n')
    f.write(tablebar + '\n')
f.write('\n' + tablebar + '\n')
f.write('|{0:<26}|{1:<22}|{2:<31}|'.format(props[0], props[3],
                                           props[4]) + '\n')
f.write(tablebar + '\n')
for n in range(len(geos)):
    f.write('|{0:<26}|{1:<22}|{2:<31}|'.format(names[n], plmeans[n],
                                               plstds[n]) + '\n')
    f.write(tablebar + '\n')
f.write('\n' + tablebar + '\n')
f.write('|{0:<26}|{1:<22}|{2:<31}|'.format(props[0], props[5],
                                           props[6]) + '\n')
f.write(tablebar + '\n')
for n in range(len(geos)):
    f.write('|{0:<26}|{1:<22}|{2:<31}|'.format(names[n], tortmeans[n],
                                             tortstds[n]) + '\n')
    f.write(tablebar + '\n')
f.close()
with(open(os.path.join(os.getcwd(), filename))) as fr:
    print(fr.read())
    
    
Alternatively, we can make the table using matplotlib: