Beispiel #1
0
int main(int argc, char **argv)
{
    SDDS_DATASET inSet, outSet;
    SCANNED_ARG *s_arg;
    char *input, *output, *zeroName, **columnName;
    long i_arg, i, pageReturned, rows, row, zrow;
    int32_t columnNames;
    double **indepData, *depenData, **slopeData, slope, offset;
    unsigned long pipeFlags, flags, majorOrderFlag;
    char s[SDDS_MAXLINE];
    short columnMajorOrder=-1;

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

    flags = pipeFlags = 0;
    input = output = NULL;
    zeroName = NULL;
    columnName = NULL;
    columnNames = 0;
    offset = 0;
    
    for (i_arg=1; i_arg<argc; i_arg++) {
        if (s_arg[i_arg].arg_type==OPTION) {
            switch (match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
            case CLO_MAJOR_ORDER:
              majorOrderFlag=0;
              s_arg[i_arg].n_items--;
              if (s_arg[i_arg].n_items>0 &&
                  (!scanItemList(&majorOrderFlag, s_arg[i_arg].list+1, &s_arg[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;
            case CLO_PIPE:
              if (!processPipeOption(s_arg[i_arg].list+1, s_arg[i_arg].n_items-1, &pipeFlags))
                SDDS_Bomb("invalid -pipe syntax");
              break;
            case CLO_ZEROESOF:
              if (s_arg[i_arg].n_items!=2)
                SDDS_Bomb("invalid -zeroesOf syntax");
                zeroName = s_arg[i_arg].list[1];
                break;
            case CLO_COLUMNS:
              if (s_arg[i_arg].n_items<2)
                SDDS_Bomb("invalid -columns syntax");
              columnName = tmalloc(sizeof(*columnName)*(columnNames = s_arg[i_arg].n_items-1));
              for (i=0; i<columnNames; i++)
                columnName[i] = s_arg[i_arg].list[i+1];
              break;
            case CLO_SLOPEOUTPUT:
              flags |= FL_SLOPEOUTPUT;
              break;
            case CLO_OFFSET:
              if (s_arg[i_arg].n_items!=2 || sscanf(s_arg[i_arg].list[1], "%le", &offset)!=1)
                SDDS_Bomb("invalid -offset syntax");
              break;
            default:
              fprintf(stderr, "Error (%s): unknown/ambiguous option: %s\n", argv[0], s_arg[i_arg].list[0]);
              exit(1);
              break;
            }
        }
        else {
          if (input==NULL) 
            input = s_arg[i_arg].list[0];
          else if (output==NULL)
            output = s_arg[i_arg].list[0];
            else
              SDDS_Bomb("too many filenames");
        }
    }
    
    processFilenames("sddszerofind", &input, &output, pipeFlags, 0, NULL);

    if (!zeroName)
        SDDS_Bomb("-zeroesOf option must be given");
    
    if (!SDDS_InitializeInput(&inSet, input))
        SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    if (!resolveColumnNames(&inSet, zeroName, &columnName, &columnNames) ||
        !SDDS_InitializeOutput(&outSet, SDDS_BINARY, 0, NULL, "sddszerofind output", output) ||
        !SDDS_TransferColumnDefinition(&outSet, &inSet, zeroName, NULL))
        SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    if (columnMajorOrder!=-1)
      outSet.layout.data_mode.column_major = columnMajorOrder;
    else
      outSet.layout.data_mode.column_major = inSet.layout.data_mode.column_major;
    for (i=0; i<columnNames; i++) {
        sprintf(s, "%sSlope", columnName[i]);
        if (!SDDS_TransferColumnDefinition(&outSet, &inSet, columnName[i], NULL) ||
            (flags&FL_SLOPEOUTPUT && 
             !SDDS_TransferColumnDefinition(&outSet, &inSet, columnName[i], s)))
            SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        }
    if (!SDDS_WriteLayout(&outSet))
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    
    indepData = tmalloc(sizeof(*indepData)*columnNames);
    slopeData = tmalloc(sizeof(*slopeData)*columnNames);

    while ((pageReturned=SDDS_ReadPage(&inSet))>0) {
        if (!SDDS_StartPage(&outSet, 0))
            SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        if ((rows=SDDS_CountRowsOfInterest(&inSet))>1) {
            if (!(depenData = SDDS_GetColumnInDoubles(&inSet, zeroName)))
                SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
            for (i=0; i<columnNames; i++) {
                if (!(indepData[i] = SDDS_GetColumnInDoubles(&inSet, columnName[i])))
                    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
                if (flags&FL_SLOPEOUTPUT)
                    slopeData[i] = tmalloc(sizeof(**slopeData)*rows);
                }
            if (offset)
              for (row=0; row<rows; row++)
                depenData[row] += offset;
            for (zrow=row=0; row<rows-1; row++) {
                if ((depenData[row]<=0 && depenData[row+1]>=0) ||
                    (depenData[row]>=0 && depenData[row+1]<=0)) {
                    for (i=0; i<columnNames; i++) {
                        if (indepData[i][row]==indepData[i][row+1]) {
                            if (flags&FL_SLOPEOUTPUT)
                                slopeData[i][zrow] = DBL_MAX;
                            indepData[i][zrow] = indepData[i][row];
                            }
                        else {
                            slope = (depenData[row+1]-depenData[row])/(indepData[i][row+1]-indepData[i][row]);
                            if (flags&FL_SLOPEOUTPUT)
                                slopeData[i][zrow] = slope;
                            if (slope)
                                indepData[i][zrow] = indepData[i][row] - depenData[row]/slope;
                            else
                                indepData[i][zrow] = (indepData[i][row] + indepData[i][row+1])/2;
                            }
                        }
                    depenData[zrow] = -offset;
                    zrow++;
                    }
                }
            if (zrow) {
                if (!SDDS_LengthenTable(&outSet, zrow) || 
                    !SDDS_SetColumnFromDoubles(&outSet, SDDS_SET_BY_NAME, depenData, zrow, zeroName))
                    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
                for (i=0; i<columnNames; i++) {
                    sprintf(s, "%sSlope", columnName[i]);
                    if (!SDDS_SetColumnFromDoubles(&outSet, SDDS_SET_BY_NAME, indepData[i], zrow, columnName[i]) ||
                        (flags&FL_SLOPEOUTPUT &&
                         !SDDS_SetColumnFromDoubles(&outSet, SDDS_SET_BY_NAME, slopeData[i], zrow, s)))
                        SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
                    }
                }
            free(depenData);
            for (i=0; i<columnNames; i++)
                free(indepData[i]);
            if (flags&FL_SLOPEOUTPUT)
                for (i=0; i<columnNames; i++)
                    free(slopeData[i]);
            }
        if (!SDDS_WritePage(&outSet))
            SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        }
    if (!SDDS_Terminate(&inSet) || !SDDS_Terminate(&outSet)) {
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
      exit(1);
    }

    return(0);
}
Beispiel #2
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;
}
Beispiel #3
0
int main(int argc, char **argv)
{
  SCANNED_ARG *scanned;
  SDDS_TABLE inputPage, outputPage, residualPage;
  char *inputfile, *outputfile;
  char **column, **excludeColumn;
  int32_t columns;
  long excludeColumns;
  char *indColumnName;
  long verbose;
  long iArg, i, j, ipage;
  double *indVar, *indVarOrig;
  char *indVarUnits;
  char **intColumn, **slopeColumn, **slopeSigmaColumn, **interceptSigmaColumn;
  char *Units,*slopeUnits;
  double *depVar, *depVarOrig;
  long order;
  double *coef, *coefsigma, *weight, *diff, *diffOrig, chi;
  long iCol, iRow;
  long rows, rowsOrig;
  double rmsResidual;
  double slopeSigma, interceptSigma;
  char **sigmaColumn, **chiSquaredColumn;
  long *sigmaColumnExists;
  long doSlopeSigma, generateSigma, doPreliminaryFit;
  long validSigmas;
  double sigmaSum, averageSigma;
  long ascii;
  char *residualFile;
  unsigned long pipeFlags;
  long tmpfile_used, noWarnings;
  double xMin, xMax;

  indVar = indVarOrig = depVar = depVarOrig = coef = coefsigma = weight = diff = NULL;
  intColumn = slopeColumn = slopeSigmaColumn = interceptSigmaColumn = sigmaColumn = chiSquaredColumn = NULL;
  slopeUnits = NULL;
  sigmaColumnExists = NULL;

  SDDS_RegisterProgramName(argv[0]);
  argc = scanargs(&scanned, argc, argv);
  if (argc == 1) 
    bomb(NULL, USAGE);

  inputfile = outputfile = NULL;
  columns = excludeColumns = 0;
  column = excludeColumn = NULL;
  indColumnName = NULL;
  verbose = 0;
  doSlopeSigma = 0;
  generateSigma = 0;
  doPreliminaryFit = 0;
  ascii = 0;
  pipeFlags = 0;
  tmpfile_used=0;
  noWarnings=0;
  residualFile = NULL;
  xMin = xMax = 0;

  for (iArg = 1;  iArg<argc;  iArg++) {
    if (scanned[iArg].arg_type == OPTION) {
      delete_chars(scanned[iArg].list[0], "_");
      switch (match_string(scanned[iArg].list[0], commandline_option, COMMANDLINE_OPTIONS, UNIQUE_MATCH)) {
      case CLO_INDEPENDENT_COLUMN:   
        if (!(indColumnName = scanned[iArg].list[1]))
          SDDS_Bomb("no string given for option -independentVariable");
        break;
      case CLO_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 CLO_EXCLUDE:
        if (excludeColumns)
          SDDS_Bomb("only one -excludecolumns option may be given");
        if (scanned[iArg].n_items<2)
          SDDS_Bomb("invalid -excludecolumns syntax");
        excludeColumn = tmalloc(sizeof(*excludeColumn)*(excludeColumns = scanned[iArg].n_items-1));
        for (i = 0;  i<excludeColumns;  i++)
          excludeColumn[i] = scanned[iArg].list[i+1];
        break;
      case CLO_VERBOSE:
        verbose = 1;
        break;
      case CLO_ASCII:
        ascii = 1;
        break;
      case CLO_PIPE:
        if (!processPipeOption(scanned[iArg].list+1, scanned[iArg].n_items-1, &pipeFlags))
          SDDS_Bomb("invalid -pipe syntax");
        break;
      case CLO_SIGMA:
        doSlopeSigma = 1;
        if (scanned[iArg].n_items > 1 ) {
          switch (match_string(scanned[iArg].list[1], sigma_option, SIGMA_OPTIONS, UNIQUE_MATCH)) {
          case SIGMA_GENERATE:
            generateSigma = 1;
            break;
          default:
            SDDS_Bomb("unrecognized sigma option given");
            break;
          }
        }
        break;
      case CLO_RESIDUAL:
        if (!(residualFile=scanned[iArg].list[1])){
          fprintf(stderr,"No file specified in -residual option.\n");
          exit(1);
        }
        break;
      case CLO_RANGE:
        if (scanned[iArg].n_items!=3 ||
            1!=sscanf(scanned[iArg].list[1], "%lf", &xMin) ||
            1!=sscanf(scanned[iArg].list[2], "%lf", &xMax) ||
            xMin>=xMax)
          SDDS_Bomb("incorrect -range syntax");
        break;
      default: 
        SDDS_Bomb("unrecognized option given");
        break;
      }
    }
    else {
      if (!inputfile)
        inputfile = scanned[iArg].list[0];
      else if (!outputfile)
        outputfile = scanned[iArg].list[0];
      else
        SDDS_Bomb("too many filenames given");
    }
  }

  if (residualFile && outputfile) {
    if (!strcmp( residualFile, outputfile)) {
      fprintf( stderr, "Residual file can't be the same as the output file.\n");
      exit(1);
    }
  }
  
  processFilenames("sddsslopes", &inputfile, &outputfile, pipeFlags, noWarnings, &tmpfile_used);

  if (!indColumnName) {
    fprintf( stderr, "independentVariable not given\n");
    exit(1);
  }
  
  if (!excludeColumns) {
    excludeColumn = defaultExcludedColumn;
    excludeColumns = DEFAULT_EXCLUDED_COLUMNS;
  }
  
  if (verbose)
    fprintf(stderr,"Reading file %s.\n",inputfile);
  if ( !SDDS_InitializeInput( &inputPage, inputfile) )
    SDDS_PrintErrors( stderr, SDDS_EXIT_PrintErrors|SDDS_VERBOSE_PrintErrors);
  while (0 < (ipage=SDDS_ReadTable( &inputPage))) {
    if (verbose) {
      fprintf(stderr, "working on page %ld\n", ipage);
    }
    rows = SDDS_CountRowsOfInterest(&inputPage);
    rowsOrig = rows;
    /*************************************\
     * make array of independent variable
     \*************************************/
    if (ipage==1) {
      indVar = (double*) malloc( sizeof(*indVar) * rows);
    }
    else {
      indVar = (double*) realloc( indVar, sizeof(*indVar) * rows);
    }
    if (ipage==1) {
      if (!SDDS_FindColumn(&inputPage, FIND_NUMERIC_TYPE, indColumnName, NULL)){
        fprintf(stderr,"Something wrong with column %s.\n", indColumnName);
        SDDS_CheckColumn(&inputPage, indColumnName, NULL, SDDS_ANY_NUMERIC_TYPE, stderr);
        exit(1);
      }
    }
    /* filter out the specified range in independent variable */
    if (xMin!=xMax) {
      if (!(indVarOrig = SDDS_GetColumnInDoubles( &inputPage, indColumnName))) 
        SDDS_PrintErrors( stderr, SDDS_EXIT_PrintErrors|SDDS_VERBOSE_PrintErrors);
      for (i=j=0; i<rowsOrig; i++) {
        if (indVarOrig[i]<=xMax && indVarOrig[i]>=xMin) {
          indVar[j] = indVarOrig[i];
          j++;
        }
      }
      rows = j;
    }
    else {
      if (!(indVar = SDDS_GetColumnInDoubles( &inputPage, indColumnName))) 
        SDDS_PrintErrors( stderr, SDDS_EXIT_PrintErrors|SDDS_VERBOSE_PrintErrors);
    }
    if ( ipage == 1 ) {
      if (!SDDS_GetColumnInformation(&inputPage, "units", &indVarUnits, SDDS_GET_BY_NAME, indColumnName))
        SDDS_PrintErrors( stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
      if (!indVarUnits) {
        indVarUnits = (char *) malloc(sizeof(*indVarUnits));
        indVarUnits[0] = 0;
      }
    }
    /************************************\
     * initialize residual file 
     \************************************/
    if (residualFile) {
      if ( ipage == 1 ) {
        if(!SDDS_InitializeOutput(&residualPage,ascii?SDDS_ASCII:SDDS_BINARY,1,
                                  "Residual of 2-term fit",NULL,outputfile) ||
           !SDDS_InitializeCopy(&residualPage, &inputPage, residualFile, "w") ||
           !SDDS_WriteLayout(&residualPage) )
          SDDS_PrintErrors(stderr,SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
      }
      if (!SDDS_CopyPage(&residualPage,&inputPage))
        SDDS_PrintErrors(stderr,SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    }
  
    /************************************\
     * get columns of interest. use set_multicolumn_flags to simply
     * return new values for array column.
     \*************************************/
    if (!set_multicolumn_flags(&inputPage, &column, &columns, excludeColumn, excludeColumns)) {
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
      exit(1);
    }
    /************************************\
     * make  column names for the output
     \*************************************/
    if (ipage==1) {
      intColumn = (char**) malloc((sizeof(char*)*columns));
      slopeColumn = (char**) malloc((sizeof(char*)*columns));
      if (doSlopeSigma) {
        slopeSigmaColumn = (char**) malloc((sizeof(char*)*columns));
        interceptSigmaColumn = (char**) malloc((sizeof(char*)*columns));
        chiSquaredColumn = (char**) malloc((sizeof(char*)*columns));
      }
      for (i=0; i<columns; i++) {
        intColumn[i] = (char*) malloc((sizeof(char)*(strlen(column[i])+strlen("Intercept")+1)));
        strcat(strcpy(intColumn[i], column[i]), "Intercept");
        slopeColumn[i] = (char*) malloc((sizeof(char)*(strlen(column[i])+strlen("Slope")+1)));
        strcat(strcpy(slopeColumn[i], column[i]), "Slope");
        if (doSlopeSigma) {
          slopeSigmaColumn[i] = (char*) malloc((sizeof(char)*(strlen(column[i])+strlen("SlopeSigma")+1)));
          strcat(strcpy(slopeSigmaColumn[i], column[i]), "SlopeSigma");
          interceptSigmaColumn[i] = (char*) malloc((sizeof(char)*(strlen(column[i])+strlen("InterceptSigma")+1)));
          strcat(strcpy(interceptSigmaColumn[i], column[i]), "InterceptSigma");
          chiSquaredColumn[i] = (char*) malloc((sizeof(char)*(strlen(column[i])+strlen("ChiSquared")+1)));
          strcat(strcpy(chiSquaredColumn[i], column[i]), "ChiSquared");
        }
      }
    }
    /************************************\
     * Write layout for output file
     \*************************************/
    if (ipage==1) {
      if (verbose)
        fprintf(stderr,"Opening file %s.\n",outputfile);
      if(!SDDS_InitializeOutput(&outputPage,ascii?SDDS_ASCII:SDDS_BINARY,1,
                                "2-term fit",NULL,outputfile) ||
         0>SDDS_DefineParameter(&outputPage, "InputFile", "InputFile", NULL,
                                "InputFile", NULL, SDDS_STRING, 0) ||
         0>SDDS_DefineColumn(&outputPage, "IndependentVariable", NULL, NULL, NULL, NULL, SDDS_STRING,0) )
        SDDS_PrintErrors(stderr,SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
      for (iCol=0; iCol<columns; iCol++) {
        if (!SDDS_GetColumnInformation(&inputPage, "units", &Units, SDDS_GET_BY_NAME, column[iCol]))
          SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        if (!Units) {
          Units = (char*) malloc(sizeof(*Units));
          Units[0] = 0;
        }
        if (0>SDDS_DefineColumn(&outputPage, intColumn[iCol], NULL, Units, NULL, NULL, SDDS_DOUBLE,0))
          SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        /* units for slopes columns */
        if (strlen(indVarUnits) && strlen(Units) ) {
          slopeUnits = (char*)malloc(sizeof(*slopeUnits)*(strlen(Units)+strlen(indVarUnits)+2));
          strcat( strcat( strcpy(slopeUnits, Units), "/"), indVarUnits);
        }
        if (strlen(indVarUnits) && !strlen(Units) ) {
          slopeUnits = (char*)malloc(sizeof(*slopeUnits)*(strlen(indVarUnits)+2));
          strcat( strcpy( slopeUnits, "1/"), indVarUnits);
        }
        if (!strlen(indVarUnits) && strlen(Units) ) {
          slopeUnits = (char*)malloc(sizeof(*slopeUnits)*(strlen(Units)+2));
          strcpy( slopeUnits, indVarUnits);
        }
        if (!strlen(indVarUnits) && !strlen(Units) ) {
          slopeUnits = (char*)malloc(sizeof(*slopeUnits));
          strcpy( slopeUnits, "");
        }
        if (0>SDDS_DefineColumn(&outputPage, slopeColumn[iCol], NULL, slopeUnits, NULL, NULL, SDDS_DOUBLE,0))
          SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        if (doSlopeSigma) {
          if (0>SDDS_DefineColumn(&outputPage, interceptSigmaColumn[iCol], NULL, Units, 
                                  NULL, NULL, SDDS_DOUBLE,0) ||
              0>SDDS_DefineColumn(&outputPage, slopeSigmaColumn[iCol], NULL, slopeUnits, 
                                  NULL, NULL, SDDS_DOUBLE,0) ||
              0>SDDS_DefineColumn(&outputPage, chiSquaredColumn[iCol], NULL, NULL, 
                                  NULL, NULL, SDDS_DOUBLE,0))
            SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        }
        free(slopeUnits);
      }
      if ( !SDDS_WriteLayout(&outputPage))
        SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    }
  
    if ( !SDDS_StartTable(&outputPage,1) ||
       !SDDS_SetParameters(&outputPage, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE,
                           "InputFile",inputfile?inputfile:"pipe",NULL) ||
       !SDDS_SetRowValues(&outputPage, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE, 0,
                          "IndependentVariable", indColumnName, NULL) )
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    
    /* determine which included columns has a Sigma column defined in the input file */
    if ( ipage == 1 ) {
      sigmaColumn = (char **) malloc( sizeof(*sigmaColumn)*columns);
      sigmaColumnExists = (long *) malloc(columns*sizeof(*sigmaColumnExists)); 
      for (iCol=0; iCol<columns; iCol++) {
        sigmaColumn[iCol] = (char *) malloc( sizeof(**sigmaColumn) * 
                                            (strlen(column[iCol]) + strlen("Sigma") + 1) );
        strcat( strcpy(sigmaColumn[iCol], column[iCol]), "Sigma");
        switch(SDDS_CheckColumn(&inputPage, sigmaColumn[iCol], NULL, SDDS_DOUBLE, NULL)) {
        case SDDS_CHECK_WRONGUNITS:
        case SDDS_CHECK_OKAY:
          sigmaColumnExists[iCol] = 1;
          break;
        default:
          /* try other possible spelling */
          strcat( strcpy(sigmaColumn[iCol] ,"Sigma"), column[iCol]);
          switch(SDDS_CheckColumn(&inputPage, sigmaColumn[iCol], NULL, SDDS_DOUBLE, NULL)) {
          case SDDS_CHECK_WRONGUNITS:
          case SDDS_CHECK_OKAY:
            sigmaColumnExists[iCol] = 1;
            break;
          default:
            sigmaColumnExists[iCol] = 0;
          }
          break;
        }
      }
    }
    
    if ( ipage == 1 ) {
      weight = (double*)malloc(sizeof(*weight)*rows);
      diff = (double*)malloc(sizeof(*diff)*rows);
      order=1;
      coef = (double*)malloc(sizeof(*coef)*(order+1));
      coefsigma = (double*)malloc(sizeof(*coefsigma)*(order+1));
    }
    else {
      weight = (double*)realloc( weight, sizeof(*weight)*rows);
      diff = (double*)realloc( diff, sizeof(*diff)*rows);
      order=1;
      coef = (double*)realloc( coef, sizeof(*coef)*(order+1));
      coefsigma = (double*)realloc( coefsigma, sizeof(*coefsigma)*(order+1));
    }
    
    if (ipage==1) {
      depVar = (double*) malloc( sizeof(*depVar) * rows);
    }
    else {
      depVar = (double*) realloc( depVar, sizeof(*depVar) * rows);
    }
    for (iCol=0; iCol<columns; iCol++) {
      if (verbose)
        fprintf(stderr,"Doing column %s.\n", column[iCol]);
      /* filter out the specified range in independent variable */
      if (xMin!=xMax) {
        if (!(depVarOrig = (double*) SDDS_GetColumnInDoubles(&inputPage, column[iCol])))
          SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors|SDDS_VERBOSE_PrintErrors);
        for (i=j=0; i<rowsOrig; i++) {
          if ( xMin <= indVarOrig[i] && indVarOrig[i] <= xMax ) {
            depVar[j] = depVarOrig[i];
            j++;
          }
        }
      }
      else {
        if (!(depVar=SDDS_GetColumnInDoubles(&inputPage, column[iCol])))
          SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors|SDDS_VERBOSE_PrintErrors);
      }
      
      /*********************
        three possibilities:
        1) don't do or write slope errors. (doSlopeSigma=0)
        do one lsf call with all weights = 1
        2) calculated slope errors from sigma columns in the input file. 
        (doSlopeSigma=1 && generateSigma=0 && sigmaColumnExists[iCol]=1 )
        do one lsf call with weights from sigma columns
        3) calculate slope errors from generated sigma from a preliminary fit. 
        (doSlopeSigma=1 && (generateSigma=1 || sigmaColumnExists[iCol]=NULL)
        do preliminary fit to generate sigma
        *********************/

      for (iRow=0; iRow<rows; iRow++)
        weight[iRow] = 1;
      if (doSlopeSigma) {
        /*********************
          check validity of sigma column values 
          *********************/
        if( !generateSigma && sigmaColumnExists[iCol]) {
          if (verbose)
            fprintf(stderr,"\tUsing column %s for sigma.\n",sigmaColumn[iCol]);
          if(!(weight=SDDS_GetColumnInDoubles(&inputPage, sigmaColumn[iCol])))
            SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors|SDDS_VERBOSE_PrintErrors);
          /* check for zero weight values which will give lsfn problems */
          validSigmas = rows;
          sigmaSum = 0;
          for (iRow=0; iRow<rows; iRow++) {
            sigmaSum += weight[iRow];
            if(!weight[iRow]) {
              validSigmas--;
              /* 
                fprintf(stderr,"Warning: %s of row number %ld is zero. Using average sigma.\n",sigmaColumn[iCol],iRow); */
            }
          }
          if (!validSigmas) {
            fprintf(stderr,"Warning: All sigmas are zero.\n");
            doPreliminaryFit = 1;
          }
          else if (validSigmas!=rows) {
            /* fix some sigmas */
            averageSigma = sigmaSum/ validSigmas;
            fprintf(stderr, "Warning: replacing %ld invalid sigmas with average (%e)\n",
                    rows-validSigmas, averageSigma);
            for (iRow=0; iRow<rows; iRow++) {
              if(!weight[iRow]) {
                weight[iRow] = averageSigma;
              }
            }
          }
        }
        else {
          doPreliminaryFit = 1;
        }
      }
      
      if (doPreliminaryFit) {
        if (verbose)
          fprintf(stderr,"\tGenerating sigmas from rms residual of a preliminary fit.\n");
        if (!(lsfn(indVar, depVar, weight, rows, order, coef, coefsigma, &chi, diff))){
          fprintf(stderr,"Problem with call to lsfn\n.");
          exit(1);
        }
        rmsResidual = 0;
        /* calculate rms residual */
        for (iRow=0; iRow<rows; iRow++) {
          rmsResidual += sqr(diff[iRow]);
        }
        rmsResidual = sqrt(rmsResidual/(rows));
        for (iRow=0; iRow<rows; iRow++) {
          weight[iRow] = rmsResidual;
        }
      }
      
      if (!(lsfn(indVar, depVar, weight, rows, order, coef, coefsigma, &chi, diff))) {
        fprintf(stderr,"Problem with call to lsfn\n.");
        exit(1);
      }
      if (!SDDS_SetRowValues(&outputPage, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE, 0,
                             intColumn[iCol], coef[0],
                             slopeColumn[iCol], coef[1], NULL))
        SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
      if (doSlopeSigma) {
        interceptSigma = coefsigma[0];
        slopeSigma = coefsigma[1];
        if (!SDDS_SetRowValues(&outputPage, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE, 0,
                               chiSquaredColumn[iCol], chi,
                               interceptSigmaColumn[iCol], interceptSigma,
                               slopeSigmaColumn[iCol], slopeSigma, NULL))
          SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
      }
      if (residualFile) {
        if (xMin!=xMax) {
          /* calculate the residuals for the whole column explicitly since there
             are points outside the range of which the lsf call did not calculate
             the difference. */
          diffOrig = (double*) malloc( rowsOrig * sizeof(double) );
          for (i=0; i<rowsOrig; i++) {
            diffOrig[i] = depVarOrig[i] - coef[0] - coef[1] * indVarOrig[i];
          }
          if( !SDDS_SetColumnFromDoubles(&residualPage, SDDS_SET_BY_NAME|SDDS_PASS_BY_REFERENCE,
                                         diffOrig,rowsOrig,column[iCol]))
            SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        }
        else {
          if( !SDDS_SetColumnFromDoubles(&residualPage, SDDS_SET_BY_NAME|SDDS_PASS_BY_REFERENCE,
                                         diff,rows,column[iCol]))
            SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        }
      }
    }

    if (residualFile) {
      if (!SDDS_WriteTable(&residualPage)) 
        SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    }
    
    if (!SDDS_WriteTable(&outputPage)) 
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  }
  
  if (residualFile) {
    if (!SDDS_Terminate(&residualPage))
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  }
  if(!SDDS_Terminate(&inputPage) || !SDDS_Terminate(&outputPage))
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  
  if (tmpfile_used && !replaceFileAndBackUp(inputfile, outputfile)) 
    exit(1);
  return(0);
}
Beispiel #4
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;
    }
Beispiel #5
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);
}
Beispiel #6
0
int main(int argc, char **argv)
{
  int iArg;
  char *input, *output,*meanPar, *sigmaPar, *maxPar, *minPar;
  long i, j, mainInputOpened, haltonID=0, requireInput=0;
  unsigned long pipeFlags;
  SCANNED_ARG *scanned;
  SDDS_DATASET SDDSin, SDDSout, *SDDSptr;
  long randomNumberSeed = 0;
  SEQ_REQUEST *seqRequest;
  long samples, values, seqRequests, randomizationGroups=0;
  double *sample, *IVValue, *CDFValue;
  char msgBuffer[1000];
  RANDOMIZED_ORDER *randomizationData = NULL;
  long verbose, optimalHalton=0;
  
  SDDS_RegisterProgramName(argv[0]);
  argc = scanargs(&scanned, argc, argv); 
  if (argc<2) {
    fprintf(stderr, "%s%s%s\n", USAGE1, USAGE2, USAGE3);
    return(1);
  }
  seqRequest = NULL;
  seqRequests = 0;
  output = input = NULL;
  pipeFlags = 0;
  samples = values = 0;
  sample = IVValue = CDFValue = NULL;
  verbose = 0;
  maxPar = minPar = meanPar = sigmaPar = 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_COLUMNS:
        if (scanned[iArg].n_items<3)
          SDDS_Bomb("invalid -columns syntax");
        if (!(seqRequest = SDDS_Realloc(seqRequest, sizeof(*seqRequest)*(seqRequests+1))))
          SDDS_Bomb("memory allocation failure");
        scanned[iArg].n_items -= 1;
        memset(seqRequest+seqRequests, 0, sizeof(*seqRequest));
        /*remove following pointer initialization because memset already initialize them */
        seqRequest[seqRequests].randomizationGroup = -1;
        seqRequest[seqRequests].factor = 1;
        seqRequest[seqRequests].offset = 0;
        if (!scanItemList(&seqRequest[seqRequests].flags, 
                          scanned[iArg].list+1, &scanned[iArg].n_items, 0,
                          "datafile", SDDS_STRING,
                          &seqRequest[seqRequests].dataFileName, 1, SEQ_DATAFILE,
                          "independentvariable", SDDS_STRING, 
                          &seqRequest[seqRequests].indepName, 1, SEQ_INDEPNAME,
                          "cdf", SDDS_STRING, 
                          &seqRequest[seqRequests].CDFName, 1, SEQ_CDFNAME,
                          "df", SDDS_STRING, 
                          &seqRequest[seqRequests].DFName, 1, SEQ_DFNAME,
                          "output", SDDS_STRING, 
                          &seqRequest[seqRequests].outputName, 1, SEQ_OUTPUTNAME,
                          "units", SDDS_STRING, 
                          &seqRequest[seqRequests].units, 1, SEQ_UNITSGIVEN,
                          "haltonradix", SDDS_LONG,
                          &seqRequest[seqRequests].haltonRadix, 1, SEQ_HALTONRADIX,
                          "haltonoffset", SDDS_LONG,
                          &seqRequest[seqRequests].haltonOffset, 1, SEQ_HALTONOFFSET,
                          "randomize", -1, NULL, 0, SEQ_RANDOMIZE,
                          "group", SDDS_LONG, 
                          &seqRequest[seqRequests].randomizationGroup, 1, SEQ_RANDOMGROUP,
                          "factor", SDDS_DOUBLE, 
                          &seqRequest[seqRequests].factor, 1, 0,
                          "offset", SDDS_DOUBLE, 
                          &seqRequest[seqRequests].offset, 1, 0,
                          NULL) ||
            bitsSet(seqRequest[seqRequests].flags&(SEQ_INDEPNAME+SEQ_CDFNAME+SEQ_DFNAME))!=2)
          SDDS_Bomb("invalid -columns syntax");
        if (seqRequest[seqRequests].flags&SEQ_RANDOMGROUP &&
            seqRequest[seqRequests].randomizationGroup<=0)
          SDDS_Bomb("use a positive integer for the randomization group ID");
        if (seqRequest[seqRequests].flags&SEQ_CDFNAME &&
            seqRequest[seqRequests].flags&SEQ_DFNAME) 
          SDDS_Bomb("give df or cdf for -columns, not both");
        if (seqRequest[seqRequests].flags&SEQ_HALTONRADIX &&
            !is_prime(seqRequest[seqRequests].haltonRadix))
          SDDS_Bomb("halton radix must be a prime number");
        seqRequests ++;
        scanned[iArg].n_items += 1;
        break;
      case CLO_GAUSSIAN:
        if (scanned[iArg].n_items<2)
          SDDS_Bomb("invalid -gaussian syntax");
        if (!(seqRequest = SDDS_Realloc(seqRequest, sizeof(*seqRequest)*(seqRequests+1))))
          SDDS_Bomb("memory allocation failure");
        memset(seqRequest+seqRequests, 0, sizeof(*seqRequest)); 
        scanned[iArg].n_items -= 1;
        seqRequest[seqRequests].randomizationGroup = -1;
        seqRequest[seqRequests].mean = 0;
        seqRequest[seqRequests].sigma = 1;
        if (!scanItemList(&seqRequest[seqRequests].flags, 
                          scanned[iArg].list+1, &scanned[iArg].n_items, 0,
                          "columnName", SDDS_STRING, &seqRequest[seqRequests].outputName, 1, SEQ_OUTPUTNAME,
                          "meanValue", SDDS_STRING,  &meanPar, 1, 0,
                          "sigmaValue", SDDS_STRING, &sigmaPar, 1, 0, 
                          "units", SDDS_STRING, &seqRequest[seqRequests].units, 1, SEQ_UNITSGIVEN,
                          NULL))
          SDDS_Bomb("invalid -gaussian syntax");
        seqRequest[seqRequests].flags |= SEQ_DIRECT_GAUSSIAN; 
        if (!(seqRequest[seqRequests].flags&SEQ_OUTPUTNAME) || !(seqRequest[seqRequests].outputName))
          SDDS_Bomb("columnName is not provided for gaussian distribution/");
        if (meanPar) {
          if (wild_match(meanPar, "@*"))
            SDDS_CopyString(&seqRequest[seqRequests].meanPar, meanPar+1);
          else if (!get_double(&seqRequest[seqRequests].mean, meanPar))  
            SDDS_Bomb("Invalid value given for mean value of -gaussian distribution.");
          free(meanPar);
          meanPar = NULL;
        }
        if (sigmaPar) {
          if (wild_match(sigmaPar, "@*"))
            SDDS_CopyString(&seqRequest[seqRequests].sigmaPar, sigmaPar+1);
          else if (!get_double(&seqRequest[seqRequests].sigma, sigmaPar)) 
            SDDS_Bomb("Invalid value given for sigma value of -gaussian distribution.");
          free(sigmaPar);
          sigmaPar = NULL;
        }
        seqRequests ++;
        scanned[iArg].n_items += 1;
        break;
      case CLO_UNIFORM:
        if (scanned[iArg].n_items<2)
          SDDS_Bomb("invalid -uniform syntax");
        if (!(seqRequest = SDDS_Realloc(seqRequest, sizeof(*seqRequest)*(seqRequests+1))))
          SDDS_Bomb("memory allocation failure");
        memset(seqRequest+seqRequests, 0, sizeof(*seqRequest));
        scanned[iArg].n_items -= 1;
        memset(seqRequest+seqRequests, 0, sizeof(*seqRequest));
        seqRequest[seqRequests].randomizationGroup = -1;
        seqRequest[seqRequests].min = 0;
        seqRequest[seqRequests].max = 1;
        if (!scanItemList(&seqRequest[seqRequests].flags, 
                          scanned[iArg].list+1, &scanned[iArg].n_items, 0,
                          "columnName", SDDS_STRING, &seqRequest[seqRequests].outputName, 1, SEQ_OUTPUTNAME,
                          "minimumValue", SDDS_STRING, &minPar, 1, 0,
                          "maximumValue", SDDS_STRING, &maxPar, 1, 0,
                          "units", SDDS_STRING, &seqRequest[seqRequests].units, 1, SEQ_UNITSGIVEN, 
                          NULL))
          SDDS_Bomb("invalid -uniform syntax");
        seqRequest[seqRequests].flags |= SEQ_DIRECT_UNIFORM; 
        if (!(seqRequest[seqRequests].flags&SEQ_OUTPUTNAME) || !(seqRequest[seqRequests].outputName))
          SDDS_Bomb("columnName is not provided for uniform distribution/");
        if (minPar) {
          if (wild_match(minPar, "@*"))
            SDDS_CopyString(&seqRequest[seqRequests].minPar, minPar+1);
          else if (!get_double(&seqRequest[seqRequests].min, minPar))  
            SDDS_Bomb("Invalid value given for minimum value of -uniform distribution.");
          free(minPar);
          minPar = NULL;
        }
        if (maxPar) {
          if (wild_match(maxPar, "@*"))
            SDDS_CopyString(&seqRequest[seqRequests].maxPar, maxPar+1);
          else if (!get_double(&seqRequest[seqRequests].max, maxPar))  
            SDDS_Bomb("Invalid value given for maximum value of -uniform distribution.");
          free(maxPar);
          maxPar = NULL;
        }
        seqRequests ++;
        scanned[iArg].n_items += 1;
        break;
      case CLO_POISSON:
        if (scanned[iArg].n_items<2)
          SDDS_Bomb("invalid -poisson syntax");
        if (!(seqRequest = SDDS_Realloc(seqRequest, sizeof(*seqRequest)*(seqRequests+1))))
          SDDS_Bomb("memory allocation failure");
        memset(seqRequest+seqRequests, 0, sizeof(*seqRequest));
        scanned[iArg].n_items -= 1;
        memset(seqRequest+seqRequests, 0, sizeof(*seqRequest));
        seqRequest[seqRequests].randomizationGroup = -1;
        seqRequest[seqRequests].mean = 1;
        if (!scanItemList(&seqRequest[seqRequests].flags, 
                          scanned[iArg].list+1, &scanned[iArg].n_items, 0,
                          "columnName", SDDS_STRING, &seqRequest[seqRequests].outputName, 1, SEQ_OUTPUTNAME,
                          "meanValue", SDDS_STRING, &meanPar, 1, 0,
                          "units", SDDS_STRING, &seqRequest[seqRequests].units, 1, SEQ_UNITSGIVEN, 
                          NULL))
          SDDS_Bomb("invalid -poisson syntax");
        seqRequest[seqRequests].flags |= SEQ_DIRECT_POISSON; 
        if (!(seqRequest[seqRequests].flags&SEQ_OUTPUTNAME) || !(seqRequest[seqRequests].outputName))
          SDDS_Bomb("columnName is not provided for uniform distribution/");
        if (meanPar) {
          if (wild_match(meanPar, "@*"))
            SDDS_CopyString(&seqRequest[seqRequests].meanPar, meanPar+1);
          else if (!get_double(&seqRequest[seqRequests].mean, meanPar))  
            SDDS_Bomb("Invalid value given for mean value of -poisson distribution.");
          free(meanPar);
          meanPar = NULL;
        } 
        seqRequests ++;
        scanned[iArg].n_items += 1;
        break;
      case CLO_SAMPLES:
        if (scanned[iArg].n_items!=2 ||
            sscanf(scanned[iArg].list[1], "%ld", &samples)!=1 || 
            samples<=0)
          SDDS_Bomb("invalid -samples syntax");
        break;
      case CLO_SEED:
        if (scanned[iArg].n_items!=2 ||
            sscanf(scanned[iArg].list[1], "%ld", &randomNumberSeed)!=1 || 
            randomNumberSeed<=0)
          SDDS_Bomb("invalid -seed 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_VERBOSE:
        verbose = 1;
        break;
      case CLO_OPTIMAL_HALTON:
        optimalHalton = 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");
    }
  }
  
  if (!seqRequests)
    SDDS_Bomb("give one or more -columns options");
  if (samples<1)
    SDDS_Bomb("-samples option not given");

  for (i=0; i<seqRequests; i++) {
    if (!(seqRequest[i].flags&
          (SEQ_DATAFILE|SEQ_DIRECT_GAUSSIAN|SEQ_DIRECT_UNIFORM|SEQ_DIRECT_POISSON)))
      break;
  }
  if (i==seqRequests) {
    /* all columns options have either their own input files or else use
     * one of the "direct" distributions.  Hence, we don't expect an input
     * file.
     */
    if (!input)
      pipeFlags |= USE_STDIN;   /* not really, but fakes out processFilenames */
    if (input && !output) {
      output = input;
      input = NULL;
      pipeFlags |= USE_STDIN;
      if (fexists(output)) {
        sprintf(msgBuffer, "%s exists already (sddssampledist)", output);
        SDDS_Bomb(msgBuffer);
      }
    }
  }
  
  processFilenames("sddssampledist", &input, &output, pipeFlags, 0, NULL);
  
  if (!SDDS_InitializeOutput(&SDDSout, SDDS_BINARY, 0, NULL, NULL, output))
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  if (verbose)
    fprintf(stderr, "Initialized output file %s\n", output);
  
  /* open and check input files */
  for (i=mainInputOpened=0; i<seqRequests; i++) {
    if (seqRequest[i].flags&SEQ_DIRECT_GAUSSIAN) {
      if (seqRequest[i].meanPar || seqRequest[i].sigmaPar) {
        if (!mainInputOpened) {
          if (!SDDS_InitializeInput(&SDDSin, input) ||
              !SDDS_TransferAllParameterDefinitions(&SDDSout, &SDDSin, 0))
            SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
          mainInputOpened = 1;
        }
        requireInput = 1;
        SDDSptr = &SDDSin; 
        if ((seqRequest[i].meanPar &&
             SDDS_CheckParameter(SDDSptr, seqRequest[i].meanPar, NULL, SDDS_ANY_NUMERIC_TYPE, stderr)!=SDDS_CHECK_OK) ||
            (seqRequest[i].sigmaPar &&
             SDDS_CheckParameter(SDDSptr, seqRequest[i].sigmaPar, NULL, SDDS_ANY_NUMERIC_TYPE, stderr)!=SDDS_CHECK_OK)) {
          SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
          exit(1);
        }
      }
      if (!SDDS_DefineSimpleColumn(&SDDSout, seqRequest[i].outputName, NULL, SDDS_DOUBLE)) 
        SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); 
    } else if (seqRequest[i].flags&SEQ_DIRECT_UNIFORM) {
      if (seqRequest[i].minPar || seqRequest[i].maxPar) {
        if (!mainInputOpened) {
          if (!SDDS_InitializeInput(&SDDSin, input) ||
              !SDDS_TransferAllParameterDefinitions(&SDDSout, &SDDSin, 0))
            SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
          mainInputOpened = 1;
        }
        requireInput = 1;
        SDDSptr = &SDDSin;
        if ((seqRequest[i].minPar &&
             SDDS_CheckParameter(SDDSptr, seqRequest[i].minPar, NULL, SDDS_ANY_NUMERIC_TYPE, stderr)!=SDDS_CHECK_OK) ||
            (seqRequest[i].maxPar &&
             SDDS_CheckParameter(SDDSptr, seqRequest[i].maxPar, NULL, SDDS_ANY_NUMERIC_TYPE, stderr)!=SDDS_CHECK_OK)) {
          SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
          exit(1);
        }
      }
      if (!SDDS_DefineSimpleColumn(&SDDSout, seqRequest[i].outputName, NULL, SDDS_DOUBLE))
        SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    } else if (seqRequest[i].flags&SEQ_DIRECT_POISSON) {
      if (seqRequest[i].meanPar) {
        if (!mainInputOpened) {
          if (!SDDS_InitializeInput(&SDDSin, input) ||
              !SDDS_TransferAllParameterDefinitions(&SDDSout, &SDDSin, 0))
            SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
          mainInputOpened = 1;
        }
        requireInput = 1;
        SDDSptr = &SDDSin;
        if ( SDDS_CheckParameter(SDDSptr, seqRequest[i].meanPar, NULL, SDDS_ANY_NUMERIC_TYPE, stderr)!=SDDS_CHECK_OK) {
          SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
          exit(1);
        }
      }
      if (!SDDS_DefineSimpleColumn(&SDDSout, seqRequest[i].outputName, NULL, SDDS_LONG))
        SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    } else {     
      if (seqRequest[i].flags&SEQ_RANDOMIZE) {
        long newGroupID=0;
        /* define randomization groups */
        if (seqRequest[i].flags&SEQ_RANDOMGROUP) {
          newGroupID = seqRequest[i].randomizationGroup;
          for (j=0; j<randomizationGroups; j++)
            if (randomizationData[j].group==newGroupID) {
              newGroupID = 0;
              break;
            }
        } else {
          seqRequest[i].randomizationGroup = newGroupID = -(i+1);
        }
        if (newGroupID!=0) {
          if (!(randomizationData = 
                SDDS_Realloc(randomizationData,
                             sizeof(*randomizationData)*(randomizationGroups+1))))
            SDDS_Bomb("memory allocation failure");
          randomizationData[randomizationGroups].group = newGroupID;
          randomizationData[randomizationGroups].order = NULL;
          randomizationGroups ++;
        }
      }
      if (seqRequest[i].flags&SEQ_DATAFILE) {
        if (!SDDS_InitializeInput(&seqRequest[i].SDDSin, 
                                  seqRequest[i].dataFileName))
          SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        SDDSptr = &seqRequest[i].SDDSin;
      } else {
        if (!mainInputOpened) {
          if (!SDDS_InitializeInput(&SDDSin, input) ||
              !SDDS_TransferAllParameterDefinitions(&SDDSout, &SDDSin, 0))
            SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
          mainInputOpened = 1;
        }
        requireInput = 1;
        SDDSptr = &SDDSin;
      }
      if (SDDS_CheckColumn(SDDSptr,
                           seqRequest[i].indepName, NULL, SDDS_ANY_NUMERIC_TYPE,
                           stderr)!=SDDS_CHECK_OK  ||
          ((seqRequest[i].flags&SEQ_CDFNAME) &&
           SDDS_CheckColumn(SDDSptr, seqRequest[i].CDFName, NULL, SDDS_ANY_NUMERIC_TYPE,
                            stderr)!=SDDS_CHECK_OK) ||
          ((seqRequest[i].flags&SEQ_DFNAME) &&
           SDDS_CheckColumn(SDDSptr, seqRequest[i].DFName, NULL, SDDS_ANY_NUMERIC_TYPE,
                            stderr)!=SDDS_CHECK_OK) ||
          !SDDS_TransferColumnDefinition(&SDDSout, SDDSptr,
                                         seqRequest[i].indepName,
                                         seqRequest[i].outputName)) {
        SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
        exit(1);
      } 
    }
    
    if (seqRequest[i].flags&SEQ_UNITSGIVEN &&
        !SDDS_ChangeColumnInformation(&SDDSout, "units", seqRequest[i].units,
                                      SDDS_SET_BY_NAME, 
                                      seqRequest[i].outputName))
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  }
  
  if (verbose)
    fprintf(stderr, "Initialized input files\n");

  if (!SDDS_WriteLayout(&SDDSout))
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  
  if (randomNumberSeed==0) {
    randomNumberSeed = (long)time((time_t *) NULL);
    randomNumberSeed = 2*(randomNumberSeed/2) + 1;
#if defined(_WIN32)
    random_1(-labs(randomNumberSeed));
#else
    random_1(-FABS(randomNumberSeed));
#endif
  } else
    random_1(-randomNumberSeed);
  
  if (!((sample = calloc(sizeof(*sample), samples))))
    SDDS_Bomb("memory allocation failure");
  while (1) {
    if (verbose)
      fprintf(stderr, "Beginning page loop\n");
    if (input && SDDS_ReadPage(&SDDSin)<=0)
      break;
    for (i=0; i<seqRequests; i++) {
      if (seqRequest[i].flags&SEQ_DATAFILE &&
          SDDS_ReadPage(&seqRequest[i].SDDSin)<=0)
        break;
    }
    if (i!=seqRequests)
      break;
    if (!SDDS_StartPage(&SDDSout, samples)  ||
        (input && !SDDS_CopyParameters(&SDDSout, &SDDSin)))
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    if (verbose)
      fprintf(stderr, "Defining randomization tables\n");
    /* define randomization tables */
    for (i=0; i<randomizationGroups; i++) {
      if (!(randomizationData[i].order=
            SDDS_Malloc(sizeof(*randomizationData[i].order)*samples)))
        SDDS_Bomb("memory allocation failure");
      for (j=0; j<samples; j++)
        randomizationData[i].order[j] = j;
      randomizeOrder((char*)randomizationData[i].order,
                     sizeof(*randomizationData[i].order), samples, 0,
                     random_1);
    }
    if (verbose)
      fprintf(stderr, "Beginning loop over sequence requests\n");
    for (i=0; i<seqRequests; i++) {
      if (verbose)
        fprintf(stderr, "Processing sequence request %ld\n", i);
      if (seqRequest[i].flags&SEQ_DIRECT_GAUSSIAN) {
        if ((seqRequest[i].meanPar && !SDDS_GetParameterAsDouble(&SDDSin, seqRequest[i].meanPar, &seqRequest[i].mean)) ||
            (seqRequest[i].sigmaPar && !SDDS_GetParameterAsDouble(&SDDSin, seqRequest[i].sigmaPar, &seqRequest[i].sigma)))
          SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        for (j=0; j<samples; j++)
          sample[j] = gauss_rn_lim(seqRequest[i].mean, seqRequest[i].sigma, -1, random_1);
      } else if (seqRequest[i].flags&SEQ_DIRECT_UNIFORM) {
        if ((seqRequest[i].minPar && !SDDS_GetParameterAsDouble(&SDDSin, seqRequest[i].minPar, &seqRequest[i].min)) ||
            (seqRequest[i].maxPar && !SDDS_GetParameterAsDouble(&SDDSin, seqRequest[i].maxPar, &seqRequest[i].max)))
          SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        for (j=0; j<samples; j++) 
          sample[j] = seqRequest[i].min + (seqRequest[i].max - seqRequest[i].min) * random_1(1);
      } else if (seqRequest[i].flags&SEQ_DIRECT_POISSON) {
        double *pos_x, *pos_cdf, CDF;
        long pos_points, code;
        pos_x = pos_cdf = NULL;
        if ((seqRequest[i].meanPar && !SDDS_GetParameterAsDouble(&SDDSin, seqRequest[i].meanPar, &seqRequest[i].mean)))
          SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        pos_points = CreatePoissonDistributionTable(&pos_x, &pos_cdf, seqRequest[i].mean);
        
        for (j=0; j<samples; j++) {
          CDF = random_1(1);
          sample[j]= (int)(interp(pos_x, pos_cdf, pos_points, CDF, 0, 1, &code));
        /*  fprintf(stderr, "%d, cdf=%f, sample=%f\n", j, CDF, sample[j]);*/
          
        }
        free(pos_x);
        free(pos_cdf);
      } else {
        if (input && !(seqRequest[i].flags&SEQ_DATAFILE))
          SDDSptr = &SDDSin;
        else
          SDDSptr = &seqRequest[i].SDDSin;
        if ((values = SDDS_CountRowsOfInterest(SDDSptr))) {
          if (!(IVValue 
                = SDDS_GetColumnInDoubles(SDDSptr, seqRequest[i].indepName)) ||
              (seqRequest[i].flags&SEQ_CDFNAME &&
               !(CDFValue 
                 = SDDS_GetColumnInDoubles(SDDSptr, seqRequest[i].CDFName))) ||
            (seqRequest[i].flags&SEQ_DFNAME &&
             !(CDFValue 
               = SDDS_GetColumnInDoubles(SDDSptr, seqRequest[i].DFName))))
            SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        } else {
          sprintf(msgBuffer, "empty page for file %s\n",
                  seqRequest[i].flags&SEQ_DATAFILE?
                  seqRequest[i].dataFileName:input);
          SDDS_Bomb(msgBuffer);
        }
        if (verbose)
          fprintf(stderr, "Checking and converting CDF/DF values\n");
        /* check/convert CDF/DF values */
        for (j=1; j<values; j++) {
          if (IVValue[j-1]>IVValue[j]) {
            sprintf(msgBuffer, "random variate values not monotonically increasing for %s", 
                    seqRequest[i].flags&SEQ_DATAFILE?
                    seqRequest[i].dataFileName:input);
            SDDS_Bomb(msgBuffer);
          }
          if (seqRequest[i].flags&SEQ_DFNAME) 
            /* convert DF to CDF */
            CDFValue[j] += CDFValue[j-1];
          if (CDFValue[j] < CDFValue[j-1]) {
            sprintf(msgBuffer, "CDF values decreasing for %s", 
                    seqRequest[i].flags&SEQ_DATAFILE?
                    seqRequest[i].dataFileName:input);
            SDDS_Bomb(msgBuffer);
          }
        }
        if (verbose)
          fprintf(stderr, "Normalizing CDF\n");
        /* normalize the CDF */
        if (CDFValue[values-1]<=0) {
          sprintf(msgBuffer, "CDF not valid for %s\n", 
                  seqRequest[i].dataFileName);
          SDDS_Bomb(msgBuffer);
        }
        for (j=0; j<values; j++) 
          CDFValue[j] /= CDFValue[values-1];
        if (seqRequest[i].flags&SEQ_HALTONRADIX) {
          if (verbose)
            fprintf(stderr, "Starting halton sequence, offset=%" PRId32 "\n", seqRequest[i].haltonOffset);
          if (!optimalHalton)
            haltonID = startHaltonSequence(&seqRequest[i].haltonRadix, 0.5);
          else
            haltonID = startModHaltonSequence(&seqRequest[i].haltonRadix, 0);
          while (seqRequest[i].haltonOffset-- >0) {
            if (!optimalHalton)
              nextHaltonSequencePoint(haltonID);
            else
              nextModHaltonSequencePoint(haltonID);
          }
        }
        if (verbose)
          fprintf(stderr, "Generating samples\n");
        for (j=0; j<samples; j++) {
          double CDF;
          long code;
          while (1) {
            if (seqRequest[i].flags&SEQ_HALTONRADIX) {
              if (!optimalHalton)
                CDF = nextHaltonSequencePoint(haltonID);
              else
                CDF = nextModHaltonSequencePoint(haltonID);
            }
            else 
              CDF = random_1(1);
            if (CDF<=CDFValue[values-1] && CDF>=CDFValue[0])
              break;
          }
          sample[j] 
            = seqRequest[i].factor*interp(IVValue, CDFValue, values, CDF, 0, 1, &code) 
              + seqRequest[i].offset;
        }
        if (seqRequest[i].flags&SEQ_RANDOMIZE) {
          long k, l;
          double *sample1;
          if (verbose)
            fprintf(stderr, "Randomizing order of values\n");
          if (!(sample1 = malloc(sizeof(*sample1)*samples)))
            SDDS_Bomb("memory allocation failure");
          for (l=0; l<randomizationGroups; l++) 
            if (randomizationData[l].group==seqRequest[i].randomizationGroup)
              break;
        if (l==randomizationGroups)
          SDDS_Bomb("problem with construction of randomization groups!");
          for (k=0; k<samples; k++)
            sample1[k] = sample[randomizationData[l].order[k]];
          free(sample);
          sample = sample1;
        } 
        free(IVValue);
        free(CDFValue);
      }
      if (verbose)
        fprintf(stderr, "Setting SDDS column values\n");
      if (!SDDS_SetColumnFromDoubles(&SDDSout, SDDS_SET_BY_NAME, 
                                     sample, samples, 
                                     seqRequest[i].outputName?
                                     seqRequest[i].outputName:
                                     seqRequest[i].indepName))
        SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); 
    }
    if (verbose)
      fprintf(stderr, "Writing data page\n");
    if (!SDDS_WritePage(&SDDSout))
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    if (!requireInput)
      break;
  }
  if (verbose)
    fprintf(stderr, "Exited read loop\n");
  free(sample);
  if ((input && !SDDS_Terminate(&SDDSin)) || !SDDS_Terminate(&SDDSout))
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  for (i=0; i<seqRequests; i++) {
    if (seqRequest[i].dataFileName) free(seqRequest[i].dataFileName);
    if (seqRequest[i].indepName) free(seqRequest[i].indepName);
    if (seqRequest[i].outputName) free(seqRequest[i].outputName);
    if (seqRequest[i].DFName) free(seqRequest[i].DFName);
    if (seqRequest[i].CDFName) free(seqRequest[i].CDFName);
    if (seqRequest[i].units) free(seqRequest[i].units);
    if (seqRequest[i].meanPar) free(seqRequest[i].meanPar);
    if (seqRequest[i].sigmaPar) free(seqRequest[i].sigmaPar);
    if (seqRequest[i].minPar) free(seqRequest[i].minPar);
    if (seqRequest[i].maxPar) free(seqRequest[i].maxPar); 
    if (seqRequest[i].flags&SEQ_DATAFILE && !SDDS_Terminate(&(seqRequest[i].SDDSin)))
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  }
  free(seqRequest);
  for (i=0; i<randomizationGroups; i++)
    free(randomizationData[i].order);
  if (randomizationData) free(randomizationData);
  
  free_scanargs(&scanned, argc);
  
  return(0);
}