121 {
123 SCANNED_ARG *s_arg;
124 long i_arg, page_returned;
125 int64_t rows, row;
126 int32_t *row_flag;
127 char *input, *output, *column_name, *par_threshold_name, *x_column_name;
128 double *data, *x_data;
129 unsigned long pipe_flags, flags, major_order_flag;
130 double threshold, ezone_fraction, change_threshold, curvature_limit;
131 short column_major_order = -1;
132
134 argc =
scanargs(&s_arg, argc, argv);
135 if (argc < 2 || argc > (2 + N_OPTIONS))
137
138 flags = pipe_flags = 0;
139 input = output = NULL;
140 column_name = NULL;
141 ezone_fraction = change_threshold = curvature_limit = 0;
142 row_flag = NULL;
143 par_threshold_name = NULL;
144 x_column_name = NULL;
145 x_data = NULL;
146
147 for (i_arg = 1; i_arg < argc; i_arg++) {
148 if (s_arg[i_arg].arg_type == OPTION) {
149 switch (
match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
150 case CLO_MAJOR_ORDER:
151 major_order_flag = 0;
152 s_arg[i_arg].n_items--;
153 if (s_arg[i_arg].n_items > 0 &&
154 (!
scanItemList(&major_order_flag, s_arg[i_arg].list + 1,
155 &s_arg[i_arg].n_items, 0, "row", -1, NULL, 0,
156 SDDS_ROW_MAJOR_ORDER, "column", -1, NULL, 0,
157 SDDS_COLUMN_MAJOR_ORDER, NULL)))
158 SDDS_Bomb(
"invalid -majorOrder syntax/values");
159 if (major_order_flag & SDDS_COLUMN_MAJOR_ORDER)
160 column_major_order = 1;
161 else if (major_order_flag & SDDS_ROW_MAJOR_ORDER)
162 column_major_order = 0;
163 break;
164 case CLO_THRESHOLD:
165 if (s_arg[i_arg].n_items == 2) {
166 if (s_arg[i_arg].list[1][0] == '@') {
168 flags |= PAR_THRESHOLD;
169 } else {
170 if (sscanf(s_arg[i_arg].list[1], "%lf", &threshold) != 1)
171 SDDS_Bomb(
"incorrect -threshold syntax");
172 flags |= THRESHOLD;
173 }
174 } else
175 SDDS_Bomb(
"incorrect -threshold syntax");
176 break;
177 case CLO_FIVEPOINT:
178 flags |= FIVEPOINT;
179 break;
180 case CLO_SEVENPOINT:
181 flags |= SEVENPOINT;
182 break;
183 case CLO_CHANGETHRESHOLD:
184 if (s_arg[i_arg].n_items != 2 ||
185 sscanf(s_arg[i_arg].list[1], "%lf", &change_threshold) != 1 ||
186 change_threshold <= 0)
187 SDDS_Bomb(
"incorrect -changeThreshold syntax or values");
188 flags |= CHANGETHRES;
189 break;
190 case CLO_CURVATURE_LIMIT:
191 if (s_arg[i_arg].n_items != 3 ||
192 !strlen(x_column_name = s_arg[i_arg].list[1]) ||
193 sscanf(s_arg[i_arg].list[2], "%lf", &curvature_limit) != 1 ||
194 curvature_limit <= 0)
195 SDDS_Bomb(
"incorrect -curvatureLimit syntax or values");
196 flags |= CURVATURELIMIT;
197 break;
198 case CLO_PIPE:
199 if (!
processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipe_flags))
201 break;
202 case CLO_COLUMN:
203 if (s_arg[i_arg].n_items != 2)
205 column_name = s_arg[i_arg].list[1];
206 break;
207 case CLO_EXCLUSIONZONE:
208 if (s_arg[i_arg].n_items != 2 ||
209 sscanf(s_arg[i_arg].list[1], "%lf", &ezone_fraction) != 1 ||
210 ezone_fraction <= 0)
211 SDDS_Bomb(
"invalid -exclusionZone syntax or value");
212 flags |= EZONEFRAC;
213 break;
214 default:
215 fprintf(stderr, "error: unknown/ambiguous option: %s\n",
216 s_arg[i_arg].list[0]);
217 exit(1);
218 break;
219 }
220 } else {
221 if (input == NULL)
222 input = s_arg[i_arg].list[0];
223 else if (output == NULL)
224 output = s_arg[i_arg].list[0];
225 else
227 }
228 }
229
231
232 if (!column_name)
233 SDDS_Bomb(
"-column option must be given");
234
237
239 SDDS_Bomb(
"the given column is nonexistent or nonnumeric");
240
241 if (x_column_name &&
243 SDDS_Bomb(
"the given x column is nonexistent or nonnumeric");
244
247
248 out_set.layout.data_mode.column_major =
249 column_major_order != -1 ? column_major_order : in_set.layout.data_mode.column_major;
250
253
254
259 }
260
263 if (!data)
265
266 if (x_column_name)
268 if (x_column_name && !x_data)
270
271 row_flag =
SDDS_Realloc(row_flag,
sizeof(*row_flag) * rows);
272 for (row = 0; row < rows; row++)
273 row_flag[row] = 0;
274
275 mark_peaks(data, row_flag, rows,
276 flags & SEVENPOINT ? 7 : (flags & FIVEPOINT ? 5 : 3));
277
278 if (flags & PAR_THRESHOLD)
281
282 if (flags & THRESHOLD || flags & PAR_THRESHOLD)
283 for (row = 0; row < rows; row++)
284 if (row_flag[row] && data[row] < threshold)
285 row_flag[row] = 0;
286
287 if (flags & CHANGETHRES || flags & CURVATURELIMIT)
288 unmark_flat_peaks(data, row_flag, rows, change_threshold,
289 flags & FIVEPOINT, flags & SEVENPOINT, x_data, curvature_limit);
290
291 if (flags & EZONEFRAC)
292 unmark_excluded_peaks(data, row_flag, rows, ezone_fraction);
293
296
297 free(data);
298 }
299
302 }
303
306 exit(1);
307 }
308
310 free(par_threshold_name);
311 free(row_flag);
312
313 return 0;
314}
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.