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

IO for result files and handling RES struct data. More...

#include "libtpccurveio.h"
#include <unistd.h>

Go to the source code of this file.

Functions

void resEmpty (RES *res)
 
void resInit (RES *res)
 
int resSetmem (RES *res, int voiNr)
 
void resFixParnames (RES *res)
 
void resPrint (RES *res)
 
int resRead (char *filename, RES *res, int verbose)
 
int resWrite (RES *res, char *filename, int verbose)
 
int resWriteHTML (RES *res, char *fname, int verbose)
 
int resWriteXHTML11_doctype (FILE *fp)
 
int resWriteXHTML11_head (FILE *fp, char *author_name)
 
int resWriteHTML_table (RES *res, FILE *fp)
 
int resFName2study (char *fname, char *studyNumber)
 
int resMedian (double *data, int nr, double *median, double *min, double *max)
 
int resMean (double *data, int nr, double *mean, double *sd)
 
void resSortByName (RES *res)
 
int resCopyMHeader (RES *res1, RES *res2)
 
int resDelete (RES *res, int voi)
 
int resSelect (RES *data, char *name)
 
int resSelectRegions (RES *res, char *region_name, int reset)
 
int resParameterPrintType (RES *res, int parIndex)
 
int resIsDuplicateNames (RES *res)
 
int resMatchHeader (RES *res1, RES *res2)
 
int resMatchRegions (RES *res1, RES *res2)
 
int resMatchParameternames (RES *res1, RES *res2)
 
int resMatchParameters (RES *res1, RES *res2, int test_par, double test_limit, int test_sd)
 
int resMatchParametersAbs (RES *res1, RES *res2, int test_par, double test_limit, int test_sd)
 
int resRNameSubfieldExists (RES *res)
 

Variables

int RESULT_TEST
 
char reserrmsg [64]
 

Detailed Description

IO for result files and handling RES struct data.

Author
Vesa Oikonen

Definition in file result.c.

Function Documentation

◆ resCopyMHeader()

int resCopyMHeader ( RES * res1,
RES * res2 )

Copy result main header information to another result structure.

Returns
Returns 0 if successful.
See also
resRead, resInit

Definition at line 1297 of file result.c.

1302 {
1303 int i;
1304
1305 if(res1==NULL || res2==NULL) return(1);
1306 strcpy(res2->program, res1->program);
1307 res2->time=res1->time;
1308 res2->parNr=res1->parNr;
1309 strcpy(res2->studynr, res1->studynr);
1310 strcpy(res2->datafile, res1->datafile);
1311 strcpy(res2->reffile, res1->reffile);
1312 strcpy(res2->plasmafile, res1->plasmafile);
1313 strcpy(res2->plasmafile2, res1->plasmafile2);
1314 strcpy(res2->bloodfile, res1->bloodfile);
1315 strcpy(res2->refroi, res1->refroi);
1316 strcpy(res2->datarange, res1->datarange);
1317 res2->datanr=res1->datanr;
1318 strcpy(res2->fitmethod, res1->fitmethod);
1319 res2->density=res1->density;
1320 res2->lc=res1->lc;
1321 res2->concentration=res1->concentration;
1322 res2->beta=res1->beta;
1323 res2->Vb=res1->Vb;
1324 res2->fA=res1->fA;
1325 res2->E=res1->E;
1326 res2->isweight=res1->isweight;
1327 for(i=0; i<res1->parNr; i++) {
1328 strcpy(res2->parname[i], res1->parname[i]);
1329 strcpy(res2->parunit[i], res1->parunit[i]);
1330 }
1331 strcpy(res2->titleline, res1->titleline);
1332 strcpy(res2->unitline, res1->unitline);
1333 return(0);
1334}
double E
double density
char plasmafile2[FILENAME_MAX]
char titleline[1024]
char studynr[MAX_STUDYNR_LEN+1]
double concentration
int parNr
char parname[MAX_RESPARAMS][MAX_RESPARNAME_LEN+1]
double fA
int datanr
double beta
char unitline[1024]
double Vb
char program[1024]
char plasmafile[FILENAME_MAX]
char datarange[128]
int isweight
double lc
char datafile[FILENAME_MAX]
char reffile[FILENAME_MAX]
char fitmethod[128]
char refroi[64]
char parunit[MAX_RESPARAMS][MAX_RESPARNAME_LEN+1]
char bloodfile[FILENAME_MAX]
time_t time

◆ resDelete()

int resDelete ( RES * res,
int voi )

Delete specified region (0..voiNr-1) from the structure.

Returns
Returns 0 if ok.
See also
resSelectRegions, resRead, resSortByName, resIsDuplicateNames
Parameters
resPointer to the result data.
voiTAC index (0..voiNr-1).

Definition at line 1342 of file result.c.

1347 {
1348 int i;
1349
1350 /* Check that region exists */
1351 if(res==NULL || voi>res->voiNr-1 || voi<0) return(1);
1352 /* If it is the last one, then just decrease the voiNr */
1353 if(voi==res->voiNr) {res->voiNr--; return(0);}
1354 /* Otherwise we have to move the following regions in its place */
1355 for(i=voi+1; i<res->voiNr; i++)
1356 memcpy(&res->voi[i-1], &res->voi[i], sizeof(ResVOI));
1357 res->voiNr--;
1358 return(0);
1359}
int voiNr
ResVOI * voi

◆ resEmpty()

void resEmpty ( RES * res)

Free memory allocated for results. All data are cleared.

See also
resInit, resSetmem
Parameters
resPointer to RES structure.

Definition at line 22 of file result.c.

25 {
26 if(res==NULL) return;
27 if(res->_voidataNr>0) {
28 free((char*)(res->voi));
29 res->_voidataNr=0;
30 }
31 res->voiNr=0;
32 res->parNr=0;
33 res->studynr[0]=(char)0;
34 for(int pi=0; pi<MAX_RESPARAMS; pi++) {
35 strcpy(res->parname[pi], ""); strcpy(res->parunit[pi], "");}
36 res->titleline[0]=res->unitline[0]=(char)0;
37 res->program[0]=(char)0; res->refroi[0]=(char)0; res->datarange[0]=(char)0;
38 res->datanr=0; res->fitmethod[0]=(char)0;
39 res->datafile[0]=res->reffile[0]=(char)0;
40 res->plasmafile[0]=res->plasmafile2[0]=res->bloodfile[0]=(char)0;
41 res->density=res->lc=res->concentration=res->beta=0.0;
42 res->Vb=-1.0;
43 res->fA=-1.0;
44 res->E=-1.0;
45}
#define MAX_RESPARAMS
int _voidataNr

Referenced by fitToResult(), resInit(), resRead(), and resSetmem().

◆ resFixParnames()

void resFixParnames ( RES * res)

Fix result parameter names and units, so that both representations are filled correctly, that is, the new string lists *parname[] and *parunit[], and the deprecated titleline[] and unitline[].

New representation, if filled, always overwrites the deprecated one. Units are assumed to follow parameter name representation.

See also
resRNameSubfieldExists
Parameters
resPointer to RES struct.

Definition at line 107 of file result.c.

110 {
111 int i, len, n;
112 char *cptr, tmp[1024], *lptr;
113
114 if(RESULT_TEST>0) printf("resFixParnames(*res)\n");
115 if(res==NULL) return;
116 if(res->parNr<1) return;
118
119 /* If new string lists are filled, then copy those to old representation */
120 for(i=n=0; i<res->parNr; i++) {
121 len=strlen(res->parname[i]); if(len<1) continue;
122 if(strcmp(res->parname[i], ".")==0) continue;
123 n++;
124 }
125 if(n>0) { // copy names and units
126 strcpy(res->titleline, "");
127 for(i=0; i<res->parNr; i++) {
128 if(1023<(1+strlen(res->titleline)+strlen(res->parname[i]))) break;
129 if(i>0) strcat(res->titleline, " ");
130 len=strlen(res->parname[i]);
131 if(len<1) strcat(res->titleline, ".");
132 else strcat(res->titleline, res->parname[i]);
133 }
134 strcpy(res->unitline, "");
135 for(i=0; i<res->parNr; i++) {
136 if(1023<(1+strlen(res->unitline)+strlen(res->parunit[i]))) break;
137 if(i>0) strcat(res->unitline, " ");
138 len=strlen(res->parunit[i]);
139 if(len<1) strcat(res->unitline, ".");
140 else strcat(res->unitline, res->parunit[i]);
141 }
142 if(RESULT_TEST>1) {
143 printf("Parameter names and units:\n");
144 for(i=0; i<res->parNr; i++)
145 printf(" %d: '%s' '%s'\n", i+1, res->parname[i], res->parunit[i]);
146 printf("Created titleline: %s\n", res->titleline);
147 printf("Created unitline: %s\n", res->unitline);
148 }
149 return;
150 }
151
152 /* If new string lists are not filled, then get them from deprecated strings */
153 for(i=0; i<res->parNr; i++) {
154 strcpy(res->parname[i], "");
155 strcpy(res->parunit[i], "");
156 }
157 strcpy(tmp, res->titleline); lptr=tmp; cptr=strtok(lptr, " \t\n\r");
158 i=0; while(cptr!=NULL && i<res->parNr) {
159 if(strcmp(cptr, ".")==0) {i++; continue;}
160 strncpy(res->parname[i], cptr, MAX_RESPARNAME_LEN);
161 res->parname[i][MAX_RESPARNAME_LEN]=(char)0;
162 cptr=strtok(NULL, " \t\n\r"); i++;
163 }
164 strcpy(tmp, res->unitline); lptr=tmp; cptr=strtok(lptr, " \t\n\r");
165 i=0; while(cptr!=NULL && i<res->parNr) {
166 if(strcmp(cptr, ".")==0) {i++; continue;}
167 strncpy(res->parunit[i], cptr, MAX_RESPARNAME_LEN);
168 res->parunit[i][MAX_RESPARNAME_LEN]=(char)0;
169 cptr=strtok(NULL, " \t\n\r"); i++;
170 }
171 if(RESULT_TEST>1) {
172 printf("Original titleline: %s\n", res->titleline);
173 printf("Original unitline: %s\n", res->unitline);
174 printf("Resolved parameter names and units:\n");
175 for(i=0; i<res->parNr; i++)
176 printf(" %d: '%s' '%s'\n", i+1, res->parname[i], res->parunit[i]);
177 }
178 return;
179}
#define MAX_RESPARNAME_LEN
int RESULT_TEST
Definition result.c:5

Referenced by dftToResult(), fitToResult(), resMatchParameternames(), resRead(), resWrite(), and resWriteHTML().

◆ resFName2study()

int resFName2study ( char * fname,
char * studyNumber )

Set study number based on file name.

See also
studynr_from_fname
Returns
Non-zero in case of an error.

Definition at line 1169 of file result.c.

1172 {
1173 return(studynr_from_fname(fname, studyNumber));
1174}
int studynr_from_fname(char *fname, char *studynr)
Definition studynr.c:119

◆ resInit()

void resInit ( RES * res)

Initiate RES structure. This should be called once before first use.

See also
resSetmem, resEmpty
Parameters
resPointer to RES structure.

Definition at line 52 of file result.c.

55 {
56 if(res==NULL) return;
57 memset(res, 0, sizeof(RES));
58 res->_voidataNr=0; res->voiNr=0; res->parNr=0;
59 //res->Vb=-1.0;
60 //res->fA=-1.0;
61 //res->E=-1.0;
62 resEmpty(res);
63}
void resEmpty(RES *res)
Definition result.c:22

◆ resIsDuplicateNames()

int resIsDuplicateNames ( RES * res)

Check if result structure contains duplicate region names.

Returns
Returns 0 if not, 1 if duplicates are found, and <0 in case of an error.
See also
resSortByName, resDelete, resRNameSubfieldExists
Parameters
resPointer to the result data.

Definition at line 1473 of file result.c.

1476 {
1477 int ri, rj;
1478
1479 if(res==NULL) return(-1);
1480 if(res->voiNr<2) return(0);
1481 for(ri=0; ri<res->voiNr-1; ri++) for(rj=ri+1; rj<res->voiNr; rj++)
1482 if(strcasecmp(res->voi[ri].name, res->voi[rj].name)==0) return(1);
1483 return(0);
1484}
char name[MAX_REGIONNAME_LEN+1]

◆ resMatchHeader()

int resMatchHeader ( RES * res1,
RES * res2 )

Check whether result header field values are the same.

Fields that are not checked: program, time, titleline.

Returns
Returns 0 in case of match, and <>0 if not matching.
See also
resRead, resMatchRegions, resMatchParameternames
Parameters
res1Pointers to the result data that are tested
res2Pointers to the result data that are tested

Definition at line 1494 of file result.c.

1499 {
1500 if(res1==NULL || res2==NULL) return(1);
1501 if(res1->voiNr!=res2->voiNr) return(3);
1502 if(res1->parNr!=res2->parNr) return(4);
1503 if(strcasecmp(res1->datafile, res2->datafile)!=0) return(6);
1504 if(strcasecmp(res1->reffile, res2->reffile)!=0) return(7);
1505 if(strcasecmp(res1->plasmafile, res2->plasmafile)!=0) return(8);
1506 if(strcasecmp(res1->plasmafile2, res2->plasmafile2)!=0) return(9);
1507 if(strcasecmp(res1->bloodfile, res2->bloodfile)!=0) return(10);
1508 if(strcasecmp(res1->refroi, res2->refroi)!=0) return(11);
1509 if(strcasecmp(res1->datarange, res2->datarange)!=0) return(12);
1510 if(res1->isweight!=res2->isweight) return(13);
1511 if(res1->density!=res2->density) return(14);
1512 if(res1->lc!=res2->lc) return(15);
1513 if(res1->beta!=res2->beta) return(16);
1514 if(res1->concentration!=res2->concentration) return(17);
1515 if(res1->Vb!=res2->Vb) return(18);
1516 if(res1->datanr!=res2->datanr) return(19);
1517 if(strcasecmp(res1->fitmethod, res2->fitmethod)!=0) return(20);
1518 if(res1->fA!=res2->fA) return(21);
1519 if(res1->E!=res2->E) return(22);
1520 /* Less important */
1521 if(strcasecmp(res1->studynr, res2->studynr)!=0) return(5);
1522 return(0);
1523}

◆ resMatchParameternames()

int resMatchParameternames ( RES * res1,
RES * res2 )

Check whether result parameter names are the same.

Returns
Returns 0 in case of match, and 1 if not matching.
See also
resMatchHeader, resMatchHeader, resMatchParameters
Parameters
res1Pointers to the result data that are tested.
res2Pointers to the result data that are tested.

Definition at line 1564 of file result.c.

1569 {
1570 int i;
1571
1572 if(res1==NULL || res2==NULL || res1->parNr!=res2->parNr) return(1);
1573
1574 resFixParnames(res1);
1575 resFixParnames(res2);
1576
1577 for(i=0; i<res1->parNr; i++) {
1578 if(strcasecmp(res1->parname[i], res2->parname[i])!=0) {
1579 if(RESULT_TEST>1)
1580 printf(" Parameter names '%s' and '%s' do not match\n",
1581 res1->parname[i], res2->parname[i]);
1582 return(1);
1583 }
1584 if(strcasecmp(res1->parunit[i], res2->parunit[i])!=0) {
1585 if(RESULT_TEST>1)
1586 printf(" Parameter units '%s' and '%s' do not match\n",
1587 res1->parunit[i], res2->parunit[i]);
1588 return(1);
1589 }
1590 }
1591 return(0);
1592}
void resFixParnames(RES *res)
Definition result.c:107

◆ resMatchParameters()

int resMatchParameters ( RES * res1,
RES * res2,
int test_par,
double test_limit,
int test_sd )

Check whether result parameter values are the same.

Returns
Returns 0 in case of match, and <>0 if not matching.
See also
resMatchParametersAbs, resMatchHeader, resMatchHeader, resMatchParameternames
Parameters
res1Pointers to the result data that are tested.
res2Pointers to the result data that are tested.
test_parParameter index (0..parNr-1) that is verified; <0, if all.
test_limitTest limit (how exact match is required).
test_sdTest (1) or do not test (0) SD and Confidence limits.

Definition at line 1600 of file result.c.

1611 {
1612 int ri, pi;
1613 double s, v1, v2;
1614
1615 if(res1==NULL || res2==NULL || res1->voiNr!=res2->voiNr) return(1);
1616 if(res1->parNr!=res2->parNr) {
1617 if(test_par<0) return(1);
1618 if(test_par+1>res1->parNr || test_par+1>res2->parNr) return(1);
1619 }
1620 for(ri=0; ri<res1->voiNr; ri++) {
1621 for(pi=0; pi<res1->parNr; pi++) {
1622 if(test_par>=0 && test_par!=pi) continue;
1623 v1=res1->voi[ri].parameter[pi]; v2=res2->voi[ri].parameter[pi];
1624 if(isnan(v1) && isnan(v2)) continue; // ok if both are NaN
1625 /* Parameter values */
1626 if(RESULT_TEST>5) printf("pi=%d ri=%d\n", pi, ri);
1627 if(RESULT_TEST>5) printf(" %g vs %g\n", v1, v2);
1628 s=fabs(v1+v2); if(isnan(s)) return(2); // Either one is NaN
1629 if(test_limit<=0.0) { // values are requested to match exactly
1630 if(v1!=v2) return(2);
1631 } if(s==0.0 || v1==0.0 || v2==0.0) { // relative matching cant be done
1632 if(fabs(v1-v2)>test_limit) return(2);
1633 } else { // test relative difference against given limit
1634 if(fabs((v1-v2)/s)>test_limit) return(2);
1635 }
1636 if(test_sd!=0) {
1637 /* SD */
1638 v1=res1->voi[ri].sd[pi]; v2=res2->voi[ri].sd[pi];
1639 if(RESULT_TEST>5) printf(" SD: %g vs %g\n", v1, v2);
1640 if(isnan(v1) && isnan(v2)) {
1641 // both are NA, that is ok
1642 } else if(isnan(v1) || isnan(v2)) {
1643 // one is NA, that is not ok
1644 return(3);
1645 } else if(test_limit<=0.0) { // values are requested to match exactly
1646 if(v1!=v2) return(3);
1647 } if(s==0.0) { // relative matching cant be done
1648 if(fabs(v1-v2)>test_limit) return(3);
1649 } else { // test relative difference against given limit
1650 if(fabs((v1-v2)/s)>test_limit) return(3);
1651 }
1652 /* CL1 */
1653 v1=res1->voi[ri].cl1[pi]; v2=res2->voi[ri].cl1[pi];
1654 if(RESULT_TEST>5) printf(" CL1: %g vs %g\n", v1, v2);
1655 if(isnan(v1) && isnan(v2)) {
1656 // both are NA, that is ok
1657 } else if(isnan(v1) || isnan(v2)) {
1658 // one is NA, that is not ok
1659 return(4);
1660 } else if(test_limit<=0.0) { // values are requested to match exactly
1661 if(v1!=v2) return(4);
1662 } if(s==0.0) { // relative matching cant be done
1663 if(fabs(v1-v2)>test_limit) return(4);
1664 } else { // test relative difference against given limit
1665 if(fabs((v1-v2)/s)>test_limit) return(4);
1666 }
1667 /* CL2 */
1668 v1=res1->voi[ri].cl2[pi]; v2=res2->voi[ri].cl2[pi];
1669 if(RESULT_TEST>5) printf(" CL2: %g vs %g\n", v1, v2);
1670 if(isnan(v1) && isnan(v2)) {
1671 // both are NA, that is ok
1672 } else if(isnan(v1) || isnan(v2)) {
1673 // one is NA, that is not ok
1674 return(5);
1675 } else if(test_limit<=0.0) { // values are requested to match exactly
1676 if(v1!=v2) return(5);
1677 } if(s==0.0) { // relative matching cant be done
1678 if(fabs(v1-v2)>test_limit) return(5);
1679 } else { // test relative difference against given limit
1680 if(fabs((v1-v2)/s)>test_limit) return(5);
1681 }
1682 }
1683 }
1684 }
1685 return(0);
1686}
double parameter[MAX_RESPARAMS]
double cl2[MAX_RESPARAMS]
double cl1[MAX_RESPARAMS]
double sd[MAX_RESPARAMS]

◆ resMatchParametersAbs()

int resMatchParametersAbs ( RES * res1,
RES * res2,
int test_par,
double test_limit,
int test_sd )

Check whether the two sets of result parameter values are similar within a given absolute range.

Returns
Returns 0 in case of match, and <>0 if not matching.
See also
resMatchParameters
Parameters
res1Pointers to the result data that are tested.
res2Pointers to the result data that are tested.
test_parParameter index (0..parNr-1) that is verified; <0, if all.
test_limitTest limit; positive value, below which the absolute difference must be.
test_sdTest (1) or do not test (0) SD and Confidence limits.

Definition at line 1694 of file result.c.

1705 {
1706 int ri, pi;
1707 double s, v1, v2;
1708
1709 if(res1==NULL || res2==NULL || res1->voiNr!=res2->voiNr) return(1);
1710 if(res1->parNr!=res2->parNr) {
1711 if(test_par<0) return(1);
1712 if(test_par+1>res1->parNr || test_par+1>res2->parNr) return(1);
1713 }
1714 if(test_limit<0.0) return(1);
1715 for(ri=0; ri<res1->voiNr; ri++) {
1716 for(pi=0; pi<res1->parNr; pi++) {
1717 if(test_par>=0 && test_par!=pi) continue;
1718 v1=res1->voi[ri].parameter[pi]; v2=res2->voi[ri].parameter[pi];
1719 if(isnan(v1) && isnan(v2)) continue;
1720 /* Parameter values */
1721 if(RESULT_TEST>5) printf("pi=%d ri=%d\n", pi, ri);
1722 if(RESULT_TEST>5) printf(" %g vs %g\n", v1, v2);
1723 s=fabs(v1-v2);
1724 if(isnan(s) || s>test_limit) return(2);
1725 if(test_sd!=0) {
1726 /* SD */
1727 v1=res1->voi[ri].sd[pi]; v2=res2->voi[ri].sd[pi];
1728 if(isnan(v1) && !isnan(v2)) return(3);
1729 if(!isnan(v1) && isnan(v2)) return(3);
1730 if(!isnan(v1) && !isnan(v2)) {
1731 if(RESULT_TEST>8) printf(" SD: %g vs %g\n", v1, v2);
1732 s=fabs(v1-v2); if(s>test_limit) return(3);
1733 }
1734 /* CL1 */
1735 v1=res1->voi[ri].cl1[pi]; v2=res2->voi[ri].cl1[pi];
1736 if(isnan(v1) && !isnan(v2)) return(4);
1737 if(!isnan(v1) && isnan(v2)) return(4);
1738 if(!isnan(v1) && !isnan(v2)) {
1739 if(RESULT_TEST>8) printf(" CL1: %g vs %g\n", v1, v2);
1740 s=fabs(v1-v2); if(s>test_limit) return(4);
1741 }
1742 /* CL2 */
1743 v1=res1->voi[ri].cl2[pi]; v2=res2->voi[ri].cl2[pi];
1744 if(isnan(v1) && !isnan(v2)) return(5);
1745 if(!isnan(v1) && isnan(v2)) return(5);
1746 if(!isnan(v1) && !isnan(v2)) {
1747 if(RESULT_TEST>8) printf(" CL2: %g vs %g\n", v1, v2);
1748 s=fabs(v1-v2); if(s>test_limit) return(5);
1749 }
1750 }
1751 }
1752 }
1753 return(0);
1754}

◆ resMatchRegions()

int resMatchRegions ( RES * res1,
RES * res2 )

Check whether result region names are the same.

Returns
Returns 0 in case of match, and 1 if not matching.
See also
resRNameSubfieldExists, resMatchHeader, resMatchParameternames
Parameters
res1Pointers to the result data that are tested.
res2Pointers to the result data that are tested.

Definition at line 1531 of file result.c.

1536 {
1537 int ri, m=0;
1538
1539 if(res1==NULL || res2==NULL || res1->voiNr!=res2->voiNr) return(1);
1540 for(ri=0; ri<res1->voiNr; ri++) {
1541 m=0;
1542// if(strcmp(res1->voi[ri].name, res2->voi[ri].name)!=0) return(1);
1543 if(strcmp(res1->voi[ri].voiname, res2->voi[ri].voiname)!=0) m++;
1544 if(strcmp(res1->voi[ri].hemisphere, res2->voi[ri].hemisphere)!=0) m++;;
1545 if(strcmp(res1->voi[ri].place, res2->voi[ri].place)!=0) m++;
1546 if(m>0) {
1547 if(RESULT_TEST>5) {
1548 printf(" '%s' vs '%s'\n", res1->voi[ri].voiname, res2->voi[ri].voiname);
1549 printf(" '%s' vs '%s'\n", res1->voi[ri].hemisphere, res2->voi[ri].hemisphere);
1550 printf(" '%s' vs '%s'\n", res1->voi[ri].place, res2->voi[ri].place);
1551 }
1552 return(1);
1553 }
1554 }
1555 return(0);
1556}
char hemisphere[MAX_REGIONSUBNAME_LEN+1]
char place[MAX_REGIONSUBNAME_LEN+1]
char voiname[MAX_REGIONSUBNAME_LEN+1]

◆ resMean()

int resMean ( double * data,
int nr,
double * mean,
double * sd )

Calculate the mean and sd in the specified double array data of length nr.

NULL pointer may be specified to function in place of an unwanted return parameter.

Returns
Returns 0 if successful.
See also
resMedian, doubleMean
Parameters
dataArray of data.
nrLength of data array.
meanPointer where mean is written.
sdPointer where S.D. is written.

Definition at line 1222 of file result.c.

1231 {
1232 int i;
1233 double sum, ssum, v;
1234
1235 /* Check the arguments */
1236 if(data==NULL) return(1);
1237 if(nr<1) return(2);
1238 /* Calculate avg and sd */
1239 for(i=0, sum=ssum=0.0; i<nr; i++) {
1240 sum+=data[i]; ssum+=data[i]*data[i];
1241 }
1242 if(mean!=NULL) *mean=sum/(double)nr;
1243 if(sd!=NULL) {
1244 if(nr>1) v=(ssum-sum*sum/(double)nr)/(double)(nr-1); else v=0.0;
1245 if(v>0.0) *sd=sqrt(v); else *sd=0.0;
1246 }
1247 return(0);
1248}
int mean(double *x, double *y, int nr, double *xmean, double *xsd, double *ymean, double *ysd)
Definition pearson.c:341

Referenced by rescoll_tabulate().

◆ resMedian()

int resMedian ( double * data,
int nr,
double * median,
double * min,
double * max )

Calculate the median and the lowest and highest value in the specified double array data of length nr.

Note that array is sorted in this function. NULL pointer may be specified to function in place of an unwanted return parameter.

Returns
Returns 0 if successful.
See also
resMean, doubleMean
Parameters
dataArray of data.
nrLength of data array.
medianPointer where median is written.
minPointer where min is written.
maxPointer where max is written.

Definition at line 1186 of file result.c.

1197 {
1198 /* Check the arguments */
1199 if(data==NULL) return(1);
1200 if(nr<1) return(2);
1201 /* Sort data in increasing order */
1202 qsort(data, nr, sizeof(double), resQSortComp);
1203 /* Get minimum and maximum */
1204 if(min!=NULL) *min=data[0];
1205 if(max!=NULL) *max=data[nr-1];
1206 /* Calculate median */
1207 if(median!=NULL) {
1208 if(nr%2) *median=data[(nr-1)/2];
1209 else *median=0.5*(data[(nr/2)-1]+data[nr/2]);
1210 }
1211 return(0);
1212}

Referenced by rescoll_tabulate().

◆ resParameterPrintType()

int resParameterPrintType ( RES * res,
int parIndex )

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

Returns
Returns the code, or <0 in case of an error.
See also
resWrite
Parameters
resPointer to the result struct.
parIndexIndex of the parameter to test.

Definition at line 1447 of file result.c.

1452 {
1453 int vi, partype=0;
1454 double x, m=0.0, pint;
1455
1456 if(res==NULL || res->voiNr<1 || parIndex<0 || parIndex>=res->parNr)
1457 return(-1);
1458 for(vi=0; vi<res->voiNr; vi++) {
1459 x=res->voi[vi].parameter[parIndex];
1460 if(modf(x, &pint)!=0.0) partype=1;
1461 x=fabs(x); if(x>m) m=x;
1462 }
1463 if(partype==1 && (m>=10.0 || m<0.1)) partype=2;
1464 return(partype);
1465}

Referenced by rescoll_tabulate(), resWrite(), and resWriteHTML_table().

◆ resPrint()

void resPrint ( RES * res)

Print to stdout the contents of RES data structure.

See also
resWrite, resInit, resRead
Parameters
resPointer to result data.

Definition at line 186 of file result.c.

189 {
190 resWrite(res, "stdout", 0);
191}
int resWrite(RES *res, char *filename, int verbose)
Definition result.c:565

◆ resRead()

int resRead ( char * filename,
RES * res,
int verbose )

Read RES file contents to the specified data structure.

Returns
In case of an error, >0 is returned, and a description is written in reserrmsg.
See also
resWrite, resInit, resPrint, resFixParnames
Parameters
filenameResult file name.
resPointer to initiated RES structure; any previous contents are deleted.
verboseVerbose level; if <=0, then nothing is printed into stdout.

Definition at line 199 of file result.c.

206 {
207 FILE *fp;
208 char *cptr, line[1024], *lptr, tmp[1024];
209 int i, n;
210 fpos_t file_loc;
211
212
213 if(verbose>0) printf("resRead(%s, *res);\n", filename);
214 if(res==NULL) return(1);
215 /* Empty data */
216 resEmpty(res);
217 res->isweight=-1; /* unknown */
218
219 /* Open file; note that 'b' is required for fgetpos() and fsetpos() to work
220 correctly */
221 fp=fopen(filename, "rb");
222 if(fp==NULL) {strcpy(reserrmsg, "cannot open file"); return(1);}
223
224 /*
225 * Read data, each result set separately, saving only the first one
226 */
227 strcpy(reserrmsg, "wrong format");
228
229 /* Read program name */
230 if(verbose>1) printf("reading program name\n");
231 while(fgets(line, 1024, fp)!=NULL) {
232 /* Ignore empty and comment lines */
233 if(strlen(line)<4 || line[0]=='#') continue; else break;
234 }
235 /* Check for string (c) or (C) */
236 if(strstr(line, "(c)") || strstr(line, "(C)")) {
237 i=strlen(line)-1; while(i>0 && isspace(line[i])) i--; line[i+1]=(char)0;
238 if(i<4) {fclose(fp); return(2);}
239 strcpy(res->program, line);
240 } else {fclose(fp); return(2);}
241
242 /* Read calculation date and time */
243 if(verbose>1) printf("reading date and time\n");
244 while(fgets(line, 1024, fp)!=NULL) if(strlen(line)>2 && line[0]!='#') break;
245 if(strncasecmp(line, "Date:", 5)) {fclose(fp); return(4);}
246 cptr=&line[5]; while(isblank(cptr[0])) cptr++;
247 if(cptr!=NULL) {
248 if(verbose>3) printf("date_str := %s", cptr);
249 struct tm st;
250 if(get_datetime(cptr, &st, verbose-3)==0) res->time=timegm(&st);
251 else if(get_date(cptr, &st)==0) res->time=timegm(&st);
252 else res->time=(time_t)0;
253 }
254
255 /* Read studynr, datafiles, ref region, data range, etc */
256 if(verbose>1) printf("reading headers\n");
257 do {
258 /* Omit comment and too short lines */
259 while((lptr=fgets(line, 1024, fp))!=NULL) {
260 if(strlen(line)>2 && line[0]!='#') break;
261 if(lptr!=NULL && verbose>6)
262 printf("omitted line[%d] := %s", (int)strlen(line), line);
263 }
264 if(lptr==NULL) break;
265 strcpy(tmp, line);
266 n=0; if(verbose>3) printf("line[%d] := %s", (int)strlen(line), line);
267 if(strncasecmp(line, "Study", 5)==0) {
268 lptr=&tmp[6]; cptr=strtok(lptr, " \t\n\r"); n=1;
269 if(cptr!=NULL && strlen(cptr)<1024) {
270 strlcpy(res->studynr, cptr, MAX_STUDYNR_LEN+1);
271 }
272 } else if(strncasecmp(line, "Data file", 9)==0) {
273 lptr=&tmp[10]; cptr=strtok(lptr, " \t\n\r"); n=1;
274 if(cptr!=NULL && strlen(cptr)<1024) strcpy(res->datafile, cptr);
275 } else if(strncasecmp(line, "ROI file", 8)==0) {
276 lptr=&tmp[9]; cptr=strtok(lptr, " \t\n\r"); n=1;
277 if(cptr!=NULL && strlen(cptr)<1024) strcpy(res->datafile, cptr);
278 } else if(strncasecmp(line, "Plasma file", 11)==0) {
279 cptr=strchr(tmp, ':')+1; while(isspace((int)*cptr)) cptr++; n=1;
280 if(cptr!=NULL && strlen(cptr)<1024) strcpy(res->plasmafile, cptr);
281 cptr=res->plasmafile+strlen(res->plasmafile)-1;
282 while(isspace((int)*cptr)) {*cptr=(char)0; cptr--;}
283 } else if(strncasecmp(line, "2nd Plasma file", 15)==0) {
284 cptr=strchr(tmp, ':')+1; while(isspace((int)*cptr)) cptr++; n=1;
285 if(cptr!=NULL && strlen(cptr)<1024) strcpy(res->plasmafile2, cptr);
286 cptr=res->plasmafile2+strlen(res->plasmafile2)-1;
287 while(isspace((int)*cptr)) {*cptr=(char)0; cptr--;}
288 } else if(strncasecmp(line, "Blood file", 10)==0) {
289 lptr=&tmp[11]; cptr=strtok(lptr, " \t\n\r"); n=1;
290 if(cptr!=NULL && strlen(cptr)<1024) strcpy(res->bloodfile, cptr);
291 } else if(strncasecmp(line, "Reference file", 14)==0) {
292 lptr=&tmp[15]; cptr=strtok(lptr, " \t\n\r"); n=1;
293 if(cptr!=NULL && strlen(cptr)<1024) strcpy(res->reffile, cptr);
294 } else if(strncasecmp(line, "Reference region", 16)==0) {
295 cptr=strchr(tmp, ':')+1; while(isspace((int)*cptr)) cptr++; n=1;
296 if(cptr!=NULL && strlen(cptr)<64) strcpy(res->refroi, cptr);
297 cptr=res->refroi+strlen(res->refroi)-1;
298 while(isspace((int)*cptr)) {*cptr=(char)0; cptr--;}
299 } else if(strncasecmp(line, "Fit time", 8)==0 || strncasecmp(line, "Data range", 10)==0) {
300 cptr=strchr(tmp, ':')+1; while(isspace((int)*cptr)) cptr++; n=1;
301 if(cptr!=NULL && strlen(cptr)<128) strcpy(res->datarange, cptr);
302 cptr=res->datarange+strlen(res->datarange)-1;
303 while(isspace((int)*cptr)) {*cptr=(char)0; cptr--;}
304 } else if(strncasecmp(line, "Data nr", 7)==0) {
305 cptr=strchr(tmp, ':')+1; while(isspace((int)*cptr)) cptr++; n=1;
306 if(cptr!=NULL) res->datanr=atoi(cptr);
307 } else if(strncasecmp(line, "Fit method", 10)==0) {
308 cptr=strchr(tmp, ':')+1; while(isspace((int)*cptr)) cptr++; n=1;
309 if(cptr!=NULL && strlen(cptr)<128) strcpy(res->fitmethod, cptr);
310 cptr=res->fitmethod+strlen(res->fitmethod)-1;
311 while(isspace((int)*cptr)) {*cptr=(char)0; cptr--;}
312 } else if(strncasecmp(line, "Tissue density", 14)==0) {
313 cptr=strchr(tmp, ':')+1; while(isspace((int)*cptr)) cptr++; n=1;
314 if(cptr!=NULL) res->density=atof_dpi(cptr);
315 } else if(strncasecmp(line, "Lumped constant", 15)==0) {
316 cptr=strchr(tmp, ':')+1; while(isspace((int)*cptr)) cptr++; n=1;
317 if(cptr!=NULL) res->lc=atof_dpi(cptr);
318 } else if(strncasecmp(line, "Concentration", 13)==0) {
319 cptr=strchr(tmp, ':')+1; while(isspace((int)*cptr)) cptr++; n=1;
320 if(cptr!=NULL) res->concentration=atof_dpi(cptr);
321 } else if(strncasecmp(line, "Beta", 4)==0) {
322 cptr=strchr(tmp, ':')+1; while(isspace((int)*cptr)) cptr++; n=1;
323 if(cptr!=NULL) res->beta=atof_dpi(cptr);
324 } else if(strncasecmp(line, "Vb", 2)==0) {
325 cptr=strchr(tmp, ':')+1; while(isspace((int)*cptr)) cptr++; n=1;
326 if(cptr!=NULL) res->Vb=atof_dpi(cptr);
327 } else if(strncasecmp(line, "fA", 2)==0) {
328 cptr=strchr(tmp, ':')+1; while(isspace((int)*cptr)) cptr++; n=1;
329 if(cptr!=NULL) res->fA=atof_dpi(cptr);
330 } else if(strncasecmp(line, "Extraction", 10)==0) {
331 cptr=strchr(tmp, ':')+1; while(isspace((int)*cptr)) cptr++; n=1;
332 if(cptr!=NULL) res->E=atof_dpi(cptr);
333 } else if(strncasecmp(line, "Weighting", 9)==0) {
334 cptr=strchr(tmp, ':')+1; while(isspace((int)*cptr)) cptr++; n=1;
335 if(strncasecmp(cptr, "yes", 1)==0) res->isweight=1;
336 else if(strncasecmp(cptr, "no", 1)==0) res->isweight=0;
337 else res->isweight=-1;
338 } else if(strncasecmp(line, "Data was weighted", 17)==0) {
339 res->isweight=1; n=1;
340 } else if(strncasecmp(line, "Data was not weighted", 21)==0) {
341 res->isweight=0; n=1;
342 } else if(strncasecmp(line, "Region", 6)==0) {
343 /* Header end, stop here */
344 n=0;
345 } else { /* Ignore all other header lines */
346 n=1;
347 }
348 } while(n);
349 if(verbose>6) printf("quit reading headers\n");
350
351 /* Read the result parameter title line */
352 if(verbose>1) printf("reading parameter titles\n");
353 if(verbose>6) printf("using previously read line[%d] := %s", (int)strlen(line), line);
354 if(strncasecmp(line, "Region", 6)) {fclose(fp); return(10);}
355 strcpy(tmp, line);
356 lptr=strpbrk(tmp+6, " \n\r\t"); if(lptr==NULL) {fclose(fp); return(10);}
357 cptr=strtok(lptr, " \n\r\t");
358 n=0;
359 if(cptr!=NULL) {
360 if(strcmp(cptr, ".")!=0) {
361 strncpy(res->parname[n], cptr, MAX_RESPARNAME_LEN);
362 res->parname[n][MAX_RESPARNAME_LEN]=(char)0;
363 } else {strcpy(res->parname[n], "");}
364 if(verbose>5) printf(" parname[%d] := '%s'\n", n, res->parname[n]);
365 n++;
366 } else {strcpy(res->parname[n], "");}
367 while(cptr!=NULL) {
368 cptr=strtok(NULL, " \n\r\t");
369 if(cptr!=NULL && n<MAX_RESPARAMS) {
370 if(strcmp(cptr, ".")!=0) {
371 strncpy(res->parname[n], cptr, MAX_RESPARNAME_LEN);
372 res->parname[n][MAX_RESPARNAME_LEN]=(char)0;
373 } else {strcpy(res->parname[n], "");}
374 if(verbose>5) printf(" parname[%d] := '%s'\n", n, res->parname[n]);
375 n++;
376 }
377 }
378 res->parNr=n; if(verbose>1) printf("parNr := %d\n", res->parNr);
379
380 /* Read the result parameter unit line */
381 if(verbose>2) printf("seeking unit line...\n");
382 if(fgetpos(fp, &file_loc)!=0) {fclose(fp); return(20);}
383 while(fgets(line, 1024, fp)!=NULL && strlen(line)<3) {
384 if(verbose>6) printf("omitted line[%d] := %s", (int)strlen(line), line);
385 /* save the file position where unit line or results really start */
386 if(fgetpos(fp, &file_loc)!=0) {fclose(fp); return(20);}
387 }
388 if(verbose>5) printf("possible unit line[%d]: %s", (int)strlen(line), line);
389 if(strncasecmp(line, "# Units :", 7)==0 ||
390 strncasecmp(line, "Units : ", 7)==0 ||
391 strncasecmp(line, "# Units: ", 7)==0 ||
392 strncasecmp(line, "Units: ", 6)==0)
393 {
394 if(verbose>1) printf("reading parameter units\n");
395 strcpy(tmp, line); lptr=strchr(tmp+5, ':');
396 if(lptr!=NULL) lptr++; else lptr=strpbrk(tmp+6, " \n\r\t");
397 cptr=strtok(lptr, " \n\r\t"); n=0;
398 if(cptr!=NULL) {
399 if(strcmp(cptr, ".")!=0) {
400 strncpy(res->parunit[n], cptr, MAX_RESPARNAME_LEN);
401 res->parunit[n][MAX_RESPARNAME_LEN]=(char)0;
402 } else {strcpy(res->parunit[n], "");}
403 if(verbose>5) printf(" parunit[%d] := '%s'\n", n, res->parunit[n]);
404 n++;
405 } else {strcpy(res->parunit[n], "");}
406 while(cptr!=NULL) {
407 cptr=strtok(NULL, " \n\r\t");
408 if(cptr!=NULL && n<MAX_RESPARAMS) {
409 if(strcmp(cptr, ".")!=0) {
410 strncpy(res->parunit[n], cptr, MAX_RESPARNAME_LEN);
411 res->parunit[n][MAX_RESPARNAME_LEN]=(char)0;
412 } else strcpy(res->parunit[n], "");
413 if(verbose>5) printf(" parunit[%d] := '%s'\n", n, res->parunit[n]);
414 n++;
415 }
416 }
417 } else {
418 if(verbose>5) printf(" ... not identified as unit line.\n");
419 /* move file pointer to the previous place */
420 if(fsetpos(fp, &file_loc)!=0) {fclose(fp); return(20);}
421 }
422
423 /* Read the nr of result lines */
424 if(verbose>1) printf("reading nr of results\n");
425 /* Set bookmark to the start of result lines */
426 if(fgetpos(fp, &file_loc)!=0) {fclose(fp); return(21);}
427 n=0;
428 while(fgets(line, 1024, fp)!=NULL) {
429 if(verbose>6) printf("line[%d] := %s", (int)strlen(line), line);
430 if(line[0]=='#' || line[0]==';') continue;
431 i=strlen(line); if(i<2) continue; if(i<3) break;
432 n++;
433 }
434 /* Return file pointer to the start of result lines */
435 if(fsetpos(fp, &file_loc)!=0) {fclose(fp); return(22);}
436 if(verbose>1) printf("nr of result lines is %d\n", n);
437 if(n<1) {
438 strcpy(reserrmsg, "invalid result lines");
439 fclose(fp); return(23);
440 }
441
442 /* Allocate memory for regional results */
443 if(verbose>2) printf("allocating memory\n");
444 if(resSetmem(res, n)) {
445 strcpy(reserrmsg, "cannot allocate memory");
446 fclose(fp); return(25);
447 }
448
449 /* Read regional results */
450 if(verbose>1) printf("reading results to memory\n");
451 int separtab=0; // 0=space as separator, 1=tab as separator
452 char separstr[12];
453 res->voiNr=0;
454 while(fgets(line, 1024, fp)!=NULL) {
455 if(verbose>6) printf("line[%d] := %s", (int)strlen(line), line);
456 if(line[0]=='#' || line[0]==';') continue;
457 i=strlen(line); if(i<2) continue; if(i<3) break;
458 strcpy(tmp, line);
459 if(verbose>2) printf("reading result %d\n", 1+res->voiNr);
460
461 /* Read region names */
462 if(strchr(tmp, '\t')==NULL) separtab=0; else separtab=1;
463 if(separtab) strcpy(separstr, "\t\n\r"); else strcpy(separstr, " \t\n\r");
464 int tokenNr=strTokenNr(tmp, separstr);
465 if(verbose>20) printf(" tokenNr := %d\n", tokenNr);
466 if(!separtab) { // old format with space as separator
467 if(verbose>20) printf("separator: space\n");
468 n=strTokenNCpy(tmp, separstr, 1, res->voi[res->voiNr].voiname, MAX_REGIONSUBNAME_LEN+1);
469 if(n==0) {fclose(fp); return(31);}
470 n=strTokenNCpy(tmp, separstr, 2, res->voi[res->voiNr].hemisphere, MAX_REGIONSUBNAME_LEN+1);
471 if(n==0) {fclose(fp); return(31);}
472 n=strTokenNCpy(tmp, separstr, 3, res->voi[res->voiNr].place, MAX_REGIONSUBNAME_LEN+1);
473 if(n==0) {fclose(fp); return(31);}
475 res->voi[res->voiNr].hemisphere, res->voi[res->voiNr].place, ' ');
476 } else { // space can exist only in TAC name
477 if(verbose>20) printf("separator: tab\n");
478 n=strTokenNCpy(tmp, separstr, 1, res->voi[res->voiNr].name, MAX_REGIONNAME_LEN+1);
479 if(n==0) {fclose(fp); return(31);}
480 rnameSplit(res->voi[res->voiNr].name, res->voi[res->voiNr].voiname,
481 res->voi[res->voiNr].hemisphere, res->voi[res->voiNr].place, MAX_REGIONSUBNAME_LEN);
482 }
483 if(strcmp(res->voi[res->voiNr].voiname, ".")==0) res->voi[res->voiNr].voiname[0]=(char)0;
484 if(strcmp(res->voi[res->voiNr].hemisphere, ".")==0) res->voi[res->voiNr].hemisphere[0]=(char)0;
485 if(strcmp(res->voi[res->voiNr].place, ".")==0) res->voi[res->voiNr].place[0]=(char)0;
486 if(verbose>18) {
487 printf(" voiname := '%s'\n", res->voi[res->voiNr].voiname);
488 printf(" hemisphere := '%s'\n", res->voi[res->voiNr].hemisphere);
489 printf(" place := '%s'\n", res->voi[res->voiNr].place);
490 }
491
492 /* Read results, continuing from the pointer after region names */
493 int tokeni=2; if(!separtab) tokeni=4;
494 char buf[128];
495 for(i=0; i<MAX_RESPARAMS && tokeni<=tokenNr; i++, tokeni++) {
496 n=strTokenNCpy(tmp, separstr, tokeni, buf, 128);
497 if(n==0) {fclose(fp); return(32);}
498 if(strlen(buf)==1 && buf[0]=='.') res->voi[res->voiNr].parameter[i]=nan("");
499 else res->voi[res->voiNr].parameter[i]=atof_dpi(buf);
500 }
501 if(verbose>5) printf(" for '%s' parNr:=%d\n", res->voi[res->voiNr].name, i);
502 //if(res->voiNr==0) {res->parNr=i;} else if(i<res->parNr) res->parNr=i;
503 if(i<res->parNr) {
504 if(verbose>0)
505 printf("Warning: smaller parNr %d on region '%s'\n", i, res->voi[res->voiNr].name);
506 res->parNr=i;
507 }
508
509 /* If 'region' name implies that this was confidence limit or sd, then */
510 /* move the values into correct places, and do not increase the voiNr */
511 if(res->voiNr==0) {res->voiNr++; continue;}
512 if(strcasecmp(res->voi[res->voiNr].voiname, "CL")==0) {
513 if(strcmp(res->voi[res->voiNr].hemisphere, "95%")==0) {
514 if(strcasecmp(res->voi[res->voiNr].place, "Lower")==0)
515 for(i=0; i<res->parNr; i++)
516 res->voi[res->voiNr-1].cl1[i]=res->voi[res->voiNr].parameter[i];
517 else if(strcasecmp(res->voi[res->voiNr].place, "Upper")==0)
518 for(i=0; i<res->parNr; i++)
519 res->voi[res->voiNr-1].cl2[i]=res->voi[res->voiNr].parameter[i];
520 continue;
521 }
522 } else if(strcasecmp(res->voi[res->voiNr].voiname, "SD")==0) {
523 for(i=0; i<res->parNr; i++)
524 res->voi[res->voiNr-1].sd[i]=res->voi[res->voiNr].parameter[i];
525 continue;
526 }
527 res->voiNr++;
528 }
529 if(res->parNr==0) {fclose(fp); return(33);}
530 if(verbose>0) printf("nr of results: %d ; nr of parameters: %d\n", res->voiNr, res->parNr);
531
532 /* Seek for other results in the same file */
533 while(fgets(line, 1024, fp)!=NULL) {
534 /* Ignore empty and comment lines */
535 if(strlen(line)<3 || line[0]=='#') continue; else break;
536 }
537 /* Check again for string (c) or (C) */
538 if(strstr(line, "(c)") || strstr(line, "(C)")) {
539 fprintf(stderr,
540 "Warning: %s contains more than one set of results; only the 1st one is used.\n", filename);
541 }
542
543 /* Close file */
544 fclose(fp);
545 strcpy(reserrmsg, "");
546
547 /* Fill studynr if it was not found in file */
548 if(!res->studynr[0]) studynr_from_fname(filename, res->studynr);
549 /* Set also deprecated parameter name and unit representations, for now */
550 resFixParnames(res);
551
552 return(0);
553}
int get_datetime(char *str, struct tm *date, int verbose)
Definition datetime.c:322
time_t timegm(struct tm *tm)
Inverse of gmtime, converting struct tm to time_t.
Definition datetime.c:69
int get_date(char *str, struct tm *date)
Definition datetime.c:377
double atof_dpi(char *str)
Definition decpoint.c:59
int rnameCatenate(char *rname, int max_rname_len, char *name1, char *name2, char *name3, char space)
Definition rname.c:189
int rnameSplit(char *rname, char *name1, char *name2, char *name3, int max_name_len)
Definition rname.c:14
#define MAX_REGIONNAME_LEN
Definition libtpcmisc.h:154
int strTokenNCpy(const char *str1, const char *str2, int i, char *str3, int count)
Definition strext.c:45
int strTokenNr(const char *str1, const char *str2)
Definition strext.c:17
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition strext.c:245
#define MAX_STUDYNR_LEN
Definition libtpcmisc.h:163
#define MAX_REGIONSUBNAME_LEN
Definition libtpcmisc.h:158
char reserrmsg[64]
Definition result.c:6
int resSetmem(RES *res, int voiNr)
Definition result.c:70

◆ resRNameSubfieldExists()

int resRNameSubfieldExists ( RES * res)

Check whether region name sub-fields exist in any region.

Returns
Returns 1 if hemisphere exists, 2 if place exists, 3 if both exist, and 0 if neither exists, and <0 in case of an error.
See also
resFixParnames, resSortByName, resIsDuplicateNames
Parameters
resPointer to RES struct.

Definition at line 1763 of file result.c.

1766 {
1767 int ri, m=0, n=0;
1768
1769 if(res==NULL) return(-1);
1770 if(res->voiNr<1) return(-1);
1771 for(ri=0; ri<res->voiNr; ri++) {
1772 if(strlen(res->voi[ri].hemisphere)>0 &&
1773 strcmp(res->voi[ri].hemisphere, ".")!=0)
1774 m++;
1775 if(strlen(res->voi[ri].place)>0 &&
1776 strcmp(res->voi[ri].place, ".")!=0)
1777 n++;
1778 }
1779 ri=0; if(m>0) ri+=1; if(n>0) ri+=2;
1780 return(ri);
1781}

◆ resSelect()

int resSelect ( RES * data,
char * name )

Select VOIs (sets sw=1), whose names are matching specified string.

If no string is specified, then all VOIs are selected.

Returns
Returns the number of matches, or <0, if an error occurred.
See also
resDelete, resSelectRegions
Parameters
dataPointer to the result data.
nameRegion name string.

Definition at line 1369 of file result.c.

1374 {
1375 unsigned int i, j, n;
1376 char *p, n1[128], n2[128], n3[128], tmp[128], sname[1024], *lptr;
1377
1378 if(data==NULL) return(-1);
1379 /* Select all, if no string was specified */
1380 if(name==NULL || strlen(name)==0) {
1381 for(i=0; i<(unsigned int)data->voiNr; i++) data->voi[i].sw=1;
1382 return(data->voiNr);
1383 }
1384 /* Make a copy of 'name' and use it */
1385 strcpy(sname, name); lptr=sname;
1386 /* Check if string contains several substrings (hemisphere and place) */
1387 n1[0]=n2[0]=n3[0]=(char)0;
1388 p=strtok(lptr, " ,;\n\t|"); if(p!=NULL) strcpy(n1, p); else return(-1);
1389 p=strtok(NULL, " ,;\n\t|"); if(p!=NULL) {
1390 strcpy(n2, p); p=strtok(NULL, " ,;\n\t|"); if(p!=NULL) strcpy(n3, p);}
1391 /* Convert strings to lowercase */
1392 for(i=0; i<strlen(n1); i++) n1[i]=tolower(n1[i]);
1393 for(i=0; i<strlen(n2); i++) n2[i]=tolower(n2[i]);
1394 for(i=0; i<strlen(n3); i++) n3[i]=tolower(n3[i]);
1395 /* Search through the data */
1396 for(i=0, n=0; i<(unsigned int)data->voiNr; i++) {
1397 data->voi[i].sw=0;
1398 snprintf(tmp, 128, "%s%s%s", data->voi[i].voiname, data->voi[i].hemisphere,
1399 data->voi[i].place);
1400 for(j=0; j<strlen(tmp); j++) tmp[j]=tolower(tmp[j]);
1401 if(strstr(tmp, n1)==NULL) continue;
1402 if(n2[0] && strstr(tmp, n2)==NULL) continue;
1403 if(n3[0] && strstr(tmp, n3)==NULL) continue;
1404 data->voi[i].sw=1; n++;
1405 }
1406 return(n);
1407}

◆ resSelectRegions()

int resSelectRegions ( RES * res,
char * region_name,
int reset )

Select the VOIs that have matching region name or number.

Sets sw=1 or sw=0. This will replace resSelect().

Returns
Returns the number of selected VOIs, or <0 in case of an error.
See also
resRead, resDelete, resIsDuplicateNames
Parameters
resPointer to RES data where VOIs are selected
region_nameName or VOI number which is searched
reset1=Non-matching VOIs are deselected, 0=Old selections are preserved

Definition at line 1417 of file result.c.

1424 {
1425 int ri, match_nr=0;
1426
1427 /* Check the input */
1428 if(res==NULL || res->voiNr<1 || strlen(region_name)<1) return(-1);
1429 /* Reset all selections if required */
1430 if(reset!=0) for(ri=0; ri<res->voiNr; ri++) res->voi[ri].sw=0;
1431 /* Check each VOI */
1432 for(ri=0; ri<res->voiNr; ri++) {
1433 if(rnameMatch(res->voi[ri].name, ri+1, region_name)!=0) {
1434 res->voi[ri].sw=1; match_nr++;
1435 }
1436 }
1437 return(match_nr);
1438}
int rnameMatch(char *rname, int rnr, char *test_str)
Definition rname.c:144

◆ resSetmem()

int resSetmem ( RES * res,
int voiNr )

Allocate memory for result data. Old data is destroyed.

See also
resInit, resEmpty
Parameters
resPointer to initiated and possibly allocated result data.
voiNrNr of regional results.

Definition at line 70 of file result.c.

75 {
76 int ri, pi;
77
78 /* Check that there is something to do */
79 if(res==NULL || voiNr<1) return(1);
80
81 /* Clear previous data, but only if necessary */
82 if(res->_voidataNr>0 || res->voiNr>0) resEmpty(res);
83
84 /* Allocate memory for regional curves */
85 res->voi=(ResVOI*)calloc(voiNr, sizeof(ResVOI));
86 if(res->voi==NULL) return(2);
87 res->_voidataNr=voiNr;
88
89 /* Set SDs and CLs to NA */
90 for(ri=0; ri<res->_voidataNr; ri++) for(pi=0; pi<MAX_RESPARAMS; pi++)
91 res->voi[ri].sd[pi]=res->voi[ri].cl1[pi]=res->voi[ri].cl2[pi]=nan("");
92
93 return(0);
94}

Referenced by fitToResult(), res_allocate_with_dft(), and resRead().

◆ resSortByName()

void resSortByName ( RES * res)

Sort RES regions by region name.

See also
resIsDuplicateNames, resRead, resWrite, resCopyMHeader

Definition at line 1266 of file result.c.

1269 {
1270 if(res==NULL || res->voiNr<=1) return;
1271 qsort(res->voi, res->voiNr, sizeof(ResVOI), resQSortName);
1272 return;
1273}

◆ resWrite()

int resWrite ( RES * res,
char * filename,
int verbose )

Write calculation results into specified file.

If file exists, a backup file (+BACKUP_EXTENSION) is written also. If "stdout" is given as filename, output is directed to stdout. If filename extension is *.htm(l), file is saved in HTML format.

Returns
In case of an error, >0 is returned, and a description is written in reserrmsg.
See also
resInit, resRead, resEmpty, resPrint, resWriteHTML
Parameters
resPointer to result data.
filenameOutput file name.
verboseVerbose level; if <=0, then nothing is printed into stdout.

Definition at line 565 of file result.c.

572 {
573 int i, j, n;
574 char tmp[1024], is_stdout=0, *cptr;
575 FILE *fp;
576 int partype[MAX_RESPARAMS]; /* 0=int, 1=double, 2=exp */
577 int colwidth[MAX_RESPARAMS];
578 double *p;
579
580
581 if(verbose>1) printf("resWrite(*res, %s, %d)\n", filename, verbose);
582 /* Check that there is some data to write */
583 if(res==NULL) {strcpy(reserrmsg, "error in result data"); return(1);}
584 if(res->voiNr<1) {strcpy(reserrmsg, "no result data"); return(1);}
585
586 /* Write results in HTML format, if necessary */
587 cptr=strrchr(filename, '.');
588 if(cptr!=NULL && (!strncasecmp(cptr, ".htm", 4)))
589 return(resWriteHTML(res, filename, verbose));
590
591 /* Check if writing to stdout */
592 if(!strcasecmp(filename, "stdout")) is_stdout=1;
593
594 /* Check if file exists; backup, if necessary */
595 if(!is_stdout) (void)backupExistingFile(filename, NULL, NULL);
596
597 resFixParnames(res);
598
599 /* Open output file */
600 if(is_stdout) fp=(FILE*)stdout;
601 else if((fp = fopen(filename, "w")) == NULL) {
602 strcpy(reserrmsg, "cannot open file"); return(2);}
603
604 /* Program name */
605 n=fprintf(fp, "%s\n\n", res->program);
606 if(n==0) {
607 strcpy(reserrmsg, "disk full");
608 if(!is_stdout) fclose(fp);
609 return(3);
610 }
611
612 /* Write calculation date and time */
613 if(!ctime_r_int(&res->time, tmp)) strcpy(tmp, "1900-01-01 00:00:00");
614 fprintf(fp, "Date:\t%s\n", tmp);
615
616 /* Write the studynr */
617 if(res->studynr[0]) fprintf(fp, "Study:\t%s\n", res->studynr);
618
619 /* Write the names of the original datafiles */
620 if(res->datafile[0]) fprintf(fp, "Data file:\t%s\n", res->datafile);
621 if(res->plasmafile[0]) fprintf(fp, "Plasma file:\t%s\n", res->plasmafile);
622 if(res->plasmafile2[0]) fprintf(fp, "2nd Plasma file:\t%s\n", res->plasmafile2);
623 if(res->bloodfile[0]) fprintf(fp, "Blood file:\t%s\n", res->bloodfile);
624 if(res->reffile[0]) fprintf(fp, "Reference file:\t%s\n", res->reffile);
625 if(res->refroi[0]) fprintf(fp, "Reference region:\t%s\n", res->refroi);
626
627 /* Write data range etc */
628 if(res->datarange[0]) fprintf(fp, "Data range:\t%s\n", res->datarange);
629 if(res->datanr>0) fprintf(fp, "Data nr:\t%d\n", res->datanr);
630 if(res->fitmethod[0]) fprintf(fp, "Fit method:\t%s\n", res->fitmethod);
631
632 /* Write constants */
633 if(res->density>0.0) fprintf(fp, "Tissue density:\t%g\n", res->density);
634 if(res->lc>0.0) fprintf(fp, "Lumped constant:\t%g\n", res->lc);
635 if(res->concentration>0.0)
636 fprintf(fp, "Concentration:\t%g\n", res->concentration);
637 if(res->beta>0.0) fprintf(fp, "Beta:\t%g\n", res->beta);
638 if(res->Vb>=0.0) fprintf(fp, "Vb:\t%g %%\n", res->Vb);
639 if(res->fA>=0.0) fprintf(fp, "fA:\t%g %%\n", res->fA);
640 if(res->E>=0.0) fprintf(fp, "Extraction:\t%g\n", res->E);
641
642 /* Weighting */
643 if(res->isweight>0) strcpy(tmp, "yes");
644 else if(res->isweight==0) strcpy(tmp, "no");
645 else strcpy(tmp, "unknown");
646 fprintf(fp, "Weighting:\t%s\n", tmp);
647
648 /* Determine column widths: */
649 for(j=0; j<res->parNr; j++) colwidth[j]=1;
650 /* should column be printed as integers (0), floats (1) or exponentials (2)? */
651 for(j=0; j<res->parNr; j++) {
652 partype[j]=resParameterPrintType(res, j);
653 }
654 /* min width required by titles */
655 for(j=0; j<res->parNr; j++) colwidth[j]=strlen(res->parname[j]);
656 if(verbose>2) {
657 printf("col widths after titles were checked:\n");
658 for(i=0; i<res->parNr; i++)
659 printf(" par%d : partype=%d colwidth=%d\n", i+1, partype[i], colwidth[i]);
660 }
661 /* min width required by units */
662 for(j=0; j<res->parNr; j++) {
663 n=strlen(res->parunit[j]); if(n>colwidth[j]) colwidth[j]=n;
664 }
665 if(verbose>2) {
666 printf("col widths after units were checked:\n");
667 for(i=0; i<res->parNr; i++)
668 printf(" par%d : partype=%d colwidth=%d\n", i+1, partype[i], colwidth[i]);
669 }
670 /* widths required by result values */
671 for(i=0; i<res->voiNr; i++) {
672 p=res->voi[i].parameter;
673 for(j=0; j<res->parNr; j++) {
674 if(isnan(p[j])) continue;
675 if(p[j]>=0) n=4; else n=3;
676 switch(partype[j]) {
677 case 0: sprintf(tmp, "%.0f", p[j]); break;
678 case 1: sprintf(tmp, "%.*f", n, p[j]); break;
679 case 2:
680 default: sprintf(tmp, "%.*e", n, p[j]); break;
681 }
682 n=strlen(tmp); if(n>colwidth[j]) colwidth[j]=n;
683 }
684 }
685 if(verbose>2) {
686 printf("col widths after result values were checked:\n");
687 for(i=0; i<res->parNr; i++)
688 printf(" par%d : partype=%d colwidth=%d\n", i+1, partype[i], colwidth[i]);
689 }
690
691 /* Title line */
692 if(verbose>4) {
693 printf(" writing title line with %d parameter(s)\n", res->parNr);
694 fflush(stdout);
695 }
696 fprintf(fp, "\n%s\t", "Region");
697 for(i=0; i<res->parNr; i++) {
698 if(strlen(res->parname[i])<1) strcpy(tmp, ".");
699 else strcpy(tmp, res->parname[i]);
700 fprintf(fp, "\t%s", tmp);
701 }
702 fprintf(fp, "\n");
703
704 /* Write units, if they exist, currently as comment line */
705 for(i=j=0; i<res->parNr; i++) if(strlen(res->parunit[i])>0) j++;
706 if(j>0) {
707 if(verbose>4) {
708 printf(" writing units line with %d parameter(s)\n", j);
709 fflush(stdout);
710 }
711 fprintf(fp, "%s", "# Units:");
712 //fprintf(fp, "%s ", "# Units :");
713 for(i=0; i<res->parNr; i++) {
714 if(strlen(res->parunit[i])<1) strcpy(tmp, ".");
715 else strcpy(tmp, res->parunit[i]);
716 fprintf(fp, "\t%s", tmp);
717 }
718 fprintf(fp, "\n");
719 }
720 fflush(fp);
721
722 /* Write regional results */
723 if(verbose>4) {
724 printf(" writing %d regional results\n", res->voiNr); fflush(stdout);
725 }
726 for(i=0; i<res->voiNr; i++) {
727 if(verbose>6) {printf(" writing region %d\n", 1+i); fflush(stdout);}
728#if(1) // new version
729 if(res->voi[i].name[0]) {
730 fprintf(fp, "%s", res->voi[i].name);
731 } else {
732 if(res->voi[i].voiname[0]) strcpy(tmp, res->voi[i].voiname); else strcpy(tmp, ".");
733 fprintf(fp, "%.*s ", MAX_REGIONSUBNAME_LEN, tmp);
734 if(res->voi[i].hemisphere[0]) strcpy(tmp, res->voi[i].hemisphere); else strcpy(tmp, ".");
735 fprintf(fp, "%.*s ", MAX_REGIONSUBNAME_LEN, tmp);
736 if(res->voi[i].place[0]) strcpy(tmp, res->voi[i].place); else strcpy(tmp, ".");
737 fprintf(fp, "%.*s", MAX_REGIONSUBNAME_LEN, tmp);
738 }
739#else // previous version
740 if(res->voi[i].voiname[0])
741 strcpy(tmp, res->voi[i].voiname); else strcpy(tmp, ".");
742 fprintf(fp, "%.*s ", MAX_REGIONSUBNAME_LEN, tmp);
743 if(res->voi[i].hemisphere[0])
744 strcpy(tmp, res->voi[i].hemisphere); else strcpy(tmp, ".");
745 fprintf(fp, "%.*s ", MAX_REGIONSUBNAME_LEN, tmp);
746 if(res->voi[i].place[0])
747 strcpy(tmp, res->voi[i].place); else strcpy(tmp, ".");
748 fprintf(fp, "%.*s", MAX_REGIONSUBNAME_LEN, tmp);
749#endif
750 p=res->voi[i].parameter;
751 for(j=0; j<res->parNr; j++) {
752 if(verbose>15) {printf(" writing par %d\n", 1+j); fflush(stdout);}
753 if(isnan(p[j])) {fprintf(fp, "\t."); continue;}
754 switch(partype[j]) {
755 case 0: fprintf(fp, "\t%.0f", p[j]); break;
756 case 1:
757 if(p[j]>=0) n=4; else n=3;
758 fprintf(fp, "\t%.*f", n, p[j]);
759 break;
760 default:
761 if(p[j]>=0) n=4; else n=3;
762 fprintf(fp, "\t%.*e", n, p[j]);
763 break;
764 }
765 }
766 fprintf(fp, "\n"); fflush(fp);
767 /* Write SD's, if they exist */
768 if(verbose>25) {printf(" sd?\n"); fflush(stdout);}
769 //if(res->voi[i].sd==NULL) {printf("NULL\n"); fflush(stdout);}
770 if(verbose>25) {printf(" parNr=%d\n", res->parNr); fflush(stdout);}
771 n=0; for(int j=0; j<res->parNr; j++) {if(!isnan(res->voi[i].sd[j])) n++;}
772 if(verbose>25) {printf(" n=%d\n", n); fflush(stdout);}
773 if(n>0) {
774 fprintf(fp, "SD . .");
775 for(j=0; j<res->parNr; j++) {
776 if(verbose>15) {printf(" writing sd %d\n", 1+j); fflush(stdout);}
777 if(!isnan(res->voi[i].sd[j])) {
778 switch(partype[j]) {
779 case 0: fprintf(fp, "\t%.0f", res->voi[i].sd[j]); break;
780 case 1:
781 if(res->voi[i].sd[j]>=0) n=4; else n=3;
782 fprintf(fp, "\t%.*f", n, res->voi[i].sd[j]);
783 break;
784 default:
785 if(res->voi[i].sd[j]>=0) n=4; else n=3;
786 fprintf(fp, "\t%.*e", n, res->voi[i].sd[j]);
787 break;
788 }
789 } else {
790 fprintf(fp, "\t.");
791 }
792 }
793 fprintf(fp, "\n"); fflush(fp);
794 }
795 /* Write lower confidence limits, if they exist */
796 if(verbose>25) {printf(" cl1?\n"); fflush(stdout);}
797 n=0; for(int j=0; j<res->parNr; j++) if(!isnan(res->voi[i].cl1[j])) n++;
798 if(verbose>25) {printf(" n=%d\n", n); fflush(stdout);}
799 if(n>0) {
800 fprintf(fp, "CL 95%% Lower");
801 for(j=0; j<res->parNr; j++) {
802 if(verbose>15) {printf(" writing CL1 %d\n", 1+j); fflush(stdout);}
803 if(!isnan(res->voi[i].cl1[j])) {
804 switch(partype[j]) {
805 case 0: fprintf(fp, "\t%.0f", res->voi[i].cl1[j]); break;
806 case 1:
807 if(res->voi[i].cl1[j]>=0) n=4; else n=3;
808 fprintf(fp, "\t%.*f", n, res->voi[i].cl1[j]);
809 break;
810 default:
811 if(res->voi[i].cl1[j]>=0) n=4; else n=3;
812 fprintf(fp, "\t%.*e", n, res->voi[i].cl1[j]);
813 break;
814 }
815 } else {
816 fprintf(fp, "\t.");
817 }
818 }
819 fprintf(fp, "\n");
820 }
821 /* Write upper confidence limits, if they exist */
822 if(verbose>25) {printf(" cl2?\n"); fflush(stdout);}
823 n=0; for(int j=0; j<res->parNr; j++) if(!isnan(res->voi[i].cl2[j])) n++;
824 if(verbose>25) {printf(" n=%d\n", n); fflush(stdout);}
825 if(n>0) {
826 fprintf(fp, "CL 95%% Upper");
827 for(j=0; j<res->parNr; j++) {
828 if(verbose>15) {printf(" writing CL2 %d\n", 1+j); fflush(stdout);}
829 if(!isnan(res->voi[i].cl2[j])) {
830 switch(partype[j]) {
831 case 0: fprintf(fp, "\t%.0f", res->voi[i].cl2[j]); break;
832 case 1:
833 if(res->voi[i].cl2[j]>=0) n=4; else n=3;
834 fprintf(fp, "\t%.*f", n, res->voi[i].cl2[j]);
835 break;
836 default:
837 if(res->voi[i].cl2[j]>=0) n=4; else n=3;
838 fprintf(fp, "\t%.*e", n, res->voi[i].cl2[j]);
839 break;
840 }
841 } else {
842 fprintf(fp, "\t.");
843 }
844 }
845 fprintf(fp, "\n"); fflush(fp);
846 }
847 } /* next region */
848
849 /* Close file */
850 if(!is_stdout) {fflush(fp); fclose(fp);}
851 strcpy(reserrmsg, "");
852 if(verbose>1) {printf("resWrite() done.\n"); fflush(stdout);}
853
854 return(0);
855}
int backupExistingFile(char *filename, char *backup_ext, char *status)
Definition backup.c:14
char * ctime_r_int(const time_t *t, char *buf)
Convert calendard time t into a null-terminated string of the form YYYY-MM-DD hh:mm:ss,...
Definition datetime.c:110
int resParameterPrintType(RES *res, int parIndex)
Definition result.c:1447
int resWriteHTML(RES *res, char *fname, int verbose)
Definition result.c:865

Referenced by resPrint().

◆ resWriteHTML()

int resWriteHTML ( RES * res,
char * fname,
int verbose )

Write calculation results into specied XHTML 1.1 file. If file exists, a backup file (+BACKUP_EXTENSION) is written also. If "stdout" is given as filename, output is directed to stdout.

Returns
In case of an error, >0 is returned, and a description is written in reserrmsg.
See also
resWrite
Parameters
resPointer to result data
fnameOutput file name
verboseVerbose level; if <=0, then nothing is printed into stdout

Definition at line 865 of file result.c.

872 {
873 int n, is_stdout=0;
874 char tmp[1024];
875 FILE *fp;
876
877
878 if(verbose>0) printf("resWriteHTML(*res, %s, %d)\n", fname, verbose);
879 /* Check that there is some data to write */
880 if(res==NULL) {strcpy(reserrmsg, "error in result data"); return(1);}
881 if(res->voiNr<1) {strcpy(reserrmsg, "no result data"); return(1);}
882 /* Check if writing to stdout */
883 if(!strcasecmp(fname, "stdout")) is_stdout=1;
884
885 resFixParnames(res);
886
887 /* Check if file exists; backup, if necessary */
888 if(!is_stdout && access(fname, 0) != -1) {
889 strcpy(tmp, fname); strcat(tmp, BACKUP_EXTENSION);
890 if(access(tmp, 0)!=-1) remove(tmp);
891 rename(fname, tmp);
892 }
893 strcpy(reserrmsg, "cannot write file");
894
895 /* Open output file */
896 if(is_stdout) fp=(FILE*)stdout;
897 else if((fp=fopen(fname, "w"))==NULL) {
898 strcpy(reserrmsg, "cannot open file"); return(2);}
899
900 /* Write XHTML 1.1 doctype and head */
902 strcpy(reserrmsg, "disk full");
903 if(!is_stdout) fclose(fp);
904 return(3);
905 }
906
907 /* Start writing the body of the HTML file */
908 fprintf(fp, "\n<body>\n");
909
910 /* Start the div for tables */
911 fprintf(fp, "\n<div id=\"tables\">\n");
912
913 /* Write results into a table */
914 if(resWriteHTML_table(res, fp)!=0) {
915 strcpy(reserrmsg, "disk full");
916 if(!is_stdout) fclose(fp);
917 return(3);
918 }
919
920 /* Stop writing the body of the HTML file, and end the file */
921 fprintf(fp, "</div>\n");
922 n=fprintf(fp, "</body></html>\n\n");
923 if(n==0) {
924 strcpy(reserrmsg, "disk full");
925 if(!is_stdout) fclose(fp);
926 return(3);
927 }
928
929 /* Close file */
930 if(!is_stdout) {fflush(fp); fclose(fp);}
931 strcpy(reserrmsg, "");
932
933 return(0);
934}
#define BACKUP_EXTENSION
int resWriteXHTML11_head(FILE *fp, char *author_name)
Definition result.c:960
int resWriteXHTML11_doctype(FILE *fp)
Definition result.c:941
int resWriteHTML_table(RES *res, FILE *fp)
Definition result.c:1013

Referenced by resWrite().

◆ resWriteHTML_table()

int resWriteHTML_table ( RES * res,
FILE * fp )

Write calculation results as one HTML table into an opened (X)HTML file.

Returns
Returns 0 if successful, non-zero in case of a failure.
Parameters
resPointer to result data.
fpOutput file pointer.

Definition at line 1013 of file result.c.

1018 {
1019 int i, j, n;
1020 char *cptr, tmp[1024];
1021 int partype[MAX_RESPARAMS]; /* 0=int, 1=double, 2=exp */
1022 double *p;
1023
1024 if(RESULT_TEST>0) printf("resWriteHTML_table(*res, fp)\n");
1025 if(fp==NULL || res==NULL) return(1);
1026
1027 /* Write the title lines to the head of table */
1028 fprintf(fp, "<table>\n");
1029 fprintf(fp, "<thead>\n");
1030 /* Program name */
1031 strcpy(tmp, res->program);
1032 cptr=strcasestr(tmp, "(c)");
1033 if(cptr!=NULL) {
1034 *cptr=(char)0;
1035 i=strlen(tmp)-1; while(i>0 && isspace(tmp[i])) i--; tmp[i+1]=(char)0;
1036 }
1037 if(tmp[0])
1038 fprintf(fp, "<tr align=left><th>Program:</th><td>%s</td></tr>\n", tmp);
1039 /* Write calculation date and time */
1040 if(!ctime_r_int(&res->time, tmp)) strcpy(tmp, "1900-01-01 00:00:00");
1041 fprintf(fp, "<tr align=left><th>Date:</th><td>%s</td></tr>\n", tmp);
1042 /* Write the studynr */
1043 if(res->studynr[0])
1044 fprintf(fp, "<tr align=left><th>Study:</th><td>%s</td></tr>\n", res->studynr);
1045 /* Write the names of the original datafiles */
1046 if(res->datafile[0])
1047 fprintf(fp, "<tr align=left><th>Data file:</th><td>%s</td></tr>\n", res->datafile);
1048 if(res->plasmafile[0])
1049 fprintf(fp, "<tr align=left><th>Plasma file:</th><td>%s</td></tr>\n", res->plasmafile);
1050 if(res->plasmafile2[0])
1051 fprintf(fp, "<tr align=left><th>2nd Plasma file:</th><td>%s</td></tr>\n", res->plasmafile2);
1052 if(res->bloodfile[0])
1053 fprintf(fp, "<tr align=left><th>Blood file:</th><td>%s</td></tr>\n", res->bloodfile);
1054 if(res->reffile[0])
1055 fprintf(fp, "<tr align=left><th>Reference file:</th><td>%s</td></tr>\n", res->reffile);
1056 if(res->refroi[0])
1057 fprintf(fp, "<tr align=left><th>Reference region:</th><td>%s</td></tr>\n", res->refroi);
1058 /* Write data range etc */
1059 if(res->datarange[0])
1060 fprintf(fp, "<tr align=left><th>Data range:</th><td>%s</td></tr>\n", res->datarange);
1061 if(res->datanr>0)
1062 fprintf(fp, "<tr align=left><th>Data nr:</th><td>%d</td></tr>\n", res->datanr);
1063 if(res->fitmethod[0])
1064 fprintf(fp, "<tr align=left><th>Fit method:</th><td>%s</td></tr>\n", res->fitmethod);
1065 /* Write constants */
1066 if(res->density>0.0)
1067 fprintf(fp, "<tr align=left><th>Tissue density:</th><td>%g</td></tr>\n", res->density);
1068 if(res->lc>0.0)
1069 fprintf(fp, "<tr align=left><th>Lumped constant:</th><td>%g</td></tr>\n", res->lc);
1070 if(res->concentration>0.0)
1071 fprintf(fp, "<tr align=left><th>Concentration:</th><td>%g</td></tr>\n", res->concentration);
1072 if(res->beta>0.0)
1073 fprintf(fp, "<tr align=left><th>Beta:</th><td>%g</td></tr>\n", res->beta);
1074 if(res->Vb>=0.0)
1075 fprintf(fp, "<tr align=left><th>Vb:</th><td>%g %%</td></tr>\n", res->Vb);
1076 if(res->fA>=0.0)
1077 fprintf(fp, "<tr align=left><th>fA:</th><td>%g %%</td></tr>\n", res->fA);
1078 if(res->E>0.0)
1079 fprintf(fp, "<tr align=left><th>Extraction:</th><td>%g</td></tr>\n", res->E);
1080 /* Weighting */
1081 if(res->isweight>0) strcpy(tmp, "yes");
1082 else if(res->isweight==0) strcpy(tmp, "no");
1083 else strcpy(tmp, "unknown");
1084 fprintf(fp, "<tr align=left><th>Weighting:</th><td>%s</td></tr>\n", tmp);
1085 /* End the head of table */
1086 fprintf(fp, "</thead>\n");
1087
1088 /* Collect info on column types */
1089 for(j=0; j<res->parNr; j++) {
1090 /* should column be printed as integers, floats or exponentials? */
1091 partype[j]=resParameterPrintType(res, j);
1092 }
1093
1094 /* Write the result data to the table body */
1095 fprintf(fp, "<tbody>\n");
1096 /* Write the result title line */
1097 fprintf(fp,"<tr align=left><th>Region</th>\n");
1098 for(i=0; i<res->parNr; i++) fprintf(fp, "<th>%s</th>", res->parname[i]);
1099 fprintf(fp, "</tr>\n");
1100 /* Write regional results */
1101 for(i=0; i<res->voiNr; i++) {
1102 if(i%2) strcpy(tmp, "evenroi"); else strcpy(tmp, "oddroi");
1103 fprintf(fp, "<tr class=\"%s\">", tmp);
1104 char *senc=strEncodeForXML(res->voi[i].name);
1105 if(senc==NULL) fprintf(fp, "<th>%s</th>", res->voi[i].name);
1106 else {fprintf(fp, "<th>%s</th>", senc); free(senc);}
1107 p=res->voi[i].parameter;
1108 for(j=0; j<res->parNr; j++) switch(partype[j]) {
1109 case 0: fprintf(fp, "<td>%.0f</td>", p[j]); break;
1110 case 1: fprintf(fp, "<td>%.4f</td>", p[j]); break;
1111 default: fprintf(fp, "<td>%.4E</td>", p[j]); break;
1112 }
1113 fprintf(fp, "</tr>\n");
1114 /* Write SD's, if they exist */
1115 p=res->voi[i].sd; for(j=n=0; j<res->parNr; j++) if(!isnan(p[j])) n++;
1116 if(n>0) {
1117 fprintf(fp, "<tr class=\"sd\">");
1118 fprintf(fp, "<th>%s</th>", "SD");
1119 for(j=0; j<res->parNr; j++) {
1120 if(!isnan(p[j])) switch(partype[j]) {
1121 case 0: fprintf(fp, "<td>%.0f</td>", p[j]); break;
1122 case 1: fprintf(fp, "<td>%.4f</td>", p[j]); break;
1123 default: fprintf(fp, "<td>%.4E</td>", p[j]); break;
1124 } else fprintf(fp, "<td></td>");
1125 }
1126 fprintf(fp, "</tr>\n");
1127 }
1128 /* Write lower confidence limits, if they exist */
1129 p=res->voi[i].cl1; for(j=n=0; j<res->parNr; j++) if(!isnan(p[j])) n++;
1130 if(n>0) {
1131 fprintf(fp, "<tr class=\"cl1\">");
1132 fprintf(fp, "<th>CL95%%L</th>");
1133 for(j=0; j<res->parNr; j++) {
1134 if(!isnan(p[j])) switch(partype[j]) {
1135 case 0: fprintf(fp, "<td>%.0f</td>", p[j]); break;
1136 case 1: fprintf(fp, "<td>%.4f</td>", p[j]); break;
1137 default: fprintf(fp, "<td>%.4E</td>", p[j]); break;
1138 } else fprintf(fp, "<td></td>");
1139 }
1140 fprintf(fp, "</tr>\n");
1141 }
1142 /* Write upper confidence limits, if they exist */
1143 p=res->voi[i].cl2; for(j=n=0; j<res->parNr; j++) if(!isnan(p[j])) n++;
1144 if(n>0) {
1145 fprintf(fp, "<tr class=\"cl2\">");
1146 fprintf(fp, "<th>CL95%%U</th>");
1147 for(j=0; j<res->parNr; j++) {
1148 if(!isnan(p[j])) switch(partype[j]) {
1149 case 0: fprintf(fp, "<td>%.0f</td>", p[j]); break;
1150 case 1: fprintf(fp, "<td>%.4f</td>", p[j]); break;
1151 default: fprintf(fp, "<td>%.4E</td>", p[j]); break;
1152 } else fprintf(fp, "<td></td>");
1153 }
1154 fprintf(fp, "</tr>\n");
1155 }
1156 }
1157 /* End the body of the table and table */
1158 fprintf(fp, "</tbody></table>\n");
1159
1160 return(0);
1161}
char * strEncodeForXML(const char *s)
Definition strext.c:364
char * strcasestr(const char *haystack, const char *needle)
Definition strext.c:279

Referenced by resWriteHTML().

◆ resWriteXHTML11_doctype()

int resWriteXHTML11_doctype ( FILE * fp)

Write XHTML 1.1 doctype into an opened file pointer.

Returns
Returns 0 if successful, non-zero in case of a failure.
Parameters
fpOutput file pointer.

Definition at line 941 of file result.c.

944 {
945 int n;
946 if(fp==NULL) return(1);
947 n=fprintf(fp, "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" ");
948 n+=fprintf(fp, "\"https://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n");
949 if(n<20) return(2);
950 n=fprintf(fp,"<html xmlns=\"https://www.w3.org/1999/xhtml\" xml:lang=\"en\">\n\n");
951 if(n<20) return(2);
952 return(0);
953}

Referenced by resWriteHTML().

◆ resWriteXHTML11_head()

int resWriteXHTML11_head ( FILE * fp,
char * author_name )

Write XHTML 1.1 head for PET results file into an opened file pointer.

Returns
Returns 0 if successful, non-zero in case of a failure.
Parameters
fpFile pointer where to write.
author_nameAuthor name, for example software name.

Definition at line 960 of file result.c.

965 {
966 int n;
967 if(fp==NULL) return(1);
968
969 n=fprintf(fp, "<head>\n"); if(n<6) return(2);
970 fprintf(fp, " <title>Tabulated PET results</title>\n");
971 fprintf(fp, " <meta http-equiv=\"content-type\" content=\"text/html; charset=iso-8859-1\" />\n");
972 fprintf(fp, " <meta http-equiv=\"content-language\" content=\"en-gb\" />\n");
973 fprintf(fp, " <meta name=\"description\" content=\"Regional PET results\" />\n");
974 fprintf(fp, " <meta name=\"author\" content=\"%s\" />\n", author_name);
975 fprintf(fp, " <meta name=\"ProgId\" content=\"Excel.Sheet\" />\n");
976 fprintf(fp, " <link rel=\"icon\" href=\"https://www.turkupetcentre.net/favicon.ico\" type=\"image/x-icon\" />\n");
977 fprintf(fp, " <link rel=\"shortcut icon\" href=\"https://www.turkupetcentre.net/favicon.ico\" type=\"image/x-icon\" />\n");
978 /* write local CSS with basic settings in case external CSS is not available */
979 fprintf(fp, " <style type=\"text/css\">\n");
980 fprintf(fp, " thead {background-color:#999999; color:black;}\n");
981//fprintf(fp, " table {text-align:left; width:100%%; border-collapse:colla");
982 fprintf(fp, " table {text-align:left; border-collapse:collapse; empty-cells:show;}\n");
983//fprintf(fp, " td {border:1px solid black;}\n");
984 fprintf(fp, " .oddroi {background-color:#FFFFFF; color:black;}\n");
985 fprintf(fp, " .evenroi {background-color:#CCCCCC; color:black;}\n");
986 fprintf(fp, " .sd {background-color:#999999; color:blue;}\n");
987 fprintf(fp, " .cl1 {background-color:#999999; color:green;}\n");
988 fprintf(fp, " .cl2 {background-color:#999999; color:green;}\n");
989 fprintf(fp, " .oddstudy {background-color:#FFFFFF; color:black;}\n");
990 fprintf(fp, " .evenstudy {background-color:#CCCCCC; color:black;}\n");
991 fprintf(fp, " .oddsum {background-color:#999999; color:black;}\n");
992 fprintf(fp, " .evensum {background-color:#CCCCCC; color:black;}\n");
993 fprintf(fp, " #regcontainer ul {margin-left:0; padding-left:0;}\n");
994 fprintf(fp, " #regcontainer ul li {display:inline; list-style-type:none;}\n");
995 fprintf(fp, " #regcontainer a {padding:2px 4px;}\n");
996 fprintf(fp, " <!--table\n");
997 fprintf(fp, " {mso-displayed-decimal-separator:\"\\.\";\n");
998 fprintf(fp, " mso-displayed-thousand-separator:\" \";}\n");
999 fprintf(fp, " -->\n");
1000 fprintf(fp, " </style>\n");
1001 /* load external CSS with more fancy settings */
1002 fprintf(fp, " <link rel=\"stylesheet\" type=\"text/css\" href=\"https://www.turkupetcentre.net/result.css\" />\n");
1003 fprintf(fp, "</head>\n");
1004 if(n<7) return(2);
1005 return(0);
1006}

Referenced by resWriteHTML().

Variable Documentation

◆ reserrmsg

char reserrmsg[64]

Error message from RES functions

Definition at line 6 of file result.c.

Referenced by resRead(), resWrite(), and resWriteHTML().

◆ RESULT_TEST

int RESULT_TEST

Verbose prints from RES functions

Definition at line 5 of file result.c.

Referenced by resFixParnames(), resMatchParameternames(), resMatchParameters(), resMatchParametersAbs(), resMatchRegions(), and resWriteHTML_table().