10#include "tpcclibConfig.h"
24static char *info[] = {
25 "Calculate average TAC of all regional TACs in the TTAC file.",
26 "Weighted average TAC can be used as a 'head curve' in time delay correction,",
27 "if reliable count-rate data is not available.",
28 "Optionally, the same file name can be given to TTAC file and avg file to",
29 "add the mean TAC into the original data file.",
31 "Usage: @P [options] ttacfile [avgfile]",
35 " TACs are weighted by the VOI sizes, if available in the TTAC file.",
37 " TACs are weighted by values given in parameter file.",
38 " If any TAC is not found in parameter file or value is invalid, zero",
39 " weight is applied to that TAC.",
40 " Parameter named as 'weight' or 'w' is used if available; if not then",
41 " the first parameter is used.",
43 " SD curve is calculated and saved; weights are not applied.",
45 " CV curve is calculated and saved; weights are not applied.",
48 "See also: taclist, tacadd, imghead, dftavg, avgttac, tacren, parmean",
50 "Keywords: TAC, average, standard deviation, noise, head-curve",
69int main(
int argc,
char **argv)
71 int ai, help=0, version=0, verbose=1;
72 char *cptr, tacfile[FILENAME_MAX], avgfile[FILENAME_MAX],
73 cvfile[FILENAME_MAX], sdfile[FILENAME_MAX],
82 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
83 avgfile[0]=cvfile[0]=sdfile[0]=wfile[0]=(char)0;
85 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
87 cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(!*cptr)
continue;
88 if(strncasecmp(cptr,
"SD=", 3)==0) {
89 if(
strlcpy(sdfile, cptr+3, FILENAME_MAX)>0)
continue;
90 }
else if(strncasecmp(cptr,
"CV=", 3)==0) {
91 if(
strlcpy(cvfile, cptr+3, FILENAME_MAX)>0)
continue;
92 }
else if(strncasecmp(cptr,
"WF=", 3)==0) {
93 if(
strlcpy(wfile, cptr+3, FILENAME_MAX)>0 && weightMode==0) {weightMode=2;
continue;}
94 }
else if(strcasecmp(cptr,
"WS")==0) {
95 if(weightMode==0) {weightMode=1;
continue;}
97 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
106 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
111 if(ai<argc) {
strlcpy(tacfile, argv[ai], FILENAME_MAX); ai++;}
112 if(ai<argc) {
strlcpy(avgfile, argv[ai], FILENAME_MAX); ai++;}
114 fprintf(stderr,
"Error: too many arguments: '%s'.\n", argv[ai]);
120 fprintf(stderr,
"Error: missing TTAC filename.\n");
123 if(!avgfile[0] && !sdfile[0] && !cvfile[0]) {
124 fprintf(stderr,
"Error: missing output filename.\n");
128 if(weightMode!=0 && (sdfile[0] || cvfile[0])) {
129 fprintf(stderr,
"Error: SD and CV cannot be computed with TAC weighting.\n");
135 printf(
"tacfile := %s\n", tacfile);
136 if(avgfile[0]) printf(
"avgfile := %s\n", avgfile);
137 if(sdfile[0]) printf(
"sdfile := %s\n", sdfile);
138 if(cvfile[0]) printf(
"cvfile := %s\n", cvfile);
139 if(wfile[0]) printf(
"wfile := %s\n", wfile);
140 printf(
"weightMode := %d\n", weightMode);
148 if(verbose>1) printf(
"reading %s\n", tacfile);
150 ret=
tacRead(&tac, tacfile, &status);
152 fprintf(stderr,
"Error (%d): %s\n", ret,
errorMsg(status.
error));
158 printf(
"tacNr := %d\n", tac.
tacNr);
159 printf(
"sampleNr := %d\n", tac.
sampleNr);
160 printf(
"isSize := %d\n", isSize);
163 if(weightMode==1 && isSize==0) {
164 fprintf(stderr,
"Error: data does not contain ROI sizes.\n");
173 if(verbose>1) printf(
"reading %s\n", wfile);
175 ret=
parRead(&par, wfile, &status);
181 printf(
"file contents:\n");
183 }
else if(verbose>2) {
185 printf(
"parNr := %d\n", par.
parNr);
186 printf(
"tacNr := %d\n", par.
tacNr);
191 for(
int i=0; i<par.
parNr; i++)
192 if(strcasecmp(par.
n[i].
name,
"W")==0) {wp=i;
break;}
193 for(
int i=0; i<par.
parNr; i++)
194 if(strncasecmp(par.
n[i].
name,
"WEIGHTS", 6)==0) {wp=i;
break;}
195 if(verbose>0) printf(
"Parameter '%s' used as weight.\n", par.
n[wp].
name);
198 for(
int j=0; j<par.
tacNr; j++) par.
r[j].
sw=0;
200 for(
int i=0; i<tac.
tacNr; i++) {
202 for(
int j=0; j<par.
tacNr; j++)
if(par.
r[j].
sw==0) {
204 if(par.
r[j].
p[wp]>=0.0) tac.
c[i].
size=par.
r[j].
p[wp];
213 fprintf(stderr,
"Error: no weights found for TACs.\n");
218 for(
int i=0; i<tac.
tacNr; i++) wsum+=tac.
c[i].
size;
219 if(!(wsum>1.0E-10)) {
220 fprintf(stderr,
"Error: invalid weights.\n");
223 if(verbose>1) printf(
"TAC weights:\n");
224 for(
int i=0; i<tac.
tacNr; i++) {
226 if(verbose>1) printf(
"\t%s\t%1.3f\n", tac.
c[i].
name, tac.
c[i].
size);
234 if(verbose>1) printf(
"calculating means...\n");
239 fprintf(stderr,
"Error: cannot allocate memory for means.\n");
245 fprintf(stderr,
"Error: cannot copy TAC header.\n");
252 fprintf(stderr,
"Error: cannot copy sample times.\n");
256 strcpy(mtac.
c[0].
name,
"Mean");
257 strcpy(mtac.
c[1].
name,
"SD");
258 strcpy(mtac.
c[2].
name,
"CV");
266 for(
int i=0; i<tac.
tacNr; i++)
267 if(!isnan(tac.
c[i].
y[j])) {
273 fprintf(stderr,
"Warning: no valid samples in frame %d.\n", 1+j);
274 mtac.
c[0].
y[j]=mtac.
c[1].
y[j]=mtac.
c[2].
y[j]=nan(
"");
277 mtac.
c[0].
y[j]=sum/(double)m;
279 if(sdfile[0] || cvfile[0]) {
281 mtac.
c[1].
y[j]=mtac.
c[2].
y[j]=0.0;
283 double sumsqr=0.0, sqrsum;
284 for(
int i=0; i<tac.
tacNr; i++)
285 if(!isnan(tac.
c[i].
y[j]))
286 sumsqr+=tac.
c[i].
y[j]*tac.
c[i].
y[j];
288 mtac.
c[1].
y[j]=sqrt( (sumsqr - sqrsum/(
double)m) / (
double)(m-1) );
289 if(fabs(mtac.
c[0].
y[j])<1.0E-30) mtac.
c[2].
y[j]=nan(
"");
290 else mtac.
c[2].
y[j]=mtac.
c[1].
y[j]/fabs(mtac.
c[0].
y[j]);
296 fprintf(stderr,
"Error: file contains no valid data.\n");
302 if(avgfile[0] && weightMode==0) {
305 if(strcasecmp(tacfile, avgfile)!=0) {
306 if(verbose>1) printf(
"writing %s\n", avgfile);
309 strcpy(avgfile, tacfile);
310 if(verbose>1) printf(
"adding mean to %s\n", avgfile);
314 fprintf(stderr,
"Error: cannot add mean TAC.\n");
320 FILE *fp; fp=fopen(avgfile,
"w");
322 fprintf(stderr,
"Error: cannot open file for writing.\n");
337 if(verbose>1) printf(
"writing %s\n", sdfile);
338 FILE *fp; fp=fopen(sdfile,
"w");
340 fprintf(stderr,
"Error: cannot open file for writing.\n");
355 if(verbose>1) printf(
"writing %s\n", cvfile);
356 FILE *fp; fp=fopen(cvfile,
"w");
358 fprintf(stderr,
"Error: cannot open file for writing.\n");
363 fclose(fp); mtac.
cunit=cunit;
372 if(weightMode==0 || !avgfile[0]) {
382 double sum=0.0, wsum=0.0;
383 for(
int i=0; i<tac.
tacNr; i++)
384 if(!isnan(tac.
c[i].
y[j]) && !isnan(tac.
c[i].
size)) {
385 sum+=tac.
c[i].
size*tac.
c[i].
y[j];
389 fprintf(stderr,
"Error: data does not contain valid weights.\n");
393 mtac.
c[0].
y[j]=sum/wsum;
400 if(strcasecmp(tacfile, avgfile)!=0) {
401 if(verbose>1) printf(
"writing %s\n", avgfile);
404 strcpy(avgfile, tacfile);
405 if(verbose>1) printf(
"adding mean to %s\n", avgfile);
409 fprintf(stderr,
"Error: cannot add mean TAC.\n");
415 FILE *fp; fp=fopen(avgfile,
"w");
417 fprintf(stderr,
"Error: cannot open file for writing.\n");
char * parFormattxt(parformat c)
int parWrite(PAR *par, FILE *fp, parformat format, int extra, TPCSTATUS *status)
int parRead(PAR *par, const char *fname, TPCSTATUS *status)
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)
int roinameMatch(const char *roiname, const char *test_str, TPCSTATUS *status)
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)
char name[MAX_PARNAME_LEN+1]
char name[MAX_TACNAME_LEN+1]
char name[MAX_TACNAME_LEN+1]
int verbose
Verbose level, used by statusPrint() etc.
tpcerror error
Error code.
int tacAllocate(TAC *tac, int sampleNr, int tacNr)
int tacAllocateMore(TAC *tac, int tacNr)
int tacCopyTacc(TACC *d1, TACC *d2, int sampleNr)
int tacCopyHdr(TAC *tac1, TAC *tac2)
Copy TAC header data from tac1 to tac2.
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 tacXCopy(TAC *tac1, TAC *tac2, int i1, int i2)
Header file for library libtpcextensions.
@ WEIGHTING_OFF
Not weighted or weights not available (weights for all included samples are 1.0).
Header file for library libtpcift.
Header file for libtpcpar.
@ PAR_FORMAT_CSV_UK
UK CSV.
Header file for library libtpctac.
@ TAC_FORMAT_UNKNOWN
Unknown format.