//Created by Paulo Aguiar [pauloaguiar@fc.up.pt] // Steps: // 1 - CREATE WDR neuron and interneuron from the respective template cells // 2 - SET INPUT SIGNALS/STIMULI // 3 - SET SYNAPSES/RECEPTORS // 4 - CONNECT STIMULI TO SYNAPSES // 5 - PROVIDE NOISE TO WDR // 6 - FINAL COMMANDS // 1 ***************************************************************************************************** // CREATE WDR neuron and interneuron from the respective template cells load_file("WDR.hoc") load_file("interneuron.hoc") objref wdr, interneuron wdr = new WDR() interneuron = new Interneuron() // 2 ***************************************************************************************************** // SET INPUT SIGNALS/STIMULI // C-fibres and Ad-fibres signals are driven by spike-times stored in vectors // noise signals are driven by NetStim objects // signal periods; all times are in ms n_burst_spikes = 1 // define the number of spikes created by each stim in the fibres T0 = 10.0 // if each stim produces a short burst of spikes, this is their ISI [ms] n_close_stims = 1 // define the number of stims in each set (ex: 1=singlet; 3=triplets) T1 = 200.0 // in heterogeneous stimulation n_close_stims are separated by T1 [ms] n_stim_sets = 15 // define the number of stim sets T2 = 1000.0 // period between stimuli sets [ms] start_time = 1000.0 // time for first stim [ms] //tstop is defined after loading the session (close to the end of this file) // NOTES: average stimuli period = T2 / n_close_stims // total stims = n_close_stims * n_stim_sets // contruct the stimulus times vector objref stim_times stim_times = new Vector(n_stim_sets*n_close_stims*n_burst_spikes, 0.0) index = 0 for i=0,n_stim_sets-1 { for j=0,n_close_stims-1 { for k=0,n_burst_spikes-1 { stim_times.x[index] = start_time + i * T2 + j * T1 + k * T0 index = index + 1 } } } printf("\nSTIMULATION TIMES") stim_times.printf() // 3 ***************************************************************************************************** // SET CONNECTIONS/SYNAPSES // Ad-fibres --> NMDAR, AMPAR --> wdr // C-fibres --> NMDAR, AMPAR, NK1R --> interneuron // interneuron --> NMDAR, AMPAR, GABAR --> wdr // interneuron --> GABAAR --> wdr // noise_inh --> GABAAR --> wdr // noise_exc --> AMPAR --> wdr // Create post-synaptic receptors for all synapses // SYNAPSES FROM Ad-FIBRES // ----------------------- N_A = 20 // number of A synapses impinging on WDR Ad_delay = 30.0 // delay in the activation of Ad synapses [ms] Ad_dispersion = 5.0 //dispersion in the arrival time of Ad signals [ms] objref nil objref ampar_Ad[N_A], nmdar_Ad[N_A] objref ampa_Ad_conn[N_A], nmda_Ad_conn[N_A] for i=0,N_A-1 { wdr.dendrite ampar_Ad[i] = new AMPA_DynSyn(0.5) ampar_Ad[i].tau_fac = 0.1 // NOT SUBJECT TO SHORT-TERM PLASTICITY ampar_Ad[i].tau_rec = 0.1 ampar_Ad[i].U1 = 1.0 ampar_Ad[i].tau_rise = 0.1 ampar_Ad[i].tau_decay = 5.0 //netcon = new NetCon(source, target, threshold [mV], delay [ms], weight [uS]) -> delay is overwritten by FIinitializeHandler ampa_Ad_conn[i] = new NetCon(nil, ampar_Ad[i], -30.0, 0.0 , 0.0008)//0.0008 wdr.dendrite nmdar_Ad[i] = new NMDA_DynSyn(0.5) nmdar_Ad[i].tau_fac = 0.1 // NOT SUBJECT TO SHORT-TERM PLASTICITY nmdar_Ad[i].tau_rec = 0.1 nmdar_Ad[i].U1 = 1.0 nmdar_Ad[i].tau_rise = 2.0 nmdar_Ad[i].tau_decay = 100.0 //netcon = new NetCon(source, target, threshold [mV], delay [ms], weight [uS]) -> delay is overwritten by FIinitializeHandler nmda_Ad_conn[i] = new NetCon(nil, nmdar_Ad[i], -30.0, 0.0 , 0.0001)//0.0001 } // the activation times of Ad-fibres are set together with C-fibres - below // SYNAPSES FROM C-FIBRES // ---------------------- objref nil objref ampar_C, nmdar_C, nk1r_C, nk1r_C_WDR objref ampa_C_conn, nmda_C_conn, nk1_C_conn, nk1_C_WDR_conn tau_fac = 0.1 //0.1 or 3000.0 (Facilitation Exp) tau_rec = 0.1 //0.1 or 4000.0 (Depression Exp) U1 = 1.0 //1.0 or 0.5 (Facilitation Exp) or 0.07 (Depression Exp) interneuron.dendrite ampar_C = new AMPA_DynSyn(0.5) ampar_C.tau_fac = tau_fac ampar_C.tau_rec = tau_rec ampar_C.U1 = U1 ampar_C.tau_rise = 0.1 ampar_C.tau_decay = 5.0 interneuron.dendrite nmdar_C = new NMDA_DynSyn(0.5) nmdar_C.tau_fac = tau_fac nmdar_C.tau_rec = tau_rec nmdar_C.U1 = U1 nmdar_C.tau_rise = 2.0 nmdar_C.tau_decay = 100.0 interneuron.dendrite nk1r_C = new NK1_DynSyn(0.5) nk1r_C.tau_fac = tau_fac nk1r_C.tau_rec = tau_rec nk1r_C.U1 = U1 nk1r_C.tau_rise = 100.0 nk1r_C.tau_decay = 3000.0 wdr.dendrite nk1r_C_WDR = new NK1_DynSyn(0.5) // substance P diffusion to deeper laminae reaches WDR which have some NK1R nk1r_C_WDR.tau_fac = tau_fac nk1r_C_WDR.tau_rec = tau_rec nk1r_C_WDR.U1 = U1 nk1r_C_WDR.tau_rise = 200.0 nk1r_C_WDR.tau_decay = 3000.0 //netcon = new NetCon(source, target, threshold [mV], delay [ms], weight [uS]) -> delay is overwritten by FIinitializeHandler ampa_C_conn = new NetCon(nil, ampar_C , -30.0, 0.0, 0.008000/U1) //0.008000 IMPORTANT: normalize all weights by U1 (for identical initial responses) nmda_C_conn = new NetCon(nil, nmdar_C , -30.0, 0.0, 0.004000/U1) //0.004000 nk1_C_conn = new NetCon(nil, nk1r_C , -30.0, 0.0, 0.000020/U1) //0.000020; if bigger interneuron will show strong windup (but constrained by iKCa) nk1_C_WDR_conn = new NetCon(nil, nk1r_C_WDR, -30.0, 0.0, 0.000015/U1) //0.000015; smaller than above to reflect diffusion and less expression //set activation times objref fih fih = new FInitializeHandler("loadqueue()") proc loadqueue() { local ii, jj, event_time localobj r r = new Random(123456789) // use a different seed if you need different random streams; "123456789" is the seed used in the paper figure //load Ad-fiber spike times for ii=0,stim_times.size()-1 { //distribute through all synapses for jj=0,N_A-1 { event_time = stim_times.x[ii] + Ad_delay + Ad_dispersion * r.repick() ampa_Ad_conn[jj].event( event_time ) nmda_Ad_conn[jj].event( event_time ) } } //load C-fiber spike times for ii=0,stim_times.size()-1 { event_time = stim_times.x[ii] // THE C-FIBRES DELAY IS PLACED AFTER THE INTERNEURON TO ALLOW CONTROLED DISPERSION ampa_C_conn.event( event_time ) nmda_C_conn.event( event_time ) nk1_C_conn.event( event_time ) nk1_C_WDR_conn.event( event_time ) } } // SYNAPSES FROM INTERNEURON // ------------------------- N_IC = 20 // number of interneuron (from C) synapses impinging on WDR C_delay = 200.0 // conduction in C-fibres is slower; this is the delay C_dispersion = 20.0 // dispersion in the arrival time of C signals [ms] objref ampar_interneuron[N_IC], nmdar_interneuron[N_IC], gabaar_interneuron[N_IC] objref ampa_interneuron_conn[N_IC], nmda_interneuron_conn[N_IC], gabaa_interneuron_conn[N_IC] objref r r = new Random(123456789) // use a different seed if you need different random streams; the seed used for the figures in the paper was 123456789 for i=0,N_IC-1 { wdr.dendrite ampar_interneuron[i] = new AMPA_DynSyn(0.5) ampar_interneuron[i].tau_fac = 0.1 ampar_interneuron[i].tau_rec = 0.1 ampar_interneuron[i].U1 = 1.0 ampar_interneuron[i].tau_rise = 0.1 ampar_interneuron[i].tau_decay = 5.0 wdr.dendrite nmdar_interneuron[i] = new NMDA_DynSyn(0.5) nmdar_interneuron[i].tau_fac = 0.1 nmdar_interneuron[i].tau_rec = 0.1 nmdar_interneuron[i].U1 = 1.0 nmdar_interneuron[i].tau_rise = 2.0 nmdar_interneuron[i].tau_decay = 100.0 wdr.dendrite gabaar_interneuron[i] = new GABAa_DynSyn(0.5) gabaar_interneuron[i].tau_fac = 0.1 // NOT SUBJECT TO SHORT-TERM PLASTICITY gabaar_interneuron[i].tau_rec = 0.1 gabaar_interneuron[i].U1 = 1.0 gabaar_interneuron[i].tau_rise = 0.1 gabaar_interneuron[i].tau_decay = 10.0 event_time = C_delay + C_dispersion * r.repick() printf("\n C-fibres activations: fibre [%d] - time = %f ms", i, event_time) //netcon = new NetCon(source, target, threshold [mV], delay [ms], weight [uS]) interneuron.hillock ampa_interneuron_conn[i] = new NetCon(&v(0.5), ampar_interneuron[i], -30.0, event_time, 0.00020) //0.00020 interneuron.hillock nmda_interneuron_conn[i] = new NetCon(&v(0.5), nmdar_interneuron[i], -30.0, event_time, 0.00020) //0.00020 interneuron.hillock gabaa_interneuron_conn[i] = new NetCon(&v(0.5), gabaar_interneuron[i], -30.0, event_time+1.0, 0.00020) //+1.0, 0.00020 } // 5 **************************************************************************************************** // PROVIDE NOISE TO THE WDR MEMBRANE POTENTIAL // create source of stimulation for inhibitory and excitatory noise synapses objref stim_inh, stim_exc wdr.soma stim_inh = new NetStim(0.5) stim_inh.interval = 10.0 stim_inh.start = 0.0 stim_inh.number = 1000000 stim_inh.noise = 1.0 wdr.soma stim_exc = new NetStim(0.5) stim_exc.interval = 10.0 stim_exc.start = 0.0 stim_exc.number = 1000000 stim_exc.noise = 1.0 objref gabaar_noise, ampar_noise wdr.soma gabaar_noise = new GABAa_DynSyn(0.5) // inhibitory gabaar_noise.tau_fac = 0.1 gabaar_noise.tau_rec = 0.1 gabaar_noise.U1 = 1.0 gabaar_noise.tau_rise = 0.1 gabaar_noise.tau_decay = 5.0 wdr.soma ampar_noise = new AMPA_DynSyn(0.5) // excitatory ampar_noise.tau_fac = 0.1 ampar_noise.tau_rec = 0.1 ampar_noise.U1 = 1.0 ampar_noise.tau_rise = 0.1 ampar_noise.tau_decay = 5.0 //netcon = new NetCon(source, target, threshold [mV], delay [ms], weight [uS]) objref ampa_noise_conn, gabaa_noise_conn ampa_noise_conn = new NetCon(stim_exc, ampar_noise, -30.0, 0.0, 0.0001) //0.0001 gabaa_noise_conn = new NetCon(stim_exc, gabaar_noise, -30.0, 0.0, 0.0001) //0.0001 //the mean of the noise current is roughly 0.001 mA/cm² //ampa_noise_conn = new NetCon(stim_exc, ampar_noise, -30.0, 0.0, 0.000) //0.000100 //gabaa_noise_conn = new NetCon(stim_inh, gabaar_noise, -30.0, 0.0, 0.000) //0.000429 //the mean of this synaptic noise current (0.000429 GABAA + 0.000100 AMPA) is roughly 0.0 mA/cm²; //the stdev of fluctuations produced in the membrane potential is 0.5226 mV //this assumes a resting potential of -64.8806 mV (E_GABAA=-80mV; E_AMPA=0mV) // 6 **************************************************************************************************** // FINAL COMMANDS // store spike-times objref nc, nil, vec interneuron.soma nc = new NetCon(&v(.5), nil, -30.0, 0.0, 1.0) vec = new Vector() nc.record(vec) // ---------- STORE TOTAL SYNAPTIC CURRENTS ---------- // targeting WDR objref vec_ampar_Ad[N_A], vec_nmdar_Ad[N_A] for s=0,N_A-1 { vec_ampar_Ad[s] = new Vector() vec_ampar_Ad[s].record(&ar_Ad[s].g) vec_nmdar_Ad[s] = new Vector() vec_nmdar_Ad[s].record(&nmdar_Ad[s].g) } objref vec_nk1r_C_WDR vec_nk1r_C_WDR = new Vector() vec_nk1r_C_WDR.record(&nk1r_C_WDR.g) objref vec_ampar_interneuron[N_IC], vec_nmdar_interneuron[N_IC], vec_gabaar_interneuron[N_IC] for s=0,N_IC-1 { vec_ampar_interneuron[s] = new Vector() vec_ampar_interneuron[s].record(&ar_interneuron[s].g) vec_nmdar_interneuron[s] = new Vector() vec_nmdar_interneuron[s].record(&nmdar_interneuron[s].g) vec_gabaar_interneuron[s] = new Vector() vec_gabaar_interneuron[s].record(&gabaar_interneuron[s].g) } //targeting Interneuron objref vec_ampar_C vec_ampar_C = new Vector() vec_ampar_C.record(&ar_C.g) objref vec_nmdar_C vec_nmdar_C = new Vector() vec_nmdar_C.record(&nmdar_C.g) objref vec_nk1r_C vec_nk1r_C = new Vector() vec_nk1r_C.record(&nk1r_C.g) // ----------------------------------------------------------- access wdr.soma load_file("wdr-complete-model.ses") tstop = (n_stim_sets + 1) * T2 + start_time celsius = 36 dt = 0.0125 //has finite representation in binary init() //forall cvode.print_event_queue() run() // write spike times to file "wdr_spike_times.dat" objref fileobj fileobj = new File() fileobj.wopen("wdr_spike_times.dat") vec.printf(fileobj) fileobj.close() // -------- Write total synaptic currents to files ------ // ampar_Ad, nmdar_Ad for s=1,N_A-1 { vec_ampar_Ad[0].add(vec_ampar_Ad[s]) vec_nmdar_Ad[0].add(vec_nmdar_Ad[s]) } objref fileobj fileobj = new File() fileobj.wopen("vec_ampar_Ad.dat") vec_ampar_Ad[0].printf(fileobj) fileobj.close() objref fileobj fileobj = new File() fileobj.wopen("vec_nmdar_Ad.dat") vec_nmdar_Ad[0].printf(fileobj) fileobj.close() // nk1r_C_WDR objref fileobj fileobj = new File() fileobj.wopen("vec_nk1r_C_WDR.dat") vec_nk1r_C_WDR.printf(fileobj) fileobj.close() // ampar_interneuron, nmdar_interneuron, gabaar_interneuron for s=1,N_IC-1 { vec_ampar_interneuron[0].add(vec_ampar_interneuron[s]) vec_nmdar_interneuron[0].add(vec_nmdar_interneuron[s]) vec_gabaar_interneuron[0].add(vec_gabaar_interneuron[s]) } objref fileobj fileobj = new File() fileobj.wopen("vec_ampar_interneuron.dat") vec_ampar_interneuron[0].printf(fileobj) fileobj.close() objref fileobj fileobj = new File() fileobj.wopen("vec_nmdar_interneuron.dat") vec_nmdar_interneuron[0].printf(fileobj) fileobj.close() objref fileobj fileobj = new File() fileobj.wopen("vec_gabaar_interneuron.dat") vec_gabaar_interneuron[0].printf(fileobj) fileobj.close() // nk1r_C objref fileobj fileobj = new File() fileobj.wopen("vec_nk1r_C.dat") vec_nk1r_C.printf(fileobj) fileobj.close() // ampar_C objref fileobj fileobj = new File() fileobj.wopen("vec_ampar_C.dat") vec_ampar_C.printf(fileobj) fileobj.close() // nmdar_C objref fileobj fileobj = new File() fileobj.wopen("vec_nmdar_C.dat") vec_nmdar_C.printf(fileobj) fileobj.close() //************************************************************************************ //UNITS //Category Variable Units //Time t [ms] //Voltage v [mV] //Current i [mA/cm2] (distributed) [nA] (point process) //Concentration ko, ki, etc. [mM] //Specific capacitance cm [uf/cm2] //Length diam, L [um] //Conductance g [S/cm2] (distributed) [uS] (point process) //Cytoplasmic resistivity Ra [ohm cm] //Resistance Ri [10E6 ohm]