Mercurial > hg > aim92
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/saitools/saicut.c Fri May 20 15:19:45 2011 +0100 @@ -0,0 +1,450 @@ +/* + Copyright (c) Applied Psychology Unit, Medical Research Council. 1993 + =========================================================================== + + Permission to use, copy, modify, and distribute this software without fee + is hereby granted for research purposes, provided that this copyright + notice appears in all copies and in all supporting documentation, and that + the software is not redistributed for any fee (except for a nominal + shipping charge). Anyone wanting to incorporate all or part of this + software in a commercial product must obtain a license from the Medical + Research Council. + + The MRC makes no representations about the suitability of this + software for any purpose. It is provided "as is" without express or + implied warranty. + + THE MRC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + THE A.P.U. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES + OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + SOFTWARE. +*/ +/* saicut.c +* ------------ +* +* Cuts out frames or channels (or both) from a .sai +* output= .sai +* +* options: -frame <start> <end> (units=frame numbers; INCLUSIVE). +* -channel <low> <high> (units=channel nos; INCLUSIVE). +* (both arguments are needed). +* +* When using verbose, those frame numbers that are NOT kept are put in +* round brackets (). +* +* +* M Akeroyd. June 1993. v1.00 Revised Spring 1994. +* Lots of extra options Winter 1995. +*/ + + + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include "tip.h" + + + + +/* Function declarations */ +/*-------------------------------------------------------------------------*/ + +void parsecommandline (int argc, char *argv[], char inputfn[], char outputfn[]); +int readheader(FILE *inputfp); +void checkheader(); +void writeheader(FILE *outputfp); +void changeheader(int no_frames, int new_pwidth, int new_nwidth, int framewidthsamples_output); +void changeheader_B(int new_mincf, int new_maxcf, int new_channels); + +void writedata_output (FILE *outputfp, int samples_to_write); +FILE *open_file (char filefn[], FILE *dir_default, int streamtype); + + +/* Data Arrays */ +/* ------------------------------------------------------------------------*/ +short inputdata[MAX_DATA]; +short inputbychannel[MAX_CHANNELS][MAX_DATA]; +short outputfiguredata[MAX_DATA]; +short outputgrounddata[MAX_DATA]; + +#define MAX_STROBES 2000 +int strobelocation[MAX_STROBES]; + +/* variables read from header */ +/*-------------------------------------------------------------------------*/ +char header[MAX_LINES_HEADER][MAX_LINE_LENGTH]; +int header_lines; + +/* .sai parameters */ +int no_frames; +int frameheight; /* number of channels */ +int framewidth_samples; /* pwidth + nwidth * samplerate */ +int frameshift_samples; /* frstep_aid * samplerate */ +int pwidth; /* in msecs */ +int nwidth; /* in msecs: NEGATIVE */ +int width_win; /* pixels */ +int height_win; /* pixels */ +long samplerate; /* samples per sec */ +int mincf; /* Hz */ +int maxcf; /* Hz */ + +/* parameters read from command line*/ +int framestart; +int frameend; +int minchannel; +int maxchannel; + +int cut_timestart; +int cut_timeend; +int counter; +float sum; +float tempf; +float timestart, timeend; + +/* misc */ +/*-----------------------------------------------------------------------*/ + +char progname[MAX_STRING_LENGTH]; +char outputfigurefn[MAX_STRING_LENGTH]; +char strobefn[MAX_STRING_LENGTH]; + + +int verboseflag = OFF; /* -v */ +int frameflag = OFF; /* -f */ +int channelflag = OFF; /* -c */ +int greyscaleflag = OFF; /* Not used: required for compilation */ +int oppositearchflag = OFF; /* -oparch : see saigraph.c for info */ +int sumflag = OFF; +int averageflag = OFF; +int timeflag = OFF; +int headerflag = ON; +int strobeflag = OFF; +int strobevalue = 1; /* the value used to mark a strobe event in + the .trigger file */ +int cutthisframe = OFF; +int infoflag = OFF; +int forceframeflag = OFF; +int forceframe = 0; +int successforceflag = OFF; + +/* ................... Main ................................*/ +/* .........................................................................*/ +/* .........................................................................*/ + + + +void main (int argc, char *argv[]) +{ + int n, sample; + int frame, channel; + int trigger_peak = 0; + int header_bytes = 0; + int cut_framestart, cut_frameend, cut_no_frames; + int cut_minchannel, cut_maxchannel, cut_frameheight; + char inputfn[MAX_STRING_LENGTH], outputbasefn[MAX_STRING_LENGTH]; + FILE *inputfp, *outputfigurefp; + FILE *strobefp; + int x, counter, previousx; + int nstrobes; + short sampledata[2]; + +/*-------------------------------------*/ + strcpy(progname, argv[0]); + strcpy(inputfn, ""); + strcpy(outputbasefn, ""); + strcpy(outputfigurefn, ""); + + parsecommandline(argc, argv, inputfn, outputbasefn); + + if (strcmp(outputbasefn, "") == 0) + strcpy(outputfigurefn, ""); + else { + strcpy(outputfigurefn, outputbasefn); +/* strcat(outputfigurefn, OUTPUT_EXT);*/ + } + +/*--------------------------------------*/ + /* open files, read and check header */ + inputfp = open_file(inputfn, stdin, READ); + outputfigurefp = open_file(outputfigurefn, stdout, WRITE); + header_bytes = readheader(inputfp); + checkheader(); + +/*-------------------------------------*/ + /* strobe code */ + if (strobeflag == ON){ + strobefp = open_file(strobefn, stderr, READ); + /* note + * add (nwidth * samplerate) to the index + * the frame number is the floor of that + 1 (because it seems to give the correct answer) + * some versions of gensai return a triggerpoint 3 samples across; take the first. + */ + for (x=0; x<MAX_STROBES; x++) + strobelocation[x] = 0; + x=0; counter=1; + previousx=0; + while( feof(strobefp) ==0) { + fread(sampledata, 2, 1, strobefp); + if (sampledata[0] >= strobevalue){ + if (((x-previousx) <= 2) && (previousx != 0)) + /* don't need this trigger */ + continue; + strobelocation[counter] = x; + tempf = (float) strobelocation[counter] + (-1.0 * nwidth * samplerate / 1000.0); + tempf = tempf * 1.0 / frameshift_samples; + /* tempf = floor(tempf);*/ + strobelocation[counter] = (int) tempf + 1.0; +/* if (verboseflag == ON) + fprintf(stderr, "strobe %i: %i samples %f (%i frames)\n", counter, x, tempf, (int)strobelocation[counter]);*/ + previousx=x; + counter++;} + x++; + if (counter >= MAX_STROBES){ + fprintf(stderr, " %s : too many strobes in .trigger file.\n", progname); + exit(-1);} + } + nstrobes=counter-1; + if (infoflag == ON){ + fprintf(stderr, "using %i frames ", nstrobes); + for (counter=1; counter <=nstrobes; counter ++) + fprintf(stderr, " %i", strobelocation[counter]); + fprintf(stderr, "\n");} + fclose(strobefp); + } + +/*--------------------------------------*/ + + /* reset the frame/channel counters */ + if (frameflag == ON) { + cut_frameend = frameend; + cut_framestart = framestart; } + else { + cut_frameend = no_frames; + cut_framestart = 1; } + + if (channelflag == ON) { + cut_maxchannel = maxchannel; + cut_minchannel = minchannel; } + else { + cut_maxchannel = frameheight; + cut_minchannel = 1; } + + if (timeflag == ON) { + cut_timestart = samplerate * timestart/1000; + cut_timeend = samplerate * timeend/1000;} + else{ + cut_timestart = 0; + cut_timeend = framewidth_samples;} + +/* fprintf(stderr, "%d \n", cut_timestart);*/ +/* fprintf(stderr, "%d \n", cut_timeend);*/ + + cut_no_frames = cut_frameend - cut_framestart + 1; /* inclusive, so +1 */ + cut_frameheight = cut_maxchannel - cut_minchannel + 1; /* inclusive, so +1 */ + if (strobeflag == ON) + cut_no_frames = nstrobes; + +/*--------------------------------------*/ +/* WARNING: 'time' options are NOT built into the headers yet */ + + changeheader(cut_no_frames, pwidth, nwidth, framewidth_samples); + changeheader_B(mincf, maxcf, cut_frameheight); + if (headerflag == ON) + writeheader(outputfigurefp); + +/*--------------------------------------*/ + + if (verboseflag==ON) { + fprintf(stderr, " frames "); + fflush(stderr);} + +/*------------------------------------------------------------------------*/ + + for (frame=1; frame<=no_frames; frame++) { + + if (strobeflag == OFF) { + if ((frame < cut_framestart) || (frame > cut_frameend )) + cutthisframe = OFF; + else + cutthisframe = ON;} + else { + cutthisframe = OFF; + for (counter=1; counter <= nstrobes; counter ++){ + if (frame == strobelocation[counter]) + cutthisframe = ON;}} + + if (forceframeflag == ON){ + if (frame < forceframe){ + cutthisframe = OFF;} + else { + if (successforceflag == OFF){ + if (cutthisframe == ON){ + successforceflag = ON; + fprintf(stdout, "%d\n", frame);}} + else + cutthisframe = OFF;}} + + if (verboseflag == ON) { + if (cutthisframe == ON){ + fprintf(stderr, " %i ", frame); fflush(stderr);} + else { + fprintf(stderr, " (%i) ", frame); fflush(stderr);}} + + /*--------------------------------------*/ + + for (channel=1; channel <=frameheight; channel ++) { + + for(sample=0; sample<framewidth_samples; sample++) + inputdata[sample] = 0; + + fread (inputdata, 2, framewidth_samples, inputfp); + + /* input check */ + for(sample=0; sample<framewidth_samples; sample++) + if (inputdata[sample] < 0 ) { + fprintf(stderr, "%s: something's gone wrong: the data is negative.\n", progname); + exit(-1); } + + for(sample=0; sample<framewidth_samples; sample++) + inputbychannel[channel][sample] = inputdata[sample]; + + } /* (loading of) channel */ + + /*--------------------------------------*/ + + /* Is this frame to be output? If not, next frame. */ + if (strobeflag == OFF){ + if ((frame < cut_framestart) || (frame > cut_frameend )) + continue;} + else { + if (cutthisframe == OFF) + continue;} + + /* output all required channels */ + for (channel = cut_minchannel; channel <= cut_maxchannel; channel++) { + sum = 0.0; + counter=0; + for(sample=cut_timestart; sample<cut_timeend; sample++) { + outputfiguredata[counter] = inputbychannel[channel][sample]; + if ((sumflag == ON) || (averageflag == ON)) + sum += inputbychannel[channel][sample]; + counter++;} + + if (sumflag == ON){ + outputfiguredata[0] = (short) sum; + counter=1;} + if (averageflag == ON){ + tempf = (float) sum/counter; + outputfiguredata[0] = (short) tempf; + counter=1;} +/* fprintf(stderr, "%f %d \n", sum, outputfiguredata[0]);*/ + + writedata_output(outputfigurefp, counter); } + + /*--------------------------------------*/ + + } /* frame */ + +/*----------------------------------------------------------------------*/ + + /* Tidy up and exit */ + if (verboseflag == ON) + fprintf(stderr, "\n"); + fclose(inputfp); fclose(outputfigurefp); + + if ( ferror(inputfp) != 0) { + fprintf(stderr, " %s : error closing input file.\n", progname); + exit(-1);} + + if ( ferror(outputfigurefp) != 0) { + fprintf(stderr, " %s : error closing figure file.\n", progname); + exit(-1);} + + exit(0); + +} /* Main */ + + + + +/*......................................................................*/ +/*......................................................................*/ + + + + + +void parsecommandline(int argc, char *argv[], char inputfn[], char outputbasefn[]) +{ + int x=1, helpflag = OFF; + + while (x < argc){ + if (!strcmp(argv[x], "-o")) {strcpy(outputbasefn, argv[x+1]); x+=2;} + else if (!strcmp(argv[x], "-output")) {strcpy(outputbasefn, argv[x+1]); x+=2;} + else if (!strcmp(argv[x], "-i")) {strcpy(inputfn, argv[x+1]); x+=2;} + else if (!strcmp(argv[x], "-t")) {strobeflag=ON; frameflag=OFF;strcpy(strobefn, argv[x+1]); x+=2;} + else if (!strcmp(argv[x], "-input")) {strcpy(inputfn, argv[x+1]); x+=2;} + else if (!strcmp(argv[x], "-help")) {helpflag = ON; x+=1;} + else if (!strcmp(argv[x], "-h")) {helpflag = ON; x+=1;} + else if (!strcmp(argv[x], "-triggerinfo")) {infoflag = ON; x+=1;} + else if (!strcmp(argv[x], "-sum")) {sumflag = ON; averageflag=OFF; x+=1;} + else if (!strcmp(argv[x], "-average")) {sumflag = OFF; averageflag=ON; x+=1;} + else if (!strcmp(argv[x], "-header")) {headerflag = ON; x+=1;} + else if (!strcmp(argv[x], "-noheader")) {headerflag = OFF; x+=1;} + else if (!strcmp(argv[x], "-verbose")) {verboseflag = ON; x+=1;} + else if (!strcmp(argv[x], "-v")) {verboseflag = ON; x+=1;} + else if (!strcmp(argv[x], "-n")) {forceframeflag=ON; forceframe=atoi(argv[x+1]); x+=2;} + else if (!strcmp(argv[x], "-f")) {frameflag=ON; framestart=atoi(argv[x+1]); frameend=atoi(argv[x+2]); x+=3;} + else if (!strcmp(argv[x], "-frames")) {frameflag=ON; framestart=atoi(argv[x+1]); frameend=atoi(argv[x+2]); x+=3;} + else if (!strcmp(argv[x], "-c")) {channelflag=ON; minchannel=atoi(argv[x+1]); maxchannel=atoi(argv[x+2]); x+=3;} + else if (!strcmp(argv[x], "-channel")) {channelflag=ON; minchannel=atoi(argv[x+1]); maxchannel=atoi(argv[x+2]); x+=3;} + else if (!strcmp(argv[x], "-time")) {timeflag=ON; timestart=atof(argv[x+1]); timeend=atof(argv[x+2]); x+=3;} + else if (!strcmp(argv[x], "-oparch")) {oppositearchflag = ON; x+=1;} + else {fprintf(stderr, "%s: unknown option %s\n", progname, argv[x]); + exit(-1);} + } + + if (helpflag == ON) + { + fprintf(stderr, "\n"); + fprintf(stderr, " %s\n", progname); + fprintf(stderr, " -----------------------------------------------------------\n"); + fprintf(stderr, " Cuts a .sai by frame or channel, and (if necessary) just some\n"); + fprintf(stderr, " of the input image\n"); + fprintf(stderr, " The -oparch option is REQUIRED if reading a Sun .sai files \n"); + fprintf(stderr, " on a DEC cpu or vice-versa.\n"); + fprintf(stderr, " Add .sai to both input and output filenames.\n"); + fprintf(stderr, " WARNING: the header is not rebuilt properly for the\n"); + fprintf(stderr, " '-time' options.\n"); + fprintf(stderr, " -----------------------------------------------------------\n"); + fprintf(stderr, " -i <.sai file> input file default = stdin\n"); + fprintf(stderr, " -o <.sai file> output file default = stdout\n"); + fprintf(stderr, " -t <.trigger file> trigger location file\n"); + fprintf(stderr, " -oparch assume input was generated on an opposing architecture cpu\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " -n <frame> take first frame after <frame>\n"); + fprintf(stderr, " -frames <start> <end> (inclusive) (default=all)\n"); + fprintf(stderr, " -time <start> <end> (inclusive; ms from leftedge)\n"); + fprintf(stderr, " -channel <low> <high> (inclusive) (default=all)\n"); + fprintf(stderr, " -sum sum and output 1 value per frame\n"); + fprintf(stderr, " -average sum, average & output 1 value per frame\n"); + fprintf(stderr, " -noheader don't output a .sai header\n"); + fprintf(stderr, " -header do output a .sai header (default)\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " -v verbose output (to stderr)\n"); + fprintf(stderr, " -triggerinfo report the 'trigger' frames (to stderr)"); + fprintf(stderr, "\n\n"); + exit(-1);} + +} + + + + + + +