def setup_electronics(model_container, data_container, compartment): """Setup voltage and current clamp circuit using DiffAmp and PID and RC filter""" command = moose.PulseGen('%s/command' % (model_container.path)) command.delay[0] = 20e-3 command.width[0] = 50e-3 command.level[0] = 100e-9 command.delay[1] = 1e9 lowpass = moose.RC('%s/lowpass' % (model_container.path)) lowpass.R = 1.0 lowpass.C = 5e-4 vclamp = moose.DiffAmp('%s/vclamp' % (model_container.path)) vclamp.saturation = 1e10 iclamp = moose.DiffAmp('%s/iclamp' % (model_container.path)) iclamp.gain = 0.0 iclamp.saturation = 1e10 pid = moose.PIDController('%s/pid' % (model_container.path)) pid.gain = compartment.Cm / 100e-6 # Cm/dt is a good number for gain pid.tauI = 100e-6 # same as dt pid.tauD = 0.0 pid.saturation = 1e10 # Current clamp circuit: connect command output to iclamp amplifier # and the output of the amplifier to compartment. moose.connect(command, 'output', iclamp, 'plusIn') moose.connect(iclamp, 'output', compartment, 'injectMsg') # Setup voltage clamp circuit: # 1. Connect command output (which is now command) to lowpass # filter. # 2. Connect lowpass output to vclamp amplifier. # 3. Connect amplifier output to PID's command input. # 4. Connect Vm of compartment to PID's sensed input. # 5. Connect PID output to compartment's injectMsg. moose.connect(command, 'output', lowpass, 'injectIn') moose.connect(lowpass, 'output', vclamp, 'plusIn') moose.connect(vclamp, 'output', pid, 'commandIn') moose.connect(compartment, 'VmOut', pid, 'sensedIn') moose.connect(pid, 'output', compartment, 'injectMsg') command_table = moose.Table('%s/command' % (data_container.path)) moose.connect(command_table, 'requestOut', command, 'getOutputValue') inject_table = moose.Table('%s/inject' % (data_container.path)) moose.connect(inject_table, 'requestOut', compartment, 'getIm') return { 'command_tab': command_table, 'inject_tab': inject_table, 'iclamp': iclamp, 'vclamp': vclamp, 'pid': pid, 'command': command }
def Vclam(delay, width, delay_2, r, c, gain, sat, gain_p, tau_1, tau_2, psat): pulseg = moose.PulseGen('pulse') pulseg.firstDelay = delay pulseg.firstWidth = width pulseg.secondDelay = delay_2 lp = moose.RC('lowpass') lp.R = r lp.C = c DA = moose.DiffAmp('diffamp') DA.gain = gain DA.saturation = sat pid = moose.PIDController('PID') pid.gain = gain_p pid.tauI = tau_1 pid.tauD = tau_2 pid.saturation = psat comp = moose.element("/proto") moose.connect(pulseg, "output", lp, "injectIn") moose.connect(lp, "output", DA, "plusIn") moose.connect(DA, "output", pid, "commandIn") moose.connect(comp, "VmOut", pid, "sensedIn") moose.connect(pid, "output", comp, "injectMsg") tab = moose.Table("/data/Im") moose.connect(tab, "requestOut", comp, "getIm") return tab
def __init__(self, path): moose.Neutral.__init__(self, path) ''' self.pulsegen = moose.PulseGen(path+"/pulse") # holding voltage/current generator self.pulsegen.count = 2 self.pulsegen.baseLevel = -65.0e-3 self.pulsegen.firstLevel = -40.0e-3 self.pulsegen.firstWidth = 50.0e-3 self.pulsegen.firstDelay = 2.0e-3 self.pulsegen.secondDelay = 0.0 self.pulsegen.trigMode = 2 self.gate = moose.PulseGen(path+"/gate") # holding voltage/current generator self.gate.level[0] = 1.0 self.gate.delay[0] = 0.0 self.gate.width[0] = 1e3 moose.connect(self.gate, 'output', self.pulsegen, 'input') ''' self.lowpass = moose.RC(path + "/lowpass") # lowpass filter self.lowpass.R = 1.0 self.lowpass.C = 0.03 self.vclamp = moose.DiffAmp(path + "/vclamp") self.vclamp.gain = 1.0 self.vclamp.saturation = 1e10 self.iclamp = moose.DiffAmp(path + "/iclamp") self.iclamp.gain = 0.0 self.iclamp.saturation = 1e10 self.pid = moose.PIDController(path + "/pid") self.pid.gain = 0.5 self.pid.tauI = 0.02e-3 self.pid.tauD = 0.005e-3 self.pid.saturation = 1e7 # Connect voltage clamp circuitry #moose.connect(self.pulsegen, "output", self.lowpass, "injectIn") moose.connect(self.lowpass, "output", self.vclamp, "plusIn") moose.connect(self.vclamp, "output", self.pid, "commandIn") #moose.connect(compartment, "VmOut", self.pid, "sensedIn") #moose.connect(self.pid, "output", compartment, "injectMsg") addmsg1 = moose.Mstring(path + '/addmsg1') addmsg1.value = './pid output .. injectMsg' addmsg2 = moose.Mstring(path + '/addmsg2') addmsg2.value = '.. VmOut ./pid sensedIn'
def createInputs(self): for inputs in self.network.findall(".//{" + nml_ns + "}inputs"): units = inputs.attrib['units'] if units == 'Physiological Units': # see pg 219 (sec 13.2) of Book of Genesis Vfactor = 1e-3 # V from mV Tfactor = 1e-3 # s from ms Ifactor = 1e-6 # A from microA else: Vfactor = 1.0 Tfactor = 1.0 Ifactor = 1.0 for inputelem in inputs.findall(".//{" + nml_ns + "}input"): inputname = inputelem.attrib['name'] pulseinput = inputelem.find(".//{" + nml_ns + "}pulse_input") if pulseinput is not None: ## If /elec doesn't exists it creates /elec ## and returns a reference to it. If it does, ## it just returns its reference. moose.Neutral('/elec') pulsegen = moose.PulseGen('/elec/pulsegen_' + inputname) iclamp = moose.DiffAmp('/elec/iclamp_' + inputname) iclamp.saturation = 1e6 iclamp.gain = 1.0 pulsegen.trigMode = 0 # free run pulsegen.baseLevel = 0.0 pulsegen.firstDelay = float( pulseinput.attrib['delay']) * Tfactor pulsegen.firstWidth = float( pulseinput.attrib['duration']) * Tfactor pulsegen.firstLevel = float( pulseinput.attrib['amplitude']) * Ifactor pulsegen.secondDelay = 1e6 # to avoid repeat pulsegen.secondLevel = 0.0 pulsegen.secondWidth = 0.0 ## do not set count to 1, let it be at 2 by default ## else it will set secondDelay to 0.0 and repeat the first pulse! #pulsegen.count = 1 moose.connect(pulsegen, 'output', iclamp, 'plusIn') target = inputelem.find(".//{" + nml_ns + "}target") population = target.attrib['population'] for site in target.findall(".//{" + nml_ns + "}site"): cell_id = site.attrib['cell_id'] if 'segment_id' in site.attrib: segment_id = site.attrib['segment_id'] else: segment_id = 0 # default segment_id is specified to be 0 ## population is populationname, self.populationDict[population][0] is cellname cell_name = self.populationDict[population][0] segment_path = self.populationDict[population][1][int(cell_id)].path+'/'+\ self.cellSegmentDict[cell_name][0][segment_id][0] compartment = moose.Compartment(segment_path) moose.connect(iclamp, 'output', compartment, 'injectMsg')
def __init__(self, path, squid): self.path = path moose.Neutral(path) self.pulsegen = moose.PulseGen(path+"/pulse") # holding voltage/current generator self.pulsegen.count = 2 self.pulsegen.firstLevel = 25.0 self.pulsegen.firstWidth = 50.0 self.pulsegen.firstDelay = 2.0 self.pulsegen.secondDelay = 0.0 self.pulsegen.trigMode = 2 self.gate = moose.PulseGen(path + "/gate") # holding voltage/current generator self.gate.level[0] = 1.0 self.gate.delay[0] = 0.0 self.gate.width[0] = 1e9 moose.connect(self.gate, "output", self.pulsegen, "input") self.lowpass = moose.RC(path + "/lowpass") # lowpass filter self.lowpass.R = 1.0 self.lowpass.C = 0.03 self.vclamp = moose.DiffAmp(path + "/vclamp") self.vclamp.gain = 0.0 self.vclamp.saturation = 1e10 self.iclamp = moose.DiffAmp(path + "/iclamp") self.iclamp.gain = 0.0 self.iclamp.saturation = 1e10 self.pid = moose.PIDController(path + "/pid") self.pid.gain = 0.5 self.pid.tauI = 0.02 self.pid.tauD = 0.005 self.pid.saturation = 1e10 # Connect current clamp circuitry moose.connect(self.pulsegen, "output", self.iclamp, "plusIn") moose.connect(self.iclamp, "output", squid.C, "injectMsg") # Connect voltage clamp circuitry moose.connect(self.pulsegen, "output", self.lowpass, "injectIn") moose.connect(self.lowpass, "output", self.vclamp, "plusIn") moose.connect(self.vclamp, "output", self.pid, "commandIn") moose.connect(squid.C, "VmOut", self.pid, "sensedIn") moose.connect(self.pid, "output", squid.C, "injectMsg") current_table = moose.Table("/data/Im") moose.connect(current_table, "requestOut", squid.C, "getIm")
def createInput(self, inputelem, Vfactor, Tfactor, Ifactor): """Create input """ inputname = inputelem.attrib['name'] pulseinput = inputelem.find(".//{" + nml_ns + "}pulse_input") if pulseinput is not None: ## If /elec doesn't exists it creates /elec ## and returns a reference to it. If it does, ## it just returns its reference. moose.Neutral('/elec') pulsegen = moose.PulseGen('/elec/pulsegen_' + inputname) iclamp = moose.DiffAmp('/elec/iclamp_' + inputname) iclamp.saturation = 1e6 iclamp.gain = 1.0 pulsegen.trigMode = 0 # free run pulsegen.baseLevel = 0.0 _logger.debug("Tfactor, Ifactor: %s, %s" % (Tfactor, Ifactor)) _logger.debug("Pulsegen attributes: %s" % str(pulseinput.attrib)) pulsegen.firstDelay = float(pulseinput.attrib['delay']) * Tfactor pulsegen.firstWidth = float( pulseinput.attrib['duration']) * Tfactor pulsegen.firstLevel = float( pulseinput.attrib['amplitude']) * Ifactor pulsegen.secondDelay = 1e6 # to avoid repeat pulsegen.secondLevel = 0.0 pulsegen.secondWidth = 0.0 ## do not set count to 1, let it be at 2 by default ## else it will set secondDelay to 0.0 and repeat the first pulse! #pulsegen.count = 1 moose.connect(pulsegen, 'output', iclamp, 'plusIn') target = inputelem.find(".//{" + nml_ns + "}target") population = target.attrib['population'] for site in target.findall(".//{" + nml_ns + "}site"): cell_id = site.attrib['cell_id'] if 'segment_id' in site.attrib: segment_id = site.attrib['segment_id'] else: segment_id = 0 # default segment_id is specified to be 0 ## population is populationname, self.populationDict[population][0] is cellname cell_name = self.populationDict[population][0] segment_path = self.populationDict[population][1][int(cell_id)].path+'/'+\ self.cellSegmentDict[cell_name][0][segment_id][0] compartment = moose.element(segment_path) _logger.debug("Adding pulse at {0}: {1}".format( segment_path, pulsegen.firstLevel)) _logger.debug("Connecting {0}:output to {1}:injectMst".format( iclamp, compartment)) moose.connect(iclamp, 'output', compartment, 'injectMsg')
def setup_vclamp(compartment, name, delay1, width1, level1, gain=0.5e-5): """ Sets up a voltage clamp with 'name' on MOOSE 'compartment' object: adapted from squid.g in DEMOS (moose/genesis) Specify the 'delay1', 'width1' and 'level1' of the voltage to be applied to the compartment. Typically you need to adjust the PID 'gain' For perhaps the Davison 4-compartment mitral or the Davison granule: 0.5e-5 optimal gain - too high 0.5e-4 drives it to oscillate at high frequency, too low 0.5e-6 makes it have an initial overshoot (due to Na channels?) Returns a MOOSE table with the PID output. """ ## If /elec doesn't exists it creates /elec and returns a reference to it. ## If it does, it just returns its reference. moose.Neutral("/elec") pulsegen = moose.PulseGen("/elec/pulsegen" + name) vclamp = moose.DiffAmp("/elec/vclamp" + name) vclamp.saturation = 999.0 vclamp.gain = 1.0 lowpass = moose.RC("/elec/lowpass" + name) lowpass.R = 1.0 lowpass.C = 50e-6 # 50 microseconds tau PID = moose.PIDController("/elec/PID" + name) PID.gain = gain PID.tau_i = 20e-6 PID.tau_d = 5e-6 PID.saturation = 999.0 # All connections should be written as source.connect('',destination,'') pulsegen.connect("outputSrc", lowpass, "injectMsg") lowpass.connect("outputSrc", vclamp, "plusDest") vclamp.connect("outputSrc", PID, "commandDest") PID.connect("outputSrc", compartment, "injectMsg") compartment.connect("VmSrc", PID, "sensedDest") pulsegen.trigMode = 0 # free run pulsegen.baseLevel = -70e-3 pulsegen.firstDelay = delay1 pulsegen.firstWidth = width1 pulsegen.firstLevel = level1 pulsegen.secondDelay = 1e6 pulsegen.secondLevel = -70e-3 pulsegen.secondWidth = 0.0 vclamp_I = moose.Table("/elec/vClampITable" + name) vclamp_I.stepMode = TAB_BUF # TAB_BUF: table acts as a buffer. vclamp_I.connect("inputRequest", PID, "output") vclamp_I.useClock(PLOTCLOCK) return vclamp_I
def setup_iclamp(compartment, name, delay1, width1, level1): moose.Neutral('/elec') # If /elec doesn't exists it creates /elec and returns a reference to it. If it does, it just returns its reference. pulsegen = moose.PulseGen('/elec/pulsegen'+name) iclamp = moose.DiffAmp('/elec/iclamp'+name) iclamp.saturation = 1e6 iclamp.gain = 1.0 pulsegen.trigMode = 0 # free run pulsegen.baseLevel = 0.0 pulsegen.firstDelay = delay1 pulsegen.firstWidth = width1 pulsegen.firstLevel = level1 pulsegen.secondDelay = 1e6 pulsegen.secondLevel = 0.0 pulsegen.secondWidth = 0.0 pulsegen.connect('outputSrc',iclamp,'plusDest') iclamp.connect('outputSrc',compartment,'injectMsg') return pulsegen
def wildcard_setup(): a = moose.Neutral('/alfa') b = moose.Compartment('/alfa/bravo') c = moose.HHChannel('/alfa/bravo/charlie') f = moose.HHChannel2D('/alfa/bravo/foxtrot') e = moose.Neutral('/alfa/echo') d = moose.DiffAmp('/alfa/echo/delta') p = moose.PulseGen('/alfa/echo/papa') e1 = moose.Pool('/alfa/bravo/charlie/echo') g = moose.HHChannel('%s/golf' % (e1.path)) f1 = moose.Neutral('/alfa/bravo/foxtail') c1 = moose.Neutral('/alfa/bravo/charlee') b.Rm = 2.0e6 c.Gbar = 1e-9 f.Gbar = 0.5e-6 p.delay[0] = 10e-3 d.gain = 3.0 g.Gbar = 1e-6
def setup_iclamp(compartment, name, delay1, width1, level1): """ Sets up a current clamp with 'name' on MOOSE 'compartment' object: Specify the 'delay1', 'width1' and 'level1' of the current pulse to be applied to the compartment. Returns the MOOSE pulsegen that sends the current pulse. """ ## If /elec doesn't exists it creates /elec and returns a reference to it. ## If it does, it just returns its reference. moose.Neutral("/elec") pulsegen = moose.PulseGen("/elec/pulsegen" + name) iclamp = moose.DiffAmp("/elec/iclamp" + name) iclamp.saturation = 1e6 iclamp.gain = 1.0 pulsegen.trigMode = 0 # free run pulsegen.baseLevel = 0.0 pulsegen.firstDelay = delay1 pulsegen.firstWidth = width1 pulsegen.firstLevel = level1 pulsegen.secondDelay = 1e6 # to avoid repeat pulsegen.secondLevel = 0.0 pulsegen.secondWidth = 0.0 pulsegen.connect("output", iclamp, "plusIn") iclamp.connect("output", compartment, "injectMsg") return pulsegen
def attachInputToMoose(self, inElemXml, factors, savePlot=True): """attachInputToMoose This function create StimulousTable in moose There can be two type of stimulous: random_stim or pulse_input. """ # If /elec doesn't exists it creates /elec and returns a reference to # it. If it does, it just returns its reference. moose.Neutral(self.elecPath) inputName = inElemXml.get('name') random_stim = inElemXml.find('.//{' + nmu.nml_ns + '}random_stim') pulse_stim = inElemXml.find('.//{' + nmu.nml_ns + '}pulse_input') if random_stim is not None: utils.dump("INFO", "Generating random stimulous") utils.dump("TODO", "Test this Poission spike train table") # Get the frequency of stimulus frequency = moose_methods.toFloat( random_stim.get('frequency', '1.0')) / factors['Tfactor'] amplitude = random_stim.get('amplitude', 1.0) synpMechanism = random_stim.get('synaptic_mechanism') # Create random stimulus vec = stimulus.generateSpikeTrainPoission(frequency, dt=self.dt, simTime=self.simTime) # Stimulus table tablePath = os.path.join(self.elecPath, "Stimulus") moose.Neutral(tablePath) stimPath = os.path.join(tablePath, inputName) stim = moose.TimeTable(stimPath) stim.vec = vec if savePlot: self.plotVector(vec, tablePath) target = inElemXml.find(".//{" + nmu.nml_ns + "}target") population = target.get('population') for site in target.findall(".//{" + nmu.nml_ns + "}site"): cell_id = site.attrib['cell_id'] if 'segment_id' in site.attrib: segment_id = site.attrib['segment_id'] else: # default segment_id is specified to be 0 segment_id = 0 # To find the cell name fetch the first element of tuple. cell_name = self.populationDict[population][0] if cell_name == 'LIF': utils.dump("NOTE", "LIF cell_name. Partial implementation", frame=inspect.currentframe()) LIF = self.populationDict[population][1][int(cell_id)] m = self.connectSynapse(stim, LIF) else: segId = '{0}'.format(segment_id) segment_path = self.populationDict[population][1]\ [int(cell_id)].path + '/' + \ self.cellSegmentDict[cell_name][segId][0] compartment = moose.Compartment(segment_path) synchan = moose.SynChan( os.path.join(compartment.path, '/synchan')) synchan.Gbar = 1e-6 synchan.Ek = 0.0 self.connectWrapper(synchan, 'channel', compartment, 'channel') synchan.numSynapses = 1 m = self.connectSynapse( stim, moose.element(synchan.path + '/synapse')) elif pulse_stim is not None: Ifactor = factors['Ifactor'] Tfactor = factors['Tfactor'] pulseinput = inElemXml.find(".//{" + nmu.nml_ns + "}pulse_input") if pulseinput is None: utils.dump("WARN", "This type of stimulous is not supported.", frame=inspect.currentframe()) return self.pulseGenPath = self.elecPath + '/PulseGen' moose.Neutral(self.pulseGenPath) pulseGenPath = '{}/{}'.format(self.pulseGenPath, inputName) pulsegen = moose.PulseGen(pulseGenPath) icClampPath = '{}/{}'.format(self.elecPath, 'iClamp') moose.Neutral(icClampPath) iclamp = moose.DiffAmp('{}/{}'.format(icClampPath, inputName)) iclamp.saturation = 1e6 iclamp.gain = 1.0 # free run pulsegen.trigMode = 0 pulsegen.baseLevel = 0.0 pulsegen.firstDelay = float(pulseinput.attrib['delay']) * Tfactor pulsegen.firstWidth = float( pulseinput.attrib['duration']) * Tfactor pulsegen.firstLevel = float( pulseinput.attrib['amplitude']) * Ifactor # to avoid repeat pulsegen.secondDelay = 1e6 pulsegen.secondLevel = 0.0 pulsegen.secondWidth = 0.0 # do not set count to 1, let it be at 2 by default else it will # set secondDelay to 0.0 and repeat the first pulse! #pulsegen.count = 1 self.connectWrapper(pulsegen, 'output', iclamp, 'plusIn') # Attach targets target = inElemXml.find(".//{" + nmu.nml_ns + "}target") population = target.attrib['population'] for site in target.findall(".//{" + nmu.nml_ns + "}site"): cell_id = site.attrib['cell_id'] if 'segment_id' in site.attrib: segment_id = site.attrib['segment_id'] else: # default segment_id is specified to be 0 segment_id = 0 # population is populationName, # self.populationDict[population][0] is cellname cell_name = self.populationDict[population][0] if cell_name == 'LIF': debug.printDebut("TODO", "Rewrite this section", frame=inspect.currentframe()) continue LIF = self.populationDict[population][1][int(cell_id)] self.connectWrapper(iclamp, 'output', LIF, 'injectMsg') else: segment_path = self.populationDict[population][1]\ [int(cell_id)].path+'/'+\ self.cellSegmentDict[cell_name][segment_id][0] compartment = moose.Compartment(segment_path) self.connectWrapper(iclamp, 'output', compartment, 'injectMsg')