TPCCLIB
Loading...
Searching...
No Matches
parres.c File Reference

TPC result (*.res) file format I/O functions. More...

#include "tpcclibConfig.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <string.h>
#include "tpcextensions.h"
#include "tpccsv.h"
#include "tpcift.h"
#include "tpcpar.h"

Go to the source code of this file.

Functions

int parWriteRES (PAR *par, FILE *fp, TPCSTATUS *status)
int parReadRES (PAR *par, CSV *csv, IFT *ift, TPCSTATUS *status)
int parPrintType (PAR *par, int parIndex)

Detailed Description

TPC result (*.res) file format I/O functions.

Definition in file parres.c.

Function Documentation

◆ parPrintType()

int parPrintType ( PAR * par,
int parIndex )

Determine whether the parameter should be printed as integer (0), float (1), or exponential (2).

Returns
Returns the code, or <0 in case of an error.
Parameters
parPointer to the PAR structure.
parIndexIndex of the parameter to test.

Definition at line 584 of file parres.c.

589 {
590 int vi, partype=0;
591 double x, m=0.0, pint;
592
593 if(par==NULL || par->tacNr<1 || parIndex<0 || parIndex>=par->tacNr)
594 return(-1);
595 for(vi=0; vi<par->tacNr; vi++) {
596 x=par->r[vi].p[parIndex];
597 if(modf(x, &pint)!=0.0) partype=1;
598 x=fabs(x); if(x>m) m=x;
599 }
600 if(partype==1 && (m>=10.0 || m<0.1)) partype=2;
601 return(partype);
602}
int tacNr
Definition tpcpar.h:104
PARR * r
Definition tpcpar.h:114
double * p
Definition tpcpar.h:64

Referenced by parWriteRES().

◆ parReadRES()

int parReadRES ( PAR * par,
CSV * csv,
IFT * ift,
TPCSTATUS * status )

Read result (RES) data into PAR struct.

Returns
enum tpcerror (TPCERROR_OK when successful).
Author
Vesa Oikonen
Parameters
parPointer to target PAR struct.
csvPointer to CSV from which data is read.
iftPointer to IFT struct which contains whole result file data, in case the data could not be read into CSV (which happens when spaces were used as field separator).
statusPointer to status data; enter NULL if not needed.

Definition at line 268 of file parres.c.

278 {
279 int verbose=0; if(status!=NULL) verbose=status->verbose;
280 if(verbose>0) {printf("%s()\n", __func__); fflush(stdout);}
281 if(par==NULL) {
282 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
283 return TPCERROR_FAIL;
284 }
285 parFree(par);
286
287 if(csv==NULL || ift==NULL || csv->row_nr<1 || csv->col_nr<1) {
288 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
289 return TPCERROR_NO_DATA;
290 }
291
292 if(verbose>10) {
293 printf("\n CSV contents shown with separator ; \n\n");
294 char sep=csv->separator;
295 csv->separator=';'; csvWrite(csv, 0, stdout, NULL); csv->separator=sep;
296 printf("\n IFT contents \n\n");
297 iftWrite(ift, stdout, NULL);
298 }
299
300 int i, ret, titlerow;
301 int ri, ci, parNr=0, tacNr=0;
302 char *cptr;
303
304 /* Find the result title line; get initial parameter and tac nr */
305 i=0; if(verbose>2) printf("estimating parNr and tacNr\n");
306 while(i<csv->nr) {
307 i=csvFindField(csv, "Region", i); if(i<0) break;
308 if(i>=0 && csv->c[i].col==0) break;
309 i++;
310 }
311 if(i<0 || i==csv->nr) {
312 parFree(par);
313 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
315 }
316 titlerow=csv->c[i].row;
317 /* Get parameter nr */
318 parNr=csvRowLength(csv, titlerow)-1;
319 // sometimes empty cells in the end
320 ci=parNr; while(ci>0 && strlen(csv->c[ci].content)<1) {ci--; parNr--;}
321 // sometimes an empty cell before parameter names
322 if(strlen(csv->c[i+1].content)<1) parNr--;
323 /* Get region nr */
324 ri=1+titlerow; ci=0;
325 cptr=csvCell(csv, ri, ci);
326 while(cptr!=NULL) {
327 if(csv->separator!=' ') {
328 if(strncasecmp(cptr, "SD . .", 3) && strncasecmp(cptr, "CL 95% ", 7)) tacNr++;
329 } else {
330 if(strcasecmp(cptr, "SD") && strcasecmp(cptr, "CL")) tacNr++;
331 }
332 ri++; cptr=csvCell(csv, ri, ci);
333 }
334 if(verbose>2) {
335 printf(" parNr := %d\n", parNr);
336 printf(" tacNr := %d\n", tacNr);
337 }
338 if(parNr<1 || tacNr<1) {
339 parFree(par);
340 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
342 }
343 /* Allocate space for parameters */
344 ret=parAllocate(par, parNr, tacNr); if(ret!=TPCERROR_OK) {
345 parFree(par);
346 statusSet(status, __func__, __FILE__, __LINE__, ret);
347 return ret;
348 }
349 par->parNr=parNr; par->tacNr=tacNr;
350
351 /* Get program name from the first non-comment IFT field */
352 if(verbose>2) printf("searching obligatory program name\n");
353 i=0;
354 while(ift->item[i].comment && i<ift->keyNr && ift->item[i].key!=NULL) i++;
355 if(verbose>3) {
356 printf("ift->item[%d].value := '%s'\n", i, ift->item[i].value);
357 }
358 if(i==ift->keyNr || !strcasestr(ift->item[i].value, "(c)")) {
359 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_UNSUPPORTED);
361 }
362 iftPut(&par->h, "program", ift->item[i].value, 0, NULL);
363
364 /* Get analysis time from IFT struct */
365 i=iftFindKey(ift, "Date", 0);
366 if(i>=0) iftPut(&par->h, "analysis_time", ift->item[i].value, 0, NULL);
367
368 /* Study number */
369 i=iftFindKey(ift, "Study", 0);
370 if(i>=0) iftPut(&par->h, "studynr", ift->item[i].value, 0, NULL);
371
372 /* Optional filenames etc */
373 i=iftFindKey(ift, "Data file", 0);
374 if(i>=0) iftPut(&par->h, "datafile", ift->item[i].value, 0, NULL);
375 i=iftFindKey(ift, "Plasma file", 0);
376 if(i>=0) iftPut(&par->h, "plasmafile", ift->item[i].value, 0, NULL);
377 i=iftFindKey(ift, "2nd plasma file", 0);
378 if(i>=0) iftPut(&par->h, "plasmafile2", ift->item[i].value, 0, NULL);
379 i=iftFindKey(ift, "Blood file", 0);
380 if(i>=0) iftPut(&par->h, "bloodfile", ift->item[i].value, 0, NULL);
381 i=iftFindKey(ift, "Reference file", 0);
382 if(i>=0) iftPut(&par->h, "reffile", ift->item[i].value, 0, NULL);
383 i=iftFindKey(ift, "Reference region", 0);
384 if(i>=0) iftPut(&par->h, "refname", ift->item[i].value, 0, NULL);
385
386 /* Fit method (optional) */
387 i=iftFindKey(ift, "Fit method", 0);
388 if(i>=0) iftPut(&par->h, "fitmethod", ift->item[i].value, 0, NULL);
389
390 /* Constants (optional) */
391 i=iftFindKey(ift, "Tissue density", 0);
392 if(i>=0) iftPut(&par->h, "density", ift->item[i].value, 0, NULL);
393 i=iftFindKey(ift, "Lumped constant", 0);
394 if(i>=0) iftPut(&par->h, "LC", ift->item[i].value, 0, NULL);
395 i=iftFindKey(ift, "Concentration", 0);
396 if(i>=0) iftPut(&par->h, "concentration", ift->item[i].value, 0, NULL);
397 i=iftFindKey(ift, "Beta", 0);
398 if(i>=0) iftPut(&par->h, "beta", ift->item[i].value, 0, NULL);
399 i=iftFindKey(ift, "Vb", 0);
400 if(i>=0) iftPut(&par->h, "Vb", ift->item[i].value, 0, NULL);
401 i=iftFindKey(ift, "fA", 0);
402 if(i>=0) iftPut(&par->h, "fA", ift->item[i].value, 0, NULL);
403 i=iftFindKey(ift, "Extraction", 0);
404 if(i>=0) iftPut(&par->h, "E", ift->item[i].value, 0, NULL);
405
406 /* Weighting (obligatory) */
407 if(verbose>2) printf("searching obligatory information on weighting\n");
408 if(iftSearchValue(ift, "not weighted", 0)>=0) {
409 iftPut(&par->h, "weighting", "no", 0, NULL);
410 } else if(iftSearchValue(ift, "was weighted", 0)>=0) {
411 iftPut(&par->h, "weighting", "yes", 0, NULL);
412 } else {
413 i=iftFindKey(ift, "Weighting", 0);
414 if(i>=0) {
415 iftPut(&par->h, "weighting", ift->item[i].value, 0, NULL);
416 } else {
417 parFree(par);
418 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
420 }
421 }
422
423 /* Read parameter names (possibly reorganized later) */
424 ri=titlerow; ci=1; cptr=csvCell(csv, ri, ci);
425 if(strlen(cptr)<1) {ci++; cptr=csvCell(csv, ri, ci);}
426 for(i=0; i<parNr; i++) {
427 strlcpy(par->n[i].name, cptr, MAX_PARNAME_LEN);
428 ci++; cptr=csvCell(csv, ri, ci);
429 }
430
431 /* Read parameter values for each region */
432 int tac=0;
433 double *dptr;
434 ri=1+titlerow; ret=TPCERROR_OK;
435 do {
436 ci=0; cptr=csvCell(csv, ri, ci);
437 if(cptr==NULL) {if(tac<tacNr) ret=TPCERROR_INVALID_FORMAT; break;}
438 //printf(" cell='%s'\n", cptr);
439 //printf(" ri=%d ci=%d tac=%d\n", ri, ci, tac);
440 /* check if this is SD line */
441 dptr=NULL;
442 if(csv->separator==' ') {
443 if(!strcasecmp(cptr, "SD")) {
444 if(tac<1) {ret=TPCERROR_INVALID_FORMAT; break;}
445 ci=3; dptr=par->r[tac-1].sd;
446 } else if(!strcasecmp(cptr, "CL")) {
447 if(tac<1) {ret=TPCERROR_INVALID_FORMAT; break;}
448 if(!strcasecmp(csvCell(csv, ri, 2), "Lower")) {
449 ci=3; dptr=par->r[tac-1].cl1;
450 } else if(!strcasecmp(csvCell(csv, ri, 2), "Upper")) {
451 ci=3; dptr=par->r[tac-1].cl2;
452 }
453 }
454 } else {
455 if(!strncasecmp(cptr, "SD . .", 3)) {
456 if(tac<1) {ret=TPCERROR_INVALID_FORMAT; break;}
457 ci=1; dptr=par->r[tac-1].sd;
458 } else if(!strncasecmp(cptr, "CL 95% Lower", 8)) {
459 if(tac<1) {ret=TPCERROR_INVALID_FORMAT; break;}
460 ci=1; dptr=par->r[tac-1].cl1;
461 } else if(!strncasecmp(cptr, "CL 95% Upper", 8)) {
462 if(tac<1) {ret=TPCERROR_INVALID_FORMAT; break;}
463 ci=1; dptr=par->r[tac-1].cl2;
464 }
465 }
466 if(dptr!=NULL) {
467 //printf(" sd or cl\n");
468 for(i=0; i<parNr; i++) {
469 cptr=csvCell(csv, ri, ci);
470 if(cptr==NULL) {ret=TPCERROR_INVALID_FORMAT; break;}
471 dptr[i]=atofVerified(cptr);
472 ci++;
473 }
474 ri++; continue;
475 }
476 if(tac>=tacNr) break;
477 //printf(" param\n");
478 /* copy tac name */
479 strlcpy(par->r[tac].name, cptr, MAX_TACNAME_LEN);
480 if(csv->separator==' ') {
481 ci++; cptr=csvCell(csv, ri, ci);
482 strlcat(par->r[tac].name, " ", MAX_TACNAME_LEN);
483 strlcat(par->r[tac].name, cptr, MAX_TACNAME_LEN);
484 ci++; cptr=csvCell(csv, ri, ci);
485 strlcat(par->r[tac].name, " ", MAX_TACNAME_LEN);
486 strlcat(par->r[tac].name, cptr, MAX_TACNAME_LEN);
487 }
488 /* copy parameter values */
489 ci++; //cptr=csvCell(csv, ri, ci); //if(strlen(cptr)<1) ci++;
490 for(i=0; i<parNr; i++) {
491 cptr=csvCell(csv, ri, ci);
492 if(cptr==NULL) {ret=TPCERROR_INVALID_FORMAT; break;}
493 par->r[tac].p[i]=atofVerified(cptr);
494 ci++;
495 }
496 if(ret!=TPCERROR_OK) break;
497 ri++; tac++;
498 } while(1);
499 if(ret!=TPCERROR_OK) {
500 parFree(par);
501 statusSet(status, __func__, __FILE__, __LINE__, ret);
502 return ret;
503 }
504
505 /* Read parameter units, if available */
506 i=iftFindKey(ift, "Units", 0);
507 if(i>0) {
508 int n=strTokenNr(ift->item[i].value, " \t");
509 if(n>parNr) n=parNr;
510 char tmp[256];
511 for(int j=0; j<n; j++) {
512 strTokenNCpy(ift->item[i].value, " \t", 1+j, tmp, 256);
513 par->n[j].unit=unitIdentify(tmp);
514 }
515 }
516
517 /* Fix region names (mainly, remove dots) */
518 {
519 int i, tac;
520 char fnsp[3][MAX_TACNAME_LEN+1];
521 for(tac=0; tac<par->tacNr; tac++) {
522 for(i=0; i<3; i++) {
523 if(roinameSubpart(par->r[tac].name, "_ ", i, fnsp[i], MAX_TACNAME_LEN)==NULL ||
524 strcmp(fnsp[i], ".")==0)
525 strcpy(fnsp[i], "");
526 }
527 strcpy(par->r[tac].name, fnsp[0]);
528 if(strlen(fnsp[1]) || strlen(fnsp[2])) strcat(par->r[tac].name, "_");
529 if(strlen(fnsp[1])) strcat(par->r[tac].name, fnsp[1]);
530 if(strlen(fnsp[2])) {
531 strcat(par->r[tac].name, "_"); strcat(par->r[tac].name, fnsp[2]);}
532 }
533 }
534
535 /* Data range (optional) */
536 i=iftFindKey(ift, "Data range", 0);
537 if(i>=0) {
538 double t1, t2;
539 char tmp[256];
540 int n;
541 n=sscanf(ift->item[i].value, "%lf - %lf %s", &t1, &t2, tmp);
542 if(n==3 && unitIdentify(tmp)==UNIT_SEC) {
543 t1/=60.; t2/=60.;
544 }
545 if(n>=2) for(i=0; i<par->tacNr; i++) {par->r[i].start=t1; par->r[i].end=t2;}
546 }
547
548
549 /* Data nr (optional) */
550 i=iftFindKey(ift, "Data nr", 0);
551 if(i>=0) {
552 int n; n=atoi(ift->item[i].value);
553 for(i=0; i<par->tacNr; i++) par->r[i].dataNr=n;
554 }
555
556 /* If one 'parameter' is named WSS or SS, then move its contents to
557 correct place inside the struct */
558 ci=-1;
559 for(i=0; i<par->parNr; i++) {
560 if(!strcasecmp(par->n[i].name, "WSS") || !strcasecmp(par->n[i].name, "SS"))
561 ci=i;
562 }
563 if(ci>=0 && ci<par->parNr && par->parNr>1) {
564 if(verbose>4) printf("column %d contains WSS, moving to correct place\n", 1+ci);
565 for(i=0; i<par->tacNr; i++) par->r[i].wss=par->r[i].p[ci];
566 /* delete the parameter column */
567 parDeletePar(par, ci);
568 }
569
570 /* Set format in struct */
572
573 /* Quit */
574 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
575 return(TPCERROR_OK);
576}
char * csvCell(CSV *csv, int row, int col)
Definition csv.c:358
int csvRowLength(CSV *csv, int row)
Definition csv.c:244
int csvFindField(CSV *csv, const char *s, int start_index)
Definition csvfind.c:27
int csvWrite(CSV *csv, int regular, FILE *fp, TPCSTATUS *status)
Definition csvio.c:52
double atofVerified(const char *s)
Definition decpoint.c:75
int iftPut(IFT *ift, const char *key, const char *value, char comment, TPCSTATUS *status)
Definition ift.c:63
int iftSearchValue(IFT *ift, const char *s, int start_index)
Definition iftfind.c:114
int iftFindKey(IFT *ift, const char *key, int start_index)
Definition iftfind.c:30
int iftWrite(IFT *ift, FILE *fp, TPCSTATUS *status)
Definition iftio.c:98
int parDeletePar(PAR *par, int pi)
Definition par.c:478
void parFree(PAR *par)
Definition par.c:75
int parAllocate(PAR *par, int parNr, int tacNr)
Definition par.c:108
char * roinameSubpart(const char *roiname, const char *dlm, const unsigned int si, char *subpart, const unsigned int slen)
Definition roiname.c:20
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
Definition statusmsg.c:142
int strTokenNr(const char *s1, const char *s2)
Definition stringext.c:25
int strTokenNCpy(const char *s1, const char *s2, int i, char *s3, int count)
Definition stringext.c:53
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition stringext.c:632
char * strcasestr(const char *haystack, const char *needle)
Definition stringext.c:155
size_t strlcat(char *dst, const char *src, size_t dstsize)
Definition stringext.c:592
int col
Definition tpccsv.h:28
int row
Definition tpccsv.h:26
char * content
Definition tpccsv.h:30
int row_nr
Definition tpccsv.h:44
int col_nr
Definition tpccsv.h:46
char separator
Definition tpccsv.h:49
CSV_item * c
Definition tpccsv.h:38
char comment
Definition tpcift.h:27
char * value
Definition tpcift.h:37
char * key
Definition tpcift.h:32
IFT_ITEM * item
Definition tpcift.h:57
int keyNr
Definition tpcift.h:47
int format
Definition tpcpar.h:102
IFT h
Optional (but often useful) header information.
Definition tpcpar.h:147
int parNr
Definition tpcpar.h:108
PARN * n
Definition tpcpar.h:112
int unit
Definition tpcpar.h:86
char name[MAX_PARNAME_LEN+1]
Definition tpcpar.h:82
double wss
Definition tpcpar.h:72
char name[MAX_TACNAME_LEN+1]
Definition tpcpar.h:50
int dataNr
Definition tpcpar.h:62
double * cl2
Definition tpcpar.h:70
double start
Definition tpcpar.h:52
double * sd
Definition tpcpar.h:66
double * cl1
Definition tpcpar.h:68
double end
Definition tpcpar.h:54
int verbose
Verbose level, used by statusPrint() etc.
#define MAX_TACNAME_LEN
Max length of TAC ID name (not including trailing zero).
@ UNIT_SEC
seconds
#define MAX_PARNAME_LEN
Max string length for PAR name.
@ TPCERROR_FAIL
General error.
@ TPCERROR_INVALID_FORMAT
Invalid file format.
@ TPCERROR_UNSUPPORTED
Unsupported file type.
@ TPCERROR_OK
No error.
@ TPCERROR_NO_DATA
File contains no data.
int unitIdentify(const char *s)
Definition units.c:162
@ PAR_FORMAT_RES
Model result format of Turku PET Centre.
Definition tpcpar.h:29

Referenced by parRead().

◆ parWriteRES()

int parWriteRES ( PAR * par,
FILE * fp,
TPCSTATUS * status )

Write PAR data into specified file pointer in result (RES) file format.

See also
parWrite
Returns
enum tpcerror (TPCERROR_OK when successful).
Author
Vesa Oikonen
Parameters
parPointer to source PAR struct, contents of which are to be written.
fpOutput file pointer.
statusPointer to status data; enter NULL if not needed.

Definition at line 26 of file parres.c.

33 {
34 int verbose=0; if(status!=NULL) verbose=status->verbose;
35 if(fp==NULL) {
36 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
38 }
39 if(verbose>0) {printf("%s():\n", __func__); fflush(stdout);}
40 if(par==NULL || par->tacNr<1 || par->parNr<1) {
41 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
42 return TPCERROR_NO_DATA;
43 }
44
45 int i, j, n;
46 char tmp[256];
47
48 /* RES format has quite strict rules on the header, therefore
49 it is written here directly and not through IFT struct etc. */
50
51 /* Analysis program name (obligatory, with (c)) */
52 i=iftFindKey(&par->h, "program", 0);
53 if(i<0 || !strcasestr(par->h.item[i].value, "(c)")) {
54 //statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_VALUE);
55 //return TPCERROR_INVALID_VALUE;
56 n=fprintf(fp, "results (c) none\n\n");
57 } else {
58 n=fprintf(fp, "%s\n\n", par->h.item[i].value);
59 }
60 if(n<6) {
61 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
63 }
64
65 /* Write calculation date and time (obligatory) */
66 i=iftFindKey(&par->h, "analysis_time", 0);
67 if(i<0) {
68 //statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_VALUE);
69 //return TPCERROR_INVALID_VALUE;
70 time_t t=time(NULL);
71 fprintf(fp, "Date:\t%s\n", ctime_r_int(&t, tmp));
72 } else {
73 fprintf(fp, "Date:\t%s\n", par->h.item[i].value);
74 }
75
76 /* Write the studynr (optional) */
77 i=iftFindKey(&par->h, "studynr", 0);
78 if(i<0) i=iftFindKey(&par->h, "study_number", 0);
79 if(i>=0) fprintf(fp, "Study:\t%s\n", par->h.item[i].value);
80
81 /* Write the names of the original datafiles (optional) */
82 i=iftFindKey(&par->h, "datafile", 0);
83 if(i>=0) fprintf(fp, "Data file:\t%s\n", par->h.item[i].value);
84 i=iftFindKey(&par->h, "plasmafile", 0);
85 if(i>=0) fprintf(fp, "Plasma file:\t%s\n", par->h.item[i].value);
86 i=iftFindKey(&par->h, "plasmafile2", 0);
87 if(i>=0) fprintf(fp, "2nd Plasma file:\t%s\n", par->h.item[i].value);
88 i=iftFindKey(&par->h, "bloodfile", 0);
89 if(i>=0) fprintf(fp, "Blood file:\t%s\n", par->h.item[i].value);
90 i=iftFindKey(&par->h, "reffile", 0);
91 if(i>=0) fprintf(fp, "Reference file:\t%s\n", par->h.item[i].value);
92 i=iftFindKey(&par->h, "refname", 0);
93 if(i>=0) fprintf(fp, "Reference region:\t%s\n", par->h.item[i].value);
94
95 /* Write data range, nr, and fit method (optional) */
96 if(!isnan(par->r[0].start) && !isnan(par->r[0].end))
97 fprintf(fp, "Data range:\t%g - %g min\n", par->r[0].start, par->r[0].end);
98 if(par->r[0].dataNr>0)
99 fprintf(fp, "Data nr:\t%d\n", par->r[0].dataNr);
100 i=iftFindKey(&par->h, "fitmethod", 0);
101 if(i>=0) fprintf(fp, "Fit method:\t%s\n", par->h.item[i].value);
102
103 /* Write constants (optional) */
104 i=iftFindKey(&par->h, "density", 0);
105 if(i>=0) fprintf(fp, "Tissue density:\t%s\n", par->h.item[i].value);
106 i=iftFindKey(&par->h, "LC", 0);
107 if(i>=0) fprintf(fp, "Lumped constant:\t%s\n", par->h.item[i].value);
108 i=iftFindKey(&par->h, "concentration", 0);
109 if(i>=0) fprintf(fp, "Concentration:\t%s\n", par->h.item[i].value);
110 i=iftFindKey(&par->h, "beta", 0);
111 if(i>=0) fprintf(fp, "Beta:\t%s\n", par->h.item[i].value);
112 i=iftFindKey(&par->h, "Vb", 0);
113 if(i>=0) fprintf(fp, "Vb:\t%s\n", par->h.item[i].value);
114 i=iftFindKey(&par->h, "fA", 0);
115 if(i>=0) fprintf(fp, "fA:\t%s\n", par->h.item[i].value);
116 i=iftFindKey(&par->h, "E", 0);
117 if(i<0) i=iftFindKey(&par->h, "extraction", 0);
118 if(i>=0) fprintf(fp, "Extraction:\t%s\n", par->h.item[i].value);
119
120 /* Weighting (obligatory) */
121 i=iftFindKey(&par->h, "weighting", 0);
122 if(i>=0) fprintf(fp, "Weighting:\t%s\n", par->h.item[i].value);
123 else fprintf(fp, "Weighting:\t%s\n", "unknown");
124
125 /* Should column be printed as integers (0), floats (1) or exponentials (2)? */
126 int partype[par->parNr]; /* 0=int, 1=double, 2=exp */
127 for(i=0; i<par->parNr; i++) partype[i]=parPrintType(par, i);
128
129 /* Title line (obligatory) */
130 fprintf(fp, "\n%s", "Region");
131 for(i=0; i<par->parNr; i++) {
132 if(strlen(par->n[i].name)<1) strcpy(tmp, ".");
133 else strcpy(tmp, par->n[i].name);
134 fprintf(fp, "\t%s", tmp);
135 }
136 if(parIsWSS(par)) fprintf(fp, "\tWSS");
137 fprintf(fp, "\n");
138
139 /* Write units, if they exist, as comment line */
140 for(i=j=0; i<par->parNr; i++) if(par->n[i].unit!=UNIT_UNKNOWN) j++;
141 if(j>0) {
142 fprintf(fp, "%s", "# Units:");
143 for(i=0; i<par->parNr; i++) {
144 fprintf(fp, "\t%s", unitName(par->n[i].unit));
145 }
146 if(parIsWSS(par)) fprintf(fp, "\t.");
147 fprintf(fp, "\n");
148 }
149
150
151 /* Write regional results */
152 for(i=0; i<par->tacNr; i++) {
153 if(strlen(par->r[i].name)>0) {
154 if(!roinameSubpart(par->r[i].name, "_- ", 0, tmp, 7)) strcpy(tmp, ".");
155 fprintf(fp, "%s ", tmp);
156 if(!roinameSubpart(par->r[i].name, "_- ", 1, tmp, 7)) strcpy(tmp, ".");
157 fprintf(fp, "%s ", tmp);
158 if(!roinameSubpart(par->r[i].name, "_- ", 2, tmp, 7)) strcpy(tmp, ".");
159 fprintf(fp, "%s", tmp);
160 } else {
161 fprintf(fp, "tac%d . .", 1+i);
162 }
163 for(j=0; j<par->parNr; j++) {
164 if(isnan(par->r[i].p[j])) {fprintf(fp, "\t."); continue;}
165 switch(partype[j]) {
166 case 0: fprintf(fp, "\t%.0f", par->r[i].p[j]); break;
167 case 1:
168 if(par->r[i].p[j]>=0) n=4; else n=3;
169 fprintf(fp, "\t%.*f", n, par->r[i].p[j]);
170 break;
171 default:
172 if(par->r[i].p[j]>=0) n=4; else n=3;
173 fprintf(fp, "\t%.*e", n, par->r[i].p[j]);
174 break;
175 }
176 }
177 if(parIsWSS(par)) {
178 if(isnan(par->r[i].wss)) fprintf(fp, "\t.");
179 else fprintf(fp, "\t%g", par->r[i].wss);
180 }
181 fprintf(fp, "\n");
182 /* Write SD's, if they exist */
183 for(j=n=0; j<par->parNr; j++) if(!isnan(par->r[i].sd[j])) n++;
184 if(n>0) {
185 fprintf(fp, "SD . .");
186 for(j=0; j<par->parNr; j++) {
187 if(!isnan(par->r[i].sd[j])) {
188 switch(partype[j]) {
189 case 0: fprintf(fp, "\t%.0f", par->r[i].sd[j]); break;
190 case 1:
191 if(par->r[i].sd[j]>=0) n=4; else n=3;
192 fprintf(fp, "\t%.*f", n, par->r[i].sd[j]);
193 break;
194 default:
195 if(par->r[i].sd[j]>=0) n=4; else n=3;
196 fprintf(fp, "\t%.*e", n, par->r[i].sd[j]);
197 break;
198 }
199 } else {
200 fprintf(fp, "\t.");
201 }
202 }
203 if(parIsWSS(par)) fprintf(fp, "\t.");
204 fprintf(fp, "\n");
205 }
206 /* Write lower confidence limits, if they exist */
207 for(j=n=0; j<par->parNr; j++) if(!isnan(par->r[i].cl1[j])) n++;
208 if(n>0) {
209 fprintf(fp, "CL 95%% Lower");
210 for(j=0; j<par->parNr; j++) {
211 if(!isnan(par->r[i].cl1[j])) {
212 switch(partype[j]) {
213 case 0: fprintf(fp, "\t%.0f", par->r[i].cl1[j]); break;
214 case 1:
215 if(par->r[i].cl1[j]>=0) n=4; else n=3;
216 fprintf(fp, "\t%.*f", n, par->r[i].cl1[j]);
217 break;
218 default:
219 if(par->r[i].cl1[j]>=0) n=4; else n=3;
220 fprintf(fp, "\t%.*e", n, par->r[i].cl1[j]);
221 break;
222 }
223 } else {
224 fprintf(fp, "\t.");
225 }
226 }
227 if(parIsWSS(par)) fprintf(fp, "\t.");
228 fprintf(fp, "\n");
229 }
230 /* Write upper confidence limits, if they exist */
231 for(j=n=0; j<par->parNr; j++) if(!isnan(par->r[i].cl2[j])) n++;
232 if(n>0) {
233 fprintf(fp, "CL 95%% Upper");
234 for(j=0; j<par->parNr; j++) {
235 if(!isnan(par->r[i].cl2[j])) {
236 switch(partype[j]) {
237 case 0: fprintf(fp, "\t%.0f", par->r[i].cl2[j]); break;
238 case 1:
239 if(par->r[i].cl2[j]>=0) n=4; else n=3;
240 fprintf(fp, "\t%.*f", n, par->r[i].cl2[j]);
241 break;
242 default:
243 if(par->r[i].cl2[j]>=0) n=4; else n=3;
244 fprintf(fp, "\t%.*e", n, par->r[i].cl2[j]);
245 break;
246 }
247 } else {
248 fprintf(fp, "\t.");
249 }
250 }
251 if(parIsWSS(par)) fprintf(fp, "\t.");
252 fprintf(fp, "\n");
253 }
254 } /* next region */
255
256
257 /* Quit */
258 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
259 return(TPCERROR_OK);
260}
char * ctime_r_int(const time_t *t, char *buf)
Convert calendar time t into a null-terminated string of the form YYYY-MM-DD hh:mm:ss,...
Definition datetime.c:119
int parIsWSS(PAR *par)
Definition par.c:252
int parPrintType(PAR *par, int parIndex)
Definition parres.c:584
@ UNIT_UNKNOWN
Unknown unit.
@ TPCERROR_CANNOT_WRITE
Cannot write file.
char * unitName(int unit_code)
Definition units.c:143

Referenced by parWrite().