コード例 #1
0
    def make_stimulus(self, stimulus='tone', cf=16000., f0=16000., simulator=None,
        rundur=0.2, pipdur=0.05, dbspl=50.,
        fmod=100., dmod=0.):
        self.stimulus = stimulus
        self.run_duration = rundur  # in seconds
        self.pip_duration = pipdur  # in seconds
        self.pip_start = [0.1]  # in seconds
        self.Fs = 100e3  # in Hz
        self.f0 = f0  # stimulus in Hz
        self.cf = cf  # SGCs in Hz
        self.fMod = fmod  # mod freq, Hz
        self.dMod = dmod  # % mod depth, Hz
        self.dbspl = dbspl
        self.simulator = simulator
        self.sr = 1  # set SR group
        if self.stimulus == 'SAM':
            self.stim = sound.SAMTone(rate=self.Fs, duration=self.run_duration, f0=self.f0, 
                          fmod=self.fMod, dmod=self.dMod, dbspl=self.dbspl,
                          ramp_duration=2.5e-3, pip_duration=self.pip_duration,
                          pip_start=self.pip_start)
        if self.stimulus == 'tone':
            self.stim = sound.TonePip(rate=self.Fs, duration=self.run_duration, f0=self.f0, dbspl=self.dbspl,
                          ramp_duration=2.5e-3, pip_duration=self.pip_duration,
                          pip_start=self.pip_start)

        if self.stimulus == 'clicks':
            self.click_rate = 0.020  # msec
            self.stim = sound.ClickTrain(rate=self.Fs, duration=self.run_duration,
                        f0=self.f0, dbspl=self.dbspl, click_start=0.010, click_duration=100.e-6,
                        click_interval=self.click_rate, nclicks=int((self.run_duration-0.01)/self.click_rate),
                        ramp_duration=2.5e-3)
コード例 #2
0
    def run(self, temp=34.0, dt=0.025, seed=575982035, simulator=None):
        preCell = cells.DummySGC(cf=4000, sr=2)
        postCell = cells.Bushy.create()
        synapse = preCell.connect(postCell)
        self.pre_cell = preCell
        self.post_cell = postCell
        self.synapse = synapse

        self.stim = sound.TonePip(rate=100e3,
                                  duration=0.1,
                                  f0=4000,
                                  dbspl=80,
                                  ramp_duration=2.5e-3,
                                  pip_duration=0.04,
                                  pip_start=[0.02])

        preCell.set_sound_stim(self.stim, seed=seed, simulator=simulator)

        self['vm'] = postCell.soma(0.5)._ref_v
        #self['prevm'] = preCell.soma(0.5)._ref_v
        for i in range(30):
            self['xmtr%d' % i] = synapse.terminal.relsite._ref_XMTR[i]
            synapse.terminal.relsite.Dep_Flag = False
        self['t'] = h._ref_t

        h.tstop = 100.0  # duration of a run
        h.celsius = temp
        h.dt = dt

        custom_init()
        h.run()
コード例 #3
0
ファイル: test_cache.py プロジェクト: rcrowder/cnmodel
def run_sim(*args):
    cf = 1000
    sr = 2
    seed = 12345678
    stim = sound.TonePip(rate=100e3,
                         duration=0.01,
                         f0=4000,
                         dbspl=80,
                         ramp_duration=0.002,
                         pip_duration=0.004,
                         pip_start=[0.001])
    spikes = an_model.get_spiketrain(cf=cf, sr=sr, seed=seed, stim=stim)
    cf = cache.get_cache_filename(cf, sr, seed, stim)
    mtime = os.stat(cf).st_mtime
    return cf, mtime, spikes
コード例 #4
0
ファイル: test_sound.py プロジェクト: rcrowder/cnmodel
def test_tonepip():
    rate = 100000
    dur = 0.1
    ps = 0.01
    rd = 0.02
    pd = 0.08
    db = 60
    s1 = sound.TonePip(rate=rate,
                       duration=dur,
                       f0=5321,
                       dbspl=db,
                       pip_duration=pd,
                       pip_start=[ps],
                       ramp_duration=rd)

    # test array sizes
    assert s1.sound.size == s1.time.size == int(dur * rate) + 1

    # test for consistency
    assert np.allclose(
        [s1.sound.min(), s1.sound.mean(),
         s1.sound.max()],
        [-0.028284253158247834, -1.0954891976168953e-10, 0.028284270354167296])

    # test that we got the requested amplitude
    assert np.allclose(s1.measure_dbspl(ps + rd, ps + pd - rd),
                       db,
                       atol=0.1,
                       rtol=0.01)

    # test for quiet before and after pip
    assert np.all(s1.sound[:int(ps * rate) - 1] == 0)
    assert np.all(s1.sound[int((ps + pd) * rate) + 1:] == 0)

    # test the sound can be recreated from its key
    key = s1.key()
    s2 = sound.create(**key)
    assert np.all(s1.time == s2.time)
    assert np.all(s1.sound == s2.sound)
コード例 #5
0
    def run(self,
            pops,
            cf=16e3,
            temp=34.0,
            dt=0.025,
            stim='sound',
            simulator='cochlea'):
        """ 
        1. Connect pop1 => pop2
        2. Instantiate a single cell in pop2
        3. Automatically generate presynaptic cells and synapses from pop1
        4. Stimulate presynaptic cells and record postsynaptically
        """

        pre_pop, post_pop = pops
        pre_pop.connect(post_pop)
        self.pre_pop = pre_pop
        self.post_pop = post_pop

        # start with one cell, selected from the user-selected population, that has
        # a cf close to the center CF
        post_cell_ind = post_pop.select(1, cf=cf, create=True)[0]
        post_cell = post_pop.get_cell(post_cell_ind)
        post_pop.resolve_inputs(depth=1)
        post_sec = post_cell.soma
        self.post_cell_ind = post_cell_ind
        self.post_cell = post_cell

        pre_cell_inds = post_pop.cell_connections(post_cell_ind)[pre_pop]
        pre_cells = [pre_pop.get_cell(i) for i in pre_cell_inds]
        pre_secs = [cell.soma for cell in pre_cells]
        self.pre_cells = pre_cells
        self.pre_cell_inds = pre_cell_inds
        self.stim = sound.TonePip(rate=100e3,
                                  duration=0.1,
                                  f0=cf,
                                  dbspl=60,
                                  ramp_duration=2.5e-3,
                                  pip_duration=0.05,
                                  pip_start=[0.02])

        ##
        ## voltage clamp the target cell
        ##
        #clampV = 40.0
        #vccontrol = h.VClamp(0.5, sec=post_cell.soma)
        #vccontrol.dur[0] = 10.0
        #vccontrol.amp[0] = clampV
        #vccontrol.dur[1] = 100.0
        #vccontrol.amp[1] = clampV
        #vccontrol.dur[2] = 20.0
        #vccontrol.amp[2] = clampV

        #
        # set up stimulation of the presynaptic cells
        #
        self.stim_params = []
        self.istim = []
        for i, pre_cell in enumerate(pre_cells):
            if stim == 'sound':
                pre_cell.set_sound_stim(self.stim, seed=i, simulator=simulator)
                amp = 0.0
            else:
                amp = 3.0
                istim = h.iStim(0.5, sec=pre_cell.soma)
                stim = {}
                stim['NP'] = 10
                stim['Sfreq'] = 100.0  # stimulus frequency
                stim['delay'] = 10.0
                stim['dur'] = 0.5
                stim['amp'] = amp
                stim['PT'] = 0.0
                stim['dt'] = dt
                (secmd, maxt, tstims) = util.make_pulse(stim)
                self.stim_params.append(stim)

                # istim current pulse train
                i_stim_vec = h.Vector(secmd)
                i_stim_vec.play(istim._ref_i, dt, 0, pre_cell.soma(0.5))
                self.istim.append((istim, i_stim_vec))
                self['istim'] = istim._ref_i

            # record presynaptic Vm
            self['v_pre%d' % i] = pre_cell.soma(0.5)._ref_v

        self['t'] = h._ref_t
        self['v_post'] = post_cell.soma(0.5)._ref_v

        #
        # Run simulation
        #
        h.dt = dt
        self.dt = dt
        h.celsius = post_cell.status['temperature']
        self.temp = h.celsius
        post_cell.cell_initialize()  # proper initialization.
        h.dt = self.dt
        custom_init(v_init=post_cell.vm0)
        h.t = 0.
        h.tstop = 200.0
        while h.t < h.tstop:
            h.fadvance()
コード例 #6
0
    def run(self,
            temp=34.0,
            dt=0.025,
            seed=575982035,
            reps=10,
            stimulus='tone',
            simulator='cochlea'):
        assert stimulus in ['tone', 'SAM', 'clicks']  # cases available
        assert self.cell in ['bushy', 'tstellate', 'octopus', 'dstellate']
        self.nrep = reps
        self.stimulus = stimulus
        self.run_duration = 0.20  # in seconds
        self.pip_duration = 0.05  # in seconds
        self.pip_start = [0.1]  # in seconds
        self.Fs = 100e3  # in Hz
        self.f0 = 4000.  # stimulus in Hz
        self.cf = 4000.  # SGCs in Hz
        self.fMod = 100.  # mod freq, Hz
        self.dMod = 0.  # % mod depth, Hz
        self.dbspl = 50.
        self.simulator = simulator
        self.sr = 1  # set SR group
        if self.stimulus == 'SAM':
            self.stim = sound.SAMTone(rate=self.Fs,
                                      duration=self.run_duration,
                                      f0=self.f0,
                                      fmod=self.fMod,
                                      dmod=self.dMod,
                                      dbspl=self.dbspl,
                                      ramp_duration=2.5e-3,
                                      pip_duration=self.pip_duration,
                                      pip_start=self.pip_start)
        if self.stimulus == 'tone':
            self.f0 = 4000.
            self.cf = 4000.
            self.stim = sound.TonePip(rate=self.Fs,
                                      duration=self.run_duration,
                                      f0=self.f0,
                                      dbspl=self.dbspl,
                                      ramp_duration=2.5e-3,
                                      pip_duration=self.pip_duration,
                                      pip_start=self.pip_start)

        if self.stimulus == 'clicks':
            self.click_rate = 0.020  # msec
            self.stim = sound.ClickTrain(
                rate=self.Fs,
                duration=self.run_duration,
                f0=self.f0,
                dbspl=self.dbspl,
                click_start=0.010,
                click_duration=100.e-6,
                click_interval=self.click_rate,
                nclicks=int((self.run_duration - 0.01) / self.click_rate),
                ramp_duration=2.5e-3)

        n_sgc = data.get('convergence',
                         species=species,
                         post_type=self.cell,
                         pre_type='sgc')[0]
        self.n_sgc = int(np.round(n_sgc))
        # for simple synapses, need this value:
        self.AMPA_gmax = data.get(
            'sgc_synapse',
            species=species,
            post_type=self.cell,
            field='AMPA_gmax')[0] / 1e3  # convert nS to uS for NEURON
        self.vms = [None for n in range(self.nrep)]
        self.synapses = [None for n in range(self.nrep)]
        self.xmtrs = [None for n in range(self.nrep)]
        self.pre_cells = [None for n in range(self.nrep)]
        self.time = [None for n in range(self.nrep)]
        info = {
            'n_sgc': self.n_sgc,
            'gmax': self.AMPA_gmax,
            'stim': self.stim,
            'simulator': self.simulator,
            'cf': self.cf,
            'sr': self.sr,
            'seed': seed,
            'run_duration': self.run_duration,
            'temp': temp,
            'dt': dt,
            'init': custom_init
        }
        if not self.parallelize:
            for nr in range(self.nrep):
                info['seed'] = seed + 3 * self.n_sgc * nr
                res = RunTrial(self.cell, info)
                # res contains: {'time': time, 'vm': Vm, 'xmtr': xmtr, 'pre_cells': pre_cells, 'post_cell': post_cell}
                self.pre_cells[nr] = res['pre_cells']
                self.time[nr] = res['time']
                self.xmtr = {k: v.to_python() for k, v in res['xmtr'].items()}
                self.vms[nr] = res['vm']
                self.synapses[nr] = res['synapses']
                self.xmtrs[nr] = self.xmtr

        if self.parallelize:
            ### Use parallelize with multiple workers
            tasks = range(len(self.nrep))
            results3 = results[:]
            start = time.time()
            #            with mp.Parallelize(enumerate(tasks), results=results, progressDialog='processing in parallel..') as tasker:
            with mp.Parallelize(enumerate(tasks), results=results) as tasker:
                for i, x in tasker:
                    tot = 0
                    for j in xrange(size):
                        tot += j * x
                    tasker.results[i] = tot
            print("\nParallel time, %d workers: %0.2f" %
                  (mp.Parallelize.suggestedWorkerCount(), time.time() - start))
            print("Results match serial:      %s" % str(results3 == results))
コード例 #7
0
    def run(self, temp=34.0, dt=0.025, seed=575982035, stimulus='tone', species='mouse'):
        assert stimulus in ['tone', 'SAM', 'clicks']  # cases available
        if self.cell == 'bushy':
            postCell = cells.Bushy.create(species=species)
        elif self.cell == 'tstellate':
            postCell = cells.TStellate.create(species=species)
        elif self.cell == 'octopus':
            postCell = cells.Octopus.create(species=species)
        elif self.cell == 'dstellate':
            postCell = cells.DStellate.create(species=species)
        else:
            raise ValueError('cell %s is not yet implemented for phaselocking' % self.cell)
        self.post_cell = postCell
        self.stimulus = stimulus
        self.run_duration = 1.  # in seconds
        self.pip_duration = 0.8  # in seconds
        self.pip_start = [0.02]  # in seconds
        self.Fs = 100e3  # in Hz
        self.f0 = 4000.  # stimulus in Hz
        self.cf = 4000.  # SGCs in Hz
        self.fMod = 100.  # mod freq, Hz
        self.dMod = 50.  # % mod depth, Hz
        self.dbspl = 60.
        if self.stimulus == 'SAM':
            self.stim = sound.SAMTone(rate=self.Fs, duration=self.run_duration, f0=self.f0, 
                          fmod=self.fMod, dmod=self.dMod, dbspl=self.dbspl,
                          ramp_duration=2.5e-3, pip_duration=self.pip_duration,
                          pip_start=self.pip_start)
        if self.stimulus == 'tone':
            self.f0 = 1000.
            self.cf = 1000.
            self.stim = sound.TonePip(rate=self.Fs, duration=self.run_duration, f0=self.f0, dbspl=self.dbspl,
                          ramp_duration=2.5e-3, pip_duration=self.pip_duration,
                          pip_start=self.pip_start)

        if self.stimulus == 'clicks':
            self.click_rate = 0.020  # msec
            self.stim = sound.ClickTrain(rate=self.Fs, duration=self.run_duration,
                        f0=self.f0, dbspl=self.dbspl, click_start=0.010, click_duration=100.e-6,
                        click_interval=self.click_rate, nclicks=int((self.run_duration-0.01)/self.click_rate),
                        ramp_duration=2.5e-3)
        
        n_sgc = data.get('convergence', species=species, post_type=postCell.type, pre_type='sgc')[0]
        self.n_sgc = int(np.round(n_sgc))

        self.pre_cells = []
        self.synapses = []
        j = 0
        for k in range(self.n_sgc):
            seed = seed + k
            preCell = cells.DummySGC(cf=self.cf, sr=2)
            synapse = preCell.connect(postCell)
            for i in range(synapse.terminal.n_rzones):
                self['xmtr%03d'%j] = synapse.terminal.relsite._ref_XMTR[i]
                j = j + 1
            synapse.terminal.relsite.Dep_Flag = False
            preCell.set_sound_stim(self.stim, seed=seed)
            self.pre_cells.append(preCell)
            self.synapses.append(synapse)
        
        self['vm'] = postCell.soma(0.5)._ref_v
        #self['prevm'] = preCell.soma(0.5)._ref_v
        self['t'] = h._ref_t
        postCell.cell_initialize()
        h.tstop = 1e3*self.run_duration # duration of a run
        h.celsius = temp
        h.dt = dt
        
        self.custom_init()
        h.run()
コード例 #8
0
    def run(self,
            temp=34.0,
            dt=0.025,
            seed=575982035,
            reps=10,
            stimulus='tone',
            simulator='cochlea',
            parallelize=False):
        assert stimulus in ['tone', 'SAM', 'clicks']  # cases available
        assert self.cell in [
            'bushy', 'tstellate', 'octopus', 'dstellate', 'tuberculoventral',
            'pyramidal'
        ]
        self.nrep = reps
        self.stimulus = stimulus
        self.run_duration = 0.20  # in seconds
        self.pip_duration = 0.05  # in seconds
        self.pip_start = [0.1]  # in seconds
        self.Fs = 100e3  # in Hz
        self.f0 = 4000.  # stimulus in Hz
        self.cf = 4000.  # SGCs in Hz
        self.fMod = 100.  # mod freq, Hz
        self.dMod = 0.  # % mod depth, Hz
        self.dbspl = 50.
        self.simulator = simulator
        self.sr = 2  # set SR group
        if self.stimulus == 'SAM':
            self.dMod = 100.
            self.stim = sound.SAMTone(rate=self.Fs,
                                      duration=self.run_duration,
                                      f0=self.f0,
                                      fmod=self.fMod,
                                      dmod=self.dMod,
                                      dbspl=self.dbspl,
                                      ramp_duration=2.5e-3,
                                      pip_duration=self.pip_duration,
                                      pip_start=self.pip_start)
        if self.stimulus == 'tone':
            self.f0 = 4000.
            self.cf = 4000.
            self.stim = sound.TonePip(rate=self.Fs,
                                      duration=self.run_duration,
                                      f0=self.f0,
                                      dbspl=self.dbspl,
                                      ramp_duration=2.5e-3,
                                      pip_duration=self.pip_duration,
                                      pip_start=self.pip_start)

        if self.stimulus == 'clicks':
            self.click_rate = 0.020  # msec
            self.stim = sound.ClickTrain(
                rate=self.Fs,
                duration=self.run_duration,
                f0=self.f0,
                dbspl=self.dbspl,
                click_start=0.010,
                click_duration=100.e-6,
                click_interval=self.click_rate,
                nclicks=int((self.run_duration - 0.01) / self.click_rate),
                ramp_duration=2.5e-3)

        n_sgc = data.get('convergence',
                         species=species,
                         post_type=self.cell,
                         pre_type='sgc')[0]
        self.n_sgc = int(np.round(n_sgc))
        # for simple synapses, need this value:
        self.AMPA_gmax = data.get(
            'sgc_synapse',
            species=species,
            post_type=self.cell,
            field='AMPA_gmax')[0] / 1e3  # convert nS to uS for NEURON
        self.vms = [None for n in range(self.nrep)]
        self.synapses = [None for n in range(self.nrep)]
        self.xmtrs = [None for n in range(self.nrep)]
        self.pre_cells = [None for n in range(self.nrep)]
        self.time = [None for n in range(self.nrep)]
        info = {
            'n_sgc': self.n_sgc,
            'gmax': self.AMPA_gmax,
            'stim': self.stim,
            'simulator': self.simulator,
            'cf': self.cf,
            'sr': self.sr,
            'seed': seed,
            'run_duration': self.run_duration,
            'temp': temp,
            'dt': dt,
            'init': custom_init
        }
        if not parallelize:
            for nr in range(self.nrep):
                info['seed'] = seed + 3 * self.n_sgc * nr
                res = runTrial(self.cell, info)
                # res contains: {'time': time, 'vm': Vm, 'xmtr': xmtr, 'pre_cells': pre_cells, 'post_cell': post_cell}
                self.pre_cells[nr] = res['pre_cells']
                self.time[nr] = res['time']
                self.xmtr = {k: v.to_python() for k, v in res['xmtr'].items()}
                self.vms[nr] = res['vm']
                self.synapses[nr] = res['synapses']
                self.xmtrs[nr] = self.xmtr

        if parallelize:
            pass
コード例 #9
0
ファイル: test_an_model.py プロジェクト: lhg0550/cnmodel
def test_an_model():
    # model fiber parameters
    CF = 1.5e3  # CF in Hz
    cohc = 1.0  # normal ohc function
    cihc = 1.0  # normal ihc function
    species = 1  # 1 for cat (2 for human with Shera et al. tuning 3 for human with Glasberg & Moore tuning)
    noiseType = 1  # 1 for variable fGn (0 for fixed fGn)
    fiberType = 3  # spontaneous rate (in spikes/s) of the fiber BEFORE refractory effects "1" = Low "2" = Medium "3" = High
    implnt = 0  # "0" for approximate or "1" for actual implementation of the power-law functions in the Synapse

    # stimulus parameters
    F0 = CF  # stimulus frequency in Hz
    Fs = 100e3  # sampling rate in Hz (must be 100, 200 or 500 kHz)
    T = 150e-3  # stimulus duration in seconds
    pdur = 0.02  # pip duration
    pstart = [0.01, 0.035]  # pip start times
    rt = 2.5e-3  # rise/fall time in seconds
    stimdb = 65  # stimulus intensity in dB SPL

    # PSTH parameters
    nrep = 1000  # number of stimulus repetitions (e.g., 50)
    psthbinwidth = 0.5e-3  # binwidth in seconds

    stim = sound.TonePip(rate=Fs,
                         duration=T,
                         f0=F0,
                         dbspl=stimdb,
                         pip_duration=pdur,
                         pip_start=pstart,
                         ramp_duration=rt)
    t = stim.time
    pin = stim.sound
    db = stim.measure_dbspl(rt, T - rt)

    an_model.seed_rng(34978)

    start = time.time()
    vihc = an_model.model_ihc(pin,
                              CF,
                              nrep,
                              1 / Fs,
                              T + 1e-3,
                              cohc,
                              cihc,
                              species,
                              _transfer=False)
    print "IHC time:", time.time() - start

    start = time.time()
    m, v, psth = an_model.model_synapse(vihc, CF, nrep, 1 / Fs, fiberType,
                                        noiseType, implnt)
    print "Syn time:", time.time() - start

    win = pg.GraphicsWindow()
    p1 = win.addPlot(title='Input Stimulus (%0.1f dBSPL)' % db)
    p1.plot(t, pin)

    p2 = win.addPlot(col=0, row=1, title='IHC voltage')
    p2.setXLink(p1)
    vihc = vihc.get()[0]
    vihc = vihc[:len(vihc) // nrep]
    t = np.arange(len(vihc)) * 1e-5
    p2.plot(t, vihc)

    p3 = win.addPlot(col=0, row=2, title='ANF PSTH')
    p3.setXLink(p2)
    ds = 100
    size = psth.size // ds
    psth = psth[:size * ds].reshape(size, ds).sum(axis=1)
    t = np.arange(len(psth)) * 1e-5 * ds
    p3.plot(t, psth[:-1], stepMode=True, fillLevel=0, fillBrush='w')
    if sys.flags.interactive == 0:
        pg.QtGui.QApplication.exec_()
コード例 #10
0
ファイル: test_physiology.py プロジェクト: lhg0550/cnmodel
            for i in range(nreps):
                tasks.append((f, db, i))

    results = {}
    workers = 1 if not parallel else None
    tot_runs = len(fvals) * len(levels) * nreps
    with mp.Parallelize(enumerate(tasks),
                        results=results,
                        progressDialog='Running parallel simulation..',
                        workers=workers) as tasker:
        for i, task in tasker:
            f, db, iteration = task
            stim = sound.TonePip(
                rate=100e3,
                duration=stimpar['dur'],
                f0=f,
                dbspl=db,  # dura 0.2, pip_start 0.1 pipdur 0.04
                ramp_duration=2.5e-3,
                pip_duration=stimpar['pip'],
                pip_start=stimpar['start'])

            print("=== Start run %d/%d ===" % (i + 1, tot_runs))
            cachefile = os.path.join(
                cachepath, 'seed=%d_f0=%f_dbspl=%f_syntype=%s_iter=%d.pk' %
                (seed, f, db, syntype, iteration))
            if '--ignore-cache' in sys.argv or not os.path.isfile(cachefile):
                result = prot.run(stim, seed=i)
                pickle.dump(result, open(cachefile, 'wb'))
            else:
                print("  (Loading cached results)")
                result = pickle.load(open(cachefile, 'rb'))
            tasker.results[(f, db, iteration)] = (stim, result)
コード例 #11
0
ファイル: test_mso_inputs.py プロジェクト: lhg0550/cnmodel
    def run(self, temp=38.0, dt=0.025, seed=575982035, simulator=None):
        ears = {'left': [500., 502, 498], 'right': [500., 502., 498]}
        
        self.beatfreq = 0.
        self.f0 = 500.
        f0 = {'left': self.f0, 'right': self.f0+self.beatfreq}
        nsgc = len(ears.keys())
        sgcCell = {}
        bushyCell = {}
        msoCell = {}
        synapse = {}
        self.stim = {}
        self.ears = ears
        self.stimdur = 0.2
        self.stimdelay = 0.02
        self.rundur = self.stimdelay + self.stimdur + 0.02

        for i, ear in enumerate(ears.keys()):
            nsgc = len(ears[ear])  # how many sgcs are specified for this ear
            sgcCell[ear] = [cells.DummySGC(cf=ears[ear][k], sr=2) for k in range(nsgc)]
            bushyCell[ear] = [cells.Bushy.create(temperature=temp)]
            synapse[ear] = [sgcCell[ear][k].connect(bushyCell[ear][0]) for k in range(nsgc)]
            self.stim[ear] = [sound.TonePip(rate=100e3, duration=self.stimdur+0.1, f0=f0[ear], dbspl=80,
                                  ramp_duration=2.5e-3, pip_duration=self.stimdur, 
                                  pip_start=[self.stimdelay]) for k in range(nsgc)]
            for k in range(len(self.stim[ear])):
                sgcCell[ear][k].set_sound_stim(self.stim[ear][k], seed=seed + i*seed + k, simulator=simulator)
            self['vm_bu_%s' % ear] = bushyCell[ear][0].soma(0.5)._ref_v
            for k in range(30):
                self['xmtr%d_%s'%(k, ear)] = synapse[ear][0].terminal.relsite._ref_XMTR[k]
            for k in range(len(synapse[ear])):
                synapse[ear][k].terminal.relsite.Dep_Flag = False  # turn off depression

        msoCell = cells.MSO.create(temperature=temp)  # one target MSO cell
        msosyn = {}
        for ear in ears:
            msosyn[ear] = bushyCell[ear][0].connect(msoCell)
        self.sgc_cells = sgcCell
        self.bushy_cells = bushyCell
        self.synapses = synapse
        self.msyns = msosyn
        self.msoCell = msoCell
        self.all_cells = []  # hold all "real" cells (DummySGC does not have mechanisms)
        for ear in ears.keys():
            self.all_cells.append([c for c in self.bushy_cells[ear]])
        self.all_cells.append([self.msoCell])
        
        self['vm_mso'] = self.msoCell.soma(0.5)._ref_v
        for k, ear in enumerate(ears.keys()):
            for i in range(30):
                self['mso_xmtr%d_%s'%(i, ear)] = msosyn[ear].terminal.relsite._ref_XMTR[i]
            msosyn[ear].terminal.relsite.Dep_Flag = False  # turn off depression

        self['t'] = h._ref_t
        
        h.tstop = self.rundur*1e3 # duration of a run
        h.celsius = temp
        h.dt = dt
        
        custom_init()
        # confirm that all cells are ok
        for cg in self.all_cells:
            for c in cg:
                c.check_all_mechs()
        while h.t < h.tstop:
            h.fadvance()