11#include "tpcclibConfig.h"
30static char *info[] = {
31 "Extracts arterial input curve from human abdominal region of a dynamic",
32 "[O-15]H2O PET image by finding the aorta, and corrects it with",
33 "recovery coefficient based on method (1, 4).",
34 "The current method does also account for effect of background",
35 "radioactivity on recovery coefficient (3).",
37 "Supported file formats are ECAT 6.3, ECAT 7, NIfTI-1, and Analyze 7.5.",
38 "In case of NIfTI and Analyze image input, you may need to add the frame",
39 "information to the blood data afterwards.",
40 "NOTICE: all image planes should contain a clear view of the abdominal",
41 "aorta that has not yet split into two vessels, and no other high spots;",
42 "crop the image before using this program.",
43 "NOTICE: It is recommended that either the full width half maximum (FWHM)",
44 "value or individually measured aorta diameter is specified as command-line",
45 "option, because both cannot be reliably estimated from a noisy image.",
46 "NOTICE: It is also recommended that the full width half maximum (FWHM)",
47 "value is determined for each scanner and reconstruction method.",
49 "Usage: @P [Options] petimage bloodfile",
53 " Enter a fixed value for FWHM (mm); fitted by default.",
54 " Results will not be reliable unless either FWHM or vessel diameter",
55 " is measured and fixed.",
57 " Enter a fixed value for inner vessel diameter (mm); fitted by default.",
58 " Results will not be reliable unless either FWHM or vessel diameter",
59 " is measured and fixed.",
60 " -plane=<Mean|Median|Best>",
61 " Model is fitted separately to all image planes, and by default",
62 " the mean FWHM and vessel diameter are used to estimate an average",
63 " blood TAC using all image planes.",
64 " With this option the median can be used instead of the mean, or",
65 " blood TAC can be estimated only from the plane that provides",
66 " the highest fitted peak.",
67 " -model=<germano|gaussian>",
68 " Select the PVE simulation method; Gaussian smoothing by default.",
69 " -pixelsize=<value>",
70 " Set image pixel size (mm) in x,y dimensions. Necessary, if image header",
71 " does not have valid pixel size.",
73 " Length (mm) of the fit square side. By default, 30x30mm square",
74 " surrounding the peak pixel value is used in the fit.",
76 " Save sum image sub-volume which is used to fit vessel position.",
77 " -sumfit=<filename>",
78 " Save fitted sum image sub-volume.",
80 " Model estimated background curve.",
82 " Model estimated peak TAC (not corrected for recovery error).",
83 " -subvol=<filename>",
84 " Subrange of the original dynamic image used in fit; for testing.",
87 "Example 1: FWHM is measured, vessel diameter is estimated from image:",
88 " eabaort -FWHM=6.3 -diameter=best s9876dy1.v s9876ab.dat ",
90 "Example 2: vessel diameter is measured, FWHM is estimated from image:",
91 " eabaort -FWHM=fit -diameter=19.2 s9876dy1.v s9876ab.dat ",
94 "1. Germano G, Chen BC, Huang S-C, Gambhir SS, Hoffman EJ, Phelps ME.",
95 " Use of abdominal aorta for arterial input function determination",
96 " in hepatic and renal PET studies. J Nucl Med 1992;33:613-620.",
97 "2. Scremin OU, Cuevas-Trisan RL, Scremin E, Brown CV, Mandelkern MA.",
98 " Functional electrical stimulation effect on skeletal muscle blood",
99 " flow measured with H215O positron emission tomography. Arch Phys",
100 " Med Rehabil 1998;79:641-646.",
101 "3. Brix G, Belleman ME, Hauser H, Doll J. Recovery-koeffizienten zur",
102 " quantifierung der arteriellen inputfunktion aus dynamischen PET-",
103 " messungen: experimentelle und theoretische bestimmung. Nuklearmedizin",
105 "4. Liukko KE, Oikonen VJ, Tolvanen TK, Virtanen KA, Viljanen AP, Sipilä HT,",
106 " Nuutila P, Iozzo P. Non-invasive estimation of subcutaneous and visceral",
107 " adipose tissue blood flow by using [15O]H2O PET with image derived input",
108 " functions. Open Med Imaging J. 2007; 1: 7-13.",
110 "See also: fit_h2o, imgflow, fitdelay, imgbox, simiart",
112 "Keywords: input, blood, image, aorta",
129double func(
int parNr,
double *p,
void*);
134enum estim_mode {P_FIXED, P_MEAN, P_MEDIAN, P_BEST};
136enum parameter {P_BKG, P_PEAK, P_POSX, P_POSY, P_RAD, P_FWHM};
138enum vm_type {VM_GERMANO, VM_GAUSSIAN};
145int vessel_model=VM_GAUSSIAN;
152int main(
int argc,
char *argv[])
154 int ai, help=0, version=0, verbose=1;
155 int fi, ret, pi, yi, xi, i;
157 int mode_plane=P_MEAN;
159 char imgfile[FILENAME_MAX], tacfile[FILENAME_MAX],
160 regfile[FILENAME_MAX], maxfile[FILENAME_MAX], bkgfile[FILENAME_MAX],
161 sumfile[FILENAME_MAX], suffile[FILENAME_MAX];
162 char tmp[512], *cptr;
163 IMG img, rimg, fimg, simg;
164 float maxv, minv, avg, f;
165 double ss, *chainptr, *chain, **p, ***pf, pxlsize=-1.0;
166 double reccoef=0, rad=0;
171 int planeNr=0, peakFrame;
173 double diameter=-1.0, radius=6., FWHM=-1.0;
180 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
181 imgfile[0]=tacfile[0]=regfile[0]=maxfile[0]=bkgfile[0]=sumfile[0]=suffile[0]=(char)0;
183 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
185 cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(cptr==NULL)
continue;
186 if(strncasecmp(cptr,
"MODEL=", 6)==0) {
187 if(strncasecmp(cptr+6,
"GERMANO", 3)==0) {
188 vessel_model=VM_GERMANO;
continue;}
189 if(strncasecmp(cptr+6,
"GAUSSIAN", 3)==0) {
190 vessel_model=VM_GAUSSIAN;
continue;}
191 }
else if(strncasecmp(cptr,
"PIXELSIZE=", 10)==0) {
192 pxlsize=
atof_dpi(cptr+10);
if(pxlsize>0)
continue;
193 }
else if(strncasecmp(cptr,
"SUBVOL=", 7)==0) {
194 strlcpy(regfile, cptr+7, FILENAME_MAX);
if(strlen(regfile)>0)
continue;
195 }
else if(strncasecmp(cptr,
"SUM=", 4)==0) {
196 strlcpy(sumfile, cptr+4, FILENAME_MAX);
if(strlen(sumfile)>0)
continue;
197 }
else if(strncasecmp(cptr,
"SUMFIT=", 7)==0) {
198 strlcpy(suffile, cptr+7, FILENAME_MAX);
if(strlen(suffile)>0)
continue;
199 }
else if(strncasecmp(cptr,
"BKG=", 4)==0) {
200 strlcpy(bkgfile, cptr+4, FILENAME_MAX);
if(strlen(bkgfile)>0)
continue;
201 }
else if(strncasecmp(cptr,
"PEAK=", 5)==0) {
202 strlcpy(maxfile, cptr+5, FILENAME_MAX);
if(strlen(maxfile)>0)
continue;
203 }
else if(strncasecmp(cptr,
"F=", 2)==0) {
204 FWHM=
atof_dpi(cptr+2);
if(FWHM>0.0)
continue;
205 }
else if(strncasecmp(cptr,
"FWHM=", 5)==0) {
206 if(strcasecmp(cptr+5,
"FIT")==0)
continue;
207 FWHM=
atof_dpi(cptr+5);
if(FWHM>0.0)
continue;
208 }
else if(strncasecmp(cptr,
"FITSIZE=", 8)==0) {
209 fitsize=
atof_dpi(cptr+8);
if(fitsize>0.0)
continue;
210 }
else if(strncasecmp(cptr,
"DIAMETER=", 9)==0) {
212 if(ret==0 && diameter>0.0)
continue;
213 }
else if(strncasecmp(cptr,
"PLANE=", 6)==0) {
214 if(strcasecmp(cptr+6,
"MEAN")==0) {mode_plane=P_MEAN;
continue;}
215 if(strcasecmp(cptr+6,
"MEDIAN")==0) {mode_plane=P_MEDIAN;
continue;}
216 if(strcasecmp(cptr+6,
"BEST")==0) {mode_plane=P_BEST;
continue;}
219 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
225 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
230 if(ai<argc)
strlcpy(imgfile, argv[ai++], FILENAME_MAX);
231 if(ai<argc)
strlcpy(tacfile, argv[ai++], FILENAME_MAX);
234 fprintf(stderr,
"Error: invalid argument '%s'.\n", argv[ai]);
241 fprintf(stderr,
"Error: missing command-line argument; use option --help\n");
247 printf(
"imgfile := %s\n", imgfile);
248 printf(
"tacfile := %s\n", tacfile);
249 printf(
"sumfile := %s\n", sumfile);
250 printf(
"suffile := %s\n", suffile);
251 printf(
"regfile := %s\n", regfile);
252 printf(
"maxfile := %s\n", maxfile);
253 printf(
"bkgfile := %s\n", bkgfile);
254 printf(
"pxlsize := %g\n", pxlsize);
255 printf(
"fitsize := %g\n", fitsize);
256 printf(
"vessel_model := %d\n", vessel_model);
257 printf(
"mode_plane := %d\n", mode_plane);
258 printf(
"diameter := %g\n", diameter);
259 printf(
"FWHM := %g\n", FWHM);
274 if(verbose>1) fprintf(stdout,
"reading %s\n", imgfile);
277 fprintf(stderr,
"Error in reading image: %s\n", img.
statmsg);
281 if(verbose>0) fprintf(stderr,
"Warning: missing pixel values.\n");
284 fprintf(stderr,
"Error: %s is not an image.\n", imgfile);
290 strcpy(tmp,
"static image can not be used to provide valid input");
292 strcpy(tmp,
"image has too few time frames to provide valid input TAC");
293 fprintf(stderr,
"Warning: %s.\n", tmp);
297 fprintf(stderr,
"\nWarning: method is only validated for [O-15]H2O!\n\n");
300 if(verbose>1) printf(
"original_image_pixel_size := %g\n", img.
sizex);
304 fprintf(stderr,
"Error: image does not contain pixel size.\n");
305 fprintf(stdout,
"Note: set pixel size with option -pixelsize.\n");
309 fprintf(stderr,
"Error: different x and y pixel size.\n");
313 if(verbose>0) printf(
"image_pixel_size := %g\n", img.
sizex);
316 fprintf(stderr,
"\nWarning: image does not contain frame times.\n\n");
318 for(fi=0; fi<img.
dimt; fi++) {
319 img.
start[fi]=(float)fi; img.
end[fi]=(float)(fi+1);
329 if(verbose>1) printf(
"searching for peak pixel\n");
330 imax.
z=imax.
y=imax.
x=imax.
f=1;
333 fprintf(stderr,
"Error: cannot find peak pixel in image (%d).\n", ret);
337 maxv=img.
m[imax.
z-1][imax.
y-1][imax.
x-1][imax.
f-1];
340 printf(
"peak_value := %g\n", maxv);
341 printf(
"peak_pos(z,y,x,t) := [%d,%d,%d,%d]\n", imax.
z, imax.
y, imax.
x, imax.
f);
351 if(verbose>1) printf(
"summing image frames 1-%d\n", imax.
f);
353 if(verbose>1 && ret!=0) printf(
"imgFrameIntegral() := %d\n", ret);
356 if(verbose>1 && ret!=0) printf(
"imgArithmConst() := %d\n", ret);
359 fprintf(stderr,
"Error: cannot calculate sum image.\n");
363 if(verbose>1) printf(
"searching for peak pixel in sum image\n");
364 imax.
z=imax.
y=imax.
x=imax.
f=1;
367 fprintf(stderr,
"Error: cannot find peak pixel in sum image (%d).\n", ret);
371 maxv=simg.
m[imax.
z-1][imax.
y-1][imax.
x-1][imax.
f-1];
373 printf(
"sum_peak_value := %g\n", maxv);
374 printf(
"sum_peak_pos(z,y,x,t) := [%d,%d,%d,%d]\n",
375 imax.
z, imax.
y, imax.
x, imax.
f);
386 if(verbose>1) printf(
"extracting image subvolume for fitting\n");
387 side=(int)ceil(fitsize/img.
sizex);
388 if(verbose>1) printf(
"side := %d\n", side);
389 if(side<3 || side>img.
dimx) {
390 fprintf(stderr,
"Error: invalid fit square area.\n");
395 ir.
x1=imax.
x-side/2;
if(ir.
x1<1) ir.
x1=1;
396 ir.
y1=imax.
y-side/2;
if(ir.
y1<1) ir.
y1=1;
400 if(verbose>1) printf(
"image fit volume: z=[%d,%d] y=[%d,%d] x=[%d,%d] f=[%d,%d]\n",
402 xorig=imax.
x; yorig=imax.
y;
408 fprintf(stderr,
"Error in extracting image fit range: %s\n", rimg.
statmsg);
415 if(verbose>0) fprintf(stdout,
"writing %s\n", regfile);
418 fprintf(stderr,
"Error in writing image: %s\n", rimg.
statmsg);
445 printf(
"estimating the position of vessel centre");
446 if(diameter<0.0) printf(
" and diameter");
447 if(FWHM<0.0) printf(
" and FWHM");
452 f=rimg.
end[peakFrame-1]-rimg.
start[0];
453 if(verbose>2) printf(
"summing first %g sec\n", f);
457 fprintf(stderr,
"Error: cannot calculate sum image.\n");
463 if(verbose>0) fprintf(stdout,
"writing %s\n", sumfile);
466 fprintf(stderr,
"Error in writing image: %s\n", simg.
statmsg);
475 if(verbose>1) printf(
"allocating memory for parameters\n");
477 chain=(
double*)malloc(parNr*rimg.
dimz*(rimg.
dimt+1)*
sizeof(
double));
478 p=(
double**)malloc(rimg.
dimz*(rimg.
dimt+1)*
sizeof(
double*));
479 pf=(
double***)malloc(rimg.
dimt*
sizeof(
double**));
480 if(chain==NULL || p==NULL || pf==NULL) {
481 fprintf(stderr,
"Error: out of memory.\n");
484 for(fi=0, chainptr=chain; fi<=rimg.
dimt; fi++) {
485 for(i=0; i<rimg.
dimz; i++) {
486 p[fi*rimg.
dimz+i]=chainptr;
490 pf[fi-1]=p+fi*rimg.
dimz;
496 if(verbose>1) printf(
"searching for maximum pixel\n");
498 if(ret==0) ret=
imgAvg(&simg, NULL, &avg);
500 fprintf(stderr,
"Error: invalid volume contents.\n");
502 free(pf); free(p); free(chain);
return(15);
505 fprintf(stdout,
"fit volume maxv=%g at x,y,z=(%d,%d,%d)\n",
506 maxv, imax.
x, imax.
y, imax.
z);
507 fprintf(stdout,
"fit volume avg=%g\n", avg);
510 fprintf(stderr,
"Error: invalid volume voxel contents.\n");
512 free(pf); free(p); free(chain);
return(15);
521 fprintf(stderr,
"Error: cannot find peak in image subvolume.\n");
523 free(pf); free(p); free(chain);
return(16);
525 xorig=ppos.
x-1; yorig=ppos.
y-1;
527 printf(
"xorig := %g\n", xorig);
528 printf(
"yorig := %g\n", yorig);
535 if(verbose>1) printf(
"allocating memory for image planes for fitting\n");
539 fprintf(stderr,
"Error: cannot allocate memory for image planes.\n");
541 free(pf); free(p); free(chain);
return(17);
545 if(verbose>1) printf(
"allocating memory for fitted image\n");
548 fprintf(stderr,
"Error: cannot allocate memory for fitted image.\n");
550 free(pf); free(p); free(chain);
return(18);
559 for(ppi=0; ppi<planeNr; ppi++) {
561 p[ppi][P_BKG]=avg;
if(p[ppi][P_BKG]<0.0) p[ppi][P_BKG]=0.0;
565 p[ppi][P_POSX]=(0.5+xorig)*simg.
sizex;
566 p[ppi][P_POSY]=(0.5+yorig)*simg.
sizey;
568 if(diameter>0.0) radius=0.5*diameter;
else radius=6.0;
569 p[ppi][P_RAD]=radius;
571 if(FWHM>0.0) p[ppi][P_FWHM]=FWHM;
else p[ppi][P_FWHM]=8.0;
578 pmin[P_BKG]=minv; pmax[P_BKG]=avg;
580 pmin[P_PEAK]=avg;
if(pmin[P_PEAK]<0.0) pmin[P_PEAK]=0.0;
581 pmax[P_PEAK]=avg+3.0*(maxv-avg);
583 pmin[P_POSX]=(xorig-0.45*(double)simg.
dimx)*simg.
sizex;
584 pmax[P_POSX]=(xorig+0.45*(double)simg.
dimx)*simg.
sizex;
585 pmin[P_POSY]=(yorig-0.45*(double)simg.
dimy)*simg.
sizey;
586 pmax[P_POSY]=(yorig+0.45*(double)simg.
dimy)*simg.
sizey;
588 if(diameter>0.0) pmin[P_RAD]=pmax[P_RAD]=0.5*diameter;
594 if(FWHM>0.0) pmin[P_FWHM]=pmax[P_FWHM]=FWHM;
595 else {pmin[P_FWHM]=0.1; pmax[P_FWHM]=20.0;}
597 fprintf(stdout,
"Initial values and constraints:\n");
598 for(pi=0; pi<parNr; pi++)
599 fprintf(stdout,
"p=%g [%g, %g]\n", p[0][pi], pmin[pi], pmax[pi]);
609 if(verbose>0) printf(
"fitting image planes...\n");
610 for(ppi=0; ppi<planeNr; ppi++) {
612 if(verbose>2 && simg.
dimz>1) printf(
"plane %d\n", 1+ppi);
613 if(verbose>5) printf(
" initial_SS := %g\n", func(parNr, p[ppi], NULL));
616 for(yi=0; yi<simg.
dimy; yi++)
for(xi=0; xi<simg.
dimx; xi++)
617 pmimg.
m[0][yi][xi][0]=simg.
m[ppi][yi][xi][0];
621 ret=
tgo(pmin, pmax, func, NULL, parNr, neighNr, &ss, p[ppi], tgoNr, 1, verbose-18);
623 fprintf(stderr,
"Error in optimization (%d).\n", ret);
626 free(pf); free(p); free(chain);
return(20);
631 sprintf(fname,
"imgsim%0d.tif", 1+ppi);
636 if(ret==1 && verbose>1) printf(
"Max iteration nr was reached.\n");
638 printf(
"param estimates:");
639 for(pi=0; pi<parNr; pi++) printf(
" %g", p[ppi][pi]);
640 printf(
" SS=%g\n", ss);
645 printf(
"fwhm[%d] := %g\n", 1+ppi, p[ppi][P_FWHM]);
646 printf(
"radius[%d] := %g\n", 1+ppi, p[ppi][P_RAD]);
647 printf(
"posx[%d] := %g\n", 1+ppi, p[ppi][P_POSX]);
648 printf(
"posy[%d] := %g\n", 1+ppi, p[ppi][P_POSY]);
649 printf(
"peak[%d] := %g\n", 1+ppi, p[ppi][P_PEAK]);
650 printf(
"bkg[%d] := %g\n", 1+ppi, p[ppi][P_BKG]);
655 for(yi=0; yi<simg.
dimy; yi++)
for(xi=0; xi<simg.
dimx; xi++)
656 fimg.
m[ppi][yi][xi][0]=psimg.
m[0][yi][xi][0];
665 printf(
"Writing fitted image in %s\n", suffile);
667 if(ret) fprintf(stderr,
"Error in writing %s\n", suffile);
677 if(mode_plane==P_BEST) {
679 best_plane=ppi=0; a=p[ppi][P_PEAK];
680 a*=
rcPeakPET(p[ppi][P_FWHM], p[ppi][P_RAD]); f=a;
681printf(
"plane %d a=%g\n", 1, a);
682 for(ppi=1; ppi<rimg.
dimz; ppi++) {
684 a*=
rcPeakPET(p[ppi][P_FWHM], p[ppi][P_RAD]);
685 if(a>f) {f=a; best_plane=ppi;}
686printf(
"plane %d a=%g\n", 1+ppi, a);
688 if(verbose>1 && rimg.
dimz>1) printf(
"best_plane := %d\n", 1+best_plane);
689 rad=radius=p[best_plane][P_RAD];
690 FWHM=p[best_plane][P_FWHM];
696 if(mode_plane==P_MEAN || mode_plane==P_MEDIAN) {
697 double *a, sd, avg, med;
698 a=(
double*)malloc(rimg.
dimz*
sizeof(
double));
700 for(ppi=0; ppi<rimg.
dimz; ppi++) a[ppi]=p[ppi][P_RAD];
703 if(verbose>1 && rimg.
dimz>1) {
704 printf(
" radius_mean := %g\n", avg);
705 printf(
" radius_sd := %g\n", sd);
706 printf(
" radius_median := %g\n", med);
708 if(mode_plane==P_MEDIAN) radius=med;
else radius=avg;
711 for(ppi=0; ppi<rimg.
dimz; ppi++) a[ppi]=p[ppi][P_FWHM];
714 if(verbose>1 && rimg.
dimz>1) {
715 printf(
" FWHM_mean := %g\n", avg);
716 printf(
" FWHM_sd := %g\n", sd);
717 printf(
" FWHM_median := %g\n", med);
719 if(mode_plane==P_MEDIAN) FWHM=med;
else FWHM=avg;
722 if(verbose>0) printf(
"vessel_radius := %g\n", radius);
723 if(verbose>0) printf(
"FWHM := %g\n", FWHM);
730 if(verbose>0) printf(
"RC := %g\n", reccoef);
731 if(verbose>0) printf(
"Correction factor (1/RC) := %.2f\n", 1.0/reccoef);
737 if(verbose>2) printf(
"allocating memory for blood TAC\n");
742 fprintf(stderr,
"Error: cannot allocate memory for blood TACs.\n");
744 free(pf); free(p); free(chain);
return(31);
764 if(verbose>1) printf(
"estimating peak and background level\n");
770 fprintf(stderr,
"Error in allocating memory for mask image.\n");
772 free(pf); free(p); free(chain);
dftEmpty(&dft);
776 double mv=0.0, r=0.0;
778 pxlMinNr=1;
if(best_plane>=0) pxlMinNr+=2;
779 for(ppi=0; ppi<planeNr; ppi++) {
780 if(best_plane>=0 && best_plane!=ppi)
continue;
781 if(verbose>1) printf(
"vessel plane := %d\n", 1+ppi);
782 r=rad/6.0; mv=0.0; ret=0;
783 while(mv<pxlMinNr && ret==0) {
784 if(verbose>2) printf(
"r := %g\n", r);
785 if(verbose>2) printf(
"mv := %g\n", mv);
786 ret=
imgCircleMask(&mask, ppi, p[ppi][P_POSX], p[ppi][P_POSY], r, 1.0,
788 if(mv<pxlMinNr) r+=0.35*rimg.
sizex;
791 fprintf(stderr,
"Error: cannot create mask mask image.\n");
793 free(pf); free(p); free(chain);
dftEmpty(&dft);
797 if(verbose>0) printf(
"vessel ROI radius: %g\n", r);
804 fprintf(stderr,
"Error: cannot calculate vessel TAC.\n");
815 fprintf(stderr,
"Error: cannot extract pixel TACs.\n");
817 ret=
dftWrite(&pdft,
"peakpixels.dft");
818 if(ret!=0) fprintf(stderr,
"Error: cannot save pixel TACs.\n");
824 pxlMinNr=2;
if(best_plane>=0) pxlMinNr+=3;
826 for(ppi=0; ppi<planeNr; ppi++) {
827 if(best_plane>=0 && best_plane!=ppi)
continue;
828 if(verbose>2) printf(
"background plane := %d\n", 1+ppi);
829 r1=rad+2.4*FWHM; r2=rad+2.5*FWHM; mv=0.0; ret=0;
830 while(mv<pxlMinNr && ret==0 && r1>0.0) {
831 if(verbose>3) printf(
"r1 := %g\n", r1);
832 if(verbose>3) printf(
"r2 := %g\n", r2);
833 ret=
imgRingMask(&mask, ppi, p[ppi][P_POSX], p[ppi][P_POSY], r1, r2, 1.0, &mv, verbose-10);
837 fprintf(stderr,
"Error: cannot create mask mask image.\n");
839 free(pf); free(p); free(chain);
dftEmpty(&dft);
849 fprintf(stderr,
"Error: cannot calculate background TAC.\n");
860 fprintf(stderr,
"Error: cannot extract pixel TACs.\n");
862 ret=
dftWrite(&pdft,
"bkgpixels.dft");
863 if(ret!=0) fprintf(stderr,
"Error: cannot save pixel TACs.\n");
871 free(pf); free(p); free(chain);
877 for(fi=0; fi<rimg.
dimt; fi++) {
881 dft.
voi[0].
y[fi]*=(1.0/reccoef);
889 if(verbose>1) printf(
"saving recovery corrected blood TAC\n");
890 snprintf(tmp, 512,
"# Image-derived input from %s\n", imgfile);
895 snprintf(tmp, 512,
"# Program: %s\n", prname);
898 snprintf(tmp, 512,
"# FWHM: %g mm\n", FWHM);
900 snprintf(tmp, 512,
"# vessel_diameter: %g mm\n", 2.0*rad);
902 snprintf(tmp, 512,
"# RC: %g\n", reccoef);
907 fprintf(stderr,
"Error in writing %s: %s\n", tacfile,
dfterrmsg);
911 if(verbose>0) fprintf(stdout,
"Corrected blood TAC written in %s\n", tacfile);
918 if(verbose>1) printf(
"saving background tac\n");
919 snprintf(tmp, 512,
"# Image-derived input background from %s\n", imgfile);
924 snprintf(tmp, 512,
"# Program: %s\n", prname);
927 snprintf(tmp, 512,
"# FWHM: %g mm\n", FWHM);
929 snprintf(tmp, 512,
"# vessel_diameter: %g mm\n", 2.0*rad);
931 snprintf(tmp, 512,
"# RC: %g\n", reccoef);
939 fprintf(stderr,
"Error in writing %s: %s\n", bkgfile,
dfterrmsg);
943 if(verbose>0) fprintf(stdout,
"Background TAC written in %s\n", bkgfile);
951 if(verbose>1) printf(
"saving noncorrected vessel peak tac\n");
952 snprintf(tmp, 512,
"# Image-derived non-corrected peak TAC from %s\n", imgfile);
957 snprintf(tmp, 512,
"# Program: %s\n", prname);
960 snprintf(tmp, 512,
"# FWHM: %g mm\n", FWHM);
962 snprintf(tmp, 512,
"# vessel_diameter: %g mm\n", 2.0*rad);
970 fprintf(stderr,
"Error in writing %s: %s\n", maxfile,
dfterrmsg);
975 fprintf(stdout,
"Noncorrected vessel peak TAC written in %s\n", maxfile);
1002double func(
int parNr,
double *p,
void *fdata)
1004 int xi, yi, pi, n=0, ret;
1005 double cbkg[1], cart[1], rad, xart, yart, FWHM, d, ss=0.0;
1013 for(pi=0; pi<parNr; pi++) printf(
" p[%d]=%g", pi, p[pi]);
1019 cbkg[0]=pa[0]; cart[0]=pa[1];
1020 xart=pa[2]; yart=pa[3]; rad=pa[4]; FWHM=pa[5];
1021 model=0;
if(vessel_model==VM_GAUSSIAN) model=1;
1025 if(1) fprintf(stderr,
" error in idiSimulateTubeImagePlane()\n");
1029 if(vessel_model==VM_GAUSSIAN) {
1030 double s=FWHM/2.354820;
1034 if(1) fprintf(stderr,
" error in imgGaussianFIRFilter()\n");
1040 for(yi=0; yi<psimg.
dimy; yi++) {
1041 for(xi=0; xi<psimg.
dimx; xi++) {
1042 d=psimg.
m[0][yi][xi][0]-pmimg.
m[0][yi][xi][0];
1046 if(n>0) ss/=(double)n;
int imgRingMask(IMG *img, int zi, double cx, double cy, double r1, double r2, double mv, double *smv, int verbose)
int imgCircleMask(IMG *img, int zi, double cx, double cy, double r, double mv, double *smv, int verbose)
int modelCheckParameters(int par_nr, double *lower_p, double *upper_p, double *test_p, double *accept_p, double *penalty)
int atof_with_check(char *double_as_string, double *result_value)
double atof_dpi(char *str)
int dftWrite(DFT *data, char *filename)
int imgMaskPixelTACs(IMG *img, IMG *mask, double thrs, DFT *dft, int verbose)
int imgExistentTimes(IMG *img)
unsigned long long imgNaNs(IMG *img, int fix)
int imgExtractRange(IMG *img1, IMG_RANGE r, IMG *img2)
int imgAllocateWithHeader(IMG *image, int planes, int rows, int columns, int frames, IMG *image_from)
void imgEmpty(IMG *image)
int imgFrameIntegral(IMG *img, int first, int last, IMG *iimg, int verbose)
int imgArithmConst(IMG *img, float operand, char operation, float ulimit, int verbose)
char * imgIsotope(IMG *img)
int imgMaskTAC(IMG *img, IMG *mask, double *tac, int verbose)
int imgRead(const char *fname, IMG *img)
int imgWrite(const char *fname, IMG *img)
int imgGaussianFIRFilter(IMG *img, float xsd, float ysd, float zsd, double tolerance, int verbose)
int imgAvg(IMG *img, IMG_RANGE *r, float *avg)
int imgRangeMinMax(IMG *img, IMG_RANGE *r, IMG_PIXEL *maxp, float *maxv, IMG_PIXEL *minp, float *minv)
int imgGetPeak(IMG *img, float beforeTime, IMG_PIXEL *p, int verbose)
int tiffWriteImg(IMG *img, int plane, int frame, float *maxvalue, int colorscale, char *fname, int matXdim, int matYdim, int verbose, char *status)
Header file for libtpccurveio.
#define DFT_TIME_STARTEND
Header file for libtpcidi.
double rcPeakPET(double FWHM, double R)
int idiSimulateTubeImgPlane(int simmet, IMG *img, int zi, double cx, double cy, double r, double FWHM, double *cbkg, double *cblo)
int imgGetConcWeightedPeakPos(IMG *img, float thrs, IMG_PIXEL *pos, int verbose)
Header file for libtpcimgio.
Header file for libtpcimgp.
Header file for libtpcmisc.
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
size_t strlcpy(char *dst, const char *src, size_t dstsize)
void tpcProgramName(const char *program, int version, int copyright, char *prname, int n)
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)
Header file for libtpcmodel.
int tgo(double *lowlim, double *uplim, double(*objf)(int, double *, void *), void *objfData, int dim, int neighNr, double *fmin, double *gmin, int samNr, int tgoNr, int verbose)
double dmean(double *data, int n, double *sd)
double dmedian(double *data, int n)
Header file for libtpcmodext.
int dftAllocateWithIMG(DFT *dft, int tacNr, IMG *img)
char comments[_DFT_COMMENT_LEN+1]
char voiname[MAX_REGIONSUBNAME_LEN+1]
char name[MAX_REGIONNAME_LEN+1]