/*************************************************************************\ * 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. \*************************************************************************/ /* program: sddscollect * purpose: collect data from many columns into a group of new columns * * Michael Borland, 1996 $Log: sddscollect.c,v $ Revision 1.21 2006/12/14 22:21:57 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.20 2006/10/19 17:55:39 soliday Updated to work with linux-x86_64. Revision 1.19 2005/11/04 22:46:12 soliday Updated code to be compiled by a 64 bit processor. Revision 1.18 2004/07/30 22:05:55 borland Added Units column to output to give the units of each row of values. Revision 1.17 2003/12/15 21:13:26 soliday Fixed issue when the exclude option is not used. Revision 1.16 2003/12/12 18:39:19 soliday Added the exlude option which can be used with the match option. Revision 1.15 2002/08/14 17:12:41 soliday Added Open License Revision 1.14 2001/01/10 19:35:33 soliday Standardized usage message. Revision 1.13 2000/06/20 13:09:59 borland Now correctly sets units when there is a mismatch of units in the input, even if -nowarning option is given. Revision 1.12 2000/03/31 23:13:45 emery Corrected the error printout for groups with different numbers. Revision 1.11 1999/07/26 19:44:57 borland Fixed bug introduced in last revision. Affected prefix mode collection. Revision 1.10 1999/07/09 13:24:53 borland Fixed bug that occurs when the column names don't sort into the same order as the rootnames. Fix works only for suffix-mode. Need more work to fix for prefix and edit modes. Revision 1.9 1999/07/08 18:37:14 borland Added -nowarnings option. Revision 1.8 1999/05/25 19:06:09 soliday Removed compiler warning on linux. Revision 1.7 1998/12/16 21:24:12 borland Brought syntax up-to-date with latest version of SDDS_TransferAllParameters. Revision 1.6 1998/06/24 19:22:29 borland Now accepts -collect=match option in addition to prefix and suffix. This permits collecting columns with more general names. * Revision 1.5 1996/02/14 01:05:10 borland * Changed over from scan_item_list() to scanItemList(). * * Revision 1.4 1996/01/31 15:26:52 borland * Fixed problem in sorting of column names; added diagnostic output for case * of a name mismatch. * * Revision 1.3 1996/01/17 23:29:16 borland * Replaced SDDS_GetColumn() call with SDDS_GetInternalColumn() call in a few * places in hopes of improving performance. * * Revision 1.2 1996/01/17 15:39:03 borland * Fixed problem that occured when input column name was shorter than part * name. Added statement to set OriginalPage parameter value. * * Revision 1.1 1996/01/17 05:56:13 borland * First version of the program. * * */ #include "mdb.h" #include "SDDS.h" #include "SDDSutils.h" #include "scan.h" #include static char *USAGE = "sddscollect [-pipe=[input][,output]] \n\ [] [] [-nowarnings]\n\ -collect={suffix=|prefix=|match=}[,column=][,editCommand=][,exclude=]... \n\n\ -pipe The standard SDDS toolkit pipe option.\n\ -collect Specifies a suffix or prefix to use in selecting columns from\n\ the input that will be collected into a new column in\n\ the output. Optionally specifies the name of the new\n\ column, which defaults to the suffix or prefix.\n\n\ Program by Michael Borland. (This is version 2, June 1998.)" ; #define CLO_COLLECT 0 #define CLO_PIPE 1 #define CLO_NOWARNINGS 2 #define CLO_OPTIONS 3 static char *option[CLO_OPTIONS] = { "collect", "pipe", "nowarnings", }; typedef struct { char *part, *newColumn, *match, *editCommand, *exclude; char **oldColumn; void **data; long oldColumns, targetIndex, size; unsigned long flags; } COLLECTION; typedef struct { char *name; void *data; long size, targetIndex; } NEW_PARAMETER; #define COLLECTION_SUFFIX 0x0001U #define COLLECTION_PREFIX 0x0002U #define COLLECTION_COLUMN 0x0004U #define COLLECTION_MATCH 0x0008U #define COLLECTION_EDIT 0x0010U #define COLLECTION_EXCLUDE 0x0020U long InitializeOutput(SDDS_DATASET *SDDSout, char *output, SDDS_DATASET *SDDSin, COLLECTION *collection, long collections, NEW_PARAMETER **newParameter, long *newParameters, char ***rootname, char ***units, long warnings); void CollectAndWriteData(SDDS_DATASET *SDDSout, COLLECTION *collection, long collections, NEW_PARAMETER *newParameter, long newParameters, char **rootname, char **units, long rootnames, long inputRow, long origPage); void GetAndOrganizeData(SDDS_DATASET *SDDSin, COLLECTION *collection, long collections, NEW_PARAMETER *newParameter, long newParameters); char **ConfirmMatchingColumns(COLLECTION *collection, long collections, SDDS_DATASET *SDDSin, SDDS_DATASET *SDDSout, long *rootnames, char ***units, long warnings); int main(int argc, char **argv) { long iArg, ic; SDDS_DATASET SDDSin, SDDSout; SCANNED_ARG *scanned; unsigned long pipeFlags, flags; COLLECTION *collection; NEW_PARAMETER *newParameter; char **rootname, **units; long collections, newParameters, rootnames, rows, row, code; char *input, *output; long warnings; SDDS_RegisterProgramName(argv[0]); argc = scanargs(&scanned, argc, argv); if (argc==1) bomb(NULL, USAGE); input = output = NULL; collection = NULL; collections = 0; pipeFlags = 0; warnings = 1; for (iArg=1; iArg0) { if (!SDDS_StartPage(&SDDSout, rootnames) || !SDDS_CopyParameters(&SDDSout, &SDDSin) || !SDDS_CopyArrays(&SDDSout, &SDDSin)) SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); if ((rows = SDDS_CountRowsOfInterest(&SDDSin))>0) { GetAndOrganizeData(&SDDSin, collection, collections, newParameter, newParameters); for (row=0; row=inputLength[ii]) continue; if (matchString) { if (wild_match(inputColumn[ii], matchString)) { if ((excludeString == NULL) || (!wild_match(inputColumn[ii], excludeString))) { if (!(collection[ic].oldColumn = SDDS_Realloc(collection[ic].oldColumn, sizeof(*collection[ic].oldColumn)*(collection[ic].oldColumns+1)))) { SDDS_Bomb("Memory allocation failure"); } collection[ic].oldColumn[collection[ic].oldColumns] = inputColumn[ii]; inputUsed[ii] = 1; inputsUsed++; collection[ic].oldColumns++; } } } else if (collection[ic].flags&COLLECTION_PREFIX) { if (strncmp(partString, inputColumn[ii], partLength)==0) { if (!(collection[ic].oldColumn = SDDS_Realloc(collection[ic].oldColumn, sizeof(*collection[ic].oldColumn)*(collection[ic].oldColumns+1)))) { SDDS_Bomb("Memory allocation failure"); } collection[ic].oldColumn[collection[ic].oldColumns] = inputColumn[ii]; inputUsed[ii] = 1; inputsUsed++; collection[ic].oldColumns++; } } else { if (strcmp(partString, inputColumn[ii]+inputLength[ii]-partLength)==0) { if (!(collection[ic].oldColumn = SDDS_Realloc(collection[ic].oldColumn, sizeof(*collection[ic].oldColumn)*(collection[ic].oldColumns+1)))) { SDDS_Bomb("Memory allocation failure"); } collection[ic].oldColumn[collection[ic].oldColumns] = inputColumn[ii]; inputUsed[ii] = 1; inputsUsed++; collection[ic].oldColumns++; } } } if (!collection[ic].oldColumns && warnings) { fprintf(stderr, "Warning (sddscollect): No columns in input for %s %s\n", collection[ic].flags&COLLECTION_PREFIX?"prefix":"suffix", collection[ic].part); } if (!(collection[ic].data = (void**)calloc(collection[ic].oldColumns, sizeof(*collection[ic].data)))) SDDS_Bomb("Memory allocation failure"); } if ((*newParameters=inputColumns-inputsUsed)) { *newParameter = (NEW_PARAMETER*)malloc(sizeof(**newParameter)*(*newParameters)); for (ii=ip=0; ii