Пример #1
0
int main(int argc, char **argv)
{
  int iArg;
  char *indepQuantity, **depenQuantity, *fileValuesQuantity, *fileValuesFile, **exclude;
  long depenQuantities, monotonicity, excludes;
  char *input, *output;
  long i, j, rows, readCode, order, valuesReadCode, fillIn, row;
  long sequencePoints, combineDuplicates, branch;
  int32_t *rowFlag;
  double sequenceStart, sequenceEnd;
  double sequenceSpacing;
  unsigned long flags, interpCode, printFlags, forceMonotonic;
  SCANNED_ARG *scanned;
  SDDS_DATASET SDDSin, SDDSout, SDDSvalues;
  OUTRANGE_CONTROL aboveRange, belowRange;
  double *atValue;
  long atValues, interpPoints, doNotRead, parallelPages;
  double *indepValue, **depenValue, *interpPoint, **outputData;
  unsigned long pipeFlags;
  FILE *fpPrint;
  short interpShort=0, interpShortOrder=-1, *shortValue=NULL;
  long nextPos;

  SDDS_RegisterProgramName(argv[0]);
  argc = scanargs(&scanned, argc, argv); 
  if (argc<3 || argc>(3+CLO_OPTIONS)) 
    bomb(NULL, USAGE);

  atValue = NULL;
  atValues = fillIn = 0;
  output = input = NULL;
  combineDuplicates = branch = sequencePoints = parallelPages = 0;
  indepQuantity = NULL;
  depenQuantity = exclude = NULL;
  depenQuantities = excludes = 0;
  aboveRange.flags = belowRange.flags = OUTRANGE_SATURATE;
  order = 1;
  readCode = interpPoints = 0;
  fileValuesFile = fileValuesQuantity = NULL;
  sequenceStart = sequenceEnd = sequenceSpacing = 0;
  printFlags = pipeFlags = 0;
  forceMonotonic = 0;
  indepValue = interpPoint = NULL;
  depenValue = outputData = NULL;

  for (iArg=1; iArg<argc; iArg++) {
    if (scanned[iArg].arg_type==OPTION) {
      /* process options here */
      switch (match_string(scanned[iArg].list[0], option, CLO_OPTIONS, 0)) {
      case CLO_ORDER:
        if (scanned[iArg].n_items!=2 || sscanf(scanned[iArg].list[1], "%ld", &order)!=1 ||
            order<1)
          SDDS_Bomb("invalid -order syntax/value");
        break;
      case CLO_ATVALUES:
        if (scanned[iArg].n_items<2)
          SDDS_Bomb("invalid -atValues syntax");
        if (atValue)
          SDDS_Bomb("give -atValues only once");
        atValue = tmalloc(sizeof(*atValue)*(atValues=scanned[iArg].n_items-1));
        for (i=0; i<atValues; i++)
          if (sscanf(scanned[iArg].list[i+1], "%lf", &atValue[i])!=1)
            SDDS_Bomb("invalid -atValues value");
        break;
      case CLO_INTERP_SHORT:
        if (scanned[iArg].n_items==2) {
          if (sscanf(scanned[iArg].list[1], "%hd", &interpShortOrder)!=1)
            SDDS_Bomb("invalid -interpShort value");
        }
        interpShort = 1;
        break;
      case CLO_SEQUENCE:
        if ((scanned[iArg].n_items!=2 && scanned[iArg].n_items!=4) ||
            sscanf(scanned[iArg].list[1], "%ld", &sequencePoints)!=1 || sequencePoints<2)
          SDDS_Bomb("invalid -sequence syntax/value");
        if (scanned[iArg].n_items==4 &&
            (sscanf(scanned[iArg].list[2], "%lf", &sequenceStart)!=1 ||
             sscanf(scanned[iArg].list[3], "%lf", &sequenceEnd)!=1))
          SDDS_Bomb("invalid -sequence syntax/value");
        if (sequenceSpacing)
          SDDS_Bomb("give only one of -sequence and -equispaced");
        break;
      case CLO_EQUISPACED:
        if ((scanned[iArg].n_items!=2 && scanned[iArg].n_items!=4) ||
            sscanf(scanned[iArg].list[1], "%lf", &sequenceSpacing)!=1 || sequenceSpacing<=0)
          SDDS_Bomb("invalid -equispaced syntax/value");
        if (scanned[iArg].n_items==4 &&
            (sscanf(scanned[iArg].list[2], "%lf", &sequenceStart)!=1 ||
             sscanf(scanned[iArg].list[3], "%lf", &sequenceEnd)!=1))
          SDDS_Bomb("invalid -equispaced syntax/values");
        if (sequencePoints)
          SDDS_Bomb("give only one of -sequence and -equispaced");
        break;
      case CLO_COLUMNS:
        if (indepQuantity)
          SDDS_Bomb("only one -columns option may be given");
        if (scanned[iArg].n_items<2)
          SDDS_Bomb("invalid -columns syntax");
        indepQuantity = scanned[iArg].list[1];
        if (scanned[iArg].n_items>=2) {
          depenQuantity = tmalloc(sizeof(*depenQuantity)*(depenQuantities=scanned[iArg].n_items-2));
          for (i=0; i<depenQuantities; i++)
            depenQuantity[i] = scanned[iArg].list[i+2];
        }
        break;
      case CLO_PRINTOUT:
        if ((scanned[iArg].n_items-=1)>=1) {
          if (!scanItemList(&printFlags, scanned[iArg].list+1, &scanned[iArg].n_items, 0,
                            "bare", -1, NULL, 0, BARE_PRINTOUT,
                            "stdout", -1, NULL, 0, STDOUT_PRINTOUT,
                            NULL)) 
            SDDS_Bomb("invalid -printout syntax");
        }
        if (!(printFlags&BARE_PRINTOUT))
          printFlags |= NORMAL_PRINTOUT;
        break;
      case CLO_FILEVALUES:
        if (scanned[iArg].n_items<2)
          SDDS_Bomb("invalid -fileValues syntax");
        fileValuesFile = scanned[iArg].list[1];
        scanned[iArg].n_items -= 2;
        if (!scanItemList(&flags, scanned[iArg].list+2, &scanned[iArg].n_items, 0,
                          "column", SDDS_STRING, &fileValuesQuantity, 1, 0,
                          "parallelpages", -1, NULL, 0, FILEVALUES_PARALLEL_PAGES,
                          NULL))
          SDDS_Bomb("invalid -fileValues syntax");
        if (flags&FILEVALUES_PARALLEL_PAGES)
          parallelPages = 1;
        break;
      case CLO_COMBINEDUPLICATES:
        SDDS_Bomb("-combineDuplicates option not implemented yet--send email to [email protected]");
        combineDuplicates = 1;
        break;
      case CLO_BRANCH:
        SDDS_Bomb("-branch option not implemented yet--send email to [email protected]");
        if (scanned[iArg].n_items!=2 || sscanf(scanned[iArg].list[1], "%ld", &branch)!=1 ||
            branch<1)
          SDDS_Bomb("invalid -branch syntax/value");
        break;
      case CLO_BELOWRANGE:
        if ((scanned[iArg].n_items-=1)<1 ||
            !scanItemList(&belowRange.flags, scanned[iArg].list+1, &scanned[iArg].n_items, 0,
                          "value", SDDS_DOUBLE, &belowRange.value, 1, OUTRANGE_VALUE,
                          "skip", -1, NULL, 0, OUTRANGE_SKIP,
                          "saturate", -1, NULL, 0, OUTRANGE_SATURATE,
                          "extrapolate", -1, NULL, 0, OUTRANGE_EXTRAPOLATE,
                          "wrap", -1, NULL, 0, OUTRANGE_WRAP,
                          "abort", -1, NULL, 0, OUTRANGE_ABORT,
                          "warn", -1, NULL, 0, OUTRANGE_WARN,
                          NULL))
          SDDS_Bomb("invalid -belowRange syntax/value");
        if ((i=bitsSet(belowRange.flags&
                       (OUTRANGE_VALUE|OUTRANGE_SKIP|OUTRANGE_SATURATE|OUTRANGE_EXTRAPOLATE|OUTRANGE_WRAP|OUTRANGE_ABORT)))>1)
          SDDS_Bomb("incompatible keywords given for -belowRange");
        if (i!=1)
          belowRange.flags |= OUTRANGE_SATURATE;
        break;
      case CLO_ABOVERANGE:
        if ((scanned[iArg].n_items-=1)<1 ||
            !scanItemList(&aboveRange.flags, scanned[iArg].list+1, &scanned[iArg].n_items, 0,
                          "value", SDDS_DOUBLE, &aboveRange.value, 1, OUTRANGE_VALUE,
                          "skip", -1, NULL, 0, OUTRANGE_SKIP,
                          "saturate", -1, NULL, 0, OUTRANGE_SATURATE,
                          "extrapolate", -1, NULL, 0, OUTRANGE_EXTRAPOLATE,
                          "wrap", -1, NULL, 0, OUTRANGE_WRAP,
                          "abort", -1, NULL, 0, OUTRANGE_ABORT,
                          "warn", -1, NULL, 0, OUTRANGE_WARN,
                          NULL))
          SDDS_Bomb("invalid -aboveRange syntax/value");
        if ((i=bitsSet(aboveRange.flags&
                       (OUTRANGE_VALUE|OUTRANGE_SKIP|OUTRANGE_SATURATE|OUTRANGE_EXTRAPOLATE|OUTRANGE_WRAP|OUTRANGE_ABORT)))>1)
          SDDS_Bomb("incompatible keywords given for -aboveRange");
        if (i!=1)
          aboveRange.flags |= OUTRANGE_SATURATE;
        break;
      case CLO_PIPE:
        if (!processPipeOption(scanned[iArg].list+1, scanned[iArg].n_items-1, &pipeFlags))
          SDDS_Bomb("invalid -pipe syntax");
        break;
      case CLO_EXCLUDE:
        if (scanned[iArg].n_items<2)
          SDDS_Bomb("invalid -exclude syntax");
        moveToStringArray(&exclude, &excludes, scanned[iArg].list+1, scanned[iArg].n_items-1);
        break;
      case CLO_FORCEMONOTONIC:
        if ((scanned[iArg].n_items-=1)>0) {
          if (!scanItemList(&forceMonotonic, scanned[iArg].list+1, &scanned[iArg].n_items, 0,
                            "increasing", -1, NULL, 0, FORCE_INCREASING,
                            "decreasing", -1, NULL, 0, FORCE_DECREASING,
                            NULL) || bitsSet(forceMonotonic)!=1)
            SDDS_Bomb("invalid -forceMonotonic syntax/value");
        }
        else 
          forceMonotonic = FORCE_MONOTONIC;
        break;
      case CLO_FILLIN:
        fillIn = 1;
        break;
      default:
        fprintf(stderr, "error: unknown/ambiguous option: %s\n", 
                scanned[iArg].list[0]);
        exit(1);
        break;
      }
    }
    else {
      if (!input)
        input = scanned[iArg].list[0];
      else if (!output)
        output = scanned[iArg].list[0];
      else
        SDDS_Bomb("too many filenames seen");
    }
  }

  processFilenames("sddsinterp", &input, &output, pipeFlags, 0, NULL);

  fpPrint = stderr;
  if (printFlags&STDOUT_PRINTOUT)
    fpPrint = stdout;

  if (!indepQuantity)
    SDDS_Bomb("supply the independent quantity name with the -columns option");

  if ((atValues?1:0)+(fileValuesFile?1:0)+(sequencePoints?1:0)+fillIn+(sequenceSpacing>0?1:0) != 1)
    SDDS_Bomb("you must give one and only one of -atValues, -fileValues, -sequence, -equispaced, and -fillIn");

  if (!SDDS_InitializeInput(&SDDSin, input))
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);

  excludes = appendToStringArray(&exclude, excludes, indepQuantity);
  if (!depenQuantities)
    depenQuantities = appendToStringArray(&depenQuantity, depenQuantities, "*"); 

  if ((depenQuantities=expandColumnPairNames(&SDDSin, &depenQuantity, NULL, depenQuantities, 
                                             exclude, excludes, FIND_NUMERIC_TYPE, 0))<=0) {
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    SDDS_Bomb("no dependent quantities selected for interpolation");
  }

  if (fileValuesFile && !SDDS_InitializeInput(&SDDSvalues, fileValuesFile))
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);

  if (!SDDS_InitializeOutput(&SDDSout, SDDS_BINARY, 0, NULL, "sddsinterp output", output))
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  if (!SDDS_TransferColumnDefinition(&SDDSout, &SDDSin, indepQuantity, NULL))
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  /*
    if (fileValuesQuantity && strcmp(fileValuesQuantity, indepQuantity)!=0 &&
    !SDDS_TransferColumnDefinition(&SDDSout, &SDDSvalues, fileValuesQuantity, NULL)) {
    fprintf(stderr, "problem creating -fileValues column %s\n", fileValuesQuantity);
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    }
    */
  if (SDDS_DefineParameter(&SDDSout, "InterpDataPage", NULL, NULL, 
                           "Page of interpolation data file used to create this page",
                           NULL, SDDS_LONG, NULL)<0 ||
      SDDS_DefineParameter(&SDDSout, "InterpPointsPage", NULL, NULL, 
                           "Page of interpolation points file used to create this page",
                           NULL, SDDS_LONG, NULL)<0)
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  for (i=0; i<depenQuantities; i++) 
    if (!SDDS_TransferColumnDefinition(&SDDSout, &SDDSin, depenQuantity[i], NULL)) {
      fprintf(stderr, "problem creating interpolated-output column %s\n", depenQuantity[i]);
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    }
  if (!SDDS_TransferAllParameterDefinitions(&SDDSout, &SDDSin, SDDS_TRANSFER_KEEPOLD) ||
      !SDDS_WriteLayout(&SDDSout))
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);

  doNotRead = 0;
  interpPoint = NULL;
  outputData = tmalloc(sizeof(*outputData)*(depenQuantities));
  depenValue = tmalloc(sizeof(*depenValue)*(depenQuantities));
  rowFlag = NULL;
  valuesReadCode = 0;

  while (doNotRead || (readCode=SDDS_ReadPage(&SDDSin))>0) {
    rows = SDDS_CountRowsOfInterest(&SDDSin);
    if (!(indepValue = SDDS_GetColumnInDoubles(&SDDSin, indepQuantity)))
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    if (atValues) {
      interpPoint = atValue;
      interpPoints = atValues;
    }
    else if (fileValuesFile) {
      if (interpPoint)
        free(interpPoint);
      if ((valuesReadCode=SDDS_ReadPage(&SDDSvalues))==0)
        SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
      else if (valuesReadCode==-1) {
        if (parallelPages) {
          fprintf(stderr, "warning: file %s ends before file %s\n", fileValuesFile, input);
          break;
        }
        else {
          /* "rewind" the values file */
          if (!SDDS_Terminate(&SDDSvalues) ||
              !SDDS_InitializeInput(&SDDSvalues, fileValuesFile))
            SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
          if ((valuesReadCode=SDDS_ReadPage(&SDDSvalues))<1) {
            fprintf(stderr, "error: unable to (re)read file %s\n", fileValuesFile);
            SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
            exit(1);
          }
          /* read the next page of the interpolation data file */
          if ((readCode=SDDS_ReadPage(&SDDSin))<1) {
            if (readCode==-1)
              break;
            SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
          }
          rows = SDDS_CountRowsOfInterest(&SDDSin);
          if (indepValue)
            free(indepValue);
          if (!(indepValue = SDDS_GetColumnInDoubles(&SDDSin, indepQuantity)))
            SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        }
      }
      
      if (!parallelPages)
        doNotRead = 1;
      interpPoints = SDDS_CountRowsOfInterest(&SDDSvalues);
      interpPoint = SDDS_GetColumnInDoubles(&SDDSvalues, fileValuesQuantity);
      if (SDDS_NumberOfErrors())
        SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    }
    else if (sequencePoints || sequenceSpacing) {
      if (interpPoint)
        free(interpPoint);
      interpPoints = sequencePoints;
      if (!(interpPoint = makeSequence(&interpPoints, sequenceStart, sequenceEnd, sequenceSpacing, 
                                       indepValue, rows)))
        exit(1);
    } else {
      /* fillIn interpolation */
      if (interpPoint)
        free(interpPoint);
      if (!(interpPoint = makeFillInSequence(indepValue, rows, &interpPoints)))
        exit(1);
    }
    
    for (i=0; i<depenQuantities; i++)
      outputData[i] = tmalloc(sizeof(*outputData[i])*interpPoints);
    rowFlag = trealloc(rowFlag, sizeof(*rowFlag)*interpPoints);
    for (j=0; j<interpPoints; j++)
      rowFlag[j] = 1;
    for (i=0; i<depenQuantities; i++) {
      if (!(depenValue[i] = SDDS_GetColumnInDoubles(&SDDSin, depenQuantity[i])))
        SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    }
    if (forceMonotonic)
      rows = forceMonotonicity(indepValue, depenValue, depenQuantities, rows, forceMonotonic);
    else if (combineDuplicates)
      rows = combineDuplicatePoints(indepValue, depenValue, depenQuantities, rows, 0.0);
    if ((monotonicity=checkMonotonicity(indepValue, rows))==0)
      SDDS_Bomb("independent data values do not change monotonically or repeated independent values exist");
    if (interpShort)
      shortValue = malloc(sizeof(*shortValue)*rows);
    
    for (i=0; i<depenQuantities; i++) {
      if (interpShort) {
        for (row=0; row<rows; row++) {
          shortValue[row] = (short)depenValue[i][row];
        }
      }
      for (j=0; j<interpPoints; j++) {
        if (!interpShort) {
          outputData[i][j] = interpolate(depenValue[i], indepValue, rows, interpPoint[j], &belowRange,
                                         &aboveRange, order, &interpCode, monotonicity);
        } else {
          outputData[i][j] = (double)interp_short(shortValue, indepValue, rows, interpPoint[j], 0, -1,
                                                  &interpCode, &nextPos);
        }
        if (interpCode) {
          if (interpCode&OUTRANGE_ABORT) {
            fprintf(stderr, "error: value %e is out of range for column %s\n",
                    interpPoint[j], depenQuantity[i]);
            exit(1);
          }
          if (interpCode&OUTRANGE_WARN)
            fprintf(stderr, "warning: value %e is out of range for column %s\n",
                    interpPoint[j], depenQuantity[i]);
          if (interpCode&OUTRANGE_SKIP) 
            rowFlag[j] = 0;
        }
      }
    }
    if (interpShort)
      free(shortValue);
    if (!SDDS_StartPage(&SDDSout, interpPoints) || 
        !SDDS_SetColumnFromDoubles(&SDDSout, SDDS_SET_BY_NAME, interpPoint, interpPoints, indepQuantity))
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    if (!SDDS_SetParameters(&SDDSout, SDDS_BY_NAME|SDDS_PASS_BY_VALUE,
                            "InterpDataPage", readCode,
                            "InterpPointsPage", valuesReadCode, NULL) ||
        !SDDS_CopyParameters(&SDDSout, &SDDSin))
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    for (i=0; i<depenQuantities; i++)
      if (!SDDS_SetColumnFromDoubles(&SDDSout, SDDS_SET_BY_NAME, outputData[i], interpPoints, depenQuantity[i]))
        SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    if (!SDDS_AssertRowFlags(&SDDSout, SDDS_FLAG_ARRAY, rowFlag, rows) || !SDDS_WritePage(&SDDSout))
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    if (printFlags&BARE_PRINTOUT) {
      for (j=0; j<interpPoints; j++)
        if (rowFlag[j]) {
          fprintf(fpPrint, "%21.15e ", interpPoint[j]);
          for (i=0; i<depenQuantities; i++)
            fprintf(fpPrint, "%21.15e ", outputData[i][j]);
          fputc('\n', fpPrint);
        }
    }
    else if (printFlags&NORMAL_PRINTOUT) {
      for (j=0; j<interpPoints; j++)
        if (rowFlag[j]) {
          fprintf(fpPrint, "%s=%21.15e ", indepQuantity, interpPoint[j]);
          for (i=0; i<depenQuantities; i++)
            fprintf(fpPrint, "%s=%21.15e ", depenQuantity[i], outputData[i][j]);
          fputc('\n', fpPrint);
        }
    }
    if (indepValue) free(indepValue);
    indepValue = NULL;
    for (i=0; i<depenQuantities; i++) {
      if (outputData[i]) free(outputData[i]);
      outputData[i] = NULL;
      if (depenValue[i]) free(depenValue[i]);
      depenValue[i] = NULL;
    }
    if (fileValuesFile) {
      if (interpPoint) free(interpPoint);
      interpPoint = NULL;
    }
    if (rowFlag) free(rowFlag);
    rowFlag = NULL;
  }

  if (!SDDS_Terminate(&SDDSin)) {
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
    exit(1);
  }
  if (!SDDS_Terminate(&SDDSout)) {
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
    exit(1);
  }
  if (fileValuesFile) {
    if (!SDDS_Terminate(&SDDSvalues)) {
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
      exit(1);
    }
  }

  return 0;
}
Пример #2
0
int main(int argc, char **argv)
{
    int iArg;
    char **outputColumn, **difColumn;
    char *indepColumn, **depenColumn, **exclude;
    long depenColumns, excludes;
    char *input, *output;
    long i, rows, readCode, optionCode;
    unsigned long flags, pipeFlags;
    SCANNED_ARG *scanned;
    SDDS_DATASET SDDSin, SDDSout;
    double *timeData, *inputData, *outputData;
    FILTER_STAGE *filterStage;
    long filterStages, totalFilters;

    SDDS_RegisterProgramName(argv[0]);
    argc = scanargs(&scanned, argc, argv); 
    if (argc<3 || argc>(3+N_OPTIONS)) 
        bomb(NULL, USAGE);

    output = input = NULL;
    flags = pipeFlags = 0;
    indepColumn = NULL;
    depenColumn = exclude = NULL;
    depenColumns = excludes = 0;
    if (!(filterStage = (FILTER_STAGE*)calloc(1, sizeof(*filterStage))))
        SDDS_Bomb("allocation failure");
    filterStage->filter = NULL;
    filterStage->filters = 0;
    filterStages = 1;
    totalFilters = 0;

    for (iArg=1; iArg<argc; iArg++) {
        if (scanned[iArg].arg_type==OPTION) {
            /* process options here */
            switch (optionCode=match_string(scanned[iArg].list[0], option, N_OPTIONS, 0)) {
              case SET_PIPE:
                if (!processPipeOption(scanned[iArg].list+1, scanned[iArg].n_items-1, &pipeFlags))
                    SDDS_Bomb("invalid -pipe syntax");
                break;
              case SET_COLUMNS:
                if (indepColumn)
                    SDDS_Bomb("only one -columns option may be given");
                if (scanned[iArg].n_items<2)
                    SDDS_Bomb("invalid -columns syntax");
                indepColumn = scanned[iArg].list[1];
                if (scanned[iArg].n_items>=2) {
                    depenColumn = tmalloc(sizeof(*depenColumn)*(depenColumns=scanned[iArg].n_items-2));
                    for (i=0; i<depenColumns; i++)
                        depenColumn[i] = scanned[iArg].list[i+2];
                    }
                break;
              case SET_THRESHOLD:
              case SET_HIGHPASS:
              case SET_LOWPASS:
              case SET_NOTCH:
              case SET_BANDPASS:
              case SET_FILTERFILE:
              case SET_CLIPFREQ:
                addFilter(filterStage+filterStages-1, optionCode, scanned+iArg);
                totalFilters++;
                break;
              case SET_CASCADE:
                if (filterStages==0)
                    SDDS_Bomb("-cascade option precedes all filter definitions");
                if (!(filterStage = SDDS_Realloc(filterStage, (filterStages+1)*sizeof(*filterStage))))
                    SDDS_Bomb("allocation failure");
                filterStage[filterStages].filter = NULL;
                filterStage[filterStages].filters = 0;
                filterStages++;
                break;
              case SET_NEWCOLUMNS:
                flags |= FL_NEWCOLUMNS;
                break;
              case SET_DIFFERENCECOLUMNS:
                flags |= FL_DIFCOLUMNS;
                break;
              case SET_EXCLUDE:
                if (scanned[iArg].n_items<2)
                    SDDS_Bomb("invalid -exclude syntax");
                moveToStringArray(&exclude, &excludes, scanned[iArg].list+1, scanned[iArg].n_items-1);
                break;
              default:
                fprintf(stderr, "error: unknown/ambiguous option: %s (%s)\n", 
                        scanned[iArg].list[0], argv[0]);
                exit(1);
                break;
                }
            }
        else {
            if (!input)
                input = scanned[iArg].list[0];
            else if (!output)
                output = scanned[iArg].list[0];
            else
                SDDS_Bomb("too many filenames seen");
            }
        }

    processFilenames("sddsfdfilter", &input, &output, pipeFlags, 0, NULL);

    if (!totalFilters)
        fputs("warning: no filters specified (sddsfdfilter)\n", stderr);

    if (!indepColumn)
        SDDS_Bomb("supply the independent column name with the -columns option");
    
    if (!SDDS_InitializeInput(&SDDSin, input))
        SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);

    if (SDDS_CheckColumn(&SDDSin, indepColumn, NULL, SDDS_ANY_NUMERIC_TYPE, stderr)!=SDDS_CHECK_OKAY) 
        exit(1);

    excludes = appendToStringArray(&exclude, excludes, indepColumn); 
    if (!depenColumns)
        depenColumns = appendToStringArray(&depenColumn, depenColumns, "*"); 

    if ((depenColumns=expandColumnPairNames(&SDDSin, &depenColumn, NULL, depenColumns, exclude, excludes,
                                            FIND_NUMERIC_TYPE, 0))<=0) {
        SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        SDDS_Bomb("No quantities selected to filter");
        }

    if (!SDDS_InitializeCopy(&SDDSout, &SDDSin, output, "w"))
        SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);

       
    if (flags&FL_NEWCOLUMNS) {
        outputColumn = tmalloc(sizeof(*outputColumn)*depenColumns);
        for (i=0; i<depenColumns; i++) {
            outputColumn[i] = tmalloc(sizeof(**outputColumn)*(strlen(depenColumn[i])+1+strlen("Filtered")));
            sprintf(outputColumn[i], "%sFiltered", depenColumn[i]);
            if (!SDDS_TransferColumnDefinition(&SDDSout, &SDDSin, depenColumn[i], outputColumn[i]))
                SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
            }
        }
    else
        outputColumn=depenColumn;
        
    difColumn = NULL;
    if (flags&FL_DIFCOLUMNS) {
        difColumn = tmalloc(sizeof(*difColumn)*depenColumns);
        for (i=0; i<depenColumns; i++) {
            difColumn[i] = tmalloc(sizeof(**difColumn)*(strlen(depenColumn[i])+1+strlen("Difference")));
            sprintf(difColumn[i], "%sDifference", depenColumn[i]);
            if (!SDDS_TransferColumnDefinition(&SDDSout, &SDDSin, depenColumn[i], difColumn[i]))
                SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
            }
        }

    if (!SDDS_WriteLayout(&SDDSout))
        SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        
    outputData = NULL;
    while ((readCode=SDDS_ReadPage(&SDDSin))>0) {
        if (!SDDS_CopyPage(&SDDSout, &SDDSin))
            SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        if ((rows = SDDS_CountRowsOfInterest(&SDDSin))<0)
            SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
	 
        if (rows) {
            if (!(timeData = SDDS_GetColumnInDoubles(&SDDSin, indepColumn)))
                SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
            if (!(outputData = SDDS_Realloc(outputData, sizeof(*outputData)*rows)))
                SDDS_Bomb("allocation failure");
            for (i=0; i<depenColumns; i++) {
                if (!(inputData = SDDS_GetColumnInDoubles(&SDDSin, depenColumn[i])))
                    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
                if (!applyFilters(outputData, inputData, timeData, rows, filterStage, filterStages))
                    exit(1);
                if (!SDDS_SetColumnFromDoubles(&SDDSout, SDDS_BY_NAME, outputData, rows, outputColumn[i]))
                    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
                if (flags&FL_DIFCOLUMNS) {
                    long j;
                    for (j=0; j<rows; j++)
                        outputData[j] = inputData[j] - outputData[j];
                    if (!SDDS_SetColumnFromDoubles(&SDDSout, SDDS_BY_NAME, outputData, rows, difColumn[i]))
                        SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
                    }
                free(inputData);
                }
            free(timeData);
            }
        if (!SDDS_WritePage(&SDDSout))
            SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        }
	
    free(outputData);	
    for(i=0;i<depenColumns;i++) {
       free(depenColumn[i]);
       if (flags&FL_NEWCOLUMNS)
          free(outputColumn[i]);
       if (flags&FL_DIFCOLUMNS) 
          free(difColumn[i]);
    }   
    for(i=0;i<excludes;i++) 
       free(exclude[i]);
    
    free(indepColumn);
    if (flags&FL_NEWCOLUMNS)
       free(outputColumn);
    free(depenColumn);
    if (flags&FL_DIFCOLUMNS) 
       free(difColumn);
    free(exclude);
    for(i=0;i<filterStages;i++) {
       long j;
       for(j=0;j<filterStage[i].filters;j++)  {
          switch (filterStage[i].filter[j].filterType) {
	  case SET_FILTERFILE :
	     free( ((FILE_FILTER*) (filterStage[i].filter[j].filter))->freqData);
	     free( ((FILE_FILTER*) (filterStage[i].filter[j].filter))->magData);
	     free( ((FILE_FILTER*) (filterStage[i].filter[j].filter))->imagData);
	     free( ((FILE_FILTER*) (filterStage[i].filter[j].filter))->realData);
	     break;
	  default :
	     break;
	  }
       }	           
    } 	   
	    
    if (!SDDS_Terminate(&SDDSout) || !SDDS_Terminate(&SDDSin))
            SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);	
    return 0;
    }
Пример #3
0
int main(int argc, char **argv)
{
    double *xData, *yData, *xError, *yError, *derivative, *derivativeError, *derivativePosition;
    char *input, *output, *xName, *xErrorName, **yName, **yErrorName, **yOutputName, **yOutputErrorName, *ptr;
    char **yOutputUnits, **yExcludeName;
    char *mainTemplate[3] = {NULL, NULL, NULL};
    char *errorTemplate[3] = {NULL, NULL, NULL};
    long i, iArg, yNames, yExcludeNames, rows;
    int32_t interval;
    SDDS_DATASET SDDSin, SDDSout;
    SCANNED_ARG *scanned;
    unsigned long flags, pipeFlags;
    long SGLeft, SGRight, SGOrder, SGDerivOrder, intervalGiven, yErrorsSeen;

    SDDS_RegisterProgramName(argv[0]);

    argc = scanargs(&scanned, argc, argv); 
    if (argc==1)
        bomb(NULL, USAGE);

    input = output = xName = xErrorName = NULL;
    yName = yErrorName = yExcludeName = NULL;
    derivative = derivativeError = derivativePosition = yError = yData = xData = xError = NULL;
    yNames = yExcludeNames = 0;
    pipeFlags = 0;
    interval = 2;
    SGOrder = -1;
    SGDerivOrder = 1;
    intervalGiven = 0;
    yErrorsSeen = 0;
    
    for (iArg=1; iArg<argc; iArg++) {
        if (scanned[iArg].arg_type==OPTION) {
            /* process options here */
            switch (match_string(scanned[iArg].list[0], option, CLO_OPTIONS, 0)) {
              case CLO_DIFFERENTIATE:
                if (scanned[iArg].n_items!=2 && scanned[iArg].n_items!=3)
                    SDDS_Bomb("invalid -differentiate syntax");
                yName = SDDS_Realloc(yName, sizeof(*yName)*(yNames+1));
                yErrorName = SDDS_Realloc(yErrorName, sizeof(*yErrorName)*(yNames+1));
                yName[yNames] = scanned[iArg].list[1];
                if (scanned[iArg].n_items==3) {
                    yErrorsSeen = 1;
                    yErrorName[yNames] = scanned[iArg].list[2];
                } else
                    yErrorName[yNames] = NULL;
                yNames++;
                break;
              case CLO_EXCLUDE:
                if (scanned[iArg].n_items<2)
                    SDDS_Bomb("invalid -exclude syntax");
                moveToStringArray(&yExcludeName, &yExcludeNames, scanned[iArg].list+1, scanned[iArg].n_items-1);
                break;
              case CLO_VERSUS:
                if (xName)
                    SDDS_Bomb("give -versus only once");
                if (scanned[iArg].n_items!=2)
                    SDDS_Bomb("invalid -versus syntax");
                xName = scanned[iArg].list[1];
                xErrorName = NULL;
                break;
              case CLO_MAINTEMPLATE:
                if (scanned[iArg].n_items<2)
                    SDDS_Bomb("invalid -mainTemplate syntax");
                scanned[iArg].n_items--;
                if (!scanItemList(&flags, scanned[iArg].list+1, &scanned[iArg].n_items, 0,
                                    "name", SDDS_STRING, mainTemplate+0, 1, 0,
                                    "description", SDDS_STRING, mainTemplate+1, 1, 0,
                                    "symbol", SDDS_STRING, mainTemplate+2, 1, 0,
                                    NULL))
                    SDDS_Bomb("invalid -mainTemplate syntax");
                break;
              case CLO_ERRORTEMPLATE:
                if (scanned[iArg].n_items<2)
                    SDDS_Bomb("invalid -errorTemplate syntax");
                scanned[iArg].n_items--;
                if (!scanItemList(&flags, scanned[iArg].list+1, &scanned[iArg].n_items, 0,
                                    "name", SDDS_STRING, errorTemplate+0, 1, 0,
                                    "description", SDDS_STRING, errorTemplate+1, 1, 0,
                                    "symbol", SDDS_STRING, errorTemplate+2, 1, 0,
                                    NULL))
                    SDDS_Bomb("invalid -errorTemplate syntax");
                break;
              case CLO_PIPE:
                if (!processPipeOption(scanned[iArg].list+1, scanned[iArg].n_items-1, &pipeFlags))
                    SDDS_Bomb("invalid -pipe syntax");
                break;
              case CLO_INTERVAL:
                if (scanned[iArg].n_items!=2 || sscanf(scanned[iArg].list[1], "%" SCNd32, &interval)!=1 ||
                    interval<=0)
                    SDDS_Bomb("invalid -interval syntax/value");
                intervalGiven = 1;
                break;
              case CLO_SAVITZKYGOLAY:
                if ((scanned[iArg].n_items!=4 && scanned[iArg].n_items!=5) ||
                    sscanf(scanned[iArg].list[1], "%ld", &SGLeft)!=1 ||
                    sscanf(scanned[iArg].list[2], "%ld", &SGRight)!=1 ||
                    sscanf(scanned[iArg].list[3], "%ld", &SGOrder)!=1 ||
                    (scanned[iArg].n_items==5 &&
                     sscanf(scanned[iArg].list[4], "%ld", &SGDerivOrder)!=1) ||
                    SGLeft<0 || SGRight<0 || (SGLeft+SGRight)<SGOrder ||
                    SGOrder<0 || SGDerivOrder<0)
                  SDDS_Bomb("invalid -SavitzkyGolay syntax/values");
                break;
              default:
                fprintf(stderr, "invalid option seen: %s\n", scanned[iArg].list[0]);
                exit(1);
                break;
                }
            }
        else {
            if (!input)
                input = scanned[iArg].list[0];
            else if (!output)
                output = scanned[iArg].list[0];
            else
                SDDS_Bomb("too many filenames");
            }
        }

    if (intervalGiven && SGOrder>=0)
      SDDS_Bomb("-interval and -SavitzkyGolay options are incompatible");
    if (SGOrder>=0 && (xErrorName || yErrorsSeen))
      SDDS_Bomb("Savitzky-Golay method does not support errors in data");
    
    processFilenames("sddsderiv", &input, &output, pipeFlags, 0, NULL);

    if (!yNames)
        SDDS_Bomb("-differentiate option must be given at least once");
    if (!checkErrorNames(yErrorName, yNames))
        SDDS_Bomb("either all -differentiate quantities must have errors, or none");

    if (!SDDS_InitializeInput(&SDDSin, input))
        SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    if (!(ptr=SDDS_FindColumn(&SDDSin, FIND_NUMERIC_TYPE, xName, NULL))) {
        fprintf(stderr, "error: column %s doesn't exist\n", xName);
        exit(1);
        }
    free(xName);
    xName = ptr;
    if (xErrorName) {
        if (!(ptr=SDDS_FindColumn(&SDDSin, FIND_NUMERIC_TYPE, xErrorName, NULL))) {
            fprintf(stderr, "error: column %s doesn't exist\n", xErrorName);
            exit(1);
            }
        else {
            free(xErrorName);
            xErrorName = ptr;
            }
        }

    if (!(yNames=expandColumnPairNames(&SDDSin, &yName, &yErrorName, yNames,
                                       yExcludeName, yExcludeNames, FIND_NUMERIC_TYPE, 0))) {
        fprintf(stderr, "error: no quantities to differentiate found in file\n");
        exit(1);
        }

    setupOutputFile(&SDDSout, &SDDSin, output, &yOutputName, &yOutputErrorName, &yOutputUnits,
                    xName, xErrorName, yName, yErrorName, yNames, mainTemplate, errorTemplate,
                    interval, SGOrder>=0?SGDerivOrder:1);

    while (SDDS_ReadPage(&SDDSin)>0) {
      if ((rows = SDDS_CountRowsOfInterest(&SDDSin))<2)
	SDDS_Bomb("Can't compute derivatives: too little data.");
      derivative = SDDS_Realloc(derivative, sizeof(*derivative)*rows);
      derivativeError = SDDS_Realloc(derivativeError, sizeof(*derivativeError)*rows);
      derivativePosition = SDDS_Realloc(derivativePosition, sizeof(*derivativePosition)*rows);
      if (!SDDS_StartPage(&SDDSout, rows) || !SDDS_CopyParameters(&SDDSout, &SDDSin))
	SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
      xError = NULL;
      if (!(xData = SDDS_GetColumnInDoubles(&SDDSin, xName)) ||
	  (xErrorName && !(xError=SDDS_GetColumnInDoubles(&SDDSin, xErrorName))))
	SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
      for (i=0; i<yNames; i++) {
	yError = NULL;
	if (!(yData = SDDS_GetColumnInDoubles(&SDDSin, yName[i])) ||
	    (yErrorName && yErrorName[i] && !(yError=SDDS_GetColumnInDoubles(&SDDSin, yErrorName[i]))))
	  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
	if (SGOrder>=0)
	  takeSGDerivative(xData, yData, rows, derivative, derivativePosition, 
			   SGLeft, SGRight, SGOrder, SGDerivOrder);
	else
	  takeDerivative(xData, yData, yError, rows, derivative, derivativeError, 
			 derivativePosition, interval);
	if (!SDDS_SetColumnFromDoubles(&SDDSout, SDDS_BY_NAME, derivative, rows, yOutputName[i]) ||
	    (yOutputErrorName && yOutputErrorName[i] && 
	     !SDDS_SetColumnFromDoubles(&SDDSout, SDDS_BY_NAME, derivativeError, rows, yOutputErrorName[i])))
	  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
	if (yData) free(yData);
	if (yError) free(yError);
	yData = yError = NULL;
      }
      if (!SDDS_SetColumnFromDoubles(&SDDSout, SDDS_BY_NAME, derivativePosition, rows, xName) ||
	  (xErrorName && !SDDS_SetColumnFromDoubles(&SDDSout, SDDS_BY_NAME, xError, rows, xErrorName)))
	SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
      if (!SDDS_WritePage(&SDDSout))
	SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
      if (xData) free(xData);
      if (xError) free(xError);
      xData = xError = NULL;
    }
    if (!SDDS_Terminate(&SDDSin) || !SDDS_Terminate(&SDDSout)) {
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
      exit(1);
    }
    if (derivative) free(derivative);
    if (derivativeError) free(derivativeError);
    if (derivativePosition) free(derivativePosition);
    return(0);
}
Пример #4
0
int main(int argc, char **argv)
{
  int iArg;
  char **column, **excludeColumn, *withOnly;
  long columns, excludeColumns;
  char *input, *output;
  SCANNED_ARG *scanned;
  SDDS_DATASET SDDSin, SDDSout;
  long i, j, row, rows, count, readCode, rankOrder, iName1, iName2;
  int32_t outlierStDevPasses;
  double **data, correlation, significance, outlierStDevLimit;
  double **rank;
  short **accept;
  char s[SDDS_MAXLINE];
  unsigned long pipeFlags, dummyFlags, majorOrderFlag;
  short columnMajorOrder=-1;
  
  SDDS_RegisterProgramName(argv[0]);
  argc = scanargs(&scanned, argc, argv); 
  if (argc<2)
    bomb(NULL, USAGE);
  
  output = input = withOnly = NULL;
  columns = excludeColumns = 0;
  column = excludeColumn = NULL;
  pipeFlags = 0;
  rankOrder = 0;
  outlierStDevPasses = 0;
  outlierStDevLimit  = 1.;
  rank = NULL;
  accept = NULL;
  
  for (iArg=1; iArg<argc; iArg++) {
    if (scanned[iArg].arg_type==OPTION) {
      /* process options here */
      switch (match_string(scanned[iArg].list[0], option, N_OPTIONS, 0)) {
      case SET_MAJOR_ORDER:
        majorOrderFlag=0;
        scanned[iArg].n_items--;
        if (scanned[iArg].n_items>0 &&
            (!scanItemList(&majorOrderFlag, scanned[iArg].list+1, &scanned[iArg].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;
      case SET_COLUMNS:
	if (columns)
	  SDDS_Bomb("only one -columns option may be given");
	if (scanned[iArg].n_items<2)
	  SDDS_Bomb("invalid -columns syntax");
	column = tmalloc(sizeof(*column)*(columns=scanned[iArg].n_items-1));
	for (i=0; i<columns; i++)
	  column[i] = scanned[iArg].list[i+1];
	break;
      case SET_EXCLUDE:
	if (scanned[iArg].n_items<2)
	  SDDS_Bomb("invalid -excludeColumns syntax");
	moveToStringArray(&excludeColumn, &excludeColumns, scanned[iArg].list+1, scanned[iArg].n_items-1);
	break;
      case SET_WITHONLY:
	if (withOnly)
	  SDDS_Bomb("only one -withOnly option may be given");
	if (scanned[iArg].n_items<2)
	  SDDS_Bomb("invalid -withOnly syntax");
	withOnly = scanned[iArg].list[1];
	break;
      case SET_PIPE:
	if (!processPipeOption(scanned[iArg].list+1, scanned[iArg].n_items-1, &pipeFlags))
	  SDDS_Bomb("invalid -pipe syntax");
	break;
      case SET_RANKORDER:
	rankOrder = 1;
	break;
      case SET_STDEVOUTLIER:
	scanned[iArg].n_items--;
	outlierStDevPasses = 1;
	outlierStDevLimit = 1;
	if (!scanItemList(&dummyFlags, scanned[iArg].list+1, &scanned[iArg].n_items, 0,
			  "limit", SDDS_DOUBLE, &outlierStDevLimit, 1, 0,
			  "passes", SDDS_LONG, &outlierStDevPasses, 1, 0,
			  NULL) || 
	    outlierStDevPasses<=0 || outlierStDevLimit<=0)
	  SDDS_Bomb("invalid -stdevOutlier syntax/values");
	break;
      default:
	fprintf(stderr, "error: unknown/ambiguous option: %s\n", 
		scanned[iArg].list[0]);
	exit(1);
	break;
      }
    }
    else {
      if (!input)
	input = scanned[iArg].list[0];
      else if (!output)
	output = scanned[iArg].list[0];
      else
	SDDS_Bomb("too many filenames seen");
    }
  }
  
  processFilenames("sddscorrelate", &input, &output, pipeFlags, 0, NULL);
  
  if (!SDDS_InitializeInput(&SDDSin, input))
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  
  if (!columns)
    columns = appendToStringArray(&column, columns, "*"); 
  if (withOnly)
    columns = appendToStringArray(&column, columns, withOnly);
  
  if ((columns=expandColumnPairNames(&SDDSin, &column, NULL, columns, 
				     excludeColumn, excludeColumns, FIND_NUMERIC_TYPE, 0))<=0) {
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    SDDS_Bomb("no columns selected for correlation analysis");
  }
  
  if (!SDDS_InitializeOutput(&SDDSout, SDDS_BINARY, 0, NULL, "sddscorrelate output", output) ||
      SDDS_DefineColumn(&SDDSout, "Correlate1Name", NULL, NULL, "Name of correlated quantity 1", NULL, SDDS_STRING, 0)<0 ||
      SDDS_DefineColumn(&SDDSout, "Correlate2Name", NULL, NULL, "Name of correlated quantity 2", NULL, SDDS_STRING, 0)<0 ||
      SDDS_DefineColumn(&SDDSout, "CorrelatePair", NULL, NULL, "Names of correlated quantities", NULL, SDDS_STRING, 0)<0 ||
      SDDS_DefineColumn(&SDDSout, "CorrelationCoefficient", "r", NULL, "Linear correlation coefficient", 
			NULL, SDDS_DOUBLE, 0)<0 ||
      SDDS_DefineColumn(&SDDSout, "CorrelationSignificance", "P$br$n", NULL, "Linear correlation coefficient significance", 
			NULL, SDDS_DOUBLE, 0)<0 ||
      SDDS_DefineColumn(&SDDSout, "CorrelationPoints", NULL, NULL, "Number of points used for correlation",
			NULL, SDDS_LONG, 0)<0 ||
      SDDS_DefineParameter(&SDDSout, "CorrelatedRows", NULL, NULL, "Number of data rows in correlation analysis", 
			   NULL, SDDS_LONG, NULL)<0 ||
      SDDS_DefineParameter(&SDDSout, "sddscorrelateInputFile", NULL, NULL, "Data file processed by sddscorrelate", 
			   NULL, SDDS_STRING, input?input:"stdin")<0 ||
      SDDS_DefineParameter(&SDDSout, "sddscorrelateMode", NULL, NULL, NULL, NULL, SDDS_STRING,
			   rankOrder?"Rank-Order (Spearman)":"Linear (Pearson)")<0 ||
      SDDS_DefineParameter1(&SDDSout, "sddscorrelateStDevOutlierPasses", NULL, NULL, 
			    "Number of passes of standard-deviation outlier elimination applied",
			    NULL, SDDS_LONG, &outlierStDevPasses)<0 ||
      SDDS_DefineParameter1(&SDDSout, "sddscorrelateStDevOutlierLimit", NULL, NULL, 
			    "Standard-deviation outlier limit applied",
			    NULL, SDDS_DOUBLE, &outlierStDevLimit)<0)
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);

  if (columnMajorOrder!=-1)
    SDDSout.layout.data_mode.column_major = columnMajorOrder;
  else
    SDDSout.layout.data_mode.column_major = SDDSin.layout.data_mode.column_major;
  
  if (!SDDS_WriteLayout(&SDDSout))
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  
  if (!(data = (double**)malloc(sizeof(*data)*columns)) ||
      (rankOrder && !(rank = (double**)malloc(sizeof(*rank)*columns))) ||
      !(accept = (short**)malloc(sizeof(*accept)*columns)))
    SDDS_Bomb("allocation failure");
  while ((readCode=SDDS_ReadPage(&SDDSin))>0) {
    if ((rows = SDDS_CountRowsOfInterest(&SDDSin))<3)
      continue;
    if (!SDDS_StartPage(&SDDSout, columns*(columns-1)/2) ||
	!SDDS_SetParameters(&SDDSout, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE, 
			    "CorrelatedRows", rows, NULL))
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    for (i=0; i<columns; i++) {
      if (!(data[i] = SDDS_GetColumnInDoubles(&SDDSin, column[i])))
	SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
      if (rankOrder)
	rank[i] = findRank(data[i], rows);
      if (outlierStDevPasses) {
	if (!(accept[i] = (short*)malloc(sizeof(**accept)*rows)))
	  SDDS_Bomb("allocation failure");
	markStDevOutliers(data[i], outlierStDevLimit, outlierStDevPasses,
			  accept[i], rows);
      }
      else
	accept[i] = NULL;
    }
    for (i=row=0; i<columns; i++) {
      for (j=i+1; j<columns; j++) {
	iName1 = i;
	iName2 = j;
	if (withOnly) {
	  if (strcmp(withOnly, column[i])==0) {
	    iName1 = j;
	    iName2 = i;
	  }
	  else if (strcmp(withOnly, column[j])==0) {
	    iName1 = i;
	    iName2 = j;
	  }
	  else 
	    continue;
	}
	correlation 
	  = linearCorrelationCoefficient(rankOrder?rank[i]:data[i], 
					 rankOrder?rank[j]:data[j], 
					 accept[i], accept[j], rows, &count);
	significance = linearCorrelationSignificance(correlation, count);
	sprintf(s, "%s.%s", column[iName1], column[iName2]);
                if (!SDDS_SetRowValues(&SDDSout, SDDS_SET_BY_INDEX|SDDS_PASS_BY_VALUE, row++,
                                       0, column[iName1], 
                                       1, column[iName2], 
                                       2, s, 3, correlation, 4, significance, 
                                       5, count, -1))
		  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
      }
    }
    for (i=0; i<columns; i++) {
      free(data[i]);
      if (rankOrder)
	free(rank[i]);
      if (accept[i])
	free(accept[i]);
    }
    if (!SDDS_WritePage(&SDDSout))
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  }
  
  if (!SDDS_Terminate(&SDDSin)) {
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
    exit(1);
  }
  if (!SDDS_Terminate(&SDDSout)) {
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
    exit(1);
  }
  
  return 0;
}
Пример #5
0
int main(int argc, char **argv)
{
  char *indepQuantity, **depenQuantity, **exclude, **depenQuantityPair;
  long depenQuantities, excludes;
  char *input, *output;
  long iArg, i, j, rows, readCode, noWarnings, items;
  long rowsToUse;
  unsigned long flags, pairFlags, tmpFlags, pipeFlags;
  SCANNED_ARG *scArg;
  SDDS_DATASET SDDSin, SDDSout;
  double *tdata, *data, t0, dt;
  double fracRMSChangeLimit, fracFreqAccuracyLimit;
  int32_t frequenciesDesired, maxFrequencies, freqCycleLimit;
  short truncate;
  double *frequency, *amplitude=NULL, *phase=NULL, *significance=NULL, *phase1=NULL, *amplitude1=NULL, *significance1=NULL;
  long frequenciesFound;
  long *frequencyIndex, *amplitudeIndex, *phaseIndex, *significanceIndex, pairs;
  long *amplitudeIndex1, *phaseIndex1, *significanceIndex1;

  SDDS_RegisterProgramName(argv[0]);

#ifdef DEBUG
  if (1) {
    long code;
    double x, y; 
    x = 1.1;
    code = OneDFunctionOptimize(&y, &x, 0.07, -4, 4, 
				trialFn, 50, 1e-6, 0, 1);
    fprintf(stderr, "code: %ld   x=%e,  y=%e\n", code, x, y);
    
    x = .9;
    code = OneDFunctionOptimize(&y, &x, 0.15, -4, 4, 
				trialFn, 50, 1e-6, 0, 1);
    fprintf(stderr, "code: %ld   x=%e,  y=%e\n", code, x, y);
    
    x = .999;
    code = OneDFunctionOptimize(&y, &x, 0.11, -4, 4, 
				trialFn, 50, 1e-6, 0, 1);
    fprintf(stderr, "code: %ld   x=%e,  y=%e\n", code, x, y);
    exit(0);
  }
#endif

  argc = scanargs(&scArg, argc, argv); 
  if (argc<3) {
    fprintf(stderr, "%s%s", USAGE1, USAGE2);
    exit(1);
  }
  output = input = NULL;
  flags = pipeFlags = excludes = truncate = pairFlags= 0;
  indepQuantity = NULL;
  depenQuantity = exclude = depenQuantityPair=NULL;
  depenQuantities = 0;
  noWarnings = 0;
  fracRMSChangeLimit = 0.0;
  fracFreqAccuracyLimit = 0.00001;
  frequenciesDesired = 1;
  maxFrequencies = 4;
  freqCycleLimit = 100;
  pairs=0;
  
  for (iArg=1; iArg<argc; iArg++) {
    if (scArg[iArg].arg_type==OPTION) {
      /* process options here */
      switch (match_string(scArg[iArg].list[0], option, N_OPTIONS, 0)) {
      case SET_TRUNCATE:
	truncate = 1;
	break;
      case SET_PAIR:
        if (depenQuantities)
          SDDS_Bomb("Invalid -pair option, the depent-quantity is provided by -column option already.");
        if (scArg[iArg].n_items!=3) 
          SDDS_Bomb("invalid -pair syntax");
        depenQuantity = SDDS_Realloc(depenQuantity, sizeof(*depenQuantity)*(pairs+1));
        depenQuantityPair = SDDS_Realloc(depenQuantityPair, sizeof(*depenQuantityPair)*(pairs+1));
        depenQuantity[pairs] = scArg[iArg].list[1];
        depenQuantityPair[pairs] = scArg[iArg].list[2];
        pairs++;
        break;
      case SET_COLUMN:
	if (indepQuantity)
	  SDDS_Bomb("only one -column option may be given");
	if (scArg[iArg].n_items<2)
	  SDDS_Bomb("invalid -column syntax");
	indepQuantity = scArg[iArg].list[1];
	if (scArg[iArg].n_items>=2) {
          if (pairs)
            SDDS_Bomb("Invalid -column syntax, the depent-quantity is provided by -pair option already.");
	  depenQuantity = tmalloc(sizeof(*depenQuantity)*(depenQuantities=scArg[iArg].n_items-2));
	  for (i=0; i<depenQuantities; i++)
	    depenQuantity[i] = scArg[iArg].list[i+2];
	}
	break;
      case SET_PIPE:
	if (!processPipeOption(scArg[iArg].list+1, scArg[iArg].n_items-1, &pipeFlags))
	  SDDS_Bomb("invalid -pipe syntax");
	break;
      case SET_EXCLUDE:
	if (scArg[iArg].n_items<2)
	  SDDS_Bomb("invalid -exclude syntax");
	moveToStringArray(&exclude, &excludes, scArg[iArg].list+1, scArg[iArg].n_items-1);
	break;
      case SET_NOWARNINGS:
	noWarnings = 1;
	break;
      case SET_TERM_SEARCH:
	items = scArg[iArg].n_items-1;
	flags &= ~(NAFF_RMS_CHANGE_LIMIT|NAFF_FREQS_DESIRED|NAFF_MAX_FREQUENCIES);
	fracRMSChangeLimit = 0;
	frequenciesDesired = 0;
	maxFrequencies = 10;
	if (!scanItemList(&tmpFlags, scArg[iArg].list+1, &items, 0,
			  "changelimit", SDDS_DOUBLE, &fracRMSChangeLimit, 1, 
			  NAFF_RMS_CHANGE_LIMIT,
			  "maxfrequencies", SDDS_LONG, &maxFrequencies, 1, 
			  NAFF_MAX_FREQUENCIES,
			  "frequencies", SDDS_LONG, &frequenciesDesired, 1, 
			  NAFF_FREQS_DESIRED,
			  NULL) ||
	    (tmpFlags&NAFF_RMS_CHANGE_LIMIT && tmpFlags&NAFF_FREQS_DESIRED) ||
	    maxFrequencies<1)
	  SDDS_Bomb("invalid -terminateSearch syntax");
	flags |= tmpFlags;
	if (frequenciesDesired)
	  maxFrequencies = frequenciesDesired;
        break;
      case SET_ITERATE_FREQ:
	items = scArg[iArg].n_items - 1;
	flags &= ~(NAFF_FREQ_CYCLE_LIMIT|NAFF_FREQ_ACCURACY_LIMIT);
	if (!scanItemList(&tmpFlags, scArg[iArg].list+1, &items, 0,
			  "cyclelimit", SDDS_LONG, &freqCycleLimit, 1, NAFF_FREQ_CYCLE_LIMIT,
			  "accuracylimit", SDDS_DOUBLE, &fracFreqAccuracyLimit, 
			  1, NAFF_FREQ_ACCURACY_LIMIT,
			  NULL) || !bitsSet(tmpFlags) || freqCycleLimit<2)
	  SDDS_Bomb("invalid -iterateFrequency syntax");
	flags |= tmpFlags;
        break;
      default:
	fprintf(stderr, "error: unknown/ambiguous option: %s\n", 
		scArg[iArg].list[0]);
	exit(1);
	break;
      }
    }
    else {
      if (!input)
	input = scArg[iArg].list[0];
      else if (!output)
	output = scArg[iArg].list[0];
      else
	SDDS_Bomb("too many filenames seen");
    }
  }
  
  processFilenames("sddsnaff", &input, &output, pipeFlags, 0, NULL);
  
  if (!indepQuantity)
    SDDS_Bomb("supply the independent quantity name with the -columns option");
  
  if (!SDDS_InitializeInput(&SDDSin, input))
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  
  if (SDDS_CheckColumn(&SDDSin, indepQuantity, NULL, SDDS_ANY_NUMERIC_TYPE, stderr)
      !=SDDS_CHECK_OKAY) 
    exit(1);
  
  excludes = appendToStringArray(&exclude, excludes, indepQuantity);
  if (pairs) {
    pairFlags = flags | NAFF_FREQ_FOUND;
    depenQuantities = pairs;
  }
  if (!depenQuantities)
    depenQuantities = appendToStringArray(&depenQuantity, depenQuantities, "*"); 
  if (!pairs) {
    if ((depenQuantities=expandColumnPairNames(&SDDSin, &depenQuantity, NULL, 
                                               depenQuantities, exclude, excludes, 
                                               FIND_NUMERIC_TYPE, 0))<=0) {
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
      SDDS_Bomb("No quantities selected to fft");
    }
  }
  
  if (!SetupNAFFOutput(&SDDSout, output, &SDDSin, indepQuantity,
		       depenQuantities, depenQuantity,
		       &frequencyIndex, &amplitudeIndex, &phaseIndex,
                       &significanceIndex, depenQuantityPair,&amplitudeIndex1,
                       &phaseIndex1,&significanceIndex1)) 
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  
  if (!(frequency = SDDS_Malloc(sizeof(*frequency)*maxFrequencies)) ||
      !(amplitude = SDDS_Malloc(sizeof(*amplitude)*maxFrequencies)) ||
      !(phase     = SDDS_Malloc(sizeof(*phase    )*maxFrequencies)) ||
      !(significance= SDDS_Malloc(sizeof(*significance)*maxFrequencies))) 
    SDDS_Bomb("memory allocation failure");
  if (pairs) {
    if (!(amplitude1 = SDDS_Malloc(sizeof(*amplitude1)*maxFrequencies)) ||
        !(phase1     = SDDS_Malloc(sizeof(*phase1    )*maxFrequencies)) ||
        !(significance1 = SDDS_Malloc(sizeof(*significance1)*maxFrequencies)))
      SDDS_Bomb("memory allocation failure");
  }
  while ((readCode=SDDS_ReadPage(&SDDSin))>0) {
    if ((rows = SDDS_CountRowsOfInterest(&SDDSin))<0) 
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    if (rows) {
      long primeRows;
      rowsToUse = rows;
      primeRows = greatestProductOfSmallPrimes(rows);
      if (rows!=primeRows) {
	if (truncate)
	  rowsToUse = greatestProductOfSmallPrimes(rows);
	else if (largest_prime_factor(rows)>100 && !noWarnings)
	  fputs("Warning: number of points has large prime factors.\nThis could take a very long time.\nConsider using the -truncate option.\n", stderr);
      }
      if (!SDDS_StartPage(&SDDSout, maxFrequencies) ||
	  !SDDS_CopyParameters(&SDDSout, &SDDSin))
	SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
      if (!(tdata = SDDS_GetColumnInDoubles(&SDDSin, indepQuantity)))
	SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
      for (i=1; i<rowsToUse; i++)
	if (tdata[i]<=tdata[i-1])
	  SDDS_Bomb("independent data is not monotonically increasing");
      dt = (tdata[rowsToUse-1]-tdata[0])/(rowsToUse-1.0),
      t0 = tdata[0];
      free(tdata);
      for (i=0; i<depenQuantities; i++) {
	if (!(data = SDDS_GetColumnInDoubles(&SDDSin, depenQuantity[i])))
	  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        for (j=0; j<maxFrequencies; j++)
          frequency[j] = amplitude[j] = phase[j] = significance[j] = -1;
	frequenciesFound = PerformNAFF(frequency, amplitude, phase, significance,
                                       t0, dt,
				       data, rowsToUse, flags,
				       fracRMSChangeLimit, maxFrequencies,
				       freqCycleLimit, fracFreqAccuracyLimit, 0, 0);
#ifdef DEBUG
        fprintf(stderr, "Column %s: ", depenQuantity[i]);
        fprintf(stderr, "f=%10.3e  a=%10.3e  p=%10.3e  s=%10.3e\n",
                frequency[0], amplitude[0], phase[0], significance[0]);
#endif
	free(data);
	data = NULL;
        if (pairs) {
          if (!(data = SDDS_GetColumnInDoubles(&SDDSin, depenQuantityPair[i])))
            SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
          frequenciesFound = PerformNAFF(frequency, amplitude1, phase1, significance1,
                                         t0, dt,
                                         data, rowsToUse, pairFlags,
                                         fracRMSChangeLimit, maxFrequencies,
                                         freqCycleLimit, fracFreqAccuracyLimit, 0, 0);
          
          for (j=0; j<maxFrequencies; j++)
            if (frequency[j]!=-1)
              frequency[j] = adjustFrequencyHalfPlane(frequency[j], phase[j], phase1[j], dt); 
          free(data);
          data = NULL;
        } 
	if (!SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX,
			    frequency, maxFrequencies, frequencyIndex[i]) ||
	    !SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX,
			    amplitude, maxFrequencies, amplitudeIndex[i]) ||
	    !SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX,
			    phase, maxFrequencies, phaseIndex[i]) ||
	    !SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX,
			    significance, maxFrequencies, significanceIndex[i]))
	  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        if (pairs) {
          if (!SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX,
                              amplitude1, maxFrequencies, amplitudeIndex1[i]) ||
              !SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX,
                              phase1, maxFrequencies, phaseIndex1[i]) ||
              !SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX,
                              significance1, maxFrequencies, significanceIndex1[i]))
            SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        }
      }
    }
    else  {
      if (!SDDS_StartPage(&SDDSout, 0) || !SDDS_CopyParameters(&SDDSout, &SDDSin))
	SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    }
    if (!SDDS_WritePage(&SDDSout))
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  }
  
  if (!SDDS_Terminate(&SDDSin)) {
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
    exit(1);
  }
  if (!SDDS_Terminate(&SDDSout)) {
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
    exit(1);
  }
  free(frequency);
  free(amplitude);
  free(phase);
  free(significance);
  if (pairs) {
    free(amplitude1);
    free(phase1);
    free(significance1);
    free(amplitudeIndex1);
    free(phaseIndex1);
    free(significanceIndex1);
    free(depenQuantityPair);
  }
  free(depenQuantity);
  free(frequencyIndex);
  free(amplitudeIndex);
  free(phaseIndex);
  free(significanceIndex);
  return 0;
}
Пример #6
0
long expandColumnPairNames(SDDS_DATASET *SDDSin, char ***name, char ***errorName, long names, char **excludeName,
                           long excludeNames, long typeMode, long typeValue)
{
    long i, j, names1, errorNames1, names2;
    char **name1, **errorName1, **name2, **errorName2;

    if (!names || !*name)
        return 0;
    name2 = errorName1 = errorName2 = NULL;
    names2 = errorNames1 = 0;
    for (i=0; i<names; i++) {
        switch (typeMode) {
        case FIND_ANY_TYPE:
        case FIND_NUMERIC_TYPE:
        case FIND_INTEGER_TYPE:
        case FIND_FLOATING_TYPE:
            names1 = SDDS_MatchColumns(SDDSin, excludeNames?NULL:&name1, SDDS_MATCH_STRING, typeMode,
                                       (*name)[i], SDDS_0_PREVIOUS|SDDS_OR);
            break;
        case FIND_SPECIFIED_TYPE:
            if (!SDDS_VALID_TYPE(typeValue))
                SDDS_Bomb("invalid type value in expandColumnPairNames");
            names1 = SDDS_MatchColumns(SDDSin, excludeNames?NULL:&name1, SDDS_MATCH_STRING, typeMode, typeValue,
                                       (*name)[i], SDDS_0_PREVIOUS|SDDS_OR);
            break;
        default:
            SDDS_Bomb("invalid typeMode in expandColumnPairNames");
            exit(1);
            break;
        }
        if (names1==0)
            continue;
        if (names1==-1) {
            SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
            SDDS_Bomb("unable to perform column name match in expandColumnPairNames");
        }

        if (excludeNames) {
            for (j=0; j<excludeNames; j++)
                if (!(names1=SDDS_MatchColumns(SDDSin, (j==excludeNames-1?&name1:0),
                                               SDDS_MATCH_STRING, FIND_ANY_TYPE,
                                               excludeName[j], SDDS_NEGATE_MATCH|SDDS_AND)))
                    break;
        }
        if (!names1)
            continue;
        moveToStringArray(&name2, &names2, name1, names1);
        if (errorName && *errorName && (*errorName)[i]) {
            if (strstr((*errorName)[i], "%s")) {
                if (!(errorName1 = (char**)malloc(sizeof(*errorName1)*names1)))
                    SDDS_Bomb("allocation failure in expandColumnPairNames");
                errorNames1 = names1;
                for (j=0; j<names1; j++) {
                    if (!(errorName1[j] = (char*)malloc(sizeof(**errorName1)*
                                                        strlen(name1[j])+strlen((*errorName)[i])+1)))
                        SDDS_Bomb("allocation failure in expandColumnPairNames");
                    replace_stringn(errorName1[j], (*errorName)[i], "%s", name1[j], 1);
                    if (SDDS_CheckColumn(SDDSin, errorName1[j], NULL, SDDS_ANY_NUMERIC_TYPE, stderr)!=SDDS_CHECK_OKAY)
                        exit(1);
                }
            }
            else if (names1==1) {
                errorNames1 = 1;
                if (!(errorName1 = (char**)malloc(sizeof(*errorName1))))
                    SDDS_Bomb("allocation failure in expandColumnPairNames");
                if (!SDDS_CopyString(errorName1, (*errorName)[i]))
                    return 0;
            }
            else
                SDDS_Bomb("%s template must be employed with error names when primary name has wildcards");
            names2 -= names1;
            moveToStringArray(&errorName2, &names2, errorName1, errorNames1);
            free(errorName1);
            free(name1);
        }
    }
    if (names2==0)
        return 0;
    SDDS_FreeStringArray(*name, names);
    *name = name2;
    if (errorName) {
        if (*errorName)
            SDDS_FreeStringArray(*errorName, names);
        *errorName = errorName2;
    }
    return names2;
}