32#include "match_string.h"
35#define SET_SIGNAL_NAME 0
36#define SET_DESCRIPTION 1
37#define SET_MPL_LABELS 2
38#define SET_INITIAL_T 3
39#define SET_SINGLE_PRECISION 4
40#define SET_SEGMENT_INTERVAL 5
41#define SET_SEPARATE_SEGMENTS 6
43#define SET_MAJOR_ORDER 8
46static char *option[N_OPTIONS] = {
58char *USAGE =
"hpif2sdds <inputfile> <outputfile>\n\
59 -signalname={<name>|<name1>,<name2>}\n\
60 [-description=<text>,<contents>]\n\
61 [-mpllabels=<title>,<topline>]\n\
62 [-initialt=<value>] [-singleprecision]\n\
63 [-segmentinterval=<time-in-secs>]\n\
64 [-separatesegments] [-pairs] [-majorOrder=row|column] \n\n\
65This program converts HP internal format waveforms to SDDS format.\n\n\
66Program by Michael Borland (" __DATE__
" " __TIME__
", SVN revision: " SVN_VERSION
")\n";
69long get_next_field(
char *buffer, FILE *fp);
70long set_2d_parameters(
SDDS_TABLE *table,
char *variable,
double initial,
long dimension,
double increment);
71long define_2d_parameters(
SDDS_TABLE *table,
char *parameter,
char *variable,
char *units);
72void swapdouble(
double *data);
74int main(
int argc,
char **argv) {
77 long i, i_arg, points, single_precision;
78 char *input, *output, buffer[BUFSIZE];
80 char *mpl_title, *mpl_topline, *descrip_text, *descrip_contents;
82 double xIncrement, xOrigin, yScale, yOffset;
83 long xReference, yReference, segments, segment_length, separate_segments;
84 double *time, *data, *data1;
85 float *sp_time, *sp_data, *sp_data1;
86 short *idata, *idata1;
87 double initial_t, segment_interval;
88 long code1, code2, pairs, size, length;
89 short columnMajorOrder = 0;
90 unsigned long majorOrderFlag;
92 argc =
scanargs(&scanned, argc, argv);
96 time = data = data1 = NULL;
97 sp_time = sp_data = sp_data1 = NULL;
98 input = output = NULL;
99 mpl_title = mpl_topline = descrip_text = descrip_contents = NULL;
101 single_precision = 0;
102 signal_name[0] = signal_name[1] = NULL;
103 segment_interval = separate_segments = pairs = 0;
105 for (i_arg = 1; i_arg < argc; i_arg++) {
106 if (scanned[i_arg].arg_type == OPTION) {
109 switch (
match_string(scanned[i_arg].list[0], option, N_OPTIONS, 0)) {
110 case SET_MAJOR_ORDER:
112 scanned[i_arg].n_items--;
113 if (scanned[i_arg].n_items > 0 && (!
scanItemList(&majorOrderFlag, scanned[i_arg].list + 1, &scanned[i_arg].n_items, 0,
"row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
"column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
114 SDDS_Bomb(
"invalid -majorOrder syntax/values");
115 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
116 columnMajorOrder = 1;
117 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
118 columnMajorOrder = 0;
120 case SET_SIGNAL_NAME:
121 if (scanned[i_arg].n_items != 2 && scanned[i_arg].n_items != 3)
123 signal_name[0] = scanned[i_arg].list[1];
124 if (scanned[i_arg].n_items == 3)
125 signal_name[1] = scanned[i_arg].list[2];
127 case SET_DESCRIPTION:
128 if (scanned[i_arg].n_items != 3)
129 SDDS_Bomb(
"invalid -description syntax");
130 descrip_text = scanned[i_arg].list[1];
131 descrip_contents = scanned[i_arg].list[2];
134 if (scanned[i_arg].n_items != 3)
136 mpl_title = scanned[i_arg].list[1];
137 mpl_topline = scanned[i_arg].list[2];
140 if (scanned[i_arg].n_items != 2 || sscanf(scanned[i_arg].list[1],
"%lf", &initial_t) != 1)
143 case SET_SINGLE_PRECISION:
144 single_precision = 1;
146 case SET_SEGMENT_INTERVAL:
147 if (scanned[i_arg].n_items != 2 || sscanf(scanned[i_arg].list[1],
"%lf", &segment_interval) != 1)
148 SDDS_Bomb(
"invalid -segmentinterval syntax");
150 case SET_SEPARATE_SEGMENTS:
151 separate_segments = 1;
162 input = scanned[i_arg].list[0];
164 output = scanned[i_arg].list[0];
175 length = strlen(
":WAV:PRE ");
176 if (fread(buffer, 1, length, fpi) != length || strncmp(buffer,
":WAV:PRE ", length) != 0) {
177 printf(
"buffer = \"%s\"\n", buffer);
178 SDDS_Bomb(
"file does not appear to be in HP internal format (1)");
180 if (!get_next_field(buffer, fpi) || sscanf(buffer,
"%ld", &code1) != 1)
181 SDDS_Bomb(
"file does not appear to be in HP internal format (2)");
182 if (!get_next_field(buffer, fpi) || sscanf(buffer,
"%ld", &code2) != 1)
183 SDDS_Bomb(
"file does not appear to be in HP internal format (3)");
184 if (!get_next_field(buffer, fpi) || sscanf(buffer,
"%ld", &segment_length) != 1)
185 SDDS_Bomb(
"file does not appear to be in HP internal format (4)");
186 if (!get_next_field(buffer, fpi) || sscanf(buffer,
"%ld", &segments) != 1) {
187 fprintf(stderr,
"file does not appear to be in HP internal format (5)\n");
190 points = segments * segment_length;
193 fprintf(stderr,
"%ld points, %ld segments\n", points, segments);
195 fprintf(stderr,
"data appears to come in point pairs\n");
198 if (!get_next_field(buffer, fpi) || sscanf(buffer,
"%le", &xIncrement) != 1)
201 fprintf(stderr,
"x increment = %e\n", xIncrement);
204 if (!get_next_field(buffer, fpi) || sscanf(buffer,
"%le", &xOrigin) != 1)
207 fprintf(stderr,
"x origin = %e\n", xOrigin);
210 if (!get_next_field(buffer, fpi) || sscanf(buffer,
"%ld", &xReference) != 1)
213 fprintf(stderr,
"x reference = %ld\n", xReference);
216 if (!get_next_field(buffer, fpi) || sscanf(buffer,
"%lf", &yScale) != 1)
217 SDDS_Bomb(
"unable to get y scale factor");
219 fprintf(stderr,
"y scale = %e\n", yScale);
222 if (!get_next_field(buffer, fpi) || sscanf(buffer,
"%lf", &yOffset) != 1)
225 fprintf(stderr,
"y offset = %e\n", yOffset);
228 if (!get_next_field(buffer, fpi) || sscanf(buffer,
"%ld", &yReference) != 1)
231 fprintf(stderr,
"y reference = %ld\n", yReference);
234 while (fread(buffer, 1, 1, fpi))
235 if (buffer[0] ==
'#')
237 fread(buffer, 1, 9, fpi);
238 if (!sscanf(buffer + 1,
"%ld", &size))
239 SDDS_Bomb(
"unable to read size of data block");
241 fprintf(stderr,
"data block is %ld bytes\n", size);
245 double segment_offset;
246 for (i = 0; i < segments; i++) {
247 if (!fread(&segment_offset,
sizeof(segment_offset), 1, fpi))
248 SDDS_Bomb(
"unable to read segment offsets");
252 idata =
tmalloc(
sizeof(*idata) * points);
253 idata1 =
tmalloc(
sizeof(*idata1) * points);
254 if (!single_precision) {
255 data =
tmalloc(
sizeof(*data) * points);
256 data1 =
tmalloc(
sizeof(*data1) * points);
258 sp_data =
tmalloc(
sizeof(*sp_data) * points);
259 sp_data1 =
tmalloc(
sizeof(*sp_data1) * points);
262 fprintf(stderr,
"arrays allocated\n");
265 if (!fread(idata, 2, points, fpi))
267 if (pairs && !fread(idata1, 2, points, fpi))
268 SDDS_Bomb(
"unable to read second data block");
270 fprintf(stderr,
"data read in\n");
273 if (!single_precision) {
274 for (i = 0; i < points; i++) {
275 data[i] = (idata[i] - yReference) * yScale + yOffset;
276 data1[i] = (idata1[i] - yReference) * yScale + yOffset;
279 for (i = 0; i < points; i++) {
280 sp_data[i] = (idata[i] - yReference) * yScale + yOffset;
281 sp_data1[i] = (idata1[i] - yReference) * yScale + yOffset;
286 fprintf(stderr,
"data copied\n");
292 fprintf(stderr,
"output initialized\n");
294 SDDS_table.layout.data_mode.column_major = columnMajorOrder;
295 if (mpl_title && (
SDDS_DefineParameter(&SDDS_table,
"mplTitle", NULL, NULL, NULL, NULL,
SDDS_STRING, mpl_title) < 0 ||
SDDS_DefineParameter(&SDDS_table,
"mplTopline", NULL, NULL, NULL, NULL,
SDDS_STRING, mpl_topline) < 0))
298 fprintf(stderr,
"title defined\n");
302 if (define_2d_parameters(&SDDS_table,
"Variable1Name",
"Segment", NULL) == 0 ||
303 define_2d_parameters(&SDDS_table,
"Variable2Name",
"t",
"s") == 0)
307 if (signal_name[0] == NULL) {
309 signal_name[0] =
"V";
311 signal_name[0] =
"V1";
312 signal_name[1] =
"V2";
316 if (pairs && !signal_name[1])
317 SDDS_Bomb(
"data contains voltage pairs--supply two signal names");
325 fflush(SDDS_table.layout.fp);
327 if (!single_precision) {
328 time =
tmalloc(
sizeof(*time) * points);
329 if (initial_t == DBL_MAX)
330 initial_t = xOrigin - xReference * xIncrement;
331 for (i = 0; i < points; i++) {
332 if (segments != 1 && i && i % segment_length == 0)
333 initial_t += segment_interval - segment_length * xIncrement;
334 time[i] = i * xIncrement + initial_t;
337 sp_time =
tmalloc(
sizeof(*sp_time) * points);
338 if (initial_t == DBL_MAX)
339 initial_t = xOrigin - xReference * xIncrement;
340 for (i = 0; i < points; i++) {
341 if (segments != 1 && i && i % segment_length == 0)
342 initial_t += segment_interval - segment_length * xIncrement;
343 sp_time[i] = i * xIncrement + initial_t;
349 if (!SDDS_StartTable(&SDDS_table, separate_segments ? segment_length : points))
351 if (segments != 1 && i == 1) {
352 if (!set_2d_parameters(&SDDS_table,
"Segment", 0.0, segments, 1.0) || !set_2d_parameters(&SDDS_table,
"t", initial_t, segment_length, xIncrement))
357 fprintf(stderr,
"row and column parameters set for table %ld\n", i);
361 single_precision ? (
void *)(sp_time + (i - 1) * segment_length)
362 : (
void *)(time + (i - 1) * segment_length),
363 separate_segments ? segment_length : points,
"t") ||
365 single_precision ? (
void *)(sp_data + (i - 1) * segment_length)
366 : (
void *)(data + (i - 1) * segment_length),
367 separate_segments ? segment_length : points, signal_name[0]) ||
368 (pairs && !
SDDS_SetColumn(&SDDS_table, SDDS_SET_BY_NAME, single_precision ? (
void *)(sp_data1 + (i - 1) * segment_length) : (
void *)(data1 + (i - 1) * segment_length), separate_segments ? segment_length : points, signal_name[1])) || !SDDS_WriteTable(&SDDS_table))
370 }
while (separate_segments && ++i <= segments);
376char *process_column_definition(
char **argv,
long argc) {
377 char buffer[SDDS_MAXLINE], *ptr;
382 sprintf(buffer,
"&column name=%s, ", argv[0]);
383 for (i = 1; i < argc; i++) {
384 if (!strchr(argv[i],
'='))
386 strcat(buffer, argv[i]);
387 strcat(buffer,
", ");
389 if (!strstr(buffer,
"type="))
390 strcat(buffer,
"type=character ");
391 strcat(buffer,
"&end");
396long get_next_field(
char *buffer, FILE *fp) {
399 while ((buffer[i] = fgetc(fp))) {
400 buffer[i] = tolower(buffer[i]);
401 if (buffer[i] ==
',' || buffer[i] ==
';')
409long define_2d_parameters(
SDDS_TABLE *table,
char *parameter,
char *variable,
char *units) {
410 char buffer[BUFSIZE];
412 sprintf(buffer,
"%sMinimum", variable);
414 sprintf(buffer,
"%sInterval", variable);
416 sprintf(buffer,
"%sDimension", variable);
425long set_2d_parameters(
SDDS_TABLE *table,
char *variable,
double initial,
long dimension,
double increment) {
426 char buffer[BUFSIZE];
427 sprintf(buffer,
"%sMinimum", variable);
428 SDDS_SetParameters(table, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, buffer, initial, NULL);
429 sprintf(buffer,
"%sInterval", variable);
430 SDDS_SetParameters(table, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, buffer, increment, NULL);
431 sprintf(buffer,
"%sDimension", variable);
432 SDDS_SetParameters(table, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, buffer, dimension, NULL);
440void swapdouble(
double *data) {
444 for (i = 0; i < 8; i++)
445 *(((
char *)data) + i) = *(((
char *)©) + (8 - i));
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
int32_t SDDS_SetColumn(SDDS_DATASET *SDDS_dataset, int32_t mode, void *data, int64_t rows,...)
Sets the values for one data column in the current data table of an SDDS dataset.
int32_t SDDS_InitializeOutput(SDDS_DATASET *SDDS_dataset, int32_t data_mode, int32_t lines_per_row, const char *description, const char *contents, const char *filename)
Initializes the SDDS output dataset.
int32_t SDDS_DefineColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, int32_t field_length)
Defines a data column within the SDDS dataset.
int32_t SDDS_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
int32_t SDDS_DefineParameter(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, char *fixed_value)
Defines a data parameter with a fixed string value.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
int32_t SDDS_NumberOfErrors()
Retrieves the number of errors recorded by SDDS library routines.
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
#define SDDS_FLOAT
Identifier for the float data type.
#define SDDS_STRING
Identifier for the string data type.
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
#define SDDS_DOUBLE
Identifier for the double data type.
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
char * cp_str(char **s, char *t)
Copies a string, allocating memory for storage.
char * delete_chars(char *s, char *t)
Removes all occurrences of characters found in string t from string s.
FILE * fopen_e(char *file, char *open_mode, long mode)
Opens a file with error checking, messages, and aborts.
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)
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.