9#include "tpcclibConfig.h"
25static char *info[] = {
26 "Calculate average TTAC(s) from several PET TTAC files with equal sample",
27 "(frame) times and regions. Each region is processed separately.",
28 "TTACs are not scaled in this process, therefore user must scale the data",
29 "to for example SUV or %ID before using this program.",
31 "Usage: @P [Options] meanfile tacfiles",
35 " Regional standard deviations are written into given datafile.",
37 " Program does not mind if the time or calibration units do not match",
38 " or files contain variable number of TACs."
41 "If only one input datafile is given, it is assumed to contain a list of",
42 "bolus datafiles with paths if necessary. Tabs, commas and newlines can be",
43 "used to separate filenames in the list file.",
46 " avgttac meansuv.dft *suv.dft",
48 " dir /b *suv.dft > filelist.txt",
49 " avgttac meansuv.dft filelist.txt",
51 "See also: avgbolus, avgfract, dftavg, dftsuv, tacsort, taccut, tacren",
53 "Keywords: TAC, average, modelling, simulation",
72int main(
int argc,
char **argv)
74 int ai, help=0, version=0, verbose=1;
75 char *cptr, outfile[FILENAME_MAX], sdfile[FILENAME_MAX];
84 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
85 outfile[0]=sdfile[0]=(char)0;
88 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
90 cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(!*cptr)
continue;
91 if(strncasecmp(cptr,
"SD=", 3)==0) {
92 if(
strlcpy(sdfile, cptr+3, FILENAME_MAX)>0)
continue;
93 }
else if(strncasecmp(cptr,
"FORCE", 1)==0) {
94 forceMode=1;
continue;
96 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
105 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
111 if(ai<argc) {
strlcpy(outfile, argv[ai], FILENAME_MAX); ai++;}
113 fprintf(stderr,
"Error: missing command-line argument; use option --help\n");
118 if(verbose>1) printf(
"reading filename list in %s\n", argv[ai]);
120 fp=fopen(argv[ai],
"r");
if(fp==NULL) {
121 fprintf(stderr,
"Error: cannot open file %s\n", argv[ai]);
return(1);}
122 ret=
csvRead(&csv, fp, &status); fclose(fp);
124 fprintf(stderr,
"Error: %s\n",
errorMsg(status.
error));
return(1);}
126 if(verbose>1) printf(
"filenames listed as arguments\n");
132 printf(
"outfile := %s\n", outfile);
133 if(sdfile[0]) printf(
"sdfile := %s\n", sdfile);
134 printf(
"forceMode := %d\n", forceMode);
135 printf(
"files:\n");
csvWrite(&csv, 0, stdout, NULL);
140 for(
int i=0; i<csv.
nr; i++) {
141 if(access(csv.
c[i].
content, 0) == -1) {
142 fprintf(stderr,
"Error: file '%s' is not accessible.\n", csv.
c[i].
content);
147 if(verbose>1) printf(
"fileNr := %d\n", fileNr);
149 fprintf(stderr,
"Error: too few TAC files for averaging.\n");
160 taclist=(
TAC*)malloc(fileNr*
sizeof(
TAC));
162 fprintf(stderr,
"Error: out of memory.\n");
166 for(
int i=0; i<fileNr; i++)
tacInit(taclist+i);
168 for(
int i=0; i<fileNr; i++) {
169 if(verbose>1) printf(
"reading %s\n", csv.
c[i].
content);
172 for(
int j=0; j<i; j++)
tacFree(taclist+j);
173 csvFree(&csv); free(taclist);
return(3);
176 printf(
"fileformat := %s\n",
tacFormattxt(taclist[i].format));
177 printf(
"tacNr := %d\n", taclist[i].tacNr);
178 printf(
"sampleNr := %d\n", taclist[i].sampleNr);
182 fprintf(stderr,
"Warning: missing sample(s) in %s\n", csv.
c[i].
content);
186 if(verbose>1) printf(
"checking data...\n");
194 for(
int i=1; i<fileNr; i++) {
195 if(taclist[i].tacNr!=tacNr) {
196 m++;
if(taclist[i].tacNr<tacNr) tacNr=taclist[i].
tacNr;
198 if(taclist[i].sampleNr!=sampleNr) {
199 n++;
if(taclist[i].sampleNr<sampleNr) sampleNr=taclist[i].
sampleNr;
202 if(!forceMode && (n>0 || m>0)) {
203 if(n>0) fprintf(stderr,
"Error: different nr of samples.\n");
204 if(m>0) fprintf(stderr,
"Error: different nr of regions.\n");
205 for(
int i=0; i<fileNr; i++)
tacFree(taclist+i);
206 csvFree(&csv); free(taclist);
return(3);
208 if(n>0) fprintf(stderr,
"Warning: different nr of samples.\n");
209 if(m>0) fprintf(stderr,
"Warning: different nr of regions.\n");
212 printf(
"commonSampleNr := %d\n", sampleNr);
213 printf(
"commonTacNr := %d\n", tacNr);
217 for(
int i=1; i<fileNr; i++) {
227 fprintf(stderr,
"Error: TAC units do match.\n");
228 for(
int i=0; i<fileNr; i++)
tacFree(taclist+i);
229 csvFree(&csv); free(taclist);
return(4);
235 if(!forceMode && tacNr>1) {
236 for(
int i=1; i<fileNr; i++) {
237 for(
int j=0; j<tacNr; j++) {
239 fprintf(stderr,
"Error: TAC names do match.\n");
240 for(
int i=0; i<fileNr; i++)
tacFree(taclist+i);
241 csvFree(&csv); free(taclist);
return(5);
252 if(verbose>1) printf(
"calculating mean...\n");
257 fprintf(stderr,
"Error: cannot allocate memory for mean TACs.\n");
258 for(
int i=0; i<fileNr; i++)
tacFree(taclist+i);
259 csvFree(&csv); free(taclist);
return(6);
264 fprintf(stderr,
"Error: cannot copy TAC header.\n");
265 for(
int i=0; i<fileNr; i++)
tacFree(taclist+i);
270 for(
int i=0; i<tacNr; i++)
tacCopyTacchdr(taclist[0].c+i, tacmean.
c+i);
272 ret=
tacXCopy(taclist, &tacmean, 0, sampleNr-1);
274 fprintf(stderr,
"Error: cannot copy sample times.\n");
275 for(
int i=0; i<fileNr; i++)
tacFree(taclist+i);
281 fprintf(stderr,
"Error: cannot allocate memory for SD data.\n");
282 for(
int i=0; i<fileNr; i++)
tacFree(taclist+i);
288 for(
int i=0; i<tacNr; i++) {
289 double tempd[fileNr], mean, sd;
290 for(
int j=0; j<sampleNr; j++) {
291 for(
int k=0; k<fileNr; k++) tempd[k]=taclist[k].c[i].y[j];
293 tacmean.
c[i].
y[j]=mean;
294 if(sdfile[0]) tacsd.
c[i].
y[j]=sd;
297 for(
int k=0; k<fileNr; k++) tempd[k]=taclist[k].c[i].size;
299 tacmean.
c[i].
size=mean;
300 if(sdfile[0]) tacsd.
c[i].
size=sd;
303 for(
int i=0; i<fileNr; i++)
tacFree(taclist+i);
311 if(verbose>1) printf(
"writing %s\n", outfile);
312 FILE *fp; fp=fopen(outfile,
"w");
314 fprintf(stderr,
"Error: cannot open file for writing.\n");
321 fprintf(stderr,
"Error (%d): %s\n", ret,
errorMsg(status.
error));
324 if(verbose>0) printf(
"Mean TAC(s) written in %s\n", outfile);
326 if(verbose>1) printf(
"writing %s\n", sdfile);
327 FILE *fp; fp=fopen(sdfile,
"w");
329 fprintf(stderr,
"Error: cannot open file for writing.\n");
336 fprintf(stderr,
"Error (%d): %s\n", ret,
errorMsg(status.
error));
339 if(verbose>0) printf(
"TAC SDs written in %s\n", sdfile);
int csvPutString(CSV *csv, const char *s, int newline)
int csvRead(CSV *csv, FILE *fp, TPCSTATUS *status)
int csvWrite(CSV *csv, int regular, FILE *fp, TPCSTATUS *status)
int statMeanSD(double *data, unsigned int n, double *mean, double *sd, unsigned int *vn)
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
int tpcHtmlUsage(const char *program, char *text[], const char *path)
void tpcPrintBuild(const char *program, FILE *fp)
void tpcPrintUsage(const char *program, char *text[], FILE *fp)
void statusInit(TPCSTATUS *s)
char * errorMsg(tpcerror e)
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
size_t strlcpy(char *dst, const char *src, size_t dstsize)
IFT h
Optional (but often useful) header information.
int verbose
Verbose level, used by statusPrint() etc.
tpcerror error
Error code.
int tacDuplicate(TAC *tac1, TAC *tac2)
Make a duplicate of TAC structure.
int tacAllocate(TAC *tac, int sampleNr, int tacNr)
int tacCopyTacchdr(TACC *d1, TACC *d2)
int tacCopyHdr(TAC *tac1, TAC *tac2)
Copy TAC header data from tac1 to tac2.
int tacCompareNames(TAC *d1, TAC *d2, const int i, TPCSTATUS *status)
int tacSetHeaderStudynr(IFT *h, const char *s)
int tacRead(TAC *d, const char *fname, TPCSTATUS *status)
char * tacFormattxt(tacformat c)
int tacWrite(TAC *tac, FILE *fp, tacformat format, int extra, TPCSTATUS *status)
int tacYUnitConvert(TAC *tac, const int u, TPCSTATUS *status)
int tacXUnitConvert(TAC *tac, const int u, TPCSTATUS *status)
int tacXCopy(TAC *tac1, TAC *tac2, int i1, int i2)
Header file for library libtpccsv.
Header file for library libtpcextensions.
@ WEIGHTING_OFF
Not weighted or weights not available (weights for all included samples are 1.0).
@ TPCERROR_UNKNOWN_UNIT
Unknown data unit.
Header file for library libtpcift.
Header file for libtpcstatist.
Header file for library libtpctac.
@ TAC_FORMAT_UNKNOWN
Unknown format.