Ejemplo n.º 1
0
bool ImageSegmentation::toSegment(const std::vector<std::vector<cv::Point>> &contours, const std::vector<cv::Vec4i> &hierarchy, const size_t index,
                                  Segment &seg, const size_t minSize, const size_t minHoleSize, const cv::Rect &roi)
{
  seg.rect = cv::boundingRect(contours[index]);
  if(!roi.contains(seg.rect.tl()) || !roi.contains(seg.rect.br()))
  {
    // outside ROI
    return false;
  }

  seg.area = cv::contourArea(contours[index]);
  seg.childrenArea = 0;
  seg.holes = 0;

  if(seg.area < minSize)
  {
    return false;
  }

  Segment child;
  for(int32_t childIndex = hierarchy[index][2]; childIndex >= 0; childIndex = hierarchy[childIndex][0])
  {
    if(toSegment(contours, hierarchy, childIndex, child, minHoleSize, minHoleSize, roi))
    {
      seg.children.push_back(child);
      seg.area -= child.area;
      seg.childrenArea += child.area;
      ++seg.holes;
    }
  }

  if(seg.area < minSize)
  {
    return false;
  }

  seg.contour = contours[index];
  computeMoments(contours, hierarchy, index, seg);
  compute2DAttributes(seg);

  return true;
}
Ejemplo n.º 2
0
/*!
  Track the ellipse in the image I.

  \param I : Image in which the ellipse appears.
*/
void
vpMeEllipse::track(const vpImage<unsigned char> &I)
{
  vpCDEBUG(1) <<"begin vpMeEllipse::track()"<<std::endl ;

  static int iter =0 ;
  //  1. On fait ce qui concerne les ellipse (peut etre vide)
  {
  }

  //vpDisplay::display(I) ;
  //  2. On appelle ce qui n'est pas specifique
  {

  try{
       vpMeTracker::track(I) ;
  }
  catch(...)
  {
    vpERROR_TRACE("Error caught") ;
    throw ;
  }
    //    std::cout << "number of signals " << numberOfSignal() << std::endl ;
  }

  // 3. On revient aux ellipses
  {
    // Estimation des parametres de la droite aux moindres carre
    suppressPoints() ;
    setExtremities() ;


    try{
      leastSquare() ;  }
    catch(...)
    {
      vpERROR_TRACE("Error caught") ;
      throw ;
    }

    seekExtremities(I) ;

    setExtremities() ;

    try
    {
      leastSquare() ;
    }
    catch(...)
    {
      vpERROR_TRACE("Error caught") ;
	  throw ;
    }

    // suppression des points rejetes par la regression robuste
    suppressPoints() ;
    setExtremities() ;

    //reechantillonage si necessaire
    reSample(I) ;

    // remet a jour l'angle delta pour chaque  point de la liste

    updateTheta() ;
    
    computeMoments();

    // Remise a jour de delta dans la liste de site me
    if (vpDEBUG_ENABLE(2))
    {
	display(I,vpColor::red) ;
	vpMeTracker::display(I) ;
	vpDisplay::flush(I) ;
    }
//     computeAngle(iP1, iP2) ;
// 
//     if (iter%5==0)
//     {
//       sample(I) ;
//       try{
// 	leastSquare() ;  }
//       catch(...)
//       {
// 	vpERROR_TRACE("Error caught") ;
// 	throw ;
//       }
//       computeAngle(iP1, iP2) ;
//     }
//     seekExtremities(I) ;
// 
//     vpMeTracker::display(I) ;
//     // vpDisplay::flush(I) ;
// 
//     // remet a jour l'angle theta pour chaque  point de la liste
//     updateTheta() ;

  }

  iter++ ;


  vpCDEBUG(1) << "end vpMeEllipse::track()"<<std::endl ;

}
int main()
{
    bool ok = true;
    df::DoublePowerLawParam paramDPL;
    paramDPL.slopeIn   = 0;
    paramDPL.slopeOut  = 7.5;
    paramDPL.J0        = 1;
    paramDPL.coefJrIn  = 0.1;
    paramDPL.coefJzIn  = (3-paramDPL.coefJrIn)/2;
    paramDPL.coefJrOut = 1.2;
    paramDPL.coefJzOut = 0.9;
    paramDPL.norm = 78.19;
    potential::Plummer pot(1., 1.);
    const actions::ActionFinderSpherical af(pot);
    const df::DoublePowerLaw dfO(paramDPL);    // original distribution function
    df::PtrActionSpaceScaling scaling(new df::ActionSpaceScalingTriangLog());
    unsigned int gridSize[3] = {40, 7, 5};
    std::vector<double> gridU(gridSize[0]),
    gridV(math::createUniformGrid(gridSize[1], 0, 1)),
    gridW(math::createUniformGrid(gridSize[2], 0, 1));
    double totalMass = pot.totalMass();
    for(unsigned int i=0; i<gridSize[0]; i++) {
        double r = getRadiusByMass(pot, totalMass * (1 - cos(M_PI * i / gridSize[0])) / 2);
        //std::cout << r << ' ';
        double J = r * v_circ(pot, r);  // r^2*Omega
        double v[3];
        scaling->toScaled(actions::Actions(0,0,J), v);
        gridU[i] = v[0];
    }
    std::vector<double> amplL = df::createInterpolatedDFAmplitudes<1>(dfO, *scaling, gridU, gridV, gridW);
    const df::InterpolatedDF<1> dfL(scaling, gridU, gridV, gridW, amplL); // linearly-interpolated DF
    std::vector<double> amplC = df::createInterpolatedDFAmplitudes<3>(dfO, *scaling, gridU, gridV, gridW);
    const df::InterpolatedDF<3> dfC(scaling, gridU, gridV, gridW, amplC); // cubic-interpolated DF
    std::cout << "Constructed interpolated DFs\n";
    std::ofstream strm, strmL, strmC;
    if(utils::verbosityLevel >= utils::VL_VERBOSE)
        strm.open("test_df_interpolated.dfval");
    for(unsigned int i=0; i<gridSize[0]; i++) {
        for(unsigned int j=0; j<gridSize[1]; j++) {
            for(unsigned int k=0; k<gridSize[2]; k++) {
                double v[3] = {gridU[i], gridV[j], gridW[k]};
                actions::Actions J = scaling->toActions(v);
                double valL = dfL.value(J), valC = dfC.value(J);
                ok &= math::fcmp(valL, valC, 1e-12) == 0;  // should be the same
                strm << v[0] << ' ' << v[1] << ' ' << v[2] << ' ' << valL << ' ' << valC << '\n';
            }
        }
        strm << '\n';
    }
    strm.close();

    double sumLin=0;
    if(utils::verbosityLevel >= utils::VL_VERBOSE)
        strm.open("test_df_interpolated.phasevolL");
    for(unsigned int i=0; i<amplL.size(); i++) {
        double phasevol = dfL.computePhaseVolume(i);
        strm << amplL[i] << ' ' << phasevol << '\n';
        sumLin += amplL[i] * phasevol;
    }
    strm.close();

    double sumCub=0;
    if(utils::verbosityLevel >= utils::VL_VERBOSE)
        strm.open("test_df_interpolated.phasevolC");
    for(unsigned int i=0; i<amplC.size(); i++) {
        double phasevol = dfC.computePhaseVolume(i);
        strm << amplC[i] << ' ' << phasevol << '\n';
        sumCub += amplC[i] * phasevol;
    }
    strm.close();

    double massOrig = dfO.totalMass();
    double massLin  = dfL.totalMass();
    double massCub  = dfC.totalMass();
    std::cout << "M=" << pot.totalMass() << ", dfOrig M=" << massOrig <<
        ", dfInterLin M=" << massLin << ", sum over components=" << sumLin << 
        ", dfInterCub M=" << massCub << ", sum over components=" << sumCub << '\n';
    ok &= math::fcmp(massOrig, massLin, 2e-2)==0 && math::fcmp(sumLin, massLin, 1e-3)==0 &&
          math::fcmp(massOrig, massCub, 2e-2)==0 && math::fcmp(sumCub, massCub, 1e-3)==0;

    if(utils::verbosityLevel >= utils::VL_VERBOSE) {
        strm.open ("test_df_interpolated.densval");
        strmL.open("test_df_interpolated.denscompL");
        strmC.open("test_df_interpolated.denscompC");
    }
    for(double r=0; r<20; r<1 ? r+=0.1 : r*=1.1) {
        coord::PosCyl point(r, 0, 0);
        std::vector<double> densArrL(dfL.size()), densArrC(dfC.size());
        double densOrig, densIntL, densIntC;
        computeMoments(galaxymodel::GalaxyModelMulticomponent(pot, af, dfL),
            point, &densArrL[0], NULL, NULL, NULL, NULL, NULL, 1e-3, 10000);
        computeMoments(galaxymodel::GalaxyModelMulticomponent(pot, af, dfC),
            point, &densArrC[0], NULL, NULL, NULL, NULL, NULL, 1e-3, 10000);
        computeMoments(galaxymodel::GalaxyModel(pot, af, dfO),
            point, &densOrig,    NULL, NULL, NULL, NULL, NULL, 1e-3, 100000);
        computeMoments(galaxymodel::GalaxyModel(pot, af, dfL),
            point, &densIntL,    NULL, NULL, NULL, NULL, NULL, 1e-3, 100000);
        computeMoments(galaxymodel::GalaxyModel(pot, af, dfC),
            point, &densIntC,    NULL, NULL, NULL, NULL, NULL, 1e-3, 100000);
        double densSumL=0;
        for(unsigned int i=0; i<densArrL.size(); i++) {
            densSumL += densArrL[i];
            strmL << densArrL[i] << '\n';
        }
        strmL << '\n';
        double densSumC=0;
        for(unsigned int i=0; i<densArrC.size(); i++) {
            densSumC += densArrC[i];
            strmC << densArrC[i] << '\n';
        }
        strmC << '\n';
        strm << r << ' ' << pot.density(point) << '\t' << densOrig << '\t' <<
            densIntL << ' ' << densSumL << '\t' << densIntC << ' ' << densSumC << '\n';
        ok &= math::fcmp(densOrig, densIntL, 2e-1)==0 && math::fcmp(densSumL, densIntL, 1e-2)==0 && 
              math::fcmp(densOrig, densIntC, 5e-2)==0 && math::fcmp(densSumC, densIntC, 1e-2)==0;
        if(!ok) std::cout << "failed at r="<<r<<"\n";
    }

    if(ok)
        std::cout << "\033[1;32mALL TESTS PASSED\033[0m\n";
    else
        std::cout << "\033[1;31mSOME TESTS FAILED\033[0m\n";
    return 0;
}
Ejemplo n.º 4
0
int main(int argc, char **argv)
{
  STAT_DEFINITION *stat;
  long stats;
  STAT_REQUEST *request;
  long requests, count;
  SCANNED_ARG *scanned; 
  SDDS_DATASET inData, outData;

  int32_t power;
  long i_arg, code, iStat, rows, tmpFileUsed, iColumn, row, posColIndex;
  long noWarnings, maxSourceColumns;
  char *input, *output, *positionColumn, **posColumnName;
  double **inputData, *outputData, value1, value2, topLimit, bottomLimit;
  unsigned long pipeFlags, scanFlags, majorOrderFlag;
  char s[100];
  double *statWorkArray;
  double quartilePoint[2] = {25.0, 75.0 }, quartileResult[2];
  double decilePoint[2]   = {10.0, 90.0 }, decileResult[2];
  double percent;
  short columnMajorOrder=-1;
  
  SDDS_RegisterProgramName(argv[0]);
  argc = scanargs(&scanned, argc, argv); 
  if (argc<2) {
    bomb("too few arguments", USAGE);
  }
  
  posColumnName = NULL;
  input = output = positionColumn = NULL;
  stat = NULL;
  request = NULL;
  stats = requests = pipeFlags = 0;
  noWarnings = 0;
  outputData = NULL;
  statWorkArray = NULL;
  
  for (i_arg=1; i_arg<argc; i_arg++) {
    scanFlags = 0;
    if (scanned[i_arg].arg_type==OPTION) {
      /* process options here */
      switch (code=match_string(scanned[i_arg].list[0], option, N_OPTIONS, 0)) {
      case SET_MAXIMUM:
      case SET_MINIMUM:
      case SET_MEAN:
      case SET_MEDIAN:
      case SET_STANDARDDEVIATION:
      case SET_RMS:
      case SET_SIGMA:
      case SET_MAD:
      case SET_COUNT:
      case SET_DRANGE:
      case SET_QRANGE:
      case SET_SMALLEST:
      case SET_LARGEST:
      case SET_SPREAD:
        if (scanned[i_arg].n_items<3) {
          fprintf(stderr, "error: invalid -%s syntax\n", option[code]);
          exit(1);
        }
        if (!scanItemList(&scanFlags, scanned[i_arg].list, &scanned[i_arg].n_items,
                          SCANITEMLIST_UNKNOWN_VALUE_OK|SCANITEMLIST_REMOVE_USED_ITEMS|
                          SCANITEMLIST_IGNORE_VALUELESS,
                          "positionColumn", SDDS_STRING, &positionColumn, 1, POSITIONCOLUMN_GIVEN,
                          "toplimit", SDDS_DOUBLE, &topLimit, 1, TOPLIMIT_GIVEN,
                          "bottomlimit", SDDS_DOUBLE, &bottomLimit, 1, BOTTOMLIMIT_GIVEN,
                          NULL)) {
          sprintf(s, "invalid -%s syntax", scanned[i_arg].list[0]);
          SDDS_Bomb(s);
        }
        requests = addStatRequests(&request, requests, scanned[i_arg].list+1, scanned[i_arg].n_items-1,
                                   code, scanFlags);
        request[requests-1].topLimit = topLimit;
        request[requests-1].bottomLimit = bottomLimit;
        if (positionColumn) {
          if (code==SET_MAXIMUM || code==SET_MINIMUM || code==SET_LARGEST || code==SET_SMALLEST) 
            SDDS_CopyString(&request[requests-1].positionColumn, positionColumn);
          free(positionColumn);
          positionColumn = NULL;
        }
        break;
      case SET_PERCENTILE:
        if (scanned[i_arg].n_items<3) {
          fprintf(stderr, "error: invalid -%s syntax\n", option[code]);
          exit(1);
        }
        if (!scanItemList(&scanFlags, scanned[i_arg].list, &scanned[i_arg].n_items, 
                          SCANITEMLIST_UNKNOWN_VALUE_OK|SCANITEMLIST_REMOVE_USED_ITEMS|
                          SCANITEMLIST_IGNORE_VALUELESS,
                          "value", SDDS_DOUBLE, &percent, 1, PERCENT_GIVEN,
                          "toplimit", SDDS_DOUBLE, &topLimit, 1, TOPLIMIT_GIVEN,
                          "bottomlimit", SDDS_DOUBLE, &bottomLimit, 1, BOTTOMLIMIT_GIVEN,
                          NULL) || 
            !(scanFlags&PERCENT_GIVEN) || percent<=0 || percent>=100) 
          SDDS_Bomb("invalid -percentile syntax");
        requests = addStatRequests(&request, requests, scanned[i_arg].list+1, scanned[i_arg].n_items-1,
                                   code, scanFlags);
        request[requests-1].percent = percent;
        request[requests-1].topLimit = topLimit;
        request[requests-1].bottomLimit = bottomLimit;
        break;
      case SET_SUM:
        if (scanned[i_arg].n_items<3) {
          fprintf(stderr, "error: invalid -%s syntax\n", option[code]);
          exit(1);
        }
        power = 1;
        if (!scanItemList(&scanFlags, scanned[i_arg].list, &scanned[i_arg].n_items, 
                          SCANITEMLIST_UNKNOWN_VALUE_OK|SCANITEMLIST_REMOVE_USED_ITEMS|
                          SCANITEMLIST_IGNORE_VALUELESS,
                          "power", SDDS_LONG, &power, 1, 0, 
                          "toplimit", SDDS_DOUBLE, &topLimit, 1, TOPLIMIT_GIVEN,
                          "bottomlimit", SDDS_DOUBLE, &bottomLimit, 1, BOTTOMLIMIT_GIVEN,
                          NULL))
          SDDS_Bomb("invalid -sum syntax");
        requests = addStatRequests(&request, requests, scanned[i_arg].list+1, scanned[i_arg].n_items-1,
                                   code, scanFlags);
        request[requests-1].sumPower = power;
        request[requests-1].topLimit = topLimit;
        request[requests-1].bottomLimit = bottomLimit;
        break;
      case SET_PIPE:
        if (!processPipeOption(scanned[i_arg].list+1, scanned[i_arg].n_items-1, &pipeFlags))
          SDDS_Bomb("invalid -pipe syntax");
        break;
      case SET_NOWARNINGS:
        noWarnings = 1;
        break;
      case SET_MAJOR_ORDER:
        majorOrderFlag=0;
        scanned[i_arg].n_items --;
        if (scanned[i_arg].n_items>0 &&
            (!scanItemList(&majorOrderFlag, scanned[i_arg].list+1, &scanned[i_arg].n_items, 0,
                           "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
                           "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER,
                           NULL)))
          SDDS_Bomb("invalid -majorOrder syntax/values");
        if (majorOrderFlag&SDDS_COLUMN_MAJOR_ORDER)
          columnMajorOrder=1;
        else if (majorOrderFlag&SDDS_ROW_MAJOR_ORDER)
          columnMajorOrder=0;
        break;
      default:
        fprintf(stderr, "error: unknown option '%s' given\n", scanned[i_arg].list[0]);
        exit(1);
        break;
      }
    }
    else {  
      /* argument is filename */
      if (!input)
        input = scanned[i_arg].list[0];
      else if (!output)
        output = scanned[i_arg].list[0];
      else
        SDDS_Bomb("too many filenames seen");
    }
  }
  
  processFilenames("sddsrowstats", &input, &output, pipeFlags, noWarnings, &tmpFileUsed);

  if (!requests)
    SDDS_Bomb("no statistics requested");
  
  if (!SDDS_InitializeInput(&inData, input))
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);

  if (!(stat=compileStatDefinitions(&inData, request, requests, &stats, noWarnings))) {
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
    exit(1);
  }
  if (stats<0) 
    SDDS_Bomb("No valid statistics requests.");
  for (iStat=maxSourceColumns=0; iStat<stats; iStat++) {
    if (stat[iStat].sourceColumns>maxSourceColumns)
      maxSourceColumns = stat[iStat].sourceColumns;
  }
  if (!(statWorkArray=malloc(sizeof(*statWorkArray)*maxSourceColumns)))
    SDDS_Bomb("allocation failure (statWorkArray)");

  if (!setupOutputFile(&outData, output, &inData, stat, stats)) {
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
    exit(1);
  }

  inputData = NULL;

  while ((code=SDDS_ReadPage(&inData))>0) {
    if (!SDDS_CopyPage(&outData, &inData)) {
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
      exit(1);
    }
    if ((rows = SDDS_CountRowsOfInterest(&inData))) {
      if (!(outputData = (double*)malloc(sizeof(*outputData)*rows))) 
        SDDS_Bomb("memory allocation failure");
      if (!(posColumnName = (char**)malloc(sizeof(*posColumnName)*rows))) 
        SDDS_Bomb("memory allocation failure");
      for (iStat=0; iStat<stats; iStat++) {
        if (!(inputData = (double**)malloc(sizeof(*inputData)*stat[iStat].sourceColumns)))
          SDDS_Bomb("memory allocation failure");
        for (iColumn=0; iColumn<stat[iStat].sourceColumns; iColumn++) {
          if (!(inputData[iColumn] = SDDS_GetColumnInDoubles(&inData, stat[iStat].sourceColumn[iColumn])))
            SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        }
        for (row=0; row<rows; row++) 
          outputData[row] = DBL_MAX;
        switch (stat[iStat].optionCode) {
        case SET_MINIMUM:
          for (row=0; row<rows; row++) {
            value1 = DBL_MAX;
            posColIndex = 0;
            posColumnName[row] = NULL;
            for (iColumn=0; iColumn<stat[iStat].sourceColumns; iColumn++) {
              if (stat[iStat].flags&TOPLIMIT_GIVEN && 
                  inputData[iColumn][row]>stat[iStat].topLimit)
                continue;
              if (stat[iStat].flags&BOTTOMLIMIT_GIVEN && 
                  inputData[iColumn][row]<stat[iStat].bottomLimit)
                continue;
              if (inputData[iColumn][row]<value1) {
                value1 = inputData[iColumn][row];
                posColIndex = iColumn;
              }
            }
            outputData[row] = value1;
            if (stat[iStat].positionColumn) 
              posColumnName[row] = stat[iStat].sourceColumn[posColIndex];
          }
          break;
        case SET_MAXIMUM:
          for (row=0; row<rows; row++) {
            posColIndex = 0;
            value1 = -DBL_MAX;
            posColumnName[row] = NULL;
            for (iColumn=0; iColumn<stat[iStat].sourceColumns; iColumn++) {
              if (stat[iStat].flags&TOPLIMIT_GIVEN && 
                  inputData[iColumn][row]>stat[iStat].topLimit)
                continue;
              if (stat[iStat].flags&BOTTOMLIMIT_GIVEN && 
                  inputData[iColumn][row]<stat[iStat].bottomLimit)
                continue;
              if (inputData[iColumn][row]>value1) {
                posColIndex = iColumn; 
                value1 = inputData[iColumn][row];
              }
            }
            outputData[row] = value1;
            if (stat[iStat].positionColumn) 
              posColumnName[row] = stat[iStat].sourceColumn[posColIndex];
          }
          break;
        case SET_MEAN:
          for (row=0; row<rows; row++) {
            value1 = 0;
            count = 0;
            for (iColumn=0; iColumn<stat[iStat].sourceColumns; iColumn++) {
              if (stat[iStat].flags&TOPLIMIT_GIVEN && 
                  inputData[iColumn][row]>stat[iStat].topLimit)
                continue;
              if (stat[iStat].flags&BOTTOMLIMIT_GIVEN && 
                  inputData[iColumn][row]<stat[iStat].bottomLimit)
                continue;
              value1 += inputData[iColumn][row];
              count ++;
            }
            if (count)
              outputData[row] = value1/count;
          }
          break;
        case SET_MEDIAN:
          for (row=0; row<rows; row++) {
            for (iColumn=count=0; iColumn<stat[iStat].sourceColumns; iColumn++) {
              if (stat[iStat].flags&TOPLIMIT_GIVEN && 
                  inputData[iColumn][row]>stat[iStat].topLimit)
                continue;
              if (stat[iStat].flags&BOTTOMLIMIT_GIVEN && 
                  inputData[iColumn][row]<stat[iStat].bottomLimit)
                continue;
              statWorkArray[count] = inputData[iColumn][row];
              count++;
            }
            if (count)
              compute_median(outputData+row, statWorkArray, count);
          }
          break;
        case SET_STANDARDDEVIATION:
          for (row=0; row<rows; row++) {
            value1 = 0;
            value2 = 0;
            count = 0;
            for (iColumn=0; iColumn<stat[iStat].sourceColumns; iColumn++) {
              if (stat[iStat].flags&TOPLIMIT_GIVEN && 
                  inputData[iColumn][row]>stat[iStat].topLimit)
                continue;
              if (stat[iStat].flags&BOTTOMLIMIT_GIVEN && 
                  inputData[iColumn][row]<stat[iStat].bottomLimit)
                continue;
              value1 += inputData[iColumn][row];
              value2 += inputData[iColumn][row]*inputData[iColumn][row];
              count ++;
            }
            if (count>1) {
              if ((value1 = value2/count - sqr(value1/count))<=0)
                outputData[row] = 0;
              else
                outputData[row] = sqrt(value1*count/(count-1.0));
            }
          }
          break;
        case SET_SIGMA:
          for (row=0; row<rows; row++) {
            value1 = 0;
            value2 = 0;
            count = 0;
            for (iColumn=0; iColumn<stat[iStat].sourceColumns; iColumn++) {
              if (stat[iStat].flags&TOPLIMIT_GIVEN && 
                  inputData[iColumn][row]>stat[iStat].topLimit)
                continue;
              if (stat[iStat].flags&BOTTOMLIMIT_GIVEN && 
                  inputData[iColumn][row]<stat[iStat].bottomLimit)
                continue;
              value1 += inputData[iColumn][row];
              value2 += inputData[iColumn][row]*inputData[iColumn][row];
              count ++;
            }
            if (count>1) {
              if ((value1 = value2/count - sqr(value1/count))<=0)
                outputData[row] = 0;
              else
                outputData[row] = sqrt(value1/(count-1.0));
            }
          }
          break;
        case SET_RMS:
          for (row=0; row<rows; row++) {
            value1 = 0;
            count = 0;
            for (iColumn=0; iColumn<stat[iStat].sourceColumns; iColumn++) {
              if (stat[iStat].flags&TOPLIMIT_GIVEN && 
                  inputData[iColumn][row]>stat[iStat].topLimit)
                continue;
              if (stat[iStat].flags&BOTTOMLIMIT_GIVEN && 
                  inputData[iColumn][row]<stat[iStat].bottomLimit)
                continue;
              value1 += sqr(inputData[iColumn][row]);
              count ++;
            }
            if (count)
              outputData[row] = sqrt(value1/count);
          }
          break;
        case SET_SUM:
          for (row=0; row<rows; row++) {
            value1 = 0;
            count = 0;
            for (iColumn=0; iColumn<stat[iStat].sourceColumns; iColumn++) {
              if (stat[iStat].flags&TOPLIMIT_GIVEN && 
                  inputData[iColumn][row]>stat[iStat].topLimit)
                continue;
              if (stat[iStat].flags&BOTTOMLIMIT_GIVEN && 
                  inputData[iColumn][row]<stat[iStat].bottomLimit)
                continue;
              value1 += ipow(inputData[iColumn][row], stat[iStat].sumPower);
              count ++;
            }
            if (count)
              outputData[row] = value1;
          }
          break;
        case SET_COUNT:
          for (row=0; row<rows; row++) {
            count = 0;
            for (iColumn=0; iColumn<stat[iStat].sourceColumns; iColumn++) {
              if (stat[iStat].flags&TOPLIMIT_GIVEN && 
                  inputData[iColumn][row]>stat[iStat].topLimit)
                continue;
              if (stat[iStat].flags&BOTTOMLIMIT_GIVEN && 
                  inputData[iColumn][row]<stat[iStat].bottomLimit)
                continue;
              count++;
            }
            outputData[row] = count;
          }
          break;
        case SET_MAD:
          for (row=0; row<rows; row++) {
            for (iColumn=count=value1=0; iColumn<stat[iStat].sourceColumns; iColumn++) {
              if (stat[iStat].flags&TOPLIMIT_GIVEN && 
                  inputData[iColumn][row]>stat[iStat].topLimit)
                continue;
              if (stat[iStat].flags&BOTTOMLIMIT_GIVEN && 
                  inputData[iColumn][row]<stat[iStat].bottomLimit)
                continue;
              statWorkArray[count] = inputData[iColumn][row];
              count++;
            }
            if (count)
              computeMoments(NULL, NULL, NULL, &outputData[row],
                             statWorkArray, count);
          }
          break;
        case SET_DRANGE:
          for (row=0; row<rows; row++) {
            for (iColumn=count=value1=0; iColumn<stat[iStat].sourceColumns; iColumn++) {
              if (stat[iStat].flags&TOPLIMIT_GIVEN &&
                  inputData[iColumn][row]>stat[iStat].topLimit)
                continue;
              if (stat[iStat].flags&BOTTOMLIMIT_GIVEN &&
                  inputData[iColumn][row]<stat[iStat].bottomLimit)
                continue;
              statWorkArray[count] = inputData[iColumn][row];
              count++;
            }
            if (count && 
                compute_percentiles(decileResult, decilePoint, 2, 
                                    statWorkArray, count))
              outputData[row] = decileResult[1] - decileResult[0];
          }
          break;
        case SET_QRANGE:
          for (row=0; row<rows; row++) {
            for (iColumn=count=value1=0; iColumn<stat[iStat].sourceColumns; iColumn++) {
              if (stat[iStat].flags&TOPLIMIT_GIVEN &&
                  inputData[iColumn][row]>stat[iStat].topLimit)
                continue;
              if (stat[iStat].flags&BOTTOMLIMIT_GIVEN &&
                  inputData[iColumn][row]<stat[iStat].bottomLimit)
                continue;
              statWorkArray[count] = inputData[iColumn][row];
              count++;
            }
            if (count && 
                compute_percentiles(quartileResult, quartilePoint, 2, 
                                    statWorkArray, count))
              outputData[row] = quartileResult[1] - quartileResult[0];
          }
          break;
        case SET_SMALLEST:
          for (row=0; row<rows; row++) {
            value1 = DBL_MAX;
            posColIndex = 0;
            posColumnName[row] = NULL;
            for (iColumn=0; iColumn<stat[iStat].sourceColumns; iColumn++) {
              if (stat[iStat].flags&TOPLIMIT_GIVEN && 
                  inputData[iColumn][row]>stat[iStat].topLimit)
                continue;
              if (stat[iStat].flags&BOTTOMLIMIT_GIVEN && 
                  inputData[iColumn][row]<stat[iStat].bottomLimit)
                continue;
              if ((value2=fabs(inputData[iColumn][row]))<value1) {
                posColIndex = iColumn;
                value1 = value2;
              }
            }
            outputData[row] = value1; 
            if (stat[iStat].positionColumn) 
              posColumnName[row] = stat[iStat].sourceColumn[posColIndex];
          }
          break;
        case SET_LARGEST:
          for (row=0; row<rows; row++) {
            value1 = 0;
            posColIndex = 0;
            posColumnName[row] = NULL;
            for (iColumn=0; iColumn<stat[iStat].sourceColumns; iColumn++) {
              if (stat[iStat].flags&TOPLIMIT_GIVEN && 
                  inputData[iColumn][row]>stat[iStat].topLimit)
                continue;
              if (stat[iStat].flags&BOTTOMLIMIT_GIVEN && 
                  inputData[iColumn][row]<stat[iStat].bottomLimit)
                continue;
              if ((value2=fabs(inputData[iColumn][row]))>value1) {
                posColIndex = iColumn;
                value1 = value2;
              }
            }
            outputData[row] = value1;
            if (stat[iStat].positionColumn) 
              posColumnName[row] = stat[iStat].sourceColumn[posColIndex];
          }
          break;
        case SET_SPREAD:
          for (row=0; row<rows; row++) {
            value1 = DBL_MAX;  /* min */
            value2 = -DBL_MAX; /* max */
            for (iColumn=0; iColumn<stat[iStat].sourceColumns; iColumn++) {
              if (stat[iStat].flags&TOPLIMIT_GIVEN && 
                  inputData[iColumn][row]>stat[iStat].topLimit)
                continue;
              if (stat[iStat].flags&BOTTOMLIMIT_GIVEN && 
                  inputData[iColumn][row]<stat[iStat].bottomLimit)
                continue;
              if (inputData[iColumn][row]<value1)
                value1 = inputData[iColumn][row];
              if (inputData[iColumn][row]>value2)
                value2 = inputData[iColumn][row];
            }
            outputData[row] = value2-value1;
          }
          break;
        case SET_PERCENTILE:
          for (row=0; row<rows; row++) {
            for (iColumn=count=value1=0; iColumn<stat[iStat].sourceColumns; iColumn++) {
              if (stat[iStat].flags&TOPLIMIT_GIVEN &&
                  inputData[iColumn][row]>stat[iStat].topLimit)
                continue;
              if (stat[iStat].flags&BOTTOMLIMIT_GIVEN &&
                  inputData[iColumn][row]<stat[iStat].bottomLimit)
                continue;
              statWorkArray[count] = inputData[iColumn][row];
              count++;
            }
            outputData[row] = HUGE_VAL;
            if (count) 
              compute_percentiles(&outputData[row], &stat[iStat].percent,  1, statWorkArray, count);
          }
          break;
        default:
          SDDS_Bomb("invalid statistic code (accumulation loop)");
          break;
        }
        if (!SDDS_SetColumn(&outData, SDDS_SET_BY_INDEX, outputData, rows, stat[iStat].resultIndex))
          SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        
        if (stat[iStat].positionColumn) {
          if (!SDDS_SetColumn(&outData, SDDS_SET_BY_INDEX, posColumnName, rows, 
                              stat[iStat].positionColumnIndex))
            SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        }
        for (iColumn=0; iColumn<stat[iStat].sourceColumns; iColumn++)
          free(inputData[iColumn]);
        free(inputData);
        inputData = NULL;
      }
      free(outputData);
      outputData = NULL;
      free(posColumnName);
      posColumnName = NULL;
    }
    if (!SDDS_WritePage(&outData))
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  }
  free_scanargs(&scanned, argc);
  for (iStat=0; iStat<stats; iStat++) { 
    if (stat[iStat].positionColumn) free(stat[iStat].positionColumn);
    for (iColumn=0; iColumn<stat[iStat].sourceColumns; iColumn++)
      free(stat[iStat].sourceColumn[iColumn]);
    free(stat[iStat].sourceColumn); 
  }
  free(request);
  free(stat);
  if (statWorkArray) free(statWorkArray);
  
  if (!SDDS_Terminate(&inData) || !SDDS_Terminate(&outData)) {
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
    exit(1);
  } 
  if (tmpFileUsed && !replaceFileAndBackUp(input, output))
    exit(1);
  return 0;
}