/* raw_main.c - main file for raw data processing */

#include "raw_proto.h"

/* main *****************************************************************
* INPUT:    argc    count of inputs on command line                     *
*           argv    array of input strings the name of file with        *
*                   the processing parameters should be specified.      *
*                   mumparms is the original file.  The 'u' specifies   *
*                   that a filename is provided at the end of the file  *
*                   defining the data file/tape from which to read data *
* PURPOSE:                                                              *
* This particular CUPRI program generates 3 moment files on either      *
* Ultrix or MacIntosh Workstations.  At present there is support only   *
* for 8bit data of single pulse (SP), double pulse (DP), Barker coded   *
* single pulse (BKSP), and Barker coded double pulse (BKDP)             *
* The raw data records must have data for 2^n ipps.                     * 
* ORIGIN:                                                               *
* based on code supplied by Wes Swartz, Dave Hysell, John Sahr,         *
* Tim Hall, John Cho, Phil Erikson                                      *
* CHANGES:                                                              *
* 94/04/07  Added Mac Compatibility to routines                         *
*           Changed float pointer for data arrays to ComplexFloat.      *
*           Added InputParm, DateTime and RawHeader structs.            *
* 94/04/11  Finished adding Barker Code routines.                       *
* 94/04/14  Finished adding double pulse routines.                      *
* 94/04/15  Added EOF check ch.h.totnwrds returns -1, files closed nice *
* 94/04/21  Added 2^n fft width input and flexibility to average data   *
*           with 2^i ipps per record where i must be a positive integer *
*           less than 8.  This allows for up to 128 pnt FFT widths.     *
* 94/09/05  Added support for up to 256 pnt FFT widths.                 *
* 94/10/16  Added selection of fftwidth via define in raw_proto.h, also *
*           added support for 2d coherence, ip.pm = 3.                  *
* 94/11/28  added support for spectral width calculations, ip.pm = 4.   *
************************************************************************/
void main(int argc, char **argv)
{
  char spfile[30],dpfile[30];     /* output file moms[mode].[ymd].[hms]   */
  char *buf;                      /* raw data input buffer                */
  char *data, *pdata;             /* pointer to beginning of data in buf  */
  InputParms ip;                  /* input parameters structure           */
  RawHeader ch,fsph,lsph,fdph,ldph, *pfh, *plh;
  /* current,first,last raw record header */
  DateTime irig, harris;          /* irig and harris times                */
  DateTime startdt, stopdt;       /* start and stop processing times      */
  long int start, stop, curr;     /* start,stop,current seconds in yr     */
  long int last_nbaudp;           /* what was nbaudp for last record?     */
  long int spwrec,dpwrec;         /* number of records written to file    */
  ProcHeader ph;                  /* processed data header                */
  float *pmdata;                  /* pointer to mode processed data       */
  ComplexFloat *pvrx;             /* pointer to converted data for ip.rx  */
  ComplexFloat *spspec, *dpspec, *pspec;
  /* complex power spectrum.              */
  ComplexFloat *spcoh, *dpcoh, *pcoh;
  /* complex coherence spectrums.         */
  /* 1 - (rx1 - rx0) gives vertical coh.  */
  /* assumes rx1 is "behind" rx0          */
  /* 2 - (rx0 - rx2) gives horizontal coh */
  /* assumes rx2 is west/south of rx0     */
  float *last_angle;              /* Used in unwrapping coherence phases. */
  ComplexFloat *wi;               /* array of wings for FFT               */
  int *br;                        /* array of bitrevered indeces          */
  int *bk;                        /* barker phase code sequence           */
  int frp,fwsp,fwdp;              /* input/output tape/file               */
  int sprec,dprec;                /* current rec of nrecs to average      */
  int changed;                    /* set to 1 if RawHeader params change. */
  int incr_pdata;                 /* do we increment pdata?               */
  int already_read = 0;           /* have we already read a raw record?   */
  int add_segs = 0;               /* additional segments available        */
  int first_sp =1, first_dp =1;   /* first time at output data loop?      */
  int curr_seg;                   /* current segment in record.  Used to  */
  /* recompute start and stop time of     */
  /* segment within harris raw record.    */
  
  /* allocation of memory */
  buf = (char *) malloc(MAX_CUPRI_BYTES*sizeof(char));
  pvrx = (ComplexFloat *) malloc(MAX_PROC_DATA*sizeof(ComplexFloat));
  spspec = (ComplexFloat *) malloc(MAX_PROC_DATA*sizeof(ComplexFloat));
  dpspec = (ComplexFloat *) malloc(MAX_PROC_DATA*sizeof(ComplexFloat));
  spcoh = (ComplexFloat *) malloc(MAX_PROC_DATA*sizeof(ComplexFloat));
  dpcoh = (ComplexFloat *) malloc(MAX_PROC_DATA*sizeof(ComplexFloat));
  last_angle = (float *) malloc(MAX_PROC_DATA*sizeof(ComplexFloat));
  br = (int *) malloc(MAX_FFT_SIZE*sizeof(int));
  wi = (ComplexFloat *) malloc(MAX_FFT_SIZE*sizeof(ComplexFloat));
  bk = (int *) malloc(MAX_BARKER_SIZE*sizeof(int));
  
  /* initializing variables */
  pdata = data = &buf[CUPRI_VOS_HEADER_SIZE];
  last_nbaudp = 0;
  spwrec = dpwrec = 0;
  already_read = 0;
  curr_seg = 0;
  sprec = dprec = 0;
  pmdata = (float *) pvrx;
  
#ifdef THINK_C
  /* the following call is needed for the Mac to provide an I/O window to input
   * parameters that would normally be entered on the command line in
   * other systems.
   */
  
  argc = ccommand(&argv);
#endif /* THINK_C */
  
  ip = get_input_parms(argv[1]);
  
#ifdef THINK_C
  initialize_graph_window();
#endif /* THINK_C */
  
  /* compute bit reversal and wings for ip.fftwdth */
  bitrev(br, ip.fftwdth);
  wings(wi, ip.fftwdth);
  
#if 1
  printf("raw_main: main: %s, %s, %ld, %ld, %s\n",
	 ip.start_str,ip.end_str,ip.maxrecs,ip.nrecs,ip.file);
#endif
  
  if((frp = open(ip.file,O_RDONLY)) == -1)
    printf_exit("raw_main: main: can't open read file\n",(long int)ip.file);
  
  /* convert input times */
  startdt = get_input_time(ip.start_str);
  stopdt = get_input_time(ip.end_str);
  
  /* convert start and stop times to seconds to use in search
   * and processing loops.
   */
  
  start = seconds(&startdt);
  stop = seconds(&stopdt);
  
#if 1
  printf("start %ld stop %ld\n",start,stop);
#endif

  /* skip first 10 records of tape ignoring timestamps */
  for(curr = 0; curr < 10; curr += 1)
  {
    get_raw_record(frp,buf,data);
  }
  
  /* loop through raw records until arrive at start time */
  printf("raw_main: main: Finding start location.\n");
  curr = 0;
  while(curr<start)
  {
    static long int last_dift = 0;
    long int li_dift;
    
    /* get current time from raw record */
    ch = get_raw_record(frp,buf,data);
    if(ch.h.totnwrds == -1)
      printf_exit("raw_main: main: Record Read Error, EOF detected\n",0);

    harris = decode_harris_time(ch.hdr);
    curr = seconds(&harris);
    
    li_dift = start - curr;
    if(!(li_dift%100) && li_dift != last_dift)
    {
      printf("%ld seconds remaining.\n",li_dift);
      last_dift = li_dift;
    }
  }
  
#if 1
  printf("raw_main: main: already_read status = %d\n",already_read);
  printf_time(&harris,"raw_main: main: Current Harris Time");
  printf("raw_main: main: current: %ld seconds.\n",curr);
  printf_time(&startdt,"raw_main: main: Start Time:");
  printf("raw_main: main: start: %ld seconds.\n",start);
  printf_time(&stopdt,"raw_main: main: Stop Time:");
  printf("raw_main: main: stop: %ld seconds.\n",stop);
#endif
  
  /* create save file: */
  sprintf(spfile,"datadump.%04ld.%06ld",
	  decimal_date(&harris),decimal_time(&harris)/10);
	
#ifdef THINK_C
  if ((fwsp = creat(spfile,O_BINARY)) == EOF)
#else /* must be MIPS */
  if ((fwsp = creat(spfile,PERMS)) == -1)
#endif /* THINK_C */
    printf_exit("raw_main: main: Unable to open output file\n",0);

  printf("raw_main: main: Generating processed data file %s\n", spfile);

  /* Now dump records to disk until stop time is reached. */
  while(curr<stop)
  {
    /* get current time from raw record */
    ch = get_raw_record(frp,buf,data);
    if(ch.h.totnwrds == -1)
      printf_exit("raw_main: main: Record Read Error, EOF detected\n",0);

    harris = decode_harris_time(ch.hdr);
    curr = seconds(&harris);

    /* write out the buf data to file on disk */
    write(fwsp,buf,ch.h.totnwrds * VOS_WORD_SIZE);
  }
  /* make sure you include an EOF indicator for processed data */
  
#if 1
  printf("raw_main: main: Closing input/output data files.\n");
#endif
  
  close(frp);
  close(fwsp);
}
