SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
sddscollapse.c
Go to the documentation of this file.
1/**
2 * @file sddscollapse.c
3 * @brief Converts SDDS file parameters into columns.
4 *
5 * @details
6 * This program processes an input SDDS file to produce an output SDDS file
7 * where each data page contains parameters represented as columns of tabular data.
8 * The rows in the output file correspond to different pages in the input file.
9 * Original file columns are ignored in this transformation.
10 *
11 * The program dynamically manages memory to handle varying numbers of parameters
12 * and data pages efficiently.
13 *
14 * @section Usage
15 * ```
16 * sddscollapse [<SDDSinputfile>] [<SDDSoutputfile>]
17 * [-pipe=[input][,output]]
18 * [-majorOrder=row|column]
19 * [-noWarnings]
20 * ```
21 *
22 * @section Options
23 * | Option | Description |
24 * |-------------------|-----------------------------------------------------------------------------|
25 * | `-pipe` | Enables piping for input/output. |
26 * | `-majorOrder` | Specifies major order for the output file as row or column. |
27 * | `-noWarnings` | Suppresses warnings during execution. |
28 *
29 * @copyright
30 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
31 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
32 *
33 * @license
34 * This file is distributed under the terms of the Software License Agreement
35 * found in the file LICENSE included with this distribution.
36 *
37 * @author
38 * M. Borland, C. Saunders, R. Soliday, H. Shang
39 */
40
41#include "mdb.h"
42#include "scan.h"
43#include "SDDS.h"
44
45typedef enum {
46 SET_PIPE, /* Option for setting up input/output pipes. */
47 SET_NOWARNINGS, /* Option to suppress warnings during execution. */
48 SET_MAJOR_ORDER, /* Option to specify row or column major order. */
49 N_OPTIONS /* Total number of options. */
50} OptionType;
51
52/* Array of option names corresponding to OptionType. */
53char *option[N_OPTIONS] =
54 {
55 "pipe",
56 "nowarnings",
57 "majorOrder",
58 };
59
60/* Usage message displayed for help. */
61char *usage =
62 "sddscollapse [<SDDSinputfile>] [<SDDSoutputfile>]\n"
63 "[-pipe=[input][,output]] [-majorOrder=row|column] \n"
64 "[-noWarnings]\n\n"
65 "sddscollapse reads data pages from a SDDS file and writes a new SDDS file \n"
66 "containing a single data page. This data page contains the parameters, \n"
67 "with each parameter forming a column of the tabular data.\n\n"
68 "Program by Michael Borland. (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ")\n";
69
70#define ROW_INCREMENT 100 /* Number of rows to increment memory allocation for output. */
71
72int main(int argc, char **argv) {
73 SDDS_DATASET SDDS_input, SDDS_output;
74 char *inputfile = NULL, *outputfile = NULL, **column;
75 long i, i_arg;
76 long page_number, no_warnings = 0, set_page_number;
77 int64_t allocated_rows;
78 int32_t columns;
79 SCANNED_ARG *s_arg;
80 char s[SDDS_MAXLINE];
81 unsigned long pipe_flags = 0, major_order_flag;
82 long buffer[16];
83 short column_major_order = -1;
84
85 /* Register the program name for error messages. */
87
88 /* Parse command-line arguments. */
89 argc = scanargs(&s_arg, argc, argv);
90 if (argc < 2)
91 bomb(NULL, usage);
92
93 /* Process each argument. */
94 for (i_arg = 1; i_arg < argc; i_arg++) {
95 if (s_arg[i_arg].arg_type == OPTION) {
96 /* Match the option type and process accordingly. */
97 switch (match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
98 case SET_MAJOR_ORDER:
99 major_order_flag = 0;
100 s_arg[i_arg].n_items -= 1;
101 if (s_arg[i_arg].n_items > 0 &&
102 (!scanItemList(&major_order_flag, s_arg[i_arg].list + 1,
103 &s_arg[i_arg].n_items, 0,
104 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
105 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER,
106 NULL)))
107 SDDS_Bomb("invalid -majorOrder syntax/values");
108 if (major_order_flag & SDDS_COLUMN_MAJOR_ORDER)
109 column_major_order = 1;
110 else if (major_order_flag & SDDS_ROW_MAJOR_ORDER)
111 column_major_order = 0;
112 break;
113 case SET_PIPE:
114 if (!processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1,
115 &pipe_flags))
116 SDDS_Bomb("invalid -pipe syntax");
117 break;
118 case SET_NOWARNINGS:
119 no_warnings = 1;
120 break;
121 default:
122 fprintf(stderr, "error: unknown switch: %s\n", s_arg[i_arg].list[0]);
123 exit(1);
124 break;
125 }
126 } else {
127 /* Process input and output filenames. */
128 if (inputfile == NULL)
129 inputfile = s_arg[i_arg].list[0];
130 else if (outputfile == NULL)
131 outputfile = s_arg[i_arg].list[0];
132 else
133 SDDS_Bomb("too many filenames");
134 }
135 }
136
137 /* Validate and prepare filenames. */
138 processFilenames("sddscollapse", &inputfile, &outputfile, pipe_flags, no_warnings, NULL);
139
140 /* Initialize input SDDS file. */
141 if (!SDDS_InitializeInput(&SDDS_input, inputfile)) {
142 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
143 exit(1);
144 }
145
146 /* Initialize output SDDS file. */
147 if (!SDDS_InitializeOutput(&SDDS_output, SDDS_input.layout.data_mode.mode, 1,
148 NULL, NULL, outputfile)) {
149 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
150 exit(1);
151 }
152
153 /* Set major order for output. */
154 if (column_major_order != -1)
155 SDDS_output.layout.data_mode.column_major = column_major_order;
156 else
157 SDDS_output.layout.data_mode.column_major = SDDS_input.layout.data_mode.column_major;
158
159 /* Get parameter names from the input file. */
160 if (!(column = SDDS_GetParameterNames(&SDDS_input, &columns))) {
161 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
162 exit(1);
163 }
164
165 /* Define output columns corresponding to input parameters. */
166 for (i = 0; i < columns; i++) {
167 if (!SDDS_DefineColumnLikeParameter(&SDDS_output, &SDDS_input, column[i], NULL)) {
168 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
169 exit(1);
170 }
171 }
172
173 /* Define a PageNumber column if it doesn't exist. */
174 sprintf(s, "corresponding page number of %s for this row",
175 inputfile ? inputfile : "stdin");
176 if (SDDS_GetColumnIndex(&SDDS_output, "PageNumber") < 0) {
177 if (SDDS_DefineColumn(&SDDS_output, "PageNumber", NULL, NULL, s, NULL,
178 SDDS_LONG, 0) < 0) {
179 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
180 exit(1);
181 }
182 set_page_number = 1;
183 } else {
184 set_page_number = 0;
185 }
186
187 /* Start writing the layout and allocate rows for output. */
188 if (!SDDS_WriteLayout(&SDDS_output) ||
189 !SDDS_StartPage(&SDDS_output, allocated_rows = ROW_INCREMENT)) {
190 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
191 exit(1);
192 }
193
194 /* Process each data page in the input file. */
195 while ((page_number = SDDS_ReadPageSparse(&SDDS_input, 0, INT32_MAX - 1, 0, 0)) > 0) {
196 /* Expand memory if necessary. */
197 if (page_number > allocated_rows) {
198 if (!SDDS_LengthenTable(&SDDS_output, ROW_INCREMENT)) {
199 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
200 exit(1);
201 }
202 allocated_rows += ROW_INCREMENT;
203 }
204
205 /* Copy parameters into corresponding columns. */
206 for (i = 0; i < columns; i++) {
207 if (!SDDS_GetParameter(&SDDS_input, column[i], buffer)) {
208 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
209 exit(1);
210 }
211 if (!SDDS_SetRowValues(&SDDS_output,
212 SDDS_SET_BY_NAME | SDDS_PASS_BY_REFERENCE,
213 page_number - 1, column[i], buffer, NULL)) {
214 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
215 exit(1);
216 }
217 }
218
219 /* Set the PageNumber column if required. */
220 if (set_page_number &&
221 !SDDS_SetRowValues(&SDDS_output,
222 SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE,
223 page_number - 1, "PageNumber", page_number, NULL)) {
224 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
225 exit(1);
226 }
227 }
228
229 /* Free allocated memory for column names. */
230 for (i = 0; i < columns; i++)
231 free(column[i]);
232 free(column);
233
234 /* Finalize the output SDDS file. */
235 if (!SDDS_WritePage(&SDDS_output)) {
236 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
237 exit(1);
238 }
239 if (page_number == 0) {
240 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
241 exit(1);
242 }
243 if (!SDDS_Terminate(&SDDS_input) || !SDDS_Terminate(&SDDS_output)) {
244 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
245 exit(1);
246 }
247 return 0;
248}
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_LengthenTable(SDDS_DATASET *SDDS_dataset, int64_t n_additional_rows)
int32_t SDDS_SetRowValues(SDDS_DATASET *SDDS_dataset, int32_t mode, int64_t row,...)
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
void * SDDS_GetParameter(SDDS_DATASET *SDDS_dataset, char *parameter_name, void *memory)
Retrieves the value of a specified parameter from the current data table of a data set.
int32_t SDDS_ReadPageSparse(SDDS_DATASET *SDDS_dataset, uint32_t mode, int64_t sparse_interval, int64_t sparse_offset, int32_t sparse_statistics)
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_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_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
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_DefineColumnLikeParameter(SDDS_DATASET *target, SDDS_DATASET *source, char *name, char *newName)
Defines a column in the target dataset based on a parameter definition from the source dataset.
char ** SDDS_GetParameterNames(SDDS_DATASET *SDDS_dataset, int32_t *number)
Retrieves the names of all parameters in the SDDS dataset.
int32_t SDDS_GetColumnIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named column in the SDDS dataset.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
Definition SDDS_utils.c:432
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:288
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:342
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
Definition SDDStypes.h:61
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.