9#include "tpcclibConfig.h"
29static char *info[] = {
30 "Make a map of cerebral blood flow from dynamic radiowater PET image,.",
31 "correcting for the PVE (Iida et al., 2000).",
32 "Partition coefficients for grey and white matter, and blood flow in white",
35 "Currently only NIfTI format is supported.",
36 "Radioactivity concentrations in image and blood data must be in same units.",
37 "Map of CBF (aG*fG + aW*fW) is saved.",
39 "Usage: @P [options] imgfile btacfile cbfmap",
42 " -end=<Fit end time (sec)>",
43 " Use data from 0 to end time; by default, 300 s.",
45 " Pixels with AUC less than (threshold/100 x BTAC AUC) are set to zero.",
48 " Map of grey matter blood flow.",
50 " Map of grey matter alpha (PTF).",
52 " Map of white matter alpha (PTF).",
53 " -Va=<filename | 0>",
54 " Va map is saved in units mL blood/mL PET volume, or, Va is fixed to 0.",
55 " -dT=<filename | delay>",
56 " Time delay map is saved, or, delay is fixed to given time in sec.",
59 "See also: fit_wcbf, imgflow, imgdelay",
61 "Keywords: image, blood flow, radiowater, brain",
104 int verbose=0;
if(status!=NULL) verbose=status->
verbose;
105 if(verbose>2) {printf(
"%s(inp, tis, %g, %g, %g, ...)\n", __func__, dtmin, dtmax, dtstep); fflush(stdout);}
113 printf(
" %d BTAC ", btac->
sampleNr);
if(btac->
isframe) printf(
"frames\n");
else printf(
"samples\n");
114 printf(
" %d TTAC ", ttac->
sampleNr);
if(ttac->
isframe) printf(
"frames\n");
else printf(
"samples\n");
120 double brange[2], trange[2];
121 if(
tacXRange(ttac, &trange[0], &trange[1])!=0 ||
tacXRange(btac, &brange[0], &brange[1])!=0) {
126 printf(
" TTAC range := %g - %g\n BTAC range := %g - %g\n",
127 trange[0], trange[1], brange[0], brange[1]);
130 if(isfinite(dtstep) && dtstep>0.0) {
131 double r=dtmax-dtmin;
132 if(!(r>5.0*dtstep)) {
142 if((brange[1]+dtmin)<0.95*trange[1]) {
143 if(verbose>2) printf(
"BTAC tmax=%g TTAC tmax=%g dtmin=%g\n", brange[1], trange[1], dtmin);
150 if(b1==NULL && b2==NULL && b3==NULL) {
151 if(verbose>2) {printf(
" no output required\n"); fflush(stdout);}
160 if(verbose>3) {printf(
" integrating BTAC samples\n"); fflush(stdout);}
165 if(verbose>3) {printf(
" integrating BTAC frames\n"); fflush(stdout);}
170 if(verbose>2) {printf(
" -> returns %d\n", ret); fflush(stdout);}
176 if(verbose>3) {printf(
" room for output\n"); fflush(stdout);}
193 if(verbose>3) {printf(
" interpolating BTAC\n"); fflush(stdout);}
195 for(
int ci=0; ci<b1->
tacNr; ci++) {
196 double dt=0.0;
if(dtNr>1) dt=dtmin+dtstep*(double)ci;
198 for(
int ti=0; ti<btac->
sampleNr; ti++) dx[ti]=btac->
x[ti]+dt;
208 if(b2!=NULL && !ret) {
209 if(verbose>3) {printf(
" interpolating BTAC integral\n"); fflush(stdout);}
211 for(
int ci=0; ci<b2->
tacNr; ci++) {
212 double dt=0.0;
if(dtNr>1) dt=dtmin+dtstep*(double)ci;
214 for(
int ti=0; ti<btac->
sampleNr; ti++) dx[ti]=ix[ti]+dt;
224 if(b3!=NULL && !ret) {
225 if(verbose>3) {printf(
" interpolating BTAC 2nd integral\n"); fflush(stdout);}
227 for(
int ci=0; ci<b3->
tacNr; ci++) {
228 double dt=0.0;
if(dtNr>1) dt=dtmin+dtstep*(double)ci;
230 for(
int ti=0; ti<btac->
sampleNr; ti++) dx[ti]=ix[ti]+dt;
241 if(verbose>2) {printf(
" -> returns %d\n", ret); fflush(stdout);}
255int main(
int argc,
char **argv)
257 int ai, help=0, version=0, verbose=1;
259 char imgfile[FILENAME_MAX], btacfile[FILENAME_MAX];
260 char fgfile[FILENAME_MAX], agfile[FILENAME_MAX], awfile[FILENAME_MAX];
261 char vafile[FILENAME_MAX], dtfile[FILENAME_MAX], ssfile[FILENAME_MAX];
262 char cbffile[FILENAME_MAX];
263 char llsqfile[FILENAME_MAX];
264 char kmapfile[FILENAME_MAX];
265 double fixedVa=nan(
"");
266 double fixeddT=nan(
"");
267 double endtime=300.0;
268 double endtimemin=120.0;
269 double dtrange[2]={-10.,+50.};
271 float calcThreshold=0.01;
282 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
283 imgfile[0]=btacfile[0]=(char)0;
284 fgfile[0]=agfile[0]=vafile[0]=awfile[0]=dtfile[0]=ssfile[0]=(char)0;
285 llsqfile[0]=kmapfile[0]=cbffile[0]=(char)0;
287 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
289 char *cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(!*cptr)
continue;
290 if(strncasecmp(cptr,
"END=", 4)==0) {
291 ret=
atofCheck(cptr+4, &endtime);
if(!ret && endtime>0.0)
continue;
292 }
else if(strncasecmp(cptr,
"MIN=", 4)==0) {
293 ret=
atofCheck(cptr+4, &dtrange[0]);
if(!ret && isfinite(dtrange[0]))
continue;
294 }
else if(strncasecmp(cptr,
"MAX=", 4)==0) {
295 ret=
atofCheck(cptr+4, &dtrange[1]);
if(!ret && isfinite(dtrange[1]))
continue;
296 }
else if(strncasecmp(cptr,
"THR=", 4)==0) {
298 if(!ret && v<100.0) {calcThreshold=(float)(0.01*v);
continue;}
299 }
else if(strncasecmp(cptr,
"FG=", 3)==0) {
300 strlcpy(fgfile, cptr+3, FILENAME_MAX);
if(strlen(fgfile))
continue;
301 }
else if(strncasecmp(cptr,
"AG=", 3)==0) {
302 strlcpy(agfile, cptr+3, FILENAME_MAX);
if(strlen(agfile))
continue;
303 }
else if(strncasecmp(cptr,
"AW=", 3)==0) {
304 strlcpy(awfile, cptr+3, FILENAME_MAX);
if(strlen(awfile))
continue;
305 }
else if(strcasecmp(cptr,
"VA=0")==0) {
306 fixedVa=0.0;
continue;
307 }
else if(strncasecmp(cptr,
"VA=", 3)==0) {
308 strlcpy(vafile, cptr+3, FILENAME_MAX);
if(strlen(vafile))
continue;
309 }
else if(strncasecmp(cptr,
"DT=", 3)==0) {
311 if(!ret && v>=-50.0 && v<=50.0) {fixeddT=v;
continue;}
312 strlcpy(dtfile, cptr+3, FILENAME_MAX);
if(strlen(dtfile))
continue;
313 }
else if(strncasecmp(cptr,
"SS=", 3)==0) {
314 strlcpy(ssfile, cptr+3, FILENAME_MAX);
if(strlen(ssfile))
continue;
315 }
else if(strncasecmp(cptr,
"LLSQ=", 5)==0) {
316 strlcpy(llsqfile, cptr+5, FILENAME_MAX);
if(strlen(llsqfile))
continue;
317 }
else if(strncasecmp(cptr,
"KMAP=", 5)==0) {
318 strlcpy(kmapfile, cptr+5, FILENAME_MAX);
if(strlen(kmapfile))
continue;
320 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
325 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
330 if(ai<argc)
strlcpy(imgfile, argv[ai++], FILENAME_MAX);
331 if(ai<argc)
strlcpy(btacfile, argv[ai++], FILENAME_MAX);
332 if(ai<argc)
strlcpy(cbffile, argv[ai++], FILENAME_MAX);
333 if(ai<argc) {fprintf(stderr,
"Error: too many arguments: '%s'.\n", argv[ai]);
return(1);}
335 if(!cbffile[0]) {
tpcPrintUsage(argv[0], info, stdout);
return(1);}
338 if(endtime<endtimemin) {
339 fprintf(stderr,
"Error: too short fit time set with option -end.\n");
342 if(isfinite(fixeddT)) {
343 dtrange[0]=dtrange[1]=fixeddT;
346 if(dtrange[0]>dtrange[1]) {
int i=dtrange[0]; dtrange[0]=dtrange[1]; dtrange[1]=i;}
347 if((dtrange[1]-dtrange[0])>180.) {
348 fprintf(stderr,
"Error: too wide delay range.\n");
350 }
else if((dtrange[1]-dtrange[0])>120.) {
351 fprintf(stderr,
"Warning: large delay range.\n");
352 }
else if((dtrange[1]-dtrange[0])<4.) {
353 fprintf(stderr,
"Error: too short delay range.\n");
360 printf(
"imgfile := %s\n", imgfile);
361 printf(
"btacfile := %s\n", btacfile);
362 printf(
"cbffile := %s\n", cbffile);
363 printf(
"endtime := %g s\n", endtime);
364 printf(
"delay_range := %g - %g s\n", dtrange[0], dtrange[1]);
365 printf(
"delay_step_size := %g s\n", dtstep);
366 printf(
"threshold := %g\n", calcThreshold);
367 if(awfile[0]) printf(
"awfile := %s\n", awfile);
368 if(vafile[0]) printf(
"vafile := %s\n", vafile);
369 if(isfinite(fixedVa)) printf(
"fixed_Va := %g\n", fixedVa);
370 if(dtfile[0]) printf(
"dtfile := %s\n", dtfile);
371 if(isfinite(fixeddT)) printf(
"fixed_dT := %g\n", fixeddT);
372 if(ssfile[0]) printf(
"ssfile := %s\n", ssfile);
373 if(llsqfile[0]) printf(
"llsqfile := %s\n", llsqfile);
374 if(kmapfile[0]) printf(
"kmapfile := %s\n", kmapfile);
375 if(fgfile[0]) printf(
"fgfile := %s\n", fgfile);
376 if(agfile[0]) printf(
"agfile := %s\n", agfile);
388 if(verbose>1) printf(
"reading %s\n", btacfile);
390 ret=
tacRead(&btac, btacfile, &status);
392 fprintf(stderr,
"Error: %s (%s)\n",
errorMsg(status.
error), btacfile);
397 printf(
"tacNr := %d\n", btac.
tacNr);
398 printf(
"sampleNr := %d\n", btac.
sampleNr);
401 printf(
"isframe := %d\n", btac.
isframe);
413 if(verbose>1) {printf(
"reading %s\n", imgfile); fflush(stdout);}
415 ret=
imgRead(&img, imgfile, &status);
418 fprintf(stderr,
"Error: %s (%s)\n",
errorMsg(status.
error), imgfile); fflush(stderr);
422 if(verbose>0) fprintf(stderr,
"Warning: missing pixel values.\n");
426 fprintf(stderr,
"Error: invalid sample times in %s\n", imgfile); fflush(stderr);
429 if(verbose>1) printf(
"Image range: %g - %g\n", ixmin, ixmax);
431 if(ixmax<endtimemin) {
432 fprintf(stderr,
"Error: image time range is too short.\n");
435 if(ixmax<endtime) endtime=ixmax;
442 if(verbose>0) fprintf(stderr,
"Warning: missing BTAC time units.\n");
445 fprintf(stderr,
"Error: invalid sample times in %s\n", btacfile); fflush(stderr);
451 fprintf(stderr,
"Warning: assuming BTAC sample times are in units %s.\n",
unitName(guessedUnit));
452 btac.
tunit=guessedUnit;
455 fprintf(stderr,
"Error: %s (%s)\n",
errorMsg(status.
error), btacfile); fflush(stderr);
465 fprintf(stderr,
"Error: invalid sample times in %s\n", btacfile); fflush(stderr);
468 if(verbose>1) printf(
"BTAC range: %g - %g\n", bxmin, bxmax);
474 fprintf(stderr,
"Warning: assuming image concentrations are in units %s.\n",
unitName(img.
cunit));
478 fprintf(stderr,
"Warning: assuming BTAC concentrations are in units %s.\n",
unitName(img.
cunit));
488 if(verbose>1) {printf(
"checking time range\n"); fflush(stdout);}
490 if(btac.
sampleNr<5) {fprintf(stderr,
"Error: BTAC has too few samples.\n"); ret++;}
491 if(img.
dimt<5) {fprintf(stderr,
"Error: image has too few frames.\n"); ret++;}
492 if(bxmax<endtimemin) {fprintf(stderr,
"Error: BTAC time range is too short.\n"); ret++;}
493 if(ixmax<endtimemin) {fprintf(stderr,
"Error: image time range is too short.\n"); ret++;}
494 if(dtrange[0]<0.0 && bxmax<(endtime+dtrange[0])) {
496 if(endtime<endtimemin) {
497 ret++; fprintf(stderr,
"Error: BTAC does not extend to required end time.\n");}
500 for(
int i=0; i<img.
dimt; i++)
if(img.
x[i]<=endtime) frameNr++;
501 if(frameNr<5) {fprintf(stderr,
"Error: image has too few frames in fit time range.\n"); ret++;}
509 fprintf(stderr,
"Error: %s\n",
errorMsg(ret));
518 if(tacInputForLLSQ(&btac, &ttac, dtrange[0], dtrange[1], dtstep, &inp, &inp2, NULL, &status)) {
524 printf(
"writing delayed, interpolated, and integrated BTACs\n");
525 FILE *fp=fopen(
"imgwcbf_input1.tac",
"w");
528 fp=fopen(
"imgwcbf_input2.tac",
"w");
541 fprintf(stderr,
"Error: cannot simulate Cwm(t).\n");
548 if(tacInputForLLSQ(&wtac, &ttac, dtrange[0], dtrange[1], dtstep, NULL, &wm2, NULL, &status)) {
555 printf(
"writing delayed and integrated WM TACs\n");
556 FILE *fp=fopen(
"imgwcbf_wm.tac",
"w");
563 if(verbose>1) {printf(
"allocating memory for LLSQ\n"); fflush(stdout);}
566 double **llsq_a=(
double**)malloc(llsq_n*
sizeof(
double*));
567 double *llsq_mat=(
double*)malloc((llsq_n*llsq_m)*
sizeof(
double));
568 if(llsq_a==NULL || llsq_mat==NULL) {
569 fprintf(stderr,
"Error: cannot allocate memory for LLSQ.\n");
573 for(
int ni=0; ni<llsq_n; ni++) llsq_a[ni]=llsq_mat+ni*llsq_m;
574 double llsq_b[llsq_m], llsq_x[llsq_n], llsq_wp[llsq_n], llsq_zz[llsq_m];
581 if(verbose>1) {printf(
"preparing LLSQ parameter map\n"); fflush(stdout);}
584 fprintf(stderr,
"Error: cannot allocate memory\n"); fflush(stderr);
586 free(llsq_a); free(llsq_mat);
594 double thrs=
tacAUC(&btac, 0, 0.0, img.
x2[frameNr-1], NULL);
603 long long pNr[llsq_n];
for(
int i=0; i<llsq_n; i++) pNr[i]=0;
604 if(verbose>0) {printf(
"processing %llu image pixels\n", pxlNr); fflush(stdout);}
605 for(
int zi=0; zi<img.
dimz; zi++) {
606 if(img.
dimz>2 && verbose>0) {fprintf(stdout,
"."); fflush(stdout);}
607 for(
int yi=0; yi<img.
dimy; yi++)
for(
int xi=0; xi<img.
dimx; xi++) {
608 for(
int pi=0; pi<map.
dimt; pi++) map.
m[zi][yi][xi][pi]=0.0;
609 for(
int mi=0; mi<llsq_m; mi++) ttac.
c[0].
y[mi]=img.
m[zi][yi][xi][mi];
613 if(ttac.
c[1].
y[llsq_m-1]<thrs)
continue;
617 double r2Best=nan(
"");
618 for(
int di=0; di<inp.
tacNr; di++) {
620 for(
int mi=0; mi<llsq_m; mi++)
621 llsq_b[mi]=ttac.
c[0].
y[mi];
622 for(
int mi=0; mi<llsq_m; mi++) {
623 if(isfinite(fixedVa))
626 llsq_mat[mi]=inp.
c[di].
y[mi];
627 llsq_mat[mi+1*llsq_m]=inp2.
c[di].
y[mi];
628 llsq_mat[mi+2*llsq_m]=wm2.
c[di].
y[mi];
629 llsq_mat[mi+3*llsq_m]=-ttac.
c[1].
y[mi];
633 int ret=
nnls(llsq_a, llsq_m, llsq_n, llsq_b, llsq_x, &r2, llsq_wp, llsq_zz, indexp);
635 if((isfinite(r2) && !isfinite(r2Best)) || r2<r2Best) {
638 for(
int pi=0; pi<llsq_n; pi++) map.
m[zi][yi][xi][pi]=llsq_x[pi];
639 map.
m[zi][yi][xi][llsq_n]=inp.
c[di].
size;
640 map.
m[zi][yi][xi][llsq_n+1]=r2;
643 if(diBest>=0) okNr++;
645 for(
int pi=0; pi<llsq_n; pi++)
if(map.
m[zi][yi][xi][pi]>0.0) pNr[pi]+=1;
649 if(img.
dimz>2 && verbose>0) {fprintf(stdout,
"\n"); fflush(stdout);}
650 free(llsq_a); free(llsq_mat);
652 fprintf(stderr,
"Error: no pixels fitted successfully\n"); fflush(stderr);
658 printf(
" LLSQ successful in %lld/%lld over-threshold pixels\n", okNr, thrsNr);
659 for(
int pi=0; pi<llsq_n; pi++)
660 printf(
" p%d non-zero in %lld pixels\n", pi, pNr[pi]);
670 fprintf(stderr,
"Error: cannot allocate memory\n"); fflush(stderr);
677 char basename[FILENAME_MAX], fname[FILENAME_MAX];
678 strcpy(basename, llsqfile);
680 for(
int i=0; i<llsq_n; i++) {
681 if(i==0 && isfinite(fixedVa))
continue;
682 sprintf(fname,
"%s_p%d%s", basename, 1+i, pext);
683 if(verbose>1) printf(
" writing %s\n", fname);
685 for(
int zi=0; zi<pimg.
dimz; zi++)
for(
int yi=0; yi<pimg.
dimy; yi++)
for(
int xi=0; xi<pimg.
dimx; xi++) {
686 pimg.
m[zi][yi][xi][0]=map.
m[zi][yi][xi][i];
689 fprintf(stderr,
"Error: %s\n",
errorMsg(status.
error)); fflush(stderr);
693 if(verbose>0) {printf(
" %s written.\n", fname); fflush(stdout);}
697 if(verbose>1) printf(
" writing %s\n", dtfile);
699 for(
int zi=0; zi<pimg.
dimz; zi++)
for(
int yi=0; yi<pimg.
dimy; yi++)
for(
int xi=0; xi<pimg.
dimx; xi++) {
700 pimg.
m[zi][yi][xi][0]=map.
m[zi][yi][xi][map.
dimt-2];
703 fprintf(stderr,
"Error: %s\n",
errorMsg(status.
error)); fflush(stderr);
707 if(verbose>0) {printf(
" %s written.\n", dtfile); fflush(stdout);}
710 if(verbose>1) printf(
" writing %s\n", ssfile);
712 for(
int zi=0; zi<pimg.
dimz; zi++)
for(
int yi=0; yi<pimg.
dimy; yi++)
for(
int xi=0; xi<pimg.
dimx; xi++) {
713 pimg.
m[zi][yi][xi][0]=map.
m[zi][yi][xi][map.
dimt-1];
716 fprintf(stderr,
"Error: %s\n",
errorMsg(status.
error)); fflush(stderr);
720 if(verbose>0) {printf(
" %s written.\n", ssfile); fflush(stdout);}
723 if(verbose>1) printf(
" writing %s\n", vafile);
725 for(
int zi=0; zi<pimg.
dimz; zi++)
for(
int yi=0; yi<pimg.
dimy; yi++)
for(
int xi=0; xi<pimg.
dimx; xi++) {
726 pimg.
m[zi][yi][xi][0]=map.
m[zi][yi][xi][0];
729 fprintf(stderr,
"Error: %s\n",
errorMsg(status.
error)); fflush(stderr);
733 if(verbose>0) {printf(
" %s written.\n", vafile); fflush(stdout);}
737 if(verbose>1) printf(
" writing %s\n", cbffile);
739 for(
int zi=0; zi<pimg.
dimz; zi++)
for(
int yi=0; yi<pimg.
dimy; yi++)
for(
int xi=0; xi<pimg.
dimx; xi++) {
740 pimg.
m[zi][yi][xi][0]=60.*(map.
m[zi][yi][xi][1] - map.
m[zi][yi][xi][0]*map.
m[zi][yi][xi][3]);
741 if(!isfinite(pimg.
m[zi][yi][xi][0]) || pimg.
m[zi][yi][xi][0]<0.0) pimg.
m[zi][yi][xi][0]=0.0;
742 else if(pimg.
m[zi][yi][xi][0]>1.6) pimg.
m[zi][yi][xi][0]=1.6;
745 fprintf(stderr,
"Error: %s\n",
errorMsg(status.
error)); fflush(stderr);
749 if(verbose>0) {printf(
" %s written.\n", vafile); fflush(stdout);}
754 for(
int zi=0; zi<pimg.
dimz; zi++)
for(
int yi=0; yi<pimg.
dimy; yi++)
for(
int xi=0; xi<pimg.
dimx; xi++) {
755 double p[llsq_n];
for(
int i=0; i<llsq_n; i++) p[i]=map.
m[zi][yi][xi][i];
758 double aw=0.0;
if(p[2]>0.0 && p[3]>(fw/pw)) aw=p[2]/(p[3]-fw/pw);
760 double ag=p[1]/fg - aw*fw/fg - p[0]/pg;
761 if(!(ag>=0.0)) ag=0.0;
else if(ag>1.0) ag=1.0;
762 map.
m[zi][yi][xi][1]=60.*fg;
763 map.
m[zi][yi][xi][2]=ag;
764 map.
m[zi][yi][xi][3]=aw;
768 if(verbose>1) printf(
" writing %s\n", kmapfile);
770 fprintf(stderr,
"Error: %s\n",
errorMsg(status.
error)); fflush(stderr);
774 if(verbose>0) {printf(
" %s written.\n", kmapfile); fflush(stdout);}
779 if(verbose>1) printf(
" writing %s\n", fgfile);
781 for(
int zi=0; zi<pimg.
dimz; zi++)
for(
int yi=0; yi<pimg.
dimy; yi++)
for(
int xi=0; xi<pimg.
dimx; xi++) {
782 pimg.
m[zi][yi][xi][0]=map.
m[zi][yi][xi][1];
786 fprintf(stderr,
"Error: %s\n",
errorMsg(status.
error)); fflush(stderr);
790 if(verbose>0) {printf(
" %s written.\n", fgfile); fflush(stdout);}
794 if(verbose>1) printf(
" writing %s\n", agfile);
796 for(
int zi=0; zi<pimg.
dimz; zi++)
for(
int yi=0; yi<pimg.
dimy; yi++)
for(
int xi=0; xi<pimg.
dimx; xi++) {
797 pimg.
m[zi][yi][xi][0]=map.
m[zi][yi][xi][2];
800 fprintf(stderr,
"Error: %s\n",
errorMsg(status.
error)); fflush(stderr);
804 if(verbose>0) {printf(
" %s written.\n", agfile); fflush(stdout);}
807 if(verbose>1) printf(
" writing %s\n", awfile);
809 for(
int zi=0; zi<pimg.
dimz; zi++)
for(
int yi=0; yi<pimg.
dimy; yi++)
for(
int xi=0; xi<pimg.
dimx; xi++) {
810 pimg.
m[zi][yi][xi][0]=map.
m[zi][yi][xi][3];
813 fprintf(stderr,
"Error: %s\n",
errorMsg(status.
error)); fflush(stderr);
817 if(verbose>0) {printf(
" %s written.\n", awfile); fflush(stdout);}
int atofCheck(const char *s, double *v)
char * filenameGetExtensions(const char *s)
Get all extensions of a file name.
void filenameRmExtensions(char *s)
int imgXUnitConvert(IMG *img, const int u)
void imgContents(IMG *img, FILE *fp)
unsigned long long imgNaNs(IMG *img, int fix)
int imgAllocate(IMG *img, const unsigned int dimz, const unsigned int dimy, const unsigned int dimx, const unsigned int dimt, TPCSTATUS *status)
int imgXRange(IMG *img, double *xmin, double *xmax)
int imgRead(IMG *img, const char *fname, TPCSTATUS *status)
int imgWrite(IMG *img, const char *fname, TPCSTATUS *status)
int liIntegrateFE(double *x1, double *x2, double *y, int nr, double *ie, double *iie, const int verbose)
Linear integration of PET TAC to frame end times.
int liIntegrate(double *x, double *y, const int nr, double *yi, const int se, const int verbose)
Linear integration of TAC with trapezoidal method.
int liIntegratePET(double *x1, double *x2, double *y, int nr, double *ie, double *iie, const int verbose)
Calculate PET TAC AUC from start to each time frame, as averages during each frame.
int liInterpolate(double *x, double *y, const int nr, double *newx, double *newy, double *newyi, double *newyii, const int newnr, const int se, const int ee, const int verbose)
Linear interpolation and/or integration with trapezoidal method.
int liInterpolateForPET(double *x, double *y, const int nr, double *newx1, double *newx2, double *newy, double *newyi, double *newyii, const int newnr, const int se, const int ee, const int verbose)
Linear TAC interpolation and/or integration to PET frames.
double tacAUC(TAC *tac, int ti, double t1, double t2, TPCSTATUS *status)
Calculates TAC AUC from t1 to t2.
int tacAllocateWithIMG(TAC *tac, IMG *img, int tacNr)
Allocate TAC based on data in IMG.
int nnls(double **a, int m, int n, double *b, double *x, double *rnorm, double *wp, double *zzp, int *indexp)
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 simC1_d(double *t, double *ca, const int nr, const double k1, const double k2, double *ct)
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)
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 tacAllocateMore(TAC *tac, int tacNr)
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 tacSetX(TAC *d, TPCSTATUS *status)
Set TAC x values based on x1 and x2 values, or guess x1 and x2 values based on x values.
int tacXRange(TAC *d, double *xmin, double *xmax)
Get the range of x values (times) in TAC structure.
Header file for libtpccm.
Header file for library libtpccsv.
Header file for library libtpcextensions.
@ UNIT_ML_PER_ML_MIN
mL/(mL*min)
@ UNIT_UNKNOWN
Unknown unit.
@ TPCERROR_INVALID_XRANGE
Invalid sample time range.
@ TPCERROR_INVALID_VALUE
Invalid value.
@ TPCERROR_FAIL
General error.
@ TPCERROR_TOO_FEW
File contains too few samples.
char * unitName(int unit_code)
Header file for library libtpcift.
Header file for libtpcimage.
Header file for libtpcli.
Header file for libtpclinopt.
Header file for library libtpctac.
@ TAC_FORMAT_PMOD
PMOD TAC format.
Header file for libtpctacimg.
int tacimgXMatch(TAC *tac, IMG *img)
int tacimgXCopy(TAC *tac, IMG *img)
Header file for libtpctacmod.