56 "sddstdrpeeling [<input>] [<output>]\n"
57 " [-pipe=[input][,output]]\n"
58 " -col=<data-column>\n"
59 " [-inputVoltage=<value|@<parameter>]]\n"
62 " -column Provide the data column name.\n"
63 " -inputVoltage Specify the input voltage in volts for TDR (Time Domain Reflectometry).\n"
64 " -z0 Set the line impedance (default is 50 ohms).\n\n"
66 " sddstdrpeeling processes TDR data using a recursive algorithm to determine the impedance of a nonuniform transmission line.\n\n"
67 "Program Information:\n"
68 " Program by Hairong Shang. (" __DATE__
" " __TIME__
", SVN revision: " SVN_VERSION
")";
80static char *option[N_OPTIONS] = {
87int main(
int argc,
char **argv) {
88 double *meas_data = NULL, input_voltage = 0.2, z0 = 50;
89 char *input = NULL, *output = NULL, *data_column = NULL, *input_vol_param = NULL;
91 double *left = NULL, *right = NULL, *gamma = NULL, *zline = NULL;
92 double g_product, vr_temp, d_increase;
95 SCANNED_ARG *scanned = NULL;
96 unsigned long pipe_flags = 0, major_order_flag = 0;
98 short column_major_order = -1;
102 argc =
scanargs(&scanned, argc, argv);
106 for (i_arg = 1; i_arg < argc; i_arg++) {
107 if (scanned[i_arg].arg_type == OPTION) {
108 switch (
match_string(scanned[i_arg].list[0], option, N_OPTIONS, 0)) {
110 if (!
processPipeOption(scanned[i_arg].list + 1, scanned[i_arg].n_items - 1, &pipe_flags)) {
114 case CLO_MAJOR_ORDER:
115 major_order_flag = 0;
116 scanned[i_arg].n_items--;
117 if (scanned[i_arg].n_items > 0 &&
118 (!
scanItemList(&major_order_flag, scanned[i_arg].list + 1, &scanned[i_arg].n_items, 0,
119 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
120 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL))) {
121 SDDS_Bomb(
"invalid -majorOrder syntax/values");
123 if (major_order_flag & SDDS_COLUMN_MAJOR_ORDER)
124 column_major_order = 1;
125 else if (major_order_flag & SDDS_ROW_MAJOR_ORDER)
126 column_major_order = 0;
128 case CLO_INPUT_VOLTAGE:
129 if (scanned[i_arg].n_items != 2)
130 SDDS_Bomb(
"invalid -inputVoltage syntax");
131 if (scanned[i_arg].list[1][0] ==
'@') {
132 cp_str(&input_vol_param, scanned[i_arg].list[1] + 1);
134 if (!
get_double(&input_voltage, scanned[i_arg].list[1]))
135 SDDS_Bomb(
"invalid -threshold value given");
139 if (scanned[i_arg].n_items != 2)
141 data_column = scanned[i_arg].list[1];
144 if (scanned[i_arg].n_items != 2)
150 fprintf(stderr,
"Unknown option %s provided\n", scanned[i_arg].list[0]);
156 input = scanned[i_arg].list[0];
158 output = scanned[i_arg].list[0];
172 if (column_major_order != -1)
173 sdds_out.layout.data_mode.column_major = column_major_order;
175 sdds_out.layout.data_mode.column_major = sdds_in.layout.data_mode.column_major;
188 if (input_vol_param) {
195 for (i = 0; i < rows; i++)
196 meas_data[i] /= input_voltage;
198 left = calloc(
sizeof(*left), rows + 1);
199 right = calloc(
sizeof(*right), rows + 1);
200 gamma = calloc(
sizeof(*gamma), rows + 1);
201 zline = calloc(
sizeof(*zline), rows + 1);
205 gamma[1] = meas_data[0];
207 g_product *= (1 - gamma[1] * gamma[1]);
210 vr_temp = (1 - gamma[1]) * right[1] + gamma[1] * left[1];
211 gamma[2] = (meas_data[1] - vr_temp) / g_product;
212 left[2] = left[1] * (1 + gamma[1]);
213 right[1] = left[2] * gamma[2];
214 g_product *= (1 - gamma[2] * gamma[2]);
216 for (i = 3; i <= rows; i++) {
217 left[i] = left[i - 1] * (1 + gamma[i - 1]);
218 left[i - 1] = left[i - 2] * (1 + gamma[i - 2]) - right[i - 2] * gamma[i - 2];
219 for (k = i - 2; k > 2; k--) {
220 right[k] = gamma[k + 1] * left[k + 1] + (1 - gamma[k + 1] * right[k + 1]);
221 left[k] = (1 + gamma[k - 1]) * left[k - 1] - gamma[k - 1] * right[k - 1];
223 right[1] = left[2] * gamma[2] + right[2] * (1 - gamma[2]);
224 vr_temp = (1 - gamma[1]) * right[1] + gamma[1] * left[1];
225 gamma[i] = (meas_data[i - 1] - vr_temp) / g_product;
226 g_product *= (1 - gamma[i] * gamma[i]);
227 d_increase = left[i] * gamma[i];
228 right[i - 1] += d_increase;
229 for (k = i - 2; k > 1; k--) {
230 d_increase *= (1 - gamma[k + 1]);
231 right[k] += d_increase;
235 for (i = 1; i <= rows; i++) {
236 zline[i] = (1 + gamma[i]) / (1 - gamma[i]) * zline[i - 1];
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_InitializeCopy(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, char *filename, char *filemode)
int32_t SDDS_CopyPage(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
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.
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.
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
#define SDDS_DOUBLE
Identifier for the double data type.
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
char * cp_str(char **s, char *t)
Copies a string, allocating memory for storage.
int get_double(double *dptr, char *s)
Parses a double value from the given string.
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)
long processPipeOption(char **item, long items, unsigned long *flags)
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
void free_scanargs(SCANNED_ARG **scanned, int argc)
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.