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

Detailed Description

Perform time conversions on SDDS data.

This program enables users to perform various time-related operations on SDDS files. These operations include breaking down epoch times into components, converting date strings to epoch times, and specifying the major order of output data.

Usage

sddstimeconvert [<SDDSinput>] [<SDDSoutput>]
[-pipe=<input>[,<output>]]
[-majorOrder=row|column]
[-breakdown={column|parameter},<timeName>[,year=<newName>][,julianDay=<newName>][,month=<newName>][,day=<newName>][,hour=<newName>][,text=<newName>]]
[-dateToTime={column|parameter},<timeName>,<newName>,<stringName>,format=<formatString>]
[-epoch={column|parameter},<newName>,year=<name>,[julianDay=<name>|month=<name>,day=<name>],hour=<name>]

Options

Optional Description
-pipe Enable pipe-based input/output processing.
-majorOrder Specify output data order: row-major or column-major.
-breakdown= Break down epoch time into components such as year, month, day, hour, etc.
-dateToTime Convert date strings to epoch times based on a specified format string.
-epoch Generate a new epoch time column or parameter with optional qualifiers.

Incompatibilities

  • For -epoch, the following requirements must be met:
    • Specify either julianDay or both month and day names.
  • For -breakdown, at least one of the following must be specified:
    • year, julianDay, month, day, hour, or text qualifiers.
  • For -dateToTime, the format string is required.
License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Authors
  • M. Borland
  • R. Soliday
  • H. Shang

Definition in file sddstimeconvert.c.

#include <time.h>
#include "mdb.h"
#include "SDDS.h"
#include "scan.h"

Go to the source code of this file.

Functions

void DoColumnEpochConversion (SDDS_DATASET *SDDSout, SDDS_DATASET *SDDSin, TIME_CONVERSION *conversion)
 
void DoParameterEpochConversion (SDDS_DATASET *SDDSout, SDDS_DATASET *SDDSin, TIME_CONVERSION *conversion)
 
void DoColumnDateToTimeConversion (SDDS_DATASET *SDDSout, SDDS_DATASET *SDDSin, TIME_CONVERSION *conversion)
 
void DoParameterDateToTimeConversion (SDDS_DATASET *SDDSout, SDDS_DATASET *SDDSin, TIME_CONVERSION *conversion)
 
void DoColumnBreakdownConversion (SDDS_DATASET *SDDSout, SDDS_DATASET *SDDSin, TIME_CONVERSION *conversion)
 
void DoParameterBreakdownConversion (SDDS_DATASET *SDDSout, SDDS_DATASET *SDDSin, TIME_CONVERSION *conversion)
 
void InitializeOutput (SDDS_DATASET *SDDSout, char *outputfile, TIME_CONVERSION *conversion, long conversions, SDDS_DATASET *SDDSin, short columnMajorOrder)
 
void CheckEpochConversionElements (SDDS_DATASET *SDDSin, TIME_CONVERSION *conversion, long conversions)
 
void CheckBreakdownConversionElements (SDDS_DATASET *SDDSin, TIME_CONVERSION *conversion, long conversions)
 
void CheckDateConversionElements (SDDS_DATASET *SDDSin, TIME_CONVERSION *conversion, long conversions)
 
int main (int argc, char **argv)
 

Function Documentation

◆ CheckBreakdownConversionElements()

void CheckBreakdownConversionElements ( SDDS_DATASET * SDDSin,
TIME_CONVERSION * conversion,
long conversions )

Definition at line 374 of file sddstimeconvert.c.

374 {
375 while (conversions-- > 0) {
376 if (!(conversion[conversions].flags & DO_BREAKDOWN))
377 continue;
378 if (conversion->flags & IS_PARAMETER) {
379 if (SDDS_CheckParameter(SDDSin, conversion->epochName, NULL, SDDS_ANY_NUMERIC_TYPE, stderr) != SDDS_CHECK_OK)
380 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
381 conversion->epochIndex = SDDS_GetParameterIndex(SDDSin, conversion->epochName);
382 } else {
383 if (SDDS_CheckColumn(SDDSin, conversion->epochName, NULL, SDDS_ANY_NUMERIC_TYPE, stderr) != SDDS_CHECK_OK)
384 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
385 conversion->epochIndex = SDDS_GetColumnIndex(SDDSin, conversion->epochName);
386 }
387 conversion++;
388 }
389}
int32_t SDDS_GetParameterIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named parameter in the SDDS dataset.
int32_t SDDS_GetColumnIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named column in the SDDS dataset.
int32_t SDDS_CheckColumn(SDDS_DATASET *SDDS_dataset, char *name, char *units, int32_t type, FILE *fp_message)
Checks if a column exists in the SDDS dataset with the specified name, units, and type.
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_CheckParameter(SDDS_DATASET *SDDS_dataset, char *name, char *units, int32_t type, FILE *fp_message)
Checks if a parameter exists in the SDDS dataset with the specified name, units, and type.
#define SDDS_ANY_NUMERIC_TYPE
Special identifier used by SDDS_Check*() routines to accept any numeric type.
Definition SDDStypes.h:157

◆ CheckDateConversionElements()

void CheckDateConversionElements ( SDDS_DATASET * SDDSin,
TIME_CONVERSION * conversion,
long conversions )

Definition at line 391 of file sddstimeconvert.c.

391 {
392 while (conversions-- > 0) {
393 if (!(conversion[conversions].flags & DO_DATECONVERSION))
394 continue;
395 if (conversion->flags & IS_PARAMETER) {
396 if (SDDS_CheckParameter(SDDSin, conversion->textName, NULL, SDDS_STRING, stderr) != SDDS_CHECK_OK)
397 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
398 conversion->textIndex = SDDS_GetParameterIndex(SDDSin, conversion->textName);
399 } else {
400 if (SDDS_CheckColumn(SDDSin, conversion->textName, NULL, SDDS_STRING, stderr) != SDDS_CHECK_OK)
401 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
402 conversion->textIndex = SDDS_GetColumnIndex(SDDSin, conversion->textName);
403 }
404 if (conversion->textIndex < 0) {
405 fprintf(stderr, "Error: '%s' does not exist in input file.\n", conversion->textName);
406 exit(EXIT_FAILURE);
407 }
408 conversion++;
409 }
410}
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85

◆ CheckEpochConversionElements()

void CheckEpochConversionElements ( SDDS_DATASET * SDDSin,
TIME_CONVERSION * conversion,
long conversions )

Definition at line 327 of file sddstimeconvert.c.

327 {
328 while (conversions-- > 0) {
329 if (!(conversion[conversions].flags & DO_EPOCH))
330 continue;
331 if (conversion->flags & IS_PARAMETER) {
332 if (SDDS_CheckParameter(SDDSin, conversion->yearName, NULL, SDDS_ANY_NUMERIC_TYPE, stderr) != SDDS_CHECK_OK ||
333 (conversion->jDayName &&
334 SDDS_CheckParameter(SDDSin, conversion->jDayName, NULL, SDDS_ANY_NUMERIC_TYPE, stderr) != SDDS_CHECK_OK) ||
335 (conversion->dayName &&
336 SDDS_CheckParameter(SDDSin, conversion->dayName, NULL, SDDS_ANY_NUMERIC_TYPE, stderr) != SDDS_CHECK_OK) ||
337 (conversion->monthName &&
338 SDDS_CheckParameter(SDDSin, conversion->monthName, NULL, SDDS_ANY_NUMERIC_TYPE, stderr) != SDDS_CHECK_OK) ||
339 SDDS_CheckParameter(SDDSin, conversion->hourName, NULL, SDDS_ANY_NUMERIC_TYPE, stderr) != SDDS_CHECK_OK)
340 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
341 conversion->yearIndex = SDDS_GetParameterIndex(SDDSin, conversion->yearName);
342 conversion->hourIndex = SDDS_GetParameterIndex(SDDSin, conversion->hourName);
343 conversion->dayIndex = conversion->jDayIndex = conversion->monthIndex = -1;
344 if (conversion->dayName)
345 conversion->dayIndex = SDDS_GetParameterIndex(SDDSin, conversion->dayName);
346 if (conversion->jDayName)
347 conversion->jDayIndex = SDDS_GetParameterIndex(SDDSin, conversion->jDayName);
348 if (conversion->monthName)
349 conversion->monthIndex = SDDS_GetParameterIndex(SDDSin, conversion->monthName);
350 } else {
351 if (SDDS_CheckColumn(SDDSin, conversion->yearName, NULL, SDDS_ANY_NUMERIC_TYPE, stderr) != SDDS_CHECK_OK ||
352 (conversion->jDayName &&
353 SDDS_CheckColumn(SDDSin, conversion->jDayName, NULL, SDDS_ANY_NUMERIC_TYPE, stderr) != SDDS_CHECK_OK) ||
354 (conversion->dayName &&
355 SDDS_CheckColumn(SDDSin, conversion->dayName, NULL, SDDS_ANY_NUMERIC_TYPE, stderr) != SDDS_CHECK_OK) ||
356 (conversion->monthName &&
357 SDDS_CheckColumn(SDDSin, conversion->monthName, NULL, SDDS_ANY_NUMERIC_TYPE, stderr) != SDDS_CHECK_OK) ||
358 SDDS_CheckColumn(SDDSin, conversion->hourName, NULL, SDDS_ANY_NUMERIC_TYPE, stderr) != SDDS_CHECK_OK)
359 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
360 conversion->yearIndex = SDDS_GetColumnIndex(SDDSin, conversion->yearName);
361 conversion->hourIndex = SDDS_GetColumnIndex(SDDSin, conversion->hourName);
362 conversion->dayIndex = conversion->jDayIndex = conversion->monthIndex = -1;
363 if (conversion->dayName)
364 conversion->dayIndex = SDDS_GetColumnIndex(SDDSin, conversion->dayName);
365 if (conversion->jDayName)
366 conversion->jDayIndex = SDDS_GetColumnIndex(SDDSin, conversion->jDayName);
367 if (conversion->monthName)
368 conversion->monthIndex = SDDS_GetColumnIndex(SDDSin, conversion->monthName);
369 }
370 conversion++;
371 }
372}

◆ DoColumnBreakdownConversion()

void DoColumnBreakdownConversion ( SDDS_DATASET * SDDSout,
SDDS_DATASET * SDDSin,
TIME_CONVERSION * conversion )

Definition at line 648 of file sddstimeconvert.c.

648 {
649 double *hour, *epochTime;
650 short *month, *day, *jDay, *year;
651 char **text;
652 int64_t row, rows;
653
654 if (!(rows = SDDS_CountRowsOfInterest(SDDSin)))
655 return;
656
657 if (!(epochTime = SDDS_GetColumnInDoubles(SDDSin, conversion->epochName)))
658 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
659
660 hour = NULL;
661 month = day = jDay = year = NULL;
662 text = NULL;
663 if ((conversion->hourName && !(hour = (double *)malloc(sizeof(*hour) * rows))) ||
664 (conversion->monthName && !(month = (short *)malloc(sizeof(*month) * rows))) ||
665 (conversion->dayName && !(day = (short *)malloc(sizeof(*day) * rows))) ||
666 (conversion->jDayName && !(jDay = (short *)malloc(sizeof(*jDay) * rows))) ||
667 (conversion->textName && !(text = (char **)malloc(sizeof(*text) * rows))) ||
668 (conversion->yearName && !(year = (short *)malloc(sizeof(*year) * rows))))
669 SDDS_Bomb("Memory allocation failure");
670
671 for (row = 0; row < rows; row++) {
672 if (text)
673 text[row] = malloc(sizeof(**text) * 30);
674 if (!TimeEpochToBreakdown(year ? year + row : NULL, jDay ? jDay + row : NULL, month ? month + row : NULL, day ? day + row : NULL, hour ? hour + row : NULL, epochTime[row]) ||
675 (text && !TimeEpochToText(text[row], epochTime[row])))
676 SDDS_Bomb("Problem performing time breakdown");
677 }
678
679 if ((year && !SDDS_SetColumn(SDDSout, SDDS_BY_NAME, year, rows, conversion->yearName)) ||
680 (day && !SDDS_SetColumn(SDDSout, SDDS_BY_NAME, day, rows, conversion->dayName)) ||
681 (month && !SDDS_SetColumn(SDDSout, SDDS_BY_NAME, month, rows, conversion->monthName)) ||
682 (jDay && !SDDS_SetColumn(SDDSout, SDDS_BY_NAME, jDay, rows, conversion->jDayName)) ||
683 (hour && !SDDS_SetColumn(SDDSout, SDDS_BY_NAME, hour, rows, conversion->hourName)) ||
684 (text && !SDDS_SetColumn(SDDSout, SDDS_BY_NAME, text, rows, conversion->textName)))
685 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
686 if (hour)
687 free(hour);
688 if (year)
689 free(year);
690 if (epochTime)
691 free(epochTime);
692 if (jDay)
693 free(jDay);
694 if (month)
695 free(month);
696 if (day)
697 free(day);
698 if (text) {
699 for (row = 0; row < rows; row++)
700 free(text[row]);
701 free(text);
702 }
703}
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.
int64_t SDDS_CountRowsOfInterest(SDDS_DATASET *SDDS_dataset)
Counts the number of rows marked as "of interest" in the current data table.
double * SDDS_GetColumnInDoubles(SDDS_DATASET *SDDS_dataset, char *column_name)
Retrieves the data of a specified numerical column as an array of doubles, considering only rows mark...
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:342
short TimeEpochToBreakdown(short *year, short *jDay, short *month, short *day, double *hour, double epochTime)
Breaks down epoch time into its constituent components.
short TimeEpochToText(char *text, double epochTime)
Converts epoch time to a formatted text string.

◆ DoColumnDateToTimeConversion()

void DoColumnDateToTimeConversion ( SDDS_DATASET * SDDSout,
SDDS_DATASET * SDDSin,
TIME_CONVERSION * conversion )

Definition at line 607 of file sddstimeconvert.c.

607 {
608#if defined(_WIN32)
609 fprintf(stderr, "Error: strptime function needed by DoColumnDateToTimeConversion is not available on Windows\n");
610 exit(EXIT_FAILURE);
611#else
612 double hour;
613 double month = 0, day = 0, year = 0, jDay = 0, *epochTime;
614 int64_t row, rows;
615 char **timestr = NULL;
616 struct tm tm = {0};
617 /* Note that tm struct:
618 tm_year: years since 1900
619 tm_mon: months since January (0-11)
620 */
621 if (!(rows = SDDS_CountRowsOfInterest(SDDSin)))
622 return;
623
624 if (!(timestr = SDDS_GetColumn(SDDSin, conversion->textName)))
625 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
626
627 if (!(epochTime = (double *)malloc(sizeof(*epochTime) * rows)))
628 SDDS_Bomb("Memory allocation failure");
629
630 for (row = 0; row < rows; row++) {
631 if (strptime(timestr[row], conversion->format, &tm) == NULL) {
632 fprintf(stderr, "Error: Failed to parse date string '%s' with format '%s'\n", timestr[row], conversion->format);
633 exit(EXIT_FAILURE);
634 }
635 year = tm.tm_year + 1900;
636 month = tm.tm_mon + 1;
637 day = tm.tm_mday;
638 hour = tm.tm_hour + tm.tm_min / 60.0 + tm.tm_sec / 3600.0;
639 TimeBreakdownToEpoch((short)year, (short)jDay, (short)month, (short)day, hour, epochTime + row);
640 }
641 if (!SDDS_SetColumnFromDoubles(SDDSout, SDDS_BY_NAME, epochTime, rows, conversion->epochName))
642 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
643 SDDS_FreeStringArray(timestr, rows);
644 free(epochTime);
645#endif
646}
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.
void * SDDS_GetColumn(SDDS_DATASET *SDDS_dataset, char *column_name)
Retrieves a copy of the data for a specified column, including only rows marked as "of interest".
int32_t SDDS_FreeStringArray(char **string, int64_t strings)
Frees an array of strings by deallocating each individual string.
short TimeBreakdownToEpoch(short year, short jDay, short month, short day, double hour, double *epochTime)
Converts a broken-down time into epoch time.

◆ DoColumnEpochConversion()

void DoColumnEpochConversion ( SDDS_DATASET * SDDSout,
SDDS_DATASET * SDDSin,
TIME_CONVERSION * conversion )

Definition at line 571 of file sddstimeconvert.c.

571 {
572 double *hour;
573 double *month, *day, *jDay, *year, *epochTime;
574 int64_t row, rows;
575
576 year = NULL;
577
578 if (!(rows = SDDS_CountRowsOfInterest(SDDSin)))
579 return;
580
581 jDay = month = day = NULL;
582 if (!(hour = SDDS_GetColumnInDoubles(SDDSin, conversion->hourName)) ||
583 !(year = SDDS_GetColumnInDoubles(SDDSin, conversion->yearName)) ||
584 (conversion->jDayName && !(jDay = SDDS_GetColumnInDoubles(SDDSin, conversion->jDayName))) ||
585 (conversion->monthName && !(month = SDDS_GetColumnInDoubles(SDDSin, conversion->monthName))) ||
586 (conversion->dayName && !(day = SDDS_GetColumnInDoubles(SDDSin, conversion->dayName))))
587 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
588
589 if (!(epochTime = (double *)malloc(sizeof(*epochTime) * rows)))
590 SDDS_Bomb("Memory allocation failure");
591
592 for (row = 0; row < rows; row++)
593 TimeBreakdownToEpoch((short)year[row], jDay ? (short)jDay[row] : 0, month ? (short)month[row] : 0, day ? (short)day[row] : 0, hour[row], epochTime + row);
594 if (!SDDS_SetColumnFromDoubles(SDDSout, SDDS_BY_NAME, epochTime, rows, conversion->epochName))
595 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
596 free(hour);
597 free(year);
598 free(epochTime);
599 if (jDay)
600 free(jDay);
601 if (month)
602 free(month);
603 if (day)
604 free(day);
605}

◆ DoParameterBreakdownConversion()

void DoParameterBreakdownConversion ( SDDS_DATASET * SDDSout,
SDDS_DATASET * SDDSin,
TIME_CONVERSION * conversion )

Definition at line 509 of file sddstimeconvert.c.

509 {
510 double hour, epochTime;
511 short year, jDay, month, day;
512 char text[30];
513
514 if (!SDDS_GetParameterAsDouble(SDDSin, conversion->epochName, &epochTime))
515 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
516 TimeEpochToBreakdown(&year, &jDay, &month, &day, &hour, epochTime);
517 TimeEpochToText(text, epochTime);
518 if ((conversion->yearName &&
519 !SDDS_SetParametersFromDoubles(SDDSout, SDDS_BY_INDEX | SDDS_PASS_BY_VALUE,
520 conversion->yearIndex, (double)year, -1)) ||
521 (conversion->dayName &&
522 !SDDS_SetParametersFromDoubles(SDDSout, SDDS_BY_INDEX | SDDS_PASS_BY_VALUE,
523 conversion->dayIndex, (double)day, -1)) ||
524 (conversion->jDayName &&
525 !SDDS_SetParametersFromDoubles(SDDSout, SDDS_BY_INDEX | SDDS_PASS_BY_VALUE,
526 conversion->jDayIndex, (double)jDay, -1)) ||
527 (conversion->monthName &&
528 !SDDS_SetParametersFromDoubles(SDDSout, SDDS_BY_INDEX | SDDS_PASS_BY_VALUE,
529 conversion->monthIndex, (double)month, -1)) ||
530 (conversion->hourName &&
531 !SDDS_SetParametersFromDoubles(SDDSout, SDDS_BY_INDEX | SDDS_PASS_BY_VALUE,
532 conversion->hourIndex, (double)hour, -1)) ||
533 (conversion->textName &&
534 !SDDS_SetParameters(SDDSout, SDDS_BY_INDEX | SDDS_PASS_BY_VALUE, conversion->textIndex, text, -1)))
535 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
536}
int32_t SDDS_SetParametersFromDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
double * SDDS_GetParameterAsDouble(SDDS_DATASET *SDDS_dataset, char *parameter_name, double *memory)
Retrieves the value of a specified parameter as a double from the current data table of an SDDS datas...

◆ DoParameterDateToTimeConversion()

void DoParameterDateToTimeConversion ( SDDS_DATASET * SDDSout,
SDDS_DATASET * SDDSin,
TIME_CONVERSION * conversion )

Definition at line 538 of file sddstimeconvert.c.

538 {
539#if defined(_WIN32)
540 fprintf(stderr, "Error: strptime function needed by DoParameterDateToTimeConversion is not available on Windows\n");
541 exit(EXIT_FAILURE);
542#else
543 double hour;
544 double month = 0, day = 0, jDay = 0, year, epochTime;
545 char *timestr = NULL;
546 struct tm tm = {0};
547 /* Note that tm struct:
548 tm_year: years since 1900
549 tm_mon: months since January (0-11)
550 */
551
552 if (!SDDS_GetParameter(SDDSin, conversion->textName, &timestr)) {
553 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
554 exit(EXIT_FAILURE);
555 }
556 if (strptime(timestr, conversion->format, &tm) == NULL) {
557 fprintf(stderr, "Error: Failed to parse date string '%s' with format '%s'\n", timestr, conversion->format);
558 exit(EXIT_FAILURE);
559 }
560 year = tm.tm_year + 1900;
561 month = tm.tm_mon + 1;
562 day = tm.tm_mday;
563 hour = tm.tm_hour + tm.tm_min / 60.0 + tm.tm_sec / 3600.0;
564
565 TimeBreakdownToEpoch((short)year, (short)jDay, (short)month, (short)day, hour, &epochTime);
566 if (!SDDS_SetParametersFromDoubles(SDDSout, SDDS_BY_NAME | SDDS_PASS_BY_VALUE, conversion->epochName, epochTime, NULL))
567 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
568#endif
569}
void * SDDS_GetParameter(SDDS_DATASET *SDDS_dataset, char *parameter_name, void *memory)
Retrieves the value of a specified parameter from the current data table of a data set.

◆ DoParameterEpochConversion()

void DoParameterEpochConversion ( SDDS_DATASET * SDDSout,
SDDS_DATASET * SDDSin,
TIME_CONVERSION * conversion )

Definition at line 491 of file sddstimeconvert.c.

491 {
492 double hour;
493 double month = 0, day = 0, jDay = 0, year, epochTime;
494
495 jDay = 0;
496 if (!SDDS_GetParameterAsDouble(SDDSin, conversion->hourName, &hour) ||
497 !SDDS_GetParameterAsDouble(SDDSin, conversion->yearName, &year) ||
498 (conversion->jDayName && !SDDS_GetParameterAsDouble(SDDSin, conversion->jDayName, &jDay)) ||
499 (conversion->monthName && !SDDS_GetParameterAsDouble(SDDSin, conversion->monthName, &month)) ||
500 (conversion->dayName && !SDDS_GetParameterAsDouble(SDDSin, conversion->dayName, &day))) {
501 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
502 exit(EXIT_FAILURE);
503 }
504 TimeBreakdownToEpoch((short)year, (short)jDay, (short)month, (short)day, hour, &epochTime);
505 if (!SDDS_SetParametersFromDoubles(SDDSout, SDDS_BY_NAME | SDDS_PASS_BY_VALUE, conversion->epochName, epochTime, NULL))
506 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
507}

◆ InitializeOutput()

void InitializeOutput ( SDDS_DATASET * SDDSout,
char * outputfile,
TIME_CONVERSION * conversion,
long conversions,
SDDS_DATASET * SDDSin,
short columnMajorOrder )

Definition at line 412 of file sddstimeconvert.c.

413 {
414 if (!SDDS_InitializeCopy(SDDSout, SDDSin, outputfile, "w"))
415 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
416 if (columnMajorOrder != -1)
417 SDDSout->layout.data_mode.column_major = columnMajorOrder;
418 else
419 SDDSout->layout.data_mode.column_major = SDDSin->layout.data_mode.column_major;
420 while (conversions-- > 0) {
421 if (conversion->flags & DO_EPOCH) {
422 if (conversion->flags & IS_PARAMETER) {
423 if ((conversion->epochIndex = SDDS_DefineParameter(SDDSout, conversion->epochName,
424 NULL, "s", "Time since start of epoch", NULL, SDDS_DOUBLE, NULL)) < 0)
425 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
426 } else {
427 if ((conversion->epochIndex = SDDS_DefineColumn(SDDSout, conversion->epochName,
428 NULL, "s", "Time since start of epoch", NULL, SDDS_DOUBLE, 0)) < 0)
429 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
430 }
431 } else if (conversion->flags & DO_BREAKDOWN) {
432 if (conversion->flags & IS_PARAMETER) {
433 if ((conversion->yearName &&
434 (conversion->yearIndex = SDDS_DefineParameter(SDDSout, conversion->yearName, NULL, NULL, "Year", NULL,
435 SDDS_SHORT, NULL)) < 0) ||
436 (conversion->dayName &&
437 (conversion->dayIndex = SDDS_DefineParameter(SDDSout, conversion->dayName, NULL, NULL, "Day of month",
438 NULL, SDDS_SHORT, NULL)) < 0) ||
439 (conversion->monthName &&
440 (conversion->monthIndex = SDDS_DefineParameter(SDDSout, conversion->monthName, NULL, NULL, "Month", NULL,
441 SDDS_SHORT, NULL)) < 0) ||
442 (conversion->jDayName &&
443 (conversion->jDayIndex = SDDS_DefineParameter(SDDSout, conversion->jDayName, NULL, NULL, "Julian day",
444 NULL, SDDS_SHORT, NULL)) < 0) ||
445 (conversion->hourName &&
446 (conversion->hourIndex = SDDS_DefineParameter(SDDSout, conversion->hourName, NULL, NULL, "Hour of day",
447 NULL, SDDS_DOUBLE, NULL)) < 0) ||
448 (conversion->textName &&
449 (conversion->textIndex = SDDS_DefineParameter(SDDSout, conversion->textName, NULL, NULL, "Timestamp",
450 NULL, SDDS_STRING, NULL)) < 0))
451 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
452 } else {
453 if ((conversion->yearName &&
454 (conversion->yearIndex = SDDS_DefineColumn(SDDSout, conversion->yearName, NULL, NULL, "Year", NULL,
455 SDDS_SHORT, 0)) < 0) ||
456 (conversion->dayName &&
457 (conversion->dayIndex = SDDS_DefineColumn(SDDSout, conversion->dayName, NULL, NULL, "Day of month",
458 NULL, SDDS_SHORT, 0)) < 0) ||
459 (conversion->monthName &&
460 (conversion->monthIndex = SDDS_DefineColumn(SDDSout, conversion->monthName, NULL, NULL, "Month", NULL,
461 SDDS_SHORT, 0)) < 0) ||
462 (conversion->jDayName &&
463 (conversion->jDayIndex = SDDS_DefineColumn(SDDSout, conversion->jDayName, NULL, NULL, "Julian day",
464 NULL, SDDS_SHORT, 0)) < 0) ||
465 (conversion->hourName &&
466 (conversion->hourIndex = SDDS_DefineColumn(SDDSout, conversion->hourName, NULL, NULL, "Hour of day",
467 NULL, SDDS_DOUBLE, 0)) < 0) ||
468 (conversion->textName &&
469 (conversion->textIndex = SDDS_DefineColumn(SDDSout, conversion->textName, NULL, NULL, "Timestamp",
470 NULL, SDDS_STRING, 0)) < 0))
471 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
472 }
473 } else {
474 /* Date to time conversion */
475 if (conversion->flags & IS_PARAMETER) {
476 if ((conversion->epochIndex = SDDS_DefineParameter(SDDSout, conversion->epochName,
477 NULL, "s", "Time since start of epoch", NULL, SDDS_DOUBLE, NULL)) < 0)
478 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
479 } else {
480 if ((conversion->epochIndex = SDDS_DefineColumn(SDDSout, conversion->epochName,
481 NULL, "s", "Time since start of epoch", NULL, SDDS_DOUBLE, 0)) < 0)
482 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
483 }
484 }
485 conversion++;
486 }
487 if (!SDDS_WriteLayout(SDDSout))
488 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
489}
int32_t SDDS_InitializeCopy(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, char *filename, char *filemode)
Definition SDDS_copy.c:40
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.
#define SDDS_SHORT
Identifier for the signed short integer data type.
Definition SDDStypes.h:73
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37

◆ main()

int main ( int argc,
char ** argv )

Definition at line 131 of file sddstimeconvert.c.

131 {
132 SDDS_DATASET SDDSin, SDDSout;
133 long i_arg, iconv;
134 SCANNED_ARG *s_arg;
135 char *input, *output;
136 TIME_CONVERSION *conversion;
137 long conversions;
138 unsigned long pipeFlags, majorOrderFlag;
139 short columnMajorOrder = -1;
140
142 argc = scanargs(&s_arg, argc, argv);
143 if (argc < 3) {
144 fprintf(stderr, "%s", USAGE);
145 exit(EXIT_FAILURE);
146 }
147
148 input = output = NULL;
149 conversions = 0;
150 conversion = NULL;
151 pipeFlags = 0;
152
153 for (i_arg = 1; i_arg < argc; i_arg++) {
154 if (s_arg[i_arg].arg_type == OPTION) {
155 switch (match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
156 case SET_MAJOR_ORDER:
157 majorOrderFlag = 0;
158 s_arg[i_arg].n_items--;
159 if (s_arg[i_arg].n_items > 0 &&
160 (!scanItemList(&majorOrderFlag, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
161 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
162 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
163 SDDS_Bomb("invalid -majorOrder syntax/values");
164 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
165 columnMajorOrder = 1;
166 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
167 columnMajorOrder = 0;
168 break;
169 case SET_EPOCH:
170 if (s_arg[i_arg].n_items < 4)
171 SDDS_Bomb("Invalid -epoch syntax");
172 if (!(conversion = SDDS_Realloc(conversion, sizeof(*conversion) * (conversions + 1))))
173 SDDS_Bomb("Memory allocation failure");
174 memset((char *)(conversion + conversions), 0, sizeof(*conversion));
175 conversion[conversions].epochName = s_arg[i_arg].list[2];
176 s_arg[i_arg].list[2] = s_arg[i_arg].list[1];
177 s_arg[i_arg].n_items -= 2;
178 if (!scanItemList(&conversion[conversions].flags,
179 s_arg[i_arg].list + 2, &s_arg[i_arg].n_items, 0,
180 "column", -1, NULL, 0, IS_COLUMN,
181 "parameter", -1, NULL, 0, IS_PARAMETER,
182 "year", SDDS_STRING, &conversion[conversions].yearName, 1, YEAR_GIVEN,
183 "julianday", SDDS_STRING, &conversion[conversions].jDayName, 1, JDAY_GIVEN,
184 "month", SDDS_STRING, &conversion[conversions].monthName, 1, MONTH_GIVEN,
185 "day", SDDS_STRING, &conversion[conversions].dayName, 1, DAY_GIVEN,
186 "hour", SDDS_STRING, &conversion[conversions].hourName, 1, HOUR_GIVEN, NULL))
187 SDDS_Bomb("invalid -epoch syntax");
188 conversion[conversions].flags |= EPOCH_GIVEN | DO_EPOCH;
189 if (!(conversion[conversions].flags & (IS_COLUMN | IS_PARAMETER)))
190 SDDS_Bomb("Specify 'column' or 'parameter' qualifier with -epoch");
191 if (conversion[conversions].flags & IS_COLUMN && conversion[conversions].flags & IS_PARAMETER)
192 SDDS_Bomb("Specify only one of 'column' or 'parameter' qualifier with -epoch");
193 if (!(conversion[conversions].flags & YEAR_GIVEN))
194 SDDS_Bomb("Specify year name with -epoch");
195 if (!(conversion[conversions].flags & JDAY_GIVEN) &&
196 (conversion[conversions].flags & (MONTH_GIVEN | DAY_GIVEN)) != (MONTH_GIVEN | DAY_GIVEN))
197 SDDS_Bomb("Specify either julianDay name, or both month and day names with -epoch");
198 if (conversion[conversions].flags & JDAY_GIVEN && conversion[conversions].flags & (MONTH_GIVEN | DAY_GIVEN))
199 SDDS_Bomb("Invalid combination of julianDay name with month or day name for -epoch");
200 conversions++;
201 break;
202 case SET_BREAKDOWN:
203 if (s_arg[i_arg].n_items < 4)
204 SDDS_Bomb("Invalid -breakdown syntax");
205 if (!(conversion = SDDS_Realloc(conversion, sizeof(*conversion) * (conversions + 1))))
206 SDDS_Bomb("Memory allocation failure");
207 memset((char *)(conversion + conversions), 0, sizeof(*conversion));
208 conversion[conversions].epochName = s_arg[i_arg].list[2];
209 s_arg[i_arg].list[2] = s_arg[i_arg].list[1];
210 s_arg[i_arg].n_items -= 2;
211 if (!scanItemList(&conversion[conversions].flags,
212 s_arg[i_arg].list + 2, &s_arg[i_arg].n_items, 0,
213 "column", -1, NULL, 0, IS_COLUMN,
214 "parameter", -1, NULL, 0, IS_PARAMETER,
215 "year", SDDS_STRING, &conversion[conversions].yearName, 1, YEAR_GIVEN,
216 "julianday", SDDS_STRING, &conversion[conversions].jDayName, 1, JDAY_GIVEN,
217 "month", SDDS_STRING, &conversion[conversions].monthName, 1, MONTH_GIVEN,
218 "day", SDDS_STRING, &conversion[conversions].dayName, 1, DAY_GIVEN,
219 "hour", SDDS_STRING, &conversion[conversions].hourName, 1, HOUR_GIVEN,
220 "text", SDDS_STRING, &conversion[conversions].textName, 1, TEXT_GIVEN, NULL))
221 SDDS_Bomb("invalid -breakdown syntax");
222 conversion[conversions].flags |= EPOCH_GIVEN | DO_BREAKDOWN;
223 if (!(conversion[conversions].flags & (IS_COLUMN | IS_PARAMETER)))
224 SDDS_Bomb("Specify 'column' or 'parameter' qualifier with -breakdown");
225 if (conversion[conversions].flags & IS_COLUMN && conversion[conversions].flags & IS_PARAMETER)
226 SDDS_Bomb("Specify only one of 'column' or 'parameter' qualifier with -breakdown");
227 if (!(conversion[conversions].flags & (YEAR_GIVEN | JDAY_GIVEN | MONTH_GIVEN | DAY_GIVEN | HOUR_GIVEN | TEXT_GIVEN)))
228 SDDS_Bomb("Specify at least one of year, julianDay, month, day, hour, or text qualifiers with -breakdown");
229 conversions++;
230 break;
231 case SET_DATE:
232 if (s_arg[i_arg].n_items < 4)
233 SDDS_Bomb("Invalid -dateToTime syntax");
234 if (!(conversion = SDDS_Realloc(conversion, sizeof(*conversion) * (conversions + 1))))
235 SDDS_Bomb("Memory allocation failure");
236 memset((char *)(conversion + conversions), 0, sizeof(*conversion));
237 conversion[conversions].textName = s_arg[i_arg].list[3];
238 conversion[conversions].epochName = s_arg[i_arg].list[2];
239 s_arg[i_arg].list[3] = s_arg[i_arg].list[1];
240 s_arg[i_arg].n_items -= 3;
241 if (!scanItemList(&conversion[conversions].flags,
242 s_arg[i_arg].list + 3, &s_arg[i_arg].n_items, 0,
243 "column", -1, NULL, 0, IS_COLUMN,
244 "parameter", -1, NULL, 0, IS_PARAMETER,
245 "format", SDDS_STRING, &conversion[conversions].format, 1, FORMAT_GIVEN, NULL))
246 SDDS_Bomb("invalid -dateToTime syntax");
247 conversion[conversions].flags |= DO_DATECONVERSION;
248 if (!(conversion[conversions].flags & (IS_COLUMN | IS_PARAMETER)))
249 SDDS_Bomb("Specify 'column' or 'parameter' qualifier with -dateToTime");
250 if (conversion[conversions].flags & IS_COLUMN && conversion[conversions].flags & IS_PARAMETER)
251 SDDS_Bomb("Specify only one of 'column' or 'parameter' qualifier with -dateToTime");
252 if (!(conversion[conversions].flags & FORMAT_GIVEN))
253 SDDS_Bomb("Format string not provided for date to time conversion");
254 conversions++;
255 break;
256 case SET_PIPE:
257 if (!processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
258 SDDS_Bomb("Invalid -pipe syntax");
259 break;
260 default:
261 fprintf(stderr, "Error: Unknown option: %s\n", s_arg[i_arg].list[0]);
262 SDDS_Bomb(NULL);
263 break;
264 }
265 } else {
266 if (!input)
267 input = s_arg[i_arg].list[0];
268 else if (!output)
269 output = s_arg[i_arg].list[0];
270 else {
271 fprintf(stderr, "Error: Argument '%s' is invalid: too many filenames (sddstimeconvert)\n", s_arg[i_arg].list[0]);
272 exit(EXIT_FAILURE);
273 }
274 }
275 }
276
277 processFilenames("sddstimeconvert", &input, &output, pipeFlags, 0, NULL);
278
279 if (!SDDS_InitializeInput(&SDDSin, input)) {
280 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
281 exit(EXIT_FAILURE);
282 }
283
284 CheckEpochConversionElements(&SDDSin, conversion, conversions);
285 CheckBreakdownConversionElements(&SDDSin, conversion, conversions);
286 CheckDateConversionElements(&SDDSin, conversion, conversions);
287
288 InitializeOutput(&SDDSout, output, conversion, conversions, &SDDSin, columnMajorOrder);
289
290 while (SDDS_ReadPage(&SDDSin) > 0) {
291 if (!SDDS_CopyPage(&SDDSout, &SDDSin)) {
292 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
293 exit(EXIT_FAILURE);
294 }
295 for (iconv = 0; iconv < conversions; iconv++) {
296 if (conversion[iconv].flags & DO_EPOCH) {
297 if (conversion[iconv].flags & IS_PARAMETER)
298 DoParameterEpochConversion(&SDDSout, &SDDSin, conversion + iconv);
299 else
300 DoColumnEpochConversion(&SDDSout, &SDDSin, conversion + iconv);
301 } else if (conversion[iconv].flags & DO_BREAKDOWN) {
302 if (conversion[iconv].flags & IS_PARAMETER)
303 DoParameterBreakdownConversion(&SDDSout, &SDDSin, conversion + iconv);
304 else
305 DoColumnBreakdownConversion(&SDDSout, &SDDSin, conversion + iconv);
306 } else {
307 /* Convert date string to double time */
308 if (conversion[iconv].flags & IS_PARAMETER)
309 DoParameterDateToTimeConversion(&SDDSout, &SDDSin, conversion + iconv);
310 else
311 DoColumnDateToTimeConversion(&SDDSout, &SDDSin, conversion + iconv);
312 }
313 }
314 if (!SDDS_WritePage(&SDDSout)) {
315 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
316 exit(EXIT_FAILURE);
317 }
318 }
319 if (!SDDS_Terminate(&SDDSin) || !SDDS_Terminate(&SDDSout)) {
320 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
321 exit(EXIT_FAILURE);
322 }
323
324 return EXIT_SUCCESS;
325}
int32_t SDDS_CopyPage(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:578
int32_t SDDS_InitializeInput(SDDS_DATASET *SDDS_dataset, char *filename)
Definition SDDS_input.c:49
int32_t SDDS_Terminate(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_ReadPage(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:288
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
Definition SDDS_utils.c:677
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
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.