// file: $USFS/class/image_eval/v1.0/imgev_stats_0.cc
//

// system include files
//
#include <math.h>

// isip include files
//
#include "image_eval.h"

#include <integral_constants.h>
#include "image_eval_constants.h"

// method: stats_cc
//
// arguments:
//  float_4& min_a: (output) minimum difference
//  float_4& median_a: (output) median
//  float_4& max_a: (output) maximum difference
//  float_4& avg_a: (output) average of differences
//  float_4& rms_a: (output) root mean square
//  char_1* min_file_a: (output) file corresponding to mininum difference
//  char_1* median_file_a: (output) file corresponding to median difference
//  char_1* max_file_a: (output) file corresponding to maximum difference
//  int_4& proc_a: (output) counter to indicate number of files
//  processed successfully
//  int_4& total_a: (output) counter to indicate total number of files
//  processed
//  char_1** ref_fnames_a: (input) reference filename buffer
//  float_4* ref_values_a: (input) reference value buffer
//  int_4 ref_num_items_a: (input) number of reference data
//  char_1** tst_fnames_a: (input) test filename buffer
//  float_4* tst_values_a: (input) test value buffer
//  int_4 tst_num_items_a: (input) number of test data
//
// return:
//  logical_1 to indicate status
//
// This method calculates the mininum, maximum, average, median, and rms of
// a set of test data and its reference data
//
//
logical_1 Image_eval::stats_cc(float_4& min_a, float_4& median_a,
			       float_4& max_a, float_4& avg_a,
			       float_4& rms_a, char_1* min_file_a,
			       char_1* median_file_a, char_1* max_file_a,
			       int_4& proc_a, int_4& total_a,
			       char_1** ref_fnames_a, float_4* ref_values_a,
			       int_4 ref_num_items_a, char_1** tst_fnames_a,
			       float_4* tst_values_a, int_4 tst_num_items_a) {

  // sort the reference filename in ascending order
  //
  int_4 ref_index[ref_num_items_a];
  
  if(qsort_cc(ref_index, ref_fnames_a, ref_num_items_a) == ISIP_FALSE) {
    error_handler_cc((char_1*)"stats_cc", (char_1*)"error while sorting");
    return ISIP_FALSE;
  }
  
  // calculate the difference between reference and test value
  //
  float_4 diff[tst_num_items_a];

  // total number of files processed is total number of test files
  //
  total_a = tst_num_items_a;
  
  if (diff_cc(diff, proc_a, ref_fnames_a, ref_values_a, ref_num_items_a,
	      ref_index, tst_fnames_a, tst_values_a, tst_num_items_a)
      == ISIP_FALSE) {
    error_handler_cc((char_1*)"stats_cc",
		     (char_1*)"error while finding the differences");
    return ISIP_FALSE;
  }

  // sort the difference in ascending order
  //
  int_4 diff_index[tst_num_items_a];

  if (qsort_cc(diff_index, diff, tst_num_items_a) == ISIP_FALSE) {
    error_handler_cc((char_1*)"stats_cc", (char_1*)"error while sorting");
    return ISIP_FALSE;
  }

  // calculate mininum 
  //
  min_a = diff[diff_index[0]];
  strcpy((char*)min_file_a, (char*)tst_fnames_a[diff_index[0]]);

  if (debug_level_d > ISIP_DEBUG_BRIEF) {
    fprintf(stdout, IMGEV_DEBUG_FORMAT_C, IMAGE_EVAL_CLASS_NAME, "stats_cc",
	    min_a, min_file_a);
  }
    
  // calculate the median
  //
  median_a = diff[diff_index[tst_num_items_a/2]];
  strcpy((char*)median_file_a,
	 (char*)tst_fnames_a[diff_index[tst_num_items_a/2]]);
  
  if (debug_level_d > ISIP_DEBUG_BRIEF) {
    fprintf(stdout, IMGEV_DEBUG_FORMAT_D, IMAGE_EVAL_CLASS_NAME, "stats_cc",
	    median_a, median_file_a);
  }
  
  // calculate maximum
  //
  max_a = diff[diff_index[tst_num_items_a-1]];
  strcpy((char*)max_file_a,
	 (char*)tst_fnames_a[diff_index[tst_num_items_a-1]]);
  
  if (debug_level_d > ISIP_DEBUG_BRIEF) {
    fprintf(stdout, IMGEV_DEBUG_FORMAT_E, IMAGE_EVAL_CLASS_NAME, "stats_cc",
	    max_a, max_file_a);
  }
  
  // calculate the average difference 
  //
  avg_a = average_cc(diff, tst_num_items_a);

  if (debug_level_d > ISIP_DEBUG_BRIEF) {
    fprintf(stdout, IMGEV_DEBUG_FORMAT_F, IMAGE_EVAL_CLASS_NAME, "stats_cc",
	    avg_a);
  }

  // calculate the rms
  //
  for (int_4 i = 0; i < tst_num_items_a; i++) {
    rms_a += diff[i] * diff[i];
  }
  rms_a = pow((rms_a / tst_num_items_a), 0.5);
  
  if (debug_level_d > ISIP_DEBUG_BRIEF) {
    fprintf(stdout, IMGEV_DEBUG_FORMAT_G, IMAGE_EVAL_CLASS_NAME, "stats_cc",
	    rms_a);
  }
  
  // exit gracefully
  //
  return ISIP_TRUE;
}





