// ************************************************************************************************************************
// An unified thalamic network model to generate delta, spindle, alpha and gamma oscillations
// Developed by Guoshi Li, University of North Carolina at Chapel Hill (guoshi_li@med.unc.edu)
// Simulation results are presented in the associated paper:
// Guoshi Li, Craig S Henriquez and Flavio Fröhlich (2017) Unified Thalamic Model Generates Multiple Distinct Oscillations
// with State-dependent Entrainment by Stimulation
// PLOS Computational Biology (In Press).
// ****************************************************************************************************************************
// Standard
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
// Own
#include "Constants.h"
#include "TC.h"
#include "IN.h"
#include "RE.h"
#include "src/CONN.h"
#include "src/AMPA_ext.h"
#include "src/AMPA.h"
#include "src/NMDA.h"
#include "src/GABA_A.h"
#include "src/Stimulation.h"
//#define PI 3.141592654
/*******************************************************************
// Declarations External Functions
*******************************************************************/
void rk(unsigned, void (unsigned, double, double*, double*), double, double,
double*, double*, double*, double*);
void fun(unsigned, double, double*, double*);
double gaussrand();
/*******************************************************************
// Declarations External Variables (File pointers)
*******************************************************************/
FILE *finput, *f_re, *f_tc1, *f_tc2, *f_in, *f_input, *f_spike, *f_ca;
FILE *f_I, *f_SI, *f_Iacs;
FILE *f_E, *f_E_TC_RE, *f_E_RE_TC, *f_W_HTC_IN;
FILE *f_m_T, *f_h_T, *f_m_H, *f_h_KS, *f_m_AHP, *f_m_A, *f_h_A;
FILE *f_connect;
/*******************************************************************
// Indices
*******************************************************************/
int i_tc1[N_TC1_X][N_TC1_Y]; // high-threshold bursting TC cell (HTC)
int i_tc2[N_TC2_X][N_TC2_Y]; // regular low-threshold TC cell (RTC)
int i_in[N_IN_X][N_IN_Y]; // LGN interneurons
int i_re[N_RE_X][N_RE_Y]; // RE cells
/*******************************************************************
// Create cells and synapses
*******************************************************************/
TC tc1_cell[N_TC1_X][N_TC1_Y];
TC tc2_cell[N_TC2_X][N_TC2_Y];
IN in_cell[N_IN_X][N_IN_Y];
RE re_cell[N_RE_X][N_RE_Y];
STIM Stim, Stim_Spin;
AMPA_ext ampa_ext_tc1[N_TC1_X][N_TC1_Y][N_INPUT_TC1];
AMPA_ext ampa_ext_tc2[N_TC2_X][N_TC2_Y][N_INPUT_TC2];
AMPA_ext ampa_ext_in[N_IN_X][N_IN_Y];
AMPA_ext ampa_ext_re[N_RE_X][N_RE_Y];
AMPA ampa_TC1_IN[N_IN_X][N_IN_Y][N_TC1];
NMDA nmda_TC1_IN[N_IN_X][N_IN_Y][N_TC1];
AMPA ampa_TC1_RE[N_RE_X][N_RE_Y][N_TC1];
NMDA nmda_TC1_RE[N_RE_X][N_RE_Y][N_TC1];
AMPA ampa_TC2_RE[N_RE_X][N_RE_Y][N_TC2];
NMDA nmda_TC2_RE[N_RE_X][N_RE_Y][N_TC2];
AMPA ampa_TC2_TC2[N_TC2_X][N_TC2_Y][N_TC2];
NMDA nmda_TC2_TC2[N_TC2_X][N_TC2_Y][N_TC2];
GABA_A gaba_IN_TC2[N_TC2_X][N_TC2_Y][N_IN];
GABA_A gaba_RE_TC1[N_TC1_X][N_TC1_Y][N_RE];
GABA_A gaba_RE_TC2[N_TC2_X][N_TC2_Y][N_RE];
GABA_A gaba_RE_IN[N_IN_X][N_IN_Y][N_RE];
GABA_A gaba_RE_RE[N_RE_X][N_RE_Y][N_RE];
CONN conn_tc1[N_TC1_X][N_TC1_Y];
CONN conn_tc2[N_TC2_X][N_TC2_Y];
CONN conn_in[N_IN_X][N_IN_Y];
CONN conn_re[N_RE_X][N_RE_Y];
/*******************************************************************
// Spike times
*******************************************************************/
double TC1_SPT[N_TC1_X][N_TC1_Y];
double TC2_SPT[N_TC2_X][N_TC2_Y];
double IN_SPT[N_IN_X][N_IN_Y];
double RE_SPT[N_RE_X][N_RE_Y];
/*******************************************************************
// External current inputs
*******************************************************************/
double input_tc1[N_TC1_X][N_TC1_Y];
double input_tc2[N_TC2_X][N_TC2_Y];
double input_in[N_IN_X][N_IN_Y];
double input_re[N_RE_X][N_RE_Y];
/*******************************************************************
//Short-term dynamics synapses
*******************************************************************/
double TC2_E[N_TC2_X][N_TC2_Y];
double RE_E[N_RE_X][N_RE_Y];
// Afferent input conductance
double g_Extern_TC1, g_Extern_TC2, g_Extern_IN, g_Extern_RE;
/*******************************************************************
// Main function
*******************************************************************/
int main(int argc,char **argv)
{
srand(RAND_SEED);
double y_ini[N_EQ], f_ini[N_EQ];
double y1[N_EQ], y2[N_EQ];
double t = 0; // time start
double tau = 0; //
double h = 0.02; // Default: 0.02; Step width solver
double gL_TC1, gKL_TC1, gL_TC2, gKL_TC2;
double gL_IN, gKL_IN, gH_IN, gCAN_IN, gL_RE, gKL_RE;
double d = 0;
int i,j, k, i1,j1, ii, jj;
double mi, mj; // indices
int PRE, POST;
int FLAG_SPINDLE_INPUT = 0;
char filepath[] = "data/";
char filename[50];
// Print the beginning time of simulation
printf("\n \n \nProgram started on ");
time_t t_start=time(0);
char * mytime= ctime(&t_start);
printf(mytime);
// Set afferent input conductance for each oscillation state
if (OSC == 1) { // Delta
g_Extern_TC1 = 0.0001; // uS
g_Extern_TC2 = 0.0001;
g_Extern_IN = 0.0001;
g_Extern_RE = 0.0001;
} else if (OSC == 2) { // Spindle
g_Extern_TC1 = 0.0003; // uS
g_Extern_TC2 = 0.0003;
g_Extern_IN = 0.0003;
g_Extern_RE = 0.0003;
FLAG_SPINDLE_INPUT = 1;
} else if (OSC == 3){ // Alpha
g_Extern_TC1 = 0.0015; // uS
g_Extern_TC2 = 0.0015;
g_Extern_IN = 0.0015;
g_Extern_RE = 0.0015;
}
else { // Gamma
g_Extern_TC1 = 0.017; // uS
g_Extern_TC2 = 0.017;
g_Extern_IN = 0.0015;
g_Extern_RE = 0.0015;
}
// Parameters of spindle-triggering input
Stim_Spin.FLAG_VAR_F = 0;
Stim_Spin.Stim_T0 = SPIN_T0; // spindle input start time
Stim_Spin.Stim_Amp = SPIN_AMP; // spindle input amplitude
Stim_Spin.F0 = SPIN_F; // spindle input frequency
Stim_Spin.T_PULSE_ON = SPIN_TT; // spindle input duration
// Constant current Injections (not used)
for(i=0; i<N_TC1_X; i++)
for(j=0; j<N_TC1_Y; j++)
input_tc1[i][j] = 0.0;
for(i=0; i<N_TC2_X; i++)
for(j=0; j<N_TC2_Y; j++)
input_tc2[i][j] = 0.0;
for(i=0; i<N_IN_X; i++)
for(j=0; j<N_IN_Y; j++)
input_in[i][j] = 0.0;
for(i=0; i< N_RE_X; i++)
for(j=0; j< N_RE_Y; j++)
input_re[i][j] = 0.0;
// Set parameters for each cell type
// High-threshold TC cells
for(i=0; i<N_TC1_X; i++)
for(j=0;j<N_TC1_Y; j++) {
gL_TC1 = GL1_TC1 + (GL2_TC1 - GL1_TC1)*(rand()/(RAND_MAX + 1.0));
if (OSC == 1) {
gKL_TC1 = GKL_TC1_S1;
} else if (OSC == 2) {
gKL_TC1 = GKL_TC1_S2;
} else {
gKL_TC1 = GKL_TC1_S3;
}
tc1_cell[i][j].G_l = gL_TC1;
tc1_cell[i][j].G_kl = gKL_TC1;
tc1_cell[i][j].G_Na = 90;
tc1_cell[i][j].G_K = 10;
tc1_cell[i][j].G_Ca0 = 2.1;
tc1_cell[i][j].G_Ca = 3.0;
tc1_cell[i][j].G_CaL = 0.5;
tc1_cell[i][j].G_AHP = 0.3;
tc1_cell[i][j].G_CAN = 0.5;
tc1_cell[i][j].G_H = 0.01;
tc1_cell[i][j].E_l = -70;
tc1_cell[i][j].Taur = 10;
tc1_cell[i][j].D = 0.5;
tc1_cell[i][j].INaK::Vtr = -30;
tc1_cell[i][j].INaK::VtrK = -30;
tc1_cell[i][j].INaK::k_h = 1;
tc1_cell[i][j].INaK::k_n = 4;
tc1_cell[i][j].IT0_TC::Shift_m = -3;
tc1_cell[i][j].IT0_TC::Shift_h = -3;
tc1_cell[i][j].IT_TC::Shift_m = 25;
tc1_cell[i][j].IT_TC::Shift_h = 25;
tc1_cell[i][j].IT_TC::K_Tau_h = 1.0;
tc1_cell[i][j].Ih_TC::Shift_m = 0;
}
// Low-threshold TC cells
for(i=0; i<N_TC2_X; i++)
for(j=0;j<N_TC2_Y; j++) {
gL_TC2 = GL1_TC2 + (GL2_TC2 - GL1_TC2)*(rand()/(RAND_MAX + 1.0));
if (OSC==1) {
gKL_TC2 = GKL_TC2_S1;
} else if (OSC==2) {
gKL_TC2 = GKL_TC2_S2;
} else {
gKL_TC2 = GKL_TC2_S3;
}
tc2_cell[i][j].G_l = gL_TC2;
tc2_cell[i][j].G_nal = 0.0 ;
tc2_cell[i][j].G_kl = gKL_TC2;
tc2_cell[i][j].G_Na = 90;
tc2_cell[i][j].G_K = 10;
tc2_cell[i][j].G_Ca0 = 2.1;
tc2_cell[i][j].G_Ca = 0.6;
tc2_cell[i][j].G_CaL = 0.3;
tc2_cell[i][j].G_AHP = 0.1;
tc2_cell[i][j].G_CAN = 0.6;
tc2_cell[i][j].G_H = 0.01;
tc2_cell[i][j].E_l = -70;
tc2_cell[i][j].Taur = 10;
tc2_cell[i][j].D = 0.5;
tc2_cell[i][j].INaK::Vtr = -40;
tc2_cell[i][j].INaK::VtrK = -40;
tc2_cell[i][j].INaK::k_h = 1;
tc2_cell[i][j].INaK::k_n = 4;
tc2_cell[i][j].IT0_TC::Shift_m = -3;
tc2_cell[i][j].IT0_TC::Shift_h = -3;
tc2_cell[i][j].IT_TC::Shift_m = 25;
tc2_cell[i][j].IT_TC::Shift_h = 25;
tc2_cell[i][j].Ih_TC::Shift_m = 0;
}
//=================================================================
// IN Cells
for(i=0; i<N_IN_X; i++)
for(j=0;j<N_IN_Y; j++) {
gL_IN = GL1_IN + (GL2_IN - GL1_IN)*(rand()/(RAND_MAX + 1.0));
if (OSC==1) {
gKL_IN = GKL_IN_S1;
} else if (OSC==2) {
gKL_IN = GKL_IN_S2;
} else {
gKL_IN = GKL_IN_S3;
}
in_cell[i][j].G_l = gL_IN;
in_cell[i][j].G_kl = gKL_IN;
in_cell[i][j].G_H = 0.05;
in_cell[i][j].G_CAN = 0.1;
in_cell[i][j].G_Na = 90;
in_cell[i][j].G_K = 10;
in_cell[i][j].G_Ca = 2.5;
in_cell[i][j].G_AHP = 0.2;
in_cell[i][j].E_l = -60;
in_cell[i][j].Taur = 10;
in_cell[i][j].D = 0.5;
in_cell[i][j].INaK::Vtr = -30;
in_cell[i][j].INaK::VtrK = -30;
in_cell[i][j].INaK::k_h = 1;
in_cell[i][j].INaK::k_n = 4;
in_cell[i][j].IT_TC::Shift_m = 25;
in_cell[i][j].IT_TC::Shift_h = 25;
in_cell[i][j].Ih_TC::Shift_m = 0;
}
//=====================================================================
// RE Cells
for(i=0; i<N_RE_X; i++)
for(j=0;j<N_RE_Y; j++) {
if (OSC==1) {
gKL_RE = GKL_RE_S1;
} else if (OSC==2) {
gKL_RE = GKL_RE_S2;
} else {
gKL_RE = GKL_RE_S3;
}
gL_RE = GL1_RE + (GL2_RE - GL1_RE)*(rand()/(RAND_MAX + 1.0));
re_cell[i][j].G_l = gL_RE;
re_cell[i][j].G_kl = gKL_RE;
re_cell[i][j].G_Na = 90;
re_cell[i][j].G_K = 10;
re_cell[i][j].G_Ca = 1.3;
re_cell[i][j].G_AHP = 0.2;
re_cell[i][j].G_CAN = 0.2;
re_cell[i][j].E_l = -60;
re_cell[i][j].Taur = 100;
re_cell[i][j].D = 0.5;
re_cell[i][j].INaK::Vtr = -40;
re_cell[i][j].INaK::VtrK = -40;
re_cell[i][j].INaK::k_h = 1;
re_cell[i][j].INaK::k_n = 1;
re_cell[i][j].IT_RE::Shift = -3;
}
// Change GABA reversal potentials for RE cells
for(i=0; i<N_RE_X; i++)
for(j=0;j<N_RE_Y; j++)
for(k=0; k<N_IN; k++) {
gaba_RE_RE[i][j][k].E_GABA = E_GABA_RE;
}
// Change Random input rate to TC cells
for(i=0; i<N_TC1_X; i++)
for(j=0;j<N_TC1_Y; j++)
for (k=0; k<N_INPUT_TC1;k++){
ampa_ext_tc1[i][j][k].w = RANDOM_F_TC;
}
for(i=0; i<N_TC2_X; i++)
for(j=0;j<N_TC2_Y; j++)
for (k=0; k<N_INPUT_TC2;k++){
ampa_ext_tc2[i][j][k].w = RANDOM_F_TC;
}
// =====================================================
// Index Cells
//======================================================
// Index TC1
for(i=0; i<N_TC1_X; i++)
for(j=0;j<N_TC1_Y; j++)
i_tc1[i][j] = (j + i*N_TC1_Y) * EQ_TC;
// Index TC2
for(i=0; i<N_TC2_X; i++)
for(j=0;j<N_TC2_Y; j++)
i_tc2[i][j] = N_EQ_TC1 + (j + i*N_TC2_Y) * EQ_TC;
// Indices INs
for(i=0; i<N_IN_X; i++)
for(j=0;j<N_IN_Y; j++)
i_in[i][j] = N_EQ_TC1 + N_EQ_TC2 + (j + i*N_IN_Y) * EQ_IN;
// Indices REs
for(i=0; i<N_RE_X; i++)
for(j=0;j<N_RE_Y; j++)
i_re[i][j] = N_EQ_TC1 + N_EQ_TC2 + N_EQ_IN + (j + i*N_RE_Y) * EQ_RE;
// =====================================================
// Initialization
//======================================================
Stim.init();
Stim_Spin.init();
// Initialize arrays
for(i=N_EQ-1; i>=0; --i)
y_ini[i] = 0, f_ini[i] = 0, y1[i] = 0, y2[i] = 0;
// Initialize Cells
for(i=0; i<N_TC1_X; i++)
for(j=0; j<N_TC1_Y; j++){
tc1_cell[i][j].init(y_ini + i_tc1[i][j]);
}
for(i=0; i<N_TC2_X; i++)
for(j=0; j<N_TC2_Y; j++){
tc2_cell[i][j].init(y_ini + i_tc2[i][j]);
}
for(i=0; i<N_IN_X; i++)
for(j=0; j<N_IN_Y; j++){
in_cell[i][j].init(y_ini + i_in[i][j]);
}
// RE
for(i=0; i<N_RE_X; i++)
for(j=0; j<N_RE_Y; j++){
re_cell[i][j].init(y_ini + i_re[i][j]);
}
// Initialize the connection arrays
for(i=0; i<N_TC1_X; i++)
for(j=0; j<N_TC1_Y; j++)
conn_tc1[i][j].INIT();
for(i=0; i<N_TC2_X; i++)
for(j=0; j<N_TC2_Y; j++)
conn_tc2[i][j].INIT();
for(i=0; i<N_IN_X; i++)
for(j=0; j<N_IN_Y; j++)
conn_in[i][j].INIT();
for(i=0; i<N_RE_X; i++)
for(j=0; j<N_RE_Y; j++)
conn_re[i][j].INIT();
// Initialize spike times
for(i=0; i<N_TC1_X; i++)
for(j=0; j<N_TC1_Y; j++)
TC1_SPT[i][j] = -10;
for(i=0; i<N_TC2_X; i++)
for(j=0; j<N_TC2_Y; j++){
TC2_SPT[i][j] = -10;
TC2_E[i][j] = 1;
}
for(i=0; i<N_IN_X; i++)
for(j=0; j<N_IN_Y; j++)
IN_SPT[i][j] = -10;
for(i=0; i<N_RE_X; i++)
for(j=0; j<N_RE_Y; j++) {
RE_SPT[i][j] = -10;
RE_E[i][j] = 1;
}
//==================================================================================
// Connectivity of the Network
//==================================================================================
// HTC cells to HTC cells connections (Gap Junctions)
for (i=0; i<N_TC1_X; i++)
for (j=0; j<N_TC1_Y; j++) {
POST = i*N_TC1_Y+j;
for (i1=0; i1<N_TC1_X; i1++)
for (j1=0; j1<N_TC1_Y; j1++) {
PRE = i1*N_TC1_Y+j1;
d = sqrt((i1-i)*(i1-i)+(j1-j)*(j1-j)); //
if ( (PRE!=POST) && (conn_tc1[i][j].C_TC1_TC1[i1][j1]==0) ) {
if ( ((rand()/(RAND_MAX + 1.0)) < P_TC1_TC1_GAP) && (d <= D_TC1_TC1) ) {
// for the post_junctional cell
k = conn_tc1[i][j].N_Pre_TC1;
conn_tc1[i][j].C_TC1_TC1[i1][j1] = 1;
conn_tc1[i][j].Pre_TC1_X[k] = i1;
conn_tc1[i][j].Pre_TC1_Y[k] = j1;
conn_tc1[i][j].Pre_TC1_D[k] = d;
conn_tc1[i][j].N_Pre_TC1++;
// for the pre_junctional cell
k = conn_tc1[i1][j1].N_Pre_TC1;
conn_tc1[i1][j1].C_TC1_TC1[i][j] = 1;
conn_tc1[i1][j1].Pre_TC1_X[k] = i;
conn_tc1[i1][j1].Pre_TC1_Y[k] = j;
conn_tc1[i1][j1].Pre_TC1_D[k] = d;
conn_tc1[i1][j1].N_Pre_TC1++;
}
}
}
}
// RTC cells to HTC cells connections (Gap Junctions)
// Select a small subset of RTC cells to form gap jucntion with HTC cells
for (i=0; i<N_TC2_X; i++)
for (j=0; j<N_TC2_Y; j++) {
if( rand()/(RAND_MAX + 1.0) < P_TC2_GAP) {
conn_tc2[i][j].F_TC2_TC1 = 1;
}
}
for (i=0; i<N_TC2_X; i++) // TC2 cells
for (j=0; j<N_TC2_Y; j++) {
POST = i*N_TC2_Y+j;
if( conn_tc2[i][j].F_TC2_TC1 == 1) {
for (i1=0; i1<N_TC1_X; i1++) // TC1 cells
for (j1=0; j1<N_TC1_Y; j1++) {
PRE = i1*N_TC1_Y+j1;
mi = (N_TC1_X-1.0)/(N_TC2_X-1.0)*i; // Projected x index in the HTC plane
mj = (N_TC1_Y-1.0)/(N_TC2_Y-1.0)*j; // Projected y index in the HTC plane
d = sqrt( (i1-mi)*(i1-mi)+(j1-mj)*(j1-mj) );
if ( (d <= D_TC2_TC1) && ((rand()/(RAND_MAX + 1.0)) < P_TC2_TC1_GAP) ) {
// for the post_junctional cell
k = conn_tc2[i][j].N_Pre_TC1;
conn_tc2[i][j].Pre_TC1_X[k] = i1;
conn_tc2[i][j].Pre_TC1_Y[k] = j1;
conn_tc2[i][j].Pre_TC1_D[k] = d;
conn_tc2[i][j].N_Pre_TC1++;
// for the pre_junctional cell
k = conn_tc1[i1][j1].N_Pre_TC2;
conn_tc1[i1][j1].Pre_TC2_X[k] = i;
conn_tc1[i1][j1].Pre_TC2_Y[k] = j;
conn_tc1[i1][j1].Pre_TC2_D[k] = d;
conn_tc1[i1][j1].N_Pre_TC2++;
}
}
}
}
// RTC cells to RTC cells connection (Chemical synapses between RTC cells)
// This connection is NOT active!!!
for (i=0; i<N_TC2_X; i++)
for (j=0; j<N_TC2_Y; j++) {
POST = i*N_TC2_Y+j;
for (i1=0; i1<N_TC2_X; i1++)
for (j1=0; j1<N_TC2_Y; j1++) {
PRE = i1*N_TC2_Y+j1;
d = sqrt((i1-i)*(i1-i)+(j1-j)*(j1-j));
if ( PRE!=POST )
if ( ((rand()/(RAND_MAX + 1.0)) < P_TC2_TC2) && (d <= D_TC2_TC2) ) {
k = conn_tc2[i][j].N_Pre_TC2;
// conn_tc2[i][j].C_TC1_TC1[i1][j1] = 1;
conn_tc2[i][j].Pre_TC2_X[k] = i1;
conn_tc2[i][j].Pre_TC2_Y[k] = j1;
conn_tc2[i][j].N_Pre_TC2++;
}
}
}
// HTC cells to IN connections
for (i=0; i<N_IN_X; i++)
for (j=0; j<N_IN_Y; j++) {
POST = i*N_IN_Y+j;
for (i1=0; i1<N_TC1_X; i1++)
for (j1=0; j1<N_TC1_Y; j1++) {
PRE = i1*N_TC1_Y+j1;
if ( (rand()/(RAND_MAX + 1.0)) < P_TC1_IN ) {
k = conn_in[i][j].N_Pre_TC1;
conn_in[i][j].Pre_TC1_X[k] = i1;
conn_in[i][j].Pre_TC1_Y[k] = j1;
conn_in[i][j].N_Pre_TC1++;
}
}
}
// HTC cells to RE cells connections
for (i=0; i<N_RE_X; i++)
for (j=0; j<N_RE_Y; j++) {
POST = i*N_RE_Y+j;
for (i1=0; i1<N_TC1_X; i1++)
for (j1=0; j1<N_TC1_Y; j1++) {
PRE = i1*N_TC1_Y+j1;
if ( (rand()/(RAND_MAX + 1.0)) < P_TC1_RE ) {
k = conn_re[i][j].N_Pre_TC1;
conn_re[i][j].Pre_TC1_X[k] = i1;
conn_re[i][j].Pre_TC1_Y[k] = j1;
conn_re[i][j].N_Pre_TC1++;
}
}
}
// RTC cells to RE cells connections
for (i=0; i<N_RE_X; i++)
for (j=0; j<N_RE_Y; j++) {
for (i1=0; i1<N_TC2_X; i1++)
for (j1=0; j1<N_TC2_Y; j1++) {
if ((rand()/(RAND_MAX + 1.0)) < P_TC2_RE) {
k = conn_re[i][j].N_Pre_TC2;
conn_re[i][j].Pre_TC2_X[k] = i1;
conn_re[i][j].Pre_TC2_Y[k] = j1;
conn_re[i][j].N_Pre_TC2++;
}
}
}
// INs to RTC cells connections
for (i=0; i<N_TC2_X; i++)
for (j=0; j<N_TC2_Y; j++) {
POST = i*N_TC2_Y+j;
for (i1=0; i1<N_IN_X; i1++)
for (j1=0; j1<N_IN_Y; j1++) {
PRE = i1*N_IN_Y+j1;
if ( (rand()/(RAND_MAX + 1.0)) < P_IN_TC2 ) {
k = conn_tc2[i][j].N_Pre_IN;
conn_tc2[i][j].Pre_IN_X[k] = i1;
conn_tc2[i][j].Pre_IN_Y[k] = j1;
conn_tc2[i][j].N_Pre_IN++;
}
}
}
// RE cells to HTC cells connections
for (i=0; i<N_TC1_X; i++)
for (j=0; j<N_TC1_Y; j++) {
for (i1=0; i1<N_RE_X; i1++)
for (j1=0; j1<N_RE_Y; j1++) {
if ((rand()/(RAND_MAX + 1.0)) < P_RE_TC1) {
k = conn_tc1[i][j].N_Pre_RE;
conn_tc1[i][j].Pre_RE_X[k] = i1;
conn_tc1[i][j].Pre_RE_Y[k] = j1;
conn_tc1[i][j].N_Pre_RE++;
}
}
}
// RE cells to RTC cells connections
for (i=0; i<N_TC2_X; i++)
for (j=0; j<N_TC2_Y; j++) {
for (i1=0; i1<N_RE_X; i1++)
for (j1=0; j1<N_RE_Y; j1++) {
if ((rand()/(RAND_MAX + 1.0)) < P_RE_TC2) {
k = conn_tc2[i][j].N_Pre_RE;
conn_tc2[i][j].Pre_RE_X[k] = i1;
conn_tc2[i][j].Pre_RE_Y[k] = j1;
conn_tc2[i][j].N_Pre_RE++;
}
}
}
// RE cells to INs connections
for (i=0; i<N_IN_X; i++)
for (j=0; j<N_IN_Y; j++) {
for (i1=0; i1<N_RE_X; i1++)
for (j1=0; j1<N_RE_Y; j1++) {
if ((rand()/(RAND_MAX + 1.0)) < P_RE_IN) {
k = conn_in[i][j].N_Pre_RE;
conn_in[i][j].Pre_RE_X[k] = i1;
conn_in[i][j].Pre_RE_Y[k] = j1;
conn_in[i][j].N_Pre_RE++;
}
}
}
// RE to RE connection (Gap junctions)
// Select a small subset of RE cells to form gap jucntions with other neighboring RE cells
for (i=0; i<N_RE_X; i++)
for (j=0; j<N_RE_Y; j++) {
if( rand()/(RAND_MAX + 1.0) < P_RE_GAP) {
conn_re[i][j].F_RE_RE = 1;
}
}
for (i=0; i<N_RE_X; i++)
for (j=0; j<N_RE_Y; j++) {
POST = i*N_RE_Y+j;
if( conn_re[i][j].F_RE_RE == 1) {
for (i1=0; i1<N_RE_X; i1++)
for (j1=0; j1<N_RE_Y; j1++) {
PRE = i1*N_RE_Y+j1;
d = sqrt( (i1-i)*(i1-i)+(j1-j)*(j1-j) );
if ( (PRE!=POST) && (conn_re[i][j].C_RE_RE[i1][j1]==0) ) {
if ( ((rand()/(RAND_MAX + 1.0)) < P_RE_RE_GAP) && (d <= D_RE_RE) ) {
// for the post_junctional cell
k = conn_re[i][j].N_Pre_RE_GAP;
conn_re[i][j].C_RE_RE[i1][j1] = 1;
conn_re[i][j].Pre_RE_X_GAP[k] = i1;
conn_re[i][j].Pre_RE_Y_GAP[k] = j1;
conn_re[i][j].Pre_RE_D_GAP[k] = d;
conn_re[i][j].N_Pre_RE_GAP++;
// for the pre_junctional cell
k = conn_re[i1][j1].N_Pre_RE_GAP;
conn_re[i1][j1].C_RE_RE[i][j] = 1;
conn_re[i1][j1].Pre_RE_X_GAP[k] = i;
conn_re[i1][j1].Pre_RE_Y_GAP[k] = j;
conn_re[i1][j1].Pre_RE_D_GAP[k] = d;
conn_re[i1][j1].N_Pre_RE_GAP++;
}
}
}
}
}
// RE to RE connections (GABAergic inhibitory synapses)
for (i=0; i<N_RE_X; i++)
for (j=0; j<N_RE_Y; j++) {
POST = i*N_RE_Y+j;
for (i1=0; i1<N_RE_X; i1++)
for (j1=0; j1<N_RE_Y; j1++) {
PRE = i1*N_RE_Y+j1;
d = sqrt( (i1-i)*(i1-i) + (j1-j)*(j1-j) );
if ( PRE!=POST ) {
if ( (rand()/(RAND_MAX + 1.0)) < P_RE_RE ) {
k = conn_re[i][j].N_Pre_RE;
conn_re[i][j].Pre_RE_X[k] = i1;
conn_re[i][j].Pre_RE_Y[k] = j1;
conn_re[i][j].N_Pre_RE++;
}
}
}
}
// Save network connectivity to file
//HTC-HTC connectivity
f_connect = fopen("data/Con_HTC_HTC", "w");
fprintf(f_connect, "The HTC-->HTC Connection Is: \n");
for(i=0; i<N_TC1_X; i++)
for(j=0; j<N_TC1_Y; j++) {
fprintf(f_connect, "\n\nHTC[%d][%d] has %d gap junctional connections with HTCs: \n", i,j, conn_tc1[i][j].N_Pre_TC1);
for(i1=0; i1<conn_tc1[i][j].N_Pre_TC1; i1++) {
if (i1%5==0)
fprintf(f_connect, "\n");
fprintf(f_connect, "HTC(%d, %d) d=%2.1f \t", conn_tc1[i][j].Pre_TC1_X[i1], conn_tc1[i][j].Pre_TC1_Y[i1],
conn_tc1[i][j].Pre_TC1_D[i1]);
}
}
fclose(f_connect);
// RTC-->HTC connectivity
f_connect = fopen("data/Con_RTC_HTC", "w");
fprintf(f_connect, "The RTC-->HTC Connection Is: \n");
for(i=0; i<N_TC1_X; i++)
for(j=0; j<N_TC1_Y; j++) {
fprintf(f_connect, "\n\nHTC[%d][%d] has %d gap junctional connections with RTCs: \n", i,j, conn_tc1[i][j].N_Pre_TC2);
for(i1=0; i1<conn_tc1[i][j].N_Pre_TC2; i1++) {
if (i1%5==0)
fprintf(f_connect, "\n");
fprintf(f_connect, "RTC(%d, %d) d=%3.2f \t", conn_tc1[i][j].Pre_TC2_X[i1], conn_tc1[i][j].Pre_TC2_Y[i1],
conn_tc1[i][j].Pre_TC2_D[i1]);
}
}
fclose(f_connect);
// HTC-->RTC connectivity
f_connect = fopen("data/Con_HTC_RTC", "w");
fprintf(f_connect, "The HTC-->RTC Connection Is: \n");
for(i=0; i<N_TC2_X; i++)
for(j=0; j<N_TC2_Y; j++) {
fprintf(f_connect, "\n\nRTC[%d][%d] has %d gap junctional connections with HTCs: \n", i,j, conn_tc2[i][j].N_Pre_TC1);
for(i1=0; i1<conn_tc2[i][j].N_Pre_TC1; i1++) {
if (i1%5==0)
fprintf(f_connect, "\n");
fprintf(f_connect, "HTC(%d, %d) d=%3.2f \t", conn_tc2[i][j].Pre_TC1_X[i1], conn_tc2[i][j].Pre_TC1_Y[i1],
conn_tc2[i][j].Pre_TC1_D[i1]);
}
}
fclose(f_connect);
//RE-RE connectivity
f_connect = fopen("data/Con_RE_RE", "w");
fprintf(f_connect, "The RE-->RE Connection Is: \n");
for(i=0; i<N_RE_X; i++)
for(j=0; j<N_RE_Y; j++) {
fprintf(f_connect, "\n\nRE[%d][%d] has %d gap junctional connections with REs: \n", i,j, conn_re[i][j].N_Pre_RE_GAP);
for(i1=0; i1<conn_re[i][j].N_Pre_RE_GAP; i1++) {
if (i1%5==0)
fprintf(f_connect, "\n");
fprintf(f_connect, "RE(%d, %d) d=%2.1f \t", conn_re[i][j].Pre_RE_X_GAP[i1], conn_re[i][j].Pre_RE_Y_GAP[i1],
conn_re[i][j].Pre_RE_D_GAP[i1]);
}
}
fclose(f_connect);
// Open output files
f_tc1 = fopen("data/tc1_all", "w");
f_tc2 = fopen("data/tc2_all", "w");
f_in = fopen("data/in_all", "w");
f_re = fopen("data/re_all", "w");
f_E = fopen("data/TC2_E", "w");
f_W_HTC_IN = fopen("data/W_HTC_IN", "w");
f_E_TC_RE = fopen("data/E_TC_RE", "w");
f_E_RE_TC = fopen("data/E_RE_TC", "w");
f_I = fopen("data/I_STIM", "w");
f_SI = fopen("data/I_SPIN", "w");
// Stim current
fprintf(f_I, "%f \t", Stim.I);
fprintf(f_I, "\n");
fprintf(f_SI, "%f \t", Stim_Spin.I);
fprintf(f_SI, "\n");
// W_HTC_IN
fprintf(f_W_HTC_IN, "%f \t", ampa_TC1_IN[0][0][0].E);
fprintf(f_W_HTC_IN, "\n");
// RTC-RE short-term depression
fprintf(f_E_TC_RE, "%f \t", ampa_TC2_RE[0][0][0].E);
fprintf(f_E_TC_RE, "\n");
// RE-RTC short-term depression
fprintf(f_E_RE_TC, "%f \t", gaba_RE_TC2[0][0][0].E);
fprintf(f_E_RE_TC, "\n");
// HTC cells
fprintf(f_tc1,"%f \t",t);
for (i=0; i<N_TC1_X; i++)
for (j=0; j<N_TC1_Y; j++) {
fprintf(f_tc1,"%f \t", y_ini[i_tc1[i][j]]);
}
fprintf(f_tc1,"\n");
// RTC cells
fprintf(f_tc2,"%f \t",t);
for (i=0; i<N_TC2_X; i++)
for (j=0; j<N_TC2_Y; j++) {
fprintf(f_tc2,"%f \t", y_ini[i_tc2[i][j]]);
fprintf(f_E,"%f \t", TC2_E[i][j]);
}
fprintf(f_tc2,"\n");
fprintf(f_E,"\n");
// INs
fprintf(f_in,"%f \t",t);
for (i=0; i<N_IN_X; i++)
for (j=0; j<N_IN_Y; j++) {
fprintf(f_in,"%f \t", y_ini[i_in[i][j]]);
}
fprintf(f_in,"\n");
// RE cells
fprintf(f_re,"%f \t",t);
for (i=0; i<N_RE_X; i++)
for (j=0; j<N_RE_Y; j++) {
fprintf(f_re,"%f \t", y_ini[i_re[i][j]]);
}
fprintf(f_re,"\n");
// Save spike times
// HTC
for(i=0; i<N_TC1_X; i++){
for(j=0; j<N_TC1_Y; j++){
sprintf(filename, "%sTC1_%d_%d", filepath, i, j);
f_spike = fopen(filename, "w");
fclose(f_spike);
}
}
// RTC
for(i=0; i<N_TC2_X; i++){
for(j=0; j<N_TC2_Y; j++){
sprintf(filename, "%sTC2_%d_%d", filepath, i, j);
f_spike = fopen(filename, "w");
fclose(f_spike);
}
}
// IN
for(i=0; i<N_IN_X; i++){
for(j=0; j<N_IN_Y; j++){
sprintf(filename, "%sIN_%d_%d", filepath, i, j);
f_spike = fopen(filename, "w");
fclose(f_spike);
}
}
// RE
for(i=0; i<N_RE_X; i++){
for(j=0; j<N_RE_Y; j++){
sprintf(filename, "%sRE_%d_%d", filepath, i, j);
f_spike = fopen(filename, "w");
fclose(f_spike);
}
}
// Configure Stimulation
printf("\n Now starting simulation: t= %lf: tmax= %lf \n", t,t_end);
ii = 0;
tau = h;
while( t <= t_end) {
// Record spike times
// HTC
for(i=0; i<N_TC1_X; i++)
for(j=0; j<N_TC1_Y; j++)
if (y_ini[i_tc1[i][j]] > 0 && (t-TC1_SPT[i][j]) > 3) {
TC1_SPT[i][j] = t;
sprintf(filename, "%sTC1_%d_%d", filepath, i, j);
f_spike = fopen(filename, "a");
fprintf(f_spike,"%f\n", t);
fclose(f_spike);
}
// RTC
for(i=0; i<N_TC2_X; i++)
for(j=0; j<N_TC2_Y; j++)
if (y_ini[i_tc2[i][j]] > 0 && (t-TC2_SPT[i][j]) > 3) {
TC2_E[i][j] = 1 - (1 - TC2_E[i][j]*(1-0.07)) * exp(-(t-TC2_SPT[i][j])/700);
TC2_SPT[i][j] = t;
sprintf(filename, "%sTC2_%d_%d", filepath, i, j);
f_spike = fopen(filename, "a");
fprintf(f_spike,"%f\n", t);
fclose(f_spike);
}
// IN
for(i=0; i<N_IN_X; i++)
for(j=0; j<N_IN_Y; j++)
if (y_ini[i_in[i][j]] > 0 && (t-IN_SPT[i][j]) > 3) {
IN_SPT[i][j] = t;
sprintf(filename, "%sIN_%d_%d", filepath, i, j);
f_spike = fopen(filename, "a");
fprintf(f_spike,"%f\n", t);
fclose(f_spike);
}
// RE
for(i=0; i<N_RE_X; i++)
for(j=0; j<N_RE_Y; j++)
if (y_ini[i_re[i][j]] > 0 && (t-RE_SPT[i][j]) > 3) {
RE_E[i][j] = 1 - (1 - RE_E[i][j]*(1-0.07)) * exp(-(t-RE_SPT[i][j])/700);
RE_SPT[i][j] = t;
sprintf(filename, "%sRE_%d_%d", filepath, i, j);
f_spike = fopen(filename, "a");
fprintf(f_spike,"%f\n", t);
fclose(f_spike);
}
//======================================================================
// Constant current injection
if (FLAG_CURRENT_INJECTION == 1) {
for(i=0; i<N_TC1_X; i++)
for(j=0; j<N_TC1_Y; j++) {
tc1_cell[i][j].setStim(input_tc1[i][j]);
}
for(i=0; i<N_TC2_X; i++)
for(j=0; j<N_TC2_Y; j++) {
tc2_cell[i][j].setStim(input_tc2[i][j]);
}
for(i=0; i<N_IN_X; i++)
for(j=0; j<N_IN_Y; j++) {
in_cell[i][j].setStim(input_in[i][j]);
}
}
// Spindle-triggering input
if (FLAG_SPINDLE_INPUT == 1) {
Stim_Spin.calc(t);
for(i=0; i<SPIN_X; i++)
for(j=0; j<SPIN_Y; j++) {
re_cell[i][j].setStim(Stim_Spin.I);
}
}
// Square Pulse Stimulation
if (FLAG_STIMULATION_LGN_PULSE == 1) {
Stim.calc(t);
for(i=0; i<N_TC1_X; i++)
for(j=0; j<N_TC1_Y; j++) {
tc1_cell[i][j].setStim(Stim.I);
}
for(i=0; i<N_TC2_X; i++)
for(j=0; j<N_TC2_Y; j++) {
tc2_cell[i][j].setStim(Stim.I);
}
for(i=0; i<N_IN_X; i++)
for(j=0; j<N_IN_Y; j++) {
in_cell[i][j].setStim(Stim.I);
}
}
if (FLAG_STIMULATION_TRN_PULSE == 1) {
Stim.calc(t);
for(i=0; i<N_RE_X; i++)
for(j=0; j<N_RE_Y; j++) {
if (FLAG_SPINDLE_INPUT == 1)
re_cell[i][j].setStim(Stim.I + Stim_Spin.I);
else
re_cell[i][j].setStim(Stim.I);
}
}
// ==================================================================
rk(N_EQ, fun, h, t, y_ini, f_ini, y1, y2);
t = t + tau;
ii++;
if( ((ii/(10000))*(10000) == ii)) {
printf("\n Time: t= %lf \n", t);
}
// Save data with a resoluton of DT = 0.2 ms
if( ((ii/(10))*(10) == ii)){
// HTC
fprintf(f_tc1,"%f \t",t);
for (i=0; i<N_TC1_X; i++)
for (j=0; j<N_TC1_Y; j++) {
fprintf(f_tc1,"%f \t", y_ini[i_tc1[i][j]]);
}
fprintf(f_tc1,"\n");
// RTC
fprintf(f_tc2,"%f \t",t);
for (i=0; i<N_TC2_X; i++)
for (j=0; j<N_TC2_Y; j++) {
fprintf(f_tc2,"%f \t", y_ini[i_tc2[i][j]]);
fprintf(f_E,"%f \t", TC2_E[i][j]);
}
fprintf(f_tc2,"\n");
fprintf(f_E,"\n");
// IN
fprintf(f_in,"%f \t",t);
for (i=0; i<N_IN_X; i++)
for (j=0; j<N_IN_Y; j++) {
fprintf(f_in,"%f \t", y_ini[i_in[i][j]]);
}
fprintf(f_in,"\n");
// RE
fprintf(f_re,"%f \t",t);
for (i=0; i<N_RE_X; i++)
for (j=0; j<N_RE_Y; j++) {
fprintf(f_re,"%f \t", y_ini[i_re[i][j]]);
}
fprintf(f_re,"\n");
// STD
fprintf(f_W_HTC_IN, "%f \t", ampa_TC1_IN[0][0][0].E);
fprintf(f_W_HTC_IN, "\n");
fprintf(f_E_TC_RE, "%f \t", ampa_TC2_RE[0][0][0].E);
fprintf(f_E_TC_RE, "\n");
fprintf(f_E_RE_TC, "%f \t", gaba_RE_TC2[0][0][0].E);
fprintf(f_E_RE_TC, "\n");
// Stimulation currents
fprintf(f_I, "%f \t", Stim.I);
fprintf(f_I, "\n");
fprintf(f_SI, "%f \t", Stim_Spin.I);
fprintf(f_SI, "\n");
}
}
// Close files
fclose(f_tc1);
fclose(f_tc2);
fclose(f_in);
fclose(f_re);
fclose(f_I);
fclose(f_SI);
fclose(f_E);
fclose(f_W_HTC_IN);
fclose(f_E_TC_RE);
fclose(f_E_RE_TC);
// Print the end time of simulation
printf("\n\nProgram ended on ");
t_start =time(0);
mytime = ctime(&t_start);
printf(mytime);
}
/*******************************************************************
// void fun()
// Evaluate right-hand side of system of coupled ODEs
*******************************************************************/
void fun(int unsigned NEQ, double x, double *y_ini, double *f_ini){
// Local variables
int i,j,i1,j1,I1,I2,k, id; // generic indices
int post, pre;
// int k_ampa, k_nmda; // local counter of number of syn per cell
int N;
double T_Start_Synapse;
if (OSC == 2) {
T_Start_Synapse = 500;
} else {
T_Start_Synapse = 0; }
//===================================================================
// Begin: Cells
// Thalamus
if (TC1_EX==1) {
for(i=0; i<N_TC1_X; i++)
for(j=0; j<N_TC1_Y; j++)
tc1_cell[i][j].calc(x, y_ini+i_tc1[i][j], f_ini+i_tc1[i][j]);
}
if (TC2_EX==1) {
for(i=0; i<N_TC2_X; i++)
for(j=0; j<N_TC2_Y; j++)
tc2_cell[i][j].calc(x, y_ini+i_tc2[i][j], f_ini+i_tc2[i][j]);
}
if (IN_EX==1) {
for(i=0; i<N_IN_X; i++)
for(j=0; j<N_IN_Y; j++)
in_cell[i][j].calc(x, y_ini + i_in[i][j], f_ini + i_in[i][j]);
}
if (RE_EX==1) {
for(i=0; i<N_RE_X; i++)
for(j=0; j<N_RE_Y; j++) {
re_cell[i][j].calc(x, y_ini + i_re[i][j], f_ini + i_re[i][j]);
}
}
// End: Cells
// ==================================================================
// External random background inputs to TC1s
if(FLAG_RANDOM_INPUT == 1) {
// TC1
if (TC1_EX==1) {
for(i=0; i<N_TC1_X; i++)
for(j=0; j<N_TC1_Y; j++) {
id = i_tc1[i][j];
for(k=0; k<N_INPUT_TC1; k++) {
ampa_ext_tc1[i][j][k].calc(g_Extern_TC1, x);
f_ini[id] = f_ini[id] - (ampa_ext_tc1[i][j][k].g * y_ini[id])/(tc1_cell[i][j].S_TC*1e3);
}
}
}
// TC2
if (TC2_EX==1) {
for(i=0; i<N_TC2_X; i++)
for(j=0; j<N_TC2_Y; j++) {
id = i_tc2[i][j];
for(k=0; k<N_INPUT_TC2; k++){
ampa_ext_tc2[i][j][k].calc(g_Extern_TC2, x);
f_ini[id] = f_ini[id] - (ampa_ext_tc2[i][j][k].g * y_ini[id])/(tc2_cell[i][j].S_TC*1e3);
}
}
}
// IN
if (IN_EX==1) {
for(i=0; i<N_IN_X; i++)
for(j=0; j<N_IN_Y; j++) {
id = i_in[i][j];
ampa_ext_in[i][j].calc(g_Extern_IN, x);
f_ini[id] = f_ini[id] - (ampa_ext_in[i][j].g * y_ini[id])/(in_cell[i][j].S_IN*1e3);
}
}
// RE
if (RE_EX==1) {
for(i=0; i<N_RE_X; i++)
for(j=0; j<N_RE_Y; j++) {
id = i_re[i][j];
ampa_ext_re[i][j].calc(g_Extern_RE, x);
f_ini[id] = f_ini[id] - (ampa_ext_re[i][j].g * y_ini[id])/(re_cell[i][j].S_RE*1e3);
}
}
}
//==========================================
// Synaptic Connections
//==========================================
// HTC-HTC Gap junctional connections
if (x >= T_Start_Synapse) {
if (TC1_EX==1) {
if (FLAG_TC1_TC1_GAP == 1) {
for(i=0; i<N_TC1_X; i++)
for(j=0; j<N_TC1_Y; j++) {
post = i_tc1[i][j];
N = conn_tc1[i][j].N_Pre_TC1;
if (N > 0){
for (k=0; k<N; k++) {
i1 = conn_tc1[i][j].Pre_TC1_X[k];
j1 = conn_tc1[i][j].Pre_TC1_Y[k];
pre = i_tc1[i1][j1];
f_ini[post] = f_ini[post] - (y_ini[post] - y_ini[pre])/R_TC1_TC1/(tc1_cell[i][j].S_TC*1e3);
}
}
}
}
}
// RTC-HTC Gap junctional connections
if (TC1_EX==1 && TC2_EX==1) {
if (FLAG_TC2_TC1_GAP == 1) {
// For HTC CELLS
for(i=0; i<N_TC1_X; i++)
for(j=0; j<N_TC1_Y; j++) {
post = i_tc1[i][j];
N = conn_tc1[i][j].N_Pre_TC2;
if (N > 0){
for (k=0; k<N; k++) {
i1 = conn_tc1[i][j].Pre_TC2_X[k];
j1 = conn_tc1[i][j].Pre_TC2_Y[k];
pre = i_tc2[i1][j1];
f_ini[post] = f_ini[post] - (y_ini[post] - y_ini[pre])/R_TC1_TC2/(tc1_cell[i][j].S_TC*1e3);
}
}
}
// For RTC CELLS
for(i=0; i<N_TC2_X; i++)
for(j=0; j<N_TC2_Y; j++) {
post = i_tc2[i][j];
N = conn_tc2[i][j].N_Pre_TC1;
if (N > 0){
for (k=0; k<N; k++) {
i1 = conn_tc2[i][j].Pre_TC1_X[k];
j1 = conn_tc2[i][j].Pre_TC1_Y[k];
pre = i_tc1[i1][j1];
f_ini[post] = f_ini[post] - (y_ini[post] - y_ini[pre])/R_TC1_TC2/(tc2_cell[i][j].S_TC*1e3);
}
}
}
}
}
// RTC-RTC chemical synaptic connections (NOT ACTIVE!)
if (TC2_EX==1) {
if (FLAG_TC2_TC2 == 1) {
for(i=0; i<N_TC2_X; i++)
for(j=0; j<N_TC2_Y; j++){
post = i_tc2[i][j];
N = conn_tc2[i][j].N_Pre_TC2;
if(N > 0) {
for (k=0; k<N; k++) {
i1 = conn_tc2[i][j].Pre_TC2_X[k];
j1 = conn_tc2[i][j].Pre_TC2_Y[k];
ampa_TC2_TC2[i][j][k].calc(g_AMPA_TC2_TC2, x, y_ini[post], TC2_SPT[i1][j1], STD_TC2_TC2);
nmda_TC2_TC2[i][j][k].calc(g_NMDA_TC2_TC2, x, y_ini[post], TC2_SPT[i1][j1], STD_TC2_TC2);
f_ini[post] = f_ini[post] - ampa_TC2_TC2[i][j][k].I/(tc2_cell[i][j].S_TC*1e3);
f_ini[post] = f_ini[post] - nmda_TC2_TC2[i][j][k].I/(tc2_cell[i][j].S_TC*1e3);
}
}
}
}
}
// HTC-->IN
if (TC1_EX==1 && IN_EX ==1) {
if (FLAG_TC1_IN == 1) {
for(i=0; i<N_IN_X; i++)
for(j=0; j<N_IN_Y; j++){
post = i_in[i][j];
N = conn_in[i][j].N_Pre_TC1;
if(N > 0) {
for (k=0; k<N; k++) {
i1 = conn_in[i][j].Pre_TC1_X[k];
j1 = conn_in[i][j].Pre_TC1_Y[k];
ampa_TC1_IN[i][j][k].calc(g_AMPA_TC1_IN, x, y_ini[post], TC1_SPT[i1][j1], STD_TC1_IN);
nmda_TC1_IN[i][j][k].calc(g_NMDA_TC1_IN, x, y_ini[post], TC1_SPT[i1][j1], STD_TC1_IN);
f_ini[post] = f_ini[post] - ampa_TC1_IN[i][j][k].I/(in_cell[i][j].S_IN*1e3);
f_ini[post] = f_ini[post] - nmda_TC1_IN[i][j][k].I/(in_cell[i][j].S_IN*1e3);
}
}
}
}
}
// HTC-->RE
if (TC1_EX==1 && RE_EX ==1) {
if (FLAG_TC1_RE == 1) {
for(i=0; i<N_RE_X; i++)
for(j=0; j<N_RE_Y; j++){
post = i_re[i][j];
N = conn_re[i][j].N_Pre_TC1;
if(N > 0) {
for (k=0; k<N; k++) {
i1 = conn_re[i][j].Pre_TC1_X[k];
j1 = conn_re[i][j].Pre_TC1_Y[k];
ampa_TC1_RE[i][j][k].calc(g_AMPA_TC1_RE, x, y_ini[post], TC1_SPT[i1][j1], STD_TC1_RE);
nmda_TC1_RE[i][j][k].calc(g_NMDA_TC1_RE, x, y_ini[post], TC1_SPT[i1][j1], STD_TC1_RE);
f_ini[post] = f_ini[post] - ampa_TC1_RE[i][j][k].I/(re_cell[i][j].S_RE*1e3);
f_ini[post] = f_ini[post] - nmda_TC1_RE[i][j][k].I/(re_cell[i][j].S_RE*1e3);
}
}
}
}
}
// IN-RTC
if (IN_EX==1 && TC2_EX ==1) {
if (FLAG_IN_TC2 == 1) {
for(i=0; i<N_TC2_X; i++)
for(j=0; j<N_TC2_Y; j++) {
post = i_tc2[i][j];
N = conn_tc2[i][j].N_Pre_IN;
if (N > 0){
for (k=0; k<N; k++) {
i1 = conn_tc2[i][j].Pre_IN_X[k];
j1 = conn_tc2[i][j].Pre_IN_Y[k];
gaba_IN_TC2[i][j][k].calc(g_GABA_IN_TC2, x, y_ini[post], IN_SPT[i1][j1], STD_IN_TC2);
f_ini[post] = f_ini[post] - gaba_IN_TC2[i][j][k].I/(tc2_cell[i][j].S_TC*1e3);
}
}
}
}
}
// RTC-RE
if (TC2_EX==1 && RE_EX ==1) {
if (FLAG_TC2_RE == 1) {
for(i=0; i<N_RE_X; i++)
for(j=0; j<N_RE_Y; j++){
post = i_re[i][j];
N = conn_re[i][j].N_Pre_TC2;
if(N > 0) {
for (k=0; k<N; k++) {
i1 = conn_re[i][j].Pre_TC2_X[k];
j1 = conn_re[i][j].Pre_TC2_Y[k];
ampa_TC2_RE[i][j][k].calc(g_AMPA_TC2_RE, x, y_ini[post], TC2_SPT[i1][j1], STD_TC2_RE);
nmda_TC2_RE[i][j][k].calc(g_NMDA_TC2_RE, x, y_ini[post], TC2_SPT[i1][j1], STD_TC2_RE);
f_ini[post] = f_ini[post] - ampa_TC2_RE[i][j][k].I/(re_cell[i][j].S_RE*1e3);
f_ini[post] = f_ini[post] - nmda_TC2_RE[i][j][k].I/(re_cell[i][j].S_RE*1e3);
}
}
}
}
}
// RE-HTC
if (TC1_EX==1 && RE_EX ==1) {
if (FLAG_RE_TC1 == 1) {
for(i=0; i<N_TC1_X; i++)
for(j=0; j<N_TC1_Y; j++) {
post = i_tc1[i][j];
N = conn_tc1[i][j].N_Pre_RE;
if (N > 0){
for (k=0; k<N; k++) {
i1 = conn_tc1[i][j].Pre_RE_X[k];
j1 = conn_tc1[i][j].Pre_RE_Y[k];
gaba_RE_TC1[i][j][k].calc(g_GABA_RE_TC1, x, y_ini[post], RE_SPT[i1][j1], STD_RE_TC1);
f_ini[post] = f_ini[post] - gaba_RE_TC1[i][j][k].I/(tc1_cell[i][j].S_TC*1e3);
}
}
}
}
}
// RE-RTC
if (TC2_EX==1 && RE_EX ==1) {
if (FLAG_RE_TC2 == 1) {
for(i=0; i<N_TC2_X; i++)
for(j=0; j<N_TC2_Y; j++) {
post = i_tc2[i][j];
N = conn_tc2[i][j].N_Pre_RE;
if (N > 0){
for (k=0; k<N; k++) {
i1 = conn_tc2[i][j].Pre_RE_X[k];
j1 = conn_tc2[i][j].Pre_RE_Y[k];
gaba_RE_TC2[i][j][k].calc(g_GABA_RE_TC2, x, y_ini[post], RE_SPT[i1][j1], STD_RE_TC2);
f_ini[post] = f_ini[post] - gaba_RE_TC2[i][j][k].I/(tc2_cell[i][j].S_TC*1e3);
}
}
}
}
}
// RE-IN
if (RE_EX ==1 && IN_EX ==1) {
if (FLAG_RE_IN == 1) {
for(i=0; i<N_IN_X; i++)
for(j=0; j<N_IN_Y; j++) {
post = i_in[i][j];
N = conn_in[i][j].N_Pre_RE;
if (N > 0){
for (k=0; k<N; k++) {
i1 = conn_in[i][j].Pre_RE_X[k];
j1 = conn_in[i][j].Pre_RE_Y[k];
gaba_RE_IN[i][j][k].calc(g_GABA_RE_IN, x, y_ini[post], RE_SPT[i1][j1], STD_RE_IN);
f_ini[post] = f_ini[post] - gaba_RE_IN[i][j][k].I/(in_cell[i][j].S_IN*1e3);
}
}
}
}
}
// RE-RE gap junctions
if (RE_EX==1) {
if (FLAG_RE_RE_GAP == 1) {
for(i=0; i<N_RE_X; i++)
for(j=0; j<N_RE_Y; j++) {
post = i_re[i][j];
N = conn_re[i][j].N_Pre_RE_GAP;
if (N > 0){
for (k=0; k<N; k++) {
i1 = conn_re[i][j].Pre_RE_X_GAP[k];
j1 = conn_re[i][j].Pre_RE_Y_GAP[k];
pre = i_re[i1][j1];
f_ini[post] = f_ini[post] - (y_ini[post] - y_ini[pre])/R_RE_RE/(re_cell[i][j].S_RE*1e3);
}
}
}
}
}
// RE-RE chemical synapses
if (RE_EX ==1) {
if (FLAG_RE_RE == 1) {
for(i=0; i<N_RE_X; i++)
for(j=0; j<N_RE_Y; j++) {
post = i_re[i][j];
N = conn_re[i][j].N_Pre_RE;
if (N > 0){
for (k=0; k<N; k++) {
i1 = conn_re[i][j].Pre_RE_X[k];
j1 = conn_re[i][j].Pre_RE_Y[k];
gaba_RE_RE[i][j][k].calc(g_GABA_RE_RE, x, y_ini[post], RE_SPT[i1][j1], STD_RE_RE);
f_ini[post] = f_ini[post] - gaba_RE_RE[i][j][k].I/(re_cell[i][j].S_RE*1e3);
}
}
}
}
}
} // End synapse
} // End fun
//***************************************************************************
// Solver
//***************************************************************************
void rk(unsigned n, void fun(unsigned, double, double*, double*),
double h, double x, double* y, double* f, double* s, double* yk)
{
int i;
double xk;
double h_half = h/2.;
fun(n, x, y, f);
for(i = n-1; i >=0; --i){
s[i] = f[i];
yk[i] = y[i] + h_half*f[i];
}
xk = x + h_half;
fun(n, xk, yk, f);
for(i = n-1; i >=0; --i){
s[i] += 2.*f[i];
yk[i] = y[i] + h_half*f[i];
}
fun(n, xk, yk, f);
for(i = n-1; i >=0; --i){
s[i] += 2.*f[i]; yk[i] = y[i] + h*f[i];
}
xk = x + h;
fun(n, xk, yk, f);
for(i = n-1; i >=0; --i){
y[i] += (h/6.)*(s[i] + f[i]);
}
}
//***************************************************************************
double gaussrand()
{
static double U, V;
static int phase = 0;
double Z;
if(phase == 0) {
U = (rand() + 1.) / (RAND_MAX + 2.);
V = rand() / (RAND_MAX + 1.);
Z = sqrt(-2 * log(U)) * sin(2 * PI * V);
} else
Z = sqrt(-2 * log(U)) * cos(2 * PI * V);
phase = 1 - phase;
return Z;
}