SDDS ToolKit Programs and Libraries for C and Python
Loading...
Searching...
No Matches
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 353 of file tek2sdds.c.

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

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