10#include "tpcclibConfig.h"
30static char *info[] = {
31 "Estimate tissue and vascular components in dynamic myocardial PET imaging",
32 "using 1TCM and LV cavity BTAC.",
34 "Usage: @P [Options] bfile imgfile tcimgfile vcimgfile",
38 " Pixels with AUC less than (threshold/100 x PTAC AUC) are set to zero;",
40 " -end=<Fit end time (min)>",
41 " Use data from 0 to end time; by default, model is fitted to all frames.",
44 "See also: imgpeak, imgaumc",
46 "Keywords: image, modelling, NNLS",
65int main(
int argc,
char **argv)
67 int ai, help=0, version=0, verbose=1;
68 char bfile[FILENAME_MAX], petfile[FILENAME_MAX], tcfile[FILENAME_MAX];
69 char vcfile[FILENAME_MAX];
70 float calcThreshold=0.01;
77 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
78 bfile[0]=petfile[0]=tcfile[0]=vcfile[0]=(char)0;
80 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
82 char *cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(cptr==NULL)
continue;
83 if(strncasecmp(cptr,
"THR=", 4)==0) {
85 if(!ret && v>=0.0 && v<=200.0) {calcThreshold=(float)(0.01*v);
continue;}
86 }
else if(strncasecmp(cptr,
"END=", 4)==0) {
87 ret=
atof_with_check(cptr+4, &fittime);
if(!ret && fittime>0.0)
continue;
89 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
95 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
100 if(ai<argc)
strlcpy(bfile, argv[ai++], FILENAME_MAX);
101 if(ai<argc)
strlcpy(petfile, argv[ai++], FILENAME_MAX);
102 if(ai<argc)
strlcpy(tcfile, argv[ai++], FILENAME_MAX);
103 if(ai<argc)
strlcpy(vcfile, argv[ai++], FILENAME_MAX);
104 if(ai<argc) {fprintf(stderr,
"Error: invalid argument '%s'.\n", argv[ai]);
return(1);}
107 fprintf(stderr,
"Error: missing command-line argument; use option --help\n");
return(1);}
110 printf(
"bfile := %s\n", bfile);
111 printf(
"petfile := %s\n", petfile);
112 printf(
"tcfile := %s\n", tcfile);
113 printf(
"vcfile := %s\n", vcfile);
114 printf(
"calcThreshold :=%g\n", calcThreshold);
115 if(fittime>0.0) printf(
"required_fittime := %g min\n", fittime);
124 if(verbose>0) printf(
"reading data files\n");
130 petfile, NULL, bfile, NULL, NULL, &fittime, &dataNr, &img,
131 NULL, &tac, 1, stdout, verbose-2, errmsg);
133 fprintf(stderr,
"Error: %s.\n", errmsg);
134 if(verbose>1) printf(
" ret := %d\n", ret);
138 if(verbose>0) fprintf(stderr,
"Warning: missing pixel values.\n");
141 for(
int fi=0; fi<tac.
frameNr; fi++) tac.
voi[0].
y2[fi]/=60.0;
142 for(
int fi=0; fi<tac.
frameNr; fi++) tac.
voi[0].
y3[fi]/=3600.0;
146 printf(
"fittimeFinal := %g min\n", fittime);
147 printf(
"dataNr := %d\n", dataNr);
151 fprintf(stderr,
"Error: too few time frames for fitting.\n");
158 if(verbose>1) fprintf(stdout,
"allocating working memory for pixel TACs\n");
161 fprintf(stderr,
"Error: cannot allocate memory.\n");
162 if(verbose>0) printf(
"ret := %d\n", ret);
165 strcpy(tac.
voi[0].
name,
"LV-cavity");
166 strcpy(tac.
voi[1].
name,
"RV-cavity");
167 strcpy(tac.
voi[2].
name,
"tissue");
173 for(
int i=0; i<tac.
frameNr; i++) tmov[i]=tac.
x[i]-7.0/60;
177 fprintf(stderr,
"Error: cannot interpolate data.\n");
183 double threshold=calcThreshold*tac.
voi[0].
y2[dataNr-1];
184 if(verbose>1) printf(
"threshold_AUC := %g\n", threshold);
190 if(verbose>1) fprintf(stdout,
"allocating memory for parametric image data\n");
196 fprintf(stderr,
"Error: cannot allocate memory for result image.\n");
202 vcimg.
end[0]=tcimg.
end[0]=60.*fittime;
204 tcimg.
unit=CUNIT_UNITLESS;
205 vcimg.
unit=CUNIT_UNITLESS;
210 int fittedNr=0, fittedokNr=0, thresholdNr=0;
215 if(verbose>1) fprintf(stdout,
"allocating memory for NNLS\n");
219 double **nnls_a, nnls_b[nnls_m], nnls_zz[nnls_m], *nnls_mat,
221 nnls_mat=(
double*)malloc((nnls_n*nnls_m)*
sizeof(
double));
222 nnls_a=(
double**)malloc(nnls_n*
sizeof(
double*));
223 if(nnls_mat==NULL || nnls_a==NULL) {
224 fprintf(stderr,
"Error: cannot allocate memory for NNLS.\n");
228 for(n=0; n<nnls_n; n++) nnls_a[n]=nnls_mat+n*nnls_m;
233 if(verbose>0) fprintf(stdout,
"computing NNLS pixel-by-pixel\n");
234 double *ct, *cti, *clv, *clvi, *crv;
238 for(
int pi=0; pi<img.
dimz; pi++) {
239 if(verbose>0) {fprintf(stdout,
"."); fflush(stdout);}
240 for(
int yi=0; yi<img.
dimy; yi++) {
241 for(
int xi=0; xi<img.
dimx; xi++) {
243 tcimg.
m[pi][yi][xi][0]=0.0;
244 vcimg.
m[pi][yi][xi][0]=0.0;
246 for(
int fi=0; fi<tac.
frameNr; fi++) ct[fi]=img.
m[pi][yi][xi][fi];
250 if(cti[dataNr-1]<threshold) {thresholdNr++;
continue;}
257 for(
int m=0; m<nnls_m; m++) {
258 nnls_a[0][m]=clvi[m];
261 nnls_a[3][m]=-cti[m];
264 if( pi==img.
dimz/2 && yi==img.
dimy/2 && xi==img.
dimx/2) {
265 printf(
"Matrix A Array B\n");
266 for(m=0; m<nnls_m; m++) {
267 printf(
"%12.3f %12.3f %12.3f %12.3f %12.3f\n",
268 nnls_a[0][m], nnls_a[1][m], nnls_a[2][m], nnls_a[3][m], nnls_b[m]);
272 int nnls_index[nnls_n];
273 double nnls_x[nnls_n], nnls_wp[nnls_n];
274 ret=
nnls(nnls_a, nnls_m, nnls_n, nnls_b, nnls_x, &nnls_rnorm, nnls_wp, nnls_zz, nnls_index);
276 if(verbose>3) printf(
"no solution possible (%d)\n", ret);
277 if(verbose>4) printf(
"nnls_n=%d nnls_m=%d\n", nnls_n, nnls_m);
278 for(
int n=0; n<nnls_n; n++) nnls_x[n]=0.0;
282 fittedNr++; fittedokNr++;
285 vcimg.
m[pi][yi][xi][0]=nnls_x[1]+0.5*nnls_x[2];
286 if(vcimg.
m[pi][yi][xi][0]>2.0) vcimg.
m[pi][yi][xi][0]=2.0;
288 tcimg.
m[pi][yi][xi][0]=nnls_x[0]-nnls_x[3]*(nnls_x[1]+0.9*nnls_x[2]);;
289 double b=nnls_x[1]+0.9*nnls_x[2];
290 if(b>0.0 && b<0.67) tcimg.
m[pi][yi][xi][0]/=(1.0-b);
291 if(tcimg.
m[pi][yi][xi][0]>1.0) tcimg.
m[pi][yi][xi][0]=1.0;
292 if(tcimg.
m[pi][yi][xi][0]<0.0) tcimg.
m[pi][yi][xi][0]=0.0;
297 if(verbose>0) {fprintf(stdout,
" done.\n"); fflush(stdout);}
298 free(nnls_mat); free(nnls_a);
302 fprintf(stdout,
"%d out of %d pixels were fitted; %d pixels ok.\n", fittedokNr, n, fittedNr);
303 fprintf(stdout,
"%d pixels were thresholded.\n", thresholdNr);
316 if(!ret) ret=
imgWrite(vcfile, &vcimg);
319 fprintf(stderr,
"Error: cannot write parametric image.\n");
322 if(verbose>0) fprintf(stdout,
"Parametric image(s) saved.\n");
int atof_with_check(char *double_as_string, double *result_value)
int dftAddmem(DFT *dft, int voiNr)
int dftTimeunitConversion(DFT *dft, int tunit)
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 petintegral(double *x1, double *x2, double *y, int nr, double *ie, double *iie)
Integrate PET TAC data to frame mid times.
int interpolate4pet(double *x, double *y, int nr, double *newx1, double *newx2, double *newy, double *newyi, double *newyii, int newnr)
Interpolate and integrate TAC to PET frames.
Header file for libtpccurveio.
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.
int nnls(double **a, int m, int n, double *b, double *x, double *rnorm, double *w, double *zz, int *index)
Header file for libtpcmodext.
char name[MAX_REGIONNAME_LEN+1]