IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 42719


Ignore:
Timestamp:
Sep 13, 2024, 10:19:51 PM (22 months ago)
Author:
hgao
Message:

finetune overscan region and stats for reducing and smoothing overscan array/vector

Location:
branches/2dbias
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • branches/2dbias/ippconfig/gpc1/format_20100723.config

    r42716 r42719  
    166166# 2D bias subtraction requires ppImage.config OVERSCAN.2D to be TRUE
    167167               CELL.BIASSEC.SOURCE     STR     VALUE
    168                CELL.BIASSEC            STR     [591:624,1:598],[1:624,599:608]
     168# exclude the last row and column from the bias region
     169               CELL.BIASSEC            STR     [591:623,1:598],[1:623,599:607]
    169170#
    170171# a single region will be used for constant and 1D bias subtraction
  • branches/2dbias/ippconfig/gpc1/ppImage.config

    r42679 r42719  
    66BIN2.YBIN               S32     150
    77
    8 OVERSCAN.SINGLE         BOOL    FALSE            # Reduce overscan to a single value?
    9 OVERSCAN.STAT           STR     MEDIAN
    10 OVERSCAN.BOXCAR         S32     3
     8OVERSCAN.SINGLE         BOOL    FALSE           # Reduce overscan to a single value?
     9OVERSCAN.STAT           STR     MEAN            # MEAN | MEDIAN
     10OVERSCAN.BOXCAR         S32     10              # Boxcar smoothing radius
     11OVERSCAN.2D             BOOL    FALSE           # use a 2D model for the overscan subtraction?
     12OVERSCAN.2D.STAT        STR     MEAN            # MEAN | MEDIAN
     13OVERSCAN.2D.BOXCAR          S32     30                          # Boxcar smoothing radius
     14
    1115
    1216OVERSCAN.2D.SUBSET METADATA
    13       XY00    BOOL    TRUE
    1417      XY01    BOOL    TRUE
    1518      XY02    BOOL    TRUE
     
    7477      XY75    BOOL    TRUE
    7578      XY76    BOOL    TRUE
    76       XY77    BOOL    TRUE
    7779END
    7880
  • branches/2dbias/psLib/src/math/psStats.c

    r41520 r42719  
    1919 */
    2020
    21 
    2221// Note: choice of return values in many places is quite grey.  For example, calculating the sample standard
    2322// deviation: here it's an error to get an array of size zero, but it's not an error to get an array of size
     
    6362#include "psString.h"
    6463
    65 
    66 
    6764/*****************************************************************************/
    6865/* DEFINE STATEMENTS                                                         */
    6966/*****************************************************************************/
    70 #define PS_GAUSS_WIDTH 3                // The width of the Gaussian smoothing.
     67#define PS_GAUSS_WIDTH 3         // The width of the Gaussian smoothing.
    7168#define PS_CLIPPED_NUM_ITER_LB 1 // This corresponds to N in the ADD.
    7269#define PS_CLIPPED_NUM_ITER_UB 10
     
    7774#define TRACE "psLib.math"
    7875
    79 #define MASK_MARK 0x80   // XXX : can we change this? bit to use internally to mark data as bad
    80 #define PS_ROBUST_MAX_ITERATIONS 20     // Maximum number of iterations for robust statistics
     76#define MASK_MARK 0x80              // XXX : can we change this? bit to use internally to mark data as bad
     77#define PS_ROBUST_MAX_ITERATIONS 20 // Maximum number of iterations for robust statistics
    8178
    8279#define PS_BIN_MIDPOINT(HISTOGRAM, BIN_NUM) \
    83 (0.5 * (HISTOGRAM->bounds->data.F32[(BIN_NUM)] + HISTOGRAM->bounds->data.F32[(BIN_NUM)+1]))
     80    (0.5 * (HISTOGRAM->bounds->data.F32[(BIN_NUM)] + HISTOGRAM->bounds->data.F32[(BIN_NUM) + 1]))
    8481
    8582// set the bin closest to the corresponding value.  if USE_END is +/- 1,
    8683// out-of-range saturates on lower/upper bin REGARDLESS of actual value
    87 #define PS_BIN_FOR_VALUE(RESULT, VECTOR, VALUE, USE_END) { \
    88         psVectorBinaryDisectResult result; \
    89         psScalar tmpScalar; \
    90         tmpScalar.type.type = PS_TYPE_F32; \
    91         tmpScalar.data.F32 = (VALUE); \
    92         RESULT = psVectorBinaryDisect (&result, VECTOR, &tmpScalar); \
    93         switch (result) { \
    94           case PS_BINARY_DISECT_PASS: \
    95             break; \
    96           case PS_BINARY_DISECT_OUTSIDE_RANGE: \
    97             psTrace(TRACE, 6, "selected bin outside range"); \
    98             if (USE_END == -1) { RESULT = 0; } \
    99             if (USE_END == +1) { RESULT = VECTOR->n - 1; } \
    100             break; \
    101           case PS_BINARY_DISECT_INVALID_INPUT: \
    102           case PS_BINARY_DISECT_INVALID_TYPE: \
    103             psAbort ("programming error"); \
    104             break; \
    105         } }
    106 
    107 # define PS_BIN_INTERPOLATE(RESULT, VECTOR, BOUNDS, BIN, VALUE) { \
    108         float dX, dY, Xo, Yo, Xt; \
    109         if (BIN == BOUNDS->n - 1) { \
    110             dX = 0.5*(BOUNDS->data.F32[BIN+1] - BOUNDS->data.F32[BIN-1]); \
    111             dY = VECTOR->data.F32[BIN] - VECTOR->data.F32[BIN-1]; \
    112             Xo = 0.5*(BOUNDS->data.F32[BIN+1] + BOUNDS->data.F32[BIN]); \
    113             Yo = VECTOR->data.F32[BIN]; \
    114         } else { \
    115             dX = 0.5*(BOUNDS->data.F32[BIN+2] - BOUNDS->data.F32[BIN]); \
    116             dY = VECTOR->data.F32[BIN+1] - VECTOR->data.F32[BIN]; \
    117             Xo = 0.5*(BOUNDS->data.F32[BIN+1] + BOUNDS->data.F32[BIN]); \
    118             Yo = VECTOR->data.F32[BIN]; \
    119         } \
    120         if (dY != 0) { \
    121             Xt = (VALUE - Yo)*dX/dY + Xo; \
    122         } else { \
    123             Xt = Xo; \
    124         } \
    125         Xt = PS_MIN (BOUNDS->data.F32[BIN+1], PS_MAX(BOUNDS->data.F32[BIN], Xt)); \
     84#define PS_BIN_FOR_VALUE(RESULT, VECTOR, VALUE, USE_END)            \
     85    {                                                               \
     86        psVectorBinaryDisectResult result;                          \
     87        psScalar tmpScalar;                                         \
     88        tmpScalar.type.type = PS_TYPE_F32;                          \
     89        tmpScalar.data.F32 = (VALUE);                               \
     90        RESULT = psVectorBinaryDisect(&result, VECTOR, &tmpScalar); \
     91        switch (result)                                             \
     92        {                                                           \
     93        case PS_BINARY_DISECT_PASS:                                 \
     94            break;                                                  \
     95        case PS_BINARY_DISECT_OUTSIDE_RANGE:                        \
     96            psTrace(TRACE, 6, "selected bin outside range");        \
     97            if (USE_END == -1)                                      \
     98            {                                                       \
     99                RESULT = 0;                                         \
     100            }                                                       \
     101            if (USE_END == +1)                                      \
     102            {                                                       \
     103                RESULT = VECTOR->n - 1;                             \
     104            }                                                       \
     105            break;                                                  \
     106        case PS_BINARY_DISECT_INVALID_INPUT:                        \
     107        case PS_BINARY_DISECT_INVALID_TYPE:                         \
     108            psAbort("programming error");                           \
     109            break;                                                  \
     110        }                                                           \
     111    }
     112
     113#define PS_BIN_INTERPOLATE(RESULT, VECTOR, BOUNDS, BIN, VALUE)                             \
     114    {                                                                                      \
     115        float dX, dY, Xo, Yo, Xt;                                                          \
     116        if (BIN == BOUNDS->n - 1)                                                          \
     117        {                                                                                  \
     118            dX = 0.5 * (BOUNDS->data.F32[BIN + 1] - BOUNDS->data.F32[BIN - 1]);            \
     119            dY = VECTOR->data.F32[BIN] - VECTOR->data.F32[BIN - 1];                        \
     120            Xo = 0.5 * (BOUNDS->data.F32[BIN + 1] + BOUNDS->data.F32[BIN]);                \
     121            Yo = VECTOR->data.F32[BIN];                                                    \
     122        }                                                                                  \
     123        else                                                                               \
     124        {                                                                                  \
     125            dX = 0.5 * (BOUNDS->data.F32[BIN + 2] - BOUNDS->data.F32[BIN]);                \
     126            dY = VECTOR->data.F32[BIN + 1] - VECTOR->data.F32[BIN];                        \
     127            Xo = 0.5 * (BOUNDS->data.F32[BIN + 1] + BOUNDS->data.F32[BIN]);                \
     128            Yo = VECTOR->data.F32[BIN];                                                    \
     129        }                                                                                  \
     130        if (dY != 0)                                                                       \
     131        {                                                                                  \
     132            Xt = (VALUE - Yo) * dX / dY + Xo;                                              \
     133        }                                                                                  \
     134        else                                                                               \
     135        {                                                                                  \
     136            Xt = Xo;                                                                       \
     137        }                                                                                  \
     138        Xt = PS_MIN(BOUNDS->data.F32[BIN + 1], PS_MAX(BOUNDS->data.F32[BIN], Xt));         \
    126139        psTrace(TRACE, 6, "(Xo, Yo, dX, dY, Xt, Yt) is (%.2f %.2f %.2f %.2f %.2f %.2f)\n", \
    127                 Xo, Yo, dX, dY, Xt, VALUE); \
    128         RESULT = Xt; }
    129 
    130 # define COUNT_WARNING(LIMIT, INTERVAL, ...) { \
    131         static int nCalls = 1; \
    132         if (nCalls < LIMIT) { \
    133             psWarning(__VA_ARGS__); \
    134         } \
    135         if (!(nCalls % INTERVAL)) { \
    136             psWarning(__VA_ARGS__); \
     140                Xo, Yo, dX, dY, Xt, VALUE);                                                \
     141        RESULT = Xt;                                                                       \
     142    }
     143
     144#define COUNT_WARNING(LIMIT, INTERVAL, ...)                 \
     145    {                                                       \
     146        static int nCalls = 1;                              \
     147        if (nCalls < LIMIT)                                 \
     148        {                                                   \
     149            psWarning(__VA_ARGS__);                         \
     150        }                                                   \
     151        if (!(nCalls % INTERVAL))                           \
     152        {                                                   \
     153            psWarning(__VA_ARGS__);                         \
    137154            psWarning("(warning raised %d times)", nCalls); \
    138         } \
    139         nCalls ++; \
    140 }
     155        }                                                   \
     156        nCalls++;                                          \
     157    }
    141158
    142159// Debug information
     
    195212To optmize this, use a macro and ifdef in or out the three states (errors, mask, range)
    196213*****************************************************************************/
    197     static bool vectorSampleMean(const psVector* myVector,
    198                                  const psVector* errors,
    199                                  const psVector* maskVector,
    200                                  psVectorMaskType maskVal,
    201                                  psStats* stats)
     214static bool vectorSampleMean(const psVector *myVector,
     215                             const psVector *errors,
     216                             const psVector *maskVector,
     217                             psVectorMaskType maskVal,
     218                             psStats *stats)
    202219{
    203     long count = 0;                     // Number of points contributing to this mean
    204     psF32 mean = 0.0;                   // The mean
     220    long count = 0;   // Number of points contributing to this mean
     221    psF32 mean = 0.0; // The mean
    205222    psF32 weight;
    206223
    207     psF32 *data = myVector->data.F32;   // Dereference
    208     int numData = myVector->n;          // Number of data points
     224    psF32 *data = myVector->data.F32; // Dereference
     225    int numData = myVector->n;        // Number of data points
    209226
    210227    psVectorMaskType *maskData = (maskVector == NULL) ? NULL : maskVector->data.PS_TYPE_VECTOR_MASK_DATA;
    211228    bool useRange = stats->options & PS_STAT_USE_RANGE;
    212229
    213     psF32 sumWeights = 0.0;  // The sum of the weights
     230    psF32 sumWeights = 0.0; // The sum of the weights
    214231    psF32 *errorsData = (errors == NULL) ? NULL : errors->data.F32;
    215232
    216     for (long i = 0; i < numData; i++) {
     233    for (long i = 0; i < numData; i++)
     234    {
    217235        // Check if the data is with the specified range
    218236        if (!isfinite(data[i]))
     
    224242        if (maskData && (maskData[i] & maskVal))
    225243            continue;
    226         if (errors) {
     244        if (errors)
     245        {
    227246            weight = (errorsData[i] == 0) ? 0.0 : PS_SQR(errorsData[i]);
    228247            mean += data[i] * weight;
    229248            sumWeights += weight;
    230         } else {
     249        }
     250        else
     251        {
    231252            mean += data[i];
    232253        }
    233254        count++;
    234 
    235     }
    236     if (errors) {
     255    }
     256    if (errors)
     257    {
    237258        mean = (count > 0) ? mean / sumWeights : NAN;
    238     } else {
     259    }
     260    else
     261    {
    239262        mean = (count > 0) ? mean / count : NAN;
    240263    }
    241264    stats->sampleMean = mean;
    242265
    243     if (!isnan(mean)) {
     266    if (!isnan(mean))
     267    {
    244268        stats->results |= PS_STAT_SAMPLE_MEAN;
    245269    }
     
    260284(mask: 1, range: 0):  0.200 sec  0.244 sec
    261285*****************************************************************************/
    262     static long vectorMinMax(const psVector* myVector,
    263                              const psVector* maskVector,
    264                              psVectorMaskType maskVal,
    265                              psStats* stats
    266         )
     286static long vectorMinMax(const psVector *myVector,
     287                         const psVector *maskVector,
     288                         psVectorMaskType maskVal,
     289                         psStats *stats)
    267290{
    268291    psF32 max = -PS_MAX_F32;            // The calculated maximum
     
    270293    psF32 *vector = myVector->data.F32; // Dereference the vector
    271294
    272     int num = myVector->n;              // Number of values
    273     int numValid = 0;                   // Number of valid values
     295    int num = myVector->n; // Number of values
     296    int numValid = 0;      // Number of valid values
    274297
    275298    psVectorMaskType *maskData = (maskVector == NULL) ? NULL : maskVector->data.PS_TYPE_VECTOR_MASK_DATA;
    276299    bool useRange = stats->options & PS_STAT_USE_RANGE;
    277300
    278     for (long i = 0; i < num; i++) {
     301    for (long i = 0; i < num; i++)
     302    {
    279303        // Check if the data is with the specified range
    280304        if (!isfinite(vector[i]))
     
    288312
    289313        numValid++;
    290         max = PS_MAX (vector[i], max);
    291         min = PS_MIN (vector[i], min);
     314        max = PS_MAX(vector[i], max);
     315        min = PS_MIN(vector[i], min);
    292316    }
    293317
    294318    // XXX save numValid in psStats?
    295     if (numValid == 0) {
     319    if (numValid == 0)
     320    {
    296321        stats->max = NAN;
    297322        stats->min = NAN;
    298     } else {
     323    }
     324    else
     325    {
    299326        stats->max = max;
    300327        stats->min = min;
     
    310337were no valid input vector elements). Expects F32 vector for input.
    311338*****************************************************************************/
    312 static bool vectorSampleMedian(const psVector* inVector,
    313                                const psVector* maskVector,
     339static bool vectorSampleMedian(const psVector *inVector,
     340                               const psVector *maskVector,
    314341                               psVectorMaskType maskVal,
    315                                psStats* stats)
     342                               psStats *stats)
    316343{
    317344    bool useRange = stats->options & PS_STAT_USE_RANGE;
    318345    psVectorMaskType *maskData = (maskVector == NULL) ? NULL : maskVector->data.PS_TYPE_VECTOR_MASK_DATA; // Dereference the vector
    319     psF32 *input = inVector->data.F32; // Dereference the vector
     346    psF32 *input = inVector->data.F32;                                                                    // Dereference the vector
    320347
    321348    // use the temporary vector for the sorted output
    322     stats->tmpData = psVectorRecycle (stats->tmpData, inVector->n, PS_TYPE_F32);
     349    stats->tmpData = psVectorRecycle(stats->tmpData, inVector->n, PS_TYPE_F32);
    323350    psVector *outVector = stats->tmpData;
    324351    psF32 *output = outVector->data.F32; // Dereference the vector
    325352
    326     if (maskData) psAssert (maskVector->n == inVector->n, "oops");
    327 
    328     long count = 0;                     // Number of valid entries
     353    if (maskData)
     354        psAssert(maskVector->n == inVector->n, "oops");
     355
     356    long count = 0; // Number of valid entries
    329357
    330358    // Store all non-masked data points within the min/max range
    331359    // into the temporary vectors.
    332     for (long i = 0; i < inVector->n; i++) {
    333         psAssert (count >= 0, "oops");
    334         psAssert (count < outVector->n, "oops");
    335         psAssert (i >= 0, "oops");
    336         psAssert (i < inVector->n, "oops");
    337 
    338         if (!isfinite(input[i])) continue;
    339         if (useRange && (input[i] < stats->min)) continue;
    340         if (useRange && (input[i] > stats->max)) continue;
    341         if (maskData && (maskData[i] & maskVal)) continue;
     360    for (long i = 0; i < inVector->n; i++)
     361    {
     362        psAssert(count >= 0, "oops");
     363        psAssert(count < outVector->n, "oops");
     364        psAssert(i >= 0, "oops");
     365        psAssert(i < inVector->n, "oops");
     366
     367        if (!isfinite(input[i]))
     368            continue;
     369        if (useRange && (input[i] < stats->min))
     370            continue;
     371        if (useRange && (input[i] > stats->max))
     372            continue;
     373        if (maskData && (maskData[i] & maskVal))
     374            continue;
    342375
    343376        output[count] = input[i];
     
    346379    outVector->n = count;
    347380
    348     if (count == 0) {
     381    if (count == 0)
     382    {
    349383        COUNT_WARNING(10, 100, "No valid data in input vector.\n");
    350384        stats->sampleUQ = NAN;
     
    355389
    356390    // Sort the temporary vector.
    357     if (!psVectorSort(outVector, outVector)) { // Sort in-place (since it's a copy, it's OK)
     391    if (!psVectorSort(outVector, outVector))
     392    { // Sort in-place (since it's a copy, it's OK)
    358393        // an error in psVectorSort is a serious error:
    359         // NULL input vector, psVectorCopy failure, invalid vector type
     394        // NULL input vector, psVectorCopy failure, invalid vector type
    360395        psError(PS_ERR_UNEXPECTED_NULL, false, _("Failed to sort input data."));
    361396        stats->sampleUQ = NAN;
     
    366401
    367402    // Calculate the median.  Use the average if the number of samples if even.
    368     int midPt = (count/2);
    369     psAssert (midPt >=           0, "oops");
    370     psAssert (midPt < outVector->n, "oops");
    371     if (count % 2 == 0) {
    372         psAssert ((midPt - 1) >=           0, "oops");
    373         psAssert ((midPt - 1) < outVector->n, "oops");
     403    int midPt = (count / 2);
     404    psAssert(midPt >= 0, "oops");
     405    psAssert(midPt < outVector->n, "oops");
     406    if (count % 2 == 0)
     407    {
     408        psAssert((midPt - 1) >= 0, "oops");
     409        psAssert((midPt - 1) < outVector->n, "oops");
    374410        stats->sampleMedian = 0.5 * (output[midPt - 1] + output[midPt]);
    375     } else {
     411    }
     412    else
     413    {
    376414        stats->sampleMedian = output[midPt];
    377415    }
    378416
    379     int Qmin = (int)(0.25*count);
    380     int Qmax = (int)(0.75*count);
    381     psAssert (Qmin >=          0, "oops");
    382     psAssert (Qmin < outVector->n, "oops");
    383     psAssert (Qmax >=          0, "oops");
    384     psAssert (Qmax < outVector->n, "oops");
     417    int Qmin = (int)(0.25 * count);
     418    int Qmax = (int)(0.75 * count);
     419    psAssert(Qmin >= 0, "oops");
     420    psAssert(Qmin < outVector->n, "oops");
     421    psAssert(Qmax >= 0, "oops");
     422    psAssert(Qmax < outVector->n, "oops");
    385423
    386424    // Calculate the quartile points exactly.
    387425    stats->sampleUQ = output[Qmax];
    388426    stats->sampleLQ = output[Qmin];
    389      
     427
    390428    stats->results |= PS_STAT_SAMPLE_MEDIAN;
    391429    stats->results |= PS_STAT_SAMPLE_QUARTILE;
     
    409447*****************************************************************************/
    410448
    411 static bool vectorSampleStdev(const psVector* myVector,
    412                               const psVector* errors,
    413                               const psVector* maskVector,
     449static bool vectorSampleStdev(const psVector *myVector,
     450                              const psVector *errors,
     451                              const psVector *maskVector,
    414452                              psVectorMaskType maskVal,
    415                               psStats* stats)
     453                              psStats *stats)
    416454{
    417455    // This procedure requires the mean.  If it has not been already
    418456    // calculated, then call vectorSampleMean()
    419     if (!(stats->results & PS_STAT_SAMPLE_MEAN)) {
     457    if (!(stats->results & PS_STAT_SAMPLE_MEAN))
     458    {
    420459        vectorSampleMean(myVector, errors, maskVector, maskVal, stats);
    421460    }
    422461
    423462    // If the mean is NAN, then generate a warning and set the stdev to NAN.
    424     if (isnan(stats->sampleMean)) {
     463    if (isnan(stats->sampleMean))
     464    {
    425465        COUNT_WARNING(10, 100, "WARNING: vectorSampleStdev(): sample mean is NAN. Setting stats->sampleStdev = NAN.");
    426466        stats->sampleStdev = NAN;
     
    428468    }
    429469
    430     psF32 *data = myVector->data.F32;   // Dereference
     470    psF32 *data = myVector->data.F32; // Dereference
    431471    psVectorMaskType *maskData = (maskVector == NULL) ? NULL : maskVector->data.PS_TYPE_VECTOR_MASK_DATA;
    432472    bool useRange = stats->options & PS_STAT_USE_RANGE;
     
    434474
    435475    // Accumulate the sums
    436     double mean = stats->sampleMean;    // The mean
    437     double sumSquares = 0.0;            // Sum of the squares
    438     double sumDiffs = 0.0;              // Sum of the differences
    439     double errorDivisor = 0.0;          // Division for errors
    440     long count = 0;                     // Number of data points being used
    441     for (long i = 0; i < myVector->n; i++) {
     476    double mean = stats->sampleMean; // The mean
     477    double sumSquares = 0.0;         // Sum of the squares
     478    double sumDiffs = 0.0;           // Sum of the differences
     479    double errorDivisor = 0.0;       // Division for errors
     480    long count = 0;                  // Number of data points being used
     481    for (long i = 0; i < myVector->n; i++)
     482    {
    442483        // Check if the data is with the specified range
    443484        if (!isfinite(data[i]))
    444485            continue;
    445         if (useRange && (data[i] < stats->min)) {
     486        if (useRange && (data[i] < stats->min))
     487        {
    446488            continue;
    447489        }
    448         if (useRange && (data[i] > stats->max)) {
     490        if (useRange && (data[i] > stats->max))
     491        {
    449492            continue;
    450493        }
    451         if (maskData && (maskData[i] & maskVal)) {
     494        if (maskData && (maskData[i] & maskVal))
     495        {
    452496            continue;
    453497        }
     
    457501        sumDiffs += diff;
    458502        count++;
    459         if (errors) {
     503        if (errors)
     504        {
    460505            errorDivisor += 1.0 / PS_SQR(errorsData[i]);
    461506        }
    462507    }
    463508
    464     if (count == 0) {
     509    if (count == 0)
     510    {
    465511        // This is an ambiguous case: error or not?
    466512        // It's not an empty array (that's been asserted on previously), but everything's been masked out.
     
    470516        return true;
    471517    }
    472     if (count == 1) {
     518    if (count == 1)
     519    {
    473520        stats->sampleStdev = 0.0;
    474521        COUNT_WARNING(10, 100, "WARNING: vectorSampleStdev(): only one valid psVector elements (%ld). Setting stats->sampleStdev = 0.0.\n", count);
     
    476523    }
    477524
    478     if (errors) {
     525    if (errors)
     526    {
    479527        stats->sampleStdev = (1.0 / sqrtf(errorDivisor));
    480     } else {
     528    }
     529    else
     530    {
    481531        stats->sampleStdev = sqrt((sumSquares - (sumDiffs * sumDiffs / (float)count)) / (float)(count - 1));
    482532    }
     
    486536}
    487537
    488 static bool vectorSampleMoments(const psVector* myVector,
    489                                 const psVector* maskVector,
     538static bool vectorSampleMoments(const psVector *myVector,
     539                                const psVector *maskVector,
    490540                                psVectorMaskType maskVal,
    491                                 psStats* stats)
     541                                psStats *stats)
    492542{
    493543    // This procedure requires the mean and standard deviation
    494     if (!(stats->results & PS_STAT_SAMPLE_MEAN)) {
     544    if (!(stats->results & PS_STAT_SAMPLE_MEAN))
     545    {
    495546        vectorSampleMean(myVector, NULL, maskVector, maskVal, stats);
    496547    }
    497     if (isnan(stats->sampleMean)) {
     548    if (isnan(stats->sampleMean))
     549    {
    498550        COUNT_WARNING(10, 100, "WARNING: vectorSampleMoments(): sample mean is NAN.\n");
    499551        goto SAMPLE_MOMENTS_BAD;
    500552    }
    501     if (!(stats->results & PS_STAT_SAMPLE_STDEV)) {
     553    if (!(stats->results & PS_STAT_SAMPLE_STDEV))
     554    {
    502555        vectorSampleStdev(myVector, NULL, maskVector, maskVal, stats);
    503556    }
    504     if (isnan(stats->sampleStdev) || stats->sampleStdev == 0.0) {
     557    if (isnan(stats->sampleStdev) || stats->sampleStdev == 0.0)
     558    {
    505559        COUNT_WARNING(10, 100, "WARNING: vectorSampleMoments(): sample stdev is NAN or 0.\n");
    506560        goto SAMPLE_MOMENTS_BAD;
    507561    }
    508562
    509     psF32 *data = myVector->data.F32;   // Dereference
     563    psF32 *data = myVector->data.F32; // Dereference
    510564    psVectorMaskType *maskData = (maskVector == NULL) ? NULL : maskVector->data.PS_TYPE_VECTOR_MASK_DATA;
    511565    bool useRange = stats->options & PS_STAT_USE_RANGE;
    512566
    513567    // Accumulate the sums
    514     double mean = stats->sampleMean;    // The mean
    515     double sum3 = 0.0;                  // Sum of the cubes of the differences
    516     double sum4 = 0.0;                  // Sum of the fourth powers of the differences
    517     long count = 0;                     // Number of data points being used
    518     for (long i = 0; i < myVector->n; i++) {
     568    double mean = stats->sampleMean; // The mean
     569    double sum3 = 0.0;               // Sum of the cubes of the differences
     570    double sum4 = 0.0;               // Sum of the fourth powers of the differences
     571    long count = 0;                  // Number of data points being used
     572    for (long i = 0; i < myVector->n; i++)
     573    {
    519574        // Check if the data is with the specified range
    520575        if (!isfinite(data[i]))
    521576            continue;
    522         if (useRange && (data[i] < stats->min)) {
     577        if (useRange && (data[i] < stats->min))
     578        {
    523579            continue;
    524580        }
    525         if (useRange && (data[i] > stats->max)) {
     581        if (useRange && (data[i] > stats->max))
     582        {
    526583            continue;
    527584        }
    528         if (maskData && (maskData[i] & maskVal)) {
     585        if (maskData && (maskData[i] & maskVal))
     586        {
    529587            continue;
    530588        }
    531589
    532         double diff = data[i] - mean;   // Difference from the mean
    533         double temp;                    // Temporary variable for accumulating
     590        double diff = data[i] - mean; // Difference from the mean
     591        double temp;                  // Temporary variable for accumulating
    534592
    535593        sum3 += temp = PS_SQR(diff);
     
    539597    }
    540598
    541     psAssert(count > 1, "impossible");                  // It should be, because we have a mean and standard deviation
    542 
    543     double stdev = stats->sampleStdev;  // Standard deviation
    544     double variance = PS_SQR(stdev);    // Variance
     599    psAssert(count > 1, "impossible"); // It should be, because we have a mean and standard deviation
     600
     601    double stdev = stats->sampleStdev; // Standard deviation
     602    double variance = PS_SQR(stdev);   // Variance
    545603
    546604    // Formula for skewness and kurtosis from Numerical Recipes in C, p 613.
     
    552610    return true;
    553611
    554  SAMPLE_MOMENTS_BAD:
     612SAMPLE_MOMENTS_BAD:
    555613    // stats->sampleStdev has already been set
    556614    stats->sampleSkewness = NAN;
     
    571629    true for success; false otherwise
    572630*****************************************************************************/
    573 static bool vectorClippedStats(const psVector* myVector,
    574                                const psVector* errors,
    575                                psVector* maskInput,
     631static bool vectorClippedStats(const psVector *myVector,
     632                               const psVector *errors,
     633                               psVector *maskInput,
    576634                               psVectorMaskType maskValInput,
    577                                psStats* stats
    578     )
     635                               psStats *stats)
    579636{
    580637    // Ensure that stats->clipIter is within the proper range.
     
    590647    // unless we succeed, these will have NAN values
    591648    stats->clippedMean = NAN;
     649    stats->clippedMedian = NAN;
    592650    stats->clippedStdev = NAN;
    593651    stats->clippedNvalues = 0;
     
    597655
    598656    // use the temporary vector for local temporary mask
    599     stats->tmpMask = psVectorRecycle (stats->tmpMask, myVector->n, PS_TYPE_VECTOR_MASK);
     657    stats->tmpMask = psVectorRecycle(stats->tmpMask, myVector->n, PS_TYPE_VECTOR_MASK);
    600658    psVector *tmpMask = stats->tmpMask;
    601659    psVectorInit(tmpMask, 0);
    602     if (maskInput) {
    603         for (long i = 0; i < myVector->n; i++) {
    604             if (maskInput->data.PS_TYPE_VECTOR_MASK_DATA[i] & maskValInput) {
     660    if (maskInput)
     661    {
     662        for (long i = 0; i < myVector->n; i++)
     663        {
     664            if (maskInput->data.PS_TYPE_VECTOR_MASK_DATA[i] & maskValInput)
     665            {
    605666                tmpMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = maskVal;
    606667            }
     
    610671    // 1. Compute the sample median, which we save for output
    611672    vectorSampleMedian(myVector, tmpMask, maskVal, stats);
    612     if (isnan(stats->sampleMedian)) {
     673    if (isnan(stats->sampleMedian))
     674    {
    613675        COUNT_WARNING(10, 100, "Call to vectorSampleMedian returned NAN\n");
    614676        return true;
     
    618680    // 2. Compute the sample standard deviation, which we save for output
    619681    vectorSampleStdev(myVector, errors, tmpMask, maskVal, stats);
    620     if (isnan(stats->sampleStdev)) {
     682    if (isnan(stats->sampleStdev))
     683    {
    621684        COUNT_WARNING(10, 100, "Call to vectorSampleStdev returned NAN\n");
    622685        return true;
     
    625688
    626689    // 3. Use the sample median as the first estimator of the mean X.
    627     psF32 clippedMean = stats->sampleMedian;
    628 
     690    psF32 clippedMedian = stats->sampleMedian;
     691   
    629692    // 4. Use the sample stdev as the first estimator of the mean stdev.
    630693    psF32 clippedStdev = stats->sampleStdev;
    631694
    632695    // 5. Repeat N (stats->clipIter) times:
    633     long numClipped = 0;                // Number of values clipped
    634     bool clipped = true;                // Have we clipped anything in this iteration
    635     for (int iter = 0; iter < stats->clipIter && clipped; iter++) {
     696    long numClipped = 0; // Number of values clipped
     697    bool clipped = true; // Have we clipped anything in this iteration
     698    for (int iter = 0; iter < stats->clipIter && clipped; iter++)
     699    {
    636700        clipped = false;
    637701        psTrace(TRACE, 6, "------------ Iteration %d ------------\n", iter);
    638702        // a) Exclude all values x_i for which |x_i - x| > K * stdev
    639         if (errors) {
     703        if (errors)
     704        {
    640705            // XXXX if we convert errors to variance, this should square the other terms (A*A faster than
    641706            // sqrt(A))
    642             for (long j = 0; j < myVector->n; j++) {
     707            for (long j = 0; j < myVector->n; j++)
     708            {
    643709                if (!tmpMask->data.PS_TYPE_VECTOR_MASK_DATA[j] &&
    644                     fabsf(myVector->data.F32[j] - clippedMean) > stats->clipSigma * errors->data.F32[j]) {
     710                    fabsf(myVector->data.F32[j] - clippedMedian) > stats->clipSigma * errors->data.F32[j])
     711                {
    645712                    tmpMask->data.PS_TYPE_VECTOR_MASK_DATA[j] = 0xff;
    646713                    psTrace(TRACE, 10, "Clipped %ld: %f +/- %f\n", j,
     
    650717                }
    651718            }
    652         } else {
    653             for (long j = 0; j < myVector->n; j++) {
     719        }
     720        else
     721        {
     722            for (long j = 0; j < myVector->n; j++)
     723            {
    654724                if (!tmpMask->data.PS_TYPE_VECTOR_MASK_DATA[j] &&
    655                     fabsf(myVector->data.F32[j] - clippedMean) > (stats->clipSigma * clippedStdev)) {
     725                    fabsf(myVector->data.F32[j] - clippedMedian) > (stats->clipSigma * clippedStdev))
     726                {
    656727                    tmpMask->data.PS_TYPE_VECTOR_MASK_DATA[j] = 0xff;
    657728                    psTrace(TRACE, 10, "Clipped %ld: %f\n", j, myVector->data.F32[j]);
     
    662733        }
    663734
    664         // b) compute new mean and stdev
     735        // b) compute new median and stdev
    665736        // Allocate a psStats structure for calculating the mean and stdev.
    666         // XXX Can we just use this psStats structure to calculate the SAMPLE MEAN and STDEV?
    667         // psStats *statsTmp = psStatsAlloc(PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_STDEV);
    668         // vectorSampleMean(myVector, errors, tmpMask, maskVal, statsTmp);
     737        // XXX Can we just use this psStats structure to calculate the SAMPLE MEDIAN and STDEV?
     738        // psStats *statsTmp = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV);
     739        // vectorSampleMedian(myVector, errors, tmpMask, maskVal, statsTmp);
    669740        // vectorSampleStdev(myVector, errors, tmpMask, maskVal, statsTmp);
    670         vectorSampleMean(myVector, errors, tmpMask, maskVal, stats);
     741        vectorSampleMedian(myVector, tmpMask, maskVal, stats);
    671742        vectorSampleStdev(myVector, errors, tmpMask, maskVal, stats);
    672         psTrace(TRACE, 6, "The new sample mean is %f\n", stats->sampleMean);
     743        psTrace(TRACE, 6, "The new sample mean is %f\n", stats->sampleMedian);
    673744        psTrace(TRACE, 6, "The new sample stdev is %f\n", stats->sampleStdev);
    674745
    675         // If the new mean and stdev are NAN, we must exit the loop.
     746        // If the new median and stdev are NAN, we must exit the loop.
    676747        // Otherwise, use the new results and continue.
    677         if (isnan(stats->sampleMean) || isnan(stats->sampleStdev)) {
     748        if (isnan(stats->sampleMedian) || isnan(stats->sampleStdev))
     749        {
    678750            iter = stats->clipIter;
    679             COUNT_WARNING(10, 100, "vectorSampleMean() or vectorSampleStdev() returned a NAN.\n");
    680             clippedMean = NAN;
     751            COUNT_WARNING(10, 100, "vectorSampleMedian() or vectorSampleStdev() returned a NAN.\n");
     752            clippedMedian = NAN;
    681753            clippedStdev = NAN;
    682754            return true;
    683         } else {
    684             clippedMean = stats->sampleMean;
     755        }
     756        else
     757        {
     758            clippedMedian = stats->sampleMedian;
    685759            clippedStdev = stats->sampleStdev;
    686760        }
     
    690764    // Number of values used in calculation is the total number of data values, minus those we clipped
    691765    stats->clippedNvalues = myVector->n - numClipped;
    692 
    693     // 7. The last calcuated value of x is the clipped mean.
     766    // calculate the clipped mean
     767    psF32 clippedMean = stats->sampleMean;
     768    vectorSampleMean(myVector, errors, tmpMask, maskVal, stats);
     769    if (isnan(stats->sampleMean))
     770    {
     771        COUNT_WARNING(10, 100, "vectorSampleMean() returned a NAN.\n");
     772        clippedMean = NAN;
     773        return true;
     774    }
     775    else
     776    {
     777        clippedMean = stats->sampleMean;
     778    }
     779
     780    // 7. The last calcuated value of x is the clipped median.
    694781    // 8. The last calcuated value of stdev is the clipped stdev.
    695     // we always return both stats even if only one was requested
     782    // we always return all stats even if only one was requested
    696783    stats->clippedMean = clippedMean;
     784    stats->clippedMedian = clippedMedian;
    697785    stats->clippedStdev = clippedStdev;
    698786
    699787    stats->results |= PS_STAT_CLIPPED_MEAN;
     788    stats->results |= PS_STAT_CLIPPED_MEDIAN;
    700789    stats->results |= PS_STAT_CLIPPED_STDEV;
    701790
    702791    psTrace(TRACE, 6, "The final clipped mean is %f\n", clippedMean);
     792    psTrace(TRACE, 6, "The final clipped median is %f\n", clippedMedian);
    703793    psTrace(TRACE, 6, "The final clipped stdev is %f\n", clippedStdev);
    704794
     
    725815*****************************************************************************/
    726816#define INITIAL_NUM_BINS 1000.0
    727 static bool vectorRobustStats(const psVector* myVector,
    728                               const psVector* errors,
    729                               psVector* maskInput,
     817static bool vectorRobustStats(const psVector *myVector,
     818                              const psVector *errors,
     819                              psVector *maskInput,
    730820                              psVectorMaskType maskValInput,
    731                               psStats* stats)
     821                              psStats *stats)
    732822{
    733     if (psTraceGetLevel("psLib.math") >= 8) {
     823    if (psTraceGetLevel("psLib.math") >= 8)
     824    {
    734825        PS_VECTOR_PRINT_F32(myVector);
    735826    }
     
    741832    psVector *mask = psVectorAlloc(myVector->n, PS_TYPE_VECTOR_MASK); // The actual mask we will use
    742833    psVectorInit(mask, 0);
    743     if (maskInput) {
    744         for (long i = 0; i < myVector->n; i++) {
    745             if (maskInput->data.PS_TYPE_VECTOR_MASK_DATA[i] & maskValInput) {
     834    if (maskInput)
     835    {
     836        for (long i = 0; i < myVector->n; i++)
     837        {
     838            if (maskInput->data.PS_TYPE_VECTOR_MASK_DATA[i] & maskValInput)
     839            {
    746840                mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = maskVal;
    747841            }
     
    751845    // statsMinMax is only applied to a subset of the data points
    752846    psStats *statsMinMax = psStatsAlloc(PS_STAT_MIN | PS_STAT_MAX); // Statistics for min and max
    753     psHistogram *histogram = NULL;      // Histogram of the data
    754     psHistogram *cumulative = NULL;     // Cumulative histogram of the data
    755     float min = NAN, max = NAN;         // Mimimum and maximum values
    756     float sigma = NAN;                  // The robust standard deviation
    757     long totalDataPoints = 0;           // Total number of (unmasked) data points
    758 
    759     float binSize = 0.0;            // Size of bins for histogram
     847    psHistogram *histogram = NULL;                                  // Histogram of the data
     848    psHistogram *cumulative = NULL;                                 // Cumulative histogram of the data
     849    float min = NAN, max = NAN;                                     // Mimimum and maximum values
     850    float sigma = NAN;                                              // The robust standard deviation
     851    long totalDataPoints = 0;                                       // Total number of (unmasked) data points
     852
     853    float binSize = 0.0; // Size of bins for histogram
    760854    long binLo, binHi;
    761855    long binL2, binH2;
     
    764858
    765859    // Iterate to get the best bin size; an iteration limit is enforced at the bottom of the loop.
    766     for (int iterate = 1; iterate > 0; iterate++) {
     860    for (int iterate = 1; iterate > 0; iterate++)
     861    {
    767862        psTrace(TRACE, 6, "-------------------- Iterating on Bin size.  Iteration number %d --------------------\n", iterate);
    768863
    769         if (iterate >= PS_ROBUST_MAX_ITERATIONS) {
    770           // This occurs when a large number of the values are identical --- a bin size cannot be found
    771           // that will spread out the distribution.  Therefore, set what we can, and fall over
    772           // gracefully.
    773           COUNT_WARNING(10, 100, "Maximum number of iterations (%d) exceeded.", PS_ROBUST_MAX_ITERATIONS);
    774           goto escape;
     864        if (iterate >= PS_ROBUST_MAX_ITERATIONS)
     865        {
     866            // This occurs when a large number of the values are identical --- a bin size cannot be found
     867            // that will spread out the distribution.  Therefore, set what we can, and fall over
     868            // gracefully.
     869            COUNT_WARNING(10, 100, "Maximum number of iterations (%d) exceeded.", PS_ROBUST_MAX_ITERATIONS);
     870            goto escape;
    775871        }
    776872
     
    779875        min = statsMinMax->min;
    780876        max = statsMinMax->max;
    781         if (numValid == 0 || isnan(min) || isnan(max)) {
     877        if (numValid == 0 || isnan(min) || isnan(max))
     878        {
    782879            // Data range calculation failed
    783880            COUNT_WARNING(10, 100, "Failed to calculate the min/max of the input vector.\n");
    784881            goto escape;
    785882        }
    786         if (!isfinite(max - min)) {
    787             COUNT_WARNING(10, 100, "Range of of the input vector is too large: %lf.\n", (double)max - (double) min);
     883        if (!isfinite(max - min))
     884        {
     885            COUNT_WARNING(10, 100, "Range of of the input vector is too large: %lf.\n", (double)max - (double)min);
    788886            goto escape;
    789887        }
     
    791889
    792890        // If all data points have the same value, then we set the appropriate members of stats and return.
    793         if (fabs(max - min) <= FLT_EPSILON) {
     891        if (fabs(max - min) <= FLT_EPSILON)
     892        {
    794893            stats->robustMedian = min;
    795894            stats->robustStdev = 0.0;
     
    807906        }
    808907
    809         if ((iterate == 1) && (stats->options & PS_STAT_USE_BINSIZE)) {
     908        if ((iterate == 1) && (stats->options & PS_STAT_USE_BINSIZE))
     909        {
    810910            // Set initial bin size to the specified value.
    811911            binSize = stats->binsize;
    812912            psTrace(TRACE, 6, "Setting initial robust bin size to %.2f\n", binSize);
    813         } else {
     913        }
     914        else
     915        {
    814916            // Determine the bin size of the robust histogram, using the pre-defined number of bins
    815             binSize = (max - min) / INITIAL_NUM_BINS;
     917            binSize = (max - min) / INITIAL_NUM_BINS;
    816918        }
    817919        psTrace(TRACE, 6, "Initial robust bin size is %.2f\n", binSize);
     
    830932        // Assert here so we can get more information about what is going wrong.
    831933        psAssert(numBins > 0, "Invalid numBins: %ld max: %f min: %f binSize: %f", numBins, max, min, binSize);
    832        
     934
    833935        // Generate the histogram
    834         histogram = psHistogramAlloc(min - 2.0*binSize, max + 2.0*binSize, numBins);
     936        histogram = psHistogramAlloc(min - 2.0 * binSize, max + 2.0 * binSize, numBins);
    835937        // XXXXX we need to consider this step if errors -> variance
    836         if (!psVectorHistogram(histogram, myVector, errors, mask, maskVal)) {
     938        if (!psVectorHistogram(histogram, myVector, errors, mask, maskVal))
     939        {
    837940            // if psVectorHistogram returns false, we have a programming error
    838941            psError(PS_ERR_UNKNOWN, false, "Unable to generate histogram for robust statistics.\n");
     
    843946            return false;
    844947        }
    845         if (psTraceGetLevel("psLib.math") >= 8) {
     948        if (psTraceGetLevel("psLib.math") >= 8)
     949        {
    846950            PS_VECTOR_PRINT_F32(histogram->bounds);
    847951            PS_VECTOR_PRINT_F32(histogram->nums);
     
    854958        int nMaxBin = histogram->nums->data.F32[0];
    855959        int iMaxBin = 0;
    856         for (long i = 1; i < histogram->nums->n; i++) {
    857             if (histogram->nums->data.F32[i] > nMaxBin) {
     960        for (long i = 1; i < histogram->nums->n; i++)
     961        {
     962            if (histogram->nums->data.F32[i] > nMaxBin)
     963            {
    858964                nMaxBin = histogram->nums->data.F32[i];
    859965                iMaxBin = i;
    860966            }
    861967        }
    862         if (nMaxBin > numValid / 2) {
    863             float minKeep = histogram->bounds->data.F32[iMaxBin] - 10*binSize;
    864             float maxKeep = histogram->bounds->data.F32[iMaxBin + 1] + 10*binSize;
     968        if (nMaxBin > numValid / 2)
     969        {
     970            float minKeep = histogram->bounds->data.F32[iMaxBin] - 10 * binSize;
     971            float maxKeep = histogram->bounds->data.F32[iMaxBin + 1] + 10 * binSize;
    865972            int nInvalid = 0;
    866             for (long i = 0; i < myVector->n; i++) {
     973            for (long i = 0; i < myVector->n; i++)
     974            {
    867975                // skip the already-masked values
    868                 if (mask->data.PS_TYPE_VECTOR_MASK_DATA[i] & maskVal) continue;
     976                if (mask->data.PS_TYPE_VECTOR_MASK_DATA[i] & maskVal)
     977                    continue;
    869978                bool invalid = false;
    870979                invalid |= (myVector->data.F32[i] < minKeep);
    871980                invalid |= (myVector->data.F32[i] > maxKeep);
    872981                invalid |= (!isfinite(myVector->data.F32[i]));
    873                 if (!invalid) continue;
     982                if (!invalid)
     983                    continue;
    874984                mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = maskVal;
    875                 nInvalid ++;
    876             }
    877 
    878             if (nInvalid) {
    879               psTrace(TRACE, 6, "data is concentrated in a single bin (%d = %f - %f), masking %d extreme outliers and retrying\n",
    880                       iMaxBin, histogram->bounds->data.F32[iMaxBin], histogram->bounds->data.F32[iMaxBin+1], nInvalid);
    881               psFree(histogram);
    882               psFree(cumulative);
    883               histogram = NULL;
    884               cumulative = NULL;
    885               continue;
     985                nInvalid++;
     986            }
     987
     988            if (nInvalid)
     989            {
     990                psTrace(TRACE, 6, "data is concentrated in a single bin (%d = %f - %f), masking %d extreme outliers and retrying\n",
     991                        iMaxBin, histogram->bounds->data.F32[iMaxBin], histogram->bounds->data.F32[iMaxBin + 1], nInvalid);
     992                psFree(histogram);
     993                psFree(cumulative);
     994                histogram = NULL;
     995                cumulative = NULL;
     996                continue;
    886997            }
    887998            // if we did not mask anything, give up.
    888999        }
    8891000
    890         // We were causing psHistogramAlloc to assert. 
     1001        // We were causing psHistogramAlloc to assert.
    8911002        // Assert here so we can get more information about what is going wrong.
    8921003        psAssert(numBins > 0, "Invalid numBins %ld max: %f min: %f binSize: %f", numBins, max, min, binSize);
     
    8981009        cumulative->bounds->data.F32[0] = histogram->bounds->data.F32[1];
    8991010
    900         // Correctly fill the cumulative distribution with monotonically increasing values (skip zero valued bins).
    901         long Nc = 1;  // track the current bin of cumulative
    902         // the boundaries for the current cumulative bin are from upper end of the last valid histogram bin to the
    903         // upper end of the current histogram bin
    904         for (long i = 1; i < histogram->nums->n - 1; i++) {
    905             if (histogram->nums->data.F32[i] == 0.0) continue;
    906             cumulative->nums->data.F32[Nc] = cumulative->nums->data.F32[Nc - 1] + histogram->nums->data.F32[i];
    907             cumulative->bounds->data.F32[Nc] = histogram->bounds->data.F32[i+1];
    908             Nc ++;
    909         }
    910         long Nlast = Nc - 1;  // last valid cumulative bin
    911         for (long i = Nc; i < histogram->nums->n; i++) { // Ensure the unused entries are filled.
    912             cumulative->nums->data.F32[i] = cumulative->nums->data.F32[Nlast];
    913             cumulative->bounds->data.F32[i] = cumulative->bounds->data.F32[i-1] + 1.0;
    914         }
    915        
    916         if (psTraceGetLevel("psLib.math") >= 8) {
     1011        // Correctly fill the cumulative distribution with monotonically increasing values (skip zero valued bins).
     1012        long Nc = 1; // track the current bin of cumulative
     1013        // the boundaries for the current cumulative bin are from upper end of the last valid histogram bin to the
     1014        // upper end of the current histogram bin
     1015        for (long i = 1; i < histogram->nums->n - 1; i++)
     1016        {
     1017            if (histogram->nums->data.F32[i] == 0.0)
     1018                continue;
     1019            cumulative->nums->data.F32[Nc] = cumulative->nums->data.F32[Nc - 1] + histogram->nums->data.F32[i];
     1020            cumulative->bounds->data.F32[Nc] = histogram->bounds->data.F32[i + 1];
     1021            Nc++;
     1022        }
     1023        long Nlast = Nc - 1; // last valid cumulative bin
     1024        for (long i = Nc; i < histogram->nums->n; i++)
     1025        { // Ensure the unused entries are filled.
     1026            cumulative->nums->data.F32[i] = cumulative->nums->data.F32[Nlast];
     1027            cumulative->bounds->data.F32[i] = cumulative->bounds->data.F32[i - 1] + 1.0;
     1028        }
     1029
     1030        if (psTraceGetLevel("psLib.math") >= 8)
     1031        {
    9171032            PS_VECTOR_PRINT_F32(cumulative->bounds);
    9181033            PS_VECTOR_PRINT_F32(cumulative->nums);
     
    9241039
    9251040        // find bin which is the lower bound of median (value[binMedian] < median < value[binMedian+1]
    926         PS_BIN_FOR_VALUE(binMedian, cumulative->nums, totalDataPoints/2.0, 0);
    927 
    928         psTrace(TRACE, 6, "The median bin is %ld (%.2f to %.2f)\n", binMedian, cumulative->bounds->data.F32[binMedian], cumulative->bounds->data.F32[binMedian+1]);
     1041        PS_BIN_FOR_VALUE(binMedian, cumulative->nums, totalDataPoints / 2.0, 0);
     1042
     1043        psTrace(TRACE, 6, "The median bin is %ld (%.2f to %.2f)\n", binMedian, cumulative->bounds->data.F32[binMedian], cumulative->bounds->data.F32[binMedian + 1]);
    9291044
    9301045        // ADD step 3: Interpolate to the exact 50% position in bin units
    9311046        // stats->robustMedian = fitQuadraticSearchForYThenReturnBin(cumulative->bounds, cumulative->nums, binMedian, totalDataPoints/2.0);
    932         // float robustBin = fitQuadraticSearchForYThenReturnXusingValues(cumulative->bounds, cumulative->nums, binMedian, totalDataPoints/2.0);
     1047        // float robustBin = fitQuadraticSearchForYThenReturnXusingValues(cumulative->bounds, cumulative->nums, binMedian, totalDataPoints/2.0);
    9331048        // fprintf (stderr, "robustBin : %f vs %f\n", robustBin, stats->robustMedian);
    934         // There's no reason to do a quadratic fit near the 50% bin, as it's approximately linear there.
    935         // Instead, do a 5-point linear fit.
    936         stats->robustMedian = fitLinearSearchForYThenReturnBin(cumulative->bounds, cumulative->nums, binMedian, totalDataPoints/2.0);
     1049        // There's no reason to do a quadratic fit near the 50% bin, as it's approximately linear there.
     1050        // Instead, do a 5-point linear fit.
     1051        stats->robustMedian = fitLinearSearchForYThenReturnBin(cumulative->bounds, cumulative->nums, binMedian, totalDataPoints / 2.0);
    9371052
    9381053        // convert bin to bin value: this is the robust histogram median.
    939         if (isnan(stats->robustMedian)) {
     1054        if (isnan(stats->robustMedian))
     1055        {
    9401056            COUNT_WARNING(10, 100, "Failed to fit a quadratic and calculate the 50-percent position.\n");
    9411057            goto escape;
     
    9491065        PS_BIN_FOR_VALUE(binL2, cumulative->nums, totalDataPoints * 0.308538f, 0);
    9501066        PS_BIN_FOR_VALUE(binH2, cumulative->nums, totalDataPoints * 0.691462f, 0);
    951         PS_BIN_FOR_VALUE(binL4, cumulative->nums, totalDataPoints * 0.022750f, 0);
    952         PS_BIN_FOR_VALUE(binH4, cumulative->nums, totalDataPoints * 0.977250f, 0);
    953        
    954        
     1067        PS_BIN_FOR_VALUE(binL4, cumulative->nums, totalDataPoints * 0.022750f, 0);
     1068        PS_BIN_FOR_VALUE(binH4, cumulative->nums, totalDataPoints * 0.977250f, 0);
     1069
    9551070        psTrace(TRACE, 6, "The 15.8655%% and 84.1345%% data point bins are (%ld, %ld).\n",
    9561071                binLo, binHi);
     
    9601075        psTrace(TRACE, 6, "binH2 midpoint is %f\n", PS_BIN_MIDPOINT(cumulative, binH2));
    9611076
    962         if ((binLo < 0) || (binHi < 0)) {
     1077        if ((binLo < 0) || (binHi < 0))
     1078        {
    9631079            COUNT_WARNING(10, 100, "Failed to calculate the 15.8655%% and 84.1345%% data points.\n");
    9641080            goto escape;
    9651081        }
    966    
     1082
    9671083        // ADD step 4b: Interpolate Sigma (linearly) to find these two positions exactly: these are the 1sigma
    9681084        // positions.
    9691085        psTrace(TRACE, 6, "binLo is %ld.  Nums at that bin and the next are (%.2f, %.2f)\n",
    970                 binLo, cumulative->nums->data.F32[binLo], cumulative->nums->data.F32[binLo+1]);
     1086                binLo, cumulative->nums->data.F32[binLo], cumulative->nums->data.F32[binLo + 1]);
    9711087        psTrace(TRACE, 6, "binHi is %ld.  Nums at that bin and the next are (%.2f, %.2f)\n",
    972                 binHi, cumulative->nums->data.F32[binHi], cumulative->nums->data.F32[binHi+1]);
     1088                binHi, cumulative->nums->data.F32[binHi], cumulative->nums->data.F32[binHi + 1]);
    9731089
    9741090        // find the +0.5 and -0.5 sigma points with linear interpolation.  binLo and binHi are the bins
     
    9771093        float binLoF32, binHiF32, binL2F32, binH2F32, binL4F32, binH4F32;
    9781094#if (0)
    979         PS_BIN_INTERPOLATE (binLoF32, cumulative->nums, cumulative->bounds, binLo,
    980                             totalDataPoints * 0.158655f);
    981         PS_BIN_INTERPOLATE (binHiF32, cumulative->nums, cumulative->bounds, binHi,
    982                             totalDataPoints * 0.841345f);
    983         PS_BIN_INTERPOLATE (binL2F32, cumulative->nums, cumulative->bounds, binL2,
    984                             totalDataPoints * 0.308538f);
    985         PS_BIN_INTERPOLATE (binH2F32, cumulative->nums, cumulative->bounds, binH2,
    986                             totalDataPoints * 0.691462f);
    987         PS_BIN_INTERPOLATE (binL4F32, cumulative->nums, cumulative->bounds, binL4,
    988                             totalDataPoints * 0.022750f);
    989         PS_BIN_INTERPOLATE (binH4F32, cumulative->nums, cumulative->bounds, binH4,
    990                             totalDataPoints * 0.977250f);
     1095        PS_BIN_INTERPOLATE(binLoF32, cumulative->nums, cumulative->bounds, binLo,
     1096                           totalDataPoints * 0.158655f);
     1097        PS_BIN_INTERPOLATE(binHiF32, cumulative->nums, cumulative->bounds, binHi,
     1098                           totalDataPoints * 0.841345f);
     1099        PS_BIN_INTERPOLATE(binL2F32, cumulative->nums, cumulative->bounds, binL2,
     1100                           totalDataPoints * 0.308538f);
     1101        PS_BIN_INTERPOLATE(binH2F32, cumulative->nums, cumulative->bounds, binH2,
     1102                           totalDataPoints * 0.691462f);
     1103        PS_BIN_INTERPOLATE(binL4F32, cumulative->nums, cumulative->bounds, binL4,
     1104                           totalDataPoints * 0.022750f);
     1105        PS_BIN_INTERPOLATE(binH4F32, cumulative->nums, cumulative->bounds, binH4,
     1106                           totalDataPoints * 0.977250f);
    9911107#else
    9921108        binLoF32 = fitLinearSearchForYThenReturnBin(cumulative->bounds, cumulative->nums, binLo, totalDataPoints * 0.158655);
    993         binHiF32 = fitLinearSearchForYThenReturnBin(cumulative->bounds, cumulative->nums, binHi, totalDataPoints * 0.841345);         
     1109        binHiF32 = fitLinearSearchForYThenReturnBin(cumulative->bounds, cumulative->nums, binHi, totalDataPoints * 0.841345);
    9941110        binL2F32 = fitLinearSearchForYThenReturnBin(cumulative->bounds, cumulative->nums, binL2, totalDataPoints * 0.308538);
    995         binH2F32 = fitLinearSearchForYThenReturnBin(cumulative->bounds, cumulative->nums, binH2, totalDataPoints * 0.691462);         
     1111        binH2F32 = fitLinearSearchForYThenReturnBin(cumulative->bounds, cumulative->nums, binH2, totalDataPoints * 0.691462);
    9961112        binL4F32 = fitLinearSearchForYThenReturnBin(cumulative->bounds, cumulative->nums, binL4, totalDataPoints * 0.022750);
    997         binH4F32 = fitLinearSearchForYThenReturnBin(cumulative->bounds, cumulative->nums, binH4, totalDataPoints * 0.977250);
    998 #endif 
     1113        binH4F32 = fitLinearSearchForYThenReturnBin(cumulative->bounds, cumulative->nums, binH4, totalDataPoints * 0.977250);
     1114#endif
    9991115        // report +/- 1 sigma points
    10001116        psTrace(TRACE, 5,
     
    10081124                binL4F32, binH4F32);
    10091125
    1010         // If some of the fits failed, attempt to fix this
    1011         if (!isfinite(binLoF32) && isfinite(binHiF32)) { binLoF32 = -1.0 * binHiF32; }
    1012         if (!isfinite(binHiF32) && isfinite(binLoF32)) { binHiF32 = -1.0 * binLoF32; }
    1013         if (!isfinite(binL2F32) && isfinite(binH2F32)) { binL2F32 = -1.0 * binH2F32; }
    1014         if (!isfinite(binH2F32) && isfinite(binL2F32)) { binH2F32 = -1.0 * binL2F32; }
    1015         if (!isfinite(binL4F32) && isfinite(binH4F32)) { binL4F32 = -1.0 * binH4F32; }
    1016         if (!isfinite(binH4F32) && isfinite(binL4F32)) { binH4F32 = -1.0 * binL4F32; }
    1017        
     1126        // If some of the fits failed, attempt to fix this
     1127        if (!isfinite(binLoF32) && isfinite(binHiF32))
     1128        {
     1129            binLoF32 = -1.0 * binHiF32;
     1130        }
     1131        if (!isfinite(binHiF32) && isfinite(binLoF32))
     1132        {
     1133            binHiF32 = -1.0 * binLoF32;
     1134        }
     1135        if (!isfinite(binL2F32) && isfinite(binH2F32))
     1136        {
     1137            binL2F32 = -1.0 * binH2F32;
     1138        }
     1139        if (!isfinite(binH2F32) && isfinite(binL2F32))
     1140        {
     1141            binH2F32 = -1.0 * binL2F32;
     1142        }
     1143        if (!isfinite(binL4F32) && isfinite(binH4F32))
     1144        {
     1145            binL4F32 = -1.0 * binH4F32;
     1146        }
     1147        if (!isfinite(binH4F32) && isfinite(binL4F32))
     1148        {
     1149            binH4F32 = -1.0 * binL4F32;
     1150        }
     1151
    10181152        // ADD step 5: Determine SIGMA as the distance between binL2 and binH2 (+/- 0.5 sigma)
    1019 
    10201153
    10211154        float sigma1 = (binH2F32 - binL2F32);
     
    10231156        float sigma4 = (binH4F32 - binL4F32) / 4.0;
    10241157
    1025         // Fix again?
    1026         if (!isfinite(sigma1) && isfinite(sigma2) && isfinite(sigma4)) { sigma1 = (sigma2 + sigma4) / 2.0; }
    1027         if (!isfinite(sigma2) && isfinite(sigma1) && isfinite(sigma4)) { sigma2 = (sigma1 + sigma4) / 2.0; }
    1028         if (!isfinite(sigma4) && isfinite(sigma2) && isfinite(sigma1)) { sigma4 = (sigma2 + sigma1) / 2.0; }
    1029        
     1158        // Fix again?
     1159        if (!isfinite(sigma1) && isfinite(sigma2) && isfinite(sigma4))
     1160        {
     1161            sigma1 = (sigma2 + sigma4) / 2.0;
     1162        }
     1163        if (!isfinite(sigma2) && isfinite(sigma1) && isfinite(sigma4))
     1164        {
     1165            sigma2 = (sigma1 + sigma4) / 2.0;
     1166        }
     1167        if (!isfinite(sigma4) && isfinite(sigma2) && isfinite(sigma1))
     1168        {
     1169            sigma4 = (sigma2 + sigma1) / 2.0;
     1170        }
     1171
    10301172        // take the smallest of the three: if we have a clump with wide outliers, sigma2 and
    10311173        // sigma4 will be biased high; if we have a bi-modal distribution, sigma1 and sigma2
    10321174        // will be biased high.
    1033         //        sigma = PS_MIN (sigma1, PS_MIN (sigma2, sigma4));
    1034         // CZW: Instead, take the median.  Taking the MIN forces a bias on unbiased data.
    1035         //      It seems like occasionally getting the wrong answer on a complex distribution
    1036         //      is more acceptable than always getting the wrong answer for simple ones.
    1037 
    1038        
    1039         sigma = PS_MAX( PS_MIN(sigma1,sigma2),
    1040                         PS_MIN( PS_MAX(sigma1,sigma2),
    1041                                 sigma4));
     1175        //        sigma = PS_MIN (sigma1, PS_MIN (sigma2, sigma4));
     1176        // CZW: Instead, take the median.  Taking the MIN forces a bias on unbiased data.
     1177        //      It seems like occasionally getting the wrong answer on a complex distribution
     1178        //      is more acceptable than always getting the wrong answer for simple ones.
     1179
     1180        sigma = PS_MAX(PS_MIN(sigma1, sigma2),
     1181                       PS_MIN(PS_MAX(sigma1, sigma2),
     1182                              sigma4));
    10421183
    10431184        psTrace(TRACE, 6, "The 1x sigma is %f.\n", sigma1);
     
    10461187
    10471188        psTrace(TRACE, 6, "The current sigma is %f.\n", sigma);
    1048         //        stats->robustStdev = sigma;
    1049         stats->robustStdev = sigma;
    1050 
    1051 #if (CZW && 0) 
    1052         // Skewness check: Find least biased sample for each pair.
    1053         sigma1 = 2.0 * PS_MIN(binH2F32 - stats->robustMedian,
    1054                               stats->robustMedian - binL2F32);
    1055         sigma2 = 1.0 * PS_MIN(binHiF32 - stats->robustMedian,
    1056                               stats->robustMedian - binLoF32);
    1057         sigma4 = 0.5 * PS_MIN(binH4F32 - stats->robustMedian,
    1058                               stats->robustMedian - binL4F32);
    1059         // Kurtosis check: Take median sample as the solution.
    1060         stats->robustStdev = PS_MAX( PS_MIN(sigma1,sigma2),
    1061                                      PS_MIN( PS_MAX(sigma1,sigma2),
    1062                                              sigma4));
     1189        //        stats->robustStdev = sigma;
     1190        stats->robustStdev = sigma;
     1191
     1192#if (CZW && 0)
     1193        // Skewness check: Find least biased sample for each pair.
     1194        sigma1 = 2.0 * PS_MIN(binH2F32 - stats->robustMedian,
     1195                              stats->robustMedian - binL2F32);
     1196        sigma2 = 1.0 * PS_MIN(binHiF32 - stats->robustMedian,
     1197                              stats->robustMedian - binLoF32);
     1198        sigma4 = 0.5 * PS_MIN(binH4F32 - stats->robustMedian,
     1199                              stats->robustMedian - binL4F32);
     1200        // Kurtosis check: Take median sample as the solution.
     1201        stats->robustStdev = PS_MAX(PS_MIN(sigma1, sigma2),
     1202                                    PS_MIN(PS_MAX(sigma1, sigma2),
     1203                                           sigma4));
    10631204#endif
    10641205
    1065        
    10661206#if (CZW)
    1067         //      printf("CZW: bad sigma?: %f %f  %f %f  %f %f  %f %f %f  %f\n",
    1068         //             binH2F32,binL2F32,binHiF32,binLoF32,binH4F32,binL4F32,
    1069         //             sigma1,sigma2,sigma4,sigma);
    1070        
    1071         printf("CZW Robust (%d): median %f sigma %f delta: %f \n\t %f %f %f %f %f %f %f \n\t %f %f %f %f %f %f %f\n",
    1072                iterate,
    1073                stats->robustMedian,stats->robustStdev,
    1074                fabs(cumulative->bounds->data.F32[binMedian] - cumulative->bounds->data.F32[binMedian + 1]),
    1075                
    1076                cumulative->bounds->data.F32[binMedian-3],cumulative->bounds->data.F32[binMedian-2],
    1077                cumulative->bounds->data.F32[binMedian-1],
    1078                cumulative->bounds->data.F32[binMedian],
    1079                cumulative->bounds->data.F32[binMedian+1],
    1080                cumulative->bounds->data.F32[binMedian+2],cumulative->bounds->data.F32[binMedian+3],
    1081                
    1082                cumulative->nums->data.F32[binMedian-3],cumulative->nums->data.F32[binMedian-2],
    1083                cumulative->nums->data.F32[binMedian-1],
    1084                cumulative->nums->data.F32[binMedian],
    1085                cumulative->nums->data.F32[binMedian+1],
    1086                cumulative->nums->data.F32[binMedian+2],cumulative->nums->data.F32[binMedian+3]);
    1087         //      PS_VECTOR_PRINT_F32(histogram->bounds);
    1088         //      PS_VECTOR_PRINT_F32(histogram->nums);
    1089         //      PS_VECTOR_PRINT_F32(cumulative->bounds);
    1090         //      PS_VECTOR_PRINT_F32(cumulative->nums);
     1207        //      printf("CZW: bad sigma?: %f %f  %f %f  %f %f  %f %f %f  %f\n",
     1208        //             binH2F32,binL2F32,binHiF32,binLoF32,binH4F32,binL4F32,
     1209        //             sigma1,sigma2,sigma4,sigma);
     1210
     1211        printf("CZW Robust (%d): median %f sigma %f delta: %f \n\t %f %f %f %f %f %f %f \n\t %f %f %f %f %f %f %f\n",
     1212               iterate,
     1213               stats->robustMedian, stats->robustStdev,
     1214               fabs(cumulative->bounds->data.F32[binMedian] - cumulative->bounds->data.F32[binMedian + 1]),
     1215
     1216               cumulative->bounds->data.F32[binMedian - 3], cumulative->bounds->data.F32[binMedian - 2],
     1217               cumulative->bounds->data.F32[binMedian - 1],
     1218               cumulative->bounds->data.F32[binMedian],
     1219               cumulative->bounds->data.F32[binMedian + 1],
     1220               cumulative->bounds->data.F32[binMedian + 2], cumulative->bounds->data.F32[binMedian + 3],
     1221
     1222               cumulative->nums->data.F32[binMedian - 3], cumulative->nums->data.F32[binMedian - 2],
     1223               cumulative->nums->data.F32[binMedian - 1],
     1224               cumulative->nums->data.F32[binMedian],
     1225               cumulative->nums->data.F32[binMedian + 1],
     1226               cumulative->nums->data.F32[binMedian + 2], cumulative->nums->data.F32[binMedian + 3]);
     1227        //      PS_VECTOR_PRINT_F32(histogram->bounds);
     1228        //      PS_VECTOR_PRINT_F32(histogram->nums);
     1229        //      PS_VECTOR_PRINT_F32(cumulative->bounds);
     1230        //      PS_VECTOR_PRINT_F32(cumulative->nums);
    10911231#endif
    10921232
    10931233        // ADD step 6: If the measured SIGMA is less than 2 times the bin size, exclude points which are more
    10941234        // than 25 bins from the median, recalculate the bin size, and perform the algorithm again.
    1095         if (sigma < (3.0 * binSize)) {
     1235        if (sigma < (3.0 * binSize))
     1236        {
    10961237            psTrace(TRACE, 6, "*************: Do another iteration (%f %f).\n", sigma, binSize);
    10971238
    1098             // these limits are supposed to be 25 x the raw bin size, NOT 25 of the cumulative histogram bins
    1099             psF32 medianLo = stats->robustMedian - 25*binSize;
    1100             psF32 medianHi = stats->robustMedian + 25*binSize;
     1239            // these limits are supposed to be 25 x the raw bin size, NOT 25 of the cumulative histogram bins
     1240            psF32 medianLo = stats->robustMedian - 25 * binSize;
     1241            psF32 medianHi = stats->robustMedian + 25 * binSize;
    11011242
    11021243            // long maskLo = PS_MAX(0, (binMedian - 25)); // Low index for masking region
     
    11071248            // psTrace(TRACE, 6, "The median is at bin number %ld.  We mask bins outside the bin range (%ld:%ld)\n", binMedian, maskLo, maskHi);
    11081249            psTrace(TRACE, 6, "Masking data outside (%f %f)\n", medianLo, medianHi);
    1109             int Nmasked = 0;
    1110             for (long i = 0 ; i < myVector->n ; i++) {
    1111                 if ((myVector->data.F32[i] < medianLo) || (myVector->data.F32[i] > medianHi)) {
    1112                     if (mask->data.PS_TYPE_VECTOR_MASK_DATA[i] & MASK_MARK) continue;
     1250            int Nmasked = 0;
     1251            for (long i = 0; i < myVector->n; i++)
     1252            {
     1253                if ((myVector->data.F32[i] < medianLo) || (myVector->data.F32[i] > medianHi))
     1254                {
     1255                    if (mask->data.PS_TYPE_VECTOR_MASK_DATA[i] & MASK_MARK)
     1256                        continue;
    11131257                    mask->data.PS_TYPE_VECTOR_MASK_DATA[i] |= MASK_MARK;
    11141258                    psTrace(TRACE, 6, "Masking element %ld is %f\n", i, myVector->data.F32[i]);
    1115                     Nmasked ++;
     1259                    Nmasked++;
    11161260                }
    11171261            }
    11181262
    1119             if (Nmasked == 0) {
    1120                 // no significant change to the sigma & binsize -- we are done here
    1121                 iterate = -1;
    1122                 continue;
    1123             }
     1263            if (Nmasked == 0)
     1264            {
     1265                // no significant change to the sigma & binsize -- we are done here
     1266                iterate = -1;
     1267                continue;
     1268            }
    11241269
    11251270            // Free the histograms; they will be recreated on the next iteration, with new bounds
     
    11301275            cumulative = NULL;
    11311276
    1132             if (iterate >= PS_ROBUST_MAX_ITERATIONS) {
     1277            if (iterate >= PS_ROBUST_MAX_ITERATIONS)
     1278            {
    11331279                // This occurs when a large number of the values are identical --- a bin size cannot be found
    11341280                // that will spread out the distribution.  Therefore, set what we can, and fall over
     
    11471293                return true;
    11481294            }
    1149         } else {
     1295        }
     1296        else
     1297        {
    11501298            // We've got the bin size correct now
    11511299            psTrace(TRACE, 6, "*************: No more iteration.  sigma is %f\n", sigma);
     
    11531301        }
    11541302    }
    1155    
     1303
    11561304    // XXX test lines while studying algorithm errors
    11571305    // fprintf (stderr, "robust stats test %7.1f +/- %7.1f : %4ld %4ld %4ld %4ld %4ld  : %f %f %f\n",
     
    11611309    // ADD step 7: Find the bins which contains the 25% and 75% data points.
    11621310    long binLo25, binHi25;
    1163     PS_BIN_FOR_VALUE (binLo25, cumulative->nums, totalDataPoints * 0.25f, 0);
    1164     PS_BIN_FOR_VALUE (binHi25, cumulative->nums, totalDataPoints * 0.75f, 0);
     1311    PS_BIN_FOR_VALUE(binLo25, cumulative->nums, totalDataPoints * 0.25f, 0);
     1312    PS_BIN_FOR_VALUE(binHi25, cumulative->nums, totalDataPoints * 0.75f, 0);
    11651313    psTrace(TRACE, 6, "The 25-percent and 75-percent data point bins are (%ld, %ld).\n", binLo25, binHi25);
    11661314
     
    11691317    psF32 binLo25F32 = fitLinearSearchForYThenReturnBin(cumulative->bounds, cumulative->nums, binLo25, totalDataPoints * 0.25f);
    11701318    psF32 binHi25F32 = fitLinearSearchForYThenReturnBin(cumulative->bounds, cumulative->nums, binHi25, totalDataPoints * 0.75f);
    1171     if (isnan(binLo25F32) || isnan(binHi25F32)) {
     1319    if (isnan(binLo25F32) || isnan(binHi25F32))
     1320    {
    11721321        COUNT_WARNING(10, 100, "could not determine the robustUQ or LQ: fitLinearSearchForYThenReturnBin() returned a NAN.\n");
    11731322        goto escape;
     
    11791328            binLo25F32, binHi25F32);
    11801329    long N50 = 0;
    1181     for (long i = 0 ; i < myVector->n ; i++) {
     1330    for (long i = 0; i < myVector->n; i++)
     1331    {
    11821332        if (!mask->data.PS_TYPE_VECTOR_MASK_DATA[i] &&
    1183             (binLo25F32 <= myVector->data.F32[i]) && (binHi25F32 >= myVector->data.F32[i])) {
     1333            (binLo25F32 <= myVector->data.F32[i]) && (binHi25F32 >= myVector->data.F32[i]))
     1334        {
    11841335            N50++;
    11851336        }
     
    12261377 * version follows the upper portion of the distribution until it passes 0.5*peak
    12271378 ********************/
    1228 static bool vectorFittedStats (const psVector* myVector,
    1229                                   const psVector* errors,
    1230                                   psVector* mask,
    1231                                   psVectorMaskType maskVal,
    1232                                   psStats* stats)
     1379static bool vectorFittedStats(const psVector *myVector,
     1380                              const psVector *errors,
     1381                              psVector *mask,
     1382                              psVectorMaskType maskVal,
     1383                              psStats *stats)
    12331384{
    12341385
    12351386    // This procedure requires the mean.  If it has not been already
    12361387    // calculated, then call vectorSampleMean()
    1237     if (!(stats->results & PS_STAT_ROBUST_MEDIAN)) {
    1238         if (!vectorRobustStats(myVector, errors, mask, maskVal, stats)) {
     1388    if (!(stats->results & PS_STAT_ROBUST_MEDIAN))
     1389    {
     1390        if (!vectorRobustStats(myVector, errors, mask, maskVal, stats))
     1391        {
    12391392            psError(PS_ERR_UNKNOWN, false, "failure to measure robust stats\n");
    12401393            return false;
     
    12431396
    12441397    // If the mean is NAN, then generate a warning and set the stdev to NAN.
    1245     if (isnan(stats->robustMedian)) {
    1246         stats->fittedMean = NAN;
    1247         stats->fittedStdev = NAN;
    1248         stats->results |= PS_STAT_FITTED_MEAN;
    1249         stats->results |= PS_STAT_FITTED_STDEV;
     1398    if (isnan(stats->robustMedian))
     1399    {
     1400        stats->fittedMean = NAN;
     1401        stats->fittedStdev = NAN;
     1402        stats->results |= PS_STAT_FITTED_MEAN;
     1403        stats->results |= PS_STAT_FITTED_STDEV;
    12501404        return true;
    12511405    }
    12521406
    1253     if (stats->robustStdev <= FLT_EPSILON) {
    1254         stats->fittedMean = stats->robustMedian;
    1255         stats->fittedStdev = stats->robustStdev;
    1256         stats->results |= PS_STAT_FITTED_MEAN;
    1257         stats->results |= PS_STAT_FITTED_STDEV;
     1407    if (stats->robustStdev <= FLT_EPSILON)
     1408    {
     1409        stats->fittedMean = stats->robustMedian;
     1410        stats->fittedStdev = stats->robustStdev;
     1411        stats->results |= PS_STAT_FITTED_MEAN;
     1412        stats->results |= PS_STAT_FITTED_STDEV;
    12581413        return true;
    12591414    }
    1260     if (myVector->n < 1) { printf("There are no elements in this vector.\n"); abort(); }
    1261     float guessStdev = stats->robustStdev;  // pass the guess sigma
    1262     float guessMean = stats->robustMedian;  // pass the guess mean
     1415    if (myVector->n < 1)
     1416    {
     1417        printf("There are no elements in this vector.\n");
     1418        abort();
     1419    }
     1420    float guessStdev = stats->robustStdev; // pass the guess sigma
     1421    float guessMean = stats->robustMedian; // pass the guess mean
    12631422
    12641423    psTrace(TRACE, 6, "The ** starting ** guess mean  is %f.\n", guessMean);
     
    12661425
    12671426    bool done = false;
    1268     for (int iteration = 0; !done && (iteration < 2); iteration ++) {
     1427    for (int iteration = 0; !done && (iteration < 2); iteration++)
     1428    {
    12691429        psStats *statsMinMax = psStatsAlloc(PS_STAT_MIN | PS_STAT_MAX); // Statistics for min and max
    12701430
    12711431        psF32 binSize = 1;
    1272         if (stats->options & PS_STAT_USE_BINSIZE) {
     1432        if (stats->options & PS_STAT_USE_BINSIZE)
     1433        {
    12731434            // Set initial bin size to the specified value.
    12741435            binSize = stats->binsize;
    12751436            psTrace(TRACE, 6, "Setting initial robust bin size to %.2f\n", binSize);
    1276         } else {
     1437        }
     1438        else
     1439        {
    12771440            // construct a histogram with (sigma/2 < binsize < sigma)
    12781441            // set roughly so that the lowest bins have about 2 cnts
    12791442            // Nsmallest ~ N50 / (4*dN))
    1280           //            psF32 dN = PS_MAX (1, PS_MIN (4, stats->robustN50 / 8));
    1281 
    1282           // CZW 2013-11-20: We know that the histogram is going to be basically Gaussian.
    1283           // Furthermore, we only use the inner +/- 2 sigma parts.  Therefore, define the
    1284           // binsize such that the bin at 2 sigma contains ~50 points (S/N ~ 7).  robustN50
    1285           // contains half the total points, so 2 * robustN50 / 50 is the fraction of all
    1286           // points in the 2 sigma bin.  Dance the erf() relations around, and it looks like
    1287           // there's a factor of about 1/20 to include.  Keep the PS_MAX to ensure we never bin
    1288           // wider than 1 sigma when the number of points is small.
    1289           psF32 dN = PS_MAX(1, (stats->robustN50 / 500.0));
    1290           binSize = guessStdev / dN;
     1443            //            psF32 dN = PS_MAX (1, PS_MIN (4, stats->robustN50 / 8));
     1444
     1445            // CZW 2013-11-20: We know that the histogram is going to be basically Gaussian.
     1446            // Furthermore, we only use the inner +/- 2 sigma parts.  Therefore, define the
     1447            // binsize such that the bin at 2 sigma contains ~50 points (S/N ~ 7).  robustN50
     1448            // contains half the total points, so 2 * robustN50 / 50 is the fraction of all
     1449            // points in the 2 sigma bin.  Dance the erf() relations around, and it looks like
     1450            // there's a factor of about 1/20 to include.  Keep the PS_MAX to ensure we never bin
     1451            // wider than 1 sigma when the number of points is small.
     1452            psF32 dN = PS_MAX(1, (stats->robustN50 / 500.0));
     1453            binSize = guessStdev / dN;
    12911454        }
    12921455
     
    12951458        float min = statsMinMax->min;
    12961459        float max = statsMinMax->max;
    1297         if (numValid == 0 || isnan(min) || isnan(max)) {
     1460        if (numValid == 0 || isnan(min) || isnan(max))
     1461        {
    12981462            COUNT_WARNING(10, 100, "Failed to calculate the min/max of the input vector.\n");
    12991463            psFree(statsMinMax);
     
    13021466
    13031467        // If all data points have the same value, then we set the appropriate members of stats and return.
    1304         if (fabs(max - min) <= FLT_EPSILON) {
     1468        if (fabs(max - min) <= FLT_EPSILON)
     1469        {
    13051470            COUNT_WARNING(10, 100, "All data points have the same value: %f.\n", min);
    13061471            stats->fittedMean = min;
     
    13141479        // XXX can we calculate the binMin, binMax **before** building this histogram?
    13151480        // if the range is too absurd, adjust numBins & binSize
    1316         // We no longer want to reset the binSize here, as it can cause odd things.  Better to select
    1317         // a number of bins, and then set the min/max values to put those bins sanely around the mean.
    1318         //        long numBins = PS_MAX (50, PS_MIN (10000, (max - min) / binSize));
    1319         //        binSize = (max - min) / (float) numBins;
     1481        // We no longer want to reset the binSize here, as it can cause odd things.  Better to select
     1482        // a number of bins, and then set the min/max values to put those bins sanely around the mean.
     1483        //        long numBins = PS_MAX (50, PS_MIN (10000, (max - min) / binSize));
     1484        //        binSize = (max - min) / (float) numBins;
    13201485        psTrace(TRACE, 6, "The new min/max values are (%f, %f).\n", min, max);
    13211486        psTrace(TRACE, 6, "The new bin size is %f.\n", binSize);
    1322         //        psTrace(TRACE, 6, "The numBins is %ld\n", numBins);
    1323 
     1487        //        psTrace(TRACE, 6, "The numBins is %ld\n", numBins);
    13241488
    13251489#define FITTED_CLIPPING_NUM 5.0
    1326         if (min < guessMean - FITTED_CLIPPING_NUM * guessStdev) {
    1327           min = guessMean - FITTED_CLIPPING_NUM * guessStdev;
    1328         }
    1329         if (max > guessMean + FITTED_CLIPPING_NUM * guessStdev) {
    1330           max = guessMean + FITTED_CLIPPING_NUM * guessStdev;
    1331         }
    1332         long numBins = PS_MAX (50, PS_MIN (10000, (max - min) / binSize));
    1333         if (CZW) { printf("I've clipped: %f %f => %f %f ; %f %ld\n",guessMean,guessStdev,min,max,binSize,stats->robustN50); }
     1490        if (min < guessMean - FITTED_CLIPPING_NUM * guessStdev)
     1491        {
     1492            min = guessMean - FITTED_CLIPPING_NUM * guessStdev;
     1493        }
     1494        if (max > guessMean + FITTED_CLIPPING_NUM * guessStdev)
     1495        {
     1496            max = guessMean + FITTED_CLIPPING_NUM * guessStdev;
     1497        }
     1498        long numBins = PS_MAX(50, PS_MIN(10000, (max - min) / binSize));
     1499        if (CZW)
     1500        {
     1501            printf("I've clipped: %f %f => %f %f ; %f %ld\n", guessMean, guessStdev, min, max, binSize, stats->robustN50);
     1502        }
    13341503        psHistogram *histogram = psHistogramAlloc(min, max, numBins); // A new histogram (without outliers)
    1335         if (!psVectorHistogram(histogram, myVector, errors, mask, maskVal)) {
     1504        if (!psVectorHistogram(histogram, myVector, errors, mask, maskVal))
     1505        {
    13361506            COUNT_WARNING(10, 100, "Unable to generate histogram for fitted statistics v4.\n");
    13371507            psFree(histogram);
     
    13391509            goto escape;
    13401510        }
    1341         if (psTraceGetLevel("psLib.math") >= 8) {
     1511        if (psTraceGetLevel("psLib.math") >= 8)
     1512        {
    13421513            PS_VECTOR_PRINT_F32(histogram->nums);
    13431514        }
     
    13471518        // set the full-range upper and lower limits
    13481519        psF32 maxFitSigma = 2.0;
    1349         if (isfinite(stats->clipSigma)) {
     1520        if (isfinite(stats->clipSigma))
     1521        {
    13501522            maxFitSigma = fabs(stats->clipSigma);
    13511523        }
    1352         if (isfinite(stats->max)) {
     1524        if (isfinite(stats->max))
     1525        {
    13531526            maxFitSigma = fabs(stats->max);
    13541527        }
    13551528
    13561529        psF32 minFitSigma = 2.0;
    1357         if (isfinite(stats->clipSigma)) {
     1530        if (isfinite(stats->clipSigma))
     1531        {
    13581532            minFitSigma = fabs(stats->clipSigma);
    13591533        }
    1360         if (isfinite(stats->min)) {
     1534        if (isfinite(stats->min))
     1535        {
    13611536            minFitSigma = fabs(stats->min);
    13621537        }
     
    13641539        // select the min and max bins, saturating on the lower and upper end-points
    13651540        long binMin, binMax;
    1366         PS_BIN_FOR_VALUE (binMin, histogram->bounds, guessMean - minFitSigma*guessStdev, 0);
    1367         PS_BIN_FOR_VALUE (binMax, histogram->bounds, guessMean + maxFitSigma*guessStdev, 0);
    1368 
    1369         if (binMin == binMax) {
     1541        PS_BIN_FOR_VALUE(binMin, histogram->bounds, guessMean - minFitSigma * guessStdev, 0);
     1542        PS_BIN_FOR_VALUE(binMax, histogram->bounds, guessMean + maxFitSigma * guessStdev, 0);
     1543
     1544        if (binMin == binMax)
     1545        {
    13701546            COUNT_WARNING(10, 100, "Failed to calculate the min/max of the input vector.\n");
    13711547            psFree(statsMinMax);
     
    13751551
    13761552        // search for mode (peak of histogram within range mean-2sigma - mean+2sigma
    1377         long  binPeak = binMin;
     1553        long binPeak = binMin;
    13781554        float valPeak = histogram->nums->data.F32[binPeak];
    1379         for (int i = binMin; i < binMax; i++) {
    1380             if (histogram->nums->data.F32[i] > valPeak) {
     1555        for (int i = binMin; i < binMax; i++)
     1556        {
     1557            if (histogram->nums->data.F32[i] > valPeak)
     1558            {
    13811559                binPeak = i;
    13821560                valPeak = histogram->nums->data.F32[binPeak];
    13831561            }
    1384             psTrace (TRACE, 6, "(%f = %.0f) ", histogram->bounds->data.F32[i], histogram->nums->data.F32[i]);
    1385             if (CZW) { printf("CENTERED_HISTOGRAM: %f %f\n",
    1386                               PS_BIN_MIDPOINT(histogram,i),
    1387                               histogram->nums->data.F32[i]); }
    1388         }
    1389         psTrace (TRACE, 6, "\n");
    1390 
    1391         if (CZW) { printf("Bin selection done: %ld %f %f %ld %f %f %ld %f %f\n",
    1392                           binMin,PS_BIN_MIDPOINT(histogram,binMin),histogram->nums->data.F32[binMin],
    1393                           binMax,PS_BIN_MIDPOINT(histogram,binMax),histogram->nums->data.F32[binMax],
    1394                           binPeak,PS_BIN_MIDPOINT(histogram,binPeak),histogram->nums->data.F32[binPeak]);
    1395         }
    1396        
     1562            psTrace(TRACE, 6, "(%f = %.0f) ", histogram->bounds->data.F32[i], histogram->nums->data.F32[i]);
     1563            if (CZW)
     1564            {
     1565                printf("CENTERED_HISTOGRAM: %f %f\n",
     1566                       PS_BIN_MIDPOINT(histogram, i),
     1567                       histogram->nums->data.F32[i]);
     1568            }
     1569        }
     1570        psTrace(TRACE, 6, "\n");
     1571
     1572        if (CZW)
     1573        {
     1574            printf("Bin selection done: %ld %f %f %ld %f %f %ld %f %f\n",
     1575                   binMin, PS_BIN_MIDPOINT(histogram, binMin), histogram->nums->data.F32[binMin],
     1576                   binMax, PS_BIN_MIDPOINT(histogram, binMax), histogram->nums->data.F32[binMax],
     1577                   binPeak, PS_BIN_MIDPOINT(histogram, binPeak), histogram->nums->data.F32[binPeak]);
     1578        }
     1579
    13971580        // assume a reasonably well-defined gaussian-like population; run from peak out until val < 0.25*peak
    13981581        psTrace(TRACE, 6, "The clipped numBins is %ld\n", binMax - binMin);
     
    14021585        psTrace(TRACE, 6, "The clipped peak value is %f\n", histogram->nums->data.F32[binPeak]);
    14031586
    1404        
    1405         float lowfitMean = NAN;
    1406         float lowfitStdev = NAN;
     1587        float lowfitMean = NAN;
     1588        float lowfitStdev = NAN;
    14071589        {
    14081590            // fit the lower half of the distribution
     
    14101592            // run up until we drop below 0.50*valPeak
    14111593            long binS = binMin;
    1412             long binE = PS_MIN (binPeak + 3, binMax);
    1413             for (int i = binPeak - 3; i >= binMin; i--) {
    1414                 if (histogram->nums->data.F32[i] < 0.25*valPeak) {
     1594            long binE = PS_MIN(binPeak + 3, binMax);
     1595            for (int i = binPeak - 3; i >= binMin; i--)
     1596            {
     1597                if (histogram->nums->data.F32[i] < 0.25 * valPeak)
     1598                {
    14151599                    binS = i;
    14161600                    break;
    14171601                }
    14181602            }
    1419             for (int i = binPeak + 3; i < binMax; i++) {
    1420                 if (histogram->nums->data.F32[i] < 0.50*valPeak) {
     1603            for (int i = binPeak + 3; i < binMax; i++)
     1604            {
     1605                if (histogram->nums->data.F32[i] < 0.50 * valPeak)
     1606                {
    14211607                    binE = i;
    14221608                    break;
     
    14311617            psVector *x = psVectorAllocEmpty(binE - binS, PS_TYPE_F32); // Vector of ordinates
    14321618            long j = 0;
    1433             for (long i = binS; i < binE; i++) {
     1619            for (long i = binS; i < binE; i++)
     1620            {
    14341621                if (histogram->nums->data.F32[i] <= 0.0)
    14351622                    continue;
     
    14401627            }
    14411628            y->n = x->n = j;
    1442            
     1629
    14431630            // fit 2nd order polynomial to ln(y) = -(x-xo)^2/2sigma^2
    14441631            // XXX this fit may fail with an error for an ill-conditioned matrix (bad data)
    14451632            // we probably should be able to handle the data errors gracefully
    14461633            psPolynomial1D *poly = psPolynomial1DAlloc(PS_POLYNOMIAL_ORD, 2);
    1447             bool status = psVectorFitPolynomial1D (poly, NULL, 0, y, NULL, x);
     1634            bool status = psVectorFitPolynomial1D(poly, NULL, 0, y, NULL, x);
    14481635#if (CZW && 1)
    1449             printf("CZW: LowfitPoly: %f %f %f\n",poly->coeff[0],poly->coeff[1],poly->coeff[2]);
    1450             for (long i = 0; i < x->n; i++) {
    1451               printf("CZW: Lowfit: %d %ld %f %f %f\n",
    1452                      status,i,x->data.F32[i],y->data.F32[i],
    1453                      poly->coeff[0] + poly->coeff[1] * x->data.F32[i] +
    1454                      poly->coeff[2] * pow(x->data.F32[i],2));
    1455             }
     1636            printf("CZW: LowfitPoly: %f %f %f\n", poly->coeff[0], poly->coeff[1], poly->coeff[2]);
     1637            for (long i = 0; i < x->n; i++)
     1638            {
     1639                printf("CZW: Lowfit: %d %ld %f %f %f\n",
     1640                       status, i, x->data.F32[i], y->data.F32[i],
     1641                       poly->coeff[0] + poly->coeff[1] * x->data.F32[i] +
     1642                           poly->coeff[2] * pow(x->data.F32[i], 2));
     1643            }
    14561644#endif
    14571645            psFree(x);
    14581646            psFree(y);
    14591647
    1460             if (!status) {
     1648            if (!status)
     1649            {
    14611650                psErrorClear();
    14621651                COUNT_WARNING(10, 100, "Failed to fit a gaussian to the robust histogram.\n");
     
    14671656            }
    14681657
    1469             if (poly->coeff[2] >= 0.0) {
     1658            if (poly->coeff[2] >= 0.0)
     1659            {
    14701660                COUNT_WARNING(10, 100, "Failed parabolic fit: %f + %f x + %f x^2\n", poly->coeff[0], poly->coeff[1], poly->coeff[2]);
    14711661
     
    14771667                // tends to be found in a single bin.  make one attempt to recover by dropping the guessStdev
    14781668                // down by a jump and trying again
    1479                 if (iteration == 0) {
    1480                     guessStdev = 0.25*guessStdev;
     1669                if (iteration == 0)
     1670                {
     1671                    guessStdev = 0.25 * guessStdev;
    14811672                    psTrace(TRACE, 6, "*** retry, new stdev is %f.\n", guessStdev);
    14821673                    continue;
     
    14881679
    14891680            // calculate lower mean & stdev from parabolic fit -- use this as the result
    1490             lowfitStdev = sqrt(-0.5/poly->coeff[2]);
    1491             lowfitMean  = poly->coeff[1]*PS_SQR(lowfitStdev);
     1681            lowfitStdev = sqrt(-0.5 / poly->coeff[2]);
     1682            lowfitMean = poly->coeff[1] * PS_SQR(lowfitStdev);
    14921683
    14931684            psTrace(TRACE, 6, "Parabolic Lower fit results: %f + %f x + %f x^2\n", poly->coeff[0], poly->coeff[1], poly->coeff[2]);
     
    14981689        }
    14991690
    1500         float fullfitMean = NAN;
    1501         float fullfitStdev = NAN;
    1502         float minValueSym = NAN;
    1503         float maxValueSym = NAN;
    1504 
    1505         // try the full fit as well:
    1506         {
     1691        float fullfitMean = NAN;
     1692        float fullfitStdev = NAN;
     1693        float minValueSym = NAN;
     1694        float maxValueSym = NAN;
     1695
     1696        // try the full fit as well:
     1697        {
    15071698            // fit a symmetric distribution
    15081699            // run up until we drop below 0.15*valPeak
     
    15101701            long binS = binMin;
    15111702            long binE = binMax;
    1512             for (int i = binPeak - 3; i >= binMin; i--) {
    1513                 if (histogram->nums->data.F32[i] < 0.15*valPeak) {
     1703            for (int i = binPeak - 3; i >= binMin; i--)
     1704            {
     1705                if (histogram->nums->data.F32[i] < 0.15 * valPeak)
     1706                {
    15141707                    binS = i;
    15151708                    break;
    15161709                }
    15171710            }
    1518             for (int i = binPeak + 3; i < binMax; i++) {
    1519                 if (histogram->nums->data.F32[i] < 0.15*valPeak) {
     1711            for (int i = binPeak + 3; i < binMax; i++)
     1712            {
     1713                if (histogram->nums->data.F32[i] < 0.15 * valPeak)
     1714                {
    15201715                    binE = i;
    15211716                    break;
     
    15311726            psVector *x = psVectorAllocEmpty(binE - binS, PS_TYPE_F32); // Vector of ordinates
    15321727            long j = 0;
    1533             for (long i = binS; i < binE; i++) {
     1728            for (long i = binS; i < binE; i++)
     1729            {
    15341730                if (histogram->nums->data.F32[i] <= 0.0)
    15351731                    continue;
     
    15431739            // fit 2nd order polynomial to ln(y) = -(x-xo)^2/2sigma^2
    15441740            psPolynomial1D *poly = psPolynomial1DAlloc(PS_POLYNOMIAL_ORD, 2);
    1545             bool status = psVectorFitPolynomial1D (poly, NULL, 0, y, NULL, x);
     1741            bool status = psVectorFitPolynomial1D(poly, NULL, 0, y, NULL, x);
    15461742#if (CZW && 1)
    1547             printf("CZW: FullfitPoly: %f %f %f\n",poly->coeff[0],poly->coeff[1],poly->coeff[2]);
    1548             for (long i = 0; i < x->n; i++) {
    1549               printf("CZW: Fullfit: %d %ld %f %f %f\n",
    1550                      status,i,x->data.F32[i],y->data.F32[i],
    1551                      poly->coeff[0] + poly->coeff[1] * x->data.F32[i] +
    1552                      poly->coeff[2] * pow(x->data.F32[i],2));
    1553             }
     1743            printf("CZW: FullfitPoly: %f %f %f\n", poly->coeff[0], poly->coeff[1], poly->coeff[2]);
     1744            for (long i = 0; i < x->n; i++)
     1745            {
     1746                printf("CZW: Fullfit: %d %ld %f %f %f\n",
     1747                       status, i, x->data.F32[i], y->data.F32[i],
     1748                       poly->coeff[0] + poly->coeff[1] * x->data.F32[i] +
     1749                           poly->coeff[2] * pow(x->data.F32[i], 2));
     1750            }
    15541751#endif
    15551752            psFree(x);
    15561753            psFree(y);
    15571754
    1558             if (!status) {
     1755            if (!status)
     1756            {
    15591757                psErrorClear();
    15601758                COUNT_WARNING(10, 100, "Failed to fit a gaussian to the robust histogram.\n");
     
    15661764
    15671765            // calculate upper mean & stdev from parabolic fit -- ignore this value
    1568             fullfitStdev = sqrt(-0.5/poly->coeff[2]);
    1569             fullfitMean = poly->coeff[1]*PS_SQR(fullfitStdev);
     1766            fullfitStdev = sqrt(-0.5 / poly->coeff[2]);
     1767            fullfitMean = poly->coeff[1] * PS_SQR(fullfitStdev);
    15701768
    15711769#ifndef PS_NO_TRACE
     
    15801778
    15811779            // saturate on min or max value
    1582             if (fullfitMean < minValueSym) {
     1780            if (fullfitMean < minValueSym)
     1781            {
    15831782                fullfitMean = minValueSym;
    15841783                psTrace(TRACE, 6, "The symmetric mean is out of bounds, saturating to %f.\n", guessMean);
     
    15861785
    15871786            // saturate on min or max value
    1588             if (fullfitMean > maxValueSym) {
     1787            if (fullfitMean > maxValueSym)
     1788            {
    15891789                fullfitMean = maxValueSym;
    15901790                psTrace(TRACE, 6, "The symmetric mean is out of bounds, saturating to %f.\n", guessMean);
    15911791            }
    15921792
    1593            
    1594             psFree (poly);
    1595         }
    1596 
    1597         // we now have the fullfit and the lowfit mean and stdev values
    1598         // accept the fullfit unless minValueSym < lowfitMean < fullfitMean
    1599 
    1600         if (isfinite(lowfitMean) && isfinite(lowfitStdev) && (lowfitMean < fullfitMean) && (lowfitMean > minValueSym)) {
    1601             guessMean  = lowfitMean;
    1602             guessStdev = lowfitStdev;
    1603         } else {
    1604             guessMean  = fullfitMean;
    1605             guessStdev = fullfitStdev;
    1606         }
    1607 
    1608         if (!isfinite(guessMean) || !isfinite(guessStdev)) {
    1609             guessMean  = stats->robustMedian;
    1610             guessStdev = stats->robustStdev;
    1611         }
    1612 
    1613         if (guessStdev > 0.75*stats->robustStdev) {
    1614             done = true;
    1615         }
    1616 
    1617        
     1793            psFree(poly);
     1794        }
     1795
     1796        // we now have the fullfit and the lowfit mean and stdev values
     1797        // accept the fullfit unless minValueSym < lowfitMean < fullfitMean
     1798
     1799        if (isfinite(lowfitMean) && isfinite(lowfitStdev) && (lowfitMean < fullfitMean) && (lowfitMean > minValueSym))
     1800        {
     1801            guessMean = lowfitMean;
     1802            guessStdev = lowfitStdev;
     1803        }
     1804        else
     1805        {
     1806            guessMean = fullfitMean;
     1807            guessStdev = fullfitStdev;
     1808        }
     1809
     1810        if (!isfinite(guessMean) || !isfinite(guessStdev))
     1811        {
     1812            guessMean = stats->robustMedian;
     1813            guessStdev = stats->robustStdev;
     1814        }
     1815
     1816        if (guessStdev > 0.75 * stats->robustStdev)
     1817        {
     1818            done = true;
     1819        }
     1820
    16181821#if (CZW && 1)
    1619         printf("CZW IN FITTED: iter   %d %f \n"
    1620                "               low    %f %f \n"
    1621                "               full   %f %f \n"
    1622                "               robust %f %f \n"
    1623                "               final  %f %f\n",
    1624                iteration,minValueSym,
    1625                lowfitMean,lowfitStdev,
    1626                fullfitMean,fullfitStdev,
    1627                stats->robustMedian,stats->robustStdev,
    1628                guessMean,guessStdev);
     1822        printf("CZW IN FITTED: iter   %d %f \n"
     1823               "               low    %f %f \n"
     1824               "               full   %f %f \n"
     1825               "               robust %f %f \n"
     1826               "               final  %f %f\n",
     1827               iteration, minValueSym,
     1828               lowfitMean, lowfitStdev,
     1829               fullfitMean, fullfitStdev,
     1830               stats->robustMedian, stats->robustStdev,
     1831               guessMean, guessStdev);
    16291832#endif
    16301833
    16311834        // Clean up after fitting
    1632         psFree (histogram);
    1633         psFree (statsMinMax);
     1835        psFree(histogram);
     1836        psFree(statsMinMax);
    16341837    }
    16351838
     
    16551858    return true;
    16561859}
    1657 
    16581860
    16591861/******************************************************************************
     
    16681870{
    16691871    psTrace(TRACE, 4, "---- %s() begin ----\n", __func__);
    1670     psTrace(TRACE, 5, "(histogram->nums->n, sigma) is (%d, %.2f\n", (int) histogram->nums->n, sigma);
     1872    psTrace(TRACE, 5, "(histogram->nums->n, sigma) is (%d, %.2f\n", (int)histogram->nums->n, sigma);
    16711873    PS_ASSERT_PTR_NON_NULL(histogram, NULL);
    16721874    PS_ASSERT_PTR_NON_NULL(histogram->bounds, NULL);
    16731875    PS_ASSERT_PTR_NON_NULL(histogram->nums, NULL);
    1674     if (psTraceGetLevel("psLib.math") >= 8) {
     1876    if (psTraceGetLevel("psLib.math") >= 8)
     1877    {
    16751878        PS_VECTOR_PRINT_F32(histogram->nums);
    16761879    }
    16771880
    1678     long numBins = histogram->nums->n;  // Number of histogram bins
     1881    long numBins = histogram->nums->n;                      // Number of histogram bins
    16791882    psVector *smooth = psVectorAlloc(numBins, PS_TYPE_F32); // Smoothed version of histogram bins
    1680     const psVector *bounds = histogram->bounds; // The bounds for the histogram bins
    1681 
    1682     if (!histogram->uniform) {
     1883    const psVector *bounds = histogram->bounds;             // The bounds for the histogram bins
     1884
     1885    if (!histogram->uniform)
     1886    {
    16831887        //
    16841888        // We get here if the histogram is non-uniform.  This code is not tested.
     
    16881892                  "histograms has not been tested or used.\n");
    16891893
    1690         for (long i = 0; i < numBins; i++) {
     1894        for (long i = 0; i < numBins; i++)
     1895        {
    16911896            // Determine the midpoint of bin i.
    16921897            float iMid = PS_BIN_MIDPOINT(histogram, i);
     
    17081913            //
    17091914            smooth->data.F32[i] = 0.0;
    1710             for (long j = jMin ; j <= jMax ; j++) {
     1915            for (long j = jMin; j <= jMax; j++)
     1916            {
    17111917                float jMid = PS_BIN_MIDPOINT(histogram, j);
    17121918                smooth->data.F32[i] +=
     
    17141920            }
    17151921        }
    1716     } else {
     1922    }
     1923    else
     1924    {
    17171925        //
    17181926        // We get here if the histogram is uniform.
    17191927        //
    1720         for (long i = 0; i < numBins; i++) {
     1928        for (long i = 0; i < numBins; i++)
     1929        {
    17211930            psF32 binSize = bounds->data.F32[1] - bounds->data.F32[0];
    17221931            psS32 gaussWidth = ((PS_GAUSS_WIDTH * sigma) / binSize);
     
    17451954            smooth->data.F32[i] = 0.0;
    17461955            float iMid = PS_BIN_MIDPOINT(histogram, i);
    1747             for (long j = jMin ; j <= jMax ; j++) {
     1956            for (long j = jMin; j <= jMax; j++)
     1957            {
    17481958                float jMid = PS_BIN_MIDPOINT(histogram, j);
    17491959                smooth->data.F32[i] +=
     
    17531963    }
    17541964
    1755     if (psTraceGetLevel("psLib.math") >= 8) {
     1965    if (psTraceGetLevel("psLib.math") >= 8)
     1966    {
    17561967        PS_VECTOR_PRINT_F32(smooth);
    17571968    }
    17581969    psTrace(TRACE, 4, "---- %s() end ----\n", __func__);
    1759     return(smooth);
     1970    return (smooth);
    17601971}
    17611972
     
    17691980static void statsFree(psStats *stats)
    17701981{
    1771     if (!stats) return;
    1772     psFree (stats->tmpData);
    1773     psFree (stats->tmpMask);
     1982    if (!stats)
     1983        return;
     1984    psFree(stats->tmpData);
     1985    psFree(stats->tmpMask);
    17741986    return;
    17751987}
     
    17781990    psStatsAlloc(): This routine must create a new psStats data structure.
    17791991*****************************************************************************/
    1780 psStats* p_psStatsAlloc(const char *file, unsigned int lineno, const char *func, psStatsOptions options)
     1992psStats *p_psStatsAlloc(const char *file, unsigned int lineno, const char *func, psStatsOptions options)
    17811993{
    17821994    psStats *stats = p_psAlloc(file, lineno, func, sizeof(psStats));
     
    17841996
    17851997    // set initial, default values
    1786     psStatsInit (stats);
     1998    psStatsInit(stats);
    17871999
    17882000    // these values are can be set as desired by the user.  they are not affected by
     
    18182030    stats->clippedMean = NAN;
    18192031    stats->clippedStdev = NAN;
    1820     stats->clippedNvalues = -1;     // XXX: This is never used
     2032    stats->clippedNvalues = -1; // XXX: This is never used
    18212033    stats->min = NAN;
    18222034    stats->max = NAN;
     
    18252037}
    18262038
    1827 
    18282039bool psMemCheckStats(psPtr ptr)
    18292040{
    18302041    PS_ASSERT_PTR(ptr, false);
    1831     return ( psMemGetDeallocator(ptr) == (psFreeFunc)statsFree );
     2042    return (psMemGetDeallocator(ptr) == (psFreeFunc)statsFree);
    18322043}
    18332044
     
    18472058XXX: Should we free stats if the asserts fail? NO; we don't own it (RHL).
    18482059*****************************************************************************/
    1849 bool psVectorStats(psStats* stats,
    1850                    const psVector* in,
    1851                    const psVector* errors,
    1852                    const psVector* mask,
     2060bool psVectorStats(psStats *stats,
     2061                   const psVector *in,
     2062                   const psVector *errors,
     2063                   const psVector *mask,
    18532064                   psVectorMaskType maskVal)
    18542065{
     
    18562067    PS_ASSERT_VECTOR_NON_NULL(in, false);
    18572068    PS_ASSERT_VECTOR_NON_EMPTY(in, false);
    1858     if (mask) {
     2069    if (mask)
     2070    {
    18592071        PS_ASSERT_VECTORS_SIZE_EQUAL(mask, in, false);
    18602072        PS_ASSERT_VECTOR_TYPE(mask, PS_TYPE_VECTOR_MASK, false);
    18612073    }
    1862     if (errors) {
     2074    if (errors)
     2075    {
    18632076        PS_ASSERT_VECTORS_SIZE_EQUAL(errors, in, false);
    18642077        PS_ASSERT_VECTOR_TYPE(errors, in->type.type, false);
     
    18662079
    18672080    // Convert types, as necessary
    1868     psVector *inF32 = NULL;             // Input vector of values, F32 version
    1869     if (in->type.type == PS_TYPE_F32) {
     2081    psVector *inF32 = NULL; // Input vector of values, F32 version
     2082    if (in->type.type == PS_TYPE_F32)
     2083    {
    18702084        inF32 = psMemIncrRefCounter((psPtr)in);
    1871     } else {
     2085    }
     2086    else
     2087    {
    18722088        inF32 = psVectorCopy(NULL, in, PS_TYPE_F32);
    18732089    }
    1874     psVector *errorsF32 = NULL;         // Input vector of errors, F32 version
    1875     if (errors) {
    1876         if (errors->type.type == PS_TYPE_F32) {
     2090    psVector *errorsF32 = NULL; // Input vector of errors, F32 version
     2091    if (errors)
     2092    {
     2093        if (errors->type.type == PS_TYPE_F32)
     2094        {
    18772095            errorsF32 = psMemIncrRefCounter((psPtr)errors);
    1878         } else {
     2096        }
     2097        else
     2098        {
    18792099            errorsF32 = psVectorCopy(NULL, errors, PS_TYPE_F32);
    18802100        }
    18812101    }
    1882     psVector *maskVector = NULL;            // Input mask vector, U8 version
    1883     if (mask) {
    1884         if (mask->type.type == PS_TYPE_VECTOR_MASK) {
     2102    psVector *maskVector = NULL; // Input mask vector, U8 version
     2103    if (mask)
     2104    {
     2105        if (mask->type.type == PS_TYPE_VECTOR_MASK)
     2106        {
    18852107            maskVector = psMemIncrRefCounter((psPtr)mask);
    1886         } else {
     2108        }
     2109        else
     2110        {
    18872111            maskVector = psVectorCopy(NULL, mask, PS_TYPE_VECTOR_MASK);
    18882112        }
    18892113    }
    18902114
    1891     if ((stats->options & PS_STAT_USE_RANGE) && (stats->min >= stats->max)) {
     2115    if ((stats->options & PS_STAT_USE_RANGE) && (stats->min >= stats->max))
     2116    {
    18922117        PS_ASSERT_FLOAT_LARGER_THAN_OR_EQUAL(stats->max, stats->min, false);
    18932118    }
    18942119
    1895     if ((stats->options & PS_STAT_USE_BINSIZE) && (stats->min >= stats->max)) {
     2120    if ((stats->options & PS_STAT_USE_BINSIZE) && (stats->min >= stats->max))
     2121    {
    18962122        PS_ASSERT_FLOAT_LARGER_THAN_OR_EQUAL(stats->binsize, 0.0, false);
    18972123    }
     
    19032129
    19042130    // ************************************************************************
    1905     if (stats->options & PS_STAT_SAMPLE_MEAN) {
    1906         // NOTE: vectorSampleMean cannot return 'false'
    1907         if (!vectorSampleMean(inF32, errorsF32, maskVector, maskVal, stats)) {
     2131    if (stats->options & PS_STAT_SAMPLE_MEAN)
     2132    {
     2133        // NOTE: vectorSampleMean cannot return 'false'
     2134        if (!vectorSampleMean(inF32, errorsF32, maskVector, maskVal, stats))
     2135        {
    19082136            psError(PS_ERR_UNKNOWN, false, "Failed to calculate vector sample mean");
    19092137            status &= false;
     
    19122140
    19132141    // ************************************************************************
    1914     if (stats->options & (PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_QUARTILE)) {
    1915         // NOTE: vectorSampleMedian only returns 'false' for very bad cases:
    1916         // NULL input vector, psVectorCopy failure, invalid vector type (likely programming errors)
    1917         if (!vectorSampleMedian(inF32, maskVector, maskVal, stats)) {
    1918             psError(PS_ERR_UNKNOWN, false, "Failed to calculate sample median");
    1919             status &= false;
    1920         }
     2142    if (stats->options & (PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_QUARTILE))
     2143    {
     2144        // NOTE: vectorSampleMedian only returns 'false' for very bad cases:
     2145        // NULL input vector, psVectorCopy failure, invalid vector type (likely programming errors)
     2146        if (!vectorSampleMedian(inF32, maskVector, maskVal, stats))
     2147        {
     2148            psError(PS_ERR_UNKNOWN, false, "Failed to calculate sample median");
     2149            status &= false;
     2150        }
    19212151    }
    19222152
    19232153    // ************************************************************************
    1924     if (stats->options & PS_STAT_SAMPLE_STDEV) {
    1925         // NOTE: vectorSampleStdev cannot return 'false'
    1926         if (!vectorSampleStdev(inF32, errorsF32, maskVector, maskVal, stats)) {
     2154    if (stats->options & PS_STAT_SAMPLE_STDEV)
     2155    {
     2156        // NOTE: vectorSampleStdev cannot return 'false'
     2157        if (!vectorSampleStdev(inF32, errorsF32, maskVector, maskVal, stats))
     2158        {
    19272159            psError(PS_ERR_UNKNOWN, false, "Failed to calculate sample stdev");
    19282160            status &= false;
     
    19302162    }
    19312163
    1932     if (stats->options & (PS_STAT_SAMPLE_SKEWNESS | PS_STAT_SAMPLE_KURTOSIS)) {
    1933         // NOTE: vectorSampleMoments cannot return 'false'
    1934         if (!vectorSampleMoments(inF32, maskVector, maskVal, stats)) {
     2164    if (stats->options & (PS_STAT_SAMPLE_SKEWNESS | PS_STAT_SAMPLE_KURTOSIS))
     2165    {
     2166        // NOTE: vectorSampleMoments cannot return 'false'
     2167        if (!vectorSampleMoments(inF32, maskVector, maskVal, stats))
     2168        {
    19352169            psError(PS_ERR_UNKNOWN, false, "Failed to calculate sample moments");
    19362170            status &= false;
     
    19392173
    19402174    // ************************************************************************
    1941     if (stats->options & (PS_STAT_MAX | PS_STAT_MIN)) {
    1942         // NOTE: vectorMinMax returns 0 if there are no valid values,
    1943         // but this is not an error condition.  stats.min,max are set to NAN.
    1944         // vectorMinMax cannot raise an error
     2175    if (stats->options & (PS_STAT_MAX | PS_STAT_MIN))
     2176    {
     2177        // NOTE: vectorMinMax returns 0 if there are no valid values,
     2178        // but this is not an error condition.  stats.min,max are set to NAN.
     2179        // vectorMinMax cannot raise an error
    19452180        vectorMinMax(inF32, maskVector, maskVal, stats);
    19462181    }
    19472182
    19482183    // ************************************************************************
    1949     if (stats->options & (PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV | PS_STAT_ROBUST_QUARTILE)) {
    1950         if (!vectorRobustStats(inF32, errorsF32, maskVector, maskVal, stats)) {
     2184    if (stats->options & (PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV | PS_STAT_ROBUST_QUARTILE))
     2185    {
     2186        if (!vectorRobustStats(inF32, errorsF32, maskVector, maskVal, stats))
     2187        {
    19512188            psError(PS_ERR_UNKNOWN, false, _("Failed to calculate robust statistics"));
    19522189            status &= false;
     
    19552192
    19562193    // ************************************************************************
    1957     if (stats->options & (PS_STAT_FITTED_MEAN | PS_STAT_FITTED_STDEV)) {
    1958         if (!vectorFittedStats(inF32, errorsF32, maskVector, maskVal, stats)) {
     2194    if (stats->options & (PS_STAT_FITTED_MEAN | PS_STAT_FITTED_STDEV))
     2195    {
     2196        if (!vectorFittedStats(inF32, errorsF32, maskVector, maskVal, stats))
     2197        {
    19592198            psError(PS_ERR_UNKNOWN, false, _("Failed to calculate fitted statistics"));
    19602199            status &= false;
     
    19632202
    19642203    // ************************************************************************
    1965     if ((stats->options & PS_STAT_CLIPPED_MEAN) || (stats->options & PS_STAT_CLIPPED_STDEV)) {
    1966         if (!vectorClippedStats(inF32, errorsF32, maskVector, maskVal, stats)) {
     2204    if ((stats->options & PS_STAT_CLIPPED_MEAN) || (stats->options & PS_STAT_CLIPPED_MEDIAN) || (stats->options & PS_STAT_CLIPPED_STDEV))
     2205    {
     2206        if (!vectorClippedStats(inF32, errorsF32, maskVector, maskVal, stats))
     2207        {
    19672208            psError(PS_ERR_UNKNOWN, false, "Failed to calculate clipped statistics\n");
    19682209            status &= false;
     
    19802221    PS_ASSERT_STRING_NON_EMPTY(string, PS_STAT_NONE);
    19812222
    1982 #define READ_STAT(NAME, SYMBOL) \
    1983     if (strcasecmp(string, NAME) == 0) { \
    1984         return SYMBOL; \
    1985     }
    1986 
    1987     READ_STAT("MEAN",       PS_STAT_SAMPLE_MEAN);
    1988     READ_STAT("STDEV",      PS_STAT_SAMPLE_STDEV);
    1989     READ_STAT("SKEWNESS",   PS_STAT_SAMPLE_SKEWNESS);
    1990     READ_STAT("KURTOSIS",   PS_STAT_SAMPLE_KURTOSIS);
    1991     READ_STAT("MEDIAN",     PS_STAT_SAMPLE_MEDIAN);
    1992     READ_STAT("QUARTILE",   PS_STAT_SAMPLE_QUARTILE);
    1993     READ_STAT("SAMPLE_MEAN",     PS_STAT_SAMPLE_MEAN);
    1994     READ_STAT("SAMPLE_STDEV",    PS_STAT_SAMPLE_STDEV);
    1995     READ_STAT("SAMPLE_MEDIAN",   PS_STAT_SAMPLE_MEDIAN);
     2223#define READ_STAT(NAME, SYMBOL)        \
     2224    if (strcasecmp(string, NAME) == 0) \
     2225    {                                  \
     2226        return SYMBOL;                 \
     2227    }
     2228
     2229    READ_STAT("MEAN", PS_STAT_SAMPLE_MEAN);
     2230    READ_STAT("STDEV", PS_STAT_SAMPLE_STDEV);
     2231    READ_STAT("SKEWNESS", PS_STAT_SAMPLE_SKEWNESS);
     2232    READ_STAT("KURTOSIS", PS_STAT_SAMPLE_KURTOSIS);
     2233    READ_STAT("MEDIAN", PS_STAT_SAMPLE_MEDIAN);
     2234    READ_STAT("QUARTILE", PS_STAT_SAMPLE_QUARTILE);
     2235    READ_STAT("SAMPLE_MEAN", PS_STAT_SAMPLE_MEAN);
     2236    READ_STAT("SAMPLE_STDEV", PS_STAT_SAMPLE_STDEV);
     2237    READ_STAT("SAMPLE_MEDIAN", PS_STAT_SAMPLE_MEDIAN);
    19962238    READ_STAT("SAMPLE_QUARTILE", PS_STAT_SAMPLE_QUARTILE);
    19972239    READ_STAT("SAMPLE_SKEWNESS", PS_STAT_SAMPLE_SKEWNESS);
    19982240    READ_STAT("SAMPLE_KURTOSIS", PS_STAT_SAMPLE_KURTOSIS);
    1999     READ_STAT("ROBUST",          PS_STAT_ROBUST_MEDIAN);
    2000     READ_STAT("ROBUST_MEDIAN",   PS_STAT_ROBUST_MEDIAN);
    2001     READ_STAT("ROBUST_STDEV",    PS_STAT_ROBUST_STDEV);
     2241    READ_STAT("ROBUST", PS_STAT_ROBUST_MEDIAN);
     2242    READ_STAT("ROBUST_MEDIAN", PS_STAT_ROBUST_MEDIAN);
     2243    READ_STAT("ROBUST_STDEV", PS_STAT_ROBUST_STDEV);
    20022244    READ_STAT("ROBUST_QUARTILE", PS_STAT_ROBUST_QUARTILE);
    2003     READ_STAT("FITTED",          PS_STAT_FITTED_MEAN);
    2004     READ_STAT("FITTED_MEAN",     PS_STAT_FITTED_MEAN);
    2005     READ_STAT("FITTED_STDEV",    PS_STAT_FITTED_STDEV);
    2006     READ_STAT("FITTED_V2",       PS_STAT_FITTED_MEAN);
    2007     READ_STAT("FITTED_MEAN_V2",  PS_STAT_FITTED_MEAN);
     2245    READ_STAT("FITTED", PS_STAT_FITTED_MEAN);
     2246    READ_STAT("FITTED_MEAN", PS_STAT_FITTED_MEAN);
     2247    READ_STAT("FITTED_STDEV", PS_STAT_FITTED_STDEV);
     2248    READ_STAT("FITTED_V2", PS_STAT_FITTED_MEAN);
     2249    READ_STAT("FITTED_MEAN_V2", PS_STAT_FITTED_MEAN);
    20082250    READ_STAT("FITTED_STDEV_V2", PS_STAT_FITTED_STDEV);
    2009     READ_STAT("FITTED_V3",       PS_STAT_FITTED_MEAN);
    2010     READ_STAT("FITTED_MEAN_V3",  PS_STAT_FITTED_MEAN);
     2251    READ_STAT("FITTED_V3", PS_STAT_FITTED_MEAN);
     2252    READ_STAT("FITTED_MEAN_V3", PS_STAT_FITTED_MEAN);
    20112253    READ_STAT("FITTED_STDEV_V3", PS_STAT_FITTED_STDEV);
    2012     READ_STAT("FITTED_V4",       PS_STAT_FITTED_MEAN);
    2013     READ_STAT("FITTED_MEAN_V4",  PS_STAT_FITTED_MEAN);
     2254    READ_STAT("FITTED_V4", PS_STAT_FITTED_MEAN);
     2255    READ_STAT("FITTED_MEAN_V4", PS_STAT_FITTED_MEAN);
    20142256    READ_STAT("FITTED_STDEV_V4", PS_STAT_FITTED_STDEV);
    2015     READ_STAT("CLIPPED",         PS_STAT_CLIPPED_MEAN);
    2016     READ_STAT("CLIPPED_MEAN",    PS_STAT_CLIPPED_MEAN);
    2017     READ_STAT("CLIPPED_STDEV",   PS_STAT_CLIPPED_STDEV);
     2257    READ_STAT("CLIPPED", PS_STAT_CLIPPED_MEAN);
     2258    READ_STAT("CLIPPED_MEAN", PS_STAT_CLIPPED_MEAN);
     2259    READ_STAT("CLIPPED_MEDIAN", PS_STAT_CLIPPED_MEDIAN);
     2260    READ_STAT("CLIPPED_STDEV", PS_STAT_CLIPPED_STDEV);
    20182261
    20192262    psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Unable to parse statistic: %s\n", string);
     
    20232266psString psStatsOptionToString(psStatsOptions option)
    20242267{
    2025     psString string = NULL;             // String to return
    2026 
    2027 #define WRITE_STAT(NAME, SYMBOL) \
    2028     if (option & SYMBOL) { \
     2268    psString string = NULL; // String to return
     2269
     2270#define WRITE_STAT(NAME, SYMBOL)              \
     2271    if (option & SYMBOL)                      \
     2272    {                                         \
    20292273        psStringAppend(&string, "%s ", NAME); \
    20302274    }
    20312275
    20322276    // Same list as above (for psStatsFromString), but with repeat symbols removed
    2033     WRITE_STAT("SAMPLE_MEAN",     PS_STAT_SAMPLE_MEAN);
    2034     WRITE_STAT("SAMPLE_STDEV",    PS_STAT_SAMPLE_STDEV);
    2035     WRITE_STAT("SAMPLE_MEDIAN",   PS_STAT_SAMPLE_MEDIAN);
     2277    WRITE_STAT("SAMPLE_MEAN", PS_STAT_SAMPLE_MEAN);
     2278    WRITE_STAT("SAMPLE_STDEV", PS_STAT_SAMPLE_STDEV);
     2279    WRITE_STAT("SAMPLE_MEDIAN", PS_STAT_SAMPLE_MEDIAN);
    20362280    WRITE_STAT("SAMPLE_QUARTILE", PS_STAT_SAMPLE_QUARTILE);
    20372281    WRITE_STAT("SAMPLE_SKEWNESS", PS_STAT_SAMPLE_SKEWNESS);
    20382282    WRITE_STAT("SAMPLE_KURTOSIS", PS_STAT_SAMPLE_KURTOSIS);
    2039     WRITE_STAT("ROBUST_MEDIAN",   PS_STAT_ROBUST_MEDIAN);
    2040     WRITE_STAT("ROBUST_STDEV",    PS_STAT_ROBUST_STDEV);
     2283    WRITE_STAT("ROBUST_MEDIAN", PS_STAT_ROBUST_MEDIAN);
     2284    WRITE_STAT("ROBUST_STDEV", PS_STAT_ROBUST_STDEV);
    20412285    WRITE_STAT("ROBUST_QUARTILE", PS_STAT_ROBUST_QUARTILE);
    2042     WRITE_STAT("FITTED_MEAN",     PS_STAT_FITTED_MEAN);
    2043     WRITE_STAT("FITTED_STDEV",    PS_STAT_FITTED_STDEV);
    2044     WRITE_STAT("CLIPPED_MEAN",    PS_STAT_CLIPPED_MEAN);
    2045     WRITE_STAT("CLIPPED_STDEV",   PS_STAT_CLIPPED_STDEV);
     2286    WRITE_STAT("FITTED_MEAN", PS_STAT_FITTED_MEAN);
     2287    WRITE_STAT("FITTED_STDEV", PS_STAT_FITTED_STDEV);
     2288    WRITE_STAT("CLIPPED_MEAN", PS_STAT_CLIPPED_MEAN);
     2289    WRITE_STAT("CLIPPED_MEDIAN", PS_STAT_CLIPPED_MEDIAN);
     2290    WRITE_STAT("CLIPPED_STDEV", PS_STAT_CLIPPED_STDEV);
    20462291
    20472292    return string;
     
    20512296{
    20522297    psList *subStrings = psStringSplit(string, " ,;", false); // List of sub-strings
    2053     if (!subStrings || psListLength(subStrings) == 0) {
     2298    if (!subStrings || psListLength(subStrings) == 0)
     2299    {
    20542300        // Nothing here
    20552301        psError(PS_ERR_BAD_PARAMETER_VALUE, false, "No string to parse for statistics: %s\n", string);
     
    20572303        return NULL;
    20582304    }
    2059     psStats *stats = psStatsAlloc(0);   // Generate empty stats structure
     2305    psStats *stats = psStatsAlloc(0);                                                // Generate empty stats structure
    20602306    psListIterator *iterator = psListIteratorAlloc(subStrings, PS_LIST_HEAD, false); // Iterator
    2061     psString statString;                // Statistic string, from iteration
    2062     while ((statString = psListGetAndIncrement(iterator))) {
     2307    psString statString;                                                             // Statistic string, from iteration
     2308    while ((statString = psListGetAndIncrement(iterator)))
     2309    {
    20632310        psStatsOptions option = psStatsOptionFromString(statString);
    2064         if (option == 0) {
     2311        if (option == 0)
     2312        {
    20652313            psWarning("Unable to interpret statistic option: %s --- ignored.\n", statString);
    20662314            continue;
     
    20802328psStatsOptions psStatsSingleOption(psStatsOptions option)
    20812329{
    2082     switch (option & ~(PS_STAT_USE_RANGE | PS_STAT_USE_BINSIZE)) {
    2083       case PS_STAT_SAMPLE_MEAN:
    2084       case PS_STAT_SAMPLE_MEDIAN:
    2085       case PS_STAT_SAMPLE_STDEV:
    2086       case PS_STAT_SAMPLE_QUARTILE:
    2087       case PS_STAT_SAMPLE_SKEWNESS:
    2088       case PS_STAT_SAMPLE_KURTOSIS:
    2089       case PS_STAT_ROBUST_MEDIAN:
    2090       case PS_STAT_ROBUST_STDEV:
    2091       case PS_STAT_ROBUST_QUARTILE:
    2092       case PS_STAT_FITTED_MEAN:
    2093       case PS_STAT_FITTED_STDEV:
    2094       case PS_STAT_CLIPPED_MEAN:
    2095       case PS_STAT_CLIPPED_STDEV:
    2096       case PS_STAT_MAX:
    2097       case PS_STAT_MIN:
     2330    switch (option & ~(PS_STAT_USE_RANGE | PS_STAT_USE_BINSIZE))
     2331    {
     2332    case PS_STAT_SAMPLE_MEAN:
     2333    case PS_STAT_SAMPLE_MEDIAN:
     2334    case PS_STAT_SAMPLE_STDEV:
     2335    case PS_STAT_SAMPLE_QUARTILE:
     2336    case PS_STAT_SAMPLE_SKEWNESS:
     2337    case PS_STAT_SAMPLE_KURTOSIS:
     2338    case PS_STAT_ROBUST_MEDIAN:
     2339    case PS_STAT_ROBUST_STDEV:
     2340    case PS_STAT_ROBUST_QUARTILE:
     2341    case PS_STAT_FITTED_MEAN:
     2342    case PS_STAT_FITTED_STDEV:
     2343    case PS_STAT_CLIPPED_MEAN:
     2344    case PS_STAT_CLIPPED_MEDIAN:
     2345    case PS_STAT_CLIPPED_STDEV:
     2346    case PS_STAT_MAX:
     2347    case PS_STAT_MIN:
    20982348        return option & ~(PS_STAT_USE_RANGE | PS_STAT_USE_BINSIZE);
    2099       default:
     2349    default:
    21002350        return 0;
    21012351    }
     
    21072357{
    21082358    return options & (PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_MEDIAN | PS_STAT_ROBUST_MEDIAN |
    2109                       PS_STAT_CLIPPED_MEAN | PS_STAT_FITTED_MEAN);
     2359                      PS_STAT_CLIPPED_MEAN | PS_STAT_CLIPPED_MEDIAN | PS_STAT_FITTED_MEAN);
    21102360}
    21112361
     
    21162366}
    21172367
    2118 
    21192368double psStatsGetValue(const psStats *stats, psStatsOptions option)
    21202369{
    21212370    // We could call psStatsSingle to check, but it would be a waste since we effectively do it anyway
    2122     switch (option & ~(PS_STAT_USE_RANGE | PS_STAT_USE_BINSIZE)) {
    2123       case PS_STAT_SAMPLE_MEAN:
     2371    switch (option & ~(PS_STAT_USE_RANGE | PS_STAT_USE_BINSIZE))
     2372    {
     2373    case PS_STAT_SAMPLE_MEAN:
    21242374        return stats->sampleMean;
    2125       case PS_STAT_SAMPLE_MEDIAN:
     2375    case PS_STAT_SAMPLE_MEDIAN:
    21262376        return stats->sampleMedian;
    2127       case PS_STAT_SAMPLE_STDEV:
     2377    case PS_STAT_SAMPLE_STDEV:
    21282378        return stats->sampleStdev;
    2129       case PS_STAT_SAMPLE_SKEWNESS:
     2379    case PS_STAT_SAMPLE_SKEWNESS:
    21302380        return stats->sampleSkewness;
    2131       case PS_STAT_SAMPLE_KURTOSIS:
     2381    case PS_STAT_SAMPLE_KURTOSIS:
    21322382        return stats->sampleKurtosis;
    2133       case PS_STAT_ROBUST_MEDIAN:
     2383    case PS_STAT_ROBUST_MEDIAN:
    21342384        return stats->robustMedian;
    2135       case PS_STAT_ROBUST_STDEV:
     2385    case PS_STAT_ROBUST_STDEV:
    21362386        return stats->robustStdev;
    2137       case PS_STAT_FITTED_MEAN:
     2387    case PS_STAT_FITTED_MEAN:
    21382388        return stats->fittedMean;
    2139       case PS_STAT_FITTED_STDEV:
     2389    case PS_STAT_FITTED_STDEV:
    21402390        return stats->fittedStdev;
    2141       case PS_STAT_CLIPPED_MEAN:
     2391    case PS_STAT_CLIPPED_MEAN:
    21422392        return stats->clippedMean;
    2143       case PS_STAT_CLIPPED_STDEV:
     2393    case PS_STAT_CLIPPED_MEDIAN:
     2394        return stats->clippedMedian;
     2395    case PS_STAT_CLIPPED_STDEV:
    21442396        return stats->clippedStdev;
    2145       case PS_STAT_MAX:
     2397    case PS_STAT_MAX:
    21462398        return stats->max;
    2147       case PS_STAT_MIN:
     2399    case PS_STAT_MIN:
    21482400        return stats->min;
    2149       case PS_STAT_SAMPLE_QUARTILE:
    2150       case PS_STAT_ROBUST_QUARTILE:
     2401    case PS_STAT_SAMPLE_QUARTILE:
     2402    case PS_STAT_ROBUST_QUARTILE:
    21512403        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Cannot return a single quartile value; "
    2152                 "get them yourself.\n");
     2404                                                  "get them yourself.\n");
    21532405        return NAN;
    2154       default:
     2406    default:
    21552407        return NAN;
    21562408    }
     
    21612413// other private functions used above
    21622414
    2163 # if (0)
     2415#if (0)
    21642416static psF32 QuadraticInverse(psF32 a,
    21652417                              psF32 b,
     
    21672419                              psF32 y,
    21682420                              psF32 xLo,
    2169                               psF32 xHi
    2170     )
     2421                              psF32 xHi)
    21712422{
    2172     psF64 tmp = sqrt((y - c)/a + (b*b)/(4.0 * a * a));
    2173 
    2174     psF64 x1 = -b/(2.0*a) + tmp;
    2175     psF64 x2 = -b/(2.0*a) - tmp;
    2176 
    2177     if (xLo <= x1 && x1 <= xHi) {
     2423    psF64 tmp = sqrt((y - c) / a + (b * b) / (4.0 * a * a));
     2424
     2425    psF64 x1 = -b / (2.0 * a) + tmp;
     2426    psF64 x2 = -b / (2.0 * a) - tmp;
     2427
     2428    if (xLo <= x1 && x1 <= xHi)
     2429    {
    21782430        return x1;
    21792431    }
    2180     if (xLo <= x2 && x2 <= xHi) {
     2432    if (xLo <= x2 && x2 <= xHi)
     2433    {
    21812434        return x2;
    21822435    }
     
    21852438
    21862439static psF32 LinearInverse(psF32 a,
    2187                            psF32 b,
    2188                            psF32 y,
    2189                            psF32 xLo,
    2190                            psF32 xHi
    2191     )
     2440                           psF32 b,
     2441                           psF32 y,
     2442                           psF32 xLo,
     2443                           psF32 xHi)
    21922444{
    21932445    psF64 x = (y - b) / a;
    21942446
    2195     if (xLo <= x && x <= xHi) {
     2447    if (xLo <= x && x <= xHi)
     2448    {
    21962449        return x;
    21972450    }
    21982451    return 0.5 * (xLo + xHi);
    21992452}
    2200 # endif
    2201 
    2202 # if (0)
     2453#endif
     2454
     2455#if (0)
    22032456/******************************************************************************
    22042457fitQuadraticSearchForYThenReturnX(*xVec, *yVec, binNum, yVal): A general
     
    22142467                                               psVector *yVec,
    22152468                                               psS32 binNum,
    2216                                                psF32 yVal
    2217     )
     2469                                               psF32 yVal)
    22182470{
    22192471    psTrace(TRACE, 4, "---- %s() begin ----\n", __func__);
    22202472    psTrace(TRACE, 5, "binNum, yVal is (%d, %f)\n", binNum, yVal);
    2221     if (psTraceGetLevel("psLib.math") >= 8) {
     2473    if (psTraceGetLevel("psLib.math") >= 8)
     2474    {
    22222475        PS_VECTOR_PRINT_F32(xVec);
    22232476        PS_VECTOR_PRINT_F32(yVec);
     
    22362489    psF32 tmpFloat = 0.0f;
    22372490
    2238     if ((binNum >= 1) && (binNum < (yVec->n - 2)) && (binNum < (xVec->n - 2))) {
     2491    if ((binNum >= 1) && (binNum < (yVec->n - 2)) && (binNum < (xVec->n - 2)))
     2492    {
    22392493        // The general case.  We have all three points.
    2240         x->data.F64[0] = (psF64) (0.5 * (xVec->data.F32[binNum - 1] + xVec->data.F32[binNum]));
    2241         x->data.F64[1] = (psF64) (0.5 * (xVec->data.F32[binNum] + xVec->data.F32[binNum+1]));
    2242         x->data.F64[2] = (psF64) (0.5 * (xVec->data.F32[binNum+1] + xVec->data.F32[binNum+2]));
     2494        x->data.F64[0] = (psF64)(0.5 * (xVec->data.F32[binNum - 1] + xVec->data.F32[binNum]));
     2495        x->data.F64[1] = (psF64)(0.5 * (xVec->data.F32[binNum] + xVec->data.F32[binNum + 1]));
     2496        x->data.F64[2] = (psF64)(0.5 * (xVec->data.F32[binNum + 1] + xVec->data.F32[binNum + 2]));
    22432497        y->data.F64[0] = yVec->data.F32[binNum - 1];
    22442498        y->data.F64[1] = yVec->data.F32[binNum];
    22452499        y->data.F64[2] = yVec->data.F32[binNum + 1];
    22462500        psTrace(TRACE, 6, "x vec (orig) is (%f %f %f %f)\n", xVec->data.F32[binNum - 1],
    2247                 xVec->data.F32[binNum], xVec->data.F32[binNum+1], xVec->data.F32[binNum+2]);
     2501                xVec->data.F32[binNum], xVec->data.F32[binNum + 1], xVec->data.F32[binNum + 2]);
    22482502        psTrace(TRACE, 6, "x data is (%f %f %f)\n", x->data.F64[0], x->data.F64[1], x->data.F64[2]);
    22492503        psTrace(TRACE, 6, "y data is (%f %f %f)\n", y->data.F64[0], y->data.F64[1], y->data.F64[2]);
     
    22522506        // Ensure that the y value lies within range of the y values.
    22532507        //
    2254         if (! (((y->data.F64[0] <= yVal) && (yVal <= y->data.F64[2])) ||
    2255                ((y->data.F64[2] <= yVal) && (yVal <= y->data.F64[0]))) ) {
     2508        if (!(((y->data.F64[0] <= yVal) && (yVal <= y->data.F64[2])) ||
     2509              ((y->data.F64[2] <= yVal) && (yVal <= y->data.F64[0]))))
     2510        {
    22562511            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    22572512                    _("Specified yVal, %g, is not within y-range, %g to %g."),
     
    22632518        //
    22642519        if (((y->data.F64[0] < y->data.F64[1]) && !(y->data.F64[1] <= y->data.F64[2])) ||
    2265             ((y->data.F64[0] > y->data.F64[1]) && !(y->data.F64[1] >= y->data.F64[2]))) {
     2520            ((y->data.F64[0] > y->data.F64[1]) && !(y->data.F64[1] >= y->data.F64[2])))
     2521        {
    22662522            psError(PS_ERR_UNKNOWN, true,
    22672523                    "This routine must be called with monotonically increasing or decreasing data points.\n");
     
    22742530        // Determine the coefficients of the polynomial.
    22752531        psPolynomial1D *myPoly = psPolynomial1DAlloc(PS_POLYNOMIAL_ORD, 2);
    2276         if (!psVectorFitPolynomial1D(myPoly, NULL, 0, y, NULL, x)) {
     2532        if (!psVectorFitPolynomial1D(myPoly, NULL, 0, y, NULL, x))
     2533        {
    22772534            psError(PS_ERR_UNEXPECTED_NULL, false,
    22782535                    _("Failed to fit a 1-dimensional polynomial to the three specified data points.  "
     
    22872544        psTrace(TRACE, 6, "myPoly->coeff[2] is %f\n", myPoly->coeff[2]);
    22882545        psTrace(TRACE, 6, "Fitted y vec is (%f %f %f)\n",
    2289                 (psF32) psPolynomial1DEval(myPoly, (psF64) x->data.F64[0]),
    2290                 (psF32) psPolynomial1DEval(myPoly, (psF64) x->data.F64[1]),
    2291                 (psF32) psPolynomial1DEval(myPoly, (psF64) x->data.F64[2]));
     2546                (psF32)psPolynomial1DEval(myPoly, (psF64)x->data.F64[0]),
     2547                (psF32)psPolynomial1DEval(myPoly, (psF64)x->data.F64[1]),
     2548                (psF32)psPolynomial1DEval(myPoly, (psF64)x->data.F64[2]));
    22922549
    22932550        psTrace(TRACE, 6, "We fit the polynomial, now find x such that f(x) equals %f\n", yVal);
     
    22962553        psFree(myPoly);
    22972554
    2298         if (isnan(tmpFloat)) {
     2555        if (isnan(tmpFloat))
     2556        {
    22992557            psError(PS_ERR_UNEXPECTED_NULL,
    23002558                    false, _("Failed to determine the median of the fitted polynomial.  Returning NAN."));
     
    23022560            psFree(y);
    23032561            psTrace(TRACE, 5, "---- %s(NAN) end ----\n", __func__);
    2304             return(NAN);
    2305         }
    2306     } else {
     2562            return (NAN);
     2563        }
     2564    }
     2565    else
     2566    {
    23072567        // These are special cases where the bin is at the beginning or end of the vector.
    2308         if (binNum == 0) {
     2568        if (binNum == 0)
     2569        {
    23092570            // We have two points only at the beginning of the vectors x and y.
    23102571            tmpFloat = 0.5 * (xVec->data.F32[binNum] +
    23112572                              xVec->data.F32[binNum + 1]);
    2312         } else if (binNum == (xVec->n - 1)) {
     2573        }
     2574        else if (binNum == (xVec->n - 1))
     2575        {
    23132576            // The special case where we have two points only at the end of
    23142577            // the vectors x and y.
    23152578            // XXX: Is this right?
    23162579            tmpFloat = xVec->data.F32[binNum];
    2317         } else if (binNum == (xVec->n - 2)) {
     2580        }
     2581        else if (binNum == (xVec->n - 2))
     2582        {
    23182583            // XXX: Is this right?
    23192584            tmpFloat = 0.5 * (xVec->data.F32[binNum] + xVec->data.F32[binNum + 1]);
     
    23412606                                                          psVector *yVec,
    23422607                                                          psS32 binNum,
    2343                                                           psF32 yVal
    2344     )
     2608                                                          psF32 yVal)
    23452609{
    23462610    psTrace(TRACE, 4, "---- %s() begin ----\n", __func__);
    23472611    psTrace(TRACE, 5, "binNum, yVal is (%d, %f)\n", binNum, yVal);
    2348     if (psTraceGetLevel("psLib.math") >= 8) {
     2612    if (psTraceGetLevel("psLib.math") >= 8)
     2613    {
    23492614        PS_VECTOR_PRINT_F32(xVec);
    23502615        PS_VECTOR_PRINT_F32(yVec);
     
    23622627    psF32 tmpFloat = 0.0f;
    23632628
    2364     if ((binNum >= 1) && (binNum < (yVec->n - 2)) && (binNum < (xVec->n - 2))) {
     2629    if ((binNum >= 1) && (binNum < (yVec->n - 2)) && (binNum < (xVec->n - 2)))
     2630    {
    23652631        // The general case.  We have all three points.
    23662632        x->data.F64[0] = xVec->data.F32[binNum - 1];
    23672633        x->data.F64[1] = xVec->data.F32[binNum];
    2368         x->data.F64[2] = xVec->data.F32[binNum+1];
     2634        x->data.F64[2] = xVec->data.F32[binNum + 1];
    23692635        y->data.F64[0] = yVec->data.F32[binNum - 1];
    23702636        y->data.F64[1] = yVec->data.F32[binNum];
    23712637        y->data.F64[2] = yVec->data.F32[binNum + 1];
    23722638        psTrace(TRACE, 6, "x vec (orig) is (%f %f %f %f)\n", xVec->data.F32[binNum - 1],
    2373                 xVec->data.F32[binNum], xVec->data.F32[binNum+1], xVec->data.F32[binNum+2]);
     2639                xVec->data.F32[binNum], xVec->data.F32[binNum + 1], xVec->data.F32[binNum + 2]);
    23742640        psTrace(TRACE, 6, "x data is (%f %f %f)\n", x->data.F64[0], x->data.F64[1], x->data.F64[2]);
    23752641        psTrace(TRACE, 6, "y data is (%f %f %f)\n", y->data.F64[0], y->data.F64[1], y->data.F64[2]);
     
    23782644        // Ensure that the y value lies within range of the y values.
    23792645        //
    2380         if (! (((y->data.F64[0] <= yVal) && (yVal <= y->data.F64[2])) ||
    2381                ((y->data.F64[2] <= yVal) && (yVal <= y->data.F64[0]))) ) {
     2646        if (!(((y->data.F64[0] <= yVal) && (yVal <= y->data.F64[2])) ||
     2647              ((y->data.F64[2] <= yVal) && (yVal <= y->data.F64[0]))))
     2648        {
    23822649            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    23832650                    _("Specified yVal, %g, is not within y-range, %g to %g."),
     
    23892656        //
    23902657        if (((y->data.F64[0] < y->data.F64[1]) && !(y->data.F64[1] <= y->data.F64[2])) ||
    2391             ((y->data.F64[0] > y->data.F64[1]) && !(y->data.F64[1] >= y->data.F64[2]))) {
     2658            ((y->data.F64[0] > y->data.F64[1]) && !(y->data.F64[1] >= y->data.F64[2])))
     2659        {
    23922660            psError(PS_ERR_UNKNOWN, true,
    23932661                    "This routine must be called with monotonically increasing or decreasing data points.\n");
     
    24002668        // Determine the coefficients of the polynomial.
    24012669        psPolynomial1D *myPoly = psPolynomial1DAlloc(PS_POLYNOMIAL_ORD, 2);
    2402         if (!psVectorFitPolynomial1D(myPoly, NULL, 0, y, NULL, x)) {
     2670        if (!psVectorFitPolynomial1D(myPoly, NULL, 0, y, NULL, x))
     2671        {
    24032672            psError(PS_ERR_UNEXPECTED_NULL, false,
    24042673                    _("Failed to fit a 1-dimensional polynomial to the three specified data points.  "
     
    24132682        psTrace(TRACE, 6, "myPoly->coeff[2] is %f\n", myPoly->coeff[2]);
    24142683        psTrace(TRACE, 6, "Fitted y vec is (%f %f %f)\n",
    2415                 (psF32) psPolynomial1DEval(myPoly, (psF64) x->data.F64[0]),
    2416                 (psF32) psPolynomial1DEval(myPoly, (psF64) x->data.F64[1]),
    2417                 (psF32) psPolynomial1DEval(myPoly, (psF64) x->data.F64[2]));
     2684                (psF32)psPolynomial1DEval(myPoly, (psF64)x->data.F64[0]),
     2685                (psF32)psPolynomial1DEval(myPoly, (psF64)x->data.F64[1]),
     2686                (psF32)psPolynomial1DEval(myPoly, (psF64)x->data.F64[2]));
    24182687
    24192688        psTrace(TRACE, 6, "We fit the polynomial, now find x such that f(x) equals %f\n", yVal);
     
    24222691        psFree(myPoly);
    24232692
    2424         if (isnan(tmpFloat)) {
     2693        if (isnan(tmpFloat))
     2694        {
    24252695            psError(PS_ERR_UNEXPECTED_NULL,
    24262696                    false, _("Failed to determine the median of the fitted polynomial.  Returning NAN."));
     
    24282698            psFree(y);
    24292699            psTrace(TRACE, 5, "---- %s(NAN) end ----\n", __func__);
    2430             return(NAN);
    2431         }
    2432     } else {
     2700            return (NAN);
     2701        }
     2702    }
     2703    else
     2704    {
    24332705        // These are special cases where the bin is at the beginning or end of the vector.
    2434         if (binNum == 0) {
     2706        if (binNum == 0)
     2707        {
    24352708            // We have two points only at the beginning of the vectors x and y.
    24362709            // XXX this does not seem to be doing the linear interpolation / extrapolation
    24372710            tmpFloat = 0.5 * (xVec->data.F32[binNum] +
    24382711                              xVec->data.F32[binNum + 1]);
    2439         } else if (binNum == (xVec->n - 1)) {
     2712        }
     2713        else if (binNum == (xVec->n - 1))
     2714        {
    24402715            // The special case where we have two points only at the end of
    24412716            // the vectors x and y.
    24422717            // XXX: Is this right?
    24432718            tmpFloat = xVec->data.F32[binNum];
    2444         } else if (binNum == (xVec->n - 2)) {
     2719        }
     2720        else if (binNum == (xVec->n - 2))
     2721        {
    24452722            // XXX: Is this right?
    24462723            tmpFloat = 0.5 * (xVec->data.F32[binNum] + xVec->data.F32[binNum + 1]);
     
    24722749                                                 psVector *yVec,
    24732750                                                 psS32 binNum,
    2474                                                  psF32 yVal
    2475     )
     2751                                                 psF32 yVal)
    24762752{
    24772753    psTrace(TRACE, 5, "binNum, yVal is (%d, %f)\n", binNum, yVal);
    2478     if (psTraceGetLevel("psLib.math") >= 8) {
     2754    if (psTraceGetLevel("psLib.math") >= 8)
     2755    {
    24792756        PS_VECTOR_PRINT_F32(xVec);
    24802757        PS_VECTOR_PRINT_F32(yVec);
     
    24952772
    24962773    //    if ((binNum >= 1) && (binNum <= (yVec->n - 2)) && (binNum <= (xVec->n - 2))) {
    2497     if ((binNum >= 2) && (binNum <= (yVec->n - 3)) && (binNum <= (xVec->n - 3))) {
     2774    if ((binNum >= 2) && (binNum <= (yVec->n - 3)) && (binNum <= (xVec->n - 3)))
     2775    {
    24982776        // The general case.  We have all three points.
    2499       //        x->data.F64[0] = binNum - 1;
    2500       //        x->data.F64[1] = binNum;
    2501       //        x->data.F64[2] = binNum + 1;
    2502       x->data.F64[0] = xVec->data.F32[binNum - 2];
    2503       x->data.F64[1] = xVec->data.F32[binNum - 1];
    2504       x->data.F64[2] = xVec->data.F32[binNum + 0];
    2505       x->data.F64[3] = xVec->data.F32[binNum + 1];
    2506       x->data.F64[4] = xVec->data.F32[binNum + 2];
     2777        //        x->data.F64[0] = binNum - 1;
     2778        //        x->data.F64[1] = binNum;
     2779        //        x->data.F64[2] = binNum + 1;
     2780        x->data.F64[0] = xVec->data.F32[binNum - 2];
     2781        x->data.F64[1] = xVec->data.F32[binNum - 1];
     2782        x->data.F64[2] = xVec->data.F32[binNum + 0];
     2783        x->data.F64[3] = xVec->data.F32[binNum + 1];
     2784        x->data.F64[4] = xVec->data.F32[binNum + 2];
    25072785        y->data.F64[0] = yVec->data.F32[binNum - 2];
    25082786        y->data.F64[1] = yVec->data.F32[binNum - 1];
    25092787        y->data.F64[2] = yVec->data.F32[binNum + 0];
    2510         y->data.F64[3] = yVec->data.F32[binNum + 1];
    2511         y->data.F64[4] = yVec->data.F32[binNum + 2];
    2512         psTrace(TRACE, 6, "x vec (orig) is (%f %f %f %f)\n", xVec->data.F32[binNum - 1], xVec->data.F32[binNum], xVec->data.F32[binNum+1], xVec->data.F32[binNum+2]);
     2788        y->data.F64[3] = yVec->data.F32[binNum + 1];
     2789        y->data.F64[4] = yVec->data.F32[binNum + 2];
     2790        psTrace(TRACE, 6, "x vec (orig) is (%f %f %f %f)\n", xVec->data.F32[binNum - 1], xVec->data.F32[binNum], xVec->data.F32[binNum + 1], xVec->data.F32[binNum + 2]);
    25132791        psTrace(TRACE, 6, "x data is (%f %f %f)\n", x->data.F64[0], x->data.F64[1], x->data.F64[2]);
    25142792        psTrace(TRACE, 6, "y data is (%f %f %f)\n", y->data.F64[0], y->data.F64[1], y->data.F64[2]);
    25152793
    2516 
    25172794        // Ensure that the y value lies within range of the y values.
    2518         if (! (((y->data.F64[0] <= yVal) && (yVal <= y->data.F64[4])) ||
    2519                ((y->data.F64[4] <= yVal) && (yVal <= y->data.F64[0]))) ) {
     2795        if (!(((y->data.F64[0] <= yVal) && (yVal <= y->data.F64[4])) ||
     2796              ((y->data.F64[4] <= yVal) && (yVal <= y->data.F64[0]))))
     2797        {
    25202798            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    25212799                    _("Specified yVal, %g, is not within y-range, %g to %g."),
     
    25262804        // Ensure that the y values are monotonic.
    25272805        if (((y->data.F64[0] < y->data.F64[1]) && !(y->data.F64[1] <= y->data.F64[2])) ||
    2528             ((y->data.F64[0] > y->data.F64[1]) && !(y->data.F64[1] >= y->data.F64[2]))) {
     2806            ((y->data.F64[0] > y->data.F64[1]) && !(y->data.F64[1] >= y->data.F64[2])))
     2807        {
    25292808            psError(PS_ERR_UNKNOWN, true,
    25302809                    "This routine must be called with monotonically increasing or decreasing data points.\n");
     
    25362815        // Determine the coefficients of the polynomial.
    25372816        psPolynomial1D *myPoly = psPolynomial1DAlloc(PS_POLYNOMIAL_ORD, 2);
    2538         if (!psVectorFitPolynomial1D(myPoly, NULL, 0, y, NULL, x)) {
     2817        if (!psVectorFitPolynomial1D(myPoly, NULL, 0, y, NULL, x))
     2818        {
    25392819            psError(PS_ERR_UNEXPECTED_NULL, false,
    25402820                    _("Failed to fit a 1-dimensional polynomial to the three specified data points.  "
     
    25492829        psTrace(TRACE, 6, "myPoly->coeff[2] is %f\n", myPoly->coeff[2]);
    25502830        psTrace(TRACE, 6, "Fitted y vec is (%f %f %f)\n",
    2551                 (psF32) psPolynomial1DEval(myPoly, (psF64) x->data.F64[0]),
    2552                 (psF32) psPolynomial1DEval(myPoly, (psF64) x->data.F64[1]),
    2553                 (psF32) psPolynomial1DEval(myPoly, (psF64) x->data.F64[2]));
     2831                (psF32)psPolynomial1DEval(myPoly, (psF64)x->data.F64[0]),
     2832                (psF32)psPolynomial1DEval(myPoly, (psF64)x->data.F64[1]),
     2833                (psF32)psPolynomial1DEval(myPoly, (psF64)x->data.F64[2]));
    25542834
    25552835        psTrace(TRACE, 6, "We fit the polynomial, now find x such that f(x) equals %f\n", yVal);
     
    25572837        psFree(myPoly);
    25582838
    2559         if (isnan(binValue)) {
     2839        if (isnan(binValue))
     2840        {
    25602841            psError(PS_ERR_UNEXPECTED_NULL,
    25612842                    false, _("Failed to determine the median of the fitted polynomial.  Returning NAN."));
    25622843            psFree(x);
    25632844            psFree(y);
    2564             return(NAN);
    2565         }
    2566        
     2845            return (NAN);
     2846        }
     2847
    25672848        // I believe that mathematically the fitted bin position must be between binNum - 1 and binNum + 1
    2568         //      assert (binValue >= binNum - 1);
    2569         //      assert (binValue <= binNum + 1);
    2570 
    2571         //      int fitBin = binValue;
    2572         //        float dX = xVec->data.F32[fitBin+1] - xVec->data.F32[fitBin];
    2573         //        float dY = binValue - fitBin;
    2574         //        tmpFloat = xVec->data.F32[fitBin] + dY * dX;
    2575         tmpFloat = binValue;
    2576        
    2577     } else {
     2849        //      assert (binValue >= binNum - 1);
     2850        //      assert (binValue <= binNum + 1);
     2851
     2852        //      int fitBin = binValue;
     2853        //        float dX = xVec->data.F32[fitBin+1] - xVec->data.F32[fitBin];
     2854        //        float dY = binValue - fitBin;
     2855        //        tmpFloat = xVec->data.F32[fitBin] + dY * dX;
     2856        tmpFloat = binValue;
     2857    }
     2858    else
     2859    {
    25782860        // These are special cases where the bin is at the beginning or end of the vector.
    2579         if (binNum == 0) {
     2861        if (binNum == 0)
     2862        {
    25802863            // We have two points only at the beginning of the vectors x and y.
    25812864            // X = (dX/dY)(Y - Yo) + Xo
    25822865            float dX = xVec->data.F32[1] - xVec->data.F32[0];
    25832866            float dY = yVec->data.F32[1] - yVec->data.F32[0];
    2584             if (dY == 0.0) {
     2867            if (dY == 0.0)
     2868            {
    25852869                tmpFloat = xVec->data.F32[0];
    2586             } else {
     2870            }
     2871            else
     2872            {
    25872873                tmpFloat = (yVal - yVec->data.F32[0]) * (dX / dY) + xVec->data.F32[0];
    25882874            }
    2589         } else if (binNum == (xVec->n - 1)) {
     2875        }
     2876        else if (binNum == (xVec->n - 1))
     2877        {
    25902878            // We have two points only at the end of the vectors x and y.
    25912879            // X = (dX/dY)(Y - Yo) + Xo
    2592             float dX = xVec->data.F32[binNum] - xVec->data.F32[binNum-1];
    2593             float dY = yVec->data.F32[binNum] - yVec->data.F32[binNum-1];
    2594             if (dY == 0.0) {
    2595                 tmpFloat = xVec->data.F32[binNum-1];
    2596             } else {
    2597                 tmpFloat = (yVal - yVec->data.F32[binNum-1]) * (dX / dY) + xVec->data.F32[binNum-1];
     2880            float dX = xVec->data.F32[binNum] - xVec->data.F32[binNum - 1];
     2881            float dY = yVec->data.F32[binNum] - yVec->data.F32[binNum - 1];
     2882            if (dY == 0.0)
     2883            {
     2884                tmpFloat = xVec->data.F32[binNum - 1];
     2885            }
     2886            else
     2887            {
     2888                tmpFloat = (yVal - yVec->data.F32[binNum - 1]) * (dX / dY) + xVec->data.F32[binNum - 1];
    25982889            }
    25992890        }
     
    26062897    return tmpFloat;
    26072898}
    2608 # endif
    2609 
     2899#endif
    26102900
    26112901/******************************************************************************
     
    26232913*****************************************************************************/
    26242914static psF32 fitLinearSearchForYThenReturnBin(const psVector *xVec,
    2625                                               psVector *yVec,
    2626                                               psS32 binNum,
    2627                                               psF32 yVal
    2628     )
     2915                                              psVector *yVec,
     2916                                              psS32 binNum,
     2917                                              psF32 yVal)
    26292918{
    26302919
    2631 # if (1)
    2632 # define HALF_SIZE 2
    2633   double Sx = 0.0;
    2634 
    2635   double Sy = 0.0;
    2636   double Sxx = 0.0;
    2637   double Sxy = 0.0;
    2638   double deltaY = 0.0;
    2639   int N = 0;
    2640 
    2641   for (int u = binNum - HALF_SIZE; u <= binNum + HALF_SIZE; u++) {
    2642     if ((u >= 0)&&(u < yVec->n)) {
    2643       if (u+1 < xVec->n) {
    2644         Sx += yVec->data.F32[u];
    2645         Sxx += PS_SQR(yVec->data.F32[u]);
    2646 
    2647         deltaY = xVec->data.F32[u];
    2648         //deltaY = 0.5 * (xVec->data.F32[u] + xVec->data.F32[u+1]);
    2649         Sy += deltaY;
    2650         Sxy += yVec->data.F32[u] * deltaY;
    2651         N += 1;
    2652       }
    2653     }
    2654   }
    2655   double Det = N * Sxx - Sx * Sx;
    2656   if (Det == 0.0) return NAN;
    2657   if (N == 0) return NAN;
    2658 
    2659   double C0 = (Sy*Sxx - Sx*Sxy) / Det;
    2660   double C1 = (Sxy*N - Sx*Sy) / Det;
    2661  
    2662   double value = C0 + yVal*C1;
    2663   return value;
    2664  
    2665  
    2666 # else
     2920#if (1)
     2921#define HALF_SIZE 2
     2922    double Sx = 0.0;
     2923
     2924    double Sy = 0.0;
     2925    double Sxx = 0.0;
     2926    double Sxy = 0.0;
     2927    double deltaY = 0.0;
     2928    int N = 0;
     2929
     2930    for (int u = binNum - HALF_SIZE; u <= binNum + HALF_SIZE; u++)
     2931    {
     2932        if ((u >= 0) && (u < yVec->n))
     2933        {
     2934            if (u + 1 < xVec->n)
     2935            {
     2936                Sx += yVec->data.F32[u];
     2937                Sxx += PS_SQR(yVec->data.F32[u]);
     2938
     2939                deltaY = xVec->data.F32[u];
     2940                // deltaY = 0.5 * (xVec->data.F32[u] + xVec->data.F32[u+1]);
     2941                Sy += deltaY;
     2942                Sxy += yVec->data.F32[u] * deltaY;
     2943                N += 1;
     2944            }
     2945        }
     2946    }
     2947    double Det = N * Sxx - Sx * Sx;
     2948    if (Det == 0.0)
     2949        return NAN;
     2950    if (N == 0)
     2951        return NAN;
     2952
     2953    double C0 = (Sy * Sxx - Sx * Sxy) / Det;
     2954    double C1 = (Sxy * N - Sx * Sy) / Det;
     2955
     2956    double value = C0 + yVal * C1;
     2957    return value;
     2958
     2959#else
    26672960    psTrace(TRACE, 5, "binNum, yVal is (%d, %f)\n", binNum, yVal);
    2668     if (psTraceGetLevel("psLib.math") >= 8) {
     2961    if (psTraceGetLevel("psLib.math") >= 8)
     2962    {
    26692963        PS_VECTOR_PRINT_F32(xVec);
    26702964        PS_VECTOR_PRINT_F32(yVec);
     
    26842978    psF32 tmpFloat = 0.0f;
    26852979
    2686     if ((binNum >= 2) && (binNum <= (yVec->n - 3)) && (binNum <= (xVec->n - 3))) {
    2687         x->data.F64[0] = xVec->data.F32[binNum - 2];
    2688         x->data.F64[1] = xVec->data.F32[binNum - 1];
    2689         x->data.F64[2] = xVec->data.F32[binNum + 0];
    2690         x->data.F64[3] = xVec->data.F32[binNum + 1];
    2691         x->data.F64[4] = xVec->data.F32[binNum + 2];
    2692 
    2693         y->data.F64[0] = yVec->data.F32[binNum - 2];
    2694         y->data.F64[1] = yVec->data.F32[binNum - 1];
    2695         y->data.F64[2] = yVec->data.F32[binNum + 0];
    2696         y->data.F64[3] = yVec->data.F32[binNum + 1];
    2697         y->data.F64[4] = yVec->data.F32[binNum + 2];
    2698         psTrace(TRACE, 6, "x vec (orig) is (%f %f %f %f)\n", xVec->data.F32[binNum - 1], xVec->data.F32[binNum], xVec->data.F32[binNum+1], xVec->data.F32[binNum+2]);
    2699         psTrace(TRACE, 6, "x data is (%f %f %f)\n", x->data.F64[0], x->data.F64[1], x->data.F64[2]);
    2700         psTrace(TRACE, 6, "y data is (%f %f %f)\n", y->data.F64[0], y->data.F64[1], y->data.F64[2]);
    2701 
    2702         // Ensure that the y value lies within range of the y values.
    2703         if (! (((y->data.F64[0] <= yVal) && (yVal <= y->data.F64[4])) ||
    2704                ((y->data.F64[4] <= yVal) && (yVal <= y->data.F64[0]))) ) {
    2705             psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    2706                     _("Specified yVal, %g, is not within y-range, %g to %g."),
     2980    if ((binNum >= 2) && (binNum <= (yVec->n - 3)) && (binNum <= (xVec->n - 3)))
     2981    {
     2982        x->data.F64[0] = xVec->data.F32[binNum - 2];
     2983        x->data.F64[1] = xVec->data.F32[binNum - 1];
     2984        x->data.F64[2] = xVec->data.F32[binNum + 0];
     2985        x->data.F64[3] = xVec->data.F32[binNum + 1];
     2986        x->data.F64[4] = xVec->data.F32[binNum + 2];
     2987
     2988        y->data.F64[0] = yVec->data.F32[binNum - 2];
     2989        y->data.F64[1] = yVec->data.F32[binNum - 1];
     2990        y->data.F64[2] = yVec->data.F32[binNum + 0];
     2991        y->data.F64[3] = yVec->data.F32[binNum + 1];
     2992        y->data.F64[4] = yVec->data.F32[binNum + 2];
     2993        psTrace(TRACE, 6, "x vec (orig) is (%f %f %f %f)\n", xVec->data.F32[binNum - 1], xVec->data.F32[binNum], xVec->data.F32[binNum + 1], xVec->data.F32[binNum + 2]);
     2994        psTrace(TRACE, 6, "x data is (%f %f %f)\n", x->data.F64[0], x->data.F64[1], x->data.F64[2]);
     2995        psTrace(TRACE, 6, "y data is (%f %f %f)\n", y->data.F64[0], y->data.F64[1], y->data.F64[2]);
     2996
     2997        // Ensure that the y value lies within range of the y values.
     2998        if (!(((y->data.F64[0] <= yVal) && (yVal <= y->data.F64[4])) ||
     2999              ((y->data.F64[4] <= yVal) && (yVal <= y->data.F64[0]))))
     3000        {
     3001            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     3002                    _("Specified yVal, %g, is not within y-range, %g to %g."),
    27073003                    (psF64)yVal, y->data.F64[0], y->data.F64[2]);
    27083004            return NAN;
     
    27113007        // Ensure that the y values are monotonic.
    27123008        if (((y->data.F64[0] < y->data.F64[1]) && !(y->data.F64[1] <= y->data.F64[2])) ||
    2713             ((y->data.F64[0] > y->data.F64[1]) && !(y->data.F64[1] >= y->data.F64[2]))) {
     3009            ((y->data.F64[0] > y->data.F64[1]) && !(y->data.F64[1] >= y->data.F64[2])))
     3010        {
    27143011            psError(PS_ERR_UNKNOWN, true,
    27153012                    "This routine must be called with monotonically increasing or decreasing data points.\n");
     
    27213018        // Determine the coefficients of the polynomial.
    27223019        psPolynomial1D *myPoly = psPolynomial1DAlloc(PS_POLYNOMIAL_ORD, 1);
    2723         if (!psVectorFitPolynomial1D(myPoly, NULL, 0, y, NULL, x)) {
     3020        if (!psVectorFitPolynomial1D(myPoly, NULL, 0, y, NULL, x))
     3021        {
    27243022            psError(PS_ERR_UNEXPECTED_NULL, false,
    27253023                    _("Failed to fit a 1-dimensional polynomial to the three specified data points.  "
     
    27333031        psTrace(TRACE, 6, "myPoly->coeff[1] is %f\n", myPoly->coeff[1]);
    27343032        psTrace(TRACE, 6, "Fitted y vec is (%f %f)\n",
    2735                 (psF32) psPolynomial1DEval(myPoly, (psF64) x->data.F64[0]),
    2736                 (psF32) psPolynomial1DEval(myPoly, (psF64) x->data.F64[1]));
     3033                (psF32)psPolynomial1DEval(myPoly, (psF64)x->data.F64[0]),
     3034                (psF32)psPolynomial1DEval(myPoly, (psF64)x->data.F64[1]));
    27373035
    27383036        psTrace(TRACE, 6, "We fit the polynomial, now find x such that f(x) equals %f\n", yVal);
     
    27403038        psFree(myPoly);
    27413039
    2742         if (isnan(binValue)) {
     3040        if (isnan(binValue))
     3041        {
    27433042            psError(PS_ERR_UNEXPECTED_NULL,
    27443043                    false, _("Failed to determine the median of the fitted polynomial.  Returning NAN."));
    27453044            psFree(x);
    27463045            psFree(y);
    2747             return(NAN);
    2748         }
    2749        
     3046            return (NAN);
     3047        }
     3048
    27503049        // I believe that mathematically the fitted bin position must be between binNum - 1 and binNum + 1
    2751         //      assert (binValue >= binNum - 1);
    2752         //      assert (binValue <= binNum + 1);
    2753 
    2754         //      int fitBin = binValue;
    2755         //        float dX = xVec->data.F32[fitBin+1] - xVec->data.F32[fitBin];
    2756         //        float dY = binValue - fitBin;
    2757         //        tmpFloat = xVec->data.F32[fitBin] + dY * dX;
    2758         tmpFloat = binValue;
    2759                
    2760        
    2761     } else {
     3050        //      assert (binValue >= binNum - 1);
     3051        //      assert (binValue <= binNum + 1);
     3052
     3053        //      int fitBin = binValue;
     3054        //        float dX = xVec->data.F32[fitBin+1] - xVec->data.F32[fitBin];
     3055        //        float dY = binValue - fitBin;
     3056        //        tmpFloat = xVec->data.F32[fitBin] + dY * dX;
     3057        tmpFloat = binValue;
     3058    }
     3059    else
     3060    {
    27623061        // These are special cases where the bin is at the beginning or end of the vector.
    2763         if (binNum == 0) {
     3062        if (binNum == 0)
     3063        {
    27643064            // We have two points only at the beginning of the vectors x and y.
    27653065            // X = (dX/dY)(Y - Yo) + Xo
    27663066            float dX = xVec->data.F32[1] - xVec->data.F32[0];
    27673067            float dY = yVec->data.F32[1] - yVec->data.F32[0];
    2768             if (dY == 0.0) {
     3068            if (dY == 0.0)
     3069            {
    27693070                tmpFloat = xVec->data.F32[0];
    2770             } else {
     3071            }
     3072            else
     3073            {
    27713074                tmpFloat = (yVal - yVec->data.F32[0]) * (dX / dY) + xVec->data.F32[0];
    27723075            }
    2773         } else if (binNum == (xVec->n - 1)) {
     3076        }
     3077        else if (binNum == (xVec->n - 1))
     3078        {
    27743079            // We have two points only at the end of the vectors x and y.
    27753080            // X = (dX/dY)(Y - Yo) + Xo
    2776             float dX = xVec->data.F32[binNum] - xVec->data.F32[binNum-1];
    2777             float dY = yVec->data.F32[binNum] - yVec->data.F32[binNum-1];
    2778             if (dY == 0.0) {
    2779                 tmpFloat = xVec->data.F32[binNum-1];
    2780             } else {
    2781                 tmpFloat = (yVal - yVec->data.F32[binNum-1]) * (dX / dY) + xVec->data.F32[binNum-1];
     3081            float dX = xVec->data.F32[binNum] - xVec->data.F32[binNum - 1];
     3082            float dY = yVec->data.F32[binNum] - yVec->data.F32[binNum - 1];
     3083            if (dY == 0.0)
     3084            {
     3085                tmpFloat = xVec->data.F32[binNum - 1];
     3086            }
     3087            else
     3088            {
     3089                tmpFloat = (yVal - yVec->data.F32[binNum - 1]) * (dX / dY) + xVec->data.F32[binNum - 1];
    27823090            }
    27833091        }
     
    27893097
    27903098    return tmpFloat;
    2791 # endif
     3099#endif
    27923100}
  • branches/2dbias/psLib/src/math/psStats.h

    r31152 r42719  
    2727 *  @see psStats, psVectorStats, psImageStats
    2828 */
    29 typedef enum {
    30     PS_STAT_NONE            = 0x000000, ///< Empty set
    31     PS_STAT_MIN             = 0x000001, ///< Maximum
    32     PS_STAT_MAX             = 0x000002, ///< Minumum
    33     PS_STAT_SAMPLE_MEAN     = 0x000004, ///< Sample Mean
    34     PS_STAT_SAMPLE_MEDIAN   = 0x000008, ///< Sample Median
    35     PS_STAT_SAMPLE_STDEV    = 0x000010, ///< Sample Standard Deviation
    36     PS_STAT_SAMPLE_QUARTILE = 0x000020, ///< Sample Quartile
    37     PS_STAT_SAMPLE_SKEWNESS = 0x000040, ///< Sample Skewness (third moment)
    38     PS_STAT_SAMPLE_KURTOSIS = 0x000080, ///< Sample Kurtosis (fourth moment)
    39     PS_STAT_ROBUST_MEDIAN   = 0x000100, ///< Robust Median
    40     PS_STAT_ROBUST_STDEV    = 0x000200, ///< Robust Standarad Deviation
    41     PS_STAT_ROBUST_QUARTILE = 0x000400, ///< Robust Quartile
    42     PS_STAT_ROBUST_SPARE1   = 0x000800, ///< Spare 1
    43     PS_STAT_FITTED_MEAN     = 0x001000, ///< Fitted Mean
    44     PS_STAT_FITTED_STDEV    = 0x002000, ///< Fitted Standard Deviation
    45     PS_STAT_CLIPPED_MEAN    = 0x040000, ///< Clipped Mean
    46     PS_STAT_CLIPPED_STDEV   = 0x080000, ///< Clipped Standard Deviation
    47     PS_STAT_USE_RANGE       = 0x100000, ///< Range
    48     PS_STAT_USE_BINSIZE     = 0x200000, ///< Binsize
     29typedef enum
     30{
     31  PS_STAT_NONE = 0x000000,            ///< Empty set
     32  PS_STAT_MIN = 0x000001,             ///< Maximum
     33  PS_STAT_MAX = 0x000002,             ///< Minumum
     34  PS_STAT_SAMPLE_MEAN = 0x000004,     ///< Sample Mean
     35  PS_STAT_SAMPLE_MEDIAN = 0x000008,   ///< Sample Median
     36  PS_STAT_SAMPLE_STDEV = 0x000010,    ///< Sample Standard Deviation
     37  PS_STAT_SAMPLE_QUARTILE = 0x000020, ///< Sample Quartile
     38  PS_STAT_SAMPLE_SKEWNESS = 0x000040, ///< Sample Skewness (third moment)
     39  PS_STAT_SAMPLE_KURTOSIS = 0x000080, ///< Sample Kurtosis (fourth moment)
     40  PS_STAT_ROBUST_MEDIAN = 0x000100,   ///< Robust Median
     41  PS_STAT_ROBUST_STDEV = 0x000200,    ///< Robust Standarad Deviation
     42  PS_STAT_ROBUST_QUARTILE = 0x000400, ///< Robust Quartile
     43  PS_STAT_ROBUST_SPARE1 = 0x000800,   ///< Spare 1
     44  PS_STAT_FITTED_MEAN = 0x001000,     ///< Fitted Mean
     45  PS_STAT_FITTED_STDEV = 0x002000,    ///< Fitted Standard Deviation
     46  PS_STAT_CLIPPED_MEDIAN = 0x020000,  ///< Clipped Median
     47  PS_STAT_CLIPPED_MEAN = 0x040000,    ///< Clipped Mean
     48  PS_STAT_CLIPPED_STDEV = 0x080000,   ///< Clipped Standard Deviation
     49  PS_STAT_USE_RANGE = 0x100000,       ///< Range
     50  PS_STAT_USE_BINSIZE = 0x200000,     ///< Binsize
    4951} psStatsOptions;
    5052
     
    5456typedef struct
    5557{
    56     double sampleMean;                 ///< formal mean of sample
    57     double sampleMedian;               ///< formal median of sample
    58     double sampleStdev;                ///< standard deviation of sample
    59     double sampleUQ;                   ///< upper quartile of sample
    60     double sampleLQ;                   ///< lower quartile of sample
    61     double sampleSkewness;             ///< skewness (third moment) of sample
    62     double sampleKurtosis;             ///< kurtosis (fourth moment) of sample
    63     double robustMedian;               ///< robust median of array
    64     double robustStdev;                ///< robust standard deviation of array
    65     double robustUQ;                   ///< robust upper quartile
    66     double robustLQ;                   ///< robust lower quartile
    67     long robustN50;                    ///< Number of points in Gaussian fit; XXX: This is currently unused.
    68     double fittedMean;                 ///< robust mean of data
    69     double fittedStdev;                ///< robust standard deviation of data
    70     long fittedNfit;                   ///< Number of points in Gaussian fit; XXX: This is currently unused
    71     double clippedMean;                ///< Nsigma clipped mean
    72     double clippedStdev;               ///< standard deviation after clipping
    73     long clippedNvalues;               ///< Number of data points used for clipped mean.
    74     double clipSigma;                  ///< Nsigma used for clipping; user input
    75     int clipIter;                      ///< Number of clipping iterations; user input
    76     double min;                        ///< minimum data value in array
    77     double max;                        ///< maximum data value in array
    78     double binsize;                    ///< binsize for robust fit (input/ouput)
    79     long nSubsample;                   ///< maxinum number of measurements (input)
    80     psStatsOptions options;            ///< bitmask of values requested
    81     psStatsOptions results;            ///< bitmask of values calculated
    82     psVector *tmpData;                 ///< temporary vector so repeated calls do not have to realloc
    83     psVector *tmpMask;                 ///< temporary vector so repeated calls do not have to realloc
    84 }
    85 psStats;
     58  double sampleMean;      ///< formal mean of sample
     59  double sampleMedian;    ///< formal median of sample
     60  double sampleStdev;     ///< standard deviation of sample
     61  double sampleUQ;        ///< upper quartile of sample
     62  double sampleLQ;        ///< lower quartile of sample
     63  double sampleSkewness;  ///< skewness (third moment) of sample
     64  double sampleKurtosis;  ///< kurtosis (fourth moment) of sample
     65  double robustMedian;    ///< robust median of array
     66  double robustStdev;     ///< robust standard deviation of array
     67  double robustUQ;        ///< robust upper quartile
     68  double robustLQ;        ///< robust lower quartile
     69  long robustN50;         ///< Number of points in Gaussian fit; XXX: This is currently unused.
     70  double fittedMean;      ///< robust mean of data
     71  double fittedStdev;     ///< robust standard deviation of data
     72  long fittedNfit;        ///< Number of points in Gaussian fit; XXX: This is currently unused
     73  double clippedMean;     ///< Nsigma clipped mean
     74  double clippedMedian;   ///< Nsigma clipped median
     75  double clippedStdev;    ///< standard deviation after clipping
     76  long clippedNvalues;    ///< Number of data points used for clipped mean.
     77  double clipSigma;       ///< Nsigma used for clipping; user input
     78  int clipIter;           ///< Number of clipping iterations; user input
     79  double min;             ///< minimum data value in array
     80  double max;             ///< maximum data value in array
     81  double binsize;         ///< binsize for robust fit (input/ouput)
     82  long nSubsample;        ///< maxinum number of measurements (input)
     83  psStatsOptions options; ///< bitmask of values requested
     84  psStatsOptions results; ///< bitmask of values calculated
     85  psVector *tmpData;      ///< temporary vector so repeated calls do not have to realloc
     86  psVector *tmpMask;      ///< temporary vector so repeated calls do not have to realloc
     87} psStats;
    8688
    8789/** Performs statistical calculations on a vector.
     
    9092 */
    9193bool psVectorStats(
    92     psStats* stats,            ///< stats structure defines stats to be calculated and how
    93     const psVector* in,                 ///< Vector to be analysed.
    94     const psVector* errors,             ///< Errors.
    95     const psVector* mask, ///< Ignore elements where (maskVector & maskVal) != 0: must be INT or NULL
     94    psStats *stats,          ///< stats structure defines stats to be calculated and how
     95    const psVector *in,      ///< Vector to be analysed.
     96    const psVector *errors,  ///< Errors.
     97    const psVector *mask,    ///< Ignore elements where (maskVector & maskVal) != 0: must be INT or NULL
    9698    psVectorMaskType maskVal ///< Only mask elements with one of these bits set in maskVector
    9799);
     
    103105 */
    104106#ifdef DOXYGEN
    105 psStats* psStatsAlloc(
    106     psStatsOptions options              ///< Statistics to calculate
     107psStats *psStatsAlloc(
     108    psStatsOptions options ///< Statistics to calculate
    107109);
    108110#else // ifdef DOXYGEN
    109 psStats* p_psStatsAlloc(
    110     const char *file,                   ///< File of caller
    111     unsigned int lineno,                ///< Line number of caller
    112     const char *func,                   ///< Function name of caller
    113     psStatsOptions options              ///< Statistics to calculate
    114 ) PS_ATTR_MALLOC;
     111psStats *p_psStatsAlloc(
     112    const char *file,      ///< File of caller
     113    unsigned int lineno,   ///< Line number of caller
     114    const char *func,      ///< Function name of caller
     115    psStatsOptions options ///< Statistics to calculate
     116    ) PS_ATTR_MALLOC;
    115117#define psStatsAlloc(options) \
    116       p_psStatsAlloc(__FILE__, __LINE__, __func__, options)
     118  p_psStatsAlloc(__FILE__, __LINE__, __func__, options)
    117119#endif // ifdef DOXYGEN
    118120
     
    124126 */
    125127bool psMemCheckStats(
    126     psPtr ptr                          ///< the pointer whose type to check
     128    psPtr ptr ///< the pointer whose type to check
    127129);
    128130
  • branches/2dbias/psLib/src/math/psVectorSmooth.c

    r42715 r42719  
    172172            if (robust)                                                            \
    173173            {                                                                      \
    174                 statistic = PS_STAT_CLIPPED_MEAN;                                  \
     174                statistic = PS_STAT_CLIPPED_MEDIAN;                                \
    175175                stats = psStatsAlloc(statistic);                                   \
     176                stats->clipSigma = 2.5;                                            \
    176177            }                                                                      \
    177178            else                                                                   \
  • branches/2dbias/psModules/src/detrend/pmOverscan.c

    r42717 r42719  
    415415                // Reduce the overscans
    416416                // XXX need to save 2 different chi-square values
    417                 psVector *yReduced = pmOverscanVector(&chi2, overscanOpts->primary, yscanPixels, false);
     417                psVector *yReduced = pmOverscanVector(&chi2, overscanOpts->primary, yscanPixels, true);
    418418                psFree(yscanPixels);
    419419                if (!yReduced)
     
    453453                        }
    454454                        // Now normVector holds the sliced data; then, compute its robust mean
    455                         psStatsOptions statistic = PS_STAT_CLIPPED_MEAN;
     455                        psStatsOptions statistic = PS_STAT_ROBUST_MEDIAN;
    456456                        psStats *stats = psStatsAlloc(statistic);
    457457                        if (!psVectorStats(stats, normVector, NULL, NULL, 0))
    458458                        {
    459                                 psError(PS_ERR_UNKNOWN, false, "failure to measure clipped mean as normalization of xReduced");
     459                                psError(PS_ERR_UNKNOWN, false, "failure to measure robust median as the normalization of xReduced");
    460460                                psFree(stats);
    461461                                psFree(normVector);
Note: See TracChangeset for help on using the changeset viewer.