SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
wfm2sdds.c
Go to the documentation of this file.
1/**
2 * @file wfm2sdds.c
3 * @brief Converts binary WFM data from Tektronix TDS oscilloscopes into SDDS format.
4 *
5 * @details
6 * This program converts Tektronix WFM files to SDDS (Self Describing Data Sets).
7 * It supports ASCII and binary output formats and allows customization via options
8 * such as including an index column and specifying numerical precision.
9 *
10 * @section Usage
11 * ```
12 * wfm2sdds [<inputFile>] [<outputFile>]
13 * [-pipe[=in][,out]]
14 * [-ascii | -binary]
15 * [-withIndex]
16 * [-float | -double]
17 * [-dumpHeader]
18 * ```
19 *
20 * @section Options
21 * | Optional | Description |
22 * |-----------------|------------------------------------------|
23 * | `-pipe` | Use pipes for input/output streams. |
24 * | `-ascii` | Requests SDDS ASCII output. Default is binary. |
25 * | `-binary` | Requests SDDS binary output. |
26 * | `-withIndex` | Adds an Index column to the output. |
27 * | `-float` | Outputs data in float format. Default is double. |
28 * | `-double` | Outputs data in double format. |
29 * | `-dumpHeader` | Prints WFM file header info to stdout. |
30 *
31 * @subsection Incompatibilities
32 * - `-ascii` is incompatible with `-binary`.
33 * - `-float` is incompatible with `-double`.
34 *
35 * @copyright
36 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
37 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
38 *
39 * @license
40 * This file is distributed under the terms of the Software License Agreement
41 * found in the file LICENSE included with this distribution.
42 *
43 * @author
44 * R. Soliday
45 */
46
47#if defined(__MINGW32__)
48# define __USE_MINGW_ANSI_STDIO 1
49#endif
50#include "mdb.h"
51#include "SDDS.h"
52#include "scan.h"
53#if defined(_WIN32)
54# include <io.h>
55# include <fcntl.h>
56# if defined(__BORLANDC__)
57# define _setmode(handle, amode) setmode(handle, amode)
58# endif
59#endif
60
61void swapdouble(double *l);
62void swapfloat(float *l);
63void swaplongLong(uint64_t *l);
64void swaplong(uint32_t *l);
65void swapshort(short *l);
66
67void swaplonglong(uint64_t *l) {
68 unsigned char *cp = (unsigned char *)l;
69 unsigned char temp;
70
71 temp = cp[0];
72 cp[0] = cp[7];
73 cp[7] = temp;
74 temp = cp[1];
75 cp[1] = cp[6];
76 cp[6] = temp;
77 temp = cp[2];
78 cp[2] = cp[5];
79 cp[5] = temp;
80 temp = cp[3];
81 cp[3] = cp[4];
82 cp[4] = temp;
83}
84
85void swapdouble(double *l) {
86 unsigned char *cp = (unsigned char *)l;
87 unsigned char temp;
88
89 temp = cp[0];
90 cp[0] = cp[7];
91 cp[7] = temp;
92 temp = cp[1];
93 cp[1] = cp[6];
94 cp[6] = temp;
95 temp = cp[2];
96 cp[2] = cp[5];
97 cp[5] = temp;
98 temp = cp[3];
99 cp[3] = cp[4];
100 cp[4] = temp;
101}
102
103void swapfloat(float *l) {
104 unsigned char *cp = (unsigned char *)l;
105 unsigned char temp;
106
107 temp = cp[0];
108 cp[0] = cp[3];
109 cp[3] = temp;
110 temp = cp[1];
111 cp[1] = cp[2];
112 cp[2] = temp;
113}
114
115void swaplong(uint32_t *l) {
116 unsigned char *cp = (unsigned char *)l;
117 unsigned char temp;
118
119 temp = cp[0];
120 cp[0] = cp[3];
121 cp[3] = temp;
122 temp = cp[1];
123 cp[1] = cp[2];
124 cp[2] = temp;
125}
126
127void swapshort(short *l) {
128 unsigned char *cp = (unsigned char *)l;
129 unsigned char temp;
130
131 temp = cp[0];
132 cp[0] = cp[1];
133 cp[1] = temp;
134}
135
136int INTEL = 0;
137
138#define SET_ASCII 0
139#define SET_BINARY 1
140#define SET_DUMPHEADER 2
141#define SET_PIPE 3
142#define SET_WITHINDEX 4
143#define SET_FLOAT 5
144#define SET_DOUBLE 6
145#define N_OPTIONS 7
146
147char *option[N_OPTIONS] = {
148 "ascii", "binary", "dumpheader", "pipe", "withindex", "float", "double"};
149
150char *USAGE =
151 "Usage: wfm2sdds [<inputFile>] [<outputFile>]\n"
152 " [-pipe[=in][,out]]\n"
153 " [-ascii | -binary]\n"
154 " [-withIndex]\n"
155 " [-float | -double]\n"
156 " [-dumpHeader]\n"
157 "\nOptions:\n"
158 " -pipe[=in][,out] SDDS toolkit pipe option.\n"
159 " -ascii Requests SDDS ASCII output. Default is binary.\n"
160 " -binary Requests SDDS BINARY output.\n"
161 " -withIndex Add Index column.\n"
162 " -float Output in float format. Default is double.\n"
163 " -double Output in double format.\n"
164 " -dumpHeader Print all header info to stdout.\n"
165 "\n"
166 "Converts Tektronix WFM files to SDDS.\n"
167 "Program by Robert Soliday. (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ")\n";
168
169int main(int argc, char **argv) {
170 FILE *fd;
171 char *input = NULL, *output = NULL;
172 SDDS_DATASET SDDSout;
173 SCANNED_ARG *scanned;
174 long iArg;
175 long ascii = 0, dumpheader = 0;
176 unsigned long pipeFlags = 0;
177 int i = 0, j = 0, n;
178 int withIndex = 0, floatValues = 0, version = 0;
179
180 /*
181 1=char
182 2=short
183 3=unsigned short
184 4=long
185 5=unsigned long
186 6=unsigned long long
187 7=float
188 8=double
189 9=char[]
190 */
191
192 short fileFormat[122] =
193 {3, 9, 1, 4, 1, 4, 4, 7, 8, 7, 9, 5, 3, 5, 5, 6, 6, 5, 4, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 3, 5, 6, 8, 8, 5, 9, 8, 8, 8, 8, 5, 5, 4, 4, 4, 4, 4, 8, 9, 8, 5, 8, 8, 8, 8, 5, 9, 8, 8, 8, 8, 5, 5, 4, 4, 4, 4, 4, 8, 9, 8, 5, 8, 8, 8, 8, 5, 9, 8, 8, 8, 8, 5, 8, 9, 8, 5, 8, 8, 8, 8, 5, 9, 8, 8, 8, 8, 5,
194 8, 9, 8, 5, 8, 8, 5, 5, 5, 5, 5, 5, 5, 8, 8, 4, 7, 5, 2, 5, 5, 5, 5, 5};
195 short fileBits[122] =
196 {2, 8, 1, 4, 1, 4, 4, 4, 8, 4, 32, 4, 2, 4, 4, 8, 8, 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 2, 4, 8, 8, 8, 4, 20, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 8, 20, 8, 4, 8, 8, 8, 8, 4, 20, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 8, 20, 8, 4, 8, 8, 8, 8, 4, 20, 8, 8, 8, 8, 4, 8, 20, 8, 4, 8, 8, 8, 8, 4, 20, 8, 8,
197 8, 8, 4, 8, 20, 8, 4, 8, 8, 4, 4, 4, 4, 4, 4, 4, 8, 8, 4, 4, 4, 2, 4, 4, 4, 4, 4};
198
199 char Char;
200 unsigned char uChar;
201 short Short;
202 unsigned short uShort;
203 int32_t Long;
204 uint32_t uLong;
205 uint64_t uLLong;
206 float Float;
207 double Double;
208 char buffer[50];
209
210 short bytesPerPoint = 2;
211 unsigned long prechargeoffset = 0;
212 unsigned long *precharge;
213 unsigned long RecLength = 0;
214 unsigned long *recordLength;
215 unsigned long postchargestart = 0, postchargestop = 0, postcharge;
216 double sampleInterval = 1;
217 char sampleUnits[50];
218 double sampleStart = 0;
219 double triggerPositionPercent = 0;
220 int32_t *triggerPoint;
221 long timeInt;
222 double *time;
223 double timeFrac = 0;
224 double expDimInterval = 1, expDimStart = 0;
225 char expDimUnits[50];
226 int32_t *index = NULL;
227 double *sample = NULL, *curve = NULL;
228 uint32_t waveform, waveforms = 1;
229 uint32_t dataType = 0;
230
232 argc = scanargs(&scanned, argc, argv);
233 if (argc < 2) {
234 fprintf(stderr, "%s", USAGE);
235 return (EXIT_FAILURE);
236 }
237
238 for (iArg = 1; iArg < argc; iArg++) {
239 if (scanned[iArg].arg_type == OPTION) {
240 switch (match_string(scanned[iArg].list[0], option, N_OPTIONS, 0)) {
241 case SET_ASCII:
242 ascii = 1;
243 break;
244 case SET_BINARY:
245 ascii = 0;
246 break;
247 case SET_DUMPHEADER:
248 dumpheader = 1;
249 break;
250 case SET_WITHINDEX:
251 withIndex = 1;
252 break;
253 case SET_FLOAT:
254 floatValues = 1;
255 break;
256 case SET_DOUBLE:
257 floatValues = 0;
258 break;
259 case SET_PIPE:
260 if (!processPipeOption(scanned[iArg].list + 1, scanned[iArg].n_items - 1, &pipeFlags)) {
261 fprintf(stderr, "invalid -pipe syntax\n");
262 return (EXIT_FAILURE);
263 }
264 break;
265 default:
266 fprintf(stderr, "invalid option seen\n");
267 fprintf(stderr, "%s", USAGE);
268 return (EXIT_FAILURE);
269 }
270 } else {
271 if (!input)
272 input = scanned[iArg].list[0];
273 else if (!output)
274 output = scanned[iArg].list[0];
275 else {
276 fprintf(stderr, "too many filenames\n");
277 fprintf(stderr, "%s", USAGE);
278 return (EXIT_FAILURE);
279 }
280 }
281 }
282
283 processFilenames("wfm2sdds", &input, &output, pipeFlags, 0, NULL);
284
285 if (input) {
286 if (!fexists(input)) {
287 fprintf(stderr, "input file not found\n");
288 return (EXIT_FAILURE);
289 }
290 if (!(fd = fopen(input, "rb"))) {
291 fprintf(stderr, "problem opening input file\n");
292 return (EXIT_FAILURE);
293 }
294 } else {
295#if defined(_WIN32)
296 if (_setmode(_fileno(stdin), _O_BINARY) == -1) {
297 fprintf(stderr, "error: unable to set stdin to binary mode\n");
298 return (EXIT_FAILURE);
299 }
300#endif
301 fd = stdin;
302 }
303
304 if (dumpheader) {
305 fprintf(stdout, "Read www.tektronix.com/Measurement/Solutions/openchoice/docs/articles/001137801.pdf for definitions for the header elements.\n");
306 }
307 for (i = 0; i < 110; i++) {
308 if ((i == 29) && (version == 1)) {
309 continue;
310 }
311 n = 0;
312 if (fileFormat[i] == 1) {
313 n = fread(&Char, 1, 1, fd);
314 } else if (fileFormat[i] == 2) {
315 n = fread(&Short, 1, 2, fd);
316 if (INTEL) {
317 swapshort((short *)&Short);
318 }
319 } else if (fileFormat[i] == 3) {
320 n = fread(&uShort, 1, 2, fd);
321 if (INTEL) {
322 swapshort((short *)&uShort);
323 }
324 } else if (fileFormat[i] == 4) {
325 n = fread(&Long, 1, 4, fd);
326 if (INTEL) {
327 swaplong((uint32_t *)&Long);
328 }
329 } else if (fileFormat[i] == 5) {
330 n = fread(&uLong, 1, 4, fd);
331 if (INTEL) {
332 swaplong((uint32_t *)&uLong);
333 }
334 } else if (fileFormat[i] == 6) {
335 n = fread(&uLLong, 1, 8, fd);
336 if (INTEL) {
337 swaplonglong((uint64_t *)&uLLong);
338 }
339 } else if (fileFormat[i] == 7) {
340 n = fread(&Float, 1, 4, fd);
341 if (INTEL) {
342 swapfloat((float *)&Float);
343 }
344 } else if (fileFormat[i] == 8) {
345 n = fread(&Double, 1, 8, fd);
346 if (INTEL) {
347 swapdouble((double *)&Double);
348 }
349 } else if (fileFormat[i] == 9) {
350 n = fread(buffer, 1, fileBits[i], fd);
351 buffer[fileBits[i]] = '\0';
352 }
353
354 if (n != fileBits[i]) {
355 fprintf(stderr, "Error: unable to read data from input file\n");
356 return (EXIT_FAILURE);
357 }
358 if (dumpheader) {
359 fprintf(stdout, "#%d \tBit Offset=%d \t", i, j);
360 if (fileFormat[i] == 1) {
361 fprintf(stdout, "Char = %d\n", Char);
362 } else if (fileFormat[i] == 2) {
363 fprintf(stdout, "Short = %d\n", Short);
364 } else if (fileFormat[i] == 3) {
365 fprintf(stdout, "uShort = %u\n", uShort);
366 } else if (fileFormat[i] == 4) {
367 fprintf(stdout, "Long = %" PRId32 "\n", Long);
368 } else if (fileFormat[i] == 5) {
369 fprintf(stdout, "uLong = %" PRIu32 "\n", uLong);
370 } else if (fileFormat[i] == 6) {
371 fprintf(stdout, "uLLong = %" PRIu64 "\n", uLLong);
372 } else if (fileFormat[i] == 7) {
373 fprintf(stdout, "Float = %15.15f\n", Float);
374 } else if (fileFormat[i] == 8) {
375 fprintf(stdout, "Double = %15.15lf\n", Double);
376 } else if (fileFormat[i] == 9) {
377 fprintf(stdout, "Char[] = %s\n", buffer);
378 }
379 j += fileBits[i];
380 }
381 if (i == 0) {
382 if (uShort == 3855) {
384 INTEL = 1;
385 else
386 INTEL = 0;
387 } else if (uShort == 61680) {
389 INTEL = 0;
390 else
391 INTEL = 1;
392 } else {
393 fprintf(stderr, "Error: invalid WFM file\n");
394 return (EXIT_FAILURE);
395 }
396 }
397 if (i == 1) {
398 if (strcmp(buffer, ":WFM#001") == 0) {
399 version = 1;
400 } else if (strcmp(buffer, ":WFM#002") == 0) {
401 version = 2;
402 } else if (strcmp(buffer, ":WFM#003") == 0) {
403 version = 3;
404 fileFormat[50] = 8;
405 fileBits[50] = 8;
406 fileFormat[71] = 8;
407 fileBits[71] = 8;
408 fileFormat[86] = 8;
409 fileBits[86] = 8;
410 fileFormat[101] = 8;
411 fileBits[101] = 8;
412 } else {
413 fprintf(stderr, "Error: invalid WFM file, expected :WFM#001, :WFM#002 or :WFM#003 as version number.\n");
414 return (EXIT_FAILURE);
415 }
416 }
417 if (i == 4) {
418 bytesPerPoint = Char;
419 }
420 if (i == 11) {
421 if (uLong != 0) {
422 waveforms = uLong + 1;
423 };
424 }
425 if (i == 14) {
426 if (uLong != 1) {
427 fprintf(stderr, "Error: cannot convert WFM files that include multiple waveforms.\n");
428 return (EXIT_FAILURE);
429 };
430 }
431 if (i == 20) {
432 if (uLong != 1) {
433 fprintf(stderr, "Error: cannot convert WFM files that include multiple implicit dimensions.\n");
434 return (EXIT_FAILURE);
435 };
436 }
437 if (i == 21) {
438 if (uLong != 1) {
439 fprintf(stderr, "Error: cannot convert WFM files that include multiple explicit dimensions.\n");
440 return (EXIT_FAILURE);
441 };
442 }
443 if (i == 22) {
444 if (uLong != 2) {
445 fprintf(stderr, "Error: cannot convert WFM files that don't include WFMDATA_VECTOR data.\n");
446 return (EXIT_FAILURE);
447 };
448 }
449 if (i == 26) {
450 if (uLong != 1) {
451 fprintf(stderr, "Error: cannot convert WFM files that include multiple curve objects.\n");
452 return (EXIT_FAILURE);
453 };
454 }
455 if (i == 32) {
456 expDimInterval = Double;
457 }
458 if (i == 33) {
459 expDimStart = Double;
460 }
461 if (i == 35) {
462 sprintf(expDimUnits, "%s", buffer);
463 }
464 if (i == 40) {
465 dataType = uLong;
466 }
467 if (i == 41) {
468 if ((uLong != 0) && (uLong != 1)) {
469 fprintf(stderr, "Error: Unable to convert WMF file due to unsupported data storage layout.\n");
470 return (EXIT_FAILURE);
471 };
472 }
473 if (i == 51) {
474 triggerPositionPercent = Double;
475 }
476 if (i == 74) {
477 sampleInterval = Double;
478 }
479 if (i == 75) {
480 sampleStart = Double;
481 }
482 if (i == 76) {
483 RecLength = uLong;
484 }
485 if (i == 77) {
486 sprintf(sampleUnits, "%s", buffer);
487 }
488 }
489
490 time = malloc(sizeof(double) * waveforms);
491 precharge = malloc(sizeof(unsigned long) * waveforms);
492 recordLength = malloc(sizeof(unsigned long) * waveforms);
493 triggerPoint = malloc(sizeof(int32_t) * waveforms);
494
495 time[0] = 0;
496 precharge[0] = 0;
497 recordLength[0] = 0;
498 triggerPoint[0] = 0;
499 for (i = 110; i < 122; i++) {
500 n = 0;
501 if (fileFormat[i] == 1) {
502 n = fread(&Char, 1, 1, fd);
503 } else if (fileFormat[i] == 2) {
504 n = fread(&Short, 1, 2, fd);
505 if (INTEL) {
506 swapshort((short *)&Short);
507 }
508 } else if (fileFormat[i] == 3) {
509 n = fread(&uShort, 1, 2, fd);
510 if (INTEL) {
511 swapshort((short *)&uShort);
512 }
513 } else if (fileFormat[i] == 4) {
514 n = fread(&Long, 1, 4, fd);
515 if (INTEL) {
516 swaplong((uint32_t *)&Long);
517 }
518 } else if (fileFormat[i] == 5) {
519 n = fread(&uLong, 1, 4, fd);
520 if (INTEL) {
521 swaplong((uint32_t *)&uLong);
522 }
523 } else if (fileFormat[i] == 6) {
524 n = fread(&uLLong, 1, 8, fd);
525 if (INTEL) {
526 swaplonglong((uint64_t *)&uLLong);
527 }
528 } else if (fileFormat[i] == 7) {
529 n = fread(&Float, 1, 4, fd);
530 if (INTEL) {
531 swapfloat((float *)&Float);
532 }
533 } else if (fileFormat[i] == 8) {
534 n = fread(&Double, 1, 8, fd);
535 if (INTEL) {
536 swapdouble((double *)&Double);
537 }
538 } else if (fileFormat[i] == 9) {
539 n = fread(buffer, 1, fileBits[i], fd);
540 buffer[fileBits[i]] = '\0';
541 }
542
543 if (n != fileBits[i]) {
544 fprintf(stderr, "Error: unable to read data from input file\n");
545 return (EXIT_FAILURE);
546 }
547 if (dumpheader) {
548 fprintf(stdout, "#%d \tBit Offset=%d \t", i, j);
549 if (fileFormat[i] == 1) {
550 fprintf(stdout, "Char = %d\n", Char);
551 } else if (fileFormat[i] == 2) {
552 fprintf(stdout, "Short = %d\n", Short);
553 } else if (fileFormat[i] == 3) {
554 fprintf(stdout, "uShort = %u\n", uShort);
555 } else if (fileFormat[i] == 4) {
556 fprintf(stdout, "Long = %" PRId32 "\n", Long);
557 } else if (fileFormat[i] == 5) {
558 fprintf(stdout, "uLong = %" PRIu32 "\n", uLong);
559 } else if (fileFormat[i] == 6) {
560 fprintf(stdout, "uLLong = %" PRIu64 "\n", uLLong);
561 } else if (fileFormat[i] == 7) {
562 fprintf(stdout, "Float = %15.15f\n", Float);
563 } else if (fileFormat[i] == 8) {
564 fprintf(stdout, "Double = %15.15lf\n", Double);
565 } else if (fileFormat[i] == 9) {
566 fprintf(stdout, "Char[] = %s\n", buffer);
567 }
568 j += fileBits[i];
569 }
570 if (i == 112) {
571 timeFrac = Double;
572 }
573 if (i == 113) {
574 timeInt = Long;
575 time[0] = timeInt + timeFrac;
576 }
577 if (i == 117) {
578 prechargeoffset = uLong;
579 precharge[0] = prechargeoffset / bytesPerPoint;
580 }
581 if (i == 119) {
582 postchargestart = uLong;
583 }
584 if (i == 120) {
585 postchargestop = uLong;
586 postcharge = (postchargestop - postchargestart) / bytesPerPoint;
587 recordLength[0] = RecLength - precharge[0] - postcharge;
588 triggerPoint[0] = round(recordLength[0] * (triggerPositionPercent / 100));
589 }
590 }
591
592 for (waveform = 1; waveform < waveforms; waveform++) {
593 time[waveform] = 0;
594 precharge[waveform] = 0;
595 recordLength[waveform] = 0;
596 triggerPoint[waveform] = 0;
597 for (i = 110; i < 114; i++) {
598 n = 0;
599 if (fileFormat[i] == 1) {
600 n = fread(&Char, 1, 1, fd);
601 } else if (fileFormat[i] == 2) {
602 n = fread(&Short, 1, 2, fd);
603 if (INTEL) {
604 swapshort((short *)&Short);
605 }
606 } else if (fileFormat[i] == 3) {
607 n = fread(&uShort, 1, 2, fd);
608 if (INTEL) {
609 swapshort((short *)&uShort);
610 }
611 } else if (fileFormat[i] == 4) {
612 n = fread(&Long, 1, 4, fd);
613 if (INTEL) {
614 swaplong((uint32_t *)&Long);
615 }
616 } else if (fileFormat[i] == 5) {
617 n = fread(&uLong, 1, 4, fd);
618 if (INTEL) {
619 swaplong((uint32_t *)&uLong);
620 }
621 } else if (fileFormat[i] == 6) {
622 n = fread(&uLLong, 1, 8, fd);
623 if (INTEL) {
624 swaplonglong((uint64_t *)&uLLong);
625 }
626 } else if (fileFormat[i] == 7) {
627 n = fread(&Float, 1, 4, fd);
628 if (INTEL) {
629 swapfloat((float *)&Float);
630 }
631 } else if (fileFormat[i] == 8) {
632 n = fread(&Double, 1, 8, fd);
633 if (INTEL) {
634 swapdouble((double *)&Double);
635 }
636 } else if (fileFormat[i] == 9) {
637 n = fread(buffer, 1, fileBits[i], fd);
638 buffer[fileBits[i]] = '\0';
639 }
640
641 if (n != fileBits[i]) {
642 fprintf(stderr, "Error: unable to read data from input file\n");
643 return (EXIT_FAILURE);
644 }
645 if (dumpheader) {
646 fprintf(stdout, "#%d \tBit Offset=%d \t", i, j);
647 if (fileFormat[i] == 1) {
648 fprintf(stdout, "Char = %d\n", Char);
649 } else if (fileFormat[i] == 2) {
650 fprintf(stdout, "Short = %d\n", Short);
651 } else if (fileFormat[i] == 3) {
652 fprintf(stdout, "uShort = %u\n", uShort);
653 } else if (fileFormat[i] == 4) {
654 fprintf(stdout, "Long = %" PRId32 "\n", Long);
655 } else if (fileFormat[i] == 5) {
656 fprintf(stdout, "uLong = %" PRIu32 "\n", uLong);
657 } else if (fileFormat[i] == 6) {
658 fprintf(stdout, "uLLong = %" PRIu64 "\n", uLLong);
659 } else if (fileFormat[i] == 7) {
660 fprintf(stdout, "Float = %15.15f\n", Float);
661 } else if (fileFormat[i] == 8) {
662 fprintf(stdout, "Double = %15.15lf\n", Double);
663 } else if (fileFormat[i] == 9) {
664 fprintf(stdout, "Char[] = %s\n", buffer);
665 }
666 j += fileBits[i];
667 }
668 if (i == 112) {
669 timeFrac = Double;
670 }
671 if (i == 113) {
672 timeInt = Long;
673 time[waveform] = timeInt + timeFrac;
674 }
675 }
676 }
677 for (waveform = 1; waveform < waveforms; waveform++) {
678 for (i = 114; i < 122; i++) {
679 n = 0;
680 if (fileFormat[i] == 1) {
681 n = fread(&Char, 1, 1, fd);
682 } else if (fileFormat[i] == 2) {
683 n = fread(&Short, 1, 2, fd);
684 if (INTEL) {
685 swapshort((short *)&Short);
686 }
687 } else if (fileFormat[i] == 3) {
688 n = fread(&uShort, 1, 2, fd);
689 if (INTEL) {
690 swapshort((short *)&uShort);
691 }
692 } else if (fileFormat[i] == 4) {
693 n = fread(&Long, 1, 4, fd);
694 if (INTEL) {
695 swaplong((uint32_t *)&Long);
696 }
697 } else if (fileFormat[i] == 5) {
698 n = fread(&uLong, 1, 4, fd);
699 if (INTEL) {
700 swaplong((uint32_t *)&uLong);
701 }
702 } else if (fileFormat[i] == 6) {
703 n = fread(&uLLong, 1, 8, fd);
704 if (INTEL) {
705 swaplonglong((uint64_t *)&uLLong);
706 }
707 } else if (fileFormat[i] == 7) {
708 n = fread(&Float, 1, 4, fd);
709 if (INTEL) {
710 swapfloat((float *)&Float);
711 }
712 } else if (fileFormat[i] == 8) {
713 n = fread(&Double, 1, 8, fd);
714 if (INTEL) {
715 swapdouble((double *)&Double);
716 }
717 } else if (fileFormat[i] == 9) {
718 n = fread(buffer, 1, fileBits[i], fd);
719 buffer[fileBits[i]] = '\0';
720 }
721
722 if (n != fileBits[i]) {
723 fprintf(stderr, "Error: unable to read data from input file\n");
724 return (EXIT_FAILURE);
725 }
726 if (dumpheader) {
727 fprintf(stdout, "#%d \tBit Offset=%d \t", i, j);
728 if (fileFormat[i] == 1) {
729 fprintf(stdout, "Char = %d\n", Char);
730 } else if (fileFormat[i] == 2) {
731 fprintf(stdout, "Short = %d\n", Short);
732 } else if (fileFormat[i] == 3) {
733 fprintf(stdout, "uShort = %u\n", uShort);
734 } else if (fileFormat[i] == 4) {
735 fprintf(stdout, "Long = %" PRId32 "\n", Long);
736 } else if (fileFormat[i] == 5) {
737 fprintf(stdout, "uLong = %" PRIu32 "\n", uLong);
738 } else if (fileFormat[i] == 6) {
739 fprintf(stdout, "uLLong = %" PRIu64 "\n", uLLong);
740 } else if (fileFormat[i] == 7) {
741 fprintf(stdout, "Float = %15.15f\n", Float);
742 } else if (fileFormat[i] == 8) {
743 fprintf(stdout, "Double = %15.15lf\n", Double);
744 } else if (fileFormat[i] == 9) {
745 fprintf(stdout, "Char[] = %s\n", buffer);
746 }
747 j += fileBits[i];
748 }
749 if (i == 117) {
750 prechargeoffset = uLong;
751 precharge[waveform] = prechargeoffset / bytesPerPoint;
752 }
753 if (i == 119) {
754 postchargestart = uLong;
755 }
756 if (i == 120) {
757 postchargestop = uLong;
758 postcharge = (postchargestop - postchargestart) / bytesPerPoint;
759 recordLength[waveform] = RecLength - precharge[waveform] - postcharge;
760 triggerPoint[waveform] = round(recordLength[waveform] * (triggerPositionPercent / 100));
761 }
762 }
763 }
764
765 if (!SDDS_InitializeOutput(&SDDSout, ascii ? SDDS_ASCII : SDDS_BINARY, 1, NULL, NULL, output)) {
766 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
767 return (EXIT_FAILURE);
768 }
769 if (!SDDS_DefineSimpleParameter(&SDDSout, "TriggerPoint", NULL, SDDS_LONG)) {
770 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
771 return (EXIT_FAILURE);
772 }
773 if (!SDDS_DefineSimpleParameter(&SDDSout, "SampleInterval", NULL, SDDS_DOUBLE)) {
774 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
775 return (EXIT_FAILURE);
776 }
777 if (!SDDS_DefineSimpleParameter(&SDDSout, "Time", NULL, SDDS_DOUBLE)) {
778 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
779 return (EXIT_FAILURE);
780 }
781 if (withIndex) {
782 if (!SDDS_DefineSimpleColumn(&SDDSout, "Index", NULL, SDDS_LONG)) {
783 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
784 return (EXIT_FAILURE);
785 }
786 }
787 if (!SDDS_DefineSimpleColumn(&SDDSout, "t", sampleUnits, floatValues ? SDDS_FLOAT : SDDS_DOUBLE)) {
788 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
789 return (EXIT_FAILURE);
790 }
791 if (!SDDS_DefineSimpleColumn(&SDDSout, "Signal", expDimUnits, floatValues ? SDDS_FLOAT : SDDS_DOUBLE)) {
792 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
793 return (EXIT_FAILURE);
794 }
795 if (!SDDS_WriteLayout(&SDDSout)) {
796 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
797 return (EXIT_FAILURE);
798 }
799
800 for (waveform = 0; waveform < waveforms; waveform++) {
801 if (withIndex) {
802 index = malloc(sizeof(int32_t) * recordLength[waveform]);
803 if (!index) {
804 fprintf(stderr, "Error: Memory allocation failed for index.\n");
805 return (EXIT_FAILURE);
806 }
807 }
808 sample = malloc(sizeof(double) * recordLength[waveform]);
809 curve = malloc(sizeof(double) * recordLength[waveform]);
810 if ((!sample) || (!curve)) {
811 fprintf(stderr, "Error: Memory allocation failed for sample or curve.\n");
812 return (EXIT_FAILURE);
813 }
814
815 for (i = 0; i < precharge[waveform]; i++) {
816 n = fread(&Short, 1, 2, fd);
817 if (n != 2) {
818 fprintf(stderr, "Error: unable to read precharge data from input file\n");
819 return (EXIT_FAILURE);
820 }
821 }
822
823 for (i = 0; i < recordLength[waveform]; i++) {
824 switch (dataType) {
825 case 0:
826 n = fread(&Short, 1, 2, fd);
827 if (INTEL)
828 swapshort((short *)&Short);
829 if (n != 2)
830 goto read_error;
831 sample[i] = sampleStart + (sampleInterval * i);
832 curve[i] = expDimStart + (Short * expDimInterval);
833 break;
834 case 1:
835 n = fread(&Long, 1, 4, fd);
836 if (INTEL)
837 swaplong((uint32_t *)&Long);
838 if (n != 4)
839 goto read_error;
840 sample[i] = sampleStart + (sampleInterval * i);
841 curve[i] = expDimStart + (Long * expDimInterval);
842 break;
843 case 2:
844 n = fread(&uLong, 1, 4, fd);
845 if (INTEL)
846 swaplong((uint32_t *)&uLong);
847 if (n != 4)
848 goto read_error;
849 sample[i] = sampleStart + (sampleInterval * i);
850 curve[i] = expDimStart + (uLong * expDimInterval);
851 break;
852 case 3:
853 n = fread(&uLLong, 1, 8, fd);
854 if (INTEL)
855 swaplonglong((uint64_t *)&uLLong);
856 if (n != 8)
857 goto read_error;
858 sample[i] = sampleStart + (sampleInterval * i);
859 curve[i] = expDimStart + (uLLong * expDimInterval);
860 break;
861 case 4:
862 n = fread(&Float, 1, 4, fd);
863 if (INTEL)
864 swapfloat((float *)&Float);
865 if (n != 4)
866 goto read_error;
867 sample[i] = sampleStart + (sampleInterval * i);
868 curve[i] = expDimStart + (Float * expDimInterval);
869 break;
870 case 5:
871 n = fread(&Double, 1, 8, fd);
872 if (INTEL)
873 swapdouble((double *)&Double);
874 if (n != 8)
875 goto read_error;
876 sample[i] = sampleStart + (sampleInterval * i);
877 curve[i] = expDimStart + (Double * expDimInterval);
878 break;
879 case 6:
880 n = fread(&uChar, 1, 1, fd);
881 if (n != 1)
882 goto read_error;
883 sample[i] = sampleStart + (sampleInterval * i);
884 curve[i] = expDimStart + (uChar * expDimInterval);
885 break;
886 case 7:
887 n = fread(&Char, 1, 1, fd);
888 if (n != 1)
889 goto read_error;
890 sample[i] = sampleStart + (sampleInterval * i);
891 curve[i] = expDimStart + (Char * expDimInterval);
892 break;
893 default:
894 fprintf(stderr, "Error: Unsupported data type encountered.\n");
895 return (EXIT_FAILURE);
896 }
897 }
898
899 // Skip any remaining data in the record
900 for (i = recordLength[waveform]; i < RecLength; i++) {
901 n = fread(&Short, 1, 2, fd);
902 if (n != 2) {
903 fprintf(stderr, "Error: unable to read postcharge data from input file\n");
904 return (EXIT_FAILURE);
905 }
906 }
907
908 if (withIndex) {
909 for (i = 0; i < recordLength[waveform]; i++) {
910 index[i] = i;
911 }
912 }
913
914 if (!SDDS_StartTable(&SDDSout, recordLength[waveform])) {
915 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
916 return (EXIT_FAILURE);
917 }
918 if (!SDDS_SetParameters(&SDDSout, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE,
919 "TriggerPoint", triggerPoint[waveform],
920 "SampleInterval", sampleInterval,
921 "Time", time[waveform],
922 NULL)) {
923 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
924 return (EXIT_FAILURE);
925 }
926 if (withIndex) {
927 if (!SDDS_SetColumnFromLongs(&SDDSout, SDDS_SET_BY_NAME, index, recordLength[waveform], "Index")) {
928 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
929 return (EXIT_FAILURE);
930 }
931 }
932 if (!SDDS_SetColumnFromDoubles(&SDDSout, SDDS_SET_BY_NAME, sample, recordLength[waveform], "t")) {
933 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
934 return (EXIT_FAILURE);
935 }
936 if (!SDDS_SetColumnFromDoubles(&SDDSout, SDDS_SET_BY_NAME, curve, recordLength[waveform], "Signal")) {
937 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
938 return (EXIT_FAILURE);
939 }
940 if (!SDDS_WriteTable(&SDDSout)) {
941 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
942 return (EXIT_FAILURE);
943 }
944 if (withIndex)
945 free(index);
946 free(sample);
947 free(curve);
948 continue;
949
950 read_error:
951 fprintf(stderr, "Error: unable to read data from input file\n");
952 return (EXIT_FAILURE);
953 }
954
955 fclose(fd);
956
957 if (!SDDS_Terminate(&SDDSout)) {
958 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
959 return (EXIT_FAILURE);
960 }
961
962 free_scanargs(&scanned, argc);
963
964 return (EXIT_SUCCESS);
965}
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_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_SetColumnFromLongs(SDDS_DATASET *SDDS_dataset, int32_t mode, int32_t *data, int64_t rows,...)
Sets the values for a single data column using long integer numbers.
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_DefineSimpleColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *unit, int32_t type)
Defines a simple data column within the SDDS dataset.
int32_t SDDS_DefineSimpleParameter(SDDS_DATASET *SDDS_dataset, const char *name, const char *unit, int32_t type)
Defines a simple data parameter 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
int32_t SDDS_IsBigEndianMachine()
Determines whether the current machine uses big-endian byte ordering.
#define SDDS_FLOAT
Identifier for the float data type.
Definition SDDStypes.h:43
#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
long fexists(const char *filename)
Checks if a file exists.
Definition fexists.c:27
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
void free_scanargs(SCANNED_ARG **scanned, int argc)
Definition scanargs.c:584