view saitools/napgraph.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 source
/*
    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.
*/
/* napgraph.c 
*
* M. Akeroyd  11th June 1993. Revised Winter 1994.
*/





#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_nap(FILE *inputfp);
void checkheader();
void writeheader(FILE *outputfp);
int fakeheader_sai();
void changeheader(int no_frames, int new_pwidth, int new_nwidth, int framewidth_samples_output);

void find_intervals_nap(int channel, int maximum_interval, int sample);

void writedata_output (FILE *outputfp, int samples_to_write);
FILE *open_file (char filefn[], FILE *dir_default, int streamtype);

void write_matrix_hori_time(int framewidth, FILE *outputfigurefp);
void write_matrix_hori_freq(int framewidth, FILE *outputfigurefp);




/* Data arrays: global */
/*---------------------------------------------------------------------------*/


short freqdata[MAX_CHANNELS];                /* input .nap: a single column */
short previousfreqdata[MAX_CHANNELS];
short previouspreviousfreqdata[MAX_CHANNELS];
short outputdata[MAX_DATA]; 
short outputfiguredata[MAX_DATA]; 
short outputgrounddata[MAX_DATA]; 

short interval[MAX_CHANNELS][MAX_DATA];      /* histogram */ 
short summation[MAX_CHANNELS];

short clip[MAX_CHANNELS];                    /* set to ON of clipping occured*/


/* other variables */
/*---------------------------------------------------------------------------*/
struct Peak peak[MAX_PEAKS];
struct Peak peak_nap_right[MAX_CHANNELS];
struct Peak peak_nap_left[MAX_CHANNELS];


/* variables read from header */
/*---------------------------------------------------------------------------*/

char header[MAX_LINES_HEADER][MAX_LINE_LENGTH];
int header_lines;

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 */

int no_columns;
int nap_height;
int greyscaleflag = OFF;


/* misc */
/*---------------------------------------------------------------------------*/

char progname[MAX_STRING_LENGTH];
char outputfigurefn[MAX_STRING_LENGTH];


int verboseflag = OFF;               /* -v */
int removeflag = OFF;                /* -r */
double removevalue = 0.1;
int widthflag = OFF;                 /* -w */     /* if OFF, use DEFAULT */
int total_width;                     /* -w */     /* total width of new .sai */
int asciiflag = OFF;
int asciireverseflag = OFF;
int summationflag = OFF;
int oppositearchflag = OFF;          /* -oparch : see saigraph.c for info */



/* ...................           Main           .............................*/
/* ..........................................................................*/
/* ..........................................................................*/



void main (int argc, char *argv[])
{
  int sample;
  int n;

  int column, channel;
  int framewidth_samples_input,
      framewidth_samples_output;
  int new_pwidth, 
         new_nwidth;
  int header_bytes = 0;
 
  char inputfn[MAX_STRING_LENGTH], 
       outputbasefn[MAX_STRING_LENGTH];

  FILE *inputfp, *outputfigurefp;


  strcpy(progname, argv[0]);
  strcpy(inputfn, "");
  strcpy(outputbasefn, "");
  strcpy(outputfigurefn, "");

  /* parse command line */
  parsecommandline(argc, argv, inputfn, outputbasefn);

  if (strcmp(outputbasefn, "") == 0) 
    strcpy(outputfigurefn, "");
  else {
    strcpy(outputfigurefn, outputbasefn);
/*    strcat(outputfigurefn, OUTPUT_EXT);*/
  }


  /* open files */
  /* default directions are:
   * input = stdin 
   * figure = stdout
   */

  inputfp = open_file(inputfn, stdin, READ);
  outputfigurefp = open_file(outputfigurefn, stdout, WRITE);

  /* read Header */
  header_bytes = readheader_nap(inputfp);

  /* do some error-checking on the header, and set the fread pointer 
   * to the right place */
  checkheader();

  /* fake the .sai header, but first copy the important variables:
   *   no of columns (no_frames)
   *   height (frameheight)
   */
  no_columns = no_frames;
  nap_height = frameheight;
  header_lines = fakeheader_sai();

  /* reset the variables */
  framewidth_samples_input = framewidth_samples;
  if (widthflag == OFF) {
    new_pwidth = + PWIDTH;
    new_nwidth = - NWIDTH;}
  else {
    new_pwidth = + NEW_PWIDTH;
    new_nwidth = - (new_pwidth + total_width);}

  framewidth_samples_output = (int) ((int) (abs(new_pwidth) + abs(new_nwidth)) * samplerate ) / 1000;
  
  if (framewidth_samples_output >= MAX_DATA) {
    fprintf(stderr, "%s: new frame is  too wide at %i: only alllowed %i samples\n", progname, framewidth_samples_output, MAX_DATA);
    exit(-1); }

  
  /* change header */
  changeheader(1, new_pwidth, new_nwidth, framewidth_samples_output);

  /* write header */
  if (asciiflag == OFF) 
    writeheader(outputfigurefp);
  else {
    /* begining of ascii header. The rest depends on the matrix format ... */
    fprintf(outputfigurefp, "# napgraph output.  %s\n", inputfn);
    fprintf(outputfigurefp, "# \n");
    fprintf(outputfigurefp, "# samplerate=%i  pwidth=%d  nwidth=%d  columns=%i ", samplerate, new_pwidth, new_nwidth, no_columns);
    fprintf(outputfigurefp, " mincf=%i  maxcf=%i  channels=%i \n", mincf, maxcf, nap_height);
    fprintf(outputfigurefp, "# \n");
  }

/* --------------------------------------------------------------------------*/


  if  (verboseflag==ON) { 
    fprintf(stderr, " channels "); 
    fflush(stderr);}

  
  /* clear arrays */
  
  for (channel=0; channel<MAX_CHANNELS; channel++) {
    previousfreqdata[channel] = previouspreviousfreqdata[channel] = 0;
    peak_nap_left[channel].sample = 0;
    peak_nap_right[channel].sample = 0;
    for(sample=0; sample<MAX_DATA; sample++)
      interval[channel][sample] = 0;
    clip[channel] = OFF;
  }


  /* Main loop */


/* .....  */

  for (column=1; column<=no_columns; column++) {

    if ((column % 100) == 1 ) { 
      if (verboseflag==ON) {
	fprintf(stderr, " %i ", column); 
	fflush(stderr);}
    }

    /* load a column's worth of data  */
    fread (freqdata, 2, (size_t) nap_height, inputfp);
    
    /* move everything UP one byte.
     * Don't know why ... */
    for (channel=nap_height; channel >=1; channel--)
      freqdata[channel] = freqdata[channel-1];

    /* This next is a simple input check: if any numbers < 0 , then say so */
    for(channel=0; channel<nap_height; channel++)
      if (freqdata[channel] < 0 )  {
	fprintf(stderr, "%s: something's gone wrong: the data is negative.\n", progname);
	exit(-1); }


    /* the important bits ... */
    for (channel=1; channel <=nap_height; channel++)
      find_intervals_nap(channel, framewidth_samples_output, column);
    

  } /* column */


/* --------------------------------------------------------------------------*/
/* --------------------------------------------------------------------------*/


  fflush(stdout);

  /* If required, sum the values */
  if (summationflag==ON) {
    /* clear ... */
    for (channel = 1; channel <= frameheight; channel ++)
	summation[channel] = 0;
    /* set ... */
    for (channel = 1; channel <= frameheight; channel ++)
      for (sample = 0; sample < framewidth_samples_output; sample++)
	summation[channel] += interval[channel][sample];
  }


  /* write output */

  if (asciiflag == OFF) {
    for (channel = 1; channel <= frameheight; channel ++){
      for (sample = 0; sample < framewidth_samples_output; sample++)
	outputfiguredata[sample] = interval[channel][sample];
      writedata_output(outputfigurefp, framewidth_samples_output);
    }
  }  
  else {
    frameheight = nap_height;
    if (asciireverseflag == OFF) 
      write_matrix_hori_freq(framewidth_samples_output, outputfigurefp);
    else
      write_matrix_hori_time(framewidth_samples_output, outputfigurefp);
}    


/* --------------------------------------------------------------------------*/
/* --------------------------------------------------------------------------*/


  /* Tidy up and exit */
  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;
  int group;

  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], "-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], "-verbose")) {verboseflag = ON; x+=1;}
    else if (!strcmp(argv[x], "-v")) {verboseflag = ON; x+=1;}
    else if (!strcmp(argv[x], "-w")) {widthflag = ON; total_width=atof(argv[x+1]); x+=2;}
    else if (!strcmp(argv[x], "-width")) {widthflag = ON; total_width=atof(argv[x+1]); x+=2;}
    else if (!strcmp(argv[x], "-v")) {verboseflag = ON; x+=1;}
    else if (!strcmp(argv[x], "-r")) { removeflag = ON; removevalue = atof(argv[x+1]); x+=2;}
    else if (!strcmp(argv[x], "-a")) { asciiflag = ON;x+=1;}
    else if (!strcmp(argv[x], "-ar")) { asciiflag = ON; asciireverseflag=ON; x+=1;}
    else if (!strcmp(argv[x], "-s")) { summationflag=ON; x+=1;}
    else if (!strcmp(argv[x], "-g")) { greyscaleflag=ON; x+=1;}
    else if (!strcmp(argv[x], "-grey")) { greyscaleflag=ON; x+=1;}
    else if (!strcmp(argv[x], "-gray")) { greyscaleflag=ON; x+=1;}
    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, " Works out a histogram of peak intervals, from a .nap\n");
      fprintf(stderr, " Default output is a .sai file: if -a or -ar specified,\n");
      fprintf(stderr, " then output is a ASCII matrix.\n");
      fprintf(stderr, "\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 .nap to input filename, .sai to output filename.\n");
      fprintf(stderr, " -----------------------------------------------------------\n");
      fprintf(stderr, " -i <.nap file>      input file             default = stdin\n");
      fprintf(stderr, " -o <.sai file>      output file            default = stdout\n");
      fprintf(stderr, " -oparch          assume input was generated on an opposing architecture cpu\n");
      fprintf(stderr, "\n");
      fprintf(stderr, " -a                  ASCII output: rows = channels\n");
      fprintf(stderr, " -ar                 ASCII output: rows = time intervals\n");
      fprintf(stderr, " -s                  include summations (ASCII only)\n");
      fprintf(stderr, "\n");
      fprintf(stderr, " -w <int>            width of graph.sai (msecs).\n");
      fprintf(stderr, " -r <fraction>       remove any peaks F(n) < F(n+1) & F(n-1) * fract \n");
      fprintf(stderr, "                                            default = %.3f\n", removevalue);
      fprintf(stderr, "\n");
      fprintf(stderr, " -v                  verbose output (to stderr)\n");
      fprintf(stderr, " -g                  Change .sai format to 'grayscale'.\n");
      fprintf(stderr, "\n\n");
      exit(-1);}

}