 /*
  * Khoros: $Id: stats.c,v 1.2 1991/10/02 00:13:52 khoros Exp $
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id: stats.c,v 1.2 1991/10/02 00:13:52 khoros Exp $";
#endif

 /*
  * $Log: stats.c,v $
 * Revision 1.2  1991/10/02  00:13:52  khoros
 * HellPatch2
 *
  */ 


/*
 *----------------------------------------------------------------------
 *
 * Copyright 1990, 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 too 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 1990 by UNM */
#include "stats.h"
#include "xprism.h"


/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   >>>>                                                       <<<<
   >>>>	    file name: stats.c
   >>>>                      
   >>>>   description: utilities to comput stats on a plot
   >>>>                    
   >>>>      routines: 	
   >>>>			plot_information
   >>>>                
   >>>> modifications:
   >>>>                                                       <<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */


/**************************************************************
*
* MODULE NAME: 
*
*     PURPOSE: lvstats computes the mean, variance, standard 
*              deviation, RMS level, and peaks with locations for 
*              an input image.  If the tflg is set, then the best-fit 
*              plane parameters are also computed (takes 
*              significantly more FLOPs).
*
*       INPUT:  The input plot 
*
*      OUTPUT:  The stat structure is loaded with the values computed
*               from the plot.
*
* CALLED FROM: main
*
**************************************************************/


struct plotstats *get_plot_stats(plot, plot_type)

XPlot *plot;
int    plot_type;
{
	int    i, j, k, m;
	float  pint,nint;
	Coord  sum, rms, pos_pts, neg_pts;
	struct plotstats *stats;
	int nr, nc, begin, end, begin_x, end_x, begin_y, end_y;
	double	tmp_row_size;
	
	nint = 0.0;
	pint = 0.0;
	rms.x = rms.y = rms.z = 0.0;
	sum.x = sum.y = sum.z = 0.0;
	pos_pts.x = pos_pts.y = pos_pts.z = 0.0;
	neg_pts.x = neg_pts.y = neg_pts.z = 0.0;

	stats = (struct plotstats *) malloc (sizeof (struct plotstats));

	if (plot->xrange != NULL)
	   stats->xrange = VStrcpy(plot->xrange);
	if (plot->yrange != NULL)
	   stats->yrange = VStrcpy(plot->yrange);
	if (plot->function != NULL)
	   stats->function = VStrcpy(plot->function);
	if (plot->color != NULL) 
	   stats->color = VStrcpy(plot->color);

	
	k = 0;

	if (PLOT_TYPE_3D(plot_type))
	{
	   nc = plot->row_size;
           nr = plot->size/plot->row_size;
	   stats->max = plot->WCmax;
	   stats->min = plot->WCmin;
	   stats->input_type = plot->input_type;

	   if (plot->begin_point.x == 0.0)
	   {
		begin_x = 0;
		end_x = nc;
	   }
	   else
	   {
                begin_x = (int) plot->begin_point.x;

		if (begin_x == 1) begin_x = 0;

                if(plot->end_point.x == 0.0)
                   end_x = nc;
                else
                   end_x = (int) plot->end_point.x;
	   }

           if( plot->begin_point.y == 0.0)
	   {
		begin_y = 0;
		end_y = nr;
	   }
	   else
	   {
                begin_y = (int) plot->begin_point.y;
		if (begin_y == 1) begin_y = 0;

                if(plot->end_point.y == 0.0)
                   end_y = nr;
                else
                   end_y = (int) plot->end_point.y;
	   }

	   stats->pt_num = ((end_x - begin_x)/((int)plot->step_size.x)) *
                           ((end_y - begin_y )/((int) plot->step_size.y));

	   for (i = begin_y; i < end_y; i += (int)plot->step_size.y)
           {
              for(j = begin_x; j < end_x;j += (int)plot->step_size.x)
              {
		 m = i * nc + j;

	         if (plot->points[m].x >= 0.0) 
		    pos_pts.x++; 
	         else 
		    neg_pts.x++; 
   	
	         if (plot->points[m].y >= 0.0) 
		    pos_pts.y++; 
	         else 
		    neg_pts.y++; 
	
	         if (plot->points[m].z >= 0.0) 
	         {
		    pos_pts.z++; 
		    pint += plot->points[m].z; 
	         }
	         else 
	         {
		    neg_pts.z++; 
		    nint += plot->points[m].z; 
	         }
	         sum.x += plot->points[m].x;
	         sum.y += plot->points[m].y;
	         sum.z += plot->points[m].z;
	         rms.x += (plot->points[m].x)*(plot->points[m].x);
	         rms.y += (plot->points[m].y)*(plot->points[m].y);
	         rms.z += (plot->points[m].z)*(plot->points[m].z);

	         k++;
	      }
	   }
	   stats->area = sum.z;
	   tmp_row_size = (double) nc / (double) plot->step_size.x;
	   stats->row_size = (int) (ceil(tmp_row_size));
	}
	else
	{
	   stats->max = plot->WCmax;
	   stats->min = plot->WCmin;
	   stats->pt_num     = plot->size;
	   stats->input_type = plot->input_type;

	   if(plot->begin_point.x == 0.0)
           {
		begin = 1;
		end = plot->size;
	   }
	   else
	   {
                begin = plot->begin_point.x;

                if(plot->end_point.x == 0.0 )
                   end = plot->size;
                else
                   end = (int)plot->end_point.x;

	   }
           stats->pt_num = (end - (begin-1))/((int) plot->step_size.x);

	   for (i= (begin-1); i < end; i+= (int)plot->step_size.x)
	   {
	      if (plot->points[i].x >= 0.0) 
		 pos_pts.x++; 
	      else 
		 neg_pts.x++; 
	
	      if (plot->points[i].y >= 0.0) 
	      {
		 pos_pts.y++; 
		 pint += plot->points[i].y; 
	      }
	      else 
	      {
		 neg_pts.y++; 
		 nint += plot->points[i].y; 
	      }
	      sum.x += plot->points[i].x;
	      sum.y += plot->points[i].y;
	      rms.x += (plot->points[i].x)*(plot->points[i].x);
	      rms.y += (plot->points[i].y)*(plot->points[i].y);

	      k++;
	   }
	   stats->area = sum.y;
	}
	stats->pos_area = pint;
	stats->neg_area = nint;

	stats->pos_pts = pos_pts;
	stats->neg_pts = neg_pts;

	stats->mean.x = sum.x / k;
	stats->mean.y = sum.y / k;

	stats->var.x     = (rms.x/k) - (stats->mean.x * stats->mean.x);
	stats->var.y     = (rms.y/k) - (stats->mean.y * stats->mean.y);
	
	stats->std_dev.x = sqrt((double)stats->var.x);
	stats->std_dev.y = sqrt((double)stats->var.y);
	
	stats->rms.x     = sqrt(rms.x/k);
	stats->rms.y     = sqrt(rms.y/k);

	if (PLOT_TYPE_3D(plot_type))
	{
	   stats->mean.z    = sum.z / k;
	   stats->var.z     = (rms.z/k) - (stats->mean.z * stats->mean.z);
	   stats->std_dev.z = sqrt((double)stats->var.z);
	   stats->rms.z     = sqrt(rms.z/k);
	}
	return(stats);
}


/************************************************************
*
*   MODULE NAME: plot_information
*
*       PURPOSE: provides information about a plot
*
*
*     CALLED BY: run_options
*
*    WRITTEN BY: Danielle Argiro & Mike Lang & Mark Young
*
*    MODIFIED BY: Scott Wilson, Fri Aug 30 03:17:46 MDT 199
*                 Changed the %f's in the output statements to
*                 %g's to give much more sane output.
*
*************************************************************/

static char *input_types[] = {"Implicit Khoros File",
                              "Explicit Khoros File",
                              "Ascii Function",
                              "Ascii File with Data Points",
                              "Function Entered From Keyboard",
                              "Raw Data File"};

plot_information()
{
	int  i;
	XPlot *plot;
	struct plotstats *stats, *get_plot_stats();

	char *prompt = "Provide information on: ",
	     *label  = "Plot Information",
	     *button = "ok",
	     *blanks = "      ";

	char *name, *vbasename(), *info[50];

          
	if ( mono_display )
	   plot = get_a_plot(label,prompt, APPEND_MARKER_TYPE);
	else
	   plot = get_a_plot(label,prompt, APPEND_COLOR);

	if (plot == NULL) return;

	/*
	 * get stats about the plot
	 */
	stats = get_plot_stats(plot, plot->plot_type);

	/*
	 * malloc info strings
	 */
	for (i = 0; i < 50; i++)
	     info[i] = (char *) calloc(1, 125*sizeof(char));

	/*
	 *  set up info strings
	 */
	i = 0;
	sprintf(info[i], "%s", blanks);			i++;
	sprintf(info[i], "Plot Number: %d", plot->id);	i++;

	if ((plot->color != NULL) && (mono_display == false))
	{
	   sprintf(info[i], "Plot Color:  %s", plot->color);	i++; 
	}
	else if ((plot->marker != NULL) && (mono_display == true))
	{
	   sprintf(info[i], "Plot Marker Type:  %s", marker_type_string(plot));i++; 
	}

	sprintf(info[i], "Input Origination:  %s", 
		   input_types[plot->input_type-1]);   i++;

	  if ((plot->input_type == KEYB_FUN) || 
	      (plot->input_type == ASCII_FUN)) 
	  {
	       if (plot->function != NULL)
	       {
	       sprintf(info[i], "     Function: %s", plot->function);     i++;
	       }
	       if (plot->xrange != NULL)
	       {
	       sprintf(info[i], "      X Range: %s", plot->xrange);       i++;
	       }
	       if (PLOT_TYPE_3D(plot->plot_type))
	       {
		  if (plot->yrange != NULL)
		  {
	          sprintf(info[i], "      Y Range: %s", plot->yrange);    i++;
		  }
	       }
	  }
	  else 
	  {
	       if (plot->filename != NULL)
	       {
	           name = vbasename(plot->filename);
	           sprintf(info[i], "     Filename: %s", name);  i++;
	       }
	  }

	  sprintf(info[i], "%s", blanks);			i++;
	  sprintf(info[i], "Number of Data Points: %d", stats->pt_num); i++;
	  if (PLOT_TYPE_3D(plot->plot_type))
          {
	      sprintf(info[i], "Number of Cols: %d",stats->row_size);     i++;
	      sprintf(info[i], "Number of Rows: %d",
			 	(int)stats->pt_num/stats->row_size);     i++;
	  }

	  sprintf(info[i], "X Minium:  %g", plot->WCmin.x);	i++;
	  sprintf(info[i], "X Maximum: %g", plot->WCmax.x);	i++;
	  sprintf(info[i], "Y Minium:  %g", plot->WCmin.y);	i++;
	  sprintf(info[i], "Y Maximum: %g", plot->WCmax.y);	i++;
	  if (PLOT_TYPE_3D(plot->plot_type))
	  {
		sprintf(info[i], "Z Minium:  %g", plot->WCmin.z);     i++;
          	sprintf(info[i], "Z Maximum: %g", plot->WCmax.z);     i++;
	  }

	  sprintf(info[i], "%s", blanks);		  	i++;
	  sprintf(info[i], "X Mean: %g", stats->mean.x);	i++;
	  sprintf(info[i], "Y Mean: %g", stats->mean.y);	i++;
	  if (PLOT_TYPE_3D(plot->plot_type))
	     sprintf(info[i], "Z Mean: %g", stats->mean.z);	i++;

	  sprintf(info[i], "X Std Deviation: %g", stats->std_dev.x);	i++;
	  sprintf(info[i], "Y Std Deviation: %g", stats->std_dev.y);	i++;
	  if (PLOT_TYPE_3D(plot->plot_type))
	     sprintf(info[i], "Z Std Deviation: %g", stats->std_dev.z);	i++;

	  sprintf(info[i], "X RMS: %g", stats->rms.x);		i++;
	  sprintf(info[i], "Y RMS: %g", stats->rms.y);		i++;
	  if (PLOT_TYPE_3D(plot->plot_type))
	     sprintf(info[i], "Z RMS: %g", stats->rms.z);	i++;

	  sprintf(info[i], "%s", blanks);		        i++;
	  xvf_inform_wait(info, i, label, button);
}
