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")
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
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")
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)
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)
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)
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)}
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)
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)
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)
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)}
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
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())
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)
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, )
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())