9#include "tpcclibConfig.h"
26static char *info[] = {
27 "Estimate Vb and (1-Vb)*Ct based on arterial blood curve (BTAC), assuming",
28 "that at BTAC peak tissue concentration is zero, thus Vb=Cpet/Cb",
29 "Vb is then reduced to assure that other TACs remain non-negative.",
31 "Do not use this oversimplified method for quantitative analyses!",
33 "Usage: @P [Options] imgfile btacfile ctimgfile",
35 "Data in image and BTAC file must be stored in the same units.",
38 " -vbfile=<filename>",
39 " Save image file containing Vb as pixel values.",
41 " Correct either arterial Vb or BTAC in injection veins, or",
45 "See also: imgcbv, taccbvp, imgpeak, imgcalc, imgthrs",
47 "Keywords: image, peak, vascular fraction",
66int main(
int argc,
char **argv)
68 int ai, help=0, version=0, verbose=1;
69 char petfile[FILENAME_MAX], btacfile[FILENAME_MAX], vbfile[FILENAME_MAX], ctfile[FILENAME_MAX];
76 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
77 petfile[0]=btacfile[0]=ctfile[0]=vbfile[0]=(char)0;
79 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
81 char *cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(cptr==NULL)
continue;
82 if(strncasecmp(cptr,
"VB=", 3)==0) {
83 strlcpy(vbfile, cptr+3, FILENAME_MAX);
continue;
84 }
else if(strcasecmp(cptr,
"LV")==0) {
86 }
else if(strcasecmp(cptr,
"RV")==0) {
89 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
94 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
99 if(ai<argc) {
strlcpy(petfile, argv[ai], FILENAME_MAX); ai++;}
100 if(ai<argc) {
strlcpy(btacfile, argv[ai], FILENAME_MAX); ai++;}
101 if(ai<argc) {
strlcpy(ctfile, argv[ai], FILENAME_MAX); ai++;}
102 if(ai<argc) {fprintf(stderr,
"Error: too many arguments.\n");
return(1);}
107 fprintf(stderr,
"Error: missing command-line argument; try %s --help\n", argv[0]);
113 printf(
"petfile := %s\n", petfile);
114 printf(
"btacfile := %s\n", btacfile);
115 printf(
"ctfile := %s\n", ctfile);
116 if(vbfile[0]) printf(
"vbfile := %s\n", vbfile);
117 printf(
"corrmode := %d\n", corrmode);
125 if(verbose>1) printf(
"reading data files\n");
132 petfile, NULL, btacfile, NULL, NULL, &endtime, &ai, &img,
133 &btac, NULL, 0, stdout, verbose-1, tmp);
135 fprintf(stderr,
"Error in reading data: %s.\n", tmp);
136 if(verbose>1) printf(
" ret := %d\n", ret);
140 if(verbose>0) fprintf(stderr,
"Warning: missing pixel values.\n");
141 if(verbose>2) printf(
"endtime := %g min\n", endtime);
145 float imgmin, imgmax;
147 fprintf(stderr,
"Error: invalid image contents.\n");
151 printf(
"image_min := %g\n", imgmin);
152 printf(
"image_max := %g\n", imgmax);
160 if(verbose>1) printf(
"finding BTAC peak\n");
161 double bpeak=btac.
voi[0].
y[0];
163 for(
int i=1; i<btac.
frameNr; i++)
164 if(btac.
voi[0].
y[i]>bpeak) {bpeak=btac.
voi[0].
y[i]; ipeak=i;}
166 printf(
" btac_maxv := %g\n", bpeak);
167 printf(
" btac_maxx := %g\n", btac.
x[ipeak]);
170 if(ipeak>0) bpeak+=btac.
voi[0].
y[ipeak-1];
172 printf(
" bpeak := %g\n", bpeak);
181 fprintf(stderr,
"Error: cannot allocate memory.\n");
184 vbimg.
unit=CUNIT_UNITLESS;
188 double rvtac[img.
dimt];
189 if(corrmode==3 || corrmode==2) {
194 for(
int zi=0; zi<img.
dimz; zi++) {
195 for(
int yi=0; yi<img.
dimy; yi++) {
196 for(
int xi=0; xi<img.
dimx; xi++) {
197 float tpeak=img.
m[zi][yi][xi][ipeak];
198 if(ipeak>0) tpeak+=img.
m[zi][yi][xi][ipeak-1];
199 if(tpeak/bpeak>2.0) {
200 for(
int ti=0; ti<img.
dimt; ti++) rvtac[ti]+=img.
m[zi][yi][xi][ti];
206 if(verbose>2) printf(
"nrv := %d\n", nrv);
207 if(nrv>0)
for(
int ti=0; ti<img.
dimt; ti++) rvtac[ti]/=(
double)nrv;
208 else for(
int ti=0; ti<img.
dimt; ti++) rvtac[ti]=0.0;
211 if(verbose>0) printf(
"RV correction not applied.\n");
212 if(corrmode==3) corrmode=1;
213 else if(corrmode==2) corrmode=0;
218 fprintf(stderr,
"Warning: no corrections applied, no files written.\n");
225 if(corrmode==0 || corrmode==2) {
228 double ymaxrv, xmaxrv;
int imaxrv;
232 for(
int ti=1; ti<img.
dimt; ti++)
if(rvtac[ti]>ymaxrv) {
238 printf(
" rv_maxv := %g\n", ymaxrv);
239 printf(
" rv_maxx := %g\n", xmaxrv);
243 for(
int zi=0; zi<img.
dimz; zi++) {
244 for(
int yi=0; yi<img.
dimy; yi++) {
245 for(
int xi=0; xi<img.
dimx; xi++) {
248 float vb=img.
m[zi][yi][xi][imaxrv]/ymaxrv;
250 for(
int ti=0; ti<img.
dimt; ti++) img.
m[zi][yi][xi][ti]=0.0;
251 vbimg.
m[zi][yi][xi][0]=vb;
256 float ct[img.
dimt], ctmin=0.0;
int ictmin=0;
257 for(
int ti=0; ti<img.
dimt; ti++) {
258 if(img.
m[zi][yi][xi][ti]>0.0) {
259 ct[ti]=img.
m[zi][yi][xi][ti]-vb*rvtac[ti];
260 if(ct[ti]<ctmin) {ctmin=ct[ti]; ictmin=ti;}
265 vb+=ctmin/rvtac[ictmin];
266 for(
int ti=0; ti<img.
dimt; ti++) {
267 if(img.
m[zi][yi][xi][ti]>0.0) {
268 ct[ti]=img.
m[zi][yi][xi][ti]-vb*rvtac[ti];
270 if(ct[ti]<0.0) ct[ti]=0.0;
274 for(
int ti=0; ti<img.
dimt; ti++) img.
m[zi][yi][xi][ti]=ct[ti];
276 vbimg.
m[zi][yi][xi][0]=vb;
284 if(corrmode==3 || corrmode==1) {
286 for(
int zi=0; zi<img.
dimz; zi++) {
287 for(
int yi=0; yi<img.
dimy; yi++) {
288 for(
int xi=0; xi<img.
dimx; xi++) {
291 float tpeak=img.
m[zi][yi][xi][ipeak];
292 if(ipeak>0) tpeak+=img.
m[zi][yi][xi][ipeak-1];
293 float vb=tpeak/bpeak;
295 for(
int ti=0; ti<img.
dimt; ti++) img.
m[zi][yi][xi][ti]=0.0;
296 vbimg.
m[zi][yi][xi][0]+=vb;
301 float ct[img.
dimt], ctmin=0.0;
int ictmin=0;
302 for(
int ti=0; ti<img.
dimt; ti++) {
303 if(img.
m[zi][yi][xi][ti]>0.0) {
304 ct[ti]=img.
m[zi][yi][xi][ti]-vb*btac.
voi[0].
y[ti];
305 if(ct[ti]<ctmin) {ctmin=ct[ti]; ictmin=ti;}
310 vb+=ctmin/btac.
voi[0].
y[ictmin];
311 for(
int ti=0; ti<img.
dimt; ti++) {
312 if(img.
m[zi][yi][xi][ti]>0.0) {
313 ct[ti]=img.
m[zi][yi][xi][ti]-vb*btac.
voi[0].
y[ti];
315 if(ct[ti]<0.0) ct[ti]=0.0;
319 for(
int ti=0; ti<img.
dimt; ti++) img.
m[zi][yi][xi][ti]=ct[ti];
321 vbimg.
m[zi][yi][xi][0]+=vb;
330 if(verbose>1) fprintf(stdout,
"writing %s\n", ctfile);
333 fprintf(stderr,
"Error: %s\n", img.
statmsg);
334 if(verbose>1) printf(
"ret=%d\n", ret);
338 if(verbose>0) printf(
"Written %s\n", ctfile);
343 if(verbose>1) fprintf(stdout,
"writing %s\n", vbfile);
346 fprintf(stderr,
"Error: %s\n", vbimg.
statmsg);
347 if(verbose>1) printf(
"ret=%d\n", ret);
351 if(verbose>0) printf(
"Written %s\n", vbfile);
unsigned long long imgNaNs(IMG *img, int fix)
int imgAllocateWithHeader(IMG *image, int planes, int rows, int columns, int frames, IMG *image_from)
void imgEmpty(IMG *image)
int imgWrite(const char *fname, IMG *img)
int imgMinMax(IMG *img, float *minvalue, float *maxvalue)
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)
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.
Header file for libtpcmodext.