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

Detailed Description

Identifies and corrects phase discontinuities in datasets using the SDDS library.

This program processes datasets to identify and correct phase discontinuities. It allows users to specify thresholds for detecting discontinuities and applies modular corrections. The input/output files must follow the SDDS format.

Usage

sddsunwrap [<input>] [<output>]
[-pipe=[input][,output]]
[-column=<list>]
[-threshold=<value>]
[-modulo=<value>]
[-majorOrder=<row|column>]

Options

Optional Description
-pipe Enables piping for input/output.
-column Specifies the columns to be unwrapped. Accepts a comma-separated list and wildcards.
-threshold Sets the discontinuity threshold (default: PI).
-modulo Sets the modulo value for unwrapping (default: 2*PI).
-majorOrder Specifies data order (row-major or column-major).

Specific Requirements

  • If -column is not specified, the program defaults to numeric columns.
License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Authors
H. Shang, R. Soliday

Definition in file sddsunwrap.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 88 of file sddsunwrap.c.

88 {
89 double *x_data, *y_data, threshold, modulo = 0;
90 char *input = NULL, *output = NULL, **column_match = NULL, **column_name = NULL, **column;
91 long i, i_arg;
92 char output_column[256];
93
94 SDDS_DATASET sdds_in, sdds_out;
95 SCANNED_ARG *scanned;
96 unsigned long pipe_flags = 0, major_order_flag = 0;
97 int32_t column_type, columns0 = 0;
98 int64_t j, k, rows;
99 int32_t columns = 0, column_matches = 0;
100 short column_major_order = -1, phase = 1, threshold_provided = 0;
101
103
104 argc = scanargs(&scanned, argc, argv);
105 if (argc == 1)
106 bomb(NULL, USAGE);
107
108 input = output = NULL;
109 x_data = y_data = NULL;
110 column_name = NULL;
111
112 for (i_arg = 1; i_arg < argc; i_arg++) {
113 if (scanned[i_arg].arg_type == OPTION) {
114 /* process options here */
115 OptionType option_type =
116 (OptionType)match_string(scanned[i_arg].list[0], option,
117 N_OPTIONS, 0);
118 switch (option_type) {
119 case OPTION_MAJOR_ORDER:
120 major_order_flag = 0;
121 scanned[i_arg].n_items--;
122 if (scanned[i_arg].n_items > 0 && (!scanItemList(&major_order_flag, scanned[i_arg].list + 1,
123 &scanned[i_arg].n_items, 0, "row", -1,
124 NULL, 0, SDDS_ROW_MAJOR_ORDER, "column", -1,
125 NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
126 SDDS_Bomb("invalid -majorOrder syntax/values");
127 if (major_order_flag & SDDS_COLUMN_MAJOR_ORDER)
128 column_major_order = 1;
129 else if (major_order_flag & SDDS_ROW_MAJOR_ORDER)
130 column_major_order = 0;
131 break;
132 case OPTION_THRESHOLD:
133 if (scanned[i_arg].n_items != 2)
134 SDDS_Bomb("invalid -threshold syntax");
135 if (!get_double(&threshold, scanned[i_arg].list[1]))
136 SDDS_Bomb("invalid -threshold value given");
137 threshold_provided = 1;
138 break;
139 case OPTION_MODULO:
140 if (scanned[i_arg].n_items != 2)
141 SDDS_Bomb("invalid -modulo syntax");
142 if (!get_double(&modulo, scanned[i_arg].list[1]))
143 SDDS_Bomb("invalid -modulo value given");
144 break;
145 case OPTION_COLUMN:
146 if ((scanned[i_arg].n_items < 2))
147 SDDS_Bomb("invalid -column syntax");
148 column_matches = scanned[i_arg].n_items - 1;
149 column_match = tmalloc(sizeof(*column_match) * column_matches);
150 for (i = 0; i < column_matches; i++)
151 column_match[i] = scanned[i_arg].list[i + 1];
152 break;
153 case OPTION_PIPE:
154 if (!processPipeOption(scanned[i_arg].list + 1,
155 scanned[i_arg].n_items - 1,
156 &pipe_flags))
157 SDDS_Bomb("invalid -pipe syntax");
158 break;
159 default:
160 fprintf(stderr, "Unknown option %s provided\n",
161 scanned[i_arg].list[0]);
162 exit(1);
163 break;
164 }
165 } else {
166 if (!input)
167 input = scanned[i_arg].list[0];
168 else if (!output)
169 output = scanned[i_arg].list[0];
170 else
171 SDDS_Bomb("too many filenames");
172 }
173 }
174 processFilenames("sddsunwrap", &input, &output, pipe_flags, 0, NULL);
175 if (phase && !threshold_provided)
176 threshold = PI;
177
178 if (!modulo)
179 modulo = 2 * threshold;
180
181 if (!SDDS_InitializeInput(&sdds_in, input))
182 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
183 if (column_matches) {
184 column = getMatchingSDDSNames(&sdds_in, column_match, column_matches,
185 &columns, SDDS_MATCH_COLUMN);
186 } else {
187 column = tmalloc(sizeof(*column) * 1);
188 if (!(column_name = (char **)SDDS_GetColumnNames(&sdds_in, &columns0)))
189 SDDS_PrintErrors(stderr,
190 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
191 for (i = 0; i < columns0; i++) {
192 if (SDDS_NUMERIC_TYPE(column_type =
193 SDDS_GetColumnType(&sdds_in, i))) {
194 SDDS_CopyString(&column[0], column_name[i]);
195 break;
196 }
197 }
198 SDDS_FreeStringArray(column_name, columns0);
199 columns = 1;
200 }
201
202 if (!SDDS_InitializeCopy(&sdds_out, &sdds_in, output, "w"))
203 SDDS_PrintErrors(stderr,
204 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
205 if (column_major_order != -1)
206 sdds_out.layout.data_mode.column_major = column_major_order;
207 else
208 sdds_out.layout.data_mode.column_major = sdds_in.layout.data_mode.column_major;
209
210 for (i = 0; i < columns; i++) {
211 sprintf(output_column, "Unwrap%s", column[i]);
212 if (!SDDS_TransferColumnDefinition(&sdds_out, &sdds_in, column[i],
213 output_column))
214 SDDS_PrintErrors(stderr,
215 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
216 }
217 if (!SDDS_WriteLayout(&sdds_out))
218 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
219
220 while (SDDS_ReadPage(&sdds_in) > 0) {
221 if ((rows = SDDS_CountRowsOfInterest(&sdds_in)) <= 0)
222 continue;
223 if (!SDDS_StartPage(&sdds_out, rows) || !SDDS_CopyPage(&sdds_out, &sdds_in))
224 SDDS_PrintErrors(stderr,
225 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
226
227 y_data = tmalloc(sizeof(*y_data) * rows);
228 for (i = 0; i < columns; i++) {
229 sprintf(output_column, "Unwrap%s", column[i]);
230 if (!(x_data = SDDS_GetColumnInDoubles(&sdds_in, column[i])))
231 SDDS_PrintErrors(stderr,
232 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
233 k = 0;
234 for (j = 0; j < rows - 1; j++) {
235 y_data[j] = x_data[j] + modulo * k; /*add 2*Pi*k to input */
236 /* check if diff is greater than alpha */
237 if (fabs(x_data[j + 1] - x_data[j]) > fabs(threshold)) {
238 if (x_data[j + 1] < x_data[j])
239 k = k + 1; /* if the pahse jump is negative, increment k */
240 else
241 k = k - 1; /* if the phase jump is positive, decrement k */
242 }
243 }
244 y_data[rows - 1] = x_data[rows - 1] + modulo * k; /* add 2*pi*k to the last element of the input */
245
246 if (x_data)
247 free(x_data);
248 x_data = NULL;
249
250 if (!SDDS_SetColumnFromDoubles(&sdds_out, SDDS_BY_NAME, y_data,
251 rows, output_column))
252 SDDS_PrintErrors(stderr,
253 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
254 }
255 free(y_data);
256 y_data = NULL;
257 if (!SDDS_WritePage(&sdds_out))
258 SDDS_PrintErrors(stderr,
259 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
260 }
261 if (!SDDS_Terminate(&sdds_in) || !SDDS_Terminate(&sdds_out)) {
262 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
263 exit(1);
264 }
265 if (column_name) {
266 SDDS_FreeStringArray(column_name, columns0);
267 free(column_name);
268 }
269 SDDS_FreeStringArray(column, columns);
270 free(column);
271 if (column_match)
272 free(column_match);
273 free_scanargs(&scanned, argc);
274 return 0;
275}
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.
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_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.
int32_t SDDS_TransferColumnDefinition(SDDS_DATASET *target, SDDS_DATASET *source, char *name, char *newName)
Transfers a column definition from a source dataset to a target dataset.
int32_t SDDS_FreeStringArray(char **string, int64_t strings)
Frees an array of strings by deallocating each individual string.
char ** getMatchingSDDSNames(SDDS_DATASET *dataset, char **matchName, int32_t matches, int32_t *names, short type)
Retrieves an array of matching SDDS entity names based on specified criteria.
char ** SDDS_GetColumnNames(SDDS_DATASET *SDDS_dataset, int32_t *number)
Retrieves the names of all columns in the SDDS dataset.
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_GetColumnType(SDDS_DATASET *SDDS_dataset, int32_t index)
Retrieves the data type of a column in the SDDS dataset by its index.
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:342
int32_t SDDS_CopyString(char **target, const char *source)
Copies a source string to a target string with memory allocation.
Definition SDDS_utils.c:856
#define SDDS_NUMERIC_TYPE(type)
Checks if the given type identifier corresponds to any numeric type.
Definition SDDStypes.h:138
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:59
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
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.