Beispiel #1
0
void XYViewValueCell::UpdateText()
{
    if (m_pGrid->gXY == 0)
    {
        SetNullStr();
        return;
    }

    const DC_XYData& currXY = *(m_pGrid->gXY);
    if (m_rowIndex >= currXY.Size())
    {
        SetNullStr();
        return;
    }

    char tempStr[80];
    CopyString(tempStr, "null", 80);
    if (isX)
    {
        double currVal = currXY.xData[m_rowIndex];
        if (!RealIsNull(currVal))
            m_pGrid->xFormat.RealToString(currVal, tempStr, 80);
    }
    else
    {
        double currVal = currXY.yData[m_rowIndex];
        if (!RealIsNull(currVal))
            m_pGrid->yFormat.RealToString(currVal, tempStr, 80);
    }
    SetText(tempStr);
}
Beispiel #2
0
bool DC_XYData::IsClean() const
{
    for (int i = 0; i < Size(); i++)
        if (RealIsNull(xData[i]) || RealIsNull(yData[i]))
            return false;

    return true;
}
Beispiel #3
0
Limit3D PFO_Scatterplot::GetPlotObjLimits()
{
    Limit3D  currLimits;
    DoStatusChk();
    if (StatusNotOK() || (!doPlot))
        return currLimits;

    bool xLin, yLin;
    GetAxesTypes(xLin, yLin);

    {
        const SC_DoubleArray& xData = scatterDataDC->dataTable[plotIVIndx];
        const SC_DoubleArray& yData = scatterDataDC->dataTable[plotDVIndx + nplotIV];

        for (int j = 0; j < xData.Size(); j++)
        {
            double xVal = xData[j];
            double yVal = yData[j];
            if ((xLin || (xVal > stdEps)) && (yLin || (yVal > stdEps)))
                currLimits.AddToLimits(Coord3D(xVal, yVal, nullReal));
        }
    }

    if (plotXGridLines)
    {
        const SC_DoubleArray& xData = xGridLinesDC->dataTable[plotIVIndx];
        for (int j = 0; j < xData.Size(); j++)
        {
            double xVal = xData[j];
            if ((!RealIsNull(xVal)) && (xLin || (xVal > stdEps)))
                currLimits.AddToLimits(Coord3D(xVal, nullReal, nullReal));
        }
    }

    if (plotYGridLines)
    {
        const SC_DoubleArray& yData = yGridLinesDC->dataTable[plotDVIndx];

        for (int j = 0; j < yData.Size(); j++)
        {
            double yVal = yData[j];
            if ((!RealIsNull(yVal)) && (yLin || (yVal > stdEps)))
                currLimits.AddToLimits(Coord3D(nullReal, yVal, nullReal));
        }
    }


    return currLimits;
}
Beispiel #4
0
double DC_Normalize::Normalize(double inNorm)
{
    if (RealIsNull(inNorm))
        return nullReal;

    double outVal = inNorm;
    if (normalizeOp != noPower)
    {
        if (outVal <= inputMinimum)
            outVal = outputMinimum;
        else if (outVal >= inputMaximum)
            outVal = outputMaximum;
        else
            outVal = (inNorm - inputMinimum) * spanMult + outputMinimum;
    }

    if ((normalizeOp != noLimit) && (fabs(outVal) > stdEps))
    {
        if (outVal < stdEps)
            outVal = pow(outVal, intPower);
        else
            outVal = pow(outVal, normPower);
    }

    return outVal;
}
Beispiel #5
0
double ParameterCurve::GetMetricCurveY(const double&   metricXVal,
                                       DC_Curve& curve)
{
  // sanity checks
  if (!curve.IsCreated())
    GenAppInternalError("ParameterCurve::GetMetricPointCurveY #1");
  if (RealIsNull(metricXVal))
    GenAppInternalError("ParameterCurve::GetMetricPointCurveY #2");

  //  convert metric x to user x
  double userX = xUnitIndex.MetricToUser(metricXVal);

  //  take log if required
  if (xIsLog10)
  {
    if (userX < stdEps)
      GenAppInternalError("ParameterCurve::GetMetricPointCurveY #3");
    userX = log10(userX);
  }

  // get curve value
  double userY = curve.GetCurveY(userX);

  // if log then transform
  if (yIsLog10)
  {
    if ((userY < -99.0) || (userY > 99.0))
      GenAppInternalError("ParameterCurve::GetMetricPointCurveY #4");
    userY = pow(10.0, userY);
  }

  //  convert units && return
  return yUnitIndex.UserToMetric(userY);
}
Beispiel #6
0
void WorkingCaptureDataBase::ApplySpec(const double& testTime)
{
    for (int i = 0; i < capturedVals.Size(); i++)
    {
        // get ref
        SC_DoubleArray& currVec = (*currCapturedData)[i+1];

        double lastVal = 0.0;   // no production at start
        if (!currVec.IsEmpty())
            lastVal = currVec.LastIndex();

        double newVal = capturedVals[i];

        // for first flow in sequence
        if (RealIsNull(lastVal))
            currVec.SetLastIndex(newVal);

        currVec += newVal;
    }

    if ((nextRestart < productionRestartTimes.Size()) && (!(*currCapturedData)[0].IsEmpty()))
    {
        if (testTime > productionRestartTimes[nextRestart])
        {
            for (int i = 0; i < productionCapture.Size(); i++)
                (*currCapturedData)[productionCapture[i] + 1].SetLastIndex(0.0);

            nextRestart++;
        }
    }
}
Beispiel #7
0
    void ValueCell::UpdateText()
    {
        DC_ColorMap& currCM = m_pGrid->gColorMap;
        if (m_rowIndex >= currCM.ncolorMap)
            {
                SetNullStr();
                return;
            }

        SC_ColorSpec& currSpec = currCM.colorMapColors[m_rowIndex];
        double currVal;
        switch (m_colIndex )
            {
            case 0 : {currVal = currSpec.RH; break;}
            case 1 : {currVal = currSpec.GS; break;}
            case 2 : {currVal = currSpec.BV; break;}
            }
        if (RealIsNull(currVal) || (currVal < 0.0) || (currVal > 1.0))
            {
                SetNullStr();
            }
        else
            {
                char tempStr[80];
                SC_DecFormat rForm(3);
                rForm.RealToString(currVal, tempStr, 80);
                SetText(tempStr);
            }
    }
Beispiel #8
0
void GridViewValueCell::UpdateText()
{
    if (m_pGrid->gGrid == 0)
    {
        SetNullStr();
        return;
    }

    const DC_GridData& currTab = *(m_pGrid->gGrid);
    if ((m_colIndex >= currTab.yData.Size()) || (m_rowIndex >= currTab.xData.Size()))
    {
        SetNullStr();
        return;
    }

    double currVal = currTab.gData[m_rowIndex][m_colIndex];
    if (RealIsNull(currVal))
    {
        SetNullStr();
    }
    else
    {
        char tempStr[80];
        m_pGrid->gridFormat.RealToString(currVal, tempStr, 80);
        SetText(tempStr);
    }
}
Beispiel #9
0
void DC_XYData::CleanUp()
{
    int nOK = 0;
    for (int i = 0; i < xData.Size(); i++)
        {
            if (RealIsNull(xData[i]) || RealIsNull(yData[i]))
                continue;

            if (nOK < i)
                {
                    xData[nOK] = xData[i];
                    yData[nOK] = yData[i];
                }
            nOK++;
        }
    SetSize(nOK);
}
Beispiel #10
0
void DC_DataLimit::AddToLimit(const double& inVal)
{
    if (RealIsNull(inVal))
        return;

    if (RealIsNull(minLimit))
        {
            minLimit = inVal;
            maxLimit = inVal;
            return;
        }

    if (inVal < minLimit)
        minLimit = inVal;
    else if (inVal > maxLimit)
        maxLimit = inVal;
}
Beispiel #11
0
bool DC_XYData::SetNDX(SC_SetupErr& err,
                       SC_DoubleArray& ndxData)const
{
    int n = 0;
    for (int i = 0; i < Size(); i++)
        {
            double x = xData[i];
            double y = yData[i];
            if (RealIsNull(x) || RealIsNull(y))
                {
                    err.SetConstantError("all x and y must be non null");
                    return false;
                }

            if ((x < 0.5) || (x > 999))
                {
                    err.SetConstantError("all x values must be integers > 0 and < 1000");
                    return false;
                }

            if (y < 1.0E-5)
                {
                    err.SetConstantError("all y values must be > 1E-5");
                    return false;
                }
            n += int(x);
        }

    if (n > 10000)
        {
            err.SetConstantError("total number of x/y ndx calculated nodes points be < 10000");
            return false;
        }

    ndxData.Alloc(n);
    for (int i = 0; i < Size(); i++)
        {
            n = int(xData[i]);
            double y = yData[i];
            for (int j = 0; j < n; j++)
                ndxData += y;
        }
    return true;

}
Beispiel #12
0
void SC_Statistics::CalcMode(const SC_DoubleArray& data)
{
    if (nOK == 0)
        return;

    // min == max
    if (realResults[soVar] < stdEps)
        {
            realResults[soMode] = realResults[soMean];
            return;
        }

    // Scott, 1979 algorithm for bin width
    // W = (3.49)(std.dev.)[(#samples)^(-1/3)]
    double width = 3.49 * realResults[soStdDev] * (pow(realResults[soN], -0.3333));
    if (width < stdEps)
        {
            realResults[soMode] = realResults[soMean];
            return;
        }

    double maxNBins = (realResults[soMax] - realResults[soMin]) / width;
    if (maxNBins > 10000.0)
        return;

    int nbins = int(ceil(maxNBins));

    // note just linear bins
    width = (realResults[soMax] - realResults[soMin]) / double(nbins);

    SC_IntArray binCount(nbins, 0);
    for (int i = 0; i < data.Size(); i++)
        {
            double dVal = data[i];
            if (RealIsNull(dVal) || (dVal < realResults[soMin])) // can happen if stats calc was log
                continue;

            int binIndex = int(floor((dVal - realResults[soMin]) / width));
            // pathological case == maxVal
            if (binIndex == nbins)
                binIndex--;

            binCount[binIndex]++;
        }

    int maxBin = 0;
    int maxCount = binCount[0];
    for (int i = 1; i < nbins; i++)
        if (binCount[i] > maxCount)
            {
                maxBin = i;
                maxCount = binCount[i];
            }

    realResults[soMode]  = realResults[soMin] + (double(maxBin) + 0.5) * width;
}
Beispiel #13
0
bool SC_SetupErr::NullDataErr(const char*   valDesc,
                              const double& chkVal)
{
    if (RealIsNull(chkVal))
        {
            SetErrText(valDesc, " is not set");
            return true;
        }
    return false;
}
Beispiel #14
0
void DataCaptureErrorListing::CreateListing()
{
  StdTitle("Simulation Results Setup Errors");

  SC_SetupErr dcErr;

  if (dataCaptureData.IsEmpty())
    AddError("no output data specified");


  for (int i = 0; i < dataCaptureData.Size(); i++)
    if (dataCaptureData.IsNotValid(i))
    {
      AddError("Null capture spec found");
    }
    else
    {
      if (!dataCaptureData.GetRef(i).SetupOK(dcErr))
      {
        AddError(dcErr);
      }
    }

  if (productionRestartTimes.Size() > 0)
  {
    double prev = productionRestartTimes[0];
    for (int i = 1; i < productionRestartTimes.Size(); i++)
    {
      double next = productionRestartTimes[i];
      if (RealIsNull(prev) || RealIsNull(next))
      {
        AddError("Null production restart time found");
        break;
      }
      if (prev >= next)
      {
        AddError("Production restart times must be ascending");
        break;
      }
    }
  }

}
 void ValueGridCell::UpdateText()
 {
     CString sText;
     if (RealIsNull(m_dval))
     {
         sText = "---";
     }
     else
     {
         SC_DecFormat corrRF(3);
         corrRF.RealToString(m_dval, sText);
     }
     SetText(sText);
 }
Beispiel #16
0
void YCell::UpdateText()
{
    char tempStr[80];
    if (m_nIndex >= xyData.Size()) {
        CopyString(tempStr, "---", 80);
    } else {
        double yVal = xyData[m_nIndex].y;
        if (RealIsNull(yVal)) {
            CopyString(tempStr, "---", 80);
        } else {
            m_pGrid->yForm.RealToString(yVal, tempStr, 80);
        }
    }
    SetText(tempStr);
}
Beispiel #17
0
void Parameter::ParValToString(const double&  metricVal,
                               CString& parString)
{
  if (useUnitFormat)
  {
    parVal.UnitIndex::GetUserString(metricVal, parString);
  }
  else if (RealIsNull(metricVal))
  {
    parString = nullStr;
  }
  else
  {
    format.RealToString(parVal.MetricToUser(metricVal), parString);
  }
}
Beispiel #18
0
bool PointsCurveValue::SetupOK(SC_SetupErr& errData,
                               bool     pIsLog)
{

  if (IsOpt())
    return pOptData->OptimizeSetupOK(errData);
  else if (IsVary())
    return pVaryData->VarySetupOK(errData);

  SC_SetupErr parErr;
  if (RealIsNull(pVal))
    parErr.SetConstantError("data value not set");
  else if (pIsLog && (pVal <= 1.0E-40))
    parErr.SetConstantError("log curve is -ve");

  return errData.SetupOK(pID, parErr);
}
Beispiel #19
0
bool DC_DataLimit::TransformValueForRange(double& inVal,
                                          bool    clipToRange) const
{
    if (RealIsNull(inVal))
        return false;

    if (logRange)
        {
            if (inVal < stdEps)
                {
                    if (clipToRange)
                        return false;
                    inVal =  minLimit;
                }
            inVal = log10(inVal);
        }
    return true;
}
Beispiel #20
0
    void SampleErrorListing::CreateListing()
    {
        StdTitle("Sampler Setup Errors");
        SC_SetupErr sampErr;

        SampVarArray currSamp;
        if (currSamp.Size() < 1)
        {
            sampErr.SetConstantError("at least 1 variable must be sampled");
            AddError(sampErr);
        }

        for (int i = 0; i < currSamp.Size(); i++)
            if (!currSamp[i]->SampleSetupOK(sampErr))
                AddError(sampErr);

        //for FOSM or PEM - check to make sure all vars belong to same corr group
        if (!IsMonteCarlo())
        {
            int uncertCorrGroup = currSamp[0]->GetCorrGroup();
            if (!forceCorrelationsToZero)
            {
                //case where no correlations are set
                if ((currSamp[0]->GetnCorrGroup(uncertCorrGroup) > 1) && (currSamp[0]->correlations.Size() == 0))
                    AddError("correlations not set or forced to zero");
            }
            for (int i = 1; i < currSamp.Size(); i++)
            {
                int currCorrGroup = currSamp[i]->GetCorrGroup();
                if (currCorrGroup != uncertCorrGroup)
                    AddError("FOSM/PEM: all uncertain vars must belong to same correlation group");
                if (!forceCorrelationsToZero)
                {
                    //case where individual correlations are not set
                    for (int j = 0; j < currSamp[i]->correlations.Size(); j++)
                    {
                        if (RealIsNull(currSamp[i]->correlations[j].correlationValue))
                            AddError("correlations not set or forced to zero");
                    }
                }
            }
        }
    }
Beispiel #21
0
void nsCollect::CollectRange()
{
  GenAppInfoMsg("nPreX", "collecting range");

  IO_RangeSimResults baseRngFile;
  DC_RangeSimResults baseRngData;

  CopyString(baseRngFile.fileName, ProcessData::spawnData[0].rngFile, stdFileStrLen);
  if (!baseRngFile.ReadSimResults(baseRngData))
    GenAppInternalError("collecting base range");

  RangeSimRunResults& baseRange = baseRngData[0];

  for (int i = 1; i < ProcessData::spawnData.Size(); i++)
  {
    IO_RangeSimResults nextRngFile;
    DC_RangeSimResults nextRngData;

    CopyString(nextRngFile.fileName, ProcessData::spawnData[i].rngFile, stdFileStrLen);
    if (!nextRngFile.ReadSimResults(nextRngData))
      GenAppInternalError("collecting range data");

    RangeSimRunResults& nextRange = nextRngData[0];

    for (int j = 0; j < baseRange.Size(); j++)
    {
      SC_DoubleArray& baseData = baseRange[j].gridCubeData;
      SC_DoubleArray& nextData = nextRange[j].gridCubeData;
      for (int k = 0; k < baseData.Size(); k++)
        if (RealIsNull(baseData[k]))
          baseData[k] = nextData[k];
    }
  }

  CopyString(baseRngFile.fileName, rangeOutputFile.fileName, stdFileStrLen);
  if (!baseRngFile.AddSimRun(baseRange, rangeOutputDesc.addExisting))
    GenAppInternalError("writing collected range");

  GenAppInfoMsg("nPreX", "range collection complete");
}
Beispiel #22
0
bool Parameter::ParValOK(const double&      pVal,
                         const char         rangeID[],
                         SC_SetupErr& errData)
{
  SC_SetupErr rangeErr;
  char rangeErrMsg[80];

  if (RealIsNull(pVal))
    rangeErr.SetConstantError("value not set");
  else if ((pVal  < minLimit) || (pVal > maxLimit))
  {
    char minStr[80];
    ParValToString(minLimit, minStr, 80);
    char maxStr[80];
    ParValToString(maxLimit, maxStr, 80);

    MakeString(rangeErrMsg, "must be > ", minStr, " and < ", maxStr, 80);

    rangeErr.SetConstantError(rangeErrMsg);
  }
  return errData.SetupOK(rangeID, rangeErr);
}
Beispiel #23
0
void DC_Normalize::DoNormalize(SC_DoubleArray& inData)
{
    if (normalizeOp != noPower)
    {
        if (autoLimit)
        {
            inData.CalcMinMax(inputMinimum, inputMaximum);
            if (RealIsNull(inputMinimum))
                return;
        }

        if (fabs(inputMaximum - inputMinimum) < stdEps)
            spanMult = 0.0;
        else
            spanMult = (outputMaximum - outputMinimum) / (inputMaximum - inputMinimum);
    }
    intPower = double(int(normPower));

    for (int i = 0; i < inData.Size(); i++)
        inData[i] = Normalize(inData[i]);

}
void DFO_TableCalibrationStatistics:: CalcOutput(FOcalcType  calcType)
{
    DoStatusChk();
    if (!StatusOK())
        return;

    const SC_DoubleArray& xIn = *selectedColData;
    const SC_DoubleArray& yIn = inputData->dataTable[selectedYCol];

    double sumRes = 0.0;
    double absRes = 0.0;
    double sumSqr = 0.0;
    double maxRes, minRes, maxY, minY;
    int numRes = 0;
    for (int i = 0; i < xIn.Size(); i++)
    {
        double nextX = xIn[i];
        double nextY = yIn[i];

        if (RealIsNull(nextX) || RealIsNull(nextY))
            continue;

        double currRes = nextX - nextY;

        if (numRes == 0)
        {
            maxRes = currRes;
            minRes = currRes;
            maxY = nextY;
            minY = nextY;
        }
        else
        {
            maxRes = DMax(maxRes, currRes);
            minRes = DMin(minRes, currRes);
            maxY = DMax(maxY, nextY);
            minY = DMin(minY, nextY);
        }
        numRes++;
        absRes += fabs(currRes);
        sumRes += currRes;
        sumSqr += Sqr(currRes);
    }

    if (numRes < 2)
    {
        SetObjErrMsg("Less than two points to calculate statistics for");
        return;
    }

    maxOverPredictionDO.InitLabelAndValue(maxRes);
    maxUnderPredictionDO.InitLabelAndValue(-minRes);
    averageResidualDO.InitLabelAndValue(sumRes/double(numRes));
    averageAbsResidualDO.InitLabelAndValue(absRes/double(numRes));
    numMeasurementsDO.InitLabelAndValue(double(numRes));
    normalizedResidualRMSDO.InitLabelAndValue(0.0);
    if (sumSqr > 0.0)
    {
        double rms = sqrt(sumSqr/double(numRes));
        residualRMSDO.InitLabelAndValue(rms);
        double dy = maxY - minY; 
        if (dy > 0.0)
            normalizedResidualRMSDO.InitLabelAndValue(rms / dy * 100.0);
    }
    else
    {
        residualRMSDO.InitLabelAndValue(0.0);
    }
    correlationCoefficientDO.InitLabelAndValue(PearsonR(xIn, yIn));
}
void DFO_TableColumnCorrelation:: CalcOutput(FOcalcType  calcType)
{
    DoStatusChk();
    if (!StatusOK())
        return;

    xcolumnIDDO.SetValueLabel(inputData->GetTitle(selectedCol));
    ycolumnIDDO.SetValueLabel(inputData->GetTitle(selectedYCol));

    const SC_DoubleArray& xIn = *selectedColData;
    const SC_DoubleArray& yIn = inputData->dataTable[selectedYCol];

    SC_DoubleArray& xCorr = outputDataDC.xData;
    SC_DoubleArray& yCorr = outputDataDC.yData;

    xCorr.Alloc(xIn.Size());
    yCorr.Alloc(xIn.Size());

    int nOK = 0;
    int i;
    for (i = 0; i < xIn.Size(); i++)
    {
        double nextX = xIn[i];
        double nextY = yIn[i];

        if (RealIsNull(nextX) || RealIsNull(nextY))
            continue;

        if (logX)
        {
            if (nextX < stdEps)
                continue;
            nextX = log10(nextX);
        }

        if (logY)
        {
            if (nextY < stdEps)
                continue;
            nextY = log10(nextY);
        }

        xCorr[nOK] = nextX;
        yCorr[nOK++] = nextY;
    }

    if (nOK < 2)
    {
        SetObjErrMsg("Less than two points to correlate");
        return;
    }
    xCorr.SetSize(nOK);
    yCorr.SetSize(nOK);

    pearsonRDO.InitLabelAndValue(PearsonR(xCorr, yCorr));
    spearmanRDO.InitLabelAndValue(SpearmanR(xCorr, yCorr));

    // make correlation line
    DC_Curve corrLine;
    corrLine.curveType = Curve::ctPolynomial;
    corrLine.polyOrder = 1;

    SC_SetupErr crvErr;
    outputLineDC.CreateFrom(xCorr, yCorr);
    if (!corrLine.CreateCurve(outputLineDC, crvErr))
    {
        SetObjErrMsg(crvErr.GetErrorText());
        return;
    }
    outputLineDC.xData.Sort(true);
    corrLine.GetCurveY(outputLineDC.xData, outputLineDC.yData);

    // unlog data
    if (logX)
    {
        outputLineDC.xData.InvLog10();
        outputDataDC.xData.InvLog10();
    }

    if (logY)
    {
        outputLineDC.yData.InvLog10();
        outputDataDC.yData.InvLog10();
    }
    lineSlopeDO.InitLabelAndValue(corrLine.GetPolyCoefficients()[1]);
    lineYInterceptDO.InitLabelAndValue(corrLine.GetPolyCoefficients()[0]);
}
Beispiel #26
0
void SC_Statistics::CalcStatistics(const SC_DoubleArray& data,
                                   bool logData, bool baseTen)
{
    Init();
    if (data.IsEmpty())
        return;

    int nData = data.Size();

    double sum = 0.0;
    double geoSum = 0.0, harmSum = 0.0; //for geometric and harmonic means
    double minV, maxV, minAV;
    int minIndx, maxIndx, minAbsIndx;

    double minPV = nullReal;
    int minPosIndx = -1;

    nOK = 0;
    nPositive = 0;

    int nnegZero = 0;
    for (int i = 0; i < nData; i++)
        {
            double dVal = data[i];
            if (dVal < 1.0E-99)
                nnegZero++;

            if (RealIsNull(dVal) || (logData && (dVal < 1.0E-99)))
                continue;

            // this used to be calculated after min/max
            // changed for SyView 1.2 - Mar 06
            // minVal, maxVal, minAV, and minIndxs now based/reported on logged data
            if (logData)
                {
                    if (baseTen)
                        {
                            dVal = log10(dVal);
                        }
                    else
                        {
                            dVal = log(dVal);
                        }
                }

            double absVal = fabs(dVal);

            if (nOK == 0)
                {
                    minV = dVal;
                    maxV = dVal;
                    minAV = absVal;
                    minIndx = i;
                    minAbsIndx = i;
                    maxIndx = i;
                }

            if (dVal < minV)
                {
                    minV = dVal;
                    minIndx = i;
                }
            else if (dVal > maxV)
                {
                    maxV = dVal;
                    maxIndx = i;
                }

            if (absVal < minAV)
                {
                    minAV = absVal;
                    minAbsIndx = i;
                }

            if (dVal > 0.0)
                {
                    if (minPosIndx < 0)
                        {
                            minPV = dVal;
                            minPosIndx = i;
                        }
                    else if (dVal < minPV)
                        {
                            minPV = dVal;
                            minPosIndx = i;
                        }
                }

            sum += dVal;
            if(dVal > 0)
                {
                    geoSum += log(dVal);
                    harmSum += 1/dVal;
                    nPositive++;
                }
            nOK++;
        }

    double  dOK = double(nOK);
    double  dPositive = double(nPositive);

    realResults[soN]     = dOK;
    realResults[soNnull] = double(nData - nOK);
    realResults[soNnegZero] = double(nnegZero);

    intResults[soN] = nOK;
    intResults[soNnull] = nData - nOK;
    intResults[soNnegZero] = nnegZero;

    if (nData > 0)
        realResults[soPercentNonNull] = dOK / double(nData) * 100.0;

    if (nOK == 0)
        return;

    resultsOK = true;

    realResults[soSum]      = sum;
    realResults[soMin]      = minV;
    realResults[soMax]      = maxV;
    realResults[soMinAbs]   = minAV;
    realResults[soMinPos]   = minPV;

    intResults[soMinIndx] = minIndx;
    intResults[soMaxIndx] = maxIndx;
    intResults[soMinAbsIndx] = minAbsIndx;
    intResults[soMinPosIndx] = minPosIndx;

    realResults[soMinIndx] = double(minIndx);
    realResults[soMaxIndx] = double(maxIndx);
    realResults[soMinAbsIndx] = double(minAbsIndx);
    realResults[soMinPosIndx] = double(minPosIndx);

    if (nOK > 0)
        {
            // pathological
            realResults[soRange]   = maxV - minV;
            if (realResults[soRange] < stdEps)
                {
                    realResults[soMean] = (minV + maxV) / 2.0;
                    realResults[soMeanGeo] = (minV + maxV) / 2.0;
                    realResults[soMeanHarm] = (minV + maxV) / 2.0;
                    realResults[soVar]  = 0.0;
                    realResults[soStdDev]  = 0.0;
                }
            else
                {
                    realResults[soMean]            = sum / dOK;
                    realResults[soMeanGeo]             = exp(geoSum / dPositive);
                    realResults[soMeanHarm]        = dPositive / harmSum;

                    // variance and std dev
                    if (nOK > 1)
                        {
                            double var = 0.0;
                            double mean = realResults[soMean];
                            for (int i = 0; i < data.Size(); i++)
                                {
                                    double dVal = data[i];
                                    if (RealIsNull(dVal) || (logData && (dVal < 1.0E-99)))
                                        continue;

                                    if (logData)  {
                                        if (baseTen)  {
                                            dVal = log10(dVal);
                                        }
                                        else {
                                            dVal = log(dVal);
                                        }
                                    }

                                    double dx = dVal - mean;
                                    var += dx * dx;
                                }

                            var /= double(nOK - 1);

                            realResults[soVar]  = var;
                            realResults[soStdDev]  = sqrt(var);
                        }
                }
        }

    /*
      mean results now log data
      if (logData) {
      if (baseTen) {
      realResults[soMean] = InvLgt(realResults[soMean]);
      }
      else {
      realResults[soMean] = exp(realResults[soMean]);
      }
      } */

}