Пример #1
0
void computeHigherOrderChromaticities(LINE_LIST *beamline, double *clorb, RUN *run,
				      long concatOrder, double deltaStep, long deltaPoints,
                                      long quickMode)
{
#define MAX_NDELTA_VALUES 101   /* must be at least 5 */
  double trace[2][MAX_NDELTA_VALUES], delta[MAX_NDELTA_VALUES];
  double eta[6];
  double coef[MAX_NDELTA_VALUES], sCoef[MAX_NDELTA_VALUES], chi;
  long i, p;
  double c1;
  VMATRIX M1, M0, *Mp;

  if (deltaPoints>MAX_NDELTA_VALUES)
    bombElegant("too many points for higher-order chromaticity", NULL);
  if (deltaPoints<5)
    deltaPoints = 5;
  if (!(beamline->matrix))
    bombElegant("no matrix for beamline (computeHigherOrderChromaticities)", NULL);
  
  beamline->chrom2[0] = beamline->chrom2[1] = 0;
  beamline->chrom3[0] = beamline->chrom3[1] = 0;
  initialize_matrices(&M0, 1);
  initialize_matrices(&M1, concatOrder);
  
  eta[0] = beamline->twiss0->etax;
  eta[1] = beamline->twiss0->etapx;
  eta[2] = beamline->twiss0->etay;
  eta[3] = beamline->twiss0->etapy;
  eta[4] = 0;
  eta[5] = 1;
  for (p=0; p<deltaPoints; p++) {
    delta[p] = (p-(deltaPoints/2+1))*deltaStep;
    for (i=0; i<6; i++) {
      M0.C[i] = (clorb?clorb[i]:0)+delta[p]*eta[i] +
	(i<4? sqr(delta[p])*beamline->eta2[i] + pow3(delta[p])*beamline->eta3[i] : 0);
      M0.R[i][i] = 1;
    }
    if (quickMode)
      concat_matrices(Mp=&M1, beamline->matrix, &M0, 0);
    else
      Mp = append_full_matrix(beamline->elem_twiss, run, &M0, concatOrder);
    for (i=0; i<2; i++)
      /* Tr[0,1][p] is the trace for x,y plane for point p */
      trace[i][p] = Mp->R[2*i][2*i] + Mp->R[2*i+1][2*i+1];
    if (!quickMode) {
      free_matrices(Mp);
      free(Mp);
      Mp = NULL;
    }
  }
  for (i=0; i<2; i++) {
    lsfn(delta, trace[i], NULL, deltaPoints, (long)(MIN(deltaPoints-2,5)), 
         coef, sCoef, &chi, NULL);
    c1 = -coef[1]/(4*PI*sin(PIx2*beamline->tune[i]));
    beamline->chrom2[i] = (
                           2*coef[2]
                           + 8*sqr(PI)*sqr(c1)*cos(PIx2*beamline->tune[i])
                           )/(-4*PI*sin(PIx2*beamline->tune[i]));
    if (quickMode)
      beamline->chrom3[i] = 0;
    else
      beamline->chrom3[i] = (
                             6*coef[3] 
                             - 16*pow3(PI*c1)*sin(PIx2*beamline->tune[i]) 
                             + 24*sqr(PI)*c1*beamline->chrom2[i]*cos(PIx2*beamline->tune[i])
                             )/(-4*PI*sin(PIx2*beamline->tune[i]));
  }
  free_matrices(&M0);
  free_matrices(&M1);
}
Пример #2
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);
}
Пример #3
0
int main(int argc, char **argv)
{
  SCANNED_ARG *scanned;
  SDDS_TABLE inputPage, *copiedPage, outputPage;
  long copiedPages;
  char *inputfile, *outputfile;
  char **column, **excludeColumn=NULL;
  int32_t columns;
  long excludeColumns;
  char *indParameterName;
  char **copyColumn;
  int32_t copyColumns;
  long verbose;
  long slopeErrors;
  long iArg,i;
  double *indVar;
  char *indVarUnits;
  char **intColumn,**slopeColumn,**slopeSigmaColumn;
  char *Units,*slopeUnits;
  double *depVar;
  long order;
  double *coef,*coefsigma,*weight,*diff,chi;
  long iCol,iRow,iPage;
  long rows;
  double *slope, slope2, slopeAve, slopeSigma;
  unsigned long pipeFlags, majorOrderFlag;
  long tmpfile_used, noWarnings;
  long generateIndex;
  short columnMajorOrder=-1;

  copiedPage = NULL;
  slopeSigmaColumn = NULL;
  slopeUnits = Units = indVarUnits = NULL;
  rows = 0;
  slope = NULL;
  slope2 = 0;
  coef = coefsigma = weight = diff = slope = NULL;
  
  argc = scanargs(&scanned, argc, argv);
  if (argc == 1) 
    bomb(NULL, USAGE);

  inputfile = outputfile = NULL;
  columns = excludeColumns = 0;
  column = excludeColumn = NULL;
  indParameterName = NULL;
  verbose = 0;
  slopeErrors = 0;
  pipeFlags = 0;
  tmpfile_used=0;
  noWarnings=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_MAJOR_ORDER:
        majorOrderFlag=0;
        scanned[iArg].n_items--;
        if (scanned[iArg].n_items>0 &&
            (!scanItemList(&majorOrderFlag, scanned[iArg].list+1, &scanned[iArg].n_items, 0,
                           "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
                           "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER,
                           NULL)))
          SDDS_Bomb("invalid -majorOrder syntax/values");
        if (majorOrderFlag&SDDS_COLUMN_MAJOR_ORDER)
          columnMajorOrder=1;
        else if (majorOrderFlag&SDDS_ROW_MAJOR_ORDER)
          columnMajorOrder=0;
        break;
      case CLO_INDEPENDENT_PARAMETER:   
        if (!(indParameterName = 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_PIPE:
        if (!processPipeOption(scanned[iArg].list+1, scanned[iArg].n_items-1, &pipeFlags))
          SDDS_Bomb("invalid -pipe syntax");
        break;
      case CLO_SLOPE_ERRORS:
        slopeErrors = 1;
        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");
    }
  }

  processFilenames("sddsvslopes", &inputfile, &outputfile, pipeFlags, noWarnings, &tmpfile_used);

  if (!indParameterName)
    SDDS_Bomb("independentVariable not given");

  if (!excludeColumns) {
    excludeColumn = defaultExcludedColumn;
    excludeColumns = DEFAULT_EXCLUDED_COLUMNS;
  }
  
  if (verbose)
    fprintf(stderr,"Reading file %s.\n",inputfile);
  SDDS_InitializeInput(&inputPage, inputfile);
  copiedPages = 0;
  while (SDDS_ReadTable(&inputPage)>0) {
    if (!copiedPages) {
      copiedPage = (SDDS_TABLE*)malloc(sizeof(SDDS_TABLE));
      rows = SDDS_CountRowsOfInterest(&inputPage);
    }
    else {
      copiedPage = (SDDS_TABLE*)realloc(copiedPage, (copiedPages+1)*sizeof(SDDS_TABLE));
    }
    if (!SDDS_InitializeCopy(&copiedPage[copiedPages], &inputPage, NULL, "m"))
      SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors|SDDS_VERBOSE_PrintErrors);
    if (!SDDS_CopyTable(&copiedPage[copiedPages], &inputPage))
      SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors|SDDS_VERBOSE_PrintErrors);
    copiedPages++;
  }
  if (copiedPages<2) {
    fprintf(stderr,"Insufficient data (i.e. number of data pages) to fit a straight line.\n");
    exit(1);
  }
  switch(SDDS_CheckColumn(&inputPage, "Rootname", NULL, SDDS_STRING, NULL)) {
  case SDDS_CHECK_WRONGUNITS:
  case SDDS_CHECK_OKAY:
    break;
  default:
    fprintf(stderr,"Something wrong with column %s.\n", "Rootname");
    exit(1);
  }
  switch(SDDS_CheckColumn(&inputPage, "Index", NULL, SDDS_LONG, NULL)) {
  case SDDS_CHECK_WRONGUNITS:
  case SDDS_CHECK_OKAY:
    generateIndex = 0;
    break;
  case SDDS_CHECK_NONEXISTENT:
    generateIndex = 1;
    break;
  default:
    fprintf(stderr,"Something wrong with column %s.\n", "Rootname");
    exit(1);
  }
  /****************\
   * make array of independent variable
   \**************/
  indVar = (double*)malloc(sizeof(*indVar)*copiedPages);
  switch(SDDS_CheckParameter(&inputPage, indParameterName, NULL, SDDS_DOUBLE, NULL)) {
  case SDDS_CHECK_WRONGUNITS:
  case SDDS_CHECK_OKAY:
    break;
  default:
    fprintf(stderr,"Something wrong with parameter %s.\n", indParameterName);
    exit(1);
  }
  for (iPage = 0; iPage<copiedPages; iPage++) {
    if (!SDDS_GetParameter(&copiedPage[iPage],indParameterName,&indVar[iPage])) 
      SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors|SDDS_VERBOSE_PrintErrors);
  }
  if (!SDDS_GetParameterInformation(&inputPage, "units", &indVarUnits, SDDS_GET_BY_NAME, indParameterName))
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  if (!indVarUnits) {
    indVarUnits = (char *) malloc(sizeof(*indVarUnits));
    indVarUnits[0] = 0;
  }
  /************************************\
   * 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
   \*************************************/
  intColumn = (char**)malloc((sizeof(char*)*columns));
  slopeColumn = (char**)malloc((sizeof(char*)*columns)); 
  if (slopeErrors)
    slopeSigmaColumn = (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 (slopeErrors) {
      slopeSigmaColumn[i] = (char*)malloc((sizeof(char)*(strlen(column[i])+strlen("SlopeSigma")+1)));
      strcat(strcpy(slopeSigmaColumn[i], column[i]), "SlopeSigma");
    }
  }
  /************************************\
   * Write layout for output file
   \*************************************/
  if (verbose)
    fprintf(stderr,"Opening file %s.\n",outputfile);
  if(!SDDS_InitializeOutput(&outputPage,SDDS_BINARY,1,
                            "lsf of sddsvexperiment",NULL,outputfile) ||
     0>SDDS_DefineParameter(&outputPage, "InputFile", "InputFile", NULL,
                            "InputFile", NULL, SDDS_STRING, 0) ||
     0>SDDS_DefineParameter(&outputPage, "IndependentVariable", "IndependentVariable", NULL,
                            "IndependentVariable", NULL, SDDS_STRING, 0) ||
     (0>SDDS_DefineColumn(&outputPage,"Index",NULL,NULL,"Rootname index",NULL,SDDS_LONG,0))||
     (0>SDDS_DefineColumn(&outputPage,"Rootname",NULL,NULL,NULL,NULL,SDDS_STRING,0)))
    SDDS_PrintErrors(stderr,SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
   if (columnMajorOrder!=-1)
     outputPage.layout.data_mode.column_major = columnMajorOrder;
   else
     outputPage.layout.data_mode.column_major = inputPage.layout.data_mode.column_major;
  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 (slopeErrors) {
      if (0>SDDS_DefineColumn(&outputPage, slopeSigmaColumn[iCol], NULL, slopeUnits, NULL, NULL, SDDS_DOUBLE,0))
        SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    }
    free(slopeUnits);
  }
  if(!SDDS_WriteLayout(&outputPage) || 
     !SDDS_StartTable(&outputPage,rows) ||
     !SDDS_SetParameters(&outputPage, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE,
                         "InputFile",inputfile?inputfile:"pipe",NULL)  ||
     !SDDS_SetParameters(&outputPage, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE, 0,
                         "IndependentVariable", indParameterName, NULL) )
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  
  /************************************\
   * Copy columns to output file (usually columns Index and Rootname)
   \*************************************/
  copyColumns = DEFAULT_COPY_COLUMNS;
  copyColumn = defaultCopyColumn;
  if (!set_multicolumn_flags(&inputPage, &copyColumn, &copyColumns, NULL, 0)) {
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    exit(1);
  }
  if(!SDDS_CopyColumns(&outputPage, &inputPage))
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  depVar = (double*)malloc(sizeof(*depVar)*copiedPages);
  weight = (double*)malloc(sizeof(*weight)*copiedPages);
  diff = (double*)malloc(sizeof(*weight)*copiedPages);
  order=1;
  coef = (double*)malloc(sizeof(*coef)*(order+1));
  coefsigma = (double*)malloc(sizeof(*coefsigma)*(order+1));
  if(slopeErrors)
    slope = (double*)malloc(sizeof(*slope)*copiedPages);
  for (iCol=0; iCol<columns; iCol++) {
    for (iPage=0; iPage<copiedPages; iPage++) 
      weight[iPage]=1;
    if (verbose)
      fprintf(stderr,"Doing column %s.\n", column[iCol]);
    for (iRow=0; iRow<rows; iRow++) {
      for (iPage=0; iPage<copiedPages; iPage++) {
        if (!SDDS_GetValue(&copiedPage[iPage], column[iCol], iRow, &depVar[iPage]))                     
          SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors|SDDS_VERBOSE_PrintErrors);
      }
      if (!(lsfn(indVar, depVar, weight, copiedPages, order, coef, coefsigma, &chi, diff))){
        fprintf(stderr,"Problem with call to lsfn\n.");
        exit(1);
      }
      if (generateIndex) {
        if (!SDDS_SetRowValues(&outputPage, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE, iRow,
                               "Index",iRow,
                               intColumn[iCol], coef[0],
                               slopeColumn[iCol], coef[1], NULL))
          SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
      }
      else {
        if (!SDDS_SetRowValues(&outputPage, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE, iRow,
                               intColumn[iCol], coef[0],
                               slopeColumn[iCol], coef[1], NULL))
          SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
      }
      if(slopeErrors){
        /* recalculate the slope with a subset of points  */
        slopeAve= slope2 = 0;
        for (iPage=0; iPage<copiedPages; iPage++) {
          weight[iPage] = 1e10;
          if(iPage)
            weight[iPage-1] = 1; 
          if (!(lsfn(indVar, depVar, weight, copiedPages, order, coef, coefsigma, &chi, diff))){
            fprintf(stderr,"Problem with call to lsfn\n.");
            exit(1);
          }
          slope[iPage] = coef[1];
          slopeAve += slope[iPage];
          slope2 += sqr(slope[iPage]);
        }
        slopeSigma = sqrt(slope2/copiedPages - sqr(slopeAve/copiedPages));
        if (!SDDS_SetRowValues(&outputPage, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE, iRow,
                               slopeSigmaColumn[iCol], slopeSigma, NULL))
          SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
      }
    }
  }
 
  if( !SDDS_WriteTable(&outputPage)|| SDDS_Terminate(&inputPage) )
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  for (iPage=0; iPage<copiedPages; iPage++) {
    if( !SDDS_Terminate(&copiedPage[iPage]) )
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  }
  
  if( SDDS_Terminate(&outputPage) )
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  if (tmpfile_used && !replaceFileAndBackUp(inputfile, outputfile)) 
    exit(1);
  SDDS_FreeStringArray(column, columns);
  free(column);
  SDDS_FreeStringArray(intColumn, columns);
  SDDS_FreeStringArray(slopeColumn, columns); 
  free(intColumn);
  free(slopeColumn);
  if (slopeErrors) {
    SDDS_FreeStringArray(slopeSigmaColumn, columns);
    free(slopeSigmaColumn);
  }
  
  free(copiedPage);
  free(indVar);
  free(depVar);
  if (weight)
    free(weight);
  if (diff)
    free(diff);
  if (slope)
    free(slope);
  if (coef) free(coef);
  if (coefsigma) free(coefsigma);
  if (Units) free(Units);
  if (indVarUnits) free(indVarUnits);
  
  free_scanargs(&scanned, argc);
  
  return(0);
}