def getSomaAxonMorph(cls, axonLength=1000.0, axonRad=0.3, somaRad=20.0, axonSections=10): somaRegion = Region("soma") axonRegion = Region("axon") axonSectionLength = float(axonLength) / float(axonSections) dummyRoot = Section(region=None, x=0.0, y=0.0, z=0.0, r=somaRad) soma = dummyRoot.extrudeChildSection(region=somaRegion, x=somaRad * 2.0, y=0.0, z=0.0, r=somaRad, idTag="soma") prevSection = soma for x in range(1, axonSections): axon = prevSection.extrudeChildSection(region=axonRegion, x=x * axonSectionLength + 2.0 * somaRad, y=0, z=0, r=axonRad, idTag="axon_%d" % x) prevSection = axon cell = MorphologyTree("SimpleSomaAxonMorph", dummysection=dummyRoot, metadata={}) return cell
def get_soma_axon_morph(cls, axon_length=1000.0, axon_radius=0.3, soma_radius=20.0, axon_sections=10): soma_region = Region("soma") axon_region = Region("axon") axon_section_length = float(axon_length) / float(axon_sections) dummy_root = Section(region=None, x=0.0, y=0.0, z=0.0, r=soma_radius) soma = dummy_root.create_distal_section(region=soma_region, x=soma_radius * 2.0, y=0.0, z=0.0, r=soma_radius, idtag="soma") prev_section = soma for x in range(1, axon_sections): axon = prev_section.create_distal_section(region=axon_region, x=x * axon_section_length + 2.0 * soma_radius, y=0, z=0, r=axon_radius, idtag="axon_%d" % x) prev_section = axon cell = MorphologyTree('SimpleSomaAxonMorph', dummysection=dummy_root, metadata={}) return cell
def get_single_section_soma(cls, rad=None, area=None): assert (rad or area) and not (rad and area) if area: area = _convert_to_unit(area, default_unit="um2").rescale("um2").magnitude rad = numpy.power((area / (4.0 * numpy.pi)), 1.0 / 2.0) else: assert isinstance(rad, int) or isinstance(rad, float) rad = _convert_to_unit(rad, default_unit="um").rescale("um").magnitude soma_region = Region("soma") dummysection = Section(region=None, x=0.0, y=0.0, z=0.0, r=rad) dummysection.create_distal_section(region=soma_region, x=rad * 2.0, y=0.0, z=0.0, r=rad, idtag="soma") cell = MorphologyTree("SimpleSomaMorph", dummysection=dummysection, metadata={}) return cell
def load_cell(cls, cellNode, regions=None): cableIDToRegionName, segmentListInfo = cls.load_cell_dictionaries(cellNode, regions=regions) # Make all the regions: regionNames = list(set(Filter(cableIDToRegionName.values(), lambda e: e is not None))) print "RegionNames:", regionNames regionNamesClean = [_clean_name(str(region_name)) for region_name in regionNames] rgns = [Region(name=region_name) for region_name in regionNamesClean] region_nameToRegionDict = dict([(rgn.name, rgn) for rgn in rgns]) cableIDToRegionDict = dict( [ (cableId, region_nameToRegionDict[_clean_name(region_name)]) if region_name is not None else (cableId, None) for cableId, region_name in cableIDToRegionName.iteritems() ] ) # Find the node without a parent: rN = SeqUtils.filter_expect_single(segmentListInfo.values(), lambda s: not s[3]) # Recursively Construct by finding what should be attached to current structure: # (id, name, cable, parent, (px, py, pz, pDiam), (dx, dy, dz, dDiam)) # rDummy = Section(region=cableIDToRegionDict[rN[2]], x=rN[4][0], y=rN[4][1], z=rN[4][2], r=rN[4][3] / 2.0) rDummy = Section(region=None, x=rN[4][0], y=rN[4][1], z=rN[4][2], r=rN[4][3] / 2.0) rActual = rDummy.create_distal_section( region=cableIDToRegionDict[rN[2]], x=rN[5][0], y=rN[5][1], z=rN[5][2], r=rN[5][3] / 2.0, idtag=rN[1] ) idToSectionMap = {rN[0]: rActual} recentlyAdded = [rN[0]] while recentlyAdded != []: curNode = recentlyAdded[0][0] curSect = idToSectionMap[curNode] recentlyAdded = recentlyAdded[1:] childNodes = Filter(segmentListInfo.values(), lambda s: s[3] == curNode) for c in childNodes: # print c newSect = curSect.create_distal_section( region=cableIDToRegionDict[c[2]], x=c[5][0], y=c[5][1], z=c[5][2], r=c[5][3] / 2.0, idtag=c[1] ) idToSectionMap[c[0]] = newSect recentlyAdded.append(c) return MorphologyTree(name="FromNeuroML", dummysection=rDummy, metadata={})
def getSingleSectionSoma(cls, rad=None, area=None): assert (rad or area) and not(rad and area) if area: area = convertToUnit(area, defaultUnit="um2" ).rescale("um2").magnitude rad = numpy.power((area / (4.0 * numpy.pi)), 1.0 / 2.0) else: assert isinstance(int,rad) or isinstance(float,rad) rad = convertToUnit(rad, defaultUnit="um" ).rescale("um").magnitude somaRegion = Region("soma") dummysection = Section(region=None, x=0.0, y=0.0, z=0.0, r=rad) dummysection.extrudeChildSection(region=somaRegion, x=rad * 2.0, y=0.0, z=0.0, r=rad, idTag="soma") cell = MorphologyTree("SimpleSomaMorph", dummysection=dummysection, metadata={}) return cell
def trim_axon_from_morphology(cls, morphology, max_dist_to_parent): dist_to_parent = SectionVistorFactory.dict_section_proximal_dist_from_soma( morph=morphology, soma_centre=False)() print sorted(dist_to_parent.values()) section_mapping_table = {} region_mapping_table = {} # Create New Regions: region_mapping_table[None] = None for rOld in morphology.get_regions(): r_new = Region(name=rOld.name) region_mapping_table[rOld] = r_new # Create New Sections: dummy_root_old = morphology.get_dummy_section() dummy_root_new = Section( region=region_mapping_table[dummy_root_old.region], x=dummy_root_old.d_x, y=dummy_root_old.d_y, z=dummy_root_old.d_z, r=dummy_root_old.d_r) section_mapping_table[dummy_root_old] = dummy_root_new for sectionOld in morphology: print 'DistToParent', dist_to_parent[sectionOld] if dist_to_parent[sectionOld] > max_dist_to_parent: continue print 'Extruding Section' old_parent = sectionOld.parent new_parent = section_mapping_table[old_parent] section_new = new_parent.create_distal_section( region=region_mapping_table[sectionOld.region], x=sectionOld.d_x, y=sectionOld.d_y, z=sectionOld.d_z, r=sectionOld.d_r, idtag=sectionOld.idtag, ) section_mapping_table[sectionOld] = section_new m = MorphologyTree('TrimmedNeuron', dummysection=dummy_root_new, metadata={}) return m
def translate(cls, morphology, offset): print offset section_mapping_table = {} region_mapping_table = {} # Create New Regions: region_mapping_table[None] = None for rOld in morphology.get_regions(): r_new = Region(name=rOld.name) region_mapping_table[rOld] = r_new # Create New Sections: dummy_root_old = morphology.get_dummy_section() dummy_root_new = \ Section(region=region_mapping_table[dummy_root_old.region], x=dummy_root_old.d_x + offset[0], y=dummy_root_old.d_y + offset[1], z=dummy_root_old.d_z + offset[2], r=dummy_root_old.d_r) section_mapping_table[dummy_root_old] = dummy_root_new for sectionOld in morphology: old_parent = sectionOld.parent new_parent = section_mapping_table[old_parent] section_new = new_parent.create_distal_section( region=region_mapping_table[sectionOld.region], x=sectionOld.d_x + offset[0], y=sectionOld.d_y + offset[1], z=sectionOld.d_z + offset[2], r=sectionOld.d_r, idtag=sectionOld.idtag, ) section_mapping_table[sectionOld] = section_new m = MorphologyTree('translatedNeuron', dummysection=dummy_root_new, metadata={}) return m
def build_root(self, section): from morphforge.morphology.core import Section, Region from morphforge.morphology.core import MorphologyTree self.orig2new_mapping = {} self.rgn_mappings = dict([(rgn, Region(rgn.name)) for rgn in self.morph.get_regions()]) self.new_morph = None (x, y, z, r) = (section.d_x, section.d_y, section.d_z, section.d_r) (X, Y, Z, R) = self.transfuctor(x, y, z, r) new_section = Section( regions=[self.rgn_mappings[region] for region in section.regions], x=X, y=Y, z=Z, r=R) self.new_morph = MorphologyTree('MorphCloned', dummysection=new_section, metadata={}) self.orig2new_mapping[section] = new_section
def load(cls, morph_dict, name=None, metadata=None): """ Load a morphology from a recursive dictionary such as: {'root': {'length': 20, 'diam': 20, 'sections': [ {'absangle': 120, 'length': 40, 'diam': 5, 'region': 'dendrite'}, {'absangle': 240, 'length': 40, 'diam': 5, 'sections': [ {'region': 'dendrite', 'diam': 5, 'relangle': 240, 'length': 40} ], 'region': 'dendrite'}, {'absangle': 5, 'length': 500, 'diam': 0.29999999999999999, 'region': 'axon'}], 'region': 'soma'}} If addRootSection is true, then we make the root section, by adding in a fake section: """ if not morph_dict or not morph_dict.has_key('root'): raise ValueError() valid_keywords = [ 'length', 'diam', 'id', 'sections', 'region', 'regions', 'relangle', 'absangle', 'xyz', ] required_keywords = ['diam'] # Does the root has a length variable? if it does, then lets add an intermediate node and remove it. root_node = morph_dict['root'] if root_node.has_key('length'): # Lets assume it extends backwards on the X-axis. This isn't great, but will work, although # visualisations are likely to look a bit screwy: assert not root_node.has_key('xyz') new_root_node = { 'region': 'soma', 'diam': root_node['diam'], 'xyz': (0.0, 0.0, 0.0), 'sections': [root_node], } root_node = new_root_node #First flatten the recursion, by copy #the dictionary and adding a parent tag: yaml_section_dict = {} # id to paramDict def recursively_add_section_to_list(sectionNode, sectionNodeParentID, sectionDictInt): for key in sectionNode.keys(): if not key in valid_keywords: raise ValueError('Invalid Keyword: ' + key) for req_kw in required_keywords: if not req_kw in sectionNode.keys(): raise ValueError('Required Key: %s not found.' % req_kw) children = sectionNode.get('sections', []) if sectionNode.has_key('sections'): del sectionNode['sections'] section_id = len(sectionDictInt) sectionDictInt[section_id] = merge_dictionaries([{ "parent": sectionNodeParentID }, sectionNode]) for child in children: recursively_add_section_to_list(child, section_id, sectionDictInt) #root_node = morph_dict["root"] recursively_add_section_to_list(root_node, None, yaml_section_dict) #We now have a dictionary similar to: # """ 0 {'length': 20, 'diam': 20, 'region': 'soma', 'parent': None} # 1 {'absangle': 120, 'length': 40, 'diam': 5, 'region': 'dendrite', 'parent': 0} # 2 {'absangle': 240, 'length': 40, 'diam': 5, 'region': 'dendrite', 'parent': 0} # 3 {'length': 40, 'region': 'dendrite', 'diam': 5, 'relangle': 240, 'parent': 2} # 4 {'absangle': 5, 'length': 500, 'diam': 0.29999999999999999, 'region': 'axon', 'parent': 0} # """ #Map a lack of region to region:"NoRegionGiven" for yml in yaml_section_dict.values(): if not ('region' in yml or 'regions' in yml): yml['region'] = 'NoRegionGiven' region_names1 = [ yml["region"] for yml in yaml_section_dict.values() if yml.has_key("region") ] region_names2 = SeqUtils.flatten([ yml["regions"] for yml in yaml_section_dict.values() if yml.has_key("regions") ]) region_names = list(set(region_names1 + region_names2)) region_dict = dict([(region_name, Region(region_name)) for region_name in region_names]) section_angles_dict = {} section_id_tags = [] # We create a 'dummy' root node, and then the real root node. # This will be at index '0' # Do we need to create a dummy node explicity? This depends on whether the root node has a length: section_dict = {} root_yaml_sect = yaml_section_dict[0] if 'length' in root_yaml_sect.keys(): assert False xyz = root_yaml_sect['xyz'] section_dict[0] = Section( x=xyz[0], y=xyz[1], z=xyz[2], r=root_yaml_sect['diam'] / 2.0, region=None, parent=None, ) # Add the remaining nodes: for (yaml_id, yaml_sect) in yaml_section_dict.iteritems(): if yaml_sect['parent'] == None: continue # print yaml_id, yaml_sect parent_section = section_dict[yaml_sect['parent']] #Region: rg_names1 = [yaml_sect["region"] ] if yaml_sect.has_key("region") else [] rg_names2 = yaml_sect["regions"] if yaml_sect.has_key( "regions") else [] rgs = [region_dict[rgName] for rgName in rg_names1 + rg_names2] # Since December 2010 each section is only allowed to have one # region. assert len(rgs) <= 1 #Diameter & length: if not yaml_sect.has_key("diam"): raise ValueError("Not radius given") diam = yaml_sect["diam"] if not (diam > 0): raise ValueError("indvalid radius: %s" % diam) rad = diam / 2.0 # End Point: def get_yaml_length(yaml_sect): if not yaml_sect.has_key("length"): raise ValueError("No Length given") length = yaml_sect["length"] if not length > 0: raise ValueError("Invalid Length") return length #We only specify end points by using angles or by xyz cooridinates: if int(yaml_sect.has_key("absangle")) + int( yaml_sect.has_key("relangle")) + int( yaml_sect.has_key("xyz")) >= 2: raise ValueError("Too many ways for specifying endpoint") if yaml_sect.has_key('xyz'): if not parent_section: angle = 0 xyz = yaml_sect['xyz'] elif yaml_sect.has_key("absangle"): length = get_yaml_length(yaml_sect) angle = yaml_sect['absangle'] xyz = (parent_section.d_x + length * math.cos(math.radians(angle)), parent_section.d_y + length * math.sin(math.radians(angle)), 0.0) elif yaml_sect.has_key('relangle'): length = get_yaml_length(yaml_sect) angle = section_angles_dict[parent_section] + yaml_sect[ "relangle"] xyz = (parent_section.d_x + length * math.cos(math.radians(angle)), parent_section.d_y + length * math.sin(math.radians(angle)), 0.0) else: # Default to 'abs'-angle to 0 length = get_yaml_length(yaml_sect) angle = 0 xyz = (parent_section.d_x + length * math.cos(math.radians(angle)), parent_section.d_y + length * math.sin(math.radians(angle)), 0.0) # Possible ID's: section_id_tag = (yaml_sect['id'] if yaml_sect.has_key('id') else None) if section_id_tag: check_cstyle_varname(section_id_tag) if section_id_tag in section_id_tags: raise ValueError('Duplicate Section ID: %s' % section_id_tag) if section_id_tag: section_id_tags.append(section_id_tag) # Create the new section: if parent_section: new_section = parent_section.create_distal_section( x=xyz[0], y=xyz[1], z=xyz[2], r=rad, region=rgs[0], idtag=section_id_tag) else: new_section = Section(x=xyz[0], y=xyz[1], z=xyz[2], r=rad, region=None, idtag=section_id_tag) section_dict[None] = new_section # Calculate the angle of the current section: if parent_section: joining_vec = new_section.get_distal_npa3( ) - parent_section.get_distal_npa3() angle = math.radians(math.atan2(joining_vec[1], joining_vec[0])) section_angles_dict[new_section] = angle #Save the section: section_dict[yaml_id] = new_section # # TODO: THIS IS A HACK! Ensure the dummy node has no attached regions: # section_dict[None].regions = [] assert section_dict[0].region == None if section_dict[0].children == []: raise ValueError("No segments found") morphs = MorphologyTree(name=name, dummysection=section_dict[0], metadata=metadata) if len(morphs) < 1: raise ValueError return morphs
def load_cell(cls, cellNode, regions=None): cableIDToRegionName, segmentListInfo = cls.load_cell_dictionaries( cellNode, regions=regions) # Make all the regions: regionNames = list( set(Filter(cableIDToRegionName.values(), lambda e: e is not None))) print 'RegionNames:', regionNames regionNamesClean = [ _clean_name(str(region_name)) for region_name in regionNames ] rgns = [Region(name=region_name) for region_name in regionNamesClean] region_nameToRegionDict = dict([(rgn.name, rgn) for rgn in rgns]) cableIDToRegionDict = dict([ (cableId, region_nameToRegionDict[_clean_name(region_name)]) if region_name is not None else (cableId, None) for cableId, region_name in cableIDToRegionName.iteritems() ]) # Find the node without a parent: rN = SeqUtils.filter_expect_single(segmentListInfo.values(), lambda s: not s[3]) #Recursively Construct by finding what should be attached to current structure: #(id, name, cable, parent, (px, py, pz, pDiam), (dx, dy, dz, dDiam)) #rDummy = Section(region=cableIDToRegionDict[rN[2]], x=rN[4][0], y=rN[4][1], z=rN[4][2], r=rN[4][3] / 2.0) rDummy = Section(region=None, x=rN[4][0], y=rN[4][1], z=rN[4][2], r=rN[4][3] / 2.0) rActual = rDummy.create_distal_section( region=cableIDToRegionDict[rN[2]], x=rN[5][0], y=rN[5][1], z=rN[5][2], r=rN[5][3] / 2.0, idtag=rN[1]) idToSectionMap = {rN[0]: rActual} recentlyAdded = [rN[0]] while recentlyAdded != []: curNode = recentlyAdded[0][0] curSect = idToSectionMap[curNode] recentlyAdded = recentlyAdded[1:] childNodes = Filter(segmentListInfo.values(), lambda s: s[3] == curNode) for c in childNodes: #print c newSect = curSect.create_distal_section( region=cableIDToRegionDict[c[2]], x=c[5][0], y=c[5][1], z=c[5][2], r=c[5][3] / 2.0, idtag=c[1]) idToSectionMap[c[0]] = newSect recentlyAdded.append(c) return MorphologyTree(name='FromNeuroML', dummysection=rDummy, metadata={})
def array_to_tree(cls, array, region_number_to_name_bidict=None): if region_number_to_name_bidict is None: if array.region_number_to_name_bidict is not None: region_number_to_name_bidict = copy.deepcopy( array.region_number_to_name_bidict) else: region_number_to_name_bidict = AutoRegionToIntMapTable() name_to_region_map = {} dummy_vertex_index = array._dummy_vertex_index index_to_section_map = {} # Create the root section: (x, y, z, r) = array._vertices[dummy_vertex_index] dummy_section = Section(region=None, x=x, y=y, z=z, r=r) index_to_section_map[dummy_vertex_index] = dummy_section indices_to_visit = collections.deque([dummy_vertex_index]) while indices_to_visit: index = indices_to_visit.pop() section = index_to_section_map[index] connections_to_index = array.connections_to_index(index) for conn in connections_to_index: # Have we made this connection already?: if conn in index_to_section_map: continue # No? Lets make a connection: else: (x, y, z, r) = array._vertices[conn] index_of_connection = array.index_of_connection( index, conn) # Create the region, if it doesn't already exist: rgn_int = array._section_types[index_of_connection] rgn_name = region_number_to_name_bidict.int_to_region_name( _int=rgn_int) if rgn_name is None: rgn = None else: if not rgn_name in name_to_region_map: name_to_region_map[rgn_name] = Region(rgn_name) rgn = name_to_region_map[rgn_name] newsection = section.create_distal_section(region=rgn, x=x, y=y, z=z, r=r) index_to_section_map[conn] = newsection indices_to_visit.append(conn) from morphforge.morphology.core import MorphologyTree tree = MorphologyTree( name=array.name, dummysection=dummy_section, region_number_to_name_bidict=region_number_to_name_bidict) # A sanity check: assert len(tree) == len(array), \ 'The tree and array are not the same size! %d vs %d' \ % (len(tree), len(array)) return tree
def load(cls, morph_dict, name=None, metadata=None): """ Load a morphology from a recursive dictionary such as: {'root': {'length': 20, 'diam': 20, 'sections': [ {'absangle': 120, 'length': 40, 'diam': 5, 'region': 'dendrite'}, {'absangle': 240, 'length': 40, 'diam': 5, 'sections': [ {'region': 'dendrite', 'diam': 5, 'relangle': 240, 'length': 40} ], 'region': 'dendrite'}, {'absangle': 5, 'length': 500, 'diam': 0.29999999999999999, 'region': 'axon'}], 'region': 'soma'}} """ if not morph_dict or not morph_dict.has_key('root'): raise ValueError() valid_keywords = [ 'length', 'diam', 'id', 'sections', 'region', 'regions', 'relangle', 'absangle', 'xyz', ] required_keywords = ['diam'] # Does the root has a length variable? if it does, then lets add an intermediate node and remove it. root_node = morph_dict['root'] if root_node.has_key('length'): # Lets assume it extends backwards on the X-axis. This isn't great, but will work, although # visualisations are likely to look a bit screwy: assert not root_node.has_key('xyz') new_root_node = { 'region': 'soma', 'diam': root_node['diam'], 'xyz': (0.0, 0.0, 0.0), 'sections': [root_node], } root_node = new_root_node #First flatten the recursion, by copy #the dictionary and adding a parent tag: yaml_section_dict = {} # id to paramDict def recursively_add_section_to_list(sectionNode, sectionNodeParentID, sectionDictInt): for key in sectionNode.keys(): if not key in valid_keywords: raise ValueError('Invalid Keyword: ' + key) for req_kw in required_keywords: if not req_kw in sectionNode.keys(): raise ValueError('Required Key: %s not found.' % req_kw) children = sectionNode.get('sections', []) if sectionNode.has_key('sections'): del sectionNode['sections'] section_id = len(sectionDictInt) sectionDictInt[section_id] = merge_dictionaries([{"parent": sectionNodeParentID}, sectionNode]) for child in children: recursively_add_section_to_list(child, section_id, sectionDictInt) #root_node = morph_dict["root"] recursively_add_section_to_list(root_node, None, yaml_section_dict) #We now have a dictionary similar to: # """ 0 {'length': 20, 'diam': 20, 'region': 'soma', 'parent': None} # 1 {'absangle': 120, 'length': 40, 'diam': 5, 'region': 'dendrite', 'parent': 0} # 2 {'absangle': 240, 'length': 40, 'diam': 5, 'region': 'dendrite', 'parent': 0} # 3 {'length': 40, 'region': 'dendrite', 'diam': 5, 'relangle': 240, 'parent': 2} # 4 {'absangle': 5, 'length': 500, 'diam': 0.29999999999999999, 'region': 'axon', 'parent': 0} # """ #Map a lack of region to region:"NoRegionGiven" for yml in yaml_section_dict.values(): if not ('region' in yml or 'regions' in yml): yml['region'] = 'NoRegionGiven' region_names1 = [yml["region"] for yml in yaml_section_dict.values() if yml.has_key("region")] region_names2 = SeqUtils.flatten([yml["regions"] for yml in yaml_section_dict.values() if yml.has_key("regions")]) region_names = list(set(region_names1 + region_names2)) region_dict = dict([(region_name, Region(region_name)) for region_name in region_names]) section_angles_dict = {} section_id_tags = [] # We create a 'dummy' root node, and then the real root node. # This will be at index '0' # Do we need to create a dummy node explicity? This depends on whether the root node has a length: section_dict = {} root_yaml_sect = yaml_section_dict[0] if 'length' in root_yaml_sect.keys(): assert False xyz = root_yaml_sect['xyz'] section_dict[0] = Section( x=xyz[0], y=xyz[1], z=xyz[2], r=root_yaml_sect['diam'] / 2.0, region=None, parent=None, ) # Add the remaining nodes: for (yaml_id, yaml_sect) in yaml_section_dict.iteritems(): if yaml_sect['parent'] == None: continue # print yaml_id, yaml_sect parent_section = section_dict[yaml_sect['parent']] #Region: rg_names1 = [yaml_sect["region"]] if yaml_sect.has_key("region") else [] rg_names2 = yaml_sect["regions"] if yaml_sect.has_key("regions") else [] rgs = [region_dict[rgName] for rgName in rg_names1 + rg_names2 ] # Since December 2010 each section is only allowed to have one # region. assert len(rgs) <= 1 #Diameter & length: if not yaml_sect.has_key("diam"): raise ValueError("Not radius given") diam = yaml_sect["diam"] if not (diam > 0): raise ValueError("indvalid radius: %s" % diam ) rad = diam / 2.0 # End Point: def get_yaml_length(yaml_sect): if not yaml_sect.has_key("length"): raise ValueError("No Length given") length = yaml_sect["length"] if not length > 0: raise ValueError("Invalid Length") return length #We only specify end points by using angles or by xyz cooridinates: if int(yaml_sect.has_key("absangle")) + int(yaml_sect.has_key("relangle")) + int(yaml_sect.has_key("xyz")) >= 2: raise ValueError("Too many ways for specifying endpoint") if yaml_sect.has_key('xyz'): if not parent_section: angle = 0 xyz = yaml_sect['xyz'] elif yaml_sect.has_key("absangle"): length = get_yaml_length(yaml_sect) angle = yaml_sect['absangle'] xyz = (parent_section.d_x + length * math.cos(math.radians(angle)), parent_section.d_y + length * math.sin(math.radians(angle)), 0.0) elif yaml_sect.has_key('relangle'): length = get_yaml_length(yaml_sect) angle = section_angles_dict[parent_section] + yaml_sect["relangle"] xyz = (parent_section.d_x + length * math.cos(math.radians(angle)), parent_section.d_y + length * math.sin(math.radians(angle)), 0.0) else: # Default to 'abs'-angle to 0 length = get_yaml_length(yaml_sect) angle = 0 xyz = (parent_section.d_x + length * math.cos(math.radians(angle)), parent_section.d_y + length * math.sin(math.radians(angle)), 0.0) # Possible ID's: section_id_tag = (yaml_sect['id'] if yaml_sect.has_key('id') else None) if section_id_tag: check_cstyle_varname(section_id_tag) if section_id_tag in section_id_tags: raise ValueError('Duplicate Section ID: %s' % section_id_tag) if section_id_tag: section_id_tags.append(section_id_tag) # Create the new section: if parent_section: new_section = parent_section.create_distal_section(x=xyz[0], y=xyz[1], z=xyz[2], r=rad, region=rgs[0], idtag=section_id_tag) else: new_section = Section(x=xyz[0], y=xyz[1], z=xyz[2], r=rad, region=None, idtag=section_id_tag) section_dict[None] = new_section # Calculate the angle of the current section: if parent_section: joining_vec = new_section.get_distal_npa3() - parent_section.get_distal_npa3() angle = math.radians(math.atan2(joining_vec[1], joining_vec[0])) section_angles_dict[new_section] = angle #Save the section: section_dict[yaml_id] = new_section # # TODO: THIS IS A HACK! Ensure the dummy node has no attached regions: # section_dict[None].regions = [] assert section_dict[0].region == None if section_dict[0].children == []: raise ValueError("No segments found") morphs = MorphologyTree(name=name, dummysection=section_dict[0], metadata=metadata) if len(morphs) < 1: raise ValueError return morphs