SDDS ToolKit Programs and Libraries for C and Python
Loading...
Searching...
No Matches
tdms2sdds.c File Reference

Detailed Description

Converts National Instruments' LabVIEW TDMS files to SDDS format.

This program reads National Instruments' LabVIEW TDMS (Technical Data Management Streaming) files and converts them into SDDS (Self Describing Data Sets) format. It supports customization of output, including ASCII or binary formats, segmentation, and other advanced features for better data management.

Usage

tdms2sdds <inputFile> [<outputFile>]
[-pipe=out]
[-ascii | -binary]
[-numOfSegments]
[-segment=<integer>]

Options

Optional Description
-pipe SDDS toolkit pipe option.
-ascii Requests SDDS ASCII output (default).
-binary Requests SDDS binary output.
-numOfSegments Prints the number of TDMS segments in the input file.
-segment Specifies a particular segment to convert.

Incompatibilities

  • Only one of the following may be specified:
    • -ascii
    • -binary
License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
R. Soliday, M. Borland

Definition in file tdms2sdds.c.

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

Go to the source code of this file.

Functions

void TDMS_ReadLeadIn (FILE *fd, TDMS_SEGMENT *segment)
 
void TDMS_ReadMetaData (FILE *fd, TDMS_SEGMENT *segment)
 
void TDMS_ReadRawData (FILE *fd, TDMS_FILE *tdms, uint32_t n_segment, long filesize)
 
void TDMS_GetValue (FILE *fd, void **value, int32_t datatype)
 
int main (int argc, char **argv)
 

Function Documentation

◆ main()

int main ( int argc,
char ** argv )

Definition at line 200 of file tdms2sdds.c.

200 {
201 FILE *fd;
202 char *input = NULL, *output = NULL;
203 SDDS_DATASET SDDSout;
204 SCANNED_ARG *scanned;
205 long iArg;
206 long ascii = 0;
207 unsigned long pipeFlags = 0;
208 int i = 0, n, found, ii, jj, kk, segment = 0, querySegments = 0;
209 long double timeValue;
210 short timeDefined = 0;
211 char buffer[1024];
212
213 TDMS_FILE tdms;
214 uint64_t rows = 0, j = 0, k;
215
217 argc = scanargs(&scanned, argc, argv);
218 if (argc < 2) {
219 fprintf(stderr, "%s", USAGE);
220 return (EXIT_FAILURE);
221 }
222
223 for (iArg = 1; iArg < argc; iArg++) {
224 if (scanned[iArg].arg_type == OPTION) {
225 switch (match_string(scanned[iArg].list[0], option, N_OPTIONS, 0)) {
226 case SET_ASCII:
227 ascii = 1;
228 break;
229 case SET_BINARY:
230 ascii = 0;
231 break;
232 case SET_SEGMENT:
233 if (scanned[iArg].n_items < 2) {
234 fprintf(stderr, "Error (%s): invalid -segment syntax\n", argv[0]);
235 return (EXIT_FAILURE);
236 }
237 if (sscanf(scanned[iArg].list[1], "%d", &segment) != 1 || segment <= 0) {
238 fprintf(stderr, "Error (%s): invalid -segment syntax or value\n", argv[0]);
239 return (EXIT_FAILURE);
240 }
241 break;
242 case SET_NUMOFSEGMENTS:
243 querySegments = 1;
244 break;
245 case SET_PIPE:
246 if (!processPipeOption(scanned[iArg].list + 1, scanned[iArg].n_items - 1, &pipeFlags)) {
247 fprintf(stderr, "invalid -pipe syntax\n");
248 return (EXIT_FAILURE);
249 }
250 break;
251 default:
252 fprintf(stderr, "invalid option seen\n");
253 fprintf(stderr, "%s", USAGE);
254 return (EXIT_FAILURE);
255 }
256 } else {
257 if (!input)
258 input = scanned[iArg].list[0];
259 else if (!output)
260 output = scanned[iArg].list[0];
261 else {
262 fprintf(stderr, "too many filenames\n");
263 fprintf(stderr, "%s", USAGE);
264 return (EXIT_FAILURE);
265 }
266 }
267 }
268 if (!querySegments) {
269 processFilenames("tdms2sdds", &input, &output, pipeFlags, 0, NULL);
270 }
271
272 if (input) {
273 if (!fexists(input)) {
274 fprintf(stderr, "input file not found\n");
275 return (EXIT_FAILURE);
276 }
277 if (!(fd = fopen(input, "rb"))) {
278 fprintf(stderr, "problem opening input file\n");
279 return (EXIT_FAILURE);
280 }
281 } else {
282 fprintf(stderr, "tdms2sdds cannot -pipe=in tdms files\n");
283 return (EXIT_FAILURE);
284 }
285
286 fseek(fd, 0L, SEEK_END);
287 tdms.filesize = ftell(fd);
288 fseek(fd, 0L, SEEK_SET);
289
290 tdms.n_segments = 0;
291 while (ftell(fd) < tdms.filesize) {
292 tdms.n_segments++;
293 if (tdms.n_segments == 1) {
294 tdms.segment = malloc(sizeof(TDMS_SEGMENT));
295 } else {
296 tdms.segment = realloc(tdms.segment, sizeof(TDMS_SEGMENT) * tdms.n_segments);
297 }
298 /* Read Lead In */
299 TDMS_ReadLeadIn(fd, &(tdms.segment[tdms.n_segments - 1]));
300 if (tdms.segment[tdms.n_segments - 1].lead_in.toc & kTocBigEndian) {
302 fprintf(stderr, "tdms2sdds does not yet support reading from non-native endian TDMS files.\n");
303 return (EXIT_FAILURE);
304 }
305 } else {
307 fprintf(stderr, "tdms2sdds does not yet support reading from non-native endian TDMS files.\n");
308 return (EXIT_FAILURE);
309 }
310 }
311 /* Read Meta Data */
312 if (tdms.segment[tdms.n_segments - 1].lead_in.toc & kTocMetaData) {
313 TDMS_ReadMetaData(fd, &(tdms.segment[tdms.n_segments - 1]));
314 }
315 /* Read Raw Data */
316 if (tdms.segment[tdms.n_segments - 1].lead_in.toc & kTocRawData) {
317 TDMS_ReadRawData(fd, &tdms, tdms.n_segments - 1, tdms.filesize);
318 }
319 }
320 fclose(fd);
321
322 if (querySegments) {
323 fprintf(stdout, "Number of segments: %u\n", tdms.n_segments);
324 return (EXIT_SUCCESS);
325 }
326 if (!SDDS_InitializeOutput(&SDDSout, ascii ? SDDS_ASCII : SDDS_BINARY, 1, NULL, NULL, output)) {
327 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
328 return (EXIT_FAILURE);
329 }
330 if (input) {
331 if (SDDS_DefineParameter(&SDDSout, "TDMSfile", NULL, NULL, NULL, NULL, SDDS_STRING, input) == -1) {
332 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
333 return (EXIT_FAILURE);
334 }
335 }
336 if (segment > tdms.n_segments) {
337 fprintf(stderr, "tdms2sdds: Error: segment selected does not exist\n");
338 return (EXIT_FAILURE);
339 } else {
340 segment--;
341 }
342 for (i = 0; i < tdms.n_segments; i++) {
343 if ((segment != -1) && (segment != i)) {
344 continue;
345 }
346 for (j = 0; j < tdms.segment[i].raw_data.n_channels; j++) {
347 if (j == 0) {
348 rows = tdms.segment[i].raw_data.channel[j].n_values;
349 } else {
350 if (rows != tdms.segment[i].raw_data.channel[j].n_values) {
351 fprintf(stderr, "tdms2sdds: Error: channels in the same TDMS segment have different lengths which is not allowed in SDDS\n");
352 return (EXIT_FAILURE);
353 }
354 }
355 }
356 k = 0;
357 for (j = 0; j < tdms.segment[i].meta_data.n_objects; j++) {
358 found = 0;
359 for (n = 0; n < tdms.segment[i].meta_data.object[j].n_properties; n++) {
360 if (strcmp(tdms.segment[i].meta_data.object[j].property[n].name, "NI_ChannelName") == 0) {
361 found = 1;
362 strcpy(buffer, tdms.segment[i].meta_data.object[j].property[n].value);
363 break;
364 }
365 }
366 if (!found) {
367 strcpy(buffer, tdms.segment[i].meta_data.object[j].path);
368 }
369 if (!edit_string(buffer, "1Z/%g/ /_/%ga/a_a%g/\'//%g/(/[/%g/)/]/%g/=/_eq_/")) {
370 fprintf(stderr, "tdms2sdds: Error: problem editing column label\n");
371 return (EXIT_FAILURE);
372 }
373 /* Check for channel name that starts with a number and prepend a semicolon */
374 if (!(isalpha(*buffer) || strchr(".:", *buffer))) {
375 if (!edit_string(buffer, "i/:/")) {
376 fprintf(stderr, "tdms2sdds: Error: problem editing column label\n");
377 return (EXIT_FAILURE);
378 }
379 }
380 strcpy(tdms.segment[i].meta_data.object[j].path, buffer);
381 if (tdms.segment[i].meta_data.object[j].raw_data_index != 0xFFFFFFFF) {
382 tdms.segment[i].raw_data.channel[k].name = tdms.segment[i].meta_data.object[j].path;
383 tdms.segment[i].raw_data.channel[k].datatype = tdms.segment[i].meta_data.object[j].raw_data_datatype;
384 }
385 if (((segment == -1) && (i == 0)) || (segment != -1)) {
386 if (tdms.segment[i].meta_data.object[j].raw_data_index != 0xFFFFFFFF) {
387 if (timeDefined == 0) {
388 if (tdms.segment[i].xpart.samples > 0) {
389 if (tdms.segment[i].xpart.name == NULL) {
390 tdms.segment[i].xpart.name = malloc(5);
391 sprintf(tdms.segment[i].xpart.name, "Time");
392 }
393 if (!SDDS_DefineSimpleColumn(&SDDSout, tdms.segment[i].xpart.name, tdms.segment[i].xpart.unit, SDDS_DOUBLE)) {
394 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
395 return (EXIT_FAILURE);
396 }
397 timeDefined = 1;
398 }
399 }
400 if ((tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeBoolean) ||
401 (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeU8) ||
402 (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeU16)) {
403 if (!SDDS_DefineSimpleColumn(&SDDSout, tdms.segment[i].meta_data.object[j].path, NULL, SDDS_USHORT)) {
404 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
405 return (EXIT_FAILURE);
406 }
407 } else if ((tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeI8) ||
408 (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeI16)) {
409 if (!SDDS_DefineSimpleColumn(&SDDSout, tdms.segment[i].meta_data.object[j].path, NULL, SDDS_SHORT)) {
410 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
411 return (EXIT_FAILURE);
412 }
413 } else if (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeI32) {
414 if (!SDDS_DefineSimpleColumn(&SDDSout, tdms.segment[i].meta_data.object[j].path, NULL, SDDS_LONG)) {
415 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
416 return (EXIT_FAILURE);
417 }
418 } else if (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeU32) {
419 if (!SDDS_DefineSimpleColumn(&SDDSout, tdms.segment[i].meta_data.object[j].path, NULL, SDDS_ULONG)) {
420 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
421 return (EXIT_FAILURE);
422 }
423 } else if (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeI64) {
424 if (!SDDS_DefineSimpleColumn(&SDDSout, tdms.segment[i].meta_data.object[j].path, NULL, SDDS_LONG64)) {
425 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
426 return (EXIT_FAILURE);
427 }
428 } else if (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeU64) {
429 if (!SDDS_DefineSimpleColumn(&SDDSout, tdms.segment[i].meta_data.object[j].path, NULL, SDDS_ULONG64)) {
430 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
431 return (EXIT_FAILURE);
432 }
433 } else if ((tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeSingleFloat) ||
434 (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeSingleFloatWithUnit)) {
435 if (!SDDS_DefineSimpleColumn(&SDDSout, tdms.segment[i].meta_data.object[j].path, NULL, SDDS_FLOAT)) {
436 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
437 return (EXIT_FAILURE);
438 }
439 } else if ((tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeDoubleFloat) ||
440 (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeDoubleFloatWithUnit) ||
441 (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeTimeStamp)) {
442 if (!SDDS_DefineSimpleColumn(&SDDSout, tdms.segment[i].meta_data.object[j].path, NULL, SDDS_DOUBLE)) {
443 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
444 return (EXIT_FAILURE);
445 }
446 } else if (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeString) {
447 fprintf(stderr, "tdms2sdds: string type channels are not yet supported in tdms2sdds\n");
448 return (EXIT_FAILURE);
449 } else if (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeVoid) {
450 fprintf(stderr, "tdms2sdds: void type channels are not yet supported in tdms2sdds\n");
451 return (EXIT_FAILURE);
452 } else if (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeExtendedFloat) {
453 fprintf(stderr, "tdms2sdds: extended float type channels are not yet supported in tdms2sdds\n");
454 return (EXIT_FAILURE);
455 } else if (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeExtendedFloatWithUnit) {
456 fprintf(stderr, "tdms2sdds: extended float with unit type channels are not yet supported in tdms2sdds\n");
457 return (EXIT_FAILURE);
458 } else if (tdms.segment[i].meta_data.object[j].raw_data_datatype == tdsTypeDAQmxRawData) {
459 fprintf(stderr, "tdms2sdds: DAQmx raw data channels are not yet supported in tdms2sdds\n");
460 return (EXIT_FAILURE);
461 } else {
462 fprintf(stderr, "tdms2sdds: unknown data type\n");
463 return (EXIT_FAILURE);
464 }
465 }
466 for (n = 0; n < tdms.segment[i].meta_data.object[j].n_properties; n++) {
467 if (strcmp(tdms.segment[i].meta_data.object[j].property[n].name, "name") == 0) {
468 continue;
469 }
470 strcpy(buffer, tdms.segment[i].meta_data.object[j].property[n].name);
471 if (!edit_string(buffer, "%g/ /_/%g/\'//%g/(/[/%g/)/]/%g/=/_eq_/")) {
472 fprintf(stderr, "tdms2sdds: Error: problem editing column label\n");
473 return (EXIT_FAILURE);
474 }
475 /* Check for channel name that starts with a number and prepend a semicolon */
476 if (!(isalpha(*buffer) || strchr(".:", *buffer))) {
477 if (!edit_string(buffer, "i/:/")) {
478 fprintf(stderr, "tdms2sdds: Error: problem editing column label\n");
479 return (EXIT_FAILURE);
480 }
481 }
482 strcpy(tdms.segment[i].meta_data.object[j].property[n].name, buffer);
483
484 /* Check if additional channels have the same property names. Only include the first */
485 if (SDDS_GetParameterIndex(&SDDSout, tdms.segment[i].meta_data.object[j].property[n].name) != -1) {
487 continue;
488 }
489 if ((tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeBoolean) ||
490 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeU8) ||
491 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeU16)) {
492 if (!SDDS_DefineSimpleParameter(&SDDSout, tdms.segment[i].meta_data.object[j].property[n].name, NULL, SDDS_USHORT)) {
493 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
494 return (EXIT_FAILURE);
495 }
496 } else if ((tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeI8) ||
497 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeI16)) {
498 if (!SDDS_DefineSimpleParameter(&SDDSout, tdms.segment[i].meta_data.object[j].property[n].name, NULL, SDDS_SHORT)) {
499 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
500 return (EXIT_FAILURE);
501 }
502 } else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeI32) {
503 if (!SDDS_DefineSimpleParameter(&SDDSout, tdms.segment[i].meta_data.object[j].property[n].name, NULL, SDDS_LONG)) {
504 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
505 return (EXIT_FAILURE);
506 }
507 } else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeU32) {
508 if (!SDDS_DefineSimpleParameter(&SDDSout, tdms.segment[i].meta_data.object[j].property[n].name, NULL, SDDS_ULONG)) {
509 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
510 return (EXIT_FAILURE);
511 }
512 } else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeI64) {
513 if (!SDDS_DefineSimpleParameter(&SDDSout, tdms.segment[i].meta_data.object[j].property[n].name, NULL, SDDS_LONG64)) {
514 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
515 return (EXIT_FAILURE);
516 }
517 } else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeU64) {
518 if (!SDDS_DefineSimpleParameter(&SDDSout, tdms.segment[i].meta_data.object[j].property[n].name, NULL, SDDS_ULONG64)) {
519 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
520 return (EXIT_FAILURE);
521 }
522 } else if ((tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeSingleFloat) ||
523 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeSingleFloatWithUnit)) {
524 if (!SDDS_DefineSimpleParameter(&SDDSout, tdms.segment[i].meta_data.object[j].property[n].name, NULL, SDDS_FLOAT)) {
525 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
526 return (EXIT_FAILURE);
527 }
528 } else if ((tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeDoubleFloat) ||
529 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeDoubleFloatWithUnit) ||
530 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeTimeStamp)) {
531 if (!SDDS_DefineSimpleParameter(&SDDSout, tdms.segment[i].meta_data.object[j].property[n].name, NULL, SDDS_DOUBLE)) {
532 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
533 return (EXIT_FAILURE);
534 }
535 } else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeString) {
536 if (!SDDS_DefineSimpleParameter(&SDDSout, tdms.segment[i].meta_data.object[j].property[n].name, NULL, SDDS_STRING)) {
537 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
538 return (EXIT_FAILURE);
539 }
540 } else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeVoid) {
541 fprintf(stderr, "tdms2sdds: void type parameters are not yet supported in tdms2sdds\n");
542 return (EXIT_FAILURE);
543 } else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeExtendedFloat) {
544 fprintf(stderr, "tdms2sdds: extended float type parameters are not yet supported in tdms2sdds\n");
545 return (EXIT_FAILURE);
546 } else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeExtendedFloatWithUnit) {
547 fprintf(stderr, "tdms2sdds: extended float with unit type parameters are not yet supported in tdms2sdds\n");
548 return (EXIT_FAILURE);
549 } else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeDAQmxRawData) {
550 fprintf(stderr, "tdms2sdds: DAQmx raw data parameters are not yet supported in tdms2sdds\n");
551 return (EXIT_FAILURE);
552 } else {
553 fprintf(stderr, "tdms2sdds: unknown data type\n");
554 return (EXIT_FAILURE);
555 }
556 }
557 }
558 if (tdms.segment[i].meta_data.object[j].raw_data_index != 0xFFFFFFFF) {
559 k++;
560 }
561 }
562 if (((segment == -1) && (i == 0)) || (segment != -1)) {
563 if (!SDDS_WriteLayout(&SDDSout)) {
564 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
565 return (EXIT_FAILURE);
566 }
567 }
568 if (!SDDS_StartTable(&SDDSout, rows)) {
569 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
570 return (EXIT_FAILURE);
571 }
572
573 if ((tdms.segment[i].xpart.name != NULL) &&
574 (tdms.segment[i].xpart.samples > 0) &&
575 (tdms.segment[i].raw_data.n_channels > 0)) {
576 timeValue = tdms.segment[i].xpart.start_time + tdms.segment[i].xpart.start_offset;
577 for (j = 0; j < rows; j++) {
578 if (!SDDS_SetRowValues(&SDDSout, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, j, tdms.segment[i].xpart.name, (double)timeValue, NULL)) {
579 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
580 return (EXIT_FAILURE);
581 }
582 timeValue += tdms.segment[i].xpart.increment;
583 }
584 }
585 for (j = 0; j < tdms.segment[i].raw_data.n_channels; j++) {
586 if ((tdms.segment[i].raw_data.channel[j].datatype == tdsTypeI16) ||
587 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeU16) ||
588 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeI32) ||
589 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeU32) ||
590 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeI64) ||
591 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeU64) ||
592 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeSingleFloat) ||
593 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeSingleFloatWithUnit) ||
594 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeDoubleFloat) ||
595 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeDoubleFloatWithUnit) ||
596 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeTimeStamp)) {
597 if (!SDDS_SetColumn(&SDDSout, SDDS_SET_BY_NAME, tdms.segment[i].raw_data.channel[j].values,
598 tdms.segment[i].raw_data.channel[j].n_values, tdms.segment[i].raw_data.channel[j].name)) {
599 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
600 return (EXIT_FAILURE);
601 }
602 } else if ((tdms.segment[i].raw_data.channel[j].datatype == tdsTypeBoolean) ||
603 (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeI8)) {
604 for (k = 0; k < rows; k++) {
605 if (!SDDS_SetRowValues(&SDDSout, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, k,
606 tdms.segment[i].raw_data.channel[j].name,
607 (int16_t)(((int8_t *)(tdms.segment[i].raw_data.channel[j].values))[k]), NULL)) {
608 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
609 return (EXIT_FAILURE);
610 }
611 }
612 } else if (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeU8) {
613 for (k = 0; k < rows; k++) {
614 if (!SDDS_SetRowValues(&SDDSout, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, k,
615 tdms.segment[i].raw_data.channel[j].name,
616 (uint16_t)(((uint8_t *)(tdms.segment[i].raw_data.channel[j].values))[k]), NULL)) {
617 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
618 return (EXIT_FAILURE);
619 }
620 }
621 } else if (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeString) {
622 fprintf(stderr, "tdms2sdds: string type channels are not yet supported in tdms2sdds\n");
623 return (EXIT_FAILURE);
624 } else if (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeVoid) {
625 fprintf(stderr, "tdms2sdds: void type channels are not yet supported in tdms2sdds\n");
626 return (EXIT_FAILURE);
627 } else if (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeExtendedFloat) {
628 fprintf(stderr, "tdms2sdds: extended float type channels are not yet supported in tdms2sdds\n");
629 return (EXIT_FAILURE);
630 } else if (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeExtendedFloatWithUnit) {
631 fprintf(stderr, "tdms2sdds: extended float with unit type channels are not yet supported in tdms2sdds\n");
632 return (EXIT_FAILURE);
633 } else if (tdms.segment[i].raw_data.channel[j].datatype == tdsTypeDAQmxRawData) {
634 fprintf(stderr, "tdms2sdds: DAQmx raw data channels are not yet supported in tdms2sdds\n");
635 return (EXIT_FAILURE);
636 } else {
637 fprintf(stderr, "tdms2sdds: unknown data type\n");
638 return (EXIT_FAILURE);
639 }
640 }
641
642 for (j = 0; j < tdms.segment[i].meta_data.n_objects; j++) {
643 for (n = 0; n < tdms.segment[i].meta_data.object[j].n_properties; n++) {
644 /* Do not write parameter if it wasn't defined in the first segment */
645 if (SDDS_GetParameterIndex(&SDDSout, tdms.segment[i].meta_data.object[j].property[n].name) == -1) {
647 continue;
648 }
649 if ((tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeI16) ||
650 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeU16) ||
651 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeI32) ||
652 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeU32) ||
653 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeI64) ||
654 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeU64) ||
655 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeSingleFloat) ||
656 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeSingleFloatWithUnit) ||
657 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeDoubleFloat) ||
658 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeDoubleFloatWithUnit) ||
659 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeTimeStamp)) {
660 if (!SDDS_SetParameters(&SDDSout, SDDS_SET_BY_NAME | SDDS_PASS_BY_REFERENCE,
661 tdms.segment[i].meta_data.object[j].property[n].name,
662 tdms.segment[i].meta_data.object[j].property[n].value, NULL)) {
663 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
664 return (EXIT_FAILURE);
665 }
666 } else if ((tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeBoolean) ||
667 (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeI8)) {
668 if (!SDDS_SetParameters(&SDDSout, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE,
669 tdms.segment[i].meta_data.object[j].property[n].name,
670 (int16_t)(*(int8_t *)(tdms.segment[i].meta_data.object[j].property[n].value)), NULL)) {
671 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
672 return (EXIT_FAILURE);
673 }
674 } else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeU8) {
675 if (!SDDS_SetParameters(&SDDSout, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE,
676 tdms.segment[i].meta_data.object[j].property[n].name,
677 (uint16_t)(*(uint8_t *)(tdms.segment[i].meta_data.object[j].property[n].value)), NULL)) {
678 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
679 return (EXIT_FAILURE);
680 }
681 } else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeString) {
682 if (!SDDS_SetParameters(&SDDSout, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE,
683 tdms.segment[i].meta_data.object[j].property[n].name,
684 tdms.segment[i].meta_data.object[j].property[n].value, NULL)) {
685 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
686 return (EXIT_FAILURE);
687 }
688 } else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeVoid) {
689 fprintf(stderr, "tdms2sdds: void type parameters are not yet supported in tdms2sdds\n");
690 return (EXIT_FAILURE);
691 } else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeExtendedFloat) {
692 fprintf(stderr, "tdms2sdds: extended float type parameters are not yet supported in tdms2sdds\n");
693 return (EXIT_FAILURE);
694 } else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeExtendedFloatWithUnit) {
695 fprintf(stderr, "tdms2sdds: extended float with unit type parameters are not yet supported in tdms2sdds\n");
696 return (EXIT_FAILURE);
697 } else if (tdms.segment[i].meta_data.object[j].property[n].datatype == tdsTypeDAQmxRawData) {
698 fprintf(stderr, "tdms2sdds: DAQmx raw data parameters are not yet supported in tdms2sdds\n");
699 return (EXIT_FAILURE);
700 } else {
701 fprintf(stderr, "tdms2sdds: unknown data type\n");
702 return (EXIT_FAILURE);
703 }
704 }
705 }
706 if (!SDDS_WriteTable(&SDDSout)) {
707 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
708 return (EXIT_FAILURE);
709 }
710 }
711 if (!SDDS_Terminate(&SDDSout)) {
712 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
713 return (EXIT_FAILURE);
714 }
715
716 if (tdms.n_segments > 0) {
717 for (i = 0; i < tdms.n_segments; i++) {
718 if (tdms.segment[i].raw_data.n_channels > 0) {
719 for (j = 0; j < tdms.segment[i].raw_data.n_channels; j++) {
720 if (tdms.segment[i].raw_data.channel[j].n_values > 0) {
721 free(tdms.segment[i].raw_data.channel[j].values);
722 }
723 }
724 free(tdms.segment[i].raw_data.channel);
725 }
726 if (tdms.segment[i].meta_data.n_objects > 0) {
727 for (j = 0; j < tdms.segment[i].meta_data.n_objects; j++) {
728 if (tdms.segment[i].meta_data.object[j].path) {
729 free(tdms.segment[i].meta_data.object[j].path);
730 }
731 if (tdms.segment[i].meta_data.object[j].n_properties > 0) {
732 for (k = 0; k < tdms.segment[i].meta_data.object[j].n_properties; k++) {
733 if (tdms.segment[i].meta_data.object[j].property[k].name) {
734 for (ii = i + 1; ii < tdms.n_segments; ii++) {
735 for (jj = 0; jj < tdms.segment[ii].meta_data.n_objects; jj++) {
736 for (kk = 0; kk < tdms.segment[ii].meta_data.object[jj].n_properties; kk++) {
737 if (tdms.segment[i].meta_data.object[j].property[k].name == tdms.segment[ii].meta_data.object[jj].property[kk].name) {
738 tdms.segment[ii].meta_data.object[jj].property[kk].name = NULL;
739 tdms.segment[ii].meta_data.object[jj].property[kk].value = NULL;
740 }
741 }
742 }
743 }
744 free(tdms.segment[i].meta_data.object[j].property[k].name);
745 tdms.segment[i].meta_data.object[j].property[k].name = NULL;
746 }
747 if (tdms.segment[i].meta_data.object[j].property[k].value) {
748 free(tdms.segment[i].meta_data.object[j].property[k].value);
749 tdms.segment[i].meta_data.object[j].property[k].value = NULL;
750 }
751 }
752 free(tdms.segment[i].meta_data.object[j].property);
753 }
754 }
755 free(tdms.segment[i].meta_data.object);
756 }
757 }
758 free(tdms.segment);
759 }
760
761 free_scanargs(&scanned, argc);
762
763 return (EXIT_SUCCESS);
764}
int32_t SDDS_SetRowValues(SDDS_DATASET *SDDS_dataset, int32_t mode, int64_t row,...)
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_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.
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.
int32_t SDDS_GetParameterIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named parameter in the SDDS dataset.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
Definition SDDS_utils.c:474
void SDDS_ClearErrors()
Clears all recorded error messages from the SDDS error stack.
Definition SDDS_utils.c:354
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:318
int32_t SDDS_IsBigEndianMachine()
Determines whether the current machine uses big-endian byte ordering.
long edit_string(char *text, char *edit)
Edits the provided text based on the specified edit commands.
Definition edit_string.c:75
#define SDDS_ULONG
Identifier for the unsigned 32-bit integer data type.
Definition SDDStypes.h:67
#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_ULONG64
Identifier for the unsigned 64-bit integer data type.
Definition SDDStypes.h:55
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
Definition SDDStypes.h:61
#define SDDS_SHORT
Identifier for the signed short integer data type.
Definition SDDStypes.h:73
#define SDDS_USHORT
Identifier for the unsigned short integer data type.
Definition SDDStypes.h:79
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37
#define SDDS_LONG64
Identifier for the signed 64-bit integer data type.
Definition SDDStypes.h:49
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:357
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
Definition scanargs.c:391
void free_scanargs(SCANNED_ARG **scanned, int argc)
Definition scanargs.c:588

◆ TDMS_GetValue()

void TDMS_GetValue ( FILE * fd,
void ** value,
int32_t datatype )

Definition at line 1158 of file tdms2sdds.c.

1158 {
1159 uint64_t uLLong;
1160 int64_t LLong;
1161 size_t bytesRead;
1162
1163 if (datatype == tdsTypeI8) {
1164 *value = malloc(sizeof(int8_t));
1165 bytesRead = fread(((int8_t *)(*value)), 1, 1, fd);
1166 } else if (datatype == tdsTypeU8) {
1167 *value = malloc(sizeof(uint8_t));
1168 bytesRead = fread(((uint8_t *)(*value)), 1, 1, fd);
1169 } else if (datatype == tdsTypeI16) {
1170 *value = malloc(sizeof(int16_t));
1171 bytesRead = fread(((int16_t *)(*value)), 1, 2, fd);
1172 } else if (datatype == tdsTypeU16) {
1173 *value = malloc(sizeof(uint16_t));
1174 bytesRead = fread(((uint16_t *)(*value)), 1, 2, fd);
1175 } else if (datatype == tdsTypeI32) {
1176 *value = malloc(sizeof(int32_t));
1177 bytesRead = fread(((int32_t *)(*value)), 1, 4, fd);
1178 } else if (datatype == tdsTypeU32) {
1179 *value = malloc(sizeof(uint32_t));
1180 bytesRead = fread(((uint32_t *)(*value)), 1, 4, fd);
1181 } else if (datatype == tdsTypeI64) {
1182 *value = malloc(sizeof(int64_t));
1183 bytesRead = fread(((int64_t *)(*value)), 1, 8, fd);
1184 } else if (datatype == tdsTypeU64) {
1185 *value = malloc(sizeof(uint64_t));
1186 bytesRead = fread(((uint64_t *)(*value)), 1, 8, fd);
1187 } else if ((datatype == tdsTypeSingleFloat) || (datatype == tdsTypeSingleFloatWithUnit)) {
1188 *value = malloc(sizeof(float));
1189 bytesRead = fread(((float *)(*value)), 1, 4, fd);
1190 } else if ((datatype == tdsTypeDoubleFloat) || (datatype == tdsTypeDoubleFloatWithUnit)) {
1191 *value = malloc(sizeof(double));
1192 bytesRead = fread(((double *)(*value)), 1, 8, fd);
1193 } else if (datatype == tdsTypeBoolean) {
1194 *value = malloc(sizeof(int8_t));
1195 bytesRead = fread(((int8_t *)(*value)), 1, 1, fd);
1196 } else if (datatype == tdsTypeTimeStamp) {
1197 *value = malloc(sizeof(double));
1198 bytesRead = fread(&uLLong, 1, 8, fd);
1199 bytesRead = fread(&LLong, 1, 8, fd);
1200 /*LLong = LLong - 2082844791LL; */ /* Subtract seconds between 1904 and 1970 */
1201 *((double *)(*value)) = LLong + (uLLong * 5.42101086242752217e-20);
1202 } else if (datatype == tdsTypeVoid) {
1203 fprintf(stderr, "tdms2sdds: datatype Void is not yet supported in tdms2sdds\n");
1204 exit(EXIT_FAILURE);
1205 } else if (datatype == tdsTypeExtendedFloat) {
1206 fprintf(stderr, "tdms2sdds: datatype ExtendedFloat is not yet supported in tdms2sdds\n");
1207 exit(EXIT_FAILURE);
1208 } else if (datatype == tdsTypeExtendedFloatWithUnit) {
1209 fprintf(stderr, "tdms2sdds: datatype ExtendedFloatWithUnit is not yet supported in tdms2sdds\n");
1210 exit(EXIT_FAILURE);
1211 } else if (datatype == tdsTypeDAQmxRawData) {
1212 fprintf(stderr, "tdms2sdds: datatype DAQmxRawData is not yet supported in tdms2sdds\n");
1213 exit(EXIT_FAILURE);
1214 } else {
1215 fprintf(stderr, "tdms2sdds: unknown data type\n");
1216 exit(EXIT_FAILURE);
1217 }
1218 (void)bytesRead;
1219}

◆ TDMS_ReadLeadIn()

void TDMS_ReadLeadIn ( FILE * fd,
TDMS_SEGMENT * segment )

Definition at line 766 of file tdms2sdds.c.

766 {
767 char buffer[50];
768 size_t bytesRead;
769
770 bytesRead = fread(buffer, 1, 4, fd);
771 (void)bytesRead;
772 buffer[4] = '\0';
773 if (strcmp(buffer, "TDSm") != 0) {
774 fprintf(stderr, "tdms2sdds: Error: File does not start with TDSm\n");
775 exit(EXIT_FAILURE);
776 }
777 bytesRead = fread(&(segment->lead_in.toc), 1, 4, fd); /* TOC */
778 (void)bytesRead;
779 bytesRead = fread(&(segment->lead_in.version), 1, 4, fd); /* Version */
780 (void)bytesRead;
781 if (segment->lead_in.version == 4712) {
782 fprintf(stderr, "tdms2sdds: Error: TDMS version 1.0 files unsupported\n");
783 exit(EXIT_FAILURE);
784 }
785 if (segment->lead_in.version != 4713) {
786 fprintf(stderr, "tdms2sdds: Error: Unknown TDMS version\n");
787 exit(EXIT_FAILURE);
788 }
789 bytesRead = fread(&(segment->lead_in.next_segment_offset), 1, 8, fd); /* Next segment offset */
790 (void)bytesRead;
791 bytesRead = fread(&(segment->lead_in.raw_data_offset), 1, 8, fd); /* Raw data offset */
792 (void)bytesRead;
793}

◆ TDMS_ReadMetaData()

void TDMS_ReadMetaData ( FILE * fd,
TDMS_SEGMENT * segment )

Definition at line 795 of file tdms2sdds.c.

795 {
796 uint32_t uLong, i, j;
797 size_t bytesRead;
798
799 segment->xpart.name = NULL;
800 segment->xpart.unit = NULL;
801 segment->xpart.start_time = 0;
802 segment->xpart.start_offset = 0;
803 segment->xpart.increment = 0;
804 segment->xpart.samples = 0;
805 segment->xpart.time_pref = NULL;
806 segment->xpart.range = 0;
807
808 bytesRead = fread(&(segment->meta_data.n_objects), 1, 4, fd);
809 (void)bytesRead;
810
811 segment->meta_data.object = malloc(sizeof(TDMS_META_DATA_OBJECT) * segment->meta_data.n_objects);
812 for (i = 0; i < segment->meta_data.n_objects; i++) {
813 bytesRead = fread(&uLong, 1, 4, fd);
814 (void)bytesRead;
815 segment->meta_data.object[i].path = malloc(sizeof(char) * (uLong + 1));
816 bytesRead = fread(segment->meta_data.object[i].path, 1, uLong, fd);
817 (void)bytesRead;
818 segment->meta_data.object[i].path[uLong] = '\0';
819 bytesRead = fread(&(segment->meta_data.object[i].raw_data_index), 1, 4, fd);
820 (void)bytesRead;
821 if ((segment->meta_data.object[i].raw_data_index != 0xFFFFFFFF) && (segment->meta_data.object[i].raw_data_index != 0x00000000)) {
822 bytesRead = fread(&(segment->meta_data.object[i].raw_data_datatype), 1, 4, fd);
823 (void)bytesRead;
824 bytesRead = fread(&(segment->meta_data.object[i].raw_data_dimensions), 1, 4, fd);
825 (void)bytesRead;
826 bytesRead = fread(&(segment->meta_data.object[i].raw_data_count), 1, 8, fd);
827 (void)bytesRead;
828 if (segment->meta_data.object[i].raw_data_datatype == tdsTypeString) {
829 bytesRead = fread(&(segment->meta_data.object[i].raw_data_total_size), 1, 8, fd);
830 (void)bytesRead;
831 }
832 }
833 bytesRead = fread(&(segment->meta_data.object[i].n_properties), 1, 4, fd);
834 (void)bytesRead;
835 segment->meta_data.object[i].property = malloc(sizeof(TDMS_META_DATA_OBJECT_PROPERTY) * segment->meta_data.object[i].n_properties);
836 for (j = 0; j < segment->meta_data.object[i].n_properties; j++) {
837 bytesRead = fread(&uLong, 1, 4, fd);
838 (void)bytesRead;
839 segment->meta_data.object[i].property[j].name = malloc(sizeof(char) * (uLong + 1));
840 bytesRead = fread(segment->meta_data.object[i].property[j].name, 1, uLong, fd);
841 (void)bytesRead;
842 segment->meta_data.object[i].property[j].name[uLong] = '\0';
843 bytesRead = fread(&(segment->meta_data.object[i].property[j].datatype), 1, 4, fd);
844 (void)bytesRead;
845 if (segment->meta_data.object[i].property[j].datatype == tdsTypeString) {
846 bytesRead = fread(&uLong, 1, 4, fd);
847 (void)bytesRead;
848 segment->meta_data.object[i].property[j].value = malloc(sizeof(char) * (uLong + 1));
849 bytesRead = fread(segment->meta_data.object[i].property[j].value, 1, uLong, fd);
850 (void)bytesRead;
851 ((char *)(segment->meta_data.object[i].property[j].value))[uLong] = '\0';
852 } else {
853 TDMS_GetValue(fd, &(segment->meta_data.object[i].property[j].value), segment->meta_data.object[i].property[j].datatype);
854 }
855 /* check for waveform channel properties */
856 if (strcmp(segment->meta_data.object[i].property[j].name, "wf_xname") == 0) {
857 segment->xpart.name = segment->meta_data.object[i].property[j].value;
858 }
859 if (strcmp(segment->meta_data.object[i].property[j].name, "wf_xunit_string") == 0) {
860 segment->xpart.unit = segment->meta_data.object[i].property[j].value;
861 }
862 if (strcmp(segment->meta_data.object[i].property[j].name, "wf_start_time") == 0) {
863 segment->xpart.start_time = *(double *)(segment->meta_data.object[i].property[j].value);
864 }
865 if (strcmp(segment->meta_data.object[i].property[j].name, "wf_start_offset") == 0) {
866 segment->xpart.start_offset = *(double *)(segment->meta_data.object[i].property[j].value);
867 }
868 if (strcmp(segment->meta_data.object[i].property[j].name, "wf_increment") == 0) {
869 segment->xpart.increment = *(double *)(segment->meta_data.object[i].property[j].value);
870 }
871 if (strcmp(segment->meta_data.object[i].property[j].name, "wf_samples") == 0) {
872 segment->xpart.samples = *(int32_t *)(segment->meta_data.object[i].property[j].value);
873 }
874 if (strcmp(segment->meta_data.object[i].property[j].name, "wf_time_pref") == 0) {
875 segment->xpart.time_pref = segment->meta_data.object[i].property[j].value;
876 }
877 }
878 }
879 (void)bytesRead;
880}

◆ TDMS_ReadRawData()

void TDMS_ReadRawData ( FILE * fd,
TDMS_FILE * tdms,
uint32_t n_segment,
long filesize )

Definition at line 882 of file tdms2sdds.c.

882 {
883 uint32_t i, j, k, n, p, a;
884 uint32_t channel_size;
885 uint32_t chunk_size = 0;
886 uint32_t total_chunks;
887 uint32_t n_chunks;
888 uint32_t chunk;
889 int64_t LLong;
890 uint64_t uLLong;
891 int prevFound = 0;
892 TDMS_SEGMENT *segment = &((*tdms).segment[n_segment]);
893 size_t bytesRead;
894
895 segment->raw_data.n_channels = 0;
896 for (i = 0; i < segment->meta_data.n_objects; i++) {
897 if (segment->meta_data.object[i].raw_data_index != 0xFFFFFFFF) {
898 if (segment->meta_data.object[i].raw_data_index == 0x00000000) {
899 /* An object with this name already exists in the previous segment.
900 Copy over meta data */
901 prevFound = 0;
902 a = 0;
903 while (prevFound == 0) {
904 a++;
905 if (a > n_segment) {
906 fprintf(stderr, "tdms2sdds: Error: unable to find %s in a previous segment.\n", segment->meta_data.object[i].path);
907 exit(EXIT_FAILURE);
908 }
909 for (n = 0; n < (*tdms).segment[n_segment - a].meta_data.n_objects; n++) {
910 if (strcmp((*tdms).segment[n_segment - a].meta_data.object[n].path, segment->meta_data.object[i].path) == 0) {
911 prevFound = 1;
912 segment->meta_data.object[i].raw_data_datatype = (*tdms).segment[n_segment - a].meta_data.object[n].raw_data_datatype;
913 segment->meta_data.object[i].raw_data_dimensions = (*tdms).segment[n_segment - a].meta_data.object[n].raw_data_dimensions;
914 segment->meta_data.object[i].raw_data_count = (*tdms).segment[n_segment - a].meta_data.object[n].raw_data_count;
915 if (segment->meta_data.object[i].raw_data_datatype == tdsTypeString) {
916 segment->meta_data.object[i].raw_data_total_size = (*tdms).segment[n_segment - a].meta_data.object[n].raw_data_total_size;
917 }
918
919 /* Copy over previous properties excluding any that were overwritten */
920 /* There will be errors if new properties are inserted after the first segment in the TDMS file */
921 for (j = 0; j < (*tdms).segment[n_segment - a].meta_data.object[n].n_properties; j++) {
922 for (k = 0; k < segment->meta_data.object[i].n_properties; k++) {
923 if (strcmp((*tdms).segment[n_segment - a].meta_data.object[n].property[j].name, segment->meta_data.object[i].property[k].name) == 0) {
924 break;
925 }
926 }
927 p = segment->meta_data.object[i].n_properties;
928 segment->meta_data.object[i].n_properties++;
929 segment->meta_data.object[i].property = realloc(segment->meta_data.object[i].property, sizeof(TDMS_META_DATA_OBJECT_PROPERTY) * segment->meta_data.object[i].n_properties);
930 segment->meta_data.object[i].property[p].name = (*tdms).segment[n_segment - a].meta_data.object[n].property[j].name;
931 segment->meta_data.object[i].property[p].datatype = (*tdms).segment[n_segment - a].meta_data.object[n].property[j].datatype;
932 segment->meta_data.object[i].property[p].value = (*tdms).segment[n_segment - a].meta_data.object[n].property[j].value;
933 /* check for waveform channel properties */
934 if (strcmp(segment->meta_data.object[i].property[p].name, "wf_xname") == 0) {
935 segment->xpart.name = segment->meta_data.object[i].property[p].value;
936 }
937 if (strcmp(segment->meta_data.object[i].property[p].name, "wf_xunit_string") == 0) {
938 segment->xpart.unit = segment->meta_data.object[i].property[p].value;
939 }
940 if (strcmp(segment->meta_data.object[i].property[p].name, "wf_start_time") == 0) {
941 segment->xpart.start_time = *(double *)(segment->meta_data.object[i].property[p].value);
942 }
943 if (strcmp(segment->meta_data.object[i].property[p].name, "wf_start_offset") == 0) {
944 segment->xpart.start_offset = *(double *)(segment->meta_data.object[i].property[p].value);
945 segment->xpart.start_offset += (*tdms).segment[n_segment - a].xpart.range;
946 /*put code here */
947 }
948 if (strcmp(segment->meta_data.object[i].property[p].name, "wf_increment") == 0) {
949 segment->xpart.increment = *(double *)(segment->meta_data.object[i].property[p].value);
950 }
951 if (strcmp(segment->meta_data.object[i].property[p].name, "wf_samples") == 0) {
952 segment->xpart.samples = *(int32_t *)(segment->meta_data.object[i].property[p].value);
953 }
954 if (strcmp(segment->meta_data.object[i].property[p].name, "wf_time_pref") == 0) {
955 segment->xpart.time_pref = segment->meta_data.object[i].property[p].value;
956 }
957 }
958 }
959 }
960 }
961 }
962
963 segment->raw_data.n_channels++;
964 if (segment->meta_data.object[i].raw_data_dimensions != 1) {
965 fprintf(stderr, "tdms2sdds: Error: raw data dimension is %d and should have been 1.\n", segment->meta_data.object[i].raw_data_dimensions);
966 exit(EXIT_FAILURE);
967 }
968 if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI8) ||
969 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU8) ||
970 (segment->meta_data.object[i].raw_data_datatype == tdsTypeBoolean)) {
971 channel_size = 1 * segment->meta_data.object[i].raw_data_dimensions * segment->meta_data.object[i].raw_data_count;
972 } else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI16) ||
973 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU16)) {
974 channel_size = 2 * segment->meta_data.object[i].raw_data_dimensions * segment->meta_data.object[i].raw_data_count;
975 } else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI32) ||
976 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU32) ||
977 (segment->meta_data.object[i].raw_data_datatype == tdsTypeSingleFloat) ||
978 (segment->meta_data.object[i].raw_data_datatype == tdsTypeSingleFloatWithUnit)) {
979 channel_size = 4 * segment->meta_data.object[i].raw_data_dimensions * segment->meta_data.object[i].raw_data_count;
980 } else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI64) ||
981 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU64) ||
982 (segment->meta_data.object[i].raw_data_datatype == tdsTypeDoubleFloat) ||
983 (segment->meta_data.object[i].raw_data_datatype == tdsTypeDoubleFloatWithUnit)) {
984 channel_size = 8 * segment->meta_data.object[i].raw_data_dimensions * segment->meta_data.object[i].raw_data_count;
985 } else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeTimeStamp) {
986 channel_size = 16 * segment->meta_data.object[i].raw_data_dimensions * segment->meta_data.object[i].raw_data_count;
987 } else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeString) {
988 fprintf(stderr, "tdms2sdds: string type channels are not yet supported in tdms2sdds\n");
989 exit(EXIT_FAILURE);
990 } else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeVoid) {
991 fprintf(stderr, "tdms2sdds: void type channels are not yet supported in tdms2sdds\n");
992 exit(EXIT_FAILURE);
993 } else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeExtendedFloat) {
994 fprintf(stderr, "tdms2sdds: extended float type channels are not yet supported in tdms2sdds\n");
995 exit(EXIT_FAILURE);
996 } else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeExtendedFloatWithUnit) {
997 fprintf(stderr, "tdms2sdds: extended float type with unit channels are not yet supported in tdms2sdds\n");
998 exit(EXIT_FAILURE);
999 } else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeDAQmxRawData) {
1000 fprintf(stderr, "tdms2sdds: extended DAQmx raw data channels are not yet supported in tdms2sdds\n");
1001 exit(EXIT_FAILURE);
1002 } else {
1003 fprintf(stderr, "tdms2sdds: unknown data type\n");
1004 exit(EXIT_FAILURE);
1005 }
1006 chunk_size += channel_size;
1007 }
1008 }
1009
1010 if (segment->lead_in.next_segment_offset == -1) {
1011 if (filesize == -1) {
1012 fprintf(stderr, "tdms2sdds: Error: cannot calculate file size because you are using stdin\n");
1013 exit(EXIT_FAILURE);
1014 }
1015 segment->lead_in.next_segment_offset = filesize;
1016 }
1017 total_chunks = segment->lead_in.next_segment_offset - segment->lead_in.raw_data_offset;
1018 n_chunks = total_chunks / chunk_size;
1019
1020 segment->raw_data.channel = malloc(sizeof(TDMS_RAW_DATA_CHANNEL) * segment->raw_data.n_channels);
1021
1022 if (segment->lead_in.toc & kTocInterleavedData) {
1023 fprintf(stderr, "tdms2sdds does not yet support interleaved data\n");
1024 exit(EXIT_FAILURE);
1025 } else {
1026 j = 0;
1027 for (i = 0; i < segment->meta_data.n_objects; i++) {
1028 if (segment->meta_data.object[i].raw_data_index != 0xFFFFFFFF) {
1029 segment->xpart.range = segment->xpart.increment * segment->meta_data.object[i].raw_data_count * n_chunks;
1030
1031 if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI8) ||
1032 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU8) ||
1033 (segment->meta_data.object[i].raw_data_datatype == tdsTypeBoolean)) {
1034 segment->raw_data.channel[j].values = malloc(1 * segment->meta_data.object[i].raw_data_count * n_chunks);
1035 } else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI16) ||
1036 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU16)) {
1037 segment->raw_data.channel[j].values = malloc(2 * segment->meta_data.object[i].raw_data_count * n_chunks);
1038 } else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI32) ||
1039 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU32) ||
1040 (segment->meta_data.object[i].raw_data_datatype == tdsTypeSingleFloat) ||
1041 (segment->meta_data.object[i].raw_data_datatype == tdsTypeSingleFloatWithUnit)) {
1042 segment->raw_data.channel[j].values = malloc(4 * segment->meta_data.object[i].raw_data_count * n_chunks);
1043 } else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeI64) ||
1044 (segment->meta_data.object[i].raw_data_datatype == tdsTypeU64) ||
1045 (segment->meta_data.object[i].raw_data_datatype == tdsTypeDoubleFloat) ||
1046 (segment->meta_data.object[i].raw_data_datatype == tdsTypeDoubleFloatWithUnit)) {
1047 segment->raw_data.channel[j].values = malloc(8 * segment->meta_data.object[i].raw_data_count * n_chunks);
1048 } else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeTimeStamp) {
1049 /* This is converted into a double value */
1050 segment->raw_data.channel[j].values = malloc(8 * segment->meta_data.object[i].raw_data_count * n_chunks);
1051 } else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeString) {
1052 fprintf(stderr, "tdms2sdds: string type channels are not yet supported in tdms2sdds\n");
1053 exit(EXIT_FAILURE);
1054 } else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeVoid) {
1055 fprintf(stderr, "tdms2sdds: void type channels are not yet supported in tdms2sdds\n");
1056 exit(EXIT_FAILURE);
1057 } else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeExtendedFloat) {
1058 fprintf(stderr, "tdms2sdds: extended float type channels are not yet supported in tdms2sdds\n");
1059 exit(EXIT_FAILURE);
1060 } else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeExtendedFloatWithUnit) {
1061 fprintf(stderr, "tdms2sdds: extended float type with unit channels are not yet supported in tdms2sdds\n");
1062 exit(EXIT_FAILURE);
1063 } else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeDAQmxRawData) {
1064 fprintf(stderr, "tdms2sdds: extended DAQmx raw data channels are not yet supported in tdms2sdds\n");
1065 exit(EXIT_FAILURE);
1066 } else {
1067 fprintf(stderr, "tdms2sdds: unknown data type\n");
1068 exit(EXIT_FAILURE);
1069 }
1070 segment->raw_data.channel[j].n_values = segment->meta_data.object[i].raw_data_count * n_chunks;
1071 j++;
1072 }
1073 }
1074 for (chunk = 0; chunk < n_chunks; chunk++) {
1075 j = 0;
1076 for (i = 0; i < segment->meta_data.n_objects; i++) {
1077 if (segment->meta_data.object[i].raw_data_index != 0xFFFFFFFF) {
1078 if (segment->meta_data.object[i].raw_data_datatype == tdsTypeBoolean) {
1079 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1080 bytesRead = fread(&(((int8_t *)(segment->raw_data.channel[j].values))[k]), 1, 1, fd);
1081 }
1082 } else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeI8) {
1083 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1084 bytesRead = fread(&(((int8_t *)(segment->raw_data.channel[j].values))[k]), 1, 1, fd);
1085 }
1086 } else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeU8) {
1087 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1088 bytesRead = fread(&(((uint8_t *)(segment->raw_data.channel[j].values))[k]), 1, 1, fd);
1089 }
1090 } else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeI16) {
1091 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1092 bytesRead = fread(&(((int16_t *)(segment->raw_data.channel[j].values))[k]), 1, 2, fd);
1093 }
1094 } else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeU16) {
1095 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1096 bytesRead = fread(&(((uint16_t *)(segment->raw_data.channel[j].values))[k]), 1, 2, fd);
1097 }
1098 } else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeI32) {
1099 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1100 bytesRead = fread(&(((int32_t *)(segment->raw_data.channel[j].values))[k]), 1, 4, fd);
1101 }
1102 } else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeU32) {
1103 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1104 bytesRead = fread(&(((uint32_t *)(segment->raw_data.channel[j].values))[k]), 1, 4, fd);
1105 }
1106 } else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeI64) {
1107 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1108 bytesRead = fread(&(((int64_t *)(segment->raw_data.channel[j].values))[k]), 1, 8, fd);
1109 }
1110 } else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeU64) {
1111 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1112 bytesRead = fread(&(((uint64_t *)(segment->raw_data.channel[j].values))[k]), 1, 8, fd);
1113 }
1114 } else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeSingleFloat) ||
1115 (segment->meta_data.object[i].raw_data_datatype == tdsTypeSingleFloatWithUnit)) {
1116 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1117 bytesRead = fread(&(((float *)(segment->raw_data.channel[j].values))[k]), 1, 4, fd);
1118 }
1119 } else if ((segment->meta_data.object[i].raw_data_datatype == tdsTypeDoubleFloat) ||
1120 (segment->meta_data.object[i].raw_data_datatype == tdsTypeDoubleFloatWithUnit)) {
1121 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1122 bytesRead = fread(&(((double *)(segment->raw_data.channel[j].values))[k]), 1, 8, fd);
1123 }
1124 } else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeTimeStamp) {
1125 for (k = chunk * segment->meta_data.object[i].raw_data_count; k < (chunk + 1) * segment->meta_data.object[i].raw_data_count; k++) {
1126 bytesRead = fread(&uLLong, 1, 8, fd);
1127 bytesRead = fread(&LLong, 1, 8, fd);
1128 /*LLong = LLong - 2082844791LL; */ /* Subtract seconds between 1904 and 1970 */
1129 segment->raw_data.channel[j].values[k] = LLong + (uLLong * 5.42101086242752217e-20);
1130 }
1131 } else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeString) {
1132 fprintf(stderr, "tdms2sdds: string type channels are not yet supported in tdms2sdds\n");
1133 exit(EXIT_FAILURE);
1134 } else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeVoid) {
1135 fprintf(stderr, "tdms2sdds: void type channels are not yet supported in tdms2sdds\n");
1136 exit(EXIT_FAILURE);
1137 } else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeExtendedFloat) {
1138 fprintf(stderr, "tdms2sdds: extended float type channels are not yet supported in tdms2sdds\n");
1139 exit(EXIT_FAILURE);
1140 } else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeExtendedFloatWithUnit) {
1141 fprintf(stderr, "tdms2sdds: extended float with unit type channels are not yet supported in tdms2sdds\n");
1142 exit(EXIT_FAILURE);
1143 } else if (segment->meta_data.object[i].raw_data_datatype == tdsTypeDAQmxRawData) {
1144 fprintf(stderr, "tdms2sdds: DAQmx raw data channels are not yet supported in tdms2sdds\n");
1145 exit(EXIT_FAILURE);
1146 } else {
1147 fprintf(stderr, "tdms2sdds: unknown data type\n");
1148 exit(EXIT_FAILURE);
1149 }
1150 j++;
1151 }
1152 }
1153 }
1154 }
1155 (void)bytesRead;
1156}