Exemple #1
0
    def get_cell(self, cellname=None):
        """ Either return a cell by name if there is more than one cell, otherwise the single cell """

        if cellname:
            return SeqUtils.filter_expect_single(self.cells,
                                                 lambda s: s.name == cellname)
        else:
            return SeqUtils.expect_single(self.cells)
    def get_cell(self, cellname=None):
        """ Either return a cell by name if there is more than one cell, otherwise the single cell """

        if cellname:
            return SeqUtils.filter_expect_single(self.cells,
                    lambda s: s.name == cellname)
        else:
            return SeqUtils.expect_single(self.cells)
    def getitem(self, *args, **kwargs):

        assert len(kwargs) == 1
        k = kwargs.keys()[0]
        v = kwargs[k]

        assert len(args) == 0
        if isinstance(k, collections.Callable):
            return SeqUtils.expect_single([k(o) for o in self.data])

        elif isinstance(k, basestring):
            return SeqUtils.expect_single([o for o in self.data if getattr(o, k) == v])
        else:
            print "Unexpected Type of %s - %s" % (k, type(k))
            assert False
    def get_evset(self, obj):
        # Get the results by string:
        if isinstance(obj, basestring):
            return SeqUtils.filter_expect_single( self.evsets, lambda s: s.name == obj)

        else:
            assert False
    def getitem(self, *args, **kwargs):

        assert len(kwargs) == 1
        k = kwargs.keys()[0]
        v = kwargs[k]

        assert len(args) == 0
        if isinstance(k, collections.Callable):
            return SeqUtils.expect_single([k(o) for o in self.data])

        elif isinstance(k, basestring):
            return SeqUtils.expect_single(
                [o for o in self.data if getattr(o, k) == v])
        else:
            print 'Unexpected Type of %s - %s' % (k, type(k))
            assert False
    def get_trace(self, obj):
        # Get the results by string:
        if isinstance(obj, basestring):
            return SeqUtils.filter_expect_single( self.traces, lambda s: s.name == obj)

        # Get the results by Recordable object:
        else:
            return self.get_trace(obj.name)
    def get_trace(self, obj):
        # Get the results by string:
        if isinstance(obj, basestring):
            return SeqUtils.filter_expect_single(self.traces,
                                                 lambda s: s.name == obj)

        # Get the results by Recordable object:
        else:
            return self.get_trace(obj.name)
Exemple #8
0
def record_from_mechanism(sim, mechanism_name, cell_location, what, on_error_skip=False, user_tags = None, **kwargs):
    user_tags = user_tags or []

    assert on_error_skip == False


    mechs = cell_location.cell.get_biophysics().get_all_mechanisms_applied_to_cell()


    chl = SeqUtils.filter_expect_single(seq=mechs, filter_func=lambda m:m.name==mechanism_name)
    r = sim.record(chl, what=what, cell_location=cell_location, user_tags = user_tags + [chl.name], **kwargs)

    return r
    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 load(cls, neuroMLFileObj, regions=None):
        """regions is a dictionary, which maps cable-groups to a Region name; this handles the
        case when there are multiple group tags in a MorphML document, since morphforge does not allow multiple regions'
        """

        doc = XML.parse(neuroMLFileObj).documentElement
        assert doc.tagName in ('morphml', 'neuroml')

        # Do the action:
        cellsNode = SeqUtils.filter_expect_single(
            doc.childNodes, filter_func=isElementWithTag("cells"))

        morphs = []
        for cellNode in Filter(cellsNode.childNodes, isElementWithTag("cell")):
            morph = cls.load_cell(cellNode, regions=regions)
            morphs.append(morph)
        assert len(morphs) == 1
        return morphs[0]
    def load(cls, src, regions=None):

        """regions is a dictionary, which maps cable-groups to a Region name; this handles the
        case when there are multiple group tags in a MorphML document, since morphforge does not allow multiple regions'
        """

        doc = XML.parse(src).documentElement
        assert doc.tagName in ("morphml", "neuroml")

        # Do the action:
        cellsNode = SeqUtils.filter_expect_single(doc.childNodes, filter_func=isElementWithTag("cells"))

        morphs = []
        for cellNode in Filter(cellsNode.childNodes, isElementWithTag("cell")):
            morph = cls.load_cell(cellNode, regions=regions)
            morphs.append(morph)
        assert len(morphs) == 1
        return morphs[0]
def buildPaneFromExistingChannelInfTau1State(existing_channel_functor, sim_config, chlname):


    # Setup the channel, so we can look at inf_tau:
    chl =  existing_channel_functor(NEURONEnvironment())

    state_name = SeqUtils.expect_single(chl.statevars.keys())

    state=buildStatePane(chl, state_name)
    general=HHGeneralPanel(
            gbar=float(chl.conductance.rescale('mS/cm2').magnitude),
            vrev=float(chl.reversalpotential.rescale("mV").magnitude)
           )


    return  HHChannelPaneInfTau1(sim_config=sim_config,
                                 general_pane=general,
                                 state_pane=state,
                                 eqn = chl.eqn,
                                 state_var_name = state_name,
                                 chlname = chlname
                               )
Exemple #13
0
def record_from_mechanism(sim,
                          mechanism_name,
                          cell_location,
                          what,
                          on_error_skip=False,
                          user_tags=None,
                          **kwargs):
    user_tags = user_tags or []

    assert on_error_skip == False

    mechs = cell_location.cell.get_biophysics(
    ).get_all_mechanisms_applied_to_cell()

    chl = SeqUtils.filter_expect_single(
        seq=mechs, filter_func=lambda m: m.name == mechanism_name)
    r = sim.record(chl,
                   what=what,
                   cell_location=cell_location,
                   user_tags=user_tags + [chl.name],
                   **kwargs)

    return r
    def load_cell_dictionaries(self, cellNode, regions=None):

        l1 = Level1NeuroMLRepresentation(cellNode)

        print "CellName:", cellNode.getAttribute("name")

        # We are not too worried about cables, but we do need the region name out of them:
        cableIDToRegionName = {}
        cablesNode = SeqUtils.filter_expect_single(cellNode.childNodes, isElementWithTag("cables"))
        for cableNode in Filter(cablesNode.childNodes, isElementWithTag("cable")):
            id = cableNode.getAttribute("id")
            name = cableNode.getAttribute("name")

            group_nodes = Filter(cableNode.childNodes, isElementWithTag("group"))

            if group_nodes:
                if regions:
                    # for n in group_nodes:
                    #    print get_text(n)
                    metaGroupNode = SeqUtils.filter_expect_single(group_nodes, lambda e: get_text(e) in regions)
                    region_name = regions[get_text(metaGroupNode)]
                else:
                    metaGroupNode = SeqUtils.expect_single(group_nodes)
                    region_name = get_text(metaGroupNode)

                assert not id in cableIDToRegionName
                cableIDToRegionName[id] = region_name

            else:
                cableIDToRegionName[id] = None
                pass

            print "Loaded Cable: ", id, name

        # Load the segments:
        segmentListInfo = {}  # id -> (id, name, cable, parent, (px, py, pz, pDiam), (dx, dy, dz, dDiam))
        segmentsNode = SeqUtils.filter_expect_single(cellNode.childNodes, isElementWithTag("segments"))
        for segNode in Filter(segmentsNode.childNodes, isElementWithTag("segment")):
            print "Segment"
            id = segNode.getAttribute("id")
            name = segNode.getAttribute("name")
            cable = segNode.getAttribute("cable")
            parent = segNode.getAttribute("parent")

            # Every point should have a distal End:
            dNode = SeqUtils.filter_expect_single(segNode.childNodes, isElementWithTag("distal"))
            d_x, d_y, d_z = dNode.getAttribute("x"), dNode.getAttribute("y"), dNode.getAttribute("z")
            d_diam = dNode.getAttribute("diameter")

            if not parent:
                pass
                pNode = SeqUtils.filter_expect_single(segNode.childNodes, isElementWithTag("proximal"))
                p_x, p_y, p_z = pNode.getAttribute("x"), pNode.getAttribute("y"), pNode.getAttribute("z")
                p_diam = pNode.getAttribute("diameter")

            else:
                # Not every point need have a proximal end, we look at the parent in case it has
                # both and check the locations agree
                parent_Dist_Loc = segmentListInfo[parent][5]

                pNode = Filter(segNode.childNodes, isElementWithTag("proximal"))
                if len(pNode) == 0:
                    p_x, p_y, p_z, p_diam = parent_Dist_Loc

                elif len(pNode) == 1:
                    p_xR, p_yR, p_zR = (
                        pNode[0].getAttribute("x"),
                        pNode[0].getAttribute("y"),
                        pNode[0].getAttribute("z"),
                    )
                    p_diamR = pNode[0].getAttribute("diameter")

                    # I do not understand MorphML to understand why these checks do not fail....
                    # print (p_xR, p_yR, p_zR)
                    # print (parent_Dist_Loc[0], parent_Dist_Loc[1], parent_Dist_Loc[2])
                    # assert (p_xR, p_yR, p_zR) == (parent_Dist_Loc[0], parent_Dist_Loc[1], parent_Dist_Loc[2])
                    # In this case, use the diameter just read:
                    p_x, p_y, p_z = p_xR, p_yR, p_zR
                    p_diam = p_diamR

                else:

                    assert False

            print id, name, cable, parent, (p_x, p_y, p_z, p_diam), (d_x, d_y, d_z, d_diam)
            infTuple = (
                id,
                name,
                cable,
                parent,
                (float(p_x), float(p_y), float(p_z), float(p_diam)),
                (float(d_x), float(d_y), float(d_z), float(d_diam)),
            )
            assert not id in segmentListInfo
            segmentListInfo[id] = infTuple

        # Now we have read the file and created the dictionaries:
        return (cableIDToRegionName, segmentListInfo)
Exemple #15
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 FilterExpectSingleChildrenByTag(node, tag):
    return SeqUtils.filter_expect_single(node.childNodes,
                                         isElementWithTag(tag))
    def load_cell_dictionaries(self, cellNode, regions=None):

        l1 = Level1NeuroMLRepresentation(cellNode)

        print 'CellName:', cellNode.getAttribute('name')

        # We are not too worried about cables, but we do need the region name out of them:
        cableIDToRegionName = {}
        cablesNode = SeqUtils.filter_expect_single(cellNode.childNodes,
                                                   isElementWithTag("cables"))
        for cableNode in Filter(cablesNode.childNodes,
                                isElementWithTag("cable")):
            id = cableNode.getAttribute("id")
            name = cableNode.getAttribute("name")

            group_nodes = Filter(cableNode.childNodes,
                                 isElementWithTag("group"))

            if group_nodes:
                if regions:
                    metaGroupNode = SeqUtils.filter_expect_single(
                        group_nodes, lambda e: get_text(e) in regions)
                    region_name = regions[get_text(metaGroupNode)]
                else:
                    metaGroupNode = SeqUtils.expect_single(group_nodes)
                    region_name = get_text(metaGroupNode)

                assert not id in cableIDToRegionName
                cableIDToRegionName[id] = region_name

            else:
                cableIDToRegionName[id] = None
                pass

            print 'Loaded Cable: ', id, name

        # Load the segments:
        segmentListInfo = {
        }  # id -> (id, name, cable, parent, (px, py, pz, pDiam), (dx, dy, dz, dDiam))
        segmentsNode = SeqUtils.filter_expect_single(
            cellNode.childNodes, isElementWithTag("segments"))
        for segNode in Filter(segmentsNode.childNodes,
                              isElementWithTag("segment")):
            print "Segment"
            id = segNode.getAttribute("id")
            name = segNode.getAttribute("name")
            cable = segNode.getAttribute("cable")
            parent = segNode.getAttribute("parent")

            # Every point should have a distal End:
            dNode = SeqUtils.filter_expect_single(segNode.childNodes,
                                                  isElementWithTag("distal"))
            d_x, d_y, d_z = dNode.getAttribute("x"), dNode.getAttribute(
                "y"), dNode.getAttribute("z")
            d_diam = dNode.getAttribute("diameter")

            if not parent:
                pass
                pNode = SeqUtils.filter_expect_single(
                    segNode.childNodes, isElementWithTag("proximal"))
                p_x, p_y, p_z = pNode.getAttribute("x"), pNode.getAttribute(
                    "y"), pNode.getAttribute("z")
                p_diam = pNode.getAttribute("diameter")

            else:
                # Not every point need have a proximal end, we look at the parent in case it has
                # both and check the locations agree
                parent_Dist_Loc = segmentListInfo[parent][5]

                pNode = Filter(segNode.childNodes,
                               isElementWithTag("proximal"))
                if len(pNode) == 0:
                    p_x, p_y, p_z, p_diam = parent_Dist_Loc

                elif len(pNode) == 1:
                    p_xR, p_yR, p_zR = pNode[0].getAttribute("x"), pNode[
                        0].getAttribute("y"), pNode[0].getAttribute("z")
                    p_diamR = pNode[0].getAttribute("diameter")

                    # I do not understand MorphML to understand why these checks do not fail....
                    #print (p_xR, p_yR, p_zR)
                    #print (parent_Dist_Loc[0], parent_Dist_Loc[1], parent_Dist_Loc[2])
                    #assert (p_xR, p_yR, p_zR) == (parent_Dist_Loc[0], parent_Dist_Loc[1], parent_Dist_Loc[2])
                    # In this case, use the diameter just read:
                    p_x, p_y, p_z = p_xR, p_yR, p_zR
                    p_diam = p_diamR

                else:

                    assert False

            print id, name, cable, parent, (p_x, p_y, p_z,
                                            p_diam), (d_x, d_y, d_z, d_diam)
            infTuple = (id, name, cable, parent, (float(p_x), float(p_y),
                                                  float(p_z), float(p_diam)),
                        (float(d_x), float(d_y), float(d_z), float(d_diam)))
            assert not id in segmentListInfo
            segmentListInfo[id] = infTuple

        # Now we have read the file and created the dictionaries:
        return (cableIDToRegionName, segmentListInfo)
    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 __init__(self, cellNode):

        self.cables = SearchableSet()
        self.cablegroups = SearchableSet()
        self.segments = SearchableSet()

        # Read the XML:

        # Start with the declared Cables:
        cablesNode = FilterExpectSingleChildrenByTag(cellNode, 'cables')

        # Load the individual cable objects
        for cableNode in FilterChildrenByTag(cablesNode, "cable"):
            if cableNode.getAttribute('id') in self.cables.keys('cable_id'):
                continue

            cable = NeuroMLCable(cable_id=cableNode.getAttribute('id'),
                                 name=cablesNode.getAttribute('name'))
            self.cables.add(cable)

            # Does the cable belong to any groups?
            for group_node in Filter(cableNode.childNodes,
                                     isElementWithTag("group")):
                cablegroupname = get_text(group_node)
                if not cablegroupname in self.cablegroups.keys('name'):
                    self.cablegroups.add(
                        NeuroMLCableGroup(name=cablegroupname))
                self.cablegroups.getitem(name=cablegroupname).add_cable(cable)

        # Load the CableGroup Objects:
        for cableGroupNode in Filter(cablesNode.childNodes,
                                     isElementWithTag("cablegroup")):

            # Get, or create, the cable node:
            cablegroupname = cableGroupNode.getAttribute('name')
            if not cablegroupname in self.cablegroups.keys('name'):
                self.cablegroups.add(NeuroMLCableGroup(name=cablegroupname))
            grp = self.cablegroups.getitem(name=cablegroupname)

            # Add the cable segments:
            for cableNode in Filter(cableGroupNode.childNodes,
                                    isElementWithTag("cable")):
                cableNodeID = cableNode.getAttribute('id')
                if not cableNodeID in self.cables.keys('cable_id'):
                    assert False
                cable = self.cables.getitem(cable_id=cableNodeID)
                grp.add_cable(cable)

        # Load the Segments Objects:
        segmentsNode = SeqUtils.filter_expect_single(
            cellNode.childNodes, isElementWithTag("segments"))
        for segmentNode in Filter(segmentsNode.childNodes,
                                  isElementWithTag("segment")):

            #Attributes:
            segment_id = segmentNode.getAttribute('id')
            parent_id = segmentNode.getAttribute('parent')
            cable_id = segmentNode.getAttribute('cable')
            cable = self.cables.getitem(
                cable_id=cable_id) if cable_id else None

            # Distal Information:
            distalNode = FilterExpectSingleChildrenByTag(segmentNode, 'distal')
            d_X, d_Y, d_Z, d_d = float(distalNode.getAttribute('x')), float(
                distalNode.getAttribute('y')), float(
                    distalNode.getAttribute('z')), float(
                        distalNode.getAttribute('diameter'))
            dInfo = (d_X, d_Y, d_Z, d_d)

            proximalNode = FilterChildrenByTag(segmentNode, 'proximal')

            # Root node:
            if not parent_id:
                assert proximalNode
                proximalNode = SeqUtils.expect_single(proximalNode)
                p_X, p_Y, p_Z, p_d = float(
                    proximalNode.getAttribute('x')), float(
                        proximalNode.getAttribute('y')), float(
                            proximalNode.getAttribute('z')), float(
                                proximalNode.getAttribute('diameter'))
                pInfo = (p_X, p_Y, p_Z, p_d)
                segment = NeuroMLSegment(segment_id=segment_id,
                                         distInfo=dInfo,
                                         proxInfo=pInfo,
                                         parent=None,
                                         cable=cable)

            #Child Node:
            else:

                # Not the root node, but a proximal node is provided:
                if proximalNode:

                    pInfo = (p_X, p_Y, p_Z, p_d)

                    # Proximal node and NOT the root:
                    if parent_id:
                        parentNode = self.segments.getitem(
                            segment_id=parent_id)
                        parentDistalInfo = parentNode.distInfo
                        eps = 0.01
                        # assert fabs(parentDistalInfo[0] - pInfo[0]) < eps
                        # assert fabs(parentDistalInfo[1] - pInfo[1]) < eps
                        # assert fabs(parentDistalInfo[2] - pInfo[2]) < eps
                        # assert fabs(parentDistalInfo[3] - pInfo[3]) < eps

                # Add the child node:
                segment = NeuroMLSegment(segment_id=segment_id,
                                         distInfo=dInfo,
                                         proxInfo=pInfo,
                                         parent=None,
                                         cable=cable)

            # Add the segment to groups?
            self.segments.add(segment)
    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
    def __init__(self, cellNode):

        self.cables = SearchableSet()
        self.cablegroups = SearchableSet()
        self.segments = SearchableSet()

        # Read the XML:

        # Start with the declared Cables:
        cablesNode = FilterExpectSingleChildrenByTag(cellNode, "cables")

        # Load the individual cable objects
        for cableNode in FilterChildrenByTag(cablesNode, "cable"):
            if cableNode.getAttribute("id") in self.cables.keys("cable_id"):
                continue

            cable = NeuroMLCable(cable_id=cableNode.getAttribute("id"), name=cablesNode.getAttribute("name"))
            self.cables.add(cable)

            # Does the cable belong to any groups?
            for group_node in Filter(cableNode.childNodes, isElementWithTag("group")):
                cablegroupname = get_text(group_node)
                if not cablegroupname in self.cablegroups.keys("name"):
                    self.cablegroups.add(NeuroMLCableGroup(name=cablegroupname))
                self.cablegroups.getitem(name=cablegroupname).add_cable(cable)

        # Load the CableGroup Objects:
        for cableGroupNode in Filter(cablesNode.childNodes, isElementWithTag("cablegroup")):

            # Get, or create, the cable node:
            cablegroupname = cableGroupNode.getAttribute("name")
            if not cablegroupname in self.cablegroups.keys("name"):
                self.cablegroups.add(NeuroMLCableGroup(name=cablegroupname))
            grp = self.cablegroups.getitem(name=cablegroupname)

            # Add the cable segments:
            for cableNode in Filter(cableGroupNode.childNodes, isElementWithTag("cable")):
                cableNodeID = cableNode.getAttribute("id")
                if not cableNodeID in self.cables.keys("cable_id"):
                    assert False
                cable = self.cables.getitem(cable_id=cableNodeID)
                grp.add_cable(cable)

        # Load the Segments Objects:
        segmentsNode = SeqUtils.filter_expect_single(cellNode.childNodes, isElementWithTag("segments"))
        for segmentNode in Filter(segmentsNode.childNodes, isElementWithTag("segment")):

            # Attributes:
            segment_id = segmentNode.getAttribute("id")
            parent_id = segmentNode.getAttribute("parent")
            cable_id = segmentNode.getAttribute("cable")
            cable = self.cables.getitem(cable_id=cable_id) if cable_id else None

            # Distal Information:
            distalNode = FilterExpectSingleChildrenByTag(segmentNode, "distal")
            d_X, d_Y, d_Z, d_d = (
                float(distalNode.getAttribute("x")),
                float(distalNode.getAttribute("y")),
                float(distalNode.getAttribute("z")),
                float(distalNode.getAttribute("diameter")),
            )
            dInfo = (d_X, d_Y, d_Z, d_d)

            proximalNode = FilterChildrenByTag(segmentNode, "proximal")

            # Root node:
            if not parent_id:
                assert proximalNode
                proximalNode = SeqUtils.expect_single(proximalNode)
                p_X, p_Y, p_Z, p_d = (
                    float(proximalNode.getAttribute("x")),
                    float(proximalNode.getAttribute("y")),
                    float(proximalNode.getAttribute("z")),
                    float(proximalNode.getAttribute("diameter")),
                )
                pInfo = (p_X, p_Y, p_Z, p_d)
                segment = NeuroMLSegment(
                    segment_id=segment_id, distInfo=dInfo, proxInfo=pInfo, parent=None, cable=cable
                )

            # Child Node:
            else:

                # Not the root node, but a proximal node is provided:
                if proximalNode:

                    pInfo = (p_X, p_Y, p_Z, p_d)

                    # Proximal node and NOT the root:
                    if parent_id:
                        parentNode = self.segments.getitem(segment_id=parent_id)
                        parentDistalInfo = parentNode.distInfo
                        eps = 0.01
                        # assert fabs(parentDistalInfo[0] - pInfo[0]) < eps
                        # assert fabs(parentDistalInfo[1] - pInfo[1]) < eps
                        # assert fabs(parentDistalInfo[2] - pInfo[2]) < eps
                        # assert fabs(parentDistalInfo[3] - pInfo[3]) < eps

                # Add the child node:
                segment = NeuroMLSegment(
                    segment_id=segment_id, distInfo=dInfo, proxInfo=pInfo, parent=None, cable=cable
                )

            # Add the segment to groups?
            self.segments.add(segment)
 def get_trace_by_tagselection(self, ts):
     import morphforge
     selector = morphforge.stdimports.TagSelector.from_string(ts)
     return SeqUtils.filter_expect_single(self.traces, selector)
def FilterExpectSingleChildrenByTag(node, tag):
    return SeqUtils.filter_expect_single(node.childNodes, isElementWithTag(tag))