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

Detailed Description

Recursive TDR Impedance Peeling Algorithm Implementation.

This file implements a program to process Time Domain Reflectometry (TDR) data using a recursive peeling algorithm. The algorithm calculates the impedance profile of a non-uniform transmission line based on input voltage and the characteristic line impedance. The program leverages the SDDS (Self Describing Data Sets) library for input and output data handling, supporting flexible data processing options.

Usage

sddstdrpeeling [<input>] [<output>]
[-pipe=[input][,output]]
-col=<data-column>
[-inputVoltage=<value|@<parameter>]]
[-z0=<value>]
[-majorOrder=row|column]

Options

Required Description
-col Specifies the data column name in the SDDS file.
Optional Description
-pipe Enables piping for input and/or output streams.
-inputVoltage Sets the input voltage directly or references a parameter for its value.
-z0 Defines the characteristic line impedance (default is 50 ohms).
-majorOrder Specifies the major order of data processing (default is based on input file).
License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
H. Shang, R. Soliday

Definition in file sddstdrpeeling.c.

#include "mdb.h"
#include "SDDS.h"
#include "SDDSutils.h"
#include "scan.h"
#include <ctype.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 84 of file sddstdrpeeling.c.

84 {
85 double *meas_data = NULL, input_voltage = 0.2, z0 = 50;
86 char *input = NULL, *output = NULL, *data_column = NULL, *input_vol_param = NULL;
87 long i_arg, k;
88 double *left = NULL, *right = NULL, *gamma = NULL, *zline = NULL;
89 double g_product, vr_temp, d_increase;
90
91 SDDS_DATASET sdds_in, sdds_out;
92 SCANNED_ARG *scanned = NULL;
93 unsigned long pipe_flags = 0, major_order_flag = 0;
94 int64_t i, rows;
95 short column_major_order = -1;
96
98
99 argc = scanargs(&scanned, argc, argv);
100 if (argc == 1)
101 bomb(NULL, USAGE);
102
103 for (i_arg = 1; i_arg < argc; i_arg++) {
104 if (scanned[i_arg].arg_type == OPTION) {
105 switch (match_string(scanned[i_arg].list[0], option, N_OPTIONS, 0)) {
106 case CLO_PIPE:
107 if (!processPipeOption(scanned[i_arg].list + 1, scanned[i_arg].n_items - 1, &pipe_flags)) {
108 SDDS_Bomb("Invalid -pipe syntax");
109 }
110 break;
111 case CLO_MAJOR_ORDER:
112 major_order_flag = 0;
113 scanned[i_arg].n_items--;
114 if (scanned[i_arg].n_items > 0 &&
115 (!scanItemList(&major_order_flag, scanned[i_arg].list + 1, &scanned[i_arg].n_items, 0,
116 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
117 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL))) {
118 SDDS_Bomb("invalid -majorOrder syntax/values");
119 }
120 if (major_order_flag & SDDS_COLUMN_MAJOR_ORDER)
121 column_major_order = 1;
122 else if (major_order_flag & SDDS_ROW_MAJOR_ORDER)
123 column_major_order = 0;
124 break;
125 case CLO_INPUT_VOLTAGE:
126 if (scanned[i_arg].n_items != 2)
127 SDDS_Bomb("invalid -inputVoltage syntax");
128 if (scanned[i_arg].list[1][0] == '@') {
129 cp_str(&input_vol_param, scanned[i_arg].list[1] + 1);
130 } else {
131 if (!get_double(&input_voltage, scanned[i_arg].list[1]))
132 SDDS_Bomb("invalid -threshold value given");
133 }
134 break;
135 case CLO_COLUMN:
136 if (scanned[i_arg].n_items != 2)
137 SDDS_Bomb("invalid -column syntax");
138 data_column = scanned[i_arg].list[1];
139 break;
140 case CLO_Z0:
141 if (scanned[i_arg].n_items != 2)
142 SDDS_Bomb("invalid -z0 syntax");
143 if (!get_double(&z0, scanned[i_arg].list[1]))
144 SDDS_Bomb("invalid -z0 value given");
145 break;
146 default:
147 fprintf(stderr, "Unknown option %s provided\n", scanned[i_arg].list[0]);
148 exit(1);
149 break;
150 }
151 } else {
152 if (!input)
153 input = scanned[i_arg].list[0];
154 else if (!output)
155 output = scanned[i_arg].list[0];
156 else
157 SDDS_Bomb("too many filenames");
158 }
159 }
160
161 processFilenames("sddstdrpeeling", &input, &output, pipe_flags, 0, NULL);
162
163 if (!SDDS_InitializeInput(&sdds_in, input))
164 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
165
166 if (!SDDS_InitializeCopy(&sdds_out, &sdds_in, output, "w"))
167 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
168
169 if (column_major_order != -1)
170 sdds_out.layout.data_mode.column_major = column_major_order;
171 else
172 sdds_out.layout.data_mode.column_major = sdds_in.layout.data_mode.column_major;
173
174 if (!SDDS_DefineSimpleColumn(&sdds_out, "PeeledImpedance", "oms", SDDS_DOUBLE))
175 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
176
177 if (!SDDS_WriteLayout(&sdds_out))
178 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
179
180 while (SDDS_ReadPage(&sdds_in) > 0) {
181 if ((rows = SDDS_CountRowsOfInterest(&sdds_in)) <= 0)
182 continue;
183 if (!SDDS_StartPage(&sdds_out, rows) || !SDDS_CopyPage(&sdds_out, &sdds_in))
184 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
185 if (input_vol_param) {
186 if (!SDDS_GetParameterAsDouble(&sdds_in, input_vol_param, &input_voltage))
187 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
188 }
189 if (!(meas_data = SDDS_GetColumnInDoubles(&sdds_in, data_column)))
190 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
191
192 for (i = 0; i < rows; i++)
193 meas_data[i] /= input_voltage;
194
195 left = calloc(sizeof(*left), rows + 1);
196 right = calloc(sizeof(*right), rows + 1);
197 gamma = calloc(sizeof(*gamma), rows + 1);
198 zline = calloc(sizeof(*zline), rows + 1);
199 g_product = 1;
200
201 if (rows >= 1) {
202 gamma[1] = meas_data[0];
203 left[1] = 1;
204 g_product *= (1 - gamma[1] * gamma[1]);
205 }
206 if (rows >= 2) {
207 vr_temp = (1 - gamma[1]) * right[1] + gamma[1] * left[1];
208 gamma[2] = (meas_data[1] - vr_temp) / g_product;
209 left[2] = left[1] * (1 + gamma[1]);
210 right[1] = left[2] * gamma[2];
211 g_product *= (1 - gamma[2] * gamma[2]);
212 }
213 for (i = 3; i <= rows; i++) {
214 left[i] = left[i - 1] * (1 + gamma[i - 1]);
215 left[i - 1] = left[i - 2] * (1 + gamma[i - 2]) - right[i - 2] * gamma[i - 2];
216 for (k = i - 2; k > 2; k--) {
217 right[k] = gamma[k + 1] * left[k + 1] + (1 - gamma[k + 1] * right[k + 1]);
218 left[k] = (1 + gamma[k - 1]) * left[k - 1] - gamma[k - 1] * right[k - 1];
219 }
220 right[1] = left[2] * gamma[2] + right[2] * (1 - gamma[2]);
221 vr_temp = (1 - gamma[1]) * right[1] + gamma[1] * left[1];
222 gamma[i] = (meas_data[i - 1] - vr_temp) / g_product;
223 g_product *= (1 - gamma[i] * gamma[i]);
224 d_increase = left[i] * gamma[i];
225 right[i - 1] += d_increase;
226 for (k = i - 2; k > 1; k--) {
227 d_increase *= (1 - gamma[k + 1]);
228 right[k] += d_increase;
229 }
230 }
231 zline[0] = z0;
232 for (i = 1; i <= rows; i++) {
233 zline[i] = (1 + gamma[i]) / (1 - gamma[i]) * zline[i - 1];
234 }
235 if (!SDDS_SetColumnFromDoubles(&sdds_out, SDDS_BY_NAME, zline + 1, rows, "PeeledImpedance") ||
236 !SDDS_WritePage(&sdds_out)) {
237 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
238 }
239
240 free(left);
241 free(right);
242 free(gamma);
243 free(zline);
244 free(meas_data);
245 meas_data = NULL;
246 }
247
248 if (!SDDS_Terminate(&sdds_in) || !SDDS_Terminate(&sdds_out)) {
249 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
250 exit(1);
251 }
252
253 free_scanargs(&scanned, argc);
254 return 0;
255}
int32_t SDDS_InitializeCopy(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, char *filename, char *filemode)
Definition SDDS_copy.c:40
int32_t SDDS_CopyPage(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:578
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
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.
double * SDDS_GetParameterAsDouble(SDDS_DATASET *SDDS_dataset, char *parameter_name, double *memory)
Retrieves the value of a specified parameter as a double from the current data table of an SDDS datas...
int64_t SDDS_CountRowsOfInterest(SDDS_DATASET *SDDS_dataset)
Counts the number of rows marked as "of interest" in the current data table.
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_ReadPage(SDDS_DATASET *SDDS_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_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
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
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:342
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
char * cp_str(char **s, char *t)
Copies a string, allocating memory for storage.
Definition cp_str.c:28
int get_double(double *dptr, char *s)
Parses a double value from the given string.
Definition data_scan.c:40
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
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.