SDDSlib
Loading...
Searching...
No Matches
hpif2sdds.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: hpif2sdds.c
11 * purpose: converts a waveform from an HP scope to
12 * SDDS format
13 *
14 * M. Borland, 1994
15 $Log: not supported by cvs2svn $
16 Revision 1.5 2001/01/23 19:14:55 soliday
17 Standardized usage message.
18
19 Revision 1.4 1999/05/25 19:02:36 soliday
20 Removed compiler warning on linux.
21
22 Revision 1.3 1999/01/06 19:54:35 borland
23 Fixed the version number in the usage message.
24
25 * Revision 1.2 1995/09/06 14:55:48 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#include <ctype.h>
34
35#define SET_SIGNAL_NAME 0
36#define SET_DESCRIPTION 1
37#define SET_MPL_LABELS 2
38#define SET_INITIAL_T 3
39#define SET_SINGLE_PRECISION 4
40#define SET_SEGMENT_INTERVAL 5
41#define SET_SEPARATE_SEGMENTS 6
42#define SET_PAIRS 7
43#define SET_MAJOR_ORDER 8
44#define N_OPTIONS 9
45
46static char *option[N_OPTIONS] = {
47 "signalname",
48 "description",
49 "mpllabels",
50 "initialt",
51 "singleprecision",
52 "segmentinterval",
53 "separatesegments",
54 "pairs",
55 "majorOrder",
56};
57
58char *USAGE = "hpif2sdds <inputfile> <outputfile>\n\
59 -signalname={<name>|<name1>,<name2>}\n\
60 [-description=<text>,<contents>]\n\
61 [-mpllabels=<title>,<topline>]\n\
62 [-initialt=<value>] [-singleprecision]\n\
63 [-segmentinterval=<time-in-secs>]\n\
64 [-separatesegments] [-pairs] [-majorOrder=row|column] \n\n\
65This program converts HP internal format waveforms to SDDS format.\n\n\
66Program by Michael Borland (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ")\n";
67
68#define BUFSIZE 256
69long get_next_field(char *buffer, FILE *fp);
70long set_2d_parameters(SDDS_TABLE *table, char *variable, double initial, long dimension, double increment);
71long define_2d_parameters(SDDS_TABLE *table, char *parameter, char *variable, char *units);
72void swapdouble(double *data);
73
74int main(int argc, char **argv) {
75 SDDS_TABLE SDDS_table;
76 SCANNED_ARG *scanned;
77 long i, i_arg, points, single_precision;
78 char *input, *output, buffer[BUFSIZE];
79 char *signal_name[2];
80 char *mpl_title, *mpl_topline, *descrip_text, *descrip_contents;
81 FILE *fpi;
82 double xIncrement, xOrigin, yScale, yOffset;
83 long xReference, yReference, segments, segment_length, separate_segments;
84 double *time, *data, *data1;
85 float *sp_time, *sp_data, *sp_data1;
86 short *idata, *idata1;
87 double initial_t, segment_interval;
88 long code1, code2, pairs, size, length;
89 short columnMajorOrder = 0;
90 unsigned long majorOrderFlag;
91
92 argc = scanargs(&scanned, argc, argv);
93 if (argc < 3)
94 bomb(NULL, USAGE);
95
96 time = data = data1 = NULL;
97 sp_time = sp_data = sp_data1 = NULL;
98 input = output = NULL;
99 mpl_title = mpl_topline = descrip_text = descrip_contents = NULL;
100 initial_t = DBL_MAX;
101 single_precision = 0;
102 signal_name[0] = signal_name[1] = NULL;
103 segment_interval = separate_segments = pairs = 0;
104
105 for (i_arg = 1; i_arg < argc; i_arg++) {
106 if (scanned[i_arg].arg_type == OPTION) {
107 delete_chars(scanned[i_arg].list[0], "_");
108 /* process options here */
109 switch (match_string(scanned[i_arg].list[0], option, N_OPTIONS, 0)) {
110 case SET_MAJOR_ORDER:
111 majorOrderFlag = 0;
112 scanned[i_arg].n_items--;
113 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)))
114 SDDS_Bomb("invalid -majorOrder syntax/values");
115 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
116 columnMajorOrder = 1;
117 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
118 columnMajorOrder = 0;
119 break;
120 case SET_SIGNAL_NAME:
121 if (scanned[i_arg].n_items != 2 && scanned[i_arg].n_items != 3)
122 SDDS_Bomb("invalid -signalname syntax");
123 signal_name[0] = scanned[i_arg].list[1];
124 if (scanned[i_arg].n_items == 3)
125 signal_name[1] = scanned[i_arg].list[2];
126 break;
127 case SET_DESCRIPTION:
128 if (scanned[i_arg].n_items != 3)
129 SDDS_Bomb("invalid -description syntax");
130 descrip_text = scanned[i_arg].list[1];
131 descrip_contents = scanned[i_arg].list[2];
132 break;
133 case SET_MPL_LABELS:
134 if (scanned[i_arg].n_items != 3)
135 SDDS_Bomb("invalid -mpllabels syntax");
136 mpl_title = scanned[i_arg].list[1];
137 mpl_topline = scanned[i_arg].list[2];
138 break;
139 case SET_INITIAL_T:
140 if (scanned[i_arg].n_items != 2 || sscanf(scanned[i_arg].list[1], "%lf", &initial_t) != 1)
141 SDDS_Bomb("invalid -initialt syntax");
142 break;
143 case SET_SINGLE_PRECISION:
144 single_precision = 1;
145 break;
146 case SET_SEGMENT_INTERVAL:
147 if (scanned[i_arg].n_items != 2 || sscanf(scanned[i_arg].list[1], "%lf", &segment_interval) != 1)
148 SDDS_Bomb("invalid -segmentinterval syntax");
149 break;
150 case SET_SEPARATE_SEGMENTS:
151 separate_segments = 1;
152 break;
153 case SET_PAIRS:
154 pairs = 1;
155 break;
156 default:
157 SDDS_Bomb("invalid option seen");
158 break;
159 }
160 } else {
161 if (!input)
162 input = scanned[i_arg].list[0];
163 else if (!output)
164 output = scanned[i_arg].list[0];
165 else
166 SDDS_Bomb("too many filenames");
167 }
168 }
169 if (!input)
170 SDDS_Bomb("input file not seen");
171 if (!output)
172 SDDS_Bomb("output file not seen");
173
174 fpi = fopen_e(input, "r", 0);
175 length = strlen(":WAV:PRE ");
176 if (fread(buffer, 1, length, fpi) != length || strncmp(buffer, ":WAV:PRE ", length) != 0) {
177 printf("buffer = \"%s\"\n", buffer);
178 SDDS_Bomb("file does not appear to be in HP internal format (1)");
179 }
180 if (!get_next_field(buffer, fpi) || sscanf(buffer, "%ld", &code1) != 1)
181 SDDS_Bomb("file does not appear to be in HP internal format (2)");
182 if (!get_next_field(buffer, fpi) || sscanf(buffer, "%ld", &code2) != 1)
183 SDDS_Bomb("file does not appear to be in HP internal format (3)");
184 if (!get_next_field(buffer, fpi) || sscanf(buffer, "%ld", &segment_length) != 1)
185 SDDS_Bomb("file does not appear to be in HP internal format (4)");
186 if (!get_next_field(buffer, fpi) || sscanf(buffer, "%ld", &segments) != 1) {
187 fprintf(stderr, "file does not appear to be in HP internal format (5)\n");
188 exit(1);
189 }
190 points = segments * segment_length;
191
192#if defined(DEBUG)
193 fprintf(stderr, "%ld points, %ld segments\n", points, segments);
194 if (pairs)
195 fprintf(stderr, "data appears to come in point pairs\n");
196#endif
197
198 if (!get_next_field(buffer, fpi) || sscanf(buffer, "%le", &xIncrement) != 1)
199 SDDS_Bomb("unable to get x increment");
200#if defined(DEBUG)
201 fprintf(stderr, "x increment = %e\n", xIncrement);
202#endif
203
204 if (!get_next_field(buffer, fpi) || sscanf(buffer, "%le", &xOrigin) != 1)
205 SDDS_Bomb("unable to get x origin");
206#if defined(DEBUG)
207 fprintf(stderr, "x origin = %e\n", xOrigin);
208#endif
209
210 if (!get_next_field(buffer, fpi) || sscanf(buffer, "%ld", &xReference) != 1)
211 SDDS_Bomb("unable to get x reference");
212#if defined(DEBUG)
213 fprintf(stderr, "x reference = %ld\n", xReference);
214#endif
215
216 if (!get_next_field(buffer, fpi) || sscanf(buffer, "%lf", &yScale) != 1)
217 SDDS_Bomb("unable to get y scale factor");
218#if defined(DEBUG)
219 fprintf(stderr, "y scale = %e\n", yScale);
220#endif
221
222 if (!get_next_field(buffer, fpi) || sscanf(buffer, "%lf", &yOffset) != 1)
223 SDDS_Bomb("unable to get y offset");
224#if defined(DEBUG)
225 fprintf(stderr, "y offset = %e\n", yOffset);
226#endif
227
228 if (!get_next_field(buffer, fpi) || sscanf(buffer, "%ld", &yReference) != 1)
229 SDDS_Bomb("unable to get y reference");
230#if defined(DEBUG)
231 fprintf(stderr, "y reference = %ld\n", yReference);
232#endif
233
234 while (fread(buffer, 1, 1, fpi))
235 if (buffer[0] == '#')
236 break;
237 fread(buffer, 1, 9, fpi);
238 if (!sscanf(buffer + 1, "%ld", &size))
239 SDDS_Bomb("unable to read size of data block");
240#if defined(DEBUG)
241 fprintf(stderr, "data block is %ld bytes\n", size);
242#endif
243
244 if (segments != 1) {
245 double segment_offset;
246 for (i = 0; i < segments; i++) {
247 if (!fread(&segment_offset, sizeof(segment_offset), 1, fpi))
248 SDDS_Bomb("unable to read segment offsets");
249 }
250 }
251
252 idata = tmalloc(sizeof(*idata) * points);
253 idata1 = tmalloc(sizeof(*idata1) * points);
254 if (!single_precision) {
255 data = tmalloc(sizeof(*data) * points);
256 data1 = tmalloc(sizeof(*data1) * points);
257 } else {
258 sp_data = tmalloc(sizeof(*sp_data) * points);
259 sp_data1 = tmalloc(sizeof(*sp_data1) * points);
260 }
261#if defined(DEBUG)
262 fprintf(stderr, "arrays allocated\n");
263#endif
264
265 if (!fread(idata, 2, points, fpi))
266 SDDS_Bomb("unable to read data");
267 if (pairs && !fread(idata1, 2, points, fpi))
268 SDDS_Bomb("unable to read second data block");
269#if defined(DEBUG)
270 fprintf(stderr, "data read in\n");
271#endif
272
273 if (!single_precision) {
274 for (i = 0; i < points; i++) {
275 data[i] = (idata[i] - yReference) * yScale + yOffset;
276 data1[i] = (idata1[i] - yReference) * yScale + yOffset;
277 }
278 } else {
279 for (i = 0; i < points; i++) {
280 sp_data[i] = (idata[i] - yReference) * yScale + yOffset;
281 sp_data1[i] = (idata1[i] - yReference) * yScale + yOffset;
282 }
283 }
284
285#if defined(DEBUG)
286 fprintf(stderr, "data copied\n");
287#endif
288
289 if (!SDDS_InitializeOutput(&SDDS_table, SDDS_BINARY, 0, descrip_text, descrip_contents, output))
290 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
291#if defined(DEBUG)
292 fprintf(stderr, "output initialized\n");
293#endif
294 SDDS_table.layout.data_mode.column_major = columnMajorOrder;
295 if (mpl_title && (SDDS_DefineParameter(&SDDS_table, "mplTitle", NULL, NULL, NULL, NULL, SDDS_STRING, mpl_title) < 0 || SDDS_DefineParameter(&SDDS_table, "mplTopline", NULL, NULL, NULL, NULL, SDDS_STRING, mpl_topline) < 0))
296 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
297#if defined(DEBUG)
298 fprintf(stderr, "title defined\n");
299#endif
300
301 if (segments != 1) {
302 if (define_2d_parameters(&SDDS_table, "Variable1Name", "Segment", NULL) == 0 ||
303 define_2d_parameters(&SDDS_table, "Variable2Name", "t", "s") == 0)
304 exit(1);
305 }
306
307 if (signal_name[0] == NULL) {
308 if (!pairs)
309 signal_name[0] = "V";
310 else {
311 signal_name[0] = "V1";
312 signal_name[1] = "V2";
313 }
314 }
315
316 if (pairs && !signal_name[1])
317 SDDS_Bomb("data contains voltage pairs--supply two signal names");
318
319 if (SDDS_DefineColumn(&SDDS_table, "t", NULL, "s", NULL, NULL,
320 (single_precision ? SDDS_FLOAT : SDDS_DOUBLE), 0) < 0 ||
321 SDDS_DefineColumn(&SDDS_table, signal_name[0], NULL, "V", NULL, NULL,
322 (single_precision ? SDDS_FLOAT : SDDS_DOUBLE), 0) < 0 ||
323 (pairs && SDDS_DefineColumn(&SDDS_table, signal_name[1], NULL, "V", NULL, NULL, (single_precision ? SDDS_FLOAT : SDDS_DOUBLE), 0) < 0) || !SDDS_WriteLayout(&SDDS_table))
324 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
325 fflush(SDDS_table.layout.fp);
326
327 if (!single_precision) {
328 time = tmalloc(sizeof(*time) * points);
329 if (initial_t == DBL_MAX)
330 initial_t = xOrigin - xReference * xIncrement;
331 for (i = 0; i < points; i++) {
332 if (segments != 1 && i && i % segment_length == 0)
333 initial_t += segment_interval - segment_length * xIncrement;
334 time[i] = i * xIncrement + initial_t;
335 }
336 } else {
337 sp_time = tmalloc(sizeof(*sp_time) * points);
338 if (initial_t == DBL_MAX)
339 initial_t = xOrigin - xReference * xIncrement;
340 for (i = 0; i < points; i++) {
341 if (segments != 1 && i && i % segment_length == 0)
342 initial_t += segment_interval - segment_length * xIncrement;
343 sp_time[i] = i * xIncrement + initial_t;
344 }
345 }
346
347 i = 1;
348 do {
349 if (!SDDS_StartTable(&SDDS_table, separate_segments ? segment_length : points))
350 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
351 if (segments != 1 && i == 1) {
352 if (!set_2d_parameters(&SDDS_table, "Segment", 0.0, segments, 1.0) || !set_2d_parameters(&SDDS_table, "t", initial_t, segment_length, xIncrement))
353 exit(1);
354 }
355
356#if defined(DEBUG)
357 fprintf(stderr, "row and column parameters set for table %ld\n", i);
358#endif
359
360 if (!SDDS_SetColumn(&SDDS_table, SDDS_SET_BY_NAME,
361 single_precision ? (void *)(sp_time + (i - 1) * segment_length)
362 : (void *)(time + (i - 1) * segment_length),
363 separate_segments ? segment_length : points, "t") ||
364 !SDDS_SetColumn(&SDDS_table, SDDS_SET_BY_NAME,
365 single_precision ? (void *)(sp_data + (i - 1) * segment_length)
366 : (void *)(data + (i - 1) * segment_length),
367 separate_segments ? segment_length : points, signal_name[0]) ||
368 (pairs && !SDDS_SetColumn(&SDDS_table, SDDS_SET_BY_NAME, single_precision ? (void *)(sp_data1 + (i - 1) * segment_length) : (void *)(data1 + (i - 1) * segment_length), separate_segments ? segment_length : points, signal_name[1])) || !SDDS_WriteTable(&SDDS_table))
369 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
370 } while (separate_segments && ++i <= segments);
371 if (!SDDS_Terminate(&SDDS_table))
372 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
373 return (0);
374}
375
376char *process_column_definition(char **argv, long argc) {
377 char buffer[SDDS_MAXLINE], *ptr;
378 long i;
379
380 if (argc < 1)
381 return (NULL);
382 sprintf(buffer, "&column name=%s, ", argv[0]);
383 for (i = 1; i < argc; i++) {
384 if (!strchr(argv[i], '='))
385 return (NULL);
386 strcat(buffer, argv[i]);
387 strcat(buffer, ", ");
388 }
389 if (!strstr(buffer, "type="))
390 strcat(buffer, "type=character ");
391 strcat(buffer, "&end");
392 cp_str(&ptr, buffer);
393 return (ptr);
394}
395
396long get_next_field(char *buffer, FILE *fp) {
397 long i;
398 buffer[i = 0] = 0;
399 while ((buffer[i] = fgetc(fp))) {
400 buffer[i] = tolower(buffer[i]);
401 if (buffer[i] == ',' || buffer[i] == ';')
402 break;
403 buffer[++i] = 0;
404 }
405 buffer[i] = 0;
406 return (1);
407}
408
409long define_2d_parameters(SDDS_TABLE *table, char *parameter, char *variable, char *units) {
410 char buffer[BUFSIZE];
411 SDDS_DefineParameter(table, parameter, NULL, NULL, NULL, NULL, SDDS_STRING, variable);
412 sprintf(buffer, "%sMinimum", variable);
413 SDDS_DefineParameter(table, buffer, NULL, units, NULL, NULL, SDDS_DOUBLE, NULL);
414 sprintf(buffer, "%sInterval", variable);
415 SDDS_DefineParameter(table, buffer, NULL, units, NULL, NULL, SDDS_DOUBLE, NULL);
416 sprintf(buffer, "%sDimension", variable);
417 SDDS_DefineParameter(table, buffer, NULL, NULL, NULL, NULL, SDDS_LONG, NULL);
418 if (SDDS_NumberOfErrors()) {
419 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
420 return (0);
421 }
422 return (1);
423}
424
425long set_2d_parameters(SDDS_TABLE *table, char *variable, double initial, long dimension, double increment) {
426 char buffer[BUFSIZE];
427 sprintf(buffer, "%sMinimum", variable);
428 SDDS_SetParameters(table, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, buffer, initial, NULL);
429 sprintf(buffer, "%sInterval", variable);
430 SDDS_SetParameters(table, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, buffer, increment, NULL);
431 sprintf(buffer, "%sDimension", variable);
432 SDDS_SetParameters(table, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, buffer, dimension, NULL);
433 if (SDDS_NumberOfErrors()) {
434 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
435 return (0);
436 }
437 return (1);
438}
439
440void swapdouble(double *data) {
441 double copy;
442 short i;
443 copy = *data;
444 for (i = 0; i < 8; i++)
445 *(((char *)data) + i) = *(((char *)&copy) + (8 - i));
446}
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
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_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
Definition SDDS_utils.c:432
int32_t SDDS_NumberOfErrors()
Retrieves the number of errors recorded by SDDS library routines.
Definition SDDS_utils.c:304
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:342
#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_LONG
Identifier for the signed 32-bit integer data type.
Definition SDDStypes.h:61
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37
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
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.