SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
col2sdds.c
Go to the documentation of this file.
1/**
2 * @file col2sdds.c
3 * @brief Converts M. Borland's older `column` format files to SDDS files.
4 *
5 * @details
6 * This program reads a specified input file containing M. Borland's older `column` format files,
7 * a precursor to SDDS, and converts them into SDDS format. It allows optional modifications
8 * to auxiliary and column names for compatibility with SDDS standards by removing `$` characters.
9 *
10 * The implementation includes robust handling of data types, arrays, and various validation
11 * mechanisms to ensure the integrity of the converted SDDS files. It leverages the SDDS library
12 * for file operations and supports both ASCII and binary SDDS formats.
13 *
14 * @section Usage
15 * ```
16 * col2sdds <inputfile> <outputfile> [-fixMplNames]
17 * ```
18 *
19 * @section Options
20 * | Optional | Description |
21 * |------------------------------|-----------------------------------------------------------|
22 * | `-fixMplNames` | Removes `$` characters from names for SDDS compatibility.|
23 *
24 * @copyright
25 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
26 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
27 *
28 * @license
29 * This file is distributed under the terms of the Software License Agreement
30 * found in the file LICENSE included with this distribution.
31 *
32 * @author
33 * R. Soliday
34 */
35
36#include "mdb.h"
37#include "SDDS.h"
38#include "scan.h"
39#include "column.h"
40
41/* Enumeration for option types */
42enum option_type {
43 SET_FIXMPLNAMES,
44 N_OPTIONS
45};
46
47char *option[N_OPTIONS] = {
48 "fixMplNames"
49};
50
51char *USAGE =
52 "Usage: col2sdds <inputfile> <outputfile> [-fixMplNames]\n"
53 "Options:\n"
54 " -fixMplNames Remove '$' characters from auxiliary and column names.\n"
55 "Link date: " __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION "\n";
56
57int main(int argc, char **argv) {
58 SCANNED_ARG *scanned;
59 char *input = NULL, *output = NULL;
60 int fixMplNames = 0;
61 long i_arg, i, j, k, len;
62 MC_TABLE mcTable;
63 SDDS_TABLE SDDS_table;
64 char buffer[100];
65 char **aux_symbol = NULL;
66 char **symbol = NULL;
67
69 argc = scanargs(&scanned, argc, argv);
70 if (argc < 3) {
71 fprintf(stderr, "%s", USAGE);
72 return EXIT_FAILURE;
73 }
74
75 for (i_arg = 1; i_arg < argc; i_arg++) {
76 if (scanned[i_arg].arg_type == OPTION) {
77 switch (match_string(scanned[i_arg].list[0], option, N_OPTIONS, 0)) {
78 case SET_FIXMPLNAMES:
79 fixMplNames = 1;
80 break;
81 default:
82 fprintf(stderr, "Invalid option: %s\n%s", scanned[i_arg].list[0], USAGE);
83 return EXIT_FAILURE;
84 }
85 } else {
86 if (!input)
87 input = scanned[i_arg].list[0];
88 else if (!output)
89 output = scanned[i_arg].list[0];
90 else {
91 fprintf(stderr, "Too many file names provided.\n%s", USAGE);
92 return EXIT_FAILURE;
93 }
94 }
95 }
96
97 if (!input) {
98 fprintf(stderr, "Error: Input file not specified.\n%s", USAGE);
99 return EXIT_FAILURE;
100 }
101
102 if (!output) {
103 fprintf(stderr, "Error: Output file not specified.\n%s", USAGE);
104 return EXIT_FAILURE;
105 }
106
107 if (get_mc_table(&mcTable, input, GMCT_WARNINGS) == 0) {
108 fprintf(stderr, "Unable to open input file: %s\n", input);
109 return EXIT_FAILURE;
110 }
111
112 if (fixMplNames) {
113 aux_symbol = malloc(sizeof(char *) * mcTable.n_auxiliaries);
114 if (!aux_symbol) {
115 fprintf(stderr, "Memory allocation failed for auxiliary symbols.\n");
116 return EXIT_FAILURE;
117 }
118
119 for (i = 0; i < mcTable.n_auxiliaries; i++) {
120 len = strlen(mcTable.aux_name[i]);
121 aux_symbol[i] = malloc(sizeof(char) * (len + 1));
122 if (!aux_symbol[i]) {
123 fprintf(stderr, "Memory allocation failed for auxiliary symbol %ld.\n", i);
124 return EXIT_FAILURE;
125 }
126 k = 0;
127 for (j = 0; j < len; j++) {
128 if (mcTable.aux_name[i][j] != '$') {
129 buffer[k++] = mcTable.aux_name[i][j];
130 }
131 }
132 buffer[k] = '\0';
133 strcpy(aux_symbol[i], buffer);
134 }
135
136 symbol = malloc(sizeof(char *) * mcTable.n_cols);
137 if (!symbol) {
138 fprintf(stderr, "Memory allocation failed for column symbols.\n");
139 return EXIT_FAILURE;
140 }
141
142 for (i = 0; i < mcTable.n_cols; i++) {
143 len = strlen(mcTable.name[i]);
144 symbol[i] = malloc(sizeof(char) * (len + 1));
145 if (!symbol[i]) {
146 fprintf(stderr, "Memory allocation failed for column symbol %ld.\n", i);
147 return EXIT_FAILURE;
148 }
149 k = 0;
150 for (j = 0; j < len; j++) {
151 if (mcTable.name[i][j] != '$') {
152 buffer[k++] = mcTable.name[i][j];
153 }
154 }
155 buffer[k] = '\0';
156 strcpy(symbol[i], buffer);
157 }
158 }
159
160 if (SDDS_InitializeOutput(&SDDS_table, SDDS_BINARY, 1, mcTable.title, mcTable.label, output) != 1) {
161 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
162 return EXIT_FAILURE;
163 }
164
165 for (i = 0; i < mcTable.n_auxiliaries; i++) {
166 const char *paramName = fixMplNames ? aux_symbol[i] : mcTable.aux_name[i];
167 const char *paramDesc = mcTable.aux_description[i];
168 const char *paramUnit = mcTable.aux_unit[i];
169 double *paramValue = &(mcTable.aux_value[i]);
170
171 if (SDDS_DefineParameter1(&SDDS_table, paramName, fixMplNames ? mcTable.aux_name[i] : NULL, paramUnit, paramDesc, NULL, SDDS_DOUBLE, paramValue) == -1) {
172 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
173 if (!fixMplNames) {
174 fprintf(stderr, "Try rerunning with the -fixMplNames option.\n");
175 }
176 return EXIT_FAILURE;
177 }
178 }
179
180 for (i = 0; i < mcTable.n_cols; i++) {
181 const char *colName = fixMplNames ? symbol[i] : mcTable.name[i];
182 const char *colDesc = mcTable.description[i];
183 const char *colUnit = mcTable.unit[i];
184 const char *colFormat = mcTable.format[i];
185
186 if (SDDS_DefineColumn(&SDDS_table, colName, fixMplNames ? mcTable.name[i] : NULL, colUnit, colDesc, colFormat, SDDS_DOUBLE, 0) == -1) {
187 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
188 if (!fixMplNames) {
189 fprintf(stderr, "Try rerunning with the -fixMplNames option.\n");
190 }
191 return EXIT_FAILURE;
192 }
193 }
194
195 if (SDDS_SaveLayout(&SDDS_table) != 1) {
196 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
197 return EXIT_FAILURE;
198 }
199
200 if (SDDS_WriteLayout(&SDDS_table) != 1) {
201 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
202 return EXIT_FAILURE;
203 }
204
205 if (SDDS_StartTable(&SDDS_table, mcTable.n_rows) != 1) {
206 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
207 return EXIT_FAILURE;
208 }
209
210 for (i = 0; i < mcTable.n_cols; i++) {
211 if (SDDS_SetColumnFromDoubles(&SDDS_table, SDDS_SET_BY_INDEX, mcTable.value[i], mcTable.n_rows, i) != 1) {
212 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
213 return EXIT_FAILURE;
214 }
215 }
216
217 if (SDDS_WriteTable(&SDDS_table) != 1) {
218 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
219 return EXIT_FAILURE;
220 }
221
222 if (SDDS_Terminate(&SDDS_table) != 1) {
223 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
224 return EXIT_FAILURE;
225 }
226
227 return EXIT_SUCCESS;
228}
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_SaveLayout(SDDS_DATASET *SDDS_dataset)
Definition SDDS_copy.c:615
int32_t SDDS_SetColumnFromDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode, double *data, int64_t rows,...)
Sets the values for a single data column using double-precision floating-point numbers.
int32_t SDDS_Terminate(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_DefineParameter1(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, void *fixed_value)
Defines a data parameter with a fixed numerical value.
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.
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
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37
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.
long get_mc_table(MC_TABLE *table, char *file, long flags)
Reads a multi-column table from a file.
Definition mcTable.c:42
int scanargs(SCANNED_ARG **scanned, int argc, char **argv)
Definition scanargs.c:36