/******************************************************************************
*
* NSSDC/CDF Calculate statistics.
*
* Version 2.6a, 18-Nov-97, Hughes STX.
*
* Modification history:
*
* V1.0 29-Aug-91, J Love Original version (for CDF V2.1).
* V2.0 16-Mar-92, J Love IBM PC port. Added fill value filtering.
* V2.1 21-Aug-92, J Love CDF V2.3 (shareable/NeXT/zVar).
* V2.2 10-Dec-93, J Love CDF V2.4.
* V2.3 6-Dec-94, J Love CDF V2.5.
* V2.4 15-May-95, J Love Moved `ASSIGNx', `EQx', etc. to `toolbox3.c'
* (and some calling sequences changed).
* V2.5 1-Sep-95, J Love Hyper groups.
* V2.5a 19-Sep-95, J Love CHECKforABORTso.
* V2.5b 29-Sep-95, J Love Less CHECKforABORTso.
* V2.6 22-Jul-96, J Love CDF V2.6.
* V2.6a 18-Nov-97, J Love Windows NT/Visual C++.
*
******************************************************************************/
#include "cdfstats.h"
/******************************************************************************
* CALCstat. Reads each record of a variable and calculates the statistics.
******************************************************************************/
Logical CALCstat (Var)
struct VarStruct *Var;
{
CDFstatus status;
long attrN;
long varyCount;
int dimN;
long dimSizes[CDF_MAX_DIMS];
size_t nValueBytes[1];
Byte **handles[1];
long nHypers, hyperN;
long nValues, valueN;
struct GroupStruct groups;
struct HyperStruct hyper;
/****************************************************************************
* Initialize for this variable.
****************************************************************************/
Var->low = 0;
Var->high = 0;
Var->fills = 0;
Var->oneINrange = FALSE;
Var->minmaxInited = FALSE;
Var->monoInited = FALSE;
varyCount = BOO(Var->recVary,1,0);
for (dimN = 0; dimN < Var->numDims; dimN++) {
if (Var->dimVarys[dimN]) {
dimSizes[dimN] = Var->dimSizes[dimN];
varyCount++;
}
else
dimSizes[dimN] = 1;
}
if (varyCount == 1)
Var->checkMonotonicVar = TRUE;
else
Var->checkMonotonicVar = FALSE;
Var->nValueBytes = Var->numElemsV * CDFelemSize(Var->dataTypeV);
/****************************************************************************
* Allocate memory.
****************************************************************************/
handles[0] = &(Var->buffer);
nValueBytes[0] = (size_t) Var->nValueBytes;
AllocateBuffers (Var->varMaxRec + 1, Var->numDims, dimSizes, &groups, 0, 1,
handles, nValueBytes, ROWmajor(majority), MINnHYPERS,
FatalError);
Var->min = cdf_AllocateMemory ((size_t) Var->nValueBytes,
FatalError);
Var->max = cdf_AllocateMemory ((size_t) Var->nValueBytes,
FatalError);
Var->last = cdf_AllocateMemory ((size_t) Var->nValueBytes,
FatalError);
if (Var->rangeCheckVar) {
Var->minINrange = cdf_AllocateMemory ((size_t) Var->nValueBytes,
FatalError);
Var->maxINrange = cdf_AllocateMemory ((size_t) Var->nValueBytes,
FatalError);
}
/****************************************************************************
* Read each value...
****************************************************************************/
status = CDFlib (SELECT_, VAR(Var->Z), Var->varN,
NULL_);
if (!StatusHandlerStats(status)) return FALSE;
InitHyperParms (&hyper, &groups, Var->numDims, &nHypers, &nValues);
for (hyperN = 0; hyperN < nHypers; hyperN++) {
status = CDFlib (SELECT_, BOO(Var->Z,zVAR_RECNUMBER_,
rVARs_RECNUMBER_), hyper.recNumber,
BOO(Var->Z,zVAR_RECCOUNT_,
rVARs_RECCOUNT_), hyper.recCount,
BOO(Var->Z,
zVAR_RECINTERVAL_,
rVARs_RECINTERVAL_), hyper.recInterval,
BOO(Var->Z,zVAR_DIMINDICES_,
rVARs_DIMINDICES_), hyper.dimIndices,
BOO(Var->Z,zVAR_DIMCOUNTS_,
rVARs_DIMCOUNTS_), hyper.dimCounts,
BOO(Var->Z,
zVAR_DIMINTERVALS_,
rVARs_DIMINTERVALS_), hyper.dimIntervals,
GET_, BOO(Var->Z,zVAR_HYPERDATA_,
rVAR_HYPERDATA_), Var->buffer,
NULL_);
if (!StatusHandlerStats(status)) return FALSE;
for (valueN = 0, Var->value = Var->buffer; valueN < nValues;
valueN++, Var->value += (size_t) Var->nValueBytes) {
if (Var->minmaxInited)
MinMaxCheck (Var);
else
MinMaxInit (Var);
if (Var->checkMonotonicVar) Monotonic (Var);
}
IncrHyperParms (&hyper, &groups, Var->numDims, ROWmajor(majority),
&nValues);
CHECKforABORTso
}
/****************************************************************************
* Display statistics.
****************************************************************************/
DISPstat (Var);
/****************************************************************************
* Update attribute(s) if requested. (NOTE: macros/functions could be used).
****************************************************************************/
if (updateValids && Var->minmaxInited) {
status = CDFlib (SELECT_, CDF_READONLY_MODE_, READONLYoff,
NULL_);
if (!StatusHandlerStats(status)) return FALSE;
status = CDFlib (GET_, ATTR_NUMBER_, "VALIDMIN", &attrN,
NULL_);
if (status == NO_SUCH_ATTR) {
status = CDFlib (CREATE_, ATTR_, "VALIDMIN", VARIABLE_SCOPE, &attrN,
NULL_);
if (!StatusHandlerStats(status)) return FALSE;
}
else
if (!StatusHandlerStats(status)) return FALSE;
status = CDFlib (SELECT_, ATTR_, attrN,
BOO(Var->Z,zENTRY_,rENTRY_), Var->varN,
PUT_, BOO(Var->Z,zENTRY_DATA_,
rENTRY_DATA_), Var->dataTypeV,
Var->numElemsV, Var->min,
NULL_);
if (!StatusHandlerStats(status)) return FALSE;
status = CDFlib (GET_, ATTR_NUMBER_, "VALIDMAX", &attrN,
NULL_);
if (status == NO_SUCH_ATTR) {
status = CDFlib (CREATE_, ATTR_, "VALIDMAX", VARIABLE_SCOPE, &attrN,
NULL_);
if (!StatusHandlerStats(status)) return FALSE;
}
else
if (!StatusHandlerStats(status)) return FALSE;
status = CDFlib (SELECT_, ATTR_, attrN,
BOO(Var->Z,zENTRY_,rENTRY_), Var->varN,
PUT_, BOO(Var->Z,zENTRY_DATA_,
rENTRY_DATA_), Var->dataTypeV,
Var->numElemsV, Var->max,
NULL_);
if (!StatusHandlerStats(status)) return FALSE;
}
if (updateScales && Var->minmaxInited) {
status = CDFlib (SELECT_, CDF_READONLY_MODE_, READONLYoff,
NULL_);
if (!StatusHandlerStats(status)) return FALSE;
status = CDFlib (GET_, ATTR_NUMBER_, "SCALEMIN", &attrN,
NULL_);
if (status == NO_SUCH_ATTR) {
status = CDFlib (CREATE_, ATTR_, "SCALEMIN", VARIABLE_SCOPE, &attrN,
NULL_);
if (!StatusHandlerStats(status)) return FALSE;
}
else
if (!StatusHandlerStats(status)) return FALSE;
status = CDFlib (SELECT_, ATTR_, attrN,
BOO(Var->Z,zENTRY_,rENTRY_), Var->varN,
PUT_, BOO(Var->Z,zENTRY_DATA_,
rENTRY_DATA_), Var->dataTypeV,
Var->numElemsV, Var->min,
NULL_);
if (!StatusHandlerStats(status)) return FALSE;
status = CDFlib (GET_, ATTR_NUMBER_, "SCALEMAX", &attrN,
NULL_);
if (status == NO_SUCH_ATTR) {
status = CDFlib (CREATE_, ATTR_, "SCALEMAX", VARIABLE_SCOPE, &attrN,
NULL_);
if (!StatusHandlerStats(status)) return FALSE;
}
else
if (!StatusHandlerStats(status)) return FALSE;
status = CDFlib (SELECT_, ATTR_, attrN,
BOO(Var->Z,zENTRY_,rENTRY_), Var->varN,
PUT_, BOO(Var->Z,zENTRY_DATA_,
rENTRY_DATA_), Var->dataTypeV,
Var->numElemsV, Var->max,
NULL_);
if (!StatusHandlerStats(status)) return FALSE;
}
if (updateMonotonic && Var->monoInited) {
char mono[MONOTON_RESULT_LEN+1];
status = CDFlib (SELECT_, CDF_READONLY_MODE_, READONLYoff,
NULL_);
if (!StatusHandlerStats(status)) return FALSE;
status = CDFlib (GET_, ATTR_NUMBER_, "MONOTON", &attrN,
NULL_);
if (status == NO_SUCH_ATTR) {
status = CDFlib (CREATE_, ATTR_, "MONOTON", VARIABLE_SCOPE, &attrN,
NULL_);
if (!StatusHandlerStats(status)) return FALSE;
}
else
if (!StatusHandlerStats(status)) return FALSE;
switch (Var->monoState) {
case _Increase:
strcpyX (mono, "INCREASE", MONOTON_RESULT_LEN);
break;
case _Decrease:
strcpyX (mono, "DECREASE", MONOTON_RESULT_LEN);
break;
default:
strcpyX (mono, "FALSE ", MONOTON_RESULT_LEN);
}
status = CDFlib (SELECT_, ATTR_, attrN,
BOO(Var->Z,zENTRY_,rENTRY_), Var->varN,
PUT_, BOO(Var->Z,zENTRY_DATA_,
rENTRY_DATA_), CDF_CHAR, 8L, mono,
NULL_);
if (!StatusHandlerStats(status)) return FALSE;
}
/****************************************************************************
* Return - note that memory allocated will be freed by the caller (or the
* caller's caller).
****************************************************************************/
return TRUE;
}
/******************************************************************************
* MinMaxInit.
******************************************************************************/
void MinMaxInit (Var)
struct VarStruct *Var;
{
Logical use;
if (Var->ignoreFillsVar)
if (NEx(Var->value,Var->fillval,Var->dataTypeV,Var->numElemsV))
use = TRUE;
else {
use = FALSE;
Var->fills++;
}
else
use = TRUE;
if (use) {
ASSIGNx (Var->min, Var->value, Var->dataTypeV, Var->numElemsV);
ASSIGNx (Var->max, Var->value, Var->dataTypeV, Var->numElemsV);
if (Var->rangeCheckVar) {
if (LTx(Var->value,Var->validmin,Var->dataTypeV,Var->numElemsV))
Var->low++;
else
if (GTx(Var->value,Var->validmax,Var->dataTypeV,Var->numElemsV))
Var->high++;
else {
Var->oneINrange = TRUE;
ASSIGNx (Var->minINrange, Var->value, Var->dataTypeV,
Var->numElemsV);
ASSIGNx (Var->maxINrange, Var->value, Var->dataTypeV,
Var->numElemsV);
}
}
Var->minmaxInited = TRUE;
}
return;
}
void MinMaxCheck (Var)
struct VarStruct *Var;
{
Logical use;
if (Var->ignoreFillsVar)
if (NEx(Var->value,Var->fillval,Var->dataTypeV,Var->numElemsV))
use = TRUE;
else {
use = FALSE;
Var->fills++;
}
else
use = TRUE;
if (use) {
if (LTx(Var->value,Var->min,Var->dataTypeV,Var->numElemsV))
ASSIGNx (Var->min, Var->value, Var->dataTypeV, Var->numElemsV);
else {
if (GTx(Var->value,Var->max,Var->dataTypeV,Var->numElemsV)) {
ASSIGNx (Var->max, Var->value, Var->dataTypeV, Var->numElemsV);
}
}
if (Var->rangeCheckVar) {
if (LTx(Var->value,Var->validmin,Var->dataTypeV,Var->numElemsV))
Var->low++;
else
if (GTx(Var->value,Var->validmax,Var->dataTypeV,Var->numElemsV))
Var->high++;
else
if (Var->oneINrange) {
if (LTx(Var->value,Var->minINrange,Var->dataTypeV,Var->numElemsV))
ASSIGNx (Var->minINrange, Var->value, Var->dataTypeV,
Var->numElemsV);
else
if (GTx(Var->value,Var->maxINrange,
Var->dataTypeV,Var->numElemsV)) {
ASSIGNx (Var->maxINrange, Var->value, Var->dataTypeV,
Var->numElemsV);
}
}
else {
Var->oneINrange = TRUE;
ASSIGNx (Var->minINrange, Var->value, Var->dataTypeV,
Var->numElemsV);
ASSIGNx (Var->maxINrange, Var->value, Var->dataTypeV,
Var->numElemsV);
}
}
}
return;
}
/******************************************************************************
* Monotonic.
******************************************************************************/
void Monotonic (Var)
struct VarStruct *Var;
{
Logical use;
if (Var->ignoreFillsVar)
if (NEx(Var->value,Var->fillval,Var->dataTypeV,Var->numElemsV))
use = TRUE;
else
use = FALSE;
else
use = TRUE;
if (use) {
if (!Var->monoInited) {
ASSIGNx (Var->last, Var->value, Var->dataTypeV, Var->numElemsV);
Var->monoState = _Init;
Var->monoInited = TRUE;
}
else {
switch (Var->monoState) {
case _Init:
if (EQx(Var->value,Var->last,Var->dataTypeV,Var->numElemsV)) {
Var->monoState = _Steady;
break;
}
if (LTx(Var->value,Var->last,Var->dataTypeV,Var->numElemsV)) {
Var->monoState = _Decrease;
break;
}
if (GTx(Var->value,Var->last,Var->dataTypeV,Var->numElemsV)) {
Var->monoState = _Increase;
break;
}
break;
case _Steady:
if (LTx(Var->value,Var->last,Var->dataTypeV,Var->numElemsV)) {
Var->monoState = _noIncrease;
break;
}
if (GTx(Var->value,Var->last,Var->dataTypeV,Var->numElemsV)) {
Var->monoState = _noDecrease;
break;
}
break;
case _Increase:
if (LTx(Var->value,Var->last,Var->dataTypeV,Var->numElemsV)) {
Var->monoState = _False;
break;
}
if (EQx(Var->value,Var->last,Var->dataTypeV,Var->numElemsV)) {
Var->monoState = _noDecrease;
break;
}
break;
case _Decrease:
if (GTx(Var->value,Var->last,Var->dataTypeV,Var->numElemsV)) {
Var->monoState = _False;
break;
}
if (EQx(Var->value,Var->last,Var->dataTypeV,Var->numElemsV)) {
Var->monoState = _noIncrease;
break;
}
break;
case _noIncrease:
if (GTx(Var->value,Var->last,Var->dataTypeV,Var->numElemsV)) {
Var->monoState = _False;
break;
}
break;
case _noDecrease:
if (LTx(Var->value,Var->last,Var->dataTypeV,Var->numElemsV)) {
Var->monoState = _False;
break;
}
case _False:
/* Do nothing? */
break;
}
ASSIGNx (Var->last, Var->value, Var->dataTypeV, Var->numElemsV);
}
}
return;
}
syntax highlighted by Code2HTML, v. 0.9.1