IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
May 27, 2004, 4:45:31 PM (22 years ago)
Author:
gusciora
Message:

More mods to get in sync with the latest SDRS.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/math/psStats.c

    r796 r797  
    1515
    1616#include "float.h"
    17 #define ROBUST_SIZE_THRESHOLD 10000   // Vectors that are large than this
     17#define ROBUST_SIZE_THRESHOLD 30000   // Vectors that are large than this
    1818// will use robust statistical methods.
    1919#define GAUSS_WIDTH 20                  // The width of the Gaussian or boxcar
     
    2727#define false 0
    2828#define MYMAXFLOAT 1e99
     29
     30void p_psVectorRobustStats(const psVector *restrict myVector,
     31                           const psVector *restrict maskVector,
     32                           unsigned int maskVal,
     33                           psStats *stats);
    2934/******************************************************************************
    3035    psStatsAlloc(): This routine must create a new psStats data structure.
     
    4045    newStruct->sampleUQ = NAN;
    4146    newStruct->sampleLQ = NAN;
    42     newStruct->sampleLimit = NAN;
     47    newStruct->sampleLimit = ROBUST_SIZE_THRESHOLD;
    4348    newStruct->robustMean = NAN;
    4449    newStruct->robustMedian = NAN;
     
    5156    newStruct->clippedMean = NAN;
    5257    newStruct->clippedStdev = NAN;
    53     newStruct->clipSigma = NAN;
    54     newStruct->clipIter = -1;
     58    newStruct->clipSigma = 3.0;
     59    newStruct->clipIter = 3.0;
    5560    newStruct->min = NAN;
    5661    newStruct->max = NAN;
     
    187192                   psVector *maskVector,
    188193                   unsigned int maskVal,
    189                    psStats *newStruct)
     194                   psStats *stats)
    190195{
    191196    int i = 0;
     
    207212 ******************************************************************************
    208213 *****************************************************************************/
     214
     215
     216/******************************************************************************
     217    ASSUMPTION: the mean is always calculated exactly.  Robust means are never
     218    calculated in this routine.
     219 *****************************************************************************/
    209220void p_psVectorSampleMean(const psVector *restrict myVector,
    210221                          const psVector *restrict maskVector,
     
    368379
    369380/******************************************************************************
    370  This routine calculates the number of non-masked pixels in the vector.
     381    This routine calculates the number of non-masked pixels in the vector.
     382    that fall within the min/max range, if given.
    371383 *****************************************************************************/
    372384int p_psVectorNValues(const psVector *restrict myVector,
    373385                      const psVector *restrict maskVector,
    374386                      unsigned int maskVal,
    375                       psStats *newStruct)
     387                      psStats *stats)
    376388{
    377389    int i = 0;
    378390    int numData = 0;
    379 
    380     if (maskVector != NULL) {
    381         for (i=0;i<myVector->n;i++) {
    382             if (!(maskVal & maskVector->vec.ui8[i])) {
    383                 numData++;
     391    float rangeMin = 0.0;
     392    float rangeMax = 0.0;
     393
     394    if (stats->options & PS_STAT_USE_RANGE) {
     395        rangeMin = stats->min;
     396        rangeMax = stats->max;
     397        if (maskVector != NULL) {
     398            for (i=0;i<myVector->n;i++) {
     399                if (!(maskVal & maskVector->vec.ui8[i]) &&
     400                        (rangeMin <= myVector->vec.f[i]) &&
     401                        (myVector->vec.f[i] <= rangeMax)) {
     402                    numData++;
     403                }
     404            }
     405        } else {
     406            for (i=0;i<myVector->n;i++) {
     407                if ((rangeMin <= myVector->vec.f[i]) &&
     408                        (myVector->vec.f[i] <= rangeMax)) {
     409                    numData++;
     410                }
    384411            }
    385412        }
    386413    } else {
    387         numData = myVector->n;
     414        rangeMin = stats->min;
     415        rangeMax = stats->max;
     416        if (maskVector != NULL) {
     417            for (i=0;i<myVector->n;i++) {
     418                if (!(maskVal & maskVector->vec.ui8[i])) {
     419                    numData++;
     420                }
     421            }
     422        } else {
     423            numData = myVector->n;
     424        }
    388425    }
    389426    return(numData);
     
    395432                            const psVector *restrict maskVector,
    396433                            unsigned int maskVal,
    397                             psStats *newStruct)
     434                            psStats *stats)
    398435{
    399436    psVector *unsortedVector = NULL;
     
    401438    int count = 0;
    402439    int i = 0;
    403     float median = 0.0;
    404440    int nValues = 0;
    405 
    406     nValues = p_psVectorNValues(myVector, maskVector, maskVal, newStruct);
     441    float rangeMin = 0.0;
     442    float rangeMax = 0.0;
     443    psStats *stats2 = NULL;
     444
     445
     446    // Determine if the number of data points exceed a threshold which will
     447    // cause to generate robust stats, as opposed to exact stats.
     448
     449    if (myVector->n > stats->sampleLimit) {
     450        // Calculate the robust quartiles.
     451        stats2 = psStatsAlloc(PS_STAT_ROBUST_MEDIAN);
     452        p_psVectorRobustStats(myVector, maskVector, maskVal, stats2);
     453
     454        // Store the robust quartiles into the sample quartile members.
     455        stats->sampleMedian = stats2->robustMedian;
     456
     457        // Free temporary data buffers.
     458        psStatsFree(stats2);
     459
     460        // Set the PS_STAT_ROBUST_FOR_SAMPLE bit in the stats structure.
     461        stats->options = stats->options | PS_STAT_ROBUST_FOR_SAMPLE;
     462
     463        return;
     464    }
     465
     466    // Determine how many data points fit inside this min/max range
     467    // and are not maxed, IF the maskVector is not NULL>
     468    nValues = p_psVectorNValues(myVector, maskVector, maskVal, stats);
     469
     470    // Allocate temporary vectors for the data.
    407471    unsortedVector = psVectorAlloc(PS_TYPE_FLOAT, nValues);
    408472    unsortedVector->n = unsortedVector->nalloc;
     
    410474    sortedVector->n = sortedVector->nalloc;
    411475
    412     if (maskVector != NULL) {
    413         for (i=0;i<myVector->n;i++) {
    414             if (!(maskVal & maskVector->vec.ui8[i])) {
    415                 unsortedVector->vec.f[count++] = myVector->vec.f[i];
    416 
    417             }
    418         }
    419         psSort(sortedVector, unsortedVector);
     476    // Determine if we must only use data points within a min/max range.
     477    if (stats->options & PS_STAT_USE_RANGE) {
     478        rangeMin = stats->min;
     479        rangeMax = stats->max;
     480
     481        // Store all non-masked data points within the min/max range
     482        // into the temporary vectors.
     483        count = 0;
     484        if (maskVector != NULL) {
     485            for (i=0;i<myVector->n;i++) {
     486                if (!(maskVal & maskVector->vec.ui8[i]) &&
     487                        (rangeMin <= myVector->vec.f[i]) &&
     488                        (myVector->vec.f[i] <= rangeMax)) {
     489                    unsortedVector->vec.f[count++] = maskVector->vec.f[i];
     490                }
     491            }
     492        } else {
     493            for (i=0;i<myVector->n;i++) {
     494                if ((rangeMin <= myVector->vec.f[i]) &&
     495                        (myVector->vec.f[i] <= rangeMax)) {
     496                    unsortedVector->vec.f[count++] = maskVector->vec.f[i];
     497                }
     498            }
     499        }
    420500    } else {
    421         psSort(sortedVector, myVector);
    422     }
    423 
     501        // Store all non-masked data points into the temporary vectors.
     502        count = 0;
     503        if (maskVector != NULL) {
     504            for (i=0;i<myVector->n;i++) {
     505                if (!(maskVal & maskVector->vec.ui8[i])) {
     506                    unsortedVector->vec.f[count++] = maskVector->vec.f[i];
     507                }
     508            }
     509        } else {
     510            for (i=0;i<myVector->n;i++) {
     511                unsortedVector->vec.f[i] = maskVector->vec.f[i];
     512            }
     513        }
     514    }
     515    // Sort the temporary vectors.
     516    psSort(sortedVector, unsortedVector);
     517
     518    // Calculate the median exactly.
    424519    if (0 == (nValues % 2)) {
    425         median = 0.5 * (sortedVector->vec.f[(nValues/2)-1] +
    426                         sortedVector->vec.f[nValues/2]);
     520        stats->sampleMedian = 0.5 * (sortedVector->vec.f[(nValues/2)-1] +
     521                                     sortedVector->vec.f[nValues/2]);
    427522    } else {
    428         median = sortedVector->vec.f[nValues/2];
    429     }
    430 
     523        stats->sampleMedian = sortedVector->vec.f[nValues/2];
     524    }
     525
     526    // Free the temporary data structures.
    431527    psVectorFree(unsortedVector);
    432528    psVectorFree(sortedVector);
    433     newStruct->sampleMedian = median;
    434 }
    435 
     529}
     530
     531/******************************************************************************
     532    This routine smoothes the data in the input robustHistogram with a
     533    Gaussian of width sigma.
     534 *****************************************************************************/
    436535void p_psVectorsmoothHistGaussian(psHistogram *robustHistogram,
    437536                                  float sigma)
     
    481580    p_psVectorSampleQuartiles()
    482581 This procedure calculates the upper and/or lower quartiles of the
    483  data set.  It is assumed that the data set is small enough that we
    484  can sort all the data points and calculate the quartiles exactly.
     582 data set.
     583 
    485584 *****************************************************************************/
    486585void p_psVectorSampleQuartiles(const psVector *restrict myVector,
    487586                               const psVector *restrict maskVector,
    488587                               unsigned int maskVal,
    489                                psStats *newStruct)
     588                               psStats *stats)
    490589{
    491590    psVector *unsortedVector = NULL;
     
    495594    int i = 0;
    496595    int nValues = 0;
    497 
    498     // return is we have already calculated both quartile points.
    499     if ((!isnan(newStruct->sampleLQ)) &&
    500             (!isnan(newStruct->sampleUQ))) {
     596    float rangeMin = 0.0;
     597    float rangeMax = 0.0;
     598    psStats *stats2 = NULL;
     599
     600    // Determine if the number of data points exceed a threshold which will
     601    // cause to generate robust stats, as opposed to exact stats.
     602    if (myVector->n > stats->sampleLimit) {
     603        // Calculate the robust quartiles.
     604        stats2 = psStatsAlloc(PS_STAT_ROBUST_QUARTILE);
     605        p_psVectorRobustStats(myVector, maskVector, maskVal, stats2);
     606
     607        // Store the robust quartiles into the sample quartile members.
     608        stats->sampleUQ = stats2->robustUQ;
     609        stats->sampleLQ = stats2->robustLQ;
     610
     611        // Free temporary data buffers.
     612        psStatsFree(stats2);
     613
     614        // Set the PS_STAT_ROBUST_FOR_SAMPLE bit in the stats structure.
     615        stats->options = stats->options | PS_STAT_ROBUST_FOR_SAMPLE;
     616
    501617        return;
    502618    }
    503619
    504     nValues = p_psVectorNValues(myVector, maskVector, maskVal, newStruct);
    505 
     620    // Determine how many data points fit inside this min/max range
     621    // and are not maxed, IF the maskVector is not NULL>
     622    nValues = p_psVectorNValues(myVector, maskVector, maskVal, stats);
     623
     624    // Allocate temporary vectors for the data.
    506625    unsortedVector = psVectorAlloc(PS_TYPE_FLOAT, nValues);
     626    unsortedVector->n = unsortedVector->nalloc;
    507627    sortedVector   = psVectorAlloc(PS_TYPE_FLOAT, nValues);
    508 
    509     count = 0;
    510     if (maskVector != NULL) {
    511         for (i=0;i<myVector->n;i++) {
    512             if (!(maskVal & maskVector->vec.ui8[i])) {
    513                 unsortedVector->vec.f[count++] = maskVector->vec.f[i];
    514             }
    515         }
    516         psSort(sortedVector, unsortedVector);
     628    sortedVector->n = sortedVector->nalloc;
     629
     630    // Determine if we must only use data points within a min/max range.
     631    if (stats->options & PS_STAT_USE_RANGE) {
     632        rangeMin = stats->min;
     633        rangeMax = stats->max;
     634        // Store all non-masked data points within the min/max range
     635        // into the temporary vectors.
     636        count = 0;
     637        if (maskVector != NULL) {
     638            for (i=0;i<myVector->n;i++) {
     639                if (!(maskVal & maskVector->vec.ui8[i]) &&
     640                        (rangeMin <= myVector->vec.f[i]) &&
     641                        (myVector->vec.f[i] <= rangeMax)) {
     642                    unsortedVector->vec.f[count++] = maskVector->vec.f[i];
     643                }
     644            }
     645        } else {
     646            for (i=0;i<myVector->n;i++) {
     647                if ((rangeMin <= myVector->vec.f[i]) &&
     648                        (myVector->vec.f[i] <= rangeMax)) {
     649                    unsortedVector->vec.f[count++] = maskVector->vec.f[i];
     650                }
     651            }
     652        }
    517653    } else {
    518         psSort(sortedVector, myVector);
    519     }
    520 
     654        // Store all non-masked data points into the temporary vectors.
     655        count = 0;
     656        if (maskVector != NULL) {
     657            for (i=0;i<myVector->n;i++) {
     658                if (!(maskVal & maskVector->vec.ui8[i])) {
     659                    unsortedVector->vec.f[count++] = maskVector->vec.f[i];
     660                }
     661            }
     662        } else {
     663            for (i=0;i<myVector->n;i++) {
     664                unsortedVector->vec.f[i] = maskVector->vec.f[i];
     665            }
     666        }
     667    }
     668
     669    // Sort the temporary vectors.
     670    psSort(sortedVector, unsortedVector);
     671
     672    // Calculate the quartile points exactly.
    521673    ind = 3 * (nValues / 4);
    522     newStruct->sampleUQ = sortedVector->vec.f[ind];
     674    stats->sampleUQ = sortedVector->vec.f[ind];
    523675    ind = (nValues / 4);
    524     newStruct->sampleLQ = sortedVector->vec.f[ind];
    525 
     676    stats->sampleLQ = sortedVector->vec.f[ind];
     677
     678    // Free the temporary data structures.
    526679    psVectorFree(unsortedVector);
    527680    psVectorFree(sortedVector);
     
    530683
    531684/******************************************************************************
    532     p_psVectorRobustStats(): this procedure calcualtes a variety of robust
     685    p_psVectorRobustStats(): this procedure calculates a variety of robust
    533686    stat measures:
    534  PS_STAT_ROBUST_MEAN
     687        PS_STAT_ROBUST_MEAN
    535688        PS_STAT_ROBUST_MEDIAN
    536689        PS_STAT_ROBUST_MODE
    537690        PS_STAT_ROBUST_STDEV
     691        PS_STAT_ROBUST_QUARTILE
    538692    I have included all that computation in a single function, as opposed to
    539693    breaking it across several functions for one primary reason: the all
     
    547701                           const psVector *restrict maskVector,
    548702                           unsigned int maskVal,
    549                            psStats *newStruct)
     703                           psStats *stats)
    550704{
    551705    psHistogram *robustHistogram = NULL;
     
    565719    // is really required.
    566720
    567     if (0.0 == newStruct->sampleUQ) {
     721    if (0.0 == stats->sampleUQ) {
     722
    568723        // GUS: fix this
    569         //        newStruct->options = newStruct->options | PS_STAT_SAMPLE_UQ;
     724        //        stats->options = stats->options | PS_STAT_SAMPLE_UQ;
    570725        p_psVectorSampleQuartiles(myVector,
    571726                                  maskVector,
    572727                                  maskVal,
    573                                   newStruct);
    574     }
    575 
    576     if (isnan(newStruct->sampleLQ)) {
     728                                  stats);
     729    }
     730
     731    if (isnan(stats->sampleLQ)) {
    577732        // GUS: fix this
    578         //        newStruct->options = newStruct->options | PS_STAT_SAMPLE_LQ;
     733        //        stats->options = stats->options | PS_STAT_SAMPLE_LQ;
    579734        p_psVectorSampleQuartiles(myVector,
    580735                                  maskVector,
    581736                                  maskVal,
    582                                   newStruct);
     737                                  stats);
    583738    }
    584739
    585740    // Compute the initial bin size of the robust histogram.
    586     sigmaE = (newStruct->sampleUQ - newStruct->sampleLQ) / 1.34f;
     741    sigmaE = (stats->sampleUQ - stats->sampleLQ) / 1.34f;
    587742    binSize = sigmaE / 10.0f;
    588743
    589744    // Detemine minimum and maximum values in the data vector.
    590     if (isnan(newStruct->min)) {
    591         p_psVectorMin(myVector, maskVector, maskVal, newStruct);
    592     }
    593     if (isnan(newStruct->max)) {
    594         p_psVectorMax(myVector, maskVector, maskVal, newStruct);
     745    if (isnan(stats->min)) {
     746        p_psVectorMin(myVector, maskVector, maskVal, stats);
     747    }
     748    if (isnan(stats->max)) {
     749        p_psVectorMax(myVector, maskVector, maskVal, stats);
    595750    }
    596751
    597752    // Create the histogram structure.
    598     robustHistogram = psHistogramAlloc(newStruct->min,
    599                                        newStruct->max,
     753    robustHistogram = psHistogramAlloc(stats->min,
     754                                       stats->max,
    600755                                       binSize);
    601756    // Populate the histogram arrat.
     
    610765    UQBinNum = -1;
    611766    for (i=0;i<robustHistogram->nums->n;i++) {
    612         if ((robustHistogram->nums->vec.i32[i] <= newStruct->sampleLQ) &&
    613                 (newStruct->sampleLQ <= robustHistogram->nums->vec.i32[i])) {
     767        if ((robustHistogram->nums->vec.i32[i] <= stats->sampleLQ) &&
     768                (stats->sampleLQ <= robustHistogram->nums->vec.i32[i])) {
    614769            LQBinNum = i;
    615770        }
    616771
    617         if ((robustHistogram->nums->vec.i32[i] <= newStruct->sampleUQ) &&
    618                 (newStruct->sampleUQ <= robustHistogram->nums->vec.i32[i])) {
     772        if ((robustHistogram->nums->vec.i32[i] <= stats->sampleUQ) &&
     773                (stats->sampleUQ <= robustHistogram->nums->vec.i32[i])) {
    619774            UQBinNum = i;
    620775        }
     
    631786    }
    632787
    633     dL = (newStruct->robustUQ - newStruct->robustLQ) / 8.0;
     788    dL = (stats->robustUQ - stats->robustLQ) / 8.0;
    634789
    635790    // Fit a Gaussian to the bins in the range MODE-dL to Mode+dL
     
    639794    // What is the mean_r?
    640795
    641     if (newStruct->options & PS_STAT_ROBUST_MEAN) {
    642         newStruct->robustMean = 0.0;
    643     }
    644 
    645     if  (newStruct->options & PS_STAT_ROBUST_MEDIAN) {
    646         newStruct->robustMedian = 0.0;
    647     }
    648     if  (newStruct->options & PS_STAT_ROBUST_MODE) {
    649         newStruct->robustMode = maxBinNum;
    650     }
    651     if  (newStruct->options & PS_STAT_ROBUST_STDEV) {
    652         newStruct->robustStdev = 0.0;
    653     }
    654     if  (newStruct->options & PS_STAT_ROBUST_QUARTILE) {
    655         newStruct->robustUQ = 0.0;
    656         newStruct->robustLQ = 0.0;
     796    if (stats->options & PS_STAT_ROBUST_MEAN) {
     797        stats->robustMean = 0.0;
     798    }
     799
     800    if  (stats->options & PS_STAT_ROBUST_MEDIAN) {
     801        stats->robustMedian = 0.0;
     802    }
     803    if  (stats->options & PS_STAT_ROBUST_MODE) {
     804        stats->robustMode = maxBinNum;
     805    }
     806    if  (stats->options & PS_STAT_ROBUST_STDEV) {
     807        stats->robustStdev = 0.0;
     808    }
     809    if  (stats->options & PS_STAT_ROBUST_QUARTILE) {
     810        stats->robustUQ = 0.0;
     811        stats->robustLQ = 0.0;
    657812    }
    658813}
     
    661816    NOTE: This function assumes that p_psVectorMean() has already been called
    662817    and the correct value is stored in stats->sampleMean.
     818 
     819    NOTE: the mean is always calculated exactly.  Robust means are never
     820    calculated in this routine.
    663821 *****************************************************************************/
    664822void p_psVectorSampleStdev(const psVector *restrict myVector,
     
    742900                            const psVector *restrict maskVector,
    743901                            unsigned int maskVal,
    744                             psStats *newStruct)
     902                            psStats *stats)
    745903{
    746904    int i = 0;
     
    750908    psVector *tmpMask = NULL;
    751909
    752     if (!((CLIPPED_NUM_ITER_LB <= newStruct->clipIter ) &&
    753             (newStruct->clipIter <= CLIPPED_NUM_ITER_UB))) {
     910    if (!((CLIPPED_NUM_ITER_LB <= stats->clipIter ) &&
     911            (stats->clipIter <= CLIPPED_NUM_ITER_UB))) {
    754912        psAbort(__func__, "Unallowed value for clipIter (%d).\n",
    755                 newStruct->clipIter);
    756     }
    757 
    758     if (!((CLIPPED_SIGMA_LB <= newStruct->clipSigma ) &&
    759             (newStruct->clipSigma <= CLIPPED_SIGMA_UB))) {
     913                stats->clipIter);
     914    }
     915
     916    if (!((CLIPPED_SIGMA_LB <= stats->clipSigma ) &&
     917            (stats->clipSigma <= CLIPPED_SIGMA_UB))) {
    760918        psAbort(__func__, "Unallowed value for clipSigma (%f).\n",
    761                 newStruct->clipSigma);
     919                stats->clipSigma);
    762920    }
    763921
     
    770928
    771929    // 1. Compute the sample median.
    772     p_psVectorSampleMedian(myVector, maskVector, maskVal, newStruct);
     930    p_psVectorSampleMedian(myVector, maskVector, maskVal, stats);
    773931
    774932    // 2. Compute the sample standard deviation.
    775     p_psVectorSampleStdev(myVector, maskVector, maskVal, newStruct);
     933    p_psVectorSampleStdev(myVector, maskVector, maskVal, stats);
    776934
    777935    // 3. Use the sample median as the first estimator of the mean X.
    778     clippedMean = newStruct->sampleMean;
     936    clippedMean = stats->sampleMean;
    779937
    780938    // 4. Use the sample stdev as the first estimator of the mean stdev.
    781     clippedStdev = newStruct->sampleStdev;
     939    clippedStdev = stats->sampleStdev;
    782940
    783941    // 5. Repeat N times:
    784942
    785     for (i=0;i<newStruct->clipIter;i++) {
     943    for (i=0;i<stats->clipIter;i++) {
    786944        for (j=0;j<myVector->n;j++) {
    787945            // a) Exclude all values x_i for which |x_i - x| > K * stdev
    788946            if ( fabs(myVector->vec.f[j] - clippedMean) >
    789                     (newStruct->clipSigma * clippedStdev)) {
     947                    (stats->clipSigma * clippedStdev)) {
    790948                tmpMask->vec.ui8[i] = 0xff;
    791949            }
     
    793951            // GUS: I should probably create a new struct here since the
    794952            // following calls will overwrite any old values in sampleMean.
    795             p_psVectorSampleMedian(myVector, tmpMask, maskVal, newStruct);
    796             p_psVectorSampleStdev(myVector, tmpMask, maskVal, newStruct);
     953            p_psVectorSampleMedian(myVector, tmpMask, maskVal, stats);
     954            p_psVectorSampleStdev(myVector, tmpMask, maskVal, stats);
    797955
    798956            // c) Use the new mean for x
    799             clippedMean = newStruct->sampleMean;
     957            clippedMean = stats->sampleMean;
    800958
    801959            // d) Use the new stdev for stdev
    802             clippedStdev = newStruct->sampleStdev;
     960            clippedStdev = stats->sampleStdev;
    803961        }
    804962    }
    805963
    806964    // 7. The last calcuated value of x is the cliped mean.
    807     if (newStruct->options & PS_STAT_CLIPPED_MEAN) {
    808         newStruct->clippedMean = clippedMean;
     965    if (stats->options & PS_STAT_CLIPPED_MEAN) {
     966        stats->clippedMean = clippedMean;
    809967    }
    810968
    811969    // 8. The last calcuated value of stdev is the cliped stdev.
    812     if (newStruct->options & PS_STAT_CLIPPED_STDEV) {
    813         newStruct->clippedStdev = clippedStdev;
     970    if (stats->options & PS_STAT_CLIPPED_STDEV) {
     971        stats->clippedStdev = clippedStdev;
    814972    }
    815973
Note: See TracChangeset for help on using the changeset viewer.