def setUp(self): '''Initialize storehouse ''' self.compartments = _moose.wildcardFind('/##[TYPE=Compartment]') self.tables = _moose.wildcardFind('/##[TYPE=Table]') self.pulse_gens = _moose.wildcardFind('/##[TYPE=PulseGen]') self.clocks = _moose.wildcardFind('/##[TYPE=Clock]') self.nonZeroClockIds = None
def assignDefaultTicks(modelRoot='/model', dataRoot='/data', solver='hsolve'): if isinstance(modelRoot, _moose.melement) or isinstance( modelRoot, _moose.vec): modelRoot = modelRoot.path if isinstance(dataRoot, _moose.melement) or isinstance( dataRoot, _moose.vec): dataRoot = dataRoot.path if solver != 'hsolve' or len( _moose.wildcardFind('%s/##[ISA=HSolve]' % (modelRoot))) == 0: _moose.useClock(0, '%s/##[ISA=Compartment]' % (modelRoot), 'init') _moose.useClock(1, '%s/##[ISA=Compartment]' % (modelRoot), 'process') _moose.useClock(2, '%s/##[ISA=HHChannel]' % (modelRoot), 'process') # _moose.useClock(2, '%s/##[ISA=ChanBase]' % (modelRoot), 'process') _moose.useClock(0, '%s/##[ISA=IzhikevichNrn]' % (modelRoot), 'process') _moose.useClock(0, '%s/##[ISA=GapJunction]' % (modelRoot), 'process') _moose.useClock(0, '%s/##[ISA=HSolve]' % (modelRoot), 'process') _moose.useClock(1, '%s/##[ISA=LeakyIaF]' % (modelRoot), 'process') _moose.useClock(1, '%s/##[ISA=IntFire]' % (modelRoot), 'process') _moose.useClock(1, '%s/##[ISA=SpikeGen]' % (modelRoot), 'process') _moose.useClock(1, '%s/##[ISA=PulseGen]' % (modelRoot), 'process') _moose.useClock(1, '%s/##[ISA=StimulusTable]' % (modelRoot), 'process') _moose.useClock(1, '%s/##[ISA=TimeTable]' % (modelRoot), 'process') _moose.useClock(2, '%s/##[ISA=HHChannel2D]' % (modelRoot), 'process') _moose.useClock(2, '%s/##[ISA=SynChan]' % (modelRoot), 'process') _moose.useClock(2, '%s/##[ISA=MgBlock]' % (modelRoot), 'process') _moose.useClock(3, '%s/##[ISA=CaConc]' % (modelRoot), 'process') _moose.useClock(3, '%s/##[ISA=Func]' % (modelRoot), 'process') # The voltage clamp circuit depends critically on the dt used for # computing soma Vm and need to be on a clock with dt=elecdt. _moose.useClock(0, '%s/##[ISA=DiffAmp]' % (modelRoot), 'process') _moose.useClock(0, '%s/##[ISA=VClamp]' % (modelRoot), 'process') _moose.useClock(0, '%s/##[ISA=PIDController]' % (modelRoot), 'process') _moose.useClock(0, '%s/##[ISA=RC]' % (modelRoot), 'process') # Special case for kinetics models kinetics = _moose.wildcardFind('%s/##[FIELD(name)=kinetics]' % modelRoot) if len(kinetics) > 0: # Do nothing for kinetics models - until multiple scheduling issue is fixed. _moose.useClock(4, '%s/##[ISA!=PoolBase]' % (kinetics[0].path), 'process') _moose.useClock(5, '%s/##[ISA==PoolBase]' % (kinetics[0].path), 'process') _moose.useClock(18, '%s/##[ISA=Table2]' % (dataRoot), 'process') else: # input() function is called in Table. process() which gets # called at each timestep. When a message is connected # explicitly to input() dest field, it is driven by the sender # and process() adds garbage value to the vector. Hence not to # be scheduled. for tab in _moose.wildcardFind('%s/##[ISA=Table]' % (dataRoot)): if len(tab.neighbors['input']) == 0: _moose.useClock(9, tab.path, 'process')
def assignDefaultTicks(modelRoot='/model', dataRoot='/data', solver='hsolve'): print 'assignDefaultTicks' if isinstance(modelRoot, _moose.melement) or isinstance(modelRoot, _moose.vec): modelRoot = modelRoot.path if isinstance(dataRoot, _moose.melement) or isinstance(dataRoot, _moose.vec): dataRoot = dataRoot.path if solver != 'hsolve' or len(_moose.wildcardFind('%s/##[ISA=HSolve]' % (modelRoot))) == 0: _moose.useClock(0, '%s/##[ISA=Compartment]' % (modelRoot), 'init') _moose.useClock(1, '%s/##[ISA=Compartment]' % (modelRoot), 'process') _moose.useClock(2, '%s/##[ISA=HHChannel]' % (modelRoot), 'process') # _moose.useClock(2, '%s/##[ISA=ChanBase]' % (modelRoot), 'process') _moose.useClock(0, '%s/##[ISA=IzhikevichNrn]' % (modelRoot), 'process') _moose.useClock(0, '%s/##[ISA=GapJunction]' % (modelRoot), 'process') _moose.useClock(0, '%s/##[ISA=HSolve]' % (modelRoot), 'process') _moose.useClock(1, '%s/##[ISA=LeakyIaF]' % (modelRoot), 'process') _moose.useClock(1, '%s/##[ISA=IntFire]' % (modelRoot), 'process') _moose.useClock(1, '%s/##[ISA=SpikeGen]' % (modelRoot), 'process') _moose.useClock(1, '%s/##[ISA=PulseGen]' % (modelRoot), 'process') _moose.useClock(1, '%s/##[ISA=StimulusTable]' % (modelRoot), 'process') _moose.useClock(1, '%s/##[ISA=TimeTable]' % (modelRoot), 'process') _moose.useClock(2, '%s/##[ISA=HHChannel2D]' % (modelRoot), 'process') _moose.useClock(2, '%s/##[ISA=SynChan]' % (modelRoot), 'process') _moose.useClock(2, '%s/##[ISA=MgBlock]' % (modelRoot), 'process') _moose.useClock(3, '%s/##[ISA=CaConc]' % (modelRoot), 'process') _moose.useClock(3, '%s/##[ISA=Func]' % (modelRoot), 'process') # The voltage clamp circuit depends critically on the dt used for # computing soma Vm and need to be on a clock with dt=elecdt. _moose.useClock(0, '%s/##[ISA=DiffAmp]' % (modelRoot), 'process') _moose.useClock(0, '%s/##[ISA=VClamp]' % (modelRoot), 'process') _moose.useClock(0, '%s/##[ISA=PIDController]' % (modelRoot), 'process') _moose.useClock(0, '%s/##[ISA=RC]' % (modelRoot), 'process') # Special case for kinetics models kinetics = _moose.wildcardFind('%s/##[FIELD(name)=kinetics]' % modelRoot) if len(kinetics) > 0: # Do nothing for kinetics models - until multiple scheduling issue is fixed. pass # _moose.useClock(4, '%s/##[ISA!=PoolBase]' % (kinetics[0].path), 'process') # _moose.useClock(5, '%s/##[ISA==PoolBase]' % (kinetics[0].path), 'process') # _moose.useClock(8, '%s/##[ISA=Table]' % (dataRoot), 'process') else: # input() function is called in Table. process() which gets # called at each timestep. When a message is connected # explicitly to input() dest field, it is driven by the sender # and process() adds garbage value to the vector. Hence not to # be scheduled. for tab in _moose.wildcardFind('%s/##[ISA=Table]' % (dataRoot)): if len(tab.neighbors['input']) == 0: _moose.useClock(9, tab.path, 'process')
def getMoosePaths(pat, isRoot=True): ''' Return a list of paths for a given pattern. ''' if type(pat) != str: pat = pat.path assert type(pat) == str moose_paths = [x.path for x in _moose.wildcardFind(pat)] return moose_paths
def findAllBut(moose_wildcard, stringToExclude): allValidObjects = _moose.wildcardFind(moose_wildcard) refinedList = [] for validObject in allValidObjects: if validObject.path.find(stringToExclude) == -1: refinedList.append(validObject) return refinedList
def resetSim(simpaths, simdt, plotdt, simmethod='hsolve'): """ For each of the MOOSE paths in simpaths, this sets the clocks and finally resets MOOSE. If simmethod=='hsolve', it sets up hsolve-s for each Neuron under simpaths, and clocks for hsolve-s too. """ print 'Solver:', simmethod _moose.setClock(INITCLOCK, simdt) _moose.setClock(ELECCLOCK, simdt) # The hsolve and ee methods use clock 1 _moose.setClock(CHANCLOCK, simdt) # hsolve uses clock 2 for mg_block, nmdachan and others. _moose.setClock(POOLCLOCK, simdt) # Ca/ion pools & funcs use clock 3 _moose.setClock(STIMCLOCK, simdt) # Ca/ion pools & funcs use clock 3 _moose.setClock(PLOTCLOCK, plotdt) # for tables for simpath in simpaths: ## User can connect [qty]Out of an element to input of Table or ## requestOut of Table to get[qty] of the element. ## Scheduling the Table to a clock tick, will call process() of the Table ## which will send a requestOut and overwrite any value set by input(), ## thus adding garbage value to the vector. Hence schedule only if ## input message is not connected to the Table. for table in _moose.wildcardFind(simpath+'/##[TYPE=Table]'): if len(table.neighbors['input']) == 0: _moose.useClock(PLOTCLOCK, table.path, 'process') _moose.useClock(ELECCLOCK, simpath+'/##[TYPE=PulseGen]', 'process') _moose.useClock(STIMCLOCK, simpath+'/##[TYPE=DiffAmp]', 'process') _moose.useClock(STIMCLOCK, simpath+'/##[TYPE=VClamp]', 'process') _moose.useClock(STIMCLOCK, simpath+'/##[TYPE=PIDController]', 'process') _moose.useClock(STIMCLOCK, simpath+'/##[TYPE=RC]', 'process') _moose.useClock(STIMCLOCK, simpath+'/##[TYPE=TimeTable]', 'process') _moose.useClock(ELECCLOCK, simpath+'/##[TYPE=LeakyIaF]', 'process') _moose.useClock(ELECCLOCK, simpath+'/##[TYPE=IntFire]', 'process') _moose.useClock(ELECCLOCK, simpath+'/##[TYPE=IzhikevichNrn]', 'process') _moose.useClock(ELECCLOCK, simpath+'/##[TYPE=SpikeGen]', 'process') _moose.useClock(ELECCLOCK, simpath+'/##[TYPE=Interpol]', 'process') _moose.useClock(ELECCLOCK, simpath+'/##[TYPE=Interpol2D]', 'process') _moose.useClock(CHANCLOCK, simpath+'/##[TYPE=HHChannel2D]', 'process') _moose.useClock(CHANCLOCK, simpath+'/##[TYPE=SynChan]', 'process') ## If simmethod is not hsolve, set clocks for the biophysics, ## else just put a clock on the hsolve: ## hsolve takes care of the clocks for the biophysics if 'hsolve' not in simmethod.lower(): print 'Using exp euler' _moose.useClock(INITCLOCK, simpath+'/##[TYPE=Compartment]', 'init') _moose.useClock(ELECCLOCK, simpath+'/##[TYPE=Compartment]', 'process') _moose.useClock(CHANCLOCK, simpath+'/##[TYPE=HHChannel]', 'process') _moose.useClock(POOLCLOCK, simpath+'/##[TYPE=CaConc]', 'process') _moose.useClock(POOLCLOCK, simpath+'/##[TYPE=Func]', 'process') else: # use hsolve, one hsolve for each Neuron print 'Using hsolve' element = _moose.Neutral(simpath) for childid in element.children: childobj = _moose.Neutral(childid) classname = childobj.className if classname in ['Neuron']: neuronpath = childobj.path h = _moose.HSolve( neuronpath+'/solve' ) h.dt = simdt h.target = neuronpath _moose.useClock(INITCLOCK, h.path, 'process') _moose.reinit()
def __init__(self, *args): super(Backend, self).__init__() self.args = args self.compartments = [] self.pulseGens = [] self.tables = [] # A set of tuple of sourceCompartment.path and targetCompartment.path self.connections = set() self.clock = _moose.wildcardFind('/clock')[0]
def modelInfo(path = '/##', **kwargs): """Generate the list of all available moose-elements in model """ info("Couting elements in model under %s" % path) msg = [] types = [ "Table", "Table2", "Compartment", "Pool", "BufPool", "Enz", "Reac" ] for t in types: paths = moose.wildcardFind("{}[TYPE={}]".format(path, t)) if len(paths) > 0: msg.append("{:>20} : {}".format(t, len(paths))) return "\n".join(msg)
def writeGraphviz(filename=None, pat='/##[TYPE=Compartment]'): '''This is a generic function. It takes the the pattern, search for paths and write a graphviz file. ''' def fix(path): '''Fix a given path so it can be written to a graphviz file''' # If no [0] is at end of the path then append it. global pathPat if not pathPat.match(path): path = path + '[0]' return path pathList = getMoosePaths(pat) compList = _moose.wildcardFind(pat) if not compList: debug.dump("WARN" , "No compartment found" , frame = inspect.currentframe() ) return None dot = [] dot.append("digraph G {") dot.append("\tconcentrate=true;") for c in compList: if c.neighbors['raxial']: for n in c.neighbors['raxial']: lhs = fix(c.path) rhs = fix(n.path) dot.append('\t"{}" -> "{}";'.format(lhs, rhs)) elif c.neighbors['axial']: for n in c.neighbors['axial']: lhs = fix(c.path) rhs = fix(n.path) dot.append('\t"{}" -> "{}" [dir=back];'.format(lhs, rhs)) else: p = fix(c.path) dot.append('\t"{}"'.format(p)) dot.append('}') dot = '\n'.join(dot) if not filename: print(dot) else: with open(filename, 'w') as graphviz: debug.dump("INFO" , "Writing compartment topology to file {}".format(filename) ) graphviz.write(dot) return True
def writeGraphviz(filename=None, pat='/##[TYPE=Compartment]'): '''This is a generic function. It takes the the pattern, search for paths and write a graphviz file. ''' def fix(path): '''Fix a given path so it can be written to a graphviz file''' # If no [0] is at end of the path then append it. global pathPat if not pathPat.match(path): path = path + '[0]' return path pathList = getMoosePaths(pat) compList = _moose.wildcardFind(pat) if not compList: debug.dump("WARN" , "No compartment found" , frame = inspect.currentframe() ) dot = [] dot.append("digraph G {") dot.append("\tconcentrate=true;") for c in compList: if c.neighbors['raxial']: for n in c.neighbors['raxial']: lhs = fix(c.path) rhs = fix(n.path) dot.append('\t"{}" -> "{}";'.format(lhs, rhs)) elif c.neighbors['axial']: for n in c.neighbors['axial']: lhs = fix(c.path) rhs = fix(n.path) dot.append('\t"{}" -> "{}" [dir=back];'.format(lhs, rhs)) else: p = fix(c.path) dot.append('\t"{}"'.format(p)) dot.append('}') dot = '\n'.join(dot) if not filename: print(dot) else: with open(filename, 'w') as graphviz: debug.dump("INFO" , "Writing compartment topology to file {}".format(filename) ) graphviz.write(dot) return True
def autoposition(root): """Automatically set the positions of the endpoints of all the compartments under `root`. This keeps x and y constant and extends the positions in z-direction only. This of course puts everything in a single line but suffices for keeping electrical properties intact. TODO: in future we may want to create the positions for nice visual layout as well. My last attempt resulted in some compartments overlapping in space. """ compartments = _moose.wildcardFind('%s/##[TYPE=Compartment]' % (root.path)) stack = [ compartment for compartment in map(_moose.element, compartments) if len(compartment.neighbors['axial']) == 0 ] if len(stack) != 1: raise Exception( 'There must be one and only one top level compartment. Found %d' % (len(topcomp_list))) ret = stack[0] while len(stack) > 0: comp = stack.pop() parentlist = comp.neighbors['axial'] parent = None if len(parentlist) > 0: parent = parentlist[0] comp.x0, comp.y0, comp.z0, = parent.x, parent.y, parent.z else: comp.x0, comp.y0, comp.z0, = (0, 0, 0) if comp.length > 0: comp.x, comp.y, comp.z, = comp.x0, comp.y0, comp.z0 + comp.length else: # for spherical compartments x0, y0, z0 are centre # position nad x,y,z are on the surface comp.x, comp.y, comp.z, = comp.x0, comp.y0, comp.z0 + comp.diameter / 2.0 # We take z == 0 as an indicator that this compartment has not # been processed before - saves against inadvertent loops. stack.extend([ childcomp for childcomp in map(_moose.element, comp.neighbors['raxial']) if childcomp.z == 0 ]) return ret
def assignDefaultTicks(modelRoot="/model", dataRoot="/data"): _moose.useClock(0, "%s/##[ISA=Compartment]" % (modelRoot), "init") _moose.useClock(1, "%s/##[ISA=LeakyIaF]" % (modelRoot), "process") _moose.useClock(1, "%s/##[ISA=IntFire]" % (modelRoot), "process") _moose.useClock(1, "%s/##[ISA=Compartment]" % (modelRoot), "process") _moose.useClock(1, "%s/##[ISA=PulseGen]" % (modelRoot), "process") _moose.useClock(2, "%s/##[ISA=ChanBase]" % (modelRoot), "process") _moose.useClock(2, "%s/##[ISA=MgBlock]" % (modelRoot), "process") _moose.useClock(3, "%s/##[ISA=CaConc]" % (modelRoot), "process") _moose.useClock(7, "%s/##[ISA=DiffAmp]" % (modelRoot), "process") _moose.useClock(7, "%s/##[ISA=VClamp]" % (modelRoot), "process") _moose.useClock(7, "%s/##[ISA=PIDController]" % (modelRoot), "process") _moose.useClock(7, "%s/##[ISA=RC]" % (modelRoot), "process") # Special case for kinetics models kinetics = _moose.wildcardFind("%s/##[FIELD(name)=kinetics]" % modelRoot) if len(kinetics) > 0: _moose.useClock(4, "%s/##[ISA!=PoolBase]" % (kinetics[0].path), "process") _moose.useClock(5, "%s/##[ISA==PoolBase]" % (kinetics[0].path), "process") _moose.useClock(8, "%s/##[ISA=Table]" % (dataRoot), "process") else: _moose.useClock(9, "%s/##[ISA=Table]" % (dataRoot), "process")
def autoposition(root): """Automatically set the positions of the endpoints of all the compartments under `root`. This keeps x and y constant and extends the positions in z-direction only. This of course puts everything in a single line but suffices for keeping electrical properties intact. TODO: in future we may want to create the positions for nice visual layout as well. My last attempt resulted in some compartments overlapping in space. """ compartments = _moose.wildcardFind("%s/##[TYPE=Compartment]" % (root.path)) stack = [ compartment for compartment in map(_moose.element, compartments) if len(compartment.neighbours["axial"]) == 0 ] if len(stack) != 1: raise Exception("There must be one and only one top level compartment. Found %d" % (len(topcomp_list))) ret = stack[0] while len(stack) > 0: comp = stack.pop() parentlist = comp.neighbours["axial"] parent = None if len(parentlist) > 0: parent = parentlist[0] comp.x0, comp.y0, comp.z0, = parent.x, parent.y, parent.z else: comp.x0, comp.y0, comp.z0, = (0, 0, 0) if comp.length > 0: comp.x, comp.y, comp.z, = comp.x0, comp.y0, comp.z0 + comp.length else: # for spherical compartments x0, y0, z0 are centre # position nad x,y,z are on the surface comp.x, comp.y, comp.z, = comp.x0, comp.y0, comp.z0 + comp.diameter / 2.0 # We take z == 0 as an indicator that this compartment has not # been processed before - saves against inadvertent loops. stack.extend([childcomp for childcomp in map(_moose.element, comp.neighbours["raxial"]) if childcomp.z == 0]) return ret
def getComparments(self, **kwargs): '''Get all compartments in moose ''' comps = _moose.wildcardFind('/##[TYPE=Compartment]') self.compartments = comps
def getPulseGens(self, **kwargs): """ Get all the pulse generators """ self.pulseGens = _moose.wildcardFind('/##[TYPE=PulseGen]')
def getTables(self, **kwargs): """ Get all table we are recording from""" self.tables = _moose.wildcardFind('/##[TYPE=Table]')
def resetSim(simpaths, simdt, plotdt, simmethod='hsolve'): """ For each of the MOOSE paths in simpaths, this sets the clocks and finally resets MOOSE. If simmethod=='hsolve', it sets up hsolve-s for each Neuron under simpaths, and clocks for hsolve-s too. """ print 'Solver:', simmethod _moose.setClock(INITCLOCK, simdt) _moose.setClock(ELECCLOCK, simdt) # The hsolve and ee methods use clock 1 _moose.setClock( CHANCLOCK, simdt) # hsolve uses clock 2 for mg_block, nmdachan and others. _moose.setClock(POOLCLOCK, simdt) # Ca/ion pools & funcs use clock 3 _moose.setClock(STIMCLOCK, simdt) # Ca/ion pools & funcs use clock 3 _moose.setClock(PLOTCLOCK, plotdt) # for tables for simpath in simpaths: ## User can connect [qty]Out of an element to input of Table or ## requestOut of Table to get[qty] of the element. ## Scheduling the Table to a clock tick, will call process() of the Table ## which will send a requestOut and overwrite any value set by input(), ## thus adding garbage value to the vector. Hence schedule only if ## input message is not connected to the Table. for table in _moose.wildcardFind(simpath + '/##[TYPE=Table]'): if len(table.neighbors['input']) == 0: _moose.useClock(PLOTCLOCK, table.path, 'process') _moose.useClock(ELECCLOCK, simpath + '/##[TYPE=PulseGen]', 'process') _moose.useClock(STIMCLOCK, simpath + '/##[TYPE=DiffAmp]', 'process') _moose.useClock(STIMCLOCK, simpath + '/##[TYPE=VClamp]', 'process') _moose.useClock(STIMCLOCK, simpath + '/##[TYPE=PIDController]', 'process') _moose.useClock(STIMCLOCK, simpath + '/##[TYPE=RC]', 'process') _moose.useClock(STIMCLOCK, simpath + '/##[TYPE=TimeTable]', 'process') _moose.useClock(ELECCLOCK, simpath + '/##[TYPE=LeakyIaF]', 'process') _moose.useClock(ELECCLOCK, simpath + '/##[TYPE=IntFire]', 'process') _moose.useClock(ELECCLOCK, simpath + '/##[TYPE=IzhikevichNrn]', 'process') _moose.useClock(ELECCLOCK, simpath + '/##[TYPE=SpikeGen]', 'process') _moose.useClock(ELECCLOCK, simpath + '/##[TYPE=Interpol]', 'process') _moose.useClock(ELECCLOCK, simpath + '/##[TYPE=Interpol2D]', 'process') _moose.useClock(CHANCLOCK, simpath + '/##[TYPE=HHChannel2D]', 'process') _moose.useClock(CHANCLOCK, simpath + '/##[TYPE=SynChan]', 'process') ## If simmethod is not hsolve, set clocks for the biophysics, ## else just put a clock on the hsolve: ## hsolve takes care of the clocks for the biophysics if 'hsolve' not in simmethod.lower(): print 'Using exp euler' _moose.useClock(INITCLOCK, simpath + '/##[TYPE=Compartment]', 'init') _moose.useClock(ELECCLOCK, simpath + '/##[TYPE=Compartment]', 'process') _moose.useClock(CHANCLOCK, simpath + '/##[TYPE=HHChannel]', 'process') _moose.useClock(POOLCLOCK, simpath + '/##[TYPE=CaConc]', 'process') _moose.useClock(POOLCLOCK, simpath + '/##[TYPE=Func]', 'process') else: # use hsolve, one hsolve for each Neuron print 'Using hsolve' element = _moose.Neutral(simpath) for childid in element.children: childobj = _moose.Neutral(childid) classname = childobj.className if classname in ['Neuron']: neuronpath = childobj.path h = _moose.HSolve(neuronpath + '/solve') h.dt = simdt h.target = neuronpath _moose.useClock(INITCLOCK, h.path, 'process') _moose.reinit()