Skip to content

Commit

Permalink
Cleaning up code: stage 1
Browse files Browse the repository at this point in the history
  • Loading branch information
lidakanari committed Mar 14, 2018
1 parent 18b8886 commit a312ad0
Show file tree
Hide file tree
Showing 23 changed files with 404 additions and 348 deletions.
19 changes: 15 additions & 4 deletions examples/fix_diameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,20 @@

# Cell to use as input for the diameter model
input_cell = './test_data/bio/C220197A-P2.h5'
# Cell be diametrized
synthesized_cell = './local/Neuron.h5'
output_cell = './local/Neuron_diam'
# Outputcell to be saved
output_cell_name = './local/Neuron_diam'

tns.diametrize(input_file=input_cell,
cell_name=synthesized_cell,
new_name=output_cell)
# Generate model from input cell
model = tns.extract_input.diameter_distributions(input_cell)

# Create the object to modify the input cell to be diametrized
# Initialize tha cell with the output cell name
G = tns.Grower(input_parameters=None, input_distributions=model, name=output_cell_name)

# Load the neuron to be modified
G.neuron.load(synthesized_cell)

# Modify the diameters using the generated model
G.diametrize()
10 changes: 3 additions & 7 deletions examples/generate_cell.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
import tns
from tns import extract_input
from tns.grower import neuron

# Extract distributions from cells in input directory
filename = './test_data/bio/'
distr = extract_input.distributions(filename)
distr = tns.extract_input.distributions(filename)

# Generate default parameters dictionary
params = extract_input.parameters(neurite_types=['basal'])
params = tns.extract_input.parameters(neurite_types=['basal'])

# Initialize a neuron
from tns.grower import neuron
N = neuron.Neuron(input_distributions=distr, input_parameters=params)
N.name = 'Neuron'
N = tns.Grower(input_distributions=distr, input_parameters=params, name='Neuron')

# Grow your neuron
N.grow()
Expand Down
Binary file added test_data/test/test_morph_v1.h5
Binary file not shown.
3 changes: 1 addition & 2 deletions tns/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@


from tns import extract_input
from tns import grower
from tns.generate.grower import Grower
from tns import core
from tns.process import diametrize
import version
25 changes: 18 additions & 7 deletions tns/core/neuron.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,15 @@ class Neuron(object):
"""

def __init__(self, name='Neuron'):
"""TNS Neuron Object
"""TNS Neuron Object where groups and points are stored
Parameters:
neuron: Obj neuron where groups and points are stored
initial_direction: 3D vector or random
initial_point: the root of the tree
radius: assuming that the radius is constant for now.
tree_type: an integer indicating the type of the tree (choose from 2, 3, 4, 5)
name: given name to be used in saving into a file.
points: a 4-D structure of points (x, y, z, radius)
groups: the structure of the tree in h5 format (SegmentID, Type, ParentID)
sections: a set of section objects as an alternative representation of groups.
"""
self.name = name

self.points = []
self.groups = [np.array([0, 1, -1])]
self.sections = [[],]
Expand All @@ -42,3 +40,16 @@ def save(self, output_path='./'):
Fdata.create_dataset(name="structure", data=np.array(self.groups))

Fdata.close()


def load(self, input_file):
'''Loads a groups-points structure
into the Neuron object.
'''
import h5py
import os

F = h5py.File(input_file)
self.points = np.array(F['points'])
self.groups = np.array(F['structure'])
self.name = os.path.basename(input_file.replace('.h5',''))
2 changes: 1 addition & 1 deletion tns/core/section.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from tns.morphmath.sample import ph_prob


class Section(object):
class SectionGrower(object):
'''Class for the section
'''
def __init__(self, neuron,
Expand Down
29 changes: 17 additions & 12 deletions tns/core/soma.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
'''
import numpy as np

class Soma(object):
class SomaGrower(object):
"""Soma class"""

def __init__(self, initial_point=(0.,0.,0.), radius=1.0):
Expand All @@ -27,17 +27,21 @@ def interpolate(self, points, N=3):
"""
from scipy.spatial import ConvexHull

hull = ConvexHull(points)

selected = np.array(points)[hull.vertices]

if len(selected) > N:
return selected.tolist()
elif len(points) > N:
print 'Warning! Convex hull failed. Original points were saved instead'
return points.tolist()
fail_msg = 'Warning! Convex hull failed. Original points were saved instead'

if len(points)>3:
hull = ConvexHull(points)
selected = np.array(points)[hull.vertices]
if len(selected) > N:
return selected.tolist()
elif len(points) > N:
print fail_msg
return points.tolist()
else:
print fail_msg
return N*points.tolist()
else:
print 'Warning! Convex hull failed. Original points were saved instead'
print fail_msg
return N*points.tolist()


Expand Down Expand Up @@ -66,7 +70,8 @@ def generate(self, neuron, trunk_angles, z_angles, plot_soma=True, interpolation
np.cos(theta + ang) * np.sin(phi),
self.center[1] + self.radius * \
np.sin(theta + ang) * np.sin(phi),
self.center[2]]) # Make soma a 2D contour
self.center[2]])
# Make soma a 2D contour
# For a 3d contour replace with
# self.center[1] + self.radius * \
# np.cos(phi)
Expand Down
77 changes: 39 additions & 38 deletions tns/core/tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def round_num(num, decimal_places=4):
4:'apical'}


class Tree(object):
class TreeGrower(object):
"""Tree class"""
def __init__(self,
initial_direction,
Expand Down Expand Up @@ -66,15 +66,15 @@ def initial_section(self, neuron, ph_angles, stop, process=None):
n_sec = len(ph_angles)
lpoint = list(self.point)

neuron.sections.append(section.Section(neuron,
parent=parent,
start_point=np.array(lpoint + [self.radius]),
direction=self.direction,
randomness=self.randomness,
targeting=self.targeting,
children=0 if n_sec > 1 else 1,
process=process,
stop_criteria=copy.deepcopy(stop)))
neuron.sections.append(section.SectionGrower(neuron,
parent=parent,
start_point=np.array(lpoint + [self.radius]),
direction=self.direction,
randomness=self.randomness,
targeting=self.targeting,
children=0 if n_sec > 1 else 1,
process=process,
stop_criteria=copy.deepcopy(stop)))


def add_section(self, neuron, act, dir1, start_point,
Expand All @@ -83,15 +83,15 @@ def add_section(self, neuron, act, dir1, start_point,
from all the required information. The section is
added to the neuron.sections and activated.
"""
neuron.sections.append(section.Section(neuron,
parent=act,
start_point=start_point,
direction=dir1,
randomness=self.randomness,
targeting=self.targeting,
children=0,
process=process,
stop_criteria=copy.deepcopy(stop)))
neuron.sections.append(section.SectionGrower(neuron,
parent=act,
start_point=start_point,
direction=dir1,
randomness=self.randomness,
targeting=self.targeting,
children=0,
process=process,
stop_criteria=copy.deepcopy(stop)))


def generate_trunk(self, neuron, input_distributions, sec_len=50, n_sec=1):
Expand All @@ -106,15 +106,15 @@ def generate_trunk(self, neuron, input_distributions, sec_len=50, n_sec=1):

neuron.groups.append(np.array([len(neuron.points), self.type, parent]))

S = section.Section(neuron,
parent=parent,
start_point=np.array(self.point + [self.radius]),
direction=self.direction,
randomness=self.randomness,
targeting=self.targeting,
children=0,
process=None,
stop_criteria={"num_seg":sec_len})
S = section.SectionGrower(neuron,
parent=parent,
start_point=np.array(self.point + [self.radius]),
direction=self.direction,
randomness=self.randomness,
targeting=self.targeting,
children=0,
process=None,
stop_criteria={"num_seg":sec_len})

S.generate_nseg()

Expand All @@ -131,15 +131,15 @@ def generate_binary(self, neuron, input_distributions, generations=4):

neuron.groups.append(np.array([len(neuron.points), self.type, parent]))

S = section.Section(neuron,
parent=parent,
start_point=np.array(self.point + [self.radius]),
direction=self.direction,
randomness=self.randomness,
targeting=self.targeting,
children=0,
process=None,
stop_criteria={"num_seg":sec_len})
S = section.SectionGrower(neuron,
parent=parent,
start_point=np.array(self.point + [self.radius]),
direction=self.direction,
randomness=self.randomness,
targeting=self.targeting,
children=0,
process=None,
stop_criteria={"num_seg":sec_len})

S.generate_nseg()

Expand Down Expand Up @@ -338,7 +338,8 @@ def generate_ph_repulsion(self, neuron, ph_angles, method):
process2 = Sec.process

else:
dir1, dir2 = rd.get_bif_soma_repulsion(Sec.direction, angles=ang, soma=self.point, curr_point=start_point[:-1])
dir1, dir2 = rd.get_bif_soma_repulsion(Sec.direction, angles=ang,
soma=self.point, curr_point=start_point[:-1])
#dir1, dir2 = rd.get_bif_symmetric(Sec.direction, angles=ang)
process1 = 'tuft'
process2 = 'tuft'
Expand Down
70 changes: 54 additions & 16 deletions tns/extract_input/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
# Module to extract morphometrics and TMD from a set of tree-shaped cells.
def default_keys():
'''Returns the important keys for the distribution extraction'''
return {'basal':{},
'apical':{},
'axon':{}}

def distributions(filepath, neurite_types=['basal', 'apical', 'axon']):

def distributions(filepath, neurite_types=['basal', 'apical', 'axon'], threshold_sections=2, diameter_model=False):
'''Extracts the input distributions from an input population
defined by a directory of swc or h5 files
'''
Expand All @@ -12,17 +18,21 @@ def distributions(filepath, neurite_types=['basal', 'apical', 'axon']):
pop_ntn = tmd.io.load_population(filepath)
pop_nm = nm.load_neurons(filepath)

input_distributions = {}
input_distributions = default_keys()

from_neurom.soma_data(pop_nm, input_distributions)
from_neurom.number_neurites_data(pop_nm, input_distributions)
from_neurom.trunk_data(pop_nm, input_distributions)
if 'basal' in neurite_types:
from_TMD.ph_basal(pop_ntn, input_distributions)
from_TMD.ph_basal(pop_ntn, input_distributions, threshold=threshold_sections)
if 'apical' in neurite_types:
from_TMD.ph_apical(pop_ntn, input_distributions)
from_TMD.ph_apical(pop_ntn, input_distributions, threshold=threshold_sections)
if 'axon' in neurite_types:
from_TMD.ph_axon(pop_ntn, input_distributions)
from_TMD.ph_axon(pop_ntn, input_distributions, threshold=threshold_sections)

if diameter_model:
import from_diameter
input_distributions["diameter_model"] = from_diameter.population_model(pop_nm)

return input_distributions

Expand All @@ -33,30 +43,58 @@ def parameters(name="Test_neuron", origin=(0.,0.,0.), neurite_types=['basal', 'a
'''
# Set up required fields

input_parameters = {"origin":origin,
"name":name,
"apical":{},
"basal":{},
"axon":{},}
input_parameters = default_keys()

input_parameters["origin"] = origin

parameters_default = {"apical_distance": 0.0,
parameters_default = {"apical_distance": None,
"randomness":0.15,
"targeting":0.12,
"radius":0.3}
"radius":0.3,
"orientation":None}

if 'basal' in neurite_types:
input_parameters["basal"].update(parameters_default)
input_parameters["basal"].update({"tree_type":3,
"branching_method": "bio_oriented",})
input_parameters["basal"].update(parameters_default)

if 'apical' in neurite_types:
input_parameters["apical"].update({"tree_type":4,
"branching_method": "directional",})
input_parameters["apical"].update(parameters_default)
input_parameters["apical"].update({"apical_distance": 0.0,
"tree_type":4,
"orientation":(0.,1.,0.),
"branching_method": "directional",})

if 'axon' in neurite_types:
input_parameters["axon"].update(parameters_default)
input_parameters["axon"].update({"tree_type":2,
"orientation":(0.,-1.,0.),
"branching_method": "bio_oriented",})
input_parameters["axon"].update(parameters_default)


return input_parameters


def diameter_distributions(filepath, distributions=None):
'''Extracts the input distributions from an input population
defined by a directory of swc or h5 files
'''
import os
import from_diameter
import neurom as nm

if os.path.isdir(filepath):
pop_nm = nm.load_neurons(filepath)
model = from_diameter.population_model(pop_nm)
elif os.path.isfile(filepath):
neu_nm = nm.load_neuron(filepath)
model = from_diameter.model(neu_nm)
else:
return "No directory or file found that matches the selected filepath!"

if distributions is None:
distributions = {}

distributions["diameter_model"] = model

return distributions
Loading

0 comments on commit a312ad0

Please sign in to comment.