CA1 pyramidal neuron: as a 2-layer NN and subthreshold synaptic summation (Poirazi et al 2003)

 Download zip file   Auto-launch 
Help downloading and running models
Accession:20212
We developed a CA1 pyramidal cell model calibrated with a broad spectrum of in vitro data. Using simultaneous dendritic and somatic recordings, and combining results for two different response measures (peak vs. mean EPSP), two different stimulus formats (single shock vs. 50 Hz trains), and two different spatial integration conditions (within vs. between-branch summation), we found the cell's subthreshold responses to paired inputs are best described as a sum of nonlinear subunit responses, where the subunits correspond to different dendritic branches. In addition to suggesting a new type of experiment and providing testable predictions, our model shows how conclusions regarding synaptic arithmetic can be influenced by an array of seemingly innocuous experimental design choices.
References:
1 . Poirazi P, Brannon T, Mel BW (2003) Arithmetic of subthreshold synaptic summation in a model CA1 pyramidal cell. Neuron 37:977-87 [PubMed]
2 . Poirazi P, Brannon T, Mel BW (2003) Pyramidal neuron as two-layer neural network. Neuron 37:989-99 [PubMed]
3 . Poirazi P, Brannon T, Mel BW (2003ab-sup) Online Supplement: About the Model Neuron 37 Online:1-20
4 . Polsky A, Mel BW, Schiller J (2004) Computational subunits in thin dendrites of pyramidal cells. Nat Neurosci 7:621-7 [PubMed]
Model Information (Click on a link to find other models with that property)
Model Type: Neuron or other electrically excitable cell;
Brain Region(s)/Organism:
Cell Type(s): Hippocampus CA1 pyramidal GLU cell;
Channel(s): I Na,p; I Na,t; I L high threshold; I T low threshold; I A; I K; I M; I h; I K,Ca; I Calcium;
Gap Junctions:
Receptor(s): GabaA; GabaB; NMDA; Glutamate;
Gene(s):
Transmitter(s):
Simulation Environment: NEURON;
Model Concept(s): Action Potential Initiation; Activity Patterns; Dendritic Action Potentials; Active Dendrites; Influence of Dendritic Geometry; Detailed Neuronal Models; Action Potentials; Depression; Delay;
Implementer(s): Poirazi, Panayiota [poirazi at imbb.forth.gr];
Search NeuronDB for information about:  Hippocampus CA1 pyramidal GLU cell; GabaA; GabaB; NMDA; Glutamate; I Na,p; I Na,t; I L high threshold; I T low threshold; I A; I K; I M; I h; I K,Ca; I Calcium;
// This experiment is used to study the effect of synapse clustering
// on the firing rate of our model cell. To this end, we perform a gradual
// dispersion of 32 or 40 synaptic contacts onto the thin oblique dendrites.  We start 
// with the optimal number of clusters (4 or 5) each consisting of the optimal 
// number of synapses (6 or 2) and in each step we destroy one cluster and disperse
// it's synapses until we end up with no intact clusters.
// Type of inhibition included: 11 gabaa/gabab synapses, 5 in soma sections and 6 every
// 60um along the apical trunk 

// Synchronous (synch=1) or asynchronous (synch=0) cases can also be tested
// In this experiment we can also include background synapses (50 excitatory and 50 inhibitory)
// firing in 5Hz for the entire duration of the experiments to account for background activity

BACK_GROUND = 0 // set to 1 when using background synapses
synch = 0        // synapses are stimulated randomly (NOT synchronously), set to 1 for synchronous stimulation

//load_proc("nrnmainmenu")
//load_template("ExperimentControl")         // load needed templates
//load_template("EPSPTuning")
//load_template("RangeRef")
load_file("nrngui.hoc")
load_file("../../template/load_templates.hoc")

objref econ                               // initialize template parameters
show_errs=1
debug_lev=1
econ=new ExperimentControl(show_errs,debug_lev)
econ.self_define(econ)
econ.morphology_dir = "../../morphology/n123"                                 // set location for morphology files
econ.add_lib_dir("Terrence","../../lib")                                      // set location for library files
econ.generic_dir    = "../../experiment/"                                     // set location for cell-setup file
econ.data_dir       = "data"                                                  // set directory to store data
strdef tips_dir
tips_dir = "../single-branch-potency/data/Apical_Tips" // set directory with single branch
sprint(econ.syscmd, "mkdir -p %s", econ.data_dir)                             // 50 Hz stimulation results
system(econ.syscmd)

actual_resolution=75                                                          // maximum nseg number 
desired_resolution=1

econ.xopen_geometry_dependent("cell")                                         // load raw cell morphology	
econ.xopen_geometry_dependent("cell-analysis")                                // load user-defined semantics on morphology 
cell_analysis(econ) 

printf("Opening cell setup\n")                                   
econ.xopen_generic("cell-setup")                                              // load cell-setup to
printf("Opened. Setting up cell\n")                                           // specify all mechanisms,
maximum_segment_length=actual_resolution                                      // membrane properties etc	 
cell_setup(econ)

// Set simulation parameters for the experiment

econ.defvar("Simulation Control", "tstop", "600", "Defines when the simulation stops.")
econ.defvar("Simulation Control", "dt", "0.1", "Timestep")
econ.defvar("Simulation Control", "steps_per_ms", "10", "How many points are plotted per ms")
setdt()

// open files with NMDA/AMPA, GABA_A/AMPA and GABA_B/GABA_B ratios
econ.xopen_geometry_dependent("nmda-ampa-ratio")
econ.xopen_geometry_dependent("gabab-gabaa-uniform-ratio")  // use to estimate GABA_A, GABA_B conductances

// Open file with tuned AMPA conductance values for all sections
objref tune_epsp_list
tune_epsp_list=new List()
strdef tunings_file
sprint(tunings_file, "%s", "tunings")
xopen("../tune-synapses/tunings.dat")

// Open library functions that will be needed
econ.xopen_library("Terrence","choose-secs")    // used to randomly select sections from a list
econ.xopen_library("Terrence","salloc")         // used to allocate synapses on sections
econ.xopen_library("Terrence","deduce-ratio")   // used to extract NMDA/AMPA, GABA_A/AMPA and GABA_B/GABA_B ratios
econ.xopen_library("Terrence","basic-graphics") // used to plot graphics 
econ.xopen_library("Terrence","spikecount")     // used to count spikes
load_template("SynapseBand")                    // template for making bands of synapses

init_cluster_number = 4                        // number of full-sized clusters of synapses
init_cluster_size = 8   //=6+2                   // number of synapses per cluster is 6 or 2
disp_size = 1                                   // dispersion step size, disperse one cluster at a time 

// init_cluster_number = 5                        // number of full-sized clusters of synapses
// init_cluster_size = 8   //=6+2                   // number of synapses per cluster is 6 or 2
// disp_size = 1                                   // dispersion step size, disperse one cluster at a time 

gmax_default = 0.0005                           // GABA_A explicit conductance value (S/cm^2)
gmaxb_default = gmax_default/3                  // GABA_B explicit conductance value (S/cm^2)
all_synapses=init_cluster_size*init_cluster_number     // total number of AMPA/NMDA synapses used 
gaba_synapses = 100                                    // maximum number of GABA synapses used  
// used with background synapses
back_syne = 50
back_syni = 50
 
 
objref input, co
input = new Vector()
co = new Vector()

experiments = init_cluster_number/disp_size + 1                 // number of experiments to run
 
print "Number of experiments ", experiments
double exp_ta[experiments]

for i=0, experiments-1  {
  exp_ta[i]=   init_cluster_number - i*disp_size      // number of intact clusters
  printf("-----------------------------------\n")       
  printf("Experiment %d\n", i)
  printf("Number of Intact Clusters: %d\n", exp_ta[i] )   
  }


// define variables
objref  vf, vf2, vf3, tmpo, vrec, spikevec, band, vrec, splot, rpid, i_nmda[40], g
objref ampa[all_synapses], nmda[all_synapses], gabaa[gaba_synapses], gabab[gaba_synapses]
objref ampa_bg[back_syne], nmda_bg[back_syne], gabaa_bg[back_syni], gabab_bg[back_syni]
objref apical_tipl, cluster2_list,  cluster6_list, random_list, inh_list
strdef tmpstr, tmpstr2, Fc
Deadtime_GLU=dt
Deadtime_NMDA=dt
Deadtime_GABAa=dt
Deadtime_GABAb=dt

//                                   Cluster allocation proceedure
//--------------------------------------------------------------------------------------------------------

proc cluster_salloc() { local cluster_size, cluster_amount, b, b2
   cluster_size=$2                  // number of synapses per cluster
   cluster_amount=$3                // number of clusters

   sprint(tmpstr, "%s/cluster6-sections", econ.data_dir)   // open file to store the name of branches containing a cluster
   vf = new File()
   vf.wopen(tmpstr)
   sprint(tmpstr, "%s/cluster2-sections", econ.data_dir)   // open file to store the name of branches containing a cluster
   vf3 = new File()
   vf3.wopen(tmpstr)

// For cluster_amount clusters, pick a different branch and put synapses on it

   cluster6_list = new SectionList()
   cluster2_list = new SectionList()
   for b=0,cluster_amount-1 {
       $o1.pick_and_remove()           // select a branch to put a cluster of synapses on
       cluster6_list.append()          // store selected branches in a list
       vf.printf("%s\n", secname())    // print branch name in file with cluster-section names
        
       $o1.pick_and_remove()           // select a branch to put a cluster of synapses on
       cluster2_list.append()          // store selected branches in a list
       vf3.printf("%s\n", secname())    // print branch name in file with cluster-section names


//     sprint(tmpstr,"%s.v(0.5)", secname())       
//     if (b < 4) {
//         addgraph(tmpstr,-70,0)
//     }
   }
   
// distribute synapses uniformly along each branch in each cluster
   forsec cluster6_list {
       cluster_size = 6
       nseg = cluster_size

       for b2=1,cluster_size {

          posn=(2*b2 -1)/(2*cluster_size)             // define location for a new synapse  	  
          ampa[synapses_alloced]=new GLU(posn)        // insert an AMPA mechanism at the above location 
          nmda[synapses_alloced]=new NMDA(posn)       // insert an NMDA mechanism at the above location
                                                      // allocate mechanisms and plot on shape graph 
          salloc2(ampa[synapses_alloced],nmda[synapses_alloced],posn,1,splot,COLOR+1) 
          synapses_alloced = synapses_alloced + 1     // update the counter of AMPA/NMDA synapses allocated
 
        }

   }
  
  forsec cluster2_list {
       cluster_size = 2
       nseg = cluster_size
       for b2=1,cluster_size {

          posn=(2*b2 -1)/(2*cluster_size)             // define location for a new synapse  
          ampa[synapses_alloced]=new GLU(posn)        // insert an AMPA mechanism at the above location 
          nmda[synapses_alloced]=new NMDA(posn)       // insert an NMDA mechanism at the above location
                                                      // allocate mechanisms and plot on shape graph 
          salloc2(ampa[synapses_alloced],nmda[synapses_alloced],posn,1,splot,COLOR+3) 
          synapses_alloced = synapses_alloced + 1     // update the counter of AMPA/NMDA synapses allocated
 
        }

    }
    

//  Randomly distribute remaining synapses on the remaining obliques
     
     sprint(tmpstr2, "%s/random-sections", econ.data_dir)
     vf2 = new File()                                 // open file to store the name of branches with random   
     vf2.wopen(tmpstr2)                               // number of synapses on 
     cluster_size=$2   
     for b=0, (all_synapses - cluster_size*cluster_amount)-1 {
 
       $o1.pick()                                     // pick a branch
       nseg = cluster_size                            // set number of segments = number of synapses in cluster
       vf2.printf("%s random_list.append()\n", secname()) // print branch name in file with random-sections names     
       ampa[synapses_alloced]=new GLU(0.5)            // insert an AMPA mechanism in the middle of the branch
       nmda[synapses_alloced]=new NMDA(0.5)           // insert an NMDA mechanism in the middle of the branch
                                                      // allocate mechanisms and plot on shape graph 
       salloc2(ampa[synapses_alloced],nmda[synapses_alloced],0.5,1,splot,COLOR)
       synapses_alloced=synapses_alloced+1            // update the counter of AMPA/NMDA synapses allocated
 
     }

// add a small fixed amount of inhibition on soma and trunk (one gabaa and one gabab) per section in list
  
   forsec inh_list {
       posa = 0.5
       posb = 0.5
       gabaa[gaba_synapses] = new GABAa(posa)       
       gabab[gaba_synapses] = new GABAb(posb)
       gmaxb = 3*gmaxb_default                     // explicitly define GABA_A and GABA_B conductances
       gmaxa = 4.8*gmax_default                    // for these sections (don't use GABA/AMPA ratios)
       ifsec soma_list {                      
           gmaxb = 0.03*gmaxb_default              // very little GABA_B at the soma
           gmaxa = 6*gmax_default                  // more GABA_A at the soma
       }
       SALLOC_GABAa(gabaa[gaba_synapses],posa,0,gmaxa)   // allocate synapses using the above conductances
       SALLOC_GABAb(gabab[gaba_synapses],posb,0,gmaxb)
       //splot.point_mark(gabab[gaba_synapses],COLOR+2)
           
       gaba_synapses = gaba_synapses + 1           // update GABA synapse counter
   }

  vf.close()
  vf2.close()
  vf3.close()

}                                                 // End of cluster allocation proceedure

//--------------------------------------------------------------------------------------------------------

hertz=50                                          // frequency of stimulation for AMPA/NMDA synapses
gaba_hertz=50                                     // frequency of stimulation for GABA synapses
perio=0                                           // spike trains for each synapse are NOT periodic


econ.xopen_library("Terrence","basic-graphics")   // open library file for graphics
addgraph("soma.v(0.5)",-72,60)                    // make a graph of somatic voltage trace
//addgraph("apical_dendrite[60].v(0.5)",-72,60)                    // make a graph of voltage trace
//addgraph("apical_dendrite[95].v(0.5)",-72,60)                    // make a graph of voltage trace

apical_tipl=new SectionList()                     // make a list of all apical oblique dendrites
forsec apical_tip_list {
       apical_tipl.append()
}
forsec apical_tip_list_addendum {
       apical_tipl.append()
}

// make a list of soma/trunk sections where a fixed amount of inhibition will be inserted

inh_list=new SectionList()
forsec "soma" {
 inh_list.append()
}

apical_dendrite[6]  inh_list.append()
apical_dendrite[26] inh_list.append()
apical_dendrite[48] inh_list.append()
apical_dendrite[64] inh_list.append()
apical_dendrite[81] inh_list.append()
apical_dendrite[104] inh_list.append()


for eiter=0,experiments-1 {                  // for all different cluster sizes

   sprint(econ.data_dir, "data/Syns=%d-Synch=%d-BACK_GROUND=%d/T600N=%d-NoCL=%d-SiCl=6_2",all_synapses, synch, BACK_GROUND, all_synapses, init_cluster_number)  
                                       
   print " ------------------------ Experiment ", eiter
   
   cluster_n = exp_ta[eiter]                 // get the cluster number
   sprint(econ.data_dir,"%s/N=%d-CLn=%d-hertz=%d-experiment-%d",econ.data_dir, all_synapses,cluster_n,hertz,eiter)
   sprint(econ.syscmd,  "mkdir -p %s", econ.data_dir) 
   system(econ.syscmd)                       // make a directory for this experiment

   econ.xopen_library("Terrence","verbose-system")
  
   for runs=0, 9 {  // do this experiment 20 times (20 different synapse distributions for the same number of clusters)

      splot=new Shape()   
      COLOR=1+runs
      rpid=new Random(runs+eiter)
      PID=int(rpid.uniform(1,10000))  // random seed for AMPA/NMDA synapses
      PID=-PID // choose branchwise  
      rpid=new Random(runs+eiter+1)
      PIDh=int(rpid.uniform(1,10000)) // random seed for GABA synapses
 
      lo=70                           // smallest distance of selected obliques from soma
      hi=10000                        // maximum  distance of selected obliques from soma

      // make a band (list) of randomly selected obliques within lo and hi microns from soma
      band=new SynapseBand(apical_tipl,lo,hi,actual_resolution,desired_resolution,PID)
      synapses_alloced=0              // initialize AMPA/NMDA synapse counter 
      gaba_synapses=0                 // initialize GABA synapse counter 

      //BACKGROUND stimulation
      // randomly distribute exitatory and inhibitory background synapses
      if (BACK_GROUND) {
            
              for i=0, back_syne -1 { 
                 band.pick()                                     // pick a branch
                 nseg = 10
                 rpid=new Random(i+runs)
                 pos1=int(rpid.uniform(0,10))/10                   // random selection of synapse location        
                 ampa_bg[i]=new GLU(pos1)                       // insert an AMPA mechanism in the middle of the branch
                 nmda_bg[i]=new NMDA(pos1)                      // insert an NMDA mechanism in the middle of the branch
                 salloc2(ampa_bg[i],nmda_bg[i],pos1,1,splot,COLOR+1)
              }
           
              for i=0, back_syni -1 {
                 band.pick()                                     // pick a branch
                 nseg = 10
                 rpid=new Random(2*i+3+runs)     
                 pos2=int(rpid.uniform(0,10))/10                    // random selection of synapse location
                 gabaa_bg[i] = new GABAa(pos2) 
                 SALLOC_GABAa(gabaa_bg[i],pos2,1,gmax_default)  // allocate mechanism using the AMPA-deduced conductance 
                 splot.point_mark(gabaa_bg[i],COLOR+1)         // plot on shape graph
                 gabab_bg[i] = new GABAb(pos2)                  // insert a GABA_B mechanism at the above location
              }
      }   
      


      printf("cluster_salloc(band, cluster_size, cluster_number)\n") // display cluster allocation proceedure start

      cluster_salloc(band,init_cluster_size,exp_ta[eiter])           // run cluster allocation proceedure
 
  
      GABA_flag = 0                                     // don't make both AMPA/NMDA and GABA trains in shiftsyn_init
      temporal_offset=0                                 // no temporal offset for spike train initiation 

      // create the stimulation trains for AMPA & NMDA synapses
      econ.xopen_library("Terrence","shiftsyn-initA")
      shiftsyn_init(all_synapses,tstop,dt,hertz,synch,perio,PID,temporal_offset,GABA_flag,"ampa","nmda")
      // Create the stimulation trains for GABA synapses
      econ.xopen_library("Terrence","GABA_shiftsyn")
      gaba_shift(gaba_synapses,tstop,dt,gaba_hertz,synch,perio,PIDh,temporal_offset,"gabaa","gabab")
        
      //BACKGROUND stimulation
      if (BACK_GROUND) {
      // create the stimulation trains for AMPA & NMDA background synapses
      econ.xopen_library("Terrence","shiftsyn-init_bg")
      shiftsyn_init(back_syne,tstop,dt,5,synch,perio,PID+2,temporal_offset,GABA_flag,"ampa_bg","nmda_bg")
      // Create the stimulation trains for GABA background synapses
      econ.xopen_library("Terrence","GABA_shiftsyn_bg")
      gaba_shift(back_syni,tstop,dt,5,synch,perio,PIDh+5,temporal_offset,"gabaa_bg","gabab_bg")
      }    
      
      vrec=new Vector(tstop/dt)                                // prepare to record somatic voltage 
      vrec.record(&soma.v(0.5))
              
      finitialize(v_init)                                      // initialize and run
      fcurrent()
      run()
 

// print the synapse distribution on the cell and the respective branch names to be used later 
// to estimate the cell firing rate using various mathematical models (linear, sigmoidal, quadratic etc).
// Model predictions are calculated (with matlab scripts) using the alpha branch coefficients estimated from 
// single-branch-stimulation experiments. The alpha coefficent for each branch is just the mean somatic
// depolarization in response to 50 Hz stimulation of increasing numbers of synapses (1-10) within
// each side branch

// sort the randomly selected sections and count the number of synapses in each one.
// Save the numbers (of synapses) in random_syn using the sorted order

     sprint(Fc, "%s/random_syn", econ.data_dir )  
     sprint(econ.syscmd,  "sort < %s | uniq -c | awk '{print $1}' > %s", tmpstr2, Fc )
     system(econ.syscmd)

// sort and save the list of randomly selected sections in random-sections
  
     strdef tmpstr3
     sprint(tmpstr2, "%s/random-sections", econ.data_dir)
     sprint(tmpstr3, "%s/random-sections-sorted", econ.data_dir)
     sprint(econ.syscmd,  "sort < %s | uniq > %s", tmpstr2, tmpstr3)
     system(econ.syscmd)

// read the sorted list of randomly selected sections
   
     random_list = new SectionList()
     xopen(tmpstr3)

// read the number of synapses per randomly selected section
  
     vf=new File()
     vf.ropen(Fc)
     input.scanf(vf) 
     vf.close()
     
   
// store the input configuration in a file
     vf=new File()
     sprint(tmpstr, "%s/input_profile", econ.data_dir)    // define file to save prediction data  
     vf.aopen(tmpstr)    


     forsec apical_tipl {
        sprint(tmpstr, "%s", secname())    
        flag = 0
        forsec cluster2_list {
            ifsec tmpstr {
                x = 2
                vf.printf("%d\t", x)
                flag = 1
                break
            }
        }
        if (flag==0) {
           forsec cluster6_list {
               ifsec tmpstr {
                   x = 6 
                   vf.printf("%d\t", x)
                   flag = 1
                   break
               }
            }
        }
        if (flag==0) {
           i = 0  
           forsec random_list {
               ifsec tmpstr {
                   x = input.x[i] 
                   vf.printf("%d\t", x)
                   flag = 1
                   break
               }
               i = i + 1
          }
       }
      if (flag==0)  {vf.printf("%d\t", 0)}
     }
     vf.printf("\n")
     vf.close()


     vf=new File()
     sprint(tmpstr, "%s/%d_synapses", econ.data_dir, all_synapses)    // define file to save cell firing rate  
     spikevec=new Vector()
     spikevec.spikebin(vrec,0)
 
     // open file and print: spikes, time
     vf.aopen(tmpstr)    
     vf.printf("%d %5d\n", spikevec.sum(), tstop)
     vf.close()

     //sprint(tmpstr, "%s/syn_distribution-CL=%d.eps", econ.data_dir, cluster_n)  // print the shape graph
     //splot.printfile(tmpstr)                                                    // with current synapse distribution

    // econ.xopen_library("Terrence","verbose-system")
     //for i=0,windex {
 
     //  sprint(econ.tmp_str, "%s/graph-%d.eps",econ.data_dir, i)      
      // win[i].printfile(econ.tmp_str)
     //}

 
    }  // end of runs

}    // end of experiments to run



Loading data, please wait...