Esempio n. 1
0
 def buildChanProto( self ):
     for i in self.chanProtoList:
         if len(i) == 1:
             chanName = self.parseChanName( i[0] )
         else:
             chanName = i[1]
         j = [i[0], chanName]
         if not self.checkAndBuildProto( "chan", j, [], ["xml"] ):
             cm = ChannelML( {'temperature': self.temperature} )
             cm.readChannelMLFromFile( i[0] )
             if ( len( i ) == 2 ):
                 chan = moose.element( '/library/' + chanName )
                 chan.name = i[1]
Esempio n. 2
0
 def buildChanProto(self):
     for i in self.chanProtoList:
         if len(i) == 1:
             chanName = self.parseChanName(i[0])
         else:
             chanName = i[1]
         j = [i[0], chanName]
         if not self.checkAndBuildProto("chan", j, [], ["xml"]):
             cm = ChannelML({'temperature': self.temperature})
             cm.readChannelMLFromFile(i[0])
             if (len(i) == 2):
                 chan = moose.element('/library/' + chanName)
                 chan.name = i[1]
Esempio n. 3
0
def main():
    cm = ChannelML( {'temperature': 32 })
    cm.readChannelMLFromFile( 'CA1_migliore_reference/hd.xml' )
    cm.readChannelMLFromFile( 'CA1_migliore_reference/kap.xml' )
    cm.readChannelMLFromFile( 'CA1_migliore_reference/kad.xml' )
    cm.readChannelMLFromFile( 'CA1_migliore_reference/kdr.xml' )
    cm.readChannelMLFromFile( 'CA1_migliore_reference/na3.xml' )
    cm.readChannelMLFromFile( 'CA1_migliore_reference/nax.xml' )
    if ( len( sys.argv ) < 2 ):
        print("Usage: ", sys.argv[0], " filename")
        return

    # filename = "./Bhavika_swcplusnmlfiles/preliminarily corrected nmlfiles/ascoli+buzsaki/valid/" + sys.argv[1]
    filename = sys.argv[1]
    moose.Neutral( '/model' )
    # Load in the swc file.
    cell = moose.loadModel( filename, '/model/ca1' )

    for i in moose.wildcardFind( '/library/##' ):
        i.tick = -1

    chanDistrib = [ \
            "EM", "#", "-58e-3", \
            "initVm", "#", "-65e-3", \
            "RM", "#", "2.8", \
            "CM", "#", "0.01", \
            "RA", "#", "1.5", \
            "RA", "#axon#", "0.5", \

            "hd", "#dend#,#apical#", "5e-2*(1+(r*3e4))", \
            "kdr", "#", "100", \
            "na3", "#soma#,#dend#,#apical#", "250", \
            "nax", "#axon#", "1250", \
            "kap", "#axon#,#soma#", "300", \
            "kap", "#dend#,#apical#", "150*(1+sign(100-r*1e6)) * (1+(r*1e4))", \
            "kad", "#dend#,#apical#", "150*(1+sign(r*1e6-100))*(1+r*1e4)", \
            ]
    moose.showfields( cell[0] )
    cell[0].channelDistribution = chanDistrib
    cell[0].parseChanDistrib()
    for i in range( 8 ):
        moose.setClock( i, simdt )
    hsolve = moose.HSolve( '/model/ca1/hsolve' )
    hsolve.dt = simdt
    hsolve.target = '/model/ca1/soma'
    '''
    '''
    moose.reinit()
    makePlot( cell[0] )

    # Now we set up the display
    moose.le( '/model/ca1/soma' )
    soma = moose.element( '/model/ca1/soma' )
    kap = moose.element( '/model/ca1/soma/kap' )

    graphs = moose.Neutral( '/graphs' )
    vtab = moose.Table( '/graphs/vtab' )
    moose.connect( vtab, 'requestOut', soma, 'getVm' )
    kaptab = moose.Table( '/graphs/kaptab' )
    moose.connect( kaptab, 'requestOut', kap, 'getGk' )

    compts = moose.wildcardFind( "/model/ca1/#[ISA=CompartmentBase]" )
    '''
    for i in compts:
        if moose.exists( i.path + '/Na' ):
            print i.path, moose.element( i.path + '/Na' ).Gbar, \
                moose.element( i.path + '/K_DR' ).Gbar, \
                i.Rm, i.Ra, i.Cm
    '''
    '''
    Na = moose.wildcardFind( '/model/ca1/#/Na#' )
    print Na
    Na2 = []
    for i in compts:
        if ( moose.exists( i.path + '/NaF2' ) ):
            Na2.append(  moose.element( i.path + '/NaF2' ) )
        if ( moose.exists( i.path + '/NaPF_SS' ) ):
            Na2.append(  moose.element( i.path + '/NaPF_SS' ) )
    ecomptPath = map( lambda x : x.path, compts )
    print "Na placed in ", len( Na ), len( Na2 ),  " out of ", len( compts ), " compts."
    '''
    compts[0].inject = inject
    ecomptPath = [x.path for x in compts]

    # Graphics stuff here.
    app = QtGui.QApplication(sys.argv)
    morphology = moogli.read_morphology_from_moose(name = "", path = "/model/ca1")
    morphology.create_group( "group_all", ecomptPath, -0.08, 0.02, \
            [0.0, 0.0, 1.0, 1.0], [1.0, 0.0, 0.0, 0.1] ) 

    viewer = moogli.DynamicMorphologyViewerWidget(morphology)
    def callback( morphology, viewer ):
        moose.start( frameRunTime )
        Vm = [moose.element( x ).Vm for x in compts]
        morphology.set_color( "group_all", Vm )
        currTime = moose.element( '/clock' ).currentTime
        #print currTime, compts[0].Vm
        if ( currTime < runtime ):
            return True
        return False

    viewer.set_callback( callback, idletime = 0 )
    viewer.showMaximized()
    viewer.show()
    app.exec_()
    t = numpy.arange( 0, runtime, vtab.dt )
    fig = plt.figure()
    p1 = fig.add_subplot(311)
    p2 = fig.add_subplot(312)
    p2.plot( t,  vtab.vector, label = 'Vm Soma' )
    p2.legend()
    p3 = fig.add_subplot(313)
    p3.plot( t, kaptab.vector, label = 'kap Soma' )
    p3.legend()
    plt.show()
Esempio n. 4
0
    def readMorphML(self,cell,params={},lengthUnits="micrometer"):
        """
        returns cellDict = { cellname: (segDict, cableDict) } # note: single cell only
        where segDict = { segid1 : [ segname,(proximalx,proximaly,proximalz),
            (distalx,distaly,distalz),diameter,length,[potential_syn1, ... ] ] , ... }
        segname is "<name>_<segid>" because 1) guarantees uniqueness,
            & 2) later scripts obtain segid from the compartment's name!
        and cableDict = { cablegroupname : [campartment1name, compartment2name, ... ], ... }.
        params is dict which can contain, combineSegments and/or createPotentialSynapses,
         both boolean.
        """
        if lengthUnits in ['micrometer','micron']:
            self.length_factor = 1e-6
        else:
            self.length_factor = 1.0
        cellname = cell.attrib["name"]
        moose.Neutral('/library') # creates /library in MOOSE tree; elif present, wraps
        _logger.info("Loading cell %s into /library ." % cellname)

        #~ moosecell = moose.Cell('/library/'+cellname)
        #using moose Neuron class - in previous version 'Cell' class Chaitanya
        moosecell = moose.Neuron('/library/'+cellname)
        self.cellDictBySegmentId[cellname] = [moosecell,{}]
        self.cellDictByCableId[cellname] = [moosecell,{}]
        self.segDict = {}
        if 'combineSegments' in params:
            self.combineSegments = params['combineSegments']
        else:
            self.combineSegments = False
        if 'createPotentialSynapses' in params:
            self.createPotentialSynapses = params['createPotentialSynapses']
        else:
            self.createPotentialSynapses = False
        _logger.info("readMorphML using combineSegments = %s" % self.combineSegments)

        ###############################################
        #### load cablegroups into a dictionary
        self.cablegroupsDict = {}
        self.cablegroupsInhomoparamsDict = {}
        ## Two ways of specifying cablegroups in neuroml 1.x
        ## <cablegroup>s with list of <cable>s
        cablegroups = cell.findall(".//{"+self.mml+"}cablegroup")
        for cablegroup in cablegroups:
            cablegroupname = cablegroup.attrib['name']
            self.cablegroupsDict[cablegroupname] = []
            self.cablegroupsInhomoparamsDict[cablegroupname] = []
            for cable in cablegroup.findall(".//{"+self.mml+"}cable"):
                cableid = cable.attrib['id']
                self.cablegroupsDict[cablegroupname].append(cableid)
            # parse inhomogenous_params
            for inhomogeneous_param in cablegroup.findall(".//{"+self.mml+"}inhomogeneous_param"):
                metric = inhomogeneous_param.find(".//{"+self.mml+"}metric")
                if metric.text == 'Path Length from root':
                    inhomoparamname = inhomogeneous_param.attrib['name']
                    inhomoparamvar = inhomogeneous_param.attrib['variable']
                    self.cablegroupsInhomoparamsDict[cablegroupname].append(\
                                (inhomoparamname,inhomoparamvar))
                else:
                    _logger.warning('Only "Path Length from root" metric is '
                            ' supported currently, ignoring %s ' % metric.text
                            )

        ## <cable>s with list of <meta:group>s
        cables = cell.findall(".//{"+self.mml+"}cable")
        for cable in cables:
            cableid = cable.attrib['id']
            cablegroups = cable.findall(".//{"+self.meta+"}group")
            for cablegroup in cablegroups:
                cablegroupname = cablegroup.text
                if cablegroupname in self.cablegroupsDict:
                    self.cablegroupsDict[cablegroupname].append(cableid)
                else:
                    self.cablegroupsDict[cablegroupname] = [cableid]

        ###################################################
        ## load all mechanisms in this cell into /library for later copying
        ## set which compartments have integrate_and_fire mechanism
        self.intFireCableIds = {}   # dict with keys as Compartments/cableIds which are IntFire
                                    # with mechanismnames as values
        for mechanism in cell.findall(".//{"+self.bio+"}mechanism"):
            mechanismname = mechanism.attrib["name"]
            passive = False
            if "passive_conductance" in mechanism.attrib:
                if mechanism.attrib['passive_conductance'] in ["true",'True','TRUE']:
                    passive = True
            if not passive:
                ## if channel does not exist in library load it from xml file
                if not moose.exists("/library/"+mechanismname):
                    _logger.info("Loading mechanism %s into library." % mechanismname)
                    cmlR = ChannelML(self.nml_params)
                    model_filename = mechanismname+'.xml'
                    model_path = neuroml_utils.find_first_file(model_filename,self.model_dir)
                    if model_path is not None:
                        cmlR.readChannelMLFromFile(model_path)
                    else:
                        raise IOError(
                            'For mechanism {0}: files {1} not found under {2}.'.format(
                                mechanismname, model_filename, self.model_dir)
                        )

                    ## set those compartments to be LIF for which
                    ## any integrate_and_fire parameter is set
                    if not moose.exists( "/library/"+mechanismname):
                        _logger.warn("Mechanism doesn't exist: %s " % mechanismname)
                        moose.le( '/library' )
                    moosemech = moose.element("/library/"+mechanismname)
                    if moose.exists(moosemech.path+"/integrate_and_fire"):
                        mooseIaF = moose.element(moosemech.path+"/integrate_and_fire") # Mstring
                        if mooseIaF.value in ['true','True','TRUE']:
                            mech_params = mechanism.findall(".//{"+self.bio+"}parameter")
                            for parameter in mech_params:
                                parametername = parameter.attrib['name']
                                ## check for the integrate_and_fire parameters
                                if parametername in ['threshold', 't_refrac', 'v_reset','g_refrac']:
                                    for group in parameter.findall(".//{"+self.bio+"}group"):
                                        cablegroupname = group.text
                                        if cablegroupname == 'all':
                                            self.intFireCableIds = {'all':mechanismname}
                                            break
                                        else:
                                            for cableid in self.cablegroupsDict[cablegroupname]:
                                                ## only one intfire mechanism is allowed in a cable
                                                ## the last one parsed will override others
                                                self.intFireCableIds[cableid] = mechanismname
                                if 'all' in self.intFireCableIds:
                                    break

        ############################################################
        #### load morphology and connections between compartments
        ## Many neurons exported from NEURON have multiple segments in a section
        ## If self.combineSegments = True,
        ##  then combine those segments into one Compartment / section
        ##  for combining, assume segments of a compartment/section are in increasing order
        ##  and assume all segments of a compartment/section have the same cableid
        ## findall() returns elements in document order:
        running_cableid = ''
        running_segid = ''
        running_comp = None
        running_diameter = 0.0
        running_dia_nums = 0
        segments = cell.findall(".//{"+self.mml+"}segment")
        segmentstotal = len(segments)
        for segnum,segment in enumerate(segments):
            segmentname = segment.attrib['name']
            ## cable is an optional attribute. WARNING: Here I assume it is always present.
            cableid = segment.attrib['cable']
            segmentid = segment.attrib['id']
            ## if old cableid still running AND self.combineSegments == True,
            ## then don't start a new compartment, skip to next segment
            if cableid == running_cableid and self.combineSegments:
                self.cellDictBySegmentId[cellname][1][segmentid] = running_comp
                proximal = segment.find('./{'+self.mml+'}proximal')
                if proximal is not None:
                    running_diameter += float(proximal.attrib["diameter"]) * self.length_factor
                    running_dia_nums += 1
                distal = segment.find('./{'+self.mml+'}distal')
                if distal is not None:
                    running_diameter += float(distal.attrib["diameter"]) * self.length_factor
                    running_dia_nums += 1
            ## if (self.combineSegments and new cableid starts) or if not self.combineSegments,
            ##  then start a new compartment
            else:
                ## Create a new compartment
                ## the moose "hsolve" method assumes compartments to be
                ## asymmetric compartments and symmetrizes them
                ## but that is not what we want when translating
                ## from Neuron which has only symcompartments -- so be careful!

                ## Check if integrate_and_fire mechanism is present,
                ## if so use LIF instead of Compartment
                moosecompname = segmentname+'_'+segmentid   # just segmentname is NOT unique
                                                            # eg: mitral bbmit exported from NEURON
                moosecomppath = moosecell.path+'/'+moosecompname
                mechanismname = None
                if 'all' in self.intFireCableIds:
                    mechanismname = self.intFireCableIds['all']
                if cableid in self.intFireCableIds:
                    mechanismname = self.intFireCableIds[cableid]
                if mechanismname is not None: # this cableid is an intfire
                    # create LIF (subclass of Compartment) and set to default values
                    moosecomp = moose.LIF(moosecomppath)
                    mname = '/library/' + mechanismname
                    moosechannel = moose.element(mname) if moose.exists(mname) else moose.Neutral(mname)
                    # Mstring values are 'string'; make sure to convert them to
                    # float else it will seg-fault with python3+
                    moosechannelval = moose.Mstring(moosechannel.path+'/vReset')
                    moosecomp.vReset = float(moosechannelval.value)
                    moosechannelval = moose.Mstring(moosechannel.path+'/thresh')
                    moosecomp.thresh = float( moosechannelval.value )
                    moosechannelval = moose.Mstring(moosechannel.path+'/refracT')
                    moosecomp.refractoryPeriod = eval(moosechannelval.value)
                    ## refracG is currently not supported by moose.LIF
                    ## when you implement it, check if refracG or g_refrac
                    ## is a conductance density or a conductance, I think the former
                    #moosechannelval = moose.Mstring(moosechannel.path+'/refracG')
                else:
                    moosecomp = moose.Compartment(moosecomppath)
                self.cellDictBySegmentId[cellname][1][segmentid] = moosecomp
                ## cables are grouped and mechanism densities are set for cablegroups later.
                ## hence I will need to refer to segment according to which cable it belongs to.
                ## if combineSegments is False, there can be multiple segments per cable,
                ##  so make array of compartments for cellDictByCableId[cellname][1][cableid]
                if cableid in self.cellDictByCableId[cellname][1]:
                    self.cellDictByCableId[cellname][1][cableid].append(moosecomp)
                else:
                    self.cellDictByCableId[cellname][1][cableid] = [moosecomp]
                running_cableid = cableid
                running_segid = segmentid
                running_comp = moosecomp
                running_diameter = 0.0
                running_dia_nums = 0
                if 'parent' in segment.attrib:
                    parentid = segment.attrib['parent'] # I assume the parent is created before the child
                                                        # so that I can immediately connect the child.
                    parent = self.cellDictBySegmentId[cellname][1][parentid]
                    ## It is always assumed that axial of parent is connected to raxial of moosesegment
                    ## THIS IS WHAT GENESIS readcell() DOES!!! UNLIKE NEURON!
                    ## THIS IS IRRESPECTIVE OF WHETHER PROXIMAL x,y,z OF PARENT = PROXIMAL x,y,z OF CHILD.
                    ## THIS IS ALSO IRRESPECTIVE OF fraction_along_parent SPECIFIED IN CABLE!
                    ## THUS THERE WILL BE NUMERICAL DIFFERENCES BETWEEN MOOSE/GENESIS and NEURON.
                    ## moosesegment sends Ra and Vm to parent, parent sends only Vm
                    ## actually for symmetric compartment, both parent and moosesegment require each other's Ra/2,
                    ## but axial and raxial just serve to distinguish ends.
                    moose.connect(parent,'axial',moosecomp,'raxial')
                else:
                    parent = None
                proximal = segment.find('./{'+self.mml+'}proximal')
                if proximal is None:         # If proximal tag is not present,
                                              # then parent attribute MUST be present in the segment tag!
                    ## if proximal is not present, then
                    ## by default the distal end of the parent is the proximal end of the child
                    moosecomp.x0 = parent.x
                    moosecomp.y0 = parent.y
                    moosecomp.z0 = parent.z
                else:
                    moosecomp.x0 = float(proximal.attrib["x"])*self.length_factor
                    moosecomp.y0 = float(proximal.attrib["y"])*self.length_factor
                    moosecomp.z0 = float(proximal.attrib["z"])*self.length_factor
                    running_diameter += float(proximal.attrib["diameter"]) * self.length_factor
                    running_dia_nums += 1
                distal = segment.find('./{'+self.mml+'}distal')
                if distal is not None:
                    running_diameter += float(distal.attrib["diameter"]) * self.length_factor
                    running_dia_nums += 1
                ## finished creating new compartment

            ## Update the end position, diameter and length, and segDict of this comp/cable/section
            ## with each segment that is part of this cable (assumes contiguous segments in xml).
            ## This ensures that we don't have to do any 'closing ceremonies',
            ## if a new cable is encoutered in next iteration.
            if distal is not None:
                running_comp.x = float(distal.attrib["x"])*self.length_factor
                running_comp.y = float(distal.attrib["y"])*self.length_factor
                running_comp.z = float(distal.attrib["z"])*self.length_factor
            ## Set the compartment diameter as the average diameter of all the segments in this section
            running_comp.diameter = running_diameter / float(running_dia_nums)
            ## Set the compartment length
            running_comp.length = math.sqrt((running_comp.x-running_comp.x0)**2+\
                (running_comp.y-running_comp.y0)**2+(running_comp.z-running_comp.z0)**2)
            ## NeuroML specs say that if (x0,y0,z0)=(x,y,z), then round compartment e.g. soma.
            ## In Moose set length = dia to give same surface area as sphere of dia.
            if running_comp.length == 0.0:
                running_comp.length = running_comp.diameter
            ## Set the segDict
            ## the empty list at the end below will get populated
            ## with the potential synapses on this segment, in function set_compartment_param(..)
            self.segDict[running_segid] = [running_comp.name,\
                (running_comp.x0,running_comp.y0,running_comp.z0),\
                (running_comp.x,running_comp.y,running_comp.z),\
                running_comp.diameter,running_comp.length,[]]
            if neuroml_utils.neuroml_debug:
                _logger.info('Set up compartment/section %s' % running_comp.name)

        ###############################################
        #### load biophysics into the compartments
        biophysics = cell.find(".//{"+self.neuroml+"}biophysics")
        if biophysics is not None:
            ## see pg 219 (sec 13.2) of Book of Genesis for Physiological Units
            if biophysics.attrib["units"] == 'Physiological Units':
                CMfactor = 1e-2 # F/m^2 from microF/cm^2
                Cfactor = 1e-6 # F from microF
                RAfactor = 1e1 # Ohm*m from KOhm*cm
                RMfactor = 1e-1 # Ohm*m^2 from KOhm*cm^2
                Rfactor = 1e-3 # Ohm from KOhm
                Efactor = 1e-3 # V from mV
                Gfactor = 1e1 # S/m^2 from mS/cm^2
                Ifactor = 1e-6 # A from microA
                Tfactor = 1e-3 # s from ms
            else:
                CMfactor = 1.0
                Cfactor = 1.0
                RAfactor = 1.0
                RMfactor = 1.0
                Rfactor = 1.0
                Efactor = 1.0
                Gfactor = 1.0
                Ifactor = 1.0
                Tfactor = 1.0

            spec_capacitance = cell.find(".//{"+self.bio+"}spec_capacitance")
            for parameter in spec_capacitance.findall(".//{"+self.bio+"}parameter"):
                self.set_group_compartment_param(cell, cellname, parameter,\
                 'CM', float(parameter.attrib["value"])*CMfactor, self.bio)
            spec_axial_resitance = cell.find(".//{"+self.bio+"}spec_axial_resistance")
            for parameter in spec_axial_resitance.findall(".//{"+self.bio+"}parameter"):
                self.set_group_compartment_param(cell, cellname, parameter,\
                 'RA', float(parameter.attrib["value"])*RAfactor, self.bio)
            init_memb_potential = cell.find(".//{"+self.bio+"}init_memb_potential")
            for parameter in init_memb_potential.findall(".//{"+self.bio+"}parameter"):
                self.set_group_compartment_param(cell, cellname, parameter,\
                 'initVm', float(parameter.attrib["value"])*Efactor, self.bio)
            chan_distrib = [] # the list for moose to parse inhomogeneous params (filled below)
            for mechanism in cell.findall(".//{"+self.bio+"}mechanism"):
                mechanismname = mechanism.attrib["name"]
                passive = False
                if "passive_conductance" in mechanism.attrib:
                    if mechanism.attrib['passive_conductance'] in ["true",'True','TRUE']:
                        passive = True
                _logger.info("Loading mechanism %s " % mechanismname)
                ## ONLY creates channel if at least one parameter (like gmax) is specified in the xml
                ## Neuroml does not allow you to specify all default values.
                ## However, granule cell example in neuroconstruct has Ca ion pool without
                ## a parameter, applying default values to all compartments!
                mech_params = mechanism.findall(".//{"+self.bio+"}parameter")
                ## if no params, apply all default values to all compartments
                if len(mech_params) == 0:
                    for compartment_list in self.cellDictByCableId[cellname][1].values():
                        for compartment in compartment_list:
                            self.set_compartment_param(compartment,None,'default',mechanismname)
                ## if params are present, apply params to specified cable/compartment groups
                for parameter in mech_params:
                    parametername = parameter.attrib['name']
                    if passive:
                        if parametername in ['gmax']:
                            self.set_group_compartment_param(cell, cellname, parameter,\
                             'RM', RMfactor*1.0/float(parameter.attrib["value"]), self.bio)
                        elif parametername in ['e','erev']:
                            self.set_group_compartment_param(cell, cellname, parameter,\
                             'Em', Efactor*float(parameter.attrib["value"]), self.bio)
                        elif parametername in ['inject']:
                            self.set_group_compartment_param(cell, cellname, parameter,\
                             'inject', Ifactor*float(parameter.attrib["value"]), self.bio)
                        else:
                            _logger.warning(["Yo programmer of MorphML! You didn't"
                                , " implement parameter %s " % parametername
                                , " in mechanism %s " % mechanismname
                                ]
                                )
                    else:
                        if parametername in ['gmax']:
                            gmaxval = float(eval(parameter.attrib["value"],{"__builtins__":None},{}))
                            self.set_group_compartment_param(cell, cellname, parameter,\
                             'Gbar', Gfactor*gmaxval, self.bio, mechanismname)
                        elif parametername in ['e','erev']:
                            self.set_group_compartment_param(cell, cellname, parameter,\
                             'Ek', Efactor*float(parameter.attrib["value"]), self.bio, mechanismname)
                        elif parametername in ['depth']: # has to be type Ion Concentration!
                            self.set_group_compartment_param(cell, cellname, parameter,\
                             'thick', self.length_factor*float(parameter.attrib["value"]),\
                             self.bio, mechanismname)
                        elif parametername in ['v_reset']:
                            self.set_group_compartment_param(cell, cellname, parameter,\
                             'v_reset', Efactor*float(parameter.attrib["value"]),\
                             self.bio, mechanismname)
                        elif parametername in ['threshold']:
                            self.set_group_compartment_param(cell, cellname, parameter,\
                             'threshold', Efactor*float(parameter.attrib["value"]),\
                             self.bio, mechanismname)
                        elif parametername in ['t_refrac']:
                            self.set_group_compartment_param(cell, cellname, parameter,\
                             't_refrac', Tfactor*float(parameter.attrib["value"]),\
                             self.bio, mechanismname)
                        else:
                            _logger.warning(["Yo programmer of MorphML import! You didn't"
                                    , " implement parameter %s " % parametername
                                    , " in mechanism %s " % mechanismname ]
                                    )

                ## variable parameters:
                ##  varying with:
                ##  p, g, L, len, dia
                ##	p: path distance from soma, measured along dendrite, in metres.
                ##	g: geometrical distance from soma, in metres.
                ##	L: electrotonic distance (# of lambdas) from soma, along dend. No units.
                ##	len: length of compartment, in metres.
                ##	dia: for diameter of compartment, in metres.
                var_params = mechanism.findall(".//{"+self.bio+"}variable_parameter")
                if len(var_params) > 0:
                    ## if variable params are present
                    ##  and use MOOSE to apply the variable formula
                    for parameter in var_params:
                        parametername = parameter.attrib['name']
                        cablegroupstr4moose = ""
                        ## the neuroml spec says there should be a single group in a variable_parameter
                        ##  of course user can always have multiple variable_parameter tags,
                        ##  if user wants multiple groups conforming to neuroml specs.
                        group = parameter.find(".//{"+self.bio+"}group")
                        cablegroupname = group.text
                        if cablegroupname == 'all':
                            cablegroupstr4moose = "#"
                        else:
                            for cableid in self.cablegroupsDict[cablegroupname]:
                                for compartment in self.cellDictByCableId[cellname][1][cableid]:
                                    cablegroupstr4moose += "#"+compartment.name+"#,"
                            if cablegroupstr4moose[-1] == ',':
                                cablegroupstr4moose = cablegroupstr4moose[:-1] # remove last comma
                        inhomo_value = parameter.find(".//{"+self.bio+"}inhomogeneous_value")
                        inhomo_value_name = inhomo_value.attrib['param_name']
                        inhomo_value_value = inhomo_value.attrib['value']
                        if parametername == 'gmax':
                            inhomo_eqn = '('+inhomo_value_value+')*'+str(Gfactor)
                                        # careful about physiol vs SI units
                        else:
                            inhomo_eqn = inhomo_value_value
                            _logger.warning('Physiol. vs SI units translation not'
                            ' implemented for parameter '+parametername+
                            'in channel '+mechanismname)+'. Use SI units'
                            'or ask for implementation.'
                        chan_distrib.extend((mechanismname,cablegroupstr4moose,parametername,inhomo_eqn,""))
                                    # use extend, not append, moose wants it this way
            ## get mooose to parse the variable parameter gmax channel distributions
            #pu.info("Some channel parameters distributed as per "+str(chan_distrib))
            moosecell.channelDistribution = chan_distrib
            #### Connect the Ca pools and channels
            #### Am connecting these at the very end so that all channels and pools have been created
            #### Note: this function is in moose.utils not moose.neuroml.utils !
            for compartment_list in self.cellDictByCableId[cellname][1].values():
                moose_utils.connect_CaConc(compartment_list,\
                    self.temperature+neuroml_utils.ZeroCKelvin) # temperature should be in Kelvin for Nernst

        ##########################################################
        #### load connectivity / synapses into the compartments
        connectivity = cell.find(".//{"+self.neuroml+"}connectivity")
        if connectivity is not None:
            for potential_syn_loc in cell.findall(".//{"+self.nml+"}potential_syn_loc"):
                if 'synapse_direction' in potential_syn_loc.attrib:
                    if potential_syn_loc.attrib['synapse_direction'] in ['post','preAndOrPost']:
                        self.set_group_compartment_param(cell, cellname, potential_syn_loc,\
                            'synapse_type', potential_syn_loc.attrib['synapse_type'],\
                            self.nml, mechanismname='synapse')
                    if potential_syn_loc.attrib['synapse_direction'] in ['pre','preAndOrPost']:
                        self.set_group_compartment_param(cell, cellname, potential_syn_loc,\
                            'spikegen_type', potential_syn_loc.attrib['synapse_type'],\
                            self.nml, mechanismname='spikegen')

        ##########################################################
        #### annotate each compartment with the cablegroups it belongs to
        self.cableDict = {}
        for cablegroupname in self.cablegroupsDict:
            comp_list = []
            for cableid in self.cablegroupsDict[cablegroupname]:
                for compartment in self.cellDictByCableId[cellname][1][cableid]:
                    cableStringPath = compartment.path+'/cable_groups'
                    cableString = moose.Mstring(cableStringPath)
                    if cableString.value == '':
                        cableString.value += cablegroupname
                    else:
                        cableString.value += ',' + cablegroupname
                    comp_list.append(compartment.name)
            self.cableDict[cablegroupname] = comp_list

        _logger.info("Finished loading into library, cell: %s " % cellname)
        return {cellname:(self.segDict,self.cableDict)}
Esempio n. 5
0
 def createProjections(self):
     self.projectionDict = {}
     projections = self.network.find(".//{" + nml_ns + "}projections")
     if projections is not None:
         if projections.attrib[
                 "units"] == 'Physiological Units':  # see pg 219 (sec 13.2) of Book of Genesis
             Efactor = 1e-3  # V from mV
             Tfactor = 1e-3  # s from ms
         else:
             Efactor = 1.0
             Tfactor = 1.0
     for projection in self.network.findall(".//{" + nml_ns +
                                            "}projection"):
         projectionname = projection.attrib["name"]
         print("setting", projectionname)
         source = projection.attrib["source"]
         target = projection.attrib["target"]
         self.projectionDict[projectionname] = (source, target, [])
         for syn_props in projection.findall(".//{" + nml_ns +
                                             "}synapse_props"):
             syn_name = syn_props.attrib['synapse_type']
             ## if synapse does not exist in library load it from xml file
             if not moose.exists("/library/" + syn_name):
                 cmlR = ChannelML(self.nml_params)
                 model_filename = syn_name + '.xml'
                 model_path = find_first_file(model_filename,
                                              self.model_dir)
                 if model_path is not None:
                     cmlR.readChannelMLFromFile(model_path)
                 else:
                     raise IOError(
                         'For mechanism {0}: files {1} not found under {2}.'
                         .format(mechanismname, model_filename,
                                 self.model_dir))
             weight = float(syn_props.attrib['weight'])
             threshold = float(syn_props.attrib['threshold']) * Efactor
             if 'prop_delay' in syn_props.attrib:
                 prop_delay = float(
                     syn_props.attrib['prop_delay']) * Tfactor
             elif 'internal_delay' in syn_props.attrib:
                 prop_delay = float(
                     syn_props.attrib['internal_delay']) * Tfactor
             else:
                 prop_delay = 0.0
             for connection in projection.findall(".//{" + nml_ns +
                                                  "}connection"):
                 pre_cell_id = connection.attrib['pre_cell_id']
                 post_cell_id = connection.attrib['post_cell_id']
                 if 'file' not in pre_cell_id:
                     # source could be 'mitrals', self.populationDict[source][0] would be 'mitral'
                     pre_cell_name = self.populationDict[source][0]
                     if 'pre_segment_id' in connection.attrib:
                         pre_segment_id = connection.attrib[
                             'pre_segment_id']
                     else:
                         pre_segment_id = "0"  # assume default segment 0, usually soma
                     pre_segment_path = self.populationDict[source][1][int(pre_cell_id)].path+'/'+\
                         self.cellSegmentDict[pre_cell_name][0][pre_segment_id][0]
                 else:
                     # I've removed extra excitation provided via files, so below comment doesn't apply.
                     # 'file[+<glomnum>]_<filenumber>' # glomnum is
                     # for mitral_granule extra excitation from unmodelled sisters.
                     pre_segment_path = pre_cell_id + '_' + connection.attrib[
                         'pre_segment_id']
                 # target could be 'PGs', self.populationDict[target][0] would be 'PG'
                 post_cell_name = self.populationDict[target][0]
                 if 'post_segment_id' in connection.attrib:
                     post_segment_id = connection.attrib['post_segment_id']
                 else:
                     post_segment_id = "0"  # assume default segment 0, usually soma
                 post_segment_path = self.populationDict[target][1][int(post_cell_id)].path+'/'+\
                     self.cellSegmentDict[post_cell_name][0][post_segment_id][0]
                 self.projectionDict[projectionname][2].append(
                     (syn_name, pre_segment_path, post_segment_path))
                 properties = connection.findall('./{' + nml_ns +
                                                 '}properties')
                 if len(properties) == 0:
                     self.connect(syn_name, pre_segment_path,
                                  post_segment_path, weight, threshold,
                                  prop_delay)
                 else:
                     for props in properties:
                         synapse_type = props.attrib['synapse_type']
                         if syn_name in synapse_type:
                             weight_override = float(props.attrib['weight'])
                             if 'internal_delay' in props.attrib:
                                 delay_override = float(
                                     props.attrib['internal_delay'])
                             else:
                                 delay_override = prop_delay
                             if weight_override != 0.0:
                                 self.connect(syn_name, pre_segment_path, post_segment_path,\
                                     weight_override, threshold, delay_override)
Esempio n. 6
0
 def createProjections(self):
     self.projectionDict={}
     projections = self.network.find(".//{"+nml_ns+"}projections")
     if projections is not None:
         if projections.attrib["units"] == 'Physiological Units': # see pg 219 (sec 13.2) of Book of Genesis
             Efactor = 1e-3 # V from mV
             Tfactor = 1e-3 # s from ms
         else:
             Efactor = 1.0
             Tfactor = 1.0
     for projection in self.network.findall(".//{"+nml_ns+"}projection"):
         projectionname = projection.attrib["name"]
         print("setting",projectionname)
         source = projection.attrib["source"]
         target = projection.attrib["target"]
         self.projectionDict[projectionname] = (source,target,[])
         for syn_props in projection.findall(".//{"+nml_ns+"}synapse_props"):
             syn_name = syn_props.attrib['synapse_type']
             ## if synapse does not exist in library load it from xml file
             if not moose.exists("/library/"+syn_name):
                 cmlR = ChannelML(self.nml_params)
                 model_filename = syn_name+'.xml'
                 model_path = find_first_file(model_filename,self.model_dir)
                 if model_path is not None:
                     cmlR.readChannelMLFromFile(model_path)
                 else:
                     raise IOError(
                         'For mechanism {0}: files {1} not found under {2}.'.format(
                             mechanismname, model_filename, self.model_dir
                         )
                     )
             weight = float(syn_props.attrib['weight'])
             threshold = float(syn_props.attrib['threshold'])*Efactor
             if 'prop_delay' in syn_props.attrib:
                 prop_delay = float(syn_props.attrib['prop_delay'])*Tfactor
             elif 'internal_delay' in syn_props.attrib:
                 prop_delay = float(syn_props.attrib['internal_delay'])*Tfactor
             else: prop_delay = 0.0
             for connection in projection.findall(".//{"+nml_ns+"}connection"):
                 pre_cell_id = connection.attrib['pre_cell_id']
                 post_cell_id = connection.attrib['post_cell_id']
                 if 'file' not in pre_cell_id:
                     # source could be 'mitrals', self.populationDict[source][0] would be 'mitral'
                     pre_cell_name = self.populationDict[source][0]
                     if 'pre_segment_id' in connection.attrib:
                         pre_segment_id = connection.attrib['pre_segment_id']
                     else: pre_segment_id = "0" # assume default segment 0, usually soma
                     pre_segment_path = self.populationDict[source][1][int(pre_cell_id)].path+'/'+\
                         self.cellSegmentDict[pre_cell_name][0][pre_segment_id][0]
                 else:
                     # I've removed extra excitation provided via files, so below comment doesn't apply.
                     # 'file[+<glomnum>]_<filenumber>' # glomnum is
                     # for mitral_granule extra excitation from unmodelled sisters.
                     pre_segment_path = pre_cell_id+'_'+connection.attrib['pre_segment_id']
                 # target could be 'PGs', self.populationDict[target][0] would be 'PG'
                 post_cell_name = self.populationDict[target][0]
                 if 'post_segment_id' in connection.attrib:
                     post_segment_id = connection.attrib['post_segment_id']
                 else: post_segment_id = "0" # assume default segment 0, usually soma
                 post_segment_path = self.populationDict[target][1][int(post_cell_id)].path+'/'+\
                     self.cellSegmentDict[post_cell_name][0][post_segment_id][0]
                 self.projectionDict[projectionname][2].append((syn_name, pre_segment_path, post_segment_path))
                 properties = connection.findall('./{'+nml_ns+'}properties')
                 if len(properties)==0:
                     self.connect(syn_name, pre_segment_path, post_segment_path, weight, threshold, prop_delay)
                 else:
                     for props in properties:
                         synapse_type = props.attrib['synapse_type']
                         if syn_name in synapse_type:
                             weight_override = float(props.attrib['weight'])
                             if 'internal_delay' in props.attrib:
                                 delay_override = float(props.attrib['internal_delay'])
                             else: delay_override = prop_delay
                             if weight_override != 0.0:
                                 self.connect(syn_name, pre_segment_path, post_segment_path,\
                                     weight_override, threshold, delay_override)
Esempio n. 7
0
    def readMorphML(self, cell, params={}, lengthUnits="micrometer"):
        """
        returns cellDict = { cellname: (segDict, cableDict) } # note: single cell only
        where segDict = { segid1 : [ segname,(proximalx,proximaly,proximalz),
            (distalx,distaly,distalz),diameter,length,[potential_syn1, ... ] ] , ... }
        segname is "<name>_<segid>" because 1) guarantees uniqueness,
            & 2) later scripts obtain segid from the compartment's name!
        and cableDict = { cablegroupname : [campartment1name, compartment2name, ... ], ... }.
        params is dict which can contain, combineSegments and/or createPotentialSynapses,
         both boolean.
        """
        if lengthUnits in ['micrometer', 'micron']:
            self.length_factor = 1e-6
        else:
            self.length_factor = 1.0
        cellname = cell.attrib["name"]
        moose.Neutral(
            '/library')  # creates /library in MOOSE tree; elif present, wraps
        _logger.info("Loading cell %s into /library ." % cellname)

        #~ moosecell = moose.Cell('/library/'+cellname)
        #using moose Neuron class - in previous version 'Cell' class Chaitanya
        moosecell = moose.Neuron('/library/' + cellname)
        self.cellDictBySegmentId[cellname] = [moosecell, {}]
        self.cellDictByCableId[cellname] = [moosecell, {}]
        self.segDict = {}
        if 'combineSegments' in params:
            self.combineSegments = params['combineSegments']
        else:
            self.combineSegments = False
        if 'createPotentialSynapses' in params:
            self.createPotentialSynapses = params['createPotentialSynapses']
        else:
            self.createPotentialSynapses = False
        _logger.info("readMorphML using combineSegments = %s" %
                     self.combineSegments)

        ###############################################
        #### load cablegroups into a dictionary
        self.cablegroupsDict = {}
        self.cablegroupsInhomoparamsDict = {}
        ## Two ways of specifying cablegroups in neuroml 1.x
        ## <cablegroup>s with list of <cable>s
        cablegroups = cell.findall(".//{" + self.mml + "}cablegroup")
        for cablegroup in cablegroups:
            cablegroupname = cablegroup.attrib['name']
            self.cablegroupsDict[cablegroupname] = []
            self.cablegroupsInhomoparamsDict[cablegroupname] = []
            for cable in cablegroup.findall(".//{" + self.mml + "}cable"):
                cableid = cable.attrib['id']
                self.cablegroupsDict[cablegroupname].append(cableid)
            # parse inhomogenous_params
            for inhomogeneous_param in cablegroup.findall(
                    ".//{" + self.mml + "}inhomogeneous_param"):
                metric = inhomogeneous_param.find(".//{" + self.mml +
                                                  "}metric")
                if metric.text == 'Path Length from root':
                    inhomoparamname = inhomogeneous_param.attrib['name']
                    inhomoparamvar = inhomogeneous_param.attrib['variable']
                    self.cablegroupsInhomoparamsDict[cablegroupname].append(\
                                (inhomoparamname,inhomoparamvar))
                else:
                    _logger.warning('Only "Path Length from root" metric is '
                                    ' supported currently, ignoring %s ' %
                                    metric.text)

        ## <cable>s with list of <meta:group>s
        cables = cell.findall(".//{" + self.mml + "}cable")
        for cable in cables:
            cableid = cable.attrib['id']
            cablegroups = cable.findall(".//{" + self.meta + "}group")
            for cablegroup in cablegroups:
                cablegroupname = cablegroup.text
                if cablegroupname in self.cablegroupsDict:
                    self.cablegroupsDict[cablegroupname].append(cableid)
                else:
                    self.cablegroupsDict[cablegroupname] = [cableid]

        ###################################################
        ## load all mechanisms in this cell into /library for later copying
        ## set which compartments have integrate_and_fire mechanism
        self.intFireCableIds = {
        }  # dict with keys as Compartments/cableIds which are IntFire
        # with mechanismnames as values
        for mechanism in cell.findall(".//{" + self.bio + "}mechanism"):
            mechanismname = mechanism.attrib["name"]
            passive = False
            if "passive_conductance" in mechanism.attrib:
                if mechanism.attrib['passive_conductance'] in [
                        "true", 'True', 'TRUE'
                ]:
                    passive = True
            if not passive:
                ## if channel does not exist in library load it from xml file
                if not moose.exists("/library/" + mechanismname):
                    _logger.info("Loading mechanism %s into library." %
                                 mechanismname)
                    cmlR = ChannelML(self.nml_params)
                    model_filename = mechanismname + '.xml'
                    model_path = neuroml_utils.find_first_file(
                        model_filename, self.model_dir)
                    if model_path is not None:
                        cmlR.readChannelMLFromFile(model_path)
                    else:
                        raise IOError(
                            'For mechanism {0}: files {1} not found under {2}.'
                            .format(mechanismname, model_filename,
                                    self.model_dir))

                    ## set those compartments to be LIF for which
                    ## any integrate_and_fire parameter is set
                    if not moose.exists("/library/" + mechanismname):
                        _logger.warn("Mechanism doesn't exist: %s " %
                                     mechanismname)
                        moose.le('/library')
                    moosemech = moose.element("/library/" + mechanismname)
                    if moose.exists(moosemech.path + "/integrate_and_fire"):
                        mooseIaF = moose.element(
                            moosemech.path + "/integrate_and_fire")  # Mstring
                        if mooseIaF.value in ['true', 'True', 'TRUE']:
                            mech_params = mechanism.findall(".//{" + self.bio +
                                                            "}parameter")
                            for parameter in mech_params:
                                parametername = parameter.attrib['name']
                                ## check for the integrate_and_fire parameters
                                if parametername in [
                                        'threshold', 't_refrac', 'v_reset',
                                        'g_refrac'
                                ]:
                                    for group in parameter.findall(".//{" +
                                                                   self.bio +
                                                                   "}group"):
                                        cablegroupname = group.text
                                        if cablegroupname == 'all':
                                            self.intFireCableIds = {
                                                'all': mechanismname
                                            }
                                            break
                                        else:
                                            for cableid in self.cablegroupsDict[
                                                    cablegroupname]:
                                                ## only one intfire mechanism is allowed in a cable
                                                ## the last one parsed will override others
                                                self.intFireCableIds[
                                                    cableid] = mechanismname
                                if 'all' in self.intFireCableIds:
                                    break

        ############################################################
        #### load morphology and connections between compartments
        ## Many neurons exported from NEURON have multiple segments in a section
        ## If self.combineSegments = True,
        ##  then combine those segments into one Compartment / section
        ##  for combining, assume segments of a compartment/section are in increasing order
        ##  and assume all segments of a compartment/section have the same cableid
        ## findall() returns elements in document order:
        running_cableid = ''
        running_segid = ''
        running_comp = None
        running_diameter = 0.0
        running_dia_nums = 0
        segments = cell.findall(".//{" + self.mml + "}segment")
        segmentstotal = len(segments)
        for segnum, segment in enumerate(segments):
            segmentname = segment.attrib['name']
            ## cable is an optional attribute. WARNING: Here I assume it is always present.
            cableid = segment.attrib['cable']
            segmentid = segment.attrib['id']
            ## if old cableid still running AND self.combineSegments == True,
            ## then don't start a new compartment, skip to next segment
            if cableid == running_cableid and self.combineSegments:
                self.cellDictBySegmentId[cellname][1][segmentid] = running_comp
                proximal = segment.find('./{' + self.mml + '}proximal')
                if proximal is not None:
                    running_diameter += float(
                        proximal.attrib["diameter"]) * self.length_factor
                    running_dia_nums += 1
                distal = segment.find('./{' + self.mml + '}distal')
                if distal is not None:
                    running_diameter += float(
                        distal.attrib["diameter"]) * self.length_factor
                    running_dia_nums += 1
            ## if (self.combineSegments and new cableid starts) or if not self.combineSegments,
            ##  then start a new compartment
            else:
                ## Create a new compartment
                ## the moose "hsolve" method assumes compartments to be
                ## asymmetric compartments and symmetrizes them
                ## but that is not what we want when translating
                ## from Neuron which has only symcompartments -- so be careful!

                ## Check if integrate_and_fire mechanism is present,
                ## if so use LIF instead of Compartment
                moosecompname = segmentname + '_' + segmentid  # just segmentname is NOT unique
                # eg: mitral bbmit exported from NEURON
                moosecomppath = moosecell.path + '/' + moosecompname
                mechanismname = None
                if 'all' in self.intFireCableIds:
                    mechanismname = self.intFireCableIds['all']
                if cableid in self.intFireCableIds:
                    mechanismname = self.intFireCableIds[cableid]
                if mechanismname is not None:  # this cableid is an intfire
                    ## create LIF (subclass of Compartment) and set to default values
                    moosecomp = moose.LIF(moosecomppath)
                    moosechannel = moose.Neutral('/library/' + mechanismname)
                    moosechannelval = moose.Mstring(moosechannel.path +
                                                    '/vReset')
                    moosecomp.vReset = moosechannelval.value
                    moosechannelval = moose.Mstring(moosechannel.path +
                                                    '/thresh')
                    moosecomp.thresh = moosechannelval.value
                    moosechannelval = moose.Mstring(moosechannel.path +
                                                    '/refracT')
                    moosecomp.refractoryPeriod = moosechannelval.value
                    ## refracG is currently not supported by moose.LIF
                    ## when you implement it, check if refracG or g_refrac
                    ## is a conductance density or a conductance, I think the former
                    #moosechannelval = moose.Mstring(moosechannel.path+'/refracG')
                else:
                    moosecomp = moose.Compartment(moosecomppath)
                self.cellDictBySegmentId[cellname][1][segmentid] = moosecomp
                ## cables are grouped and mechanism densities are set for cablegroups later.
                ## hence I will need to refer to segment according to which cable it belongs to.
                ## if combineSegments is False, there can be multiple segments per cable,
                ##  so make array of compartments for cellDictByCableId[cellname][1][cableid]
                if cableid in self.cellDictByCableId[cellname][1]:
                    self.cellDictByCableId[cellname][1][cableid].append(
                        moosecomp)
                else:
                    self.cellDictByCableId[cellname][1][cableid] = [moosecomp]
                running_cableid = cableid
                running_segid = segmentid
                running_comp = moosecomp
                running_diameter = 0.0
                running_dia_nums = 0
                if 'parent' in segment.attrib:
                    parentid = segment.attrib[
                        'parent']  # I assume the parent is created before the child
                    # so that I can immediately connect the child.
                    parent = self.cellDictBySegmentId[cellname][1][parentid]
                    ## It is always assumed that axial of parent is connected to raxial of moosesegment
                    ## THIS IS WHAT GENESIS readcell() DOES!!! UNLIKE NEURON!
                    ## THIS IS IRRESPECTIVE OF WHETHER PROXIMAL x,y,z OF PARENT = PROXIMAL x,y,z OF CHILD.
                    ## THIS IS ALSO IRRESPECTIVE OF fraction_along_parent SPECIFIED IN CABLE!
                    ## THUS THERE WILL BE NUMERICAL DIFFERENCES BETWEEN MOOSE/GENESIS and NEURON.
                    ## moosesegment sends Ra and Vm to parent, parent sends only Vm
                    ## actually for symmetric compartment, both parent and moosesegment require each other's Ra/2,
                    ## but axial and raxial just serve to distinguish ends.
                    moose.connect(parent, 'axial', moosecomp, 'raxial')
                else:
                    parent = None
                proximal = segment.find('./{' + self.mml + '}proximal')
                if proximal is None:  # If proximal tag is not present,
                    # then parent attribute MUST be present in the segment tag!
                    ## if proximal is not present, then
                    ## by default the distal end of the parent is the proximal end of the child
                    moosecomp.x0 = parent.x
                    moosecomp.y0 = parent.y
                    moosecomp.z0 = parent.z
                else:
                    moosecomp.x0 = float(
                        proximal.attrib["x"]) * self.length_factor
                    moosecomp.y0 = float(
                        proximal.attrib["y"]) * self.length_factor
                    moosecomp.z0 = float(
                        proximal.attrib["z"]) * self.length_factor
                    running_diameter += float(
                        proximal.attrib["diameter"]) * self.length_factor
                    running_dia_nums += 1
                distal = segment.find('./{' + self.mml + '}distal')
                if distal is not None:
                    running_diameter += float(
                        distal.attrib["diameter"]) * self.length_factor
                    running_dia_nums += 1
                ## finished creating new compartment

            ## Update the end position, diameter and length, and segDict of this comp/cable/section
            ## with each segment that is part of this cable (assumes contiguous segments in xml).
            ## This ensures that we don't have to do any 'closing ceremonies',
            ## if a new cable is encoutered in next iteration.
            if distal is not None:
                running_comp.x = float(distal.attrib["x"]) * self.length_factor
                running_comp.y = float(distal.attrib["y"]) * self.length_factor
                running_comp.z = float(distal.attrib["z"]) * self.length_factor
            ## Set the compartment diameter as the average diameter of all the segments in this section
            running_comp.diameter = running_diameter / float(running_dia_nums)
            ## Set the compartment length
            running_comp.length = math.sqrt((running_comp.x-running_comp.x0)**2+\
                (running_comp.y-running_comp.y0)**2+(running_comp.z-running_comp.z0)**2)
            ## NeuroML specs say that if (x0,y0,z0)=(x,y,z), then round compartment e.g. soma.
            ## In Moose set length = dia to give same surface area as sphere of dia.
            if running_comp.length == 0.0:
                running_comp.length = running_comp.diameter
            ## Set the segDict
            ## the empty list at the end below will get populated
            ## with the potential synapses on this segment, in function set_compartment_param(..)
            self.segDict[running_segid] = [running_comp.name,\
                (running_comp.x0,running_comp.y0,running_comp.z0),\
                (running_comp.x,running_comp.y,running_comp.z),\
                running_comp.diameter,running_comp.length,[]]
            if neuroml_utils.neuroml_debug:
                _logger.info('Set up compartment/section %s' %
                             running_comp.name)

        ###############################################
        #### load biophysics into the compartments
        biophysics = cell.find(".//{" + self.neuroml + "}biophysics")
        if biophysics is not None:
            ## see pg 219 (sec 13.2) of Book of Genesis for Physiological Units
            if biophysics.attrib["units"] == 'Physiological Units':
                CMfactor = 1e-2  # F/m^2 from microF/cm^2
                Cfactor = 1e-6  # F from microF
                RAfactor = 1e1  # Ohm*m from KOhm*cm
                RMfactor = 1e-1  # Ohm*m^2 from KOhm*cm^2
                Rfactor = 1e-3  # Ohm from KOhm
                Efactor = 1e-3  # V from mV
                Gfactor = 1e1  # S/m^2 from mS/cm^2
                Ifactor = 1e-6  # A from microA
                Tfactor = 1e-3  # s from ms
            else:
                CMfactor = 1.0
                Cfactor = 1.0
                RAfactor = 1.0
                RMfactor = 1.0
                Rfactor = 1.0
                Efactor = 1.0
                Gfactor = 1.0
                Ifactor = 1.0
                Tfactor = 1.0

            spec_capacitance = cell.find(".//{" + self.bio +
                                         "}spec_capacitance")
            for parameter in spec_capacitance.findall(".//{" + self.bio +
                                                      "}parameter"):
                self.set_group_compartment_param(cell, cellname, parameter,\
                 'CM', float(parameter.attrib["value"])*CMfactor, self.bio)
            spec_axial_resitance = cell.find(".//{" + self.bio +
                                             "}spec_axial_resistance")
            for parameter in spec_axial_resitance.findall(".//{" + self.bio +
                                                          "}parameter"):
                self.set_group_compartment_param(cell, cellname, parameter,\
                 'RA', float(parameter.attrib["value"])*RAfactor, self.bio)
            init_memb_potential = cell.find(".//{" + self.bio +
                                            "}init_memb_potential")
            for parameter in init_memb_potential.findall(".//{" + self.bio +
                                                         "}parameter"):
                self.set_group_compartment_param(cell, cellname, parameter,\
                 'initVm', float(parameter.attrib["value"])*Efactor, self.bio)
            chan_distrib = [
            ]  # the list for moose to parse inhomogeneous params (filled below)
            for mechanism in cell.findall(".//{" + self.bio + "}mechanism"):
                mechanismname = mechanism.attrib["name"]
                passive = False
                if "passive_conductance" in mechanism.attrib:
                    if mechanism.attrib['passive_conductance'] in [
                            "true", 'True', 'TRUE'
                    ]:
                        passive = True
                _logger.info("Loading mechanism %s " % mechanismname)
                ## ONLY creates channel if at least one parameter (like gmax) is specified in the xml
                ## Neuroml does not allow you to specify all default values.
                ## However, granule cell example in neuroconstruct has Ca ion pool without
                ## a parameter, applying default values to all compartments!
                mech_params = mechanism.findall(".//{" + self.bio +
                                                "}parameter")
                ## if no params, apply all default values to all compartments
                if len(mech_params) == 0:
                    for compartment_list in self.cellDictByCableId[cellname][
                            1].values():
                        for compartment in compartment_list:
                            self.set_compartment_param(compartment, None,
                                                       'default',
                                                       mechanismname)
                ## if params are present, apply params to specified cable/compartment groups
                for parameter in mech_params:
                    parametername = parameter.attrib['name']
                    if passive:
                        if parametername in ['gmax']:
                            self.set_group_compartment_param(cell, cellname, parameter,\
                             'RM', RMfactor*1.0/float(parameter.attrib["value"]), self.bio)
                        elif parametername in ['e', 'erev']:
                            self.set_group_compartment_param(cell, cellname, parameter,\
                             'Em', Efactor*float(parameter.attrib["value"]), self.bio)
                        elif parametername in ['inject']:
                            self.set_group_compartment_param(cell, cellname, parameter,\
                             'inject', Ifactor*float(parameter.attrib["value"]), self.bio)
                        else:
                            _logger.warning([
                                "Yo programmer of MorphML! You didn't",
                                " implement parameter %s " % parametername,
                                " in mechanism %s " % mechanismname
                            ])
                    else:
                        if parametername in ['gmax']:
                            gmaxval = float(
                                eval(parameter.attrib["value"],
                                     {"__builtins__": None}, {}))
                            self.set_group_compartment_param(cell, cellname, parameter,\
                             'Gbar', Gfactor*gmaxval, self.bio, mechanismname)
                        elif parametername in ['e', 'erev']:
                            self.set_group_compartment_param(cell, cellname, parameter,\
                             'Ek', Efactor*float(parameter.attrib["value"]), self.bio, mechanismname)
                        elif parametername in [
                                'depth'
                        ]:  # has to be type Ion Concentration!
                            self.set_group_compartment_param(cell, cellname, parameter,\
                             'thick', self.length_factor*float(parameter.attrib["value"]),\
                             self.bio, mechanismname)
                        elif parametername in ['v_reset']:
                            self.set_group_compartment_param(cell, cellname, parameter,\
                             'v_reset', Efactor*float(parameter.attrib["value"]),\
                             self.bio, mechanismname)
                        elif parametername in ['threshold']:
                            self.set_group_compartment_param(cell, cellname, parameter,\
                             'threshold', Efactor*float(parameter.attrib["value"]),\
                             self.bio, mechanismname)
                        elif parametername in ['t_refrac']:
                            self.set_group_compartment_param(cell, cellname, parameter,\
                             't_refrac', Tfactor*float(parameter.attrib["value"]),\
                             self.bio, mechanismname)
                        else:
                            _logger.warning([
                                "Yo programmer of MorphML import! You didn't",
                                " implement parameter %s " % parametername,
                                " in mechanism %s " % mechanismname
                            ])

                ## variable parameters:
                ##  varying with:
                ##  p, g, L, len, dia
                ##	p: path distance from soma, measured along dendrite, in metres.
                ##	g: geometrical distance from soma, in metres.
                ##	L: electrotonic distance (# of lambdas) from soma, along dend. No units.
                ##	len: length of compartment, in metres.
                ##	dia: for diameter of compartment, in metres.
                var_params = mechanism.findall(".//{" + self.bio +
                                               "}variable_parameter")
                if len(var_params) > 0:
                    ## if variable params are present
                    ##  and use MOOSE to apply the variable formula
                    for parameter in var_params:
                        parametername = parameter.attrib['name']
                        cablegroupstr4moose = ""
                        ## the neuroml spec says there should be a single group in a variable_parameter
                        ##  of course user can always have multiple variable_parameter tags,
                        ##  if user wants multiple groups conforming to neuroml specs.
                        group = parameter.find(".//{" + self.bio + "}group")
                        cablegroupname = group.text
                        if cablegroupname == 'all':
                            cablegroupstr4moose = "#"
                        else:
                            for cableid in self.cablegroupsDict[
                                    cablegroupname]:
                                for compartment in self.cellDictByCableId[
                                        cellname][1][cableid]:
                                    cablegroupstr4moose += "#" + compartment.name + "#,"
                            if cablegroupstr4moose[-1] == ',':
                                cablegroupstr4moose = cablegroupstr4moose[:
                                                                          -1]  # remove last comma
                        inhomo_value = parameter.find(".//{" + self.bio +
                                                      "}inhomogeneous_value")
                        inhomo_value_name = inhomo_value.attrib['param_name']
                        inhomo_value_value = inhomo_value.attrib['value']
                        if parametername == 'gmax':
                            inhomo_eqn = '(' + inhomo_value_value + ')*' + str(
                                Gfactor)
                            # careful about physiol vs SI units
                        else:
                            inhomo_eqn = inhomo_value_value
                            _logger.warning(
                                'Physiol. vs SI units translation not'
                                ' implemented for parameter ' + parametername +
                                'in channel ' +
                                mechanismname) + '. Use SI units'
                            'or ask for implementation.'
                        chan_distrib.extend(
                            (mechanismname, cablegroupstr4moose, parametername,
                             inhomo_eqn, ""))
                        # use extend, not append, moose wants it this way
            ## get mooose to parse the variable parameter gmax channel distributions
            #pu.info("Some channel parameters distributed as per "+str(chan_distrib))
            moosecell.channelDistribution = chan_distrib
            #### Connect the Ca pools and channels
            #### Am connecting these at the very end so that all channels and pools have been created
            #### Note: this function is in moose.utils not moose.neuroml.utils !
            for compartment_list in self.cellDictByCableId[cellname][1].values(
            ):
                moose_utils.connect_CaConc(compartment_list,\
                    self.temperature+neuroml_utils.ZeroCKelvin) # temperature should be in Kelvin for Nernst

        ##########################################################
        #### load connectivity / synapses into the compartments
        connectivity = cell.find(".//{" + self.neuroml + "}connectivity")
        if connectivity is not None:
            for potential_syn_loc in cell.findall(".//{" + self.nml +
                                                  "}potential_syn_loc"):
                if 'synapse_direction' in potential_syn_loc.attrib:
                    if potential_syn_loc.attrib['synapse_direction'] in [
                            'post', 'preAndOrPost'
                    ]:
                        self.set_group_compartment_param(cell, cellname, potential_syn_loc,\
                            'synapse_type', potential_syn_loc.attrib['synapse_type'],\
                            self.nml, mechanismname='synapse')
                    if potential_syn_loc.attrib['synapse_direction'] in [
                            'pre', 'preAndOrPost'
                    ]:
                        self.set_group_compartment_param(cell, cellname, potential_syn_loc,\
                            'spikegen_type', potential_syn_loc.attrib['synapse_type'],\
                            self.nml, mechanismname='spikegen')

        ##########################################################
        #### annotate each compartment with the cablegroups it belongs to
        self.cableDict = {}
        for cablegroupname in self.cablegroupsDict:
            comp_list = []
            for cableid in self.cablegroupsDict[cablegroupname]:
                for compartment in self.cellDictByCableId[cellname][1][
                        cableid]:
                    cableStringPath = compartment.path + '/cable_groups'
                    cableString = moose.Mstring(cableStringPath)
                    if cableString.value == '':
                        cableString.value += cablegroupname
                    else:
                        cableString.value += ',' + cablegroupname
                    comp_list.append(compartment.name)
            self.cableDict[cablegroupname] = comp_list

        _logger.info("Finished loading into library, cell: %s " % cellname)
        return {cellname: (self.segDict, self.cableDict)}
Esempio n. 8
0
 def createProjection(self, projection, Efactor, Tfactor):
     projectionname = projection.attrib["name"]
     _logger.info("Setting %s" % projectionname)
     source = projection.attrib["source"]
     target = projection.attrib["target"]
     self.projectionDict[projectionname] = (source, target, [])
     for syn_props in projection.findall(".//{" + nml_ns + "}synapse_props"):
         syn_name = syn_props.attrib["synapse_type"]
         ## if synapse does not exist in library load it from xml file
         if not moose.exists("/library/" + syn_name):
             cmlR = ChannelML(self.nml_params)
             model_filename = syn_name + ".xml"
             model_path = find_first_file(model_filename, self.model_dir)
             if model_path is not None:
                 cmlR.readChannelMLFromFile(model_path)
             else:
                 raise IOError(
                     "For mechanism {0}: files {1} not found under {2}.".format(
                         mechanismname, model_filename, self.model_dir
                     )
                 )
         weight = float(syn_props.attrib["weight"])
         threshold = float(syn_props.attrib["threshold"]) * Efactor
         if "prop_delay" in syn_props.attrib:
             prop_delay = float(syn_props.attrib["prop_delay"]) * Tfactor
         elif "internal_delay" in syn_props.attrib:
             prop_delay = float(syn_props.attrib["internal_delay"]) * Tfactor
         else:
             prop_delay = 0.0
         for connection in projection.findall(".//{" + nml_ns + "}connection"):
             pre_cell_id = connection.attrib["pre_cell_id"]
             post_cell_id = connection.attrib["post_cell_id"]
             if "file" not in pre_cell_id:
                 # source could be 'mitrals', self.populationDict[source][0] would be 'mitral'
                 pre_cell_name = self.populationDict[source][0]
                 if "pre_segment_id" in connection.attrib:
                     pre_segment_id = connection.attrib["pre_segment_id"]
                 else:
                     pre_segment_id = "0"  # assume default segment 0, usually soma
                 pre_segment_path = (
                     self.populationDict[source][1][int(pre_cell_id)].path
                     + "/"
                     + self.cellSegmentDict[pre_cell_name][0][pre_segment_id][0]
                 )
             else:
                 # I've removed extra excitation provided via files, so below comment doesn't apply.
                 # 'file[+<glomnum>]_<filenumber>' # glomnum is
                 # for mitral_granule extra excitation from unmodelled sisters.
                 pre_segment_path = pre_cell_id + "_" + connection.attrib["pre_segment_id"]
             # target could be 'PGs', self.populationDict[target][0] would be 'PG'
             post_cell_name = self.populationDict[target][0]
             if "post_segment_id" in connection.attrib:
                 post_segment_id = connection.attrib["post_segment_id"]
             else:
                 post_segment_id = "0"  # assume default segment 0, usually soma
             post_segment_path = (
                 self.populationDict[target][1][int(post_cell_id)].path
                 + "/"
                 + self.cellSegmentDict[post_cell_name][0][post_segment_id][0]
             )
             self.projectionDict[projectionname][2].append((syn_name, pre_segment_path, post_segment_path))
             properties = connection.findall("./{" + nml_ns + "}properties")
             if len(properties) == 0:
                 self.connect(syn_name, pre_segment_path, post_segment_path, weight, threshold, prop_delay)
             else:
                 for props in properties:
                     synapse_type = props.attrib["synapse_type"]
                     if syn_name in synapse_type:
                         weight_override = float(props.attrib["weight"])
                         if "internal_delay" in props.attrib:
                             delay_override = float(props.attrib["internal_delay"])
                         else:
                             delay_override = prop_delay
                         if weight_override != 0.0:
                             self.connect(
                                 syn_name,
                                 pre_segment_path,
                                 post_segment_path,
                                 weight_override,
                                 threshold,
                                 delay_override,
                             )