Mercurial > hg > aim92
comparison saitools/saicut.c @ 0:5242703e91d3 tip
Initial checkin for AIM92 aimR8.2 (last updated May 1997).
author | tomwalters |
---|---|
date | Fri, 20 May 2011 15:19:45 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:5242703e91d3 |
---|---|
1 /* | |
2 Copyright (c) Applied Psychology Unit, Medical Research Council. 1993 | |
3 =========================================================================== | |
4 | |
5 Permission to use, copy, modify, and distribute this software without fee | |
6 is hereby granted for research purposes, provided that this copyright | |
7 notice appears in all copies and in all supporting documentation, and that | |
8 the software is not redistributed for any fee (except for a nominal | |
9 shipping charge). Anyone wanting to incorporate all or part of this | |
10 software in a commercial product must obtain a license from the Medical | |
11 Research Council. | |
12 | |
13 The MRC makes no representations about the suitability of this | |
14 software for any purpose. It is provided "as is" without express or | |
15 implied warranty. | |
16 | |
17 THE MRC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING | |
18 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL | |
19 THE A.P.U. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES | |
20 OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |
21 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |
22 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | |
23 SOFTWARE. | |
24 */ | |
25 /* saicut.c | |
26 * ------------ | |
27 * | |
28 * Cuts out frames or channels (or both) from a .sai | |
29 * output= .sai | |
30 * | |
31 * options: -frame <start> <end> (units=frame numbers; INCLUSIVE). | |
32 * -channel <low> <high> (units=channel nos; INCLUSIVE). | |
33 * (both arguments are needed). | |
34 * | |
35 * When using verbose, those frame numbers that are NOT kept are put in | |
36 * round brackets (). | |
37 * | |
38 * | |
39 * M Akeroyd. June 1993. v1.00 Revised Spring 1994. | |
40 * Lots of extra options Winter 1995. | |
41 */ | |
42 | |
43 | |
44 | |
45 #include <stdio.h> | |
46 #include <string.h> | |
47 #include <stdlib.h> | |
48 #include "tip.h" | |
49 | |
50 | |
51 | |
52 | |
53 /* Function declarations */ | |
54 /*-------------------------------------------------------------------------*/ | |
55 | |
56 void parsecommandline (int argc, char *argv[], char inputfn[], char outputfn[]); | |
57 int readheader(FILE *inputfp); | |
58 void checkheader(); | |
59 void writeheader(FILE *outputfp); | |
60 void changeheader(int no_frames, int new_pwidth, int new_nwidth, int framewidthsamples_output); | |
61 void changeheader_B(int new_mincf, int new_maxcf, int new_channels); | |
62 | |
63 void writedata_output (FILE *outputfp, int samples_to_write); | |
64 FILE *open_file (char filefn[], FILE *dir_default, int streamtype); | |
65 | |
66 | |
67 /* Data Arrays */ | |
68 /* ------------------------------------------------------------------------*/ | |
69 short inputdata[MAX_DATA]; | |
70 short inputbychannel[MAX_CHANNELS][MAX_DATA]; | |
71 short outputfiguredata[MAX_DATA]; | |
72 short outputgrounddata[MAX_DATA]; | |
73 | |
74 #define MAX_STROBES 2000 | |
75 int strobelocation[MAX_STROBES]; | |
76 | |
77 /* variables read from header */ | |
78 /*-------------------------------------------------------------------------*/ | |
79 char header[MAX_LINES_HEADER][MAX_LINE_LENGTH]; | |
80 int header_lines; | |
81 | |
82 /* .sai parameters */ | |
83 int no_frames; | |
84 int frameheight; /* number of channels */ | |
85 int framewidth_samples; /* pwidth + nwidth * samplerate */ | |
86 int frameshift_samples; /* frstep_aid * samplerate */ | |
87 int pwidth; /* in msecs */ | |
88 int nwidth; /* in msecs: NEGATIVE */ | |
89 int width_win; /* pixels */ | |
90 int height_win; /* pixels */ | |
91 long samplerate; /* samples per sec */ | |
92 int mincf; /* Hz */ | |
93 int maxcf; /* Hz */ | |
94 | |
95 /* parameters read from command line*/ | |
96 int framestart; | |
97 int frameend; | |
98 int minchannel; | |
99 int maxchannel; | |
100 | |
101 int cut_timestart; | |
102 int cut_timeend; | |
103 int counter; | |
104 float sum; | |
105 float tempf; | |
106 float timestart, timeend; | |
107 | |
108 /* misc */ | |
109 /*-----------------------------------------------------------------------*/ | |
110 | |
111 char progname[MAX_STRING_LENGTH]; | |
112 char outputfigurefn[MAX_STRING_LENGTH]; | |
113 char strobefn[MAX_STRING_LENGTH]; | |
114 | |
115 | |
116 int verboseflag = OFF; /* -v */ | |
117 int frameflag = OFF; /* -f */ | |
118 int channelflag = OFF; /* -c */ | |
119 int greyscaleflag = OFF; /* Not used: required for compilation */ | |
120 int oppositearchflag = OFF; /* -oparch : see saigraph.c for info */ | |
121 int sumflag = OFF; | |
122 int averageflag = OFF; | |
123 int timeflag = OFF; | |
124 int headerflag = ON; | |
125 int strobeflag = OFF; | |
126 int strobevalue = 1; /* the value used to mark a strobe event in | |
127 the .trigger file */ | |
128 int cutthisframe = OFF; | |
129 int infoflag = OFF; | |
130 int forceframeflag = OFF; | |
131 int forceframe = 0; | |
132 int successforceflag = OFF; | |
133 | |
134 /* ................... Main ................................*/ | |
135 /* .........................................................................*/ | |
136 /* .........................................................................*/ | |
137 | |
138 | |
139 | |
140 void main (int argc, char *argv[]) | |
141 { | |
142 int n, sample; | |
143 int frame, channel; | |
144 int trigger_peak = 0; | |
145 int header_bytes = 0; | |
146 int cut_framestart, cut_frameend, cut_no_frames; | |
147 int cut_minchannel, cut_maxchannel, cut_frameheight; | |
148 char inputfn[MAX_STRING_LENGTH], outputbasefn[MAX_STRING_LENGTH]; | |
149 FILE *inputfp, *outputfigurefp; | |
150 FILE *strobefp; | |
151 int x, counter, previousx; | |
152 int nstrobes; | |
153 short sampledata[2]; | |
154 | |
155 /*-------------------------------------*/ | |
156 strcpy(progname, argv[0]); | |
157 strcpy(inputfn, ""); | |
158 strcpy(outputbasefn, ""); | |
159 strcpy(outputfigurefn, ""); | |
160 | |
161 parsecommandline(argc, argv, inputfn, outputbasefn); | |
162 | |
163 if (strcmp(outputbasefn, "") == 0) | |
164 strcpy(outputfigurefn, ""); | |
165 else { | |
166 strcpy(outputfigurefn, outputbasefn); | |
167 /* strcat(outputfigurefn, OUTPUT_EXT);*/ | |
168 } | |
169 | |
170 /*--------------------------------------*/ | |
171 /* open files, read and check header */ | |
172 inputfp = open_file(inputfn, stdin, READ); | |
173 outputfigurefp = open_file(outputfigurefn, stdout, WRITE); | |
174 header_bytes = readheader(inputfp); | |
175 checkheader(); | |
176 | |
177 /*-------------------------------------*/ | |
178 /* strobe code */ | |
179 if (strobeflag == ON){ | |
180 strobefp = open_file(strobefn, stderr, READ); | |
181 /* note | |
182 * add (nwidth * samplerate) to the index | |
183 * the frame number is the floor of that + 1 (because it seems to give the correct answer) | |
184 * some versions of gensai return a triggerpoint 3 samples across; take the first. | |
185 */ | |
186 for (x=0; x<MAX_STROBES; x++) | |
187 strobelocation[x] = 0; | |
188 x=0; counter=1; | |
189 previousx=0; | |
190 while( feof(strobefp) ==0) { | |
191 fread(sampledata, 2, 1, strobefp); | |
192 if (sampledata[0] >= strobevalue){ | |
193 if (((x-previousx) <= 2) && (previousx != 0)) | |
194 /* don't need this trigger */ | |
195 continue; | |
196 strobelocation[counter] = x; | |
197 tempf = (float) strobelocation[counter] + (-1.0 * nwidth * samplerate / 1000.0); | |
198 tempf = tempf * 1.0 / frameshift_samples; | |
199 /* tempf = floor(tempf);*/ | |
200 strobelocation[counter] = (int) tempf + 1.0; | |
201 /* if (verboseflag == ON) | |
202 fprintf(stderr, "strobe %i: %i samples %f (%i frames)\n", counter, x, tempf, (int)strobelocation[counter]);*/ | |
203 previousx=x; | |
204 counter++;} | |
205 x++; | |
206 if (counter >= MAX_STROBES){ | |
207 fprintf(stderr, " %s : too many strobes in .trigger file.\n", progname); | |
208 exit(-1);} | |
209 } | |
210 nstrobes=counter-1; | |
211 if (infoflag == ON){ | |
212 fprintf(stderr, "using %i frames ", nstrobes); | |
213 for (counter=1; counter <=nstrobes; counter ++) | |
214 fprintf(stderr, " %i", strobelocation[counter]); | |
215 fprintf(stderr, "\n");} | |
216 fclose(strobefp); | |
217 } | |
218 | |
219 /*--------------------------------------*/ | |
220 | |
221 /* reset the frame/channel counters */ | |
222 if (frameflag == ON) { | |
223 cut_frameend = frameend; | |
224 cut_framestart = framestart; } | |
225 else { | |
226 cut_frameend = no_frames; | |
227 cut_framestart = 1; } | |
228 | |
229 if (channelflag == ON) { | |
230 cut_maxchannel = maxchannel; | |
231 cut_minchannel = minchannel; } | |
232 else { | |
233 cut_maxchannel = frameheight; | |
234 cut_minchannel = 1; } | |
235 | |
236 if (timeflag == ON) { | |
237 cut_timestart = samplerate * timestart/1000; | |
238 cut_timeend = samplerate * timeend/1000;} | |
239 else{ | |
240 cut_timestart = 0; | |
241 cut_timeend = framewidth_samples;} | |
242 | |
243 /* fprintf(stderr, "%d \n", cut_timestart);*/ | |
244 /* fprintf(stderr, "%d \n", cut_timeend);*/ | |
245 | |
246 cut_no_frames = cut_frameend - cut_framestart + 1; /* inclusive, so +1 */ | |
247 cut_frameheight = cut_maxchannel - cut_minchannel + 1; /* inclusive, so +1 */ | |
248 if (strobeflag == ON) | |
249 cut_no_frames = nstrobes; | |
250 | |
251 /*--------------------------------------*/ | |
252 /* WARNING: 'time' options are NOT built into the headers yet */ | |
253 | |
254 changeheader(cut_no_frames, pwidth, nwidth, framewidth_samples); | |
255 changeheader_B(mincf, maxcf, cut_frameheight); | |
256 if (headerflag == ON) | |
257 writeheader(outputfigurefp); | |
258 | |
259 /*--------------------------------------*/ | |
260 | |
261 if (verboseflag==ON) { | |
262 fprintf(stderr, " frames "); | |
263 fflush(stderr);} | |
264 | |
265 /*------------------------------------------------------------------------*/ | |
266 | |
267 for (frame=1; frame<=no_frames; frame++) { | |
268 | |
269 if (strobeflag == OFF) { | |
270 if ((frame < cut_framestart) || (frame > cut_frameend )) | |
271 cutthisframe = OFF; | |
272 else | |
273 cutthisframe = ON;} | |
274 else { | |
275 cutthisframe = OFF; | |
276 for (counter=1; counter <= nstrobes; counter ++){ | |
277 if (frame == strobelocation[counter]) | |
278 cutthisframe = ON;}} | |
279 | |
280 if (forceframeflag == ON){ | |
281 if (frame < forceframe){ | |
282 cutthisframe = OFF;} | |
283 else { | |
284 if (successforceflag == OFF){ | |
285 if (cutthisframe == ON){ | |
286 successforceflag = ON; | |
287 fprintf(stdout, "%d\n", frame);}} | |
288 else | |
289 cutthisframe = OFF;}} | |
290 | |
291 if (verboseflag == ON) { | |
292 if (cutthisframe == ON){ | |
293 fprintf(stderr, " %i ", frame); fflush(stderr);} | |
294 else { | |
295 fprintf(stderr, " (%i) ", frame); fflush(stderr);}} | |
296 | |
297 /*--------------------------------------*/ | |
298 | |
299 for (channel=1; channel <=frameheight; channel ++) { | |
300 | |
301 for(sample=0; sample<framewidth_samples; sample++) | |
302 inputdata[sample] = 0; | |
303 | |
304 fread (inputdata, 2, framewidth_samples, inputfp); | |
305 | |
306 /* input check */ | |
307 for(sample=0; sample<framewidth_samples; sample++) | |
308 if (inputdata[sample] < 0 ) { | |
309 fprintf(stderr, "%s: something's gone wrong: the data is negative.\n", progname); | |
310 exit(-1); } | |
311 | |
312 for(sample=0; sample<framewidth_samples; sample++) | |
313 inputbychannel[channel][sample] = inputdata[sample]; | |
314 | |
315 } /* (loading of) channel */ | |
316 | |
317 /*--------------------------------------*/ | |
318 | |
319 /* Is this frame to be output? If not, next frame. */ | |
320 if (strobeflag == OFF){ | |
321 if ((frame < cut_framestart) || (frame > cut_frameend )) | |
322 continue;} | |
323 else { | |
324 if (cutthisframe == OFF) | |
325 continue;} | |
326 | |
327 /* output all required channels */ | |
328 for (channel = cut_minchannel; channel <= cut_maxchannel; channel++) { | |
329 sum = 0.0; | |
330 counter=0; | |
331 for(sample=cut_timestart; sample<cut_timeend; sample++) { | |
332 outputfiguredata[counter] = inputbychannel[channel][sample]; | |
333 if ((sumflag == ON) || (averageflag == ON)) | |
334 sum += inputbychannel[channel][sample]; | |
335 counter++;} | |
336 | |
337 if (sumflag == ON){ | |
338 outputfiguredata[0] = (short) sum; | |
339 counter=1;} | |
340 if (averageflag == ON){ | |
341 tempf = (float) sum/counter; | |
342 outputfiguredata[0] = (short) tempf; | |
343 counter=1;} | |
344 /* fprintf(stderr, "%f %d \n", sum, outputfiguredata[0]);*/ | |
345 | |
346 writedata_output(outputfigurefp, counter); } | |
347 | |
348 /*--------------------------------------*/ | |
349 | |
350 } /* frame */ | |
351 | |
352 /*----------------------------------------------------------------------*/ | |
353 | |
354 /* Tidy up and exit */ | |
355 if (verboseflag == ON) | |
356 fprintf(stderr, "\n"); | |
357 fclose(inputfp); fclose(outputfigurefp); | |
358 | |
359 if ( ferror(inputfp) != 0) { | |
360 fprintf(stderr, " %s : error closing input file.\n", progname); | |
361 exit(-1);} | |
362 | |
363 if ( ferror(outputfigurefp) != 0) { | |
364 fprintf(stderr, " %s : error closing figure file.\n", progname); | |
365 exit(-1);} | |
366 | |
367 exit(0); | |
368 | |
369 } /* Main */ | |
370 | |
371 | |
372 | |
373 | |
374 /*......................................................................*/ | |
375 /*......................................................................*/ | |
376 | |
377 | |
378 | |
379 | |
380 | |
381 void parsecommandline(int argc, char *argv[], char inputfn[], char outputbasefn[]) | |
382 { | |
383 int x=1, helpflag = OFF; | |
384 | |
385 while (x < argc){ | |
386 if (!strcmp(argv[x], "-o")) {strcpy(outputbasefn, argv[x+1]); x+=2;} | |
387 else if (!strcmp(argv[x], "-output")) {strcpy(outputbasefn, argv[x+1]); x+=2;} | |
388 else if (!strcmp(argv[x], "-i")) {strcpy(inputfn, argv[x+1]); x+=2;} | |
389 else if (!strcmp(argv[x], "-t")) {strobeflag=ON; frameflag=OFF;strcpy(strobefn, argv[x+1]); x+=2;} | |
390 else if (!strcmp(argv[x], "-input")) {strcpy(inputfn, argv[x+1]); x+=2;} | |
391 else if (!strcmp(argv[x], "-help")) {helpflag = ON; x+=1;} | |
392 else if (!strcmp(argv[x], "-h")) {helpflag = ON; x+=1;} | |
393 else if (!strcmp(argv[x], "-triggerinfo")) {infoflag = ON; x+=1;} | |
394 else if (!strcmp(argv[x], "-sum")) {sumflag = ON; averageflag=OFF; x+=1;} | |
395 else if (!strcmp(argv[x], "-average")) {sumflag = OFF; averageflag=ON; x+=1;} | |
396 else if (!strcmp(argv[x], "-header")) {headerflag = ON; x+=1;} | |
397 else if (!strcmp(argv[x], "-noheader")) {headerflag = OFF; x+=1;} | |
398 else if (!strcmp(argv[x], "-verbose")) {verboseflag = ON; x+=1;} | |
399 else if (!strcmp(argv[x], "-v")) {verboseflag = ON; x+=1;} | |
400 else if (!strcmp(argv[x], "-n")) {forceframeflag=ON; forceframe=atoi(argv[x+1]); x+=2;} | |
401 else if (!strcmp(argv[x], "-f")) {frameflag=ON; framestart=atoi(argv[x+1]); frameend=atoi(argv[x+2]); x+=3;} | |
402 else if (!strcmp(argv[x], "-frames")) {frameflag=ON; framestart=atoi(argv[x+1]); frameend=atoi(argv[x+2]); x+=3;} | |
403 else if (!strcmp(argv[x], "-c")) {channelflag=ON; minchannel=atoi(argv[x+1]); maxchannel=atoi(argv[x+2]); x+=3;} | |
404 else if (!strcmp(argv[x], "-channel")) {channelflag=ON; minchannel=atoi(argv[x+1]); maxchannel=atoi(argv[x+2]); x+=3;} | |
405 else if (!strcmp(argv[x], "-time")) {timeflag=ON; timestart=atof(argv[x+1]); timeend=atof(argv[x+2]); x+=3;} | |
406 else if (!strcmp(argv[x], "-oparch")) {oppositearchflag = ON; x+=1;} | |
407 else {fprintf(stderr, "%s: unknown option %s\n", progname, argv[x]); | |
408 exit(-1);} | |
409 } | |
410 | |
411 if (helpflag == ON) | |
412 { | |
413 fprintf(stderr, "\n"); | |
414 fprintf(stderr, " %s\n", progname); | |
415 fprintf(stderr, " -----------------------------------------------------------\n"); | |
416 fprintf(stderr, " Cuts a .sai by frame or channel, and (if necessary) just some\n"); | |
417 fprintf(stderr, " of the input image\n"); | |
418 fprintf(stderr, " The -oparch option is REQUIRED if reading a Sun .sai files \n"); | |
419 fprintf(stderr, " on a DEC cpu or vice-versa.\n"); | |
420 fprintf(stderr, " Add .sai to both input and output filenames.\n"); | |
421 fprintf(stderr, " WARNING: the header is not rebuilt properly for the\n"); | |
422 fprintf(stderr, " '-time' options.\n"); | |
423 fprintf(stderr, " -----------------------------------------------------------\n"); | |
424 fprintf(stderr, " -i <.sai file> input file default = stdin\n"); | |
425 fprintf(stderr, " -o <.sai file> output file default = stdout\n"); | |
426 fprintf(stderr, " -t <.trigger file> trigger location file\n"); | |
427 fprintf(stderr, " -oparch assume input was generated on an opposing architecture cpu\n"); | |
428 fprintf(stderr, "\n"); | |
429 fprintf(stderr, " -n <frame> take first frame after <frame>\n"); | |
430 fprintf(stderr, " -frames <start> <end> (inclusive) (default=all)\n"); | |
431 fprintf(stderr, " -time <start> <end> (inclusive; ms from leftedge)\n"); | |
432 fprintf(stderr, " -channel <low> <high> (inclusive) (default=all)\n"); | |
433 fprintf(stderr, " -sum sum and output 1 value per frame\n"); | |
434 fprintf(stderr, " -average sum, average & output 1 value per frame\n"); | |
435 fprintf(stderr, " -noheader don't output a .sai header\n"); | |
436 fprintf(stderr, " -header do output a .sai header (default)\n"); | |
437 fprintf(stderr, "\n"); | |
438 fprintf(stderr, " -v verbose output (to stderr)\n"); | |
439 fprintf(stderr, " -triggerinfo report the 'trigger' frames (to stderr)"); | |
440 fprintf(stderr, "\n\n"); | |
441 exit(-1);} | |
442 | |
443 } | |
444 | |
445 | |
446 | |
447 | |
448 | |
449 | |
450 |