146 {
147 int iArg;
150 long normRequests, normSpecs, i, readCode;
151 int64_t j, rows;
152 char *input, *output, *modeString;
153 unsigned long pipeFlags, majorOrderFlag;
154 SCANNED_ARG *scanned;
156 double *data, *funcOfData, factor, min, max;
157 short columnMajorOrder = -1;
158 int threads = 1;
159
161 argc =
scanargs(&scanned, argc, argv);
162 if (argc < 3)
164
165 output = input = NULL;
166 pipeFlags = 0;
167 normRequest = NULL;
168 normSpec = NULL;
169 normRequests = normSpecs = 0;
170
171 for (iArg = 1; iArg < argc; iArg++) {
172 if (scanned[iArg].arg_type == OPTION) {
173
174 switch (
match_string(scanned[iArg].list[0], option, N_OPTIONS, 0)) {
175 case CLO_MAJOR_ORDER:
176 majorOrderFlag = 0;
177 scanned[iArg].n_items--;
178 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)))
179 SDDS_Bomb(
"invalid -majorOrder syntax/values");
180 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
181 columnMajorOrder = 1;
182 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
183 columnMajorOrder = 0;
184 break;
185 case CLO_COLUMNS:
186 if (!(normRequest =
SDDS_Realloc(normRequest,
sizeof(*normRequest) * (normRequests + 1))))
188 normRequest[normRequests].exclude = normRequest[normRequests].suffix = NULL;
190 scanned[iArg].list, &scanned[iArg].n_items,
191 SCANITEMLIST_UNKNOWN_VALUE_OK | SCANITEMLIST_REMOVE_USED_ITEMS |
192 SCANITEMLIST_IGNORE_VALUELESS,
193 "mode",
SDDS_STRING, &modeString, 1, FL_MODE_GIVEN,
194 "suffix",
SDDS_STRING, &normRequest[normRequests].suffix, 1, FL_SUFFIX_GIVEN,
195 "functionof",
SDDS_STRING, &normRequest[normRequests].functionOf, 1, FL_FUNCOF_GIVEN,
196 "exclude",
SDDS_STRING, &normRequest[normRequests].exclude, 1, 0, NULL))
198 if (normRequest[normRequests].flags & FL_MODE_GIVEN) {
199 if ((normRequest[normRequests].mode =
match_string(modeString, normMode, NORM_OPTIONS, 0)) < 0)
200 SDDS_Bomb(
"invalid -columns syntax: unknown mode");
201 } else
202 normRequest[normRequests].mode = NORM_LARGEST;
203 if (scanned[iArg].n_items < 1)
204 SDDS_Bomb(
"invalid -columns syntax: no columns listed");
205 normRequest[normRequests].source = scanned[iArg].list + 1;
206 normRequest[normRequests].sources = scanned[iArg].n_items - 1;
207 normRequests++;
208 break;
209 case CLO_THREADS:
210 if (scanned[iArg].n_items != 2 ||
211 !sscanf(scanned[iArg].list[1], "%d", &threads) || threads < 1)
213 break;
214 case CLO_PIPE:
215 if (!
processPipeOption(scanned[iArg].list + 1, scanned[iArg].n_items - 1, &pipeFlags))
217 break;
218 default:
219 fprintf(stderr, "error: unknown/ambiguous option: %s\n", scanned[iArg].list[0]);
220 exit(EXIT_FAILURE);
221 break;
222 }
223 } else {
224 if (!input)
225 input = scanned[iArg].list[0];
226 else if (!output)
227 output = scanned[iArg].list[0];
228 else
230 }
231 }
232
234
235 if (!normRequests)
236 SDDS_Bomb(
"supply the names of columns to normalize with the -columns option");
237
240
241 if (!resolveColumnNames(&SDDSin, normRequest, normRequests, &normSpec, &normSpecs))
243
244 if (!normSpecs)
245 SDDS_Bomb(
"no columns selected for normalization");
246
249 if (columnMajorOrder != -1)
250 SDDSout.layout.data_mode.column_major = columnMajorOrder;
251 else
252 SDDSout.layout.data_mode.column_major = SDDSin.layout.data_mode.column_major;
253 for (i = 0; i < normSpecs; i++) {
254 if (normSpec[i].flags & FL_SUFFIX_GIVEN) {
260 }
261
264
268 if ((rows = SDDS_RowCount(&SDDSin))) {
269 for (i = 0; i < normSpecs; i++) {
272 funcOfData = NULL;
273 if (normSpec[i].functionOf &&
277 min = max = 1;
278 switch (normSpec[i].mode) {
279 case NORM_RMS:
281 break;
282 case NORM_STDEV:
284 break;
285 case NORM_MINIMUM:
286 factor = min;
287 break;
288 case NORM_MAXIMUM:
289 factor = max;
290 break;
291 case NORM_LARGEST:
292 min = fabs(min);
293 max = fabs(max);
294 factor = MAX(min, max);
295 break;
296 case NORM_SLARGEST:
297 if (fabs(min) > fabs(max))
298 factor = min;
299 else
300 factor = max;
301 break;
302 case NORM_SPREAD:
303 factor = max - min;
304 break;
305 case NORM_SUM:
306 for (j = factor = 0; j < rows; j++)
307 factor += data[j];
308 break;
309 case NORM_AREA:
310 if (!funcOfData)
311 SDDS_Bomb(
"functionOf qualifier must be given for area normalization");
313 break;
314 case NORM_AVERAGE:
315 for (j = factor = 0; j < rows; j++)
316 factor += data[j];
317 factor /= rows;
318 break;
319 default:
320 SDDS_Bomb(
"Invalid normalization mode---programming error");
321 break;
322 }
323 if (funcOfData)
324 free(funcOfData);
325 if (factor)
326 for (j = 0; j < rows; j++)
327 data[j] /= factor;
330 free(data);
331 }
332 }
335 }
338 return EXIT_FAILURE;
339 }
342 return EXIT_FAILURE;
343 }
344
345 return EXIT_SUCCESS;
346}
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.