Index: /branches/eam_branches/ipp-dev-20210817/Ohana/src/opihi/cmd.data/medimage_calc.c
===================================================================
--- /branches/eam_branches/ipp-dev-20210817/Ohana/src/opihi/cmd.data/medimage_calc.c	(revision 41849)
+++ /branches/eam_branches/ipp-dev-20210817/Ohana/src/opihi/cmd.data/medimage_calc.c	(revision 41850)
@@ -19,5 +19,5 @@
 static float *irls_testval = NULL;
 
-enum {CALC_MEDIAN, CALC_MEAN, CALC_IRLS, CALC_WTMEAN};
+enum {CALC_MEDIAN, CALC_MEAN, CALC_IRLS, CALC_WTMEAN, CALC_INNER_FRACTION};
 
 int medimage_calc (int argc, char **argv) {
@@ -39,4 +39,7 @@
   }
 
+  float minRange = NAN;
+  float maxRange = NAN;
+
   int mode = CALC_MEDIAN;
   if ((N = get_argument (argc, argv, "-mean"))) {
@@ -45,15 +48,28 @@
   }
   if ((N = get_argument (argc, argv, "-irls"))) {
-    if (mode != CALC_MEDIAN) { gprint (GP_ERR, "supply only one of -mean, -median, -irls, -wtmean\n"); return FALSE; }
+    if (mode != CALC_MEDIAN) goto choose_one;
     mode = CALC_IRLS;
     remove_argument (N, &argc, argv);
   }
   if ((N = get_argument (argc, argv, "-wtmean"))) {
-    if (mode != CALC_MEDIAN) { gprint (GP_ERR, "supply only one of -mean, -median, -irls, -wtmean\n"); return FALSE; }
+    if (mode != CALC_MEDIAN) goto choose_one;
     mode = CALC_WTMEAN;
     remove_argument (N, &argc, argv);
   }
+  if ((N = get_argument (argc, argv, "-inner-fraction"))) {
+    if (mode != CALC_MEDIAN) goto choose_one;
+    if (argc < N + 3) goto fraction_options;
+    mode = CALC_INNER_FRACTION;
+    remove_argument (N, &argc, argv);
+    minRange = atof(argv[N]);
+    if ((minRange < 0.0) || (minRange > 1.0)) goto fraction_options;
+    remove_argument (N, &argc, argv);
+    maxRange = atof(argv[N]);
+    if ((maxRange < 0.0) || (maxRange > 1.0)) goto fraction_options;
+    if (maxRange <= minRange) goto fraction_options;
+    remove_argument (N, &argc, argv);
+  }
   if ((N = get_argument (argc, argv, "-median"))) {
-    if (mode != CALC_MEDIAN) { gprint (GP_ERR, "supply only one of -mean, -median, -irls, -wtmean\n"); return FALSE; }
+    if (mode != CALC_MEDIAN) goto choose_one;
     mode = CALC_MEDIAN;
     remove_argument (N, &argc, argv);
@@ -157,4 +173,25 @@
 	  }
 	  break;
+	case CALC_INNER_FRACTION:
+	  fsort (val, N);
+	  int Ns = MIN(MAX(0, minRange * N),N); // e.g., 0.1 * 50 = 5
+	  int Ne = MIN(MAX(0, maxRange * N),N); // e.g., 0.9 * 50 = 45 
+	  int Npt = Ne - Ns;
+
+	  float sum = 0.0;
+	  for (n = Ns; n < Ne; n++) {
+	    sum += val[n];
+	  }
+	  outvalue[Npix] = sum / (float) Npt;
+
+	  if (varvalue) {
+	    float sum = 0.0;
+	    for (n = Ns; n < Ne; n++) {
+	      sum += SQ(val[n] - outvalue[Npix]);
+	    }
+	    // variance on the mean (stdev / sqrt(N))^2
+	    varvalue[Npix] = sum / (Npt - 1) / Npt;
+	  }
+	  break;
 	case CALC_MEAN: {
 	  float sum = 0.0;
@@ -195,4 +232,12 @@
   irls_free();
   return TRUE;
+
+ choose_one:
+  gprint (GP_ERR, "supply only one of -mean, -median, -irls, -wtmean, -inner-fraction\n");
+  return FALSE; 
+
+ fraction_options:
+  gprint (GP_ERR, "USE: -inner-fraction (min) (max) : min & max in range 0.0 to 1.0\n");
+  return FALSE; 
 }
 
