예제 #1
0
def make_new_synapse(syn_name, postcomp, syn_name_full, nml_params):
    ## if channel does not exist in library load it from xml file
    if not moose.exists("/library/" + syn_name):
        cmlR = ChannelML(nml_params)
        model_filename = syn_name + ".xml"
        model_path = utils.find_first_file(model_filename, nml_params["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
                )
            )
    ## deep copies the library SynChan and SynHandler
    ## to instances under postcomp named as <arg3>
    synid = moose.copy(moose.element("/library/" + syn_name), postcomp, syn_name_full)
    # synhandlerid = moose.copy(moose.element('/library/'+syn_name+'/handler'), postcomp,syn_name_full+'/handler') This line was a bug: double handler
    synhandler = moose.element(synid.path + "/handler")
    syn = moose.SynChan(synid)
    synhandler = moose.element(synid.path + "/handler")  # returns SimpleSynHandler or STDPSynHandler

    ## connect the SimpleSynHandler or the STDPSynHandler to the SynChan (double exp)
    moose.connect(synhandler, "activationOut", syn, "activation")
    # mgblock connections if required
    childmgblock = moose_utils.get_child_Mstring(syn, "mgblockStr")
    #### connect the post compartment to the synapse
    if childmgblock.value == "True":  # If NMDA synapse based on mgblock, connect to mgblock
        mgblock = moose.Mg_block(syn.path + "/mgblock")
        moose.connect(postcomp, "channel", mgblock, "channel")
    else:  # if SynChan or even NMDAChan, connect normally
        moose.connect(postcomp, "channel", syn, "channel")
예제 #2
0
    def addSyapseProperties(self, projection,  syn_props, source, target):
        '''Add Synapse properties'''
        synName = syn_props.attrib['synapse_type']
        ## if synapse does not exist in library load it from xml file
        if not moose.exists(os.path.join(self.libraryPath, synName)):
            cmlR = ChannelML.ChannelML(self.nml_params)
            modelFileName = synName+'.xml'
            model_path = nmu.find_first_file(modelFileName
                    , self.modelDir
                    )
            if model_path is not None:
                cmlR.readChannelMLFromFile(model_path)
            else:
                msg = 'For mechanism {0}: files {1} not found under {2}.'.format(
                        synName, modelFileName, self.modelDir
                    )
                raise UserWarning(msg)

        weight = float(syn_props.attrib['weight'])
        threshold = float(syn_props.attrib['threshold']) * self.Efactor
        if 'prop_delay' in syn_props.attrib:
            propDelay = float(syn_props.attrib['prop_delay']) * self.Tfactor
        elif 'internal_delay' in syn_props.attrib:
            propDelay = float(syn_props.attrib['internal_delay']) * self.Tfactor
        else:
            propDelay = 0.0

        options = { 'syn_name' : synName , 'weight' : weight
                   , 'source' : source , 'target' : target
                   , 'threshold' : threshold , 'prop_delay' : propDelay 
                   }
        return options
예제 #3
0
def make_new_synapse(syn_name, postcomp, syn_name_full, nml_params):
    ## if channel does not exist in library load it from xml file
    if not moose.exists('/library/' + syn_name):
        cmlR = ChannelML(nml_params)
        model_filename = syn_name + '.xml'
        model_path = utils.find_first_file(model_filename,
                                           nml_params['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))
    ## deep copies the library SynChan and SynHandler
    ## to instances under postcomp named as <arg3>
    synid = moose.copy(moose.element('/library/' + syn_name), postcomp,
                       syn_name_full)
    #synhandlerid = moose.copy(moose.element('/library/'+syn_name+'/handler'), postcomp,syn_name_full+'/handler') This line was a bug: double handler
    synhandler = moose.element(synid.path + '/handler')
    syn = moose.SynChan(synid)
    synhandler = moose.element(
        synid.path + '/handler')  # returns SimpleSynHandler or STDPSynHandler

    ## connect the SimpleSynHandler or the STDPSynHandler to the SynChan (double exp)
    moose.connect(synhandler, 'activationOut', syn, 'activation')
    # mgblock connections if required
    childmgblock = moose_utils.get_child_Mstring(syn, 'mgblockStr')
    #### connect the post compartment to the synapse
    if childmgblock.value == 'True':  # If NMDA synapse based on mgblock, connect to mgblock
        mgblock = moose.Mg_block(syn.path + '/mgblock')
        moose.connect(postcomp, "channel", mgblock, "channel")
    else:  # if SynChan or even NMDAChan, connect normally
        moose.connect(postcomp, "channel", syn, "channel")
예제 #4
0
 def createPopulations(self):
     self.populationDict = {}
     for population in self.network.findall(".//{"+nml_ns+"}population"):
         cellname = population.attrib["cell_type"]
         populationname = population.attrib["name"]
         print "loading", populationname
         ## if cell does not exist in library load it from xml file
         if not moose.exists('/library/'+cellname):
             mmlR = MorphML(self.nml_params)
             model_filenames = (cellname+'.xml', cellname+'.morph.xml')
             success = False
             for model_filename in model_filenames:
                 model_path = find_first_file(model_filename,self.model_dir)
                 if model_path is not None:
                     cellDict = mmlR.readMorphMLFromFile(model_path)
                     success = True
                     break
             if not success:
                 raise IOError(
                     'For cell {0}: files {1} not found under {2}.'.format(
                         cellname, model_filenames, self.model_dir
                     )
                 )
             self.cellSegmentDict.update(cellDict)
         if cellname == 'LIF':
             libcell = moose.LeakyIaF('/library/'+cellname)
         else:
             libcell = moose.Neuron('/library/'+cellname) #added cells as a Neuron class.
         self.populationDict[populationname] = (cellname,{})
         moose.Neutral('/cells')
         for instance in population.findall(".//{"+nml_ns+"}instance"):
             instanceid = instance.attrib['id']
             location = instance.find('./{'+nml_ns+'}location')
             rotationnote = instance.find('./{'+meta_ns+'}notes')
             if rotationnote is not None:
                 ## the text in rotationnote is zrotation=xxxxxxx
                 zrotation = float(string.split(rotationnote.text,'=')[1])
             else:
                 zrotation = 0
             ## deep copies the library cell to an instance under '/cells' named as <arg3>
             ## /cells is useful for scheduling clocks as all sim elements are in /cells
             cellid = moose.copy(libcell,moose.Neutral('/cells'),populationname+"_"+instanceid)
             if cellname == 'LIF':
                 cell = moose.LeakyIaF(cellid)
                 self.populationDict[populationname][1][int(instanceid)]=cell
             else:
                 cell = moose.Neuron(cellid) # No Cell class in MOOSE anymore! :( addded Neuron class - Chaitanya
                 self.populationDict[populationname][1][int(instanceid)]=cell
                 x = float(location.attrib['x'])*self.length_factor
                 y = float(location.attrib['y'])*self.length_factor
                 z = float(location.attrib['z'])*self.length_factor
                 self.translate_rotate(cell,x,y,z,zrotation)
예제 #5
0
    def createPopulation(self, population):
        """Create a population with given cell type """
        cellname = population.attrib["cell_type"]
        populationname = population.attrib["name"]

        if not moose.exists('/library/'+cellname):
            ## if cell does not exist in library load it from xml file
            mmlR = MorphML(self.nml_params)
            model_filenames = (cellname+'.xml', cellname+'.morph.xml')
            success = False
            for model_filename in model_filenames:
                model_path = find_first_file(model_filename, self.model_dir)
                if model_path is not None:
                    cellDict = mmlR.readMorphMLFromFile(model_path, self.params)
                    success = True
                    break
            if not success:
                raise IOError(
                    'For cell {0}: files {1} not found under {2}.'.format(
                        cellname, model_filenames, self.model_dir
                    )
                )
            self.cellSegmentDict.update(cellDict)

        libcell = moose.Neuron('/library/'+cellname) #added cells as a Neuron class.
        self.populationDict[populationname] = (cellname,{})
        moose.Neutral('/cells')
        _logger.info(
                "Creating population {0} of cell type {1}".format(
                    populationname, cellname
                    )
                )

        for instance in population.findall(".//{"+nml_ns+"}instance"):
            instanceid = instance.attrib['id']
            location = instance.find('./{'+nml_ns+'}location')
            rotationnote = instance.find('./{'+meta_ns+'}notes')
            if rotationnote is not None:
                ## the text in rotationnote is zrotation=xxxxxxx
                zrotation = float(rotationnote.text.split('=')[1])
            else:
                zrotation = 0
            ## deep copies the library cell to an instance under '/cells' named as <arg3>
            ## /cells is useful for scheduling clocks as all sim elements are in /cells
            cellid = moose.copy(libcell,moose.Neutral('/cells'),populationname+"_"+instanceid)
            cell = moose.Neuron(cellid)
            self.populationDict[populationname][1][int(instanceid)]=cell
            x = float(location.attrib['x'])*self.length_factor
            y = float(location.attrib['y'])*self.length_factor
            z = float(location.attrib['z'])*self.length_factor
            self.translate_rotate(cell,x,y,z,zrotation)
예제 #6
0
    def createPopulation(self, population):
        """Create a population with given cell type """
        cellname = population.attrib["cell_type"]
        populationname = population.attrib["name"]

        if not moose.exists('/library/' + cellname):
            ## if cell does not exist in library load it from xml file
            mmlR = MorphML(self.nml_params)
            model_filenames = (cellname + '.xml', cellname + '.morph.xml')
            success = False
            for model_filename in model_filenames:
                model_path = find_first_file(model_filename, self.model_dir)
                if model_path is not None:
                    cellDict = mmlR.readMorphMLFromFile(
                        model_path, self.params)
                    success = True
                    break
            if not success:
                raise IOError(
                    'For cell {0}: files {1} not found under {2}.'.format(
                        cellname, model_filenames, self.model_dir))
            self.cellSegmentDict.update(cellDict)

        libcell = moose.Neuron('/library/' +
                               cellname)  #added cells as a Neuron class.
        self.populationDict[populationname] = (cellname, {})
        moose.Neutral('/cells')
        _logger.info("Creating population {0} of cell type {1}".format(
            populationname, cellname))

        for instance in population.findall(".//{" + nml_ns + "}instance"):
            instanceid = instance.attrib['id']
            location = instance.find('./{' + nml_ns + '}location')
            rotationnote = instance.find('./{' + meta_ns + '}notes')
            if rotationnote is not None:
                ## the text in rotationnote is zrotation=xxxxxxx
                zrotation = float(rotationnote.text.split('=')[1])
            else:
                zrotation = 0
            ## deep copies the library cell to an instance under '/cells' named as <arg3>
            ## /cells is useful for scheduling clocks as all sim elements are in /cells
            cellid = moose.copy(libcell, moose.Neutral('/cells'),
                                populationname + "_" + instanceid)
            cell = moose.Neuron(cellid)
            self.populationDict[populationname][1][int(instanceid)] = cell
            x = float(location.attrib['x']) * self.length_factor
            y = float(location.attrib['y']) * self.length_factor
            z = float(location.attrib['z']) * self.length_factor
            self.translate_rotate(cell, x, y, z, zrotation)
예제 #7
0
파일: MorphML.py 프로젝트: hrani/moose-core
    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)}
예제 #8
0
    def createPopulations(self):
        """
        Create population dictionary.
        """
        populations =  self.network.findall(".//{"+nmu.nml_ns+"}population")
        if not populations:
            utils.dump("WARN"
                    , [ 
                        "No population find in model"
                        , "Searching in namespace {}".format(nmu.nml_ns)
                        ]
                    , frame = inspect.currentframe()
                    )

        for population in populations:
            cellname = population.attrib["cell_type"]
            populationName = population.attrib["name"]
            utils.dump("INFO"
                    , "Loading population `{0}`".format(populationName)
                    )
            # if cell does not exist in library load it from xml file
            if not moose.exists(self.libraryPath+'/'+cellname):
                utils.dump("DEBUG"
                        , "Searching in subdirectories for cell types" + 
                        " in `{0}.xml` and `{0}.morph.xml` ".format(cellname)
                        )
                mmlR = MorphML.MorphML(self.nml_params)
                model_filenames = (cellname+'.xml', cellname+'.morph.xml')
                success = False
                for modelFile in model_filenames:
                    model_path = nmu.find_first_file(modelFile
                            , self.modelDir
                            )
                    if model_path is not None:
                        cellDict = mmlR.readMorphMLFromFile(model_path)
                        success = True
                        break
                if not success:
                    raise IOError(
                        'For cell {0}: files {1} not found under {2}.'.format(
                            cellname, model_filenames, self.modelDir
                        )
                    )
                self.cellSegmentDict.update(cellDict)
            if cellname == 'LIF':
                cellid = moose.LeakyIaF(self.libraryPath+'/'+cellname)
            else:
                # added cells as a Neuron class.
                cellid = moose.Neuron(self.libraryPath+'/'+cellname) 

            self.populationDict[populationName] = (cellname,{})

            for instance in population.findall(".//{"+nmu.nml_ns+"}instance"):
                instanceid = instance.attrib['id']
                location = instance.find('./{'+nmu.nml_ns+'}location')
                rotationnote = instance.find('./{'+nmu.meta_ns+'}notes')
                if rotationnote is not None:
                    # the text in rotationnote is zrotation=xxxxxxx
                    zrotation = float(rotationnote.text.split('=')[1])
                else:
                    zrotation = 0
                if cellname == 'LIF':
                    cell = moose.LeakyIaF(cellid)
                    self.populationDict[populationName][1][int(instanceid)] = cell
                else:
                    # No Cell class in MOOSE anymore! :( addded Neuron class -
                    # Chaitanya
                    cell = moose.Neuron(cellid) 
                    self.populationDict[populationName][1][int(instanceid)] = cell
                    x = float(location.attrib['x']) * self.length_factor
                    y = float(location.attrib['y']) * self.length_factor
                    z = float(location.attrib['z']) * self.length_factor
                    self.translate_rotate(cell, x, y, z, zrotation)
예제 #9
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)
예제 #10
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)
예제 #11
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)}
예제 #12
0
    def set_compartment_param(self, compartment, name, value, mechanismname):
        """ Set the param for the compartment depending on name and mechanismname. """
        if name == 'CM':
            compartment.Cm = value*math.pi*compartment.diameter*compartment.length
        elif name == 'RM':
            compartment.Rm = value/(math.pi*compartment.diameter*compartment.length)
        elif name == 'RA':
            compartment.Ra = value*compartment.length/(math.pi*(compartment.diameter/2.0)**2)
        elif name == 'Em':
            compartment.Em = value
        elif name == 'initVm':
            compartment.initVm = value
        elif name == 'inject':
            print compartment.name, 'inject', value, 'A.'
            compartment.inject = value
        elif mechanismname is 'synapse': # synapse being added to the compartment
            ## these are potential locations, we do not actually make synapses.
            #synapse = self.context.deepCopy(self.context.pathToId('/library/'+value),\
            #    self.context.pathToId(compartment.path),value) # value contains name of synapse i.e. synapse_type
            #moose.connect(compartment,"channel", synapse, "channel")
            ## I assume below that compartment name has _segid at its end
            segid = string.split(compartment.name,'_')[-1] # get segment id from compartment name
            self.segDict[segid][5].append(value)
        elif mechanismname is 'spikegen': # spikegen being added to the compartment
            ## these are potential locations, we do not actually make the spikegens.
            ## spikegens for different synapses can have different thresholds,
            ## hence include synapse_type in its name
            ## value contains name of synapse i.e. synapse_type
            #spikegen = moose.SpikeGen(compartment.path+'/'+value+'_spikegen')
            #moose.connect(compartment,"VmSrc",spikegen,"Vm")
            pass
        elif mechanismname is not None:
            ## if mechanism is not present in compartment, deep copy from library
            if not moose.exists(compartment.path+'/'+mechanismname):
                ## if channel does not exist in library load it from xml file
                if not moose.exists("/library/"+mechanismname):
                    cmlR = ChannelML(self.nml_params)
                    model_filename = mechanismname+'.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
                            )
                        )

                neutralObj = moose.Neutral("/library/"+mechanismname)
                if 'CaConc' == neutralObj.class_: # Ion concentration pool
                    libcaconc = moose.CaConc("/library/"+mechanismname)
                    ## deep copies the library caconc under the compartment
                    channel = moose.copy(libcaconc,compartment,mechanismname)
                    channel = moose.CaConc(channel)
                    ## CaConc connections are made later using connect_CaConc()
                    ## Later, when calling connect_CaConc,
                    ## B is set for caconc based on thickness of Ca shell and compartment l and dia.
                elif 'HHChannel2D' == neutralObj.class_ : ## HHChannel2D
                    libchannel = moose.HHChannel2D("/library/"+mechanismname)
                    ## deep copies the library channel under the compartment
                    channel = moose.copy(libchannel,compartment,mechanismname)
                    channel = moose.HHChannel2D(channel)
                    moose.connect(channel,'channel',compartment,'channel')
                elif 'HHChannel' == neutralObj.class_ : ## HHChannel
                    libchannel = moose.HHChannel("/library/"+mechanismname)
                    ## deep copies the library channel under the compartment
                    channel = moose.copy(libchannel,compartment,mechanismname)
                    channel = moose.HHChannel(channel)
                    moose.connect(channel,'channel',compartment,'channel')
            ## if mechanism is present in compartment, just wrap it
            else:
                neutralObj = moose.Neutral(compartment.path+'/'+mechanismname)
                if 'CaConc' == neutralObj.class_: # Ion concentration pool
                    caconc = moose.CaConc(compartment.path+'/'+mechanismname) # wraps existing channel
                elif 'HHChannel2D' == neutralObj.class_ : ## HHChannel2D
                    channel = moose.HHChannel2D(compartment.path+'/'+mechanismname) # wraps existing channel
                elif 'HHChannel' == neutralObj.class_ : ## HHChannel
                    channel = moose.HHChannel(compartment.path+'/'+mechanismname) # wraps existing channel
            if name == 'Gbar':
                channel.Gbar = value*math.pi*compartment.diameter*compartment.length
            elif name == 'Ek':
                channel.Ek = value
            elif name == 'thick':
                caconc.thick = value ## JUST THIS WILL NOT DO - HAVE TO SET B based on this thick!
                ## Later, when calling connect_CaConc,
                ## B is set for caconc based on thickness of Ca shell and compartment l and dia.
        if neuroml_debug: print "Setting ",name," for ",compartment.path," value ",value
예제 #13
0
    def set_compartment_param(self, compartment, name, value, mechName):
        """ Set the param for the compartment depending on name and mechName. """
        if name == 'CM':
            compartment.Cm = value *math.pi*compartment.diameter*compartment.length
        elif name == 'RM':
            compartment.Rm = value/(math.pi*compartment.diameter*compartment.length)
        elif name == 'RA':
            compartment.Ra = value * compartment.length / \
                    (math.pi*(compartment.diameter/2.0)**2)
        elif name == 'Em':
            compartment.Em = value
        elif name == 'initVm':
            compartment.initVm = value
        elif name == 'inject':
            msg = " {0} inject {1} A.".format(compartment.name, value)
            debug.printDebug("INFO", msg)
            compartment.inject = value
        elif mechName is 'synapse':

           # synapse being added to the compartment
           # these are potential locations, we do not actually make synapses.
           # I assume below that compartment name has _segid at its end

           # get segment id from compartment name
           segid = moose_methods.getCompartmentId(compartment.name)
           self.segDict[segid][5].append(value)

        # spikegen being added to the compartment
        elif mechName is 'spikegen': 
            # these are potential locations, we do not actually make the
            # spikegens.  spikegens for different synapses can have different
            # thresholds, hence include synapse_type in its name value contains
            # name of synapse i.e. synapse_type
            #spikegen = moose.SpikeGen(compartment.path+'/'+value+'_spikegen')
            #moose.connect(compartment,"VmSrc",spikegen,"Vm")
            pass
        elif mechName is not None:

            # if mechanism is not present in compartment, deep copy from library
            if not moose.exists(compartment.path+'/'+mechName):

                # if channel does not exist in library load it from xml file
                if not moose.exists(self.libraryPath+"/"+mechName):
                    cmlR = ChannelML(self.nml_params)
                    model_filename = mechName+'.xml'
                    model_path = neuroml_utils.find_first_file(
                        model_filename
                        , self.model_dir
                    )
                    if model_path is not None:
                        cmlR.readChannelMLFromFile(model_path)
                    else:
                        msg = 'Mechanism {0}: files {1} not found under {2}'\
                                .format( mechName
                                        , model_filename
                                        , self.model_dir
                                        )
                        debug.printDebug("ERROR"
                                , msg
                                , frame = inspect.currentframe()
                                )
                        sys.exit(0)

                neutralObj = moose.Neutral(self.libraryPath+"/"+mechName)

                # Ion concentration pool
                if 'CaConc' == neutralObj.className:
                    libcaconc = moose.CaConc(self.libraryPath+"/"+mechName)

                    # deep copies the library caconc under the compartment
                    caconc = moose.copy(libcaconc,compartment,mechName)
                    caconc = moose.CaConc(caconc)

                    # CaConc connections are made later using connect_CaConc()
                    # Later, when calling connect_CaConc, B is set for caconc
                    # based on thickness of Ca shell and compartment l and dia
                    # OR based on the Mstring phi under CaConc path.
                    channel = None

                elif 'HHChannel2D' == neutralObj.className : ## HHChannel2D
                    libchannel = moose.HHChannel2D(self.libraryPath+"/"+mechName)
                    ## deep copies the library channel under the compartment
                    channel = moose.copy(libchannel,compartment,mechName)
                    channel = moose.HHChannel2D(channel)
                    moose.connect(channel,'channel',compartment,'channel')
                elif 'HHChannel' == neutralObj.className : ## HHChannel
                    libchannel = moose.HHChannel(self.libraryPath+"/"+mechName)

                    # deep copies the library channel under the compartment
                    channel = moose.copy(libchannel,compartment,mechName)
                    channel = moose.HHChannel(channel)
                    moose.connect(channel,'channel',compartment,'channel')
            # if mechanism is present in compartment, just wrap it
            else:
                neutralObj = moose.Neutral(compartment.path+'/'+mechName)
                # Ion concentration pool
                if 'CaConc' == neutralObj.className:
                    # wraps existing channel
                    caconc = moose.CaConc(compartment.path+'/'+mechName)
                    channel = None
                elif 'HHChannel2D' == neutralObj.className: ## HHChannel2D
                    # wraps existing channel
                    channel = moose.HHChannel2D(compartment.path+'/'+mechName)
                elif 'HHChannel' == neutralObj.className : ## HHChannel
                    # wraps existing channel
                    channel = moose.HHChannel(compartment.path+'/'+mechName)
            if name == 'Gbar':
                # if CaConc, neuroConstruct uses gbar for thickness or phi
                if channel is None:
                    # If child Mstring 'phi' is present, set gbar as phi BUT,
                    # value has been multiplied by Gfactor as a Gbar, SI or
                    # physiological not known here, ignoring Gbar for CaConc,
                    # instead of passing units here
                    child = moose_utils.get_child_Mstring(caconc,'phi')
                    if child is not None:
                        #child.value = value
                        pass
                    else:
                        #caconc.thick = value
                        pass
                else: # if ion channel, usual Gbar
                    channel.Gbar = value * math.pi * compartment.diameter \
                            * compartment.length
            elif name == 'Ek':
                channel.Ek = value

            # thick seems to be NEURON's extension to NeuroML level 2.
            elif name == 'thick':
                # JUST THIS WILL NOT DO - HAVE TO SET B based on this thick!
                caconc.thick = value
                # Later, when calling connect_CaConc, B is set for caconc based
                # on thickness of Ca shell and compartment l and dia.  OR based
                # on the Mstring phi under CaConc path.

        if neuroml_utils.neuroml_debug:
            msg = "Setting {0} for {1} value {2}".format(name, compartment.path
                                                         , value
                                                         )
            debug.printDebug("DEBUG", msg, frame=inspect.currentframe())
예제 #14
0
    def createPopulations(self):
        """
        Create population dictionary.
        """
        populations = self.network.findall(".//{" + nmu.nml_ns + "}population")
        if not populations:
            utils.dump("WARN", [
                "No population find in model",
                "Searching in namespace {}".format(nmu.nml_ns)
            ],
                       frame=inspect.currentframe())

        for population in populations:
            cellname = population.attrib["cell_type"]
            populationName = population.attrib["name"]
            utils.dump("INFO",
                       "Loading population `{0}`".format(populationName))
            # if cell does not exist in library load it from xml file
            if not moose.exists(self.libraryPath + '/' + cellname):
                utils.dump(
                    "DEBUG", "Searching in subdirectories for cell types" +
                    " in `{0}.xml` and `{0}.morph.xml` ".format(cellname))
                mmlR = MorphML.MorphML(self.nml_params)
                model_filenames = (cellname + '.xml', cellname + '.morph.xml')
                success = False
                for modelFile in model_filenames:
                    model_path = nmu.find_first_file(modelFile, self.modelDir)
                    if model_path is not None:
                        cellDict = mmlR.readMorphMLFromFile(model_path)
                        success = True
                        break
                if not success:
                    raise IOError(
                        'For cell {0}: files {1} not found under {2}.'.format(
                            cellname, model_filenames, self.modelDir))
                self.cellSegmentDict.update(cellDict)
            if cellname == 'LIF':
                cellid = moose.LeakyIaF(self.libraryPath + '/' + cellname)
            else:
                # added cells as a Neuron class.
                cellid = moose.Neuron(self.libraryPath + '/' + cellname)

            self.populationDict[populationName] = (cellname, {})

            for instance in population.findall(".//{" + nmu.nml_ns +
                                               "}instance"):
                instanceid = instance.attrib['id']
                location = instance.find('./{' + nmu.nml_ns + '}location')
                rotationnote = instance.find('./{' + nmu.meta_ns + '}notes')
                if rotationnote is not None:
                    # the text in rotationnote is zrotation=xxxxxxx
                    zrotation = float(rotationnote.text.split('=')[1])
                else:
                    zrotation = 0
                if cellname == 'LIF':
                    cell = moose.LeakyIaF(cellid)
                    self.populationDict[populationName][1][int(
                        instanceid)] = cell
                else:
                    # No Cell class in MOOSE anymore! :( addded Neuron class -
                    # Chaitanya
                    cell = moose.Neuron(cellid)
                    self.populationDict[populationName][1][int(
                        instanceid)] = cell
                    x = float(location.attrib['x']) * self.length_factor
                    y = float(location.attrib['y']) * self.length_factor
                    z = float(location.attrib['z']) * self.length_factor
                    self.translate_rotate(cell, x, y, z, zrotation)
예제 #15
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,
                             )
예제 #16
0
    def set_compartment_param(self, compartment, name, value, mechName):
        """ Set the param for the compartment depending on name and mechName. """
        if name == 'CM':
            compartment.Cm = value * math.pi * compartment.diameter * compartment.length
        elif name == 'RM':
            compartment.Rm = value / (math.pi * compartment.diameter *
                                      compartment.length)
        elif name == 'RA':
            compartment.Ra = value * compartment.length / \
                    (math.pi*(compartment.diameter/2.0)**2)
        elif name == 'Em':
            compartment.Em = value
        elif name == 'initVm':
            compartment.initVm = value
        elif name == 'inject':
            msg = " {0} inject {1} A.".format(compartment.name, value)
            debug.printDebug("INFO", msg)
            compartment.inject = value
        elif mechName is 'synapse':

            # synapse being added to the compartment
            # these are potential locations, we do not actually make synapses.
            # I assume below that compartment name has _segid at its end

            # get segment id from compartment name
            segid = moose_methods.getCompartmentId(compartment.name)
            self.segDict[segid][5].append(value)

        # spikegen being added to the compartment
        elif mechName is 'spikegen':
            # these are potential locations, we do not actually make the
            # spikegens.  spikegens for different synapses can have different
            # thresholds, hence include synapse_type in its name value contains
            # name of synapse i.e. synapse_type
            #spikegen = moose.SpikeGen(compartment.path+'/'+value+'_spikegen')
            #moose.connect(compartment,"VmSrc",spikegen,"Vm")
            pass
        elif mechName is not None:

            # if mechanism is not present in compartment, deep copy from library
            if not moose.exists(compartment.path + '/' + mechName):

                # if channel does not exist in library load it from xml file
                if not moose.exists(self.libraryPath + "/" + mechName):
                    cmlR = ChannelML(self.nml_params)
                    model_filename = mechName + '.xml'
                    model_path = neuroml_utils.find_first_file(
                        model_filename, self.model_dir)
                    if model_path is not None:
                        cmlR.readChannelMLFromFile(model_path)
                    else:
                        msg = 'Mechanism {0}: files {1} not found under {2}'\
                                .format( mechName
                                        , model_filename
                                        , self.model_dir
                                        )
                        debug.printDebug("ERROR",
                                         msg,
                                         frame=inspect.currentframe())
                        sys.exit(0)

                neutralObj = moose.Neutral(self.libraryPath + "/" + mechName)

                # Ion concentration pool
                if 'CaConc' == neutralObj.className:
                    libcaconc = moose.CaConc(self.libraryPath + "/" + mechName)

                    # deep copies the library caconc under the compartment
                    caconc = moose.copy(libcaconc, compartment, mechName)
                    caconc = moose.CaConc(caconc)

                    # CaConc connections are made later using connect_CaConc()
                    # Later, when calling connect_CaConc, B is set for caconc
                    # based on thickness of Ca shell and compartment l and dia
                    # OR based on the Mstring phi under CaConc path.
                    channel = None

                elif 'HHChannel2D' == neutralObj.className:  ## HHChannel2D
                    libchannel = moose.HHChannel2D(self.libraryPath + "/" +
                                                   mechName)
                    ## deep copies the library channel under the compartment
                    channel = moose.copy(libchannel, compartment, mechName)
                    channel = moose.HHChannel2D(channel)
                    moose.connect(channel, 'channel', compartment, 'channel')
                elif 'HHChannel' == neutralObj.className:  ## HHChannel
                    libchannel = moose.HHChannel(self.libraryPath + "/" +
                                                 mechName)

                    # deep copies the library channel under the compartment
                    channel = moose.copy(libchannel, compartment, mechName)
                    channel = moose.HHChannel(channel)
                    moose.connect(channel, 'channel', compartment, 'channel')
            # if mechanism is present in compartment, just wrap it
            else:
                neutralObj = moose.Neutral(compartment.path + '/' + mechName)
                # Ion concentration pool
                if 'CaConc' == neutralObj.className:
                    # wraps existing channel
                    caconc = moose.CaConc(compartment.path + '/' + mechName)
                    channel = None
                elif 'HHChannel2D' == neutralObj.className:  ## HHChannel2D
                    # wraps existing channel
                    channel = moose.HHChannel2D(compartment.path + '/' +
                                                mechName)
                elif 'HHChannel' == neutralObj.className:  ## HHChannel
                    # wraps existing channel
                    channel = moose.HHChannel(compartment.path + '/' +
                                              mechName)
            if name == 'Gbar':
                # if CaConc, neuroConstruct uses gbar for thickness or phi
                if channel is None:
                    # If child Mstring 'phi' is present, set gbar as phi BUT,
                    # value has been multiplied by Gfactor as a Gbar, SI or
                    # physiological not known here, ignoring Gbar for CaConc,
                    # instead of passing units here
                    child = moose_utils.get_child_Mstring(caconc, 'phi')
                    if child is not None:
                        #child.value = value
                        pass
                    else:
                        #caconc.thick = value
                        pass
                else:  # if ion channel, usual Gbar
                    channel.Gbar = value * math.pi * compartment.diameter \
                            * compartment.length
            elif name == 'Ek':
                channel.Ek = value

            # thick seems to be NEURON's extension to NeuroML level 2.
            elif name == 'thick':
                # JUST THIS WILL NOT DO - HAVE TO SET B based on this thick!
                caconc.thick = value
                # Later, when calling connect_CaConc, B is set for caconc based
                # on thickness of Ca shell and compartment l and dia.  OR based
                # on the Mstring phi under CaConc path.

        if neuroml_utils.neuroml_debug:
            msg = "Setting {0} for {1} value {2}".format(
                name, compartment.path, value)
            debug.printDebug("DEBUG", msg, frame=inspect.currentframe())