def create_LIF(): neuromlR = NeuroML() neuromlR.readNeuroMLFromFile('cells_channels/LIF.morph.xml') libcell = moose.Neuron('/library/LIF') LIFCellid = moose.copy(libcell,moose.Neutral('/cells'),'IF1') LIFCell = moose.Neuron(LIFCellid) return LIFCell
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 loadGran98NeuroML_L123(filename, params): neuromlR = NeuroML() populationDict, projectionDict = \ neuromlR.readNeuroMLFromFile(filename,params=params) print "Number of compartments =",\ len(moose.Neuron(populationDict['CA1group'][1][0].path).children) soma_path = populationDict['CA1group'][1][0].path + '/Seg0_soma_0_0' somaVm = setupTable('somaVm', moose.Compartment(soma_path), 'Vm') #somaCa = setupTable('somaCa',moose.CaConc(soma_path+'/Gran_CaPool_98'),'Ca') #somaIKCa = setupTable('somaIKCa',moose.HHChannel(soma_path+'/Gran_KCa_98'),'Gk') #KDrX = setupTable('ChanX',moose.HHChannel(soma_path+'/Gran_KDr_98'),'X') soma = moose.Compartment(soma_path) print "Reinit MOOSE ... " resetSim(['/elec', '/cells'], simdt, plotdt, simmethod='hsolve') # from moose.utils print "Running ... " moose.start(runtime) tvec = arange(0.0, runtime, simdt) plot(tvec, somaVm.vector[1:]) title('Soma Vm') xlabel('time (s)') ylabel('Voltage (V)') print "Showing plots ..." show()
def makePassiveSoma(name, length, diamater): elecid = moose.Neuron('/library/' + name) dend = moose.Compartment(elecid.path + '/soma') dend.diameter = params['dendDia'] dend.length = params['dendL'] dend.x = params['dendL'] return elecid
def makeCellProto( name ): elec = moose.Neuron( '/library/' + name ) ecompt = [] soma = rd.buildCompt( elec, 'soma', somaDia, somaDia, -somaDia, RM, RA, CM ) dend = rd.buildCompt( elec, 'dend', dendLen, dendDia, 0, RM, RA, CM ) moose.connect( soma, 'axial', dend, 'raxial' ) elec.buildSegmentTree()
def test(): mc = moose.Neutral('model') dc = moose.Neutral('data') nrn = moose.Neuron('%s/nrn' % (mc.path)) x = SquidAxon('%s/squid' % (nrn.path)) clampv = [10.0, 20.0, 30.0, 40.0, 50.0] data = vclamptest(x, clampv, duration=20.0, delay=100.0, vhold=0.0, mc=mc, dc=dc, simdt=1e-2, plotdt=1e-2, solver='hsolve') plt.subplot(311) plt.title('Membrane potential throughout experiment') plt.plot(data['ts'], data['Vm'], label='Vm') plt.legend() plt.subplot(312) plt.title('Injection current throughout experiment') plt.plot(data['ts'], data['inject'], label='Inject') plt.legend() plt.subplot(313) plt.title('Injection currents for different clamp volatge values') for ii, inject in enumerate(data['injectArrays']): plt.plot(inject, label='V = %g' % (clampv[ii])) plt.legend() plt.show()
def makePassiveSoma(name, length, diameter): elecid = moose.Neuron('/library/' + name) dend = moose.Compartment(elecid.path + '/soma') dend.diameter = diameter dend.length = length dend.x = length return elecid
def makeCellProto(name): elec = moose.Neuron('/library/' + name) ecompt = [] #soma = rd.buildCompt( elec, 'soma', dx=somaDia, dia=somaDia, x=-somaDia, RM=RM, RA=RA, CM=CM ) dend = rd.buildCompt(elec, 'dend', dx=dendLen, dia=dendDia, x=0, RM=RM, RA=RA, CM=CM) #moose.connect( soma, 'axial', dend, 'raxial' ) prev = dend x = dendLen for i in range(numDendSegments): compt = rd.buildCompt(elec, 'dend' + str(i), dx=dendLen, dia=dendDia, x=x, RM=RM, RA=RA, CM=CM) moose.connect(prev, 'axial', compt, 'raxial') prev = compt x = x + dendLen elec.buildSegmentTree()
def makeDendProto(name): dend = moose.Neuron('/library/dend') prev = rd.buildCompt(dend, 'soma', RM=RM, RA=RA, CM=CM, dia=2.0e-06, x=0, dx=comptLen) x = comptLen y = 0.0 comptDia = 1e-06 for i in range(numDendSegments): dx = comptLen dy = 0 compt = rd.buildCompt(dend, 'dend' + str(i), RM=RM, RA=RA, CM=CM, x=x, y=y, dx=dx, dy=dy, dia=comptDia) moose.connect(prev, 'axial', compt, 'raxial') prev = compt x += dx y += dy
def makePassiveSoma( name, length, diameter): print("length: ", length) print("diameter: ", diameter) numComp = 10 x = length/float(numComp) # x = length elecid = moose.Neuron( '/library/' + name ) soma = moose.Compartment( elecid.path + '/soma' ) soma.diameter = diameter soma.length = length soma.x0 = 0 soma.x = x ls = x n = 2.0 dendList = [] for i in range(numComp -1): dendList.append(moose.Compartment( elecid.path + '/dend' + str(i) )) dend = dendList[-1] dend.diameter = diameter/n # dl = ls + x dend.x0 = ls dend.x = ls + x dend.length = x ls += x n += 1.0 if i == 0: moose.connect( soma, 'axial', dendList[i], 'raxial') else: moose.connect( dendList[i-1], 'axial', dendList[i], 'raxial') return elecid
def makeAxonProto(): axon = moose.Neuron('/library/axon') prev = rd.buildCompt(axon, 'soma', RM=RM, RA=RA, CM=CM, dia=10e-6, x=0, dx=comptLen) theta = 0 x = comptLen y = 0.0 for i in range(numAxonSegments): dx = comptLen * np.cos(theta) dy = comptLen * np.sin(theta) r = np.sqrt(x * x + y * y) theta += comptLen / r compt = rd.buildCompt(axon, 'axon' + str(i), RM=RM, RA=RA, CM=CM, x=x, y=y, dx=dx, dy=dy, dia=comptDia) moose.connect(prev, 'axial', compt, 'raxial') prev = compt x += dx y += dy return axon
def loadModel(filename): global soma_, cellSpikeTable_ neuromlR = NeuroML() neuromlR.readNeuroMLFromFile(filename) libcell = moose.Neuron('/library/CA1soma') CA1Cellid = moose.copy(libcell,moose.Neutral('/cells'),'CA1') CA1Cell = moose.Neuron(CA1Cellid) spikeGen = moose.SpikeGen(CA1Cell.path+'/spikeGen') spikeGen.threshold = -30e-3 # V soma_ = moose.Compartment(CA1Cell.path+'/Seg0_soma_0_0') soma_.inject = 0 # by default the cell has a current injection moose.connect(soma_,'VmOut',spikeGen,'Vm') table_path = moose.Neutral(CA1Cell.path+'/data').path cellSpikeTable_ = moose.Table(table_path+'/spikesTable') moose.connect(spikeGen,'spikeOut', cellSpikeTable_,'input')
def makeDendProto(): dend=moose.Neuron('/library/dend') #prev=rd.buildCompt(dend,'soma',RM=RM,RA=RA,CM=CM,dia=0.3e-06,x=0,dx=comptLenBuff) prev=rd.buildCompt(dend,'soma',RM=RM,RA=RA,CM=CM,dia=0.3e-06,x=0,dx=comptLen) #x=comptLenBuff x=comptLen y=0.0 comptDia=0.3e-06 for i in range(numDendSegments-1): dx=comptLen dy=0 #comptDia +=1.7e-08 compt=rd.buildCompt(dend,'dend'+str(i),RM=RM,RA=RA,CM=CM,x=x,y=y,dx=dx,dy=dy,dia=comptDia) moose.connect(prev,'axial',compt,'raxial') prev=compt x+=dx y+=dy print i for i in range(numDendSegments,numDendSegments+lenbfNotch): print i dx=comptLen dy=0 comptDia -=0.5e-07 print comptDia compt=rd.buildCompt(dend,'dend'+str(i),RM=RM,RA=RA,CM=CM,x=x,dx=dx,dy=dy,dia=comptDia) moose.connect(prev,'axial',compt,'raxial') prev=compt x+=dx y+=dy for i in range(numDendSegments+lenbfNotch,numDendSegments+lenbfNotch+lenafNotch): dx=comptLen dy=0 comptDia +=0.5e-07 print comptDia compt=rd.buildCompt(dend,'dend'+str(i),RM=RM,RA=RA,CM=CM,x=x,dx=dx,dy=dy,dia=comptDia) moose.connect(prev,'axial',compt,'raxial') prev=compt x+=dx y+=dy for i in range (numDendSegments+lenbfNotch+lenafNotch,numDendSegments+lenbfNotch+lenafNotch+numDendSegmentsSlope): dx=comptLen dy=0 #comptDia -=0.1e-07 print comptDia compt=rd.buildCompt(dend,'dend'+str(i),RM=RM,RA=RA,CM=CM,x=x,y=y,dx=dx,dy=dy,dia=comptDia) moose.connect(prev,'axial',compt,'raxial') prev=compt x+=dx y+=dy #compt=rd.buildCompt(dend,'dendL',RM=RM,RA=RA,CM=CM,x=x,y=y,dx=comptLenBuff,dy=dy,dia=comptDia) #moose.connect(prev,'axial',compt,'raxial') return dend
def create_LIF(): neuromlR = NeuroML() neuromlR.readNeuroMLFromFile('cells_channels/LIF.morph.xml') libcell = moose.Neuron('/library/LIF') LIFCellid = moose.copy(libcell,moose.Neutral('/cells'),'IF1') # FIXME: No LeakyIaF is found in MOOSE. LIFCell = moose.LeakyIaF(LIFCellid) return LIFCell
def createCellPrototype(self, cell, symmetric=False): """To be completed - create the morphology, channels in prototype""" nrn = moose.Neuron('%s/%s' % (self.lib.path, cell.id)) self.proto_cells[cell.id] = nrn self.nml_to_moose[cell] = nrn self.moose_to_nml[nrn] = cell self.createMorphology(cell, nrn, symmetric=symmetric) self.importBiophysics(cell, nrn) return cell, nrn
def __init__(self, path): if not moose.exists(path): path_tokens = path.rpartition('/') moose.copy(self.prototype, path_tokens[0], path_tokens[-1]) moose.Neuron( path ) moose.Neutral.__init__(self, path) self.solver = moose.HSolve('{}/solver'.format(path)) self.solver.target = path self.solver.dt = config.simulationSettings.simulationDt
def makeCellProto(name): elec = moose.Neuron('/library/' + name) ecompt = [] ec = rd.buildCompt(elec, 'dend', dx=dendLen, dia=2.0e-6, x=0, RM=RM, RA=RA, CM=CM) elec.buildSegmentTree()
def makeCellProto(name): elec = moose.Neuron('/library/' + name) ecompt = [] ###soma = rd.buildCompt( elec, 'soma', dx=somaDia, dia=somaDia, x=-somaDia, RM=RM, RA=RA, CM=CM ) dend = rd.buildCompt(elec, 'dend', dx=dendLen, dia=dendDia, x=0, RM=RM, RA=RA, CM=CM) ###moose.connect( soma, 'axial', dend, 'raxial' ) elec.buildSegmentTree()
def makePassiveHHsoma(name = 'passiveHHsoma', parent='/library'): ''' Make HH squid model sized compartment: len and dia 500 microns. CM = 0.01 F/m^2, RA = ''' elecpath = parent + '/' + name if not moose.exists( elecpath ): elecid = moose.Neuron( elecpath ) dia = 500e-6 soma = buildCompt( elecid, 'soma', dx = dia, dia = dia, x = 0.0, RM = 0.33333333, RA = 3000, CM = 0.01 ) soma.initVm = -65e-3 # Resting of -65, from HH soma.Em = -54.4e-3 # 10.6 mV above resting of -65, from HH else: elecid = moose.element( elecpath ) return elecid
def setUp(self): self.test_id = uuid.uuid4() self.model_container = moose.Neutral('test%s' % (self.test_id)) self.neuron = moose.Neuron('%s/cell' % (self.model_container.path)) self.soma = moose.Compartment('%s/soma' % (self.neuron.path)) self.soma.diameter = 20e-6 self.soma.length = 0.0 parent = self.soma comps = [] for ii in range(100): comp = moose.Compartment('%s/comp_%d' % (self.neuron.path, ii)) comp.diameter = 10e-6 comp.length = 100e-6 moose.connect(parent, 'raxial', comp, 'axial') comps.append(comp) parent = comp
def makeCellProto(name): print(('IN: makeCellProto( ', name, ')')) elec = moose.Neuron('/library/' + name) ecompt = [] for i in range(numDendSegments): ec = rd.buildCompt(elec, 'dend' + str(i), segLen, 2.0e-6, i * segLen, RM, RA, CM) ecompt.append(ec) if i > 0: moose.connect(ecompt[i - 1], 'axial', ec, 'raxial') else: ec.name = "soma" for i in ecompt: i.z0 = i.x0 i.x0 = 0 i.z = i.x i.x = 0
def makeDendProto(): dend = moose.Neuron('/library/dend') prev = rd.buildCompt(dend, 'soma', RM=RM, RA=RA, CM=CM, dia=10e-06, x=0, dx=comptLenBuff) x = comptLenBuff y = 0.0 comptDia = 10e-06 for i in range(numDendSegments): dx = comptLen dy = 0 #comptDia +=1.7e-08 compt = rd.buildCompt(dend, 'dend' + str(i), RM=RM, RA=RA, CM=CM, x=x, y=y, dx=dx, dy=dy, dia=comptDia) moose.connect(prev, 'axial', compt, 'raxial') prev = compt x += dx y += dy compt = rd.buildCompt(dend, 'dendL', RM=RM, RA=RA, CM=CM, x=x, y=y, dx=comptLenBuff, dy=dy, dia=comptDia) moose.connect(prev, 'axial', compt, 'raxial') return dend
def readMorphML(self, cell, params={}, lengthUnits="micrometer"): """ returns {cellName:segDict} 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! """ debug.printDebug("DEBUG", "Entered function readMorphML") if lengthUnits in ['micrometer', 'micron']: self.length_factor = 1e-6 else: self.length_factor = 1.0 cellName = cell.attrib["name"] if cellName == 'LIF': self.mooseCell = moose.LeakyIaF(self.cellPath + '/' + cellName) self.segDict = {} else: # using moose Neuron class - in previous version 'Cell' class # Chaitanya. self.mooseCell = moose.Neuron(self.cellPath + '/' + cellName) self.cellDictBySegmentId[cellName] = [self.mooseCell, {}] self.cellDictByCableId[cellName] = [self.mooseCell, {}] self.segDict = {} # load morphology and connections between compartments Many neurons # exported from NEURON have multiple segments in a section Combine # those segments into one Compartment / section 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: self.running_cableid = '' running_segid = '' segments = cell.findall(".//{" + self.mml + "}segment") segmentstotal = len(segments) for segnum, segment in enumerate(segments): self.addSegment(cellName, segnum, segment) # load cablegroups into a dictionary self.cablegroupsDict = {} # 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] = [] for cable in cablegroup.findall(".//{" + self.mml + "}cable"): cableid = cable.attrib['id'] self.cablegroupsDict[cablegroupname].append(cableid) # <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 list(self.cablegroupsDict.keys()): self.cablegroupsDict[cablegroupname].append(cableid) else: self.cablegroupsDict[cablegroupname] = [cableid] # Add bioPhysics to the cell self.addBiophysics(cell, cellName) # load connectivity / synapses into the compartments connectivity = cell.find(".//{" + self.neuroml + "}connectivity") if connectivity is not None: self.addConnectivity(cell, cellName, connectivity) return {cellName: self.segDict}
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 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 makePassiveSoma(name, length, diameter): # segmentLength = 1e-6 # segmentDia = 1e-6 # shaftLength = 1e-6 # shaftDia = 0.2e-6 # headLength = 0.5e-6 # headDia = 0.5e-6 # cell = moose.Neutral( '/library/' + name ) # model = moose.element( '/library' ) # prev = makeCompt( '/library/cell/soma', # model, 0.0, segmentLength, segmentDia ) # dend = prev # for i in range( 0, numSeg ): # nameDend = '/library/cell/dend' + str( i ) # dend = makeCompt( nameDend, dend, 0.0, segmentLength, segmentDia ) # # name = '/model/cell/shaft' + str( i ) # # shaft = makeCompt( name, dend, shaftLength, 0.0, shaftDia ) # # name = '/model/cell/head' + str( i ) # # head = makeCompt( name, shaft, headLength, 0.0, headDia ) # return cell elecid = moose.Neuron('/library/' + name) # soma = moose.Compartment(elecid.path + '/soma') '''This will not work: since we cannot connect messages wherein source and destination are the same. Error: SharedFinfo::addMsg: MessageId 5[13] Source Element == DestElement == dend Recommend that you individually set up messages for the components of the SharedFinfo, to ensure that the direction of messaging is consistent. 0: Error: Shell::handleAddMsg: Unable to make/connect Msg: Single from dend to dend ''' prev = moose.Compartment(elecid.path + '/soma') parent = elecid # segmentLength = 1e-6 # segmentDia = 1e-6 segmentDia = diameter segmentLength = length shaftLength = 1e-6 shaftDia = 0.2e-6 headLength = 0.5e-6 headDia = 0.5e-6 dx = 0.0 dy = segmentLength dia = segmentDia RM = 1.0 RA = 1.0 CM = 0.01 EM = -0.065 pax = 0 pay = 0 if (parent.className == "Compartment"): pax = parent.x pay = parent.y prev = moose.Compartment(name) prev.x0 = pax prev.y0 = pay prev.z0 = 0 prev.x = pax + dx prev.y = pay + dy prev.z = 0 prev.diameter = dia clen = numpy.sqrt(dx * dx + dy * dy) prev.length = clen prev.Rm = RM / (numpy.pi * dia * clen) prev.Ra = RA * 4.0 * numpy.pi * clen / (dia * dia) prev.Cm = CM * numpy.pi * dia * clen # dia = segmentDia parent = prev for i in range(4): dx = 0.0 dy = segmentLength dia = dia - 1.0 name = '/library/cell/dend' + str(i) # dend = makeCompt( name, dend, 0.0, segmentLength, segmentDia ) RM = 1.0 RA = 1.0 CM = 0.01 EM = -0.065 pax = 0 pay = 0 if (parent.className == "Compartment"): pax = parent.x pay = parent.y compt = moose.Compartment(name) compt.x0 = pax compt.y0 = pay compt.z0 = 0 compt.x = pax + dx compt.y = pay + dy compt.z = 0 compt.diameter = dia clen = numpy.sqrt(dx * dx + dy * dy) compt.length = clen # compt.Rm = RM / (numpy.pi * dia * clen) # compt.Ra = RA * 4.0 * numpy.pi * clen / ( dia * dia ) # compt.Cm = CM * numpy.pi * dia * clen if (parent.className == "Compartment"): moose.connect(parent, 'raxial', compt, 'axial') parent = compt # dend_vec = moose.vec( elecid.path + '/soma', n=4, dtype='Compartment' ) # dend.diameter = diameter # dend.length = length # dend.x0 = 0 # dend.x = length # dend.Em = -65e-3 # Leak potential # dend.initVm = -65e-3 # Initial membrane potential # dend.Rm = 5e9 # Total membrane resistance of the compartment # dend.Cm = 1e-12 # Total membrane capacitance of the compartment # dend.Ra = 1e6 # ls = 0.0 # n = 1.0 # for ind,dend in enumerate(dend_vec): # dend.diameter = diameter/n # # dl = ls+length/2 # dend.x0 = ls # dend.x = ls + length/2 # # dend.y0 = ls # # dend.y = dl # dend.length = length/2 # # dend.length = np.sqrt( 2*(dl**2)) # ls = ls + length/2 # # n = n + 1.0 # n = n * 2 # print("dend path: ", dend.path) # print("dend diameter: ", dend.diameter) # print("dend start: ", dend.x0) # print("dend end: ", dend.x) # if ind!=0: # moose.connect(dend_vec[ind-1], 'raxial', dend_vec[ind], 'axial') # moose.connect(dend, 'raxial', dend1, 'axial') # moose.connect(dend_vec[0], 'raxial', dend_vec[1], 'axial') # moose.connect(dend_vec[1], 'raxial', dend_vec[2], 'axial') # moose.connect(dend_vec[2], 'raxial', dend_vec[3], 'axial') # moose.connect(dend_vec, 'raxial', '') # dendComp = moose.Compartment( elecid.path + '/soma') # dend1 = moose.Compartment( elecid.path + '/dend[1]' ) # dend2 = moose.Compartment( elecid.path + '/dend[2]' ) # dend3 = moose.Compartment( elecid.path + '/dend[3]' ) # dend4 = moose.Compartment( elecid.path + '/dend[4]' ) # ls = length # n = 1.0 # dendList = [dend1, dend2, dend3, dend4] # for ind,dend in enumerate(dendList): # dend.diameter = diameter/n # dl = ls+length/4 # dend.x0 = 0 # dend.x = dl # dend.y0 = ls # dend.y = dl # dend.length = np.sqrt( 2*(dl**2)) # ls = ls + length/4 # n = n + 1.0 # print("dend path: ", dend.path) # print("dend diameter: ", dend.diameter) # print("dend start: ", dend.x0) # print("dend end: ", dend.x) # # print("dend raxial: ", dend.raxial) # moose.connect(dendComp, 'raxial', dend1, 'axial') # moose.connect(dend1, 'raxial', dend2, 'axial') # moose.connect(dend2, 'raxial', dend3, 'axial') # moose.connect(dend3, 'raxial', dend4, 'axial') return elecid
import moose from moose.utils import * from moose.neuroml.NeuroML import NeuroML from pylab import * SIMDT = 25e-6 # s PLOTDT = 25e-6 # s RUNTIME = 2.0 # s injectmax = 20e-12 # Amperes neuromlR = NeuroML() neuromlR.readNeuroMLFromFile('cells_channels/Granule_98.morph.xml') libcell = moose.Neuron('/library/Granule_98') granCellid = moose.copy(libcell, moose.Neutral('/cells'), 'granCell') granCell = moose.Neuron(granCellid) ## edge-detect the spikes using spike-gen (table does not have edge detect) spikeGen = moose.SpikeGen(granCell.path + '/spikeGen') spikeGen.threshold = 0e-3 # V granCellSoma = moose.Compartment(granCell.path + '/Soma_0') moose.connect(granCellSoma, 'VmOut', spikeGen, 'Vm') ## save spikes in table table_path = moose.Neutral(granCell.path + '/data').path granCellSpikesTable = moose.Table(table_path + '/spikesTable') moose.connect(spikeGen, 'spikeOut', granCellSpikesTable, 'input') ## from moose_utils.py sets clocks and resets/reinits resetSim(['/cells'], SIMDT, PLOTDT, simmethod='hsolve')
import moose from moose.utils import * from moose.neuroml.NeuroML import NeuroML from pylab import * SIMDT = 25e-6 # s PLOTDT = 25e-6 # s RUNTIME = 1.0 # s injectmax = 2e-12 # Amperes neuromlR = NeuroML() neuromlR.readNeuroMLFromFile('cells_channels/CA1soma.morph.xml') libcell = moose.Neuron('/library/CA1soma') CA1Cellid = moose.copy(libcell,moose.Neutral('/cells'),'CA1') CA1Cell = moose.Neuron(CA1Cellid) #printCellTree(CA1Cell) ## edge-detect the spikes using spike-gen (table does not have edge detect) spikeGen = moose.SpikeGen(CA1Cell.path+'/spikeGen') spikeGen.threshold = -30e-3 # V CA1CellSoma = moose.Compartment(CA1Cell.path+'/Seg0_soma_0_0') CA1CellSoma.inject = 0 # by default the cell has a current injection moose.connect(CA1CellSoma,'VmOut',spikeGen,'Vm') ## save spikes in table table_path = moose.Neutral(CA1Cell.path+'/data').path CA1CellSpikesTable = moose.Table(table_path+'/spikesTable') moose.connect(spikeGen,'spikeOut',CA1CellSpikesTable,'input')