SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
sddssort.c
Go to the documentation of this file.
1/**
2 * @file sddssort.c
3 * @brief Sorts an SDDS dataset by column or parameter values.
4 *
5 * @details
6 * The `sddssort` program provides flexible sorting capabilities for SDDS datasets. Users can sort by one or more
7 * columns or parameters, perform unique row elimination, and handle multi-criteria optimization through
8 * non-dominated sorting. The program supports numeric sorting, absolute value sorting, and major order changes
9 * for row or column storage.
10 *
11 * @section Usage
12 * ```
13 * sddssort [<inputfile>] [<outputfile>]
14 * [-pipe=[input][,output]]
15 * [-column=<name>[,{increasing|decreasing}|{minimize|maximize}][,absolute]...]
16 * [-unique[=count]]
17 * [-nowarnings]
18 * [-parameter=<name>[,{increasing|decreasing}]...]
19 * [-numericHigh]
20 * [-nonDominateSort]
21 * [-majorOrder=row|column]
22 * ```
23 *
24 * @section Options
25 * | Optional | Description |
26 * |---------------------------------------|---------------------------------------------------------------------------------------|
27 * | `-pipe` | Enables piping for input and/or output. |
28 * | `-column` | Specifies columns for sorting with optional modifiers. |
29 * | `-unique` | Removes duplicate rows. If `count` is specified, includes an `IdenticalCount` column. |
30 * | `-nowarnings` | Suppresses warning messages. |
31 * | `-parameter` | Specifies parameters for sorting with optional modifiers. |
32 * | `-numericHigh` | Prioritizes numeric characters in string comparisons. |
33 * | `-nonDominateSort` | Enables non-dominated sorting for numeric columns. |
34 * | `-majorOrder` | Changes the data storage order to row-major or column-major. |
35 *
36 * @subsection spec_req Specific Requirements
37 * - For `-nonDominateSort`:
38 * - Requires at least two columns.
39 * - Columns must contain numeric data types.
40 *
41 * @copyright
42 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
43 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
44 *
45 * @license
46 * This file is distributed under the terms of the Software License Agreement
47 * found in the file LICENSE included with this distribution.
48 *
49 * @author
50 * M. Borland, C. Saunders, R. Soliday, H. Shang
51 */
52
53#include "mdb.h"
54#include "SDDS.h"
55#include "scan.h"
56#include "non_dominated_sort.h"
57#if defined(_WIN32)
58# include <process.h>
59# define pid_t int
60#else
61# if defined(linux)
62# include <sys/types.h>
63# endif
64# include <unistd.h>
65#endif
66
67/* Enumeration for option types */
68enum option_type {
69 SET_COLUMN,
70 SET_PARAMETER,
71 SET_NOWARNINGS,
72 SET_PIPE,
73 SET_UNIQUE,
74 SET_NUMERICHIGH,
75 SET_NON_DOMINATE_SORT,
76 SET_MAJOR_ORDER,
77 N_OPTIONS
78};
79
80char *option[N_OPTIONS] = {
81 "column",
82 "parameter",
83 "nowarnings",
84 "pipe",
85 "unique",
86 "numerichigh",
87 "nonDominateSort",
88 "majorOrder",
89};
90
91/* Improved Usage Message */
92char *USAGE =
93 "sddssort [<SDDSinput>] [<SDDSoutput>]\n"
94 " [-pipe=[input][,output]]\n"
95 " [-column=<name>[,{increasing|decreasing}|{minimize|maximize}][,absolute]...] \n"
96 " [-unique[=count]]\n"
97 " [-nowarnings] \n"
98 " [-parameter=<name>[,{increasing|decreasing}]...]\n"
99 " [-numericHigh] \n"
100 " [-nonDominateSort] \n"
101 " [-majorOrder=row|column]\n"
102 "Options:\n"
103 " -pipe=[input][,output]\n"
104 " Enable piping for input and/or output.\n\n"
105 " -column=<name>[,{increasing|decreasing}|{minimize|maximize}][,absolute]...\n"
106 " Specify one or more columns to sort by.\n"
107 " - 'increasing' or 'decreasing' sets the sorting direction for regular sorting.\n"
108 " - 'minimize' or 'maximize' sets the sorting direction for non-dominated sorting.\n"
109 " - 'absolute' sorts based on absolute values.\n\n"
110 " -unique[=count]\n"
111 " Eliminate duplicate rows based on sort columns.\n"
112 " If 'count' is specified, an 'IdenticalCount' column is added to indicate the number of identical rows.\n\n"
113 " -nowarnings\n"
114 " Suppress warning messages.\n\n"
115 " -parameter=<name>[,{increasing|decreasing}]...\n"
116 " Specify parameters to sort by.\n\n"
117 " -numericHigh\n"
118 " Prioritize numeric characters over other characters in string comparisons.\n"
119 " Also ranks numeric character sets with fewer characters below those with more characters.\n\n"
120 " -nonDominateSort\n"
121 " Perform non-dominated sorting when multiple sort columns are provided.\n"
122 " Note: Non-dominated sorting only works for numeric columns.\n\n"
123 " -majorOrder=row|column\n"
124 " Set the major order for data storage, either row-major or column-major.\n\n"
125 "Program by Michael Borland. (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ")\n";
126
127typedef struct
128{
129 char *name;
130 long index, type;
131 short decreasing_order, maximize_order, absolute;
132 double *data;
134
135static char *order_mode[5] = {
136 "increasing",
137 "decreasing",
138 "minimize",
139 "maximize",
140 "absolute",
141};
142
143long SDDS_SortRows(SDDS_DATASET *SDDS_dataset, SORT_REQUEST *xsort_request, long xsort_requests, long non_dominate_sort);
144long SDDS_UnsetDuplicateRows(SDDS_DATASET *SDDS_dataset, SORT_REQUEST *xsort_request, long xsort_requests, long provideIdenticalCount);
145
146long SDDS_SortAll(SDDS_DATASET *SDDS_input, SDDS_DATASET *SDDS_output, SORT_REQUEST *xsort_request, long xsort_requests,
147 SORT_REQUEST *xsort_parameter, long xsort_parameters, long uniqueRows, long provideIdenticalCount,
148 long pipeFlags, long non_dominate_sort);
149
150double *read_constr_violation(SDDS_DATASET *SDDS_dataset);
151
152long numericHigh = 0, constDefined = 0;
153
154int main(int argc, char **argv) {
155 SDDS_DATASET SDDS_input, SDDS_output, SDDS_tmp;
156 char *input, *output;
157 long i_arg, non_dominate_sort = 0;
158 SCANNED_ARG *s_arg;
159
160 long tmpfile_used, sort_requests, noWarnings, uniqueRows, provideIdenticalCount, tmpfileForInternalPipe;
161 long sort_parameters;
162 SORT_REQUEST *sort_request, *sort_parameter;
163 unsigned long pipeFlags, majorOrderFlag;
164 short columnMajorOrder = -1;
165
167 argc = scanargs(&s_arg, argc, argv);
168 if (argc < 2) {
169 bomb(NULL, USAGE);
170 }
171
172 input = output = NULL;
173 tmpfile_used = sort_requests = noWarnings = sort_parameters = tmpfileForInternalPipe = 0;
174 sort_request = sort_parameter = NULL;
175 pipeFlags = 0;
176 uniqueRows = provideIdenticalCount = 0;
177 for (i_arg = 1; i_arg < argc; i_arg++) {
178 if (s_arg[i_arg].arg_type == OPTION) {
179 switch (match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
180 case SET_MAJOR_ORDER:
181 majorOrderFlag = 0;
182 s_arg[i_arg].n_items--;
183 if (s_arg[i_arg].n_items > 0 &&
184 (!scanItemList(&majorOrderFlag, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
185 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
186 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
187 SDDS_Bomb("invalid -majorOrder syntax/values");
188 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
189 columnMajorOrder = 1;
190 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
191 columnMajorOrder = 0;
192 break;
193 case SET_NON_DOMINATE_SORT:
194 non_dominate_sort = 1;
195 break;
196 case SET_COLUMN:
197 if (s_arg[i_arg].n_items < 2 || s_arg[i_arg].n_items > 4)
198 SDDS_Bomb("invalid -column syntax");
199 sort_request = trealloc(sort_request, sizeof(*sort_request) * (sort_requests + 1));
200 sort_request[sort_requests].name = s_arg[i_arg].list[1];
201 sort_request[sort_requests].maximize_order = 0;
202 sort_request[sort_requests].decreasing_order = 0;
203 sort_request[sort_requests].absolute = 0;
204 if (s_arg[i_arg].n_items >= 3) {
205 int j;
206 for (j = 2; j < s_arg[i_arg].n_items; j++) {
207 switch (match_string(s_arg[i_arg].list[j], order_mode, 5, 0)) {
208 case 0:
209 break;
210 case 1:
211 sort_request[sort_requests].decreasing_order = 1;
212 break;
213 case 2:
214 break;
215 case 3:
216 sort_request[sort_requests].maximize_order = 1;
217 break;
218 case 4:
219 sort_request[sort_requests].absolute = 1;
220 break;
221 default:
222 fprintf(stderr, "unknown sort order specified--give 'increasing' or 'decreasing' for dominated sorting\n or'maximize' or 'minimize' for non-dominated-sorting.\n");
223 exit(EXIT_FAILURE);
224 break;
225 }
226 }
227 }
228 sort_requests++;
229 break;
230 case SET_PARAMETER:
231 if (s_arg[i_arg].n_items < 2 || s_arg[i_arg].n_items > 3)
232 SDDS_Bomb("invalid -parameter syntax");
233 sort_parameter = trealloc(sort_parameter, sizeof(*sort_parameter) * (sort_parameters + 1));
234 sort_parameter[sort_parameters].name = s_arg[i_arg].list[1];
235 if (s_arg[i_arg].n_items == 3) {
236 if ((sort_parameter[sort_parameters].decreasing_order = match_string(s_arg[i_arg].list[2], order_mode, 2, 0)) < 0)
237 SDDS_Bomb("unknown sort order specified--give 'increasing' or 'decreasing'");
238 } else
239 sort_parameter[sort_parameters].decreasing_order = 0;
240 sort_parameters++;
241 break;
242 case SET_NOWARNINGS:
243 noWarnings = 1;
244 break;
245 case SET_NUMERICHIGH:
246 numericHigh = 1;
247 break;
248 case SET_PIPE:
249 if (!processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
250 SDDS_Bomb("invalid -pipe syntax");
251 break;
252 case SET_UNIQUE:
253 uniqueRows = 1;
254 if (s_arg[i_arg].n_items > 1) {
255 str_tolower(s_arg[i_arg].list[1]);
256 if (s_arg[i_arg].n_items > 2 ||
257 strncmp("count", s_arg[i_arg].list[1], strlen(s_arg[i_arg].list[1])) != 0)
258 SDDS_Bomb("invalid -unique syntax");
259 provideIdenticalCount = 1;
260 }
261 break;
262 default:
263 fprintf(stderr, "error: unknown switch: %s\n", s_arg[i_arg].list[0]);
264 exit(EXIT_FAILURE);
265 break;
266 }
267 } else {
268 if (input == NULL)
269 input = s_arg[i_arg].list[0];
270 else if (output == NULL)
271 output = s_arg[i_arg].list[0];
272 else
273 SDDS_Bomb("too many filenames");
274 }
275 }
276
277 if (!sort_requests && !sort_parameters)
278 SDDS_Bomb("No sorting requests!");
279 processFilenames("sddssort", &input, &output, pipeFlags, noWarnings, &tmpfile_used);
280 if (!SDDS_InitializeInput(&SDDS_input, input)) {
281 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
282 exit(EXIT_FAILURE);
283 }
284 if (sort_requests <= 1)
285 non_dominate_sort = 0;
286
287 if (SDDS_input.layout.popenUsed) {
288 /* SDDS library has opened the file using a command on a pipe, usually for
289 * decompression in the absence of the zlib library.
290 */
291 pid_t pid;
292 char tmpfileName[1024];
293 pid = getpid();
294 sprintf(tmpfileName, "/tmp/sddssort.%ld", (long)pid);
295 tmpfileForInternalPipe = 1;
296 if (!SDDS_InitializeCopy(&SDDS_tmp, &SDDS_input, tmpfileName, "w")) {
297 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
298 exit(EXIT_FAILURE);
299 }
300 if (columnMajorOrder != -1)
301 SDDS_tmp.layout.data_mode.column_major = columnMajorOrder;
302 else
303 SDDS_tmp.layout.data_mode.column_major = SDDS_input.layout.data_mode.column_major;
304 if (non_dominate_sort) {
305 if (!SDDS_DefineSimpleColumn(&SDDS_output, "Rank", NULL, SDDS_LONG) ||
306 !SDDS_DefineSimpleColumn(&SDDS_output, "CrowdingDistance", NULL, SDDS_DOUBLE)) {
307 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
308 exit(EXIT_FAILURE);
309 }
310 if (SDDS_CheckColumn(&SDDS_input, "ConstraintsViolation", NULL, SDDS_ANY_NUMERIC_TYPE, NULL) != SDDS_CHECK_OK) {
311 if (!SDDS_DefineSimpleColumn(&SDDS_output, "ConstraintsViolation", NULL, SDDS_DOUBLE))
312 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
313 constDefined = 1;
314 }
315 }
316
317 if (!SDDS_WriteLayout(&SDDS_tmp)) {
318 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
319 exit(EXIT_FAILURE);
320 }
321 while (SDDS_ReadPage(&SDDS_input) > 0) {
322 if (!SDDS_CopyPage(&SDDS_tmp, &SDDS_input) || !SDDS_WritePage(&SDDS_tmp)) {
323 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
324 exit(EXIT_FAILURE);
325 }
326 }
327 if (!SDDS_Terminate(&SDDS_tmp)) {
328 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
329 exit(EXIT_FAILURE);
330 }
331 if (!SDDS_InitializeInput(&SDDS_input, tmpfileName)) {
332 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
333 exit(EXIT_FAILURE);
334 }
335 }
336 if (!SDDS_InitializeCopy(&SDDS_output, &SDDS_input, output, "w")) {
337 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
338 exit(EXIT_FAILURE);
339 }
340 if (columnMajorOrder != -1)
341 SDDS_output.layout.data_mode.column_major = columnMajorOrder;
342 else
343 SDDS_output.layout.data_mode.column_major = SDDS_input.layout.data_mode.column_major;
344 if (provideIdenticalCount &&
345 !SDDS_DefineSimpleColumn(&SDDS_output, "IdenticalCount", NULL, SDDS_LONG64)) {
346 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
347 exit(EXIT_FAILURE);
348 }
349 if (non_dominate_sort) {
350 if (!SDDS_DefineSimpleColumn(&SDDS_output, "Rank", NULL, SDDS_LONG) ||
351 !SDDS_DefineSimpleColumn(&SDDS_output, "CrowdingDistance", NULL, SDDS_DOUBLE)) {
352 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
353 exit(EXIT_FAILURE);
354 }
355 if (SDDS_CheckColumn(&SDDS_input, "ConstraintsViolation", NULL, SDDS_ANY_NUMERIC_TYPE, NULL) != SDDS_CHECK_OK) {
356 if (!SDDS_DefineSimpleColumn(&SDDS_output, "ConstraintsViolation", NULL, SDDS_DOUBLE))
357 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
358 constDefined = 1;
359 }
360 }
361 if (!SDDS_WriteLayout(&SDDS_output))
362 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
363 if (!SDDS_SortAll(&SDDS_input, &SDDS_output, sort_request, sort_requests, sort_parameter, sort_parameters,
364 uniqueRows, provideIdenticalCount, pipeFlags, non_dominate_sort)) {
365 SDDS_SetError("Problem sorting data");
366 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
367 }
368 if (!SDDS_Terminate(&SDDS_input) || !SDDS_Terminate(&SDDS_output)) {
369 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
370 exit(EXIT_FAILURE);
371 }
372 if (tmpfile_used && !replaceFileAndBackUp(input, output))
373 exit(EXIT_FAILURE);
374 free_scanargs(&s_arg, argc);
375 /* if (tmpfileForInternalPipe)
376 system("rm /tmp/tmpfile"); */
377 return EXIT_SUCCESS;
378}
379
380static SDDS_DATASET *SDDS_sort;
381static SORT_REQUEST *sort_request;
382static long sort_requests;
383static int64_t *sort_row_index;
384
385int SDDS_CompareData(SDDS_DATASET *SDDS_dataset, short type, short absolute, void *data1, void *data2) {
386 double ldouble_diff;
387 double double_diff;
388 float float_diff;
389 int32_t long_diff;
390 int64_t long64_diff;
391 short short_diff;
392 int char_diff;
393
394 if (!absolute) {
395 switch (type) {
396 case SDDS_LONGDOUBLE:
397 if ((ldouble_diff = *(long double *)data1 - *(long double *)data2) > 0)
398 return (1);
399 else if (ldouble_diff < 0)
400 return (-1);
401 return (0);
402 case SDDS_DOUBLE:
403 if ((double_diff = *(double *)data1 - *(double *)data2) > 0)
404 return (1);
405 else if (double_diff < 0)
406 return (-1);
407 return (0);
408 case SDDS_FLOAT:
409 if ((float_diff = *(float *)data1 - *(float *)data2) > 0)
410 return (1);
411 else if (float_diff < 0)
412 return (-1);
413 return (0);
414 case SDDS_LONG64:
415 if ((long64_diff = *(int64_t *)data1 - *(int64_t *)data2) > 0)
416 return (1);
417 else if (long64_diff < 0)
418 return (-1);
419 return (0);
420 case SDDS_LONG:
421 if ((long_diff = *(int32_t *)data1 - *(int32_t *)data2) > 0)
422 return (1);
423 else if (long_diff < 0)
424 return (-1);
425 return (0);
426 case SDDS_SHORT:
427 if ((short_diff = *(short *)data1 - *(short *)data2) > 0)
428 return (1);
429 else if (short_diff < 0)
430 return (-1);
431 return (0);
432 case SDDS_ULONG64:
433 if (*(uint64_t *)data1 > *(uint64_t *)data2)
434 return 1;
435 if (*(uint64_t *)data1 < *(uint64_t *)data2)
436 return -1;
437 return 0;
438 case SDDS_ULONG:
439 if (*(uint32_t *)data1 > *(uint32_t *)data2)
440 return 1;
441 if (*(uint32_t *)data1 < *(uint32_t *)data2)
442 return -1;
443 return 0;
444 case SDDS_USHORT:
445 if (*(unsigned short *)data1 > *(unsigned short *)data2)
446 return 1;
447 if (*(unsigned short *)data1 < *(unsigned short *)data2)
448 return -1;
449 return 0;
450 case SDDS_CHARACTER:
451 if ((char_diff = *(char *)data1 - *(char *)data2) > 0)
452 return (1);
453 else if (char_diff < 0)
454 return (-1);
455 return (0);
456 case SDDS_STRING:
457 if (numericHigh)
458 return (strcmp_nh(*(char **)data1, *(char **)data2));
459 else
460 return (strcmp(*(char **)data1, *(char **)data2));
461 default:
462 SDDS_SetError("Problem doing data comparison--invalid data type (SDDS_CompareData)");
463 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
464 exit(EXIT_FAILURE);
465 }
466 } else {
467 switch (type) {
468 case SDDS_LONGDOUBLE:
469 if ((ldouble_diff = fabsl(*(long double *)data1) - fabsl(*(long double *)data2)) > 0)
470 return (1);
471 else if (ldouble_diff < 0)
472 return (-1);
473 return (0);
474 case SDDS_DOUBLE:
475 if ((double_diff = fabs(*(double *)data1) - fabs(*(double *)data2)) > 0)
476 return (1);
477 else if (double_diff < 0)
478 return (-1);
479 return (0);
480 case SDDS_FLOAT:
481 if ((float_diff = fabsf(*(float *)data1) - fabsf(*(float *)data2)) > 0)
482 return (1);
483 else if (float_diff < 0)
484 return (-1);
485 return (0);
486 case SDDS_LONG64:
487 if ((long64_diff = llabs(*(int64_t *)data1) - llabs(*(int64_t *)data2)) > 0)
488 return (1);
489 else if (long64_diff < 0)
490 return (-1);
491 return (0);
492 case SDDS_LONG:
493 if ((long_diff = labs(*(int32_t *)data1) - labs(*(int32_t *)data2)) > 0)
494 return (1);
495 else if (long_diff < 0)
496 return (-1);
497 return (0);
498 case SDDS_SHORT:
499 if ((short_diff = abs(*(short *)data1) - abs(*(short *)data2)) > 0)
500 return (1);
501 else if (short_diff < 0)
502 return (-1);
503 return (0);
504 case SDDS_ULONG64:
505 if (*(uint64_t *)data1 > *(uint64_t *)data2)
506 return (1);
507 if (*(uint64_t *)data1 < *(uint64_t *)data2)
508 return (-1);
509 return (0);
510 case SDDS_ULONG:
511 if (*(uint32_t *)data1 > *(uint32_t *)data2)
512 return (1);
513 if (*(uint32_t *)data1 < *(uint32_t *)data2)
514 return (-1);
515 return (0);
516 case SDDS_USHORT:
517 if (*(unsigned short *)data1 > *(unsigned short *)data2)
518 return (1);
519 if (*(unsigned short *)data1 < *(unsigned short *)data2)
520 return (-1);
521 return (0);
522 case SDDS_CHARACTER:
523 if ((char_diff = *(char *)data1 - *(char *)data2) > 0)
524 return (1);
525 else if (char_diff < 0)
526 return (-1);
527 return (0);
528 case SDDS_STRING:
529 if (numericHigh)
530 return (strcmp_nh(*(char **)data1, *(char **)data2));
531 else
532 return (strcmp(*(char **)data1, *(char **)data2));
533 default:
534 SDDS_SetError("Problem doing data comparison--invalid data type (SDDS_CompareData)");
535 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
536 exit(EXIT_FAILURE);
537 }
538 }
539}
540
541int SDDS_CompareRows(const void *vrow1, const void *vrow2) {
542 /* I'm assuming that a double is large enough to store any of the data types,
543 * including a pointer
544 */
545 static double data1, data2;
546 static int64_t row1, row2;
547 long i;
548 int comparison;
549 void *p1, *p2;
550 row1 = *(int64_t *)vrow1;
551 row2 = *(int64_t *)vrow2;
552
553 for (i = 0; i < sort_requests; i++) {
554 if (!SDDS_GetValueByAbsIndex(SDDS_sort, sort_request[i].index, row1, &data1) ||
555 !SDDS_GetValueByAbsIndex(SDDS_sort, sort_request[i].index, row2, &data2)) {
556 SDDS_SetError("Problem getting value for sort (SDDS_CompareRows)");
557 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
558 exit(EXIT_FAILURE);
559 }
560 if ((comparison = SDDS_CompareData(SDDS_sort, sort_request[i].type, sort_request[i].absolute,
561 (void *)&data1, (void *)&data2))) {
562 if (sort_request[i].type == SDDS_STRING) {
563 p1 = &data1;
564 p2 = &data2;
565 free(*((char **)p1));
566 free(*((char **)p2));
567 // free(*((char**)&data1));
568 // free(*((char**)&data2));
569 }
570 return (sort_request[i].decreasing_order ? -comparison : comparison);
571 }
572 if (sort_request[i].type == SDDS_STRING) {
573 p1 = &data1;
574 p2 = &data2;
575 free(*((char **)p1));
576 free(*((char **)p2));
577 // free(*((char**)&data1));
578 // free(*((char**)&data2));
579 }
580 }
581 return (0);
582}
583
584long SDDS_SwapRows(SDDS_DATASET *SDDS_dataset, int64_t row1, int64_t row2) {
585#define SWAP_BUFFER_SIZE 16
586 static char buffer[SWAP_BUFFER_SIZE];
587 void **data;
588 long i, size;
589 data = SDDS_dataset->data;
590#if defined(DEBUG)
591 fprintf(stderr, "swapping row %" PRId64 " with row %" PRId64 "\n", row1, row2);
592#endif
593 for (i = 0; i < SDDS_dataset->layout.n_columns; i++) {
594 if ((size = SDDS_GetTypeSize(SDDS_dataset->layout.column_definition[i].type)) > SWAP_BUFFER_SIZE) {
595 SDDS_SetError("Unable to swap rows--swap buffer is too small (SDDS_SwapRows)");
596 return (0);
597 }
598#if defined(DEBUG)
599 if (SDDS_dataset->layout.column_definition[i].type == SDDS_STRING)
600 fprintf(stderr, " %s <--> %s\n", *(char **)((char *)(data[i]) + row1 * size), *(char **)((char *)(data[i]) + row2 * size));
601#endif
602 memcpy((char *)buffer, (char *)(data[i]) + row1 * size, size);
603 memcpy((char *)(data[i]) + row1 * size, (char *)(data[i]) + row2 * size, size);
604 memcpy((char *)(data[i]) + row2 * size, (char *)buffer, size);
605 }
606 return (1);
607}
608
609long SDDS_SortRows(SDDS_DATASET *SDDS_dataset, SORT_REQUEST *xsort_request, long xsort_requests, long non_dominate_sort) {
610 int64_t i, j, k, rows;
611 int64_t *row_location;
612 char s[1024];
613 double **data = NULL, *dist = NULL, *const_violation = NULL;
614 int32_t *rank = NULL;
615 population pop;
616 long *maximize = NULL;
617
618 SDDS_sort = SDDS_dataset;
619 sort_request = xsort_request;
620 sort_requests = xsort_requests;
621 if ((rows = SDDS_CountRowsOfInterest(SDDS_sort)) < 0)
622 return (0);
623
624 for (i = 0; i < sort_requests; i++) {
625 if ((sort_request[i].index = SDDS_GetColumnIndex(SDDS_sort, sort_request[i].name)) < 0) {
626 sprintf(s, "column name \"%s\" is not recognized(SDDS_GetColumnIndex)", sort_request[i].name);
627 SDDS_SetError(s);
628 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
629 return (0);
630 }
631 sort_request[i].type = SDDS_GetColumnType(SDDS_sort, sort_request[i].index);
632 }
633 if (non_dominate_sort) {
634 data = (double **)malloc(sizeof(*data) * sort_requests);
635 maximize = (long *)malloc(sizeof(*maximize) * sort_requests);
636 for (i = 0; i < sort_requests; i++) {
637 if (sort_request[i].type == SDDS_STRING) {
638 fprintf(stderr, "Non-dominated sort is not available for string column.\n");
639 exit(EXIT_FAILURE);
640 }
641 if (!(data[i] = (double *)SDDS_GetColumnInDoubles(SDDS_sort, sort_request[i].name))) {
642 SDDS_SetError("Problem performing sort");
643 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
644 exit(EXIT_FAILURE);
645 }
646 maximize[i] = sort_request[i].maximize_order;
647 }
648 const_violation = read_constr_violation(SDDS_sort);
649 fill_population(&pop, rows, sort_requests, data, maximize, const_violation);
650 sort_row_index = non_dominated_sort(&pop);
651 rank = (int32_t *)malloc(sizeof(*rank) * rows);
652 dist = (double *)malloc(sizeof(*dist) * rows);
653 if (!const_violation)
654 const_violation = calloc(rows, sizeof(*const_violation));
655 for (i = 0; i < rows; i++) {
656 rank[i] = pop.ind[sort_row_index[i]].rank;
657 dist[i] = pop.ind[sort_row_index[i]].crowd_dist;
658 const_violation[i] = pop.ind[sort_row_index[i]].constr_violation;
659 }
660 free_pop_mem(&pop);
661 for (i = 0; i < sort_requests; i++)
662 free(data[i]);
663 free(data);
664 free(maximize);
665 } else {
666 sort_row_index = tmalloc(sizeof(*sort_row_index) * rows);
667 for (i = 0; i < rows; i++)
668 sort_row_index[i] = i;
669 /* After this sort, sort_row_index will contain the indices of the rows
670 * in sorted order
671 */
672 qsort((void *)sort_row_index, rows, sizeof(*sort_row_index), SDDS_CompareRows);
673
674 /* create an array to give the location in the sort_row_index array of
675 * a particular row
676 */
677#if defined(DEBUG)
678 fprintf(stderr, "new row order:\n");
679 for (i = 0; i < rows; i++)
680 fprintf(stderr, "%" PRId64 " %" PRId64 "\n", i, sort_row_index[i]);
681 fprintf(stderr, "\n");
682#endif
683 }
684 row_location = tmalloc(sizeof(*sort_row_index) * rows);
685 for (i = 0; i < rows; i++)
686 row_location[sort_row_index[i]] = i;
687 for (i = 0; i < rows; i++) {
688 if ((j = sort_row_index[i]) != i) {
689 /* move this row from position i to position j, where it belongs */
690 if (!SDDS_SwapRows(SDDS_sort, i, j)) {
691 SDDS_SetError("Problem swapping rows after index sort (SDDS_SortRows");
692 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
693 exit(EXIT_FAILURE);
694 }
695 /* adjust the indices to reflect the swap */
696 sort_row_index[i] = i;
697 k = row_location[i];
698 row_location[i] = i;
699 sort_row_index[k] = j;
700 row_location[j] = k;
701 }
702#if defined(DEBUG)
703 fprintf(stderr, "new row order:\n");
704 for (j = 0; j < rows; j++)
705 fprintf(stderr, "%" PRId64 " %" PRId64 "\n", j, sort_row_index[j]);
706 fprintf(stderr, "\n");
707#endif
708 }
709 if (non_dominate_sort) {
710 if (SDDS_SetColumn(SDDS_sort, SDDS_SET_BY_NAME, rank, rows, "Rank", NULL) != 1 ||
711 SDDS_SetColumn(SDDS_sort, SDDS_SET_BY_NAME, dist, rows, "CrowdingDistance", NULL) != 1 ||
712 SDDS_SetColumn(SDDS_sort, SDDS_SET_BY_NAME, const_violation, rows, "ConstraintsViolation", NULL) != 1) {
713 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
714 exit(EXIT_FAILURE);
715 }
716 free(rank);
717 free(dist);
718 free(const_violation);
719 }
720 free(sort_row_index);
721 free(row_location);
722 return 1;
723}
724
725long SDDS_UnsetDuplicateRows(SDDS_DATASET *SDDS_dataset, SORT_REQUEST *xsort_request, long xsort_requests, long provideIdenticalCount) {
726 int64_t rows, i, j;
727 int64_t *identicalCount;
728 int32_t *rowFlag;
729 char s[1024];
730
731 SDDS_sort = SDDS_dataset;
732 sort_request = xsort_request;
733 sort_requests = xsort_requests;
734
735 for (i = 0; i < sort_requests; i++) {
736 if ((sort_request[i].index = SDDS_GetColumnIndex(SDDS_sort, sort_request[i].name)) < 0) {
737 sprintf(s, "column name \"%s\" is not recognized(SDDS_GetColumnIndex)", sort_request[i].name);
738 SDDS_SetError(s);
739 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
740 return 0;
741 }
742 sort_request[i].type = SDDS_GetColumnType(SDDS_sort, sort_request[i].index);
743 }
744
745 if ((rows = SDDS_CountRowsOfInterest(SDDS_sort)) < 0)
746 return (0);
747
748 rowFlag = tmalloc(sizeof(*rowFlag) * rows);
749 identicalCount = tmalloc(sizeof(*identicalCount) * rows);
750 for (i = 0; i < rows; i++)
751 rowFlag[i] = identicalCount[i] = 1;
752
753 for (i = 0; i < rows - 1; i++) {
754 if (!rowFlag[i])
755 continue;
756 for (j = i + 1; j < rows; j++) {
757 if (rowFlag[j]) {
758 if (SDDS_CompareRows(&i, &j) == 0) {
759 identicalCount[i] += 1;
760 rowFlag[j] = 0;
761 } else
762 break;
763 }
764 }
765 }
766 if (!SDDS_AssertRowFlags(SDDS_sort, SDDS_FLAG_ARRAY, rowFlag, rows))
767 return 0;
768 if (provideIdenticalCount && !SDDS_SetColumn(SDDS_sort, SDDS_SET_BY_NAME, identicalCount, rows, "IdenticalCount"))
769 return 0;
770 free(rowFlag);
771 return 1;
772}
773
774static SORT_REQUEST *sort_parameter;
775static long sort_parameters;
776static SDDS_DATASET *SDDS_sortpage;
777
778int SDDS_ComparePages(const void *vpage1, const void *vpage2) {
779 /* I'm assuming that a double is large enough to store any of the data types,
780 * including a pointer
781 */
782 static int32_t page1, page2;
783 long i;
784 int comparison;
785
786 page1 = *(int32_t *)vpage1;
787 page2 = *(int32_t *)vpage2;
788
789 for (i = 0; i < sort_parameters; i++) {
790 if ((comparison = SDDS_CompareData(SDDS_sortpage, sort_parameter[i].type, sort_parameter[i].absolute,
791 (void *)&(sort_parameter[i].data[page1]), (void *)&(sort_parameter[i].data[page2])))) {
792 /* if (sort_parameter[i].type==SDDS_STRING) {
793 * free(*((char**)&(sort_parameter[i].data[page1])));
794 * free(*((char**)&(sort_parameter[i].data[page2])));
795 * } */
796 return (sort_parameter[i].decreasing_order ? -comparison : comparison);
797 }
798 /* if (sort_parameter[i].type==SDDS_STRING) {
799 * free(*((char**)&(sort_parameter[i].data[page1])));
800 * free(*((char**)&(sort_parameter[i].data[page2])));
801 * } */
802 }
803 return (0);
804}
805
806long SDDS_SortAll(SDDS_DATASET *SDDS_inputx, SDDS_DATASET *SDDS_outputx, SORT_REQUEST *xsort_request,
807 long xsort_requests, SORT_REQUEST *xsort_parameter, long xsort_parameters, long uniqueRows,
808 long provideIdenticalCount, long xpipeFlags, long non_dominate_sort) {
809 long i, j, k, pages;
810 int32_t *xsort_page_index;
811 char s[1024];
812 SDDS_DATASET *tmp_datasets;
813
814 tmp_datasets = NULL;
815 SDDS_sortpage = SDDS_inputx;
816 sort_parameter = xsort_parameter;
817 sort_parameters = xsort_parameters;
818 sort_request = xsort_request;
819 sort_requests = xsort_requests;
820 xsort_page_index = NULL;
821 pages = i = j = k = 0;
822 for (i = 0; i < sort_parameters; i++) {
823 if ((sort_parameter[i].index = SDDS_GetParameterIndex(SDDS_sortpage, sort_parameter[i].name)) < 0) {
824 sprintf(s, "Unable to get parameter value--parameter name \"%s\" is not recognized(SDDS_GetParameterIndex)", sort_parameter[i].name);
825 SDDS_SetError(s);
826 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
827 return (0);
828 }
829 sort_parameter[i].type = SDDS_GetParameterType(SDDS_sortpage, sort_parameter[i].index);
830 }
831 if (sort_parameters) {
832 if (xpipeFlags == 0 && !SDDS_sortpage->layout.gzipFile)
834 for (i = 0; i < sort_parameters; i++)
835 sort_parameter[i].data = NULL;
836 while (SDDS_ReadPage(SDDS_sortpage) > 0) {
837 if (xpipeFlags || SDDS_sortpage->layout.gzipFile) {
838 /* copy each page of sortpage into tmp_datasets indexed by the pages, i.e.
839 * tmp_datasets[pages] contains only one page */
840 tmp_datasets = realloc(tmp_datasets, sizeof(*tmp_datasets) * (pages + 1));
841 if (!SDDS_InitializeCopy(&tmp_datasets[pages], SDDS_sortpage, NULL, "m")) {
842 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
843 return (0);
844 }
845 if (!SDDS_CopyPage(&tmp_datasets[pages], SDDS_sortpage)) {
846 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
847 return (0);
848 }
849 }
850 for (i = 0; i < sort_parameters; i++) {
851 sort_parameter[i].data = realloc(sort_parameter[i].data, sizeof(*sort_parameter[i].data) * (pages + 1));
852
853 if (!SDDS_GetParameterByIndex(SDDS_sortpage, sort_parameter[i].index, &(sort_parameter[i].data[pages]))) {
854 SDDS_SetError("Problem getting parameter value for sort (SDDS_SortAll)");
855 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
856 exit(EXIT_FAILURE);
857 }
858 }
859 pages++;
860 }
861 /* sort pages by parameter */
862 xsort_page_index = tmalloc(sizeof(*xsort_page_index) * pages);
863 for (k = 0; k < pages; k++)
864 xsort_page_index[k] = k;
865 if (pages > 1)
866 qsort((void *)xsort_page_index, pages, sizeof(*xsort_page_index), SDDS_ComparePages);
867
868 /* sort_page_index=xsort_page_index; */
869 for (i = 0; i < pages; i++) {
870 j = xsort_page_index[i];
871 if (xpipeFlags || SDDS_sortpage->layout.gzipFile) {
872 if (!SDDS_CopyPage(SDDS_outputx, &tmp_datasets[j])) {
873 SDDS_SetError("Problem copying data from memory");
874 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
875 exit(EXIT_FAILURE);
876 }
877 if (!SDDS_Terminate(&tmp_datasets[j])) {
878 SDDS_SetError("Problem terminate datasets");
879 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
880 exit(EXIT_FAILURE);
881 }
882 } else {
883 if (!SDDS_GotoPage(SDDS_sortpage, j + 1)) {
884 SDDS_SetError("Problem goto page");
885 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
886 exit(EXIT_FAILURE);
887 }
888 if (SDDS_ReadPage(SDDS_sortpage) < 1) {
889 SDDS_SetError("Problem read page");
890 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
891 exit(EXIT_FAILURE);
892 }
893 if (!SDDS_CopyPage(SDDS_outputx, SDDS_sortpage)) {
894 SDDS_SetError("Problem copying data");
895 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
896 exit(EXIT_FAILURE);
897 }
898 }
899 if (sort_requests) {
900 if (SDDS_CountRowsOfInterest(SDDS_outputx) > 0) {
901 if (!SDDS_SortRows(SDDS_outputx, sort_request, sort_requests, non_dominate_sort)) {
902 SDDS_SetError("Problem performing sort");
903 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
904 exit(EXIT_FAILURE);
905 }
906 if (uniqueRows && !SDDS_UnsetDuplicateRows(SDDS_outputx, sort_request, sort_requests, provideIdenticalCount)) {
907 SDDS_SetError("Problem marking duplicate rows.");
908 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
909 exit(EXIT_FAILURE);
910 }
911 }
912 }
913 if (!SDDS_WritePage(SDDS_outputx)) {
914 SDDS_SetError("Problem writing data to output file");
915 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
916 exit(EXIT_FAILURE);
917 }
918 }
919 } else {
920 while (SDDS_ReadPage(SDDS_inputx) > 0) {
921 if (!SDDS_CopyPage(SDDS_outputx, SDDS_inputx)) {
922 SDDS_SetError("Problem copying data for output file");
923 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
924 exit(EXIT_FAILURE);
925 }
926 if (SDDS_CountRowsOfInterest(SDDS_outputx) > 0) {
927 if (!SDDS_SortRows(SDDS_outputx, sort_request, sort_requests, non_dominate_sort)) {
928 SDDS_SetError("Problem performing sort");
929 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
930 exit(EXIT_FAILURE);
931 }
932 if (uniqueRows && !SDDS_UnsetDuplicateRows(SDDS_outputx, sort_request, sort_requests, provideIdenticalCount)) {
933 SDDS_SetError("Problem marking duplicate rows.");
934 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
935 exit(EXIT_FAILURE);
936 }
937 }
938 if (!SDDS_WritePage(SDDS_outputx)) {
939 SDDS_SetError("Problem writing data to output file");
940 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
941 exit(EXIT_FAILURE);
942 }
943 }
944 }
945 if (tmp_datasets)
946 free(tmp_datasets);
947 if (xsort_page_index)
948 free(xsort_page_index);
949 return 1;
950}
951
952double *read_constr_violation(SDDS_DATASET *SDDS_dataset) {
953 double *const_violation = NULL, **data = NULL;
954 int32_t columns, constraints, j;
955 int64_t i, rows;
956 char **columnName = NULL;
957
958 columns = constraints = 0;
959 rows = SDDS_CountRowsOfInterest(SDDS_dataset);
960 if (!constDefined && !(const_violation = (double *)SDDS_GetColumnInDoubles(SDDS_dataset, "ConstraintsViolation")))
961 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
962 else {
963 if (!(columnName = (char **)SDDS_GetColumnNames(SDDS_dataset, &columns)))
964 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
965 for (i = 0; i < columns; i++) {
966 if (wild_match(columnName[i], "*Constraints*") && strcmp(columnName[i], "ConstraintsViolation") != 0) {
967 data = SDDS_Realloc(data, sizeof(*data) * (constraints + 1));
968 data[constraints] = NULL;
969 if (!(data[constraints] = (double *)SDDS_GetColumnInDoubles(SDDS_dataset, columnName[i])))
970 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
971 constraints++;
972 }
973 }
974 if (constraints) {
975 const_violation = calloc(rows, sizeof(*const_violation));
976 for (i = 0; i < rows; i++) {
977 for (j = 0; j < constraints; j++) {
978 if (data[j][i] < 0)
979 const_violation[i] += data[j][i];
980 }
981 }
982 for (j = 0; j < constraints; j++)
983 free(data[j]);
984 free(data);
985 }
986 }
987 return const_violation;
988}
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_SetDefaultIOBufferSize(int32_t newValue)
Definition SDDS_binary.c:66
int32_t SDDS_InitializeCopy(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, char *filename, char *filemode)
Definition SDDS_copy.c:40
int32_t SDDS_CopyPage(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:578
int32_t SDDS_SetColumn(SDDS_DATASET *SDDS_dataset, int32_t mode, void *data, int64_t rows,...)
Sets the values for one data column in the current data table of an SDDS dataset.
int32_t SDDS_AssertRowFlags(SDDS_DATASET *SDDS_dataset, uint32_t mode,...)
Sets acceptance flags for rows based on specified criteria.
int64_t SDDS_CountRowsOfInterest(SDDS_DATASET *SDDS_dataset)
Counts the number of rows marked as "of interest" in the current data table.
void * SDDS_GetParameterByIndex(SDDS_DATASET *SDDS_dataset, int32_t index, void *memory)
Retrieves the value of a specified parameter by its index from the current data table of a data set.
void * SDDS_GetValueByAbsIndex(SDDS_DATASET *SDDS_dataset, int32_t column_index, int64_t row_index, void *memory)
Retrieves the value from a specified column and absolute row index, optionally storing it in provided...
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_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_GotoPage(SDDS_DATASET *SDDS_dataset, int32_t page_number)
Sets the current page of the SDDS dataset to the specified page number.
int32_t SDDS_DefineSimpleColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *unit, int32_t type)
Defines a simple data column within the SDDS dataset.
int32_t SDDS_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
int32_t SDDS_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
void SDDS_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_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_CheckColumn(SDDS_DATASET *SDDS_dataset, char *name, char *units, int32_t type, FILE *fp_message)
Checks if a column exists in the SDDS dataset with the specified name, units, and type.
char ** SDDS_GetColumnNames(SDDS_DATASET *SDDS_dataset, int32_t *number)
Retrieves the names of all columns in the SDDS dataset.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
Definition SDDS_utils.c:432
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:288
int32_t SDDS_GetTypeSize(int32_t type)
Retrieves the size in bytes of a specified SDDS data type.
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
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
Definition SDDS_utils.c:677
#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_ANY_NUMERIC_TYPE
Special identifier used by SDDS_Check*() routines to accept any numeric type.
Definition SDDStypes.h:157
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37
#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 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.
int64_t * non_dominated_sort(population *new_pop)
Performs non-dominated sorting on a population and assigns ranks and crowding distances.
void fill_population(population *pop, long rows, long columns, double **columnValue, long *maximize, double *const_violation)
Initializes and fills the population structure with individuals and their objective values.
void free_pop_mem(population *pop)
Frees all dynamically allocated memory associated with a population.
long replaceFileAndBackUp(char *file, char *replacement)
Replaces a file with a replacement file and creates a backup of the original.
Definition replacefile.c:75
int scanargs(SCANNED_ARG **scanned, int argc, char **argv)
Definition scanargs.c:36
long processPipeOption(char **item, long items, unsigned long *flags)
Definition scanargs.c:356
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
Definition scanargs.c:390
void free_scanargs(SCANNED_ARG **scanned, int argc)
Definition scanargs.c:584
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.
char * str_tolower(char *s)
Convert a string to lower case.
Definition str_tolower.c:27
int wild_match(char *string, char *template)
Determine whether one string is a wildcard match for another.
Definition wild_match.c:49
int strcmp_nh(const char *s1, const char *s2)
Compare two strings with a custom non-hierarchical ranking.
Definition wild_match.c:583