 /*
  * Khoros: $Id: dpeakpick.c,v 1.2 1992/03/20 23:15:59 dkhoros Exp $
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id: dpeakpick.c,v 1.2 1992/03/20 23:15:59 dkhoros Exp $";
#endif

 /*
  * $Log: dpeakpick.c,v $
 * Revision 1.2  1992/03/20  23:15:59  dkhoros
 * VirtualPatch5
 *
  */

/*
 *----------------------------------------------------------------------
 *
 * Copyright 1991, University of New Mexico.  All rights reserved.
 * Permission to copy and modify this software and its documen-
 * tation only for internal use in your organization is hereby
 * granted, provided that this notice is retained thereon and
 * on all copies.  UNM makes no representations as to the sui-
 * tability and operability of this software for any purpose.
 * It is provided "as is" without express or implied warranty.
 * 
 * UNM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
 * NESS.  IN NO EVENT SHALL UNM BE LIABLE FOR ANY SPECIAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY OTHER DAMAGES WHAT-
 * SOEVER 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 PER-
 * FORMANCE OF THIS SOFTWARE.
 * 
 * No other rights, including, for example, the right to redis-
 * tribute this software and its documentation or the right to
 * prepare derivative works, are granted unless specifically
 * provided in a separate license agreement.
 *---------------------------------------------------------------------
 */

#include "unmcopyright.h"        /* Copyright 1991 by UNM */

/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 >>>>
 >>>>         File Name: dpeakpick.c
 >>>>
 >>>>      Program Name: dpeakpick
 >>>>
 >>>>      Program Desc: 
 >>>>	
 >>>>	Find peaks or troughs in 1D data set
 >>>>	
 >>>>	

 >>>>            Author: Donna Koechner
 >>>>
 >>>> Date Last Updated: Sat Feb 15 16:28:22 1992
 >>>>
 >>>>          Routines: main- the main program for dpeakpick
 >>>> 		 gw_usage - gives usage of the program
 >>>> 		 gw_args  - gets arguments of program from command line
 >>>>
 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/


#include "dpeakpick.h"


/****************************************************************
 *
 * Routine Name:  main program for dpeakpick
 *
 *       Input:  
 *           -i  input file 
 *
 *
 *           [-f] output ASCII file
 *           [-o] VIFF format output file
 *           [-p] if true, find peaks 
 *           [-m] if FALSE find first n, and if TRUE find max/min n, peaks or troughs
 *           [-e] If TRUE, endpoints will be considered for peak designation
 *           [-w] Num steps on both sides of point on which to base peak decision  (value > 0)
 *           [-hwr] min that abs value of average slope over window can be  (value >= 0.0)
 *           [-d] data processing direction (0 = down vectors, 1 = across bands)
 *
 *           [-all  Find all peaks or troughs   -OR-
 *            -n  Number of peaks or troughs to find     (value > 0)) ]
 *
 *
 *
 ****************************************************************/


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

/* -main_variable_list */
struct xvimage  *image, *readimage();
struct p_info   **peak_info;
struct v_info   *vect_info;
FILE            *printdev;
int             sig_length,
                num_signals,
                w,i,j;
double          hwr;
char            *PTS_str,
                *pts_str,
                *ptp_str,
                *BV_str;

/* -main_variable_list_end */

	program = VStrcpy(argv[0]);
	ac = argc;
	av = argv;

	khoros_init();

	gw_get_args();

/* -main_before_lib_call */
  if(check_args()) {
    fprintf(stderr, "%s: Illegal arguments on command line.\n", program);
    exit(1);
  }

  READINPUT(image);
  CHECKTYPE(program, image);
  CHECKINPUT(program, image);

 /* set up defaults */
  if(!dpeakpick->p_flag)
    dpeakpick->p_logic = TRUE;

  if(!dpeakpick->e_flag)
    dpeakpick->e_logic = FALSE;

  if(!dpeakpick->m_flag)
    dpeakpick->m_logic = TRUE;

  if(!dpeakpick->d_flag)
    dpeakpick->d_logic = DSP_BAND;

  if(!dpeakpick->all_flag && !dpeakpick->n_flag)
    dpeakpick->all_logic = TRUE;
  else if(!dpeakpick->all_flag && dpeakpick->n_flag)
    dpeakpick->all_logic = FALSE;

 /* 
  *  Setup ascii output file if selected. 
  */
  if(dpeakpick->f_flag) {
    if(! vwrite_ascii(dpeakpick->f_file, &printdev)) {
      (void) fprintf(stderr, "%s:  Can't open ascii output file: \\n",program);
      exit(1);
    }
  }
  else if (!dpeakpick->f_flag && !dpeakpick->o_flag) {
    printdev = stdout;
    dpeakpick->f_flag = TRUE;
  }

 /*
  *  Calculate number of vectors or bands.
  */
  switch(dpeakpick->d_logic) {
    case DSP_VECTOR:
         num_signals = image->row_size * image->col_size;
         sig_length = image->num_data_bands;
         BV_str = "Vector";
         break;
    case DSP_BAND:
         num_signals = image->num_data_bands;
         sig_length = image->row_size * image->col_size;
         BV_str = "Band";
         break;
    default:
         (void)fprintf(stderr,"%s: unknown process direction (-d): %d\n",
                       program, dpeakpick->d_logic);
         exit(1);
  }

 /*
  * Check for window option and, if selected, set window to specified 
  * value.  Otherwise set window value to 1.  Then make sure that it is
  * valid.
  */
  w = 1;
  if(dpeakpick->w_flag) 
    w = dpeakpick->w_int;
  if( w > ((int)((sig_length-1)/2)) || w < 1 ) {
    (void)fprintf(stderr,"%s: window size must not be greater",program);
    (void)fprintf(stderr," than\n(number of points-1)/2,");
    (void)fprintf(stderr," or less than one.");
    (void)fprintf(stderr,"    window size = %d\n",w);
    (void)fprintf(stderr,"    number of points = %d\n",sig_length);
  }

 /*
  * Check for height to width ratio option and, if selected, set hwr to
  * specified value.  Otherwise set hwr to 0.
  */
  hwr = 0.0;
  if(dpeakpick->hwr_flag)
    hwr = (double)dpeakpick->hwr_float;


/* -main_before_lib_call_end */

/* -main_library_call */
if(!ldpeakpick(image, dpeakpick->p_logic, dpeakpick->all_logic, 
                dpeakpick->n_int, dpeakpick->m_logic, dpeakpick->e_logic,
                w, hwr, dpeakpick->d_logic, &peak_info, &vect_info) ) {
  (void)fprintf(stderr,"%s: ldpeakpick failed!\n",program);
  exit(1);
}

/* -main_library_call_end */

/* -main_after_lib_call */

/* write to ascii file (if selected) */
if(dpeakpick->f_flag) {
  if(dpeakpick->p_logic) {
    PTS_str = "Peaks";
    pts_str = "peaks";
    ptp_str = " peak  to  peak ";
  }
  else {
    PTS_str = "Troughs";
    pts_str = "troughs";
    ptp_str = "trough to trough";
  }

  (void) fprintf(printdev,"\n%s found in File: %s\n", 
                 PTS_str, dpeakpick->i_file);
  (void) fprintf(printdev,"\nWindow size\t\t= %d\n", w);
  (void) fprintf(printdev,"Height to Width ratio\t= %f\n", hwr);
  if(dpeakpick->n_flag) {
    (void) fprintf(printdev,"Number of %s specified to be found = %d\n", 
                             pts_str, dpeakpick->n_int);
  }

  switch(image->data_storage_type) {
    case VFF_TYP_FLOAT:
      for(i=0; i<num_signals; i++) {
        (void)fprintf(printdev,"\n*******  %s #%d  ****** \n\n",
                        BV_str, i);
        (void)fprintf(printdev,"Number %s found\t\t\t%d\n", 
                      pts_str, vect_info[i].p_count);
        (void)fprintf(printdev,"Mean of %s distance\t%g\n", 
                      ptp_str, vect_info[i].p2p_dist_mean);
        (void)fprintf(printdev,"Variance of %s distance\t%g\n\n", 
                      ptp_str, vect_info[i].p2p_dist_var);
        (void)fprintf(printdev,"POSITION\tVALUE\n");

        for(j=0; j<vect_info[i].p_count; j++) {
          (void)fprintf(printdev,"%d\t\t%g\n", peak_info[i][j].p_position, 
                        peak_info[i][j].p_value);
        }
      }
    break;

    case VFF_TYP_COMPLEX:
      for(i=0; i<num_signals*2; i++) {
        (void)fprintf(printdev,"\n*******  %s #%d  ****** \n",
                        BV_str, i/2);
        (void)fprintf(printdev,"\t\t\t\t\tREAL\t\tIMAGINARY\n");
        (void)fprintf(printdev,"Number %s found\t\t\t%d\t\t%d\n", 
                      pts_str, vect_info[i].p_count, vect_info[i+1].p_count);
        (void)fprintf(printdev,"Mean of %s distance\t%g\t\t%g\n", 
                      ptp_str, vect_info[i].p2p_dist_mean, 
                      vect_info[i+1].p2p_dist_mean);
        (void)fprintf(printdev,"Variance of %s distance\t%g\t\t%g\n\n", 
                      ptp_str, vect_info[i].p2p_dist_var,
                      vect_info[i+1].p2p_dist_var);

        (void)fprintf(printdev,"%s Found in Real Component of %s %d\n",
                                PTS_str, BV_str, i/2);
        (void)fprintf(printdev,"POSITION\tVALUE\n");

        for(j=0; j<vect_info[i].p_count; j++) {
          (void)fprintf(printdev,"%d\t\t%g\n", peak_info[i][j].p_position, 
                        peak_info[i][j].p_value);
        }

        (void)fprintf(printdev,"\n%s Found in Imaginary Component of %s #%d\n", 
                                PTS_str, BV_str, i/2);
        (void)fprintf(printdev,"POSITION\tVALUE\n");
        i++;
        for(j=0; j<vect_info[i].p_count; j++) {
          (void)fprintf(printdev,"%d\t\t%g\n", peak_info[i][j].p_position, 
                        peak_info[i][j].p_value);
        }
      }
    break;

    default:
      (void)fprintf(stderr,"%s: unknown data storage type\n", program);
      exit(1);
  }
}

/* write out viff file (if selected) */
if(dpeakpick->o_flag) 
  (void) writeimage(dpeakpick->o_file,image);

/* -main_after_lib_call_end */


	khoros_close();
}


/****************************************************************
*
* Routine Name:  gw_usage 
*
*
* Purpose:  prints out the usage for dpeakpick 
*
* Input:  none 
*
* Output:  none 
*
* Written By:  automatically generated by ghostwriter
*
****************************************************************/


gw_usage()
{
	fprintf(stderr, "dpeakpick :\n");
	fprintf(stderr, "\t\n");
	fprintf(stderr, "\tFind peaks or troughs in 1D data set\n");
	fprintf(stderr, "\t\n");
	fprintf(stderr, "\t\n");

/* -usage_additions */
/* -usage_additions_end */

	fprintf(stderr,"\t-i  input file  (infile)\n");
	fprintf(stderr, "\n");
	fprintf(stderr, "\n");
	fprintf(stderr,"\t[-f]  output ASCII file (outfile) [null]\n");
	fprintf(stderr,"\t[-o]  VIFF format output file (outfile) [null]\n");
	fprintf(stderr,"\t[-p]  if true, find peaks  (boolean) [true]\n");
	fprintf(stderr,"\t[-m]  if FALSE find first n, and if TRUE find max/min n, peaks or troughs (boolean) [true]\n");
	fprintf(stderr,"\t[-e]  If TRUE, endpoints will be considered for peak designation (boolean) [false]\n");
	fprintf(stderr,"\t[-w]  Num steps on both sides of point on which to base peak decision (integer, > 0) [1]\n");
	fprintf(stderr,"\t[-hwr]  min that abs value of average slope over window can be (float, >= 0.0) [0]\n");
	fprintf(stderr,"\t[-d]  data processing direction (0 = down vectors, 1 = across bands) (boolean) [true]\n");
	fprintf(stderr, " \n");
	fprintf(stderr, "\t[ ");
	fprintf(stderr,"-all  Find all peaks or troughs  (boolean) -OR- \n");
	fprintf(stderr,"\t  -n  Number of peaks or troughs to find   (integer, > 0) ]\n\n");
	fprintf(stderr, "\n");
	fprintf(stderr, "\t[-V] Gives the version for dpeakpick\n");
	fprintf(stderr, "\t[-U] Gives the usage for dpeakpick\n");
	fprintf(stderr, "\t[-P] Prompts for command line options\n");
	fprintf(stderr, "\t[-A [file1]] Creates the answer file called dpeakpick.ans or file1 \n");
	fprintf(stderr, "\t[-a [file1]] Uses dpeakpick.ans or file1 as the answer file \n\n\n");

}


/****************************************************************
*
* Routine Name:  gw_getargs 
*
*
* Purpose:  gets arguments off command line for dpeakpick
*
* Input:  none 
*
* Output:  none 
*
* Written By:  automatically generated by ghostwriter
*
****************************************************************/


gw_get_args()
{

char	*i_pstr = 
	"\nEnter: (i) input file \n        {infile}: "; 
char	*f_pstr = 
	"\nEnter: (f) output ASCII file \n        {outfile}: "; 
char	*o_pstr = 
	"\nEnter: (o) VIFF format output file \n        {outfile}: "; 
char	*p_pstr = 
	"\nEnter: (p) if true, find peaks  \n        {boolean, (y/n)  [yes] }: "; 
char	*m_pstr = 
	"\nEnter: (m) if FALSE find first n, and if TRUE find max/min n, peaks or troughs \n        {boolean, (y/n)  [yes] }: "; 
char	*e_pstr = 
	"\nEnter: (e) If TRUE, endpoints will be considered for peak designation \n        {boolean, (y/n)  [no] }: "; 
char	*w_pstr = 
	"\nEnter: (w) Num steps on both sides of point on which to base peak decision \n        {integer, > 0 [1] }: "; 
char	*hwr_pstr = 
	"\nEnter: (hwr) min that abs value of average slope over window can be \n        {float, >= 0.0 [0.000000] }: "; 
char	*d_pstr = 
	"\nEnter: (d) data processing direction (0 = down vectors, 1 = across bands) \n        {boolean, (y/n)  [yes] }: "; 
char	*all_pstr = 
	"\nEnter: (all) Find all peaks or troughs \n        {boolean, (y/n)  [yes] }: "; 
char	*n_pstr = 
	"\nEnter: (n) Number of peaks or troughs to find  \n        {integer, > 0 [1] }: "; 
char  answer_file[512], temp[512];



int	fid = -1,
	error, query, ok, count;
	int prompt_flag = FALSE;

	/*
	 * print version if necessary
	 */
	vgparml(fid, "-V", "noprompt", &query, 0, 0, &error);
	if (error == 0)
	{
	    printf ("\n%s: %s: Version %d.%d\n\n",
	    "dpeakpick", RELEASE_NAME, RELEASE_MAJOR, RELEASE_MINOR);
	    exit(1);
	}

	/*
	 * print usage if necessary
	 */
	vgparml(fid, "-U", "noprompt", &query, 0, 0, &error);
	if (error == 0)
	{
	    gw_usage();
	    exit(1);
	}

	/*
	 * see if interactive prompting is desired
	 */
	vgparml(fid, "-P", "noprompt", &query, 0, 0, &error);
	if (error == 0)
	    prompt_flag = TRUE;

	/*
	 * see if answer file is to be used
	 */
	vgparms(fid, "-a", "noprompt", answer_file, 0, 0, &error);
	if (error == 0)
	{
	     if (VStrlen(answer_file) == 0)
		sprintf(answer_file, "dpeakpick.ans");
	     while (fid < 0)
	     {
		if ((fid = open(answer_file, O_RDONLY, 0666))== -1)
		{
		    fprintf(stderr, "dpeakpick: can't open answer file \"%s\"",
			    answer_file); 
		    fprintf(stderr, "please re-enter: ");
		    (void) gets(answer_file);
		    if (VStrlen(answer_file) == 0)
			sprintf(answer_file, "dpeakpick.ans");
		}

	     }

	}

	/*
	 * allocate the dpeakpick structure
	 */
	dpeakpick = (dpeakpick_struct *) 
	       calloc((unsigned)1, (unsigned) sizeof (dpeakpick_struct));

	/*
	 * get required arguments for dpeakpick
	 */
	if (prompt_flag == TRUE)
	    fprintf(stderr,"\nRequired Arguments:\n\n");

	if (!(dpeakpick->i_flag = vget_infile(fid, prompt_flag,
			"-i", i_pstr, &(dpeakpick->i_file))
))
	{
	    if (prompt_flag == TRUE)
	    {
		while(!(dpeakpick->i_flag))
		{
		    fprintf(stderr, "\t\ti is required, please re-enter: \n");
		    dpeakpick->i_flag = vget_infile(fid, prompt_flag,
		    "-i", i_pstr, &(dpeakpick->i_file))
;

		}
	    }
	    else
	    {
		fprintf(stderr, "Error: '-i' is a required argument\n");
		gw_usage();
		exit(1);
	    }
	}

	/*
	 * get optional arguments for dpeakpick
	 */
	if (prompt_flag == TRUE)
	   fprintf(stderr,"\nOptional Arguments:\n\n");

	dpeakpick->f_flag = vget_outfile(fid, prompt_flag,
	"-f", f_pstr, &(dpeakpick->f_file))
;

	dpeakpick->o_flag = vget_outfile(fid, prompt_flag,
	"-o", o_pstr, &(dpeakpick->o_file))
;

	dpeakpick->p_flag = vget_logic(fid, prompt_flag,
	"-p", p_pstr, &(dpeakpick->p_logic), 1);

	dpeakpick->m_flag = vget_logic(fid, prompt_flag,
	"-m", m_pstr, &(dpeakpick->m_logic), 1);

	dpeakpick->e_flag = vget_logic(fid, prompt_flag,
	"-e", e_pstr, &(dpeakpick->e_logic), 0);

	dpeakpick->w_flag = vget_int(fid, prompt_flag,
	"-w", w_pstr, &(dpeakpick->w_int),
	1, 2, 2);

	dpeakpick->hwr_flag = vget_float(fid, prompt_flag,
	"-hwr", hwr_pstr, &(dpeakpick->hwr_float),
	0.000000, 1.000000, 1.000000);

	dpeakpick->d_flag = vget_logic(fid, prompt_flag,
	"-d", d_pstr, &(dpeakpick->d_logic), 1);

	/*
	 * get optional mutually exclusive groups for dpeakpick
	 */
	if (prompt_flag == TRUE)
	{
		   fprintf(stderr, "\nThe following prompts are mutually exclusive.\n");
		   fprintf(stderr, "\nHit <cr> until the desired prompt appears.\n");
		dpeakpick->all_flag = vget_logic(fid, prompt_flag,
		    "-all", all_pstr, &(dpeakpick->all_logic), 1);

    		if(!( (dpeakpick->all_flag)))
		    dpeakpick->n_flag = vget_int(fid, prompt_flag,
		    "-n", n_pstr, &(dpeakpick->n_int),
		    1, 2, 2);

		   fprintf(stderr, "\n ------\n");
	}
	else
	{
		count = 0;
		if(dpeakpick->all_flag = vget_logic(fid, prompt_flag,
		    "-all", all_pstr, &(dpeakpick->all_logic), 1))
		    count++;

		if(dpeakpick->n_flag = vget_int(fid, prompt_flag,
		    "-n", n_pstr, &(dpeakpick->n_int),
		    1, 2, 2))
		    count++;

		if (count > 1)
		{
		    fprintf(stderr, "Error: You may specify ONLY ONE of :\n");
		    fprintf(stderr, " -all  -n \n");
		    gw_usage();
		    exit(1);
		}

	}


}



