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); }
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); }
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, ©Column, ©Columns, 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); }