133 {
134 int iArg;
135 char **inputColumn;
136 char *input, *output;
137 long readCode, repeats, repeat, fitTerms = 2;
138 int64_t rows, i, j;
139 int32_t columns;
140 unsigned long pipeFlags, methodFlags, selectFlags, dummyFlags, majorOrderFlag;
141 SCANNED_ARG *scanned;
143 double *data, *indepData;
144 int32_t endPoints, antiOutlierPasses;
145 short *selected;
146 double outsideFWHA;
147 long nonnegative;
148 int32_t despikePasses, despikeWidthLimit;
149 short columnMajorOrder = -1;
150
152 argc =
scanargs(&scanned, argc, argv);
153 if (argc < 2)
155
156 output = input = NULL;
157 inputColumn = NULL;
158 columns = nonnegative = 0;
159 repeats = 1;
160 pipeFlags = methodFlags = selectFlags = dummyFlags = 0;
161 endPoints = antiOutlierPasses = 0;
162 outsideFWHA = 0;
163 despikePasses = 0;
164 despikeWidthLimit = 2;
165
166 for (iArg = 1; iArg < argc; iArg++) {
167 if (scanned[iArg].arg_type == OPTION) {
168
169 switch (
match_string(scanned[iArg].list[0], option, N_OPTIONS, 0)) {
170 case CLO_MAJOR_ORDER:
171 majorOrderFlag = 0;
172 scanned[iArg].n_items -= 1;
173 if (scanned[iArg].n_items > 0 &&
174 (!
scanItemList(&majorOrderFlag, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
175 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
176 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
177 SDDS_Bomb(
"invalid -majorOrder syntax/values");
178 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
179 columnMajorOrder = 1;
180 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
181 columnMajorOrder = 0;
182 break;
183 case CLO_COLUMNS:
184 if (scanned[iArg].n_items < 2)
186 inputColumn =
tmalloc(
sizeof(*inputColumn) * (columns = scanned[iArg].n_items - 1));
187 for (i = 0; i < columns; i++)
188 inputColumn[i] = scanned[iArg].list[i + 1];
189 break;
190 case CLO_PIPE:
191 if (!
processPipeOption(scanned[iArg].list + 1, scanned[iArg].n_items - 1, &pipeFlags))
193 break;
194 case CLO_METHOD:
195 if (!(scanned[iArg].n_items -= 1))
197 if (!
scanItemList(&methodFlags, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
198 "average", -1, NULL, 0, METHOD_AVERAGE,
199 "fit", -1, NULL, 0, METHOD_FIT,
200 "terms",
SDDS_LONG, &fitTerms, 1, 0, NULL) ||
201 bitsSet(methodFlags) != 1 || fitTerms < 2)
202 SDDS_Bomb(
"invalid -method syntax/values");
203 break;
204 case CLO_SELECT:
205 if (!(scanned[iArg].n_items -= 1))
207 if (!
scanItemList(&selectFlags, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
208 "endpoints",
SDDS_LONG, &endPoints, 1, SELECT_ENDPOINTS,
209 "outsidefwha",
SDDS_DOUBLE, &outsideFWHA, 1, SELECT_OUTSIDEFWHA,
210 "antioutlier",
SDDS_LONG, &antiOutlierPasses, 1, SELECT_ANTIOUTLIER, NULL) ||
212 SDDS_Bomb(
"invalid -select syntax/values");
213 break;
214 case CLO_NONNEGATIVE:
215 nonnegative = 1;
216 break;
217 case CLO_REPEATS:
218 if (scanned[iArg].n_items != 2 ||
219 sscanf(scanned[iArg].list[1], "%ld", &repeats) != 1 ||
220 repeats <= 0)
222 break;
223 case CLO_DESPIKE:
224 despikePasses = 1;
225 if (!(scanned[iArg].n_items -= 1))
227 if (!
scanItemList(&dummyFlags, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
228 "passes",
SDDS_LONG, &despikePasses, 1, 0,
229 "widthlimit",
SDDS_LONG, &despikeWidthLimit, 1, 0, NULL) ||
230 despikePasses < 0 ||
231 despikeWidthLimit < 1)
232 SDDS_Bomb(
"invalid -despike syntax/values");
233 break;
234 default:
235 fprintf(stderr, "error: unknown/ambiguous option: %s\n", scanned[iArg].list[0]);
236 exit(EXIT_FAILURE);
237 break;
238 }
239 } else {
240 if (!input)
241 input = scanned[iArg].list[0];
242 else if (!output)
243 output = scanned[iArg].list[0];
244 else
246 }
247 }
248
253
254 if (!nonnegative && despikePasses)
255 SDDS_Bomb(
"not meaningful to despike without setting -nonnegative");
256 if (!nonnegative && repeats > 1)
257 SDDS_Bomb(
"not meaningful to repeat without setting -nonnegative");
258
260
261 if (!columns)
262 SDDS_Bomb(
"supply the names of columns to process with the -columns option");
263
266
267 if (!resolveColumnNames(&SDDSin, &inputColumn, &columns))
269 if (!columns)
270 SDDS_Bomb(
"no columns selected for processing");
271
276 if (columnMajorOrder != -1)
277 SDDSout.layout.data_mode.column_major = columnMajorOrder;
278 else
279 SDDSout.layout.data_mode.column_major = SDDSin.layout.data_mode.column_major;
282
283 indepData = NULL;
284 selected = NULL;
289 if (!(indepData =
SDDS_Realloc(indepData,
sizeof(*indepData) * rows)) ||
290 !(selected =
SDDS_Realloc(selected,
sizeof(*selected) * rows)))
292 for (i = 0; i < rows; i++)
293 indepData[i] = i;
294 for (i = 0; i < columns; i++) {
297 for (repeat = 0; repeat < repeats; repeat++) {
298 for (j = 0; j < rows; j++)
299 selected[j] = 0;
300 switch (selectFlags) {
301 case SELECT_ENDPOINTS:
302 selectEndpoints(selected, rows, endPoints);
303 break;
304 case SELECT_OUTSIDEFWHA:
305 selectOutsideFWHA(data, indepData, selected, rows, outsideFWHA);
306 break;
307 case SELECT_ANTIOUTLIER:
308 selectAntiOutlier(data, selected, rows, antiOutlierPasses);
309 break;
310 default:
312 break;
313 }
314 switch (methodFlags) {
315 case METHOD_FIT:
316 fitAndRemoveBaseline(data, indepData, selected, rows, fitTerms);
317 break;
318 case METHOD_AVERAGE:
319 averageAndRemoveBaseline(data, selected, rows);
320 break;
321 default:
322 break;
323 }
324 if (nonnegative) {
325 for (j = 0; j < rows; j++)
326 if (data[j] < 0)
327 data[j] = 0;
328 if (despikePasses)
329 despikeProfile(data, rows, despikeWidthLimit, despikePasses);
330 }
331 }
333 !
SDDS_SetColumn(&SDDSout, SDDS_SET_BY_NAME, selected, rows,
"SelectedForBaselineDetermination"))
335 free(data);
336 }
337 }
340 }
343 return EXIT_FAILURE;
344 }
347 return EXIT_FAILURE;
348 }
349 if (indepData)
350 free(indepData);
351 if (selected)
352 free(selected);
353 return EXIT_SUCCESS;
354}
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_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_SetColumn(SDDS_DATASET *SDDS_dataset, int32_t mode, void *data, int64_t rows,...)
Sets the values for one data column in the current data table of an SDDS dataset.
int32_t SDDS_DefineSimpleColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *unit, int32_t type)
Defines a simple data column within the 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.
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.
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
#define SDDS_SHORT
Identifier for the signed short integer data type.
#define SDDS_DOUBLE
Identifier for the double data type.
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
long bitsSet(unsigned long data)
Counts the number of set bits (1s) in the given data.
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)
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.