/*************************************************************************\ * Copyright (c) 2002 The University of Chicago, as Operator of Argonne * National Laboratory. * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. * This file is distributed subject to a Software License Agreement found * in the file LICENSE that is included with this distribution. \*************************************************************************/ /* $Log: sddsinterpset.c,v $ Revision 1.14 2006/12/14 22:21:59 soliday Updated a bunch of programs because SDDS_SaveLayout is now called by SDDS_WriteLayout and it is no longer required to be called directly. Also the AutoCheckMode is turned off by default now so I removed calls to SDDS_SetAutoCheckMode that would attempt to turn it off. It is now up to the programmer to turn it on in new programs until debugging is completed and then remove the call to SDDS_SetAutoCheckMode. Revision 1.13 2005/11/07 21:48:10 soliday Updated to remove Linux compiler warnings. Revision 1.12 2005/11/04 22:46:14 soliday Updated code to be compiled by a 64 bit processor. Revision 1.11 2005/08/23 19:25:21 jiaox fixed the bug that causes the column definition failure. Revision 1.9 2003/11/14 19:00:13 shang added "setting the functionOf column with given atValue" back, which was omitted in previous version. Revision 1.8 2003/11/11 15:39:16 shang it now processes multiply-page input data and accepts multiply data options. Revision 1.7 2003/10/07 16:32:11 shang removed interpolate() and the definition of OUTRANGE_CONTROL structure, since they have been moved to libary Revision 1.6 2003/09/02 19:16:05 soliday Cleaned up code for Linux. Revision 1.5 2002/10/23 02:49:33 shang added SDDS_CopyParameter so that the output file has the parameters from the input Revision 1.4 2002/08/14 17:12:48 soliday Added Open License Revision 1.3 2002/04/25 15:53:21 soliday Added support for WIN32 Revision 1.2 2002/03/22 22:59:54 soliday Modifed free_scanargs argument. Revision 1.1 2002/02/13 22:59:45 shang first version */ #include "mdb.h" #include "SDDS.h" #include "scan.h" #include "SDDSutils.h" #include #define CLO_ORDER 0 #define CLO_PIPE 1 #define CLO_BELOWRANGE 2 #define CLO_ABOVERANGE 3 #define CLO_DATA 4 #define CLO_VERBOSE 5 #define CLO_OPTIONS 6 char *option[CLO_OPTIONS] = { "order","pipe","belowrange","aboverange","data","verbose", }; static char *USAGE1 = "sddsinterpset [] [] [-pipe=[input][,output]]\n\ [-order=] [-verbose] \n\ [-data=fileColumn=,interpolate=,functionof=, \n\ column= | atValue=] \n\ [-belowRange={value=|skip|saturate|extrapolate|wrap}[,{abort|warn}]]\n\ [-aboveRange={value=|skip|saturate|extrapolate|wrap}[,{abort|warn}]]\n\ -verbose -- print out messages. \n\ -pipe -- The standard SDDS Toolkit pipe option. \n\ -data option: \n\ -fileColumn -- Gives the name of a column in that contains the \n\ names of files with tables of data. \n\ -interpolate-- Gives the name of a column that must exist in all the \n\ files named in fileColumn. This column will exist in \n\ the output file. \n\ -functionOf -- Gives the name of a column that must exist in all the \n\ files named in fileColumn. The 'interpolate' column \n\ is viewed as a function of this column: I(F). \n\ -column -- Gives the name of a column in . The primary output \n\ is I(C). \n"; static char *USAGE2 = " -atValue -- Gives a number at which to perform the interpolations. \n\ -order -- the order of the polynomials to use for interpolation. \n\ The default is 1, indicating linear interpolation. \n\ -belowRange \n\ -aboveRange -- They have the same options, which specify the behavior \n\ in the event that an interpolation point is, respectively, \n\ below or above the range of the independent data. If such an \n\ out-of-range point occurs, the default behavior is to assign \n\ the value at the nearest endpoint of the data; this is identical \n\ to specifying saturate. One may specify use of a specific value \n\ with value=value. skip specifies that offending points should be \n\ discarded. extrapolate specifies extrapolation beyond the limits \n\ of the data. wrap specifies that the data should be treated as \n\ periodic. abort specifies that the program should terminate. warn \n\ requests warnings for out-of-bounds points. \n\ sddsinterpset is used to perform multiple interpolations. The file provided in each row of \n\ the input file is the source of an interpolation table. \n\n\ Program by Hairong Shang. (This is version 1, Feb. 2002)\n"; #define AT_COLUMN 0x00000001 #define AT_VALUE 0x00000002 typedef struct { char *fileColumn,*interpCol, *funcOfCol,*atCol; char **file; /*an name array of files which contain the data */ long files; double atValue; /*it should not appear if atCol is given */ double *colValue; /*the value of atCol in the input*/ unsigned long hasdata, flags; } DATA_CONTROL; long processDataControls(char *input, DATA_CONTROL **data_control, long dataControls,long verbose, SDDS_DATASET *SDDSout, char *output,long *rows); long checkMonotonicity(double *indepValue, long rows); void freedatacontrol(DATA_CONTROL *data_control, long dataControls); int main(int argc, char **argv) { int i_arg; char *input,*output, **interpCol,**funcOf; long i,j,order,dataControls,verbose, outputs,valid_option,monotonicity,datarows; SCANNED_ARG *s_arg; OUTRANGE_CONTROL aboveRange, belowRange; DATA_CONTROL *data_control; unsigned long pipeFlags, dummyFlags, interpCode; SDDS_DATASET SDDSdata, SDDSout, SDDSin; double *indepValue, *depenValue,**out_depenValue, atValue=0; int32_t **rowFlag; long valid_data=0,index,row,pages; int32_t *rows; SDDS_RegisterProgramName(argv[0]); argc = scanargs(&s_arg, argc, argv); if (argc<3) { fprintf(stderr, "%s%s", USAGE1, USAGE2); exit(1); } data_control=NULL; input=output=NULL; interpCol=funcOf=NULL; dataControls=verbose=outputs=0; order=1; pipeFlags=dummyFlags=0; indepValue=depenValue=NULL; out_depenValue=NULL; rows=NULL; aboveRange.flags = belowRange.flags = OUTRANGE_SATURATE; valid_option=1; rowFlag=NULL; for (i_arg=1;i_arg1) SDDS_Bomb("incompatible keywords given for -aboveRange"); if (i!=1) aboveRange.flags |= OUTRANGE_SATURATE; break; case CLO_VERBOSE: verbose=1; break; case CLO_BELOWRANGE: if ((s_arg[i_arg].n_items-=1)<1 || !scanItemList(&belowRange.flags, s_arg[i_arg].list+1, &s_arg[i_arg].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_DATA: if ((s_arg[i_arg].n_items -=1)<4) SDDS_Bomb("invalid -data syntax"); data_control=SDDS_Realloc(data_control,sizeof(*data_control)*(dataControls+1)); data_control[dataControls].fileColumn=data_control[dataControls].interpCol= data_control[dataControls].funcOfCol=data_control[dataControls].atCol=NULL; data_control[dataControls].file=NULL; data_control[dataControls].files=0; data_control[dataControls].hasdata=0; data_control[dataControls].colValue=NULL; data_control[dataControls].flags=0; if (!scanItemList(&data_control[dataControls].flags,s_arg[i_arg].list+1,&s_arg[i_arg].n_items,0, "fileColumn",SDDS_STRING,&(data_control[dataControls].fileColumn),1,0, "interpolate",SDDS_STRING,&(data_control[dataControls].interpCol),1,0, "functionof",SDDS_STRING,&(data_control[dataControls].funcOfCol),1,0, "column",SDDS_STRING,&(data_control[dataControls].atCol),1,AT_COLUMN, "atValue",SDDS_DOUBLE,&(data_control[dataControls].atValue),1,AT_VALUE, NULL) || !data_control[dataControls].fileColumn || !data_control[dataControls].interpCol || !data_control[dataControls].funcOfCol) SDDS_Bomb("Invalid -data syntax"); if (!(data_control[dataControls].flags&AT_COLUMN) && !(data_control[dataControls].flags&AT_VALUE)) SDDS_Bomb("Invali -data syntax: either column or atValue option should be given."); if ( (dummyFlags&AT_COLUMN) && (dummyFlags&AT_VALUE)) SDDS_Bomb("Invali -data syntax: column and atValue options are not compatible."); valid_option=1; if (dataControls) { if (match_string(data_control[dataControls].funcOfCol,funcOf,dataControls,EXACT_MATCH)>0) { fprintf(stderr,"Multiple independent columns provided!"); exit(1); } if (match_string(data_control[dataControls].interpCol,interpCol,dataControls,EXACT_MATCH)>0) { fprintf(stderr,"Warning:Interpolate column %s has been used.\n",data_control[dataControls].interpCol); valid_option=0; } } if (valid_option) { interpCol=SDDS_Realloc(interpCol,sizeof(*interpCol)*(dataControls+1)); funcOf=SDDS_Realloc(funcOf,sizeof(*funcOf)*(dataControls+1)); interpCol[dataControls]=data_control[dataControls].interpCol; funcOf[dataControls]=data_control[dataControls].funcOfCol; dataControls++; } break; default: fprintf(stderr, "error: unknown/ambiguous option: %s\n", s_arg[i_arg].list[0]); exit(1); break; } } else { if (!input) input=s_arg[i_arg].list[0]; else if (!output) output=s_arg[i_arg].list[0]; else SDDS_Bomb("too many filenams seen"); } } processFilenames("sddsinterpset", &input, &output, pipeFlags, 0, NULL); /*if (!processDataControls(input,&data_control,dataControls,verbose,&SDDSout,output,&rows)) { fprintf(stderr,"No valid -data options given for processing data.\n"); exit(1); } */ if (!SDDS_InitializeInput(&SDDSin, input)) SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); for (i=0;i0) { rows=SDDS_Realloc(rows,sizeof(*rows)*(pages+1)); out_depenValue=SDDS_Realloc(out_depenValue,sizeof(*out_depenValue)*(pages+1)); rowFlag=SDDS_Realloc(rowFlag,sizeof(*rowFlag)*(pages+1)); if (!(rows[pages]=SDDS_CountRowsOfInterest(&SDDSin))) { fprintf(stderr,"No data found in input file %s.\n",input); exit(1); } rowFlag[pages]=(int32_t*)malloc(sizeof(**rowFlag)*rows[pages]); out_depenValue[pages]=(double*)malloc(sizeof(**out_depenValue)*rows[pages]); for (i=0;iindepValue[0]) { while (--rows>0) if (indepValue[rows]0) if (indepValue[rows]>indepValue[rows-1]) return 0; return -1; } } void freedatacontrol(DATA_CONTROL *data_control, long dataControls) { long i; for (i=0;i