/* Author: Johannes Luthman This file connects the synapses and the corresponding stimulus elements, and then steps the simulation forward in the runSimulation() proc. Subroutines in this file: main: DCNrun() setupSimulation() runSimulation() isItTimeToSaveTrace() getSizeOfTraceVectors() */ objref oRndInh, oRndExc objref gammaStimPC[PCtoDCNconvergence] objref netconPC[INHTOTALSYNAPSES] // Declare instances of the GammaStim objects for excitatory synapses // (1 GammaStim activates 1 AMPA + 1 fNMDA + 1 sNMDA) and the corresponding // NetCon objects (=1 each for AMPA, fNMDA, and sNMDA). objref gammaStimExc[EXCTOTALSYNAPSES] objref netconExc[3 * EXCTOTALSYNAPSES] /////////////////////////////////////////////////////////////// proc DCNrun() { load_file("DCN_recording.hoc") setupSimulation() runSimulation() } proc setupSimulation() { // Work around the error that sets in when both tTraceStart and tTraceStop = 0 // (the latter setting is used to not record any traces). if (tTraceStop[0] == 0) { tTraceStart[0] = 1 } // Set up size of recording vectors. nRecVectElements = int(runTime/recInterval) + 2 //+1 is ok for recInterval=100us, // but +2 is needed for recInterval=50us. stepsPerRec = int(recInterval/dt) // Set up a different size for the trace vectors. if (tTraceStop[0] > 0) { recordTraces = 1 sizeVectorOfTrace = getSizeOfTraceVectors() } else { recordTraces = 0 } } // end of proc setupSimulation() proc runSimulation() { // Set up the excitatory synapses oRndExc = new Random() oRndExc.ACG(randomiserSeed) // Add GammaStims and connect them with the synaptic mechanisms using NetCons. // As an ARTIFICIAL_CELL, it doesn't matter where a GammaStim.mod is placed. // For convenience, I place all the GammaStims in the soma. for (c=0; c < EXCTOTALSYNAPSES; c+=1) { soma gammaStimExc[c] = new GammaStim(0.5) gammaStimExc[c].start = 0 gammaStimExc[c].noise = noiseFractionExcSyn gammaStimExc[c].duration = runTime gammaStimExc[c].order = gammaOrderExc gammaStimExc[c].refractoryPeriod = refractoryPeriodExc } // Set up the excitatory NetCons. ncIndex = 0 for (c=0; c < EXCTOTALSYNAPSES; c+=1) { // Create three NetCons for each excitatory GammaStim to connect it // to the ampa and the two nmda receptors. netconExc[ncIndex] = new NetCon(gammaStimExc[c], ampa[c]) netconExc[ncIndex].threshold = 0 //mV netconExc[ncIndex].weight = gAMPA netconExc[ncIndex+1] = new NetCon(gammaStimExc[c], fnmda[c]) netconExc[ncIndex+1].threshold = 0 //mV netconExc[ncIndex+1].weight = gfNMDA netconExc[ncIndex+2] = new NetCon(gammaStimExc[c], snmda[c]) netconExc[ncIndex+2].threshold = 0 //mV netconExc[ncIndex+2].weight = gsNMDA ncIndex = ncIndex + 3 } // Set up the inhibitory synapses // For synapses not incorporating synaptic depression, set the max GABA // conductance to equal what is reached for depressed synapses on // completely regular input at the used input frequency. if (useGABAsyndep == 0) { // The following calculation is the same as in DCN_mechs.hoc where it's explained: initDeprLevel = 0.08 + 0.60*exp(-2.84*inhibitoryHz) + 0.32*exp(-0.02*inhibitoryHz) gGABA = gGABA*initDeprLevel } oRndInh = new Random() oRndInh.ACG(randomiserSeed) for (c=0; c 0) { iRecTrace = 0 } // Counter for when to record variables ndtSinceRecording = stepsPerRec InstantiateRecObjects() // procedure in file DCN_recording.hoc SetupOutputFiles() // procedure in file DCN_recording.hoc t = 0 finitialize (vInit) // Set properties of the inhibitory GammaStim elements if (inhibitoryHz > 0) { intervalInh = 1000 / inhibitoryHz delayInh = oRndInh.uniform(0, intervalInh) } else { // No inhibitory input is to be provided - set delay so the // first spike occurs outside of the simulation time. intervalInh = 1e5 delayInh = runTime } for (c=0; c < PCtoDCNconvergence; c+=1) { gammaStimPC[c].interval = intervalInh } // Set delays of the inhibitory netCons. counterOfNetCons = 0 for (cGABA=0; cGABA < INHTOTALSYNAPSES; cGABA=cGABA+1) { netconPC[cGABA].delay = delayInh if (counterOfNetCons == (nDCNsynsPerPC-1)) { if (inhibitoryHz > 0) { delayInh = oRndInh.repick() } counterOfNetCons = 0 } else { counterOfNetCons+=1 } } // Excitatory synaptic inputs if (excitatoryHz > 0) { intervalExc = 1000 / excitatoryHz delayExc = oRndExc.uniform(0, intervalExc) } else { // No excitatory input is to be provided - set delay so the // first spike occurs outside of the simulation time. intervalExc = 1e5 delayExc = runTime } for (c=0; c < EXCTOTALSYNAPSES; c+=1) { gammaStimExc[c].interval = intervalExc } // Set delay for this stage. for (c=0; c < (3 * EXCTOTALSYNAPSES); c=c+3) { if (excitatoryHz > 0) { delayExc = oRndExc.repick() } netconExc[c].delay = delayExc netconExc[c+1].delay = delayExc netconExc[c+2].delay = delayExc } // Step through the simulation while (t < runTime) { // Write variables to vectors if the time interval since the last recording // has been reached if (ndtSinceRecording == stepsPerRec) { writeToTimeAndVoltVectors() // procedure in file DCN_recording.hoc iRecTimeVolt+=1 if (recordTraces == 1) { if (isItTimeToSaveTrace() == 1) { writeToTraceVectors() iRecTrace = iRecTrace+1 } } ndtSinceRecording = 0 } fadvance() ndtSinceRecording+=1 } // Save any recordings of traces to file (they're usually set to only a small interval // of the whole simulation, making it more efficient to save all of it here at the end. if (recordTraces == 1) { writeTracesToFile() // procedure in file DCN_recording.hoc } writeSpikeTimesToFile() } // end of "proc runSimulation()". func isItTimeToSaveTrace() { local subBoolean // Check if the current time is within the time frame set in DCN_simulation.hoc // for recording of the traces (there's no "exit for" in hoc..) subBoolean = 0 for (c=0; c < nStepsSaveTrace; c+=1) { if (t>=tTraceStart[c] && t<=tTraceStop[c]) { subBoolean = 1 } } return subBoolean } func getSizeOfTraceVectors() { local subC, subSumIndeces // For each step of recording the full voltage/current trace/s, calculate // how many vector indeces will be needed for it. In the following, // +1 is to get the extra index a exactly time // tTraceStart[subC]. subSumIndeces = 0 for (subC=0; subC < nStepsSaveTrace; subC=subC+1) { subSumIndeces = subSumIndeces + int((tTraceStop[subC] - tTraceStart[subC]) \ / recInterval) + 2 } return int(subSumIndeces) } func getPCtoDCNdelay() { local subTemp, subMean, subSD subMean = $1 subSD = $2 if (subSD >= 0.000001) { subTemp = oRndInh.repick() while (subTemp < 0) { subTemp = oRndInh.repick() } } else { subTemp = subMean } return subTemp } xpanel("Luthman et al. 2011") xbutton("DCNrun()","DCNrun()") xpanel()