59static char *USAGE =
"\n"
60 "sddsunwrap [<input>] [<output>]\n"
61 " [-pipe=[input][,output]]\n"
63 " [-threshold=<value>]\n"
64 " [-modulo=<value>]\n"
65 " [-majorOrder=<row|column>]\n"
67 -pipe=[input][,output] Use pipes for input/output.\n\
68 -column=list Specify columns to be unwrapped, separated by commas.\n\
70 -threshold=<value> Set the discontinuity threshold to identify a wrap.\n\
72 -modulo=<value> Set the value used to unwrap the data.\n\
74 -majorOrder=<row|column> Specify the data order (row-major or column-major).\n\
76 sddsunwrap identifies discontinuities greater than the threshold in a set of data\n\
77 and adds the appropriate multiple of the modulo to the data set.\n\
78Program by Hairong Shang. (" __DATE__
" " __TIME__
", SVN revision: " SVN_VERSION
")";
80static char *option[N_OPTIONS] = {
88int main(
int argc,
char **argv) {
89 double *x_data, *y_data, threshold, modulo = 0;
90 char *input = NULL, *output = NULL, **column_match = NULL, **column_name = NULL, **column;
92 char output_column[256];
96 unsigned long pipe_flags = 0, major_order_flag = 0;
97 int32_t column_type, columns0 = 0;
99 int32_t columns = 0, column_matches = 0;
100 short column_major_order = -1, phase = 1, threshold_provided = 0;
104 argc =
scanargs(&scanned, argc, argv);
108 input = output = NULL;
109 x_data = y_data = NULL;
112 for (i_arg = 1; i_arg < argc; i_arg++) {
113 if (scanned[i_arg].arg_type == OPTION) {
115 OptionType option_type =
116 (OptionType)
match_string(scanned[i_arg].list[0], option,
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;
132 case OPTION_THRESHOLD:
133 if (scanned[i_arg].n_items != 2)
135 if (!
get_double(&threshold, scanned[i_arg].list[1]))
136 SDDS_Bomb(
"invalid -threshold value given");
137 threshold_provided = 1;
140 if (scanned[i_arg].n_items != 2)
142 if (!
get_double(&modulo, scanned[i_arg].list[1]))
143 SDDS_Bomb(
"invalid -modulo value given");
146 if ((scanned[i_arg].n_items < 2))
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];
155 scanned[i_arg].n_items - 1,
160 fprintf(stderr,
"Unknown option %s provided\n",
161 scanned[i_arg].list[0]);
167 input = scanned[i_arg].list[0];
169 output = scanned[i_arg].list[0];
175 if (phase && !threshold_provided)
179 modulo = 2 * threshold;
183 if (column_matches) {
185 &columns, SDDS_MATCH_COLUMN);
187 column =
tmalloc(
sizeof(*column) * 1);
190 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
191 for (i = 0; i < columns0; i++) {
204 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
205 if (column_major_order != -1)
206 sdds_out.layout.data_mode.column_major = column_major_order;
208 sdds_out.layout.data_mode.column_major = sdds_in.layout.data_mode.column_major;
210 for (i = 0; i < columns; i++) {
211 sprintf(output_column,
"Unwrap%s", column[i]);
215 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
225 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
227 y_data =
tmalloc(
sizeof(*y_data) * rows);
228 for (i = 0; i < columns; i++) {
229 sprintf(output_column,
"Unwrap%s", column[i]);
232 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
234 for (j = 0; j < rows - 1; j++) {
235 y_data[j] = x_data[j] + modulo * k;
237 if (fabs(x_data[j + 1] - x_data[j]) > fabs(threshold)) {
238 if (x_data[j + 1] < x_data[j])
244 y_data[rows - 1] = x_data[rows - 1] + modulo * k;
251 rows, output_column))
253 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
259 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
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_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.
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
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.
int32_t SDDS_CopyString(char **target, const char *source)
Copies a source string to a target string with memory allocation.
#define SDDS_NUMERIC_TYPE(type)
Checks if the given type identifier corresponds to any numeric type.
Utility functions for SDDS dataset manipulation and string array operations.
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
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.