SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
table.c File Reference

Detailed Description

DPL/MPL format input/output functions.

Contains functions: get_table(), put_table(), float_array_from_double(), get_table_float(), put_table_float(), double_array_from_float(), delete_trailing_blanks(), fgets_skip().

Author
Michael Borland
Date
1988

Definition in file table.c.

#include "mdb.h"
#include <ctype.h>
#include "table.h"
#include "SDDS.h"

Go to the source code of this file.

Functions

int32_t SDDS_ReadIntoMplTable (TABLE *mpl_data, char *file, int64_t sample_interval, int32_t mpl_flags, char *SDDS_tags)
 Reads SDDS data into an MPL-compatible table structure.
 
int32_t SDDS_WriteMplTable (TABLE *mpl_data, char *file)
 Writes an MPL-compatible table to an SDDS file.
 
long SDDS_AddMplDefinition (SDDS_TABLE *SDDS_table, char *label, char *suffix, char *default_name, char *filename)
 Adds an MPL-compatible column definition to an SDDS dataset.
 
void SDDS_ExtractNameAndUnit (char **name, char **unit, char *label)
 Extracts the name and unit from a labeled string.
 
void SDDS_FixMplName (char *name)
 Cleans and fixes an MPL-compatible name by removing specific sequences and extra spaces.
 
void delete_trailing_blanks (char *s)
 
long get_table (TABLE *tab, char *file, int64_t sample_interval, long flags)
 Gets a table from a file in DPL format.
 
void put_table (char *file, TABLE *tab, char *format)
 
long get_table_float (TABLE_FLOAT *tab, char *file, long sample_interval, long flags)
 
void put_table_float (char *file, TABLE_FLOAT *tab, char *format)
 
float * float_array_from_double (double *x, long n)
 
double * double_array_from_float (float *x, long n)
 
char * fgets_skip (char *s, long slen, FILE *fp, char skip_char, long skip_lines)
 

Function Documentation

◆ delete_trailing_blanks()

void delete_trailing_blanks ( char * s)
extern

Definition at line 599 of file table.c.

599 {
600 register char *ptr;
601
602 ptr = strlen(s) - 1 + s;
603 while (ptr >= s && isspace(*ptr))
604 *ptr-- = 0;
605}

◆ double_array_from_float()

double * double_array_from_float ( float * x,
long n )

Definition at line 583 of file table.c.

583 {
584 register double *ptr;
585 register long i;
586
587 if (!(ptr = tmalloc(n * sizeof(*ptr))))
588 return (ptr);
589
590 for (i = 0; i < n; i++)
591 ptr[i] = x[i];
592 return (ptr);
593}
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:59

◆ fgets_skip()

char * fgets_skip ( char * s,
long slen,
FILE * fp,
char skip_char,
long skip_lines )

Definition at line 612 of file table.c.

617 {
618 register long i;
619 char c;
620
621 i = 0;
622 do {
623 if (!fgets(s, slen, fp))
624 return (NULL);
625 if (s[0] != skip_char)
626 i++;
627 } while (i < skip_lines);
628 if ((long)strlen(s) >= slen - 1) {
629 while ((c = getc(fp)))
630 if (c == '\n')
631 break;
632 }
633 return (s);
634}

◆ float_array_from_double()

float * float_array_from_double ( double * x,
long n )

Definition at line 567 of file table.c.

567 {
568 register float *ptr;
569 register long i;
570
571 if (!(ptr = tmalloc(n * sizeof(*ptr))))
572 return (ptr);
573
574 for (i = 0; i < n; i++)
575 ptr[i] = x[i];
576 return (ptr);
577}

◆ get_table()

long get_table ( TABLE * tab,
char * file,
int64_t sample_interval,
long flags )

Gets a table from a file in DPL format.

Parameters
tabPointer to a TABLE structure to store the data.
fileName of the file to read.
sample_intervalSampling interval for reading data points.
flagsFlags to control the reading behavior.
Returns
Returns 1 on success, 0 on failure.

Definition at line 45 of file table.c.

45 {
46 long i, n, m;
47 long sigma_y_present, sigma_x_and_y_present;
48 char s[OAGBUFSIZ];
49 double tmp;
50 FILE *fp;
51 char *ptr, *sdds_tags=NULL, *orig_tag = NULL;
52 long sdds_expected = 0, sdds_data = 0;
53
54 sigma_y_present = sigma_x_and_y_present = 0;
55 tab->c1 = tab->c2 = tab->s1 = tab->s2 = NULL;
56 tab->xlab = tab->ylab = tab->topline = tab->title = NULL;
57 tab->flags = 0;
58 tab->n_data = 0;
59
60#if defined(SDDS_SUPPORT)
61
62 if ((orig_tag = strchr(file, '='))) {
63 sdds_tags = orig_tag;
64 *sdds_tags = 0;
65 if (!fexists(file))
66 *sdds_tags = '=';
67 else {
68 sdds_expected = 1;
69 sdds_tags++;
70 }
71 }
72
73 if (!(fp = fopen_e(file, "r", FOPEN_RETURN_ON_ERROR))) {
74 fprintf(stderr, "error: unable to open file %s in mode r (get_table)\n", file);
75 exit(1);
76 }
77
78 if (!fgets_skip(s, OAGBUFSIZ, fp, '!', 1))
79 return (0);
80 fclose(fp);
81 if (strncmp(s, "SDDS", 4) == 0) {
82 if (!SDDS_ReadIntoMplTable(tab, file, sample_interval, flags, sdds_tags)) {
83 fprintf(stderr, "error: unable to read requested data from SDDS file %s\n", file);
84 exit(1);
85 }
86 sdds_data = 1;
87 sigma_x_and_y_present = (sigma_y_present = tab->flags & SIGMA_Y_PRESENT) && (tab->flags & SIGMA_X_PRESENT);
88 }
89 if (sdds_expected && !sdds_data)
90 *orig_tag = '=';
91
92#endif /* SDDS_SUPPORT */
93
94 if (!sdds_data) {
95 fp = fopen_e(file, "r", 0);
96#ifdef DEBUG
97 fprintf(stderr, "file %s opened: sample_interval=%ld flags=%x\n", file, sample_interval, flags);
98#endif
99
100 /* read in plot labels, skipping comment lines (! lines) */
101 fgets_skip(s, OAGBUFSIZ, fp, '!', 1);
102 delete_trailing_blanks(s);
103 cp_str(&(tab->xlab), s);
104 fgets_skip(s, OAGBUFSIZ, fp, '!', 1);
105 delete_trailing_blanks(s);
106 cp_str(&(tab->ylab), s);
107 fgets_skip(s, OAGBUFSIZ, fp, '!', 1);
108 delete_trailing_blanks(s);
109 cp_str(&(tab->title), s);
110 fgets_skip(s, OAGBUFSIZ, fp, '!', 1);
111 delete_trailing_blanks(s);
112 cp_str(&(tab->topline), s);
113#ifdef DEBUG
114 fprintf(stderr, "labels:\n<%s>\n<%s>\n<%s>\n<%s>\n", tab->xlab, tab->ylab, tab->title, tab->topline);
115#endif
116 }
117
118 if (flags & SWAP) {
119 ptr = tab->xlab;
120 tab->xlab = tab->ylab;
121 tab->ylab = ptr;
122 }
123
124 if (flags & READ_LABELS_ONLY) {
125 if (!sdds_data)
126 fclose(fp);
127 return (1);
128 }
129
130 if (!sdds_data) {
131 /* read in the number of data points */
132 fgets_skip(s, OAGBUFSIZ, fp, '!', 1);
133 if (!*s || 1 != sscanf(s, "%lf", &tmp)) {
134 fprintf(stderr, "error in format of file %s--couldn't scan number of points\n", file);
135 exit(1);
136 }
137 n = tmp + 0.5;
138#ifdef DEBUG
139 fprintf(stderr, "n_pts = %ld\n", n);
140#endif
141
142 /* adjust the number of data points for the sampling interval */
143 if (sample_interval <= 0)
144 sample_interval = 1;
145 n = n / sample_interval;
146
147 /* allocate memory for column 1 and 2 data and sigmas */
148 tab->c1 = tmalloc(sizeof(*(tab->c1)) * n);
149 tab->c2 = tmalloc(sizeof(*(tab->c2)) * n);
150 tab->s1 = tmalloc(sizeof(*(tab->s1)) * n);
151 tab->s2 = tmalloc(sizeof(*(tab->s2)) * n);
152 tab->flags = 0;
153
154#ifdef DEBUG
155 fprintf(stderr, "data pointers are: %x, %x, %x, %x\n", (unsigned long)tab->c1, (unsigned long)tab->c2, (unsigned long)tab->s1, (unsigned long)tab->s2);
156#endif
157
158 /* read in the data points, one by one */
159 for (i = 0; i < n; i++) {
160 if (fgets_skip(s, OAGBUFSIZ, fp, '!', (i == 0 ? 1 : sample_interval))) {
161#ifdef DEBUG
162 fprintf(stderr, "string: <%s>\n", s);
163#endif
164 if ((ptr = strchr(s, '!')))
165 *ptr = 0;
166 if (!get_double(tab->c1 + i, s) || !get_double(tab->c2 + i, s)) {
167 fprintf(stderr, "warning: error in format of file %s\n", file);
168 n = i - 1;
169 tab->c1 = trealloc((void *)tab->c1, sizeof(*(tab->c1)) * n);
170 tab->c2 = trealloc((void *)tab->c2, sizeof(*(tab->c2)) * n);
171 tab->s1 = trealloc((void *)tab->s1, sizeof(*(tab->s1)) * n);
172 tab->s2 = trealloc((void *)tab->s2, sizeof(*(tab->s2)) * n);
173 break;
174 }
175 tab->s1[i] = tab->s2[i] = 0;
176 if (i == 0) {
177 /* First point--establish the number of sigma values in the
178 * data. If there's only one sigma, interpret it as sigma_y,
179 * otherwise, the sigmas are sigma_x and sigma_y, in that
180 * order.
181 */
182 if (get_double(tab->s1 + i, s)) {
183 if (get_double(tab->s2 + i, s)) {
184 sigma_x_and_y_present = 1;
185 tab->flags |= SIGMA_X_PRESENT + SIGMA_Y_PRESENT;
186 } else {
187 tab->s2[i] = tab->s1[i];
188 tab->s1[i] = 0;
189 tab->flags |= SIGMA_Y_PRESENT;
190 sigma_y_present = 1;
191 }
192 }
193#ifdef DEBUG
194 fprintf(stderr, "tab->flags = %x\n", tab->flags);
195#endif
196 } else {
197 /* Scan sigma_y or (sigma_x, sigma_y) values, according
198 * to what the first line indicated is supposed to be present.
199 */
200 if (sigma_y_present && !get_double(tab->s2 + i, s)) {
201 fprintf(stderr, "error in format of file %s--expected sigma is missing\n", file);
202 exit(1);
203 } else if (sigma_x_and_y_present && (!get_double(tab->s1 + i, s) || !get_double(tab->s2 + i, s))) {
204 fprintf(stderr, "error in format of file %s--expected sigma is missing\n", file);
205 exit(1);
206 }
207 }
208 if (flags & SWAP) {
209 /* exchange x and y data points */
210 tmp = tab->c1[i];
211 tab->c1[i] = tab->c2[i];
212 tab->c2[i] = tmp;
213 /* exchange the sigmas, too */
214 tmp = tab->s1[i];
215 tab->s1[i] = tab->s2[i];
216 tab->s2[i] = tmp;
217 }
218 } else {
219 fprintf(stderr, "Warning: file %s contains only %ld of %ld expected points.\n", file, i, n);
220 n = i;
221 tab->c1 = trealloc((void *)tab->c1, sizeof(*(tab->c1)) * n);
222 tab->c2 = trealloc((void *)tab->c2, sizeof(*(tab->c2)) * n);
223 tab->s1 = trealloc((void *)tab->s1, sizeof(*(tab->s1)) * n);
224 tab->s2 = trealloc((void *)tab->s2, sizeof(*(tab->s2)) * n);
225 break;
226 }
227 }
228 tab->n_data = n;
229 }
230 n = tab->n_data;
231
232 /* Check to see if the data needs to be reverse in order, i.e.,
233 * if the first point should be the last and the last first.
234 */
235 if (flags & REVERSE || ((flags & REORDER_ASCENDING) && tab->c1[0] > tab->c1[n - 1]) || ((flags & REORDER_DESCENDING) && tab->c1[0] < tab->c1[n - 1])) {
236 /* Reverse the order of the data. */
237 m = n - 1;
238 for (i = 0; i < n / 2; i++) {
239 if (m - i > n - 1)
240 bomb("something impossible happened in get_table()", NULL);
241 tmp = tab->c1[i];
242 tab->c1[i] = tab->c1[m - i];
243 tab->c1[m - i] = tmp;
244 tmp = tab->c2[i];
245 tab->c2[i] = tab->c2[m - i];
246 tab->c2[m - i] = tmp;
247 tmp = tab->s1[i];
248 tab->s1[i] = tab->s1[m - i];
249 tab->s1[m - i] = tmp;
250 tmp = tab->s2[i];
251 tab->s2[i] = tab->s2[m - i];
252 tab->s2[m - i] = tmp;
253 }
254 }
255
256 if (!sdds_data) {
257 /* Check file for extra data. */
258 if (fgets_skip(s, OAGBUFSIZ, fp, '!', sample_interval))
259 fprintf(stderr, "Warning: file %s contains excess data (which is ignored).\n", file);
260 fclose(fp);
261 }
262
263 /* If there were no sigmas, free the arrays. */
264 if (!(tab->flags & SIGMA_X_PRESENT || tab->flags & SIGMA_Y_PRESENT) && !(flags & SAVE_SIGMA_ARRAYS)) {
265 if (tab->s1) {
266 tfree(tab->s1);
267 tab->s1 = NULL;
268 }
269 if (tab->s2) {
270 tfree(tab->s2);
271 tab->s2 = NULL;
272 }
273 }
274
275#ifdef DEBUG
276 for (i = 0; i < n; i++) {
277 fprintf(stderr, "%ldth point: c1=%le c2=%le", i, tab->c1[i], tab->c2[i]);
278 if (tab->s1)
279 fprintf(stderr, " s1=%le s2=%le\n", tab->s1[i], tab->s2[i]);
280 else
281 fputc('\n', stderr);
282 }
283#endif
284
285 return (1);
286}
void * trealloc(void *old_ptr, uint64_t size_of_block)
Reallocates a memory block to a new size.
Definition array.c:181
int tfree(void *ptr)
Frees a memory block and records the deallocation if tracking is enabled.
Definition array.c:230
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
char * cp_str(char **s, char *t)
Copies a string, allocating memory for storage.
Definition cp_str.c:28
int get_double(double *dptr, char *s)
Parses a double value from the given string.
Definition data_scan.c:40
long fexists(const char *filename)
Checks if a file exists.
Definition fexists.c:27
FILE * fopen_e(char *file, char *open_mode, long mode)
Opens a file with error checking, messages, and aborts.
Definition fopen_e.c:30
int32_t SDDS_ReadIntoMplTable(TABLE *mpl_data, char *file, int64_t sample_interval, int32_t mpl_flags, char *SDDS_tags)
Reads SDDS data into an MPL-compatible table structure.

◆ get_table_float()

long get_table_float ( TABLE_FLOAT * tab,
char * file,
long sample_interval,
long flags )

Definition at line 334 of file table.c.

334 {
335 long i, n, m;
336 long sigma_y_present, sigma_x_and_y_present;
337 char s[OAGBUFSIZ];
338 float tmp;
339 FILE *fp;
340 char *ptr;
341
342 fp = fopen_e(file, "r", 0);
343#ifdef DEBUG
344 fprintf(stderr, "file %s opened: sample_interval=%ld flags=%x\n", file, sample_interval, flags);
345#endif
346
347 sigma_y_present = sigma_x_and_y_present = 0;
348
349 /* read in plot labels, skipping comment lines (! lines) */
350 fgets_skip(s, OAGBUFSIZ, fp, '!', 1);
351 delete_trailing_blanks(s);
352 cp_str(&(tab->xlab), s);
353 fgets_skip(s, OAGBUFSIZ, fp, '!', 1);
354 delete_trailing_blanks(s);
355 cp_str(&(tab->ylab), s);
356 fgets_skip(s, OAGBUFSIZ, fp, '!', 1);
357 delete_trailing_blanks(s);
358 cp_str(&(tab->title), s);
359 fgets_skip(s, OAGBUFSIZ, fp, '!', 1);
360 delete_trailing_blanks(s);
361 cp_str(&(tab->topline), s);
362 if (flags & SWAP) {
363 ptr = tab->xlab;
364 tab->xlab = tab->ylab;
365 tab->ylab = ptr;
366 }
367#ifdef DEBUG
368 fprintf(stderr, "labels:\n<%s>\n<%s>\n<%s>\n<%s>\n", tab->xlab, tab->ylab, tab->title, tab->topline);
369#endif
370
371 if (flags & READ_LABELS_ONLY) {
372 fclose(fp);
373 return (1);
374 }
375
376 /* read in the number of data points */
377 fgets_skip(s, OAGBUFSIZ, fp, '!', 1);
378 if (!*s || 1 != sscanf(s, "%f", &tmp)) {
379 fprintf(stderr, "error in format of file %s--couldn't scan number of points\n", file);
380 exit(1);
381 }
382 n = tmp + 0.5;
383#ifdef DEBUG
384 fprintf(stderr, "n_pts = %ld\n", n);
385#endif
386
387 /* adjust the number of data points for the sampling interval */
388 if (sample_interval <= 0)
389 sample_interval = 1;
390 n = n / sample_interval;
391
392 /* allocate memory for column 1 and 2 data and sigmas */
393 tab->c1 = tmalloc(sizeof(*(tab->c1)) * n);
394 tab->c2 = tmalloc(sizeof(*(tab->c2)) * n);
395 tab->s1 = tmalloc(sizeof(*(tab->s1)) * n);
396 tab->s2 = tmalloc(sizeof(*(tab->s2)) * n);
397 tab->flags = 0;
398
399#ifdef DEBUG
400 fprintf(stderr, "data pointers are: %x, %x, %x, %x\n", (unsigned long)tab->c1, (unsigned long)tab->c2, (unsigned long)tab->s1, (unsigned long)tab->s2);
401#endif
402
403 /* read in the data points, one by one */
404 for (i = 0; i < n; i++) {
405 if (fgets_skip(s, OAGBUFSIZ, fp, '!', (i == 0 ? 1 : sample_interval))) {
406#ifdef DEBUG
407 fprintf(stderr, "string: <%s>\n", s);
408#endif
409 if ((ptr = strchr(s, '!')))
410 *ptr = 0;
411 if (!get_float(tab->c1 + i, s) || !get_float(tab->c2 + i, s)) {
412 fprintf(stderr, "warning: error in format of file %s--point %ld\n", file, n);
413 n = i - 1;
414 tab->c1 = trealloc((void *)tab->c1, sizeof(*(tab->c1)) * n);
415 tab->c2 = trealloc((void *)tab->c2, sizeof(*(tab->c2)) * n);
416 tab->s1 = trealloc((void *)tab->s1, sizeof(*(tab->s1)) * n);
417 tab->s2 = trealloc((void *)tab->s2, sizeof(*(tab->s2)) * n);
418 break;
419 }
420 tab->s1[i] = tab->s2[i] = 0;
421 if (i == 0) {
422 /* First point--establish the number of sigma values in the
423 * data. If there's only one sigma, interpret it as sigma_y,
424 * otherwise, the sigmas are sigma_x and sigma_y, in that
425 * order.
426 */
427 if (get_float(tab->s1 + i, s)) {
428 if (get_float(tab->s2 + i, s)) {
429 sigma_x_and_y_present = 1;
430 tab->flags |= SIGMA_X_PRESENT + SIGMA_Y_PRESENT;
431 } else {
432 tab->s2[i] = tab->s1[i];
433 tab->s1[i] = 0;
434 tab->flags |= SIGMA_Y_PRESENT;
435 sigma_y_present = 1;
436 }
437 }
438#ifdef DEBUG
439 fprintf(stderr, "tab->flags = %x\n", tab->flags);
440#endif
441 } else {
442 /* Scan sigma_y or (sigma_x, sigma_y) values, according
443 * to what the first line indicated is supposed to be present.
444 */
445 if (sigma_y_present && !get_float(tab->s2 + i, s)) {
446 fprintf(stderr, "error in format of file %s--expected sigma is missing\n", file);
447 exit(1);
448 } else if (sigma_x_and_y_present && (!get_float(tab->s1 + i, s) || !get_float(tab->s2 + i, s))) {
449 fprintf(stderr, "error in format of file %s--expected sigma is missing\n", file);
450 exit(1);
451 }
452 }
453 if (flags & SWAP) {
454 /* exchange x and y data points */
455 tmp = tab->c1[i];
456 tab->c1[i] = tab->c2[i];
457 tab->c2[i] = tmp;
458 /* exchange the sigmas, too */
459 tmp = tab->s1[i];
460 tab->s1[i] = tab->s2[i];
461 tab->s2[i] = tmp;
462 }
463 } else {
464 fprintf(stderr, "Warning: file %s contains only %ld of %ld expected points.\n", file, i, n);
465 n = i;
466 tab->c1 = trealloc((void *)tab->c1, sizeof(*(tab->c1)) * n);
467 tab->c2 = trealloc((void *)tab->c2, sizeof(*(tab->c2)) * n);
468 tab->s1 = trealloc((void *)tab->s1, sizeof(*(tab->s1)) * n);
469 tab->s2 = trealloc((void *)tab->s2, sizeof(*(tab->s2)) * n);
470 break;
471 }
472 }
473 tab->n_data = n;
474
475 /* Check to see if the data needs to be reverse in order, i.e.,
476 * if the first point should be the last and the last first.
477 */
478 if (flags & REVERSE || ((flags & REORDER_ASCENDING) && tab->c1[0] > tab->c1[n - 1]) || ((flags & REORDER_DESCENDING) && tab->c1[0] < tab->c1[n - 1])) {
479 /* Reverse the order of the data. */
480 m = n - 1;
481 for (i = 0; i < n / 2; i++) {
482 tmp = tab->c1[i];
483 tab->c1[i] = tab->c1[m - i];
484 tab->c1[m - i] = tmp;
485 tmp = tab->c2[i];
486 tab->c2[i] = tab->c2[m - i];
487 tab->c2[m - i] = tmp;
488 tmp = tab->s1[i];
489 tab->s1[i] = tab->s1[m - i];
490 tab->s1[m - i] = tmp;
491 tmp = tab->s2[i];
492 tab->s2[i] = tab->s2[m - i];
493 tab->s2[m - i] = tmp;
494 }
495 }
496
497 /* Check file for extra data. */
498 if (fgets_skip(s, OAGBUFSIZ, fp, '!', sample_interval))
499 fprintf(stderr, "Warning: file %s contains excess data (which is ignored).\n", file);
500
501 /* If there were no sigmas, free the arrays. */
502 if (!(tab->flags & SIGMA_X_PRESENT || tab->flags & SIGMA_Y_PRESENT) && !(flags & SAVE_SIGMA_ARRAYS)) {
503 tfree(tab->s1);
504 tab->s1 = NULL;
505 tfree(tab->s2);
506 tab->s2 = NULL;
507 }
508
509#ifdef DEBUG
510 for (i = 0; i < n; i++) {
511 fprintf(stderr, "%ldth point: c1=%le c2=%le", i, tab->c1[i], tab->c2[i]);
512 if (tab->s1)
513 fprintf(stderr, " s1=%le s2=%le\n", tab->s1[i], tab->s2[i]);
514 else
515 fputc('\n', stderr);
516 }
517#endif
518
519 fclose(fp);
520 return (1);
521}
int get_float(float *fptr, char *s)
Parses a float value from the given string.
Definition data_scan.c:208

◆ put_table()

void put_table ( char * file,
TABLE * tab,
char * format )

Definition at line 294 of file table.c.

294 {
295 register long i;
296 FILE *fp;
297
298 if (SDDS_WriteMplTable(tab, file))
299 return;
300
301 fp = fopen_e(file, "w", FOPEN_SAVE_IF_EXISTS);
302
303 fprintf(fp, "%s\n%s\n%s\n%s\n%-10ld\n", tab->xlab, tab->ylab, tab->title, tab->topline, tab->n_data);
304
305 if (tab->flags & SIGMA_X_PRESENT && tab->flags & SIGMA_Y_PRESENT) {
306 if (format == NULL)
307 format = "%le %le %le %le\n";
308 for (i = 0; i < tab->n_data; i++)
309 fprintf(fp, format, tab->c1[i], tab->c2[i], tab->s1[i], tab->s2[i]);
310 } else if (tab->flags & SIGMA_X_PRESENT) {
311 if (format == NULL)
312 format = "%le %le %le 0.0\n";
313 for (i = 0; i < tab->n_data; i++)
314 fprintf(fp, format, tab->c1[i], tab->c2[i], tab->s1[i]);
315 } else if (tab->flags & SIGMA_Y_PRESENT) {
316 if (format == NULL)
317 format = "%le %le %le\n";
318 for (i = 0; i < tab->n_data; i++)
319 fprintf(fp, format, tab->c1[i], tab->c2[i], tab->s2[i]);
320 } else {
321 if (format == NULL)
322 format = "%le %le\n";
323 for (i = 0; i < tab->n_data; i++)
324 fprintf(fp, format, tab->c1[i], tab->c2[i]);
325 }
326
327 fclose(fp);
328}
int32_t SDDS_WriteMplTable(TABLE *mpl_data, char *file)
Writes an MPL-compatible table to an SDDS file.

◆ put_table_float()

void put_table_float ( char * file,
TABLE_FLOAT * tab,
char * format )

Definition at line 530 of file table.c.

530 {
531 register long i;
532 FILE *fp;
533
534 fp = fopen_e(file, "w", FOPEN_SAVE_IF_EXISTS);
535
536 fprintf(fp, "%s\n%s\n%s\n%s\n%-10ld\n", tab->xlab, tab->ylab, tab->title, tab->topline, tab->n_data);
537
538 if (tab->flags & SIGMA_X_PRESENT && tab->flags & SIGMA_Y_PRESENT) {
539 if (format == NULL)
540 format = "%e %e %e %e\n";
541 for (i = 0; i < tab->n_data; i++)
542 fprintf(fp, format, tab->c1[i], tab->c2[i], tab->s1[i], tab->s2[i]);
543 } else if (tab->flags & SIGMA_X_PRESENT) {
544 if (format == NULL)
545 format = "%e %e %e 0.0\n";
546 for (i = 0; i < tab->n_data; i++)
547 fprintf(fp, format, tab->c1[i], tab->c2[i], tab->s1[i]);
548 } else if (tab->flags & SIGMA_Y_PRESENT) {
549 if (format == NULL)
550 format = "%e %e %e\n";
551 for (i = 0; i < tab->n_data; i++)
552 fprintf(fp, format, tab->c1[i], tab->c2[i], tab->s2[i]);
553 } else {
554 if (format == NULL)
555 format = "%e %e\n";
556 for (i = 0; i < tab->n_data; i++)
557 fprintf(fp, format, tab->c1[i], tab->c2[i]);
558 }
559
560 fclose(fp);
561}

◆ SDDS_AddMplDefinition()

long SDDS_AddMplDefinition ( SDDS_DATASET * SDDS_dataset,
char * label,
char * suffix,
char * default_name,
char * filename )

Adds an MPL-compatible column definition to an SDDS dataset.

This function defines a new column in the provided SDDS_dataset based on the given label, suffix, and default name. It handles the extraction of the symbol and unit from the label, ensures that the column name is unique within the dataset, and appends the suffix to create the final column name.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure where the column will be added.
labelThe label string containing the name and optionally the unit in the format "Name (Unit)".
suffixAn optional suffix to append to the column name. Can be NULL if no suffix is needed.
default_nameThe default name to use if the label is blank.
filenameThe name of the file being processed, used for error reporting.
Returns
Returns the index of the newly added column on success, or -1 if an error occurs.
See also
SDDS_DefineColumn

Definition at line 764 of file SDDS_mplsupport.c.

764 {
765 char *symbol, *name, *unit;
766 int32_t index;
767
768 unit = NULL;
769 if (SDDS_StringIsBlank(label)) {
770 name = SDDS_Malloc(sizeof(*name) * (strlen(default_name) + (suffix ? strlen(suffix) : 0) + 1));
771 sprintf(name, "%s%s", default_name, suffix ? suffix : "");
772 SDDS_CopyString(&symbol, name);
773 } else {
774 SDDS_ExtractNameAndUnit(&symbol, &unit, label);
775 name = SDDS_Malloc(sizeof(*name) * (strlen(symbol) + (suffix ? strlen(suffix) : 0) + 1));
776 sprintf(name, "%s%s", symbol, suffix ? suffix : "");
777 SDDS_FixMplName(name);
778 }
779 if (SDDS_GetColumnIndex(SDDS_dataset, name) >= 0) {
780 fprintf(stderr, "error: column name %s already exists in file %s\n", name, filename);
781 return -1;
782 }
783 if ((index = SDDS_DefineColumn(SDDS_dataset, name, symbol, unit, NULL, NULL, SDDS_DOUBLE, 0)) < 0) {
784 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
785 return -1;
786 }
787 free(name);
788 free(symbol);
789 if (unit)
790 free(unit);
791 return index;
792}
void SDDS_FixMplName(char *name)
Cleans and fixes an MPL-compatible name by removing specific sequences and extra spaces.
void SDDS_ExtractNameAndUnit(char **name, char **unit, char *label)
Extracts the name and unit from a labeled string.
int32_t SDDS_DefineColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, int32_t field_length)
Defines a data column within the SDDS dataset.
int32_t SDDS_GetColumnIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named column 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_Malloc(size_t size)
Allocates memory of a specified size.
Definition SDDS_utils.c:639
int32_t SDDS_StringIsBlank(char *s)
Checks if a string is blank (contains only whitespace characters).
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
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37

◆ SDDS_ExtractNameAndUnit()

void SDDS_ExtractNameAndUnit ( char ** name,
char ** unit,
char * label )

Extracts the name and unit from a labeled string.

This function parses a label string to separate the name and its associated unit. It looks for the pattern " (unit)" within the label. If found, it splits the label into the name and unit components. The function also trims any trailing spaces from the name.

Parameters
nameDouble pointer to a string where the extracted name will be stored. Memory is allocated internally.
unitDouble pointer to a string where the extracted unit will be stored. Memory is allocated internally. If no unit is found, *unit is set to NULL.
labelThe input label string containing the name and optionally the unit in the format "Name (Unit)".
Note
The caller is responsible for freeing the memory allocated for *name and *unit if they are not NULL.

Definition at line 730 of file SDDS_mplsupport.c.

730 {
731 char *ptr, *uptr;
732
733 if ((uptr = strstr(label, " ("))) {
734 *uptr = 0;
735 uptr += 2;
736 if ((ptr = strchr(uptr, ')')))
737 *ptr = 0;
738 SDDS_CopyString(unit, uptr);
739 } else
740 *unit = NULL;
741 ptr = label + strlen(label) - 1;
742 while (ptr != label && *ptr == ' ')
743 *ptr-- = 0;
744 SDDS_CopyString(name, label);
745}

◆ SDDS_FixMplName()

void SDDS_FixMplName ( char * name)

Cleans and fixes an MPL-compatible name by removing specific sequences and extra spaces.

This function iterates through the provided name string and removes any occurrence of a dollar sign ('$') followed by specific characters (‘'a’,'b','n','g','r', 's','e','d','i','v','u'`). Additionally, it removes any extra spaces within the string, ensuring that only single spaces remain between words.

Parameters
nameA mutable string representing the name to be fixed. The string is modified in place.
Note
This function assumes that the name string is mutable and has sufficient space to handle in-place modifications.

Definition at line 684 of file SDDS_mplsupport.c.

684 {
685 char *ptr, *ptr1;
686 ptr = name;
687 while ((ptr = strchr(ptr, '$'))) {
688 switch (*(ptr + 1)) {
689 case 'a':
690 case 'b':
691 case 'n':
692 case 'g':
693 case 'r':
694 case 's':
695 case 'e':
696 case 'd':
697 case 'i':
698 case 'v':
699 case 'u':
700 strcpy(ptr, ptr + 2);
701 break;
702 default:
703 ptr += 1;
704 break;
705 }
706 }
707 ptr = name;
708 while ((ptr = strchr(ptr, ' '))) {
709 ptr1 = ptr;
710 while (*ptr1 == ' ')
711 ptr1++;
712 strcpy(ptr, ptr1);
713 }
714}

◆ SDDS_ReadIntoMplTable()

int32_t SDDS_ReadIntoMplTable ( TABLE * mpl_data,
char * file,
int64_t sample_interval,
int32_t mpl_flags,
char * SDDS_tags )

Reads SDDS data into an MPL-compatible table structure.

This function initializes an SDDS dataset from the specified file, processes the data according to the provided sample interval and flags, and populates the mpl_data table with the sampled data. It handles column and parameter-based matching as specified by SDDS_tags.

Parameters
mpl_dataPointer to the TABLE structure where the SDDS data will be stored.
fileThe filename of the SDDS data file to read.
sample_intervalThe interval at which data points are sampled from the source.
mpl_flagsFlags controlling the behavior of the MPL data processing.
SDDS_tagsOptional tags specifying columns or parameters of interest.
Returns
Returns 1 on successful reading and processing, or 0 if an error occurs.

Definition at line 294 of file SDDS_mplsupport.c.

294 {
295 SDDS_DATASET SDDS_dataset;
296 int32_t first;
297 int64_t i, new_points, n_rows;
298 SDDS_LAYOUT *layout;
299 char *xname, *yname, *sxname, *syname, *option_string, *ptr;
300 COLUMN_DEFINITION *xdef, *ydef, *sxdef, *sydef;
301 PARAMETER_DEFINITION *xpdef, *ypdef, *sxpdef, *sypdef;
302 PARAMETER_DEFINITION *titledef, *toplinedef, *pardef;
303 char s[SDDS_MAXLINE];
304 double *data;
305 MATCH_TERM *column_match, *parameter_match;
306 int32_t accept = 1;
307
308 xname = yname = sxname = syname = NULL;
309 xdef = ydef = sxdef = sydef = NULL;
310 xpdef = ypdef = sxpdef = sypdef = titledef = toplinedef = NULL;
311 n_rows = 0;
312
313 if (!SDDS_InitializeInput(&SDDS_dataset, file)) {
314 SDDS_PrintErrors(stderr, 1);
315 return (0);
316 }
317 layout = &SDDS_dataset.layout;
318 if (SDDS_dataset.layout.n_columns < 1 && SDDS_dataset.layout.n_parameters < 1)
319 return (0);
320
321 first = 1;
322 while (SDDS_ReadPage(&SDDS_dataset) > 0) {
323 if (first) {
324 first = 0;
325#if 0
326 if ((pardef = SDDS_GetParameterDefinition(&SDDS_dataset, "mplTitle")) && pardef->type == SDDS_STRING)
327 mpl_data->title = SDDS_GetParameter(&SDDS_dataset, "mplTitle", NULL);
328 else
329 SDDS_CopyString(&mpl_data->title, "");
330 if ((pardef = SDDS_GetParameterDefinition(&SDDS_dataset, "mplTopline")) && pardef->type == SDDS_STRING)
331 mpl_data->topline = SDDS_GetParameter(&SDDS_dataset, "mplTopline", NULL);
332 else
333 SDDS_CopyString(&mpl_data->topline, "");
334#endif
335
336 xname = yname = sxname = syname = option_string = NULL;
337 xdef = ydef = sxdef = sydef = NULL;
338 xpdef = ypdef = sxpdef = sypdef = NULL;
339 if (SDDS_tags) {
340 /* expect columns-of-interest to be specified in this string as
341 * <xname>+<yname>[+<syname>][,<options>] or
342 * <xname>+<yname>[+<sxname>+<syname>][,<options>]
343 */
344 xname = SDDS_tags;
345 if ((yname = strchr(xname, '+'))) {
346 ptr = yname;
347 while ((option_string = strchr(ptr, ','))) {
348 if (option_string != ptr && *(option_string - 1) == '\\')
349 ptr = option_string + 1;
350 else {
351 *option_string++ = 0;
352 break;
353 }
354 }
355 *yname++ = 0;
356 if ((sxname = strchr(yname, '+'))) {
357 *sxname++ = 0;
358 if ((syname = strchr(sxname, '+'))) {
359 *syname++ = 0;
360 } else {
361 syname = sxname;
362 sxname = NULL;
363 }
364 }
365 }
366 delete_bounding_characters(xname, "\"'");
367 delete_bounding_characters(yname, "\"'");
368 if (sxname)
369 delete_bounding_characters(sxname, "\"'");
370 if (syname)
371 delete_bounding_characters(syname, "\"'");
372 }
373
374 if (!xname || !yname) {
375 xname = yname = NULL;
376 /* No columns-of-interest found in SDDS_tags. Check for parameters mplxName and mplyName */
377 if ((pardef = SDDS_GetParameterDefinition(&SDDS_dataset, "mplxName")) && pardef->type == SDDS_STRING && (pardef = SDDS_GetParameterDefinition(&SDDS_dataset, "mplyName")) && pardef->type == SDDS_STRING) {
378 xname = SDDS_GetParameter(&SDDS_dataset, "mplxName", NULL);
379 yname = SDDS_GetParameter(&SDDS_dataset, "mplyName", NULL);
380 if (xname && yname) {
381 /* check for mplSigmaxName and mplSigmayName */
382 if ((pardef = SDDS_GetParameterDefinition(&SDDS_dataset, "mplSigmayName")) && pardef->type == SDDS_STRING)
383 syname = SDDS_GetParameter(&SDDS_dataset, "mplSigmayName", NULL);
384 if ((pardef = SDDS_GetParameterDefinition(&SDDS_dataset, "mplSigmaxName")) && pardef->type == SDDS_STRING)
385 sxname = SDDS_GetParameter(&SDDS_dataset, "mplSigmaxName", NULL);
386 }
387 }
388 }
389
390 if (!xname || !yname) {
391 /* No columns-of-interest found in SDDS_tags or parameters. Just take the first two numeric
392 * column definitions in order
393 */
394 for (i = 0; i < layout->n_columns; i++) {
395 if (SDDS_NUMERIC_TYPE(layout->column_definition[i].type)) {
396 if (!xname)
397 xname = layout->column_definition[i].name;
398 else if (!yname)
399 yname = layout->column_definition[i].name;
400 else
401 break;
402 }
403 }
404 if (sxname && !syname) {
405 syname = sxname;
406 sxname = NULL;
407 }
408 }
409
410 if (!xname || !yname)
411 return (0);
412
413 if (!((xdef = SDDS_GetColumnDefinition(&SDDS_dataset, xname)) && SDDS_NUMERIC_TYPE(xdef->type)) && !((xpdef = SDDS_GetParameterDefinition(&SDDS_dataset, xname)) && SDDS_NUMERIC_TYPE(xpdef->type))) {
414 fprintf(stderr, "error: column (or parameter) %s does not exist or is non-numeric\n", xname);
415 SDDS_PrintListOfColumns(&SDDS_dataset, "Valid columns are:\n", stderr);
416 SDDS_PrintListOfParameters(&SDDS_dataset, "Valid parameters are:\n", stderr);
417 return (0);
418 }
419 if (xdef) {
420 if (!((ydef = SDDS_GetColumnDefinition(&SDDS_dataset, yname)) && SDDS_NUMERIC_TYPE(ydef->type))) {
421 fprintf(stderr, "error: column %s does not exist or is non-numeric\n", yname);
422 SDDS_PrintListOfColumns(&SDDS_dataset, "Valid columns are:\n", stderr);
423 return (0);
424 }
425 if (sxname && !((sxdef = SDDS_GetColumnDefinition(&SDDS_dataset, sxname)) && SDDS_NUMERIC_TYPE(sxdef->type))) {
426 fprintf(stderr, "error: column %s does not exist or is non-numeric\n", sxname);
427 SDDS_PrintListOfColumns(&SDDS_dataset, "Valid columns are:\n", stderr);
428 return (0);
429 }
430 if (syname && !((sydef = SDDS_GetColumnDefinition(&SDDS_dataset, syname)) && SDDS_NUMERIC_TYPE(sydef->type))) {
431 fprintf(stderr, "error: column %s does not exist or is non-numeric\n", syname);
432 SDDS_PrintListOfColumns(&SDDS_dataset, "Valid columns are:\n", stderr);
433 return (0);
434 }
435 if (xdef->symbol && !(mpl_flags & SDDS_NOCOMPRESS_NAMES))
436 delete_chars(xdef->symbol, " ");
437 if (ydef->symbol && !(mpl_flags & SDDS_NOCOMPRESS_NAMES))
438 delete_chars(ydef->symbol, " ");
439 if (sxdef && sxdef->symbol && !(mpl_flags & SDDS_NOCOMPRESS_NAMES))
440 delete_chars(sxdef->symbol, " ");
441 if (sydef && sydef->symbol && !(mpl_flags & SDDS_NOCOMPRESS_NAMES))
442 delete_chars(sydef->symbol, " ");
443
444 if (xdef->units && !SDDS_StringIsBlank(xdef->units))
445 sprintf(s, "%s (%s)", xdef->symbol ? xdef->symbol : xdef->name, xdef->units);
446 else
447 sprintf(s, "%s", xdef->symbol ? xdef->symbol : xdef->name);
448 SDDS_CopyString(&mpl_data->xlab, s);
449 if (ydef->units && !SDDS_StringIsBlank(ydef->units))
450 sprintf(s, "%s (%s)", ydef->symbol ? ydef->symbol : ydef->name, ydef->units);
451 else
452 sprintf(s, "%s", ydef->symbol ? ydef->symbol : ydef->name);
453 SDDS_CopyString(&mpl_data->ylab, s);
454 toplinedef = titledef = NULL;
455 if ((toplinedef = SDDS_GetParameterDefinition(&SDDS_dataset, "mplTopline")) && (toplinedef->type != SDDS_STRING || !SDDS_GetParameter(&SDDS_dataset, toplinedef->name, &mpl_data->topline))) {
457 toplinedef = NULL;
458 }
459 if (!toplinedef) {
460 if (layout->description)
461 SDDS_CopyString(&mpl_data->topline, layout->description);
462 else
463 SDDS_CopyString(&mpl_data->topline, "");
464 }
465 if ((titledef = SDDS_GetParameterDefinition(&SDDS_dataset, "mplTitle"))) {
466 if (titledef->type != SDDS_STRING || !SDDS_GetParameter(&SDDS_dataset, titledef->name, &mpl_data->title))
467 titledef = NULL;
468 }
469 if (!titledef) {
470 if (!option_string)
471 sprintf(s, "%s vs %s", ydef->description ? ydef->description : (ydef->symbol ? ydef->symbol : yname), xdef->description ? xdef->description : (xdef->symbol ? xdef->symbol : xname));
472 else
473 sprintf(s, "%s vs %s : %s", ydef->description ? ydef->description : (ydef->symbol ? ydef->symbol : yname), xdef->description ? xdef->description : (xdef->symbol ? xdef->symbol : xname), option_string);
474 SDDS_CopyString(&mpl_data->title, s);
475 }
476 } else {
477 if (!((ypdef = SDDS_GetParameterDefinition(&SDDS_dataset, yname)) && SDDS_NUMERIC_TYPE(ypdef->type))) {
478 fprintf(stderr, "error: parameter %s does not exist or is non-numeric\n", yname);
479 SDDS_PrintListOfParameters(&SDDS_dataset, "Valid parameters are:\n", stderr);
480 return (0);
481 }
482 if (sxname && !((sxpdef = SDDS_GetParameterDefinition(&SDDS_dataset, sxname)) && SDDS_NUMERIC_TYPE(sxpdef->type))) {
483 fprintf(stderr, "error: parameter %s does not exist or is non-numeric\n", sxname);
484 SDDS_PrintListOfParameters(&SDDS_dataset, "Valid parameters are:\n", stderr);
485 return (0);
486 }
487 if (syname && !((sypdef = SDDS_GetParameterDefinition(&SDDS_dataset, syname)) && SDDS_NUMERIC_TYPE(sypdef->type))) {
488 fprintf(stderr, "error: parameter %s does not exist or is non-numeric\n", syname);
489 SDDS_PrintListOfParameters(&SDDS_dataset, "Valid parameters are:\n", stderr);
490 return (0);
491 }
492
493 if (xpdef->units && !SDDS_StringIsBlank(xpdef->units))
494 sprintf(s, "%s (%s)", xpdef->symbol ? delete_chars(xpdef->symbol, " ") : xpdef->name, xpdef->units);
495 else
496 sprintf(s, "%s", xpdef->symbol ? delete_chars(xpdef->symbol, " ") : xpdef->name);
497 SDDS_CopyString(&mpl_data->xlab, s);
498 if (ypdef->units && !SDDS_StringIsBlank(ypdef->units))
499 sprintf(s, "%s (%s)", ypdef->symbol ? delete_chars(ypdef->symbol, " ") : ypdef->name, ypdef->units);
500 else
501 sprintf(s, "%s", ypdef->symbol ? delete_chars(ypdef->symbol, " ") : ypdef->name);
502 SDDS_CopyString(&mpl_data->ylab, s);
503 toplinedef = titledef = NULL;
504 if ((toplinedef = SDDS_GetParameterDefinition(&SDDS_dataset, "mplTopline")) && (toplinedef->type != SDDS_STRING || !SDDS_GetParameter(&SDDS_dataset, toplinedef->name, &mpl_data->topline))) {
506 toplinedef = NULL;
507 }
508 if (!toplinedef) {
509 if (layout->description)
510 SDDS_CopyString(&mpl_data->topline, layout->description);
511 else
512 SDDS_CopyString(&mpl_data->topline, "");
513 }
514 if ((titledef = SDDS_GetParameterDefinition(&SDDS_dataset, "mplTitle"))) {
515 if (titledef->type != SDDS_STRING || !SDDS_GetParameter(&SDDS_dataset, titledef->name, &mpl_data->title))
516 titledef = NULL;
517 }
518 if (!titledef) {
519 if (!option_string)
520 sprintf(s, "%s vs %s", ypdef->description ? ypdef->description : (ypdef->symbol ? ypdef->symbol : yname), xpdef->description ? xpdef->description : (xpdef->symbol ? xpdef->symbol : xname));
521 else
522 sprintf(s, "%s vs %s : %s", ypdef->description ? ypdef->description : (ypdef->symbol ? ypdef->symbol : yname), xpdef->description ? xpdef->description : (xpdef->symbol ? xpdef->symbol : xname), option_string);
523 SDDS_CopyString(&mpl_data->title, s);
524 }
525 }
526
527 mpl_data->c1 = mpl_data->c2 = mpl_data->s1 = mpl_data->s2 = NULL;
528 mpl_data->n_data = 0;
529 mpl_data->flags = (sxname ? SIGMA_X_PRESENT : 0) + (syname ? SIGMA_Y_PRESENT : 0);
530
531 column_match = parameter_match = NULL;
532 if (option_string && !process_match_requests(&column_match, &parameter_match, option_string))
533 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
534 } /* end of block for first page */
535 if (!SDDS_dataset.n_rows && xdef)
536 continue;
537
538 accept = 1;
539 if (parameter_match) {
540 i = -1;
541 do {
542 i++;
543 if (!(pardef = SDDS_GetParameterDefinition(&SDDS_dataset, parameter_match[i].name)) || !(pardef->type == SDDS_STRING || pardef->type == SDDS_CHARACTER)) {
544 fprintf(stderr, "error: unknown or numeric parameter %s given for match\n", parameter_match[i].name);
545 exit(1);
546 }
547 if (pardef->type == SDDS_STRING) {
548 char **ppc;
549 ppc = SDDS_GetParameter(&SDDS_dataset, parameter_match[i].name, NULL);
550 strcpy(s, *ppc);
551 } else {
552 char *pc;
553 pc = SDDS_GetParameter(&SDDS_dataset, parameter_match[i].name, NULL);
554 sprintf(s, "%c", *pc);
555 }
556 accept = SDDS_Logic(accept, wild_match(s, parameter_match[i].string), parameter_match[i].logic);
557 } while (!parameter_match[i].last);
558 }
559 if (!accept)
560 continue;
561
562 if (xdef) {
563 if (!SDDS_SetColumnFlags(&SDDS_dataset, 1) ||
564 (sxname && syname &&
565 !SDDS_SetColumnsOfInterest(&SDDS_dataset, SDDS_NAME_STRINGS, xname, yname, sxname, syname, NULL)) ||
566 (syname && !sxname && !SDDS_SetColumnsOfInterest(&SDDS_dataset, SDDS_NAME_STRINGS, xname, yname, syname, NULL)) || !SDDS_SetColumnsOfInterest(&SDDS_dataset, SDDS_NAME_STRINGS, xname, yname, NULL))
567 return (0);
568
569 if (column_match) {
570 i = -1;
571 do {
572 i++;
573 if (SDDS_MatchRowsOfInterest(&SDDS_dataset, column_match[i].name, column_match[i].string, column_match[i].logic) < 0) {
574 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
575 exit(1);
576 }
577 } while (!column_match[i].last);
578 }
579
580 if ((n_rows = SDDS_CountRowsOfInterest(&SDDS_dataset)) <= 0)
581 continue;
582
583 if (!(new_points = ceil((1.0 * n_rows) / sample_interval)))
584 new_points = 1;
585 } else
586 new_points = 1;
587
588 /* allocate all four arrays, since that is the expected behavior from get_table() */
589 if (!(mpl_data->c1 = SDDS_Realloc(mpl_data->c1, sizeof(*mpl_data->c1) * (mpl_data->n_data + new_points))) ||
590 !(mpl_data->c2 = SDDS_Realloc(mpl_data->c2, sizeof(*mpl_data->c2) * (mpl_data->n_data + new_points))) ||
591 !(mpl_data->s1 = SDDS_Realloc(mpl_data->s1, sizeof(*mpl_data->s1) * (mpl_data->n_data + new_points))) || !(mpl_data->s2 = SDDS_Realloc(mpl_data->s2, sizeof(*mpl_data->s2) * (mpl_data->n_data + new_points)))) {
592 SDDS_SetError("Allocation failure creating mpl-compatible structure");
593 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
594 }
595
596 for (i = 0; i < new_points; i++)
597 mpl_data->c1[i + mpl_data->n_data] = mpl_data->c2[i + mpl_data->n_data] = mpl_data->s1[i + mpl_data->n_data] = mpl_data->s2[i + mpl_data->n_data] = 0;
598
599 if (xdef) {
600 if (!(data = SDDS_GetColumnInDoubles(&SDDS_dataset, xdef->name)) || (i = copy_doubles_with_sampling((mpl_flags & SWAP ? mpl_data->c2 : mpl_data->c1) + mpl_data->n_data, data, n_rows, sample_interval)) != new_points) {
601 sprintf(s, "Sampling problem: %" PRId64 " rows created, %" PRId64 " expected", i, new_points);
602 SDDS_SetError(s);
603 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
604 return (0);
605 }
606 free(data);
607 if (!(data = SDDS_GetColumnInDoubles(&SDDS_dataset, ydef->name)) || (i = copy_doubles_with_sampling((mpl_flags & SWAP ? mpl_data->c1 : mpl_data->c2) + mpl_data->n_data, data, n_rows, sample_interval)) != new_points) {
608 sprintf(s, "Sampling problem: %" PRId64 " rows created, %" PRId64 " expected", i, new_points);
609 SDDS_SetError(s);
610 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
611 return (0);
612 }
613 free(data);
614 if (sxdef) {
615 if (!(data = SDDS_GetColumnInDoubles(&SDDS_dataset, sxdef->name)) || (i = copy_doubles_with_sampling((mpl_flags & SWAP ? mpl_data->s2 : mpl_data->s1) + mpl_data->n_data, data, n_rows, sample_interval)) != new_points) {
616 sprintf(s, "Sampling problem: %" PRId64 " rows created, %" PRId64 " expected", i, new_points);
617 SDDS_SetError(s);
618 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
619 return (0);
620 }
621 free(data);
622 }
623 if (sydef) {
624 if (!(data = SDDS_GetColumnInDoubles(&SDDS_dataset, sydef->name)) || (i = copy_doubles_with_sampling((mpl_flags & SWAP ? mpl_data->s1 : mpl_data->s2) + mpl_data->n_data, data, n_rows, sample_interval)) != new_points) {
625 sprintf(s, "Sampling problem: %" PRId64 " rows created, %" PRId64 " expected", i, new_points);
626 SDDS_SetError(s);
627 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
628 return (0);
629 }
630 free(data);
631 }
632 } else {
633 int32_t buffer[16];
634 SDDS_GetParameter(&SDDS_dataset, xpdef->name, buffer);
635 mpl_data->c1[mpl_data->n_data] = SDDS_ConvertToDouble(xpdef->type, buffer, 0);
636 SDDS_GetParameter(&SDDS_dataset, ypdef->name, buffer);
637 mpl_data->c2[mpl_data->n_data] = SDDS_ConvertToDouble(ypdef->type, buffer, 0);
638 if (sxpdef) {
639 SDDS_GetParameter(&SDDS_dataset, sxpdef->name, buffer);
640 mpl_data->s1[mpl_data->n_data] = SDDS_ConvertToDouble(sxpdef->type, buffer, 0);
641 }
642 if (sypdef) {
643 SDDS_GetParameter(&SDDS_dataset, sypdef->name, buffer);
644 mpl_data->s2[mpl_data->n_data] = SDDS_ConvertToDouble(sypdef->type, buffer, 0);
645 }
646 if (SDDS_NumberOfErrors()) {
647 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
648 return (0);
649 }
650 }
651 mpl_data->n_data += new_points;
652 }
653 if (xdef)
655 if (ydef)
657 if (sxdef)
659 if (sydef)
661 if (titledef)
663 if (toplinedef)
665 if (first || !SDDS_Terminate(&SDDS_dataset)) {
666 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
667 return (0);
668 }
669 return (1);
670}
int64_t SDDS_CountRowsOfInterest(SDDS_DATASET *SDDS_dataset)
Counts the number of rows marked as "of interest" in the current data table.
int32_t SDDS_SetColumnsOfInterest(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
Sets the acceptance flags for columns based on specified naming criteria.
int64_t SDDS_MatchRowsOfInterest(SDDS_DATASET *SDDS_dataset, char *selection_column, char *label_to_match, int32_t logic)
Matches and marks rows of interest in an SDDS dataset based on label matching.
int32_t SDDS_Logic(int32_t previous, int32_t match, uint32_t logic)
Applies logical operations to determine the new state of a row flag based on previous and current mat...
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.
int32_t SDDS_SetColumnFlags(SDDS_DATASET *SDDS_dataset, int32_t column_flag_value)
Sets the acceptance flags for all columns in the current data table of a data set.
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)
int64_t copy_doubles_with_sampling(double *target, double *source, int64_t source_points, int64_t sample_interval)
Copies elements from the source array to the target array with sampling.
int32_t process_match_requests(MATCH_TERM **column_match, MATCH_TERM **parameter_match, char *option_string)
Processes match requests for columns and parameters based on an option string.
void SDDS_PrintListOfParameters(SDDS_DATASET *SDDS_dataset, char *message, FILE *fp)
Prints a list of parameters in the SDDS dataset.
void SDDS_PrintListOfColumns(SDDS_DATASET *SDDS_dataset, char *message, FILE *fp)
Prints a list of columns in the SDDS dataset.
char * delete_bounding_characters(char *s, char *t)
Removes specified bounding characters from a string.
double SDDS_ConvertToDouble(int32_t type, void *data, int64_t index)
Converts a value to double based on its type.
Definition SDDS_rpn.c:199
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
Definition SDDS_utils.c:379
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_NumberOfErrors()
Retrieves the number of errors recorded by SDDS library routines.
Definition SDDS_utils.c:304
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
Definition SDDS_utils.c:677
int32_t SDDS_FreeColumnDefinition(COLUMN_DEFINITION *source)
Frees memory allocated for a column definition.
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_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
#define SDDS_CHARACTER
Identifier for the character data type.
Definition SDDStypes.h:91
#define SDDS_NUMERIC_TYPE(type)
Checks if the given type identifier corresponds to any numeric type.
Definition SDDStypes.h:138
char * delete_chars(char *s, char *t)
Removes all occurrences of characters found in string t from string s.
int wild_match(char *string, char *template)
Determine whether one string is a wildcard match for another.
Definition wild_match.c:49

◆ SDDS_WriteMplTable()

int32_t SDDS_WriteMplTable ( TABLE * mpl_data,
char * file )

Writes an MPL-compatible table to an SDDS file.

This function initializes an SDDS output file, defines necessary columns based on the provided mpl_data, and writes the data to the file. It handles optional sigma columns, ensures that the output file does not overwrite existing files by renaming them if necessary, and respects environment variables for output configuration.

Parameters
mpl_dataPointer to the TABLE structure containing MPL data to be written.
fileThe filename of the SDDS file where the data will be written.
Returns
Returns 1 on successful writing of the MPL table, or 0 if an error occurs.
Note
This function relies on several SDDS utility functions and assumes that the SDDS library is properly initialized and configured.
See also
SDDS_DefineColumn
SDDS_WritePage

Definition at line 813 of file SDDS_mplsupport.c.

813 {
814 SDDS_DATASET page;
815 char *mplSDDSOutput = NULL;
816 int32_t mplSDDS_datamode = SDDS_BINARY, mplSDDS_disable = 1;
817 int32_t sx_index, sy_index;
818
819 if (!mpl_data) {
820 fprintf(stderr, "error: NULL mpl TABLE passed (SDDS_WriteMplTable)\n");
821 return 0;
822 }
823 if (!file) {
824 fprintf(stderr, "error: NULL filename passed (SDDS_WriteMplTable)\n");
825 return 0;
826 }
827 if (!mplSDDSOutput) {
828 if (!(mplSDDSOutput = getenv("mplSDDSOutput")))
829 SDDS_CopyString(&mplSDDSOutput, "");
830 }
831 if (mplSDDSOutput[0]) {
832 if (strstr(mplSDDSOutput, "enable"))
833 mplSDDS_disable = 0;
834 if (strstr(mplSDDSOutput, "ascii"))
835 mplSDDS_datamode = SDDS_ASCII;
836 }
837
838 if (mplSDDS_disable)
839 return 0;
840
841 if (fexists(file)) {
842 char *buffer;
843 buffer = SDDS_Malloc(sizeof(*file) * (strlen(file) + 2));
844 sprintf(buffer, "%s~", file);
845 if (rename(file, buffer) != 0) {
846 SDDS_SetError("Cannot save previous version of output file (SDDS_WriteMplTable)");
847 free(buffer);
848 return 0;
849 }
850 free(buffer);
851 }
852
853 if (!SDDS_InitializeOutput(&page, mplSDDS_datamode, 1, NULL, NULL, file) ||
854 (mpl_data->topline && !SDDS_StringIsBlank(mpl_data->topline) && SDDS_DefineParameter(&page, "mplTopline", NULL, NULL, NULL, NULL, SDDS_STRING, mpl_data->topline) < 0) || (mpl_data->title && !SDDS_StringIsBlank(mpl_data->title) && SDDS_DefineParameter(&page, "mplTitle", NULL, NULL, NULL, NULL, SDDS_STRING, mpl_data->title) < 0)) {
855 SDDS_SetError("Problem initializing SDDS output of mpl page data (SDDS_WriteMplTable)");
856 return 0;
857 }
858 if (SDDS_AddMplDefinition(&page, mpl_data->xlab, NULL, "x", file) < 0 || SDDS_AddMplDefinition(&page, mpl_data->ylab, NULL, "y", file) < 0) {
859 SDDS_SetError("Unable to define primary mpl columns for SDDS output (SDDS_WriteMplTable)");
860 return 0;
861 }
862 sx_index = sy_index = -1;
863 if (mpl_data->flags & SIGMA_X_PRESENT && (sx_index = SDDS_AddMplDefinition(&page, mpl_data->xlab, "Sigma", "x", file)) < 0) {
864 SDDS_SetError("Unable to define sigma-x column for SDDS output (SDDS_WriteMplTable)");
865 return 0;
866 }
867 if (mpl_data->flags & SIGMA_Y_PRESENT && (sy_index = SDDS_AddMplDefinition(&page, mpl_data->ylab, "Sigma", "y", file)) < 0) {
868 SDDS_SetError("Unable to define sigma-y column for SDDS output (SDDS_WriteMplTable)");
869 return 0;
870 }
871 if (!SDDS_WriteLayout(&page)) {
872 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
873 return 0;
874 }
875 if (!SDDS_StartPage(&page, mpl_data->n_data)) {
876 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
877 return 0;
878 }
879 if (!SDDS_SetColumn(&page, SDDS_SET_BY_INDEX, mpl_data->c1, mpl_data->n_data, 0) ||
880 !SDDS_SetColumn(&page, SDDS_SET_BY_INDEX, mpl_data->c2, mpl_data->n_data, 1) || (sx_index >= 0 && !SDDS_SetColumn(&page, SDDS_SET_BY_INDEX, mpl_data->s1, mpl_data->n_data, sx_index)) || (sy_index >= 0 && !SDDS_SetColumn(&page, SDDS_SET_BY_INDEX, mpl_data->s2, mpl_data->n_data, sy_index))) {
881 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
882 return 0;
883 }
884 if (!SDDS_WritePage(&page) || !SDDS_Terminate(&page)) {
885 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
886 return 0;
887 }
888 return 1;
889}
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
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_AddMplDefinition(SDDS_DATASET *SDDS_dataset, char *label, char *suffix, char *default_name, char *filename)
Adds an MPL-compatible column definition to an SDDS dataset.
int32_t SDDS_InitializeOutput(SDDS_DATASET *SDDS_dataset, int32_t data_mode, int32_t lines_per_row, const char *description, const char *contents, const char *filename)
Initializes the SDDS output dataset.
int32_t SDDS_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
int32_t SDDS_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
int32_t SDDS_DefineParameter(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, char *fixed_value)
Defines a data parameter with a fixed string value.