def convert_morphology(root, positions='auto'): """Convert moose neuron morphology contained under `root` into a NeuroML object. The id of the return object is {root.name}_morphology. Each segment object gets the numeric value of the moose id of the object. The name of the segments are same as the corresponding moose compartment. Parameters ---------- root : a moose element containing a single cell model. positions : string flag to indicate if the positions of the end points of the compartments are explicitly available in the compartments or should be automatically generated. Possible values: `auto` - automatically generate z coordinates using length of the compartments. `explicit` - model has explicit coordinates for all compartments. Return ------ a neuroml.Morphology instance. """ if positions == 'auto': queue = deque([autoposition(root)]) elif positions == 'explicit': compartments = moose.wildcardFind('%s/##[TYPE=Compartment]' % (root.path)) queue = deque([compartment for compartment in map(moose.element, compartments) if len(compartment.neighbours['axial']) == 0]) if len(queue) != 1: raise Exception('There must be one and only one top level compartment. Found %d' % (len(topcomp_list))) else: raise Exception('allowed values for keyword argument positions=`auto` or `explicit`') comp_seg = {} parent = None while len(queue) > 0: compartment = queue.popleft() proximal = neuroml.Point3DWithDiam(x=compartment.x0, y=compartment.y0, z=compartment.z0, diameter=compartment.diameter) distal = neuroml.Point3DWithDiam(x=compartment.x, y=compartment.y, z=compartment.z, diameter=compartment.diameter) plist = list(map(moose.element, compartment.neighbours['axial'])) try: parent = neuroml.SegmentParent(segments=comp_seg[moose.element(plist[0])].id) except (KeyError, IndexError) as e: parent = None segment = neuroml.Segment(id=compartment.id_.value, proximal=proximal, distal=distal, parent=parent) # TODO: For the time being using numerical value of the moose # id for neuroml id.This needs to be updated for handling # array elements segment.name = compartment.name comp_seg[compartment] = segment queue.extend([comp for comp in map(moose.element, compartment.neighbours['raxial'])]) morph = neuroml.Morphology(id='%s_morphology' % (root.name)) morph.segments.extend(comp_seg.values()) return morph