SDDSlib
Loading...
Searching...
No Matches
sddscollect.c File Reference

Collects data from multiple columns into new grouped columns based on specified criteria. More...

#include "mdb.h"
#include "SDDS.h"
#include "SDDSutils.h"
#include "scan.h"
#include <ctype.h>

Go to the source code of this file.

Classes

struct  COLLECTION
 
struct  NEW_PARAMETER
 

Macros

#define COLLECTION_SUFFIX   0x0001U
 
#define COLLECTION_PREFIX   0x0002U
 
#define COLLECTION_COLUMN   0x0004U
 
#define COLLECTION_MATCH   0x0008U
 
#define COLLECTION_EDIT   0x0010U
 
#define COLLECTION_EXCLUDE   0x0020U
 

Enumerations

enum  option_type {
  CLO_COLLECT , CLO_PIPE , CLO_NOWARNINGS , CLO_MAJOR_ORDER ,
  N_OPTIONS
}
 

Functions

long InitializeOutput (SDDS_DATASET *SDDSout, char *output, SDDS_DATASET *SDDSin, COLLECTION *collection, long collections, NEW_PARAMETER **newParameter, int *newParameters, char ***rootname, char ***units, long warnings)
 
void CollectAndWriteData (SDDS_DATASET *SDDSout, COLLECTION *collection, long collections, NEW_PARAMETER *newParameter, int newParameters, char **rootname, char **units, long rootnames, int64_t inputRow, long origPage)
 
void GetAndOrganizeData (SDDS_DATASET *SDDSin, COLLECTION *collection, long collections, NEW_PARAMETER *newParameter, int 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)
 

Variables

static char * USAGE
 
static char * option [N_OPTIONS]
 

Detailed Description

Collects data from multiple columns into new grouped columns based on specified criteria.

The program processes SDDS (Self Describing Data Sets) files, allowing users to collect data from various input columns and organize them into new output columns with specified suffixes, prefixes, or matching patterns. It supports options for pipeline processing, controlling warnings, and setting the major order of the output data.

@usage sddscollect [options] [<input>] [<output>]

@options -pipe=[input][,output] Use the standard SDDS toolkit pipe option for input and output.

-collect={suffix=<string>|prefix=<string>|match=<string>}[,column=<newName>][,editCommand=<string>][,exclude=<wildcard>]... Collects columns based on the specified suffix, prefix, or matching pattern.

  • suffix: Selects columns ending with the given string.
  • prefix: Selects columns starting with the given string.
  • match: Selects columns matching the given wildcard pattern.
  • column: (Optional) Specifies the name of the new column. Defaults to the suffix or prefix.
  • editCommand: (Optional) Specifies a command to edit the column names.
  • exclude: (Optional) Excludes columns matching the given wildcard pattern.

-nowarnings Suppresses warning messages.

-majorOrder=row|column Specifies the major order of the output file. Can be either row-major or column-major.

License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
M. Borland, R. Soliday, L. Emery

Definition in file sddscollect.c.

Macro Definition Documentation

◆ COLLECTION_COLUMN

#define COLLECTION_COLUMN   0x0004U

Definition at line 100 of file sddscollect.c.

◆ COLLECTION_EDIT

#define COLLECTION_EDIT   0x0010U

Definition at line 102 of file sddscollect.c.

◆ COLLECTION_EXCLUDE

#define COLLECTION_EXCLUDE   0x0020U

Definition at line 103 of file sddscollect.c.

◆ COLLECTION_MATCH

#define COLLECTION_MATCH   0x0008U

Definition at line 101 of file sddscollect.c.

◆ COLLECTION_PREFIX

#define COLLECTION_PREFIX   0x0002U

Definition at line 99 of file sddscollect.c.

◆ COLLECTION_SUFFIX

#define COLLECTION_SUFFIX   0x0001U

Definition at line 98 of file sddscollect.c.

Enumeration Type Documentation

◆ option_type

enum option_type

Definition at line 67 of file sddscollect.c.

67 {
68 CLO_COLLECT,
69 CLO_PIPE,
70 CLO_NOWARNINGS,
71 CLO_MAJOR_ORDER,
72 N_OPTIONS
73};

Function Documentation

◆ CollectAndWriteData()

void CollectAndWriteData ( SDDS_DATASET * SDDSout,
COLLECTION * collection,
long collections,
NEW_PARAMETER * newParameter,
int newParameters,
char ** rootname,
char ** units,
long rootnames,
int64_t inputRow,
long origPage )

Definition at line 249 of file sddscollect.c.

251 {
252 long ic, ip, ir;
253 if (rootnames) {
254 if (!SDDS_SetColumn(SDDSout, SDDS_PASS_BY_VALUE | SDDS_SET_BY_NAME, rootname, rootnames, "Rootname")) {
255 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
256 }
257 if (!SDDS_SetColumn(SDDSout, SDDS_PASS_BY_VALUE | SDDS_SET_BY_NAME, units, rootnames, "Units")) {
258 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
259 }
260 for (ic = 0; ic < collections; ic++) {
261 for (ir = 0; ir < rootnames; ir++) {
262 if (!SDDS_SetRowValues(SDDSout, SDDS_PASS_BY_REFERENCE | SDDS_SET_BY_INDEX,
263 ir, collection[ic].targetIndex,
264 ((char *)(collection[ic].data[ir])) + inputRow * collection[ic].size, -1)) {
265 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
266 }
267 }
268 }
269 }
270
271 for (ip = 0; ip < newParameters; ip++) {
272 if (!SDDS_SetParameters(SDDSout, SDDS_PASS_BY_REFERENCE | SDDS_SET_BY_NAME,
273 newParameter[ip].name,
274 ((char *)(newParameter[ip].data) + inputRow * newParameter[ip].size), NULL)) {
275 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
276 }
277 }
278 if (!SDDS_SetParameters(SDDSout, SDDS_PASS_BY_VALUE | SDDS_SET_BY_NAME,
279 "OriginalPage", origPage, NULL) ||
280 !SDDS_WritePage(SDDSout)) {
281 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
282 }
283}
int32_t SDDS_SetRowValues(SDDS_DATASET *SDDS_dataset, int32_t mode, int64_t row,...)
int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
int32_t SDDS_SetColumn(SDDS_DATASET *SDDS_dataset, int32_t mode, void *data, int64_t rows,...)
Sets the values for one data column in the current data table of an SDDS dataset.
int32_t SDDS_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
Definition SDDS_utils.c:432

◆ ConfirmMatchingColumns()

char ** ConfirmMatchingColumns ( COLLECTION * collection,
long collections,
SDDS_DATASET * SDDSin,
SDDS_DATASET * SDDSout,
long * rootnames,
char *** units,
long warnings )

Definition at line 430 of file sddscollect.c.

431 {
432 long ic, ip, ii, partLength;
433 char **rootname, editBuffer[1024];
434 char saveChar;
435
436 partLength = 0;
437 rootname = NULL;
438 *units = NULL;
439 *rootnames = 0;
440 if (!collections)
441 return NULL;
442 for (ic = 0; ic < collections; ic++) {
443 if (!collection[ic].oldColumns)
444 continue;
445 if (collection[ic].part)
446 partLength = strlen(collection[ic].part);
447 if (collection[ic].part && collection[ic].flags & COLLECTION_SUFFIX) {
448 /* sort collection according to truncated string */
449 saveChar = collection[ic].part[0];
450 for (ip = 0; ip < collection[ic].oldColumns; ip++)
451 collection[ic].oldColumn[ip][strlen(collection[ic].oldColumn[ip]) - partLength] = 0;
452 qsort(collection[ic].oldColumn, collection[ic].oldColumns, sizeof(*collection[ic].oldColumn), string_cmpasc);
453 /* now restore the strings (column names) to original form */
454 for (ip = 0; ip < collection[ic].oldColumns; ip++)
455 collection[ic].oldColumn[ip][strlen(collection[ic].oldColumn[ip])] = saveChar;
456 } else {
457 qsort(collection[ic].oldColumn, collection[ic].oldColumns, sizeof(*collection[ic].oldColumn), string_cmpasc);
458 }
459 if (rootname)
460 continue;
461 *rootnames = collection[ic].oldColumns;
462 if (!(rootname = (char **)malloc(sizeof(*rootname) * (*rootnames)))) {
463 SDDS_Bomb("Memory allocation failure");
464 }
465 if (!(*units = (char **)malloc(sizeof(**units) * (*rootnames)))) {
466 SDDS_Bomb("Memory allocation failure");
467 }
468 for (ip = 0; ip < (*rootnames); ip++) {
469 if (SDDS_GetColumnInformation(SDDSin, "units", *units + ip, SDDS_GET_BY_NAME, collection[ic].oldColumn[ip]) != SDDS_STRING) {
470 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
471 }
472 if (collection[ic].flags & COLLECTION_EDIT) {
473 strcpy(editBuffer, collection[ic].oldColumn[ip]);
474 if (!edit_string(editBuffer, collection[ic].editCommand)) {
475 SDDS_Bomb("Problem editing column name.");
476 }
477 SDDS_CopyString(rootname + ip, editBuffer);
478 } else if (collection[ic].flags & COLLECTION_PREFIX) {
479 SDDS_CopyString(rootname + ip, collection[ic].oldColumn[ip] + partLength);
480 } else {
481 SDDS_CopyString(rootname + ip, collection[ic].oldColumn[ip]);
482 rootname[ip][strlen(rootname[ip]) - partLength] = 0;
483 }
484 }
485 }
486 if (!(*rootnames))
487 return NULL;
488
489 for (ic = 0; ic < collections; ic++) {
490 if (!collection[ic].oldColumns)
491 continue;
492 if (collection[ic].oldColumns != (*rootnames)) {
493 fprintf(stderr, "Error (sddscollect): Groups have different numbers of members\n");
494 for (ip = 0; ip < collections; ip++) {
495 fprintf(stderr, "%ld in %s\n", collection[ip].oldColumns,
496 collection[ip].part ? collection[ip].part : collection[ip].match);
497 }
498 exit(EXIT_FAILURE);
499 }
500 if (collection[ic].flags & COLLECTION_MATCH)
501 continue;
502 for (ip = 0; ip < collection[ic].oldColumns; ip++)
503 if (strstr(collection[ic].oldColumn[ip], rootname[ip]) == NULL) {
504 fprintf(stderr, "Error (sddscollect): Mismatch with rootname %s for column %s in group %s\n",
505 rootname[ip], collection[ic].oldColumn[ip],
506 collection[ic].part ? collection[ic].part : collection[ic].match);
507 /* about to bomb here, so it's okay to reuse these indices */
508 for (ic = 0; ic < collections; ic++) {
509 fprintf(stderr, "Group %s (%ld):\n",
510 collection[ic].part ? collection[ic].part : collection[ic].match, ic);
511 for (ip = 0; ip < collection[ic].oldColumns; ip++)
512 fprintf(stderr, " old column[%ld] = %s\n", ip, collection[ic].oldColumn[ip]);
513 }
514 exit(EXIT_FAILURE);
515 }
516 }
517
518 for (ic = 0; ic < collections; ic++) {
519 char *units;
520 int32_t type = 0;
521 long unitsMismatch;
522 if (!collection[ic].oldColumns)
523 continue;
524 if (!SDDS_TransferColumnDefinition(SDDSout, SDDSin, collection[ic].oldColumn[0], collection[ic].newColumn) ||
525 (collection[ic].targetIndex = SDDS_GetColumnIndex(SDDSout, collection[ic].newColumn)) < 0 ||
526 SDDS_GetColumnInformation(SDDSout, "units", &units, SDDS_GET_BY_NAME, collection[ic].newColumn) != SDDS_STRING ||
527 SDDS_GetColumnInformation(SDDSout, "type", &type, SDDS_GET_BY_NAME, collection[ic].newColumn) != SDDS_LONG) {
528 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
529 }
530 collection[ic].size = SDDS_GetTypeSize(type);
531 unitsMismatch = 0;
532 for (ii = 1; ii < collection[ic].oldColumns; ii++) {
533 if (SDDS_CheckColumn(SDDSin, collection[ic].oldColumn[ii], NULL, type, stderr) == SDDS_CHECK_WRONGTYPE) {
534 fprintf(stderr, "Error (sddscollect): Inconsistent data types for suffix/prefix/match %s\n",
535 collection[ic].part ? collection[ic].part : collection[ic].match);
536 exit(EXIT_FAILURE);
537 }
538 if (SDDS_CheckColumn(SDDSin, collection[ic].oldColumn[ii], units, type, NULL) == SDDS_CHECK_WRONGUNITS)
539 unitsMismatch = 1;
540 }
541 if (unitsMismatch) {
542 if (warnings)
543 fprintf(stderr, "Warning (sddscollect): Inconsistent units for suffix/prefix %s\n", collection[ic].part);
544 if (!SDDS_ChangeColumnInformation(SDDSout, "units", "?", SDDS_BY_NAME, collection[ic].newColumn)) {
545 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
546 }
547 }
548 }
549
550 return rootname;
551}
int32_t SDDS_ChangeColumnInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode,...)
Modifies a specific field in a column definition within the SDDS dataset.
Definition SDDS_info.c:364
int32_t SDDS_GetColumnInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode,...)
Retrieves information about a specified column in the SDDS dataset.
Definition SDDS_info.c:41
int32_t SDDS_TransferColumnDefinition(SDDS_DATASET *target, SDDS_DATASET *source, char *name, char *newName)
Transfers a column definition from a source dataset to a target dataset.
int32_t SDDS_GetColumnIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named column in the SDDS dataset.
int32_t SDDS_CheckColumn(SDDS_DATASET *SDDS_dataset, char *name, char *units, int32_t type, FILE *fp_message)
Checks if a column exists in the SDDS dataset with the specified name, units, and type.
int32_t SDDS_GetTypeSize(int32_t type)
Retrieves the size in bytes of a specified SDDS data type.
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:342
int32_t SDDS_CopyString(char **target, const char *source)
Copies a source string to a target string with memory allocation.
Definition SDDS_utils.c:856
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
Definition SDDStypes.h:61
int string_cmpasc(const void *a, const void *b)
Compare two strings in ascending order.

◆ GetAndOrganizeData()

void GetAndOrganizeData ( SDDS_DATASET * SDDSin,
COLLECTION * collection,
long collections,
NEW_PARAMETER * newParameter,
int newParameters )

Definition at line 285 of file sddscollect.c.

286 {
287 long ic, ip, ii;
288 for (ic = 0; ic < collections; ic++) {
289 for (ii = 0; ii < collection[ic].oldColumns; ii++) {
290 if (!(collection[ic].data[ii] = SDDS_GetInternalColumn(SDDSin, collection[ic].oldColumn[ii]))) {
291 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
292 }
293 }
294 }
295 for (ip = 0; ip < newParameters; ip++) {
296 if (!(newParameter[ip].data = SDDS_GetColumn(SDDSin, newParameter[ip].name))) {
297 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
298 }
299 }
300}
void * SDDS_GetColumn(SDDS_DATASET *SDDS_dataset, char *column_name)
Retrieves a copy of the data for a specified column, including only rows marked as "of interest".
void * SDDS_GetInternalColumn(SDDS_DATASET *SDDS_dataset, char *column_name)
Retrieves an internal pointer to the data of a specified column, including all rows.

◆ InitializeOutput()

long InitializeOutput ( SDDS_DATASET * SDDSout,
char * output,
SDDS_DATASET * SDDSin,
COLLECTION * collection,
long collections,
NEW_PARAMETER ** newParameter,
int * newParameters,
char *** rootname,
char *** units,
long warnings )

Definition at line 302 of file sddscollect.c.

304 {
305 char **inputColumn, *partString;
306 long partLength, *inputLength;
307 int32_t inputColumns;
308 short *inputUsed;
309 long ic, ii, ip, inputsUsed, rootnames;
310 char *matchString, *excludeString;
311
312 partLength = 0;
313 inputLength = NULL;
314
315 if (!SDDS_InitializeOutput(SDDSout, SDDS_BINARY, 0, NULL, "sddscollect output", output) ||
316 !SDDS_TransferAllParameterDefinitions(SDDSout, SDDSin, 0) ||
317 !SDDS_TransferAllArrayDefinitions(SDDSout, SDDSin, 0)) {
318 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
319 }
320
321 if (!(inputColumn = SDDS_GetColumnNames(SDDSin, &inputColumns)) || inputColumns == 0) {
322 SDDS_Bomb("No columns in input file");
323 }
324 if (!(inputUsed = (short *)calloc(inputColumns, sizeof(*inputUsed))) ||
325 !(inputLength = (long *)calloc(inputColumns, sizeof(*inputLength)))) {
326 SDDS_Bomb("Memory allocation failure");
327 }
328 for (ii = 0; ii < inputColumns; ii++)
329 inputLength[ii] = strlen(inputColumn[ii]);
330
331 inputsUsed = 0;
332 matchString = NULL;
333 excludeString = NULL;
334 for (ic = 0; ic < collections; ic++) {
335 if (!collection[ic].newColumn)
336 SDDS_CopyString(&collection[ic].newColumn, collection[ic].part);
337 if ((partString = collection[ic].part))
338 partLength = strlen(partString);
339 if (collection[ic].match) {
340 matchString = collection[ic].match;
341 partLength = -1;
342 }
343 if (collection[ic].exclude) {
344 excludeString = collection[ic].exclude;
345 }
346 collection[ic].oldColumn = NULL;
347 collection[ic].oldColumns = 0;
348 for (ii = 0; ii < inputColumns; ii++) {
349 if (inputUsed[ii])
350 continue;
351 if (partLength >= inputLength[ii])
352 continue;
353 if (matchString) {
354 if (wild_match(inputColumn[ii], matchString)) {
355 if ((excludeString == NULL) || (!wild_match(inputColumn[ii], excludeString))) {
356 if (!(collection[ic].oldColumn = SDDS_Realloc(collection[ic].oldColumn,
357 sizeof(*collection[ic].oldColumn) * (collection[ic].oldColumns + 1)))) {
358 SDDS_Bomb("Memory allocation failure");
359 }
360 collection[ic].oldColumn[collection[ic].oldColumns] = inputColumn[ii];
361 inputUsed[ii] = 1;
362 inputsUsed++;
363 collection[ic].oldColumns++;
364 }
365 }
366 } else if (collection[ic].flags & COLLECTION_PREFIX) {
367 if (strncmp(partString, inputColumn[ii], partLength) == 0) {
368 if (!(collection[ic].oldColumn = SDDS_Realloc(collection[ic].oldColumn,
369 sizeof(*collection[ic].oldColumn) * (collection[ic].oldColumns + 1)))) {
370 SDDS_Bomb("Memory allocation failure");
371 }
372 collection[ic].oldColumn[collection[ic].oldColumns] = inputColumn[ii];
373 inputUsed[ii] = 1;
374 inputsUsed++;
375 collection[ic].oldColumns++;
376 }
377 } else {
378 if (strcmp(partString, inputColumn[ii] + inputLength[ii] - partLength) == 0) {
379 if (!(collection[ic].oldColumn = SDDS_Realloc(collection[ic].oldColumn,
380 sizeof(*collection[ic].oldColumn) * (collection[ic].oldColumns + 1)))) {
381 SDDS_Bomb("Memory allocation failure");
382 }
383 collection[ic].oldColumn[collection[ic].oldColumns] = inputColumn[ii];
384 inputUsed[ii] = 1;
385 inputsUsed++;
386 collection[ic].oldColumns++;
387 }
388 }
389 }
390 if (!collection[ic].oldColumns && warnings) {
391 fprintf(stderr, "Warning (sddscollect): No columns in input for %s %s\n",
392 collection[ic].flags & COLLECTION_PREFIX ? "prefix" : "suffix", collection[ic].part);
393 }
394 if (!(collection[ic].data = (void **)calloc(collection[ic].oldColumns, sizeof(*collection[ic].data)))) {
395 SDDS_Bomb("Memory allocation failure");
396 }
397 }
398
399 if ((*newParameters = inputColumns - inputsUsed)) {
400 *newParameter = (NEW_PARAMETER *)malloc(sizeof(**newParameter) * (*newParameters));
401 for (ii = ip = 0; ii < inputColumns; ii++) {
402 if (inputUsed[ii])
403 continue;
404 if (!SDDS_CopyString(&(*newParameter)[ip].name, inputColumn[ii]) ||
405 !SDDS_DefineParameterLikeColumn(SDDSout, SDDSin, inputColumn[ii], NULL) ||
406 ((*newParameter)[ip].targetIndex = SDDS_GetParameterIndex(SDDSout, inputColumn[ii])) < 0) {
407 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
408 }
409 (*newParameter)[ip].size = SDDS_GetTypeSize(SDDS_GetParameterType(SDDSout, (*newParameter)[ip].targetIndex));
410 ip++;
411 }
412 }
413
414 *rootname = ConfirmMatchingColumns(collection, collections, SDDSin, SDDSout, &rootnames, units, warnings);
415
416 if (SDDS_DefineParameter(SDDSout, "OriginalPage", NULL, NULL, NULL, NULL, SDDS_LONG, NULL) < 0) {
417 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
418 }
419 if (rootnames &&
420 (SDDS_DefineColumn(SDDSout, "Rootname", NULL, NULL, NULL, NULL, SDDS_STRING, 0) < 0 ||
421 SDDS_DefineColumn(SDDSout, "Units", NULL, NULL, NULL, NULL, SDDS_STRING, 0) < 0)) {
422 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
423 }
424 if (!SDDS_WriteLayout(SDDSout)) {
425 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
426 }
427 return rootnames;
428}
int32_t SDDS_InitializeOutput(SDDS_DATASET *SDDS_dataset, int32_t data_mode, int32_t lines_per_row, const char *description, const char *contents, const char *filename)
Initializes the SDDS output dataset.
int32_t SDDS_DefineColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, int32_t field_length)
Defines a data column within the SDDS dataset.
int32_t SDDS_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
int32_t SDDS_DefineParameter(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, char *fixed_value)
Defines a data parameter with a fixed string value.
int32_t SDDS_TransferAllArrayDefinitions(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, uint32_t mode)
Transfers all array definitions from a source dataset to a target dataset.
int32_t SDDS_TransferAllParameterDefinitions(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, uint32_t mode)
Transfers all parameter definitions from a source dataset to a target dataset.
int32_t SDDS_DefineParameterLikeColumn(SDDS_DATASET *target, SDDS_DATASET *source, char *name, char *newName)
Defines a parameter in the target dataset based on a column definition from the source dataset.
int32_t SDDS_GetParameterType(SDDS_DATASET *SDDS_dataset, int32_t index)
Retrieves the data type of a parameter in the SDDS dataset by its index.
int32_t SDDS_GetParameterIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named parameter in the SDDS dataset.
char ** SDDS_GetColumnNames(SDDS_DATASET *SDDS_dataset, int32_t *number)
Retrieves the names of all columns in the SDDS dataset.
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
Definition SDDS_utils.c:677
int wild_match(char *string, char *template)
Determine whether one string is a wildcard match for another.
Definition wild_match.c:49

◆ main()

int main ( int argc,
char ** argv )

Definition at line 110 of file sddscollect.c.

110 {
111 long iArg, ic;
112 SDDS_DATASET SDDSin, SDDSout;
113 SCANNED_ARG *scanned;
114 unsigned long pipeFlags, flags, majorOrderFlag;
115 COLLECTION *collection;
116 NEW_PARAMETER *newParameter;
117 char **rootname, **units;
118 long collections, rootnames, code;
119 int newParameters = 0;
120 int64_t rows, row;
121 char *input, *output;
122 long warnings;
123 short columnMajorOrder = -1;
124
126
127 argc = scanargs(&scanned, argc, argv);
128 if (argc == 1) {
129 bomb(NULL, USAGE);
130 return EXIT_FAILURE;
131 }
132
133 input = output = NULL;
134 collection = NULL;
135 collections = 0;
136 pipeFlags = 0;
137 warnings = 1;
138
139 for (iArg = 1; iArg < argc; iArg++) {
140 if (scanned[iArg].arg_type == OPTION) {
141 /* process options here */
142 switch (match_string(scanned[iArg].list[0], option, N_OPTIONS, 0)) {
143 case CLO_MAJOR_ORDER:
144 majorOrderFlag = 0;
145 scanned[iArg].n_items--;
146 if (scanned[iArg].n_items > 0 &&
147 (!scanItemList(&majorOrderFlag, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
148 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
149 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL))) {
150 SDDS_Bomb("Invalid -majorOrder syntax/values");
151 }
152 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
153 columnMajorOrder = 1;
154 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
155 columnMajorOrder = 0;
156 break;
157 case CLO_COLLECT:
158 if (!(collection = SDDS_Realloc(collection, sizeof(*collection) * (collections + 1)))) {
159 SDDS_Bomb("Memory allocation failure");
160 }
161 ic = collections;
162 collection[ic].newColumn = collection[ic].part = collection[ic].match = collection[ic].editCommand = NULL;
163 collection[ic].exclude = NULL;
164 if (--scanned[iArg].n_items == 0 ||
165 !scanItemList(&flags, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
166 "suffix", SDDS_STRING, &collection[ic].part, 1, COLLECTION_SUFFIX,
167 "prefix", SDDS_STRING, &collection[ic].part, 1, COLLECTION_PREFIX,
168 "column", SDDS_STRING, &collection[ic].newColumn, 1, COLLECTION_COLUMN,
169 "match", SDDS_STRING, &collection[ic].match, 1, COLLECTION_MATCH,
170 "editcommand", SDDS_STRING, &collection[ic].editCommand, 1, COLLECTION_EDIT,
171 "exclude", SDDS_STRING, &collection[ic].exclude, 1, COLLECTION_EXCLUDE, NULL) ||
172 ((flags & COLLECTION_SUFFIX && flags & COLLECTION_PREFIX) ||
173 (flags & COLLECTION_SUFFIX && flags & COLLECTION_MATCH) ||
174 (flags & COLLECTION_PREFIX && flags & COLLECTION_MATCH))) {
175 SDDS_Bomb("Invalid -collect syntax");
176 }
177 if (flags & COLLECTION_MATCH &&
178 (!(flags & COLLECTION_EDIT) || !(flags & COLLECTION_COLUMN))) {
179 SDDS_Bomb("Invalid -collect syntax: must give editCommand and column with match");
180 }
181 collection[ic].flags = flags;
182 collections++;
183 break;
184 case CLO_PIPE:
185 if (!processPipeOption(scanned[iArg].list + 1, scanned[iArg].n_items - 1, &pipeFlags)) {
186 SDDS_Bomb("Invalid -pipe syntax");
187 }
188 break;
189 case CLO_NOWARNINGS:
190 warnings = 0;
191 break;
192 default:
193 fprintf(stderr, "Invalid option seen: %s\n", scanned[iArg].list[0]);
194 exit(EXIT_FAILURE);
195 break;
196 }
197 } else {
198 if (!input)
199 input = scanned[iArg].list[0];
200 else if (!output)
201 output = scanned[iArg].list[0];
202 else
203 SDDS_Bomb("Too many filenames");
204 }
205 }
206
207 if (!collections) {
208 SDDS_Bomb("At least one -collect option must be given");
209 }
210
211 processFilenames("sddscollect", &input, &output, pipeFlags, !warnings, NULL);
212
213 if (!SDDS_InitializeInput(&SDDSin, input)) {
214 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
215 }
216
217 rootnames = InitializeOutput(&SDDSout, output, &SDDSin, collection, collections,
218 &newParameter, &newParameters, &rootname, &units, warnings);
219 if (columnMajorOrder != -1)
220 SDDSout.layout.data_mode.column_major = columnMajorOrder;
221 else
222 SDDSout.layout.data_mode.column_major = SDDSin.layout.data_mode.column_major;
223
224 while ((code = SDDS_ReadPage(&SDDSin)) > 0) {
225 if (!SDDS_StartPage(&SDDSout, rootnames) ||
226 !SDDS_CopyParameters(&SDDSout, &SDDSin) ||
227 !SDDS_CopyArrays(&SDDSout, &SDDSin)) {
228 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
229 }
230 if ((rows = SDDS_CountRowsOfInterest(&SDDSin)) > 0) {
231 GetAndOrganizeData(&SDDSin, collection, collections, newParameter, newParameters);
232 for (row = 0; row < rows; row++) {
233 CollectAndWriteData(&SDDSout, collection, collections, newParameter, newParameters,
234 rootname, units, rootnames, row, code);
235 if (row != rows - 1 && !SDDS_StartPage(&SDDSout, rootnames)) {
236 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
237 }
238 }
239 } else if (!SDDS_WritePage(&SDDSout)) {
240 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
241 }
242 }
243 if (!code || !SDDS_Terminate(&SDDSout) || !SDDS_Terminate(&SDDSin)) {
244 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
245 }
246 return EXIT_SUCCESS;
247}
int32_t SDDS_CopyParameters(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:286
int32_t SDDS_CopyArrays(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:334
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
int64_t SDDS_CountRowsOfInterest(SDDS_DATASET *SDDS_dataset)
Counts the number of rows marked as "of interest" in the current data table.
int32_t SDDS_InitializeInput(SDDS_DATASET *SDDS_dataset, char *filename)
Definition SDDS_input.c:49
int32_t SDDS_Terminate(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_ReadPage(SDDS_DATASET *SDDS_dataset)
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:288
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
long match_string(char *string, char **option, long n_options, long mode)
Matches a given string against an array of option strings based on specified modes.
int scanargs(SCANNED_ARG **scanned, int argc, char **argv)
Definition scanargs.c:36
long processPipeOption(char **item, long items, unsigned long *flags)
Definition scanargs.c:356
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
Definition scanargs.c:390
long scanItemList(unsigned long *flags, char **item, long *items, unsigned long mode,...)
Scans a list of items and assigns values based on provided keywords and types.

Variable Documentation

◆ option

char* option[N_OPTIONS]
static
Initial value:
= {
"collect",
"pipe",
"nowarnings",
"majorOrder",
}

Definition at line 75 of file sddscollect.c.

75 {
76 "collect",
77 "pipe",
78 "nowarnings",
79 "majorOrder",
80};

◆ USAGE

char* USAGE
static
Initial value:
=
"Usage: sddscollect [options] [<input>] [<output>]\n\n"
"Options:\n"
" -pipe=[input][,output]\n"
" Use the standard SDDS toolkit pipe option for input and output.\n\n"
" -collect={suffix=<string>|prefix=<string>|match=<string>}\n"
" Collects columns based on the specified suffix, prefix, or matching pattern.\n"
" Additional parameters:\n"
" column=<newName> (Optional) Name of the new column. Defaults to suffix or prefix.\n"
" editCommand=<string> (Optional) Command to edit the column names.\n"
" exclude=<wildcard> (Optional) Exclude columns matching the wildcard pattern.\n\n"
" -nowarnings\n"
" Suppresses warning messages.\n\n"
" -majorOrder=row|column\n"
" Specifies the major order of the output file. Can be either row-major or column-major.\n\n"
"Program by Michael Borland. (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ")"

Definition at line 49 of file sddscollect.c.