156 {
157 int iArg;
160 long normRequests, normSpecs, i, readCode;
161 int64_t j, rows;
162 char *input, *output, *modeString;
163 unsigned long pipeFlags, majorOrderFlag;
164 SCANNED_ARG *scanned;
166 double *data, *funcOfData, factor, min, max;
167 short columnMajorOrder = -1;
168 int threads = 1;
169
171 argc =
scanargs(&scanned, argc, argv);
172 if (argc < 3)
174
175 output = input = NULL;
176 pipeFlags = 0;
177 normRequest = NULL;
178 normSpec = NULL;
179 normRequests = normSpecs = 0;
180
181 for (iArg = 1; iArg < argc; iArg++) {
182 if (scanned[iArg].arg_type == OPTION) {
183
184 switch (
match_string(scanned[iArg].list[0], option, N_OPTIONS, 0)) {
185 case CLO_MAJOR_ORDER:
186 majorOrderFlag = 0;
187 scanned[iArg].n_items--;
188 if (scanned[iArg].n_items > 0 && (!
scanItemList(&majorOrderFlag, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
"row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
"column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
189 SDDS_Bomb(
"invalid -majorOrder syntax/values");
190 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
191 columnMajorOrder = 1;
192 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
193 columnMajorOrder = 0;
194 break;
195 case CLO_COLUMNS:
196 if (!(normRequest =
SDDS_Realloc(normRequest,
sizeof(*normRequest) * (normRequests + 1))))
198 normRequest[normRequests].exclude = normRequest[normRequests].suffix = NULL;
200 scanned[iArg].list, &scanned[iArg].n_items,
201 SCANITEMLIST_UNKNOWN_VALUE_OK | SCANITEMLIST_REMOVE_USED_ITEMS |
202 SCANITEMLIST_IGNORE_VALUELESS,
203 "mode",
SDDS_STRING, &modeString, 1, FL_MODE_GIVEN,
204 "suffix",
SDDS_STRING, &normRequest[normRequests].suffix, 1, FL_SUFFIX_GIVEN,
205 "functionof",
SDDS_STRING, &normRequest[normRequests].functionOf, 1, FL_FUNCOF_GIVEN,
206 "exclude",
SDDS_STRING, &normRequest[normRequests].exclude, 1, 0, NULL))
208 if (normRequest[normRequests].flags & FL_MODE_GIVEN) {
209 if ((normRequest[normRequests].mode =
match_string(modeString, normMode, NORM_OPTIONS, 0)) < 0)
210 SDDS_Bomb(
"invalid -columns syntax: unknown mode");
211 } else
212 normRequest[normRequests].mode = NORM_LARGEST;
213 if (scanned[iArg].n_items < 1)
214 SDDS_Bomb(
"invalid -columns syntax: no columns listed");
215 normRequest[normRequests].source = scanned[iArg].list + 1;
216 normRequest[normRequests].sources = scanned[iArg].n_items - 1;
217 normRequests++;
218 break;
219 case CLO_THREADS:
220 if (scanned[iArg].n_items != 2 ||
221 !sscanf(scanned[iArg].list[1], "%d", &threads) || threads < 1)
223 break;
224 case CLO_PIPE:
225 if (!
processPipeOption(scanned[iArg].list + 1, scanned[iArg].n_items - 1, &pipeFlags))
227 break;
228 default:
229 fprintf(stderr, "error: unknown/ambiguous option: %s\n", scanned[iArg].list[0]);
230 exit(EXIT_FAILURE);
231 break;
232 }
233 } else {
234 if (!input)
235 input = scanned[iArg].list[0];
236 else if (!output)
237 output = scanned[iArg].list[0];
238 else
240 }
241 }
242
244
245 if (!normRequests)
246 SDDS_Bomb(
"supply the names of columns to normalize with the -columns option");
247
250
251 if (!resolveColumnNames(&SDDSin, normRequest, normRequests, &normSpec, &normSpecs))
253
254 if (!normSpecs)
255 SDDS_Bomb(
"no columns selected for normalization");
256
259 if (columnMajorOrder != -1)
260 SDDSout.layout.data_mode.column_major = columnMajorOrder;
261 else
262 SDDSout.layout.data_mode.column_major = SDDSin.layout.data_mode.column_major;
263 for (i = 0; i < normSpecs; i++) {
264 if (normSpec[i].flags & FL_SUFFIX_GIVEN) {
270 }
271
274
278 if ((rows = SDDS_RowCount(&SDDSin))) {
279 for (i = 0; i < normSpecs; i++) {
282 funcOfData = NULL;
283 if (normSpec[i].functionOf &&
287 min = max = 1;
288 switch (normSpec[i].mode) {
289 case NORM_RMS:
291 break;
292 case NORM_STDEV:
294 break;
295 case NORM_MINIMUM:
296 factor = min;
297 break;
298 case NORM_MAXIMUM:
299 factor = max;
300 break;
301 case NORM_LARGEST:
302 min = fabs(min);
303 max = fabs(max);
304 factor = MAX(min, max);
305 break;
306 case NORM_SLARGEST:
307 if (fabs(min) > fabs(max))
308 factor = min;
309 else
310 factor = max;
311 break;
312 case NORM_SPREAD:
313 factor = max - min;
314 break;
315 case NORM_SUM:
316 for (j = factor = 0; j < rows; j++)
317 factor += data[j];
318 break;
319 case NORM_AREA:
320 if (!funcOfData)
321 SDDS_Bomb(
"functionOf qualifier must be given for area normalization");
323 break;
324 case NORM_AVERAGE:
325 for (j = factor = 0; j < rows; j++)
326 factor += data[j];
327 factor /= rows;
328 break;
329 default:
330 SDDS_Bomb(
"Invalid normalization mode---programming error");
331 break;
332 }
333 if (funcOfData)
334 free(funcOfData);
335 if (factor)
336 for (j = 0; j < rows; j++)
337 data[j] /= factor;
340 free(data);
341 }
342 }
345 }
348 return EXIT_FAILURE;
349 }
352 return EXIT_FAILURE;
353 }
354
355 return EXIT_SUCCESS;
356}
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_ChangeColumnInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode,...)
Modifies a specific field in a column definition 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.
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.
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_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
#define SDDS_STRING
Identifier for the string data type.
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
int find_min_max(double *min, double *max, double *list, int64_t n)
Finds the minimum and maximum values in a list of doubles.
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.
double standardDeviationThreaded(double *x, long n, long numThreads)
Calculates the standard deviation of an array of doubles using multiple threads.
double rmsValueThreaded(double *y, long n, long numThreads)
Calculates the RMS (Root Mean Square) value of an array of doubles using multiple threads.
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.
long trapazoidIntegration(double *x, double *y, long n, double *integral)
Computes the integral of a dataset using the trapezoidal rule.