SDDSlib
Loading...
Searching...
No Matches
sddsunwrap.c File Reference

Program to unwrap data by identifying and correcting phase discontinuities. More...

#include "mdb.h"
#include "SDDS.h"
#include "SDDSutils.h"
#include "scan.h"
#include <ctype.h>

Go to the source code of this file.

Enumerations

enum  OptionType {
  OPTION_PIPE , OPTION_COLUMN , OPTION_THRESHOLD , OPTION_MAJOR_ORDER ,
  OPTION_MODULO , N_OPTIONS
}
 

Functions

int main (int argc, char **argv)
 

Variables

static char * USAGE
 
static char * option [N_OPTIONS]
 

Detailed Description

Program to unwrap data by identifying and correcting phase discontinuities.

This program processes a dataset to identify discontinuities larger than a specified threshold and applies the appropriate multiple of a modulo value to remove these discontinuities. It is designed to handle Self Describing Data Set (SDDS) files, providing options for input/output redirection, column selection, and order specification.

The program supports the following options:

  • -pipe=[input][,output]: Use pipes for input/output.
  • -column=list: Specify columns to unwrap, separated by commas (supports wildcards).
  • -threshold=<value>: Set the discontinuity threshold (default: PI).
  • -modulo=<value>: Set the modulo value for unwrapping (default: 2*PI).
  • -majorOrder=<row|column>: Specify the data order (row-major or column-major).

Example usage:

sddsunwrap input.sdds output.sdds -column=Phase -threshold=3.14 -modulo=6.28
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 sddsunwrap.c.

Enumeration Type Documentation

◆ OptionType

enum OptionType

Definition at line 40 of file sddsunwrap.c.

40 {
41 OPTION_PIPE,
42 OPTION_COLUMN,
43 OPTION_THRESHOLD,
44 OPTION_MAJOR_ORDER,
45 OPTION_MODULO,
46 N_OPTIONS
OptionType
Enumeration for command-line options.

Function Documentation

◆ main()

int main ( int argc,
char ** argv )

Definition at line 72 of file sddsunwrap.c.

72 {
73 double *x_data, *y_data, threshold, modulo = 0;
74 char *input = NULL, *output = NULL, **column_match = NULL, **column_name = NULL, **column;
75 long i, i_arg;
76 char output_column[256];
77
78 SDDS_DATASET sdds_in, sdds_out;
79 SCANNED_ARG *scanned;
80 unsigned long pipe_flags = 0, major_order_flag = 0;
81 int32_t column_type, columns0 = 0;
82 int64_t j, k, rows;
83 int32_t columns = 0, column_matches = 0;
84 short column_major_order = -1, phase = 1, threshold_provided = 0;
85
87
88 argc = scanargs(&scanned, argc, argv);
89 if (argc == 1)
90 bomb(NULL, USAGE);
91
92 input = output = NULL;
93 x_data = y_data = NULL;
94 column_name = NULL;
95
96 for (i_arg = 1; i_arg < argc; i_arg++) {
97 if (scanned[i_arg].arg_type == OPTION) {
98 /* process options here */
99 OptionType option_type =
100 (OptionType)match_string(scanned[i_arg].list[0], option,
101 N_OPTIONS, 0);
102 switch (option_type) {
103 case OPTION_MAJOR_ORDER:
104 major_order_flag = 0;
105 scanned[i_arg].n_items--;
106 if (scanned[i_arg].n_items > 0 && (!scanItemList(&major_order_flag, scanned[i_arg].list + 1,
107 &scanned[i_arg].n_items, 0, "row", -1,
108 NULL, 0, SDDS_ROW_MAJOR_ORDER, "column", -1,
109 NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
110 SDDS_Bomb("invalid -majorOrder syntax/values");
111 if (major_order_flag & SDDS_COLUMN_MAJOR_ORDER)
112 column_major_order = 1;
113 else if (major_order_flag & SDDS_ROW_MAJOR_ORDER)
114 column_major_order = 0;
115 break;
116 case OPTION_THRESHOLD:
117 if (scanned[i_arg].n_items != 2)
118 SDDS_Bomb("invalid -threshold syntax");
119 if (!get_double(&threshold, scanned[i_arg].list[1]))
120 SDDS_Bomb("invalid -threshold value given");
121 threshold_provided = 1;
122 break;
123 case OPTION_MODULO:
124 if (scanned[i_arg].n_items != 2)
125 SDDS_Bomb("invalid -modulo syntax");
126 if (!get_double(&modulo, scanned[i_arg].list[1]))
127 SDDS_Bomb("invalid -modulo value given");
128 break;
129 case OPTION_COLUMN:
130 if ((scanned[i_arg].n_items < 2))
131 SDDS_Bomb("invalid -column syntax");
132 column_matches = scanned[i_arg].n_items - 1;
133 column_match = tmalloc(sizeof(*column_match) * column_matches);
134 for (i = 0; i < column_matches; i++)
135 column_match[i] = scanned[i_arg].list[i + 1];
136 break;
137 case OPTION_PIPE:
138 if (!processPipeOption(scanned[i_arg].list + 1,
139 scanned[i_arg].n_items - 1,
140 &pipe_flags))
141 SDDS_Bomb("invalid -pipe syntax");
142 break;
143 default:
144 fprintf(stderr, "Unknown option %s provided\n",
145 scanned[i_arg].list[0]);
146 exit(1);
147 break;
148 }
149 } else {
150 if (!input)
151 input = scanned[i_arg].list[0];
152 else if (!output)
153 output = scanned[i_arg].list[0];
154 else
155 SDDS_Bomb("too many filenames");
156 }
157 }
158 processFilenames("sddsunwrap", &input, &output, pipe_flags, 0, NULL);
159 if (phase && !threshold_provided)
160 threshold = PI;
161
162 if (!modulo)
163 modulo = 2 * threshold;
164
165 if (!SDDS_InitializeInput(&sdds_in, input))
166 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
167 if (column_matches) {
168 column = getMatchingSDDSNames(&sdds_in, column_match, column_matches,
169 &columns, SDDS_MATCH_COLUMN);
170 } else {
171 column = tmalloc(sizeof(*column) * 1);
172 if (!(column_name = (char **)SDDS_GetColumnNames(&sdds_in, &columns0)))
173 SDDS_PrintErrors(stderr,
174 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
175 for (i = 0; i < columns0; i++) {
176 if (SDDS_NUMERIC_TYPE(column_type =
177 SDDS_GetColumnType(&sdds_in, i))) {
178 SDDS_CopyString(&column[0], column_name[i]);
179 break;
180 }
181 }
182 SDDS_FreeStringArray(column_name, columns0);
183 columns = 1;
184 }
185
186 if (!SDDS_InitializeCopy(&sdds_out, &sdds_in, output, "w"))
187 SDDS_PrintErrors(stderr,
188 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
189 if (column_major_order != -1)
190 sdds_out.layout.data_mode.column_major = column_major_order;
191 else
192 sdds_out.layout.data_mode.column_major = sdds_in.layout.data_mode.column_major;
193
194 for (i = 0; i < columns; i++) {
195 sprintf(output_column, "Unwrap%s", column[i]);
196 if (!SDDS_TransferColumnDefinition(&sdds_out, &sdds_in, column[i],
197 output_column))
198 SDDS_PrintErrors(stderr,
199 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
200 }
201 if (!SDDS_WriteLayout(&sdds_out))
202 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
203
204 while (SDDS_ReadPage(&sdds_in) > 0) {
205 if ((rows = SDDS_CountRowsOfInterest(&sdds_in)) <= 0)
206 continue;
207 if (!SDDS_StartPage(&sdds_out, rows) || !SDDS_CopyPage(&sdds_out, &sdds_in))
208 SDDS_PrintErrors(stderr,
209 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
210
211 y_data = tmalloc(sizeof(*y_data) * rows);
212 for (i = 0; i < columns; i++) {
213 sprintf(output_column, "Unwrap%s", column[i]);
214 if (!(x_data = SDDS_GetColumnInDoubles(&sdds_in, column[i])))
215 SDDS_PrintErrors(stderr,
216 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
217 k = 0;
218 for (j = 0; j < rows - 1; j++) {
219 y_data[j] = x_data[j] + modulo * k; /*add 2*Pi*k to input */
220 /* check if diff is greater than alpha */
221 if (fabs(x_data[j + 1] - x_data[j]) > fabs(threshold)) {
222 if (x_data[j + 1] < x_data[j])
223 k = k + 1; /* if the pahse jump is negative, increment k */
224 else
225 k = k - 1; /* if the phase jump is positive, decrement k */
226 }
227 }
228 y_data[rows - 1] = x_data[rows - 1] + modulo * k; /* add 2*pi*k to the last element of the input */
229
230 if (x_data)
231 free(x_data);
232 x_data = NULL;
233
234 if (!SDDS_SetColumnFromDoubles(&sdds_out, SDDS_BY_NAME, y_data,
235 rows, output_column))
236 SDDS_PrintErrors(stderr,
237 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
238 }
239 free(y_data);
240 y_data = NULL;
241 if (!SDDS_WritePage(&sdds_out))
242 SDDS_PrintErrors(stderr,
243 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
244 }
245 if (!SDDS_Terminate(&sdds_in) || !SDDS_Terminate(&sdds_out)) {
246 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
247 exit(1);
248 }
249 if (column_name) {
250 SDDS_FreeStringArray(column_name, columns0);
251 free(column_name);
252 }
253 SDDS_FreeStringArray(column, columns);
254 free(column);
255 if (column_match)
256 free(column_match);
257 free_scanargs(&scanned, argc);
258 return 0;
259}
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.

Variable Documentation

◆ option

char* option[N_OPTIONS]
static
Initial value:
= {
"pipe",
"column",
"threshold",
"majorOrder",
"modulo",
}

Definition at line 64 of file sddsunwrap.c.

64 {
65 "pipe",
66 "column",
67 "threshold",
68 "majorOrder",
69 "modulo",
70};

◆ USAGE

char* USAGE
static
Initial value:
= "Usage: sddsunwrap [<input>] [<output>]\n\
Options:\n\
-pipe=[input][,output] Use pipes for input/output.\n\
-column=list Specify columns to be unwrapped, separated by commas.\n\
Accepts wildcards.\n\
-threshold=<value> Set the discontinuity threshold to identify a wrap.\n\
Default: PI.\n\
-modulo=<value> Set the value used to unwrap the data.\n\
Default: 2*PI.\n\
-majorOrder=<row|column> Specify the data order (row-major or column-major).\n\
Description:\n\
sddsunwrap identifies discontinuities greater than the threshold in a set of data\n\
and adds the appropriate multiple of the modulo to the data set.\n\
Program by Hairong Shang. (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ")"

Definition at line 49 of file sddsunwrap.c.