10#include "tpcclibConfig.h"
27static char *info[] = {
28 "Program calculates the average TAC from all pixels in a PET image or scan",
29 "file in ECAT 6.3 or 7 format, or PET image in NIfTI-1 or Analyze format,",
30 "to be used as 'head curve' or 'count-rate' file in time delay correction.",
31 "Decay correction is not changed: if image or sinogram is decay corrected,",
32 "head curve will be decay corrected, and vice versa.",
34 "Usage: @P [Options] petfile headcurve",
37 " -thr[=<Threshold-%>,<<Nr of frames>|<a>|<fh>>]",
38 " TAC is calculated from pixels exceeding the specified threshold level,",
39 " or 10% level with only -thr.",
40 " Specified number or default five last frames are used in determining",
41 " threshold level; alternatively, with 'a' all frames, or with 'fh'",
42 " the first half of frames are used in thresholding.",
43 " Without -thr option all pixels are included.",
45 " TAC times are written in minutes or seconds (default).",
47 " Frames with negative mean value are not set to zero.",
48 " -sum | -cps | -peakmax | -framemax",
49 " By default, mean of all or thresholded pixels is calculated;",
50 " with option -sum the sum of pixel values is reported, or",
51 " with option -cps the total radioactivity (not concentration), or",
52 " with option -peakmax the TAC of pixel which has the max peak value, or",
53 " with option -framemax the TAC with values of max at each frame.",
57 " @P -thr=10,5 ub6789dy1.v ub6789head.tac",
59 "See also: eframe, pxl2tac, img2dft, tocr, fitdelay, tac2svg, tacformat",
61 "Keywords: image, time delay, count-rate, head-curve, input, TAC",
80int main(
int argc,
char **argv)
82 int ai, help=0, version=0, verbose=1;
84 int timeunit=TUNIT_SEC;
89 int first, last, thr_nr=0;
90 char petfile[FILENAME_MAX], headfile[FILENAME_MAX], *cptr;
93 float threshold=0.0, thr_value;
99 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
100 petfile[0]=headfile[0]=(char)0;
102 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
103 cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(cptr==NULL)
continue;
105 if(strcasecmp(cptr,
"SUM")==0) {
107 }
else if(strcasecmp(cptr,
"CPS")==0) {
109 }
else if(strncasecmp(cptr,
"MIN", 1)==0) {
110 timeunit=TUNIT_MIN;
continue;
111 }
else if(strncasecmp(cptr,
"SEC", 1)==0) {
112 timeunit=TUNIT_SEC;
continue;
113 }
else if(strcasecmp(cptr,
"THR")==0) {
114 threshold=0.10; thr_nr=5;
continue;
115 }
else if(strncasecmp(cptr,
"THR=", 4)==0) {
117 cptr+=4; threshold=0.01*atof(cptr);
118 while(*cptr && *cptr!=
',') cptr++;
121 if(strcasecmp(cptr,
"A")==0) thr_nr=-1;
122 else if(strcasecmp(cptr,
"FH")==0) thr_nr=-2;
123 else thr_nr=atoi(cptr);
125 if(thr_nr!=0 && threshold>=0.0 && threshold<1.0)
continue;
126 }
else if(strncasecmp(cptr,
"KEEPNEGAT", 4)==0) {
127 keepnegat=1;
continue;
128 }
else if(strncasecmp(cptr,
"PEAKMAX", 4)==0) {
130 }
else if(strncasecmp(cptr,
"FRAMEMAX", 5)==0) {
134 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
139 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
144 if(ai<argc) {
strlcpy(petfile, argv[ai], FILENAME_MAX); ai++;}
145 if(ai<argc) {
strlcpy(headfile, argv[ai], FILENAME_MAX); ai++;}
146 if(ai<argc) {fprintf(stderr,
"Error: too many arguments.\n");
return(1);}
150 fprintf(stderr,
"Error: missing command-line argument; use option --help\n");
153 if(strcasecmp(petfile, headfile)==0) {
154 fprintf(stderr,
"Error: check the output filename.\n");
158 if(calcsum>0) fprintf(stderr,
"Warning: options -sum and -cps ignored.\n");
164 printf(
"petfile := %s\n", petfile);
165 printf(
"headfile := %s\n", headfile);
166 printf(
"threshold := %g%%\n", 100.*threshold);
167 printf(
"thr_nr := %d\n", thr_nr);
168 printf(
"keepnegat := %d\n", keepnegat);
169 printf(
"calcsum := %d\n", calcsum);
170 printf(
"maxpix := %d\n", maxpix);
171 printf(
"timeunit := %d\n", timeunit);
180 if(verbose>0) printf(
"reading %s\n", petfile);
183 fprintf(stderr,
"Error: %s\n", img.
statmsg);
184 if(verbose>1) printf(
"ret=%d\n", ret);
188 if(verbose>0) fprintf(stderr,
"Warning: missing pixel values.\n");
193 fprintf(stderr,
"Error: cannot correct sinogram counts.\n");
194 if(verbose>1) printf(
"ret=%d\n", ret);
201 if(verbose>1) printf(
"preparing head TAC\n");
206 fprintf(stderr,
"Error: cannot allocate memory for head TAC.\n");
213 char *p; p=strrchr(headfile,
'.');
224 if(verbose>1) printf(
"studynr := %s\n", dft.
studynr);
229 if(verbose>1) printf(
"original unit := %s\n",
petCunit(unit));
230 if(unit==CUNIT_BQ_PER_ML) unit=CUNIT_BQ;
231 else if(unit==CUNIT_KBQ_PER_ML) unit=CUNIT_KBQ;
232 else if(unit==CUNIT_MBQ_PER_ML) unit=CUNIT_MBQ;
233 else if(unit==CUNIT_NCI_PER_ML) unit=CUNIT_NCI;
234 else if(unit==CUNIT_UCI_PER_ML) unit=CUNIT_UCI;
235 else unit=CUNIT_UNKNOWN;
237 if(verbose>1) printf(
"count unit := %s\n", dft.
unit);
240 if(verbose>2) printf(
"setting TAC times\n");
244 if(timeunit==TUNIT_MIN) {
245 for(
int i=0; i<dft.
frameNr; i++) {
247 dft.
x1[i]/=60.0; dft.
x2[i]/=60.0; dft.
x[i]/=60.0;
251 if(verbose>2) printf(
"setting TAC names\n");
252 strcpy(dft.
voi[0].
name,
"Head");
262 if(verbose>5) printf(
"isotope := '%s'\n",
imgIsotope(&img));
273 if(verbose>1) printf(
"pxlvol := %g cc\n", pxlvol);
279 if(verbose>0) fprintf(stdout,
"calculating head curve\n");
281 if(verbose>1) fprintf(stdout,
"no thresholding\n");
283 if(verbose>1) fprintf(stdout,
"computing mean of pixels\n");
286 fprintf(stderr,
"Error: cannot calculate average TAC.\n");
287 if(verbose>1) printf(
"ret := %d\n", ret);
294 if(verbose>2) printf(
"sum of %d pixels\n", n);
295 for(fi=0; fi<img.
dimt; fi++) img.
sd[fi]*=(
float)n;
298 if(calcsum==2)
for(fi=0; fi<img.
dimt; fi++) img.
sd[fi]*=pxlvol;
299 }
else if(maxpix==1) {
300 if(verbose>1) fprintf(stdout,
"searching max peak\n");
304 fprintf(stderr,
"Error: cannot find peak value in image.\n");
305 if(verbose>1) printf(
"ret := %d\n", ret);
310 printf(
"image max at [%d,%d,%d,%d]\n", pxl.
x, pxl.
y, pxl.
z, pxl.
f);
311 for(fi=0; fi<img.
dimt; fi++)
312 img.
sd[fi]=img.
m[pxl.
z-1][pxl.
y-1][pxl.
x-1][fi];
314 if(verbose>1) fprintf(stdout,
"searching max for each frame\n");
316 for(fi=0; fi<img.
dimt && ret==0; fi++)
319 fprintf(stderr,
"Error: cannot find frame max in image.\n");
320 if(verbose>1) printf(
"ret := %d\n", ret);
328 last=img.
dimt-1; first=1+last-thr_nr;
if(first<0) first=0;
329 }
else if(thr_nr==-2) {
330 last=(img.
dimt-1)/2; first=0;
332 first=0; last=img.
dimt-1;
335 printf(
"calculating sum image from frames %d-%d\n", first+1, last+1);
336 if(img.
dimt>=last+2) printf(
"excluding frames %d-%d\n", last+2, img.
dimt);
337 else printf(
"all frames included\n");
344 fprintf(stderr,
"Error: cannot calculate sum image (%d).\n", ret);
349 if(verbose>2) printf(
"searching for maximum integral\n");
350 ret=
imgMax(&iimg, &thr_value);
351 if(verbose>1) printf(
"maximum integral value := %g\n", thr_value);
352 thr_value*=threshold;
354 if(verbose>1) printf(
"making a template image with threshold %g\n", thr_value);
357 fprintf(stderr,
"Error (%d): cannot threshold.\n", ret);
363 printf(
"First frame values of the thresholded pixels:\n");
365 for(zz=0; zz<timg.
dimz; zz++)
for(yy=0; yy<timg.
dimy; yy++)
366 for(xx=0; xx<timg.
dimx; xx++)
if(timg.
m[zz][yy][xx][0]>0) {
367 printf(
" v[%d][%d][%d] := %g\n", zz, yy, xx, img.
m[zz][yy][xx][0]);
373 if(ret==0) printf(
"template.v image saved for testing\n");
374 else fprintf(stderr,
"template.v image could not be saved for testing\n");
377 if(verbose>1) fprintf(stdout,
"computing mean of pixels\n");
381 fprintf(stderr,
"Error: cannot calculate average TAC (%d).\n", ret);
389 for(zz=0; zz<timg.
dimz; zz++)
for(yy=0; yy<timg.
dimy; yy++)
390 for(xx=0; xx<timg.
dimx; xx++)
if(timg.
m[zz][yy][xx][0]>0) n++;
391 if(verbose>1) printf(
"sum of %lld thresholded pixels\n", n);
392 for(
int i=0; i<img.
dimt; i++) img.
sd[i]*=(
float)n;
395 if(calcsum==2)
for(
int i=0; i<img.
dimt; i++) img.
sd[i]*=pxlvol;
396 }
else if(maxpix==1) {
397 if(verbose>1) fprintf(stdout,
"searching max peak\n");
399 for(zz=0; zz<timg.
dimz; zz++)
400 for(yy=0; yy<timg.
dimy; yy++)
401 for(xx=0; xx<timg.
dimx; xx++)
if(timg.
m[zz][yy][xx][0]<0.0001)
402 for(
int i=0; i<img.
dimt; i++) img.
sd[i]=0.0;
406 fprintf(stderr,
"Error: cannot find peak value in image.\n");
407 if(verbose>1) printf(
"ret := %d\n", ret);
412 printf(
"image max at [%d,%d,%d,%d]\n", pxl.
x, pxl.
y, pxl.
z, pxl.
f);
413 for(fi=0; fi<img.
dimt; fi++)
414 img.
sd[fi]=img.
m[pxl.
z-1][pxl.
y-1][pxl.
x-1][fi];
416 if(verbose>1) fprintf(stdout,
"searching max for each frame\n");
418 for(zz=0; zz<timg.
dimz; zz++)
419 for(yy=0; yy<timg.
dimy; yy++)
420 for(xx=0; xx<timg.
dimx; xx++)
if(timg.
m[zz][yy][xx][0]<0.0001)
421 for(
int i=0; i<img.
dimt; i++) img.
sd[i]=0.0;
423 for(fi=0; fi<img.
dimt && ret==0; fi++)
426 fprintf(stderr,
"Error: cannot find frame max in image.\n");
427 if(verbose>1) printf(
"ret := %d\n", ret);
434 if(verbose>3) printf(
"head TAC computed\n");
436 for(
int i=0; i<img.
dimt; i++) dft.
voi[0].
y[i]=img.
sd[i];
445 if(verbose>3) printf(
"checking whether initial zero is needed\n");
448 dft.
x1[0]=0.0; dft.
x2[0]=dft.
x1[1];
449 dft.
x[0]=0.5*(dft.
x1[0]+dft.
x2[0]);
450 dft.
voi[0].
y[0]=0.0;}
453 dft.
x[0]=dft.
x1[1]; dft.
voi[0].
y[0]=0.0;}
461 if(verbose>3) printf(
"removing subzero values\n");
462 for(
int i=0, n=0; i<dft.
frameNr; i++)
463 if(dft.
voi[0].
y[i]<0.0) {dft.
voi[0].
y[i]=0.0; n++;}
465 if(ret>0) printf(
"%d negative mean(s) changed to zero.\n", n);
466 else printf(
"all mean values were positive.\n");
472 if(verbose>3) printf(
"converting to MBq\n");
474 if(verbose>0 && ret!=0) fprintf(stderr,
"Warning: cannot convert units.\n");
475 if(verbose>2) printf(
"new unit := %s\n", dft.
unit);
481 if(verbose>1) fprintf(stdout,
"writing head curve in %s\n", headfile);
482 if(verbose>2) printf(
"dft._type := %d\n", dft.
_type);
485 fprintf(stderr,
"Error in writing '%s': %s\n", headfile,
dfterrmsg);
488 if(verbose>0) fprintf(stdout,
"Head curve written in %s\n", headfile);
491 if(verbose>0) fprintf(stdout,
"done.\n");
char * ctime_r_int(const time_t *t, char *buf)
Convert calendard time t into a null-terminated string of the form YYYY-MM-DD hh:mm:ss,...
int dftAddnullframe(DFT *data)
int dftWrite(DFT *data, char *filename)
int dftUnitConversion(DFT *dft, int dunit)
unsigned long long imgNaNs(IMG *img, int fix)
void imgEmpty(IMG *image)
int imgFrameIntegral(IMG *img, int first, int last, IMG *iimg, int verbose)
int imgRawCountsPerTime(IMG *img, int operation)
char * imgIsotope(IMG *img)
int imgAverageTAC(IMG *img, float *tac)
int imgAverageMaskTAC(IMG *img, IMG *timg, float *tac)
int imgRead(const char *fname, IMG *img)
int imgWrite(const char *fname, IMG *img)
int imgFrameMinMax(IMG *img, int frame, float *minvalue, float *maxvalue)
int imgGetPeak(IMG *img, float beforeTime, IMG_PIXEL *p, int verbose)
int imgMax(IMG *img, float *maxvalue)
int imgThresholdMask(IMG *img, float minValue, float maxValue, IMG *timg)
Header file for libtpccurveio.
#define DFT_FORMAT_CSV_UK
#define DFT_FORMAT_STANDARD
#define DFT_TIME_STARTEND
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)
int studynr_from_fname2(char *fname, char *studynr, int force)
int petCunitId(const char *unit)
char * petCunit(int cunit)
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 libtpcmodext.
int dftAllocateWithIMG(DFT *dft, int tacNr, IMG *img)
char studynr[MAX_STUDYNR_LEN+1]
char unit[MAX_UNITS_LEN+1]
char radiopharmaceutical[32]
char radiopharmaceutical[32]
char voiname[MAX_REGIONSUBNAME_LEN+1]
char name[MAX_REGIONNAME_LEN+1]
char hemisphere[MAX_REGIONSUBNAME_LEN+1]
char place[MAX_REGIONSUBNAME_LEN+1]