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

Detailed Description

Converts waveforms from Tektronix ASCII format to SDDS format.

This program processes Tektronix ASCII files containing waveform data and converts them into SDDS format for improved interoperability and analysis. It supports defining signal names, setting descriptions, and specifying data layouts using various options.

Usage

tek2sdds <inputfile> <outputfile>
-signalname=<name>
[-description=<text>,<contents>]
[-mpllabels=<title>,<topline>]
[-majorOrder=row|column]

Options

Required Description
-signalname Specifies the name of the signal to use in the SDDS file.
Optional Description
-description Adds a description with specified text and contents to the SDDS output.
-mpllabels Sets MPL labels such as the title and topline for graphing purposes.
-majorOrder Defines the major order for data layout in the SDDS file (row or column).
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 tek2sdds.c.

#include "mdb.h"
#include "SDDS.h"
#include "scan.h"
#include "match_string.h"
#include <stdlib.h>

Go to the source code of this file.

Functions

long GetNextItem (char *buffer, long bufsize, FILE *fpi)
 
int main (int argc, char **argv)
 

Function Documentation

◆ GetNextItem()

long GetNextItem ( char * buffer,
long bufsize,
FILE * fpi )

Definition at line 351 of file tek2sdds.c.

351 {
352 long i;
353 char c;
354
355 i = c = 0;
356 while (i < bufsize && (c = getc(fpi)) != EOF) {
357 if (c == ',' || c == ';' || c == '%')
358 break;
359 buffer[i++] = c;
360 }
361 if (c == EOF && i == 0)
362 return 0;
363 buffer[i] = '\0';
364 if (c == ',')
365 return 1;
366 if (c == ';')
367 return 2;
368 if (c == EOF)
369 return 3;
370 fprintf(stderr, "warning: invalid data seen--ignoring\n");
371 return 4;
372}

◆ main()

int main ( int argc,
char ** argv )

Definition at line 126 of file tek2sdds.c.

126 {
127 SDDS_TABLE SDDS_table;
128 SCANNED_ARG *scanned;
129 long i, i_arg, index, points, bytes_per_number;
130 // long lsb_first;
131 char *input, *output, buffer[BUFSIZE];
132 char *signal_name, *ptr, *parameter_name;
133 char *mpl_title, *mpl_topline, *descrip_text, *descrip_contents;
134 FILE *fpi;
135 long code, binary;
136 double xIncrement, xZero, yMultiplier, yZero;
137 char *xUnits, *yUnits;
138 double *time, *data;
139 short columnMajorOrder = 0;
140 unsigned long majorOrderFlag;
141
142 xUnits = yUnits = NULL;
143
144 argc = scanargs(&scanned, argc, argv);
145 if (argc < 3) {
146 bomb(NULL, USAGE);
147 }
148
149 input = output = signal_name = NULL;
150 mpl_title = mpl_topline = descrip_text = descrip_contents = NULL;
151 binary = 0;
152
153 for (i_arg = 1; i_arg < argc; i_arg++) {
154 if (scanned[i_arg].arg_type == OPTION) {
155 delete_chars(scanned[i_arg].list[0], "_");
156 /* process options here */
157 switch (match_string(scanned[i_arg].list[0], option, N_OPTIONS, 0)) {
158 case SET_MAJOR_ORDER:
159 majorOrderFlag = 0;
160 scanned[i_arg].n_items--;
161 if (scanned[i_arg].n_items > 0 &&
162 (!scanItemList(&majorOrderFlag, scanned[i_arg].list + 1, &scanned[i_arg].n_items, 0,
163 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
164 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
165 SDDS_Bomb("invalid -majorOrder syntax/values");
166 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
167 columnMajorOrder = 1;
168 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
169 columnMajorOrder = 0;
170 break;
171 case SET_SIGNAL_NAME:
172 if (scanned[i_arg].n_items != 2) {
173 bomb("invalid -signalname syntax", USAGE);
174 }
175 signal_name = scanned[i_arg].list[1];
176 break;
177 case SET_DESCRIPTION:
178 if (scanned[i_arg].n_items != 3) {
179 bomb("invalid -description syntax", USAGE);
180 }
181 descrip_text = scanned[i_arg].list[1];
182 descrip_contents = scanned[i_arg].list[2];
183 break;
184 case SET_MPL_LABELS:
185 if (scanned[i_arg].n_items != 3) {
186 bomb("invalid -mpllabels syntax", USAGE);
187 }
188 mpl_title = scanned[i_arg].list[1];
189 mpl_topline = scanned[i_arg].list[2];
190 break;
191 default:
192 bomb("invalid option seen", USAGE);
193 break;
194 }
195 } else {
196 if (!input)
197 input = scanned[i_arg].list[0];
198 else if (!output)
199 output = scanned[i_arg].list[0];
200 else
201 bomb("too many filenames", USAGE);
202 }
203 }
204 if (!input)
205 SDDS_Bomb("input file not seen");
206 if (!output)
207 SDDS_Bomb("output file not seen");
208 if (!signal_name)
209 signal_name = "V";
210
211 fpi = fopen_e(input, "r", 0);
212 if (fread(buffer, 1, strlen(TEK_PreambleString), fpi) != strlen(TEK_PreambleString) ||
213 strncmp(TEK_PreambleString, buffer, strlen(TEK_PreambleString)) != 0)
214 SDDS_Bomb("file does not appear to be in Tektronix format");
215
216 parameter_name = buffer;
217 while ((code = GetNextItem(buffer, BUFSIZE, fpi)) < 3) {
218 if (!(ptr = strchr(buffer, ':')))
219 SDDS_Bomb("error parsing input file--missing colon on parameter tag");
220 *ptr++ = 0;
221 if (strcmp(TEK_DataMarker, parameter_name) == 0)
222 break;
223 index = 0;
224 while (TEK_parameter[index].TEK_name) {
225 if (strcmp(TEK_parameter[index].TEK_name, parameter_name) == 0)
226 break;
227 index++;
228 }
229 if (!TEK_parameter[index].TEK_name) {
230 fprintf(stderr, "warning: parameter %s is not recognized\n", parameter_name);
231 continue;
232 }
233 if (TEK_parameter[index].value_string) {
234 fprintf(stderr, "error: duplicate entries for parameter %s\n", parameter_name);
235 exit(EXIT_FAILURE);
236 }
238 SDDS_CopyString(&TEK_parameter[index].value_string, ptr);
239 if (code == 2 || code == 3)
240 break;
241 }
242 if (code != 2)
243 SDDS_Bomb("unexpected end of file");
244
245 if (fread(buffer, 1, strlen(TEK_DataMarker), fpi) != strlen(TEK_DataMarker) ||
246 strncmp(TEK_DataMarker, buffer, strlen(TEK_DataMarker)) != 0)
247 SDDS_Bomb("CURVE item missing or not in right place");
248
249 if (!SDDS_InitializeOutput(&SDDS_table, SDDS_BINARY, 0, descrip_text, descrip_contents, output))
250 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
251 SDDS_table.layout.data_mode.column_major = columnMajorOrder;
252
253 index = 0;
254 while (TEK_parameter[index].TEK_name) {
255 if (!TEK_parameter[index].value_string) {
256 index++;
257 continue;
258 }
259 if (strcmp(TEK_parameter[index].TEK_name, TEK_XIncrementName) == 0) {
260 if (sscanf(TEK_parameter[index].value_string, "%lf", &xIncrement) != 1)
261 SDDS_Bomb("unable to scan value for x increment");
262 } else if (strcmp(TEK_parameter[index].TEK_name, TEK_XZeroName) == 0) {
263 if (sscanf(TEK_parameter[index].value_string, "%lf", &xZero) != 1)
264 SDDS_Bomb("unable to scan value for x zero");
265 } else if (strcmp(TEK_parameter[index].TEK_name, TEK_YZeroName) == 0) {
266 if (sscanf(TEK_parameter[index].value_string, "%lf", &yZero) != 1)
267 SDDS_Bomb("unable to scan value for y zero");
268 } else if (strcmp(TEK_parameter[index].TEK_name, TEK_YMultiplierName) == 0) {
269 if (sscanf(TEK_parameter[index].value_string, "%lf", &yMultiplier) != 1)
270 SDDS_Bomb("unable to scan value for y multiplier");
271 } else if (strcmp(TEK_parameter[index].TEK_name, TEK_XUnitsName) == 0) {
272 xUnits = TEK_parameter[index].value_string;
273 str_tolower(xUnits);
274 } else if (strcmp(TEK_parameter[index].TEK_name, TEK_YUnitsName) == 0) {
275 yUnits = TEK_parameter[index].value_string;
276 str_tolower(yUnits);
277 } else if (strcmp(TEK_parameter[index].TEK_name, TEK_PointsName) == 0) {
278 if (sscanf(TEK_parameter[index].value_string, "%ld", &points) != 1)
279 SDDS_Bomb("unable to scan value for number of points");
280 } else if (strcmp(TEK_parameter[index].TEK_name, TEK_EncodingName) == 0) {
281 if (strcmp(TEK_parameter[index].value_string, "ASCII") == 0)
282 binary = 0;
283 else if (strcmp(TEK_parameter[index].value_string, "BINARY") == 0)
284 binary = 1;
285 else
286 SDDS_Bomb("data encoding is neither ASCII nor BINARY");
287 } else if (strcmp(TEK_parameter[index].TEK_name, TEK_BytesPerNumberName) == 0) {
288 if (sscanf(TEK_parameter[index].value_string, "%ld", &bytes_per_number) != 1)
289 SDDS_Bomb("unable to scan value bytes per number");
290 } else if (strcmp(TEK_parameter[index].value_string, TEK_ByteOrderName) == 0) {
291 // lsb_first = 1;
292 if (strcmp(TEK_parameter[index].value_string, "LSB") != 0) {
293 // lsb_first = 0;
294 }
295 }
296 if (SDDS_DefineParameter(&SDDS_table, TEK_parameter[index].SDDS_name, NULL, NULL, TEK_parameter[index].TEK_name,
297 NULL, TEK_parameter[index].type, TEK_parameter[index].value_string) < 0)
298 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
299 index++;
300 }
301
302 if (mpl_title &&
303 (SDDS_DefineParameter(&SDDS_table, "mplTitle", NULL, NULL, NULL, NULL, SDDS_STRING, mpl_title) < 0 ||
304 SDDS_DefineParameter(&SDDS_table, "mplTopline", NULL, NULL, NULL, NULL, SDDS_STRING, mpl_topline) < 0))
305 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
306
307 if (SDDS_DefineColumn(&SDDS_table, "t", NULL, xUnits, NULL, NULL, SDDS_DOUBLE, 0) < 0 ||
308 SDDS_DefineColumn(&SDDS_table, signal_name, NULL, yUnits, NULL, NULL, SDDS_DOUBLE, 0) < 0 ||
309 !SDDS_WriteLayout(&SDDS_table) || !SDDS_StartTable(&SDDS_table, points))
310 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
311
312 data = tmalloc(sizeof(*data) * points);
313 time = tmalloc(sizeof(*time) * points);
314 if (!binary) {
315 for (i = 0; i < points; i++) {
316
317 if (!(code = GetNextItem(buffer, BUFSIZE, fpi)))
318 SDDS_Bomb("insufficient data in input file");
319 if (code == 4) {
320 points = i;
321 break;
322 }
323 time[i] = xZero + i * xIncrement;
324 if (sscanf(buffer, "%lf", data + i) != 1)
325 SDDS_Bomb("invalid data in input file");
326 data[i] = yZero + data[i] * yMultiplier;
327 }
328 } else {
329 short sdata;
330 fread(buffer, sizeof(char), 4, fpi);
331 for (i = 0; i < points; i++) {
332 if (fread(&sdata, sizeof(sdata), 1, fpi) != 1) {
333 fprintf(stderr, "file ends unexpectedly\n");
334 points = i;
335 break;
336 }
337 time[i] = xZero + i * xIncrement;
338 data[i] = sdata;
339 data[i] = yZero + data[i] * yMultiplier;
340 }
341 }
342
343 if (!SDDS_SetColumn(&SDDS_table, SDDS_SET_BY_NAME, time, points, "t") ||
344 !SDDS_SetColumn(&SDDS_table, SDDS_SET_BY_NAME, data, points, signal_name) ||
345 !SDDS_WriteTable(&SDDS_table) ||
346 !SDDS_Terminate(&SDDS_table))
347 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
348 return EXIT_SUCCESS;
349}
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_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:342
int32_t SDDS_CopyString(char **target, const char *source)
Copies a source string to a target string with memory allocation.
Definition SDDS_utils.c:856
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
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
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.
char * str_tolower(char *s)
Convert a string to lower case.
Definition str_tolower.c:27