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

Detailed Description

Converts a data file from Hewlett-Packard/Keysight Technologies' CITI format to SDDS format.

This program reads a waveform data file in Hewlett-Packard/Keysight Technologies' CITI format (Common Instrumentation Transfer and Interchange file) and converts it into the SDDS (Self Describing Data Sets) format. It supports various options to customize the output, including setting descriptions, MPL labels, and specifying the major order of data.

Usage

citi2sdds <inputfile> <outputfile>
[-description=<text>,<contents>]
[-mpllabels=<title>,<topline>]
[-majorOrder=row|column]

Options

Optional Description
-description Adds a description text and content to the SDDS output file.
-mpllabels Sets MPL (Matplotlib) title and top-line labels for the SDDS output.
-majorOrder Specifies the major order of data in the SDDS output. Defaults to row-major order.

Incompatibilities

  • Only one of the following options may be specified:
    • -description
    • -mpllabels
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, C. Saunders, R. Soliday, H. Shang

Definition in file citi2sdds.c.

#include "mdb.h"
#include "SDDS.h"
#include "scan.h"
#include "match_string.h"

Go to the source code of this file.

Functions

long read_CITI_var_list (FILE *fpi, double *var_list, long points)
 
long read_CITI_data (FILE *fpi, double *real_data, double *imag_data, long points)
 
long read_CITI_seg_list (FILE *fpi, double *seg_list, long points)
 
void alter_data_name (char *name)
 
int main (int argc, char **argv)
 
char * process_column_definition (char **argv, long argc)
 

Function Documentation

◆ alter_data_name()

void alter_data_name ( char * name)

Definition at line 456 of file citi2sdds.c.

456 {
457 char *ptr;
458 if ((ptr = strchr(name, '[')))
459 strcpy_ss(ptr, ptr + 1);
460 if ((ptr = strchr(name, ']')))
461 strcpy_ss(ptr, ptr + 1);
462 if ((ptr = strchr(name, ',')))
463 strcpy_ss(ptr, ptr + 1);
464}
char * strcpy_ss(char *dest, const char *src)
Safely copies a string, handling memory overlap.
Definition str_copy.c:34

◆ main()

int main ( int argc,
char ** argv )

Definition at line 99 of file citi2sdds.c.

99 {
100 SDDS_TABLE SDDS_table;
101 SCANNED_ARG *scanned;
102 long i, i_arg, points;
103 char *input, *output, *name, *indep_var, *var_list_format;
104 char *mpl_title, *mpl_topline, *descrip_text, *descrip_contents;
105 FILE *fpi;
106 char buffer[BUFSIZE], buffer0[BUFSIZE], buffer1[BUFSIZE];
107 char *ptr, *ptr1, *ptr2;
108 char **data_name, *package_name, *data_format;
109 long data_names, data_sets_seen, data_sets_expected, realIndex, imagIndex;
110 double **real_data, **imag_data, *var_list;
111 unsigned long majorOrderFlag;
112 short columnMajorOrder = 0;
113
114 argc = scanargs(&scanned, argc, argv);
115 if (argc < 3) {
116 fprintf(stderr, "%s", USAGE);
117 return EXIT_FAILURE;
118 }
119
120 input = output = package_name = data_format = indep_var = var_list_format = ptr = NULL;
121 mpl_title = mpl_topline = descrip_text = descrip_contents = NULL;
122 data_names = realIndex = imagIndex = 0;
123 data_name = NULL;
124 real_data = imag_data = NULL;
125 var_list = NULL;
126 data_sets_expected = data_sets_seen = 0;
127 points = 0;
128
129 for (i_arg = 1; i_arg < argc; i_arg++) {
130 if (scanned[i_arg].arg_type == OPTION) {
131 delete_chars(scanned[i_arg].list[0], "_");
132 /* process options here */
133 switch (match_string(scanned[i_arg].list[0], option, N_OPTIONS, 0)) {
134 case SET_MAJOR_ORDER:
135 majorOrderFlag = 0;
136 scanned[i_arg].n_items--;
137 if (scanned[i_arg].n_items > 0 && (!scanItemList(&majorOrderFlag, scanned[i_arg].list + 1, &scanned[i_arg].n_items, 0, "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER, "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
138 SDDS_Bomb("invalid -majorOrder syntax/values");
139 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
140 columnMajorOrder = 1;
141 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
142 columnMajorOrder = 0;
143 break;
144 case SET_DESCRIPTION:
145 if (scanned[i_arg].n_items != 3) {
146 SDDS_Bomb("invalid -description syntax");
147 }
148 descrip_text = scanned[i_arg].list[1];
149 descrip_contents = scanned[i_arg].list[2];
150 break;
151 case SET_MPL_LABELS:
152 if (scanned[i_arg].n_items != 3) {
153 SDDS_Bomb("invalid -mpllabels syntax");
154 }
155 mpl_title = scanned[i_arg].list[1];
156 mpl_topline = scanned[i_arg].list[2];
157 break;
158 default:
159 SDDS_Bomb("invalid option seen");
160 break;
161 }
162 } else {
163 if (!input)
164 input = scanned[i_arg].list[0];
165 else if (!output)
166 output = scanned[i_arg].list[0];
167 else {
168 SDDS_Bomb("too many filenames");
169 }
170 }
171 }
172 if (!input) {
173 SDDS_Bomb("input file not seen");
174 }
175 if (!output) {
176 SDDS_Bomb("output file not seen");
177 }
178
179 fpi = fopen_e(input, "r", 0);
180 if (!fgets(buffer, BUFSIZE, fpi) || strncmp(buffer, CITIFILE_TAG, strlen(CITIFILE_TAG)) != 0 || !(ptr = strchr(buffer, ' '))) {
181 SDDS_Bomb("valid CITIFILE version line not found");
182 }
183 *ptr++ = 0;
184 ptr[strlen(ptr) - 1] = 0;
185 if (strncmp(ptr, CITIFILE_VERSION, strlen(CITIFILE_VERSION)) != 0)
186 fprintf(stderr, "warning: the CITIFILE version is %s--this program is only designed for version %s\n", ptr, CITIFILE_VERSION);
187
188 if (!SDDS_InitializeOutput(&SDDS_table, SDDS_BINARY, 0, descrip_text, descrip_contents, output))
189 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
190 SDDS_table.layout.data_mode.column_major = columnMajorOrder;
191 if ((mpl_title && SDDS_DefineParameter(&SDDS_table, "mplTitle", NULL, NULL, NULL, NULL, SDDS_STRING, mpl_title) < 0) ||
192 (mpl_topline && SDDS_DefineParameter(&SDDS_table, "mplTopline", NULL, NULL, NULL, NULL, SDDS_STRING, mpl_topline) < 0))
193 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
194
195 while (fgets(buffer, BUFSIZE, fpi)) {
196#if DEBUG
197 fputs(buffer, stderr);
198#endif
199 buffer[strlen(buffer) - 1] = 0;
200 strcpy(buffer0, buffer);
201 ptr1 = NULL;
202 if ((ptr1 = strchr(buffer, ' ')))
203 *ptr1++ = 0;
204 switch (match_string(buffer, citi_keyword, N_CITI_KEYWORDS, EXACT_MATCH)) {
205 case CITI_NA_KEYWORD:
206 name = buffer + 1;
207 if (!*ptr1 || !(ptr2 = strchr(ptr1, ' '))) {
208 fprintf(stderr, "The following line contains an apparently invalid #NA keyword:\n%s\n", buffer0);
209 return EXIT_FAILURE;
210 }
211 *(ptr1 - 1) = '_';
212 *ptr2++ = 0;
213 if (SDDS_DefineParameter(&SDDS_table, name, NULL, NULL, NULL, NULL, SDDS_STRING, ptr2) < 0) {
214 SDDS_SetError(buffer0);
215 SDDS_SetError("Problem creating parameter for #NA keyword in the following line:");
216 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
217 }
218 break;
219 case CITI_NAME_KEYWORD:
220 if (!ptr1 || SDDS_StringIsBlank(ptr1)) {
221 fprintf(stderr, "The following line contains erroneous input:\n%s\n", buffer0);
222 return EXIT_FAILURE;
223 }
224#if DEBUG
225 fprintf(stderr, "NAME: %s\n", ptr1);
226#endif
227 cp_str(&package_name, ptr1);
228 if (SDDS_DefineParameter(&SDDS_table, "CITIPackageName", NULL, NULL, NULL, NULL, SDDS_STRING, package_name) < 0) {
229 SDDS_SetError(buffer0);
230 SDDS_SetError("Problem creating parameter for NAME keyword in the following line:");
231 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
232 }
233 break;
234 case CITI_VAR_KEYWORD:
235 if (!ptr1 || SDDS_StringIsBlank(ptr1)) {
236 fprintf(stderr, "The following line contains erroneous input:\n%s\n", buffer0);
237 return EXIT_FAILURE;
238 }
239#if DEBUG
240 fprintf(stderr, "VAR: %s\n", ptr1);
241#endif
242 if (!(indep_var = get_token(ptr1)) || !(var_list_format = get_token(ptr1)) || !get_long(&points, ptr1) || points <= 0) {
243 fprintf(stderr, "The following line contains erroneous input:\n%s\n", buffer0);
244 return EXIT_FAILURE;
245 }
246 if (SDDS_DefineColumn(&SDDS_table, indep_var, NULL, NULL, NULL, NULL, SDDS_DOUBLE, 0) < 0) {
247 SDDS_SetError(buffer0);
248 SDDS_SetError("Problem creating column for data element in the following line:");
249 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
250 }
251 break;
252 case CITI_CONSTANT_KEYWORD:
253 if (!ptr1 || !(ptr2 = strchr(ptr1, ' '))) {
254 fprintf(stderr, "The following line contains erroneous input:\n%s\n", buffer0);
255 return EXIT_FAILURE;
256 }
257#if DEBUG
258 fprintf(stderr, "CONSTANT: %s\n", ptr1);
259#endif
260 *ptr2++ = 0;
261 if (SDDS_DefineParameter(&SDDS_table, ptr1, NULL, NULL, NULL, NULL, SDDS_STRING, ptr2) < 0) {
262 SDDS_SetError(buffer0);
263 SDDS_SetError("Problem creating parameter for CONSTANT keyword in the following line:");
264 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
265 }
266 break;
267 case CITI_COMMENT_KEYWORD:
268 if (!ptr1 || SDDS_StringIsBlank(ptr1)) {
269 fprintf(stderr, "The following line contains erroneous input:\n%s\n", buffer0);
270 return EXIT_FAILURE;
271 }
272#if DEBUG
273 fprintf(stderr, "COMMENT: %s\n", ptr1);
274#endif
275 break;
276 case CITI_DATA_KEYWORD:
277 if (!ptr1 || !(ptr2 = strchr(ptr1, ' '))) {
278 fprintf(stderr, "The following line contains erroneous input:\n%s\n", buffer0);
279 return EXIT_FAILURE;
280 }
281#if DEBUG
282 fprintf(stderr, "DATA: %s\n", ptr1);
283#endif
284 *ptr2++ = 0;
285 cp_str(&data_format, ptr2);
286 data_name = trealloc(data_name, sizeof(*data_name) * (data_names + 1));
287 cp_str(data_name + data_names, ptr1);
288 alter_data_name(data_name[data_names]);
289 real_data = trealloc(real_data, sizeof(*real_data) * (data_names + 1));
290 imag_data = trealloc(imag_data, sizeof(*imag_data) * (data_names + 1));
291 sprintf(buffer, "%sReal", data_name[data_names]);
292 sprintf(buffer1, "%sImag", data_name[data_names]);
293 if ((realIndex = SDDS_DefineColumn(&SDDS_table, buffer, NULL, NULL, NULL, NULL, SDDS_DOUBLE, 0)) < 0 ||
294 (imagIndex = SDDS_DefineColumn(&SDDS_table, buffer1, NULL, NULL, NULL, NULL, SDDS_DOUBLE, 0)) < 0) {
295 SDDS_SetError(buffer0);
296 SDDS_SetError("Problem creating column for data element in the following line:");
297 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
298 }
299 data_names++;
300 break;
301 case CITI_VAR_LIST_KEYWORD:
302 if (ptr1 && !SDDS_StringIsBlank(ptr1)) {
303 fprintf(stderr, "The following line contains erroneous input:\n%s\n", buffer0);
304 return EXIT_FAILURE;
305 }
306#if DEBUG
307 fprintf(stderr, "VAR_LIST_BEGIN seen\n");
308#endif
309 if (points == 0)
310 SDDS_Bomb("VAR_LIST_BEGIN statement seen without prior VAR statement");
311 var_list = tmalloc(sizeof(*var_list) * points);
312 if (!read_CITI_var_list(fpi, var_list, points))
313 SDDS_Bomb("unable to read VAR_LIST");
314 break;
315 case CITI_BEGIN_KEYWORD:
316 if (ptr1 && !SDDS_StringIsBlank(ptr1)) {
317 fprintf(stderr, "The following line contains erroneous input:\n%s\n", buffer0);
318 return EXIT_FAILURE;
319 }
320#if DEBUG
321 fprintf(stderr, "BEGIN seen\n");
322#endif
323 if (points == 0)
324 SDDS_Bomb("BEGIN statement seen without prior VAR statement");
325 real_data[data_sets_seen] = tmalloc(sizeof(**real_data) * points);
326 imag_data[data_sets_seen] = tmalloc(sizeof(**imag_data) * points);
327 if (!read_CITI_data(fpi, real_data[data_sets_seen], imag_data[data_sets_seen], points))
328 SDDS_Bomb("problem reading data section");
329 data_sets_seen++;
330 break;
331 case CITI_SEG_LIST_BEGIN:
332 if (ptr1 && !SDDS_StringIsBlank(ptr1)) {
333 fprintf(stderr, "The following line contains erroneous input:\n%s\n", buffer0);
334 return EXIT_FAILURE;
335 }
336#if DEBUG
337 fprintf(stderr, "SEG_LIST_BEGIN seen\n");
338#endif
339 if (points == 0)
340 SDDS_Bomb("SEG_LIST_BEGIN statement seen without prior SEG statement");
341 var_list = tmalloc(sizeof(*var_list) * points);
342 if (!read_CITI_seg_list(fpi, var_list, points))
343 SDDS_Bomb("unable to read SEG_LIST");
344 break;
345 default:
346 fprintf(stderr, "Unidentifiable line in file--not CITI format:\n\"%s\"\n", buffer0);
347 return EXIT_FAILURE;
348 break;
349 }
350 }
351 if (!points)
352 SDDS_Bomb("no data in file");
353 if (data_sets_seen != (data_sets_expected = data_names))
354 SDDS_Bomb("fewer data sets than expected were actually present");
355 if (!var_list) {
356 fprintf(stderr, "warning: no independent variable data---supplying index\n");
357 var_list = tmalloc(sizeof(*var_list) * points);
358 for (i = 0; i < points; i++)
359 var_list[i] = i;
360 }
361 if (!SDDS_WriteLayout(&SDDS_table) || !SDDS_StartTable(&SDDS_table, points))
362 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
363 if (!SDDS_SetColumn(&SDDS_table, SDDS_SET_BY_NAME, (void *)var_list, points, indep_var))
364 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
365 for (i = 0; i < data_sets_expected; i++) {
366 if (!SDDS_SetColumn(&SDDS_table, SDDS_SET_BY_INDEX, (void *)real_data[i], points, realIndex) ||
367 !SDDS_SetColumn(&SDDS_table, SDDS_SET_BY_INDEX, (void *)imag_data[i], points, imagIndex)) {
368 fprintf(stderr, "Problem setting data for column(s) %s\n", data_name[i]);
369 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
370 }
371 }
372 if (!SDDS_WriteTable(&SDDS_table) || !SDDS_Terminate(&SDDS_table))
373 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
374
375 return EXIT_SUCCESS;
376}
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_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_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.
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
Definition SDDS_utils.c:379
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
Definition SDDS_utils.c:432
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
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37
void * trealloc(void *old_ptr, uint64_t size_of_block)
Reallocates a memory block to a new size.
Definition array.c:181
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:59
char * cp_str(char **s, char *t)
Copies a string, allocating memory for storage.
Definition cp_str.c:28
int get_long(long *iptr, char *s)
Parses a long integer value from the given string.
Definition data_scan.c:255
char * get_token(char *s)
Extracts the next token from the input string.
Definition data_scan.c:413
char * delete_chars(char *s, char *t)
Removes all occurrences of characters found in string t from string s.
FILE * fopen_e(char *file, char *open_mode, long mode)
Opens a file with error checking, messages, and aborts.
Definition fopen_e.c:30
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 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.

◆ process_column_definition()

char * process_column_definition ( char ** argv,
long argc )

Definition at line 378 of file citi2sdds.c.

378 {
379 char buffer[SDDS_MAXLINE], *ptr;
380 long i;
381
382 if (argc < 1)
383 return (NULL);
384 sprintf(buffer, "&column name=%s, ", argv[0]);
385 for (i = 1; i < argc; i++) {
386 if (!strchr(argv[i], '='))
387 return (NULL);
388 strcat(buffer, argv[i]);
389 strcat(buffer, ", ");
390 }
391 if (!strstr(buffer, "type="))
392 strcat(buffer, "type=character ");
393 strcat(buffer, "&end");
394 cp_str(&ptr, buffer);
395 return (ptr);
396}

◆ read_CITI_data()

long read_CITI_data ( FILE * fpi,
double * real_data,
double * imag_data,
long points )

Definition at line 416 of file citi2sdds.c.

416 {
417 long i;
418 char buffer[BUFSIZE];
419
420 i = 0;
421 while (fgets(buffer, BUFSIZE, fpi) && i < points) {
422 buffer[strlen(buffer) - 1] = 0;
423 if (strcmp(buffer, "END") == 0)
424 break;
425 if (!get_double(real_data + i, buffer) || !get_double(imag_data + i, buffer))
426 return (0);
427 i++;
428 }
429 if (i != points)
430 return (0);
431 return (1);
432}
int get_double(double *dptr, char *s)
Parses a double value from the given string.
Definition data_scan.c:40

◆ read_CITI_seg_list()

long read_CITI_seg_list ( FILE * fpi,
double * seg_list,
long points )

Definition at line 434 of file citi2sdds.c.

434 {
435 char buffer[BUFSIZE];
436 long i;
437 double start, end, delta;
438
439 if (!fgets(buffer, BUFSIZE, fpi) || !get_double(&start, buffer) || !get_double(&end, buffer) || !get_long(&i, buffer))
440 return (0);
441 if (i != points)
442 return (0);
443 delta = (end - start) / (points - 1);
444
445 if (!fgets(buffer, BUFSIZE, fpi))
446 return (0);
447 buffer[strlen(buffer) - 1] = 0;
448 if (strcmp(buffer, "SEG_LIST_END") != 0)
449 return (0);
450
451 for (i = 0; i < points; i++)
452 seg_list[i] = start + i * delta;
453 return (1);
454}

◆ read_CITI_var_list()

long read_CITI_var_list ( FILE * fpi,
double * var_list,
long points )

Definition at line 398 of file citi2sdds.c.

398 {
399 long i;
400 char buffer[BUFSIZE];
401
402 i = 0;
403 while (fgets(buffer, BUFSIZE, fpi) && i < points) {
404 buffer[strlen(buffer) - 1] = 0;
405 if (strcmp(buffer, "VAR_LIST_END") == 0)
406 break;
407 if (!get_double(var_list + i, buffer))
408 return (0);
409 i++;
410 }
411 if (i != points)
412 return (0);
413 return (1);
414}