e231d173a9bee19af2a31ec8193c00a294a1a3a0
kent
  Tue May 27 20:03:59 2014 -0700
Polishing doubleBoxWhiskerCalc to work well for small Ns.
diff --git src/lib/common.c src/lib/common.c
index 50d6c69..494a201 100644
--- src/lib/common.c
+++ src/lib/common.c
@@ -479,42 +479,67 @@
 doubleSort(count, array);
 if ((count&1) == 1)
     median = array[count>>1];
 else
     {
     count >>= 1;
     median = (array[count] + array[count-1]) * 0.5;
     }
 return median;
 }
 
 void doubleBoxWhiskerCalc(int count, double *array, double *retMin,
                           double *retQ1, double *retMedian, double *retQ3, double *retMax)
 /* Calculate what you need to draw a box and whiskers plot from an array of doubles. */
 {
+if (count <= 0)
+    errAbort("doubleBoxWhiskerCalc needs a positive number, not %d for count", count);
+if (count == 1)
+    {
+    *retMin = *retQ1 = *retMedian = *retQ3 = *retMax = array[0];
+    return;
+    }
 doubleSort(count, array);
-*retMin = array[0];
-*retQ1 = array[(count+2)/4];
+double min = array[0];
+double max = array[count-1];
+double median;
 int halfCount = count>>1;
 if ((count&1) == 1)
-    *retMedian = array[halfCount];
+    median = array[halfCount];
 else
     {
-    *retMedian = (array[halfCount] + array[halfCount-1]) * 0.5;
+    median = (array[halfCount] + array[halfCount-1]) * 0.5;
     }
-*retQ3 = array[(3*count+2)/4];
-*retMax = array[count-1];
+double q1, q3;
+if (count <= 3)
+    {
+    q1 = 0.5 * (median + min);
+    q3 = 0.5 * (median + max);
+    }
+else
+    {
+    int q1Ix = count/4;
+    int q3Ix = count - 1 - q1Ix;
+    uglyf("count %d, q1Ix %d, q3Ix %d\n", count, q1Ix, q3Ix);
+    q1 = array[q1Ix];
+    q3 = array[q3Ix];
+    }
+*retMin = min;
+*retQ1 = q1;
+*retMedian = median;
+*retQ3 = q3;
+*retMax = max;
 }
 
 struct slDouble *slDoubleNew(double x)
 /* Return a new double. */
 {
 struct slDouble *a;
 AllocVar(a);
 a->val = x;
 return a;
 }
 
 int slDoubleCmp(const void *va, const void *vb)
 /* Compare two slDoubles. */
 {
 const struct slDouble *a = *((struct slDouble **)va);