Python and NEURON scripts for running network simulations of reduced-morphology layer V pyramidal cells. Tuomo Maki-Marttunen, 2015-2018 CC BY 4.0 HOC-commands for simulations including in vivo-like synaptic firing based on (Hay & Segev 2015, "Dendritic excitability and gain control in recurrent cortical microcircuits", Cerebral Cortex 25(10): 3561-3571) Library of variants based on (Maki-Marttunen et al. 2016, "Functional Effects of Schizophrenia-Linked Genetic Variants on Intrinsic Single-Neuron Excitability: A Modeling Study", Biol Psychiatry Cogn Neurosci Neuroimaging. 2016 Jan 1;1(1):49-59. Files included: CaDynamics_E2.mod #mod file for Intracellular Ca dynamics Ca_HVA.mod #mod file for HVA Ca currents Ca_LVAst.mod #mod file for LVA Ca currents Ih.mod #mod file for HCN current Im.mod #mod file for M-current K_Pst.mod #mod file for persistent K current K_Tst.mod #mod file for transient K current NaTa_t.mod #mod file for transient Na current Nap_Et2.mod #mod file for persistent Na current ProbAMPANMDA2.mod #mod file for probabilistic glutamatergic synapse ProbAMPANMDA2group.mod #mod file for probabilistic glutamatergic synapse group ProbAMPANMDA2groupdet.mod #mod file for probabilistic glutamatergic synapse group with pre-determined activation times ProbUDFsyn2.mod #mod file for probabilistic GABAergic synapse ProbUDFsyn2group.mod #mod file for probabilistic GABAergic synapse group ProbUDFsyn2groupdet.mod #mod file for probabilistic GABAergic synapse group with pre-determined activation times README.html #This file SK_E2.mod #mod file for SK current SKv3_1.mod #mod file for Kv3.1 potassium current approxhaynetstuff.py #Python library for running simulations with reduced-morphology L5PCs calcEEG.py #Python file for predicting the EEG signal. For spikes*.sav that have already been combined calcEEG_uncombined.py #Python file for the EEG signal. For spikes*.sav that have not been combined (assumes they were run single-thread) calcmutgains.py #Python file for running non-oscillatory simulations of single variants calcmutgains_comb.py #Python file for running non-oscillatory simulations of variant combinations calcmutoscs.py #Python file for running oscillatory simulations of single variants calcmutoscs_comb.py #Python file for running oscillatory simulations of variant combinations calcspectra.py #Python file for calculating the power spectrum of the population spike trains (single variants) calcspectra_comb.py #Python file for calculating the power spectrum of the population spike trains (variant combinations) combinemutgains_parallel.py #Python file for combining simulation results (single-variant, non-oscillatory) combinemutgains_parallel_comb.py #Python file for combining simulation results (variant combination, non-oscillatory) combinemutgains_parallel_withLFP.py #Python file for combining simulation results (single-variant, non-oscillatory, with recording of dipole moments) combinemutoscs_parallel.py #Python file for combining simulation results (single-variant, oscillatory) combinemutoscs_parallel_comb.py #Python file for combining simulation results (variant combination, oscillatory) drawfig1ab.py #Python file for drawing simulated results (Fig. 1A--B) drawfig1c.py #Python file for drawing simulated results (Fig. 1C) drawfig2ab.py #Python file for drawing simulated results (Fig. 2A--B) drawfig2c.py #Python file for drawing simulated results (Fig. 2C) drawstationary_EEG.py #Python file for plotting single-cell simulation results with dipole moments and EEG signal (Fig. 4A--C) drawstationary_EEG_pop.py #Python file for plotting network simulation results with dipole moments and EEG signal (Fig. 4D--F) mutation_stuff.py #Python library for the effects of SNP-like SCZ-associated variants mytools.py #Python library, general tools runmanycellsLFP.py #Python file for running a single cell simulation with recording of dipole moments runsinglecellLFP.py #Python file for running a network simulation with recording of dipole moments saveisidists.py #Python file for saving the ISI distributions (needed for making isidist*.sav) savespikesshufflephases.py #Python file for saving oscillatory Poisson ISIs (needed for making isidist*.sav) simosc_parallel.py #Python library, main simulation code for oscillatory simulations (single variants) simosc_parallel_comb_varconn.py #Python library, main simulation code for oscillatory simulations (variant combinations) simseedburst_func.py #Python library, main simulation code for nonoscillatory simulations (single variants) simseedburst_func_comb_varconn.py #Python library, main simulation code for nonoscillatory simulations (variant combinations) simseedburst_func_withLFP.py #Python library, main simulation code for nonoscillatory simulations, including the recording of dipole moments models #Directory with HOC files pars_withmids_combfs_final.sav #Data file with parameters for the reduced-morphology L5PCs scalings_cs.sav #Data file with scaling coefficients for each variant of mutation_stuff.py To run NEURON simulation of the network model and plot the results (Figure 1), run the following commands: ################ Initialization ################ NUMP=1 #How many CPUs do you want to use in parallel? Change this to speed up simulations (in single thread, one #network simulation took me approximately 2 hours). LASTSEED=0 #In this example, only one repetition used in most simulations. Note that in the article normally 5-15 #repetitions used, and at times much larger. Change this to get more accurate predictions. nrnivmodl #Compile the mechanisms ########## Simulations for Fig 1 A--B ########## # If your NEURON installation does not support running scripts in the "nrniv -python" manner, try either of the following: # 1) Replace "nrniv" by the full path to the binary (typically NEURON_INSTALLATION_DIRECTORY/nrn/x86_64/bin/nrniv # 2) Replace "mpirun -np $NUMP nrniv -python -mpi PYTHON_SCRIPT.py" by a single-CPU run "python PYTHON_SCRIPT.py NULL NULL NULL". # The three gibberish arguments are necessary as the scripts (calcmutgains*.py and calmutoscs*.py) consider the arguments from # the 4th argument on. Thus, the first simulation below would be "python calcmutgains.py NULL NULL NULL 0 $irate 0" rates=( 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 ) #Rate coefficient array seeds=( `seq 1 200` ) #Seed array for (( irate=0; irate<${#rates[@]}; irate++ )); #Go through the rate array do mpirun -np $NUMP nrniv -python -mpi calcmutgains.py 0 $irate 0 #Main simulation (control) python combinemutgains_parallel.py 0 $irate 0 $NUMP #Combine results (needed if # many CPUs were used) echo "rm spikes_parallel_5_11000_0_0.00039_0.0006_${rates[irate]}_1.07_1.07_${seeds[iseed]}_*_of_150.sav" #Remove the uncombined rm spikes_parallel_5_11000_0_0.00039_0.0006_${rates[irate]}_1.07_1.07_${seeds[iseed]}_*_of_150.sav # data files. done mpirun -np $NUMP nrniv -python -mpi calcmutgains.py 70 6 0 #Main simulation (variant) python combinemutgains_parallel.py 70 6 0 $NUMP #Combine results echo "rm spikes_parallel_5_11000_70_0.00039_0.0006_1.0_1.07_1.07_${seeds[iseed]}_*_of_150.sav" #Remove the uncombined rm spikes_parallel_5_11000_70_0.00039_0.0006_1.0_1.07_1.07_${seeds[iseed]}_*_of_150.sav # data files. python drawfig1ab.py #Plot the results (Fig1A,B) ############ Simulations for Fig 1 C ########### # Note that simulations in ../haymod have to # # be performed in advance # ################################################ MS=( 0 125 126 127 128 189 190 191 192 293 294 295 296 313 314 315 316 333 334 335 336 369 370 371 372 421 422 423 424 441 442 443 444 ) MCS=( 0 1 2 3 ) for iseed in `seq 0 $LASTSEED`; do #Single-variant simulations: for (( iimut=0; iimut<${#MS[@]}; iimut++ )); do imut=${MS[iimut]} for (( irate=0; irate<${#rates[@]}; irate++ )); do mpirun -np $NUMP nrniv -python -mpi calcmutgains.py $imut $irate $iseed python combinemutgains_parallel.py $imut $irate $iseed $NUMP echo "rm spikes_parallel_5_11000_${imut}_0.00039_0.0006_${rates[irate]}_1.07_1.07_${seeds[iseed]}_*_of_150.sav" rm spikes_parallel_5_11000_${imut}_0.00039_0.0006_${rates[irate]}_1.07_1.07_${seeds[iseed]}_*_of_150.sav done done #Combination simulations: for (( iimut=0; iimut<${#MCS[@]}; iimut++ )); do imut=${MCS[iimut]} for (( irate=0; irate<${#rates[@]}; irate++ )); do mpirun -np $NUMP nrniv -python -mpi calcmutgains_comb.py $imut $irate $iseed python combinemutgains_parallel_comb.py $imut $irate $iseed $NUMP echo "rm spikes_parallel_5_11000_comb${imut}_5.0_NsynE10000_NsynI2500_0.00039_0.0006_${rates[irate]}_1.07_1.07_${seeds[iseed]}_*_of_150.sav" rm spikes_parallel_5_11000_comb${imut}_5.0_NsynE10000_NsynI2500_0.00039_0.0006_${rates[irate]}_1.07_1.07_${seeds[iseed]}_*_of_150.sav done done done python drawfig1c.py ########## Simulations for Fig 2 A--B ########## # In order to model the L5PC network response to oscillations, we need the cumulative probability functions # of intervals between synaptic activation times (these do not anymore follow exponential distribution as # in the case of stationary Poisson inputs). The values of the cumulative probability functions are pre-saved # in files isidists_XXX_0.25.sav (0.25 referring to the fact that the lambda term oscillated +-25%) for each # phase of the oscillation; these files can be downloaded in Open Science Framework (https://osf.io/2k5ub/). # Alternatively, the event times of oscillatory Poisson processes could be generated on the fly in the main # simulation script using mytools.oscillatorypoissontimeseries(), but if the same oscillation frequency is # used many times, it turns out to be more efficient to save the cumulative probability functions of the # inter-event intervals for each phase of the oscillation and sample from that distribution. wget https://osf.io/zv29k/download # zipped file size 200 MB mv download isidists.tar.gz # This is the original name of the file tar xvfz isidists.tar.gz # NB: This will need an extra 4 GB of space! If you only want to simulate # panel B, only extract isidists_1.5_0.25.sav, and if you # want to simulate panel A but not C, choose the isidist files of the 17 # frequencies needed and remove the rest # Alternatively, these files can be generated from scratch as follows (this is a heavy operation): FREQARRAY=( 0.5 0.625 0.75 0.875 1.0 1.25 1.5 1.75 2.0 2.5 3.0 3.5 4.0 5.0 7.5 10.0 15.0 ) for (( iosc=0; iosc<${#FREQARRAY[@]}; iosc++ )); #Go through the frequency array do for (( iphase=0; iphase<50; iphase++ )); #Go through 50 phases do #For each of the 50 phases, simulate python savespikesshufflephases.py $iphase 12000 ${FREQARRAY[iosc]} 0.25 #oscillatory Poisson trains of events. done # python saveisidists.py ${FREQARRAY[iosc]} 0.25 #Save the inter-event distributions done #to files isidists_$freq_0.25.sav # The simulation of L5PC network activity in the presence of oscillations in the backround synaptic firing # starts here. FREQARRAY=( 0.5 0.625 0.75 0.875 1.0 1.25 1.5 1.75 2.0 2.5 3.0 3.5 4.0 5.0 7.5 10.0 15.0 ) seeds=( `seq 1 200` ) #Seed array for (( iosc=0; iosc<${#FREQARRAY[@]}; iosc++ )); #Go through the frequency array do mpirun -np $NUMP nrniv -python -mpi calcmutoscs.py 0 $iosc 0 #Main simulation (control) python combinemutoscs_parallel.py 0 $iosc 0 $NUMP #Combine results (needed if # many CPUs were used) echo "rm spikes_parallel_osc${FREQARRAY[iosc]}_5_11000_0_0.00039_0.0006_1.0_1.07_1.07_${seeds[iseed]}_*_of_150.sav" #Remove the uncombined rm spikes_parallel_osc${FREQARRAY[iosc]}_5_11000_0_0.00039_0.0006_1.0_1.07_1.07_${seeds[iseed]}_*_of_150.sav # data files. done mpirun -np $NUMP nrniv -python -mpi calcmutoscs.py 70 6 0 #Main simulation (variant) python combinemutoscs_parallel.py 70 6 0 $NUMP #Combine results echo "rm spikes_parallel_osc1.5_5_11000_70_0.00039_0.0006_1.0_1.07_1.07_${seeds[iseed]}_*_of_150.sav" #Remove the uncombined rm spikes_parallel_osc1.5_5_11000_70_0.00039_0.0006_1.0_1.07_1.07_${seeds[iseed]}_*_of_150.sav # data files. for (( iosc=0; iosc<${#FREQARRAY[@]}; iosc++ )); #Go through the frequency array do python calcspectra.py 0 ${FREQARRAY[iosc]} #Calculate the power spectrum of the control #network's population spike train response #Saves spectrum_freq*_0.sav done python calcspectra.py 70 1.5 #Calculate the spectra for variant network #Saves spectrum_freq1.5_70.sav python drawfig2ab.py #Plot the results (Fig1A,B) ############ Simulations for Fig 2 C ########### MS=( 0 125 126 127 128 189 190 191 192 293 294 295 296 313 314 315 316 333 334 335 336 369 370 371 372 421 422 423 424 441 442 443 444 ) MCS=( 0 1 2 3 ) for iseed in `seq 0 $LASTSEED`; do #Single-variant simulations: for (( iimut=0; iimut<${#MS[@]}; iimut++ )); do imut=${MS[iimut]} for (( iosc=0; iosc<${#FREQARRAY[@]}; iosc++ )); do mpirun -np $NUMP nrniv -python -mpi calcmutoscs.py $imut $iosc $iseed python combinemutoscs_parallel.py $imut $iosc $iseed $NUMP echo "rm spikes_parallel_osc${FREQARRAY[iosc]}_5_11000_${imut}_0.00039_0.0006_1.0_1.07_1.07_${seeds[iseed]}_*_of_150.sav" rm spikes_parallel_osc${FREQARRAY[iosc]}_5_11000_${imut}_0.00039_0.0006_1.0_1.07_1.07_${seeds[iseed]}_*_of_150.sav done done #Combination simulations: for (( iimut=0; iimut<${#MCS[@]}; iimut++ )); do imut=${MCS[iimut]} for (( iosc=0; iosc<${#FREQARRAY[@]}; iosc++ )); do mpirun -np $NUMP nrniv -python -mpi calcmutoscs_comb.py $imut $iosc $iseed python combinemutoscs_parallel_comb.py $imut $iosc $iseed $NUMP echo "rm spikes_parallel_osc${FREQARRAY[iosc]}_5_11000_comb${imut}_5.0_NsynE10000_NsynI2500_0.00039_0.0006_1.0_1.07_1.07_${seeds[iseed]}_*_of_150.sav" rm spikes_parallel_osc${FREQARRAY[iosc]}_5_11000_comb${imut}_5.0_NsynE10000_NsynI2500_0.00039_0.0006_1.0_1.07_1.07_${seeds[iseed]}_*_of_150.sav done done done #Calculate the spectra for each variant and each frequency: for (( iosc=0; iosc<${#FREQARRAY[@]}; iosc++ )); do for (( iimut=0; iimut<${#MS[@]}; iimut++ )); do python calcspectra.py ${MS[iimut]} ${FREQARRAY[iosc]} #Saves spectrum_freq*_${MS[iimut]}.sav done python calcspectra_comb.py ${FREQARRAY[iosc]} #Saves spectrum_freq*_comb0.sav done python drawfig2c.py ########## Simulations for Fig 4 A--F ########## # In order to model the EEG signature of the neuron population, we use a slightly modified simulation script # (simseeburst_func_withLFP.py). This script uses the functionality of the LFPy toolbox, where the main # NEURON simulation loop is replaced by our own step-by-step simulation loop that calculates and stores all # dipole moments. This script does not need LFPy to be installed, but the parts of LFPy that were needed are # hard-coded in the script. From the output of this script, we calculate the EEG signature of the population. # This, by contrast, requires that LFPy be installed (see https://lfpy.github.io/) # # Note that while the above parts work fine with NEURON 7.4, the part below requires NEURON 7.5 due to the # use_fast_imem() functionality of the CVode. python runsinglecellLFP.py # This is a rather light operation as it is only one cell simulated for 11000 ms. python calcEEG_uncombined.py spikes_parallel_5_11000_0_0.00039_0.0006_1.0_1.07_1.07_1_0_of_1_withLFP.sav # Calculates the EEG signature using the head model of four concentric spheres. # Saves to spikes_parallel_5_11000_0_0.00039_0.0006_1.0_1.07_1.07_1_0_of_1_withLFP_EEG.sav python drawstationary_EEG.py 1 # Draws the results (Fig 4 A--C) python runmanycellsLFP.py # This takes several hours on an average PC. To speed up use an alternative # mpirun -np $NUMP nrniv -python -mpi runmanycellsLFP.py (but then the # NUMP argument in the following line should also be set to $NUMP, i.e. #python combinemutgains_parallel_withLFP.py 0 6 0 $NUMP python combinemutgains_parallel_withLFP.py 0 6 0 1 # Saves spikes_parallel150_mutID0_1.0_gNoise1.07_gsyn1.07_seed1_withLFP.sav python calcEEG.py spikes_parallel150_mutID0_1.0_gNoise1.07_gsyn1.07_seed1_withLFP.sav # Calculates the EEG signature using the head model of four concentric spheres. # Saves to spikes_parallel150_mutID0_1.0_gNoise1.07_gsyn1.07_seed1_withLFP_EEG.sav python drawstationary_EEG_pop.py 1 # Draws the results (Fig 4 D--E)