SDDSlib
All Classes Files Functions Variables Macros Pages
hpwf2sdds.c File Reference

Converts waveform data from the older HP oscilloscope's verbose format to SDDS (Self Describing Data Sets) format. More...

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

Go to the source code of this file.

Classes

struct  HP_PARAMETER
 

Macros

#define HP_PARAMETERS   23
 
#define BUFSIZE   256
 

Enumerations

enum  option_type {
  SET_SIGNAL_NAME , SET_DESCRIPTION , SET_MPL_LABELS , SET_MAJOR_ORDER ,
  N_OPTIONS
}
 

Functions

int main (int argc, char **argv)
 
char * process_column_definition (char **argv, long argc)
 

Variables

static char * option [N_OPTIONS]
 
char * USAGE
 
HP_PARAMETER HP_parameter [HP_PARAMETERS]
 
char * HP_DataMarker = "Data"
 
char * HP_XIncrementName = "XInc"
 
char * HP_XOriginName = "XOrg"
 
char * HP_XReferenceName = "XRef"
 
char * HP_XUnitsName = "X Units"
 
char * HP_YUnitsName = "Y Units"
 
char * HP_PointsName = "Points"
 

Detailed Description

Converts waveform data from the older HP oscilloscope's verbose format to SDDS (Self Describing Data Sets) format.

This program reads a waveform from an HP scope output file and converts it into the SDDS format, which is widely used for storing and sharing scientific data. The user can specify various options to customize the conversion process, including setting signal names, descriptions, MPL (Matplotlib) labels, and the major order of data storage.

Usage

hpwf2sdds <inputfile> <outputfile> [options]
  • <inputfile>: Path to the input file containing the HP waveform data.
  • <outputfile>: Path where the converted SDDS file will be saved.

Options

  • -signalname=<name>: Specifies the name of the signal in the SDDS file.
  • -description=<text>,<contents>: Provides a description for the SDDS data set.
  • -mpllabels=<title>,<topline>: Sets the title and topline labels for MPL (Matplotlib) plots.
  • -majorOrder=row|column: Determines the major order of data storage, either row-major or column-major.
License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
M. Borland, C. Saunders, R. Soliday, H. Shang

Definition in file hpwf2sdds.c.

Macro Definition Documentation

◆ BUFSIZE

#define BUFSIZE   256

Definition at line 112 of file hpwf2sdds.c.

◆ HP_PARAMETERS

#define HP_PARAMETERS   23

Definition at line 77 of file hpwf2sdds.c.

Enumeration Type Documentation

◆ option_type

enum option_type

Definition at line 43 of file hpwf2sdds.c.

43 {
44 SET_SIGNAL_NAME,
45 SET_DESCRIPTION,
46 SET_MPL_LABELS,
47 SET_MAJOR_ORDER,
48 N_OPTIONS
49};

Function Documentation

◆ main()

int main ( int argc,
char ** argv )

Definition at line 114 of file hpwf2sdds.c.

114 {
115 SDDS_TABLE SDDS_table;
116 SCANNED_ARG *scanned;
117 long i, i_arg, index, points;
118 char *input, *output, buffer[BUFSIZE];
119 char *signal_name, *ptr, *parameter_name;
120 char *mpl_title, *mpl_topline, *descrip_text, *descrip_contents;
121 FILE *fpi;
122 double xIncrement, xOrigin, xReference;
123 char *xUnits, *yUnits;
124 double *time, *data;
125 unsigned long majorOrderFlag;
126 short columnMajorOrder = -1;
127
128 argc = scanargs(&scanned, argc, argv);
129 if (argc < 3) {
130 fprintf(stderr, "Error: Insufficient arguments provided.\n\n%s", USAGE);
131 return EXIT_FAILURE;
132 }
133
134 input = output = signal_name = xUnits = yUnits = NULL;
135 mpl_title = mpl_topline = descrip_text = descrip_contents = NULL;
136
137 for (i_arg = 1; i_arg < argc; i_arg++) {
138 if (scanned[i_arg].arg_type == OPTION) {
139 delete_chars(scanned[i_arg].list[0], "_");
140 /* Process options here */
141 switch (match_string(scanned[i_arg].list[0], option, N_OPTIONS, 0)) {
142 case SET_MAJOR_ORDER:
143 majorOrderFlag = 0;
144 scanned[i_arg].n_items--;
145 if (scanned[i_arg].n_items > 0 &&
146 !scanItemList(&majorOrderFlag, scanned[i_arg].list + 1, &scanned[i_arg].n_items, 0,
147 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
148 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)) {
149 fprintf(stderr, "Error: Invalid syntax or value for -majorOrder option.\n");
150 return EXIT_FAILURE;
151 }
152 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
153 columnMajorOrder = 1;
154 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
155 columnMajorOrder = 0;
156 break;
157 case SET_SIGNAL_NAME:
158 if (scanned[i_arg].n_items != 2) {
159 fprintf(stderr, "Error: Invalid syntax for -signalname option.\n");
160 return EXIT_FAILURE;
161 }
162 signal_name = scanned[i_arg].list[1];
163 break;
164 case SET_DESCRIPTION:
165 if (scanned[i_arg].n_items != 3) {
166 fprintf(stderr, "Error: Invalid syntax for -description option.\n");
167 return EXIT_FAILURE;
168 }
169 descrip_text = scanned[i_arg].list[1];
170 descrip_contents = scanned[i_arg].list[2];
171 break;
172 case SET_MPL_LABELS:
173 if (scanned[i_arg].n_items != 3) {
174 fprintf(stderr, "Error: Invalid syntax for -mpllabels option.\n");
175 return EXIT_FAILURE;
176 }
177 mpl_title = scanned[i_arg].list[1];
178 mpl_topline = scanned[i_arg].list[2];
179 break;
180 default:
181 fprintf(stderr, "Error: Unrecognized option '%s'.\n", scanned[i_arg].list[0]);
182 return EXIT_FAILURE;
183 }
184 } else {
185 if (!input)
186 input = scanned[i_arg].list[0];
187 else if (!output)
188 output = scanned[i_arg].list[0];
189 else {
190 fprintf(stderr, "Error: Too many filenames provided.\n");
191 return EXIT_FAILURE;
192 }
193 }
194 }
195
196 if (!input) {
197 fprintf(stderr, "Error: Input file not specified.\n\n%s", USAGE);
198 return EXIT_FAILURE;
199 }
200 if (!output) {
201 fprintf(stderr, "Error: Output file not specified.\n\n%s", USAGE);
202 return EXIT_FAILURE;
203 }
204 if (!signal_name) {
205 fprintf(stderr, "Error: -signalname option not specified.\n\n%s", USAGE);
206 return EXIT_FAILURE;
207 }
208
209 fpi = fopen_e(input, "r", 0);
210 parameter_name = buffer;
211 while (fgets(buffer, BUFSIZE, fpi)) {
212 if (!(ptr = strchr(buffer, ':'))) {
213 fprintf(stderr, "Error: Missing colon in parameter tag '%s'.\n", buffer);
214 return EXIT_FAILURE;
215 }
216 *ptr++ = '\0';
217 if (strcmp(HP_DataMarker, parameter_name) == 0)
218 break;
219 index = 0;
220 while (HP_parameter[index].HP_name) {
221 if (strcmp(HP_parameter[index].HP_name, parameter_name) == 0)
222 break;
223 index++;
224 }
225 if (!HP_parameter[index].HP_name) {
226 fprintf(stderr, "Error: Unrecognized parameter name '%s'.\n", parameter_name);
227 return EXIT_FAILURE;
228 }
229 if (HP_parameter[index].value_string) {
230 fprintf(stderr, "Error: Duplicate entry for parameter '%s'.\n", parameter_name);
231 return EXIT_FAILURE;
232 }
234 cp_str(&HP_parameter[index].value_string, ptr);
235 }
236
237 if (!SDDS_InitializeOutput(&SDDS_table, SDDS_BINARY, 0, descrip_text, descrip_contents, output)) {
238 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
239 return EXIT_FAILURE;
240 }
241 if (columnMajorOrder != -1)
242 SDDS_table.layout.data_mode.column_major = columnMajorOrder;
243
244 index = 0;
245 while (HP_parameter[index].HP_name) {
246 if (!HP_parameter[index].value_string) {
247 index++;
248 continue;
249 }
250 if (strcmp(HP_parameter[index].HP_name, HP_XIncrementName) == 0) {
251 if (sscanf(HP_parameter[index].value_string, "%lf", &xIncrement) != 1) {
252 fprintf(stderr, "Error: Unable to parse value for X increment.\n");
253 return EXIT_FAILURE;
254 }
255 } else if (strcmp(HP_parameter[index].HP_name, HP_XOriginName) == 0) {
256 if (sscanf(HP_parameter[index].value_string, "%lf", &xOrigin) != 1) {
257 fprintf(stderr, "Error: Unable to parse value for X origin.\n");
258 return EXIT_FAILURE;
259 }
260 } else if (strcmp(HP_parameter[index].HP_name, HP_XReferenceName) == 0) {
261 if (sscanf(HP_parameter[index].value_string, "%lf", &xReference) != 1) {
262 fprintf(stderr, "Error: Unable to parse value for X reference.\n");
263 return EXIT_FAILURE;
264 }
265 } else if (strcmp(HP_parameter[index].HP_name, HP_XUnitsName) == 0) {
266 xUnits = HP_parameter[index].value_string;
267 } else if (strcmp(HP_parameter[index].HP_name, HP_YUnitsName) == 0) {
268 yUnits = HP_parameter[index].value_string;
269 } else if (strcmp(HP_parameter[index].HP_name, HP_PointsName) == 0) {
270 if (sscanf(HP_parameter[index].value_string, "%ld", &points) != 1) {
271 fprintf(stderr, "Error: Unable to parse value for number of points.\n");
272 return EXIT_FAILURE;
273 }
274 }
275 if (SDDS_DefineParameter(&SDDS_table, HP_parameter[index].SDDS_name, NULL, NULL,
276 HP_parameter[index].HP_name, NULL,
277 HP_parameter[index].type, HP_parameter[index].value_string) < 0) {
278 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
279 return EXIT_FAILURE;
280 }
281 index++;
282 }
283
284 if (mpl_title && (SDDS_DefineParameter(&SDDS_table, "mplTitle", NULL, NULL, NULL, NULL, SDDS_STRING, mpl_title) < 0 ||
285 SDDS_DefineParameter(&SDDS_table, "mplTopline", NULL, NULL, NULL, NULL, SDDS_STRING, mpl_topline) < 0)) {
286 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
287 return EXIT_FAILURE;
288 }
289
290 if (SDDS_DefineColumn(&SDDS_table, "t", NULL, xUnits, NULL, NULL, SDDS_DOUBLE, 0) < 0 ||
291 SDDS_DefineColumn(&SDDS_table, signal_name, NULL, yUnits, NULL, NULL, SDDS_DOUBLE, 0) < 0 ||
292 !SDDS_WriteLayout(&SDDS_table) ||
293 !SDDS_StartTable(&SDDS_table, points)) {
294 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
295 return EXIT_FAILURE;
296 }
297 fflush(SDDS_table.layout.fp);
298
299 data = tmalloc(sizeof(*data) * points);
300 time = tmalloc(sizeof(*time) * points);
301 for (i = 0; i < points; i++) {
302 if (!fgets(buffer, BUFSIZE, fpi)) {
303 fprintf(stderr, "Error: Insufficient data in input file.\n");
304 return EXIT_FAILURE;
305 }
306 time[i] = xOrigin + (i - xReference) * xIncrement;
307 if (sscanf(buffer, "%lf", &data[i]) != 1) {
308 fprintf(stderr, "Error: Invalid data format in input file at line %ld.\n", i + 1);
309 return EXIT_FAILURE;
310 }
311 }
312
313 if (!SDDS_SetColumn(&SDDS_table, SDDS_SET_BY_NAME, time, points, "t") ||
314 !SDDS_SetColumn(&SDDS_table, SDDS_SET_BY_NAME, data, points, signal_name) ||
315 !SDDS_WriteTable(&SDDS_table) ||
316 !SDDS_Terminate(&SDDS_table)) {
317 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
318 return EXIT_FAILURE;
319 }
320
321 free(data);
322 free(time);
323 fclose(fpi);
324 return EXIT_SUCCESS;
325}
int32_t SDDS_SetColumn(SDDS_DATASET *SDDS_dataset, int32_t mode, void *data, int64_t rows,...)
Sets the values for one data column in the current data table of an SDDS dataset.
int32_t SDDS_Terminate(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_InitializeOutput(SDDS_DATASET *SDDS_dataset, int32_t data_mode, int32_t lines_per_row, const char *description, const char *contents, const char *filename)
Initializes the SDDS output dataset.
int32_t SDDS_DefineColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, int32_t field_length)
Defines a data column within the SDDS dataset.
int32_t SDDS_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
int32_t SDDS_DefineParameter(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, char *fixed_value)
Defines a data parameter with a fixed string value.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
Definition SDDS_utils.c:432
void SDDS_RemovePadding(char *s)
Removes leading and trailing whitespace from a string.
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:59
char * cp_str(char **s, char *t)
Copies a string, allocating memory for storage.
Definition cp_str.c:28
char * delete_chars(char *s, char *t)
Removes all occurrences of characters found in string t from string s.
FILE * fopen_e(char *file, char *open_mode, long mode)
Opens a file with error checking, messages, and aborts.
Definition fopen_e.c:30
long match_string(char *string, char **option, long n_options, long mode)
Matches a given string against an array of option strings based on specified modes.
int scanargs(SCANNED_ARG **scanned, int argc, char **argv)
Definition scanargs.c:36
long scanItemList(unsigned long *flags, char **item, long *items, unsigned long mode,...)
Scans a list of items and assigns values based on provided keywords and types.

◆ process_column_definition()

char * process_column_definition ( char ** argv,
long argc )

Definition at line 327 of file hpwf2sdds.c.

327 {
328 char buffer[SDDS_MAXLINE], *ptr;
329 long i;
330
331 if (argc < 1)
332 return NULL;
333 snprintf(buffer, sizeof(buffer), "&column name=%s, ", argv[0]);
334 for (i = 1; i < argc; i++) {
335 if (!strchr(argv[i], '=')) {
336 return NULL;
337 }
338 strcat(buffer, argv[i]);
339 strcat(buffer, ", ");
340 }
341 if (!strstr(buffer, "type="))
342 strcat(buffer, "type=character ");
343 strcat(buffer, "&end");
344 cp_str(&ptr, buffer);
345 return ptr;
346}

Variable Documentation

◆ HP_DataMarker

char* HP_DataMarker = "Data"

Definition at line 104 of file hpwf2sdds.c.

◆ HP_parameter

HP_PARAMETER HP_parameter[HP_PARAMETERS]
Initial value:
= {
{"Type", "Type", NULL, SDDS_STRING},
{"Points", "Points", NULL, SDDS_LONG},
{"Count", "Count", NULL, SDDS_LONG},
{"XInc", "XInc", NULL, SDDS_DOUBLE},
{"XOrg", "XOrg", NULL, SDDS_DOUBLE},
{"XRef", "XRef", NULL, SDDS_DOUBLE},
{"YData range", "YDataRange", NULL, SDDS_DOUBLE},
{"YData center", "YDataCenter", NULL, SDDS_DOUBLE},
{"Coupling", "Coupling", NULL, SDDS_STRING},
{"XRange", "XRange", NULL, SDDS_DOUBLE},
{"XOffset", "XOffset", NULL, SDDS_DOUBLE},
{"YRange", "YRange", NULL, SDDS_DOUBLE},
{"YOffset", "YOffset", NULL, SDDS_DOUBLE},
{"Date", "Date", NULL, SDDS_STRING},
{"Time", "Time", NULL, SDDS_STRING},
{"Frame", "Frame", NULL, SDDS_STRING},
{"Acq mode", "AcqMode", NULL, SDDS_STRING},
{"Completion", "Completion", NULL, SDDS_STRING},
{"X Units", "XUnits", NULL, SDDS_STRING},
{"Y Units", "YUnits", NULL, SDDS_STRING},
{"Max Bandwidth", "MaxBandwidth", NULL, SDDS_DOUBLE},
{"Min Bandwidth", "MinBandwidth", NULL, SDDS_DOUBLE},
{NULL, NULL, NULL, 0},
}
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
Definition SDDStypes.h:61

Definition at line 78 of file hpwf2sdds.c.

78 {
79 {"Type", "Type", NULL, SDDS_STRING},
80 {"Points", "Points", NULL, SDDS_LONG},
81 {"Count", "Count", NULL, SDDS_LONG},
82 {"XInc", "XInc", NULL, SDDS_DOUBLE},
83 {"XOrg", "XOrg", NULL, SDDS_DOUBLE},
84 {"XRef", "XRef", NULL, SDDS_DOUBLE},
85 {"YData range", "YDataRange", NULL, SDDS_DOUBLE},
86 {"YData center", "YDataCenter", NULL, SDDS_DOUBLE},
87 {"Coupling", "Coupling", NULL, SDDS_STRING},
88 {"XRange", "XRange", NULL, SDDS_DOUBLE},
89 {"XOffset", "XOffset", NULL, SDDS_DOUBLE},
90 {"YRange", "YRange", NULL, SDDS_DOUBLE},
91 {"YOffset", "YOffset", NULL, SDDS_DOUBLE},
92 {"Date", "Date", NULL, SDDS_STRING},
93 {"Time", "Time", NULL, SDDS_STRING},
94 {"Frame", "Frame", NULL, SDDS_STRING},
95 {"Acq mode", "AcqMode", NULL, SDDS_STRING},
96 {"Completion", "Completion", NULL, SDDS_STRING},
97 {"X Units", "XUnits", NULL, SDDS_STRING},
98 {"Y Units", "YUnits", NULL, SDDS_STRING},
99 {"Max Bandwidth", "MaxBandwidth", NULL, SDDS_DOUBLE},
100 {"Min Bandwidth", "MinBandwidth", NULL, SDDS_DOUBLE},
101 {NULL, NULL, NULL, 0},
102};

◆ HP_PointsName

char* HP_PointsName = "Points"

Definition at line 110 of file hpwf2sdds.c.

◆ HP_XIncrementName

char* HP_XIncrementName = "XInc"

Definition at line 105 of file hpwf2sdds.c.

◆ HP_XOriginName

char* HP_XOriginName = "XOrg"

Definition at line 106 of file hpwf2sdds.c.

◆ HP_XReferenceName

char* HP_XReferenceName = "XRef"

Definition at line 107 of file hpwf2sdds.c.

◆ HP_XUnitsName

char* HP_XUnitsName = "X Units"

Definition at line 108 of file hpwf2sdds.c.

◆ HP_YUnitsName

char* HP_YUnitsName = "Y Units"

Definition at line 109 of file hpwf2sdds.c.

◆ option

char* option[N_OPTIONS]
static
Initial value:
= {
"signalname", "description", "mpllabels", "majorOrder"}

Definition at line 51 of file hpwf2sdds.c.

51 {
52 "signalname", "description", "mpllabels", "majorOrder"};

◆ USAGE

char* USAGE
Initial value:
=
"Usage: hpwf2sdds <inputfile> <outputfile> [options]\n"
"\n"
"Options:\n"
" -signalname=<name> Specify the signal name in the SDDS file.\n"
" -description=<text>,<contents> Provide a description for the SDDS data set.\n"
" -mpllabels=<title>,<topline> Set the title and topline labels for MPL plots.\n"
" -majorOrder=row|column Set the major order of data storage.\n"
"\n"
"Example:\n"
" hpwf2sdds waveform.txt waveform.sdds -signalname=Voltage -description=\"Test Signal\",\"Generated by HP oscilloscope\" \\\n"
" -mpllabels=\"Voltage Signal\",\"Time (s)\" -majorOrder=column\n"
"\n"
"This program converts HP verbose format waveforms to SDDS format.\n\n"
"Program by Michael Borland (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ")\n"

Definition at line 54 of file hpwf2sdds.c.