/****************************************************************************************************************
****************************************************************************************************************/
/**
* @file BGThNetwork_1DModel.c
* @author Osvaldo M Velarde
* @date May 2017
* @brief Simulation of a Cortico-Basal Ganglia-Thalamocortical network model.
* The architecture and dynamics of the network can be seen in the reference.
* The objective is to analyze the effect of the intensities of the synaptic connections on the dynamics of the network.
* In particular, associating pathological and physiological states in Parkinson's disease.
* Furthermore, it is desired to study the effect of deep brain stimulation on the pathological dynamics of the network.
* @see https://doi.org/10.1371/journal.pone.0182884
*/
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>
#include<time.h>
/* Simulation times (ms)*/
#define t_0_sim 0.0 // Start time
#define t_f_sim 6000.0 // End time
#define dt 0.5 // Temporal step
/* External input in Cortex (Ctx). Time interval = [t_0_Ctx, t_f_Ctx] (ms)*/
#define t_0_Ctx 250.0
#define t_f_Ctx 6000.0
/* External input in Striatum (Str). Time intervals = [t_0_Str1, t_f_Str1] U [t_0_Str2, t_f_Str2](ms)*/
#define t_0_Str1 300.0
#define t_f_Str1 1000.0
#define t_0_Str2 3000.0
#define t_f_Str2 4000.0
/* Deep Brain Stimulation (DBS). Time interval = [t_0_DBS, t_f_DBS] (ms)*/
#define t_0_DBS 1000.0
#define t_f_DBS 6000.0
#define PI 3.1415926
/*------------------ Structures -------------------------*/
/*-------------------------------------------------------*/
/**
* @brief neuron_struct represents to a neuron in a population.
*/
typedef struct neuron_struct{
double parameters[3]; /**< Values of "threshold", "external input", "noise level". */
double input_det; /**< Total input. */
double input_sto; /**< Noise. */
double angle; /**< Position. */
double (*ext)(double ext_p[5],double k,double t); /**< External input. */
}neuron;
/**
* @brief BGan_struct represents to a neuronal population.
*/
typedef struct BGan_struct{
neuron *circle; /**< Array of neurons. */
int neuron_number; /**< Number of neurons in a circle. */
}BGan;
/**
* @brief connection_struct represents to a synapse between two neurons (pre and post- synaptic).
*/
typedef struct connection_struct{
double sinaptic_curr; /**< Synaptic current m_ij. */
struct neuron_struct *last; /**< Pre-synaptic neuron i. */
struct neuron_struct *next; /**< Post-synaptic neuron j. */
}connection;
/**
* @brief cable represents to an array of synapses. All synapses in the "cable" have the same post-synaptic neuron.
*/
typedef connection* cable;
/**
* @brief conductor saves the information on the parameters of the connections between populations.
*/
typedef struct {
double parameters[3]; /**< Values of synaptic efficacy, time constant and delay. */
cable* cond; /**< Array of "cable". Each element of the array is asociated with a neuron in post-sinaptic population*/
BGan* last; /**< Pre-synaptic Population. */
BGan* next; /**< Post-synaptic Population. */
int K; /**< Average number of connections per neuron. */
double level_div; /**< Variance of number of connections. */
}conductor;
/*------------------ Functions: Use of angles --------------------------------*/
/*----------------------------------------------------------------------------*/
/**
* @brief Wrap a double to the interval [-pi,pi)
* @param value Angle (rad).
* @return Angle (rad) between [-pi, pi].
*/
double normalize_angle(double value){
double v1=cos(value);
double v2=sin(value);
double theta=acos(v1);
if(v2>=0)
return theta;
else
return -theta;}
/**
* @brief Sum of angles
* @param theta1 Angle (rad) in [-pi,pi).
* @param theta2 Angle (rad) in [-pi,pi).
* @return Sum of theta1 and theta2 (rad) in [-pi,pi).
*/
double sum_angle(double theta1,double theta2){
theta1=normalize_angle(theta1);
theta2=normalize_angle(theta2);
double theta= theta1+theta2;
theta=normalize_angle(theta);
return theta;}
/*----------------- Connectivity: Probability of connection ------------------*/
/*----------------------------------------------------------------------------*/
/**
* @brief Function required to calculate the probability of connection between two neurons.
* @param x Variable
* @param sigma Parameter of function.
* @return exp((x-1.0)/sigma^2)
*/
double function_gauss(double x,double sigma){
double e=exp((x-1.0)/(sigma*sigma));
return e;
}
/**
* @brief Approximation of Gaussian Function in angle variables.
* The probability of connection between two neurons depends of the angular distance.
* d_12 = 1 - Cos(theta1 - theta2)
* Probability is proporcional to exp(d_12/sigma^2)
* @param theta1 Angle (rad) in [-pi,pi)
* @param theta2 Angle (rad) in [-pi,pi)
* @param sigma Variance.
* @return Probability of connection between neuron 1 (in theta1) and neuron 2 (in theta2)
*/
double probability_connect(double theta_1,double theta_2,double sigma){
double delta=sum_angle(theta_1,-theta_2);
double x=cos(delta);
double e=function_gauss(x,sigma);
return e;
}
/**
* @brief Computer of normalization constant for the distribution of connections-
* @param A Pre-synaptic population
* @param i Index for neuron in A. Integer value in [0, Num_neurons_A)
* @param B Post-synaptic population
* @param K_ab Average number of connections per neuron "i".
* @param sigma Variance.
* @return Normalization constant
*/
double cte_normalizat(BGan A,int i,BGan B,int K_ab,double sigma){
int j;
double No=0;
K_ab=1.0*K_ab;
for(j=0;j<B.neuron_number;j++){
No=No+ probability_connect(A.circle[i].angle,B.circle[j].angle,sigma);
}
No=No/K_ab;
return No;
}
/*------------------ Electrode: Spatial Modulation --------------------------*/
/*---------------------------------------------------------------------------*/
/**
* @brief Spatial modulation for measurement and stimulation by electrodes.
* @param position Position of electrode [-pi,pi)
* @param threshold Threshold of electrode [0,1)
* @param vol_tissue Angular volume of tissue involved in measurement or stimulation (rad)
* @param angle Position of neuron.
* @return Spatial modulation.
*/
double spatial_electrode(double position, double threshold, double vol_tissue, double angle){
double z=(cos(angle-position)-1)/(cos(vol_tissue/2)-1);
z=(1.0-1.0/threshold)*z;
return 1.0/(1-z);
}
/*----------------------------- NOISE & INPUTS--------------------------------*/
/*----------------------------------------------------------------------------*/
/**
* @brief Generation of random numbers (normal distribution)
* @param mean Mean of distribution position Position of electrode [-pi,pi)
* @param sigma Standard desviation of distribution
* @return Random number (White noise).
*/
double external_noise(double mean,double sigma){
double x,y,z;
x=(double)rand()/(double)RAND_MAX;
y=(double)rand()/(double)RAND_MAX;
if(x!=0 && y!=0){
z=sqrt(-2.0*log(x))*cos(4.0*y*asin(1.0));
z=sigma*z+mean;
return z;}
if (x==0 && y!=0){
z=sqrt(-2.0*log(y));
z=sigma*z+mean;
return z;}
if (x!=0 && y==0){
z=sqrt(-2.0*log(x));
z=sigma*z+mean;
return z;}
else
return 0;
}
/** OBSERVATION: All external_inputs functions follow the form:
* (a + b*cos(angle)) * (c + d*cos(2pi *t/T) )
* def_parameters = [a,b,c,d,T]
* angle: position of neuron
* t: time.
*/
double external_default(double def_parameters[5],double angle, double t){
return def_parameters[0];
}
double external_Ctx(double Ctx_parameters[5],double angle, double t){
if (t_0_Ctx<t && t<t_f_Ctx){
double spatial_comp=Ctx_parameters[0]+Ctx_parameters[1]*cos(angle);
double temporal_comp=Ctx_parameters[2]+Ctx_parameters[3]*cos(2*PI*t/Ctx_parameters[4]);
return spatial_comp*temporal_comp;
}
return 0;
}
double external_Str(double Str_parameters[5],double angle, double t){
if ((t_0_Str1<t && t<t_f_Str1)||(t_0_Str2<t && t<t_f_Str2)){
double spatial_comp=Str_parameters[0]+Str_parameters[1]*cos(angle);
double temporal_comp=Str_parameters[2]+Str_parameters[3]*cos(2*PI*t/Str_parameters[4]);
return spatial_comp*temporal_comp;
}
return 0;
}
/*---------------------- Deep Brain Stimulation ---------------------------*/
/*-------------------------------------------------------------------------*/
double DBS_Period(double t,double amplitude,double width, double slope){
if (0<=t && t<slope)
return amplitude*t/slope;
if(slope<=t && t<=slope+width)
return amplitude;
if(slope+width<t && t<2*slope+width)
return amplitude*(2 - (t-width)/slope);
else
return 0;
}
double DBS_Periodic(double t, double amplitude, double period,double width,double slope){
if (t_0_DBS<=t && t<t_f_DBS){
double theta=2*PI*(t-t_0_DBS)/period;
double y=acos(cos(theta));
if (sin(theta)>0)
return DBS_Period(period*(y/(2*PI)),amplitude,width,slope);
else
return DBS_Period(period*(1-y/(2*PI)),amplitude,width,slope);}
else
return 0.0;
}
double random_frequency(double mean_frequency,double coef_var){
if (coef_var==0)
return mean_frequency;
else{
double p=1/pow(coef_var,2);
double a=p/mean_frequency;
double x_1=rand()/(double)RAND_MAX;
double x_2=rand()/(double)RAND_MAX;
double e_1=-log(1-x_1);
double e_2=-log(1-x_2);
while(e_2 < (p-1)*(e_1- 1 -log(e_1))){
x_1=rand()/(double)RAND_MAX;
x_2=rand()/(double)RAND_MAX;
e_1=-log(1-x_1);
e_2=-log(1-x_2);}
double z=p*e_1/a;
return z;}
}
double DBS_Random(double t,double amplitude, double width,double slope, double* start,int number_pulse){
int i;
for(i=0;i<number_pulse;i++){
if (start[i]<=t && t<=start[i]+width)
return amplitude;
if (start[i]+width<t && t<start[i+1])
return 0;
}
return 0;
}
/*------------------- Network construction -----------------------------------*/
/*----------------------------------------------------------------------------*/
int Network_construction(BGan **Population,int Number_BG,conductor **Network,int ***Numbers_Connection){
int i,j,k; // Auxiliar indexs
double p1,p2,p3; // Parameters
int N_neuron, N_conductor; // Number of neurons
int a,b; // Last,Next BGanglia (Conductor)
int K,sigma; // NÂș average of connections and level of divergence
int n,m; // Number of neurons in last and next BG
int K_max; // Max number of connections (aproximmate)
int count; // Number of connections in each cable.
double No; // Constant of normalization
double p,x; // Probability.
//Data files: Conductors, BGanglia and propierties
FILE *Interaction;
FILE *Parameters_C;
FILE *Parameters_G;
//Create Number_BG
*Population= (BGan*)malloc(Number_BG*sizeof(BGan));
//Create neurons in each BGan - Load parameters.
Parameters_G=fopen("Ganglios.dat","r");
for(i=0;i<Number_BG;i++){
fscanf(Parameters_G,"%lf \t %lf \t %lf \t %d\n",&p1,&p2,&p3,&N_neuron); // Threshold - External input - Noise - Number_neurons
(*Population)[i].neuron_number=N_neuron;
(*Population)[i].circle=(neuron*)malloc(N_neuron*sizeof(neuron));
for(j=0;j<N_neuron;j++){
(*Population)[i].circle[j].angle=-PI+(j*2*PI)/(1.0*N_neuron);
(*Population)[i].circle[j].parameters[0]=p1;
(*Population)[i].circle[j].parameters[1]=p2;
(*Population)[i].circle[j].parameters[2]=p3;
(*Population)[i].circle[j].input_det=0;
(*Population)[i].circle[j].input_sto=0;
(*Population)[i].circle[j].ext=external_default;
}
}
fclose(Parameters_G);
//Conductors between BGanglia
Interaction=fopen("Interaction.dat","r");
i=0;
while (feof(Interaction)==0){
fscanf(Interaction,"%d\n",&a);
i=i+1;
}
N_conductor=i/4;
rewind(Interaction);
//Create conductors.
*Network= (conductor*)malloc(N_conductor*sizeof(conductor));
//Create a matrix for count number of connections.
*Numbers_Connection=(int**)malloc(N_conductor*sizeof(int*));
//For each conductor, create connections
for(i=0;i<N_conductor;i++){
//Last BGanglia and Next BGanglia
fscanf(Interaction,"%d \t %d \t %d \t %d \n",&a,&b,&K,&sigma);
(*Network)[i].last=&(*Population)[a-1];
(*Network)[i].next=&(*Population)[b-1];
n=(*Network)[i].last->neuron_number;
m=(*Network)[i].next->neuron_number;
//Struct propierties
(*Network)[i].K=K;
(*Network)[i].level_div=1.0*sigma/100;
//For each conductor, create "n" (last_neuron_number) cables
(*Network)[i].cond=(cable*)malloc(n*sizeof(cable));
(*Numbers_Connection)[i]=(int*)malloc(n*sizeof(int));
//Maximum number of possible connections (aprox).
K_max=K+10*floor(sqrt(1.0*K));
for(j=0;j<n;j++){
//In each cable, there are K connections (aprox). Upper bounded is K_max.
((*Network)[i].cond)[j]=(connection*)malloc(K_max*sizeof(connection));
count=0;
No=cte_normalizat(*((*Network)[i].last),j,*((*Network)[i].next),(*Network)[i].K,(*Network)[i].level_div); //NORMALIZACION.
//Using random laws, create connections.
for(k=0;k<m;k++){
x=rand()/(double)RAND_MAX;
p=probability_connect((*(*Network)[i].last).circle[j].angle,(*(*Network)[i].next).circle[k].angle,(*Network)[i].level_div)/No;
if(x<p){
((*Network)[i].cond)[j][count].last=&(*Population)[a-1].circle[j];
((*Network)[i].cond)[j][count].next=&(*Population)[b-1].circle[k];
count=count+1;}
}
(*Numbers_Connection)[i][j]=count;
}
}
fclose(Interaction);
//Load parameters of connections.
Parameters_C=fopen("Conductores.dat","r");
for (i=0;i<N_conductor;i++){
fscanf(Parameters_C,"%lf \t %lf \t %lf\n",&p1,&p2,&p3);
(*Network)[i].parameters[0]=p1;
(*Network)[i].parameters[1]=p2;
(*Network)[i].parameters[2]=p3;
}
fclose(Parameters_C);
return N_conductor;
}
/*-----------------------LISTAS COMO VECTORES---------------------------------*/
/*----------------------------------------------------------------------------*/
int insertarfinal(double *v, int *pnum, double value,int MAX) {
if((*pnum)==MAX)
return -1;
v[*pnum]=value;
(*pnum)++;
return 0;}
int borrarinicio(double *v, int *pnum, double *pvalue) {
int i;
if((*pnum)==0)
return -1;
*pvalue = v[0];
for(i=1;i<(*pnum);i++)
v[i-1]=v[i];
(*pnum)--;
return 0;
}
/*------------------- CAMBIAR INPUT EXTERNO-----------------------------------*/
/*----------------------------------------------------------------------------*/
void Change_InputExt(BGan **Population,double (*New_function)(double ext_param[5],double k, double t),int index_BG, int index_neuron){
if (0<=index_neuron && index_neuron<(*Population)[index_BG-1].neuron_number){
(*Population)[index_BG-1].circle[index_neuron].ext=New_function;
}
else
printf("Error al Cambio %d\n",index_neuron);
}
/*------------------- FUNCION DE ACTIVACION- ---------------------------------*/
/*----------------------------------------------------------------------------*/
double Activation_function(double det_input,double stoch_input,double threshold,double *aux){
double z;
double total_input=det_input+stoch_input;
if (total_input<threshold){
*aux=0.0;
return 0.0;}
else
{z=det_input-threshold;
*aux=stoch_input;
return z;}
}
void solve_equations(BGan *Population,int Number_BG,conductor *Network,int N_BGconnection, double ****data_delayed,int dim_delay[],int **Numbers_Connection,int BG_Spike,double **ext_parameters,double **LFP_parameter,double *Electr_parameter,double *DBS_parameter){
//void solve_equations(BGan *Population,int Number_BG,conductor *Network,int N_BGconnection, double ****data_delayed,int dim_delay[],int **Numbers_Connection,int BG_Spike,double **ext_parameters,double **LFP_parameter,double *Electr_parameter,double *DBS_parameter,double Variability){
//Inputs:
//-Population[Number_BG]
//-Network[N_BGconnection]
//data_delayed[BG_index,neuron_index,connection,time]
//dim_delay[N_BGconnection]
//Numbers_connection[BG_index, neuron_index]
//index BG_spike
//[H_Ctx,H_str] LFP_parameters(g) DBS_parameters(g) DBS_parameters(t) variability
int i,j,k,s; //indexs
int N_aux,Kab; //aux integers
double value, aux; //aux doubles
double theta;
double sigma;
double synp_eff;
double tau;
double input_det;
double input_sto;
double threshold;
double Activity;
/*Equations parameters*/
double t=t_0_sim; //Initial time
double x_0=0.0; //Initial condition for m_ij
int temp_steps= floor((t_f_sim-t_0_sim)/dt); // # of steps (time).
/*Initial condition for m_{i->j} is zero*/
int ***ocu=NULL;
ocu=(int***)malloc(N_BGconnection*sizeof(int**));
for(i=0;i<N_BGconnection;i++){
N_aux=Network[i].last->neuron_number;
ocu[i]=(int**)malloc(N_aux*sizeof(int*));
for(j=0;j<N_aux;j++){
Kab=Numbers_Connection[i][j];
ocu[i][j]=(int*)malloc(Kab*sizeof(int));
for(k=0;k<Kab;k++){
(Network[i].cond)[j][k].sinaptic_curr=x_0;
ocu[i][j][k]=dim_delay[i];}
}
}
/*Files - Results*/
//FILE *SPIKES; //Save (neuron,time) of spike
FILE *CTX, *STN,*GPI;//,*THA,*CTX,*STR; //Save current in BG.
FILE *HCTX,*HSTR; //Verification External Input
FILE *HDBS; //Verification DBS
//FILE *Output_A_B;
//SPIKES=fopen("SPIKES.dat","w");
STN=fopen("STN.dat","w");
GPI=fopen("GPI.dat","w");
//THA=fopen("THA.dat","w");
CTX=fopen("CTX.dat","w");
//STR=fopen("STR.dat","w");
HCTX=fopen("H_CTX.dat","w");
HSTR=fopen("H_STR.dat","w");
HDBS=fopen("H_DBS.dat","w");
//Output_A_B=fopen("Output_A_B.dat","w");
/*DBS parameters*/
int BG_dbs_index= floor(Electr_parameter[0]); //index_stimulation
/*Random pulses*/
//double frec_m=1.0/DBS_parameter[1]; //mean frequency
//double per=Variability; //sigma/f_med
//double interval=(t_f_DBS-t_0_DBS); //ms
//int n_pulse=floor((frec_m*interval)*(1-pow(per,2)));
//double *inicios=(double*)malloc(n_pulse*sizeof(double));
//srand(time(NULL));
//inicios[0]=t_0_DBS;
//for(i=1;i<n_pulse;i++){
// inicios[i]=inicios[i-1]+1.0/random_frequency(frec_m,per);}
/*Temporal solution of eqs dif*/
for(i=0;i<temp_steps;i++){
fprintf(STN,"%f \t",t);
fprintf(GPI,"%f \t",t);
//fprintf(THA,"%f \t",t);
fprintf(CTX,"%f \t",t);
//fprintf(STR,"%f \t",t);
fprintf(HCTX,"%f \t",t);
fprintf(HSTR,"%f \t",t);
fprintf(HDBS,"%f \t",t);
//fprintf(Output_A_B,"%f \t",t);
/*----------------------------------------------------------------------------------------------------------*/
/*Load external (deterministic and noise) input */
for(j=0;j<Number_BG;j++){
for(k=0;k<Population[j].neuron_number;k++){
theta=Population[j].circle[k].angle;
Population[j].circle[k].input_det = Population[j].circle[k].ext(ext_parameters[j],cos(theta),t);
sigma=Population[j].circle[k].parameters[2];
Population[j].circle[k].input_sto = external_noise(0,sigma);}
}
/*Total inputs*/
for(j=0;j<N_BGconnection;j++){
N_aux=Network[j].last->neuron_number;
synp_eff=Network[j].parameters[0];
for(k=0;k<N_aux;k++){
for(s=0;s<Numbers_Connection[j][k];s++){
borrarinicio(data_delayed[j][k][s],&(ocu[j][k][s]),&value);
((Network[j].cond)[k][s].next)->input_det = ((Network[j].cond)[k][s].next)->input_det + (synp_eff*value);}
}
}
/*DBS Stimulation*/
for(k=0;k<Population[BG_dbs_index-1].neuron_number;k++){
theta=Population[BG_dbs_index-1].circle[k].angle;
Population[BG_dbs_index-1].circle[k].input_det=Population[BG_dbs_index-1].circle[k].input_det+spatial_electrode(Electr_parameter[1],Electr_parameter[2],Electr_parameter[3],theta)*DBS_Periodic(t,DBS_parameter[0],DBS_parameter[1],DBS_parameter[2],DBS_parameter[3]);}
//Population[BG_dbs_index-1].circle[k].input_det=Population[BG_dbs_index-1].circle[k].input_det+spatial_electrode(Electr_parameter[1],Electr_parameter[2],Electr_parameter[3],theta)*DBS_Random(t,DBS_parameter[0],DBS_parameter[2],DBS_parameter[3],inicios,n_pulse);}
/*----------------------------------------------------------------------------------------------------------*/
/*Verification external iputs*/
fprintf(HCTX,"%f \n",Population[1].circle[1400].ext(ext_parameters[1],cos(Population[1].circle[1400].angle),t));
fprintf(HSTR,"%f \n",Population[3].circle[1400].ext(ext_parameters[3],cos(Population[3].circle[1400].angle),t));
fprintf(HDBS,"%f \n",DBS_Periodic(t,DBS_parameter[0],DBS_parameter[1],DBS_parameter[2],DBS_parameter[3]));
//fprintf(HDBS,"%f \n",DBS_Random(t,DBS_parameter[0],DBS_parameter[2],DBS_parameter[3],inicios,n_pulse));
/*Synaptic current*/
/*for(k=0;k<Population[0].neuron_number;k++){
fprintf(THA,"%lf \t",Population[0].circle[k].input_det+Population[0].circle[k].input_sto);}
fprintf(THA,"\n");*/
for(k=0;k<Population[1].neuron_number;k++){
fprintf(CTX,"%lf \t",Population[1].circle[k].input_det+Population[1].circle[k].input_sto);}
fprintf(CTX,"\n");
for(k=0;k<Population[2].neuron_number;k++){
fprintf(STN,"%lf \t",Population[2].circle[k].input_det+Population[2].circle[k].input_sto);}
fprintf(STN,"\n");
/*for(k=0;k<Population[3].neuron_number;k++){
fprintf(STR,"%lf \t",Population[3].circle[k].input_det+Population[3].circle[k].input_sto);}
fprintf(STR,"\n");*/
for(k=0;k<Population[4].neuron_number;k++){
fprintf(GPI,"%lf \t",Population[4].circle[k].input_det+Population[4].circle[k].input_sto);}
fprintf(GPI,"\n");
/*----------------------------------------------------------------------------------------------------------*/
/*Generation of spikes*/
/*for(k=0;k<Population[BG_Spike-1].neuron_number;k++){
value=rand()/(double)RAND_MAX;
input_det=Population[BG_Spike-1].circle[k].input_det;
input_sto=Population[BG_Spike-1].circle[k].input_sto;
threshold=Population[BG_Spike-1].circle[k].parameters[0];
if(value< dt*(Activation_function(input_det,input_sto,threshold,&aux)+aux)){
fprintf(SPIKES,"%d \t %lf \n",k,t);}
}
/*----------------------------------------------------------------------------------------------------------*/
/*VARIABLE M_Alpha->Beta (Output)*/
//for (j=0;j<C;j++){
// fprintf(Output_A_B,"%f \t",(Red[j].cond)[0][0].M);}
//fprintf(Output_A_B,"\n");
/*----------------------------------------------------------------------------------------------------------*/
/*Solving system*/
for (j=0;j<N_BGconnection;j++){
N_aux=Network[j].last->neuron_number;
for(k=0;k<N_aux;k++){
for(s=0;s<Numbers_Connection[j][k];s++){
input_det=(Network[j].cond)[k][s].last->input_det;
input_sto=(Network[j].cond)[k][s].last->input_sto;
threshold=(Network[j].cond)[k][s].last->parameters[0];
tau=(Network[j].parameters[1]);
Activity=Activation_function(input_det,input_sto,threshold,&aux);
(Network[j].cond)[k][s].sinaptic_curr = (Network[j].cond)[k][s].sinaptic_curr + dt * (Activity -(Network[j].cond)[k][s].sinaptic_curr)/ tau + (sqrt(dt)*aux)/tau;
insertarfinal(data_delayed[j][k][s],&(ocu[j][k][s]),(Network[j].cond)[k][s].sinaptic_curr,dim_delay[j]);}
}
}
t=t+dt;
}
//fclose(SPIKES);
fclose(STN);
fclose(GPI);
//fclose(THA);
fclose(CTX);
//fclose(STR);
fclose(HCTX);
fclose(HSTR);
fclose(HDBS);
//fclose(Output_A_B);
}
int main(){
//int main(int argc, char *argv[]){
//argc = ["main", H_ctx, H_str,amplitude_DBS,period_DBS,width_DBS,slope_DBS,variability (option)]
srand(time(NULL));
char *endptr;
int i,j,k; //indexs
int aux;
/*-------------------BUILD NETWORK-------------------------------*/
/*---------------------------------------------------------------*/
BGan *Population=NULL; //Populations of basal ganglia
conductor *Network=NULL; //Connections between neurons
int **Numbers_Connection=NULL; //Number of connection for each neuron (in each BG)
int Number_BG=5;
printf("1-Iniciando. \n");
int N_BGconnection=Network_construction(&Population,Number_BG,&Network,&Numbers_Connection); //Building network - N_BGconnection: number of connections between BG's.
printf("2-Red Construida. \n");
/*--------------------DELAYED DATA-------------------------------*/
/*---------------------------------------------------------------*/
double ****data_delayed=(double ****)malloc(N_BGconnection*sizeof(double***)); //values of m_ij "t in(-delay,0)" [BG_index][neuron_index][connection_index][time]
int dim_delay[N_BGconnection]; //Dimension of delay vector for each BG connections
for(i=0;i<N_BGconnection;i++){ //for each connection i between BG's
dim_delay[i]=floor(Network[i].parameters[2]/dt); //dim _ delay = delay / dt
aux=Network[i].last->neuron_number; //aux:number of neurons in BG input
data_delayed[i]=(double***)malloc(aux*sizeof(double**));
for(j=0;j<aux;j++){ //for each neuron j in this BG.
data_delayed[i][j]=(double**)malloc(Numbers_Connection[i][j]*sizeof(double*));
for(k=0;k<Numbers_Connection[i][j];k++){ //for each connection k of neuron j
data_delayed[i][j][k]=(double*)calloc(dim_delay[i],sizeof(double));} //data delayed = vector of dim dim_delay[i]
}
}
printf("3-Vectores delays listos.\n");
//- PARA VER DISTRIBUCION DE CONEXIONES -//
//FILE *fp;
//fp=fopen("Numbers_Connection-Gpi-Th.dat","w");
//
//for(i=0;i<2800;i++){
// fprintf(fp,"%d \n",Numbers_Connection[5][i]);
//}
//
//fclose(fp);
/*-----INPUTS EXTERNOS CTX-STR------*/
double **ext_parameters=(double**)malloc(Number_BG*sizeof(double*)); //Numeration 1-Th; 2-Ctx; 3-STN; 4-Str; 5-GPi
for (i=0;i<Number_BG;i++){ //Mean spat, mod spat, mean temp, mod temp, period
ext_parameters[i]=(double*)calloc(5,sizeof(double));
ext_parameters[i][2]=1.0;
ext_parameters[i][4]=1.0;
}
scanf("%lf \t %lf \t",&ext_parameters[1][0],&ext_parameters[3][1]);
//ext_parameters[1][0]=strtod(argv[1],&endptr); //CTX
//ext_parameters[3][1]=strtod(argv[2],&endptr); //Str
for(j=0;j<Population[1].neuron_number;j++){
Change_InputExt(&Population,external_Ctx,2,j);}
for(j=0;j<Population[3].neuron_number;j++){
Change_InputExt(&Population,external_Str,4,j);}
printf("4-Se cambiaron las entradas.\n");
/*----------------LFP PARAMETERS(geometric)-----------------------*/
/*---------------------------------------------------------------*/
FILE *Electr_LFP;
Electr_LFP=fopen("ElectrodosLFP.dat","r");
double **LFP_parameter=(double**)malloc(Number_BG*sizeof(double*));
for(i=0;i<Number_BG;i++){ //for each BG: [index_BG,ang_center,threshold,volumen_integration]
LFP_parameter[i]=(double*)malloc(4*sizeof(double));
fscanf(Electr_LFP,"%lf \t %lf \t %lf \t %lf \n",&LFP_parameter[i][0],&LFP_parameter[i][1],&LFP_parameter[i][2],&LFP_parameter[i][3]);}
fclose(Electr_LFP);
/*-------------STIMULATOR PARAMETERS(geometric)------------------*/
/*---------------------------------------------------------------*/
FILE *Electr_Geometry;
Electr_Geometry=fopen("ElectrodosEstim.dat","r");
double *Electr_parameter=(double*)malloc(4*sizeof(double)); //[index_BG,ang_center,threshold,VTA]
fscanf(Electr_Geometry,"%lf \t %lf \t %lf \t %lf \n",&Electr_parameter[0],&Electr_parameter[1],&Electr_parameter[2],&Electr_parameter[3]);
fclose(Electr_Geometry);
/*-------------STIMULATOR PARAMETERS(temporal)-------------------*/
/*---------------------------------------------------------------*/
double DBS_parameter[4]; //[amplitude,period,width,slope]
scanf("%lf \t %lf \t %lf \t %lf",&DBS_parameter[0],&DBS_parameter[1],&DBS_parameter[2],&DBS_parameter[3]);
//for(i=0;i<4;i++){
// DBS_parameter[i]=strtod(argv[i+3],&endptr);}
//double Variability=strtod(argv[7],&endptr); //variability in random DBS.
printf("5-Electrodos configurados.\n");
/*-----------------------SOLVING SYSTEM--------------------------*/
/*---------------------------------------------------------------*/
printf("6-Resolviendo sistema.\n");
int BG_spike=3; //Numeration 1-Th; 2-Ctx; 3-STN; 4-Str; 5-GPi
solve_equations(Population,Number_BG,Network,N_BGconnection,data_delayed,dim_delay,Numbers_Connection,BG_spike,ext_parameters,LFP_parameter,Electr_parameter,DBS_parameter);
//solve_equations(Population,Number_BG,Network,N_BGconnection,data_delayed,dim_delay,Numbers_Connection,BG_spike,ext_parameters,LFP_parameter,Electr_parameter,DBS_parameter,Variability);
printf("7-Fin\n");
return 0;
}