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

Detailed Description

Converts Agilent Arbitrary Waveform files to SDDS format.

This program reads Agilent Arbitrary Waveform files and converts them into SDDS (Self Describing Data Set) format. It supports various output options such as ASCII or binary formats, inclusion of an index column, and output precision (float or double).

Usage

agilentArb2sdds [<inputFile>] [<outputFile>]
[-pipe[=in][,out]]
[-ascii | -binary]
[-withIndex]
[-float | -double]
[-dumpHeader]

Options

Optional Description
-pipe Enable pipe mode with optional input and output pipes.
-ascii Request SDDS ASCII output. Default unless -binary is specified.
-binary Request SDDS binary output.
-withIndex Add an Index column to the output.
-float Output data in float format. Default is double precision.
-double Output data in double format.
-dumpHeader Output SDDS header information.

Incompatibilities

  • -ascii is incompatible with -binary.
  • -float is incompatible with -double.
License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
R. Soliday

Definition in file agilentArb2sdds.c.

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

Go to the source code of this file.

Functions

int main (int argc, char *argv[])
 

Function Documentation

◆ main()

int main ( int argc,
char * argv[] )

Definition at line 96 of file agilentArb2sdds.c.

96 {
97 SCANNED_ARG *scanned;
98 long iArg;
99 int ascii = 0, withIndex = 0, floatValues = 0;
100 unsigned long pipeFlags = 0;
101 char *input = NULL, *output = NULL;
102 FILE *fd;
103 SDDS_DATASET SDDSout;
104
105 long points;
106 short waveform[2 * MAX_NUM_POINTS];
107 char *pChar;
108 char buf;
109 int i;
110 double *IwaveIn;
111 double *QwaveIn;
112 int32_t *index = NULL;
113
115 argc = scanargs(&scanned, argc, argv);
116 if (argc < 2) {
117 fprintf(stderr, "%s", USAGE);
118 return EXIT_FAILURE;
119 }
120
121 for (iArg = 1; iArg < argc; iArg++) {
122 if (scanned[iArg].arg_type == OPTION) {
123 switch (match_string(scanned[iArg].list[0], option, N_OPTIONS, 0)) {
124 case SET_ASCII:
125 ascii = 1;
126 break;
127 case SET_BINARY:
128 ascii = 0;
129 break;
130 case SET_WITHINDEX:
131 withIndex = 1;
132 break;
133 case SET_FLOAT:
134 floatValues = 1;
135 break;
136 case SET_DOUBLE:
137 floatValues = 0;
138 break;
139 case SET_PIPE:
140 if (!processPipeOption(scanned[iArg].list + 1, scanned[iArg].n_items - 1, &pipeFlags)) {
141 fprintf(stderr, "Error: Invalid -pipe syntax.\n");
142 fprintf(stderr, "%s", USAGE);
143 return EXIT_FAILURE;
144 }
145 break;
146 default:
147 fprintf(stderr, "Error: Invalid option '%s'.\n", scanned[iArg].list[0]);
148 fprintf(stderr, "%s", USAGE);
149 return EXIT_FAILURE;
150 }
151 } else {
152 if (!input)
153 input = scanned[iArg].list[0];
154 else if (!output)
155 output = scanned[iArg].list[0];
156 else {
157 fprintf(stderr, "Error: Too many filenames provided.\n");
158 fprintf(stderr, "%s", USAGE);
159 return EXIT_FAILURE;
160 }
161 }
162 }
163
164 processFilenames("agilentArb2sdds", &input, &output, pipeFlags, 0, NULL);
165
166 if (input) {
167 if (!fexists(input)) {
168 fprintf(stderr, "Error: Input file '%s' not found.\n", input);
169 return EXIT_FAILURE;
170 }
171 if (!(fd = fopen(input, "rb"))) {
172 fprintf(stderr, "Error: Unable to open input file '%s'.\n", input);
173 return EXIT_FAILURE;
174 }
175 } else {
176#if defined(_WIN32)
177 if (_setmode(_fileno(stdin), _O_BINARY) == -1) {
178 fprintf(stderr, "Error: Unable to set stdin to binary mode.\n");
179 return EXIT_FAILURE;
180 }
181#endif
182 fd = stdin;
183 }
184
185 points = fread((void *)waveform, sizeof(short), MAX_NUM_POINTS * 2, fd);
186 if (points == MAX_NUM_POINTS * 2) {
187 fprintf(stderr, "Error: Number of points in the waveform exceeds the maximum (%d).\n", MAX_NUM_POINTS);
188 return EXIT_FAILURE;
189 }
190 fclose(fd);
191
193 pChar = (char *)&waveform[0];
194 for (i = 0; i < points; i++) {
195 buf = *pChar;
196 *pChar = *(pChar + 1);
197 *(pChar + 1) = buf;
198 pChar += 2;
199 }
200 }
201
202 points = points / 2;
203 IwaveIn = malloc(sizeof(double) * points);
204 QwaveIn = malloc(sizeof(double) * points);
205 if (!IwaveIn || !QwaveIn) {
206 fprintf(stderr, "Error: Memory allocation failed for waveform data.\n");
207 return EXIT_FAILURE;
208 }
209
210 for (i = 0; i < points; i++) {
211 IwaveIn[i] = waveform[2 * i] / 32767.0;
212 QwaveIn[i] = waveform[2 * i + 1] / 32767.0;
213 }
214
215 if (withIndex) {
216 index = malloc(sizeof(int32_t) * points);
217 if (!index) {
218 fprintf(stderr, "Error: Memory allocation failed for index data.\n");
219 return EXIT_FAILURE;
220 }
221 for (i = 0; i < points; i++) {
222 index[i] = i;
223 }
224 }
225
226 if (!SDDS_InitializeOutput(&SDDSout, ascii ? SDDS_ASCII : SDDS_BINARY, 1, NULL, NULL, output)) {
227 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
228 return EXIT_FAILURE;
229 }
230
231 if (withIndex) {
232 if (!SDDS_DefineSimpleColumn(&SDDSout, "Index", NULL, SDDS_LONG)) {
233 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
234 return EXIT_FAILURE;
235 }
236 }
237
238 if (!SDDS_DefineSimpleColumn(&SDDSout, "I", NULL, floatValues ? SDDS_FLOAT : SDDS_DOUBLE)) {
239 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
240 return EXIT_FAILURE;
241 }
242
243 if (!SDDS_DefineSimpleColumn(&SDDSout, "Q", NULL, floatValues ? SDDS_FLOAT : SDDS_DOUBLE)) {
244 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
245 return EXIT_FAILURE;
246 }
247
248 if (!SDDS_WriteLayout(&SDDSout)) {
249 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
250 return EXIT_FAILURE;
251 }
252
253 if (!SDDS_StartTable(&SDDSout, points)) {
254 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
255 return EXIT_FAILURE;
256 }
257
258 if (withIndex) {
259 if (!SDDS_SetColumnFromLongs(&SDDSout, SDDS_SET_BY_NAME, index, points, "Index")) {
260 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
261 return EXIT_FAILURE;
262 }
263 }
264
265 if (!SDDS_SetColumnFromDoubles(&SDDSout, SDDS_SET_BY_NAME, IwaveIn, points, "I")) {
266 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
267 return EXIT_FAILURE;
268 }
269
270 if (!SDDS_SetColumnFromDoubles(&SDDSout, SDDS_SET_BY_NAME, QwaveIn, points, "Q")) {
271 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
272 return EXIT_FAILURE;
273 }
274
275 if (!SDDS_WriteTable(&SDDSout)) {
276 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
277 return EXIT_FAILURE;
278 }
279
280 if (!SDDS_Terminate(&SDDSout)) {
281 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
282 return EXIT_FAILURE;
283 }
284
285 if (withIndex)
286 free(index);
287 free_scanargs(&scanned, argc);
288 free(IwaveIn);
289 free(QwaveIn);
290
291 return EXIT_SUCCESS;
292}
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.
int32_t SDDS_SetColumnFromLongs(SDDS_DATASET *SDDS_dataset, int32_t mode, int32_t *data, int64_t rows,...)
Sets the values for a single data column using long integer numbers.
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_DefineSimpleColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *unit, int32_t type)
Defines a simple data column within the SDDS dataset.
int32_t SDDS_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
Definition SDDS_utils.c:432
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:288
int32_t SDDS_IsBigEndianMachine()
Determines whether the current machine uses big-endian byte ordering.
#define SDDS_FLOAT
Identifier for the float data type.
Definition SDDStypes.h:43
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
Definition SDDStypes.h:61
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37
long fexists(const char *filename)
Checks if a file exists.
Definition fexists.c:27
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
void free_scanargs(SCANNED_ARG **scanned, int argc)
Definition scanargs.c:584