SDDSlib
Loading...
Searching...
No Matches
citi2sdds.c
1/*************************************************************************\
2 * Copyright (c) 2002 The University of Chicago, as Operator of Argonne
3 * National Laboratory.
4 * Copyright (c) 2002 The Regents of the University of California, as
5 * Operator of Los Alamos National Laboratory.
6 * This file is distributed subject to a Software License Agreement found
7 * in the file LICENSE that is included with this distribution.
8\*************************************************************************/
9
10/* program: citi2sdds.c
11 * purpose: converts a data file from HP's CITI format to
12 * SDDS format
13 *
14 * M. Borland, 1994
15 $Log: not supported by cvs2svn $
16 Revision 1.5 2001/01/23 19:14:54 soliday
17 Standardized usage message.
18
19 Revision 1.4 1999/05/25 19:02:07 soliday
20 Removed compiler warning on linux.
21
22 Revision 1.3 1996/02/15 19:21:16 borland
23 Added slightly better formating of error message for unrecognized input.
24
25 * Revision 1.2 1995/09/06 14:55:46 saunders
26 * First test release of SDDS1.5
27 *
28 */
29#include "mdb.h"
30#include "SDDS.h"
31#include "scan.h"
32#include "match_string.h"
33
34#define SET_DESCRIPTION 0
35#define SET_MPL_LABELS 1
36#define SET_MAJOR_ORDER 2
37#define N_OPTIONS 3
38
39static char *option[N_OPTIONS] = {
40 "description", "mpllabels"};
41
42char *USAGE = "citi2sdds <inputfile> <outputfile>\n\
43 [-description=<text>,<contents>]\n\
44 [-mpllabels=<title>,<topline>] [-majorOrder=row|column]\n\n\
45This program converts HP CITI format waveforms to SDDS format.\n\n\
46Program by Michael Borland (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ")\n";
47
48#define BUFSIZE 256
49
50#define CITIFILE_TAG "CITIFILE"
51#define CITIFILE_VERSION "A.01.00"
52
53#define CITI_NA_KEYWORD 0
54#define CITI_NAME_KEYWORD 1
55#define CITI_VAR_KEYWORD 2
56#define CITI_DATA_KEYWORD 3
57#define CITI_VAR_LIST_KEYWORD 4
58#define CITI_BEGIN_KEYWORD 5
59#define CITI_SEG_LIST_BEGIN 6
60#define CITI_COMMENT_KEYWORD 7
61#define CITI_CONSTANT_KEYWORD 8
62#define N_CITI_KEYWORDS 9
63static char *citi_keyword[N_CITI_KEYWORDS] = {
64 "#NA", "NAME", "VAR", "DATA", "VAR_LIST_BEGIN", "BEGIN",
65 "SEG_LIST_BEGIN", "COMMENT", "CONSTANT"};
66
67long read_CITI_var_list(FILE *fpi, double *var_list, long points);
68long read_CITI_data(FILE *fpi, double *real_data, double *imag_data, long points);
69long read_CITI_seg_list(FILE *fpi, double *seg_list, long points);
70void alter_data_name(char *name);
71
72int main(int argc, char **argv) {
73 SDDS_TABLE SDDS_table;
74 SCANNED_ARG *scanned;
75 long i, i_arg, points;
76 char *input, *output, *name, *indep_var, *var_list_format;
77 char *mpl_title, *mpl_topline, *descrip_text, *descrip_contents;
78 FILE *fpi;
79 char buffer[BUFSIZE], buffer0[BUFSIZE], buffer1[BUFSIZE];
80 char *ptr, *ptr1, *ptr2;
81 char **data_name, *package_name, *data_format;
82 long data_names, data_sets_seen, data_sets_expected, realIndex, imagIndex;
83 double **real_data, **imag_data, *var_list;
84 unsigned long majorOrderFlag;
85 short columnMajorOrder = 0;
86
87 argc = scanargs(&scanned, argc, argv);
88 if (argc < 3)
89 bomb(NULL, USAGE);
90
91 input = output = package_name = data_format = indep_var = var_list_format = ptr = NULL;
92 mpl_title = mpl_topline = descrip_text = descrip_contents = NULL;
93 data_names = realIndex = imagIndex = 0;
94 data_name = NULL;
95 real_data = imag_data = NULL;
96 var_list = NULL;
97 data_sets_expected = data_sets_seen = 0;
98 points = 0;
99
100 for (i_arg = 1; i_arg < argc; i_arg++) {
101 if (scanned[i_arg].arg_type == OPTION) {
102 delete_chars(scanned[i_arg].list[0], "_");
103 /* process options here */
104 switch (match_string(scanned[i_arg].list[0], option, N_OPTIONS, 0)) {
105 case SET_MAJOR_ORDER:
106 majorOrderFlag = 0;
107 scanned[i_arg].n_items--;
108 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)))
109 SDDS_Bomb("invalid -majorOrder syntax/values");
110 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
111 columnMajorOrder = 1;
112 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
113 columnMajorOrder = 0;
114 break;
115 case SET_DESCRIPTION:
116 if (scanned[i_arg].n_items != 3)
117 SDDS_Bomb("invalid -description syntax");
118 descrip_text = scanned[i_arg].list[1];
119 descrip_contents = scanned[i_arg].list[2];
120 break;
121 case SET_MPL_LABELS:
122 if (scanned[i_arg].n_items != 3)
123 SDDS_Bomb("invalid -mpllabels syntax");
124 mpl_title = scanned[i_arg].list[1];
125 mpl_topline = scanned[i_arg].list[2];
126 break;
127 default:
128 SDDS_Bomb("invalid option seen");
129 break;
130 }
131 } else {
132 if (!input)
133 input = scanned[i_arg].list[0];
134 else if (!output)
135 output = scanned[i_arg].list[0];
136 else
137 SDDS_Bomb("too many filenames");
138 }
139 }
140 if (!input)
141 SDDS_Bomb("input file not seen");
142 if (!output)
143 SDDS_Bomb("output file not seen");
144
145 fpi = fopen_e(input, "r", 0);
146 if (!fgets(buffer, BUFSIZE, fpi) || strncmp(buffer, CITIFILE_TAG, strlen(CITIFILE_TAG)) != 0 || !(ptr = strchr(buffer, ' ')))
147 SDDS_Bomb("valid CITIFILE version line not found");
148 *ptr++ = 0;
149 ptr[strlen(ptr) - 1] = 0;
150 if (strncmp(ptr, CITIFILE_VERSION, strlen(CITIFILE_VERSION)) != 0)
151 fprintf(stderr, "warning: the CITIFILE version is %s--this program is only designed for version %s\n", ptr, CITIFILE_VERSION);
152
153 if (!SDDS_InitializeOutput(&SDDS_table, SDDS_BINARY, 0, descrip_text, descrip_contents, output))
154 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
155 SDDS_table.layout.data_mode.column_major = columnMajorOrder;
156 if ((mpl_title && SDDS_DefineParameter(&SDDS_table, "mplTitle", NULL, NULL, NULL, NULL, SDDS_STRING, mpl_title) < 0) || (mpl_topline && SDDS_DefineParameter(&SDDS_table, "mplTopline", NULL, NULL, NULL, NULL, SDDS_STRING, mpl_topline) < 0))
157 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
158
159 while (fgets(buffer, BUFSIZE, fpi)) {
160#if DEBUG
161 fputs(buffer, stderr);
162#endif
163 buffer[strlen(buffer) - 1] = 0;
164 strcpy(buffer0, buffer);
165 ptr1 = NULL;
166 if ((ptr1 = strchr(buffer, ' ')))
167 *ptr1++ = 0;
168 switch (match_string(buffer, citi_keyword, N_CITI_KEYWORDS, EXACT_MATCH)) {
169 case CITI_NA_KEYWORD:
170 name = buffer + 1;
171 if (!*ptr1 || !(ptr2 = strchr(ptr1, ' '))) {
172 fprintf(stderr, "The following line contains an apparently invalid #NA keyword:\n%s\n", buffer0);
173 exit(1);
174 }
175 *(ptr1 - 1) = '_';
176 *ptr2++ = 0;
177 if (SDDS_DefineParameter(&SDDS_table, name, NULL, NULL, NULL, NULL, SDDS_STRING, ptr2) < 0) {
178 SDDS_SetError(buffer0);
179 SDDS_SetError("Problem creating parameter for #NA keyword in the following line:");
180 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
181 }
182 break;
183 case CITI_NAME_KEYWORD:
184 if (!ptr1 || SDDS_StringIsBlank(ptr1)) {
185 fprintf(stderr, "The following line contains erroneous input:\n%s\n", buffer0);
186 exit(1);
187 }
188#if DEBUG
189 fprintf(stderr, "NAME: %s\n", ptr1);
190#endif
191 cp_str(&package_name, ptr1);
192 if (SDDS_DefineParameter(&SDDS_table, "CITIPackageName", NULL, NULL, NULL, NULL, SDDS_STRING, package_name) < 0) {
193 SDDS_SetError(buffer0);
194 SDDS_SetError("Problem creating parameter for NAME keyword in the following line:");
195 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
196 }
197 break;
198 case CITI_VAR_KEYWORD:
199 if (!ptr1 || SDDS_StringIsBlank(ptr1)) {
200 fprintf(stderr, "The following line contains erroneous input:\n%s\n", buffer0);
201 exit(1);
202 }
203#if DEBUG
204 fprintf(stderr, "VAR: %s\n", ptr1);
205#endif
206 if (!(indep_var = get_token(ptr1)) || !(var_list_format = get_token(ptr1)) || !get_long(&points, ptr1) || points <= 0) {
207 fprintf(stderr, "The following line contains erroneous input:\n%s\n", buffer0);
208 exit(1);
209 }
210 if (SDDS_DefineColumn(&SDDS_table, indep_var, NULL, NULL, NULL, NULL, SDDS_DOUBLE, 0) < 0) {
211 SDDS_SetError(buffer0);
212 SDDS_SetError("Problem creating column for data element in the following line:");
213 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
214 }
215 break;
216 case CITI_CONSTANT_KEYWORD:
217 if (!ptr1 || !(ptr2 = strchr(ptr1, ' '))) {
218 fprintf(stderr, "The following line contains erroneous input:\n%s\n", buffer0);
219 exit(1);
220 }
221#if DEBUG
222 fprintf(stderr, "CONSTANT: %s\n", ptr1);
223#endif
224 *ptr2++ = 0;
225 if (SDDS_DefineParameter(&SDDS_table, ptr1, NULL, NULL, NULL, NULL, SDDS_STRING, ptr2) < 0) {
226 SDDS_SetError(buffer0);
227 SDDS_SetError("Problem creating parameter for CONSTANT keyword in the following line:");
228 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
229 }
230 break;
231 case CITI_COMMENT_KEYWORD:
232 if (!ptr1 || SDDS_StringIsBlank(ptr1)) {
233 fprintf(stderr, "The following line contains erroneous input:\n%s\n", buffer0);
234 exit(1);
235 }
236#if DEBUG
237 fprintf(stderr, "COMMENT: %s\n", ptr1);
238#endif
239 break;
240 case CITI_DATA_KEYWORD:
241 if (!ptr1 || !(ptr2 = strchr(ptr1, ' '))) {
242 fprintf(stderr, "The following line contains erroneous input:\n%s\n", buffer0);
243 exit(1);
244 }
245#if DEBUG
246 fprintf(stderr, "DATA: %s\n", ptr1);
247#endif
248 *ptr2++ = 0;
249 cp_str(&data_format, ptr2);
250 data_name = trealloc(data_name, sizeof(*data_name) * (data_names + 1));
251 cp_str(data_name + data_names, ptr1);
252 alter_data_name(data_name[data_names]);
253 real_data = trealloc(real_data, sizeof(*real_data) * (data_names + 1));
254 imag_data = trealloc(imag_data, sizeof(*imag_data) * (data_names + 1));
255 sprintf(buffer, "%sReal", data_name[data_names]);
256 sprintf(buffer1, "%sImag", data_name[data_names]);
257 if ((realIndex = SDDS_DefineColumn(&SDDS_table, buffer, NULL, NULL, NULL, NULL, SDDS_DOUBLE, 0)) < 0 || (imagIndex = SDDS_DefineColumn(&SDDS_table, buffer1, NULL, NULL, NULL, NULL, SDDS_DOUBLE, 0)) < 0) {
258 SDDS_SetError(buffer0);
259 SDDS_SetError("Problem creating column for data element in the following line:");
260 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
261 }
262 data_names++;
263 break;
264 case CITI_VAR_LIST_KEYWORD:
265 if (ptr1 && !SDDS_StringIsBlank(ptr1))
266 fprintf(stderr, "The following line contains erroneous input:\n%s\n", buffer0);
267#if DEBUG
268 fprintf(stderr, "VAR_LIST_BEGIN seen\n");
269#endif
270 if (points == 0)
271 SDDS_Bomb("VAR_LIST_BEGIN statement seen without prior VAR statement");
272 var_list = tmalloc(sizeof(*var_list) * points);
273 if (!read_CITI_var_list(fpi, var_list, points))
274 SDDS_Bomb("unable to read VAR_LIST");
275 break;
276 case CITI_BEGIN_KEYWORD:
277 if (ptr1 && !SDDS_StringIsBlank(ptr1))
278 fprintf(stderr, "The following line contains erroneous input:\n%s\n", buffer0);
279#if DEBUG
280 fprintf(stderr, "BEGIN seen\n");
281#endif
282 if (points == 0)
283 SDDS_Bomb("BEGIN statement seen without prior VAR statement");
284 real_data[data_sets_seen] = tmalloc(sizeof(**real_data) * points);
285 imag_data[data_sets_seen] = tmalloc(sizeof(**imag_data) * points);
286 if (!read_CITI_data(fpi, real_data[data_sets_seen], imag_data[data_sets_seen], points))
287 SDDS_Bomb("problem reading data section");
288 data_sets_seen++;
289 break;
290 case CITI_SEG_LIST_BEGIN:
291 if (ptr1 && !SDDS_StringIsBlank(ptr1))
292 fprintf(stderr, "The following line contains erroneous input:\n%s\n", buffer0);
293#if DEBUG
294 fprintf(stderr, "SEG_LIST_BEGIN seen\n");
295#endif
296 if (points == 0)
297 SDDS_Bomb("SEG_LIST_BEGIN statement seen without prior SEG statement");
298 var_list = tmalloc(sizeof(*var_list) * points);
299 if (!read_CITI_seg_list(fpi, var_list, points))
300 SDDS_Bomb("unable to read SEG_LIST");
301 break;
302 default:
303 fprintf(stderr, "unidentifiable line in file--not CITI format:\n\"%s\"\n", buffer0);
304 exit(1);
305 break;
306 }
307 }
308 if (!points)
309 SDDS_Bomb("no data in file");
310 if (data_sets_seen != (data_sets_expected = data_names))
311 SDDS_Bomb("fewer data sets than expected were actually present");
312 if (!var_list) {
313 fprintf(stderr, "warning: no independent variable data---supplying index\n");
314 var_list = tmalloc(sizeof(*var_list) * points);
315 for (i = 0; i < points; i++)
316 var_list[i] = i;
317 }
318 if (!SDDS_WriteLayout(&SDDS_table) || !SDDS_StartTable(&SDDS_table, points))
319 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
320 if (!SDDS_SetColumn(&SDDS_table, SDDS_SET_BY_NAME, (void *)var_list, points, indep_var))
321 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
322 for (i = 0; i < data_sets_expected; i++) {
323 if (!SDDS_SetColumn(&SDDS_table, SDDS_SET_BY_INDEX, (void *)real_data[i], points, realIndex) || !SDDS_SetColumn(&SDDS_table, SDDS_SET_BY_INDEX, (void *)imag_data[i], points, imagIndex)) {
324 fprintf(stderr, "problem setting data for column(s) %s\n", data_name[i]);
325 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
326 }
327 }
328 if (!SDDS_WriteTable(&SDDS_table) || !SDDS_Terminate(&SDDS_table))
329 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
330 return (0);
331}
332
333char *process_column_definition(char **argv, long argc) {
334 char buffer[SDDS_MAXLINE], *ptr;
335 long i;
336
337 if (argc < 1)
338 return (NULL);
339 sprintf(buffer, "&column name=%s, ", argv[0]);
340 for (i = 1; i < argc; i++) {
341 if (!strchr(argv[i], '='))
342 return (NULL);
343 strcat(buffer, argv[i]);
344 strcat(buffer, ", ");
345 }
346 if (!strstr(buffer, "type="))
347 strcat(buffer, "type=character ");
348 strcat(buffer, "&end");
349 cp_str(&ptr, buffer);
350 return (ptr);
351}
352
353long read_CITI_var_list(FILE *fpi, double *var_list, long points) {
354 long i;
355 char buffer[BUFSIZE];
356
357 i = 0;
358 while (fgets(buffer, BUFSIZE, fpi) && i < points) {
359 buffer[strlen(buffer) - 1] = 0;
360 if (strcmp(buffer, "VAR_LIST_END") == 0)
361 break;
362 if (!get_double(var_list + i, buffer))
363 return (0);
364 i++;
365 }
366 if (i != points)
367 return (0);
368 return (1);
369}
370
371long read_CITI_data(FILE *fpi, double *real_data, double *imag_data, long points) {
372 long i;
373 char buffer[BUFSIZE];
374
375 i = 0;
376 while (fgets(buffer, BUFSIZE, fpi) && i < points) {
377 buffer[strlen(buffer) - 1] = 0;
378 if (strcmp(buffer, "END") == 0)
379 break;
380 if (!get_double(real_data + i, buffer) || !get_double(imag_data + i, buffer))
381 return (0);
382 i++;
383 }
384 if (i != points)
385 return (0);
386 return (1);
387}
388
389long read_CITI_seg_list(FILE *fpi, double *seg_list, long points) {
390 char buffer[BUFSIZE];
391 long i;
392 double start, end, delta;
393
394 if (!fgets(buffer, BUFSIZE, fpi) || !get_double(&start, buffer) || !get_double(&end, buffer) || !get_long(&i, buffer))
395 return (0);
396 if (i != points)
397 return (0);
398 delta = (end - start) / (points - 1);
399
400 if (!fgets(buffer, BUFSIZE, fpi))
401 return (0);
402 buffer[strlen(buffer) - 1] = 0;
403 if (strcmp(buffer, "SEG_LIST_END") != 0)
404 return (0);
405
406 for (i = 0; i < points; i++)
407 seg_list[i] = start + i * delta;
408 return (1);
409}
410
411void alter_data_name(char *name) {
412 char *ptr;
413 if ((ptr = strchr(name, '[')))
414 strcpy_ss(ptr, ptr + 1);
415 if ((ptr = strchr(name, ']')))
416 strcpy_ss(ptr, ptr + 1);
417 if ((ptr = strchr(name, ',')))
418 strcpy_ss(ptr, ptr + 1);
419}
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
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
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
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
int get_double(double *dptr, char *s)
Parses a double value from the given string.
Definition data_scan.c:40
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.
char * strcpy_ss(char *dest, const char *src)
Safely copies a string, handling memory overlap.
Definition str_copy.c:34