SDDSlib
Loading...
Searching...
No Matches
SDDSaps.c
1/*************************************************************************\
2* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
3* National Laboratory.
4* Copyright (c) 2002 The Regents of the University of California, as
5* Operator of Los Alamos National Laboratory.
6* This file is distributed subject to a Software License Agreement found
7* in the file LICENSE that is included with this distribution.
8\*************************************************************************/
9
10/* file: SDDSaps.c
11 * contents: routines used by SDDS command-line applications
12 *
13 * M. Borland, 1993.
14 $Log: not supported by cvs2svn $
15 Revision 1.72 2011/10/04 20:27:11 borland
16 Added gmintegral processing option to allow integration using Gill-Miller method.
17
18 Revision 1.71 2011/05/16 20:52:13 shang
19 added lower and upper limit parameter for processing_definition so that the lower and upper limit can be obtained from parameters.
20
21 Revision 1.70 2010/12/10 18:18:49 soliday
22 Added support for algebraic mode when getting an equation from a parameter.
23
24 Revision 1.69 2010/12/09 16:13:26 borland
25 The ifnot and ifis options now respect the -nowarnings request.
26
27 Revision 1.68 2010/12/07 17:11:38 borland
28 Removed debugging statement from sddsprocess (related to @parameter equations).
29 Added test to ensure that @parameter equation isn't used for algebraic mode.
30
31 Revision 1.67 2010/12/02 22:51:28 borland
32 Added signedlargest and signedsmallest processing modes.
33
34 Revision 1.66 2010/06/11 17:11:37 borland
35 Allow lower limit to equal upper limit in filtering for -process.
36
37 Revision 1.65 2009/07/10 21:03:20 shang
38 modified the filter option to accept string as parameter name for defining lower and upper limit of the filter
39
40 Revision 1.64 2008/01/15 22:19:16 shang
41 Added -process mode for percentile range computation (prange).
42
43 Revision 1.63 2007/11/15 20:33:51 shang
44 added -1 arguments to SDDS_SetParametersFromDoubles in cast_parameter_value() routine and fixed the
45 problem that cannot cast parameter.
46
47 Revision 1.62 2005/11/15 20:53:58 soliday
48 Updated some routines used by sddsprocess that were causing trouble when
49 compiled with a 64bit compiler.
50
51 Revision 1.61 2005/11/07 21:48:09 soliday
52 Updated to remove Linux compiler warnings.
53
54 Revision 1.60 2004/03/03 18:59:03 borland
55 For count processing mode, return a valid value even if matching/filtering
56 eliminates all data points.
57
58 Revision 1.59 2003/11/24 17:35:12 borland
59 Added internal flag to indicate that processing result has the same units as
60 the thing processed. For 'count' processing, this flag is not set so the
61 result is now dimensionless.
62
63 Revision 1.58 2003/10/28 19:44:45 borland
64 Added edit qualifier to scan option. Allows pre-editing a string before
65 scanning it, which may save creation of an intermediate parameter or
66 column.
67
68 Revision 1.57 2003/09/23 22:02:56 soliday
69 Added the exclude option in the expandDefinitions function.
70
71 Revision 1.56 2003/09/02 19:16:01 soliday
72 Cleaned up code for Linux.
73
74 Revision 1.55 2003/07/22 21:05:37 soliday
75 IEEE functions are always used.
76
77 Revision 1.54 2003/07/22 15:21:32 soliday
78 Added the product process.
79
80 Revision 1.53 2003/06/02 21:39:12 soliday
81 Added the function to add parentheses around a string before calling if2pf
82
83 Revision 1.52 2003/06/02 20:26:31 borland
84 Now add ( and ) around all algebraic expressions to restore possible
85 lost parentheses (side effect of parseList() in scanargs.c).
86
87 Revision 1.51 2003/04/14 19:56:49 soliday
88 Fixed problem with last change on Windows.
89
90 Revision 1.50 2003/04/04 23:53:37 shang
91 fixed bugs in process_new_time_filter_definition()
92
93 Revision 1.49 2003/04/04 00:49:57 shang
94 added functions for processing time filter definitions
95
96 Revision 1.48 2003/03/21 23:51:50 borland
97 Added "integral" processing mode.
98
99 Revision 1.47 2003/03/14 20:42:11 soliday
100 Removed debuging statements.
101
102 Revision 1.46 2003/01/17 16:33:40 soliday
103 Fixed problem with last change.
104
105 Revision 1.45 2003/01/13 16:16:32 soliday
106 Fixed a bug in print_column_value so that it cannot use the target column
107 as the source column.
108
109 Revision 1.44 2002/08/14 17:12:34 soliday
110 Added Open License
111
112 Revision 1.43 2002/04/05 21:56:07 shang
113 removed pick function
114
115 Revision 1.42 2002/03/25 21:06:21 shang
116 added process_new_fclip_definition() function and modified record_processing_definition(),
117 process_column() and process_string_column()
118
119 Revision 1.41 2001/05/26 22:11:10 borland
120 Improved robustness of finding FWHA etc. for highly peaked, badly-sampled
121 functions.
122
123 Revision 1.40 2001/04/10 20:42:28 soliday
124 Added the ability to convert algebraic equations to rpn equations.
125
126 Revision 1.39 2000/10/11 21:50:23 soliday
127 Changed definition of isinf so that sunmath is no longer needed.
128
129 Revision 1.38 2000/10/07 01:20:01 borland
130 Added 'mode' processing mode. (The mode is the value that occurs most often.)
131
132 Revision 1.37 2000/08/10 21:16:59 soliday
133 Added support for gcc on Solaris.
134
135 Revision 1.36 2000/04/13 19:51:01 soliday
136 Added missing include statement.
137
138 Revision 1.35 2000/04/12 15:16:00 soliday
139 Fixed the Solaris compiler warnings.
140
141 Revision 1.34 1999/05/25 19:00:56 soliday
142 Removed compiler warning on linux.
143
144 Revision 1.33 1999/04/05 18:36:38 borland
145 Unescapes escaped wildcard characters after expanding commandline options.
146
147 Revision 1.32 1998/12/16 21:22:43 borland
148 Renamed SDDS_RedefineParameter and SDDS_RedefineColumn by appending
149 "CL" to the names.
150
151 Revision 1.31 1998/11/13 22:39:35 borland
152 Fixed a end-of-string runover problem
153
154 Revision 1.30 1998/08/26 14:47:51 borland
155 Treatment of IEEE math function isinf is now uniform. If on solaris
156 and sunmath is missing, then modify mdb.h and Makefile.Unix.
157
158 Revision 1.29 1998/06/24 19:23:46 borland
159 The -process option now allows specifying a string column with the
160 functionOf qualifier for some types of processing. This is allowed
161 if the position qualifier is also given, resulting in the ability to
162 pick out string data based on processing of numeric data.
163
164 Revision 1.28 1998/06/03 17:32:59 borland
165 Added support for templates in -print option. Printing to columns is
166 now faster and also implements printing of information from column
167 metadata (e.g., name, symbol, units).
168
169 Revision 1.27 1998/04/24 14:32:31 borland
170 Fixed smallest processing. Also changed largest processing, but it worked
171 properly before.
172
173 Revision 1.26 1997/05/08 21:46:46 borland
174 Now allows -print and -edit operations on character data (not just string
175 data).
176
177 Revision 1.25 1996/10/30 21:57:19 borland
178 Added -process mode for percentile computation.
179
180 Revision 1.24 1996/08/26 20:08:14 borland
181 Removed code for tokenIsNumber() and tokenIsInteger(). Now in mdblib.
182
183 Revision 1.23 1996/08/23 19:32:17 borland
184 Improved function of routines that determine whether a token is a number or
185 an integer.
186
187 * Revision 1.22 1996/07/05 16:33:07 borland
188 * Added 0 for new mode argument of SDDS_PrintTypedValue and/or
189 * SDDS_SprintTypedValue.
190 *
191 * Revision 1.21 1996/07/02 01:38:07 borland
192 * Added -cast option to convert between numerical types.
193 *
194 * Revision 1.20 1996/05/23 21:19:10 borland
195 * Added -format option and supporting routines.
196 *
197 * Revision 1.19 1996/05/02 02:03:13 borland
198 * Added better diagnostic printouts for bad keywords during redefinitions.
199 *
200 * Revision 1.18 1996/05/01 23:29:21 borland
201 * Now handles -redefine with templates properly.
202 *
203 * Revision 1.17 1996/03/28 23:47:56 borland
204 * Added checks for NaN and Inf to processing if filters are invoked.
205 *
206 * Revision 1.16 1996/02/17 20:16:40 borland
207 * Fixed bug in process_column having to do with not returning a count of 0 when
208 * there are no rows in the page.
209 *
210 * Revision 1.15 1996/02/15 16:16:13 borland
211 * Added -reedit option.
212 *
213 * Revision 1.14 1996/02/14 01:05:04 borland
214 * Changed over from scan_item_list() to scanItemList().
215 *
216 * Revision 1.13 1996/02/12 17:22:26 borland
217 * Added expandDefinitions() for template subsitution of many commandline
218 * options. Removed expandProcessingDefinitions(), expandConversionDefinitions(),
219 * and 2 associated routines. Added substitueString().
220 *
221 * Revision 1.12 1996/01/17 23:29:13 borland
222 * Replaced SDDS_GetColumn() call with SDDS_GetInternalColumn() call in a few
223 * places in hopes of improving performance.
224 *
225 * Revision 1.11 1996/01/17 16:44:46 borland
226 * Added support for wildcard strings in units conversion (-convertUnits option).
227 *
228 * Revision 1.10 1996/01/12 19:02:18 borland
229 * Added -numberTest option to sddsprocess, with supporting code in SDDSaps.*.
230 *
231 * Revision 1.9 1995/12/10 02:34:30 borland
232 * Added quartile and decile range -process modes.
233 *
234 * Revision 1.8 1995/10/07 22:43:00 borland
235 * Changed code to use topLimit and bottomLimit consistently rather than
236 * Threshold; redo of earlier change that was somehow lost.
237 *
238 * Revision 1.7 1995/10/07 18:40:41 borland
239 * Added argument to process_column() to carry -nowarnings option from
240 * sddsprocess commandline.
241 *
242 * Revision 1.6 1995/10/06 18:02:42 borland
243 * Added topLimit and bottomLimit qualifiers for sddsprocess -process option;
244 * added code to support this in SDDSaps.
245 *
246 * Revision 1.5 1995/09/13 02:23:29 borland
247 * Added warning messages for -print option when a source name exists as
248 * both a column and a parameter.
249 *
250 * Revision 1.4 1995/09/12 03:09:19 borland
251 * Added support for case-insensitive string matching with -match=<class>,<name>=+<string>
252 *
253 * Revision 1.3 1995/09/06 14:55:40 saunders
254 * First test release of SDDS1.5
255 *
256 */
257#include <ctype.h>
258#include "mdb.h"
259#include "SDDS.h"
260#include "SDDSaps.h"
261#include "rpn.h"
262#if !defined(_WIN32)
263# include <sys/time.h>
264#endif
265
266#undef DEBUG
267
268char *data_class_keyword[DATA_CLASS_KEYWORDS] = {
269 "column",
270 "parameter",
271 "array",
272};
273
274/*
275static long udfCounter = 0;
276*/
277typedef struct {
278 char *name, *description;
279 unsigned long flags;
281#define PROCMODE_NORMAL 0x0000UL
282#define PROCMODE_FUNCOF_REQUIRED 0x0001UL
283#define PROCMODE_FUNCOF_UNITS 0x0002UL
284#define PROCMODE_WEIGHT_OK 0x0004UL
285#define PROCMODE_POSITION_OK 0x0008UL
286#define PROCMODE_STRING_OK 0x0010UL
287#define PROCMODE_YoX_UNITS 0x0020UL
288#define PROCMODE_STRINGPOS_OK 0x0040UL
289#define PROCMODE_YtX_UNITS 0x0080UL
290#define PROCMODE_Y_UNITS 0x0100UL
291#define PROCMODE_NO_UNITS x00200UL
292
293static char *process_column_name[N_PROCESS_COLUMN_MODES] = {NULL};
294static PROCESS_COLUMN_DATA process_column_data[N_PROCESS_COLUMN_MODES] = {
295 {"average", "average of ", PROCMODE_NORMAL | PROCMODE_Y_UNITS | PROCMODE_WEIGHT_OK},
296 {"rms", "rms of ", PROCMODE_NORMAL | PROCMODE_Y_UNITS | PROCMODE_WEIGHT_OK},
297 {"sum", "sum of ", PROCMODE_NORMAL | PROCMODE_Y_UNITS | PROCMODE_WEIGHT_OK},
298 {"standarddeviation", "standard deviation of ", PROCMODE_NORMAL | PROCMODE_Y_UNITS | PROCMODE_WEIGHT_OK},
299 {"mad", "mean absolute deviation of ", PROCMODE_NORMAL | PROCMODE_Y_UNITS | PROCMODE_WEIGHT_OK},
300 {"minimum", "minimum of ", PROCMODE_NORMAL | PROCMODE_Y_UNITS | PROCMODE_POSITION_OK | PROCMODE_STRINGPOS_OK},
301 {"maximum", "maximum of ", PROCMODE_NORMAL | PROCMODE_Y_UNITS | PROCMODE_POSITION_OK | PROCMODE_STRINGPOS_OK},
302 {"smallest", "smallest of ", PROCMODE_NORMAL | PROCMODE_Y_UNITS | PROCMODE_POSITION_OK | PROCMODE_STRINGPOS_OK},
303 {"largest", "largest of ", PROCMODE_NORMAL | PROCMODE_Y_UNITS | PROCMODE_POSITION_OK | PROCMODE_STRINGPOS_OK},
304 {"first", "first ", PROCMODE_NORMAL | PROCMODE_Y_UNITS | PROCMODE_STRING_OK},
305 {"last", "last ", PROCMODE_NORMAL | PROCMODE_Y_UNITS | PROCMODE_STRING_OK},
306 {"count", "count ", PROCMODE_NORMAL},
307 {"spread", "spread in ", PROCMODE_NORMAL | PROCMODE_Y_UNITS},
308 {"median", "median of ", PROCMODE_NORMAL | PROCMODE_Y_UNITS},
309 {"baselevel", "base level of ", PROCMODE_NORMAL | PROCMODE_Y_UNITS},
310 {"toplevel", "top level of ", PROCMODE_NORMAL | PROCMODE_Y_UNITS},
311 {"amplitude", "amplitude of ", PROCMODE_NORMAL | PROCMODE_Y_UNITS},
312 {"risetime", "risetime of ", PROCMODE_FUNCOF_REQUIRED | PROCMODE_FUNCOF_UNITS},
313 {"falltime", "falltime of", PROCMODE_FUNCOF_REQUIRED | PROCMODE_FUNCOF_UNITS},
314 {"fwhm", "fwhm of ", PROCMODE_FUNCOF_REQUIRED | PROCMODE_FUNCOF_UNITS},
315 {"fwtm", "fwtm of ", PROCMODE_FUNCOF_REQUIRED | PROCMODE_FUNCOF_UNITS},
316 {"center", "center of ", PROCMODE_FUNCOF_REQUIRED | PROCMODE_FUNCOF_UNITS},
317 {"zerocrossing", "zero crossing of ", PROCMODE_FUNCOF_REQUIRED | PROCMODE_FUNCOF_UNITS},
318 {"fwha", "fwha of ", PROCMODE_FUNCOF_REQUIRED | PROCMODE_FUNCOF_UNITS},
319 {"fwta", "fwta of ", PROCMODE_FUNCOF_REQUIRED | PROCMODE_FUNCOF_UNITS},
320 {"sigma", "sigma of ", PROCMODE_NORMAL | PROCMODE_Y_UNITS | PROCMODE_WEIGHT_OK},
321 {"slope", "slope of ", PROCMODE_FUNCOF_REQUIRED | PROCMODE_YoX_UNITS},
322 {"intercept", "intercept of ", PROCMODE_NORMAL | PROCMODE_Y_UNITS},
323 {"lfsd", "linear-fit standard deviation of ", PROCMODE_NORMAL | PROCMODE_Y_UNITS},
324 {"qrange", "quartile range", PROCMODE_NORMAL | PROCMODE_Y_UNITS},
325 {"drange", "decile range", PROCMODE_NORMAL | PROCMODE_Y_UNITS},
326 {"percentile", "percentile", PROCMODE_NORMAL | PROCMODE_Y_UNITS},
327 {"mode", "mode of", PROCMODE_NORMAL | PROCMODE_Y_UNITS},
328 {"integral", "integral of ", PROCMODE_NORMAL | PROCMODE_FUNCOF_REQUIRED | PROCMODE_YtX_UNITS},
329 {"product", "product of ", PROCMODE_NORMAL | PROCMODE_WEIGHT_OK},
330 {"prange", "percentile range", PROCMODE_NORMAL | PROCMODE_Y_UNITS},
331 {"signedsmallest", "signed smallest of ", PROCMODE_NORMAL | PROCMODE_Y_UNITS | PROCMODE_POSITION_OK | PROCMODE_STRINGPOS_OK},
332 {"signedlargest", "signed largest of ", PROCMODE_NORMAL | PROCMODE_Y_UNITS | PROCMODE_POSITION_OK | PROCMODE_STRINGPOS_OK},
333 {"gmintegral", "integral of ", PROCMODE_NORMAL | PROCMODE_FUNCOF_REQUIRED | PROCMODE_YtX_UNITS},
334 {"correlation", "correlation coefficient", PROCMODE_FUNCOF_REQUIRED}};
335
336/* these are used for options that support wildcard-based processing
337 * using syntax like -define=column,%sFoo,"%sBar 2 *",select=x*
338 */
339#define SELECT_QUALIFIER 0
340#define EDITSELECTION_QUALIFIER 1
341#define EXCLUDE_QUALIFIER 2
342#define SELECT_QUALIFIERS 3
343static char *selectQualifier[SELECT_QUALIFIERS] = {
344 "select", "editselection", "exclude"};
345
346void GillMillerIntegration1(double *indepData, double *data, long n_data, double *result);
347
348void show_process_modes(FILE *fp) {
349 long i, length, maxLength, nPerLine;
350 char format[30];
351
352 maxLength = 0;
353 for (i = 0; i < N_PROCESS_COLUMN_MODES; i++)
354 if ((length = strlen(process_column_data[i].name)) > maxLength)
355 maxLength = length;
356 sprintf(format, "%%%lds%%c", maxLength + 1);
357 nPerLine = 80 / (maxLength + 2);
358 fprintf(fp, "processing modes:\n");
359 for (i = 0; i < N_PROCESS_COLUMN_MODES; i++)
360 fprintf(fp, format, process_column_data[i].name, (i + 1) % nPerLine ? ' ' : '\n');
361 if (i % nPerLine)
362 fputc('\n', fp);
363}
364
365void add_ifitem(IFITEM_LIST *ifitem, char **name, long names) {
366 long i, type;
367 if (ifitem->items == 0) {
368 ifitem->name = NULL;
369 ifitem->type = NULL;
370 }
371 ifitem->name = trealloc(ifitem->name, sizeof(*ifitem->name) * (ifitem->items + names - 1));
372 ifitem->type = trealloc(ifitem->type, sizeof(*ifitem->type) * (ifitem->items + names - 1));
373 if ((type = match_string(name[0], data_class_keyword, DATA_CLASS_KEYWORDS, 0)) < 0)
374 SDDS_Bomb("invalid -ifnot syntax---column, parameter, or array keyword required");
375 for (i = 1; i < names; i++)
376 ifitem->type[ifitem->items + i - 1] = type;
377 if (!SDDS_CopyStringArray(ifitem->name + ifitem->items, name + 1, names - 1))
378 SDDS_Bomb("problem copying names for -ifnot or -ifis option");
379 ifitem->items += names - 1;
380}
381
382long check_ifitems(SDDS_DATASET *SDDS_dataset, IFITEM_LIST *ifitem, long desired, long announce) {
383 long i, index;
384 for (i = 0; i < ifitem->items; i++) {
385 switch (ifitem->type[i]) {
386 case COLUMN_BASED:
387 index = SDDS_GetColumnIndex(SDDS_dataset, ifitem->name[i]);
388 break;
389 case PARAMETER_BASED:
390 index = SDDS_GetParameterIndex(SDDS_dataset, ifitem->name[i]);
391 break;
392 case ARRAY_BASED:
393 index = SDDS_GetArrayIndex(SDDS_dataset, ifitem->name[i]);
394 break;
395 default:
396 SDDS_Bomb("internal error---unknown ifitem type");
397 exit(1);
398 break;
399 }
400 if ((index >= 0) != desired) {
401 if (desired) {
402 if (announce)
403 fprintf(stderr, "%s %s does not exist--aborting\n",
404 data_class_keyword[ifitem->type[i]], ifitem->name[i]);
405 return 0;
406 }
407 if (announce)
408 fprintf(stderr, "%s %s exists--aborting\n",
409 data_class_keyword[ifitem->type[i]], ifitem->name[i]);
410 return 0;
411 }
412 }
413 return 1;
414}
415
416FILTER_DEFINITION *process_new_filter_definition(char **argument, long arguments) {
417 FILTER_DEFINITION *defi;
418
419 if (!(defi = tmalloc(sizeof(*defi))))
420 SDDS_Bomb("memory allocation failure (process_new_filter_definition)");
421 switch (match_string(argument[0], data_class_keyword, DATA_CLASS_KEYWORDS, 0)) {
422 case COLUMN_BASED:
423 defi->is_parameter = 0;
424 break;
425 case PARAMETER_BASED:
426 defi->is_parameter = 1;
427 break;
428 default:
429 fprintf(stderr, "error: column or parameter must be specified for filter\n");
430 return (NULL);
431 }
432 if (!(defi->filter_terms =
433 process_filter_request(&(defi->filter_term), argument + 1, arguments - 1)))
434 return (NULL);
435 return (defi);
436}
437
438TIME_FILTER_DEFINITION *process_new_time_filter_definition(char **argument, long arguments) {
440 char *before, *after, *year, *month = NULL, *day = NULL, *hour, *minute, *second;
441 short minute_n, second_n, hour_n;
442 double hour_n1;
443 minute_n = second_n = hour_n = 0;
444
445 before = after = NULL;
446 if (!(defi = tmalloc(sizeof(*defi))))
447 SDDS_Bomb("memory allocation failure (process_new_filter_definition)");
448 switch (match_string(argument[0], data_class_keyword, DATA_CLASS_KEYWORDS, 0)) {
449 case COLUMN_BASED:
450 defi->is_parameter = 0;
451 break;
452 case PARAMETER_BASED:
453 defi->is_parameter = 1;
454 break;
455 default:
456 fprintf(stderr, "error: column or parameter must be specified for filter\n");
457 return (NULL);
458 }
459 defi->flags = 0;
460 defi->before = defi->after = 0;
461 hour = minute = second = 0;
462 defi->name = argument[1];
463 arguments -= 2;
464 argument += 2;
465 if (!scanItemList(&defi->flags, argument, &arguments, 0,
466 "before", SDDS_STRING, &before, 1, TIMEFILTER_BEFORE_GIVEN,
467 "after", SDDS_STRING, &after, 1, TIMEFILTER_AFTER_GIVEN,
468 "invert", -1, NULL, 0, TIMEFILTER_INVERT_GIVEN,
469 NULL))
470 SDDS_Bomb("invalid -timeFilter syntax");
471 if (before) {
472 minute_n = second_n = hour_n = 0;
473 if (!(year = get_token_tq(before, "", "/", "", "")) ||
474 !(month = get_token_tq(before, "/", "/", "", "")) ||
475 !(day = get_token_tq(before, "/", "@", "", "")))
476 SDDS_Bomb("invalid \"before\" date given, the specified data should be YYYY/MM/DD@HH:MM:SS");
477 if ((hour = get_token_tq(before, "@", ":", "", "")))
478 hour_n = atol(hour);
479 if ((minute = get_token_tq(before, ":", ":", "", "")))
480 minute_n = atol(minute);
481 if ((second = get_token_tq(before, ":", "", "", "")))
482 second_n = atol(second);
483 hour_n1 = hour_n * 1.0 + minute_n / 60.0 + second_n / 3600.0;
484 if (!TimeBreakdownToEpoch(atol(year), 0, atol(month), atol(day), hour_n1, &defi->before))
485 SDDS_Bomb("invalid -timeFilter before syntax (something wrong with time convert)");
486 /*fprintf(stderr,"before: hour=%d,minute=%d,second=%d, time=%f\n",hour_n,minute_n,second_n,defi->before);*/
487 }
488 if (after) {
489 minute_n = second_n = hour_n = 0;
490 if (!(year = get_token_tq(after, "", "/", "", "")) ||
491 !(month = get_token_tq(after, "/", "/", "", "")) ||
492 !(day = get_token_tq(after, "/", "@", "", "")))
493 SDDS_Bomb("invalid \"after\" date given, the specified data should be YYYY/MM/DD@HH:MM:SS");
494 if ((hour = get_token_tq(after, "@", ":", "", "")))
495 hour_n = atol(hour);
496 if ((minute = get_token_tq(after, ":", ":", "", "")))
497 minute_n = atol(minute);
498 if ((second = get_token_tq(after, ":", "", "", "")))
499 second_n = atol(second);
500 hour_n1 = hour_n * 1.0 + minute_n / 60.0 + second_n / 3600.0;
501 if (!TimeBreakdownToEpoch(atol(year), 0, atol(month), atol(day), hour_n1, &defi->after))
502 SDDS_Bomb("invalid -timeFilter after syntax (something wrong with time convert)");
503 /* fprintf(stderr,"after: hour=%d,minute=%d,second=%d, time=%f\n",hour_n,minute_n,second_n,defi->after); */
504 }
505 if (before && after && defi->before < defi->after)
506 SDDS_Bomb("Invalid -timeFilter syntx, before date is earlier than the after date!");
507 if (!before)
508 defi->before = getTimeInSecs() + 3600.0;
509 /*no before time is given, accept all the time from the after date to now+3600*/
510 if (!after)
511 defi->after = -1; /*no after time is given, accept all the time before the before date */
512 /*fprintf(stderr,"before=%f, after=%f\n",defi->before,defi->after); */
513 return (defi);
514}
515
516MATCH_DEFINITION *process_new_match_definition(char **argument, long arguments) {
517 MATCH_DEFINITION *defi;
518
519 if (!(defi = tmalloc(sizeof(*defi))))
520 SDDS_Bomb("memory allocation failure (process_new_match_definition)");
521 switch (match_string(argument[0], data_class_keyword, DATA_CLASS_KEYWORDS, 0)) {
522 case COLUMN_BASED:
523 defi->is_parameter = 0;
524 break;
525 case PARAMETER_BASED:
526 defi->is_parameter = 1;
527 break;
528 default:
529 fprintf(stderr, "error: column or parameter must be specified for match\n");
530 return (NULL);
531 }
532 if (!(defi->match_terms =
533 process_match_request(&(defi->match_term), argument + 1, arguments - 1)))
534 return (NULL);
535 return (defi);
536}
537
538long process_filter_request(FILTER_TERM **filter, char **argument, long arguments) {
539 long i, filters, max_filters;
540 long need_name, need_operation;
541
542 filters = 0;
543 i = 0;
544 max_filters = (arguments + 1) / 3 + 1;
545 *filter = tmalloc(sizeof(**filter) * max_filters);
546
547 need_name = 1;
548 need_operation = -1;
549 do {
550 if (is_logic_character(argument[i][0])) {
551 if (need_name)
552 return (0);
553 do {
554 /* will come here only for &, |, or ! applying to expressions */
555 if (need_name)
556 return (0);
557 switch (argument[i][0]) {
558 case '&':
559 if ((*filter)[filters].logic & SDDS_AND || (*filter)[filters].logic & SDDS_OR ||
560 (*filter)[filters].logic & SDDS_NEGATE_EXPRESSION)
561 return (0);
562 (*filter)[filters].logic |= SDDS_AND;
563 break;
564 case '|':
565 if ((*filter)[filters].logic & SDDS_AND || (*filter)[filters].logic & SDDS_OR ||
566 (*filter)[filters].logic & SDDS_NEGATE_EXPRESSION)
567 return (0);
568 (*filter)[filters].logic |= SDDS_OR;
569 break;
570 case '!':
571 if (!((*filter)[filters].logic & SDDS_AND || (*filter)[filters].logic & SDDS_OR) ||
572 (*filter)[filters].logic & SDDS_NEGATE_EXPRESSION)
573 return (0);
574 (*filter)[filters].logic |= SDDS_NEGATE_EXPRESSION;
575 }
576 } while (++i < arguments && is_logic_character(argument[i][0]));
577 filters++;
578 if (i >= arguments)
579 break;
580 need_name = 1;
581 } else if (need_operation > 0)
582 return (0);
583
584 /* should have a triplet (name, lower, upper) in argument list now */
585 if (is_logic_character(argument[i][0]))
586 return (0);
587 if (arguments - i < 3)
588 return (0);
589 if (filters + 1 >= max_filters)
590 *filter = trealloc(*filter, sizeof(**filter) * (max_filters += 2));
591 (*filter)[filters].name = argument[i++];
592 if (sscanf(argument[i], "%lf", &(*filter)[filters].lower) != 1)
593 (*filter)[filters].lowerPar = argument[i];
594 else
595 (*filter)[filters].lowerPar = NULL;
596 i++;
597 if (sscanf(argument[i], "%lf", &(*filter)[filters].upper) != 1)
598 (*filter)[filters].upperPar = argument[i];
599 else
600 (*filter)[filters].upperPar = NULL;
601 i++;
602 if ((*filter)[filters].lowerPar == NULL && (*filter)[filters].upperPar == NULL && (*filter)[filters].upper < (*filter)[filters].lower)
603 return (0);
604 (*filter)[filters].logic = 0;
605 if (arguments - i > 0 && argument[i][0] == '!') {
606 (*filter)[filters].logic = SDDS_NEGATE_MATCH;
607 i++;
608 }
609 if (++need_operation > 0)
610 need_name = 0;
611 else
612 filters++;
613 } while (arguments > i);
614 (*filter)[0].logic |= SDDS_AND;
615 return (filters);
616}
617
618long process_match_request(MATCH_TERM **match, char **argument, long arguments) {
619 long i, matches, max_matches;
620 long need_name, need_operation;
621 char *ptr;
622
623 matches = 0;
624 i = 0;
625 max_matches = (arguments + 1) / 3 + 1;
626 *match = tmalloc(sizeof(**match) * max_matches);
627
628 need_name = 1;
629 need_operation = -1;
630 do {
631 if (is_logic_character(argument[i][0])) {
632 if (need_name)
633 return (0);
634 do {
635 /* will come here only for &, |, or ! applying to expressions */
636 if (need_name)
637 return (0);
638 switch (argument[i][0]) {
639 case '&':
640 if ((*match)[matches].logic & SDDS_AND || (*match)[matches].logic & SDDS_OR ||
641 (*match)[matches].logic & SDDS_NEGATE_EXPRESSION)
642 return (0);
643 (*match)[matches].logic |= SDDS_AND;
644 break;
645 case '|':
646 if ((*match)[matches].logic & SDDS_AND || (*match)[matches].logic & SDDS_OR ||
647 (*match)[matches].logic & SDDS_NEGATE_EXPRESSION)
648 return (0);
649 (*match)[matches].logic |= SDDS_OR;
650 break;
651 case '!':
652 if (!((*match)[matches].logic & SDDS_AND || (*match)[matches].logic & SDDS_OR) ||
653 (*match)[matches].logic & SDDS_NEGATE_EXPRESSION)
654 return (0);
655 (*match)[matches].logic |= SDDS_NEGATE_EXPRESSION;
656 }
657 } while (++i < arguments && is_logic_character(argument[i][0]));
658 matches++;
659 if (i >= arguments)
660 break;
661 need_name = 1;
662 } else if (need_operation > 0)
663 return (0);
664
665 /* should have a name=string object now */
666 if (is_logic_character(argument[i][0]))
667 return (0);
668 if (arguments - i < 1)
669 return (0);
670 if (matches + 1 >= max_matches)
671 *match = trealloc(*match, sizeof(**match) * (max_matches += 2));
672 if (!(ptr = strchr(argument[i], '=')))
673 return (0);
674 *ptr = 0;
675 (*match)[matches].logic = 0;
676 if (*(ptr + 1) == '+') {
677 (*match)[matches].logic |= SDDS_NOCASE_COMPARE;
678 ptr++;
679 }
680 if (*(ptr + 1) == '@') {
681 (*match)[matches].logic |= SDDS_INDIRECT_MATCH;
682 ptr++;
683 }
684 (*match)[matches].name = argument[i++];
685 (*match)[matches].string = ptr + 1;
686 if (arguments - i > 0 && argument[i][0] == '!') {
687 (*match)[matches].logic |= SDDS_NEGATE_MATCH;
688 i++;
689 }
690 if (++need_operation > 0)
691 need_name = 0;
692 else
693 matches++;
694 } while (arguments > i);
695 (*match)[0].logic |= SDDS_AND;
696 return (matches);
697}
698
699void scan_label_parameter(LABEL_PARAMETER *label, char *string) {
700 char *ptr;
701 label->format = NULL;
702 if ((ptr = strchr(string, '='))) {
703 *ptr = 0;
704 label->format = ptr + 1;
705 }
706 label->name = string;
707}
708
709void show_matches(char *type, MATCH_TERM *match, long matches) {
710 long i;
711 fprintf(stderr, "\n %s matching logic:\n", type);
712 for (i = 0; i < matches; i++) {
713 if (match[i].logic & SDDS_NEGATE_MATCH)
714 fprintf(stderr, " <%s> != ", match[i].name);
715 else
716 fprintf(stderr, " <%s> == ", match[i].name);
717 if (match[i].logic & SDDS_INDIRECT_MATCH)
718 fprintf(stderr, "<%s>", match[i].string);
719 else
720 fprintf(stderr, "\"%s\"", match[i].string);
721 if (match[i].logic & SDDS_NOCASE_COMPARE)
722 fprintf(stderr, " (case insensitive)\n");
723 else
724 fprintf(stderr, " (case sensitive)\n");
725 if (i != 0) {
726 if (match[i].logic & SDDS_AND)
727 fprintf(stderr, "&& ");
728 if (match[i].logic & SDDS_OR)
729 fprintf(stderr, "|| ");
730 }
731 if (match[i].logic & SDDS_NEGATE_EXPRESSION)
732 fputc('!', stderr);
733 fputc('\n', stderr);
734 }
735}
736
737void show_filters(char *type, FILTER_TERM *filter, long filters) {
738 long i;
739 fprintf(stderr, "\n %s filtering logic:\n", type);
740 for (i = 0; i < filters; i++) {
741 if (filter[i].logic & SDDS_NEGATE_MATCH)
742 fprintf(stderr, " !( <%s>:[%22.15e, %22.15e] ) ", filter[i].name, filter[i].lower, filter[i].upper);
743 else
744 fprintf(stderr, " <%s>:[%22.15e, %22.15e] ", filter[i].name, filter[i].lower, filter[i].upper);
745 if (i != 0) {
746 if (filter[i].logic & SDDS_AND)
747 fprintf(stderr, "&& ");
748 if (filter[i].logic & SDDS_OR)
749 fprintf(stderr, "|| ");
750 }
751 if (filter[i].logic & SDDS_NEGATE_EXPRESSION)
752 fputc('!', stderr);
753 fputc('\n', stderr);
754 }
755}
756
757EQUATION_DEFINITION *process_new_equation_definition(char **argument, long arguments) {
758 static char s[SDDS_MAXLINE];
759 char *ptr, *equation;
760 long i, code, algebraic = 0;
762 char pfix[IFPF_BUF_SIZE];
763
764 if (!(defi = tmalloc(sizeof(*defi))))
765 SDDS_Bomb("memory allocation failure (process_new_equation_definition)");
766 defi->name = defi->text = defi->equation = defi->udf_name =
767 defi->editSelection = defi->select = defi->exclude = NULL;
768 defi->argv = NULL;
769 switch (match_string(argument[0], data_class_keyword, DATA_CLASS_KEYWORDS, 0)) {
770 case COLUMN_BASED:
771 defi->is_parameter = 0;
772 sprintf(s, "&column name=\"%s\", ", argument[1]);
773 break;
774 case PARAMETER_BASED:
775 defi->is_parameter = 1;
776 sprintf(s, "&parameter name=\"%s\", ", argument[1]);
777 break;
778 default:
779 fprintf(stderr, "error: column or parameter must be specified for definition\n");
780 return (NULL);
781 }
782 SDDS_CopyString(&defi->name, argument[1]);
783
784 for (i = 3; i < arguments; i++) {
785 if (strncmp(argument[i], "algebraic", strlen(argument[i])) == 0) {
786 algebraic = 1;
787 break;
788 }
789 }
790
791 defi->argc = 0;
792
793 if (algebraic) {
794 if (argument[2][0] == '@') {
795 /*Add second @ symbol to signify that the parameter contains algebraic notation*/
796 equation = malloc(sizeof(char) * strlen(argument[2]) + 1);
797 sprintf(equation, "@%s", argument[2]);
798 } else {
799 ptr = addOuterParentheses(argument[2]);
800 if2pf(pfix, ptr, sizeof pfix);
801 free(ptr);
802
803 if (!SDDS_CopyString(&equation, pfix)) {
804 fprintf(stderr, "error: problem copying argument string\n");
805 return NULL;
806 }
807 }
808 if (arguments > 4) {
809 defi->argv = tmalloc(sizeof(*defi->argv) * (arguments - 3));
810 } else {
811 defi->argv = tmalloc(sizeof(*defi->argv) * 1);
812 }
813 } else {
814 equation = argument[2];
815 if (arguments > 3) {
816 defi->argv = tmalloc(sizeof(*defi->argv) * (arguments - 2));
817 } else {
818 defi->argv = tmalloc(sizeof(*defi->argv) * 1);
819 }
820 }
821 for (i = 3; i < arguments; i++) {
822 if (!(ptr = strchr(argument[i], '='))) {
823 if (strncmp(argument[i], "algebraic", strlen(argument[i])) == 0)
824 continue;
825 fprintf(stderr, "error: invalid definition-entry: %s\n", argument[i]);
826 return (NULL);
827 }
828 *ptr = 0;
829 switch (code = match_string(argument[i], selectQualifier, SELECT_QUALIFIERS, 0)) {
830 case SELECT_QUALIFIER:
831 SDDS_CopyString(&defi->select, ptr + 1);
832 break;
833 case EDITSELECTION_QUALIFIER:
834 SDDS_CopyString(&defi->editSelection, ptr + 1);
835 break;
836 case EXCLUDE_QUALIFIER:
837 SDDS_CopyString(&defi->exclude, ptr + 1);
838 break;
839 default:
840 break;
841 }
842 *ptr = '=';
843 if (code >= 0)
844 continue;
845 if (!SDDS_CopyString(defi->argv + defi->argc, argument[i])) {
846 fprintf(stderr, "error: problem copying argument string\n");
847 return NULL;
848 }
849 defi->argc += 1;
850 *ptr = 0;
851 strcat(s, argument[i]);
852 strcat(s, "=\"");
853 strcat(s, ptr + 1);
854 strcat(s, "\", ");
855 *ptr = '=';
856 }
857 if (!strstr(s, ", type=")) {
858 strcat(s, " type=\"double\", ");
859 SDDS_CopyString(defi->argv + defi->argc, "type=double");
860 defi->argc += 1;
861 }
862 strcat(s, "&end");
863 if (!SDDS_CopyString(&defi->text, s) || !SDDS_CopyString(&defi->equation, equation))
864 SDDS_Bomb("string copying failed (process_new_equation_definition)");
865 return (defi);
866}
867
868EVALUATE_DEFINITION *process_new_evaluate_definition(char **argument, long arguments) {
869 static char s[SDDS_MAXLINE];
870 long i;
872
873 if (!(defi = tmalloc(sizeof(*defi))))
874 SDDS_Bomb("memory allocation failure (process_new_evaluate_definition)");
875 defi->name = defi->text = defi->source = NULL;
876 switch (match_string(argument[0], data_class_keyword, DATA_CLASS_KEYWORDS, 0)) {
877 case COLUMN_BASED:
878 defi->is_parameter = 0;
879 sprintf(s, "&column name=\"%s\", ", argument[1]);
880 break;
881 case PARAMETER_BASED:
882 defi->is_parameter = 1;
883 sprintf(s, "&parameter name=\"%s\", ", argument[1]);
884 break;
885 default:
886 fprintf(stderr, "error: column or parameter must be specified for definition\n");
887 return (NULL);
888 }
889 SDDS_CopyString(&defi->name, argument[1]);
890
891 defi->name = argument[1];
892 defi->source = argument[2];
893
894 for (i = 3; i < arguments; i++) {
895 strcat(s, ", ");
896 strcat(s, argument[i]);
897 }
898 if (!strstr(s, ", type=")) {
899 strcat(s, " type=double, ");
900 }
901 strcat(s, " &end");
902 if (!SDDS_CopyString(&defi->text, s))
903 SDDS_Bomb("string copying failed (process_new_evaluate_definition)");
904 return (defi);
905}
906
907SCAN_DEFINITION *process_new_scan_definition(char **argument, long arguments) {
908 static char s[SDDS_MAXLINE];
909 char *ptr;
910 long i;
911 SCAN_DEFINITION *defi;
912
913 if (!(defi = tmalloc(sizeof(*defi))))
914 SDDS_Bomb("memory allocation failure (process_new_scan_definition)");
915 switch (match_string(argument[0], data_class_keyword, DATA_CLASS_KEYWORDS, 0)) {
916 case COLUMN_BASED:
917 defi->is_parameter = 0;
918 sprintf(s, "&column name=\"%s\", ", argument[1]);
919 break;
920 case PARAMETER_BASED:
921 defi->is_parameter = 1;
922 sprintf(s, "&parameter name=\"%s\", ", argument[1]);
923 break;
924 default:
925 fprintf(stderr, "error: column or parameter must be specified for scan\n");
926 return (NULL);
927 }
928 defi->new_name = argument[1];
929 defi->source = argument[2];
930 defi->sscanf_string = argument[3];
931 defi->edit = NULL;
932 for (i = 4; i < arguments; i++) {
933 if (!(ptr = strchr(argument[i], '=')))
934 return (NULL);
935 *ptr = 0;
936 if (strncasecmp(argument[i], "edit", strlen(argument[i])) == 0) {
937 /* pre-edit option */
938 SDDS_CopyString(&defi->edit, ptr + 1);
939 } else {
940 strcat(s, argument[i]);
941 strcat(s, "=\"");
942 strcat(s, ptr + 1);
943 strcat(s, "\", ");
944 }
945 }
946 if (!strstr(s, ", type="))
947 strcat(s, " type=\"double\", ");
948 strcat(s, "&end");
949 if (!SDDS_CopyString(&defi->text, s))
950 SDDS_Bomb("unable to copy text of scan definition (process_new_scan_definition)");
951 return (defi);
952}
953
954CAST_DEFINITION *process_new_cast_definition(char **argument, long arguments) {
955 CAST_DEFINITION *defi;
956
957 if (!(defi = tmalloc(sizeof(*defi))))
958 SDDS_Bomb("memory allocation failure (process_new_cast_definition)");
959 switch (match_string(argument[0], data_class_keyword, DATA_CLASS_KEYWORDS, 0)) {
960 case COLUMN_BASED:
961 defi->isParameter = 0;
962 break;
963 case PARAMETER_BASED:
964 defi->isParameter = 1;
965 break;
966 default:
967 fprintf(stderr, "error: column or parameter must be specified for cast\n");
968 return (NULL);
969 }
970 defi->newName = argument[1];
971 defi->source = argument[2];
972 defi->newTypeName = argument[3];
973 if (strcmp(defi->newName, defi->source) == 0) {
974 fprintf(stderr, "error: can't cast something to the same name (sddsprocess)\n");
975 return NULL;
976 }
977 return (defi);
978}
979
980long complete_cast_definition(SDDS_DATASET *SDDSout, CAST_DEFINITION *defi,
981 SDDS_DATASET *SDDSin) {
982 char s[1024];
983
984 if (!(defi->newType = SDDS_IdentifyType(defi->newTypeName))) {
985 sprintf(s, "Unable to cast parameter %s to unknown type %s from column %s",
986 defi->newName, defi->newTypeName, defi->source);
987 SDDS_SetError(s);
988 return 0;
989 }
990 if (defi->isParameter) {
991 if (!SDDS_TransferParameterDefinition(SDDSout, SDDSout,
992 defi->source, defi->newName) ||
993 !SDDS_ChangeParameterInformation(SDDSout, "type", &defi->newType,
994 SDDS_BY_NAME, defi->newName)) {
995 sprintf(s, "Unable to cast parameter %s to type %s from column %s",
996 defi->newName, defi->newTypeName, defi->source);
997 SDDS_SetError(s);
998 return 0;
999 }
1000 } else {
1001 if (!SDDS_TransferColumnDefinition(SDDSout, SDDSout,
1002 defi->source, defi->newName) ||
1003 !SDDS_ChangeColumnInformation(SDDSout, "type", &defi->newType,
1004 SDDS_BY_NAME, defi->newName)) {
1005 sprintf(s, "Unable to cast column %s to type %s from column %s",
1006 defi->newName, defi->newTypeName, defi->source);
1007 SDDS_SetError(s);
1008 return 0;
1009 }
1010 }
1011 return 1;
1012}
1013
1014NUMBERTEST_DEFINITION *process_new_numbertest_definition(char **argument, long arguments) {
1015 static char s[SDDS_MAXLINE];
1016 long i, j;
1017
1019#define NUMBERTEST_QUALIFIERS 2
1020 static char *numbertestQualifier[NUMBERTEST_QUALIFIERS] = {
1021 "invert",
1022 "strict",
1023 };
1024 static unsigned long numbertestFlag[NUMBERTEST_QUALIFIERS] = {
1025 NUMSCANFILTER_INVERT,
1026 NUMSCANFILTER_STRICT,
1027 };
1028
1029 if (!(defi = tmalloc(sizeof(*defi))))
1030 SDDS_Bomb("memory allocation failure (process_new_numbertest_definition)");
1031 switch (match_string(argument[0], data_class_keyword, DATA_CLASS_KEYWORDS, 0)) {
1032 case COLUMN_BASED:
1033 defi->is_parameter = 0;
1034 sprintf(s, "&column name=\"%s\", ", argument[1]);
1035 break;
1036 case PARAMETER_BASED:
1037 defi->is_parameter = 1;
1038 sprintf(s, "&parameter name=\"%s\", ", argument[1]);
1039 break;
1040 default:
1041 fprintf(stderr, "error: column or parameter must be specified for numbertest\n");
1042 return (NULL);
1043 }
1044 defi->name = argument[1];
1045 defi->flags = 0;
1046 for (i = 2; i < arguments; i++) {
1047 switch (j = match_string(argument[i], numbertestQualifier, NUMBERTEST_QUALIFIERS, 0)) {
1048 case -1:
1049 fprintf(stderr, "error: unknown qualifer to -numberTest: %s\n", argument[i]);
1050 exit(1);
1051 break;
1052 default:
1053 defi->flags |= numbertestFlag[j];
1054 break;
1055 }
1056 }
1057 return (defi);
1058}
1059
1060EDIT_DEFINITION *process_new_edit_definition(char **argument, long arguments, short reedit) {
1061 static char s[SDDS_MAXLINE];
1062 char *ptr;
1063 long i, offset, hasType;
1064 EDIT_DEFINITION *defi;
1065
1066 if (!(defi = tmalloc(sizeof(*defi))))
1067 SDDS_Bomb("memory allocation failure (process_new_edit_definition)");
1068 switch (match_string(argument[0], data_class_keyword, DATA_CLASS_KEYWORDS, 0)) {
1069 case COLUMN_BASED:
1070 defi->is_parameter = 0;
1071 sprintf(s, "&column name=\"%s\", ", argument[1]);
1072 break;
1073 case PARAMETER_BASED:
1074 defi->is_parameter = 1;
1075 sprintf(s, "&parameter name=\"%s\", ", argument[1]);
1076 break;
1077 default:
1078 fprintf(stderr, "error: column or parameter must be specified for edit\n");
1079 return (NULL);
1080 }
1081 defi->new_name = argument[1];
1082 if (!reedit) {
1083 defi->source = argument[2];
1084 defi->edit_command = argument[3];
1085 offset = 4;
1086 } else {
1087 defi->source = defi->new_name;
1088 defi->edit_command = argument[2];
1089 offset = 3;
1090 }
1091 if (arguments > offset) {
1092 defi->argv = tmalloc(sizeof(*defi->argv) * (arguments - offset));
1093 if (!SDDS_CopyStringArray(defi->argv, argument + offset, arguments - offset))
1094 SDDS_Bomb("string array copy failed (process_new_edit_definition)");
1095 defi->argc = arguments - offset;
1096 } else {
1097 defi->argc = 0;
1098 defi->argv = NULL;
1099 }
1100 hasType = 0;
1101 for (i = offset; i < arguments; i++) {
1102 if (!(ptr = strchr(argument[i], '=')))
1103 return (NULL);
1104 *ptr = 0;
1105 if (strcmp(argument[i], "type") == 0)
1106 hasType = 1;
1107 strcat(s, argument[i]);
1108 strcat(s, "=\"");
1109 strcat(s, ptr + 1);
1110 strcat(s, "\", ");
1111 }
1112 if (!hasType)
1113 strcat(s, " type=string &end");
1114 else
1115 strcat(s, " &end");
1116 if (!SDDS_CopyString(&defi->text, s))
1117 SDDS_Bomb("unable to copy text of edit definition (process_new_edit_definition)");
1118 return (defi);
1119}
1120
1121long edit_column_value(SDDS_DATASET *SDDS_dataset, char *target, char *source, char *edit_command) {
1122 char **source_value;
1123 long target_type, target_index, source_index;
1124 int64_t i, rows;
1125 static char s[SDDS_MAXLINE];
1126
1127 if ((source_index = SDDS_GetColumnIndex(SDDS_dataset, source)) < 0 ||
1128 (target_index = SDDS_GetColumnIndex(SDDS_dataset, target)) < 0) {
1129 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
1130 return (0);
1131 }
1132 if (SDDS_GetColumnType(SDDS_dataset, source_index) != SDDS_STRING) {
1133 fprintf(stderr, "error: source column %s has wrong type for editing--must be string\n", source);
1134 return (0);
1135 }
1136 if ((target_type = SDDS_GetColumnType(SDDS_dataset, target_index)) != SDDS_STRING &&
1137 target_type != SDDS_CHARACTER) {
1138 fprintf(stderr, "error: target column %s has wrong type for editing--must be string or character\n", target);
1139 return (0);
1140 }
1141
1142 if ((rows = SDDS_CountRowsOfInterest(SDDS_dataset)) < 0) {
1143 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
1144 return (0);
1145 }
1146
1147 if (!(source_value = SDDS_GetInternalColumn(SDDS_dataset, source))) {
1148 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
1149 return (0);
1150 }
1151
1152 for (i = 0; i < rows; i++) {
1153 if (!source_value[i])
1154 s[0] = 0;
1155 else
1156 strcpy(s, source_value[i]);
1157 if (!edit_string(s, edit_command)) {
1158 fprintf(stderr, "error: unable to edit source string \"%s\" to make %s\n", source_value[i], target);
1159 return (0);
1160 }
1161 if ((target_type == SDDS_STRING &&
1162 !SDDS_SetRowValues(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, i, target_index, s, -1)) ||
1163 (target_type == SDDS_CHARACTER &&
1164 !SDDS_SetRowValues(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, i, target_index, s[0], -1))) {
1165 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
1166 return (0);
1167 }
1168 /*
1169 if (source_value[i])
1170 free(source_value[i]);
1171 */
1172 }
1173 /*
1174 free(source_value);
1175 */
1176 return (1);
1177}
1178
1179long edit_parameter_value(SDDS_DATASET *SDDS_dataset, char *target, char *source, char *edit_command) {
1180 char *source_value, **ptr;
1181 long target_type, target_index, source_index;
1182 static char s[SDDS_MAXLINE];
1183
1184 if ((source_index = SDDS_GetParameterIndex(SDDS_dataset, source)) < 0 ||
1185 (target_index = SDDS_GetParameterIndex(SDDS_dataset, target)) < 0) {
1186 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
1187 return (0);
1188 }
1189 if (SDDS_GetParameterType(SDDS_dataset, source_index) != SDDS_STRING) {
1190 fprintf(stderr, "error: source parameter %s has wrong type for editing--must be string\n", source);
1191 return (0);
1192 }
1193 if ((target_type = SDDS_GetParameterType(SDDS_dataset, target_index)) != SDDS_STRING &&
1194 target_type != SDDS_CHARACTER) {
1195 fprintf(stderr, "error: target parameter %s has wrong type for editing--must be string or character\n", target);
1196 return (0);
1197 }
1198
1199 if (!(ptr = SDDS_GetParameter(SDDS_dataset, source, NULL))) {
1200 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
1201 return (0);
1202 }
1203 if (!(source_value = *ptr))
1204 s[0] = 0;
1205 else
1206 strcpy(s, source_value);
1207 if (!edit_string(s, edit_command)) {
1208 fprintf(stderr, "error: unable to edit source string \"%s\" to make %s\n", source_value, target);
1209 return (0);
1210 }
1211 if ((target_type == SDDS_STRING &&
1212 !SDDS_SetParameters(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, target_index, s, -1)) ||
1213 (target_type == SDDS_CHARACTER &&
1214 !SDDS_SetParameters(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, target_index, s[0], -1))) {
1215 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
1216 return (0);
1217 }
1218 if (source_value)
1219 free(source_value);
1220 free(ptr);
1221 return (1);
1222}
1223
1224OUTPUT_REQUEST *process_output_request(char **argument, long arguments, OUTPUT_REQUEST *last_request) {
1225 OUTPUT_REQUEST *request;
1226 request = tmalloc(sizeof(*request));
1227 switch (match_string(argument[0], data_class_keyword, DATA_CLASS_KEYWORDS, 0)) {
1228 case COLUMN_BASED:
1229 request->parameter_output = 0;
1230 break;
1231 case PARAMETER_BASED:
1232 request->parameter_output = 1;
1233 break;
1234 default:
1235 fprintf(stderr, "error: column or parameter must be specified for output\n");
1236 return (NULL);
1237 }
1238 argument++;
1239 arguments--;
1240
1241 request->fp = NULL;
1242 request->points = 0;
1243 request->counter = 0;
1244
1245 if (!(request->item[0] = determine_item_name(argument, last_request, 0)))
1246 return (NULL);
1247
1248 if (!(request->item[1] = determine_item_name(argument, last_request, 1)))
1249 return (NULL);
1250
1251 request->item[2] = request->item[3] = NULL;
1252 request->columns = 2;
1253
1254 if (arguments < 3)
1255 return (request);
1256
1257 request->columns = 3;
1258 if (!(request->item[2] = determine_item_name(argument, last_request, 2)))
1259 return (NULL);
1260
1261 if (arguments < 4)
1262 return (request);
1263
1264 request->columns = 4;
1265 if (!(request->item[3] = determine_item_name(argument, last_request, 3)))
1266 return (NULL);
1267
1268 return (request);
1269}
1270
1271char *determine_item_name(char **argument, OUTPUT_REQUEST *last_request, long index) {
1272 if (strcmp(argument[index], ".") == 0) {
1273 if (!last_request)
1274 return (NULL);
1275 return (last_request->item[index]);
1276 }
1277 return (argument[index]);
1278}
1279
1280void set_up_output(char *filename, OUTPUT_REQUEST *output, LABEL_PARAMETER *label_parameter, long label_parameters,
1281 long separate_pages, long announce_openings, SDDS_DATASET *SDDS_dataset) {
1282 COLUMN_DEFINITION **coldef;
1283 PARAMETER_DEFINITION **pardef, *pardefptr;
1284 long j;
1285 double param;
1286 char *mplTitle, *mplTopline;
1287
1288 output->fp = fopen_e(filename, "w", 0);
1289 if (announce_openings)
1290 fprintf(stderr, "file opened: %s\n", filename);
1291 if (!output->parameter_output) {
1292 coldef = (COLUMN_DEFINITION **)(output->definitions = tmalloc(sizeof(*coldef) * 4));
1293 coldef[0] = coldef[1] = coldef[2] = coldef[3] = NULL;
1294 if (!(coldef[0] = SDDS_GetColumnDefinition(SDDS_dataset, output->item[0])) ||
1295 !(coldef[1] = SDDS_GetColumnDefinition(SDDS_dataset, output->item[1])) ||
1296 (output->item[2] && !(coldef[2] = SDDS_GetColumnDefinition(SDDS_dataset, output->item[2]))) ||
1297 (output->item[3] && !(coldef[3] = SDDS_GetColumnDefinition(SDDS_dataset, output->item[3])))) {
1298 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
1299 exit(1);
1300 }
1301 fputs(coldef[0]->symbol ? coldef[0]->symbol : output->item[0], output->fp);
1302 if (coldef[0]->units && !is_blank(coldef[0]->units))
1303 fprintf(output->fp, " (%s)", coldef[0]->units);
1304 fprintf(output->fp, "\n%s", coldef[1]->symbol ? coldef[1]->symbol : output->item[1]);
1305 if (coldef[1]->units && !is_blank(coldef[1]->units))
1306 fprintf(output->fp, " (%s)", coldef[1]->units);
1307 if (label_parameters) {
1308 fputc('\n', output->fp);
1309 for (j = 0; j < label_parameters; j++) {
1310 if (!(pardefptr = SDDS_GetParameterDefinition(SDDS_dataset, label_parameter[j].name))) {
1311 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
1312 exit(1);
1313 }
1314 if (!SDDS_GetParameter(SDDS_dataset, label_parameter[j].name, &param)) {
1315 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
1316 exit(1);
1317 }
1318 fprintf(output->fp, "%s=", pardefptr->symbol ? pardefptr->symbol : label_parameter[j].name);
1319 SDDS_PrintTypedValue((void *)&param, 0, pardefptr->type,
1320 (label_parameter[j].format ? label_parameter[j].format : pardefptr->format_string), output->fp,
1321 0);
1322 if (pardefptr->units) {
1323 if (isdigit(pardefptr->units[0]))
1324 fputc(' ', output->fp);
1325 fprintf(output->fp, "%s%s", pardefptr->units, j == label_parameters - 1 ? "\n" : " ");
1326 } else
1327 fprintf(output->fp, "%s", j == label_parameters - 1 ? "\n" : " ");
1328 }
1329 } else {
1330 if (SDDS_GetParameterIndex(SDDS_dataset, "mplTitle") < 0)
1331 fprintf(output->fp, "\n%s vs %s\n",
1332 coldef[1]->description ? coldef[1]->description : (coldef[1]->symbol ? coldef[1]->symbol : output->item[1]),
1333 coldef[0]->description ? coldef[0]->description : (coldef[0]->symbol ? coldef[0]->symbol : output->item[0]));
1334 else {
1335 if (!SDDS_GetParameter(SDDS_dataset, "mplTitle", &mplTitle)) {
1336 SDDS_SetError("Unable to get value of parameter mplTitle");
1337 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
1338 }
1339 fprintf(output->fp, "\n%s\n", mplTitle);
1340 free(mplTitle);
1341 }
1342 }
1343 } else {
1344 pardef = (PARAMETER_DEFINITION **)(output->definitions = tmalloc(sizeof(*pardef) * 4));
1345 pardef[0] = pardef[1] = pardef[2] = pardef[3] = NULL;
1346 if (!(pardef[0] = SDDS_GetParameterDefinition(SDDS_dataset, output->item[0])) ||
1347 !(pardef[1] = SDDS_GetParameterDefinition(SDDS_dataset, output->item[1])) ||
1348 (output->item[2] && !(pardef[2] = SDDS_GetParameterDefinition(SDDS_dataset, output->item[2]))) ||
1349 (output->item[3] && !(pardef[3] = SDDS_GetParameterDefinition(SDDS_dataset, output->item[3])))) {
1350 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
1351 exit(1);
1352 }
1353 fputs(pardef[0]->symbol ? pardef[0]->symbol : output->item[0], output->fp);
1354 if (pardef[0]->units && !is_blank(pardef[0]->units))
1355 fprintf(output->fp, " (%s)", pardef[0]->units);
1356 fprintf(output->fp, "\n%s", pardef[1]->symbol ? pardef[1]->symbol : output->item[1]);
1357 if (pardef[1]->units && !is_blank(pardef[1]->units))
1358 fprintf(output->fp, " (%s)", pardef[1]->units);
1359 if (label_parameters) {
1360 fputc('\n', output->fp);
1361 for (j = 0; j < label_parameters; j++) {
1362 if (!(pardefptr = SDDS_GetParameterDefinition(SDDS_dataset, label_parameter[j].name))) {
1363 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
1364 exit(1);
1365 }
1366 if (!SDDS_GetParameter(SDDS_dataset, label_parameter[j].name, &param)) {
1367 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
1368 exit(1);
1369 }
1370 fprintf(output->fp, "%s=", pardefptr->symbol ? pardefptr->symbol : label_parameter[j].name);
1371 SDDS_PrintTypedValue((void *)&param, 0, pardefptr->type,
1372 (label_parameter[j].format ? label_parameter[j].format : pardefptr->format_string), output->fp,
1373 0);
1374 if (pardefptr->units) {
1375 if (isdigit(pardefptr->units[0]))
1376 fputc(' ', output->fp);
1377 fprintf(output->fp, "%s%s", pardefptr->units, j == label_parameters - 1 ? "\n" : " ");
1378 } else
1379 fprintf(output->fp, "%s", j == label_parameters - 1 ? "\n" : " ");
1380 }
1381 } else {
1382 if (SDDS_GetParameterIndex(SDDS_dataset, "mplTitle") < 0)
1383 fprintf(output->fp, "\n%s vs %s\n",
1384 pardef[1]->description ? pardef[1]->description : (pardef[1]->symbol ? pardef[1]->symbol : output->item[1]),
1385 pardef[0]->description ? pardef[0]->description : (pardef[0]->symbol ? pardef[0]->symbol : output->item[0]));
1386 else {
1387 if (!SDDS_GetParameter(SDDS_dataset, "mplTitle", &mplTitle)) {
1388 SDDS_SetError("Unable to get value of parameter mplTitle");
1389 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
1390 }
1391 fprintf(output->fp, "\n%s\n", mplTitle);
1392 free(mplTitle);
1393 }
1394 }
1395 }
1396 if (SDDS_GetParameterIndex(SDDS_dataset, "mplTopline") < 0) {
1397 fprintf(output->fp, "Data extracted from SDDS file %s", SDDS_dataset->layout.filename);
1398 if (separate_pages)
1399 fprintf(output->fp, ", page %" PRId32, SDDS_dataset->page_number);
1400 } else {
1401 if (!SDDS_GetParameter(SDDS_dataset, "mplTopline", &mplTopline)) {
1402 SDDS_SetError("Unable to get value of parameter mplTopline");
1403 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
1404 }
1405 fprintf(output->fp, "%s", mplTopline);
1406 free(mplTopline);
1407 }
1408 fprintf(output->fp, "\n%-10" PRId64 "\n", SDDS_dataset->n_rows);
1409}
1410
1411#define DEBUG 0
1412
1413long process_column(SDDS_DATASET *Dataset, PROCESSING_DEFINITION *processing_ptr,
1414 double *result, char **stringResult, long warnings, int threads) {
1415 double *data, *indepData, *weightData;
1416 long i1, i2 = 0, i2save, mode;
1417 int64_t imin, imax;
1418 int64_t i, n_data, count;
1419 double min, max, top, base, point1, point2;
1420 double slope, intercept, variance;
1421 long returnValue, matchfound;
1422 char **stringData, **matchData;
1423 short *keep;
1424 double quartilePoint[2] = {25.0, 75.0}, quartileResult[2];
1425 double decilePoint[2] = {10.0, 90.0}, decileResult[2];
1426 double percentilePoint[2], percentileResult[2];
1427 char temp_str[256];
1428
1429 i1 = i2save = 0;
1430 matchfound = 0;
1431 mode = processing_ptr->mode;
1432#if DEBUG
1433 fprintf(stderr, "process_column: column=%s, mode=%s\n", processing_ptr->column_name,
1434 process_column_data[mode].name);
1435#endif
1436
1437 *stringResult = NULL;
1438 if ((n_data = SDDS_CountRowsOfInterest(Dataset)) <= 0) {
1439 if (mode != PROCESS_COLUMN_COUNT)
1440 *result = processing_ptr->defaultValue;
1441 else
1442 *result = n_data;
1443 return 1;
1444 }
1445 if (processing_ptr->lower_par && !SDDS_GetParameterAsDouble(Dataset, processing_ptr->lower_par,
1446 &processing_ptr->lowerLimit))
1447 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1448 if (processing_ptr->upper_par && !SDDS_GetParameterAsDouble(Dataset, processing_ptr->upper_par,
1449 &processing_ptr->upperLimit))
1450 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1451
1452 if (processing_ptr->head_par && !SDDS_GetParameterAsLong(Dataset, processing_ptr->head_par,
1453 &processing_ptr->head))
1454 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1455 if (processing_ptr->tail_par && !SDDS_GetParameterAsLong(Dataset, processing_ptr->tail_par,
1456 &processing_ptr->tail))
1457 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1458 if (processing_ptr->fhead_par && !SDDS_GetParameterAsDouble(Dataset, processing_ptr->fhead_par,
1459 &processing_ptr->fhead))
1460 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1461 if (processing_ptr->ftail_par && !SDDS_GetParameterAsDouble(Dataset, processing_ptr->ftail_par,
1462 &processing_ptr->ftail))
1463 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1464 if (processing_ptr->offset_par) {
1465 if (wild_match(processing_ptr->offset_par, "%s*")) {
1466 sprintf(temp_str, processing_ptr->offset_par, processing_ptr->column_name);
1467 if (!SDDS_GetParameterAsDouble(Dataset, temp_str,
1468 &processing_ptr->offset))
1469 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1470 } else if (!SDDS_GetParameterAsDouble(Dataset, processing_ptr->offset_par,
1471 &processing_ptr->offset))
1472 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1473 }
1474 if (processing_ptr->factor_par) {
1475 if (wild_match(processing_ptr->factor_par, "%s*")) {
1476 sprintf(temp_str, processing_ptr->factor_par, processing_ptr->column_name);
1477 if (!SDDS_GetParameterAsDouble(Dataset, temp_str,
1478 &processing_ptr->factor))
1479 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1480 } else if (!SDDS_GetParameterAsDouble(Dataset, processing_ptr->factor_par,
1481 &processing_ptr->factor))
1482 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1483 }
1484 if ((processing_ptr->flags & PROCESSING_INVERT_OFFSET) && (processing_ptr->flags & PROCESSING_OFFSET_GIVEN))
1485 processing_ptr->offset *=-1;
1486 if ((processing_ptr->flags & PROCESSING_FACTOR_GIVEN) && (processing_ptr->flags & PROCESSING_INVERT_FACTOR))
1487 processing_ptr->factor = 1/processing_ptr->factor;
1488
1489 if (!(data = SDDS_GetColumnInDoubles(Dataset, processing_ptr->column_name)))
1490 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1491 indepData = weightData = NULL;
1492 stringData = matchData = NULL;
1493
1494 if (processing_ptr->weightBy && !(weightData = SDDS_GetColumnInDoubles(Dataset, processing_ptr->weightBy)))
1495 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1496 if (processing_ptr->functionOf &&
1497 processing_ptr->outputType != SDDS_STRING &&
1498 !(indepData = SDDS_GetColumnInDoubles(Dataset, processing_ptr->functionOf)))
1499 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1500 if (processing_ptr->functionOf &&
1501 processing_ptr->outputType == SDDS_STRING &&
1502 !(stringData = SDDS_GetColumn(Dataset, processing_ptr->functionOf)))
1503 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1504
1505 keep = NULL;
1506 if (processing_ptr->flags & (PROCESSING_LOLIM_GIVEN | PROCESSING_UPLIM_GIVEN | PROCESSING_TAIL_GIVEN | PROCESSING_HEAD_GIVEN | PROCESSING_FTAIL_GIVEN | PROCESSING_FHEAD_GIVEN | PROCESSING_MATCHCOLUMN_GIVEN | PROCESSING_TOPLIM_GIVEN | PROCESSING_BOTLIM_GIVEN)) {
1507 keep = tmalloc(sizeof(*keep) * n_data);
1508 for (i = 0; i < n_data; i++)
1509 keep[i] = 1;
1510 }
1511 if (processing_ptr->flags & PROCESSING_MATCHCOLUMN_GIVEN) {
1512 if (!(matchData = SDDS_GetColumn(Dataset, processing_ptr->match_column)))
1513 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1514 for (i = 0; i < n_data; i++)
1515 keep[i] = 0;
1516 for (i = 0; i < n_data; i++) {
1517 if (wild_match(matchData[i], processing_ptr->match_value)) {
1518 matchfound = 1;
1519 keep[i] = 1;
1520 }
1521 }
1522 for (i = 0; i < n_data; i++)
1523 free(matchData[i]);
1524 free(matchData);
1525 if (!matchfound) {
1526 if (warnings)
1527 fprintf(stderr, "Warning: no values in column %s match %s.\n",
1528 processing_ptr->match_column, processing_ptr->match_value);
1529 free(keep);
1530 free(data);
1531 *result = processing_ptr->defaultValue;
1532 return 1;
1533 }
1534 }
1535 if (processing_ptr->flags & PROCESSING_LOLIM_GIVEN && indepData) {
1536#if DEBUG
1537 fprintf(stderr, "lower limit processing: value %e\n", processing_ptr->lowerLimit);
1538#endif
1539 for (i = 0; i < n_data; i++)
1540 if (processing_ptr->lowerLimit > indepData[i])
1541 keep[i] = 0;
1542 }
1543
1544 if (processing_ptr->flags & PROCESSING_UPLIM_GIVEN && indepData) {
1545#if DEBUG
1546 fprintf(stderr, "upper limit processing: value %e\n", processing_ptr->upperLimit);
1547#endif
1548 for (i = 0; i < n_data; i++) {
1549 if (processing_ptr->upperLimit < indepData[i])
1550 keep[i] = 0;
1551 if (isinf(indepData[i]) || isnan(indepData[i]))
1552 keep[i] = 0;
1553 }
1554 }
1555
1556 if (processing_ptr->flags & PROCESSING_TOPLIM_GIVEN) {
1557 for (i = 0; i < n_data; i++) {
1558 if (processing_ptr->topLimit < data[i])
1559 keep[i] = 0;
1560 if (isinf(data[i]) || isnan(data[i]))
1561 keep[i] = 0;
1562 }
1563 }
1564
1565 if (processing_ptr->flags & PROCESSING_BOTLIM_GIVEN) {
1566 for (i = 0; i < n_data; i++)
1567 if (processing_ptr->bottomLimit > data[i])
1568 keep[i] = 0;
1569 }
1570
1571 if (processing_ptr->flags & PROCESSING_HEAD_GIVEN) {
1572 count = 0;
1573#if DEBUG
1574 fprintf(stderr, "head processing: %ld points\n", processing_ptr->head);
1575#endif
1576 if (processing_ptr->head > 0) {
1577 /* keep first head points */
1578 for (i = 0; i < n_data && count < processing_ptr->head; i++)
1579 if (keep[i])
1580 count++;
1581 for (; i < n_data; i++)
1582 keep[i] = 0;
1583 } else {
1584 /* kill first -head points */
1585 for (i = 0; i < n_data && count < -processing_ptr->head; i++)
1586 if (keep[i]) {
1587 count++;
1588 keep[i] = 0;
1589 }
1590 }
1591 }
1592
1593 if (processing_ptr->flags & PROCESSING_FHEAD_GIVEN) {
1594 long head;
1595 count = 0;
1596 head = fabs(n_data * processing_ptr->fhead + 0.5);
1597 if (processing_ptr->fhead > 0) {
1598 for (i = 0; i < n_data && count < head; i++)
1599 if (keep[i])
1600 count++;
1601 for (; i < n_data; i++)
1602 keep[i] = 0;
1603 } else
1604 for (i = 0; i < n_data && count < head; i++)
1605 if (keep[i]) {
1606 count++;
1607 keep[i] = 0;
1608 }
1609 }
1610
1611 if (processing_ptr->flags & PROCESSING_TAIL_GIVEN) {
1612 count = 0;
1613#if DEBUG
1614 fprintf(stderr, "tail processing: %ld points\n", processing_ptr->tail);
1615#endif
1616 if (processing_ptr->tail > 0) {
1617 for (i = n_data - 1; i >= 0 && count < processing_ptr->tail; i--)
1618 if (keep[i])
1619 count++;
1620 for (; i >= 0; i--)
1621 keep[i] = 0;
1622 } else
1623 for (i = n_data - 1; i >= 0 && count < -processing_ptr->tail; i--)
1624 if (keep[i]) {
1625 count++;
1626 keep[i] = 0;
1627 }
1628 }
1629
1630 if (processing_ptr->flags & PROCESSING_FTAIL_GIVEN) {
1631 long tail;
1632 count = 0;
1633 tail = fabs(processing_ptr->ftail * n_data + 0.5);
1634 if (processing_ptr->ftail > 0) {
1635 for (i = n_data - 1; i >= 0 && count < tail; i--)
1636 if (keep[i])
1637 count++;
1638 for (; i >= 0; i--)
1639 keep[i] = 0;
1640 } else
1641 for (i = n_data - 1; i >= 0 && count < tail; i--)
1642 if (keep[i]) {
1643 count++;
1644 keep[i] = 0;
1645 }
1646 }
1647
1648 if (keep) {
1649 int64_t j;
1650 for (i = j = 0; i < n_data; i++) {
1651 if (keep[i]) {
1652 if (i != j) {
1653 data[j] = data[i];
1654 if (indepData)
1655 indepData[j] = indepData[i];
1656 if (stringData) {
1657 free(stringData[j]);
1658 stringData[j] = stringData[i];
1659 stringData[i] = NULL;
1660 }
1661 if (weightData)
1662 weightData[j] = weightData[i];
1663 }
1664 j++;
1665 }
1666 }
1667 n_data = j;
1668#if DEBUG
1669 fprintf(stderr, "%" PRId64 " points kept\n", n_data);
1670#endif
1671 }
1672 if (n_data == 0) {
1673 free(data);
1674 if (indepData)
1675 free(indepData);
1676 if (weightData)
1677 free(weightData);
1678 if (keep)
1679 free(keep);
1680 if (warnings)
1681 fprintf(stderr, "warning: no matches found");
1682 if (mode != PROCESS_COLUMN_COUNT) {
1683 *result = processing_ptr->defaultValue;
1684 *stringResult = NULL;
1685 return 1;
1686 } else {
1687 *result = 0;
1688 *stringResult = NULL;
1689 return 1;
1690 }
1691 }
1692
1693 if (processing_ptr->flags & PROCESSING_OFFSET_GIVEN) {
1694#if DEBUG
1695 fprintf(stderr, "offsetting by %f\n", processing_ptr->offset);
1696#endif
1697 for (i = 0; i < n_data; i++)
1698 data[i] += processing_ptr->offset;
1699 }
1700
1701 if (processing_ptr->flags & PROCESSING_FACTOR_GIVEN) {
1702#if DEBUG
1703 fprintf(stderr, "multiplying by %f\n", processing_ptr->factor);
1704#endif
1705 for (i = 0; i < n_data; i++)
1706 data[i] *= processing_ptr->factor;
1707 }
1708
1709#if DEBUG
1710 fprintf(stderr, "data points:\n");
1711 for (i = 0; i < n_data; i++)
1712 fprintf(stderr, "%e%c", data[i], (i + 1) % 8 == 0 ? '\n' : ' ');
1713 fputc('\n', stderr);
1714#endif
1715
1716 *result = 0;
1717 returnValue = 1;
1718 switch (mode) {
1719 case PROCESS_COLUMN_ZEROCROSSING:
1720 for (i = 0; i < n_data - 1; i++) {
1721 if (data[i] == 0)
1722 break;
1723 if ((data[i] < 0 && data[i + 1] >= 0) || (data[i] > 0 && data[i + 1] <= 0))
1724 break;
1725 }
1726 if (i != n_data - 1) {
1727 if (indepData) {
1728 if (data[i] == 0)
1729 *result = indepData[i];
1730 else
1731 *result = indepData[i] + (indepData[i + 1] - indepData[i]) / (data[i + 1] - data[i]) * (-data[i]);
1732 }
1733 if (stringData) {
1734 *stringResult = stringData[i];
1735 stringData[i] = NULL;
1736 }
1737 } else
1738 returnValue = 0;
1739 break;
1740 case PROCESS_COLUMN_MEAN:
1741 if (weightData)
1742 *result = weightedAverageThreaded(data, weightData, n_data, threads);
1743 else
1744 *result = arithmeticAverageThreaded(data, n_data, threads);
1745 break;
1746 case PROCESS_COLUMN_RMS:
1747 if (weightData)
1748 *result = weightedRMSThreaded(data, weightData, n_data, threads);
1749 else
1750 *result = rmsValueThreaded(data, n_data, threads);
1751 break;
1752 case PROCESS_COLUMN_SUM:
1753 if (weightData) {
1754 double sum;
1755 for (i = sum = 0; i < n_data; i++)
1756 sum += data[i] * weightData[i];
1757 *result = sum;
1758 } else
1759 *result = arithmeticAverageThreaded(data, n_data, threads) * n_data;
1760 break;
1761 case PROCESS_COLUMN_PRODUCT:
1762 if (weightData) {
1763 double product = 1;
1764 for (i = 0; i < n_data; i++)
1765 product *= data[i] * weightData[i];
1766 *result = product;
1767 } else {
1768 double product = 1;
1769 for (i = 0; i < n_data; i++)
1770 product *= data[i];
1771 *result = product;
1772 }
1773 break;
1774 case PROCESS_COLUMN_STAND_DEV:
1775 if (weightData)
1776 *result = weightedStDevThreaded(data, weightData, n_data, threads);
1777 else
1778 *result = standardDeviationThreaded(data, n_data, threads);
1779 break;
1780 case PROCESS_COLUMN_SIGMA:
1781 if (weightData)
1782 *result = weightedStDevThreaded(data, weightData, n_data, threads);
1783 else
1784 *result = standardDeviationThreaded(data, n_data, threads);
1785 *result /= sqrt(1.0 * n_data);
1786 break;
1787 case PROCESS_COLUMN_MAD:
1788 if (weightData)
1789 *result = weightedMADThreaded(data, weightData, n_data, threads);
1790 else
1791 *result = meanAbsoluteDeviationThreaded(data, n_data, threads);
1792 break;
1793 case PROCESS_COLUMN_SIGNEDSMALLEST:
1794 imin = 0;
1795 for (i = 1; i < n_data; i++)
1796 if (fabs(data[imin]) > fabs(data[i]))
1797 imin = i;
1798 *result = data[imin];
1799 if (processing_ptr->flags & PROCESSING_POSITION_GIVEN) {
1800 if (indepData)
1801 *result = indepData[imin];
1802 if (stringData) {
1803 *stringResult = stringData[imin];
1804 stringData[imin] = NULL;
1805 }
1806 }
1807 break;
1808 case PROCESS_COLUMN_SIGNEDLARGEST:
1809 imax = 0;
1810 for (i = 1; i < n_data; i++)
1811 if (fabs(data[imax]) < fabs(data[i]))
1812 imax = i;
1813 *result = data[imax];
1814 if (processing_ptr->flags & PROCESSING_POSITION_GIVEN) {
1815 if (indepData)
1816 *result = indepData[imax];
1817 if (stringData) {
1818 *stringResult = stringData[imax];
1819 stringData[imax] = NULL;
1820 }
1821 }
1822 break;
1823 case PROCESS_COLUMN_SMALLEST:
1824 case PROCESS_COLUMN_LARGEST:
1825 for (i = 0; i < n_data; i++)
1826 data[i] = fabs(data[i]);
1827 if (!index_min_max(&imin, &imax, data, n_data))
1828 returnValue = 0;
1829 else {
1830 switch (mode) {
1831 case PROCESS_COLUMN_SMALLEST:
1832 *result = data[i1 = imin];
1833 break;
1834 case PROCESS_COLUMN_LARGEST:
1835 *result = data[i1 = imax];
1836 break;
1837 }
1838 if (processing_ptr->flags & PROCESSING_POSITION_GIVEN) {
1839 if (indepData)
1840 *result = indepData[i1];
1841 if (stringData) {
1842 *stringResult = stringData[i1];
1843 stringData[i1] = NULL;
1844 }
1845 }
1846 }
1847 break;
1848 case PROCESS_COLUMN_MINIMUM:
1849 case PROCESS_COLUMN_MAXIMUM:
1850 case PROCESS_COLUMN_SPREAD:
1851 if (!index_min_max(&imin, &imax, data, n_data))
1852 returnValue = 0;
1853 else {
1854 min = data[imin];
1855 max = data[imax];
1856 switch (mode) {
1857 case PROCESS_COLUMN_MINIMUM:
1858 i1 = imin;
1859 *result = min;
1860 break;
1861 case PROCESS_COLUMN_MAXIMUM:
1862 i1 = imax;
1863 *result = max;
1864 break;
1865 case PROCESS_COLUMN_SMALLEST:
1866 if (fabs(min) < fabs(max)) {
1867 i1 = imin;
1868 *result = fabs(min);
1869 } else {
1870 i1 = imax;
1871 *result = fabs(max);
1872 }
1873 break;
1874 case PROCESS_COLUMN_LARGEST:
1875 if (fabs(min) > fabs(max)) {
1876 i1 = imin;
1877 *result = fabs(min);
1878 } else {
1879 i1 = imax;
1880 *result = fabs(max);
1881 }
1882 break;
1883 case PROCESS_COLUMN_SPREAD:
1884 *result = max - min;
1885 break;
1886 }
1887 if (processing_ptr->flags & PROCESSING_POSITION_GIVEN) {
1888 if (indepData)
1889 *result = indepData[i1];
1890 if (stringData) {
1891 *stringResult = stringData[i1];
1892 stringData[i1] = NULL;
1893 }
1894 }
1895 }
1896 break;
1897 case PROCESS_COLUMN_FIRST:
1898 *result = data[0];
1899 break;
1900 case PROCESS_COLUMN_LAST:
1901 *result = data[n_data - 1];
1902 break;
1903 case PROCESS_COLUMN_COUNT:
1904 *result = n_data;
1905 break;
1906 case PROCESS_COLUMN_MEDIAN:
1907 if (compute_median(result, data, n_data) <= 0)
1908 returnValue = 0;
1909 break;
1910 case PROCESS_COLUMN_MODE:
1911 if (processing_ptr->flags & PROCESSING_BINSIZE_GIVEN) {
1912 if (computeMode(result, data, n_data, processing_ptr->binSize, 0) <= 0)
1913 returnValue = 0;
1914 } else if (computeMode(result, data, n_data, 0, 100) <= 0)
1915 returnValue = 0;
1916 break;
1917 case PROCESS_COLUMN_BASELEVEL:
1918 case PROCESS_COLUMN_TOPLEVEL:
1919 case PROCESS_COLUMN_AMPLITUDE:
1920 case PROCESS_COLUMN_RISETIME:
1921 case PROCESS_COLUMN_FALLTIME:
1922 case PROCESS_COLUMN_FWHA:
1923 case PROCESS_COLUMN_FWTA:
1924 case PROCESS_COLUMN_CENTER:
1925 case PROCESS_COLUMN_FWHM:
1926 case PROCESS_COLUMN_FWTM:
1927 if (!findTopBaseLevels(&top, &base, data, n_data, 50, 2.0) ||
1928 !index_min_max(&imin, &imax, data, n_data))
1929 returnValue = 0;
1930 else {
1931 if ((top - base) < 0.75 * (data[imax] - base))
1932 top = data[imax];
1933 switch (mode) {
1934 case PROCESS_COLUMN_BASELEVEL:
1935 *result = base;
1936 break;
1937 case PROCESS_COLUMN_TOPLEVEL:
1938 *result = top;
1939 break;
1940 case PROCESS_COLUMN_AMPLITUDE:
1941 *result = top - base;
1942 break;
1943 case PROCESS_COLUMN_RISETIME:
1944 if ((i1 = findCrossingPoint(0, data, n_data, base + (top - base) * 0.1, 1, indepData, &point1)) < 0 ||
1945 (i2 = findCrossingPoint(i1, data, n_data, base + (top - base) * 0.9, 1, indepData, &point2)) < 0)
1946 returnValue = 0;
1947 else
1948 *result = point2 - point1;
1949 break;
1950 case PROCESS_COLUMN_FALLTIME:
1951 if ((i1 = findCrossingPoint(0, data, n_data, base + (top - base) * 0.9, -1, indepData, &point1)) < 0 ||
1952 (i2 = findCrossingPoint(i1, data, n_data, base + (top - base) * 0.1, -1, indepData, &point2)) < 0)
1953 returnValue = 0;
1954 else
1955 *result = point2 - point1;
1956 break;
1957 case PROCESS_COLUMN_FWHA:
1958 if ((i1 = findCrossingPoint(0, data, n_data, base + (top - base) * 0.5, 1, indepData, &point1)) < 0 ||
1959 (i2 = i2save = findCrossingPoint(i1, data, n_data, base + (top - base) * 0.9, -1, NULL, NULL)) < 0 ||
1960 (i2 = findCrossingPoint(i2, data, n_data, base + (top - base) * 0.5, -1, indepData, &point2)) < 0) {
1961 if (warnings) {
1962 fprintf(stderr, "warning: couldn't find crossing point for FWHA of %s\n",
1963 processing_ptr->column_name);
1964 fprintf(stderr, "top, base = %e, %e min, max = %e, %e\n", top, base,
1965 data[imin], data[imax]);
1966 if (i1 > 0)
1967 fprintf(stderr, "#1: %ld, (%e, %e)\n",
1968 i1, indepData[i1], data[i1]);
1969 if (i2save > 0)
1970 fprintf(stderr, "#2: %ld, (%e, %e)\n",
1971 i2save, indepData[i2save], data[i2save]);
1972 if (i2 > 0)
1973 fprintf(stderr, "#2a: %ld, (%e, %e)\n",
1974 i2, indepData[i2], data[i2]);
1975 }
1976 if ((i1 = findCrossingPoint(0, data, n_data, base + (top - base) * 0.5, 1, indepData, &point1)) < 0 ||
1977 (i2 = i2save = findCrossingPoint(i1, data, n_data, base + (top - base) * 0.9, 1, NULL, NULL)) < 0 ||
1978 (i2 = findCrossingPoint(i2, data, n_data, base + (top - base) * 0.5, -1, indepData, &point2)) < 0) {
1979 returnValue = 0;
1980 } else {
1981 *result = point2 - point1;
1982 }
1983 } else
1984 *result = point2 - point1;
1985 break;
1986 case PROCESS_COLUMN_FWTA:
1987 if ((i1 = findCrossingPoint(0, data, n_data, base + (top - base) * 0.1, 1, indepData, &point1)) < 0 ||
1988 (i2 = findCrossingPoint(i1, data, n_data, base + (top - base) * 0.9, -1, NULL, NULL)) < 0 ||
1989 (i2 = findCrossingPoint(i2, data, n_data, base + (top - base) * 0.1, -1, indepData, &point2)) < 0) {
1990 if ((i1 = findCrossingPoint(0, data, n_data, base + (top - base) * 0.1, 1, indepData, &point1)) < 0 ||
1991 (i2 = findCrossingPoint(i1, data, n_data, base + (top - base) * 0.9, 1, NULL, NULL)) < 0 ||
1992 (i2 = findCrossingPoint(i2, data, n_data, base + (top - base) * 0.1, -1, indepData, &point2)) < 0) {
1993 returnValue = 0;
1994 } else {
1995 *result = point2 - point1;
1996 }
1997 } else
1998 *result = point2 - point1;
1999 break;
2000 case PROCESS_COLUMN_FWHM:
2001 if ((i1 = findCrossingPoint(0, data, n_data, top * 0.5, 1, indepData, &point1)) < 0 ||
2002 (i2 = i2save = findCrossingPoint(i1, data, n_data, top * 0.9, -1, NULL, NULL)) < 0 ||
2003 (i2 = findCrossingPoint(i2, data, n_data, top * 0.5, -1, indepData, &point2)) < 0) {
2004 if (warnings) {
2005 fprintf(stderr, "warning: couldn't find crossing point for FWHM of %s\n",
2006 processing_ptr->column_name);
2007 fprintf(stderr, "top, base = %e, %e\n", top, base);
2008 if (i1 > 0)
2009 fprintf(stderr, "#1: %ld, (%e, %e)\n",
2010 i1, indepData[i1], data[i1]);
2011 if (i2save > 0)
2012 fprintf(stderr, "#2: %ld, (%e, %e)\n",
2013 i2save, indepData[i2save], data[i2save]);
2014 }
2015 if ((i1 = findCrossingPoint(0, data, n_data, top * 0.5, 1, indepData, &point1)) < 0 ||
2016 (i2 = i2save = findCrossingPoint(i1, data, n_data, top * 0.9, 1, NULL, NULL)) < 0 ||
2017 (i2 = findCrossingPoint(i2, data, n_data, top * 0.5, -1, indepData, &point2)) < 0) {
2018 returnValue = 0;
2019 } else {
2020 *result = point2 - point1;
2021 }
2022 } else
2023 *result = point2 - point1;
2024 break;
2025 case PROCESS_COLUMN_FWTM:
2026 if ((i1 = findCrossingPoint(0, data, n_data, top * 0.1, 1, indepData, &point1)) < 0 ||
2027 (i2 = findCrossingPoint(i1, data, n_data, top * 0.9, -1, NULL, NULL)) < 0 ||
2028 (i2 = findCrossingPoint(i2, data, n_data, top * 0.1, -1, indepData, &point2)) < 0) {
2029 if ((i1 = findCrossingPoint(0, data, n_data, top * 0.1, 1, indepData, &point1)) < 0 ||
2030 (i2 = findCrossingPoint(i1, data, n_data, top * 0.9, 1, NULL, NULL)) < 0 ||
2031 (i2 = findCrossingPoint(i2, data, n_data, top * 0.1, -1, indepData, &point2)) < 0) {
2032 returnValue = 0;
2033 } else {
2034 *result = point2 - point1;
2035 }
2036 } else
2037 *result = point2 - point1;
2038 break;
2039 case PROCESS_COLUMN_CENTER:
2040 if ((i1 = findCrossingPoint(0, data, n_data, base + (top - base) * 0.5, 1, indepData, &point1)) < 0 ||
2041 (i2 = findCrossingPoint(i1, data, n_data, base + (top - base) * 0.9, -1, NULL, NULL)) < 0 ||
2042 (i2 = findCrossingPoint(i2, data, n_data, base + (top - base) * 0.5, -1, indepData, &point2)) < 0) {
2043 if ((i1 = findCrossingPoint(0, data, n_data, base + (top - base) * 0.5, 1, indepData, &point1)) < 0 ||
2044 (i2 = findCrossingPoint(i1, data, n_data, base + (top - base) * 0.9, 1, NULL, NULL)) < 0 ||
2045 (i2 = findCrossingPoint(i2, data, n_data, base + (top - base) * 0.5, -1, indepData, &point2)) < 0) {
2046 returnValue = 0;
2047 } else {
2048 *result = (point1 + point2) / 2;
2049 }
2050 } else
2051 *result = (point1 + point2) / 2;
2052 break;
2053 }
2054 }
2055 break;
2056 case PROCESS_COLUMN_SLOPE:
2057 case PROCESS_COLUMN_INTERCEPT:
2058 case PROCESS_COLUMN_LFSD:
2059 if (!unweightedLinearFit(indepData, data, n_data, &slope, &intercept, &variance))
2060 returnValue = 0;
2061 else
2062 switch (mode) {
2063 case PROCESS_COLUMN_SLOPE:
2064 *result = slope;
2065 break;
2066 case PROCESS_COLUMN_INTERCEPT:
2067 *result = intercept;
2068 break;
2069 case PROCESS_COLUMN_LFSD:
2070 *result = sqrt(variance);
2071 break;
2072 }
2073 break;
2074 case PROCESS_COLUMN_INTEGRAL:
2075 trapazoidIntegration(indepData, data, n_data, result);
2076 break;
2077 case PROCESS_COLUMN_GMINTEGRAL:
2078 GillMillerIntegration1(indepData, data, n_data, result);
2079 break;
2080 case PROCESS_COLUMN_QRANGE:
2081 if (!compute_percentiles(quartileResult, quartilePoint, 2, data, n_data))
2082 returnValue = 0;
2083 else
2084 *result = quartileResult[1] - quartileResult[0];
2085 break;
2086 case PROCESS_COLUMN_DRANGE:
2087 if (!compute_percentiles(decileResult, decilePoint, 2, data, n_data))
2088 returnValue = 0;
2089 else
2090 *result = decileResult[1] - decileResult[0];
2091 break;
2092 case PROCESS_COLUMN_PERCENTILE:
2093 if (!compute_percentiles(percentileResult, &processing_ptr->percentileLevel, 1, data, n_data))
2094 returnValue = 0;
2095 else {
2096 *result = percentileResult[0];
2097 returnValue = 1;
2098 }
2099 break;
2100 case PROCESS_COLUMN_PRANGE:
2101 percentilePoint[1] = 50 + processing_ptr->percentileLevel / 2.0;
2102 percentilePoint[0] = 50 - processing_ptr->percentileLevel / 2.0;
2103 if (!compute_percentiles(percentileResult, percentilePoint, 2, data, n_data))
2104 returnValue = 0;
2105 else {
2106 *result = percentileResult[1] - percentileResult[0];
2107 returnValue = 1;
2108 }
2109 break;
2110 case PROCESS_COLUMN_CORRELATION:
2111 *result = linearCorrelationCoefficient(data, indepData, NULL, NULL, n_data, NULL);
2112 returnValue = 1;
2113 break;
2114 default:
2115 returnValue = 0;
2116 break;
2117 }
2118
2119 free(data);
2120 if (indepData)
2121 free(indepData);
2122 if (weightData)
2123 free(weightData);
2124 if (keep)
2125 free(keep);
2126 if (stringData) {
2127 for (i = 0; i < n_data; i++)
2128 if (stringData[i])
2129 free(stringData[i]);
2130 free(stringData);
2131 }
2132 if (!returnValue) {
2133 if (warnings)
2134 fprintf(stderr, "warning: processing of %s with mode %s failed--value %e returned\n",
2135 processing_ptr->column_name,
2136 process_column_name[processing_ptr->mode],
2137 processing_ptr->defaultValue);
2138 *result = processing_ptr->defaultValue;
2139 *stringResult = NULL;
2140 }
2141 return 1;
2142}
2143
2144char *process_string_column(SDDS_DATASET *Dataset, PROCESSING_DEFINITION *processing_ptr, long warnings) {
2145 char **data, *result, **matchData;
2146 long mode, matchfound;
2147 int64_t i, n_data, count;
2148 short *keep;
2149
2150 mode = processing_ptr->mode;
2151 matchData = NULL;
2152 matchfound = 0;
2153
2154 if ((n_data = SDDS_CountRowsOfInterest(Dataset)) <= 0 && mode != PROCESS_COLUMN_COUNT)
2155 return NULL;
2156
2157 if (!(data = SDDS_GetColumn(Dataset, processing_ptr->column_name)))
2158 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
2159
2160 keep = NULL;
2161 if (processing_ptr->flags & (PROCESSING_TAIL_GIVEN | PROCESSING_HEAD_GIVEN |
2162 PROCESSING_FTAIL_GIVEN | PROCESSING_FHEAD_GIVEN |
2163 PROCESSING_MATCHCOLUMN_GIVEN)) {
2164 keep = tmalloc(sizeof(*keep) * n_data);
2165 for (i = 0; i < n_data; i++)
2166 keep[i] = 1;
2167 }
2168
2169 if (processing_ptr->flags & PROCESSING_MATCHCOLUMN_GIVEN) {
2170 if (!(matchData = SDDS_GetColumn(Dataset, processing_ptr->match_column)))
2171 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
2172 for (i = 0; i < n_data; i++)
2173 keep[i] = 0;
2174 for (i = 0; i < n_data; i++) {
2175 if (wild_match(matchData[i], processing_ptr->match_value)) {
2176 matchfound = 1;
2177 keep[i] = 1;
2178 }
2179 }
2180 for (i = 0; i < n_data; i++)
2181 free(matchData[i]);
2182 free(matchData);
2183 if (!matchfound) {
2184 if (warnings)
2185 fprintf(stderr, "Warning: no values in column %s match %s.\n",
2186 processing_ptr->match_column, processing_ptr->match_value);
2187 free(keep);
2188 for (i = 0; i < n_data; i++)
2189 free(data[i]);
2190 free(data);
2191 SDDS_CopyString(&result, "_NoResultFound_");
2192 return result;
2193 }
2194 }
2195 if (processing_ptr->flags & PROCESSING_HEAD_GIVEN) {
2196 count = 0;
2197 for (i = 0; i < n_data && count < processing_ptr->head; i++)
2198 if (keep[i])
2199 count++;
2200 for (; i < n_data; i++)
2201 keep[i] = 0;
2202 }
2203
2204 if (processing_ptr->flags & PROCESSING_FHEAD_GIVEN) {
2205 long head;
2206 count = 0;
2207 head = n_data * processing_ptr->fhead + 0.5;
2208 for (i = 0; i < n_data && count < head; i++)
2209 if (keep[i])
2210 count++;
2211 for (; i < n_data; i++)
2212 keep[i] = 0;
2213 }
2214
2215 if (processing_ptr->flags & PROCESSING_TAIL_GIVEN) {
2216 count = 0;
2217 for (i = n_data - 1; i >= 0 && count < processing_ptr->tail; i--)
2218 if (keep[i])
2219 count++;
2220 for (; i >= 0; i--)
2221 keep[i] = 0;
2222 }
2223
2224 if (processing_ptr->flags & PROCESSING_FTAIL_GIVEN) {
2225 long tail;
2226 count = 0;
2227 tail = processing_ptr->ftail * n_data + 0.5;
2228 for (i = n_data - 1; i >= 0 && count < tail; i--)
2229 if (keep[i])
2230 count++;
2231 for (; i >= 0; i--)
2232 keep[i] = 0;
2233 }
2234
2235 if (keep) {
2236 int64_t j;
2237 for (i = j = 0; i < n_data; i++) {
2238 if (keep[i]) {
2239 if (i != j)
2240 data[j] = data[i];
2241 j++;
2242 } else
2243 free(data[i]);
2244 }
2245 n_data = j;
2246 }
2247 if (n_data > 0) {
2248 switch (mode) {
2249 case PROCESS_COLUMN_FIRST:
2250 SDDS_CopyString(&result, data[0]);
2251 break;
2252 case PROCESS_COLUMN_LAST:
2253 SDDS_CopyString(&result, data[n_data - 1]);
2254 break;
2255 default:
2256 SDDS_Bomb("invalid processing mode for string data (sddsprocess)");
2257 exit(1);
2258 break;
2259 }
2260 } else {
2261 if (warnings)
2262 fprintf(stderr, "warning, no matches found.");
2263 SDDS_CopyString(&result, "_NoResultFound_");
2264 }
2265 for (i = 0; i < n_data; i++)
2266 free(data[i]);
2267 free(data);
2268 if (keep)
2269 free(keep);
2270 return result;
2271}
2272
2273static char *PROCESSING_USAGE =
2274 " [-process=<column-name>,<analysis-name>,<result-name>[,description=<string>][,symbol=<string>][,weightBy=<column-name>]\n\
2275 [,match=<column-name>,value=<match-string>]\n\
2276 [,head=<number>][,tail=<number>][fhead=<fraction>][ftail=<fraction>][,topLimit=<value>][,bottomLimit=<value>]\n\
2277 [,functionOf=<column-name>[,lowerLimit=<value>|@parameter_name][,upperLimit=<value>|@<parameter_name>][,position]]\n\
2278 [,offset=<value>][,factor=<value>][match=<column-name>,value=<string>][,overwrite],[default=<value>]]\n\
2279 [,binSize=<value>]\n";
2280
2281PROCESSING_DEFINITION *record_processing_definition(char **argument, long arguments) {
2283 char *lower_str = NULL, *upper_str = NULL;
2284 char *head_str=NULL, *tail_str=NULL, *fhead_str=NULL, *ftail_str=NULL, *offset_str=NULL, *factor_str=NULL;
2285 char *invert_str=NULL;
2286 pd = tmalloc(sizeof(*pd));
2287 if (arguments < 3)
2288 bomb("invalid -process syntax--wrong number of arguments", PROCESSING_USAGE);
2289 SDDS_CopyString(&pd->column_name, argument[0]);
2290 if (process_column_name[0] == NULL) {
2291 long i;
2292 for (i = 0; i < N_PROCESS_COLUMN_MODES; i++)
2293 process_column_name[i] = process_column_data[i].name;
2294 }
2295 pd->lower_par = pd->upper_par = pd->head_par = pd->tail_par = pd->fhead_par = pd->ftail_par = pd->offset_par=pd->factor_par=NULL;
2296 if ((pd->mode = match_string(argument[1], process_column_name, N_PROCESS_COLUMN_MODES, 0)) < 0) {
2297 fprintf(stderr, "invalid -process mode: %s\n", argument[1]);
2298 show_process_modes(stderr);
2299 exit(1);
2300 }
2301
2302 SDDS_CopyString(&pd->parameter_name, argument[2]);
2303 argument += 3;
2304 arguments -= 3;
2305 pd->defaultValue = DBL_MAX;
2306 if (!scanItemList(&pd->flags, argument, &arguments, 0,
2307 "functionof", SDDS_STRING, &pd->functionOf, 1, PROCESSING_FUNCOF_GIVEN,
2308 "weightby", SDDS_STRING, &pd->weightBy, 1, PROCESSING_WEIGHT_GIVEN,
2309 "description", SDDS_STRING, &pd->description, 1, PROCESSING_DESCRIP_GIVEN,
2310 "symbol", SDDS_STRING, &pd->symbol, 1, PROCESSING_SYMBOL_GIVEN,
2311 "toplimit", SDDS_DOUBLE, &pd->topLimit, 1, PROCESSING_TOPLIM_GIVEN,
2312 "bottomlimit", SDDS_DOUBLE, &pd->bottomLimit, 1, PROCESSING_BOTLIM_GIVEN,
2313 "lowerlimit", SDDS_STRING, &lower_str, 1, PROCESSING_LOLIM_GIVEN,
2314 "upperlimit", SDDS_STRING, &upper_str, 1, PROCESSING_UPLIM_GIVEN,
2315 "head", SDDS_STRING, &head_str, 1, PROCESSING_HEAD_GIVEN,
2316 "tail", SDDS_STRING, &tail_str, 1, PROCESSING_TAIL_GIVEN,
2317 "fhead", SDDS_STRING, &fhead_str, 1, PROCESSING_FHEAD_GIVEN,
2318 "ftail", SDDS_STRING, &ftail_str, 1, PROCESSING_FTAIL_GIVEN,
2319 "position", -1, NULL, 0, PROCESSING_POSITION_GIVEN,
2320 "offset", SDDS_STRING, &offset_str, 1, PROCESSING_OFFSET_GIVEN,
2321 "factor", SDDS_STRING, &factor_str, 1, PROCESSING_FACTOR_GIVEN,
2322 "percentlevel", SDDS_DOUBLE, &pd->percentileLevel, 1, PROCESSING_PERCLEVEL_GIVEN,
2323 "binsize", SDDS_DOUBLE, &pd->binSize, 1, PROCESSING_BINSIZE_GIVEN,
2324 "match", SDDS_STRING, &pd->match_column, 1, PROCESSING_MATCHCOLUMN_GIVEN,
2325 "value", SDDS_STRING, &pd->match_value, 1, PROCESSING_MATCHVALUE_GIVEN,
2326 "overwrite", -1, NULL, 0, PROCESSING_OVERWRITE_GIVEN,
2327 "invert", SDDS_STRING, &invert_str, 1, 0,
2328 "default", SDDS_DOUBLE, &pd->defaultValue, 1, PROCESSING_DEFAULTVALUE_GIVEN,
2329 NULL))
2330 bomb("invalid -process syntax", PROCESSING_USAGE);
2331 if (invert_str) {
2332 if (strncmp_case_insensitive(invert_str, "offset", strlen(invert_str))==0)
2333 pd->flags |= PROCESSING_INVERT_OFFSET;
2334 else if (strncmp_case_insensitive(invert_str, "factor", strlen(invert_str))==0)
2335 pd->flags |= PROCESSING_INVERT_FACTOR;
2336 else if (strncmp_case_insensitive(invert_str, "both", strlen(invert_str))==0) {
2337 pd->flags |= PROCESSING_INVERT_OFFSET;
2338 pd->flags |= PROCESSING_INVERT_FACTOR;
2339 } else {
2340 fprintf(stdout, "Warning, invalid invert %s provided for process.\n", invert_str);
2341 }
2342 free(invert_str);
2343 }
2344 if (lower_str) {
2345 if (wild_match(lower_str, "@*")) {
2346 SDDS_CopyString(&pd->lower_par, lower_str + 1);
2347 free(lower_str);
2348 } else if (!get_double(&pd->lowerLimit, lower_str)) {
2349 bomb("invalid lower limit provided for -process option", PROCESSING_USAGE);
2350 }
2351 }
2352 if (upper_str) {
2353 if (wild_match(upper_str, "@*")) {
2354 SDDS_CopyString(&pd->upper_par, upper_str + 1);
2355 free(upper_str);
2356 } else if (!get_double(&pd->upperLimit, upper_str)) {
2357 bomb("invalid upper limit provided for -process option", PROCESSING_USAGE);
2358 }
2359 }
2360 if (head_str) {
2361 if (wild_match(head_str, "@*")) {
2362 SDDS_CopyString(&pd->head_par, head_str + 1);
2363 free(head_str);
2364 } else if (!get_int(&pd->head, head_str)) {
2365 bomb("invalid head provided for -process option", PROCESSING_USAGE);
2366 }
2367 }
2368 if (tail_str) {
2369 if (wild_match(tail_str, "@*")) {
2370 SDDS_CopyString(&pd->tail_par, tail_str + 1);
2371 free(tail_str);
2372 } else if (!get_int(&pd->tail, tail_str)) {
2373 bomb("invalid tail provided for -process option", PROCESSING_USAGE);
2374 }
2375 }
2376 if (fhead_str) {
2377 if (wild_match(fhead_str, "@*")) {
2378 SDDS_CopyString(&pd->fhead_par, fhead_str + 1);
2379 free(fhead_str);
2380 } else if (!get_double(&pd->fhead, fhead_str)) {
2381 bomb("invalid fhead provided for -process option", PROCESSING_USAGE);
2382 }
2383 }
2384 if (ftail_str) {
2385 if (wild_match(ftail_str, "@*")) {
2386 SDDS_CopyString(&pd->ftail_par, ftail_str + 1);
2387 free(ftail_str);
2388 } else if (!get_double(&pd->ftail, ftail_str)) {
2389 bomb("invalid ftail provided for -process option", PROCESSING_USAGE);
2390 }
2391 }
2392 if (offset_str) {
2393 if (wild_match(offset_str, "@*")) {
2394 SDDS_CopyString(&pd->offset_par, offset_str + 1);
2395 free(offset_str);
2396 } else if (wild_match(offset_str, "%s*")) {
2397 SDDS_CopyString(&pd->offset_par, offset_str);
2398 free(ftail_str);
2399 } else if (!get_double(&pd->offset, offset_str)) {
2400 bomb("invalid offset provided for -process option", PROCESSING_USAGE);
2401 }
2402 }
2403 if (factor_str) {
2404 if (wild_match(factor_str, "@*")) {
2405 SDDS_CopyString(&pd->factor_par, factor_str + 1);
2406 free(factor_str);
2407 } else if (wild_match(factor_str, "%s*")) {
2408 SDDS_CopyString(&pd->factor_par, factor_str);
2409 free(factor_str);
2410 } else if (!get_double(&pd->factor, factor_str)) {
2411 bomb("invalid factor provided for -process option", PROCESSING_USAGE);
2412 }
2413 }
2414
2415 if (pd->flags & PROCESSING_BINSIZE_GIVEN && pd->binSize <= 0)
2416 SDDS_Bomb("invalid -process syntax---bin size is zero");
2417 if (pd->flags & PROCESSING_FACTOR_GIVEN && pd->factor == 0)
2418 SDDS_Bomb("invalid -process syntax---factor field is zero");
2419 if ((process_column_data[pd->mode].flags & PROCMODE_FUNCOF_REQUIRED) &&
2420 !(pd->flags & PROCESSING_FUNCOF_GIVEN))
2421 SDDS_Bomb("invalid -process syntax---functionOf option required for given mode");
2422 if (pd->flags & PROCESSING_WEIGHT_GIVEN &&
2423 !(process_column_data[pd->mode].flags & PROCMODE_WEIGHT_OK))
2424 SDDS_Bomb("invalid -process specification---weightBy option not available for given mode");
2425 if (pd->flags & PROCESSING_POSITION_GIVEN) {
2426 if (!(pd->flags & PROCESSING_FUNCOF_GIVEN))
2427 SDDS_Bomb("invalid -process syntax---functionOf required with position option");
2428 if (!(process_column_data[pd->mode].flags & PROCMODE_POSITION_OK))
2429 SDDS_Bomb("invalid -process syntax---position option not permitted for given mode");
2430 }
2431 if (pd->flags & PROCESSING_LOLIM_GIVEN && pd->flags & PROCESSING_UPLIM_GIVEN &&
2432 pd->lowerLimit > pd->upperLimit)
2433 SDDS_Bomb("invalid -process syntax---lowerLimit>upperLimit");
2434 if (pd->flags & PROCESSING_TOPLIM_GIVEN && pd->flags & PROCESSING_BOTLIM_GIVEN && pd->topLimit < pd->bottomLimit)
2435 SDDS_Bomb("invalid -process syntax---bottomLimit>topLimit");
2436 if (pd->flags & PROCESSING_HEAD_GIVEN && !pd->head_par && pd->head == 0)
2437 SDDS_Bomb("invalid -process syntax---head=0");
2438 if (pd->flags & PROCESSING_FHEAD_GIVEN && !pd->fhead_par && pd->fhead == 0)
2439 SDDS_Bomb("invalid -process syntax---fhead=0");
2440 if (pd->flags & PROCESSING_TAIL_GIVEN && !pd->tail_par && pd->tail == 0)
2441 SDDS_Bomb("invalid -process syntax---tail=0");
2442 if (pd->flags & PROCESSING_FTAIL_GIVEN && !pd->ftail_par && pd->ftail == 0)
2443 SDDS_Bomb("invalid -process syntax---ftail=0");
2444 if (pd->flags & (PROCESSING_LOLIM_GIVEN | PROCESSING_UPLIM_GIVEN) && !(pd->flags & PROCESSING_FUNCOF_GIVEN))
2445 SDDS_Bomb("invalid -process syntax---must give -functionOf with limit options");
2446 if (pd->mode == PROCESS_COLUMN_PERCENTILE && !(pd->flags & PROCESSING_PERCLEVEL_GIVEN))
2447 SDDS_Bomb("invalid -process syntax---must give percentLevel with percentile processing");
2448 if (pd->flags & PROCESSING_MATCHCOLUMN_GIVEN && !(pd->flags & PROCESSING_MATCHVALUE_GIVEN))
2449 SDDS_Bomb("invalid -process syntax---must give value for match column");
2450 return (pd);
2451}
2452
2453SDDS_ENUM_PAIR typeEnumPair_local[SDDS_NUM_TYPES + 1] = {
2454 {"longdouble", SDDS_LONGDOUBLE},
2455 {"double", SDDS_DOUBLE},
2456 {"float", SDDS_FLOAT},
2457 {"short", SDDS_SHORT},
2458 {"ushort", SDDS_USHORT},
2459 {"long", SDDS_LONG},
2460 {"ulong", SDDS_ULONG},
2461 {"long64", SDDS_LONG64},
2462 {"ulong64", SDDS_ULONG64},
2463 {"character", SDDS_CHARACTER},
2464 {"string", SDDS_STRING},
2465 {NULL, 0}};
2466
2467long complete_processing_definitions(PROCESSING_DEFINITION **processing_definition,
2468 long processing_definitions,
2469 SDDS_DATASET *SDDS_dataset) {
2470 static char s[SDDS_MAXLINE], t[SDDS_MAXLINE];
2471 long i, index, index1;
2472 PARAMETER_DEFINITION *pardef = NULL, pardef1;
2473 SDDS_FIELD_INFORMATION SDDS_ParameterFieldInformation_local[SDDS_PARAMETER_FIELDS] = {
2474 {"name", offsetof(PARAMETER_DEFINITION, name), SDDS_STRING},
2475 {"symbol", offsetof(PARAMETER_DEFINITION, symbol), SDDS_STRING},
2476 {"units", offsetof(PARAMETER_DEFINITION, units), SDDS_STRING},
2477 {"description", offsetof(PARAMETER_DEFINITION, description), SDDS_STRING},
2478 {"format_string", offsetof(PARAMETER_DEFINITION, format_string), SDDS_STRING},
2479 {"type", offsetof(PARAMETER_DEFINITION, type), SDDS_LONG, typeEnumPair_local},
2480 {"fixed_value", offsetof(PARAMETER_DEFINITION, fixed_value), SDDS_STRING},
2481 };
2482
2483 index1 = 0;
2484
2485 for (i = 0; i < processing_definitions; i++) {
2486 if ((index = SDDS_GetColumnIndex(SDDS_dataset, processing_definition[i]->column_name)) < 0) {
2487 sprintf(s, "column %s does not exist", processing_definition[i]->column_name);
2488 SDDS_SetError(s);
2489 return (0);
2490 }
2491 switch (processing_definition[i]->type =
2492 processing_definition[i]->outputType =
2493 SDDS_GetColumnType(SDDS_dataset, index)) {
2494 case SDDS_STRING:
2495 if (!(process_column_data[processing_definition[i]->mode].flags & PROCMODE_STRING_OK)) {
2496 fprintf(stderr, "column %s has the wrong type for processing (sddsprocess)\n",
2497 processing_definition[i]->column_name);
2498 exit(1);
2499 }
2500 break;
2501 case SDDS_LONG:
2502 case SDDS_SHORT:
2503 case SDDS_FLOAT:
2504 case SDDS_DOUBLE:
2505 case SDDS_LONG64:
2506 case SDDS_CHARACTER:
2507 case SDDS_ULONG64:
2508 case SDDS_ULONG:
2509 case SDDS_USHORT:
2510 case SDDS_LONGDOUBLE:
2511 break;
2512 default:
2513 fprintf(stderr, "column %s has the wrong type for processing (sddsprocess)\n",
2514 processing_definition[i]->column_name);
2515 exit(1);
2516 break;
2517 }
2518 if (processing_definition[i]->flags & PROCESSING_DESCRIP_GIVEN) {
2519 if (strstr(processing_definition[i]->description, "%s")) {
2520 sprintf(s, processing_definition[i]->description,
2521 processing_definition[i]->column_name);
2522 free(processing_definition[i]->description);
2523 SDDS_CopyString(&processing_definition[i]->description, s);
2524 }
2525 } else {
2526 sprintf(s, "%s%s", process_column_data[processing_definition[i]->mode].description,
2527 processing_definition[i]->column_name);
2528 SDDS_CopyString(&processing_definition[i]->description, s);
2529 }
2530 if (strstr(processing_definition[i]->parameter_name, "%s")) {
2531 sprintf(s, processing_definition[i]->parameter_name, processing_definition[i]->column_name);
2532 free(processing_definition[i]->parameter_name);
2533 SDDS_CopyString(&processing_definition[i]->parameter_name, s);
2534 }
2535 if (processing_definition[i]->flags & PROCESSING_WEIGHT_GIVEN &&
2536 SDDS_GetColumnIndex(SDDS_dataset, processing_definition[i]->weightBy) < 0) {
2537 sprintf(s, "column %s does not exist", processing_definition[i]->weightBy);
2538 SDDS_SetError(s);
2539 return 0;
2540 }
2541 if (processing_definition[i]->flags & PROCESSING_MATCHCOLUMN_GIVEN &&
2542 SDDS_GetColumnIndex(SDDS_dataset, processing_definition[i]->match_column) < 0) {
2543 sprintf(s, "column %s does not exist", processing_definition[i]->match_column);
2544 SDDS_SetError(s);
2545 return 0;
2546 }
2547 if (processing_definition[i]->flags & PROCESSING_FUNCOF_GIVEN) {
2548 if ((index1 = SDDS_GetColumnIndex(SDDS_dataset, processing_definition[i]->functionOf)) < 0) {
2549 sprintf(s, "column %s does not exist", processing_definition[i]->functionOf);
2550 SDDS_SetError(s);
2551 return 0;
2552 }
2553 if (processing_definition[i]->flags & PROCESSING_POSITION_GIVEN &&
2554 (processing_definition[i]->outputType = SDDS_GetColumnType(SDDS_dataset, index1)) == SDDS_STRING &&
2555 !(process_column_data[processing_definition[i]->mode].flags & PROCMODE_STRINGPOS_OK)) {
2556 sprintf(s, "Can't have string column for position data with %s processing",
2557 process_column_data[processing_definition[i]->mode].name);
2558 SDDS_SetError(s);
2559 return 0;
2560 }
2561 }
2562 if (processing_definition[i]->outputType != SDDS_STRING)
2563 sprintf(s, "&parameter name=\"%s\", type=double, description=\"%s\", ",
2564 processing_definition[i]->parameter_name, processing_definition[i]->description);
2565 else
2566 sprintf(s, "&parameter name=\"%s\", type=string, description=\"%s\", ",
2567 processing_definition[i]->parameter_name, processing_definition[i]->description);
2568 if (process_column_data[processing_definition[i]->mode].flags & PROCMODE_FUNCOF_UNITS ||
2569 (processing_definition[i]->flags & PROCESSING_FUNCOF_GIVEN &&
2570 processing_definition[i]->flags & PROCESSING_POSITION_GIVEN)) {
2571 if (SDDS_dataset->layout.column_definition[index1].units) {
2572 sprintf(t, "units=\"%s\", ", SDDS_dataset->layout.column_definition[index1].units);
2573 strcat(s, t);
2574 }
2575 } else if (process_column_data[processing_definition[i]->mode].flags & PROCMODE_YoX_UNITS) {
2576 t[0] = 0;
2577 if (!SDDS_StringIsBlank(SDDS_dataset->layout.column_definition[index].units) &&
2578 !SDDS_StringIsBlank(SDDS_dataset->layout.column_definition[index1].units))
2579 sprintf(t, "units=\"(%s)/(%s)\", ",
2580 SDDS_dataset->layout.column_definition[index].units,
2581 SDDS_dataset->layout.column_definition[index1].units);
2582 else if (!SDDS_StringIsBlank(SDDS_dataset->layout.column_definition[index].units))
2583 sprintf(t, "units=\"%s\", ",
2584 SDDS_dataset->layout.column_definition[index].units);
2585 else if (!SDDS_StringIsBlank(SDDS_dataset->layout.column_definition[index1].units))
2586 sprintf(t, "units=\"1/(%s)\", ",
2587 SDDS_dataset->layout.column_definition[index1].units);
2588 strcat(s, t);
2589 } else if (process_column_data[processing_definition[i]->mode].flags & PROCMODE_YtX_UNITS) {
2590 t[0] = 0;
2591 if (!SDDS_StringIsBlank(SDDS_dataset->layout.column_definition[index].units) &&
2592 !SDDS_StringIsBlank(SDDS_dataset->layout.column_definition[index1].units))
2593 sprintf(t, "units=\"%s*%s\", ",
2594 SDDS_dataset->layout.column_definition[index].units,
2595 SDDS_dataset->layout.column_definition[index1].units);
2596 else if (!SDDS_StringIsBlank(SDDS_dataset->layout.column_definition[index].units))
2597 sprintf(t, "units=\"%s\", ",
2598 SDDS_dataset->layout.column_definition[index].units);
2599 else if (!SDDS_StringIsBlank(SDDS_dataset->layout.column_definition[index1].units))
2600 sprintf(t, "units=\"%s\", ",
2601 SDDS_dataset->layout.column_definition[index1].units);
2602 strcat(s, t);
2603 } else if (process_column_data[processing_definition[i]->mode].flags & PROCMODE_Y_UNITS) {
2604 if (SDDS_dataset->layout.column_definition[index].units) {
2605 sprintf(t, "units=\"%s\", ", SDDS_dataset->layout.column_definition[index].units);
2606 strcat(s, t);
2607 }
2608 }
2609 if (processing_definition[i]->symbol) {
2610 sprintf(t, "symbol=\"%s\", ", processing_definition[i]->symbol);
2611 strcat(s, t);
2612 }
2613 strcat(s, "&end");
2614 if ((index = SDDS_GetParameterIndex(SDDS_dataset, processing_definition[i]->parameter_name)) >= 0 &&
2615 processing_definition[i]->flags & PROCESSING_OVERWRITE_GIVEN) {
2616 pardef1.name = pardef1.symbol = pardef1.units = pardef1.description =
2617 pardef1.format_string = pardef1.fixed_value = NULL;
2618 pardef1.type = -1;
2619 if (!SDDS_ParseNamelist((void *)&pardef1, SDDS_ParameterFieldInformation_local,
2620 SDDS_PARAMETER_FIELDS, s)) {
2621 SDDS_SetError("Problem parsing parameter namelist");
2622 return 0;
2623 }
2624 if ((pardef1.symbol && !SDDS_ChangeParameterInformation(SDDS_dataset, "symbol", &pardef1.symbol, SDDS_BY_INDEX, index)) ||
2625 (pardef1.units && !SDDS_ChangeParameterInformation(SDDS_dataset, "units", &pardef1.units, SDDS_BY_INDEX, index)) ||
2626 (pardef1.description && !SDDS_ChangeParameterInformation(SDDS_dataset, "description", &pardef1.description, SDDS_BY_INDEX, index)) ||
2627 (pardef1.format_string && !SDDS_ChangeParameterInformation(SDDS_dataset, "format_string", &pardef1.format_string, SDDS_BY_INDEX, index)) ||
2628 (pardef1.fixed_value && !SDDS_ChangeParameterInformation(SDDS_dataset, "fixed_value", &pardef1.fixed_value, SDDS_BY_INDEX, index)) ||
2629 (pardef1.type >= 0 && !SDDS_ChangeParameterInformation(SDDS_dataset, "type", &pardef1.type, SDDS_BY_INDEX, index))) {
2630 SDDS_SetError("Problem changing parameter definitions");
2631 return 0;
2632 }
2633 } else {
2634 if (!SDDS_ProcessParameterString(SDDS_dataset, s, SDDS_WRITEONLY_DEFINITION) ||
2635 !(pardef = SDDS_GetParameterDefinition(SDDS_dataset, processing_definition[i]->parameter_name)))
2636 return (0);
2637 processing_definition[i]->memory_number = pardef->memory_number;
2639 }
2640 }
2641 return (1);
2642}
2643
2644CONVERSION_DEFINITION *process_conversion_definition(char **argument, long arguments) {
2645 CONVERSION_DEFINITION *request;
2646 request = tmalloc(sizeof(*request));
2647 if (arguments != 5)
2648 return (NULL);
2649 switch (match_string(argument[0], data_class_keyword, DATA_CLASS_KEYWORDS, 0)) {
2650 case COLUMN_BASED:
2651 request->is_parameter = 0;
2652 break;
2653 case PARAMETER_BASED:
2654 request->is_parameter = 1;
2655 break;
2656 default:
2657 return (NULL);
2658 }
2659 argument++;
2660 arguments--;
2661
2662 request->name = argument[0];
2663 request->new_units = argument[1];
2664 request->old_units = argument[2];
2665 if (sscanf(argument[3], "%lf", &request->factor) != 1)
2666 return (NULL);
2667
2668 return (request);
2669}
2670
2671#include <stddef.h>
2672
2673char *substituteString(char *template, char *pattern, char *replacement) {
2674 char *ptr, *ptr0, *buffer, c;
2675 long count = 0, patternLength, newLength;
2676
2677 if (!(patternLength = strlen(pattern)))
2678 return NULL;
2679 if (!(ptr = template))
2680 return NULL;
2681 while ((ptr = strstr(ptr, pattern))) {
2682 count++;
2683 ptr += patternLength;
2684 }
2685 if ((newLength = strlen(template) - count * patternLength + count * strlen(replacement) + 1) <= 0 ||
2686 !(buffer = malloc(newLength * sizeof(*buffer))))
2687 return NULL;
2688
2689 ptr0 = template;
2690 *buffer = 0;
2691 while (ptr0 && *ptr0 && (ptr = strstr(ptr0, pattern))) {
2692 c = *ptr;
2693 *ptr = 0;
2694 strcat(buffer, ptr0);
2695 strcat(buffer, replacement);
2696 *ptr = c;
2697 ptr0 = ptr = ptr + patternLength;
2698 }
2699 if (ptr0 && *ptr0)
2700 strcat(buffer, ptr0);
2701 return buffer;
2702}
2703
2704void expandDefinitions(DEFINITION **definition, long *definitions, SDDS_DATASET *SDDS_dataset) {
2705 long names, idef, jdef, is_parameter, templates, itemplate, definitionType, i, j;
2706 char **name, **wildcardName, *editSelection, **target, **excludeWildcardName = NULL;
2707 size_t structSize;
2708 void *defStruct;
2709 char editBuffer[SDDS_MAXLINE];
2710 long maxTemplates = 10, requireWildcard;
2711 struct {
2712 long offset;
2713 short isPointer, isBase;
2714 size_t arraySize;
2715 long index;
2716 char *template;
2717 } * targetData;
2718
2719 is_parameter = 0;
2720 structSize = 0;
2721
2722 if (!(targetData = SDDS_Malloc(sizeof(*targetData) * maxTemplates)))
2723 SDDS_Bomb("Memory allocation failure");
2724
2725 for (idef = 0; idef < *definitions; idef++) {
2726 editSelection = NULL;
2727 requireWildcard = 0; /* If nonzero, don't try to process an expansion unless the
2728 * name being expanded has wildcards.
2729 */
2730 for (i = 0; i < maxTemplates; i++) {
2731 targetData[i].isPointer = 0;
2732 }
2733 switch (definitionType = (*definition)[idef].type) {
2734 case IS_EQUATION_DEFINITION:
2735 /* e.g., -define=column,%sDiff,"%sSet %sRead -",select=Current*Set,edit=%/Set// */
2736 wildcardName = &((EQUATION_DEFINITION *)(*definition)[idef].structure)->select;
2737 excludeWildcardName = &((EQUATION_DEFINITION *)(*definition)[idef].structure)->exclude;
2738 is_parameter = ((EQUATION_DEFINITION *)(*definition)[idef].structure)->is_parameter;
2739 editSelection = ((EQUATION_DEFINITION *)(*definition)[idef].structure)->editSelection;
2740 structSize = sizeof(EQUATION_DEFINITION);
2741 targetData[0].offset = offsetof(EQUATION_DEFINITION, name);
2742 targetData[1].offset = offsetof(EQUATION_DEFINITION, equation);
2743 targetData[2].offset = offsetof(EQUATION_DEFINITION, text);
2744 SDDS_CopyString(&targetData[0].template,
2745 ((EQUATION_DEFINITION *)(*definition)[idef].structure)->name);
2746 SDDS_CopyString(&targetData[1].template,
2747 ((EQUATION_DEFINITION *)(*definition)[idef].structure)->equation);
2748 SDDS_CopyString(&targetData[2].template,
2749 ((EQUATION_DEFINITION *)(*definition)[idef].structure)->text);
2750 templates = 3;
2751 break;
2752 case IS_PRINT_DEFINITION:
2753 /* e.g., -print=column,%sLabel,"%s = %f%s",%s.name,%s,%s.units,select=Current* */
2754 wildcardName = &((PRINT_DEFINITION *)(*definition)[idef].structure)->select;
2755 excludeWildcardName = &((PRINT_DEFINITION *)(*definition)[idef].structure)->exclude;
2756 is_parameter = ((PRINT_DEFINITION *)(*definition)[idef].structure)->is_parameter;
2757 editSelection = ((PRINT_DEFINITION *)(*definition)[idef].structure)->editSelection;
2758 structSize = sizeof(PRINT_DEFINITION);
2759 targetData[0].offset = offsetof(PRINT_DEFINITION, new_name);
2760 targetData[1].offset = offsetof(PRINT_DEFINITION, text);
2761 SDDS_CopyString(&targetData[0].template,
2762 ((PRINT_DEFINITION *)(*definition)[idef].structure)->new_name);
2763 SDDS_CopyString(&targetData[1].template,
2764 ((PRINT_DEFINITION *)(*definition)[idef].structure)->text);
2765 if (((PRINT_DEFINITION *)(*definition)[idef].structure)->sources + 2 > maxTemplates) {
2766 maxTemplates = 2 * ((PRINT_DEFINITION *)(*definition)[idef].structure)->sources + 2;
2767 if (!(targetData = SDDS_Realloc(targetData, sizeof(*targetData) * maxTemplates)))
2768 SDDS_Bomb("Memory allocation failure");
2769 }
2770 for (i = 0; i < ((PRINT_DEFINITION *)(*definition)[idef].structure)->sources; i++) {
2771 targetData[i + 2].isPointer = 1;
2772 if (i == 0) {
2773 targetData[i + 2].isBase = 1;
2774 targetData[i + 2].arraySize = sizeof(*(((PRINT_DEFINITION *)(*definition)[idef].structure)->source)) *
2775 ((PRINT_DEFINITION *)(*definition)[idef].structure)->sources;
2776 } else
2777 targetData[i + 2].isBase = 0;
2778 targetData[i + 2].index = i;
2779 targetData[i + 2].offset = offsetof(PRINT_DEFINITION, source);
2780 SDDS_CopyString(&targetData[i + 2].template,
2781 ((PRINT_DEFINITION *)(*definition)[idef].structure)->source[i]);
2782 }
2783 templates = ((PRINT_DEFINITION *)(*definition)[idef].structure)->sources + 2;
2784 break;
2785 case IS_SCAN_DEFINITION:
2786 /* e.g., -scan=column,%sNum,Current*,"%f" */
2787 wildcardName = &((SCAN_DEFINITION *)(*definition)[idef].structure)->source;
2788 requireWildcard = 1;
2789 is_parameter = ((SCAN_DEFINITION *)(*definition)[idef].structure)->is_parameter;
2790 structSize = sizeof(SCAN_DEFINITION);
2791 targetData[0].offset = offsetof(SCAN_DEFINITION, new_name);
2792 targetData[1].offset = offsetof(SCAN_DEFINITION, text);
2793 targetData[2].offset = offsetof(SCAN_DEFINITION, source);
2794 SDDS_CopyString(&targetData[0].template,
2795 ((SCAN_DEFINITION *)(*definition)[idef].structure)->new_name);
2796 SDDS_CopyString(&targetData[1].template,
2797 ((SCAN_DEFINITION *)(*definition)[idef].structure)->text);
2798 SDDS_CopyString(&targetData[2].template, "%s");
2799 templates = 3;
2800 break;
2801 case IS_EDIT_DEFINITION:
2802 /* e.g., -edit=column,%sEdited,String*,%/Fred/Sally/ */
2803 wildcardName = &((EDIT_DEFINITION *)(*definition)[idef].structure)->source;
2804 requireWildcard = 1;
2805 is_parameter = ((EDIT_DEFINITION *)(*definition)[idef].structure)->is_parameter;
2806 structSize = sizeof(EDIT_DEFINITION);
2807 targetData[0].offset = offsetof(EDIT_DEFINITION, new_name);
2808 targetData[1].offset = offsetof(EDIT_DEFINITION, text);
2809 targetData[2].offset = offsetof(EDIT_DEFINITION, source);
2810 SDDS_CopyString(&targetData[0].template,
2811 ((EDIT_DEFINITION *)(*definition)[idef].structure)->new_name);
2812 SDDS_CopyString(&targetData[1].template,
2813 ((EDIT_DEFINITION *)(*definition)[idef].structure)->text);
2814 SDDS_CopyString(&targetData[2].template, "%s");
2815 templates = 3;
2816 break;
2817 case IS_PROCESSING_DEFINITION:
2818 /* e.g., -process=Current*,average,%sMean */
2819 wildcardName = &((PROCESSING_DEFINITION *)(*definition)[idef].structure)->column_name;
2820 requireWildcard = 1;
2821 is_parameter = 0;
2822 structSize = sizeof(PROCESSING_DEFINITION);
2823 targetData[0].offset = offsetof(PROCESSING_DEFINITION, parameter_name);
2824 targetData[1].offset = offsetof(PROCESSING_DEFINITION, column_name);
2825 targetData[2].offset = offsetof(PROCESSING_DEFINITION, functionOf);
2826 targetData[3].offset = offsetof(PROCESSING_DEFINITION, weightBy);
2827 targetData[4].offset = offsetof(PROCESSING_DEFINITION, description);
2828 targetData[5].offset = offsetof(PROCESSING_DEFINITION, symbol);
2829 SDDS_CopyString(&targetData[0].template,
2830 ((PROCESSING_DEFINITION *)(*definition)[idef].structure)->parameter_name);
2831 SDDS_CopyString(&targetData[1].template, "%s");
2832 SDDS_CopyString(&targetData[2].template,
2833 ((PROCESSING_DEFINITION *)(*definition)[idef].structure)->functionOf);
2834 SDDS_CopyString(&targetData[3].template,
2835 ((PROCESSING_DEFINITION *)(*definition)[idef].structure)->weightBy);
2836 SDDS_CopyString(&targetData[4].template,
2837 ((PROCESSING_DEFINITION *)(*definition)[idef].structure)->description);
2838 SDDS_CopyString(&targetData[5].template,
2839 ((PROCESSING_DEFINITION *)(*definition)[idef].structure)->symbol);
2840 templates = 6;
2841 break;
2842 case IS_CONVERSION_DEFINITION:
2843 /* e.g., -convert=column,Current*,mA,A,1000 */
2844 wildcardName = &((CONVERSION_DEFINITION *)(*definition)[idef].structure)->name;
2845 requireWildcard = 1;
2846 is_parameter = ((CONVERSION_DEFINITION *)(*definition)[idef].structure)->is_parameter;
2847 structSize = sizeof(CONVERSION_DEFINITION);
2848 targetData[0].offset = offsetof(CONVERSION_DEFINITION, name);
2849 SDDS_CopyString(&targetData[0].template, "%s");
2850 templates = 1;
2851 break;
2852 case IS_SYSTEM_DEFINITION:
2853 /* e.g., -system=column,SysResult%s,Command* */
2854 wildcardName = &((SYSTEM_DEFINITION *)(*definition)[idef].structure)->source;
2855 requireWildcard = 1;
2856 is_parameter = ((SYSTEM_DEFINITION *)(*definition)[idef].structure)->is_parameter;
2857 structSize = sizeof(SYSTEM_DEFINITION);
2858 targetData[0].offset = offsetof(SYSTEM_DEFINITION, new_name);
2859 targetData[1].offset = offsetof(SYSTEM_DEFINITION, text);
2860 targetData[2].offset = offsetof(SYSTEM_DEFINITION, source);
2861 SDDS_CopyString(&targetData[0].template,
2862 ((SYSTEM_DEFINITION *)(*definition)[idef].structure)->new_name);
2863 SDDS_CopyString(&targetData[1].template,
2864 ((SYSTEM_DEFINITION *)(*definition)[idef].structure)->text);
2865 SDDS_CopyString(&targetData[2].template, "%s");
2866 templates = 3;
2867 break;
2868 case IS_CAST_DEFINITION:
2869 /* e.g., -cast=column,%sLong,Current*,long */
2870 wildcardName = &((CAST_DEFINITION *)(*definition)[idef].structure)->source;
2871 requireWildcard = 1;
2872 is_parameter = ((CAST_DEFINITION *)(*definition)[idef].structure)->isParameter;
2873 structSize = sizeof(CAST_DEFINITION);
2874 targetData[0].offset = offsetof(CAST_DEFINITION, newName);
2875 targetData[1].offset = offsetof(CAST_DEFINITION, source);
2876 SDDS_CopyString(&targetData[0].template,
2877 ((CAST_DEFINITION *)(*definition)[idef].structure)->newName);
2878 SDDS_CopyString(&targetData[1].template, "%s");
2879 templates = 2;
2880 break;
2881 default:
2882 wildcardName = NULL;
2883 templates = 0;
2884 break;
2885 }
2886 if ((!wildcardName || !*wildcardName) || (requireWildcard && !has_wildcards(*wildcardName))) {
2887 if (wildcardName && *wildcardName)
2888 unescape_wildcards(*wildcardName);
2889 continue;
2890 }
2891
2892 if (is_parameter) {
2893 if ((excludeWildcardName == NULL) || (*excludeWildcardName == NULL)) {
2894 if ((names = SDDS_MatchParameters(SDDS_dataset, &name, SDDS_MATCH_STRING, FIND_ANY_TYPE,
2895 *wildcardName, SDDS_AND | SDDS_1_PREVIOUS)) <= 0) {
2896 fprintf(stderr, "Error (expandDefinitions): unable to find match to parameter name %s\n", *wildcardName);
2897 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
2898 exit(1);
2899 }
2900 } else {
2901 if ((names = SDDS_MatchParameters(SDDS_dataset, &name, SDDS_MATCH_EXCLUDE_STRING, FIND_ANY_TYPE,
2902 *wildcardName, *excludeWildcardName,
2903 SDDS_AND | SDDS_1_PREVIOUS)) <= 0) {
2904 fprintf(stderr, "Error (expandDefinitions): unable to find match to parameter name %s\n", *wildcardName);
2905 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
2906 exit(1);
2907 }
2908 }
2909 } else {
2910 if ((excludeWildcardName == NULL) || (*excludeWildcardName == NULL)) {
2911 if ((names = SDDS_MatchColumns(SDDS_dataset, &name, SDDS_MATCH_STRING, FIND_ANY_TYPE,
2912 *wildcardName, SDDS_AND | SDDS_1_PREVIOUS)) <= 0) {
2913 fprintf(stderr, "Error (expandDefinitions): unable to find match to column name %s\n", *wildcardName);
2914 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
2915 exit(1);
2916 }
2917 } else {
2918 if ((names = SDDS_MatchColumns(SDDS_dataset, &name, SDDS_MATCH_EXCLUDE_STRING, FIND_ANY_TYPE,
2919 *wildcardName, *excludeWildcardName,
2920 SDDS_AND | SDDS_1_PREVIOUS)) <= 0) {
2921 fprintf(stderr, "Error (expandDefinitions): unable to find match to column name %s\n", *wildcardName);
2922 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
2923 exit(1);
2924 }
2925 }
2926 }
2927 if (editSelection)
2928 edit_strings(name, names, editBuffer, editSelection);
2929 *definition = SDDS_Realloc(*definition, sizeof(**definition) * (*definitions - 1 + names));
2930 for (jdef = *definitions - 1; jdef > idef; jdef--) {
2931 (*definition)[jdef + names - 1].structure = (*definition)[jdef].structure;
2932 (*definition)[jdef + names - 1].type = (*definition)[jdef].type;
2933 }
2934 for (jdef = names - 1; jdef >= 0; jdef--) {
2935 if (jdef) {
2936 if (!(defStruct = (*definition)[idef + jdef].structure = calloc(1, structSize)))
2937 SDDS_Bomb("memory allocation failure (expandDefinitions)");
2938 memcpy((char *)defStruct, (char *)(*definition)[idef].structure, structSize);
2939 } else
2940 defStruct = (*definition)[idef + jdef].structure;
2941 (*definition)[idef + jdef].type = definitionType;
2942 for (itemplate = 0; itemplate < templates; itemplate++) {
2943 if (targetData[itemplate].isPointer) {
2944 char **ptr;
2945 if (targetData[itemplate].isBase) {
2946 *(char ***)((char *)defStruct + targetData[itemplate].offset) =
2947 SDDS_Malloc(targetData[itemplate].arraySize);
2948 }
2949 ptr = *(char ***)((char *)defStruct + targetData[itemplate].offset);
2950 target = ptr + targetData[itemplate].index;
2951 } else
2952 target = (char **)((char *)defStruct + targetData[itemplate].offset);
2953 if (!(*target =
2954 substituteString(targetData[itemplate].template, "%s", name[jdef])) &&
2955 targetData[itemplate].template) {
2956 fputs("Error: problem doing pattern substitution (expandDefinitions)\n", stderr);
2957 fprintf(stderr, "template is \"%s\", instance is \"%s\"\n",
2958 targetData[itemplate].template, name[jdef]);
2959 exit(1);
2960 }
2961 }
2962 }
2963 *definitions += names - 1;
2964 idef += names - 1;
2965 for (j = 0; j < names; j++)
2966 free(name[j]);
2967 free(name);
2968 }
2969 free(targetData);
2970}
2971
2972long scan_column_value(SDDS_DATASET *SDDS_dataset, char *target, char *source, char *format,
2973 char *edit_command) {
2974 char **source_value, char_value, *sourcePtr;
2975 long target_type, target_index, source_index;
2976 int64_t i, rows;
2977 float float_value;
2978 double double_value;
2979 int64_t long64_value;
2980 int32_t long_value;
2981 short short_value;
2982 static char s[SDDS_MAXLINE];
2983
2984 if ((source_index = SDDS_GetColumnIndex(SDDS_dataset, source)) < 0 ||
2985 (target_index = SDDS_GetColumnIndex(SDDS_dataset, target)) < 0) {
2986 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
2987 return (0);
2988 }
2989 if (SDDS_GetColumnType(SDDS_dataset, source_index) != SDDS_STRING) {
2990 fprintf(stderr, "error: source column %s has wrong type for scanning--must be string\n", source);
2991 return (0);
2992 }
2993 target_type = SDDS_GetColumnType(SDDS_dataset, target_index);
2994
2995 if ((rows = SDDS_CountRowsOfInterest(SDDS_dataset)) < 0) {
2996 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
2997 return (0);
2998 }
2999
3000 if (!(source_value = SDDS_GetInternalColumn(SDDS_dataset, source))) {
3001 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3002 return (0);
3003 }
3004
3005 for (i = 0; i < rows; i++) {
3006 sourcePtr = source_value[i];
3007 if (!source_value[i]) {
3008 if (SDDS_NUMERIC_TYPE(target_type))
3009 strcpy(s, "NaN");
3010 else
3011 strcpy(s, "\0");
3012 sourcePtr = s;
3013 } else if (edit_command && strlen(edit_command)) {
3014 strncpy(s, source_value[i], SDDS_MAXLINE - 1);
3015 sourcePtr = s;
3016 if (!edit_string(s, edit_command)) {
3017 fprintf(stderr, "error: unable to preedit source string \"%s\" to scan into %s\n", source_value[i], target);
3018 return (0);
3019 }
3020 }
3021 switch (target_type) {
3022 case SDDS_DOUBLE:
3023 if (sscanf(sourcePtr, format, &double_value) != 1) {
3024 fprintf(stderr, "error: unable to scan source string \"%s\" to make %s\n", sourcePtr, target);
3025 return (0);
3026 }
3027 if (!SDDS_SetRowValues(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, i, target_index, double_value, -1)) {
3028 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3029 return (0);
3030 }
3031 break;
3032 case SDDS_FLOAT:
3033 if (sscanf(sourcePtr, format, &float_value) != 1) {
3034 fprintf(stderr, "error: unable to scan source string \"%s\" to make %s\n", sourcePtr, target);
3035 return (0);
3036 }
3037 if (!SDDS_SetRowValues(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, i, target_index, float_value, -1)) {
3038 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3039 return (0);
3040 }
3041 break;
3042 case SDDS_LONG64:
3043 if (sscanf(sourcePtr, format, &long64_value) != 1) {
3044 fprintf(stderr, "error: unable to scan source string \"%s\" to make %s\n", sourcePtr, target);
3045 return (0);
3046 }
3047 if (!SDDS_SetRowValues(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, i, target_index, long64_value, -1)) {
3048 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3049 return (0);
3050 }
3051 break;
3052 case SDDS_LONG:
3053 if (sscanf(sourcePtr, format, &long_value) != 1) {
3054 fprintf(stderr, "error: unable to scan source string \"%s\" to make %s\n", sourcePtr, target);
3055 return (0);
3056 }
3057 if (!SDDS_SetRowValues(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, i, target_index, long_value, -1)) {
3058 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3059 return (0);
3060 }
3061 break;
3062 case SDDS_SHORT:
3063 if (sscanf(sourcePtr, format, &short_value) != 1) {
3064 fprintf(stderr, "error: unable to scan source string \"%s\" to make %s\n", sourcePtr, target);
3065 return (0);
3066 }
3067 if (!SDDS_SetRowValues(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, i, target_index, short_value, -1)) {
3068 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3069 return (0);
3070 }
3071 break;
3072 case SDDS_CHARACTER:
3073 if (sscanf(sourcePtr, format, &char_value) != 1) {
3074 fprintf(stderr, "error: unable to scan source string \"%s\" to make %s\n", sourcePtr, target);
3075 return (0);
3076 }
3077 if (!SDDS_SetRowValues(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, i, target_index, char_value, -1)) {
3078 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3079 return (0);
3080 }
3081 break;
3082 case SDDS_STRING:
3083 if (sscanf(sourcePtr, format, s) != 1) {
3084 fprintf(stderr, "error: unable to scan source string \"%s\" to make %s\n", sourcePtr, target);
3085 return (0);
3086 }
3087 if (!SDDS_SetRowValues(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, i, target_index, s, -1)) {
3088 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3089 return (0);
3090 }
3091 break;
3092 default:
3093 SDDS_Bomb("error: unknown type encountered--this shouldn't happen (scan_column_value)");
3094 break;
3095 }
3096 }
3097 return (1);
3098}
3099
3100long scan_parameter_value(SDDS_DATASET *SDDS_dataset, char *target, char *source, char *format,
3101 char *edit_command) {
3102 char *source_value, **ptr, char_value;
3103 long target_type, target_index, source_index;
3104 float float_value;
3105 double double_value;
3106 int64_t long64_value;
3107 int32_t long_value;
3108 short short_value;
3109 static char s[SDDS_MAXLINE];
3110
3111 if ((source_index = SDDS_GetParameterIndex(SDDS_dataset, source)) < 0 ||
3112 (target_index = SDDS_GetParameterIndex(SDDS_dataset, target)) < 0) {
3113 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3114 return (0);
3115 }
3116 if (SDDS_GetParameterType(SDDS_dataset, source_index) != SDDS_STRING) {
3117 fprintf(stderr, "error: source parameter %s has wrong type for scanning--must be string\n", source);
3118 return (0);
3119 }
3120 target_type = SDDS_GetParameterType(SDDS_dataset, target_index);
3121
3122 if (!(ptr = SDDS_GetParameter(SDDS_dataset, source, NULL))) {
3123 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3124 return (0);
3125 }
3126 source_value = *ptr;
3127 if (!source_value) {
3128 if (SDDS_NUMERIC_TYPE(target_type))
3129 SDDS_CopyString(&source_value, "NaN");
3130 else
3131 SDDS_CopyString(&source_value, "\0");
3132 } else if (edit_command) {
3133 strncpy(s, source_value, SDDS_MAXLINE - 1);
3134 if (!edit_string(s, edit_command)) {
3135 fprintf(stderr, "error: unable to preedit source string \"%s\" for scanning into %s\n", source_value, target);
3136 return (0);
3137 }
3138 free(source_value);
3139 SDDS_CopyString(&source_value, s);
3140 }
3141 switch (target_type) {
3142 case SDDS_DOUBLE:
3143 if (sscanf(source_value, format, &double_value) != 1) {
3144 fprintf(stderr, "error: unable to scan source string \"%s\" to make %s\nsscanf string was:", source_value, target);
3145 fputs(format, stderr);
3146 fputc('\n', stderr);
3147 return (0);
3148 }
3149 if (!SDDS_SetParameters(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, target_index, double_value, -1)) {
3150 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3151 return (0);
3152 }
3153 break;
3154 case SDDS_FLOAT:
3155 if (sscanf(source_value, format, &float_value) != 1) {
3156 fprintf(stderr, "error: unable to scan source string \"%s\" to make %s\nsscanf string was:", source_value, target);
3157 fputs(format, stderr);
3158 fputc('\n', stderr);
3159 return (0);
3160 }
3161 if (!SDDS_SetParameters(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, target_index, float_value, -1)) {
3162 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3163 return (0);
3164 }
3165 break;
3166 case SDDS_LONG64:
3167 if (sscanf(source_value, format, &long64_value) != 1) {
3168 fprintf(stderr, "error: unable to scan source string \"%s\" to make %s\nsscanf string was:", source_value, target);
3169 fputs(format, stderr);
3170 fputc('\n', stderr);
3171 return (0);
3172 }
3173 if (!SDDS_SetParameters(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, target_index, long64_value, -1)) {
3174 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3175 return (0);
3176 }
3177 break;
3178 case SDDS_LONG:
3179 if (sscanf(source_value, format, &long_value) != 1) {
3180 fprintf(stderr, "error: unable to scan source string \"%s\" to make %s\nsscanf string was:", source_value, target);
3181 fputs(format, stderr);
3182 fputc('\n', stderr);
3183 return (0);
3184 }
3185 if (!SDDS_SetParameters(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, target_index, long_value, -1)) {
3186 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3187 return (0);
3188 }
3189 break;
3190 case SDDS_SHORT:
3191 if (sscanf(source_value, format, &short_value) != 1) {
3192 fprintf(stderr, "error: unable to scan source string \"%s\" to make %s\nsscanf string was:", source_value, target);
3193 fputs(format, stderr);
3194 fputc('\n', stderr);
3195 return (0);
3196 }
3197 if (!SDDS_SetParameters(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, target_index, short_value, -1)) {
3198 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3199 return (0);
3200 }
3201 break;
3202 case SDDS_CHARACTER:
3203 if (sscanf(source_value, format, &char_value) != 1) {
3204 fprintf(stderr, "error: unable to scan source string \"%s\" to make %s\nsscanf string was:", source_value, target);
3205 fputs(format, stderr);
3206 fputc('\n', stderr);
3207 return (0);
3208 }
3209 if (!SDDS_SetParameters(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, target_index, char_value, -1)) {
3210 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3211 return (0);
3212 }
3213 break;
3214 case SDDS_STRING:
3215 if (sscanf(source_value, format, s) != 1) {
3216 fprintf(stderr, "error: unable to scan source string \"%s\" to make %s\nsscanf string was:", source_value, target);
3217 fputs(format, stderr);
3218 fputc('\n', stderr);
3219 return (0);
3220 }
3221 if (!SDDS_SetParameters(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, target_index, s, -1)) {
3222 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3223 return (0);
3224 }
3225 break;
3226 default:
3227 SDDS_Bomb("error: unknown type encountered--this shouldn't happen (scan_parameter_value)");
3228 break;
3229 }
3230 free(source_value);
3231 return (1);
3232}
3233
3234PRINT_DEFINITION *process_new_print_definition(char **argument, long arguments) {
3235 static char s[SDDS_MAXLINE];
3236 char *ptr;
3237 long i, hasType, code;
3238 PRINT_DEFINITION *defi;
3239
3240 hasType = 0;
3241 if (!(defi = tmalloc(sizeof(*defi))))
3242 SDDS_Bomb("memory allocation failure (process_new_print_definition)");
3243 switch (match_string(argument[0], data_class_keyword, DATA_CLASS_KEYWORDS, 0)) {
3244 case COLUMN_BASED:
3245 defi->is_parameter = 0;
3246 sprintf(s, "&column name=\"%s\", ", argument[1]);
3247 break;
3248 case PARAMETER_BASED:
3249 defi->is_parameter = 1;
3250 sprintf(s, "&parameter name=\"%s\", ", argument[1]);
3251 break;
3252 default:
3253 fprintf(stderr, "error: column or parameter must be specified for print\n");
3254 return (NULL);
3255 }
3256 defi->new_name = argument[1];
3257 defi->source = NULL;
3258 defi->sources = 0;
3259 defi->printf_string = argument[2];
3260
3261 for (i = 3; i < arguments; i++) {
3262 if (!(ptr = strchr(argument[i], '='))) {
3263 /* source entry */
3264 defi->source = trealloc(defi->source, sizeof(*defi->source) * (defi->sources + 1));
3265 defi->source[defi->sources++] = argument[i];
3266 } else
3267 break;
3268 }
3269 for (; i < arguments; i++) {
3270 /* should only have qualifiers from here on */
3271 if (!(ptr = strchr(argument[i], '='))) {
3272 fprintf(stderr, "error: invalid definition-entry: %s\n", argument[i]);
3273 return (NULL);
3274 }
3275 *ptr = 0;
3276 switch (code = match_string(argument[i], selectQualifier, SELECT_QUALIFIERS, 0)) {
3277 case SELECT_QUALIFIER:
3278 defi->select = ptr + 1;
3279 break;
3280 case EDITSELECTION_QUALIFIER:
3281 defi->editSelection = ptr + 1;
3282 break;
3283 case EXCLUDE_QUALIFIER:
3284 defi->exclude = ptr + 1;
3285 break;
3286 default:
3287 break;
3288 }
3289 *ptr = '=';
3290 if (code >= 0)
3291 continue;
3292 *ptr = 0;
3293 strcat(s, argument[i]);
3294 if (strcmp(argument[i], "type") == 0)
3295 hasType = 1;
3296 strcat(s, "=\"");
3297 strcat(s, ptr + 1);
3298 strcat(s, "\", ");
3299 *ptr = '=';
3300 }
3301 if (!hasType)
3302 strcat(s, " type=string &end");
3303 else
3304 strcat(s, " &end");
3305 if (!SDDS_CopyString(&defi->text, s))
3306 SDDS_Bomb("unable to copy text of print definition (process_new_print_definition)");
3307 return (defi);
3308}
3309
3310long print_parameter_value(SDDS_DATASET *SDDS_dataset, char *target, char **source, long sources, char *format) {
3311 char *print_pos, **ptr, *fptr1, *fptr2 = NULL, *fptr3, *cptr;
3312 long source_type, source_index, target_index, target_type;
3313 long i, use_info;
3314 static char s[SDDS_MAXLINE];
3315 static char *info = NULL;
3316
3317 if (!info && !(info = malloc(sizeof(double) * 2)))
3318 SDDS_Bomb("Allocation failure in print_parameter_value");
3319
3320 if ((target_index = SDDS_GetParameterIndex(SDDS_dataset, target)) < 0) {
3321 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3322 return (0);
3323 }
3324 if ((target_type = SDDS_GetParameterType(SDDS_dataset, target_index)) != SDDS_STRING &&
3325 target_type != SDDS_CHARACTER) {
3326 fprintf(stderr, "error: target parameter %s has wrong type for printing--must be string or character\n", target);
3327 return (0);
3328 }
3329 fptr1 = format;
3330 s[0] = 0;
3331 if (sources == 0)
3332 strcpy(s, format);
3333 for (i = 0; i < sources; i++) {
3334 print_pos = s + strlen(s);
3335 use_info = 0;
3336 if ((source_index = SDDS_GetParameterIndex(SDDS_dataset, source[i])) < 0 ||
3337 (source_type = SDDS_GetParameterType(SDDS_dataset, source_index)) < 0) {
3338 if ((cptr = strrchr(source[i], '.'))) {
3339 *cptr = 0;
3340 if (!(source_type = SDDS_GetParameterInformation(SDDS_dataset, cptr + 1, info, SDDS_GET_BY_NAME, source[i])) &&
3341 !(source_type = SDDS_GetColumnInformation(SDDS_dataset, cptr + 1, info, SDDS_GET_BY_NAME, source[i]))) {
3342 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3343 return (0);
3344 }
3345 if (strcmp(cptr + 1, "type") == 0) {
3346 if (source_type != SDDS_LONG)
3347 return bombre("internal error: type of data-type information is not long", NULL, 0);
3348 SDDS_CopyString((char **)info, SDDS_type_name[*(long *)info - 1]);
3349 source_type = SDDS_STRING;
3350 }
3351 *cptr = '.';
3352 use_info = 1;
3353 if (source_type == SDDS_STRING && *(char **)info == NULL)
3354 SDDS_CopyString((char **)info, "");
3355 } else {
3356 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3357 return (0);
3358 }
3359 }
3360 if (use_info)
3361 ptr = (char **)info;
3362 else if (!(ptr = SDDS_GetParameter(SDDS_dataset, source[i], NULL))) {
3363 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3364 return (0);
3365 }
3366
3367 fptr3 = fptr1;
3368 while (*fptr3) {
3369 if (!(fptr2 = strchr(fptr3, '%'))) {
3370 fprintf(stderr, "Error: invalid sprintf string\n");
3371 return (0);
3372 }
3373 if (*(fptr2 + 1) == '%')
3374 fptr3 = fptr2 + 2;
3375 else if (fptr2 != format && *(fptr2 - 1) == '\\')
3376 fptr3 = fptr2 + 1;
3377 else
3378 break;
3379 }
3380 if (*fptr3 == 0) {
3381 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3382 return (0);
3383 }
3384 if ((fptr2 = strchr(fptr2 + 1, '%')) && i != (sources - 1))
3385 *fptr2 = 0;
3386 else
3387 fptr2 = NULL;
3388 switch (source_type) {
3389 case SDDS_DOUBLE:
3390 sprintf(print_pos, fptr1, *(double *)ptr);
3391 break;
3392 case SDDS_FLOAT:
3393 sprintf(print_pos, fptr1, *(float *)ptr);
3394 break;
3395 case SDDS_LONG64:
3396 sprintf(print_pos, fptr1, *(int64_t *)ptr);
3397 break;
3398 case SDDS_ULONG64:
3399 sprintf(print_pos, fptr1, *(uint64_t *)ptr);
3400 break;
3401 case SDDS_LONG:
3402 sprintf(print_pos, fptr1, *(int32_t *)ptr);
3403 break;
3404 case SDDS_ULONG:
3405 sprintf(print_pos, fptr1, *(uint32_t *)ptr);
3406 break;
3407 case SDDS_SHORT:
3408 sprintf(print_pos, fptr1, *(short *)ptr);
3409 break;
3410 case SDDS_USHORT:
3411 sprintf(print_pos, fptr1, *(unsigned short *)ptr);
3412 break;
3413 case SDDS_CHARACTER:
3414 sprintf(print_pos, fptr1, *(char *)ptr);
3415 break;
3416 case SDDS_STRING:
3417 sprintf(print_pos, fptr1, *(char **)ptr);
3418 free(*ptr);
3419 break;
3420 default:
3421 SDDS_Bomb("error: unknown type encountered--this shouldn't happen (print_parameter_value)");
3422 break;
3423 }
3424 if (!(fptr1 = fptr2))
3425 break;
3426 *fptr1 = '%';
3427 if (!use_info)
3428 free(ptr);
3429 }
3430 if ((target_type == SDDS_STRING &&
3431 !SDDS_SetParameters(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, target_index, s, -1)) ||
3432 (target_type == SDDS_CHARACTER &&
3433 !SDDS_SetParameters(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, target_index, s[0], -1))) {
3434 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3435 return (0);
3436 }
3437 return (1);
3438}
3439
3440long print_column_value(SDDS_DATASET *SDDS_dataset, char *target, char **source, long sources, char *format) {
3441 char *print_pos, **ptr, *fptr1, *fptr2 = NULL, *fptr3, *cptr;
3442 long target_index, target_type;
3443 long i;
3444 int64_t j, rows;
3445 static char s[SDDS_MAXLINE];
3446 static long firstCall = 1;
3447 struct {
3448 long source_type, source_index;
3449 short is_parameter, is_column, use_info;
3450 char *info;
3451 } * sourceData;
3452
3453 ptr = NULL;
3454 if ((target_index = SDDS_GetColumnIndex(SDDS_dataset, target)) < 0) {
3455 SDDS_SetError("Unable to find print target");
3456 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3457 return (0);
3458 }
3459 if ((target_type = SDDS_GetColumnType(SDDS_dataset, target_index)) != SDDS_STRING &&
3460 target_type != SDDS_CHARACTER) {
3461 fprintf(stderr, "error: target column %s has wrong type for printing--must be string or character\n", target);
3462 return (0);
3463 }
3464 if ((rows = SDDS_CountRowsOfInterest(SDDS_dataset)) < 0) {
3465 SDDS_SetError("Error counting rows to print.");
3466 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3467 return (0);
3468 }
3469
3470 if (!(sourceData = SDDS_Malloc(sizeof(*sourceData) * sources)))
3471 SDDS_Bomb("Memory allocation failure doing printing.");
3472 for (i = 0; i < sources; i++) {
3473 print_pos = s + strlen(s);
3474 sourceData[i].is_column = sourceData[i].is_parameter =
3475 sourceData[i].use_info = 0;
3476 if (((sourceData[i].source_index = SDDS_GetColumnIndex(SDDS_dataset, source[i])) >= 0) &&
3477 ((sourceData[i].source_type = SDDS_GetColumnType(SDDS_dataset, sourceData[i].source_index)) >= 0))
3478 sourceData[i].is_column = 1;
3479 else if ((sourceData[i].source_index = SDDS_GetParameterIndex(SDDS_dataset, source[i])) >= 0 &&
3480 (sourceData[i].source_type = SDDS_GetParameterType(SDDS_dataset, sourceData[i].source_index)) >= 0)
3481 sourceData[i].is_parameter = 1;
3482 else if ((cptr = strrchr(source[i], '.'))) {
3483 *cptr = 0;
3484 if ((sourceData[i].source_type =
3485 SDDS_GetParameterInformation(SDDS_dataset, cptr + 1, &sourceData[i].info, SDDS_GET_BY_NAME, source[i])))
3486 sourceData[i].is_parameter = 1;
3487 else if ((sourceData[i].source_type =
3488 SDDS_GetColumnInformation(SDDS_dataset, cptr + 1, &sourceData[i].info, SDDS_GET_BY_NAME, source[i])))
3489 sourceData[i].is_column = 1;
3490 else {
3491 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3492 return (0);
3493 }
3494 if (strcmp(cptr + 1, "type") == 0) {
3495 if (sourceData[i].source_type != SDDS_LONG)
3496 return bombre("internal error: type of data-type information is not long", NULL, 0);
3497 SDDS_CopyString((char **)sourceData[i].info, SDDS_type_name[*(long *)sourceData[i].info - 1]);
3498 sourceData[i].source_type = SDDS_STRING;
3499 }
3500 *cptr = '.';
3501 sourceData[i].use_info = 1;
3502 if (sourceData[i].source_type == SDDS_STRING && sourceData[i].info == NULL)
3503 SDDS_CopyString(&sourceData[i].info, "");
3504 } else {
3505 sprintf(s, "Unable to find print source %s.", source[i]);
3506 SDDS_SetError(s);
3507 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3508 return (0);
3509 }
3510 }
3511
3512 for (j = 0; j < rows; j++) {
3513 fptr1 = format;
3514 s[0] = 0;
3515 if (sources == 0)
3516 strcpy(s, format);
3517 for (i = 0; i < sources; i++) {
3518 print_pos = s + strlen(s);
3519 if (sourceData[i].is_column && !sourceData[i].use_info) {
3520 if (!(ptr = SDDS_GetValue(SDDS_dataset, source[i], j, NULL))) {
3521 SDDS_SetError("Unable to get column value for printing");
3522 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3523 return (0);
3524 }
3525 if (!j && firstCall && SDDS_GetParameterIndex(SDDS_dataset, source[i]) >= 0) {
3526 if (*ptr == NULL) {
3527 fprintf(stderr, "error: -print option for column %s uses source %s which is defined\n",
3528 target, source[i]);
3529 fprintf(stderr, "as both a column and a parameter\n");
3530 return (0);
3531 } else {
3532 fprintf(stderr, "warning: -print option for column %s uses source %s which is defined\n",
3533 target, source[i]);
3534 fprintf(stderr, "as both a column and a parameter---column values are used!\n");
3535 }
3536 }
3537 }
3538 if (sourceData[i].is_parameter && !sourceData[i].use_info) {
3539 if (!(ptr = SDDS_GetParameter(SDDS_dataset, source[i], NULL))) {
3540 SDDS_SetError("Unable to get print source parameter value.");
3541 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3542 return (0);
3543 }
3544 }
3545 if (sourceData[i].use_info)
3546 ptr = &sourceData[i].info;
3547 fptr3 = fptr1;
3548 while (*fptr3) {
3549 if (!(fptr2 = strchr(fptr3, '%'))) {
3550 fprintf(stderr, "Error: invalid sprintf string\n");
3551 return (0);
3552 }
3553 if (*(fptr2 + 1) == '%')
3554 fptr3 = fptr2 + 2;
3555 else if (fptr2 != format && *(fptr2 - 1) == '\\')
3556 fptr3 = fptr2 + 1;
3557 else
3558 break;
3559 }
3560 if (*fptr3 == 0) {
3561 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3562 return (0);
3563 }
3564 if ((fptr2 = strchr(fptr2 + 1, '%')) && i != (sources - 1))
3565 *fptr2 = 0;
3566 else
3567 fptr2 = NULL;
3568 switch (sourceData[i].source_type) {
3569 case SDDS_DOUBLE:
3570 sprintf(print_pos, fptr1, *(double *)ptr);
3571 break;
3572 case SDDS_FLOAT:
3573 sprintf(print_pos, fptr1, *(float *)ptr);
3574 break;
3575 case SDDS_LONG64:
3576 sprintf(print_pos, fptr1, *(int64_t *)ptr);
3577 break;
3578 case SDDS_ULONG64:
3579 sprintf(print_pos, fptr1, *(uint64_t *)ptr);
3580 break;
3581 case SDDS_LONG:
3582 sprintf(print_pos, fptr1, *(int32_t *)ptr);
3583 break;
3584 case SDDS_ULONG:
3585 sprintf(print_pos, fptr1, *(uint32_t *)ptr);
3586 break;
3587 case SDDS_SHORT:
3588 sprintf(print_pos, fptr1, *(short *)ptr);
3589 break;
3590 case SDDS_USHORT:
3591 sprintf(print_pos, fptr1, *(unsigned short *)ptr);
3592 break;
3593 case SDDS_CHARACTER:
3594 sprintf(print_pos, fptr1, *(char *)ptr);
3595 break;
3596 case SDDS_STRING:
3597 sprintf(print_pos, fptr1, *(char **)ptr);
3598 if (!sourceData[i].use_info)
3599 free(*ptr);
3600 break;
3601 default:
3602 SDDS_Bomb("error: unknown type encountered--this shouldn't happen (print_column_value)");
3603 break;
3604 }
3605 if (!sourceData[i].use_info)
3606 free(ptr);
3607 if (!(fptr1 = fptr2))
3608 break;
3609 *fptr1 = '%';
3610 }
3611 if ((target_type == SDDS_STRING &&
3612 !SDDS_SetRowValues(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, j, target_index, s, -1)) ||
3613 (target_type == SDDS_CHARACTER &&
3614 !SDDS_SetRowValues(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, j, target_index, s[0],
3615 -1))) {
3616 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3617 return (0);
3618 }
3619 }
3620 firstCall = 0;
3621 SDDS_Free(sourceData);
3622 return (1);
3623}
3624
3625FORMAT_DEFINITION *process_new_format_definition(char **argument, long arguments) {
3626 FORMAT_DEFINITION *defi;
3627 unsigned long flags;
3628
3629 if (!(defi = tmalloc(sizeof(*defi))))
3630 SDDS_Bomb("memory allocation failure (process_new_format_definition)");
3631 switch (match_string(argument[0], data_class_keyword, DATA_CLASS_KEYWORDS, 0)) {
3632 case COLUMN_BASED:
3633 defi->is_parameter = 0;
3634 break;
3635 case PARAMETER_BASED:
3636 defi->is_parameter = 1;
3637 break;
3638 default:
3639 fprintf(stderr, "error: column or parameter must be specified for format\n");
3640 return (NULL);
3641 }
3642 defi->target = argument[1];
3643 defi->source = argument[2];
3644 defi->stringFormat = NULL;
3645 defi->doubleFormat = NULL;
3646 defi->longFormat = NULL;
3647
3648 arguments -= 3;
3649 argument += 3;
3650 if (!scanItemList(&flags, argument, &arguments, 0,
3651 "stringformat", SDDS_STRING, &defi->stringFormat, 1, 0,
3652 "doubleformat", SDDS_STRING, &defi->doubleFormat, 1, 0,
3653 "longformat", SDDS_STRING, &defi->longFormat, 1, 0,
3654 NULL)) {
3655 bomb("invalid -format syntax", NULL);
3656 }
3657 return (defi);
3658}
3659
3660long format_parameter_value(SDDS_DATASET *SDDS_dataset, FORMAT_DEFINITION *definition) {
3661 static char *buffer = NULL;
3662 static long bufferSize = 0;
3663 char *ptr, *doubleFormat, *longFormat, *stringFormat;
3664 long target_index, source_index, bufferRequired;
3665
3666 if ((source_index = SDDS_GetParameterIndex(SDDS_dataset, definition->source)) < 0 || (target_index = SDDS_GetParameterIndex(SDDS_dataset, definition->target)) < 0) {
3667 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3668 return 0;
3669 }
3670 if (SDDS_GetParameterType(SDDS_dataset, source_index) != SDDS_STRING) {
3671 fprintf(stderr, "error: target parameter %s has wrong type for formatting--must be string\n", definition->source);
3672 return 0;
3673 }
3674 if (SDDS_GetParameterType(SDDS_dataset, target_index) != SDDS_STRING) {
3675 fprintf(stderr, "error: target parameter %s has wrong type for formatting--must be string\n", definition->target);
3676 return 0;
3677 }
3678 if (!(ptr = SDDS_GetParameter(SDDS_dataset, definition->source, NULL))) {
3679 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3680 return 0;
3681 }
3682 if ((bufferRequired = 2 * strlen(ptr) + 1024) > bufferSize) {
3683 /* guessing that string won't more than double in length */
3684 bufferSize = bufferRequired;
3685 if (!(buffer = SDDS_Realloc(buffer, sizeof(*buffer) * bufferRequired))) {
3686 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3687 return 0;
3688 }
3689 }
3690
3691 if (!(doubleFormat = definition->doubleFormat))
3692 doubleFormat = "%21.15e";
3693 if (!(longFormat = definition->longFormat))
3694 longFormat = "%ld";
3695 if (!(stringFormat = definition->stringFormat))
3696 stringFormat = "%s";
3697
3698 if (!reformatString(buffer, bufferSize, ptr, stringFormat, doubleFormat, longFormat))
3699 return 0;
3700
3701 if (!SDDS_SetParameters(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, target_index, buffer, -1)) {
3702 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3703 return 0;
3704 }
3705 return 1;
3706}
3707
3708long reformatString(char *buffer, long bufferSize, char *string, char *stringFormat,
3709 char *doubleFormat, char *longFormat) {
3710 long bufferUseLimit, length, lValue;
3711 double dValue;
3712 char *bufferPosition, *token0, *token1;
3713
3714 bufferPosition = buffer;
3715 *buffer = 0;
3716 bufferUseLimit = bufferSize * 0.9 + 1;
3717
3718 token1 = string;
3719 while ((token0 = strtok(token1, " "))) {
3720 token1 = NULL;
3721
3722 if (tokenIsInteger(token0)) {
3723 if (sscanf(token0, "%ld", &lValue) == 1)
3724 sprintf(bufferPosition, longFormat, lValue);
3725 else {
3726 fprintf(stderr, "Error: problem formatting token %s as long integer.\n", token0);
3727 return 0;
3728 }
3729 } else if (tokenIsNumber(token0)) {
3730 if (sscanf(token0, "%lf", &dValue) == 1)
3731 sprintf(bufferPosition, doubleFormat, dValue);
3732 else {
3733 fprintf(stderr, "Error: problem formatting token %s as double.\n", token0);
3734 return 0;
3735 }
3736 } else
3737 sprintf(bufferPosition, stringFormat, token0);
3738 if ((length = strlen(buffer)) > bufferUseLimit) {
3739 fprintf(stderr, "Error: format buffer overflow (sddsprocess).\n");
3740 return 0;
3741 }
3742 bufferPosition = buffer + length;
3743 *bufferPosition = ' ';
3744 *++bufferPosition = 0;
3745 }
3746 if ((--bufferPosition) >= buffer)
3747 *bufferPosition = 0;
3748 return 1;
3749}
3750
3751long format_column_value(SDDS_DATASET *SDDS_dataset, FORMAT_DEFINITION *definition) {
3752 static char *buffer = NULL;
3753 static long bufferSize = 0;
3754 char **ptr, *longFormat, *doubleFormat, *stringFormat;
3755 long source_index, target_index, bufferRequired;
3756 int64_t row, rows;
3757
3758 if ((source_index = SDDS_GetColumnIndex(SDDS_dataset, definition->source)) < 0 ||
3759 (target_index = SDDS_GetColumnIndex(SDDS_dataset, definition->target)) < 0) {
3760 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3761 return 0;
3762 }
3763 if (SDDS_GetColumnType(SDDS_dataset, source_index) != SDDS_STRING) {
3764 fprintf(stderr, "error: target column %s has wrong type for formatting--must be string\n", definition->source);
3765 return 0;
3766 }
3767 if (SDDS_GetColumnType(SDDS_dataset, target_index) != SDDS_STRING) {
3768 fprintf(stderr, "error: target column %s has wrong type for formatting--must be string\n", definition->target);
3769 return 0;
3770 }
3771 if ((rows = SDDS_CountRowsOfInterest(SDDS_dataset)) < 0) {
3772 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3773 return 0;
3774 }
3775 if (!(ptr = SDDS_GetColumn(SDDS_dataset, definition->source))) {
3776 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3777 return 0;
3778 }
3779
3780 if (!(doubleFormat = definition->doubleFormat))
3781 doubleFormat = "%21.15e";
3782 if (!(longFormat = definition->longFormat))
3783 longFormat = "%ld";
3784 if (!(stringFormat = definition->stringFormat))
3785 stringFormat = "%s";
3786
3787 for (row = 0; row < rows; row++) {
3788 if ((bufferRequired = 2 * strlen(ptr[row]) + 1024) > bufferSize) {
3789 bufferSize = bufferRequired;
3790 if (!(buffer = SDDS_Realloc(buffer, sizeof(*buffer) * bufferRequired))) {
3791 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3792 return 0;
3793 }
3794 }
3795 if (!reformatString(buffer, bufferSize, ptr[row], stringFormat, doubleFormat, longFormat)) {
3796 fprintf(stderr, "Error: problem formatting string >%s< (sddsprocess).\n",
3797 ptr[row]);
3798 return 0;
3799 }
3800 if (!SDDS_SetRowValues(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, row, target_index, buffer, -1)) {
3801 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
3802 return 0;
3803 }
3804 }
3805 return 1;
3806}
3807
3808void add_definition(DEFINITION **definition, long *definitions, void *structure, long type) {
3809 *definition = trealloc(*definition, sizeof(**definition) * (*definitions + 1));
3810 (*definition)[*definitions].structure = structure;
3811 (*definition)[*definitions].type = type;
3812 *definitions += 1;
3813}
3814
3815RPNTEST_DEFINITION *process_new_rpntest_definition(char **argument, long arguments) {
3816 RPNTEST_DEFINITION *defi;
3817 int i, algebraic = 0;
3818 char pfix[IFPF_BUF_SIZE];
3819
3820 if (!(defi = tmalloc(sizeof(*defi))))
3821 SDDS_Bomb("memory allocation failure (process_new_print_definition)");
3822 switch (match_string(argument[0], data_class_keyword, DATA_CLASS_KEYWORDS, 0)) {
3823 case COLUMN_BASED:
3824 defi->is_parameter = 0;
3825 break;
3826 case PARAMETER_BASED:
3827 defi->is_parameter = 1;
3828 break;
3829 default:
3830 fprintf(stderr, "error: column or parameter must be specified for rpntest\n");
3831 return (NULL);
3832 }
3833 defi->autostop = 0;
3834
3835 for (i = 2; i < arguments; i++) {
3836 if (strncmp(argument[i], "autostop", strlen(argument[i])) == 0)
3837 defi->autostop = 1;
3838 else if (strncmp(argument[i], "algebraic", strlen(argument[i])) == 0)
3839 algebraic = 1;
3840 else
3841 return (NULL);
3842 }
3843 if (algebraic) {
3844 char *ptr;
3845 ptr = addOuterParentheses(argument[1]);
3846 if2pf(pfix, ptr, sizeof pfix);
3847 free(ptr);
3848 if (!SDDS_CopyString(&defi->expression, pfix)) {
3849 fprintf(stderr, "error: problem copying argument string\n");
3850 return NULL;
3851 }
3852 } else
3853 defi->expression = argument[1];
3854 return (defi);
3855}
3856
3857RPNEXPRESSION_DEFINITION *process_new_rpnexpression_definition(char **argument, long arguments) {
3859 int i, algebraic = 0;
3860 char pfix[IFPF_BUF_SIZE];
3861
3862 if (arguments > 2)
3863 return (NULL);
3864 if (!(defi = tmalloc(sizeof(*defi))))
3865 SDDS_Bomb("memory allocation failure (process_new_rpnexpression_definition)");
3866 defi->repeat = 0;
3867
3868 for (i = 1; i < arguments; i++) {
3869 if (strncmp(argument[i], "repeat", strlen(argument[i])) == 0)
3870 defi->repeat = 1;
3871 else if (strncmp(argument[i], "algebraic", strlen(argument[i])) == 0)
3872 algebraic = 1;
3873 else
3874 return NULL;
3875 }
3876 if (algebraic) {
3877 char *ptr;
3878 ptr = addOuterParentheses(argument[0]);
3879 if2pf(pfix, ptr, sizeof pfix);
3880 free(ptr);
3881 if (!SDDS_CopyString(&defi->expression, pfix)) {
3882 fprintf(stderr, "error: problem copying argument string\n");
3883 return NULL;
3884 }
3885 } else
3886 defi->expression = argument[0];
3887 return (defi);
3888}
3889
3890CLIP_DEFINITION *process_new_clip_definition(char **argument, long arguments) {
3891 CLIP_DEFINITION *defi;
3892
3893 if (arguments < 2 || arguments > 3)
3894 return (NULL);
3895 if (!(defi = tmalloc(sizeof(*defi))))
3896 SDDS_Bomb("memory allocation failure (process_new_clip_definition)");
3897 if (sscanf(argument[0], "%" SCNd64, &defi->head) != 1 ||
3898 sscanf(argument[1], "%" SCNd64, &defi->tail) != 1 ||
3899 defi->head < 0 || defi->tail < 0)
3900 return NULL;
3901
3902 defi->invert = 0;
3903 if (arguments == 3) {
3904 if (strncmp(argument[2], "invert", strlen(argument[2])) != 0)
3905 return NULL;
3906 defi->invert = 1;
3907 }
3908 return (defi);
3909}
3910FCLIP_DEFINITION *process_new_fclip_definition(char **argument, long arguments) {
3911 FCLIP_DEFINITION *defi;
3912
3913 if (arguments < 2 || arguments > 3)
3914 return (NULL);
3915 if (!(defi = tmalloc(sizeof(*defi))))
3916 SDDS_Bomb("memory allocation failure (process_new_clip_definition)");
3917 if (sscanf(argument[0], "%le", &defi->fhead) != 1 ||
3918 sscanf(argument[1], "%le", &defi->ftail) != 1 ||
3919 defi->fhead < 0 || defi->ftail < 0)
3920 return NULL;
3921
3922 defi->invert = 0;
3923 if (arguments == 3) {
3924 if (strncmp(argument[2], "invert", strlen(argument[2])) != 0)
3925 return NULL;
3926 defi->invert = 1;
3927 }
3928 return (defi);
3929}
3930SPARSE_DEFINITION *process_new_sparse_definition(char **argument, long arguments) {
3931 SPARSE_DEFINITION *defi;
3932
3933 if (arguments < 1 || arguments > 2)
3934 return (NULL);
3935 if (!(defi = tmalloc(sizeof(*defi))))
3936 SDDS_Bomb("memory allocation failure (process_new_sparse_definition)");
3937 if (sscanf(argument[0], "%" SCNd64, &defi->interval) != 1 || defi->interval <= 0 ||
3938 (arguments == 2 && (sscanf(argument[1], "%" SCNd64, &defi->offset) != 1 || defi->offset < 0)))
3939 return NULL;
3940 return defi;
3941}
3942
3943SAMPLE_DEFINITION *process_new_sample_definition(char **argument, long arguments) {
3944 SAMPLE_DEFINITION *defi;
3945
3946 if (arguments < 1)
3947 return (NULL);
3948 if (!(defi = tmalloc(sizeof(*defi))))
3949 SDDS_Bomb("memory allocation failure (process_new_sample_definition)");
3950 if (sscanf(argument[0], "%lf", &defi->fraction) != 1)
3951 return NULL;
3952 return defi;
3953}
3954
3955SYSTEM_DEFINITION *process_new_system_definition(char **argument, long arguments) {
3956 static char s[SDDS_MAXLINE];
3957 char *ptr;
3958 long i;
3959 SYSTEM_DEFINITION *defi;
3960
3961 if (!(defi = tmalloc(sizeof(*defi))))
3962 SDDS_Bomb("memory allocation failure (process_new_system_definition)");
3963 switch (match_string(argument[0], data_class_keyword, DATA_CLASS_KEYWORDS, 0)) {
3964 case COLUMN_BASED:
3965 defi->is_parameter = 0;
3966 sprintf(s, "&column name=\"%s\", ", argument[1]);
3967 break;
3968 case PARAMETER_BASED:
3969 defi->is_parameter = 1;
3970 sprintf(s, "&parameter name=\"%s\", ", argument[1]);
3971 break;
3972 default:
3973 fprintf(stderr, "error: column or parameter must be specified for system\n");
3974 return (NULL);
3975 }
3976 defi->new_name = argument[1];
3977 defi->source = argument[2];
3978 for (i = 3; i < arguments; i++) {
3979 if (!(ptr = strchr(argument[i], '=')))
3980 return (NULL);
3981 *ptr = 0;
3982 if (strcmp(argument[i], "type") == 0)
3983 continue;
3984 strcat(s, argument[i]);
3985 strcat(s, "=\"");
3986 strcat(s, ptr + 1);
3987 strcat(s, "\", ");
3988 }
3989 strcat(s, " type=string &end");
3990 if (!SDDS_CopyString(&defi->text, s))
3991 SDDS_Bomb("unable to copy text of system definition (process_new_system_definition)");
3992 return (defi);
3993}
3994
3995long system_column_value(SDDS_DATASET *SDDS_dataset, char *target, char *source) {
3996 char **source_value, *command;
3997 int64_t i, rows;
3998 long target_index, source_index;
3999 static char s[SDDS_MAXLINE];
4000
4001 if ((source_index = SDDS_GetColumnIndex(SDDS_dataset, source)) < 0 ||
4002 (target_index = SDDS_GetColumnIndex(SDDS_dataset, target)) < 0) {
4003 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
4004 return (0);
4005 }
4006 if (SDDS_GetColumnType(SDDS_dataset, source_index) != SDDS_STRING) {
4007 fprintf(stderr, "error: source column %s has wrong type for system call--must be string\n", source);
4008 return (0);
4009 }
4010 if (SDDS_GetColumnType(SDDS_dataset, target_index) != SDDS_STRING) {
4011 fprintf(stderr, "error: target column %s has wrong type for system call--must be string\n", target);
4012 return (0);
4013 }
4014
4015 if ((rows = SDDS_CountRowsOfInterest(SDDS_dataset)) < 0) {
4016 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
4017 return (0);
4018 }
4019
4020 if (!(source_value = SDDS_GetInternalColumn(SDDS_dataset, source))) {
4021 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
4022 return (0);
4023 }
4024
4025 for (i = 0; i < rows; i++) {
4026 s[0] = 0;
4027 if ((command = source_value[i]) && !run_on_pipe(command, s, SDDS_MAXLINE)) {
4028 sprintf(s, "Problem with subprocess call (system_column_value)---command was\n%s\n",
4029 command);
4030 SDDS_SetError(s);
4031 return (0);
4032 }
4033 if (!SDDS_SetRowValues(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, i, target_index, s, -1)) {
4034 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
4035 return (0);
4036 }
4037 }
4038 return (1);
4039}
4040
4041long system_parameter_value(SDDS_DATASET *SDDS_dataset, char *target, char *source) {
4042 char *command, **ptr;
4043 long target_index, source_index;
4044 static char s[SDDS_MAXLINE];
4045
4046 if ((source_index = SDDS_GetParameterIndex(SDDS_dataset, source)) < 0 ||
4047 (target_index = SDDS_GetParameterIndex(SDDS_dataset, target)) < 0) {
4048 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
4049 return (0);
4050 }
4051 if (SDDS_GetParameterType(SDDS_dataset, source_index) != SDDS_STRING) {
4052 fprintf(stderr, "error: source parameter %s has wrong type for system call--must be string\n", source);
4053 return (0);
4054 }
4055 if (SDDS_GetParameterType(SDDS_dataset, target_index) != SDDS_STRING) {
4056 fprintf(stderr, "error: target parameter %s has wrong type for system call--must be string\n", target);
4057 return (0);
4058 }
4059
4060 if (!(ptr = SDDS_GetParameter(SDDS_dataset, source, NULL))) {
4061 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
4062 return (0);
4063 }
4064 s[0] = 0;
4065 if ((command = *ptr) && !run_on_pipe(command, s, SDDS_MAXLINE)) {
4066 sprintf(s, "Problem with subprocess call (system_parameter_value)---command was\n%s\n",
4067 command);
4068 SDDS_SetError(s);
4069 return (0);
4070 }
4071 if (!SDDS_SetParameters(SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, target_index, s, -1)) {
4072 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
4073 return (0);
4074 }
4075 if (command)
4076 free(command);
4077 free(ptr);
4078 return (1);
4079}
4080
4081long run_on_pipe(char *command, char *buffer, long buffer_length) {
4082 FILE *fp;
4083 long length;
4084
4085 if (!(fp = popen(command, "r")))
4086 return (0);
4087 buffer[0] = 0;
4088 if (!fgets(buffer, buffer_length, fp)) {
4089 pclose(fp);
4090 return (0);
4091 }
4092 if (buffer[(length = strlen(buffer)) - 1] == '\n')
4093 buffer[length - 1] = 0;
4094 pclose(fp);
4095 return (1);
4096}
4097
4098/* used for redefining parameters using sddsprocess-style commandline arguments */
4099long SDDS_RedefineParameterCL(SDDS_DATASET *SDDS_dataset, char *parameter, char **argv, long argc) {
4100 char *value, *keyword;
4101 long i;
4102
4103 for (i = 0; i < argc; i++) {
4104 keyword = argv[i];
4105 if (!(value = strchr(argv[i], '='))) {
4106 fprintf(stderr, "error: missing = in qualifier string for redefine: %s\n", argv[i]);
4107 return (0);
4108 }
4109 *value++ = 0;
4110 if (!SDDS_ChangeParameterInformation(SDDS_dataset, keyword, value, SDDS_PASS_BY_STRING | SDDS_SET_BY_NAME,
4111 parameter)) {
4112 fprintf(stderr, "Problem redefining %s for %s\n",
4113 keyword, parameter);
4114 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
4115 return (0);
4116 }
4117 *--value = '=';
4118 }
4119 return (1);
4120}
4121
4122/* used for redefining columns using sddsprocess-style commandline arguments */
4123long SDDS_RedefineColumnCL(SDDS_DATASET *SDDS_dataset, char *column, char **argv, long argc) {
4124 char *value, *keyword;
4125 long i;
4126
4127 for (i = 0; i < argc; i++) {
4128 keyword = argv[i];
4129 if (!(value = strchr(argv[i], '='))) {
4130 fprintf(stderr, "error: missing = in qualifier string for redefine: %s\n", argv[i]);
4131 return (0);
4132 }
4133 *value++ = 0;
4134 if (!SDDS_ChangeColumnInformation(SDDS_dataset, keyword, value, SDDS_PASS_BY_STRING | SDDS_SET_BY_NAME,
4135 column)) {
4136 fprintf(stderr, "Problem redefining %s for %s\n",
4137 keyword, column);
4138 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
4139 return (0);
4140 }
4141 *--value = '=';
4142 }
4143 return (1);
4144}
4145
4146long add_sddsfile_arguments(SCANNED_ARG **scanned, int argc) {
4147 long iarg, datacode, index, argc_got;
4148 int64_t j;
4149 SDDS_DATASET dataset;
4150 static char *choice[2] = {"column", "parameter"};
4151 char *dataname, *filename, **argv_got;
4152 SCANNED_ARG *sa_got;
4153
4154 index = 0;
4155
4156 argv_got = NULL;
4157 for (iarg = 0; iarg < argc; iarg++) {
4158 if (!((*scanned)[iarg].arg_type == OPTION) ||
4159 strcmp((*scanned)[iarg].list[0], "getargs") != 0 ||
4160 (*scanned)[iarg].n_items != 3 ||
4161 !(dataname = strchr((*scanned)[iarg].list[2], '=')) || (*dataname++ = 0) ||
4162 ((datacode = match_string((*scanned)[iarg].list[2], choice, 2, 0)) < 0))
4163 continue;
4164 filename = (*scanned)[iarg].list[1];
4165 if (!SDDS_InitializeInput(&dataset, filename))
4166 continue;
4167 if ((datacode == 0 && (index = SDDS_GetColumnIndex(&dataset, dataname)) < 0) ||
4168 (datacode == 1 && (index = SDDS_GetParameterIndex(&dataset, dataname)) < 0)) {
4169 fprintf(stderr, "error: %s %s not found in file %s--can't process -getargs request\n",
4170 choice[datacode], dataname, filename);
4171 /* SDDS_Terminate(&dataset); */
4172 exit(1);
4173 }
4174 if ((datacode == 0 && SDDS_GetColumnType(&dataset, index) != SDDS_STRING) ||
4175 (datacode == 1 && SDDS_GetParameterType(&dataset, index) != SDDS_STRING)) {
4176 fprintf(stderr, "error: %s %s from file %s does not have string type--can't use for -getargs\n",
4177 choice[datacode], dataname, filename);
4178 /* SDDS_Terminate(&dataset); */
4179 exit(1);
4180 }
4181
4182 argc_got = 0;
4183 switch (datacode) {
4184 case 0:
4185 while (SDDS_ReadPage(&dataset) > 0) {
4186 char **column;
4187 int64_t rows;
4188 if ((rows = SDDS_CountRowsOfInterest(&dataset)) <= 0)
4189 continue;
4190 if (!(column = SDDS_GetColumn(&dataset, dataname)))
4191 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
4192 argv_got = trealloc(argv_got, sizeof(*argv_got) * (rows + argc_got));
4193 for (j = 0; j < rows; j++) {
4194 delete_chars(column[j], "\"");
4195 argv_got[argc_got + j] = column[j];
4196 }
4197 free(column);
4198 argc_got += j;
4199 }
4200 break;
4201 case 1:
4202 while (SDDS_ReadPage(&dataset) > 0) {
4203 char *parameter;
4204 if (!SDDS_GetParameter(&dataset, dataname, &parameter))
4205 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
4206 argv_got = trealloc(argv_got, sizeof(*argv_got) * (argc_got + 1));
4207 argv_got[argc_got] = parameter;
4208 argc_got += 1;
4209 }
4210 break;
4211 default:
4212 break;
4213 }
4214 SDDS_Terminate(&dataset);
4215 argc_got = scanargsg(&sa_got, argc_got, argv_got);
4216 *scanned = trealloc(*scanned, sizeof(**scanned) * (argc + argc_got));
4217 if (argc_got > 1)
4218 for (j = argc - 1; j > iarg; j--)
4219 (*scanned)[j + argc_got - 1] = (*scanned)[j];
4220 for (j = 0; j < argc_got; j++)
4221 (*scanned)[j + iarg] = sa_got[j];
4222 argc += argc_got - 1;
4223 iarg += argc_got - 1;
4224 }
4225 return argc;
4226}
4227
4228long ParameterScansAsNumber(SDDS_DATASET *dataset, char *name, short invert) {
4229 char **ptr;
4230 double value;
4231 if (SDDS_CheckParameter(dataset, name, NULL, SDDS_STRING, stderr) != SDDS_CHECK_OKAY) {
4232 fprintf(stderr, "Error: parameter %s nonexistent or not string type---can't use with -numberTest\n",
4233 name);
4234 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
4235 exit(1);
4236 }
4237 if (!(ptr = SDDS_GetParameter(dataset, name, NULL))) {
4238 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
4239 exit(1);
4240 }
4241 if (sscanf(*ptr, "%lf", &value) != 1) {
4242 free(*ptr);
4243 return invert;
4244 }
4245 free(*ptr);
4246 return !invert;
4247}
4248
4249long cast_column_value(SDDS_DATASET *SDDS_dataset, CAST_DEFINITION *cast) {
4250 char **source_value, **target_value;
4251 long target_index, source_index, size;
4252 int64_t i, rows;
4253 long source_type, target_type;
4254 char s[1024];
4255
4256 if ((source_index = SDDS_GetColumnIndex(SDDS_dataset, cast->source)) < 0 ||
4257 (target_index = SDDS_GetColumnIndex(SDDS_dataset, cast->newName)) < 0) {
4258 sprintf(s, "Unable to cast %s to %s--column not found", cast->source,
4259 cast->newName);
4260 SDDS_SetError(s);
4261 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
4262 return (0);
4263 }
4264 source_type = SDDS_GetColumnType(SDDS_dataset, source_index);
4265 if (!SDDS_NUMERIC_TYPE(source_type)) {
4266 sprintf(s, "source column %s has wrong type for casting--must be number\n",
4267 cast->source);
4268 SDDS_SetError(s);
4269 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
4270 return (0);
4271 }
4272
4273 target_type = SDDS_GetColumnType(SDDS_dataset, target_index);
4274 if (!SDDS_NUMERIC_TYPE(target_type)) {
4275 sprintf(s, "target column %s has wrong type for casting--must be number\n",
4276 cast->newName);
4277 SDDS_SetError(s);
4278 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
4279 return (0);
4280 }
4281
4282 if ((rows = SDDS_CountRowsOfInterest(SDDS_dataset)) < 0) {
4283 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
4284 return (0);
4285 }
4286
4287 if (!(source_value = SDDS_GetInternalColumn(SDDS_dataset, cast->source))) {
4288 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
4289 return (0);
4290 }
4291 if (!(target_value = SDDS_GetInternalColumn(SDDS_dataset, cast->newName))) {
4292 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
4293 return (0);
4294 }
4295 size = SDDS_GetTypeSize(target_type);
4296 for (i = 0; i < rows; i++) {
4297 if (!SDDS_CastValue(source_value, i, source_type, target_type,
4298 (void *)((char *)target_value + size * i))) {
4299 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
4300 return (0);
4301 }
4302 }
4303 return (1);
4304}
4305
4306long cast_parameter_value(SDDS_DATASET *SDDS_dataset, CAST_DEFINITION *cast) {
4307 double doubleValue;
4308 int32_t targetIndex, sourceIndex;
4309 static char s[SDDS_MAXLINE];
4310
4311 if ((sourceIndex = SDDS_GetParameterIndex(SDDS_dataset, cast->source)) < 0 ||
4312 (targetIndex = SDDS_GetParameterIndex(SDDS_dataset, cast->newName)) < 0) {
4313 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
4314 return (0);
4315 }
4316 if (!SDDS_NUMERIC_TYPE(SDDS_GetParameterType(SDDS_dataset, sourceIndex))) {
4317 sprintf(s, "error: source parameter %s has wrong type for casting--must be number\n",
4318 cast->source);
4319 SDDS_SetError(s);
4320 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
4321 return (0);
4322 }
4323 if (!SDDS_NUMERIC_TYPE(SDDS_GetParameterType(SDDS_dataset, targetIndex))) {
4324 fprintf(stderr, "error: target parameter %s has wrong type for casting--must be number\n",
4325 cast->newName);
4326 return (0);
4327 }
4328
4329 if (!SDDS_GetParameterAsDouble(SDDS_dataset, cast->source, &doubleValue)) {
4330 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
4331 return (0);
4332 }
4333
4334 if (!SDDS_SetParametersFromDoubles(SDDS_dataset,
4335 SDDS_BY_INDEX | SDDS_PASS_BY_VALUE,
4336 targetIndex, doubleValue, -1)) {
4337 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
4338 return (0);
4339 }
4340 return (1);
4341}
4342
4343char *addOuterParentheses(char *arg) {
4344 char *ptr;
4345 ptr = tmalloc(sizeof(*ptr) * (strlen(arg) + 2));
4346 sprintf(ptr, "(%s)", arg);
4347 return ptr;
4348}
4349
4350void GillMillerIntegration1(double *indepData, double *data, long n_data, double *result) {
4351 double *integral;
4352 integral = tmalloc(sizeof(*integral) * n_data);
4353 GillMillerIntegration(integral, NULL, data, indepData, n_data);
4354 *result = integral[n_data - 1];
4355 free(integral);
4356}
int GillMillerIntegration(double *integral, double *error, double *f, double *x, long n)
Performs numerical integration using the Gill-Miller method.
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
char * SDDS_type_name[SDDS_NUM_TYPES]
Array of supported data type names.
Definition SDDS_data.c:43
int32_t SDDS_SetRowValues(SDDS_DATASET *SDDS_dataset, int32_t mode, int64_t row,...)
int32_t SDDS_SetParametersFromDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
int32_t * SDDS_GetParameterAsLong(SDDS_DATASET *SDDS_dataset, char *parameter_name, int32_t *memory)
Retrieves the value of a specified parameter as a 32-bit integer from the current data table of a dat...
void * SDDS_GetColumn(SDDS_DATASET *SDDS_dataset, char *column_name)
Retrieves a copy of the data for a specified column, including only rows marked as "of interest".
double * SDDS_GetParameterAsDouble(SDDS_DATASET *SDDS_dataset, char *parameter_name, double *memory)
Retrieves the value of a specified parameter as a double from the current data table of an SDDS datas...
int64_t SDDS_CountRowsOfInterest(SDDS_DATASET *SDDS_dataset)
Counts the number of rows marked as "of interest" in the current data table.
void * SDDS_GetInternalColumn(SDDS_DATASET *SDDS_dataset, char *column_name)
Retrieves an internal pointer to the data of a specified column, including all rows.
void * SDDS_GetParameter(SDDS_DATASET *SDDS_dataset, char *parameter_name, void *memory)
Retrieves the value of a specified parameter from the current data table of a data set.
void * SDDS_GetValue(SDDS_DATASET *SDDS_dataset, char *column_name, int64_t srow_index, void *memory)
Retrieves the value from a specified column and selected row, optionally storing it in provided memor...
double * SDDS_GetColumnInDoubles(SDDS_DATASET *SDDS_dataset, char *column_name)
Retrieves the data of a specified numerical column as an array of doubles, considering only rows mark...
int32_t SDDS_ChangeParameterInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode,...)
Modifies a specific field in a parameter definition within the SDDS dataset.
Definition SDDS_info.c:485
int32_t SDDS_GetParameterInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode,...)
Retrieves information about a specified parameter in the SDDS dataset.
Definition SDDS_info.c:117
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.
Definition SDDS_info.c:364
int32_t SDDS_GetColumnInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode,...)
Retrieves information about a specified column in the SDDS dataset.
Definition SDDS_info.c:41
int32_t SDDS_InitializeInput(SDDS_DATASET *SDDS_dataset, char *filename)
Definition SDDS_input.c:49
int32_t SDDS_Terminate(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_ReadPage(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_ProcessParameterString(SDDS_DATASET *SDDS_dataset, char *string, int32_t mode)
Process a parameter definition string.
int32_t SDDS_ParseNamelist(void *data, SDDS_FIELD_INFORMATION *fieldInfo, int32_t fieldInfos, char *s)
Parse a namelist string and populate the corresponding data structure.
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.
int32_t SDDS_TransferParameterDefinition(SDDS_DATASET *target, SDDS_DATASET *source, char *name, char *newName)
Transfers a parameter definition from a source dataset to a target dataset.
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
Definition SDDS_utils.c:379
int32_t SDDS_GetParameterType(SDDS_DATASET *SDDS_dataset, int32_t index)
Retrieves the data type of a parameter in the SDDS dataset by its index.
int32_t SDDS_GetArrayIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named array in the SDDS dataset.
PARAMETER_DEFINITION * SDDS_GetParameterDefinition(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the definition of a specified parameter from the SDDS dataset.
int32_t SDDS_FreeParameterDefinition(PARAMETER_DEFINITION *source)
Frees memory allocated for a parameter definition.
int32_t SDDS_GetParameterIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named parameter in the SDDS dataset.
int32_t SDDS_GetColumnIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named column in the SDDS dataset.
int32_t SDDS_MatchParameters(SDDS_DATASET *SDDS_dataset, char ***nameReturn, int32_t matchMode, int32_t typeMode,...)
Matches and retrieves parameter names from an SDDS dataset based on specified criteria.
void * SDDS_CastValue(void *data, int64_t index, int32_t data_type, int32_t desired_type, void *memory)
Casts a value from one SDDS data type to another.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
Definition SDDS_utils.c:432
int32_t SDDS_CopyStringArray(char **target, char **source, int64_t n_strings)
Copies an array of strings from source to target.
void * SDDS_Malloc(size_t size)
Allocates memory of a specified size.
Definition SDDS_utils.c:639
int32_t SDDS_IdentifyType(char *typeName)
Identifies the SDDS data type based on its string name.
int32_t SDDS_GetTypeSize(int32_t type)
Retrieves the size in bytes of a specified SDDS data type.
int32_t SDDS_StringIsBlank(char *s)
Checks if a string is blank (contains only whitespace characters).
int32_t SDDS_MatchColumns(SDDS_DATASET *SDDS_dataset, char ***nameReturn, int32_t matchMode, int32_t typeMode,...)
Matches and retrieves column names from an SDDS dataset based on specified criteria.
int32_t SDDS_GetColumnType(SDDS_DATASET *SDDS_dataset, int32_t index)
Retrieves the data type of a column in the SDDS dataset by its index.
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:342
int32_t SDDS_CheckParameter(SDDS_DATASET *SDDS_dataset, char *name, char *units, int32_t type, FILE *fp_message)
Checks if a parameter exists in the SDDS dataset with the specified name, units, and type.
int32_t SDDS_CopyString(char **target, const char *source)
Copies a source string to a target string with memory allocation.
Definition SDDS_utils.c:856
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
Definition SDDS_utils.c:677
int32_t SDDS_PrintTypedValue(void *data, int64_t index, int32_t type, char *format, FILE *fp, uint32_t mode)
Prints a data value of a specified type using an optional printf format string.
Definition SDDS_utils.c:59
void SDDS_Free(void *mem)
Free memory previously allocated by SDDS_Malloc.
Definition SDDS_utils.c:655
COLUMN_DEFINITION * SDDS_GetColumnDefinition(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the definition of a specified column from the SDDS dataset.
Definition SDDS_utils.c:978
#define SDDS_NUM_TYPES
Total number of defined SDDS data types.
Definition SDDStypes.h:97
#define SDDS_ULONG
Identifier for the unsigned 32-bit integer data type.
Definition SDDStypes.h:67
#define SDDS_FLOAT
Identifier for the float data type.
Definition SDDStypes.h:43
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
#define SDDS_ULONG64
Identifier for the unsigned 64-bit integer data type.
Definition SDDStypes.h:55
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
Definition SDDStypes.h:61
#define SDDS_SHORT
Identifier for the signed short integer data type.
Definition SDDStypes.h:73
#define SDDS_CHARACTER
Identifier for the character data type.
Definition SDDStypes.h:91
#define SDDS_USHORT
Identifier for the unsigned short integer data type.
Definition SDDStypes.h:79
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37
#define SDDS_NUMERIC_TYPE(type)
Checks if the given type identifier corresponds to any numeric type.
Definition SDDStypes.h:138
#define SDDS_LONGDOUBLE
Identifier for the long double data type.
Definition SDDStypes.h:31
#define SDDS_LONG64
Identifier for the signed 64-bit integer data type.
Definition SDDStypes.h:49
void * trealloc(void *old_ptr, uint64_t size_of_block)
Reallocates a memory block to a new size.
Definition array.c:181
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:59
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
long bombre(char *error, char *usage, long return_value)
Reports error messages to the terminal and returns a specified value.
Definition bomb.c:44
int get_double(double *dptr, char *s)
Parses a double value from the given string.
Definition data_scan.c:40
long tokenIsNumber(char *token)
Checks if the given token represents a valid number.
Definition data_scan.c:530
int get_int(int *iptr, char *s)
Parses an integer value from the given string.
Definition data_scan.c:380
long tokenIsInteger(char *token)
Checks if the given token represents a valid integer.
Definition data_scan.c:509
char * delete_chars(char *s, char *t)
Removes all occurrences of characters found in string t from string s.
void edit_strings(char **string, long strings, char *buffer, char *edit)
Applies edit commands to an array of strings.
int index_min_max(int64_t *imin, int64_t *imax, double *list, int64_t n)
Finds the indices of the minimum and maximum values in a list of doubles.
Definition findMinMax.c:116
FILE * fopen_e(char *file, char *open_mode, long mode)
Opens a file with error checking, messages, and aborts.
Definition fopen_e.c:30
char * get_token_tq(char *s, char *ts, char *te, char *qs, char *qe)
Extracts a token from a string with support for multiple delimiter and quotation sets.
long is_blank(char *s)
Determine whether a string is composed entirely of whitespace characters.
Definition is_blank.c:27
double linearCorrelationCoefficient(double *data1, double *data2, short *accept1, short *accept2, long rows, long *count)
Compute the linear correlation coefficient for two data sets.
Definition lincorr.c:32
long unweightedLinearFit(double *xData, double *yData, long nData, double *slope, double *intercept, double *variance)
Performs an unweighted linear fit on the provided data.
Definition linfit.c:37
double getTimeInSecs()
Get the current time in seconds since the Epoch with high resolution.
long computeMode(double *result, double *data, long pts, double binSize, long bins)
Computes the mode of a dataset using histogram binning.
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 strncmp_case_insensitive(char *s1, char *s2, long n)
Compares up to a specified number of characters of two strings in a case-insensitive manner.
long compute_percentiles(double *position, double *percent, long positions, double *x, long n)
Computes multiple percentiles of an array of doubles.
Definition median.c:84
long compute_median(double *value, double *x, long n)
Computes the median of an array of doubles.
Definition median.c:29
double weightedStDevThreaded(double *y, double *w, long n, long numThreads)
Calculates the weighted standard deviation of an array of doubles using multiple threads.
Definition moments.c:910
double standardDeviationThreaded(double *x, long n, long numThreads)
Calculates the standard deviation of an array of doubles using multiple threads.
Definition moments.c:51
double rmsValueThreaded(double *y, long n, long numThreads)
Calculates the RMS (Root Mean Square) value of an array of doubles using multiple threads.
Definition moments.c:597
double arithmeticAverageThreaded(double *y, long n, long numThreads)
Calculates the arithmetic average of an array of doubles using multiple threads.
Definition moments.c:547
double weightedRMSThreaded(double *y, double *w, long n, long numThreads)
Calculates the weighted RMS (Root Mean Square) value of an array of doubles using multiple threads.
Definition moments.c:774
double meanAbsoluteDeviationThreaded(double *y, long n, long numThreads)
Calculates the mean absolute deviation of an array of doubles using multiple threads.
Definition moments.c:647
double weightedMADThreaded(double *y, double *w, long n, long numThreads)
Calculates the weighted mean absolute deviation of an array of doubles using multiple threads.
Definition moments.c:833
double weightedAverageThreaded(double *y, double *w, long n, long numThreads)
Calculates the weighted average of an array of doubles using multiple threads.
Definition moments.c:715
int scanargsg(SCANNED_ARG **scanned, int argc, char **argv)
Definition scanargs.c:163
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.
short TimeBreakdownToEpoch(short year, short jDay, short month, short day, double hour, double *epochTime)
Converts a broken-down time into epoch time.
long findTopBaseLevels(double *top, double *base, double *data, int64_t points, long bins, double sigmasRequired)
Finds the top-level and base-level of a dataset.
Definition topbase.c:36
int64_t findCrossingPoint(int64_t start, double *data, int64_t points, double level, long direction, double *indepData, double *location)
Finds the crossing point in the data where the data crosses a specified level.
Definition topbase.c:118
long trapazoidIntegration(double *x, double *y, long n, double *integral)
Computes the integral of a dataset using the trapezoidal rule.
Definition trapInteg.c:29
int has_wildcards(char *template)
Check if a template string contains any wildcard characters.
Definition wild_match.c:498
int wild_match(char *string, char *template)
Determine whether one string is a wildcard match for another.
Definition wild_match.c:49
char * unescape_wildcards(char *template)
Remove escape characters from wildcard characters in a template string.
Definition wild_match.c:534