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

Detailed Description

Converts SDDS files to Agilent Arbitrary Waveform files.

This program reads an SDDS file, extracts the "I" and "Q" floating-point columns, scales the data to fit the [-32767, 32767] range, and writes the results to an output file in a binary format compatible with Agilent arbitrary waveform generators. The program supports input and output via pipes, little-endian to big-endian conversion, and error handling for invalid options and inputs.

Usage

sdds2agilentArb [<inputFile>] [<outputFile>] [-pipe[=in][,out]]

Options

Option Description
-pipe Use pipes for input and/or output.

Requirements

  • Input file must contain the "I" and "Q" floating-point columns.
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 sdds2agilentArb.c.

#include "SDDS.h"
#include "mdb.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 61 of file sdds2agilentArb.c.

61 {
62 SCANNED_ARG *scanned;
63 long i_arg;
64 unsigned long pipe_flags = 0;
65 char *input = NULL, *output = NULL;
66 FILE *fd;
67 SDDS_DATASET sdds_dataset;
68
69 long points;
70 double *i_wave;
71 double *q_wave;
72 double max_amp = 0;
73 double min_amp = 0;
74 int i;
75 double scale;
76 short *waveform = NULL;
77 char buf;
78 char *p_char;
79
81 argc = scanargs(&scanned, argc, argv);
82 if (argc < 2) {
83 fprintf(stderr, "%s", usage);
84 return 1;
85 }
86 for (i_arg = 1; i_arg < argc; i_arg++) {
87 if (scanned[i_arg].arg_type == OPTION) {
88 switch (match_string(scanned[i_arg].list[0], option, N_OPTIONS, 0)) {
89 case SET_PIPE:
90 if (!processPipeOption(scanned[i_arg].list + 1,
91 scanned[i_arg].n_items - 1, &pipe_flags)) {
92 fprintf(stderr, "invalid -pipe syntax\n");
93 return 1;
94 }
95 break;
96 default:
97 fprintf(stderr, "invalid option seen\n");
98 fprintf(stderr, "%s", usage);
99 return 1;
100 }
101 } else {
102 if (!input)
103 input = scanned[i_arg].list[0];
104 else if (!output)
105 output = scanned[i_arg].list[0];
106 else {
107 fprintf(stderr, "too many filenames\n");
108 fprintf(stderr, "%s", usage);
109 return 1;
110 }
111 }
112 }
113 processFilenames("sdds2agilentArb", &input, &output, pipe_flags, 0, NULL);
114
115 if (!SDDS_InitializeInput(&sdds_dataset, input)) {
116 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
117 }
118 if ((SDDS_CheckColumn(&sdds_dataset, "I", NULL, SDDS_ANY_FLOATING_TYPE,
119 NULL)) != SDDS_CHECK_OKAY) {
120 fprintf(stderr, "error: Floating type column named I does not exist\n");
121 return 1;
122 }
123 if ((SDDS_CheckColumn(&sdds_dataset, "Q", NULL, SDDS_ANY_FLOATING_TYPE,
124 NULL)) != SDDS_CHECK_OKAY) {
125 fprintf(stderr, "error: Floating type column named Q does not exist\n");
126 return 1;
127 }
128
129 if (SDDS_ReadTable(&sdds_dataset) != 1) {
130 fprintf(stderr, "error: No data found in SDDS file\n");
131 return 1;
132 }
133 points = SDDS_RowCount(&sdds_dataset);
134
135 i_wave = SDDS_GetColumnInDoubles(&sdds_dataset, "I");
136 q_wave = SDDS_GetColumnInDoubles(&sdds_dataset, "Q");
137 if (!SDDS_Terminate(&sdds_dataset)) {
138 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
139 exit(1);
140 }
141
142 max_amp = i_wave[0];
143 min_amp = i_wave[0];
144 for (i = 0; i < points; i++) {
145 if (max_amp < i_wave[i])
146 max_amp = i_wave[i];
147 else if (min_amp > i_wave[i])
148 min_amp = i_wave[i];
149 if (max_amp < q_wave[i])
150 max_amp = q_wave[i];
151 else if (min_amp > q_wave[i])
152 min_amp = q_wave[i];
153 }
154 max_amp = fabs(max_amp);
155 min_amp = fabs(min_amp);
156 if (min_amp > max_amp)
157 max_amp = min_amp;
158
159 scale = 32767 / max_amp;
160 waveform = malloc(sizeof(short) * points * 2);
161 for (i = 0; i < points; i++) {
162 waveform[2 * i] = (short)floor(i_wave[i] * scale + 0.5);
163 waveform[2 * i + 1] = (short)floor(q_wave[i] * scale + 0.5);
164 }
165 free(i_wave);
166 free(q_wave);
167
169 p_char = (char *)&waveform[0];
170 for (i = 0; i < 2 * points; i++) {
171 buf = *p_char;
172 *p_char = *(p_char + 1);
173 *(p_char + 1) = buf;
174 p_char += 2;
175 }
176 }
177
178 if (!output) {
179#if defined(_WIN32)
180 if (_setmode(_fileno(stdout), _O_BINARY) == -1) {
181 fprintf(stderr, "error: unable to set stdout to binary mode\n");
182 exit(1);
183 }
184#endif
185 fd = stdout;
186 } else {
187 fd = fopen(output, "wb");
188 }
189 if (fd == NULL) {
190 fprintf(stderr, "unable to open output file for writing\n");
191 exit(1);
192 }
193 fwrite((void *)waveform, sizeof(short), points * 2, fd);
194 fclose(fd);
195 if (waveform)
196 free(waveform);
197 free_scanargs(&scanned, argc);
198
199 return 0;
200}
double * SDDS_GetColumnInDoubles(SDDS_DATASET *SDDS_dataset, char *column_name)
Retrieves the data of a specified numerical column as an array of doubles, considering only rows mark...
int32_t SDDS_InitializeInput(SDDS_DATASET *SDDS_dataset, char *filename)
Definition SDDS_input.c:49
int32_t SDDS_Terminate(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_CheckColumn(SDDS_DATASET *SDDS_dataset, char *name, char *units, int32_t type, FILE *fp_message)
Checks if a column exists in the SDDS dataset with the specified name, units, and type.
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_ANY_FLOATING_TYPE
Special identifier used by SDDS_Check*() routines to accept any floating-point type.
Definition SDDStypes.h:165
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