-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathanmodel.cpp
More file actions
289 lines (266 loc) · 9.65 KB
/
anmodel.cpp
File metadata and controls
289 lines (266 loc) · 9.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
/** \file anmodel.cpp
* \brief This is the main file for the AN model.
* <p>the output is stored in filterout, synapseout
* <p>The stimulus is read from the file(default filename is "click")
* <p>The program initializes the filter bank model first(according to the parameters
* specified in the commandline).
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream.h>
#include <fstream.h>
#include "cmpa.hpp"
#include "complex.hpp"
#define NSTIMMAX 100000 // enough points for durations up to 250 msec
#define NUMCHANS 64 // Number of fibers in the population to be simulated
#define MAXSPIKES 10000
double stim[NSTIMMAX];
double sout[NSTIMMAX];
double sptime[MAXSPIKES]; //spike time storage
/// This structure defines the parameters needed for the model
typedef struct {
char wavefile[100]; //filename for stimulus waveform
int banks; //number of filters in filterbank
double delx; //"delta x", or spacing of "IHC"s along BM (linearly spaced IHCs in terms of location along BM
// results in approximately logarithmic spacing in terms of frequency.
int stim;
double tdres; //time step (time domain resolution)
int nstim,nrep; // nstim=number of pts in stimulus; nrep is number of reps of stimulus
int runmode;
double freqt,spl,dur,reptim; //for tone and other stim
//noise(2),click(3)
double F1,F2,spl1,spl2; //for two tone suppression(8)
double *buf;
double rf; //rise & fall
int rfmethod;// rise & fall method
double cfhi,cflo,cfinc;
double splhi,spllo,splinc;
double freqthi,freqtlo,freqtinc;
} T_stim;
int parsecommandline(TAuditoryNerve *pan,T_stim *ptm,int argc, char* argv[]);
int synapse(TAuditoryNerve *pan,int nstim,int nrep,double *sout,double *sptime);
int main(int argc, char* argv[])
{
static T_stim tm; // structure to store the input parameters
static TAuditoryNerve an[NUMCHANS]; // filter bank(Maximum 64)
double xlo,xhi,delx,xcenter;
int species = 1; //CAT
int icenter;
int icf;
int nspikes;
double x,cf;
FILE *fpstim,*fpbm,*fpsout; //open these file when run
double buf; //tempory value to store the stimulus
long flag,nowstim,totalstim;
an[0].tdres = tm.tdres = 10e-6; //default sample rate = 500kHz
an[0].cf = 1000; //default CF : 1000 Hz
an[0].spont = 50; // spont rate : 50
strcpy(tm.wavefile,"click"); //input file : click
tm.reptim = 0.020; //repetition time : 20 msec
tm.delx = 0.05; //distance between two filters along BM : 0.05mm
tm.cflo = -1;
tm.cfhi = -1;
tm.banks = -1; //default : no filters
tm.nrep = 0;
parsecommandline(&an[0],&tm,argc,argv); // get the parameters from command line
if(tm.banks == -1) //this is for a simulation of a single anditory nerve fiber
{
tm.banks = 1;
xcenter = cochlea_f2x(species,an[0].cf); //convert from CF to BM location
delx = 0;
}
else if(tm.cflo == -1) //this is for AN fiber population
{
xcenter = cochlea_f2x(species,an[0].cf);
delx = tm.delx;
}
else
{
if(tm.cfhi<tm.cflo) error("cfhi should be greater than cflo");
xlo = cochlea_f2x(species,tm.cflo);
xhi = cochlea_f2x(species,tm.cfhi);
xcenter = (xhi -xlo)/2. + xlo;
delx = (xhi-xlo)/(tm.banks-1);
an[0].cf = cochlea_x2f(species,xcenter);
};
printf("\n Filter Bank: center CF=%f, xcenter=%f(mm from apex), number of fibers= %d\n",an[0].cf,xcenter,tm.banks);
icenter = tm.banks/2;
nowstim = 0;
totalstim = (long)(tm.reptim/an[0].tdres);
buf = 0.0;
// ******************now begin to pass the stimulus to the model************************
// Read in the stimulus
for(nowstim=0; nowstim<NSTIMMAX; nowstim++) stim[nowstim] = 0.0;
printf("\nReading in stimulus \n");
fpstim = fopen(tm.wavefile,"r");
nowstim=0;
while((fscanf(fpstim,"%le",&stim[nowstim]) != EOF) & nowstim<NSTIMMAX)
nowstim++;
printf("%d points read in\n",nowstim);
if(totalstim < nowstim) totalstim=nowstim;
fclose(fpstim);
if(nowstim>=NSTIMMAX) error("Entire stim not read in: increase NSTIMMAX");
if(totalstim>=NSTIMMAX) error("Entire reptim too long: increase NSTTMMAX");
// construct the model
for(icf = 0; icf < tm.banks; icf++) /* Loop through the filters */
{
x = xcenter + (icf - icenter)*delx;
cf = cochlea_x2f(species,x); // from BM location to CF
an[icf].cf = cf;
an[icf].tdres = an[0].tdres;
an[icf].spont = an[0].spont;
an[icf].construct();
an[icf].init(cf,an[icf].spont);
printf("icf = %d out of %d x= %f cf= %f\n",icf,tm.banks,x,cf);
};
flag = 0; //if = 1,don't read from stimulus file but set zero as input
nowstim = 0;
fpbm = fopen("filterout","w");
fpsout = fopen("synapseout","w");
while(nowstim<totalstim)
{
buf = stim[nowstim];
fprintf(fpbm,"%g",nowstim*an[0].tdres);
fprintf(fpsout,"%g",nowstim*an[0].tdres);
for(icf = 0; icf < tm.banks; icf++) // Loop through the filters
{
an[icf].run(buf);
fprintf(fpbm," %g",an[icf].bmbuf); // Write filter response out to file
fprintf(fpsout," %g",an[icf].sbuf); // Write synapse output to file
};
fprintf(fpbm,"\n");
fprintf(fpsout,"\n");
sout[nowstim] = an[0].sbuf;
nowstim++;
}; //end of while
fclose(fpbm);
fclose(fpsout);
printf("\n AN filter bank simulation is complete. \n");
if((tm.nrep>0)&&(tm.banks==1))
{
printf("\n Generate spike times and the PST histogram(write out to files pstplot and sptime...\n");
nspikes = synapse(&an[0],totalstim,tm.nrep,sout,sptime);
double bin = 0.0001;
int nbins = (int)(tm.reptim / bin + 1);
int *pst = new int[nbins];
int i;
/* Construct PST HISTOGRAM, Interval hist, Period hist. */
for(i = 0; i < nbins; i++) pst[i] = 0;
for(i = 0; i < nspikes; i++)
{
/* both sptime and bin are in secs */
int ipst = (int)(fmod(sptime[i],tm.tdres*totalstim) / bin);
pst[ipst] = pst[ipst] + 1;
}
fstream *fp = new fstream("pstplot",ios::out);
for(i = 0; i < nbins; i++)
{
(*fp)<<(i*bin)<<' '<<pst[i]<<"\n";
};
delete fp;
delete pst;
fp = new fstream("sptime",ios::out);
for(i = 0; i < nspikes; i++)
{
(*fp)<<i<<' '<<sptime[i]<<"\n";
};
delete fp;
};
};
// ----------------------------------------------------------------
/**
* This function reads the command line options and store them in the structure
*/
int parsecommandline(TAuditoryNerve *pan,T_stim *ptm,int argc, char* argv[])
{
int i;
int needhelp = 0;
char *para;
i = 1;
if(argc ==1 ) needhelp = 1;
while(i<argc)
{ para = argv[i];
if((*para)=='-')
{ para++;
if(strcmp(para,"tdres")==0)
{
pan->tdres = double(atof(argv[++i]));
ptm->tdres = pan->tdres;
}
else if(strcmp(para,"cf")==0)
pan->cf = double(atof(argv[++i]));
else if(strcmp(para,"spont")==0)
pan->spont = double(atof(argv[++i]));
else if(strcmp(para,"fibers")==0)
ptm->banks = atoi(argv[++i]);
else if(strcmp(para,"reptim")==0)
ptm->reptim = double(atof(argv[++i]));
else if(strcmp(para,"delx")==0)
ptm->delx = double(atof(argv[++i]));
else if(strcmp(para,"trials")==0)
ptm->nrep = atoi(argv[++i]);
else if(strcmp(para,"cfhi")==0)
ptm->cfhi = double(atof(argv[++i]));
else if(strcmp(para,"cflo")==0)
ptm->cflo = double(atof(argv[++i]));
else if(strcmp(para,"wavefile")==0)
{
ptm->stim = 11;
strcpy(ptm->wavefile,argv[++i]);
}
else if(strcmp(para,"help")==0)
needhelp = 1;
else
{ printf("\nUnkown parameters --> %s",para); needhelp = 1; break; };
}
else { printf("\nUnkown parameters --> %s",para); needhelp = 1; break; };
i++;
};
if(needhelp==1)
{
printf("\n This program accepts following parameters:\n");
printf("\n -cf #(1000) --> character frequency of the AN model fiber (or center CF for filter bank)");
printf("\n -spont #(50) --> spontaneous rate of the fiber");
printf("\n -tdres #(10e-6)--> time domain resolution(in seconds)");
printf("\n -fibers #(1) --># of filters, use this option with cf,cflo,cfhi,delx");
printf("\n -wavefile filename(click) --> specify the stimulus wavefile name(click)");
printf("\n -delx #(0.05mm) --> distance between filters along basilar membrane");
printf("\n -reptim #(0.02) --> Total duration of stimulation(20msec)");
printf("\n -cfhi #(-1) --> highest cf in population (specify cfhi,cflo will recalculate cf&delx");
printf("\n -cflo #(-1) --> lowest cf in population");
printf("\n -trials #(0) --> spike generation trials (this is valid only if # of fibers=1)");
printf("\n");
exit(1);
};
return(0);
};
// --------------------------------------------------------------------------------
/** this routine generates spike times according to *sout with nrep representation
put the spikes time into buffer *spikes, nspikes
*/
int synapse(TAuditoryNerve *pan,int nstim,int nrep,double *sout,double *sptime)
{
int i,j,isp;
int nspikes = 0;
/* sout[] contains prob of spike vs. time - run through it nrep times to look for spikes */
isp = 0;
sptime[0] = 0.; /* start out with a spike at t=0 on 1st rep */
pan->sg->init(sout[0]); //initialize the spike generator
for(i = 0; i < nrep; i++)
{
pan->sg->init(sout[0]);
for( j = 0; j < nstim; j++)
{
if(pan->sg->run(sout[j])==1)
{
sptime[isp] = pan->sg->Get_rtime(); /* leave sptime in sec */
isp++;
if(isp>MAXSPIKES) error("\nToo much spikes generated: increase MAXSPIKES\n");
}
}
nspikes = isp;
};
return nspikes;
};