105 {
107 SCANNED_ARG *s_arg;
108 long i_arg, page_returned;
109 int64_t rows, row;
110 int32_t *row_flag;
111 char *input, *output, *column_name, *par_threshold_name, *x_column_name;
112 double *data, *x_data;
113 unsigned long pipe_flags, flags, major_order_flag;
114 double threshold, ezone_fraction, change_threshold, curvature_limit;
115 short column_major_order = -1;
116
118 argc =
scanargs(&s_arg, argc, argv);
119 if (argc < 2 || argc > (2 + N_OPTIONS))
121
122 flags = pipe_flags = 0;
123 input = output = NULL;
124 column_name = NULL;
125 ezone_fraction = change_threshold = curvature_limit = 0;
126 row_flag = NULL;
127 par_threshold_name = NULL;
128 x_column_name = NULL;
129 x_data = NULL;
130
131 for (i_arg = 1; i_arg < argc; i_arg++) {
132 if (s_arg[i_arg].arg_type == OPTION) {
133 switch (
match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
134 case CLO_MAJOR_ORDER:
135 major_order_flag = 0;
136 s_arg[i_arg].n_items--;
137 if (s_arg[i_arg].n_items > 0 &&
138 (!
scanItemList(&major_order_flag, s_arg[i_arg].list + 1,
139 &s_arg[i_arg].n_items, 0, "row", -1, NULL, 0,
140 SDDS_ROW_MAJOR_ORDER, "column", -1, NULL, 0,
141 SDDS_COLUMN_MAJOR_ORDER, NULL)))
142 SDDS_Bomb(
"invalid -majorOrder syntax/values");
143 if (major_order_flag & SDDS_COLUMN_MAJOR_ORDER)
144 column_major_order = 1;
145 else if (major_order_flag & SDDS_ROW_MAJOR_ORDER)
146 column_major_order = 0;
147 break;
148 case CLO_THRESHOLD:
149 if (s_arg[i_arg].n_items == 2) {
150 if (s_arg[i_arg].list[1][0] == '@') {
152 flags |= PAR_THRESHOLD;
153 } else {
154 if (sscanf(s_arg[i_arg].list[1], "%lf", &threshold) != 1)
155 SDDS_Bomb(
"incorrect -threshold syntax");
156 flags |= THRESHOLD;
157 }
158 } else
159 SDDS_Bomb(
"incorrect -threshold syntax");
160 break;
161 case CLO_FIVEPOINT:
162 flags |= FIVEPOINT;
163 break;
164 case CLO_SEVENPOINT:
165 flags |= SEVENPOINT;
166 break;
167 case CLO_CHANGETHRESHOLD:
168 if (s_arg[i_arg].n_items != 2 ||
169 sscanf(s_arg[i_arg].list[1], "%lf", &change_threshold) != 1 ||
170 change_threshold <= 0)
171 SDDS_Bomb(
"incorrect -changeThreshold syntax or values");
172 flags |= CHANGETHRES;
173 break;
174 case CLO_CURVATURE_LIMIT:
175 if (s_arg[i_arg].n_items != 3 ||
176 !strlen(x_column_name = s_arg[i_arg].list[1]) ||
177 sscanf(s_arg[i_arg].list[2], "%lf", &curvature_limit) != 1 ||
178 curvature_limit <= 0)
179 SDDS_Bomb(
"incorrect -curvatureLimit syntax or values");
180 flags |= CURVATURELIMIT;
181 break;
182 case CLO_PIPE:
183 if (!
processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipe_flags))
185 break;
186 case CLO_COLUMN:
187 if (s_arg[i_arg].n_items != 2)
189 column_name = s_arg[i_arg].list[1];
190 break;
191 case CLO_EXCLUSIONZONE:
192 if (s_arg[i_arg].n_items != 2 ||
193 sscanf(s_arg[i_arg].list[1], "%lf", &ezone_fraction) != 1 ||
194 ezone_fraction <= 0)
195 SDDS_Bomb(
"invalid -exclusionZone syntax or value");
196 flags |= EZONEFRAC;
197 break;
198 default:
199 fprintf(stderr, "error: unknown/ambiguous option: %s\n",
200 s_arg[i_arg].list[0]);
201 exit(1);
202 break;
203 }
204 } else {
205 if (input == NULL)
206 input = s_arg[i_arg].list[0];
207 else if (output == NULL)
208 output = s_arg[i_arg].list[0];
209 else
211 }
212 }
213
215
216 if (!column_name)
217 SDDS_Bomb(
"-column option must be given");
218
221
223 SDDS_Bomb(
"the given column is nonexistent or nonnumeric");
224
225 if (x_column_name &&
227 SDDS_Bomb(
"the given x column is nonexistent or nonnumeric");
228
231
232 out_set.layout.data_mode.column_major =
233 column_major_order != -1 ? column_major_order : in_set.layout.data_mode.column_major;
234
237
238
243 }
244
247 if (!data)
249
250 if (x_column_name)
252 if (x_column_name && !x_data)
254
255 row_flag =
SDDS_Realloc(row_flag,
sizeof(*row_flag) * rows);
256 for (row = 0; row < rows; row++)
257 row_flag[row] = 0;
258
259 mark_peaks(data, row_flag, rows,
260 flags & SEVENPOINT ? 7 : (flags & FIVEPOINT ? 5 : 3));
261
262 if (flags & PAR_THRESHOLD)
265
266 if (flags & THRESHOLD || flags & PAR_THRESHOLD)
267 for (row = 0; row < rows; row++)
268 if (row_flag[row] && data[row] < threshold)
269 row_flag[row] = 0;
270
271 if (flags & CHANGETHRES || flags & CURVATURELIMIT)
272 unmark_flat_peaks(data, row_flag, rows, change_threshold,
273 flags & FIVEPOINT, flags & SEVENPOINT, x_data, curvature_limit);
274
275 if (flags & EZONEFRAC)
276 unmark_excluded_peaks(data, row_flag, rows, ezone_fraction);
277
280
281 free(data);
282 }
283
286 }
287
290 exit(1);
291 }
292
294 free(par_threshold_name);
295 free(row_flag);
296
297 return 0;
298}
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_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_SetError(char *error_text)
Records an error message in the SDDS error stack.
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.
char * SDDS_FindColumn(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
Finds the first column in the SDDS dataset that matches the specified criteria.
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.
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
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.