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
Example #6
0
    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
Example #7
0
    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
Example #9
0
    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