ACnet23 primary auditory cortex model (Beeman et al 2019)

 Download zip file 
Help downloading and running models
Accession:261423
These scripts were used to model a patch of layer 2/3 primary auditory cortex, making use of the the improvements to PGENESIS by Crone, et al. (2019). This single layer model contains a 48 x 48 grid of pyramidal cells (PCs) and a 24 x 24 grid of basket cells (BCs). The reduced PC models have 17 compartments with dimensions and passive properties that were fit to human cortical PC reconstructions. This parallel version of the simulation was used by Beeman, et al. (2019) to understand the effects of inhibition of PCs by BCs on auditory evoked potentials.
References:
1 . Beeman D, Yu A, Crone J (2019) Studying evoked potentials in large cortical networks with PGENESIS 2.4 BMC Neuroscience 20 Suppl 1:P46
2 . Crone JC, Vindiola MM, Yu AB, Boothe DL, Beeman D, Oie KS, Franaszczuk PJ (2019) Enabling Large-Scale Simulations With the GENESIS Neuronal Simulator Frontiers in Neuroinformatics 13:69
Model Information (Click on a link to find other models with that property)
Model Type: Realistic Network;
Brain Region(s)/Organism: Auditory cortex;
Cell Type(s): Neocortex L2/3 pyramidal GLU cell; Neocortex fast spiking (FS) interneuron;
Channel(s):
Gap Junctions:
Receptor(s): GabaA; AMPA;
Gene(s):
Transmitter(s): Gaba; Glutamate;
Simulation Environment: PGENESIS; GENESIS;
Model Concept(s):
Implementer(s): Beeman, Dave;
Search NeuronDB for information about:  Neocortex L2/3 pyramidal GLU cell; GabaA; AMPA; Gaba; Glutamate;
// simple_inputs.g - used by ACnet2-default.g and variants

/* This version of simple_inputs2-9.g defines row_sep (row difference between
   input1 and input2) as a global.
*/

int first_row = 16  // input row for stimulus 1
int row_sep = 7 // default input row for stimulus 2

str input_source = "/MGBv" // Name of the array of input elements
echo " input_source = "{input_source}

/* The following global variables are defined in the ACnet network script:

   int Ninputs // number of auditory inputs
   // approx 1 mm/octave - gives integer rows/octave
   float octave_distance = 0.96e-3
   float Ex_SEP_Y // separation between rows of Ex cells
   int input_spread // input to row_num +/- input_spread

   float spike_jitter = 0.0005 // 0.5 msec jitter in thalamic inputs
       or spike_jitter = 0.0

   float input_delay = 0.0	 // seconds
   float input_jitter = 0.0

   str input_type // "pulsed_spiketrain", "pulsed_randomspike", "MGBv"
   str input_pattern  // == "row", "line", "box"

   This version also needs Ex_SEP_X, Inh_SEP_X, Inh_SEP_Y
*/

int rows_per_octave = {round {octave_distance/Ex_SEP_Y}}

/* Input target rows are numbered 1 through Ninputs, and cell rows are
   numbered 0 through Ex_NY - 1.  The first and last one-third octave
   of the cell rows do not receive MGBv input, so the cell row number
   is offset from the input row by input_offset.
*/
int input_offset = {round {rows_per_octave/3.0}} - 1

// Pulsed spike generator -- for constant input, use pulsewidth >= tmax
float pulse_width =  0.05    // width of pulse
float pulse_delay = 0.05        // delay before start of pulse
float pulse_interval = 0.15 // time from start of pulse to next (period)
float spikefreq = 110          // just to initialize the dialog

/* Default input conduction delay and jitter - the many targets of a single
   MGBv cell will receive a spike with delay ranging from
   input_delay*(1 - input_jitter) to input_delay*(1 + input_jitter)

   This may be used to reduce the correlation between the inputs to the
   target rows.
   
*/

// These are set in the main script
// float input_delay = 0.0  // seconds
// float input_jitter = 0.0
// float spike_jitter = 0.0005 // 0.5 msec jitter in thalamic inputs

//===============================
//      Function Definitions
//===============================


/* Functions to create the MGBv cells that will provide the inputs 
   In this case the "cells" are spikegens controlled by pulsegens
*/

function make_MGBvcell(path)
    str path
    // The full MGBvcell model would have  MGBvcell parameters here
    // Pulsed spike generator -- for constant input, use pulsewidth >= tmax
    // these will get changed
    float pulse_width = {tmax}     // width of pulse
    float pulse_delay = 0          // delay before start of pulse
    float pulse_interval = {tmax}  // interval before next pulse
    float spikefreq = 110 // Hz.   // initial value of frequency

    // This parameter is used for the full MGBvcell model
    // float spike_weight = 8
    /* Create the basic cell as a container for the pulsegen and spikegen */
    create neutral {path}

    // add fields to keep the target row, frequency and weight
    addfield {path} input_row
    setfield {path} input_row 0 // just to initialize it
    addfield {path} dest_row
    setfield {path} dest_row 0 // just to initialize it
    addfield {path} input_freq
    setfield {path} input_freq {spikefreq}
    addfield {path} output_weight
    setfield {path} output_weight 1.0

    create pulsegen {path}/spikepulse // Make a periodic pulse to control spikes
    // make a spikegen to deliver the spikes
    create spikegen {path}/spikepulse/spike
    setfield {path}/spikepulse/spike thresh 0.5
    setfield {path}/spikepulse width1 {pulse_width} delay1 {pulse_delay}  \
          baselevel 0.0 trig_mode 0 delay2 {pulse_interval - pulse_delay} width2 0

    if (input_type == "pulsed_spiketrain")
        if (debug_level >= 1)
            echo "Using simple pulsed spiketrain input"
        end  
        // set the spikegen refractory period = 1/freq
        setfield {path}/spikepulse/spike abs_refract {1.0/spikefreq}
        addmsg {path}/spikepulse {path}/spikepulse/spike INPUT output
    elif (input_type == "pulsed_randomspike")
        if (debug_level >= 1)
            echo "Using pulsed random (Poisson) spike input"
        end  
        create randomspike {path}/randspike
        setfield {path}/spikepulse/spike abs_refract 0.0009 // 1100 Hz max
        // Intialize randomspike amplitude to zero
	setfield {path}/randspike min_amp 0.0 max_amp 0.0 \
            reset 1 reset_value 0  rate {spikefreq}
        // gate the randomspike by setting min and max to pulsegen output
        addmsg {path}/spikepulse {path}/randspike MINMAX output output
        // This will gate the state of the randomspike, but not prevent it
        // from registering events. The state should be sent to the spikegen
        addmsg {path}/randspike {path}/spikepulse/spike INPUT state
   else
      echo "No input_type was specified!"
      quit
    end
end // function make_MGBvcell

function set_input_freq(cell, input_freq)
    str cell; float freq, input_freq
    setfield {cell} input_freq {input_freq}
    freq = input_freq
    if ({input_freq} > 1000)
        freq = 1000
    end
    float abs_refract = 1e6 // A very low frequency
    if ({freq} > 1.0e-6)
       abs_refract = 1.0/freq
    end
    if (input_type == "pulsed_spiketrain")
        setfield {cell}/spikepulse/spike abs_refract {abs_refract}
    elif (input_type == "pulsed_randomspike")
        setfield {cell}/randspike rate {freq}
    else
      echo "No input_type was specified!"
      return
    end
end // set_input_freq(cell, freq)

// Set parameters for spike train pulses
function set_pulse_params(input_num, frequency, delay, width, interval)
    int input_num
    float frequency, delay, width, interval, abs_refract
    setfield {input_source}[{input_num}]/spikepulse width1 {width} delay1 \
        {delay} baselevel 0.0 trig_mode 0 delay2 {interval - delay} width2 0
    // free run mode with very long delay for 2nd pulse (non-repetitive)
    // level1 is set by GUI spiketoggle function, or by a batch mode command
    // set the abs_refract of the spikegen to spike every 1/frequency
    set_input_freq {input_source}[{input_num}] {frequency}
end

function set_spiketrain_weight(input_num, weight)
    int input_num
    float weight
    str Ex_layer = "Ex_" @ {default_layer}
    str Inh_layer = "Inh_" @ {default_layer}
    setfield {input_source}[{input_num}] output_weight {weight}
    // Now set the weights of all network cell targets (not Inh feedback)
    // The optional 2nd arg for target isn't used here
    rvolumeweight {input_source}[{input_num}]/spikepulse/spike  \
        -fixed {weight}
end

function setall_driveweights(weight)
    int i
    float weight
    for (i=1; i <= {Ninputs}; i=i+1)
        set_spiketrain_weight {i} {weight}
    end
end

/* Set up the circuitry to provide spike trains to the network */
function make_input_source(input_num)
    int input_num, input_row
    float x0, y0, z0, y
    x0 = 0; y0 = input_offset*Ex_SEP_Y; z0 =0;
    make_MGBvcell {input_source}[{input_num}]
    // Set the separations of the vertical array of inputs to that of network
    y = y0 + input_num*Ex_SEP_Y
    setfield {input_source}[{input_num}] x {x0} y {y} z {z0} // initial setting
    // Special case for Ninputs <=2, with inputs to rows 16 and 23
    if (Ninputs > 2)
        first_row =  {round {rows_per_octave/3.0}}
        row_sep = 1
    end // else use the global value

     input_row = first_row + (input_num-1)*row_sep
    // for now, these are the same
    setfield {input_source}[{input_num}] input_row {input_row}
    setfield {input_source}[{input_num}] dest_row  {input_row}
end // function make_input_source

/* make_inputs and connect_inputs are the two functions called by ACnet2
   to set up the inputs to the network
*/

// Make array of pulsed inputs ({input_source}[{input_num}]) and initialize
function make_inputs(f0)
    int i, input_row, input_offset
    float f0, freq
    f0 = 110
    if ({argc} == 1)
        f0 = {argv 1}
    end
    input_offset = {round {rows_per_octave/3.0}}
    if (Ninputs > 2)
        first_row =  {round {rows_per_octave/3.0}}
        row_sep = 1
    end //else use default global value

    for (i=1; i <= {Ninputs}; i=i+1)
        make_input_source {i}
        // This assignment can be changed as needed
        input_row = first_row + (i-1)*row_sep

        freq = f0*{pow 2.0 \
            {1.0*((i-1)*row_sep + first_row - input_offset)/rows_per_octave} }
        set_pulse_params {i} {freq} {pulse_delay} {pulse_width} {pulse_interval}
        if (debug_level > 1)
            echo "source "{i}"  freq = "{freq}
        end
    end
end // function make_inputs

function set_input_delays(delay, jitter_factor)
    str Ex_layer = "Ex_" @ {default_layer}
    str Inh_layer = "Inh_" @ {default_layer}
    // give a random delay unfiformly distributed between
    // delay*(1 - jitter_factor) and delay*(1 + jitter_factor)
    float delay, jitter_factor
    // be careful to do it for just the network targets  
    rvolumedelay /MGBv[]/spikepulse/spike  \
        -fixed {delay} -uniform {jitter_factor}
end

// Asume that spike_jitter < 1.0/input_freq (e.g. 2 kHz for 0.5 msec jitter)
function add_spike_jitter
    int i
    float st
    for (i=1; i <= {Ninputs}; i=i+1)
	st = 1.0/{getfield {input_source}[{i}] input_freq}
	setrandfield  {input_source}[{i}]/spikepulse/spike abs_refract \
            -gaussian {st} {spike_jitter}
    end
end

function make_jitter_adder
    create script_out /jitter_adder
    enable /jitter_adder
    useclock /jitter_adder 2 // same as netview_dt
    setfield /jitter_adder command "add_spike_jitter"
end


/* --------------- Notes on function connect_inputs ------------------

  The default input_pattern = "row" makes connections to all cells on the
  specified row.  If input_spread > 0, connections with an exponentially
  decaying probablility will be made to adjacent rows +/- input_spread.

  There are two versions:

  function connect_inputs makes connections from the input source to rows
  with rvolumeconnect to a region encompassing a particular row. The connection
  probability for each row is set as described above. When PGENESIS 2.4
  rvolumeconnect, this means that a row will be picked with with the given
  probability and connections will be made to each cell in the row with
  100% probability.

  function connect_inputs2 makes the connections using raddmsg in a loop
  over the cells in a row. This way, a separate random number is assigned
  to each target cell.

*/

function connect_inputs
    /* 
       Note that the Inh cells are displaced from Ex by Ex_SEP_X/2,
       Ex_SEP_Y/2, with twice the spacing.

       Also, note the that '-relative' option is not used here.

 */
    float xmin, ymin, xmax, ymax
    
    if (input_pattern == "row")  // The usual option to target a full row
      /* Use code from MGBv_input2-5.g to provide input_spread */
      int i, k
      float target_y, y, ymin, ymax, prob, max_prob
      // number of rows below and above "target row" of input spread
      int kspread = input_spread // defined in main ACnet script
      int kmax = kspread  // number of rows to go above target row
      int kmin = -1*kspread  // number of rows to go below target row
      /* Target rows are numbered 1 through Ninputs, and cell rows are
          numbered 0 through Ex_NY - 1.  The first and last one-third octave
          of the cell rows do not receive MGBv input, so the cell row number
          is offset from the input row by input_offset.
      */

      max_prob = 1.1 // just to be sure that all target row cells get input
      
      // Below, the exponential decay of probability is set to give
      // prob(kmax) = exp(-2.0), to make it independent of Ex_SEP_Y
      float decay_rate
      if (kspread == 0)
          decay_rate = 1.0 // avoid a singularity if no spread
      else
        decay_rate = 2.0/kspread
      end
      for (i=1; i <= {Ninputs}; i=i+1) // loop over inputs
        target_y = {getfield {input_source}[{i}] dest_row} * Ex_SEP_Y
        if (debug_level > 1)
           echo "source "{i}"  target_y = "{target_y}
        end
        // Now get the input_row number for the source to target_y
//        setfield {input_source}[{i}] input_row {i + input_offset}
        // Special case: for Ninputs <=2, have inputs to rows 16 and 23
        str Ex_layer = "Ex_" @ {default_layer}
        str Inh_layer = "Inh_" @ {default_layer}
        for (k = kmin; k <= kmax; k=k+1)  // loop over spread about target
          y = target_y + k*Ex_SEP_Y
          prob = max_prob*{exp {-1.0*decay_rate*{abs {k}}} }
          ymin = target_y + (k - 0.2)*Ex_SEP_Y
          ymax = target_y + (k + 0.2)*Ex_SEP_Y
          rvolumeconnect {input_source}[{i}]/spikepulse/spike \
            /{Ex_layer}/{Ex_cell_name}[]/{Ex_drive_synpath}@{workers} \
            -sourcemask box -1 -1 -1 1 1 1 \
            -destmask box -1 {ymin} -1 1 {ymax} 1 \
            -probability {prob}
          // Earlier versions of simple_inputs set the Inh drive connection prob = 0
          rvolumeconnect {input_source}[{i}]/spikepulse/spike \
            /{Inh_layer}/{Inh_cell_name}[]/{Inh_drive_synpath}@{workers} \
            -sourcemask box -1 -1 -1 1 1 1 \ // be sure to include the source
            -destmask box -1 {ymin + 0.5*Ex_SEP_Y} -1 1 {ymax + 0.5*Ex_SEP_Y} 1 \
            -probability {0.65*prob}
        end // for k
      end // for i
    end

    // give a random delay unfiformly distributed between
    // delay*(1 - jitter_factor) and delay*(1 + jitter_factor)
    set_input_delays {input_delay} {input_jitter}

    if (({spike_jitter} > 0.0) && ({input_type} == "pulsed_spiketrain"))
        // Create a script_out to provide jitter in spike arrival time
        make_jitter_adder
    end
end // function connect_inputs

function connect_inputs2
    /* 
       Note that the Inh cells are displaced from Ex by Ex_SEP_X/2,
       Ex_SEP_Y/2, with twice the spacing.

       Also, note the that '-relative' option is not used here.

 */
    str src, dst, dst_cell_path
    int input_row, Inh_input_row, i, j, k, cell_num, dst_index, dst_node
    if (input_pattern == "row")  // The usual option to target a full row
      /* Use code from MGBv_input2-5.g to provide input_spread */
      float prob, max_prob
      // number of rows below and above "target row" of input spread
      int kspread = input_spread // defined in main ACnet script
      int kmax = kspread  // number of rows to go above target row
      int kmin = -1*kspread  // number of rows to go below target row
       /* Target rows are numbered 1 through Ninputs, and cell rows are
         numbered 0 through Ex_NY - 1. In some versions of the input model,
         There is an input for every row except the first and last one-third
         octave of the cell rows. These do not receive MGBv input, so the cell
         row number is offset from the input row by input_offset. In this
         version there are only 2 inputs (1 and 2) with input_row = first_row,
         and first_row + row_sep.
       */

      max_prob = 1.1 // just to be sure that all target row cells get input
      
      // Below, the exponential decay of probability is set to give
      // prob(kmax) = exp(-2.0), to make it independent of Ex_SEP_Y
      float decay_rate
      if (kspread == 0)
          decay_rate = 1.0 // avoid a singularity if no spread
      else
        decay_rate = 2.0/kspread
      end
      for (i=1; i <= {Ninputs}; i=i+1) // loop over inputs
        input_row = {getfield {input_source}[{i}] input_row}
        if (conn_debug)
           echo "source "{i}"   input_row = " {input_row}
        end
        // Now get the input_row number for the source to target_y
        // setfield {input_source}[{i}] input_row {i + input_offset}
        // Special case: for Ninputs <=2, have inputs only to rows 16 and 28
        str Ex_layer = "Ex_" @ {default_layer}
        str Inh_layer = "Inh_" @ {default_layer}
        src =  {input_source} @ "[" @{i} @ "]/spikepulse/spike"
        if (conn_debug)
            echo "spike input source is "{src}
        end
        for (k = kmin; k <= kmax; k=k+1)  // loop over spread about target
            prob = max_prob*{exp {-1.0*decay_rate*{abs {k}}} }
            dst_cell_path = "/" @ {Ex_layer} @"/" @ {Ex_cell_name}
            if (conn_debug)
                echo "For input_row = " {input_row} "Spike src = " {src}
            end
            for (j=0; j<Ex_NX; j=j+1) // loop over the Ex_cells in row k
                cell_num = (input_row + k)*Ex_NX + j		    
                if ({rand 0 1} <= prob)
                    dst_node = {cell_node {cell_num} {Ex_cells_per_slice}}
                    dst_index = {cell_index {cell_num} {Ex_cells_per_slice}}
                    dst = {dst_cell_path} @ "[" @ {dst_index} @ "]/" @ {Ex_drive_synpath}
                    if (conn_debug)
                        echo "cell_num = " {cell_num} "dst = " {dst} "  dst_node = " {dst_node}
                    end
                    raddmsg {src} {dst}@{dst_node} SPIKE
                end
            end // loop over cells in a row  
            // Earlier versions of simple_inputs set the Inh drive connection prob = 0
            prob = 0.65*prob // lesser probablity for Inh_cells
            dst_cell_path = "/" @ {Inh_layer} @"/" @ {Inh_cell_name}
            // Inh rows have twice the spacing. input_row could be odd.
            Inh_input_row = {round {(input_row -0.1)/2.0}}
	        for (j=0; j<Inh_NX;  j=j+1) // now loop over the Inh cells in row k
                cell_num = (Inh_input_row + k)*Inh_NX + j
                if ({rand 0 1} <= prob)
                    dst_node = {cell_node {cell_num} {Inh_cells_per_slice}}
                    dst_index = {cell_index {cell_num} {Inh_cells_per_slice}}
                    dst = {dst_cell_path} @ "[" @ {dst_index} @ "]/" @ {Inh_drive_synpath}
                    raddmsg {src} {dst}@{dst_node} SPIKE
               end 
            end // loop over cells in a row  
        end // for k
      end // for i
    end // if (input_pattern=="row") -- the only option allowed in this version

    // give a random delay unfiformly distributed between
    // delay*(1 - jitter_factor) and delay*(1 + jitter_factor)
    set_input_delays {input_delay} {input_jitter}

    if (({spike_jitter} > 0.0) && ({input_type} == "pulsed_spiketrain"))
        // Create a script_out to provide jitter in spike arrival time
        make_jitter_adder
    end
end // function connect_inputs2

Loading data, please wait...