SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
sdds2math.c File Reference

Detailed Description

Converts SDDS files to a Mathematica-compatible format.

This program reads an SDDS (Self Describing Data Sets) file and converts it into a format that can be easily imported and used within Mathematica. The output is structured as a single Mathematica variable containing descriptions, column definitions, parameter definitions, array definitions, associations, and tables of data.

The output Mathematica variable has the following structure:

sdds = {description, coldef, pardef, arraydef, associates, tables}
  • description: Contains text and contents descriptions.
  • coldef: Defines columns with name, units, symbol, format, type, field length, and description.
  • pardef: Defines parameters with name, fixed value, units, symbol, type, and description.
  • arraydef: Defines arrays with name, units, symbol, format, type, field length, group, and description.
  • associates: Lists associations with SDDS flag, filename, path, contents, and description.
  • tables: Contains data tables with parameters and row data.

Usage

sdds2math [<SDDSfilename>] [<outputname>]
[-pipe[=in][,out]]
[-comments]
[-verbose]
[-format=<format-string>]

Options

Option Description
-pipe Standard SDDS Toolkit pipe option.
-comments Include helpful Mathematica comments in the output file.
-format Specify the format for double precision numbers (Default: g).
-verbose Display header information to the terminal similar to sddsquery.

Specific Requirements

  • If -format=<format-string> is used, <format-string> must be a valid printf-style format.
License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
K. Evans, C. Saunders, M. Borland, R. Soliday

Definition in file sdds2math.c.

#include <stdio.h>
#include <string.h>
#include <math.h>
#include "mdb.h"
#include "SDDS.h"
#include "scan.h"

Go to the source code of this file.

Functions

int main (int argc, char **argv)
 

Function Documentation

◆ main()

int main ( int argc,
char ** argv )

Definition at line 104 of file sdds2math.c.

104 {
105 FILE *outfile;
106 SDDS_TABLE SDDS_table;
107 SDDS_LAYOUT *layout;
108 COLUMN_DEFINITION *coldef;
109 PARAMETER_DEFINITION *pardef;
110 ARRAY_DEFINITION *arraydef;
111 char s[256];
112 char *input, *output;
113 long i, i_arg, ntable;
114 int64_t nrows, j;
115 SCANNED_ARG *s_arg;
116 char *text, *contents, *ss, *ptr, *iformat = FORMAT, *format, *rformat;
117 long verbose = 0, comments = 0, addquotes = 1;
118 short nexp;
119 double dd, ddred;
120 float ff, ffred;
121 void *data;
122 unsigned long pipeFlags;
123
125
126 input = output = NULL;
127 pipeFlags = 0;
128
129 argc = scanargs(&s_arg, argc, argv);
130 if (argc == 1) {
131 fprintf(stderr, "%s", USAGE);
132 exit(EXIT_FAILURE);
133 }
134
135 for (i_arg = 1; i_arg < argc; i_arg++) {
136 if (s_arg[i_arg].arg_type == OPTION) {
137 switch (match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
138 case SET_COMMENTS:
139 comments = 1;
140 break;
141 case SET_FORMAT:
142 if (s_arg[i_arg].n_items < 2)
143 SDDS_Bomb("Invalid -format syntax");
144 iformat = s_arg[i_arg].list[1]; /* Input format */
145 break;
146 case SET_VERBOSE:
147 verbose = 1;
148 break;
149 case SET_PIPE:
150 if (!processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
151 SDDS_Bomb("Invalid -pipe syntax");
152 break;
153 default:
154 fprintf(stderr, "Unknown option: %s\n", s_arg[i_arg].list[0]);
155 fprintf(stderr, "%s", USAGE);
156 exit(EXIT_FAILURE);
157 }
158 } else {
159 if (input == NULL)
160 input = s_arg[i_arg].list[0];
161 else if (output == NULL)
162 output = s_arg[i_arg].list[0];
163 else
164 SDDS_Bomb("Too many filenames provided.");
165 }
166 }
167
168 processFilenames("sdds2math", &input, &output, pipeFlags, 0, NULL);
169
170 if (output) {
171 outfile = fopen(output, "w");
172 if (!outfile) {
173 fprintf(stderr, "Error: Cannot open output file '%s'\n", output);
174 exit(EXIT_FAILURE);
175 }
176 } else {
177 outfile = stdout;
178 }
179
180 /* Calculate formats for converting to Mathematica convention */
181 format = (char *)calloc(256, sizeof(char)); /* Whole format */
182 if (!format) {
183 fprintf(stderr, "Memory allocation error for format.\n");
184 exit(EXIT_FAILURE);
185 }
186
187 rformat = (char *)calloc(256, sizeof(char)); /* Part before e */
188 if (!rformat) {
189 fprintf(stderr, "Memory allocation error for rformat.\n");
190 free(format);
191 exit(EXIT_FAILURE);
192 }
193
194 strcpy(format, iformat);
195 if ((ptr = strchr(format, 'E')))
196 *ptr = 'e'; /* Convert 'E' to 'e' */
197 if ((ptr = strchr(format, 'G')))
198 *ptr = 'g'; /* Convert 'G' to 'g' */
199 strcpy(rformat, format);
200 if ((ptr = strpbrk(rformat, "eg")))
201 *ptr = 'f';
202
203 /* Initialize SDDS input */
204 if (!SDDS_InitializeInput(&SDDS_table, input)) {
205 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
206 exit(EXIT_FAILURE);
207 }
208
209 layout = &SDDS_table.layout;
210
211 /* Start top level */
212 fprintf(outfile, "{");
213
214 /* Description */
215 fprintf(outfile, "{");
216 if (verbose)
217 printf("\nFile '%s' is in SDDS protocol version %" PRId32 "\n", input, layout->version);
218
219 if (!SDDS_GetDescription(&SDDS_table, &text, &contents))
220 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
221
222 if (text) {
223 if (verbose)
224 printf("Description: %s\n", text);
225 fprintf(outfile, "\"%s\",", text);
226 }
227
228 if (contents) {
229 if (verbose)
230 printf("Contents: %s\n", contents);
231 fprintf(outfile, "\"%s\"", contents);
232 } else {
233 fprintf(outfile, "\"No contents\"");
234 }
235
236 if (layout->data_mode.mode == SDDS_ASCII) {
237 if (verbose)
238 printf("\nData is ASCII with %" PRId32 " lines per row and %" PRId32 " additional header lines expected.\n",
239 layout->data_mode.lines_per_row, layout->data_mode.additional_header_lines);
240 if (verbose)
241 printf("Row counts: %s\n", layout->data_mode.no_row_counts ? "No" : "Yes");
242 } else if (verbose) {
243 printf("\nData is binary\n");
244 }
245
246 fprintf(outfile, "},\n");
247
248 /* Columns */
249 fprintf(outfile, " {");
250 if (layout->n_columns) {
251 if (verbose)
252 printf("\n%" PRId32 " columns of data:\n", layout->n_columns);
253 if (verbose)
254 printf("NAME UNITS SYMBOL FORMAT TYPE FIELD DESCRIPTION\n");
255 if (verbose)
256 printf(" LENGTH\n");
257 for (i = 0; i < layout->n_columns; i++) {
258 if (i > 0)
259 fprintf(outfile, ",\n ");
260 coldef = layout->column_definition + i;
261 if (verbose)
262 printf("%-15s %-15s %-15s %-15s %-7s %-7" PRId32 " %s\n",
263 coldef->name ? coldef->name : "No name",
264 coldef->units ? coldef->units : "",
265 coldef->symbol ? coldef->symbol : "",
266 coldef->format_string ? coldef->format_string : "",
267 SDDS_type_name[coldef->type - 1],
268 coldef->field_length,
269 coldef->description ? coldef->description : "No description");
270 fprintf(outfile, "{\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",%" PRId32 ",\"%s\"}",
271 coldef->name ? coldef->name : "No name",
272 coldef->units ? coldef->units : "",
273 coldef->symbol ? coldef->symbol : "",
274 coldef->format_string ? coldef->format_string : "",
275 SDDS_type_name[coldef->type - 1],
276 coldef->field_length,
277 coldef->description ? coldef->description : "No description");
278 }
279 }
280 fprintf(outfile, "},\n");
281
282 /* Parameters */
283 fprintf(outfile, " {");
284 if (layout->n_parameters) {
285 if (verbose)
286 printf("\n%" PRId32 " parameters:\n", layout->n_parameters);
287 if (verbose)
288 printf("NAME UNITS SYMBOL TYPE DESCRIPTION\n");
289 for (i = 0; i < layout->n_parameters; i++) {
290 if (i > 0)
291 fprintf(outfile, ",\n ");
292 pardef = layout->parameter_definition + i;
293 if (verbose)
294 printf("%-19s %-19s %-19s %-19s %s\n",
295 pardef->name ? pardef->name : "No name",
296 pardef->units ? pardef->units : "",
297 pardef->symbol ? pardef->symbol : "",
298 SDDS_type_name[pardef->type - 1],
299 pardef->description ? pardef->description : "No description");
300 fprintf(outfile, "{\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"}",
301 pardef->name ? pardef->name : "No name",
302 pardef->fixed_value ? pardef->fixed_value : "",
303 pardef->units ? pardef->units : "",
304 pardef->symbol ? pardef->symbol : "",
305 SDDS_type_name[pardef->type - 1],
306 pardef->description ? pardef->description : "No description");
307 }
308 }
309 fprintf(outfile, "},\n");
310
311 /* Arrays */
312 fprintf(outfile, " {");
313 if (layout->n_arrays) {
314 if (verbose)
315 printf("\n%" PRId32 " arrays of data:\n", layout->n_arrays);
316 if (verbose)
317 printf("NAME UNITS SYMBOL FORMAT TYPE FIELD GROUP DESCRIPTION\n");
318 if (verbose)
319 printf(" LENGTH NAME\n");
320 for (i = 0; i < layout->n_arrays; i++) {
321 if (i > 0)
322 fprintf(outfile, ",\n ");
323 arraydef = layout->array_definition + i;
324 if (verbose)
325 printf("%-15s %-15s %-15s %-7s %-8s*^%-5" PRId32 " %-7" PRId32 " %-15s %s\n",
326 arraydef->name ? arraydef->name : "No name",
327 arraydef->units ? arraydef->units : "",
328 arraydef->symbol ? arraydef->symbol : "",
329 arraydef->format_string ? arraydef->format_string : "",
330 SDDS_type_name[arraydef->type - 1],
331 arraydef->dimensions,
332 arraydef->field_length,
333 arraydef->group_name ? arraydef->group_name : "",
334 arraydef->description ? arraydef->description : "No description");
335 fprintf(outfile, "{\"%s\",\"%s\",\"%s\",\"%s\",\"%s*^%" PRId32 "\",%" PRId32 ",\"%s\",\"%s\"}",
336 arraydef->name ? arraydef->name : "No name",
337 arraydef->units ? arraydef->units : "",
338 arraydef->symbol ? arraydef->symbol : "",
339 arraydef->format_string ? arraydef->format_string : "",
340 SDDS_type_name[arraydef->type - 1],
341 arraydef->dimensions,
342 arraydef->field_length,
343 arraydef->group_name ? arraydef->group_name : "",
344 arraydef->description ? arraydef->description : "No description");
345 }
346 }
347 fprintf(outfile, "},\n");
348
349 /* Associates */
350 fprintf(outfile, " {");
351 if (layout->n_associates) {
352 if (verbose)
353 printf("\n%" PRId32 " associates:\n", layout->n_associates);
354 if (verbose)
355 printf("SDDS FILENAME PATH CONTENTS DESCRIPTION\n");
356 for (i = 0; i < layout->n_associates; i++) {
357 if (i > 0)
358 fprintf(outfile, ",\n ");
359 if (verbose)
360 printf("%-5s %-19s %-29s %-19s %s\n",
361 layout->associate_definition[i].sdds ? "True" : "False",
362 layout->associate_definition[i].filename ? layout->associate_definition[i].filename : "",
363 layout->associate_definition[i].path ? layout->associate_definition[i].path : "",
364 layout->associate_definition[i].contents ? layout->associate_definition[i].contents : "",
365 layout->associate_definition[i].description ? layout->associate_definition[i].description : "No description");
366 fprintf(outfile, "{\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"}",
367 layout->associate_definition[i].sdds ? "True" : "False",
368 layout->associate_definition[i].filename ? layout->associate_definition[i].filename : "",
369 layout->associate_definition[i].path ? layout->associate_definition[i].path : "",
370 layout->associate_definition[i].contents ? layout->associate_definition[i].contents : "",
371 layout->associate_definition[i].description ? layout->associate_definition[i].description : "No description");
372 }
373 }
374 fprintf(outfile, "},\n");
375
376 /* Process tables */
377 fprintf(outfile, " {"); /* Start of array of tables */
378 while ((ntable = SDDS_ReadTable(&SDDS_table)) > 0) {
379 if (ntable > 1)
380 fprintf(outfile, ",\n ");
381 if (comments)
382 fprintf(outfile, "(*Table %ld*)", ntable);
383 fprintf(outfile, "{\n"); /* Start of this table */
384
385 /* Variable parameters */
386 fprintf(outfile, " {"); /* Start of parameters */
387 for (i = 0; i < layout->n_parameters; i++) {
388 if (i > 0)
389 fprintf(outfile, ",\n ");
390 pardef = layout->parameter_definition + i;
391 if (!(data = SDDS_GetParameter(&SDDS_table, pardef->name, NULL))) {
392 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
393 exit(EXIT_FAILURE);
394 }
395
396 /* This parameter */
397 if (comments)
398 fprintf(outfile, "(* %s *)", pardef->name);
399
400 addquotes = 1;
401 switch (pardef->type) {
402 case SDDS_DOUBLE:
403 dd = *(double *)data;
404 sprintf(s, format, dd);
405 if ((ptr = strchr(s, 'e'))) {
406 *ptr = ' ';
407 sscanf(s, "%lf %hd", &ddred, &nexp);
408 fprintf(outfile, rformat, ddred);
409 fprintf(outfile, "*10^%d", nexp);
410 } else {
411 fprintf(outfile, "%s", s);
412 }
413 break;
414 case SDDS_FLOAT:
415 ff = *(float *)data;
416 sprintf(s, format, ff);
417 if ((ptr = strchr(s, 'e'))) {
418 *ptr = ' ';
419 sscanf(s, "%f %hd", &ffred, &nexp);
420 fprintf(outfile, rformat, ffred);
421 fprintf(outfile, "*10^%d", nexp);
422 } else {
423 fprintf(outfile, "%s", s);
424 }
425 break;
426 case SDDS_STRING:
427 ss = *(char **)data;
428 if (*ss == '"')
429 addquotes = 0;
430 else if (SDDS_StringIsBlank(ss) || SDDS_HasWhitespace(ss))
431 addquotes = 0;
432 case SDDS_CHARACTER:
433 if (addquotes)
434 fprintf(outfile, "\"");
435 SDDS_PrintTypedValue(data, 0, pardef->type, NULL, outfile, 0);
436 if (addquotes)
437 fprintf(outfile, "\"");
438 break;
439 default:
440 SDDS_PrintTypedValue(data, 0, pardef->type, NULL, outfile, 0);
441 break;
442 }
443 }
444 fprintf(outfile, "},\n"); /* End of parameters */
445
446 /* Columns */
447 fprintf(outfile, " {"); /* Start of data array */
448 if (layout->n_columns) {
449 SDDS_SetColumnFlags(&SDDS_table, 1);
450 SDDS_SetRowFlags(&SDDS_table, 1);
451 if ((nrows = SDDS_CountRowsOfInterest(&SDDS_table)) < 0) {
452 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
453 exit(EXIT_FAILURE);
454 }
455
456 if (nrows) {
457 for (j = 0; j < nrows; j++) {
458 if (j > 0)
459 fprintf(outfile, ",\n ");
460 fprintf(outfile, "{"); /* Start of row */
461 for (i = 0; i < layout->n_columns; i++) {
462 if (i > 0)
463 fprintf(outfile, ",");
464 coldef = layout->column_definition + i;
465 if (!(data = SDDS_GetValue(&SDDS_table, coldef->name, j, NULL))) {
466 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
467 exit(EXIT_FAILURE);
468 }
469
470 addquotes = 1;
471 switch (coldef->type) {
472 case SDDS_DOUBLE:
473 dd = *(double *)data;
474 sprintf(s, format, dd);
475 if ((ptr = strchr(s, 'e'))) {
476 *ptr = ' ';
477 sscanf(s, "%lf %hd", &ddred, &nexp);
478 fprintf(outfile, rformat, ddred);
479 fprintf(outfile, "*10^%d", nexp);
480 } else {
481 fprintf(outfile, "%s", s);
482 }
483 break;
484 case SDDS_FLOAT:
485 ff = *(float *)data;
486 sprintf(s, format, ff);
487 if ((ptr = strchr(s, 'e'))) {
488 *ptr = ' ';
489 sscanf(s, "%f %hd", &ffred, &nexp);
490 fprintf(outfile, rformat, ffred);
491 fprintf(outfile, "*10^%d", nexp);
492 } else {
493 fprintf(outfile, "%s", s);
494 }
495 break;
496 case SDDS_STRING:
497 ss = *(char **)data;
498 if (*ss == '"')
499 addquotes = 0;
500 else if (SDDS_StringIsBlank(ss) || SDDS_HasWhitespace(ss))
501 addquotes = 0;
502 case SDDS_CHARACTER:
503 if (addquotes)
504 fprintf(outfile, "\"");
505 SDDS_PrintTypedValue(data, 0, coldef->type, NULL, outfile, 0);
506 if (addquotes)
507 fprintf(outfile, "\"");
508 break;
509 default:
510 SDDS_PrintTypedValue(data, 0, coldef->type, NULL, outfile, 0);
511 break;
512 }
513 }
514 fprintf(outfile, "}"); /* End of row */
515 }
516 }
517 }
518 fprintf(outfile, "}"); /* End of data array */
519 fprintf(outfile, "}"); /* End of this table */
520 }
521 fprintf(outfile, "\n }\n"); /* End of array of tables, last major component */
522
523 /* End top level */
524 fprintf(outfile, "}\n"); /* End of top level */
525
526 /* Clean up and exit */
527 fflush(stdout);
528 if (!SDDS_Terminate(&SDDS_table)) {
529 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
530 exit(EXIT_FAILURE);
531 }
532
533 free(format);
534 free(rformat);
535
536 return EXIT_SUCCESS;
537}
char * SDDS_type_name[SDDS_NUM_TYPES]
Array of supported data type names.
Definition SDDS_data.c:43
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_SetRowFlags(SDDS_DATASET *SDDS_dataset, int32_t row_flag_value)
Sets the acceptance flags for all rows in the current data table of a data set.
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_SetColumnFlags(SDDS_DATASET *SDDS_dataset, int32_t column_flag_value)
Sets the acceptance flags for all columns in the current data table of a data set.
int32_t SDDS_GetDescription(SDDS_DATASET *SDDS_dataset, char **text, char **contents)
Retrieves the text and contents descriptions from an SDDS dataset.
void * SDDS_GetValue(SDDS_DATASET *SDDS_dataset, char *column_name, int64_t srow_index, void *memory)
Retrieves the value from a specified column and selected row, optionally storing it in provided memor...
int32_t SDDS_InitializeInput(SDDS_DATASET *SDDS_dataset, char *filename)
Definition SDDS_input.c:49
int32_t SDDS_Terminate(SDDS_DATASET *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
int32_t SDDS_StringIsBlank(char *s)
Checks if a string is blank (contains only whitespace characters).
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:342
int32_t SDDS_PrintTypedValue(void *data, int64_t index, int32_t type, char *format, FILE *fp, uint32_t mode)
Prints a data value of a specified type using an optional printf format string.
Definition SDDS_utils.c:59
int32_t SDDS_HasWhitespace(char *string)
Checks if a string contains any whitespace characters.
#define SDDS_FLOAT
Identifier for the float data type.
Definition SDDStypes.h:43
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
#define SDDS_CHARACTER
Identifier for the character data type.
Definition SDDStypes.h:91
#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.
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