/*************************************************************************\ * 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: sddscombinelogfiles.c,v $ Revision 1.9 2011/06/14 16:55:56 lemery Corrected an error in the minor edit of the usage message. Revision 1.8 2011/06/14 16:51:25 lemery Minor edit of usage message. Revision 1.7 2008/09/23 20:10:38 soliday Fixed a bug that caused problems when a file has zero rows. Revision 1.6 2008/09/22 21:22:05 soliday Fixed an variable initialization issue. Revision 1.5 2008/09/22 21:18:08 soliday Fixed problem that occured when multiple rows in the same file had the same Time. I didn't expect this to happen but it did. Revision 1.4 2008/09/19 21:06:52 soliday Sped up the code by 35 percent by avoiding calls to FindMatchingKeyGroup if it is fairly certain that the time values matchup throughout the files. It does this by checking that they have the same number of rows and that the time values are equal for the first few and last few rows. Revision 1.3 2008/09/18 20:18:26 soliday Modified to use new SDDS_GetColumnInFloats and SDDS_SetColumnFromFloats procedures to reduce the memory required when dealing with doubles instead of floats. Revision 1.2 2008/09/16 20:07:45 soliday Added units to the Time column. Revision 1.1 2008/09/15 21:34:42 soliday This tool is used to combine multiple log files in the one PV per file format into one larger file with all the PVs. Only the timestamps that exist for all the PVs are kept. * */ #include "mdb.h" #include "scan.h" #include "SDDS.h" #define SET_PIPE 0 #define SET_OVERWRITE 1 #define N_OPTIONS 2 static char *option[N_OPTIONS] = { "pipe", "overwrite" }; char *USAGE="sddscombinelogfiles [] []\n\ [-pipe=[output]] [-overwrite]\n\n\ This program is used to combine data logger output files that are in\n\ the one-PV-per-file format.\n"; int main(int argc, char **argv) { SDDS_DATASET SDDS_input; SDDS_DATASET SDDS_output; SCANNED_ARG *s_arg; KEYED_EQUIVALENT **keyGroup=NULL; long keyGroups=0; char **inputfile=NULL; int inputfiles=0; char *outputfile=NULL; int i_arg, i, j, n, m, r, row, s, z; unsigned long pipeFlags=0; int overwrite=0; char **columnname; int32_t columnnames; int caerrorsIndex; int timeIndex; int dataIndex; double **timeValues=NULL; float **dataValues=NULL; short **flag=NULL; int32_t *rows=NULL; char **dataNames=NULL; char **uniqueDataName=NULL; int uniqueDataNames=0; int page=0; int pages; int found; double *outputTimeValues=NULL; float **outputDataValues=NULL; int allocated_rows=0; int **array=NULL; int *arrayCount; SDDS_RegisterProgramName(argv[0]); argc = scanargs(&s_arg, argc, argv); if (argc<3) { fprintf(stderr, "%s", USAGE); return(1); } for (i_arg=1; i_arg1) { if (!(pipeFlags&USE_STDOUT)) { outputfile = inputfile[--inputfiles]; if (fexists(outputfile) && !overwrite) { fprintf(stderr, "output file exists already--give -overWrite option to force replacement\n"); return(1); } } } else if (inputfiles==1) { if (pipeFlags&USE_STDOUT && outputfile) { fprintf(stderr, "too many filenames given with -pipe=output\n"); return(1); } } else { fprintf(stderr, "too few filenames given\n"); return(1); } for (i=0 ; i 3) || (columnnames < 2)) { fprintf(stderr, "unexpected columns in data logger file\n"); return(1); } if (columnnames == 2) { if (strcmp("Time", columnname[0]) == 0) { timeIndex = 0; dataIndex = 1; } else if (strcmp("Time", columnname[1]) == 0) { timeIndex = 1; dataIndex = 0; } else { fprintf(stderr, "Time column is missing in data logger file\n"); return(1); } } if (columnnames == 3) { if (strcmp("CAerrors", columnname[0]) == 0) { caerrorsIndex = 0; if (strcmp("Time", columnname[1]) == 0) { timeIndex = 1; dataIndex = 2; } else if (strcmp("Time", columnname[2]) == 0) { timeIndex = 2; dataIndex = 1; } else { fprintf(stderr, "Time column is missing in data logger file\n"); return(1); } } else if (strcmp("CAerrors", columnname[1]) == 0) { caerrorsIndex = 1; if (strcmp("Time", columnname[0]) == 0) { timeIndex = 0; dataIndex = 2; } else if (strcmp("Time", columnname[2]) == 0) { timeIndex = 2; dataIndex = 0; } else { fprintf(stderr, "Time column is missing in data logger file\n"); return(1); } } else if (strcmp("CAerrors", columnname[2]) == 0) { caerrorsIndex = 2; if (strcmp("Time", columnname[0]) == 0) { timeIndex = 0; dataIndex = 1; } else if (strcmp("Time", columnname[1]) == 0) { timeIndex = 1; dataIndex = 0; } else { fprintf(stderr, "Time column is missing in data logger file\n"); return(1); } } else { fprintf(stderr, "CAerrors column is missing in data logger file\n"); return(1); } } while (SDDS_ReadTable(&SDDS_input)>0) { timeValues = realloc(timeValues, sizeof(*timeValues)*(page+1)); dataValues = realloc(dataValues, sizeof(*dataValues)*(page+1)); dataNames = realloc(dataNames, sizeof(*dataNames)*(page+1)); rows = realloc(rows, sizeof(*rows)*(page+1)); SDDS_CopyString(&dataNames[page], columnname[dataIndex]); rows[page] = SDDS_RowCount(&SDDS_input); if (rows[page] > 0) { timeValues[page] = SDDS_GetColumnInDoubles(&SDDS_input, "Time"); if (timeValues[page] == NULL) { SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors); return(1); } dataValues[page] = SDDS_GetColumnInFloats(&SDDS_input, columnname[dataIndex]); if (dataValues[page] == NULL) { SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors); return(1); } } else { timeValues[page]=NULL; dataValues[page]=NULL; } page++; } for (j=0; j 10)) { if ((timeValues[array[0][i]][0] == timeValues[array[n][m]][0]) && (timeValues[array[0][i]][1] == timeValues[array[n][m]][1]) && (timeValues[array[0][i]][rows[array[0][i]]-2] == timeValues[array[n][m]][rows[array[n][m]]-2]) && (timeValues[array[0][i]][rows[array[0][i]]-1] == timeValues[array[n][m]][rows[array[n][m]]-1])) { /*Assume the entire page matches because it has the same number or rows and the first few and last few lines match*/ for (r=0; r=0) { flag[array[0][i]][row] += 1; flag[array[n][m]][r] = 1; } } } } for (j=0; jequivalent); free(keyGroup[j]); } free(keyGroup); } z = uniqueDataNames-1; for (n=0; n= z) { allocated_rows++; } } } outputTimeValues = malloc(sizeof(*outputTimeValues)*allocated_rows); for (i=0; i= z) { outputTimeValues[s] = timeValues[array[0][i]][j]; outputDataValues[0][s] = dataValues[array[0][i]][j]; s++; } } } if (s==0) { fprintf(stderr, "No matching Time rows in input files\n"); return(1); } keyGroup = MakeSortedKeyGroups(&keyGroups, SDDS_DOUBLE, outputTimeValues, s); for (n=1; n=0) { outputDataValues[n][row] = dataValues[array[n][m]][r]; } } } } } for (i=0; iequivalent) free(keyGroup[j]->equivalent); if (keyGroup[j]) free(keyGroup[j]); } for (page=0; page 0) { free(inputfile); } free_scanargs(&s_arg,argc); return(0); }