IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Nov 11, 2004, 10:13:57 AM (22 years ago)
Author:
gusciora
Message:

Adding further error checking code to psStats.c.

File:
1 edited

Legend:

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

    r2329 r2339  
    99 *  @author GLG, MHPCC
    1010 *
    11  *  @version $Revision: 1.89 $ $Name: not supported by cvs2svn $
    12  *  @date $Date: 2004-11-10 23:22:32 $
     11 *  @version $Revision: 1.90 $ $Name: not supported by cvs2svn $
     12 *  @date $Date: 2004-11-11 20:13:57 $
    1313 *
    1414 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    5353/*****************************************************************************/
    5454psVector* p_psConvertToF32(psVector* in);
    55 
    5655/*****************************************************************************/
    5756/* GLOBAL VARIABLES                                                          */
     
    124123
    125124/******************************************************************************
    126     MISC PRIVATE STATISTICAL FUNCTIONS
     125MISC PRIVATE STATISTICAL FUNCTIONS
    127126 
    128     NOTE: it is assumed that any call to these statistical functions will
    129     have been preceded by a call to the psVectorStats() function.  Various
    130     sanity tests will only be performed in psVectorStats().
    131         Is the mask vector the same length as the data vector?
    132         Is the mask vector of type PS_TYPE_U8?
    133         Is the stats data structure NULL?
    134         Is the in data structure NULL?
    135         Is the in data structure of type PS_TYPE_F32?
     127NOTE: it is assumed that any call to these statistical functions will have
     128been preceded by a call to the psVectorStats() function.  Various sanity tests
     129will only be performed in psVectorStats().
    136130 
     131XXX: Should we perform the sanity checks in each routine anyway?
     132 
     133XXX: For many of these private stats routines, what should be done if there
     134are now acceptable elements in the input vector (if no elements lie within
     135range, or there are no unmasked elements, or the input vector is NULL)?
     136Currently we set the value to NAN.
     137 
     138XXX: Optimization: many routines have an "empty" boolean variable which keeps
     139track of whether or not the vector has any valid elements.  This code can
     140possibly be optimized away.
    137141 *****************************************************************************/
    138142/******************************************************************************
     
    146150Returns
    147151    NULL
    148  *****************************************************************************/
    149 
     152 
     153 *****************************************************************************/
    150154void p_psVectorSampleMean(const psVector* restrict myVector,
    151155                          const psVector* restrict maskVector,
     
    156160    float mean = 0.0;           // The mean
    157161    psS32 count = 0;            // # of points in this mean
    158     float rangeMin = 0.0;       // Exclude data below this
    159     float rangeMax = 0.0;       // Exclude date above this
    160162
    161163    // If PS_STAT_USE_RANGE is requested, then we enter a slightly different
    162164    // loop.
    163165    if (stats->options & PS_STAT_USE_RANGE) {
    164         rangeMin = stats->min;
    165         rangeMax = stats->max;
    166166        if (maskVector != NULL) {
    167167            for (i = 0; i < myVector->n; i++) {
    168168                // Check if the data is with the specified range
    169169                if (!(maskVal & maskVector->data.U8[i]) &&
    170                         (rangeMin <= myVector->data.F32[i]) &&
    171                         (myVector->data.F32[i] <= rangeMax)) {
     170                        (stats->min <= myVector->data.F32[i]) &&
     171                        (myVector->data.F32[i] <= stats->max)) {
    172172                    mean += myVector->data.F32[i];
    173173                    count++;
     
    182182        } else {
    183183            for (i = 0; i < myVector->n; i++) {
    184                 if ((rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
     184                if ((stats->min <= myVector->data.F32[i]) &&
     185                        (myVector->data.F32[i] <= stats->max)) {
    185186                    mean += myVector->data.F32[i];
    186187                    count++;
     
    234235{
    235236    psS32 i = 0;                // Loop index variable
    236     float max = -PS_MAX_F32;  // The calculated maximum
    237     float rangeMin = 0.0;       // Exclude data below this
    238     float rangeMax = 0.0;       // Exclude date above this
     237    float max = -PS_MAX_F32;    // The calculated maximum
     238    psS32 empty = true;         // Does this vector have valid elements?
    239239
    240240    // If PS_STAT_USE_RANGE is requested, then we enter a different loop.
    241241    if (stats->options & PS_STAT_USE_RANGE) {
    242         rangeMin = stats->min;
    243         rangeMax = stats->max;
    244242        if (maskVector != NULL) {
    245243            for (i = 0; i < myVector->n; i++) {
    246244                if (!(maskVal & maskVector->data.U8[i])) {
    247245                    if ((myVector->data.F32[i] > max) &&
    248                             (rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
     246                            (stats->min <= myVector->data.F32[i]) &&
     247                            (myVector->data.F32[i] <= stats->max)) {
    249248                        max = myVector->data.F32[i];
     249                        empty = false;
    250250                    }
    251251                }
     
    254254            for (i = 0; i < myVector->n; i++) {
    255255                if ((myVector->data.F32[i] > max) &&
    256                         (rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
     256                        (stats->min <= myVector->data.F32[i]) &&
     257                        (myVector->data.F32[i] <= stats->max)) {
    257258                    max = myVector->data.F32[i];
     259                    empty = false;
    258260                }
    259261            }
     
    265267                    if (myVector->data.F32[i] > max) {
    266268                        max = myVector->data.F32[i];
     269                        empty = false;
    267270                    }
    268271                }
     
    272275                if (myVector->data.F32[i] > max) {
    273276                    max = myVector->data.F32[i];
    274                 }
    275             }
    276         }
    277     }
    278 
    279     stats->max = max;
     277                    empty = false;
     278                }
     279            }
     280        }
     281    }
     282    if (empty == false) {
     283        stats->max = max;
     284    } else {
     285        stats->max = NAN;
     286    }
    280287}
    281288
     
    298305    psS32 i = 0;                // Loop index variable
    299306    float min = PS_MAX_F32;   // The calculated maximum
    300     float rangeMin = 0.0;       // Exclude data below this
    301     float rangeMax = 0.0;       // Exclude date above this
     307    psS32 empty = true;         // Does this vector have valid elements?
    302308
    303309    if (stats->options & PS_STAT_USE_RANGE) {
    304         rangeMin = stats->min;
    305         rangeMax = stats->max;
    306310        if (maskVector != NULL) {
    307311            for (i = 0; i < myVector->n; i++) {
    308312                if (!(maskVal & maskVector->data.U8[i])) {
    309313                    if ((myVector->data.F32[i] < min) &&
    310                             (rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
     314                            (stats->min <= myVector->data.F32[i]) &&
     315                            (myVector->data.F32[i] <= stats->max)) {
    311316                        min = myVector->data.F32[i];
     317                        empty = false;
    312318                    }
    313319                }
     
    316322            for (i = 0; i < myVector->n; i++) {
    317323                if ((myVector->data.F32[i] < min) &&
    318                         (rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
     324                        (stats->min <= myVector->data.F32[i]) &&
     325                        (myVector->data.F32[i] <= stats->max)) {
    319326                    min = myVector->data.F32[i];
     327                    empty = false;
    320328                }
    321329            }
     
    327335                    if (myVector->data.F32[i] < min) {
    328336                        min = myVector->data.F32[i];
     337                        empty = false;
    329338                    }
    330339                }
     
    334343                if (myVector->data.F32[i] < min) {
    335344                    min = myVector->data.F32[i];
    336                 }
    337             }
    338         }
    339     }
    340 
    341     stats->min = min;
     345                    empty = false;
     346                }
     347            }
     348        }
     349    }
     350
     351    if (empty == false) {
     352        stats->min = min;
     353    } else {
     354        stats->min = NAN;
     355    }
    342356}
    343357
     
    345359p_psVectorNValues(myVector, maskVector, maskVal, stats): calculates the
    346360number of non-masked pixels in the vector that fall within the min/max
    347 range, if given.
     361range, if specified.
    348362Inputs
    349363    myVector
     
    363377    psS32 i = 0;                // Loop index variable
    364378    psS32 numData = 0;          // The number of data points
    365     float rangeMin = 0.0;       // Exclude data below this
    366     float rangeMax = 0.0;       // Exclude date above this
    367379
    368380    if (stats->options & PS_STAT_USE_RANGE) {
    369         rangeMin = stats->min;
    370         rangeMax = stats->max;
    371381        if (maskVector != NULL) {
    372382            for (i = 0; i < myVector->n; i++) {
    373383                if (!(maskVal & maskVector->data.U8[i]) &&
    374                         (rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
     384                        (stats->min <= myVector->data.F32[i]) &&
     385                        (myVector->data.F32[i] <= stats->max)) {
    375386                    numData++;
    376387                }
     
    378389        } else {
    379390            for (i = 0; i < myVector->n; i++) {
    380                 if ((rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
     391                if ((stats->min <= myVector->data.F32[i]) &&
     392                        (myVector->data.F32[i] <= stats->max)) {
    381393                    numData++;
    382394                }
     
    394406        }
    395407    }
     408
    396409    return (numData);
    397410}
     
    408421    NULL
    409422 *****************************************************************************/
    410 void p_psVectorSampleMedian(const psVector* restrict myVector,
     423bool p_psVectorSampleMedian(const psVector* restrict myVector,
    411424                            const psVector* restrict maskVector,
    412425                            psU32 maskVal,
     
    418431    psS32 count = 0;                    // # of points in this mean?
    419432    psS32 nValues = 0;                  // # of points in vector
    420     float rangeMin = 0.0;               // Exclude data below this
    421     float rangeMax = 0.0;               // Exclude date above this
    422433
    423434    // Determine how many data points fit inside this min/max range
     
    425436    nValues = p_psVectorNValues(myVector, maskVector, maskVal, stats);
    426437
     438    // XXX: Is a warning message appropriate?  What value should we set the
     439    // sampleMedian to?  Should we generate an error?
     440    if (nValues <= 0) {
     441        printf("WARNING: p_psVectorSampleMedian(): no valid elements in input vector.\n");
     442        return(true);
     443        stats->sampleMedian = 0;
     444    }
     445
    427446    // Allocate temporary vectors for the data.
    428447    unsortedVector = psVectorAlloc(nValues, PS_TYPE_F32);
    429     sortedVector = psVectorAlloc(nValues, PS_TYPE_F32);
    430448
    431449    // Determine if we must only use data points within a min/max range.
    432450    if (stats->options & PS_STAT_USE_RANGE) {
    433         rangeMin = stats->min;
    434         rangeMax = stats->max;
    435 
    436451        // Store all non-masked data points within the min/max range
    437452        // into the temporary vectors.
     
    440455            for (i = 0; i < myVector->n; i++) {
    441456                if (!(maskVal & maskVector->data.U8[i]) &&
    442                         (rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
    443                     unsortedVector->data.F32[count++] = maskVector->data.F32[i];
     457                        (stats->min <= myVector->data.F32[i]) &&
     458                        (myVector->data.F32[i] <= stats->max)) {
     459                    unsortedVector->data.F32[count] = myVector->data.F32[i];
     460                    count++;
    444461                }
    445462            }
    446463        } else {
    447464            for (i = 0; i < myVector->n; i++) {
    448                 if ((rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
    449                     unsortedVector->data.F32[count++] = myVector->data.F32[i];
     465                if ((stats->min <= myVector->data.F32[i]) &&
     466                        (myVector->data.F32[i] <= stats->max)) {
     467                    unsortedVector->data.F32[count] = myVector->data.F32[i];
     468                    count++;
    450469                }
    451470            }
     
    457476            for (i = 0; i < myVector->n; i++) {
    458477                if (!(maskVal & maskVector->data.U8[i])) {
    459                     unsortedVector->data.F32[count++] = myVector->data.F32[i];
     478                    unsortedVector->data.F32[count] = myVector->data.F32[i];
     479                    count++;
    460480                }
    461481            }
     
    467487    }
    468488    // Sort the temporary vectors.
    469     psVectorSort(sortedVector, unsortedVector);
     489    sortedVector = psVectorSort(sortedVector, unsortedVector);
     490    if (sortedVector == NULL) {
     491        psError(PS_ERR_UNEXPECTED_NULL,
     492                false,
     493                PS_ERRORTEXT_psStats_STATS_SAMPLE_MEDIAN_SORT_PROBLEM);
     494        return(false);
     495    }
    470496
    471497    // Calculate the median exactly.
     
    480506    psFree(unsortedVector);
    481507    psFree(sortedVector);
     508
     509    // Return "true" on success.
     510    return(true);
    482511}
    483512
     
    485514p_psVectorSmoothHistGaussian(): This routine smoothes the data in the input
    486515robustHistogram with a Gaussian of width sigma.
     516 
     517XXX: Only PS_TYPE_F32 is supported.
     518 
     519XXX: Write a general routine which smoothes a psVector.  This routine should
     520call that.  Is that possible?
    487521 *****************************************************************************/
    488522psVector* p_psVectorSmoothHistGaussian(psHistogram* robustHistogram,
    489523                                       float sigma)
    490524{
     525    PS_PTR_CHECK_NULL(robustHistogram, NULL);
     526    PS_PTR_CHECK_NULL(robustHistogram->bounds, NULL);
     527
    491528    psS32 i = 0;                  // Loop index variable
    492529    psS32 j = 0;                  // Loop index variable
     
    504541    x.type.type = PS_TYPE_F32;
    505542    for (i = 0; i < numBins; i++) {
     543        // Determine the midpoint of bin i.
    506544        iMid = (robustHistogram->bounds->data.F32[i] +
    507545                robustHistogram->bounds->data.F32[i+1]) / 2.0;
     546
     547
     548        // We determine the bin numbers corresponding to a range of data
     549        // values surrounding iMid.  The ranges is of size
     550        // s*PS_GAUSS_WIDTH*sigma
    508551
    509552        // YYY: The p_psVectorBinDisect() routine does much of the work of
     
    516559        if ((x.data.F32 >= firstBound) && (x.data.F32 <= lastBound)) {
    517560            jMin = p_psVectorBinDisect(robustHistogram->bounds, &x);
     561            if (jMin < 0) {
     562                psError(PS_ERR_UNEXPECTED_NULL,
     563                        false,
     564                        PS_ERRORTEXT_psStats_STATS_VECTOR_BIN_DISECT_PROBLEM);
     565                return(NULL);
     566            }
    518567        } else if (x.data.F32 <= firstBound) {
    519568            jMin = 0;
Note: See TracChangeset for help on using the changeset viewer.